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); }
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); }
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; } } }
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; } } }
/// <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); }