Example #1
0
        /// <summary><para>Die Funktion verschiebt das Datum von <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.Potsdam">Potsdam</see> (nur Deutschland) nach <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84</see> (international).
        /// <para>Die Funktion ist nur für interne Berechnungen bestimmt.</para></para></summary>
        /// <remarks><para>
        /// Hintergründe zum Problem der Koordinatentransformationen sowie entsprechende  mathematische 
        /// Formeln können den einschlägigen Fachbüchern oder dem Internet entnommen werden.<p />
        /// Quellen: 
        /// Bundesamt für Kartographie und Geodäsie<br />
        /// <a href="http://www.bkg.bund.de" target="_blank">http://www.bkg.bund.de</a><br />
        /// <a href="http://crs.bkg.bund.de" target="_blank">http://crs.bkg.bund.de</a><br />
        /// </para></remarks>
        /// 
        /// <param name="geo">Ein <see cref="GeoUtility.GeoSystem.Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.Potsdam">Potsdam-Datum</see></param>
        /// <returns>Ein <see cref="GeoUtility.GeoSystem.Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84-Datum</see>.</returns>
        internal Geographic PODWGS(Geographic geo)
        {

            double laengePotsdam = geo.Longitude;
            double breitePotsdam = geo.Latitude;

            // Breite und Länge (Rad)
            double breiteRad = breitePotsdam * (Math.PI / 180);
            double laengeRad = laengePotsdam * (Math.PI / 180);

            // Querkrümmung
            double qkhm = HALBACHSE / Math.Sqrt(1 - EXZENT * Math.Sin(breiteRad) * Math.Sin(breiteRad));

            // Kartesische Koordinaten Potsdam
            double xPotsdam = qkhm * Math.Cos(breiteRad) * Math.Cos(laengeRad);
            double yPotsdam = qkhm * Math.Cos(breiteRad) * Math.Sin(laengeRad);
            double zPotsdam = (1 - EXZENT) * qkhm * Math.Sin(breiteRad);

            // Kartesische Koordinaten WGS84
            double x = xPotsdam + POTSDAM_DATUM_SHIFT_X;
            double y = yPotsdam + POTSDAM_DATUM_SHIFT_Y;
            double z = zPotsdam + POTSDAM_DATUM_SHIFT_Z;

            // Breite und Länge im WGS84 Datum
            double b = Math.Sqrt(x * x + y * y);
            double breite = (180 / Math.PI) * Math.Atan((z / b) / (1 - WGS84_EXZENT));

            double laenge = 0;
            if (x > 0) laenge = (180 / Math.PI) * Math.Atan(y / x);
            if (x < 0 && y > 0) laenge = (180 / Math.PI) * Math.Atan(y / x) + 180;
            if (x < 0 && y < 0) laenge = (180 / Math.PI) * Math.Atan(y / x) - 180;

            return new Geographic(laenge, breite, GeoDatum.WGS84);
        }
Example #2
0
        /// <summary><para>Die Funktion wandelt geographische Koordinaten (Länge/Breite) eines <see cref="GeoSystem.Geographic"/>-Objektes 
        /// in ein <see cref="GeoUtility.GeoSystem.GaussKrueger">GaussKrueger</see>-Objekt um.
        /// <para>Die Funktion ist nur für interne Berechnungen bestimmt.</para></para></summary>
        /// <remarks><para>
        /// Hintergründe zum Problem der Koordinatentransformationen sowie entsprechende mathematische 
        /// Formeln können den einschlägigen Fachbüchern oder dem Internet entnommen werden.<p />
        /// Quellen: 
        /// Bundesamt für Kartographie und Geodäsie<br />
        /// <a href="http://www.bkg.bund.de" target="_blank">http://www.bkg.bund.de</a><br />
        /// <a href="http://crs.bkg.bund.de" target="_blank">http://crs.bkg.bund.de</a><br />
        /// </para></remarks>
        /// 
        /// <param name="geo"><see cref="GeoSystem.Geographic"/>-Objekt (<see cref="GeoUtility.GeoSystem.Helper.GeoDatum.Potsdam">Potsdam-Datum</see>)</param>
        /// <returns>Ein <see cref="GeoUtility.GeoSystem.GaussKrueger "/>-Objekt.</returns>
        internal GaussKrueger WGSGK(Geographic geo)
        {

            double laenge = geo.Longitude;
            double breite = geo.Latitude;

            if (breite < MIN_NORD || breite > MAX_NORD || laenge < MIN_OST || laenge > MAX_OST)
            {
                throw new ErrorProvider.GeoException(new ErrorProvider.ErrorMessage("ERROR_GK_OUT_OF_RANGE"));
            }

            // Datum muss eventuell erst nach Potsdam transformiert werden.
            if (geo.Datum == GeoDatum.WGS84) geo.SetDatum(GeoDatum.Potsdam);

            // Koeffizienten für Länge Meridianbogen
            double koeff0 = POL * (Math.PI / 180) * (1 - 3 * EXZENT2 / 4 + 45 * EXZENT4 / 64 - 175 * EXZENT6 / 256 + 11025 * EXZENT8 / 16384);
            double koeff2 = POL * (-3 * EXZENT2 / 8 + 15 * EXZENT4 / 32 - 525 * EXZENT6 / 1024 + 2205 * EXZENT8 / 4096);
            double koeff4 = POL * (15 * EXZENT4 / 256 - 105 * EXZENT6 / 1024 + 2205 * EXZENT8 / 16384);
            double koeff6 = POL * (-35 * EXZENT6 / 3072 + 315 * EXZENT8 / 12288);

            // Breite (Rad)
            double breiteRad = breite * Math.PI / 180;

            double tangens1 = Math.Tan(breiteRad);
            double tangens2 = Math.Pow(tangens1, 2);
            double tangens4 = Math.Pow(tangens1, 4);
            double cosinus1 = Math.Cos(breiteRad);
            double cosinus2 = Math.Pow(cosinus1, 2);
            double cosinus3 = Math.Pow(cosinus1, 3);
            double cosinus4 = Math.Pow(cosinus1, 4);
            double cosinus5 = Math.Pow(cosinus1, 5);

            double eta = EXZENT2 * cosinus2;

            // Querkrümmung
            double qkhm = POL / Math.Sqrt(1 + eta);

            // Länge des Meridianbogens
            double lmbog = koeff0 * breite + koeff2 * Math.Sin(2 * breiteRad) + koeff4 * Math.Sin(4 * breiteRad) + koeff6 * Math.Sin(6 * breiteRad);

            // Differenz zum Bezugsmeridian
            int kfakt = (int)((laenge + 1.5) / 3);
            int merid = kfakt * 3;
            double dlaenge1 = (laenge - merid) * Math.PI / 180;
            double dlaenge2 = Math.Pow(dlaenge1, 2);
            double dlaenge3 = Math.Pow(dlaenge1, 3);
            double dlaenge4 = Math.Pow(dlaenge1, 4);
            double dlaenge5 = Math.Pow(dlaenge1, 5);

            // Hochwert, Rechtswert
            double hoch = (lmbog + qkhm * cosinus2 * tangens1 * dlaenge2 / 2 + qkhm * cosinus4 * tangens1 * (5 - tangens2 + 9 * eta) * dlaenge4 / 24);
            double rechts = (qkhm * cosinus1 * dlaenge1 + qkhm * cosinus3 * (1 - tangens2 + eta) * dlaenge3 / 6 + qkhm * cosinus5 * (5 - 18 * tangens2 + tangens4) * dlaenge5 / 120 + kfakt * 1e6 + 500000);

            return new GaussKrueger(rechts, hoch); ;
        }
Example #3
0
        /// <summary><para>Die Funktion berechnet den internen Schlüssel für ein Luftbild, welches zu den Geodaten gehört.</para></summary>
        /// <remarks><para>Um nicht für die verschiedenen MapService-Dienste jeweils eigene Funktionen anbieten zu müssen, 
        /// werden alle Berechnungen intern mit einem generischen Schlüssel durchgeführt und später gegebenenfalls 
        /// in den gewählten MapService-Dienst übersetzt. 
        /// <para>Die Funktion ist nur für interne Berechnungen bestimmt.</para>
        /// </para></remarks>
        /// 
        /// <param name="geo"><see cref="Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84-Datum</see></param>
        /// <param name="zoom">Zoomlevel 1-21</param>
        /// <returns>Interner Schlüssel als <see cref="MapService.Info.MapServiceInternalMapTile"/>-Objekt.</returns>
        internal MapService.Info.MapServiceInternalMapTile WGSIMAP(Geographic geo, int zoom)
        {
            double laenge = geo.Longitude;
            double breite = geo.Latitude;

            if (laenge > 180) laenge -= 360;
            laenge /= 180;

            // Breitengrad in den Bereich -1 bis +1 bringen
            breite = Math.Log(Math.Tan((Math.PI / 4) + ((0.5 * Math.PI * breite) / 180))) / Math.PI;

            double tBreite = -1;
            double tLaenge = -1;
            double laengeWidth = 2;
            double breiteHeight = 2;
            StringBuilder key = new StringBuilder("t");

            // Interner Schlüssel berechnen 
            for (int i = 0; i < zoom; i++)
            {
                laengeWidth /= 2;
                breiteHeight /= 2;
                if ((tBreite + breiteHeight) > breite)
                {
                    if ((tLaenge + laengeWidth) > laenge)
                    {
                        key.Append('t');
                    }
                    else
                    {
                        tLaenge += laengeWidth;
                        key.Append('s');
                    }
                }
                else
                {
                    tBreite += breiteHeight;
                    if ((tLaenge + laengeWidth) > laenge)
                    {
                        key.Append('q');
                    }
                    else
                    {
                        tLaenge += laengeWidth;
                        key.Append('r');
                    }
                }
            }

            return new MapService.Info.MapServiceInternalMapTile(key.ToString());
        }
Example #4
0
        /// <summary><para>Die Funktion verschiebt das Datum von <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84</see> (international) nach <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.Potsdam">Potsdam</see> (nur Deutschland).
        /// <para>Die Funktion ist nur für interne Berechnungen bestimmt.</para></para></summary>
        /// <remarks><para>
        /// Hintergründe zum Problem der Koordinatentransformationen sowie entsprechende  mathematische 
        /// Formeln können den einschlägigen Fachbüchern oder dem Internet entnommen werden.<p />
        /// Quellen: 
        /// Bundesamt für Kartographie und Geodäsie<br />
        /// <a href="http://www.bkg.bund.de" target="_blank">http://www.bkg.bund.de</a><br />
        /// <a href="http://crs.bkg.bund.de" target="_blank">http://crs.bkg.bund.de</a><br />
        /// </para></remarks>
        ///         
        /// <param name="geo">Ein <see cref="GeoUtility.GeoSystem.Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84-Datum</see>.</param>
        /// <returns>Ein <see cref="GeoUtility.GeoSystem.Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.Potsdam">Potsdam-Datum</see>.</returns>
        internal Geographic WGSPOD(Geographic geo)
        {

            double laengeWGS84 = geo.Longitude;
            double breiteWGS84 = geo.Latitude;

            // Breite und Länge (Rad)
            double breiteRad = breiteWGS84 * (Math.PI / 180);
            double laengeRad = laengeWGS84 * (Math.PI / 180);

            // Querkrümmung
            double qkhm = WGS84_HALBACHSE / Math.Sqrt(1 - WGS84_EXZENT * Math.Sin(breiteRad) * Math.Sin(breiteRad));

            // Kartesische Koordinaten WGS84
            double xWGS84 = qkhm * Math.Cos(breiteRad) * Math.Cos(laengeRad);
            double yWGS84 = qkhm * Math.Cos(breiteRad) * Math.Sin(laengeRad);
            double zWGS84 = (1 - WGS84_EXZENT) * qkhm * Math.Sin(breiteRad);

            // Kartesische Koordinaten Potsdam
            double x = xWGS84 - POTSDAM_DATUM_SHIFT_X;
            double y = yWGS84 - POTSDAM_DATUM_SHIFT_Y;
            double z = zWGS84 - POTSDAM_DATUM_SHIFT_Z;

            // Breite und Länge im Potsdam Datum
            double b = Math.Sqrt(x * x + y * y);
            double breite = (180 / Math.PI) * Math.Atan((z / b) / (1 - EXZENT));

            double laenge = 0;
            if (x > 0) laenge = (180 / Math.PI) * Math.Atan(y / x);
            if (x < 0 && y > 0) laenge = (180 / Math.PI) * Math.Atan(y / x) + 180;
            if (x < 0 && y < 0) laenge = (180 / Math.PI) * Math.Atan(y / x) - 180;

            if (laenge < MIN_OST || laenge > MAX_OST || breite < MIN_NORD || breite > MAX_NORD)
            {
                throw new ErrorProvider.GeoException(new ErrorProvider.ErrorMessage("ERROR_GK_OUT_OF_RANGE"));
            }

            return new Geographic(laenge, breite, GeoDatum.Potsdam);
        }
Example #5
0
        public string GetMGRS()
        {
            Geographic geo = new Geographic(Lng, Lat);

            MGRS mgrs = (MGRS)geo;

            return mgrs.ToString();
        }
        /// <summary><para>Die Funktion wandelt die geographischen Koordinaten eines <see cref="GeoSystem.Geographic"/>-Objekts 
        /// in die Koordinaten eines <see cref="GeoSystem.UTM"/>-Objekts um.
        /// <para>Die Funktion ist nur für interne Berechnungen bestimmt.</para></para></summary>
        /// <remarks><para>
        /// Hintergründe zum Problem der Koordinatentransformationen sowie entsprechende  mathematische 
        /// Formeln können den einschlägigen Fachbüchern oder dem Internet entnommen werden.<p />
        /// Quellen: 
        /// Bundesamt für Kartographie und Geodäsie<br />
        /// <a href="http://www.bkg.bund.de" target="_blank">http://www.bkg.bund.de</a><br />
        /// <a href="http://crs.bkg.bund.de" target="_blank">http://crs.bkg.bund.de</a><br />
        /// </para></remarks>
        /// 
        /// <param name="geo"><see cref="GeoSystem.Geographic"/>-Objekt im <see cref="GeoUtility.GeoSystem.Helper.GeoDatum.WGS84">WGS84-Datum</see>.</param>
        /// <returns>Ein <see cref="GeoSystem.UTM"/>-Objekt.</returns>
        internal UTM WGSUTM(Geographic geo)
        {

            // falls geo Objekt nicht im WGS84-Datum
            if (geo.Datum != GeoDatum.WGS84) geo = this.PODWGS(geo);

            double laenge = geo.Longitude;
            double breite = geo.Latitude;

            if (laenge <= MIN_LAENGE || laenge > MAX_LAENGE || breite < MIN_BREITE || breite > MAX_BREITE)
            {
                throw new ErrorProvider.GeoException(new ErrorProvider.ErrorMessage("ERROR_GEO2UTM"));
            }

            // Koeffizienten für Länge Meridianbogen
            double koeff0 = WGS84_POL * (Math.PI / 180) * (1 - 3 * WGS84_EXZENT2 / 4 + 45 * WGS84_EXZENT4 / 64 - 175 * WGS84_EXZENT6 / 256 + 11025 * WGS84_EXZENT8 / 16384);
            double koeff2 = WGS84_POL * (-3 * WGS84_EXZENT2 / 8 + 15 * WGS84_EXZENT4 / 32 - 525 * WGS84_EXZENT6 / 1024 + 2205 * WGS84_EXZENT8 / 4096);
            double koeff4 = WGS84_POL * (15 * WGS84_EXZENT4 / 256 - 105 * WGS84_EXZENT6 / 1024 + 2205 * WGS84_EXZENT8 / 16384);
            double koeff6 = WGS84_POL * (-35 * WGS84_EXZENT6 / 3072 + 315 * WGS84_EXZENT8 / 12288);

            // Berechnung Zone, Band
            int zone = (int)((laenge + 180) / 6) + 1;
            // Handling UTM exception 
            if ((breite >= 56d) && (breite < 64d) && (laenge >= 3d) && (laenge < 12d)) 
            {
                // South-Norway 31V-32V (32V extends to the west from 3 to 12 degrees, with degree 9 as meridian)
                zone = 32;

            }
            else if (breite >= 72d) 
            {
                // Arctic region exceptions
                if ((laenge >= 0d) && (laenge < 9d)) zone = 31;
                else if ((laenge >= 9d) && (laenge < 21d)) zone = 33;
                else if ((laenge >= 21d) && (laenge < 33d)) zone = 35;
                else if ((laenge >= 33d) && (laenge < 42d)) zone = 37;
            }

            string sZone = string.Format("00", zone);
            int bandIndex = (int)(1 + (breite + 80) / 8);
            string band = UTM_BAND.Substring(bandIndex - 1, 1);

            // Geographische Breite (Rad)
            double breiteRad = breite * Math.PI / 180;

            double tangens1 = Math.Tan(breiteRad);
            double tangens2 = Math.Pow(tangens1, 2);
            double tangens4 = Math.Pow(tangens1, 4);
            double cosinus1 = Math.Cos(breiteRad);
            double cosinus2 = Math.Pow(cosinus1, 2);
            double cosinus3 = Math.Pow(cosinus1, 3);
            double cosinus4 = Math.Pow(cosinus1, 4);
            double cosinus5 = Math.Pow(cosinus1, 5);

            double eta = WGS84_EXZENT2 * cosinus2;

            // Querkrümmung
            double qkhm = WGS84_POL / Math.Sqrt(1 + eta);

            // Länge des Meridianbogens
            double lmbog = (koeff0 * breite) + (koeff2 * Math.Sin(2 * breiteRad)) + (koeff4 * Math.Sin(4 * breiteRad)) + (koeff6 * Math.Sin(6 * breiteRad));

            // Differenz zum Bezugsmeridian
            int merid = (zone - 30) * 6 - 3;

            double dlaenge1 = (laenge - merid) * Math.PI / 180;
            double dlaenge2 = Math.Pow(dlaenge1, 2);
            double dlaenge3 = Math.Pow(dlaenge1, 3);
            double dlaenge4 = Math.Pow(dlaenge1, 4);
            double dlaenge5 = Math.Pow(dlaenge1, 5);

            // Berechnung East, North
            double east, north;
            if (breite < 0)
            {
                north = 10E+06 + UTM_FAKTOR * (lmbog + qkhm * cosinus2 * tangens1 * dlaenge2 / 2 + qkhm * cosinus4 * tangens1 * (5 - tangens2 + 9 * eta) * dlaenge4 / 24);
            }
            else
            {
                north = UTM_FAKTOR * (lmbog + qkhm * cosinus2 * tangens1 * dlaenge2 / 2 + qkhm * cosinus4 * tangens1 * (5 - tangens2 + 9 * eta) * dlaenge4 / 24);
            }
            east = UTM_FAKTOR * (qkhm * cosinus1 * dlaenge1 + qkhm * cosinus3 * (1 - tangens2 + eta) * dlaenge3 / 6 + qkhm * cosinus5 * (5 - 18 * tangens2 + tangens4) * dlaenge5 / 120) + UTM_FALSE_EASTING;

            north = Math.Round(north, 3);
            east = Math.Round(east, 3);

            return new UTM(zone, band, east, north);
        }
Example #7
0
 public MGRS ConvertToMgrs()
 {
     var geo = new Geographic(Longitude, Latitude, GeoDatum.WGS84);
     return (MGRS)geo;
 }
Example #8
0
 public UTM ConvertToUtm()
 {
     var geo = new Geographic(Longitude, Latitude, GeoDatum.WGS84);
     return (UTM)geo;
 }