示例#1
0
        public void CanWriteMultiPoint()
        {
            Pnt3D point1 = new Pnt3D(2600001.123, 1200000.987, 432.1);
            Pnt3D point2 = new Pnt3D(2600002.234, 1200002.876, 321.98);

            IList <IPnt> multipoint = new IPnt[]
            {
                point1,
                point2
            };

            WkbGeomWriter writer = new WkbGeomWriter();

            byte[] bytes = writer.WriteMultipoint(multipoint);

            WkbGeomReader reader = new WkbGeomReader();

            List <IPnt> deserizalized = reader.ReadMultiPoint(new MemoryStream(bytes)).ToList();

            Assert.AreEqual(multipoint.Count, deserizalized.Count);

            for (int i = 0; i < multipoint.Count; i++)
            {
                Assert.IsTrue(deserizalized[i].Equals(multipoint[i]));
            }
        }
示例#2
0
        public void CanDetermineDistancePerpendicular()
        {
            var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0));
            var point = new Pnt3D(10, 0, 0);

            double d = line1.GetDistancePerpendicular(point);

            double epsilon = MathUtils.GetDoubleSignificanceEpsilon(10);

            double expectedDist2D = Math.Sqrt(100 + 100) / 2;

            Assert.AreEqual(expectedDist2D, d, epsilon);

            point = new Pnt3D(10, 0, 10);
            d     = line1.GetDistancePerpendicular(point);
            Assert.AreEqual(Math.Sqrt(expectedDist2D * expectedDist2D + 100), d, epsilon);

            point = new Pnt3D(0, 0, 0);
            d     = line1.GetDistancePerpendicular(point);
            Assert.AreEqual(0, d, epsilon);

            point = new Pnt3D(6, 6, 0);
            d     = line1.GetDistancePerpendicular(point);
            Assert.AreEqual(0, d, epsilon);
        }
示例#3
0
        public void CanInterpolateUndefinedZsInLinestring()
        {
            var ring1 = new List <Pnt3D>();

            // ring1: horizontal:
            ring1.Add(new Pnt3D(0, 0, 10));
            ring1.Add(new Pnt3D(0, 100, 20));
            ring1.Add(new Pnt3D(100, 100, double.NaN));
            ring1.Add(new Pnt3D(50, 50, double.NaN));
            ring1.Add(new Pnt3D(100, 0, 20 + 10 + 10 * Math.Sqrt(2)));

            Pnt3D testPoint1 = new Pnt3D(100, 100, double.NaN);
            Pnt3D testPoint2 = new Pnt3D(50, 50, double.NaN);

            Linestring linestring = null;

            for (var i = 0; i < ring1.Count; i++)
            {
                Pnt3D[] array1 = ring1.ToArray();
                CollectionUtils.Rotate(array1, i);
                var rotatedRing = new List <Pnt3D>(array1);

                linestring = new Linestring(rotatedRing);

                bool nanStartOrEnd = double.IsNaN(linestring.StartPoint.Z) ||
                                     double.IsNaN(linestring.EndPoint.Z);

                Assert.True(linestring.TryInterpolateUndefinedZs());

                int?pt1Idx = linestring.FindPointIdx(testPoint1, true);
                Assert.NotNull(pt1Idx);

                Pnt3D foundPt1 = linestring.GetPoint3D(pt1Idx.Value);

                int?pt2Idx = linestring.FindPointIdx(testPoint2, true);
                Assert.NotNull(pt2Idx);

                Pnt3D foundPt2 = linestring.GetPoint3D(pt2Idx.Value);

                if (!nanStartOrEnd)
                {
                    // incline: 10m per 100m:
                    double testPoint1ExpectedZ = 20 + 10;
                    Assert.AreEqual(testPoint1ExpectedZ, foundPt1.Z);

                    testPoint1ExpectedZ += 5 * Math.Sqrt(2);

                    Assert.AreEqual(testPoint1ExpectedZ, foundPt2.Z);
                }

                Assert.False(linestring.GetPoints().Any(p => double.IsNaN(p.Z)));
            }

            Pnt3D point = linestring[2].StartPoint;

            linestring.UpdatePoint(2, point.X, point.Y, double.NaN);

            Assert.True(linestring.TryInterpolateUndefinedZs());
            Assert.False(double.IsNaN(linestring[2].StartPoint.Z));
        }
示例#4
0
        public static void AddPaths([NotNull] IList <Linestring> linestringsToAdd,
                                    [NotNull] IPolyline toResult)
        {
            Func <Pnt3D, WKSPointZ> createPoint;

            if (GeometryUtils.IsZAware(toResult))
            {
                createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, p.Z);
            }
            else
            {
                createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, double.NaN);
            }

            IPath pathTemplate = GeometryFactory.CreateEmptyPath(toResult);

            foreach (Linestring resultLinestring in linestringsToAdd)
            {
                var pathPoints = new WKSPointZ[resultLinestring.SegmentCount + 1];

                var i = 0;
                foreach (Line3D line3D in resultLinestring)
                {
                    pathPoints[i++] = createPoint(line3D.StartPoint);
                }

                Pnt3D last = resultLinestring[resultLinestring.SegmentCount - 1].EndPoint;
                pathPoints[i] = createPoint(last);

                IPath path = GeometryFactory.Clone(pathTemplate);
                GeometryUtils.AddWKSPointZs((IPointCollection4)path, pathPoints);
                ((IGeometryCollection)toResult).AddGeometry(path);
            }
        }
示例#5
0
        public static bool?AreCoplanar([NotNull] IList <Pnt3D> points,
                                       [NotNull] Plane3D plane,
                                       double tolerance,
                                       out double maxDeviationFromPlane,
                                       out string message)
        {
            message = null;

            if (!plane.IsDefined)
            {
                message =
                    $"The plane is not sufficiently defined by the input points {StringUtils.Concatenate(points, ", ")}.";
                maxDeviationFromPlane = double.NaN;
                return(null);
            }

            if (MathUtils.AreEqual(
                    0, GeomUtils.GetArea3D(points, new Pnt3D(plane.Normal))))
            {
                // Technically, the plane could be defined, but it is quite random
                message =
                    $"The ring is degenerate without 3D area {StringUtils.Concatenate(points, ", ")}.";
                maxDeviationFromPlane = double.NaN;
                return(null);
            }

            var coplanar = true;

            double maxDistance      = 0;
            Pnt3D  maxDistancePoint = null;

            foreach (Pnt3D pnt3D in points)
            {
                double d = plane.GetDistanceSigned(pnt3D);

                if (!MathUtils.AreEqual(d, 0, tolerance))
                {
                    if (Math.Abs(d) > Math.Abs(maxDistance))
                    {
                        maxDistance      = d;
                        maxDistancePoint = pnt3D;
                    }

                    coplanar = false;
                }
            }

            if (!coplanar)
            {
                _msg.VerboseDebug(
                    $"Coplanarity of point {maxDistancePoint} with plane {plane} is violated: {maxDistance}m");
                message =
                    $"Coplanarity of the plane is violated by {maxDistance} at point {maxDistancePoint}";
            }

            maxDeviationFromPlane = Math.Abs(maxDistance);

            return(coplanar);
        }
示例#6
0
        public void CanGetAngle3DInRad180()
        {
            var a = new Pnt3D(0, 0, 0);
            var b = new Pnt3D(100, 100, 60);
            var c = new Pnt3D(200, 200, 120);

            Assert.AreEqual(MathUtils.ToRadians(180), GeomUtils.GetAngle3DInRad(a, b, c),
                            MathUtils.GetDoubleSignificanceEpsilon(3));
        }
 public Pnt3DIntersectionPoint([NotNull] Pnt3D point,
                               [NotNull] ISpatialReference spatialReference,
                               double otherZ,
                               double?zDifference = null)
 {
     Point = GeometryFactory.CreatePoint(point.X, point.Y, point.Z, double.NaN,
                                         spatialReference);
     Point.SnapToSpatialReference();
     OtherZ   = otherZ;
     Distance = zDifference;
 }
示例#8
0
        public void CanReadWritePoint()
        {
            IPoint pointXy  = GeometryFactory.CreatePoint(2600000, 1200000);
            IPoint pointXyz = GeometryFactory.CreatePoint(2600000, 1200000, 400);

            WkbGeometryWriter writer = new WkbGeometryWriter();

            byte[] wkb2D = writer.WritePoint(pointXy);
            byte[] wkb3D = writer.WritePoint(pointXyz);

            // Compare with AO (2D only)
            byte[] arcObjectsWkb = GeometryUtils.ToWkb(pointXy);
            Assert.AreEqual(arcObjectsWkb, wkb2D);

            // Compare with Wkx
            byte[] wkx2D = ToChristianSchwarzWkb(pointXy);
            Assert.AreEqual(wkx2D, wkb2D);

            byte[] wkx3D = ToChristianSchwarzWkb(pointXyz);
            Assert.AreEqual(wkx3D, wkb3D);

            // Bonus test: Geom
            WkbGeomWriter geomWriter = new WkbGeomWriter();
            Pnt3D         pnt2D      = new Pnt3D(pointXy.X, pointXy.Y, double.NaN);

            byte[] bytesGeom2D = geomWriter.WritePoint(pnt2D, Ordinates.Xy);
            Assert.AreEqual(wkb2D, bytesGeom2D);

            Pnt3D pnt3D = new Pnt3D(pointXyz.X, pointXyz.Y, pointXyz.Z);

            byte[] bytesGeom3D = geomWriter.WritePoint(pnt3D);
            Assert.AreEqual(wkb3D, bytesGeom3D);

            // NOTE: Comparison with ST_Geometry SDE.ST_AsBinary(SHAPE) using nHibernate
            // connection is performed in StGeometryPerimeterRepositoryTest

            // Read back:
            WkbGeometryReader reader = new WkbGeometryReader();

            IPoint restored = reader.ReadPoint(new MemoryStream(wkb2D));

            Assert.IsTrue(GeometryUtils.AreEqual(pointXy, restored));

            restored = reader.ReadPoint(new MemoryStream(wkb3D));
            Assert.IsTrue(GeometryUtils.AreEqual(pointXyz, restored));

            // Geom:
            WkbGeomReader geomReader = new WkbGeomReader();

            Assert.IsTrue(pnt2D.Equals(geomReader.ReadPoint(new MemoryStream(bytesGeom2D))));

            Assert.IsTrue(pnt3D.Equals(geomReader.ReadPoint(new MemoryStream(bytesGeom3D))));
        }
示例#9
0
        public void CanGetAngle3DInRad0()
        {
            var a = new Pnt3D(3333.33, 4444.44444, 5555.55555);
            var b = new Pnt3D(12345.6789, 9876.54321, 5678.90123);

            double calculated = GeomUtils.GetAngle3DInRad(a, b, a);

            // Problem: How should the client code know the applicable epsilon whithout knowledge of the internal algorithm?
            double epsilon = MathUtils.GetDoubleSignificanceEpsilon(a.X * b.X, a.Y * b.Y);

            Assert.AreEqual(0, calculated, epsilon);
        }
示例#10
0
        public void CanWritePoint()
        {
            Pnt3D point = new Pnt3D(2600001.123, 1200000.987, 432.1);

            WkbGeomWriter writer = new WkbGeomWriter();

            byte[] bytes = writer.WritePoint(point);

            WkbGeomReader reader = new WkbGeomReader();

            IPnt deserializedPoint = reader.ReadPoint(new MemoryStream(bytes));

            Assert.IsTrue(deserializedPoint.Equals(point));
        }
示例#11
0
        public void CanDetermineIntersectionPointXYOutsideLineEnds()
        {
            var line1 = new Line3D(new Pnt3D(0, 6, 0), new Pnt3D(10, 10, 0));
            var line2 = new Line3D(new Pnt3D(0, 4, 0), new Pnt3D(10, 1, 0));

            double line1Factor, line2Factor;

            Assert.False(line1.HasIntersectionPointXY(line2, 2, out line1Factor,
                                                      out line2Factor));

            Pnt3D pointAlong1 = line1.GetPointAlong(line1Factor, true);

            Assert.Less(pointAlong1.X, -2);
        }
示例#12
0
        public void CanDetermineIntersectionPointXY()
        {
            var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0));
            var line2 = new Line3D(new Pnt3D(2, 8, 0), new Pnt3D(10, 1, 0));

            double line1Factor, line2Factor;

            Assert.True(
                line1.HasIntersectionPointXY(line2, 0, out line1Factor, out line2Factor));
            Assert.Greater(line1Factor, line2Factor);

            double epsilon     = MathUtils.GetDoubleSignificanceEpsilon(10);
            Pnt3D  pointAlong1 = line1.GetPointAlong(line1Factor, true);
            Pnt3D  pointAlong2 = line2.GetPointAlong(line2Factor, true);

            Assert.True(pointAlong1.Equals(pointAlong2, epsilon));
        }
示例#13
0
        public void CanGetAngle3DInRad90()
        {
            var a = new Pnt3D(0, 0, 0);
            var b = new Pnt3D(0, 100, 0);
            var c = new Pnt3D(50, 100, 0);

            double expected   = MathUtils.ToRadians(90);
            double calculated = GeomUtils.GetAngle3DInRad(a, b, c);
            double epsilon    = MathUtils.GetDoubleSignificanceEpsilon(3);

            Assert.AreEqual(expected, calculated, epsilon);

            var d = new Pnt3D(-50, 100, 0);

            calculated = GeomUtils.GetAngle3DInRad(a, b, d);
            Assert.AreEqual(expected, calculated, epsilon);
        }
示例#14
0
        public void CanDetermineDistanceAlong()
        {
            var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0));
            var point = new Pnt3D(2, 2, 0);

            double d = line1.GetDistanceAlong(point);

            double epsilon = MathUtils.GetDoubleSignificanceEpsilon(10);

            double expectedDist2D = Math.Sqrt(4 + 4);

            Assert.AreEqual(expectedDist2D, d, epsilon);

            point = new Pnt3D(2, 2, 24);
            d     = line1.GetDistancePerpendicular(point);

            Assert.AreEqual(24, d, epsilon);
        }
示例#15
0
        private static IEnumerable <Pnt3D> CreateRandomPoints(int pointCount,
                                                              double x, double y, double z)
        {
            Random random = new Random();

            Pnt3D result = new Pnt3D(x, y, z);

            const double averageLength = 1.5;

            for (int i = 0; i < pointCount; i++)
            {
                result = result.ClonePnt3D();

                result.X += (random.NextDouble() - 0.5) * averageLength;
                result.Y += (random.NextDouble() - 0.5) * averageLength;
                result.Z  = (random.NextDouble()) * averageLength;

                yield return(result);
            }
        }
示例#16
0
        private bool CutLineHull3D([NotNull] Pnt3D p0s,
                                   [NotNull] Pnt3D l0,
                                   [NotNull] Pnt3D p1s,
                                   [NotNull] Pnt3D l1,
                                   double r2,
                                   out double tMin, out double tMax,
                                   out NearSegment hullStartNear,
                                   out NearSegment hullEndNear)
        {
            // Equation for points X on cylinder around p1 + u * l1 with square radius = r2
            //                2          2
            // ((X - p1) x l1)  = r2 * l1
            //
            // with X = p0 + t * l0, tMin and tMax can be determined
            //
            hullStartNear = NearSegment.NotNear;
            hullEndNear   = NearSegment.NotNear;

            if (Geom.IsParallel)             // parallel
            {
                return(Parallel(p0s, l0, p1s, l1, r2,
                                out tMin, out tMax, ref hullStartNear,
                                ref hullEndNear));
            }

            double l12   = l1 * l1;
            double r2l12 = r2 * l12;

            var   p0_p1    = (Pnt3D)(p0s - p1s);
            Pnt3D p0_p1xl1 = p0_p1.VectorProduct(l1);

            if (SegmentUtils.SolveSqr(Geom.L0xl12, 2 * Geom.L0xl1 * p0_p1xl1,
                                      p0_p1xl1 * p0_p1xl1 - r2l12,
                                      out tMin, out tMax))
            {
                return(Near(p0s, l0, p1s, l1, r2, l12, ref tMin, ref tMax,
                            ref hullStartNear, ref hullEndNear));
            }

            return(false);
        }
        private static Linestring GetLineString(
            [NotNull] IEnumerable <SegmentProxy> segments)
        {
            Pnt3D previousPoint = null;
            var   points        = new List <Pnt3D>();

            foreach (var segment in segments)
            {
                var start = (Pnt3D)segment.GetStart(true);
                var end   = (Pnt3D)segment.GetEnd(true);

                if (!Equals(previousPoint, start))
                {
                    points.Add(start);
                }

                points.Add(end);
                previousPoint = end;
            }

            return(new Linestring(points));
        }
示例#18
0
        public void CanGetDistanceXYPerpendicularSigned()
        {
            var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0));
            var point = new Pnt3D(2, 2, 0);

            double distanceAlong;

            Assert.AreEqual(0, line1.GetDistanceXYPerpendicularSigned(point));
            Assert.AreEqual(
                0, line1.GetDistanceXYPerpendicularSigned(point, out distanceAlong));
            Assert.AreEqual(0.2, distanceAlong);

            double epsilon = MathUtils.GetDoubleSignificanceEpsilon(5);

            // slightly on the left:
            point = new Pnt3D(5.0, 5.01, 17);
            double expectedOffset      = Math.Sqrt(2) * 0.01 / 2;
            double expectedOffsetAlong = expectedOffset / line1.Length2D;

            Assert.AreEqual(expectedOffset, line1.GetDistanceXYPerpendicularSigned(point),
                            epsilon);
            Assert.AreEqual(expectedOffset,
                            line1.GetDistanceXYPerpendicularSigned(
                                point, out distanceAlong),
                            epsilon);
            Assert.AreEqual(0.5 + expectedOffsetAlong, distanceAlong, epsilon);

            // slightly on the right:
            point = new Pnt3D(5.0, 4.99, 17);
            Assert.AreEqual(-expectedOffset,
                            line1.GetDistanceXYPerpendicularSigned(point),
                            epsilon);
            Assert.AreEqual(-expectedOffset,
                            line1.GetDistanceXYPerpendicularSigned(
                                point, out distanceAlong),
                            epsilon);
            Assert.AreEqual(0.5 - expectedOffsetAlong, distanceAlong, epsilon);
        }
示例#19
0
        public void CanWriteMultiPoint()
        {
            Pnt3D point1 = new Pnt3D(2600001.123, 1200000.987, 432.1);
            Pnt3D point2 = new Pnt3D(2600002.234, 1200002.876, 321.98);

            var multipoint = new Multipoint <IPnt>(new[]
            {
                point1,
                point2
            });

            WkbGeomWriter writer = new WkbGeomWriter();

            byte[] bytes = writer.WriteMultipoint(multipoint);

            WkbGeomReader reader = new WkbGeomReader();

            Multipoint <IPnt> deserizalized = reader.ReadMultiPoint(new MemoryStream(bytes));

            Assert.AreEqual(multipoint.PointCount, deserizalized.PointCount);

            Assert.IsTrue(deserizalized.Equals(multipoint));
        }
示例#20
0
        public void CanCreateUndefinedPlaneFromCollinearPoints()
        {
            // first and last point is identical:
            var points = new List <Pnt3D>
            {
                new Pnt3D(2577627.794, 1183434.723, 635.800000000003),
                new Pnt3D(2577627.643, 1183437.291, 635.804999999993),
                new Pnt3D(2577627.794, 1183434.723, 635.800000000003)
            };

            Plane3D plane = Plane3D.FitPlane(points, isRing: false);

            Assert.False(plane.IsDefined);
            Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon);

            // generally collinear:
            points = new List <Pnt3D>
            {
                new Pnt3D(2577627.794, 1183434.723, 635.800000000003),
                new Pnt3D(2577629.643, 1183437.291, 635.804999999993)
            };

            Pnt3D pnt3D = points[0] + (points[1] - points[0]) * 3.5;

            points.Add(pnt3D);

            plane = Plane3D.FitPlane(points, isRing: false);

            Assert.False(plane.IsDefined);
            Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon);

            points.Add(points[0]);
            plane = Plane3D.FitPlane(points, isRing: true);

            Assert.False(plane.IsDefined);
            Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon);
        }
示例#21
0
        public void CanDetermineCorrectOrientationForPseudoLinearIntersecion()
        {
            // The linear intersection can be somewhat un-intuitive if the end points are witin the tolerance to the
            // other line but just outside the tolerance to the other end point.

            Line3D line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(5, 0, 0));
            Line3D line2 = new Line3D(new Pnt3D(0.011, 0, 0), new Pnt3D(-10, 10, 0));

            const double tolerance = 0.01;

            SegmentIntersection intersection =
                AssertLinearIntersection(line1, line2, tolerance, true);

            double startAlongSource;
            Pnt3D  sourceStart =
                intersection.GetLinearIntersectionStart(line1, out startAlongSource);

            double endAlongSource;
            Pnt3D  sourceEnd = intersection.GetLinearIntersectionEnd(line1, out endAlongSource);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);

            line2 = new Line3D(new Pnt3D(0.009, -0.008, 0), new Pnt3D(-10, 10, 0));
            AssertLinearIntersection(line1, line2, tolerance, true);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);

            // Really acute:
            line2 = new Line3D(new Pnt3D(0.03, 0.0, 0), new Pnt3D(-10, 1, 0));
            AssertLinearIntersection(line1, line2, tolerance, true);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);
        }
示例#22
0
        public TileIndex GetTileIndexAt([NotNull] Pnt3D point)
        {
            Assert.ArgumentNotNull(point, nameof(point));

            return(GetTileIndexAt(point.X, point.Y));
        }
示例#23
0
        public void CanGetContainsXY()
        {
            var ring1 = new List <Pnt3D>();

            ring1.Add(new Pnt3D(0, 0, 10));
            ring1.Add(new Pnt3D(0, 100, 20));
            ring1.Add(new Pnt3D(100, 100, 10));
            ring1.Add(new Pnt3D(50, 50, 10));
            ring1.Add(new Pnt3D(25, 75, 10));
            ring1.Add(new Pnt3D(0, 0, 10));

            Linestring l = new Linestring(ring1);

            double tolerance = 0.001;

            var pointOutsideRightOfCape = new Pnt3D(70, 50, 2);

            Assert.IsFalse(
                GeomRelationUtils.AreBoundsDisjoint(l, pointOutsideRightOfCape, tolerance));
            Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointOutsideRightOfCape, tolerance));
            Assert.IsFalse(
                GeomRelationUtils.PolycurveContainsXY(l, pointOutsideRightOfCape, tolerance));

            Assert.AreEqual(
                false, GeomRelationUtils.AreaContainsXY(l, pointOutsideRightOfCape, tolerance));
            Assert.AreEqual(
                false,
                GeomRelationUtils.AreaContainsXY(l, pointOutsideRightOfCape, tolerance, true));

            var pointOutsideLeftOfCape = new Pnt3D(40, 50, 2);

            Assert.IsFalse(
                GeomRelationUtils.AreBoundsDisjoint(l, pointOutsideLeftOfCape, tolerance));
            Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointOutsideLeftOfCape, tolerance));
            Assert.IsFalse(
                GeomRelationUtils.PolycurveContainsXY(l, pointOutsideLeftOfCape, tolerance));

            Assert.AreEqual(
                false, GeomRelationUtils.AreaContainsXY(l, pointOutsideLeftOfCape, tolerance));
            Assert.AreEqual(
                false,
                GeomRelationUtils.AreaContainsXY(l, pointOutsideLeftOfCape, tolerance, true));

            var pointInside = new Pnt3D(10, 90, 123);

            Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointInside, tolerance));
            Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointInside, tolerance));
            Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointInside, tolerance));

            Assert.AreEqual(true, GeomRelationUtils.AreaContainsXY(l, pointInside, tolerance));
            Assert.AreEqual(
                true, GeomRelationUtils.AreaContainsXY(l, pointInside, tolerance, true));

            var pointOnTopRightCorner = new Pnt3D(100, 100, 2);

            Assert.IsFalse(
                GeomRelationUtils.AreBoundsDisjoint(l, pointOnTopRightCorner, tolerance));
            Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnTopRightCorner, tolerance));
            Assert.IsTrue(
                GeomRelationUtils.PolycurveContainsXY(l, pointOnTopRightCorner, tolerance));
            Assert.AreEqual(
                null, GeomRelationUtils.AreaContainsXY(l, pointOnTopRightCorner, tolerance));
            Assert.AreEqual(
                null, GeomRelationUtils.AreaContainsXY(l, pointOnTopRightCorner, tolerance, true));

            var pointOnCape = new Pnt3D(50, 50, 321);

            Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointOnCape, tolerance));
            Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnCape, tolerance));
            Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointOnCape, tolerance));
            Assert.AreEqual(null, GeomRelationUtils.AreaContainsXY(l, pointOnCape, tolerance));
            Assert.AreEqual(
                null, GeomRelationUtils.AreaContainsXY(l, pointOnCape, tolerance, true));

            var pointOnLeftEdge = new Pnt3D(0, 50, 2);

            Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointOnLeftEdge, tolerance));
            Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnLeftEdge, tolerance));
            Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointOnLeftEdge, tolerance));
            Assert.AreEqual(null, GeomRelationUtils.AreaContainsXY(l, pointOnLeftEdge, tolerance));
            Assert.AreEqual(
                null, GeomRelationUtils.AreaContainsXY(l, pointOnLeftEdge, tolerance, true));
        }
示例#24
0
        public void CanCalculateOrientationVertical()
        {
            var ring = new List <Pnt3D>();

            // ring1: horizontal:
            ring.Add(new Pnt3D(2600000, 1200000, 500));
            ring.Add(new Pnt3D(2600080, 1200060, 500));
            ring.Add(new Pnt3D(2600080, 1200060, 530));
            ring.Add(new Pnt3D(2600040, 1200030, 540));
            ring.Add(new Pnt3D(2600000, 1200000, 530));

            for (var i = 0; i < ring.Count; i++)
            {
                Pnt3D[] array1 = ring.ToArray();
                CollectionUtils.Rotate(array1, i);
                var rotatedRing = new List <Pnt3D>(array1);

                rotatedRing.Add((Pnt3D)rotatedRing[0].Clone());

                Linestring original = new Linestring(rotatedRing);

                Pnt3D rightMostBottomPoint = GetRightMostBottomPoint(original);

                Linestring linestring = original.Clone();
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));
                AssertVerticalRing(linestring);
                linestring.ReverseOrientation();
                AssertVerticalRing(linestring);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));

                // New linestring from segments
                linestring = new Linestring(original.Segments);
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));
                AssertVerticalRing(linestring);
                linestring.ReverseOrientation();
                AssertVerticalRing(linestring);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));

                // New linestring from segments (reversed)
                rotatedRing.Reverse();
                linestring = new Linestring(rotatedRing);
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));
                AssertVerticalRing(linestring);
                linestring.ReverseOrientation();
                AssertVerticalRing(linestring);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));

                // reverse, back, use (referenced!) segments again:
                linestring.ReverseOrientation();
                linestring = new Linestring(linestring.Segments);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));
                Assert.True(linestring.IsClosed);
                AssertVerticalRing(linestring);
                linestring.ReverseOrientation();
                AssertVerticalRing(linestring);
                Assert.True(
                    rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring),
                                                  double.Epsilon));
            }

            // And a version with some slight deviations
            ring.Add(ring[0]);
            ring.Insert(1, new Pnt3D(2600040.01, 1200030.01, 500));
            Linestring verticalWithin1mm = new Linestring(ring);

            Assert.True(verticalWithin1mm.IsVerticalRing(0.01));
        }
示例#25
0
        public void CanCalculateOrientation()
        {
            var ring1 = new List <Pnt3D>();

            // ring1: horizontal:
            ring1.Add(new Pnt3D(0, 0, 9));
            ring1.Add(new Pnt3D(0, 100, 9));
            ring1.Add(new Pnt3D(100, 100, 9));
            ring1.Add(new Pnt3D(70, 20, 9));
            ring1.Add(new Pnt3D(100, 0, 9));

            for (var i = 0; i < ring1.Count; i++)
            {
                Pnt3D[] array1 = ring1.ToArray();
                CollectionUtils.Rotate(array1, i);
                var rotatedRing = new List <Pnt3D>(array1);

                rotatedRing.Add((Pnt3D)rotatedRing[0].Clone());

                Linestring original = new Linestring(rotatedRing);

                Pnt3D rightMostBottomPoint = GetRightMostBottomPoint(original);

                Linestring linestring = original.Clone();
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));
                Assert.True(linestring.ClockwiseOriented == true);
                linestring.ReverseOrientation();
                Assert.True(linestring.ClockwiseOriented == false);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));

                linestring = new Linestring(original.Segments);
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));
                Assert.True(linestring.ClockwiseOriented == true);
                linestring.ReverseOrientation();
                Assert.True(linestring.ClockwiseOriented == false);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));

                rotatedRing.Reverse();
                linestring = new Linestring(rotatedRing);
                Assert.True(linestring.IsClosed);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));
                Assert.True(linestring.ClockwiseOriented == false);
                linestring.ReverseOrientation();
                Assert.True(linestring.ClockwiseOriented == true);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));

                // reverse, back, use (referenced!) segments again:
                linestring.ReverseOrientation();
                linestring = new Linestring(linestring.Segments);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));
                Assert.True(linestring.IsClosed);
                Assert.True(linestring.ClockwiseOriented == false);
                linestring.ReverseOrientation();
                Assert.True(linestring.ClockwiseOriented == true);
                Assert.True(
                    rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring)));
            }
        }
示例#26
0
        public void CanGetPointsFromLinestring()
        {
            var startPoint = new Pnt3D(-5, -15, -25);
            var endPoint   = new Pnt3D(10, 20, 30);

            var line1 = new Line3D(startPoint, endPoint);

            Linestring linestring = new Linestring(new List <Line3D> {
                line1
            });

            Pnt3D start = linestring.GetPoint3D(0);

            Assert.True(ReferenceEquals(startPoint, start));

            Pnt3D end = linestring.GetPoint3D(1);

            Assert.True(ReferenceEquals(endPoint, end));

            var list = linestring.GetPoints(0, 1).ToList();

            Assert.AreEqual(1, list.Count);
            Assert.True(ReferenceEquals(startPoint, list[0]));

            list = linestring.GetPoints(1, 1).ToList();
            Assert.AreEqual(1, list.Count);
            Assert.True(ReferenceEquals(endPoint, list[0]));

            list = linestring.GetPoints(0, 2).ToList();
            Assert.AreEqual(2, list.Count);
            Assert.True(ReferenceEquals(startPoint, list[0]));
            Assert.True(ReferenceEquals(endPoint, list[1]));

            // The same using default values
            list = linestring.GetPoints().ToList();
            Assert.AreEqual(2, list.Count);
            Assert.True(Equals(startPoint, list[0]));
            Assert.True(Equals(endPoint, list[1]));

            // The same with clone
            list = linestring.GetPoints(0, null, true).ToList();
            Assert.AreEqual(2, list.Count);
            Assert.False(ReferenceEquals(startPoint, list[0]));
            Assert.True(startPoint.Equals(list[0]));
            Assert.False(ReferenceEquals(endPoint, list[1]));
            Assert.True(endPoint.Equals(list[1]));

            var intermediatePoint = new Pnt3D(0, 0, 0);

            linestring = new Linestring(new[] { startPoint, intermediatePoint, endPoint });

            start = linestring.GetPoint3D(0);
            Assert.True(ReferenceEquals(startPoint, start));

            end = linestring.GetPoint3D(2);
            Assert.True(ReferenceEquals(endPoint, end));

            list = linestring.GetPoints(0, 1).ToList();
            Assert.AreEqual(1, list.Count);
            Assert.True(ReferenceEquals(startPoint, list[0]));

            list = linestring.GetPoints(2, 1).ToList();
            Assert.AreEqual(1, list.Count);
            Assert.True(ReferenceEquals(endPoint, list[0]));

            list = linestring.GetPoints(0, 2).ToList();
            Assert.AreEqual(2, list.Count);
            Assert.True(ReferenceEquals(startPoint, list[0]));
            Assert.True(ReferenceEquals(intermediatePoint, list[1]));

            list = linestring.GetPoints().ToList();
            Assert.AreEqual(3, list.Count);
            Assert.True(ReferenceEquals(startPoint, list[0]));
            Assert.True(ReferenceEquals(intermediatePoint, list[1]));
            Assert.True(ReferenceEquals(endPoint, list[2]));
        }
示例#27
0
        public static List <WKSPointZ> ProjectToPlane([NotNull] Plane plane,
                                                      [NotNull] IEnumerable <Pnt> points)
        {
            if (plane.IsDefined)
            {
                WKSPointZ planeVector1;
                WKSPointZ planeVector2;                 // orthogonal to planeVector1
                plane.GetPlaneVectors(out planeVector1, out planeVector2);

                var projectedPoints = new List <WKSPointZ>();

                foreach (Pnt point in points)
                {
                    var projected =
                        new WKSPointZ
                    {
                        X = planeVector1.X * point.X +
                            planeVector1.Y * point.Y +
                            planeVector1.Z * point[2],
                        Y = planeVector2.X * point.X +
                            planeVector2.Y * point.Y +
                            planeVector2.Z * point[2]
                    };

                    projectedPoints.Add(projected);
                }

                return(projectedPoints);
            }

            // the plane is not defined

            var linears = new List <WKSPointZ>();

            Pnt start     = null;
            Pnt direction = null;

            foreach (Pnt point in points)
            {
                if (start == null)
                {
                    start = point;
                }

                double dx = point.X - start.X;
                double dy = point.Y - start.Y;
                double dz = point[2] - start[2];

                double l = Math.Sqrt(dx * dx + dy * dy + dz * dz);

                if (Math.Abs(l) > double.Epsilon)
                {
                    if (direction == null)
                    {
                        direction = new Pnt3D(dx, dy, dz);
                    }
                    else
                    {
                        l = l * Math.Sign(direction.X * dx + direction.Y * dy +
                                          direction[2] * dz);
                    }
                }

                var linear = new WKSPointZ {
                    X = l
                };

                linears.Add(linear);
            }

            return(linears);
        }
示例#28
0
        public void CanCutAlongUsingZSources()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            GeometryUtils.MakeZAware(sourceFeature.Shape);
            GeometryUtils.MakeZAware(targetFeature.Shape);

            var   normal     = new Vector(new[] { 0.5, 0.5, 2 });
            Pnt3D planePoint = new Pnt3D(2600000, 1200000, 600);

            Plane3D sourcePlane = new Plane3D(normal, planePoint);

            ChangeAlongZUtils.AssignZ((IPointCollection)sourceFeature.Shape, sourcePlane);

            GeometryUtils.ApplyConstantZ(targetFeature.Shape, 500);

            CalculateCutLinesRequest calculationRequest =
                CreateCalculateCutLinesRequest(sourceFeature, targetFeature);

            CalculateCutLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability);

            AssertReshapeLineCount(calculateResponse.CutLines, 1, 1);

            IPolyline reshapeLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(calculateResponse.CutLines[0].Path);

            Assert.NotNull(reshapeLine);
            Assert.AreEqual(1000, (reshapeLine).Length);

            Linestring cutLinestring =
                GeometryConversionUtils.GetLinestring(GeometryUtils.GetPaths(reshapeLine).Single());

            Pnt3D midPoint = (Pnt3D)cutLinestring.GetPointAlong(0.5, true);

            List <Pnt3D> points = GeometryConversionUtils.GetPntList(reshapeLine);

            Assert.IsTrue(points.All(p => MathUtils.AreEqual(p.Z, 500.0)));

            //
            // Cutting - TargetZ
            //
            var applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.Target;

            ApplyCutLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            List <IGeometry> cutGeometries =
                applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            List <MultiPolycurve> multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                Line3D segment = multiPolycurve.FindSegments(midPoint, 0.001).First().Value;
                Assert.AreEqual(500, segment.StartPoint.Z);
                Assert.AreEqual(500, segment.EndPoint.Z);
            }

            //
            // Cutting - Interpolate
            //
            applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.InterpolatedSource;

            applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                List <Line3D> segments
                    = multiPolycurve.FindSegments(midPoint, 0.001)
                      .Select(kvp => kvp.Value).ToList();

                Assert.AreEqual(2, segments.Count);

                // Check if they are properly ordered and same length
                Assert.AreEqual(segments[0].EndPoint, segments[1].StartPoint);
                Assert.AreEqual(segments[0].Length2D, segments[1].Length2D);

                // Check if they are interpolated
                double average = (segments[0].StartPoint.Z + segments[1].EndPoint.Z) / 2;

                Assert.AreEqual(average, segments[0].EndPoint.Z);
            }

            //
            // Cutting - Plane
            //
            applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.SourcePlane;

            applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                bool?coplanar = ChangeAlongZUtils.AreCoplanar(
                    multiPolycurve.GetPoints().ToList(), sourcePlane,
                    0.01, out double _, out string _);

                Assert.IsTrue(coplanar);
            }
        }