public QaLineIntersect( [Doc(nameof(DocStrings.QaLineIntersect_polylineClasses))][NotNull] IList <IFeatureClass> polylineClasses, [Doc(nameof(DocStrings.QaLineIntersect_validRelationConstraint))][CanBeNull] string validRelationConstraint, [Doc(nameof(DocStrings.QaLineIntersect_allowedEndpointInteriorIntersections))] AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, [Doc(nameof(DocStrings.QaLineIntersect_reportOverlaps))] bool reportOverlaps) : base(polylineClasses, GetSpatialRel(allowedEndpointInteriorIntersections, reportOverlaps)) { Assert.ArgumentNotNull(polylineClasses, nameof(polylineClasses)); _allowedEndpointInteriorIntersections = allowedEndpointInteriorIntersections; _reportOverlaps = reportOverlaps; _validRelationConstraintSql = StringUtils.IsNotEmpty(validRelationConstraint) ? validRelationConstraint : null; AllowedInteriorIntersections = _defaultAllowedInteriorIntersections; _xyTolerances = new List <double>(polylineClasses.Count); _xyResolutions = new List <double>(polylineClasses.Count); foreach (IFeatureClass polylineClass in polylineClasses) { _xyTolerances.Add(GeometryUtils.GetXyTolerance(polylineClass)); _xyResolutions.Add(GeometryUtils.GetXyResolution(polylineClass)); } }
private static ArgumentOutOfRangeException CreateArgumentOutOfRangeException( AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections) { return(new ArgumentOutOfRangeException( nameof(allowedEndpointInteriorIntersections), allowedEndpointInteriorIntersections, string.Format("Unknown constraint: {0}", allowedEndpointInteriorIntersections))); }
private static IMultipoint RemoveAllowedEndPointIntersections( [NotNull] IMultipoint intersections, [NotNull] IPolyline polyline1, [NotNull] IPolyline polyline2, AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, double vertexSearchDistance) { if (allowedEndpointInteriorIntersections == AllowedEndpointInteriorIntersections.None && GeometryUtils.GetPointCount(intersections) == 1) { // NOTE this assumes that HasInvalidIntersections has returned 'true' for these lines // --> if there is a unique intersection point, we know it's not at two touching end points return(intersections); } // this fails if polylines are non-simple IGeometry shape1Endpoints = ((ITopologicalOperator)polyline1).Boundary; IGeometry shape2Endpoints = ((ITopologicalOperator)polyline2).Boundary; IMultipoint innerIntersections = GetIntersectionsInvolvingInterior(intersections, shape1Endpoints, shape2Endpoints); if (innerIntersections.IsEmpty) { return(innerIntersections); } switch (allowedEndpointInteriorIntersections) { case AllowedEndpointInteriorIntersections.All: // remove all intersection points that coincide with any end point return(RemoveAnyEndpoints(innerIntersections, shape1Endpoints, shape2Endpoints)); case AllowedEndpointInteriorIntersections.Vertex: // remove intersections that coincide with an end point of one polyline and a vertex of the other return(RemoveEndPointVertexIntersections(innerIntersections, polyline1, shape1Endpoints, polyline2, shape2Endpoints, vertexSearchDistance)); case AllowedEndpointInteriorIntersections.None: return(innerIntersections); default: throw new ArgumentOutOfRangeException( nameof(allowedEndpointInteriorIntersections)); } }
private double GetVertexIntersectionTolerance( int tableIndex1, int tableIndex2, AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections) { switch (allowedEndpointInteriorIntersections) { case AllowedEndpointInteriorIntersections.All: case AllowedEndpointInteriorIntersections.None: return(0); // doesn't matter case AllowedEndpointInteriorIntersections.Vertex: return(Math.Max(_xyTolerances[tableIndex1], _xyTolerances[tableIndex2])); default: throw CreateArgumentOutOfRangeException(allowedEndpointInteriorIntersections); } }
private bool HasInvalidIntersection( [NotNull] IPolyline polyline1, [NotNull] IPolyline polyline2, AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, bool reportOverlaps, double vertexSearchDistance) { IPoint outPoint; return(LineIntersectionUtils.HasInvalidIntersection( polyline1, polyline2, allowedEndpointInteriorIntersections, reportOverlaps, _pointTemplate1, _pointTemplate2, vertexSearchDistance, out outPoint)); }
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)); }
private static esriSpatialRelEnum GetSpatialRel( AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, bool reportOverlaps) { if (reportOverlaps) { return(esriSpatialRelEnum.esriSpatialRelIntersects); } switch (allowedEndpointInteriorIntersections) { case AllowedEndpointInteriorIntersections.All: return(esriSpatialRelEnum.esriSpatialRelCrosses); case AllowedEndpointInteriorIntersections.Vertex: case AllowedEndpointInteriorIntersections.None: return(esriSpatialRelEnum.esriSpatialRelIntersects); default: throw CreateArgumentOutOfRangeException(allowedEndpointInteriorIntersections); } }
public static bool HasInvalidIntersection( [NotNull] IPolyline polyline1, [NotNull] IPolyline polyline2, AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections, bool reportOverlaps, [NotNull] IPoint pointTemplate1, [NotNull] IPoint pointTemplate2, double vertexSearchDistance, [CanBeNull] out IPoint knownInvalidIntersection) { var relOp1 = (IRelationalOperator)polyline1; // NOTE: if Overlaps is true then Crosses is false // EVEN IF THERE IS A CROSSING IN ADDITION TO THE OVERLAP if (relOp1.Crosses(polyline2)) { knownInvalidIntersection = null; return(true); } if (reportOverlaps && relOp1.Overlaps(polyline2)) { knownInvalidIntersection = null; return(true); } if (allowedEndpointInteriorIntersections == AllowedEndpointInteriorIntersections.All) { knownInvalidIntersection = null; return(false); } bool allowVertexIntersections = allowedEndpointInteriorIntersections == AllowedEndpointInteriorIntersections.Vertex; foreach (IPoint p2 in QueryEndpoints(polyline2, pointTemplate1)) { if (relOp1.Disjoint(p2) || IntersectsEndPoint(p2, polyline1, pointTemplate2)) { continue; } // end point of polyline2 intersects the interior of polyline1 if (allowVertexIntersections && IntersectsVertex(p2, polyline1, pointTemplate2, vertexSearchDistance)) { continue; } knownInvalidIntersection = GeometryFactory.Clone(p2); return(true); } var relOp2 = (IRelationalOperator)polyline2; foreach (IPoint p1 in QueryEndpoints(polyline1, pointTemplate1)) { if (relOp2.Disjoint(p1) || IntersectsEndPoint(p1, polyline2, pointTemplate2)) { continue; } // end point of polyline1 intersects the interior of polyline2 if (allowVertexIntersections && IntersectsVertex(p1, polyline2, pointTemplate2, vertexSearchDistance)) { continue; } knownInvalidIntersection = GeometryFactory.Clone(p1); return(true); } knownInvalidIntersection = null; return(false); }