public static GeoCoordinate GetEndPoint(GeoCoordinate start, double azimuth, double distance)
        {
            double b     = distance / OrthographicProjection.EarthRadiusKm;
            double sLat  = ToRadians(90 - start.Latitude);
            double radAz = ToRadians(azimuth);
            double a     = Math.Acos(Math.Cos(b) * Math.Cos(sLat) + Math.Sin(sLat) * Math.Sin(b) * Math.Cos(radAz));
            double B     = Math.Asin(Math.Sin(b) * Math.Sin(radAz) / Math.Sin(a));
            double lat2  = ToDegrees(a);

            lat2 = 90 - lat2;
            double lon2 = ToDegrees(B) + start.Longitude;

            lon2 = OrthographicProjection.SanitizeLongitude(lon2);
            return(new GeoCoordinate(lat2, lon2));
        }
Example #2
0
        public static void LLtoUTM(int referenceEllipsoid, double lat, double Long,
                                   out double utmNorthing, out double utmEasting,
                                   out string utmZone)
        {
            //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
            //Written by Chuck Gantz- [email protected]

            double a          = ellipsoid[referenceEllipsoid].EquatorialRadius;
            double eccSquared = ellipsoid[referenceEllipsoid].eccentricitySquared;
            double k0         = 0.9996;

            double LongOrigin;
            double eccPrimeSquared;
            double N, T, C, A, M;

            //Make sure the longitude is between -180.00 .. 179.9
            double LongTemp = OrthographicProjection.SanitizeLongitude(Long);

            double LatRad  = OrthographicProjection.ToRadians(lat);
            double LongRad = OrthographicProjection.ToRadians(LongTemp);
            double LongOriginRad;
            int    ZoneNumber;

            ZoneNumber = (int)((LongTemp + 180) / 6) + 1;


            if (lat >= 56.0 && lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0)
            {
                ZoneNumber = 32;
            }

            // Special zones for Svalbard
            if (lat >= 72.0 && lat < 84.0)
            {
                if (LongTemp >= 0.0 && LongTemp < 9.0)
                {
                    ZoneNumber = 31;
                }
                else if (LongTemp >= 9.0 && LongTemp < 21.0)
                {
                    ZoneNumber = 33;
                }
                else if (LongTemp >= 21.0 && LongTemp < 33.0)
                {
                    ZoneNumber = 35;
                }
                else if (LongTemp >= 33.0 && LongTemp < 42.0)
                {
                    ZoneNumber = 37;
                }
            }
            LongOrigin    = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin in middle of zone
            LongOriginRad = OrthographicProjection.ToRadians(LongOrigin);

            //compute the UTM Zone from the latitude and longitude
            utmZone = String.Format("{0}{1}", ZoneNumber, UTMLetterDesignator(lat));

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

            N = a / Math.Sqrt(1 - eccSquared * Math.Sin(LatRad) * Math.Sin(LatRad));
            T = Math.Tan(LatRad) * Math.Tan(LatRad);
            C = eccPrimeSquared * Math.Cos(LatRad) * Math.Cos(LatRad);
            A = Math.Cos(LatRad) * (LongRad - LongOriginRad);

            M = a * ((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));

            utmEasting = 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;

            utmNorthing = 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 (lat < 0)
            {
                utmNorthing += 10000000.0; //10000000 meter offset for southern hemisphere
            }
        }
Example #3
0
        static public void UTMtoLL(int referenceEllipsoid, double utmNorthing, double utmEasting, string utmZone,
                                   out double lat, out double Long)
        {
            //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.
            //Written by Chuck Gantz- [email protected]

            double k0         = 0.9996;
            double a          = ellipsoid[referenceEllipsoid].EquatorialRadius;
            double eccSquared = ellipsoid[referenceEllipsoid].eccentricitySquared;
            double eccPrimeSquared;
            double e1 = (1 - Math.Sqrt(1 - eccSquared)) / (1 + Math.Sqrt(1 - eccSquared));
            double N1, T1, C1, R1, D, M;
            double LongOrigin;
            double mu, phi1, phi1Rad;
            double x, y;
            int    ZoneNumber;
            string ZoneLetter;
            int    NorthernHemisphere; //1 for northern hemispher, 0 for southern

            x = utmEasting - 500000.0; //remove 500,000 meter offset for longitude
            y = utmNorthing;

            // UTM zone is number and letter
            utmZone = utmZone.Trim();
            int idx = utmZone.Length - 1;

            ZoneLetter = utmZone.Substring(idx);      // last character
            ZoneNumber = int.Parse(utmZone.Substring(0, idx));
            if (String.Compare(ZoneLetter, "N") >= 0) //	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
            }

            LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3;  //+3 puts origin in middle of zone

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

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

            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);
            phi1 = OrthographicProjection.ToDegrees(phi1Rad);

            N1 = a / Math.Sqrt(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad));
            T1 = Math.Tan(phi1Rad) * Math.Tan(phi1Rad);
            C1 = eccPrimeSquared * Math.Cos(phi1Rad) * Math.Cos(phi1Rad);
            R1 = a * (1 - eccSquared) / Math.Pow(1 - eccSquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad), 1.5);
            D  = x / (N1 * k0);

            lat = 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);
            lat = OrthographicProjection.ToDegrees(lat);

            Long = (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);
            Long = LongOrigin + OrthographicProjection.ToDegrees(Long);
        }