private static bool PathRunsAlongTwoPolygons([NotNull] IPath path, [NotNull] IList <IGeometry> polygons) { // For a potential performance improvement, see StickyIntersections var touchCount = 0; IGeometry highLevelPath = GeometryUtils.GetHighLevelGeometry(path, true); // it's a bag of polygons foreach (IGeometry polygon in polygons) { if (GeometryUtils.Touches(highLevelPath, polygon)) { // filter out those that only touch in the start point and do not run along the boundary IPolyline outline = GeometryFactory.CreatePolyline(polygon); IPolyline lineAlongBoundary = IntersectionUtils.GetIntersectionLines( outline, (IPolycurve)highLevelPath, true, true); if (!lineAlongBoundary.IsEmpty) { touchCount++; if (touchCount == 2) { return(true); } } } } return(false); }
private static bool IsPathFullyCovered( [NotNull] IPath path, [NotNull] IPolygon insideSourcePolygon, [NotNull] IEnumerable <CutSubcurve> bySubCurves) { IPolyline classicCurvesPolyline = GeometryFactory.CreateEmptyPolyline(path); object missing = Type.Missing; foreach (IPath classicCurve in bySubCurves.Select( cutSubcurve => cutSubcurve.Path)) { ((IGeometryCollection)classicCurvesPolyline).AddGeometry(classicCurve, ref missing, ref missing); } IGeometry highLevelPath = GeometryUtils.GetHighLevelGeometry(path); IGeometry highLevelPathInside = IntersectionUtils.GetIntersectionLines( (IPolyline)highLevelPath, insideSourcePolygon, true, true); IGeometry difference = ReshapeUtils.GetDifferencePolyline( (IPolyline)highLevelPathInside, classicCurvesPolyline); // Test: Simplify required? return(difference.IsEmpty); }
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)); }
private static bool PathRunsAlongSeveralPolygons( [NotNull] IPath path, [NotNull] IList <IGeometry> allPolygons, [NotNull] IPoint startingAt, out IList <IGeometry> alongPolygons) { alongPolygons = new List <IGeometry>(allPolygons.Count); var touchCount = 0; IGeometry highLevelPath = GeometryUtils.GetHighLevelGeometry(path, true); foreach (IGeometry polygon in allPolygons) { // NOTE: Using GeometryUtils.Touches and Intersection of highLevelPath with polygon is very slow! // -> extract only the relevant segments IPolyline polygonOutlinePart = TryGetAdjacentSegmentsAsPolyline( (IPolygon)polygon, startingAt); if (polygonOutlinePart == null || polygonOutlinePart.IsEmpty) { continue; } IPolyline lineAlongBoundary = IntersectionUtils.GetIntersectionLines( polygonOutlinePart, (IPolycurve)highLevelPath, true, true); if (!lineAlongBoundary.IsEmpty) { touchCount++; alongPolygons.Add(polygon); } Marshal.ReleaseComObject(polygonOutlinePart); Marshal.ReleaseComObject(lineAlongBoundary); } Marshal.ReleaseComObject(highLevelPath); return(touchCount > 1); }
private static IPolyline GetCutLine(IMultiPatch sourceMultipatch, IPolygon overlappingPolygon) { IPolygon sourceFootprint = GeometryFactory.CreatePolygon(sourceMultipatch); IPolyline sourceFootprintBoundary = GeometryFactory.CreatePolyline(sourceFootprint); IPolyline overlappingPolygonBoundary = GeometryFactory.CreatePolyline(overlappingPolygon); const bool assumeIntersecting = true; const bool allowRandomStartPointsForClosedIntersections = true; IPolyline intersectionLines = IntersectionUtils.GetIntersectionLines( sourceFootprint, overlappingPolygonBoundary, assumeIntersecting, allowRandomStartPointsForClosedIntersections); // the intersectionLines also run along the boundary, but we only want the interior intersections var interiorIntersection = (IPolyline)IntersectionUtils.Difference( intersectionLines, sourceFootprintBoundary); return(interiorIntersection); }