Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #8
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));
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }