Exemple #1
0
        /// <summary>
        /// Returns the minimum distance between this Geometry <paramref name="g0"/> and another Geometry <paramref name="g1"/>, by calculating the nearest
        /// points in NTS and then asking (Sharp)Proj to get the actual distance in meters.
        /// </summary>
        /// <param name="g0">Geometry 1</param>
        /// <param name="g1">Geometry 2</param>
        /// <returns>The distance in meters between g0 and g1, or null if unable to calculate</returns>
        /// <exception cref="ArgumentNullException">g0 or g1 is null</exception>
        /// <exception cref="ArgumentOutOfRangeException">The SRID of g0 and g1 don't match, are 0 or can't be resolved using <see cref="SridRegister"/></exception>
        /// <exception cref="ArgumentException"></exception>
        public static double?MeterDistance(this Geometry g0, Geometry g1)
        {
            if (g0 == null)
            {
                throw new ArgumentNullException(nameof(g0));
            }
            else if (g1 == null)
            {
                throw new ArgumentNullException(nameof(g1));
            }

            int srid = g0.SRID;

            if (srid == 0 || g1.SRID != g0.SRID)
            {
                throw new ArgumentOutOfRangeException("SRID is 0 or doesn't match");
            }

            SridItem sridItem;

            try
            {
                sridItem = SridRegister.GetByValue(srid);
            }
            catch (IndexOutOfRangeException sridExcepton)
            {
                throw new ArgumentOutOfRangeException("SRID not resolveable", sridExcepton);
            }

            using (var dt = sridItem.CRS.DistanceTransform.Clone()) // Thread safe with clone
            {
                return(g0.MeterDistance(g1, dt));
            }
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TGeometry"></typeparam>
        /// <param name="geometry"></param>
        /// <param name="toSrid"></param>
        /// <returns></returns>
        public static TGeometry Reproject <TGeometry>(this TGeometry geometry, SridItem toSrid)
            where TGeometry : Geometry
        {
            if (geometry == null)
            {
                return(null);
            }

            if (toSrid == null)
            {
                throw new ArgumentNullException(nameof(toSrid));
            }

            int srcSRID = geometry.SRID;

            if (srcSRID == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(geometry), "Geometry doesn't have valid srid");
            }

            SridItem srcItem = SridRegister.GetByValue(srcSRID);

            using (ProjContext pc = toSrid.CRS.Context.Clone()) // Make thread-safe. Use settings from crs
                using (CoordinateTransform ct = CoordinateTransform.Create(srcItem, toSrid, pc))
                {
                    return(Reproject(geometry, ct, toSrid.Factory));
                }
        }
Exemple #3
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TGeometry"></typeparam>
        /// <param name="geometry"></param>
        /// <param name="toSRID"></param>
        /// <returns></returns>
        public static TGeometry Reproject <TGeometry>(this TGeometry geometry, int toSRID)
            where TGeometry : Geometry
        {
            if (geometry == null)
            {
                return(null);
            }

            SridItem toSridItem = SridRegister.GetByValue(toSRID);

            return(Reproject(geometry, toSridItem));
        }
Exemple #4
0
        /// <summary>
        /// Returns a boolean indicating whether this Geometry <paramref name="g0"/> is within <paramref name="distanceInMeter"/> meters
        /// of Geometry <paramref name="g1"/>.
        /// </summary>
        /// <param name="g0">Geometry 1</param>
        /// <param name="g1">Geometry 2</param>
        /// <param name="distanceInMeter">The distance limit</param>
        /// <returns>true if the geometries are within distance, false if not and NULL if unable to calculate</returns>
        /// <exception cref="ArgumentNullException">g0 or g1 is null</exception>
        /// <exception cref="ArgumentOutOfRangeException">The SRID of g0 and g1 don't match, are 0 or can't be resolved using <see cref="SridRegister"/></exception>
        /// <exception cref="ArgumentException"></exception>
        public static bool?IsWithinMeterDistance(this Geometry g0, Geometry g1, double distanceInMeter)
        {
            if (g0 == null)
            {
                throw new ArgumentNullException(nameof(g0));
            }
            else if (g1 == null)
            {
                throw new ArgumentNullException(nameof(g1));
            }

            int srid = g0.SRID;

            if (srid == 0 || g1.SRID != g0.SRID)
            {
                throw new ArgumentOutOfRangeException("SRID is 0 or doesn't match");
            }

            DistanceOp distanceOp = new DistanceOp(g0, g1);

            Coordinate[] nearestPoints = distanceOp.NearestPoints();

            SridItem sridItem;

            try
            {
                sridItem = SridRegister.GetByValue(srid);
            }
            catch (IndexOutOfRangeException sridExcepton)
            {
                throw new ArgumentOutOfRangeException("SRID not resolveable", sridExcepton);
            }

            // TODO: There should be possible optimizations now, with knowledg of the CRS
            //       Maybe we can assume that this is always false if the NTS cut-off thinks it's false
            //       Not 100% sure and we want correctness

            using (var dt = sridItem.CRS.DistanceTransform.Clone()) // Thread safe with clone
            {
                double d = dt.GeoDistance(nearestPoints[0].ToPPoint(), nearestPoints[1].ToPPoint());

                if (double.IsInfinity(d) || double.IsNaN(d))
                {
                    return(null);
                }
                else
                {
                    return(d <= distanceInMeter);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Generic low-level reprojection. Used by the other methods
        /// </summary>
        /// <typeparam name="TGeometry"></typeparam>
        /// <param name="geometry"></param>
        /// <param name="operation"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public static TGeometry Reproject <TGeometry>(this TGeometry geometry, CoordinateTransform operation, GeometryFactory factory)
            where TGeometry : Geometry
        {
            if (geometry is null)
            {
                throw new ArgumentNullException(nameof(geometry));
            }
            else if (operation is null)
            {
                throw new ArgumentNullException(nameof(operation));
            }
            else if (factory is null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            return(SridRegister.ReProject(geometry, factory,
                                          sq => factory.CoordinateSequenceFactory.Create(sq.ToPPoints().Select(x => operation.Apply(x)).ToCoordinates().ToArray())));
        }
Exemple #6
0
        public void EpsgEnumTests()
        {
            var r       = SridRegister.GetById(Epsg.Netherlands);
            var factory = r.Factory;

            //SharpProj.
            Assert.AreEqual((int)Epsg.Netherlands, r.SRID);
            Assert.AreEqual((int)Epsg.Netherlands, factory.SRID);

            Assert.AreEqual((int)Epsg.BelgiumLambert, SridRegister.GetById(Epsg.BelgiumLambert).SRID);

            Assert.AreEqual(2, r.CRS.CoordinateSystem.Axis.Count);
            Point p = factory.CreatePoint(new Coordinate(155000, 463000));

            Point pp = p.Reproject(SridRegister.GetById(Epsg.BelgiumLambert));

            Assert.IsNotNull(pp);

            Assert.IsNotNull(p.Reproject <Geometry>(SridRegister.GetById(Epsg.BelgiumLambert)));

            Assert.AreEqual((int)Epsg.BelgiumLambert, pp.SRID);
            Assert.AreEqual(new Point(719706, 816781), new Point(pp.Coordinate.RoundAll(0)));

            using (CoordinateTransform t = CoordinateTransform.Create(SridRegister.GetByValue(p.SRID), SridRegister.GetById(Epsg.BelgiumLambert), new CoordinateTransformOptions {
                NoBallparkConversions = true
            }))
            {
                if (t is CoordinateTransformList mc)
                {
                    Assert.AreEqual(3, mc.Count);
                    Assert.AreEqual(5, mc[0].Parameters.Count);
                    Assert.AreEqual(7, mc[1].Parameters.Count);
                    Assert.AreEqual(6, mc[2].Parameters.Count);
                }
                else
                {
                    Assert.Fail();
                }

                var rr = t.Apply(new PPoint(155000, 463000));
            }
        }
Exemple #7
0
        public void NtsMeterDistance()
        {
            PPoint amersfoortRD = new PPoint(155000, 463000);

            var srid = SridRegister.GetById(Epsg.Netherlands);

            var t1 = CreateTriangle(srid.Factory, amersfoortRD.Offset(-50000, 0).ToCoordinate(), 5000);
            var t2 = CreateTriangle(srid.Factory, amersfoortRD.Offset(20, 50000).ToCoordinate(), 5000);
            var t3 = CreateTriangle(srid.Factory, amersfoortRD.ToCoordinate(), 100000);


            Assert.AreEqual(300000, Math.Round(t3.ExteriorRing.Length, 5));                       // Pythagoras. By definition

            Assert.AreEqual(65908.18, Math.Round(t1.Distance(t2), 2), "Distance pythagoras");     // Pythagoras
            Assert.AreEqual(65913.62, Math.Round(t1.MeterDistance(t2).Value, 2), "Geo distance"); // Via NL CRS



            Assert.AreEqual(300024.180, Math.Round(t3.ExteriorRing.MeterLength().Value, 3));



            Assert.IsTrue(t1.IsWithinMeterDistance(t2, 70000).Value);
            Assert.IsFalse(t2.IsWithinMeterDistance(t1, 64000).Value);


            Assert.IsTrue(t1.Centroid.Coordinate.Equals3D(t1.Centroid.Coordinate));

            Assert.AreEqual(4330127018.92, Math.Round(t3.Area, 2));

            // Test the raw (signed) operations to return the same thing. On polygon the value is taken absolute (unsigned)
            Assert.AreEqual(4330127018.92, Math.Round(NetTopologySuite.Algorithm.Area.OfRingSigned(t3.ExteriorRing.Coordinates), 2));
            Assert.AreEqual(4330957964.64, Math.Round(srid.CRS.DistanceTransform.GeoArea(t3.Coordinates), 2));

            Assert.AreEqual(4330957964.64, Math.Round(t3.MeterArea().Value, 2)); // Not using backing data yet
        }
Exemple #8
0
        public void NotSameTwice()
        {
            CoordinateReferenceSystem crs = SridRegister.GetById(Epsg.Netherlands);

            SridRegister.Ensure((Epsg)(-1), () => crs, -1);
        }
Exemple #9
0
 public void Init()
 {
     SridRegister.Ensure(Epsg.Netherlands, () => CoordinateReferenceSystem.Create("EPSG:28992"), (int)Epsg.Netherlands);
     SridRegister.Ensure(Epsg.BelgiumLambert, () => CoordinateReferenceSystem.Create("EPSG:3812"), (int)Epsg.BelgiumLambert);
     SridRegister.Ensure(Epsg.AnotherNL, () => CoordinateReferenceSystem.Create("EPSG:28992"), (int)Epsg.AnotherNL); // Different EPSG, same definition. Ok. But can't use same CRS instance
 }