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); }
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)); }