private void OnConvertLatLon(object sender, EventArgs e)
 {
     try
     {
         int    zone;
         bool   northp;
         double x, y;
         string str;
         double lat = Double.Parse(m_latitudeTextBox.Text);
         double lon = Double.Parse(m_longitudeTextBox.Text);
         UTMUPS.Forward(lat, lon, out zone, out northp, out x, out y, (int)UTMUPS.ZoneSpec.STANDARD, true);
         m_utmPoleCheckBox.Checked = northp;
         m_utmXTextBox.Text        = x.ToString();
         m_utmYTextBox.Text        = y.ToString();
         m_utmZoneTextBox.Text     = zone.ToString();
         MGRS.Forward(zone, northp, x, y, 8, out str);
         m_mgrsTextBox.Text = str;
         OSGB.Forward(lat, lon, out x, out y);
         m_osgbXTextBox.Text = x.ToString();
         m_osgbYTextBox.Text = y.ToString();
         OSGB.GridReference(x, y, 8, out str);
         m_osgbTextBox.Text = str;
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Exemple #2
0
 static void Main(string[] args)
 {
     try {
         // See also example-GeoCoords.cpp
         {
             // Sample forward calculation
             double lat = 33.3, lon = 44.4; // Baghdad
             int    zone;
             bool   northp;
             double x, y;
             UTMUPS.Forward(lat, lon, out zone, out northp, out x, out y, -1, true);
             string zonestr = UTMUPS.EncodeZone(zone, northp, true);
             Console.WriteLine(String.Format("{0} {1} {2}", zonestr, x, y));
         }
         {
             // Sample reverse calculation
             string zonestr = "38N";
             int    zone;
             bool   northp;
             UTMUPS.DecodeZone(zonestr, out zone, out northp);
             double x = 444e3, y = 3688e3;
             double lat, lon;
             UTMUPS.Reverse(zone, northp, x, y, out lat, out lon, true);
             Console.WriteLine(String.Format("{0} {1}", lat, lon));
         }
     }
     catch (GeographicErr e) {
         Console.WriteLine(String.Format("Caught exception: {0}", e.Message));
     }
 }
Exemple #3
0
        public void TestForward(double lat, double lon, string expeted)
        {
            var(zone, northp, x, y) = UTMUPS.Forward(lat, lon);
            var mgrs = MGRS.Forward(zone, northp, x, y, 5);

            Assert.AreEqual(expeted, mgrs);
        }
Exemple #4
0
 static void Main(string[] args)
 {
     try {
         // See also example-GeoCoords.cpp
         {
             // Sample forward calculation
             double lat = 33.3, lon = 44.4; // Baghdad
             int    zone;
             bool   northp;
             double x, y;
             UTMUPS.Forward(lat, lon, out zone, out northp, out x, out y, -1, true);
             string mgrs;
             MGRS.Forward(zone, northp, x, y, lat, 5, out mgrs);
             Console.WriteLine(mgrs);
         }
         {
             // Sample reverse calculation
             string mgrs = "38SMB4488";
             int    zone, prec;
             bool   northp;
             double x, y;
             MGRS.Reverse(mgrs, out zone, out northp, out x, out y, out prec, true);
             double lat, lon;
             UTMUPS.Reverse(zone, northp, x, y, out lat, out lon, true);
             Console.WriteLine(String.Format("Latitude: {0} Longitude: {1}", lat, lon));
         }
     }
     catch (GeographicErr e) {
         Console.WriteLine(String.Format("Caught exception: {0}", e.Message));
     }
 }
        private void OnValidate(object sender, EventArgs e)
        {
            try
            {
                string str;
                int    prec, zone, zout;
                bool   northp;
                double x, y, x1, y1, gamma, k, lat, lon;
                OSGB.Forward(52.0, -2.0, out x, out y, out gamma, out k);
                OSGB.Forward(52.0, -2.0, out x1, out y1);
                if (x != x1 || y != y1)
                {
                    throw new Exception("Error in OSGB.Forward");
                }
                OSGB.Reverse(x, y, out lat, out lon, out gamma, out k);
                OSGB.Reverse(x, y, out x1, out y1);
                if (lat != x1 || lon != y1)
                {
                    throw new Exception("Error in OSGB.Reverse");
                }
                OSGB.GridReference(x, y, 8, out str);
                OSGB.GridReference(str, out x1, out y1, out prec, true);
                UTMUPS.StandardZone(32.0, -80.0, (int)UTMUPS.ZoneSpec.STANDARD);
                UTMUPS.UTMShift();
                UTMUPS.StandardZone(32.0, -86.0, (int)UTMUPS.ZoneSpec.STANDARD);
                UTMUPS.Forward(32.0, -86.0, out zone, out northp, out x, out y, out gamma, out k, (int)UTMUPS.ZoneSpec.STANDARD, true);
                UTMUPS.Forward(32.0, -86.0, out zone, out northp, out x1, out y1, (int)UTMUPS.ZoneSpec.STANDARD, true);
                if (x != x1 || y != y1)
                {
                    throw new Exception("Error in UTMUPS.Forward");
                }
                UTMUPS.Reverse(zone, northp, x, y, out lat, out lon, out gamma, out k, true);
                UTMUPS.Reverse(zone, northp, x, y, out x1, out y1, true);
                if (lat != x1 || lon != y1)
                {
                    throw new Exception("Error in UTMUPS.Reverse");
                }
                UTMUPS.Transfer(zone, northp, x, y, zone + 1, true, out x1, out y1, out zout);
                str  = UTMUPS.EncodeZone(zone, northp, true);
                prec = UTMUPS.EncodeEPSG(zone, northp);
                UTMUPS.DecodeZone(str, out zone, out northp);
                UTMUPS.DecodeEPSG(prec, out zone, out northp);
                MGRS.Forward(zone, northp, x, y, 8, out str);
                MGRS.Forward(zone, northp, x, y, 32.0, 8, out str);
                MGRS.Reverse(str, out zone, out northp, out x, out y, out prec, true);

                MessageBox.Show("No errors detected", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception xcpt)
            {
                MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Exemple #6
0
        /// <summary>
        /// Perform some checks on the <see cref="UTMUPS"/> coordinates on this ellipsoid.
        /// Throw an error if any of the assumptions made in the <see cref="MGRS"/> class is not true.
        /// This check needs to be carried out if the ellipsoid parameters (or the UTM/UPS scales) are ever changed.
        /// </summary>
        public static void Check()
        {
            double t = tile_;

            var(_, lon) = UTMUPS.Reverse(31, true, 1 * t, 0 * t);
            if (!(lon < 0))
            {
                throw new GeographicException("MGRS::Check: equator coverage failure");
            }
            var(lat, _) = UTMUPS.Reverse(31, true, 1 * t, 95 * t);
            if (!(lat > 84))
            {
                throw new GeographicException("MGRS::Check: UTM doesn't reach latitude = 84");
            }
            (lat, _) = UTMUPS.Reverse(31, false, 1 * t, 10 * t);
            if (!(lat < -80))
            {
                throw new GeographicException("MGRS::Check: UTM doesn't reach latitude = -80");
            }
            var(_, _, x, _) = UTMUPS.Forward(56, 3, 32);
            if (!(x > 1 * t))
            {
                throw new GeographicException("MGRS::Check: Norway exception creates a gap");
            }
            (_, _, x, _) = UTMUPS.Forward(72, 21, 35);
            if (!(x > 1 * t))
            {
                throw new GeographicException("MGRS::Check: Svalbard exception creates a gap");
            }
            (lat, _) = UTMUPS.Reverse(0, true, 20 * t, 13 * t);
            if (!(lat < 84))
            {
                throw new GeographicException("MGRS::Check: North UPS doesn't reach latitude = 84");
            }
            (lat, _) = UTMUPS.Reverse(0, false, 20 * t, 8 * t);
            if (!(lat > -80))
            {
                throw new GeographicException("MGRS::Check: South UPS doesn't reach latitude = -80");
            }

            var bandchecks = tab.Length / 3;

            for (int i = 0; i < bandchecks; ++i)
            {
                (lat, _) = UTMUPS.Reverse(38, true, tab[3 * i + 1] * t, tab[3 * i + 2] * t);
                if (!(LatitudeBand(lat) == tab[3 * i + 0]))
                {
                    throw new GeographicException(
                              $"MGRS::Check: Band error, b = {tab[3 * i + 0]}, x = {tab[3 * i + 1]}00km, y = {tab[3 * i + 2]}00km");
                }
            }
        }
Exemple #7
0
        public void TestReverse(double lat, double lon, string input)
        {
            var(zone, northp, x, y, _) = MGRS.Reverse(input);
            var(olat, olon)            = UTMUPS.Reverse(zone, northp, x, y);

            Assert.AreEqual(olat, lat, 1e-5);

            // No need to check longitude when near pole.
            if (Math.Abs(lat) != 90)
            {
                Assert.AreEqual(olon, lon, 1e-5);
            }
        }
        private void OnConvertMGRS(object sender, EventArgs e)
        {
            int    zone, prec;
            bool   northp;
            double x, y, lat, lon;

            MGRS.Reverse(m_mgrsTextBox.Text, out zone, out northp, out x, out y, out prec, true);
            m_utmPoleCheckBox.Checked = northp;
            m_utmXTextBox.Text        = x.ToString();
            m_utmYTextBox.Text        = y.ToString();
            m_utmZoneTextBox.Text     = zone.ToString();
            UTMUPS.Reverse(zone, northp, x, y, out lat, out lon, true);
            m_latitudeTextBox.Text  = lat.ToString();
            m_longitudeTextBox.Text = lon.ToString();
        }
Exemple #9
0
        /// <summary>
        /// Convert UTM or UPS coordinate to an MGRS coordinate.
        /// </summary>
        /// <param name="zone">UTM zone (zero means UPS).</param>
        /// <param name="northp">hemisphere (<see langword="true"/> means north, <see langword="false"/> means south).</param>
        /// <param name="x">easting of point (meters).</param>
        /// <param name="y">northing of point (meters).</param>
        /// <param name="prec">precision relative to 100 km.</param>
        /// <returns>A <see cref="MGRS"/> string.</returns>
        /// <remarks>
        /// <i>prec</i> specifies the precision of the <see cref="MGRS"/> as follows:
        /// <list type="bullet">
        /// <item><i>prec</i> = -1 (min), only the grid zone is returned</item>
        /// <item><i>prec</i> = 0, 100km</item>
        /// <item><i>prec</i> = 1, 10km</item>
        /// <item><i>prec</i> = 2, 1km</item>
        /// <item><i>prec</i> = 3, 100m</item>
        /// <item><i>prec</i> = 4, 10m</item>
        /// <item><i>prec</i> = 5, 1m</item>
        /// <item><i>prec</i> = 6, 0.1m</item>
        /// <item>...</item>
        /// <item><i>prec</i> = 11 (max), 1μm</item>
        /// </list>
        /// <para>
        /// UTM eastings are allowed to be in the range [100 km, 900 km],
        /// northings are allowed to be in in [0 km, 9500 km] for the northern hemisphere and in [1000 km, 10000 km] for the southern hemisphere.
        /// (However UTM northings can be continued across the equator. So the actual limits on the northings are [−9000 km, 9500 km]
        /// for the "northern" hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.)
        /// </para>
        /// <para>
        /// UPS eastings/northings are allowed to be in the range [1300 km, 2700 km] in the northern hemisphere
        /// and in [800 km, 3200 km] in the southern hemisphere.
        /// </para>
        /// <para>
        /// The ranges are 100 km more restrictive than for the conversion between geographic coordinates and UTM and UPS given by <see cref="UTMUPS"/>.
        /// These restrictions are dictated by the allowed letters in <see cref="MGRS"/> coordinates.
        /// The choice of 9500 km for the maximum northing for northern hemisphere and of 1000 km as the minimum northing for southern hemisphere
        /// provide at least 0.5 degree extension into standard UPS zones.
        /// The upper ends of the ranges for the UPS coordinates is dictated by requiring symmetry about the meridians <c>0E</c> and <c>90E</c>.
        /// </para>
        /// <para>
        /// All allowed UTM and UPS coordinates may now be converted to legal <see cref="MGRS"/> coordinates with the proviso that eastings and northings
        /// on the upper boundaries are silently reduced by about 4 nm (4 nanometers) to place them within the allowed range.
        /// (This includes reducing a southern hemisphere northing of 10000 km by 4 nm so that it is placed in latitude band <c>M</c>.)
        /// The UTM or UPS coordinates are truncated to requested precision to determine the <see cref="MGRS"/> coordinate.
        /// Thus in UTM zone <c>38N</c>, the square area with easting in [444 km, 445 km) and northing in [3688 km, 3689 km) maps to <see cref="MGRS"/>
        /// coordinate <c>38SMB4488</c> (at <i>prec</i> = 2, 1 km), Khulani Sq., Baghdad.
        /// </para>
        /// <para>
        /// The UTM/UPS selection and the UTM zone is preserved in the conversion to <see cref="MGRS"/> coordinate.
        /// Thus for <i>zone</i> > 0, the <see cref="MGRS"/> coordinate begins with the zone number followed by one of [<c>C</c>–<c>M</c>] for the southern hemisphere
        /// and [<c>N</c>–<c>X</c>] for the northern hemisphere. For <i>zone</i> = 0, the <see cref="MGRS"/> coordinates begins with one of [<c>AB</c>] for the
        /// southern hemisphere and [<c>XY</c>] for the northern hemisphere.
        /// </para>
        /// <para>
        /// The conversion to the <see cref="MGRS"/> is exact for prec in [0, 5] except that a neighboring
        /// latitude band letter may be given if the point is within 5nm of a band boundary. For <i>prec</i> in [6, 11], the conversion is accurate to roundoff.
        /// </para>
        /// <para>
        /// If <i>prec</i> = −1, then the "grid zone designation", e.g., <c>18T</c>, is returned.
        /// This consists of the UTM zone number (absent for UPS) and the first letter of the <see cref="MGRS"/> string which labels the latitude band
        /// for UTM and the hemisphere for UPS.
        /// </para>
        /// <para>
        /// If <i>x</i> or <i>y</i> is <see cref="double.NaN"/> or if zone is <see cref="ZoneSpec.Invalid"/>, the returned <see cref="MGRS"/> string is "INVALID".
        /// </para>
        /// </remarks>
        public static string Forward(int zone, bool northp, double x, double y, int prec)
        {
            double lat;

            if (zone > 0)
            {
                // Does a rough estimate for latitude determine the latitude band?
                var ys = northp ? y : y - utmNshift_;
                // A cheap calculation of the latitude which results in an "allowed"
                // latitude band would be
                //   lat = ApproxLatitudeBand(ys) * 8 + 4;
                //
                // Here we do a more careful job using the band letter corresponding to
                // the actual latitude.
                ys /= tile_;
                if (Abs(ys) < 1)
                {
                    lat = 0.9 * ys;         // accurate enough estimate near equator
                }
                else
                {
                    double
                    // The poleward bound is a fit from above of lat(x,y)
                    // for x = 500km and y = [0km, 950km]
                        latp = 0.901 * ys + (ys > 0 ? 1 : -1) * 0.135,
                    // The equatorward bound is a fit from below of lat(x,y)
                    // for x = 900km and y = [0km, 950km]
                        late = 0.902 * ys * (1 - 1.85e-6 * ys * ys);
                    if (LatitudeBand(latp) == LatitudeBand(late))
                    {
                        lat = latp;
                    }
                    else
                    {
                        // bounds straddle a band boundary so need to compute lat accurately
                        (lat, _) = UTMUPS.Reverse(zone, northp, x, y);
                    }
                }
            }
            else
            {
                // Latitude isn't needed for UPS specs or for INVALID
                lat = 0;
            }

            return(Forward(zone, northp, x, y, lat, prec));
        }
 private void OnConvertUTMUPS(object sender, EventArgs e)
 {
     try
     {
         double lat, lon;
         string str;
         double x    = Double.Parse(m_utmXTextBox.Text);
         double y    = Double.Parse(m_utmYTextBox.Text);
         int    zone = Int32.Parse(m_utmZoneTextBox.Text);
         UTMUPS.Reverse(zone, m_utmPoleCheckBox.Checked, x, y, out lat, out lon, true);
         m_latitudeTextBox.Text  = lat.ToString();
         m_longitudeTextBox.Text = lon.ToString();
         MGRS.Forward(zone, m_utmPoleCheckBox.Checked, x, y, 8, out str);
         m_mgrsTextBox.Text = str;
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }