Esempio n. 1
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);
        }
Esempio n. 2
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);
        }
Esempio n. 3
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;
                }
            }
        }
Esempio n. 4
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);
        }
        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;
                }
            }
        }
Esempio n. 6
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);
        }