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); }
private static FeatureCutter CreateFeatureCutter([NotNull] ApplyCutLinesRequest request, out IList <IFeature> targetFeatures) { GetFeatures(request.CalculationRequest.SourceFeatures, request.CalculationRequest.TargetFeatures, request.CalculationRequest.ClassDefinitions, out IList <IFeature> sourceFeatures, out targetFeatures); ChangeAlongZSource zSource = (ChangeAlongZSource)request.ChangedVerticesZSource; DatasetSpecificSettingProvider <ChangeAlongZSource> zSourceProvider = new DatasetSpecificSettingProvider <ChangeAlongZSource>( "Z values for changed vertices", zSource); var cutter = new FeatureCutter(sourceFeatures) { ZSourceProvider = zSourceProvider }; if (request.InsertVerticesInTarget) { cutter.TargetFeatures = targetFeatures; } return(cutter); }
public void CanCutPolygonWithCorrectZ_Top4666() { // Tests the work-around for TOP-4666 // TODO: Report ArcObjects bug to Esri Inc. IFeature polygonFeature = TestUtils.CreateMockFeature("PolygonTop4666.xml"); var cutLine = (IPolyline) TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath("CutLineTop4666.xml")); GeometryUtils.EnsureSpatialReference( cutLine, polygonFeature.Shape.SpatialReference); var cutter = new FeatureCutter(new[] { polygonFeature }); Stopwatch watch = Stopwatch.StartNew(); cutter.Cut(cutLine); watch.Stop(); Console.WriteLine("Cut large feature: {0}ms", watch.ElapsedMilliseconds); Assert.AreEqual(5, cutter.ResultGeometriesByFeature[polygonFeature].Count); foreach (IGeometry geometry in cutter.ResultGeometriesByFeature[ polygonFeature]) { var polygon = (IPolygon)geometry; Assert.False(GeometryUtils.HasUndefinedZValues(polygon)); GeometryUtils.Simplify(polygon); Assert.False(GeometryUtils.HasUndefinedZValues(polygon)); foreach (IPoint point in GeometryUtils.GetPoints( (IPointCollection)polygon)) { Assert.AreNotEqual(0, point.Z); } IPolyline resultAsPolyline = GeometryFactory.CreatePolyline(polygon); IPolyline zDifference = ReshapeUtils.GetZOnlyDifference(resultAsPolyline, cutLine); // ArcObjects uses the cutLine's Z also at the intersection points. // Do the same in CustomIntersect? Assert.IsNull(zDifference); } }
public void CanCutMultipatchWithSelfIntersectingSketch() { // {FE286920-3D4C-4CB3-AC22-51056B97A23F} from TLM: IFeature mockFeature = TestUtils.CreateMockFeature("MultipatchWithVerticalWalls.xml"); ISpatialReference lv95 = mockFeature.Shape.SpatialReference; // Use case: snap inside the multipatch in order to create a sketch segment along an existing multipatch segment to cut along, // then use F7 (segment deflection) with deflection 0 to prolong the sketch line to make sure it cuts across the entire multipatch. // NOTE: The non-simple intersect output can only be reproduced with these real-world coordinates / snapped to storage SR it would work ok // Fix: simplify IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2574913.26117225, 1196875.8438835, lv95), GeometryFactory.CreatePoint(2574917.7921709, 1196878.12591931, lv95), GeometryFactory.CreatePoint(2574908.14863447, 1196873.26895571, lv95), GeometryFactory.CreatePoint(2574922.05492981, 1196880.27285628, lv95)); double originalArea = ((IArea3D)mockFeature.Shape).Area3D; 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 totalParts = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); totalParts += ((IGeometryCollection)result).GeometryCount; areaSum += ((IArea3D)result).Area3D; } Assert.AreEqual(6, totalParts); const double epsilon = 0.0001; Assert.IsTrue(MathUtils.AreEqual(originalArea, areaSum, epsilon)); }
public static ApplyCutLinesResponse ApplyCutLines( [NotNull] ApplyCutLinesRequest request, [CanBeNull] ITrackCancel trackCancel) { IList <CutSubcurve> cutCurves = request.CutLines.Select(FromReshapeLineMsg).ToList(); FeatureCutter cutter = CreateFeatureCutter(request, out IList <IFeature> targetFeatures); cutter.Cut(cutCurves); List <IFeature> storedFeatures = new List <IFeature>(); var response = new ApplyCutLinesResponse(); if (cutter.ResultGeometriesByFeature.Count > 0) { cutter.StoreResultFeatures(storedFeatures); cutter.LogSuccessfulCut(); ICollection <KeyValuePair <IFeature, IList <IFeature> > > insertsByOriginal = cutter.InsertedFeaturesByOriginal; IList <ResultObjectMsg> ResultObjectMsgs = GetResultFeatureMessages(insertsByOriginal, storedFeatures); response.ResultFeatures.AddRange(ResultObjectMsgs); // Calculate the new cut lines: List <IFeature> newSourceFeatures = new List <IFeature>(cutter.SourceFeatures); newSourceFeatures.AddRange( insertsByOriginal.SelectMany(kvp => kvp.Value)); var newSubcurves = CalculateCutLines(newSourceFeatures, targetFeatures, request.CalculationRequest, trackCancel, out ReshapeAlongCurveUsability usability); response.CutLinesUsability = (int)usability; response.NewCutLines.AddRange(newSubcurves.Select(ToReshapeLineMsg)); return(response); } _msg.WarnFormat("The selection was not cut. Please select the lines to cut along"); return(response); }
public void CanCutMultipatchWithVerticalWalls() { // {FE286920-3D4C-4CB3-AC22-51056B97A23F} from TLM: IFeature mockFeature = TestUtils.CreateMockFeature("MultipatchWithVerticalWalls.xml"); ISpatialReference lv95 = mockFeature.Shape.SpatialReference; IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2574909.000, 1196870.000, lv95), GeometryFactory.CreatePoint(2574924.000, 1196878.000, lv95)); double originalArea = ((IArea)mockFeature.Shape).Area; double originalPartAreaSum = GeometryUtils.GetParts((IGeometryCollection)mockFeature.Shape) .Sum(part => ((IArea)part).Area); 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; double partAreaSum = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); Assert.AreEqual(3, ((IGeometryCollection)result).GeometryCount); areaSum += ((IArea)result).Area; partAreaSum += GeometryUtils.GetParts((IGeometryCollection)result) .Sum(part => ((IArea)part).Area); } // The sum of all parts is not the same because some rings have negative orientation Assert.AreEqual(originalArea, areaSum, 0.01); Assert.AreEqual(originalPartAreaSum, partAreaSum, 0.01); }
public void CanCutMultipatchWithVerticalWallsThroughVerticalWallsSnapped() { // {FE286920-3D4C-4CB3-AC22-51056B97A23F} from TLM: IFeature mockFeature = TestUtils.CreateMockFeature("MultipatchWithVerticalWalls.xml"); ISpatialReference lv95 = mockFeature.Shape.SpatialReference; IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2574923.000, 1196869.000, lv95), GeometryFactory.CreatePoint(2574912.000, 1196885.000, lv95)); IPolygon origFootprint = GeometryFactory.CreatePolygon(mockFeature.Shape); cutLine = IntersectionUtils.GetIntersectionLines( cutLine, origFootprint, true, true); double originalArea = ((IArea3D)mockFeature.Shape).Area3D; 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 totalParts = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); totalParts += ((IGeometryCollection)result).GeometryCount; areaSum += ((IArea3D)result).Area3D; } Assert.AreEqual(7, totalParts); Assert.IsTrue(MathUtils.AreEqual(originalArea, areaSum, 0.01)); }
public void CanCutMultipatchWithCutBackAtBottomRight() { // TOP-5226 // This case has a cut-back (duplicate segment) at the bottom right due to TOP-5227 // (Cracker creates cut-back for pointy angles and a vertex within the crack tolerance) IFeature mockFeature = TestUtils.CreateMockFeature("MultipatchWithCutBack.xml"); IPolyline cutLine = (IPolyline)TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath("MultipatchWithCutBackCutLine.xml")); double originalArea = ((IArea3D)mockFeature.Shape).Area3D; 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 totalParts = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); totalParts += ((IGeometryCollection)result).GeometryCount; areaSum += ((IArea3D)result).Area3D; } Assert.AreEqual(2, totalParts); // why is this so inaccurate??? const double epsilon = 2.2; Assert.IsTrue(MathUtils.AreEqual(originalArea, areaSum, epsilon)); }
public void CanCutMultipatchThroughVerticalWall_Top5022b() { // {5C8388FB-9A00-4AF4-BB0D-D120C8BDA88D} only the northern dormer window: IFeature mockFeature = TestUtils.CreateMockFeature("TOP5022b_MultipatchToCut.xml"); ISpatialReference lv95 = mockFeature.Shape.SpatialReference; IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2694073.141, 1263073.24, 408.781000000003), GeometryFactory.CreatePoint(2694073.91, 1263036.271, 408.781000000003)); cutLine.SpatialReference = lv95; double originalArea = ((IArea3D)mockFeature.Shape).Area3D; 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 totalParts = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); totalParts += ((IGeometryCollection)result).GeometryCount; areaSum += ((IArea3D)result).Area3D; } Assert.AreEqual(7, totalParts); Assert.IsTrue(MathUtils.AreEqual(originalArea, areaSum, 0.01)); }
public void CanCutMultipatch() { ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95); IPolygon originalPoly = GeometryFactory.CreatePolygon( GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 50, 20, lv95)); IMultiPatch multiPatch = GeometryFactory.CreateMultiPatch(originalPoly); 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; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); areaSum += GeometryUtils.GetParts((IGeometryCollection)result) .Sum(part => ((IArea)part).Area); } Assert.IsTrue(MathUtils.AreEqual(((IArea)originalPoly).Area, areaSum)); }
public void CanCutMultipatchThroughVerticalWall_Top5022a() { // {4286CCE0-4539-4D91-B14B-1C3D79640021} from TLM: IFeature mockFeature = TestUtils.CreateMockFeature("TOP5022a_MultipatchToCut.xml"); ISpatialReference lv95 = mockFeature.Shape.SpatialReference; IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2694016.709, 1263646, lv95), GeometryFactory.CreatePoint(2694025, 1263657, lv95)); double originalArea = ((IArea3D)mockFeature.Shape).Area3D; 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 totalParts = 0; foreach (IGeometry result in cutter.ResultGeometriesByFeature[mockFeature]) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); totalParts += ((IGeometryCollection)result).GeometryCount; areaSum += ((IArea3D)result).Area3D; } Assert.AreEqual(6, totalParts); Assert.IsTrue(MathUtils.AreEqual(originalArea, areaSum, 0.01)); }
public void CanCutMultipartPolyline() { ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95); IPath path1 = GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600000, 1200000, lv95), GeometryFactory.CreatePoint(2600010, 1200000, lv95)); IPath path2 = GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600000, 1200002, lv95), GeometryFactory.CreatePoint(2600010, 1200002, lv95)); ICollection <IPath> pathCollection = new List <IPath> { path1, path2 }; IPolyline multipartPolyline = GeometryFactory.CreatePolyline( pathCollection, lv95); // cuts the lower path and assigns the western part to the original feature IPolyline cutOnePartLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2600006, 1200000), GeometryFactory.CreatePoint(2600006, 1200001)); cutOnePartLine.SpatialReference = lv95; IFeature mockFeature = TestUtils.CreateMockFeature(multipartPolyline); var cutter = new FeatureCutter(new[] { mockFeature }); cutter.Cut(cutOnePartLine); IList <IGeometry> results = cutter.ResultGeometriesByFeature[mockFeature]; Assert.AreEqual(2, results.Count); double sizeSum = 0; foreach (IGeometry result in results) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); sizeSum += GeometryUtils.GetParts((IGeometryCollection)result) .Sum(part => ((ICurve)part).Length); } Assert.IsTrue( MathUtils.AreEqual(((ICurve)multipartPolyline).Length, sizeSum)); // cuts both remaining parts into 4 pieces // Consider re-joining the parts at the left of the line and those at the right // But this logic would also have to be applied for polygons and should probably be optional IPolyline cutBothPartsLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2600004, 1200000), GeometryFactory.CreatePoint(2600004, 1200002)); cutBothPartsLine.SpatialReference = lv95; // the largest ist the first mockFeature.Shape = results[0]; cutter = new FeatureCutter(new[] { mockFeature }); cutter.Cut(cutBothPartsLine); results = cutter.ResultGeometriesByFeature[mockFeature]; Assert.AreEqual(2, results.Count); sizeSum = 0; foreach (IGeometry result in results) { Assert.IsFalse(GeometryUtils.HasUndefinedZValues(result)); sizeSum += GeometryUtils.GetParts((IGeometryCollection)result) .Sum(part => ((ICurve)part).Length); } Assert.IsTrue( MathUtils.AreEqual(((ICurve)mockFeature.Shape).Length, sizeSum)); }
public void CanCutMultipatchResultingInDegenerateMultipatchFootprint_Top5258() { // Degenerate result multipatch: IFeature mockFeature = TestUtils.CreateMockFeature( "MultipatchCutResultWithDegenerateFootprint_Source.xml"); IPolyline cutLine = (IPolyline)TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath( "MultipatchCutResultWithDegenerateFootprint_Target.xml")); var cutter = new FeatureCutter(new[] { mockFeature }) { DegenerateMultipatchFootprintAction = DegenerateMultipatchFootprintAction.Discard }; cutter.Cut(cutLine); IList <IGeometry> results = cutter.ResultGeometriesByFeature[mockFeature]; Assert.AreEqual(1, results.Count); cutter = new FeatureCutter(new[] { mockFeature }) { DegenerateMultipatchFootprintAction = DegenerateMultipatchFootprintAction.Keep }; cutter.Cut(cutLine); results = cutter.ResultGeometriesByFeature[mockFeature]; Assert.AreEqual(2, results.Count); cutter = new FeatureCutter(new[] { mockFeature }) { DegenerateMultipatchFootprintAction = DegenerateMultipatchFootprintAction.Throw }; Assert.Throws <DegenerateResultGeometryException>(() => cutter.Cut(cutLine)); // // Clear case of TOP-5258: mockFeature = TestUtils.CreateMockFeature( "MultipatchCutResultWithOkFootprint_Source.xml"); cutLine = (IPolyline)TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath( "MultipatchCutResultWithOkFootprint_Target.xml")); cutter = new FeatureCutter(new[] { mockFeature }) { DegenerateMultipatchFootprintAction = DegenerateMultipatchFootprintAction.Throw }; cutter.Cut(cutLine); results = cutter.ResultGeometriesByFeature[mockFeature]; Assert.AreEqual(2, results.Count); // // Unclear case of TOP-5258: (depends on tolerance, fuzzy!) // Probably the sqare footprint check should be done after assigning the storage SR mockFeature = TestUtils.CreateMockFeature( "MultipatchCutResultWithBorderlineFootprint_Source.xml"); cutLine = (IPolyline)TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath( "MultipatchCutResultWithBorderlineFootprint_Target.xml")); // Currently it throws, but in ArcMap the footprint is not square!?! cutter = new FeatureCutter(new[] { mockFeature }) { DegenerateMultipatchFootprintAction = DegenerateMultipatchFootprintAction.Throw }; Assert.Throws <DegenerateResultGeometryException>(() => cutter.Cut(cutLine)); }
public void CannotCutMultipatchWithTriangleStrip() { // To support triangles, triangle fans, etc.: // Consider implementing a completely different approach: // Go through points, determine for each point if it is on the left or right side of the cut line (above or below for vertical surfaces) // If the side changes, use intersection point to finish the strip on the one side and to start the strip on the other. ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95); object missing = Type.Missing; IMultiPatch multiPatch = new MultiPatchClass(); IPointCollection newStrip = new TriangleStripClass(); newStrip.AddPoint(GeometryFactory.CreatePoint(2600000, 1200000, 500), ref missing, ref missing); newStrip.AddPoint(GeometryFactory.CreatePoint(2600002, 1200000, 550), ref missing, ref missing); newStrip.AddPoint(GeometryFactory.CreatePoint(2600002, 1200002, 550), ref missing, ref missing); ((IGeometryCollection)multiPatch).AddGeometry( (IGeometry)newStrip, ref missing, ref missing); multiPatch.SpatialReference = lv95; GeometryUtils.MakeZAware(multiPatch); IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2600000, 1200001), GeometryFactory.CreatePoint(2600002, 1200001)); cutLine.SpatialReference = lv95; IFeature mockFeature = TestUtils.CreateMockFeature(multiPatch); var cutter = new FeatureCutter(new[] { mockFeature }); Exception assertionException = null; try { cutter.Cut(cutLine); } catch (Exception e) { assertionException = e; } Assert.NotNull(assertionException); // Once it is implemented: //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); }