Beispiel #1
0
        private static Int32 GridSize(Int16 digits)
        {
            Int16 actualDigits = UtmPoint.MakeDigitValid(digits);
            Int32 result       = Convert.ToInt32(Math.Pow(10, UtmPoint.MaximumDigits - actualDigits));

            return(result);
        }
Beispiel #2
0
        private Boolean SameZone(UtmPoint point)
        {
            GeoPoint geoPoint = new GeoPoint(point, Datum);
            UtmPoint realUtm  = geoPoint.CalcUTM();
            Boolean  result   = (CentralPoint.ZoneNumber == realUtm.ZoneNumber);

            return(result);
        }
Beispiel #3
0
        private void SetMgrs(String value)
        {
            String mgrs   = value.Replace(" ", "");
            Int16  digits = Convert.ToInt16((mgrs.Length - 1) / 2);

            CentralPoint = MakeCentral(UtmPoint.ParseMgrsString(value), digits);
            _Digits      = digits;
            Name         = value;
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the GeoPoint class.
        /// </summary>
        /// <param name="utmPoint">UTM coordinates.</param>
        /// <param name="datum">Geographical datum.</param>
        public GeoPoint(UtmPoint utmPoint, GeoDatum datum)
        {
            Double excentricitySquared = datum.Ellipsoid.ExcentricitySquared;
            Double equatorialRadius    = datum.Ellipsoid.SemiMajorAxis;

            Boolean northernHemisphere = utmPoint.IsNorthernHemisphere;
            Int32   zoneNumber         = utmPoint.ZoneNumber;

            Double x = utmPoint.Easting - 500000.0; //remove 500,000 meter offset for longitude
            Double y = utmPoint.Northing;

            if (!northernHemisphere)
            {
                // point is in southern hemisphere
                y = y - 10000000.0; // remove 10,000,000 meter offset used for southern hemisphere
            }

            Double longOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin in middle of zone

            Double excentricityPrimeSquared = (excentricitySquared) / (1 - excentricitySquared);

            Double M  = y / dScaleFactor;
            Double mu = M / (equatorialRadius * (1 - excentricitySquared / 4 - 3 * excentricitySquared * excentricitySquared / 64 - 5 * excentricitySquared * excentricitySquared * excentricitySquared / 256));

            Double e1 = (1 - Math.Sqrt(1 - excentricitySquared)) / (1 + Math.Sqrt(1 - excentricitySquared));
            // phi in radians
            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);
            // convert to degrees
            Double phi1 = phi1Rad * _convertRadianToDegree;

            Double N1 = equatorialRadius / Math.Sqrt(1 - excentricitySquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad));
            Double T1 = Math.Tan(phi1Rad) * Math.Tan(phi1Rad);
            Double C1 = excentricityPrimeSquared * Math.Cos(phi1Rad) * Math.Cos(phi1Rad);
            Double R1 = equatorialRadius * (1 - excentricitySquared) / Math.Pow(1 - excentricitySquared * Math.Sin(phi1Rad) * Math.Sin(phi1Rad), 1.5);
            Double D  = x / (N1 * dScaleFactor);

            // phi in radians
            Double latitude = phi1Rad - (N1 * Math.Tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * excentricityPrimeSquared) * D * D * D * D / 24
                                                                         + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * excentricityPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720);

            // convert to degrees
            latitude = latitude * _convertRadianToDegree;

            // lon in radians
            Double longitude = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * excentricityPrimeSquared + 24 * T1 * T1)
                                * D * D * D * D * D / 120) / Math.Cos(phi1Rad);

            // convert to degrees
            longitude = longOrigin + longitude * _convertRadianToDegree;

            Longitude = longitude;
            Latitude  = latitude;
            _Datum    = datum;
        }
Beispiel #5
0
        private static UtmPoint MakeCentral(UtmPoint point, Int16 digits)
        {
            String   value       = point.ToUtmString(digits);
            UtmPoint utmPoint    = new UtmPoint(value);
            Double   distance    = 0.5 * GridSize(digits);
            Double   easting     = utmPoint.Easting + distance;
            Double   northing    = utmPoint.Northing + distance;
            UtmPoint middlePoint = new UtmPoint(easting, northing, utmPoint.ZoneNumber, utmPoint.IsNorthernHemisphere);

            return(middlePoint);
        }
Beispiel #6
0
        public UtmPoint NorthWestCornerUtm()
        {
            String   value  = CentralPoint.ToUtmString(_Digits);
            UtmPoint result = new UtmPoint(value);

            if (!SameZone(result))
            {
                result = LimitToZone(result);
            }
            return(result);
        }
Beispiel #7
0
        public UtmPoint SouthEastCornerUtm()
        {
            String   value  = CentralPoint.ToUtmString(_Digits);
            UtmPoint result = new UtmPoint(value);

            result.Easting  += GridSize(_Digits);
            result.Northing += GridSize(_Digits);
            if (!SameZone(result))
            {
                result = LimitToZone(result);
            }
            return(result);
        }
Beispiel #8
0
        private UtmPoint LimitToZone(UtmPoint point)
        {
            UtmPoint result     = new UtmPoint(point);
            Int32    minEasting = 0;
            Int32    maxEasting = 0;

            if (point.Easting < CentralPoint.Easting)
            {
                minEasting = point.Easting;
                maxEasting = minEasting + GridSize(_Digits);
            }
            else
            {
                maxEasting = point.Easting;
                minEasting = maxEasting - GridSize(_Digits);
            }
            Int32 leftZone = 0;
            {
                UtmPoint tempUtmPoint = new UtmPoint(point);
                tempUtmPoint.Easting = minEasting;
                GeoPoint tempGeoPoint = new GeoPoint(tempUtmPoint, Datum);
                tempUtmPoint = tempGeoPoint.CalcUTM();
                leftZone     = tempUtmPoint.ZoneNumber;
            }
            Int32 eastingDiff = maxEasting - minEasting;

            while (eastingDiff > 1)
            {
                Int32 tempEasting = minEasting + eastingDiff / 2;
                result         = new UtmPoint(point);
                result.Easting = tempEasting;
                GeoPoint tempGeoPoint = new GeoPoint(result, Datum);
                UtmPoint empUtmPoint  = tempGeoPoint.CalcUTM();
                if (empUtmPoint.ZoneNumber > leftZone)
                {
                    maxEasting = tempEasting;
                }
                else
                {
                    minEasting = tempEasting;
                }
                eastingDiff = eastingDiff / 2;
            }
            return(result);
        }
Beispiel #9
0
        public UtmPoint ActualCentralPoint()
        {
            String   value = CentralPoint.ToUtmString(_Digits);
            UtmPoint west  = new UtmPoint(value);

            west.Northing += GridSize(_Digits) / 2;
            UtmPoint east = new UtmPoint(west);

            east.Easting += GridSize(_Digits);
            if (!SameZone(west))
            {
                west = LimitToZone(west);
            }
            if (!SameZone(east))
            {
                east = LimitToZone(east);
            }
            UtmPoint result = new UtmPoint(value);

            result.Northing += GridSize(_Digits) / 2;
            result.Easting   = (west.Easting + east.Easting) / 2;
            return(result);
        }
Beispiel #10
0
        public UtmPoint CalcUTM()
        {
            //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

            double eccSquared        = _Datum.Ellipsoid.ExcentricitySquared;
            double dEquatorialRadius = _Datum.Ellipsoid.SemiMajorAxis;

            double k0 = 0.9996;

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

            //Make sure the longitude is between -180.00 .. 179.9
            double lLongitude = (Longitude + 180) - Math.Truncate((Longitude + 180) / 360) * 360 - 180; // -180.00 .. 179.9;

            double LatRad  = Latitude / _convertRadianToDegree;
            double LongRad = Longitude / _convertRadianToDegree;

            Int32 ZoneNumber = (Int32)Math.Truncate((lLongitude + 180) / 6) + 1;

            if (Latitude >= 56.0 && Latitude < 64.0 && lLongitude >= 3.0 && lLongitude < 12.0)
            {
                ZoneNumber = 32; // larger zone for southern Norway
            }
            if (Latitude >= 72.0 && Latitude < 84.0)
            {
                // Special zones for Svalbard
                if (lLongitude >= 0.0 && lLongitude < 9.0)
                {
                    ZoneNumber = 31;
                }
                else if (lLongitude >= 9.0 && lLongitude < 21.0)
                {
                    ZoneNumber = 33;
                }
                else if (lLongitude >= 21.0 && lLongitude < 33.0)
                {
                    ZoneNumber = 35;
                }
                else if (lLongitude >= 33.0 && lLongitude < 42.0)
                {
                    ZoneNumber = 37;
                }
            }
            LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3;  //+3 puts origin in middle of zone
            double LongOriginRad = LongOrigin / _convertRadianToDegree;

            double N = dEquatorialRadius / 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 = dEquatorialRadius * ((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));

            double UTMEasting = (double)(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);
            double UTMNorthing = (double)(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)
            {
                UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere
            }
            UtmPoint lResult = new UtmPoint(
                (Int32)Math.Truncate(UTMEasting),
                (Int32)Math.Truncate(UTMNorthing),
                ZoneNumber, Latitude >= 0);

            return(lResult);
        }