コード例 #1
0
        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));
            }
        }
コード例 #2
0
 private static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(
     AllowedEndpointInteriorIntersections allowedEndpointInteriorIntersections)
 {
     return(new ArgumentOutOfRangeException(
                nameof(allowedEndpointInteriorIntersections),
                allowedEndpointInteriorIntersections,
                string.Format("Unknown constraint: {0}", allowedEndpointInteriorIntersections)));
 }
コード例 #3
0
        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));
            }
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        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);
        }