コード例 #1
0
        public void CanCutMultipatchWithInnerRingThroughInnerRing()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            IPolygon originalPoly = GeometryFactory.CreatePolygon(
                GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 50, 50, lv95));

            IPolygon innerRingPoly = GeometryFactory.CreatePolygon(
                GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 10, 10, lv95));
            var innerRing = (IRing)((IGeometryCollection)innerRingPoly).Geometry[0];

            innerRing.ReverseOrientation();

            IMultiPatch multiPatch = GeometryFactory.CreateMultiPatch(originalPoly);

            GeometryFactory.AddRingToMultiPatch(innerRing, multiPatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchInnerRing);

            // cut line cuts through the inner ring
            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600000 - 100, 1200000),
                GeometryFactory.CreatePoint(2600000 + 100, 1200000));

            cutLine.SpatialReference = lv95;

            IFeature mockFeature = TestUtils.CreateMockFeature(multiPatch);

            var cutter = new FeatureCutter(new[] { mockFeature });

            cutter.ZSourceProvider =
                new DatasetSpecificSettingProvider <ChangeAlongZSource>(
                    string.Empty, ChangeAlongZSource.SourcePlane);

            cutter.Cut(cutLine);

            IList <IGeometry> results = cutter.ResultGeometriesByFeature[mockFeature];

            Assert.AreEqual(2, results.Count);

            double areaSum   = 0;
            var    partCount = 0;

            foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature])
            {
                Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result));

                areaSum +=
                    GeometryUtils.GetParts((IGeometryCollection)result)
                    .Sum(part => ((IArea)part).Area);

                partCount += GeometryUtils.GetParts((IGeometryCollection)result).Count();
            }

            Assert.AreEqual(2, partCount);

            Assert.AreEqual(((IArea)originalPoly).Area + ((IArea)innerRing).Area,
                            areaSum, 0.0001);
        }
コード例 #2
0
        private static void AddToMultipatch(IMultiPatch result, IPolygon poly,
                                            bool invert, int?pointId)
        {
            IList <IRing> exteriorRings;
            var           innerRings = GeometryUtils.GetRings(poly, out exteriorRings);

            Assert.AreEqual(1, exteriorRings.Count, "Unexpected ring count");

            IRing mainRing = exteriorRings[0];

            if (pointId != null)
            {
                GeometryUtils.AssignConstantPointID((IPointCollection)mainRing,
                                                    pointId.Value);
            }

            if (invert)
            {
                mainRing.ReverseOrientation();

                foreach (IRing innerRing in innerRings)
                {
                    innerRing.ReverseOrientation();
                }
            }

            GeometryFactory.AddRingToMultiPatch(
                mainRing, result, esriMultiPatchRingType.esriMultiPatchOuterRing);

            foreach (IRing innerRing in innerRings)
            {
                if (pointId != null)
                {
                    GeometryUtils.AssignConstantPointID((IPointCollection)innerRing,
                                                        pointId.Value);
                }

                GeometryFactory.AddRingToMultiPatch(
                    innerRing, result,
                    esriMultiPatchRingType.esriMultiPatchInnerRing);
            }
        }
コード例 #3
0
        private IMultiPatch ReadMultipatch(BinaryReader reader,
                                           Ordinates expectedOrdinates,
                                           bool groupPartsByPointIDs = false)
        {
            IMultiPatch result = new MultiPatchClass();

            if (groupPartsByPointIDs)
            {
                GeometryUtils.MakePointIDAware(result);
            }

            int polyhedraCount = checked ((int)reader.ReadUInt32());

            for (int i = 0; i < polyhedraCount; i++)
            {
                WkbGeometryType geometryType;
                Ordinates       ordinates;
                ReadWkbType(reader, false,
                            out geometryType, out ordinates);

                Assert.AreEqual(WkbGeometryType.PolyhedralSurface, geometryType,
                                "Unexpected geometry type");

                Assert.AreEqual(expectedOrdinates, ordinates,
                                "Unexpected ordinates dimension");

                int polygonCount = checked ((int)reader.ReadUInt32());

                for (int p = 0; p < polygonCount; p++)
                {
                    ReadWkbType(reader, false,
                                out geometryType, out expectedOrdinates);

                    Assert.AreEqual(WkbGeometryType.Polygon, geometryType,
                                    "Unexpected geometry type");

                    var rings = ReadSingleExteriorRingPolygon(reader, ordinates, false).ToList();

                    if (rings.Count == 0)
                    {
                        continue;
                    }

                    if (groupPartsByPointIDs)
                    {
                        AssignPointIds(rings, i);
                    }

                    var outerRingType = rings.Count > 1
                                                                    ? esriMultiPatchRingType.esriMultiPatchOuterRing
                                                                    : p == 0 || groupPartsByPointIDs
                                                                            ? esriMultiPatchRingType.esriMultiPatchFirstRing
                                                                            : esriMultiPatchRingType.esriMultiPatchRing;

                    IRing outerRing = rings[0];
                    GeometryFactory.AddRingToMultiPatch(outerRing, result, outerRingType);

                    if (rings.Count > 1)
                    {
                        for (int r = 1; r < rings.Count; r++)
                        {
                            IRing innerRing = rings[r];
                            GeometryFactory.AddRingToMultiPatch(
                                innerRing, result, esriMultiPatchRingType.esriMultiPatchInnerRing);
                        }
                    }
                }
            }

            return(result);
        }
コード例 #4
0
        public void CannotPerformVerticalReshapeOnFlatRing()
        {
            // Originally this geometry resulted in an endless loop because
            // IntersectionUtils.IntersectNonPlanar returned the incorrect result
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            // The problem cannot be reproduced with standard resolution
            var srResolution = (ISpatialReferenceResolution)lv95;

            srResolution.set_XYResolution(true, 0.001);

            var srTolerance = (ISpatialReferenceTolerance)lv95;

            srTolerance.XYTolerance = 0.01;

            // Vertical triangle, oriented towards the south:
            var points = new WKSPointZ[6];

            points[0] = new WKSPointZ
            {
                X = 2578309.3000000007,
                Y = 1183264.3999999985,
                Z = 619.14500000000407
            };

            points[1] = new WKSPointZ
            {
                X = 2578295.6829999983,
                Y = 1183260.568,
                Z = 619.14500000000407
            };

            points[2] = new WKSPointZ
            {
                X = 2578293.9990000017,
                Y = 1183266.5500000007,
                Z = 619.14500000000407
            };

            points[3] = new WKSPointZ
            {
                X = 2578295.9070000015,
                Y = 1183267.1559999995,
                Z = 619.14500000000407
            };

            points[4] = new WKSPointZ
            {
                X = 2578307.5989999995,
                Y = 1183270.4450000003,
                Z = 619.14500000000407
            };

            points[5] = new WKSPointZ
            {
                X = 2578309.3000000007,
                Y = 1183264.3999999985,
                Z = 619.14500000000407
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2578314.9090000018, 1183246.2400000021),
                GeometryFactory.CreatePoint(2578307.4299999997, 1183270.4310000017));

            cutLine.SpatialReference = lv95;

            //GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null);

            IList <IPath> verticalPaths;

            Assert.IsFalse(reshapeInfo.IsVerticalRingReshape(0, out verticalPaths));

            Assert.AreEqual(0, verticalPaths.Count);

            Assert.IsTrue(ReshapeUtils.ReshapeGeometry(reshapeInfo, reshapePath));

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(6, ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);
        }
コード例 #5
0
        public void CanReshapeVerticalRingWithMutipleReshapeLineCrossings()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            // Vertical triangle, oriented towards the south:
            var points = new WKSPointZ[4];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600075, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600075, 1200000 + 100, 222),
                GeometryFactory.CreatePoint(2600025, 1200000 + 100, 222),
                GeometryFactory.CreatePoint(2600025, 1200000 - 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null);

            IList <IPath> verticalPaths;

            Assert.IsTrue(reshapeInfo.IsVerticalRingReshape(0, out verticalPaths));

            Assert.AreEqual(2, verticalPaths.Count);

            // Currently it is the caller's responsability to make 2 different reshapes using the desired side...

            // We want the middle part:

            // verticalPaths[0] is the one at X=2600025
            var reshape1 = new ReshapeInfo(multipatch, verticalPaths[0], null);

            reshape1.RingReshapeSide = RingReshapeSideOfLine.Right;
            reshape1.NonPlanar       = true;

            ReshapeUtils.ReshapeGeometry(reshape1, verticalPaths[0]);

            // verticalPaths[1] is the one at X=2600075
            var reshape2 = new ReshapeInfo(multipatch, verticalPaths[1], null);

            reshape2.RingReshapeSide = RingReshapeSideOfLine.Left;
            reshape2.NonPlanar       = true;

            ReshapeUtils.ReshapeGeometry(reshape2, verticalPaths[1]);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(6, ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            double expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 1.0 + 50 + 2 * 250;

            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            var newPoints = new WKSPointZ[6];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600025,
                Y = 1200000,
                Z = 500
            }, newPoints[0], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            }, newPoints[3], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600025,
                Y = 1200000,
                Z = 750
            }, newPoints[4], 0, 0));
        }
コード例 #6
0
        public void CanReshapeVerticalTriangularRingInMultipatch()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            //IRing ring = GeometryFactory.CreateRing(
            //	GeometryFactory.CreatePath())
            var points = new WKSPointZ[4];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            int originalPointCount = ((IPointCollection)unReshaped).PointCount;

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600075, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600075, 1200000 + 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            IList <ReshapeInfo> singleReshapes;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(originalPointCount + 1,
                            ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            double expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 1.5 + 75 + 250;

            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            var newPoints = new WKSPointZ[5];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            // first, fourth and last
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[0], newPoints[0], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[2], newPoints[3], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[3], newPoints[4], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            // And now reshape right through the vertex at the top, this time reshape the left
            cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600050, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600050, 1200000 + 100, 222));
            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            // keep the right (small part)
            reshapeInfo.RingReshapeSide = RingReshapeSideOfLine.Right;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(5, ((IPointCollection)reshapedRing).PointCount);
            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 0.5 + 25 + 500 + 250;
            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            newPoints = new WKSPointZ[5];
            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 500
            }, newPoints[0], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            }, newPoints[3], 0, 0));
        }
コード例 #7
0
        public void CanReshapeVerticalSquareRingInMultipatch()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            //IRing ring = GeometryFactory.CreateRing(
            //	GeometryFactory.CreatePath())
            var points = new WKSPointZ[5];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 1000
            };

            points[4] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            int originalPointCount = ((IPointCollection)unReshaped).PointCount;

            // Left reshape is slightly larger -> vertical reshape side is determined by size only
            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600051, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600051, 1200000 + 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            IList <ReshapeInfo> singleReshapes;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(originalPointCount,
                            ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);
            Assert.AreEqual(2 * 500 + 2 * 51, ((ICurve3D)reshapedRing).Length3D);

            var newPoints = new WKSPointZ[5];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            // first, fourth and last
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[0], newPoints[0], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[3], newPoints[3], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[4], newPoints[4], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600051,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600051,
                Y = 1200000,
                Z = 1000
            }, newPoints[2], 0, 0));
        }