Пример #1
0
        public Pnt3D GetNonIntersectingTargetPoint(
            [NotNull] Linestring targetRing,
            double distanceFromIntersectionAsRatio)
        {
            if (Type == IntersectionPointType.LinearIntersectionIntermediate ||
                Type == IntersectionPointType.Unknown)
            {
                throw new InvalidOperationException(
                          $"Cannot get the non-intersecting target point for an intersection point type {Type}");
            }

            bool?deviationIsBackward = null;

            if (Type == IntersectionPointType.LinearIntersectionStart ||
                Type == IntersectionPointType.LinearIntersectionEnd)
            {
                // the direction matters:
                deviationIsBackward =
                    Type == IntersectionPointType.LinearIntersectionStart;

                if (SegmentIntersection.LinearIntersectionInOppositeDirection)
                {
                    deviationIsBackward = !deviationIsBackward;
                }
            }

            double targetFactor;
            int    targetSegmentIdx =
                GetLocalTargetIntersectionSegmentIdx(targetRing, out targetFactor);

            double adjustedTargetFactor;

            if (deviationIsBackward == true)
            {
                adjustedTargetFactor = targetFactor - distanceFromIntersectionAsRatio;
            }
            else
            {
                // forward or null (i.e. does not matter)
                adjustedTargetFactor = targetFactor + distanceFromIntersectionAsRatio;

                if (adjustedTargetFactor > 1)
                {
                    int?nextIdx = targetRing.NextSegmentIndex(targetSegmentIdx);
                    if (nextIdx != null)
                    {
                        targetSegmentIdx      = nextIdx.Value;
                        adjustedTargetFactor -= 1;
                    }
                    else if (deviationIsBackward == null)
                    {
                        // cannot go forward, try backward:
                        adjustedTargetFactor =
                            targetFactor - distanceFromIntersectionAsRatio;
                    }
                }
            }

            if (adjustedTargetFactor < 0)
            {
                int?previousIdx = targetRing.PreviousSegmentIndex(targetSegmentIdx);
                if (previousIdx == null)
                {
                    return(null);
                }

                targetSegmentIdx      = previousIdx.Value;
                adjustedTargetFactor += 1;
            }

            return(targetRing[targetSegmentIdx].GetPointAlong(adjustedTargetFactor, true));
        }
Пример #2
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);
        }