/// <summary> /// Gets the intersection points (also including linear intersection end points) between crossingLine crosses the /// and polycurveToCross excluding start and end point of the crossingLine. This is not the same as interior intersection. /// </summary> /// <param name="crossingLine"></param> /// <param name="polycurveToCross"></param> /// <returns></returns> private static IPointCollection GetCrossingPoints([NotNull] ICurve crossingLine, [NotNull] IGeometry polycurveToCross) { // TODO: extracted from GetCrossingPointCount (various copies) -> move to ReshapeUtils IGeometry highLevelCrossingLine = GeometryUtils.GetHighLevelGeometry(crossingLine); // NOTE: IRelationalOperator.Crosses() does not find cases where the start point is tangential and // neither it finds cases where there is also a 1-dimensional intersection in addition to a point-intersection // NOTE: use GeometryUtils.GetIntersectionPoints to find also these cases where some intersections are 1-dimensional var intersectionPoints = (IPointCollection) IntersectionUtils.GetIntersectionPoints(polycurveToCross, highLevelCrossingLine); // count the points excluding start and end point of the crossing line var result = (IPointCollection)GeometryFactory.CreateEmptyMultipoint(polycurveToCross); foreach (IPoint point in GeometryUtils.GetPoints(intersectionPoints)) { if (GeometryUtils.AreEqualInXY(point, crossingLine.FromPoint) || GeometryUtils.AreEqualInXY(point, crossingLine.ToPoint)) { continue; } result.AddPoint(point); } return(result); }
private IMultipoint CalculateSourceIntersections( [NotNull] IEnumerable <IPolycurve> sourceGeometries) { IMultipoint sourceIntersectionPoints = null; IPolyline sourceIntersectionLines = null; foreach ( KeyValuePair <IPolycurve, IPolycurve> pair in CollectionUtils.GetAllTuples(sourceGeometries)) { IPolycurve polycurve1 = pair.Key; IPolycurve polycurve2 = pair.Value; IPolyline intersectionLines = GeometryFactory.CreateEmptyPolyline(polycurve1); IMultipoint intersectionPoints = IntersectionUtils.GetIntersectionPoints( polycurve1, polycurve2, false, IntersectionPointOptions.IncludeLinearIntersectionEndpoints, intersectionLines); if (sourceIntersectionPoints == null) { sourceIntersectionPoints = intersectionPoints; } else { ((IPointCollection)sourceIntersectionPoints).AddPointCollection( (IPointCollection)intersectionPoints); } if (intersectionLines != null && !intersectionLines.IsEmpty) { if (sourceIntersectionLines == null) { sourceIntersectionLines = intersectionLines; } else { ((IGeometryCollection)sourceIntersectionLines).AddGeometryCollection( (IGeometryCollection)intersectionLines); } } } Assert.NotNull(sourceIntersectionPoints); GeometryUtils.Simplify(sourceIntersectionPoints); // un-simplified! _sourceIntersectionLines = sourceIntersectionLines; return(sourceIntersectionPoints); }
private static IPath GetSharedBoundaryProlongation([NotNull] ICurve curveToReshape, [NotNull] IPath sourceReplacementPath, bool atSourceReplacementFromPoint, [NotNull] IPath reshapePath, double tolerance, out IPoint targetConnectPoint) { IPoint sourceConnectPoint = atSourceReplacementFromPoint ? sourceReplacementPath.FromPoint : sourceReplacementPath.ToPoint; // try elongate the curveToReshape's last segment that's not part of the replacement path ISegment sourceSegment = GetConnectSegment(sourceReplacementPath, curveToReshape, sourceConnectPoint, tolerance); IPath result = ReshapeUtils.GetProlongation(curveToReshape, sourceSegment, reshapePath, out targetConnectPoint); if (result == null) { // check if the reshape path intersects the source segment: IGeometry highLevelSourceSegment = GeometryUtils.GetHighLevelGeometry(sourceSegment, true); IGeometry highLevelReshapePath = GeometryUtils.GetHighLevelGeometry(reshapePath, true); var intersectionPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( highLevelReshapePath, highLevelSourceSegment, false); if (intersectionPoints.PointCount == 1) { result = CreateSinglePointPath(intersectionPoints.Point[0]); targetConnectPoint = intersectionPoints.Point[0]; } else { _msg.DebugFormat( "The source last shared segment has {0} intersection points with the reshape path. Currently not supported", intersectionPoints.PointCount); } } return(result); }
/// <summary> /// Gets the number of times the crossingLine crosses the polylineToCross excluding start and end point /// of the crossingLine. This is not the same as interior-intersects. /// </summary> /// <param name="crossingLine"></param> /// <param name="polylineToCross"></param> /// <returns></returns> private static int GetCrossingPointCount([NotNull] ICurve crossingLine, [NotNull] IPolyline polylineToCross) { // TODO: copy from ConnectLineCalculatorBase -> move to ReshapeUtils IGeometry highLevelCrossingLine = GeometryUtils.GetHighLevelGeometry(crossingLine, true); // NOTE: IRelationalOperator.Crosses() does not find cases where the start point is tangential and // neither it finds cases where there is also a 1-dimensional intersection in addition to a point-intersection // NOTE: use GeometryUtils.GetIntersectionPoints to find also these cases where some intersections are 1-dimensional var intersectionPoints = (IPointCollection) IntersectionUtils.GetIntersectionPoints(polylineToCross, highLevelCrossingLine); // count the points excluding start and end point of the crossing line var crossingPointCount = 0; for (var i = 0; i < intersectionPoints.PointCount; i++) { intersectionPoints.QueryPoint(i, _pointTemplate); if (GeometryUtils.AreEqualInXY(_pointTemplate, crossingLine.FromPoint) || GeometryUtils.AreEqualInXY(_pointTemplate, crossingLine.ToPoint)) { continue; } crossingPointCount++; } if (crossingPointCount > 0 && _msg.IsVerboseDebugEnabled) { _msg.DebugFormat( "Intersections between crossing line {0} and polylineToCross: {1}", GeometryUtils.ToString(crossingLine), GeometryUtils.ToString((IMultipoint)intersectionPoints)); } if (highLevelCrossingLine != crossingLine) { Marshal.ReleaseComObject(highLevelCrossingLine); } return(crossingPointCount); }
private static IPointCollection GetFilteredPoints(IPointCollection inputPoints, IGeometry subSelectionPerimeter) { IPointCollection resultPoints; if (subSelectionPerimeter == null) { resultPoints = (IPointCollection)GeometryFactory.Clone((IGeometry)inputPoints); } else { resultPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( subSelectionPerimeter, (IGeometry)inputPoints); } return(resultPoints); }
private static IPath TrimCutLine([NotNull] IPath cutLine, [NotNull] IPolygon originalPolygon, [NotNull] IList <IGeometry> cutGeometries) { var intersectionPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( (IPolyline)GeometryUtils.GetHighLevelGeometry(cutLine), originalPolygon, true, IntersectionPointOptions.IncludeLinearIntersectionEndpoints); double tolerance = GeometryUtils.GetXyTolerance(originalPolygon); var highLevelPath = (IPolyline)GeometryUtils.GetHighLevelGeometry(cutLine); List <KeyValuePair <IPoint, double> > orderedIntersections = GeometryUtils.GetDistancesAlongPolycurve( intersectionPoints, highLevelPath, tolerance, false); // ascending sort order orderedIntersections.Sort((x, y) => x.Value.CompareTo(y.Value)); double fromDistance = GetFirstIntersectionTouchingTwoGeometries( orderedIntersections, cutGeometries); orderedIntersections.Reverse(); double toDistance = GetFirstIntersectionTouchingTwoGeometries( orderedIntersections, cutGeometries); ICurve result; if (fromDistance >= 0 && toDistance >= 0) { cutLine.GetSubcurve(fromDistance, toDistance, false, out result); } else { result = cutLine; } return((IPath)result); }
protected IPolyline RemoveVerticesBeyondBarrier([NotNull] IPolyline originalPolyline, [NotNull] IPolyline polylineWithUpdatedEnd, [NotNull] IPoint newEndPoint, bool newEndAtFromPoint) { var intersectionPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( originalPolyline, BarrierGeometryChanged, true, IntersectionPointOptions.IncludeLinearIntersectionEndpoints); if (intersectionPoints.PointCount != 0) { IPolyline cracked = GeometryFactory.Clone(polylineWithUpdatedEnd); const bool createParts = true; const bool projectPointsOntoPathToSplit = true; GeometryUtils.CrackPolycurve(cracked, intersectionPoints, projectPointsOntoPathToSplit, createParts); IPoint unChangedPoint = newEndAtFromPoint ? polylineWithUpdatedEnd.ToPoint : polylineWithUpdatedEnd.FromPoint; foreach (IPath subCurve in GeometryUtils.GetPaths(cracked)) { var highLevelSubCurve = (IPolyline)GeometryUtils.GetHighLevelGeometry(subCurve, true); if (GeometryUtils.Intersects(highLevelSubCurve, unChangedPoint)) { // re-apply the end point - this could still result in bbarrier crossings, but only on the last segment SetEndpoint(highLevelSubCurve, newEndPoint, newEndAtFromPoint); polylineWithUpdatedEnd = highLevelSubCurve; break; } } } return(polylineWithUpdatedEnd); }
public static IMultipoint GetInvalidIntersections( [NotNull] IPolyline polyline1, [NotNull] IPolyline polyline2, AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, AllowedLineInteriorIntersections allowedLineInteriorIntersections, bool reportOverlaps, double vertexSearchDistance) { Assert.ArgumentNotNull(polyline1, nameof(polyline1)); Assert.ArgumentNotNull(polyline2, nameof(polyline2)); IntersectionPointOptions intersectionPointOptions = reportOverlaps ? IntersectionPointOptions.IncludeLinearIntersectionEndpoints : IntersectionPointOptions.DisregardLinearIntersections; // NOTE: this does not reliably find endpoint/interior intersections -> empty!! (even if Disjoint does return false) const bool assumeIntersecting = true; IMultipoint intersections = IntersectionUtils.GetIntersectionPoints(polyline1, polyline2, assumeIntersecting, intersectionPointOptions); // TODO catch missed end point/interior intersections by checking end points explicitly if (intersections.IsEmpty) { return(intersections); } intersections = RemoveAllowedEndPointIntersections(intersections, polyline1, polyline2, allowedEndpointInteriorIntersections, vertexSearchDistance); return(RemoveAllowedInteriorIntersections(intersections, polyline1, polyline2, allowedLineInteriorIntersections, vertexSearchDistance)); }
public static IList <IGeometry> TryCut([NotNull] IPolyline inputPolyline, [NotNull] IPolyline cutPolyline) { var splitPoints = (IPointCollection) IntersectionUtils.GetIntersectionPoints(inputPolyline, cutPolyline); if (splitPoints.PointCount == 0) { return(null); } List <IGeometry> splitGeometries = GeometryUtils.GetPartCount(inputPolyline) > 1 ? SplitMultipartPolyline(inputPolyline, cutPolyline, splitPoints) : SplitPolyline(inputPolyline, splitPoints); // largest first splitGeometries.Sort(CompareGeometrySize); splitGeometries.Reverse(); return(splitGeometries); }
public static IEnumerable <LineIntersection> GetIntersections( [NotNull] IPolyline polyline1, [NotNull] IPolyline polyline2, bool is3D) { const bool assumeIntersecting = true; IMultipoint intersections = IntersectionUtils.GetIntersectionPoints( polyline1, polyline2, assumeIntersecting, IntersectionPointOptions.DisregardLinearIntersections); if (intersections.IsEmpty) { yield break; } IEnumVertex enumIntersectionPoints = ((IPointCollection)intersections).EnumVertices; do { int vertexIndex; int outPartIndex; enumIntersectionPoints.QueryNext(TemplatePoint1, out outPartIndex, out vertexIndex); if (outPartIndex < 0 || vertexIndex < 0) { break; } var intersection = new LineIntersection(polyline1, polyline2, TemplatePoint1, is3D); yield return(intersection); } while (true); }
private static IPointCollection GetSketchIntersectionPointsWithOriginalGeometries( [NotNull] IEnumerable <IGeometry> geometriesToReshape, [NotNull] IPolyline highLevelReshapePath) { IPointCollection sketchOriginalIntersectionPoints = null; foreach (IGeometry geometry in geometriesToReshape) { if (sketchOriginalIntersectionPoints == null) { sketchOriginalIntersectionPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( highLevelReshapePath, geometry); } else { sketchOriginalIntersectionPoints.AddPointCollection( (IPointCollection)IntersectionUtils.GetIntersectionPoints( highLevelReshapePath, geometry)); } } return(sketchOriginalIntersectionPoints); }
private IGeometryCollection CalculateDifferences( [NotNull] IPolyline preprocessedSourcePolyline, [NotNull] IPolyline targetPolyline, [CanBeNull] ITrackCancel trackCancel, out IPointCollection intersectionPoints) { double originalToleranceSource = GeometryUtils.GetXyTolerance(preprocessedSourcePolyline); double originalToleranceTarget = GeometryUtils.GetXyTolerance(targetPolyline); IGeometryCollection differences; intersectionPoints = null; try { if (UseMinimumTolerance) { GeometryUtils.SetMinimumXyTolerance(preprocessedSourcePolyline); GeometryUtils.SetMinimumXyTolerance(targetPolyline); } differences = GetReshapableAlongGeometries(preprocessedSourcePolyline, targetPolyline, originalToleranceSource); if (trackCancel != null && !trackCancel.Continue()) { return(null); } if (differences == null) { return(null); } // TODO: Consider using intersection point calculator from cracker in minimum-tolerance mode and / or // use the target segments (GetTargetSegmentsAlong) also in non-minimum tolerance mode. // This could possibly improve the situation from unit test CanReshapeAlongWithSmallIntersectionAngle const bool assumeIntersecting = true; intersectionPoints = (IPointCollection)IntersectionUtils.GetIntersectionPoints( (IPolyline)differences, preprocessedSourcePolyline, assumeIntersecting); } finally { if (UseMinimumTolerance) { // The Reshape Curves are sometimes not correct if not using the normal tolerance when splitting // (see unit test CanReshapeAlongEnsureCorrectTargetVerticesLocationWithMinimalTolerance) GeometryUtils.SetXyTolerance(preprocessedSourcePolyline, originalToleranceSource); GeometryUtils.SetXyTolerance(targetPolyline, originalToleranceTarget); if (intersectionPoints != null) { GeometryUtils.SetXyTolerance((IGeometry)intersectionPoints, originalToleranceSource); } // NOTE: difference will be cracked into reshape paths. However, if two points are closer than the tolerance // the point (too) close to the intersection is eliminated by polycurve.SplitAtPoint resulting in // a slightly changed reshape path -> keep the minimum tolerance for the difference to be more accurate. } } return(differences); }