コード例 #1
0
        private static Linestring CreateWithBoundaryLoop(Linestring containingSourceRing,
                                                         Linestring touchingInteriorRing,
                                                         IntersectionPoint3D touchIntersection,
                                                         double tolerance)
        {
            double sourceTouchPointRatio;
            int    sourceTouchSegmentIdx =
                touchIntersection.GetLocalSourceIntersectionSegmentIdx(
                    containingSourceRing, out sourceTouchPointRatio);
            List <Linestring> subcurves = new List <Linestring>();

            subcurves.Add(containingSourceRing.GetSubcurve(
                              0, 0, sourceTouchSegmentIdx, sourceTouchPointRatio,
                              false));

            double targetTouchPointRatio;
            int    targetTouchSegmentIdx =
                touchIntersection.GetLocalTargetIntersectionSegmentIdx(
                    touchingInteriorRing, out targetTouchPointRatio);

            subcurves.Add(touchingInteriorRing.GetSubcurve(
                              targetTouchSegmentIdx, targetTouchPointRatio, false,
                              true));

            subcurves.Add(containingSourceRing.GetSubcurve(
                              sourceTouchSegmentIdx, sourceTouchPointRatio,
                              containingSourceRing.SegmentCount - 1, 1, false));

            Linestring withBoundaryLoop =
                GeomTopoOpUtils.MergeConnectedLinestrings(subcurves, null, tolerance);

            return(withBoundaryLoop);
        }
コード例 #2
0
        protected static Linestring GetTargetSubcurve(
            [NotNull] Linestring target,
            [NotNull] IntersectionPoint3D fromIntersection,
            [NotNull] IntersectionPoint3D toIntersection,
            bool forward)
        {
            double fromDistanceAlongAsRatio;
            int    fromIndex = fromIntersection.GetLocalTargetIntersectionSegmentIdx(
                target, out fromDistanceAlongAsRatio);

            double toDistanceAlongAsRatio;
            int    toIndex = toIntersection.GetLocalTargetIntersectionSegmentIdx(
                target, out toDistanceAlongAsRatio);

            if (!forward &&
                fromIntersection.VirtualTargetVertex > toIntersection.VirtualTargetVertex)
            {
            }

            Linestring subcurve = target.GetSubcurve(
                fromIndex, fromDistanceAlongAsRatio,
                toIndex, toDistanceAlongAsRatio,
                false, !forward);

            // Replace the start / end with the actual intersection (correct source Z, exactly matching previous subcurve end)
            subcurve.ReplacePoint(0, fromIntersection.Point);
            subcurve.ReplacePoint(subcurve.SegmentCount, toIntersection.Point);

            return(subcurve);
        }
コード例 #3
0
        private bool CanFollowTarget(IntersectionPoint3D startingAt,
                                     bool forward,
                                     int initialSourcePart)
        {
            if (Target.GetPart(startingAt.TargetPartIndex).IsClosed)
            {
                return(true);
            }

            if (forward &&
                !CanConnectToSourcePartAlongTargetForward(startingAt, initialSourcePart))
            {
                // last intersection along a non-closed target (dangle!), cannot follow
                return(false);
            }

            if (!forward &&
                !CanConnectToSourcePartAlongTargetBackwards(startingAt, initialSourcePart))
            {
                // first intersection along a non-closed target, cannot follow
                return(false);
            }

            return(true);
        }
コード例 #4
0
        protected override IntersectionPoint3D FollowUntilNextIntersection(
            IntersectionPoint3D previousIntersection,
            bool continueOnSource,
            int partIndex,
            bool continueForward,
            out Linestring subcurve)
        {
            IntersectionPoint3D nextIntersection;

            if (continueOnSource)
            {
                nextIntersection = GetNextIntersectionAlongSource(previousIntersection);

                subcurve = GetSourceSubcurve(previousIntersection, nextIntersection);
            }
            else
            {
                // TODO: Handle verticals?
                nextIntersection =
                    GetNextIntersectionAlongTarget(previousIntersection, continueForward);

                Linestring targetPart = Target.GetPart(previousIntersection.TargetPartIndex);

                subcurve = GetTargetSubcurve(targetPart, previousIntersection,
                                             nextIntersection, continueForward);
            }

            return(nextIntersection);
        }
コード例 #5
0
        /// <summary>
        /// Creates the IntersectionPoint3D of type <see cref="IntersectionPointType.LinearIntersectionEnd"/>
        /// that corresponds to the second intersection along the source segment.
        /// </summary>
        /// <param name="intersection">The intersection</param>
        /// <param name="sourceSegments"></param>
        /// <param name="targetSegments"></param>
        /// <returns></returns>
        public static IntersectionPoint3D GetLinearIntersectionEnd(
            [NotNull] SegmentIntersection intersection,
            [NotNull] ISegmentList sourceSegments,
            [NotNull] ISegmentList targetSegments)
        {
            Line3D sourceSegment = sourceSegments[intersection.SourceIndex];

            double endFactor;
            Pnt3D  toPoint =
                intersection.GetLinearIntersectionEnd(sourceSegment, out endFactor);

            int sourcePartIdx;
            int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex(
                intersection.SourceIndex, out sourcePartIdx);

            IntersectionPoint3D result =
                new IntersectionPoint3D(
                    toPoint, sourceSegmentIndex + endFactor, intersection)
            {
                Type            = IntersectionPointType.LinearIntersectionEnd,
                SourcePartIndex = sourcePartIdx
            };

            int targetPartIdx;

            result.VirtualTargetVertex = CalculateVirtualTargetVertex(
                targetSegments, result.Type, intersection, out targetPartIdx);

            result.TargetPartIndex = targetPartIdx;

            return(result);
        }
コード例 #6
0
        protected Linestring GetSourceSubcurve(
            [NotNull] IntersectionPoint3D fromIntersection,
            [NotNull] IntersectionPoint3D toIntersection)
        {
            Assert.ArgumentCondition(
                fromIntersection.SourcePartIndex == toIntersection.SourcePartIndex,
                "Cannot jump between source parts");

            Linestring source = GetSourcePart(fromIntersection.SourcePartIndex);

            double fromDistanceAlongAsRatio;
            int    fromIndex = fromIntersection.GetLocalSourceIntersectionSegmentIdx(
                source, out fromDistanceAlongAsRatio);

            double toDistanceAlongAsRatio;
            int    toIndex = toIntersection.GetLocalSourceIntersectionSegmentIdx(
                source, out toDistanceAlongAsRatio);

            Linestring subcurve = source.GetSubcurve(
                fromIndex, fromDistanceAlongAsRatio,
                toIndex, toDistanceAlongAsRatio,
                false);

            return(subcurve);
        }
コード例 #7
0
        private static void ClassifyIntersection([NotNull] ISegmentList source,
                                                 [NotNull] ISegmentList target,
                                                 [NotNull] IntersectionPoint3D intersectionPoint,
                                                 out bool isInbound,
                                                 out bool isOutbound)
        {
            Assert.False(intersectionPoint.Type == IntersectionPointType.Unknown,
                         "Cannot classify unknown intersection type.");

            if (intersectionPoint.Type ==
                IntersectionPointType.LinearIntersectionIntermediate)
            {
                isInbound  = false;
                isOutbound = false;
                return;
            }

            int?previousTargetSegment =
                intersectionPoint.GetNonIntersectingTargetSegmentIndex(target, false);
            int?nextTargetSegment =
                intersectionPoint.GetNonIntersectingTargetSegmentIndex(target, true);

            Pnt3D previousPntAlongTarget = previousTargetSegment == null
                                                               ? null
                                                               : target[previousTargetSegment.Value].StartPoint;

            Pnt3D nextPntAlongTarget = nextTargetSegment == null
                                                           ? null
                                                           : target[nextTargetSegment.Value].EndPoint;

            isInbound = nextPntAlongTarget != null &&
                        intersectionPoint.IsOnTheRightSide(source, nextPntAlongTarget, true);
            isOutbound = previousPntAlongTarget != null &&
                         intersectionPoint.IsOnTheRightSide(source, previousPntAlongTarget, true);
        }
コード例 #8
0
 public IntersectionRun(IntersectionPoint3D nextIntersection,
                        Linestring subcurve,
                        Pnt3D includedRingStartPoint)
 {
     _includedRingStartPoint = includedRingStartPoint;
     NextIntersection        = nextIntersection;
     Subcurve = subcurve;
 }
コード例 #9
0
 protected override void SetTurnDirection(
     IntersectionPoint3D startIntersection,
     IntersectionPoint3D intersection,
     ref bool alongSource, ref int partIndex, ref bool forward)
 {
     SetTurnDirection(startIntersection, intersection, ref alongSource, ref partIndex,
                      ref forward, PreferredTurnDirection);
 }
コード例 #10
0
        protected override void SetTurnDirection(
            IntersectionPoint3D startIntersection,
            IntersectionPoint3D intersection,
            ref bool alongSource, ref int partIndex, ref bool forward)
        {
            Assert.AreEqual(TurnDirection.Right, PreferredTurnDirection,
                            "Unsupported turn direction for single ring navigator");

            // First set the base line, along which we're arriving at the junction:
            double distanceAlongSource;
            int    sourceSegmentIdx =
                intersection.GetLocalSourceIntersectionSegmentIdx(_sourceRing,
                                                                  out distanceAlongSource);
            Line3D entryLine =
                GetEntryLine(intersection, _sourceRing, _target, alongSource, forward);

            Line3D alongSourceLine = distanceAlongSource < 1
                                                         ? _sourceRing[sourceSegmentIdx]
                                                         : _sourceRing.NextSegmentInRing(sourceSegmentIdx);

            double?sourceForwardDirection =
                GetDirectionChange(entryLine, alongSourceLine);

            double?targetForwardDirection;
            double?targetBackwardDirection;

            GetAlongTargetDirectionChanges(intersection, entryLine,
                                           out targetForwardDirection,
                                           out targetBackwardDirection);

            // Order the direction change: the largest is the right-most
            if (IsMoreRight(sourceForwardDirection, targetForwardDirection))
            {
                if (IsMoreRight(sourceForwardDirection, targetBackwardDirection))
                {
                    alongSource = true;
                    forward     = true;
                }
                else if (IsMoreRight(targetBackwardDirection, sourceForwardDirection))
                {
                    alongSource = false;
                    forward     = false;
                }
            }
            else if (IsMoreRight(targetForwardDirection, sourceForwardDirection))
            {
                if (IsMoreRight(targetForwardDirection, targetBackwardDirection))
                {
                    alongSource = false;
                    forward     = true;
                }
                else if (IsMoreRight(targetBackwardDirection, targetForwardDirection))
                {
                    alongSource = false;
                    forward     = false;
                }
            }
        }
コード例 #11
0
        protected override IntersectionPoint3D GetNextIntersectionAlongSource(
            IntersectionPoint3D thisIntersection)
        {
            int previousSourceIdx  = IntersectionOrders[thisIntersection].Key;
            int nextAlongSourceIdx = (previousSourceIdx + 1) % IntersectionsAlongSource.Count;

            IntersectionPoint3D nextIntersection = IntersectionsAlongSource[nextAlongSourceIdx];

            return(nextIntersection);
        }
コード例 #12
0
        protected override IntersectionPoint3D FollowUntilNextIntersection(
            IntersectionPoint3D previousIntersection,
            bool continueOnSource,
            int partIndex,
            bool continueForward,
            out Linestring subcurve)
        {
            IntersectionPoint3D nextIntersection;

            if (continueOnSource)
            {
                nextIntersection = GetNextIntersectionAlongSource(previousIntersection);

                subcurve = GetSourceSubcurve(previousIntersection, nextIntersection);
            }
            else
            {
                int previousTargetIdx = IntersectionOrders[previousIntersection].Value;

                // If there are vertical rings, there can be 2 intersections at the exact same target distance
                int otherDirectionIdx = GetNextAlongTargetIdx(
                    previousTargetIdx, !continueForward,
                    IntersectionsAlongTarget);

                double epsilon = MathUtils.GetDoubleSignificanceEpsilon(
                    previousIntersection.Point.X,
                    previousIntersection.Point.Y);

                int nextAlongTargetIdx;
                if (MathUtils.AreEqual(
                        IntersectionsAlongTarget[otherDirectionIdx].VirtualTargetVertex,
                        IntersectionsAlongTarget[previousTargetIdx].VirtualTargetVertex,
                        epsilon))
                {
                    // vertical ring, 2 intersections at same XY location
                    nextAlongTargetIdx = otherDirectionIdx;
                }
                else
                {
                    nextAlongTargetIdx = GetNextAlongTargetIdx(
                        previousTargetIdx, continueForward,
                        IntersectionsAlongTarget);
                }

                nextIntersection = IntersectionsAlongTarget[nextAlongTargetIdx];

                subcurve = GetTargetSubcurve(_target, previousIntersection,
                                             nextIntersection, continueForward);
            }

            return(nextIntersection);
        }
コード例 #13
0
        private static void TryAddLinearIntersectionStretch(
            [CanBeNull] IntersectionPoint3D startPoint,
            [CanBeNull] IntersectionPoint3D endPoint,
            [NotNull] List <IntersectionPoint3D> result)
        {
            if (startPoint != null)
            {
                result.Add(startPoint);
            }

            if (endPoint != null)
            {
                result.Add(endPoint);
            }
        }
コード例 #14
0
        protected IntersectionPoint3D GetNextIntersectionAlongTarget(
            IntersectionPoint3D current, bool continueForward)
        {
            int nextAlongTargetIdx;
            int count = 0;

            int currentTargetIdx = IntersectionOrders[current].Value;

            do
            {
                nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) %
                                     IntersectionsAlongTarget.Count;

                // TODO: CollectionUtils.GetPreviousInCircularList()
                if (nextAlongTargetIdx < 0)
                {
                    nextAlongTargetIdx += IntersectionsAlongTarget.Count;
                }

                Assert.True(count++ <= IntersectionsAlongTarget.Count,
                            "Cannot find next intersection in same target part");

                currentTargetIdx = nextAlongTargetIdx;
            } while (IntersectionsAlongTarget[nextAlongTargetIdx].TargetPartIndex !=
                     current.TargetPartIndex);
            //int currentTargetIdx = IntersectionOrders[current].Value;

            //int nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) %
            //                         IntersectionsAlongTarget.Count;

            //// TODO: CollectionUtils.GetPreviousInCircularList()
            //if (nextAlongTargetIdx < 0)
            //{
            //	nextAlongTargetIdx += IntersectionsAlongTarget.Count;
            //}

            //IntersectionPoint3D next = IntersectionsAlongTarget[nextAlongTargetIdx];

            //int count = 0;
            //while (next.TargetPartIndex != partIndex)
            //{
            //	next = GetNextIntersectionAlongTarget(next, continueForward, partIndex);
            //	Assert.True(count < IntersectionsAlongTarget.Count,
            //	            "Cannot find next intersection in same target part");
            //}

            return(IntersectionsAlongTarget[nextAlongTargetIdx]);
        }
コード例 #15
0
        protected IntersectionPoint3D GetNextIntersectionAlongTarget(
            IntersectionPoint3D current, bool continueForward)
        {
            int currentTargetIdx = IntersectionOrders[current].Value;

            int nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) %
                                     IntersectionsAlongTarget.Count;

            // TODO: CollectionUtils.GetPreviousInCircularList()
            if (nextAlongTargetIdx < 0)
            {
                nextAlongTargetIdx += IntersectionsAlongTarget.Count;
            }

            return(IntersectionsAlongTarget[nextAlongTargetIdx]);
        }
コード例 #16
0
        private bool IsFirstIntersectionInTargetPart(IntersectionPoint3D intersection)
        {
            int targetIdx = IntersectionOrders[intersection].Value;

            // Any previous intersection in the same part that intersects the same source part?
            while (--targetIdx >= 0)
            {
                IntersectionPoint3D previousIntersection = IntersectionsAlongTarget[targetIdx];

                if (previousIntersection.TargetPartIndex == intersection.TargetPartIndex &&
                    previousIntersection.SourcePartIndex == intersection.SourcePartIndex)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #17
0
        private bool IsLastIntersectionInTargetPart(IntersectionPoint3D intersection,
                                                    int initialSourcePartIdx)
        {
            int targetIdx = IntersectionOrders[intersection].Value;

            // Any following intersection in the same target part that intersects the same source part?
            while (++targetIdx < IntersectionsAlongTarget.Count)
            {
                IntersectionPoint3D laterIntersection = IntersectionsAlongTarget[targetIdx];

                if (laterIntersection.TargetPartIndex == intersection.TargetPartIndex &&
                    laterIntersection.SourcePartIndex == initialSourcePartIdx)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #18
0
        private bool CanConnectToSourcePartAlongTargetBackwards(
            IntersectionPoint3D fromIntersection,
            int initialSourcePartIdx)
        {
            int targetIdx = IntersectionOrders[fromIntersection].Value;

            // Any previous intersection in the same part that intersects the same source part?
            while (--targetIdx >= 0)
            {
                IntersectionPoint3D previousIntersection = IntersectionsAlongTarget[targetIdx];

                if (previousIntersection.TargetPartIndex == fromIntersection.TargetPartIndex &&
                    previousIntersection.SourcePartIndex == initialSourcePartIdx)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #19
0
        private static Linestring GetSourceSubcurve(
            [NotNull] Linestring source,
            [NotNull] IntersectionPoint3D fromIntersection,
            [NotNull] IntersectionPoint3D toIntersection)
        {
            double fromDistanceAlongAsRatio;
            int    fromIndex = fromIntersection.GetLocalSourceIntersectionSegmentIdx(
                source, out fromDistanceAlongAsRatio);

            double toDistanceAlongAsRatio;
            int    toIndex = toIntersection.GetLocalSourceIntersectionSegmentIdx(
                source, out toDistanceAlongAsRatio);

            Linestring subcurve = source.GetSubcurve(
                fromIndex, fromDistanceAlongAsRatio,
                toIndex, toDistanceAlongAsRatio,
                false);

            return(subcurve);
        }
コード例 #20
0
        private bool CanConnectToSourcePartAlongTargetForward(
            [NotNull] IntersectionPoint3D fromIntersection,
            int initialSourcePartIdx)
        {
            int targetIdx = IntersectionOrders[fromIntersection].Value;

            // Any following intersection along the same target part that intersects the required source part?
            while (++targetIdx < IntersectionsAlongTarget.Count)
            {
                IntersectionPoint3D laterIntersection = IntersectionsAlongTarget[targetIdx];

                if (laterIntersection.TargetPartIndex == fromIntersection.TargetPartIndex &&
                    laterIntersection.SourcePartIndex == initialSourcePartIdx)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #21
0
        protected override IntersectionPoint3D GetNextIntersectionAlongSource(
            IntersectionPoint3D thisIntersection)
        {
            int previousSourceIdx = IntersectionOrders[thisIntersection].Key;

            int nextSourceIdx = previousSourceIdx + 1;

            if (nextSourceIdx == IntersectionsAlongSource.Count)
            {
                nextSourceIdx = 0;
            }

            int thisPartIdx = thisIntersection.SourcePartIndex;

            if (nextSourceIdx < IntersectionsAlongSource.Count &&
                IntersectionsAlongSource[nextSourceIdx].SourcePartIndex == thisPartIdx)
            {
                return(IntersectionsAlongSource[nextSourceIdx]);
            }

            return(IntersectionsAlongSource.First(i => i.SourcePartIndex == thisPartIdx));
        }
コード例 #22
0
        private void GetAlongTargetDirectionChanges(
            int initialSourcePart,
            [NotNull] IntersectionPoint3D startingAt,
            [NotNull] Line3D entryLine,
            out double?targetForwardDirection,
            out double?targetBackwardDirection)
        {
            targetForwardDirection  = null;
            targetBackwardDirection = null;

            if (CanFollowTarget(startingAt, true, initialSourcePart))
            {
                int?forwardSegmentIdx =
                    startingAt.GetNonIntersectingTargetSegmentIndex(Target, true);

                if (forwardSegmentIdx != null)
                {
                    Line3D targetForward = Target[forwardSegmentIdx.Value];

                    targetForwardDirection = GetDirectionChange(entryLine, targetForward);
                }
            }

            if (CanFollowTarget(startingAt, false, initialSourcePart))
            {
                int?backwardSegmentIdx =
                    startingAt.GetNonIntersectingTargetSegmentIndex(Target, false);

                if (backwardSegmentIdx != null)
                {
                    Line3D targetBackward = Target[backwardSegmentIdx.Value].Clone();
                    targetBackward.ReverseOrientation();

                    targetBackwardDirection =
                        GetDirectionChange(entryLine, targetBackward);
                }
            }
        }
コード例 #23
0
        private bool CanFollowTarget(IntersectionPoint3D startingAt, bool forward)
        {
            if (_target.IsClosed)
            {
                return(true);
            }

            int targetIdx = IntersectionOrders[startingAt].Value;

            if (forward && targetIdx == IntersectionsAlongTarget.Count - 1)
            {
                // last intersection along a non-closed target (dangle!), cannot follow
                return(false);
            }

            if (!forward && targetIdx == 0)
            {
                // first intersection along a non-closed target, cannot follow
                return(false);
            }

            return(true);
        }
コード例 #24
0
        private void SetTurnDirection(
            IntersectionPoint3D startIntersection,
            IntersectionPoint3D intersection,
            ref bool alongSource, ref int partIndex, ref bool forward,
            TurnDirection preferredDirection)
        {
            // First set the base line, along which we're arriving at the junction:
            Linestring sourceRing = Source.GetPart(intersection.SourcePartIndex);
            Linestring target     = Target.GetPart(intersection.TargetPartIndex);

            Line3D entryLine = GetEntryLine(intersection, sourceRing, target,
                                            alongSource, forward);

            double distanceAlongSource;
            int    sourceSegmentIdx =
                intersection.GetLocalSourceIntersectionSegmentIdx(sourceRing,
                                                                  out distanceAlongSource);

            Line3D alongSourceLine = distanceAlongSource < 1
                                                         ? sourceRing[sourceSegmentIdx]
                                                         : sourceRing.NextSegmentInRing(sourceSegmentIdx);

            double?sourceForwardDirection =
                GetDirectionChange(entryLine, alongSourceLine);

            double?targetForwardDirection;
            double?targetBackwardDirection;

            GetAlongTargetDirectionChanges(startIntersection.SourcePartIndex, intersection,
                                           entryLine,
                                           out targetForwardDirection,
                                           out targetBackwardDirection);

            // Order the direction change
            if (true == IsMore(preferredDirection, sourceForwardDirection, targetForwardDirection))
            {
                if (true == IsMore(preferredDirection, sourceForwardDirection,
                                   targetBackwardDirection))
                {
                    alongSource = true;
                    forward     = true;
                }
                else if (true == IsMore(preferredDirection, targetBackwardDirection,
                                        sourceForwardDirection))
                {
                    alongSource = false;
                    forward     = false;
                }
            }
            else if (true == IsMore(preferredDirection, targetForwardDirection,
                                    sourceForwardDirection))
            {
                if (true == IsMore(preferredDirection, targetForwardDirection,
                                   targetBackwardDirection))
                {
                    alongSource = false;
                    forward     = true;
                }
                else if (true == IsMore(preferredDirection, targetBackwardDirection,
                                        targetForwardDirection))
                {
                    alongSource = false;
                    forward     = false;
                }
            }
        }
コード例 #25
0
        /// <summary>
        ///   Gets the line that enters the intersection point when moving along as specified
        ///   with the direction parameters alongSource and forward.
        /// </summary>
        /// <param name="intoIntersection"></param>
        /// <param name="target"></param>
        /// <param name="alongSource"></param>
        /// <param name="forward"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        protected static Line3D GetEntryLine([NotNull] IntersectionPoint3D intoIntersection,
                                             [NotNull] Linestring source,
                                             [NotNull] Linestring target,
                                             bool alongSource, bool forward)
        {
            Line3D entryLine;

            if (alongSource)
            {
                double distanceAlongSource;
                int    sourceSegmentIdx =
                    intoIntersection.GetLocalSourceIntersectionSegmentIdx(
                        source, out distanceAlongSource);

                entryLine = distanceAlongSource > 0
                                                    ? source[sourceSegmentIdx]
                                                    : source.PreviousSegmentInRing(sourceSegmentIdx);
            }
            else
            {
                double distanceAlongTarget;
                int    targetSegmentIdx = intoIntersection.GetLocalTargetIntersectionSegmentIdx(
                    target, out distanceAlongTarget);

                if (forward)
                {
                    if (distanceAlongTarget > 0)
                    {
                        entryLine = target[targetSegmentIdx];
                    }
                    else
                    {
                        // There must be a previous segment if we have come along the target
                        int previousTargetIdx =
                            Assert.NotNull(target.PreviousSegmentIndex(targetSegmentIdx)).Value;

                        entryLine = target[previousTargetIdx];
                    }
                }
                else
                {
                    if (distanceAlongTarget < 1)
                    {
                        entryLine = target[targetSegmentIdx];
                    }
                    else
                    {
                        // There must be a next segment if we have come backwards along the target
                        int nextTargetIdx =
                            Assert.NotNull(target.NextSegmentIndex(targetSegmentIdx)).Value;

                        entryLine = target[nextTargetIdx];
                    }

                    entryLine = entryLine.Clone();
                    entryLine.ReverseOrientation();
                }
            }

            return(entryLine);
        }
コード例 #26
0
        private IEnumerable <IntersectionRun> NavigateSubcurves(
            IntersectionPoint3D startIntersection)
        {
            if (VisitedOutboundTarget.Contains(startIntersection) ||
                VisitedInboundTarget.Contains(startIntersection))
            {
                yield break;
            }

            IntersectionPoint3D previousIntersection = startIntersection;
            IntersectionPoint3D nextIntersection     = null;

            int count = 0;
            // Start by following the source:
            bool continueOnSource = true;
            bool forward          = true;
            int  partIndex        = startIntersection.SourcePartIndex;

            while (nextIntersection == null ||
                   !nextIntersection.Point.Equals(startIntersection.Point))
            {
                Assert.True(count++ <= IntersectionPoints.Count,
                            "Intersections seen twice");

                if (nextIntersection != null)
                {
                    // Determine if at the next intersection we must
                    // - continue along the source (e.g. because the source touches from the inside)
                    // - continue along the target (forward or backward)
                    SetTurnDirection(startIntersection, previousIntersection,
                                     ref continueOnSource, ref partIndex, ref forward);
                }

                Linestring subcurve;
                nextIntersection = FollowUntilNextIntersection(
                    previousIntersection, continueOnSource, partIndex, forward, out subcurve);

                Pnt3D containedSourceStart = null;
                if (continueOnSource &&
                    previousIntersection.SourcePartIndex == nextIntersection.SourcePartIndex &&
                    (MathUtils.AreEqual(previousIntersection.VirtualSourceVertex, 0) ||
                     forward && previousIntersection.VirtualSourceVertex >
                     nextIntersection.VirtualSourceVertex))
                {
                    Linestring sourcePart = GetSourcePart(previousIntersection.SourcePartIndex);
                    containedSourceStart = sourcePart.StartPoint;
                }

                if (continueOnSource)
                {
                    // Remove, if we follow the source through an intersection from other start.
                    // This happens with vertical rings and multiple targets.
                    if (IntersectionsOutboundTarget.Contains(previousIntersection))
                    {
                        // TODO: if the current startIntersection is inbound make sure the left/right assignment is cleared!
                        VisitedOutboundTarget.Add(previousIntersection);
                    }
                    else if (IntersectionsInboundTarget.Contains(previousIntersection))
                    {
                        // TODO: if the current startIntersection is outbound make sure the left/right assignment is cleared!
                        VisitedInboundTarget.Add(previousIntersection);
                    }
                }

                IntersectionRun next =
                    new IntersectionRun(nextIntersection, subcurve, containedSourceStart);

                next.ContinuingOnSource = continueOnSource;

                yield return(next);

                previousIntersection = nextIntersection;
            }
        }
コード例 #27
0
 protected abstract void SetTurnDirection(
     [NotNull] IntersectionPoint3D startIntersection,
     [NotNull] IntersectionPoint3D intersection,
     ref bool alongSource, ref int partIndex, ref bool forward);
コード例 #28
0
 protected abstract IntersectionPoint3D FollowUntilNextIntersection(
     [NotNull] IntersectionPoint3D previousIntersection,
     bool continueOnSource,
     int partIndex,
     bool continueForward,
     out Linestring subcurve);
コード例 #29
0
        public static IntersectionPoint3D CreateSingleIntersectionPoint(
            [NotNull] SegmentIntersection intersection,
            [NotNull] ISegmentList sourceSegments,
            [NotNull] ISegmentList targetSegments,
            double tolerance)
        {
            Line3D sourceSegment = sourceSegments.GetSegment(intersection.SourceIndex);
            double?targetIntersectionFactorOnSource =
                intersection.GetIntersectionPointFactorAlongSource();

            int sourcePartIdx;
            int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex(
                intersection.SourceIndex, out sourcePartIdx);

            Pnt3D  point;
            double sourceIndex;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (targetIntersectionFactorOnSource == 0)
            {
                point       = sourceSegment.StartPoint;
                sourceIndex = sourceSegmentIndex;
            }
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            else if (targetIntersectionFactorOnSource == 1)
            {
                point       = sourceSegment.EndPoint;
                sourceIndex = sourceSegmentIndex + 1;
            }
            else
            {
                point = sourceSegment.GetPointAlong(
                    targetIntersectionFactorOnSource.Value, true);
                sourceIndex = sourceSegmentIndex +
                              targetIntersectionFactorOnSource.Value;
            }

            IntersectionPoint3D result = new IntersectionPoint3D(point, sourceIndex, intersection)
            {
                SourcePartIndex = sourcePartIdx
            };

            bool?targetDeviatesToLeft;

            result.Type = intersection.IsCrossingInPoint(
                sourceSegments, targetSegments, tolerance,
                out targetDeviatesToLeft)
                                              ? IntersectionPointType.Crossing
                                              : IntersectionPointType.TouchingInPoint;

            result.TargetDeviatesToLeftOfSource = targetDeviatesToLeft;

            int targetPartIdx;

            result.VirtualTargetVertex = CalculateVirtualTargetVertex(
                targetSegments, result.Type, intersection, out targetPartIdx);

            result.TargetPartIndex = targetPartIdx;

            return(result);
        }
コード例 #30
0
 protected abstract IntersectionPoint3D GetNextIntersectionAlongSource(
     IntersectionPoint3D thisIntersection);