Beispiel #1
0
        public void TestConstructor2()
        {
            var e = new EuclidianCoordinate(projection, new double[] { -3, -4 });

            Assert.AreEqual(e.X, -3);
            Assert.AreEqual(e.Y, -4);
        }
Beispiel #2
0
        public void TestEquals2()
        {
            var e1 = new EuclidianCoordinate(projection, -3, -4);
            var e2 = "123";

            Assert.AreNotEqual(e1, e2);
        }
Beispiel #3
0
        public void TestNotSameProjection()
        {
            var e1 = new EuclidianCoordinate(projection, -3, -4);
            var e2 = new EuclidianCoordinate(new EllipticalMercatorProjection(), -3, -4);

            Assert.ThrowsException <ArgumentException>(() => e1.DistanceTo(e2));
        }
Beispiel #4
0
        public void TestEquals3()
        {
            var e1 = new EuclidianCoordinate(projection, -3, -4);
            var e2 = new EuclidianCoordinate(new EllipticalMercatorProjection(), -3, -4);

            Assert.AreNotEqual(e1, e2);
        }
Beispiel #5
0
        public void TestEquals5()
        {
            var e1 = new EuclidianCoordinate(projection, -3, -4);
            var e2 = new EuclidianCoordinate(projection, -3, -4 + 1e-13);

            Assert.AreEqual(e1, e2);
        }
Beispiel #6
0
        public void TestHash()
        {
            var e1 = new EuclidianCoordinate(projection, -3, -4);
            var e2 = new EuclidianCoordinate(projection, -3, -4 + 1e-13);

            Assert.AreNotEqual(e1.GetHashCode(), e2.GetHashCode());
        }
Beispiel #7
0
        public void TestConstructor1()
        {
            var e = new EuclidianCoordinate(projection, -1, -2);

            Assert.AreEqual(e.X, -1);
            Assert.AreEqual(e.Y, -2);
        }
Beispiel #8
0
 /// <summary>
 /// Check whether another euclidian point belongs to the same projection
 /// </summary>
 /// <param name="other">The other point</param>
 /// <returns>True if they belong to the same projection, false otherwise</returns>
 public override bool IsSameProjection(EuclidianCoordinate other)
 {
     if (other is UtmCoordinate utmOther)
     {
         return(utmOther.Grid.Equals(Grid));
     }
     return(false);
 }
Beispiel #9
0
 /// <summary>
 /// Compute the euclidian distance to another point
 /// </summary>
 /// <param name="other">The other point</param>
 /// <returns>The distance</returns>
 /// <exception cref="ArgumentException"></exception>
 public override double DistanceTo(EuclidianCoordinate other)
 {
     if (!(other is UtmCoordinate obj) || !Grid.Equals(obj.Grid))
     {
         throw new ArgumentException();
     }
     return(base.DistanceTo(other));
 }
        /// <summary>
        /// Compute a loxodromic path from start to end witha given number of points
        /// </summary>
        /// <param name="start">starting coordinates</param>
        /// <param name="end">ending coordinates</param>
        /// <param name="mercatorRhumbDistance">The distance of the two points on a Rhumb line on the Mercator projection</param>
        /// <param name="bearing">The constant course for the path</param>
        /// <param name="numberOfPoints">Number of points on the path (including start and end)</param>
        /// <returns>An array of points describing the loxodromic path from start to end</returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public GlobalCoordinates[] CalculatePath(GlobalCoordinates start, GlobalCoordinates end, out double mercatorRhumbDistance, out Angle bearing, int numberOfPoints = 10)
        {
            mercatorRhumbDistance = 0;
            bearing = 0;

            if (numberOfPoints < 2)
            {
                throw new ArgumentOutOfRangeException(Properties.Resources.GEODETIC_PATH_MIN_2);
            }

            if (start == end || numberOfPoints == 2)
            {
                return new[] { start, end }
            }
            ;

            var cStart = ToEuclidian(start);
            var cEnd   = ToEuclidian(end);
            var dist   = EuclidianDistance(cStart, cEnd);
            var step   = dist / (numberOfPoints - 1);
            var dx     = (cEnd.X - cStart.X) / dist;
            var dy     = (cEnd.Y - cStart.Y) / dist;

            bearing         = 0;
            bearing.Radians = Math.Atan2(dx, dy);
            if (bearing < 0)
            {
                bearing += 360;
            }
            if (bearing == 90 || bearing == 270)
            {
                mercatorRhumbDistance = dist * ScaleFactor(start.Latitude.Degrees);
            }
            else
            {
                // This is based on a paper published by Miljenko Petrović
                // See: http://hrcak.srce.hr/file/24998
                var e2 = ReferenceGlobe.Eccentricity * ReferenceGlobe.Eccentricity;
                mercatorRhumbDistance = ReferenceGlobe.SemiMajorAxis / Math.Cos(bearing.Radians) *
                                        ((1 - e2 / 4.0) * (end.Latitude - start.Latitude).Radians
                                         -
                                         e2 * (Math.Sin(2 * end.Latitude.Radians)
                                               - Math.Sin(2 * start.Latitude.Radians)) * 3.0 / 8.0);
            }
            var result = new GlobalCoordinates[numberOfPoints];

            result[0] = start;
            result[numberOfPoints - 1] = end;
            for (var i = 1; i < numberOfPoints - 1; i++)
            {
                var point = new EuclidianCoordinate(this, cStart.X + i * dx * step, cStart.Y + i * dy * step);
                result[i] = FromEuclidian(point);
            }
            return(result);
        }
    }
        /// <summary>
        /// Compute the euclidian distance between two points given by rectangular coordinates
        /// Please note, that due to scaling effects this might be quite different from the true
        /// geodetic distance. To get a good approximation, you must divide this value by a
        /// scale factor.
        /// </summary>
        /// <param name="point1">The first point</param>
        /// <param name="point2">The second point</param>
        /// <returns>The distance between the points</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public double EuclidianDistance(EuclidianCoordinate point1, EuclidianCoordinate point2)
        {
            if (point1 is null || point2 is null)
            {
                throw new ArgumentNullException();
            }

            if (!(point1.Projection.Equals(this) && point2.Projection.Equals(this)))
            {
                throw new ArgumentException(Properties.Resources.POINT_NOT_OWNED);
            }

            return(point1.DistanceTo(point2));
        }
 /// <summary>
 /// Get the latitude/longitude coordinates from the euclidian coordinates
 /// </summary>
 /// <param name="xy">The euclidien coordinates</param>
 /// <returns>The latitude/longitude coordinates of that point</returns>
 public override GlobalCoordinates FromEuclidian(EuclidianCoordinate xy)
 {
     return(new GlobalCoordinates(YToLatitude(xy.Y), XToLongitude(xy.X)));
 }
Beispiel #13
0
 public void TestNotSameProjection()
 {
     var e1 = new EuclidianCoordinate(projection, -3, -4);
     var e2 = new EuclidianCoordinate(new EllipticalMercatorProjection(), -3, -4);
     var d  = e1.DistanceTo(e2);
 }
        /// <summary>
        /// Convert a XY position on a Mercator map into global coordinates
        /// </summary>
        /// <param name="xy">The xy position on the Mercator map</param>
        /// <returns>The global coordinates</returns>
        public GlobalCoordinates XyToGlobalCoordinates(double[] xy)
        {
            var e = new EuclidianCoordinate(this, xy);

            return(FromEuclidian(e));
        }
Beispiel #15
0
        /// <summary>
        /// Froms the euclidian.
        /// </summary>
        /// <param name="xy">The xy.</param>
        /// <param name="scaleFactor">The scale factor.</param>
        /// <param name="meridianConvergence">The meridian convergence.</param>
        /// <returns>GlobalCoordinates.</returns>
        /// <exception cref="ArgumentException"></exception>
        internal GlobalCoordinates FromEuclidian(EuclidianCoordinate xy, out double scaleFactor, out double meridianConvergence)
        {
            if (xy is UtmCoordinate point)
            {
                var hemi = point.Grid.IsNorthern ? 1 : -1;

                var northingOffset = point.Grid.IsNorthern ? 0.0 : 10000000.0;
                var chi            = (point.Y - northingOffset) / (_m.K0 * _m.A);
                var eta            = (point.X - _m.E0) / (_m.K0 * _m.A);

                var sum = 0.0;
                for (var j = 1; j <= 3; j++)
                {
                    sum += _m.Beta[j - 1] * Math.Sin(2.0 * j * chi) * Math.Cosh(2.0 * j * eta);
                }
                var chitick = chi - sum;

                sum = 0.0;
                for (var j = 1; j <= 3; j++)
                {
                    sum += _m.Beta[j - 1] * Math.Cos(2.0 * j * chi) * Math.Sinh(2.0 * j * eta);
                }
                var etatick = eta - sum;

                sum = 0.0;
                for (var j = 1; j <= 3; j++)
                {
                    sum += 2.0 * j * _m.Beta[j - 1] * Math.Cos(2.0 * j * chi) * Math.Cosh(2.0 * j * eta);
                }
                var sigmatick = 1.0 - sum;

                var tautick = 0.0;
                for (var j = 1; j <= 3; j++)
                {
                    tautick += 2.0 * j * _m.Beta[j - 1] * Math.Sin(2.0 * j * chi) * Math.Sinh(2.0 * j * eta);
                }
                var xi = Math.Asin(Math.Sin(chitick) / Math.Cosh(etatick));

                var phi = xi;
                for (var j = 1; j <= 3; j++)
                {
                    phi += _m.Delta[j - 1] * Math.Sin(2.0 * j * xi);
                }

                var lambda0 = point.Grid.CenterMeridian.Radians;
                var lambda  = lambda0 + Math.Atan(Math.Sinh(etatick) / Math.Cos(chitick));
                var k       = _m.K0 * _m.A / ReferenceGlobe.SemiMajorAxis *
                              Math.Sqrt((Math.Pow(Math.Cos(chitick), 2.0) + Math.Pow(Math.Sinh(etatick), 2.0)) /
                                        (sigmatick * sigmatick + tautick * tautick) *
                                        (1.0 + Math.Pow((1.0 - _m.N) / (1.0 + _m.N) * Math.Tan(phi), 2.0)));
                var gamma = Math.Atan((tautick + sigmatick * Math.Tan(chitick) * Math.Tanh(etatick)) /
                                      (sigmatick - tautick * Math.Tan(chitick) * Math.Tanh(etatick))) * hemi;

                scaleFactor         = k;
                meridianConvergence = gamma;
                return(new GlobalCoordinates(Angle.RadToDeg(phi), Angle.RadToDeg(lambda)));
            }
            else
            {
                throw new ArgumentException(Properties.Resources.NO_UTM_COORDINATE);
            }
        }
Beispiel #16
0
 /// <summary>
 /// Get the latitude/longitude coordinates from the euclidian coordinates
 /// </summary>
 /// <param name="xy">The euclidien coordinates</param>
 /// <returns>The latitude/longitude coordinates of that point</returns>
 public override GlobalCoordinates FromEuclidian(EuclidianCoordinate xy)
 {
     return(FromEuclidian(xy, out _, out _));
 }
Beispiel #17
0
 public void TestConstructor3()
 {
     var e = new EuclidianCoordinate(projection, new double[] { -3, -4, -5 });
 }
 /// <summary>
 /// Get the latitude/longitude coordinates from the euclidian coordinates
 /// </summary>
 /// <param name="xy">The euclidien coordinates</param>
 /// <returns>The latitude/longitude coordinates of that point</returns>
 public abstract GlobalCoordinates FromEuclidian(EuclidianCoordinate xy);