Пример #1
0
        //converts UTM coords to lat/long.  Equations from USGS Bulletin 1532
        //East Longitudes are positive, West longitudes are negative.
        //North latitudes are positive, South latitudes are negative
        //Lat and Long are in decimal degrees.
        //Does not take into account the special UTM zones between 0 degrees
        //and 36 degrees longitude above 72 degrees latitude and a special
        //zone 32 between 56 degrees and 64 degrees north latitude
        //Written by Chuck Gantz- [email protected]
        // Ported to C by David Baird, 1998, Re-ported to C# by David Baird 2010
        public static void UTMToLatLong(Ellipsoid referenceEllipsoid, double northing, double easting, string zone, out double latitude, out double longitude)
        {
            latitude = 0;
            longitude = 0;

            const double k0 = 0.9996;
            double a = referenceEllipsoid.EquatorialRadius;
            double eccSquared = referenceEllipsoid.EccentricitySquared;
            double e1 = (1 - Math.Sqrt(1 - eccSquared)) / (1 + Math.Sqrt(1 - eccSquared));
            // int NorthernHemisphere; //1 for northern hemispher, 0 for southern

            double x = easting - 500000.0;
            double y = northing;
            //if ( x <= 2875) x = 2875;		    // -db- 01/09/1998 To stop errors when Easting = 500000
            if (y == 0) y = 0.000000001;		// -db- 01/09/1998 To stop errors when Northing = 0

            var match = ZoneRegex.Match(zone);
            if (!match.Success) {
                return;
            }

            char zoneLetter = match.Groups[2].Value.ToUpper()[0];
            int zoneNumber = Int32.Parse(match.Groups[1].Value);

            if ((zoneLetter - 'N') > 0) {
                // NorthernHemisphere = 1;//point is in northern hemisphere
            } else {
                // NorthernHemisphere = 0;//point is in southern hemisphere
                y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
            }

            double longOrigin = (zoneNumber - 1) * 6 - 180 + 3;

            double eccPrimeSquared = (eccSquared) / (1 - eccSquared);

            double m = y / k0;
            double mu = m / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));

            double phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.Sin(2 * mu)
                             + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.Sin(4 * mu)
                             + (151 * e1 * e1 * e1 / 96) * Math.Sin(6 * mu);

            double n1 = a / Math.Sqrt(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad));
            double t1 = Math.Tan(phi1Rad) * Math.Tan(phi1Rad);
            double c1 = eccPrimeSquared * Math.Cos(phi1Rad) * Math.Cos(phi1Rad);
            double r1 = a * (1 - eccSquared) / Math.Pow(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad), 1.5);
            double d = x / (n1 * k0);

            latitude = phi1Rad - (n1 * Math.Tan(phi1Rad) / r1) * (d * d / 2 - (5 + 3 * t1 + 10 * c1 - 4 * c1 * c1 - 9 * eccPrimeSquared) * d * d * d * d / 24
                            + (61 + 90 * t1 + 298 * c1 + 45 * t1 * t1 - 252 * eccPrimeSquared - 3 * c1 * c1) * d * d * d * d * d * d / 720);
            latitude = latitude * RadsToDegrees;

            longitude = (d - (1 + 2 * t1 + c1) * d * d * d / 6 + (5 - 2 * c1 + 28 * t1 - 3 * c1 * c1 + 8 * eccPrimeSquared + 24 * t1 * t1)
                            * d * d * d * d * d / 120) / Math.Cos(phi1Rad);
            longitude = longOrigin + longitude * RadsToDegrees;
        }
Пример #2
0
        //converts UTM coords to lat/long.  Equations from USGS Bulletin 1532
        //East Longitudes are positive, West longitudes are negative.
        //North latitudes are positive, South latitudes are negative
        //Lat and Long are in decimal degrees.
        //Does not take into account the special UTM zones between 0 degrees
        //and 36 degrees longitude above 72 degrees latitude and a special
        //zone 32 between 56 degrees and 64 degrees north latitude
        //Written by Chuck Gantz- [email protected]
        // Ported to C by David Baird, 1998, Re-ported to C# by David Baird 2010
        public static void UTMToLatLong(Ellipsoid referenceEllipsoid, double northing, double easting, string zone, out double latitude, out double longitude)
        {
            latitude  = 0;
            longitude = 0;

            const double k0         = 0.9996;
            double       a          = referenceEllipsoid.EquatorialRadius;
            double       eccSquared = referenceEllipsoid.EccentricitySquared;
            double       e1         = (1 - Math.Sqrt(1 - eccSquared)) / (1 + Math.Sqrt(1 - eccSquared));
            // int NorthernHemisphere; //1 for northern hemispher, 0 for southern

            double x = easting - 500000.0;
            double y = northing;

            //if ( x <= 2875) x = 2875;		    // -db- 01/09/1998 To stop errors when Easting = 500000
            if (y == 0)
            {
                y = 0.000000001;                        // -db- 01/09/1998 To stop errors when Northing = 0
            }
            var match = ZoneRegex.Match(zone);

            if (!match.Success)
            {
                return;
            }

            char zoneLetter = match.Groups[2].Value.ToUpper()[0];
            int  zoneNumber = Int32.Parse(match.Groups[1].Value);

            if ((zoneLetter - 'N') > 0)
            {
                // NorthernHemisphere = 1;//point is in northern hemisphere
            }
            else
            {
                // NorthernHemisphere = 0;//point is in southern hemisphere
                y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
            }

            double longOrigin = (zoneNumber - 1) * 6 - 180 + 3;

            double eccPrimeSquared = (eccSquared) / (1 - eccSquared);

            double m  = y / k0;
            double mu = m / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));

            double phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.Sin(2 * mu)
                             + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.Sin(4 * mu)
                             + (151 * e1 * e1 * e1 / 96) * Math.Sin(6 * mu);

            double n1 = a / Math.Sqrt(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad));
            double t1 = Math.Tan(phi1Rad) * Math.Tan(phi1Rad);
            double c1 = eccPrimeSquared * Math.Cos(phi1Rad) * Math.Cos(phi1Rad);
            double r1 = a * (1 - eccSquared) / Math.Pow(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad), 1.5);
            double d  = x / (n1 * k0);

            latitude = phi1Rad - (n1 * Math.Tan(phi1Rad) / r1) * (d * d / 2 - (5 + 3 * t1 + 10 * c1 - 4 * c1 * c1 - 9 * eccPrimeSquared) * d * d * d * d / 24
                                                                  + (61 + 90 * t1 + 298 * c1 + 45 * t1 * t1 - 252 * eccPrimeSquared - 3 * c1 * c1) * d * d * d * d * d * d / 720);
            latitude = latitude * RadsToDegrees;

            longitude = (d - (1 + 2 * t1 + c1) * d * d * d / 6 + (5 - 2 * c1 + 28 * t1 - 3 * c1 * c1 + 8 * eccPrimeSquared + 24 * t1 * t1)
                         * d * d * d * d * d / 120) / Math.Cos(phi1Rad);
            longitude = longOrigin + longitude * RadsToDegrees;
        }
Пример #3
0
        // converts lat/long to UTM coords.  Equations from USGS Bulletin 1532
        // East Longitudes are positive, West longitudes are negative.
        // North latitudes are positive, South latitudes are negative
        // Lat and Long are in decimal degrees
        // Does not take into account thespecial UTM zones between 0 degrees and
        // 36 degrees longitude above 72 degrees latitude and a special zone 32
        // between 56 degrees and 64 degrees north latitude
        // Originally written by Chuck Gantz- [email protected]. Ported to C by David Baird, 1998, Re-ported to c# David Baird 2010
        public static void LatLongToUTM(Ellipsoid referenceEllipsoid, double latitude, double longitude, out double northing, out double easting, out string zone)
        {
            double equatorialRadius = referenceEllipsoid.EquatorialRadius;
            double eccSquared = referenceEllipsoid.EccentricitySquared;
            const double k0 = 0.9996; // Magic constant :-(

            double longOrigin;

            double latRad = latitude * DegreesToRads;
            double longRad = longitude * DegreesToRads;

            // Outside bounds checking -db- 01/09/1998
            if (latitude < -90.0) {
                latitude = -90.0;
            }

            if (latitude > 90.0) {
                latitude = 90.0;
            }

            if (longitude < -180.0) {
                longitude = -180.0;
            }

            if (longitude > 180.0) {
                longitude = 180.0;
            }

            if (longitude > -6 && longitude <= 0) {
                longOrigin = -3;	//arbitrarily set origin at 0 longitude to 3W
            } else if (longitude < 6 && longitude > 0) {
                longOrigin = 3;
            } else {
                longOrigin = ((int)longitude / 6) * 6 + 3 * ((int)longitude / 6) / Math.Abs((int)longitude / 6);
            }

            double longOriginRad = longOrigin * DegreesToRads;

            //compute the UTM Zone from the latitude and longitude
            zone = string.Format("{0}{1}", (int)((longitude + 180) / 6) + 1, UTMLetterDesignator(latitude));

            double eccPrimeSquared = (eccSquared) / (1 - eccSquared);

            double n = equatorialRadius / Math.Sqrt(1 - eccSquared * Math.Sin(latRad) * Math.Sin(latRad));
            double T = Math.Tan(latRad) * Math.Tan(latRad);
            double c = eccPrimeSquared * Math.Cos(latRad) * Math.Cos(latRad);
            double a = Math.Cos(latRad) * (longRad - longOriginRad);

            double m = equatorialRadius * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad
                            - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(2 * latRad)
                            + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(4 * latRad)
                            - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.Sin(6 * latRad));

            easting = k0 * n * (a + (1 - T + c) * a * a * a / 6 + (5 - 18 * T + T * T + 72 * c - 58 * eccPrimeSquared) * a * a * a * a * a / 120) + 500000.0;

            northing = k0 * (m + n * Math.Tan(latRad) * (a * a / 2 + (5 - T + 9 * c + 4 * c * c) * a * a * a * a / 24 + (61 - 58 * T + T * T + 600 * c - 330 * eccPrimeSquared) * a * a * a * a * a * a / 720));
            if (latitude <= 0) {
                northing += 10000000.0; //10000000 meter offset for southern hemisphere
            }
        }
Пример #4
0
        // converts lat/long to UTM coords.  Equations from USGS Bulletin 1532
        // East Longitudes are positive, West longitudes are negative.
        // North latitudes are positive, South latitudes are negative
        // Lat and Long are in decimal degrees
        // Does not take into account thespecial UTM zones between 0 degrees and
        // 36 degrees longitude above 72 degrees latitude and a special zone 32
        // between 56 degrees and 64 degrees north latitude
        // Originally written by Chuck Gantz- [email protected]. Ported to C by David Baird, 1998, Re-ported to c# David Baird 2010
        public static void LatLongToUTM(Ellipsoid referenceEllipsoid, double latitude, double longitude, out double northing, out double easting, out string zone)
        {
            double       equatorialRadius = referenceEllipsoid.EquatorialRadius;
            double       eccSquared       = referenceEllipsoid.EccentricitySquared;
            const double k0 = 0.9996; // Magic constant :-(

            double longOrigin;

            double latRad  = latitude * DegreesToRads;
            double longRad = longitude * DegreesToRads;

            // Outside bounds checking -db- 01/09/1998
            if (latitude < -90.0)
            {
                latitude = -90.0;
            }

            if (latitude > 90.0)
            {
                latitude = 90.0;
            }

            if (longitude < -180.0)
            {
                longitude = -180.0;
            }

            if (longitude > 180.0)
            {
                longitude = 180.0;
            }

            if (longitude > -6 && longitude <= 0)
            {
                longOrigin = -3;        //arbitrarily set origin at 0 longitude to 3W
            }
            else if (longitude < 6 && longitude > 0)
            {
                longOrigin = 3;
            }
            else
            {
                longOrigin = ((int)longitude / 6) * 6 + 3 * ((int)longitude / 6) / Math.Abs((int)longitude / 6);
            }

            double longOriginRad = longOrigin * DegreesToRads;

            //compute the UTM Zone from the latitude and longitude
            zone = string.Format("{0}{1}", (int)((longitude + 180) / 6) + 1, UTMLetterDesignator(latitude));

            double eccPrimeSquared = (eccSquared) / (1 - eccSquared);

            double n = equatorialRadius / Math.Sqrt(1 - eccSquared * Math.Sin(latRad) * Math.Sin(latRad));
            double T = Math.Tan(latRad) * Math.Tan(latRad);
            double c = eccPrimeSquared * Math.Cos(latRad) * Math.Cos(latRad);
            double a = Math.Cos(latRad) * (longRad - longOriginRad);

            double m = equatorialRadius * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad
                                           - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(2 * latRad)
                                           + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.Sin(4 * latRad)
                                           - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.Sin(6 * latRad));

            easting = k0 * n * (a + (1 - T + c) * a * a * a / 6 + (5 - 18 * T + T * T + 72 * c - 58 * eccPrimeSquared) * a * a * a * a * a / 120) + 500000.0;

            northing = k0 * (m + n * Math.Tan(latRad) * (a * a / 2 + (5 - T + 9 * c + 4 * c * c) * a * a * a * a / 24 + (61 - 58 * T + T * T + 600 * c - 330 * eccPrimeSquared) * a * a * a * a * a * a / 720));
            if (latitude <= 0)
            {
                northing += 10000000.0; //10000000 meter offset for southern hemisphere
            }
        }