protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1, SegmentNeighbors processed1, SegmentParts partsOfSeg0, bool coincident) { TryAssignComplete(seg1, processed1, partsOfSeg0); SegmentParts coincidentPartsOfSeg0; var key = new SegmentPart(seg0, 0, 1, true); if (!_coincidentParts.TryGetValue(key, out coincidentPartsOfSeg0)) { coincidentPartsOfSeg0 = new SegmentParts(); _coincidentParts.Add(key, coincidentPartsOfSeg0); } if (coincident) { partsOfSeg0.IsComplete = true; coincidentPartsOfSeg0.Add(key); return(false); } //return true; IBox seg0Box = seg0.Extent; seg0Box = new Box(Pnt.Create(seg0Box.Min), Pnt.Create(seg0Box.Max)); if (_coincidenceTolerance > 0) { seg0Box.Min.X -= _coincidenceTolerance; seg0Box.Min.Y -= _coincidenceTolerance; seg0Box.Max.X += _coincidenceTolerance; seg0Box.Max.Y += _coincidenceTolerance; } if (!seg0Box.Intersects(seg1.Extent)) { return(true); } var cap = new RoundCap(); NearSegment hullStart; NearSegment hullEnd; bool isCoincident; IList <double[]> limits = FindNeighborhood( new SegmentHull(seg0, 0, cap, cap), new SegmentHull(seg1, _coincidenceTolerance, cap, cap), _is3D, 0, out hullStart, out hullEnd, out isCoincident); IList <SegmentPart> addParts = GetSegmentParts(seg0, seg1, limits, isCoincident); coincidentPartsOfSeg0.AddRange(addParts); bool isComplete = SegmentPart.VerifyComplete(coincidentPartsOfSeg0); partsOfSeg0.IsComplete = isComplete; return(!isComplete); }
/// <summary> /// /// </summary> public SegmentEnumerator(ReadCursor start, ReadCursor end) { _startIndex = start.Index; _segment = start.Segment; _endSegment = end.Segment; _endIndex = end.Index; _current = default(SegmentPart); }
private int CreateFlatEnds([NotNull] NeighboredSegmentsSubpart segmentsSubpartx, double rowDistance, [NotNull] Dictionary <FeaturePoint, SegmentInfo> flatEnds, [NotNull] ContinuationFinder continuationFinder, bool atStart) { var errorCount = 0; double sumLength = 0; SegmentProxyInfo first = null; foreach (SegmentProxyInfo info in GetSegmentProxies(segmentsSubpartx, continuationFinder, atStart)) { first = first ?? info; var segmentPartKey = new SegmentPart(info.SegmentProxy, 0, 1, complete: true); NeighboredSegmentsSubpart segmentsSubpart = info.Subpart; SegmentParts neighboredParts; segmentsSubpart.SegmentNeighbors.TryGetValue(segmentPartKey, out neighboredParts); var featurePointKey = new FeaturePoint( segmentsSubpart.BaseFeature, segmentsSubpart.TableIndex, segmentPartKey.PartIndex, segmentPartKey.SegmentIndex); SegmentInfo segmentInfo; if (!flatEnds.TryGetValue(featurePointKey, out segmentInfo)) { // TODO revise: neighboredParts can be null here, but SegmentInfo property is later expected to be NotNull segmentInfo = new SegmentInfo(neighboredParts); flatEnds.Add(featurePointKey, segmentInfo); } if (atStart) { segmentInfo.FlatStart = true; } else { segmentInfo.FlatEnd = true; } if (info != first) { errorCount += VerifyAngle(first, info, rowDistance, segmentsSubpart); } sumLength += info.SegmentProxy.Length; if (sumLength >= rowDistance) { break; } } return(errorCount); }
protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1, SegmentNeighbors processed1, SegmentParts partsOfSeg0, bool coincident) { bool isComplete = SegmentPart.VerifyComplete(partsOfSeg0); TryAssignComplete(seg1, processed1, partsOfSeg0); return(!isComplete); }
protected static IList <Subcurve> GetMissingSegments( [NotNull] IFeature feature, [NotNull] IIndexedSegments segList, [NotNull] SortedDictionary <SegmentPart, SegmentParts> nearList) { var result = new List <Subcurve>(); foreach (SegmentProxy segProxy in segList.GetSegments()) { int partIndex = segProxy.PartIndex; int segmentIndex = segProxy.SegmentIndex; var key = new SegmentPart(partIndex, segmentIndex, 0, 1, true); SegmentParts parts; if (!nearList.TryGetValue(key, out parts)) { // ReSharper disable once RedundantAssignment parts = null; } if (parts == null) { AddSegment(feature, segList, result, segProxy, 0, 1); continue; } parts.Sort(new SegmentPartComparer()); double tMax = 0; foreach (SegmentPart part in parts) { if (part.MinFraction > tMax) { AddSegment(feature, segList, result, segProxy, tMax, part.MinFraction); } tMax = Math.Max(tMax, part.MaxFraction); } if (tMax < 1) { AddSegment(feature, segList, result, segProxy, tMax, 1); } } return(result); }
private static SegmentProxyInfo GetSegmentproxyInfo( [NotNull] NeighboredSegmentsSubpart segmentsSubpart, int baseSegmentIndex) { int subpartIndex = segmentsSubpart.FullStartFraction < segmentsSubpart.FullEndFraction ? baseSegmentIndex - segmentsSubpart.FullStartFraction : segmentsSubpart.FullStartFraction - baseSegmentIndex - 1; SegmentProxy segmentProxy = segmentsSubpart.GetSegment(subpartIndex); var key = new SegmentPart(segmentProxy, 0, 1, true); // SegmentPart key = new SegmentPart(segmentsSubpart.PartIndex, iSegment, 0, 1, true); SegmentParts segmentParts; segmentsSubpart.SegmentNeighbors.TryGetValue(key, out segmentParts); return(new SegmentProxyInfo(segmentProxy, segmentsSubpart)); }
/// <summary> /// Moves to the next <see cref="Memory{Byte}"/> in the <see cref="ReadableBuffer"/> /// </summary> /// <returns></returns> public bool MoveNext() { if (_segment == null) { return(false); } int start = _segment.Start; int end = _segment.End; if (_startIndex != 0) { start = _startIndex; _startIndex = 0; } if (_segment == _endSegment) { end = _endIndex; } _current = new SegmentPart() { Segment = _segment, Start = start, End = end, }; if (_segment == _endSegment) { _segment = null; } else { _segment = _segment.Next; if (_segment == null) { throw new InvalidOperationException("Segments ended by end was never seen"); } } return(true); }
public bool MoveNext() { var segment = _segment; if (segment == null) { return(false); } var start = _startIndex; var end = segment.End; if (segment == _endSegment) { end = _endIndex; _segment = null; } else { _segment = segment.Next; if (_segment == null) { if (_endSegment != null) { ThrowEndNotSeen(); } } else { _startIndex = _segment.Start; } } _current = new SegmentPart() { Segment = segment, Start = start, End = end, }; return(true); }
private static void DropParts( [NotNull] Dictionary <FeaturePoint, List <NeighboredSegmentsSubpart> > splittedParts, [NotNull] HashSet <FeaturePoint> dropParts) { // TODO? : transfer SegmentParts of coincident neighbor (due to differing offsets), (Add needed Info to dropParts values) foreach (List <NeighboredSegmentsSubpart> featureParts in splittedParts.Values) { foreach (NeighboredSegmentsSubpart featurePart in featureParts) { foreach (KeyValuePair <SegmentPart, SegmentParts> pair in featurePart.SegmentNeighbors) { SegmentPart segmentKey = pair.Key; SegmentParts neighboredParts = pair.Value; if (dropParts.Contains(featurePart.CreateFeaturePoint(segmentKey))) { neighboredParts.Clear(); continue; } var remaining = new List <SegmentPart>(neighboredParts.Count); foreach (SegmentPart segmentPart in neighboredParts) { var part = (SegmentPartWithNeighbor)segmentPart; if (!dropParts.Contains(part.CreateNeighborFeaturePoint())) { remaining.Add(part); } } if (remaining.Count < neighboredParts.Count) { neighboredParts.Clear(); neighboredParts.AddRange(remaining); } } } } }
public override ObservableCollection<SegmentPart> CreateSegmentValues() { if(_declinationPart == null) { _declinationPart = new SegmentPart(); _declinationPart.Caption = "Declination : "; _declinationPart.Value = this.Declination; } if(_rightAscensionPart == null) { _rightAscensionPart = new SegmentPart(); _rightAscensionPart.Caption = "Right ascension : "; _rightAscensionPart.Value = this.RightAscension; } _parts.Add(_declinationPart); _parts.Add(_rightAscensionPart); return _parts; }
private static void GetClosePart([NotNull] SegmentProxy neighbor, [NotNull] IIndexedSegments geom, [NotNull] SegmentPart segPart, double searchDistanceSquared, bool is3D, out double min, out double max) { SegmentProxy part = geom.GetSegment(segPart.PartIndex, segPart.SegmentIndex); IPnt start = part.GetPointAt(segPart.MinFraction); double minStart, maxStart; GetClosePart(neighbor, start, searchDistanceSquared, is3D, out minStart, out maxStart); IPnt end = part.GetPointAt(segPart.MaxFraction); double minEnd, maxEnd; GetClosePart(neighbor, end, searchDistanceSquared, is3D, out minEnd, out maxEnd); min = Math.Min(minStart, minEnd); max = Math.Max(maxStart, maxEnd); }
public Segment(string value) { this.Value = value; this.IsLiteral = !(value.Contains(ValueStart) || value.Contains(ValueStop)); this.IsRepeating = value.StartsWith(TemplateRepeat); value = value.TrimStart('~'); if (this.IsRepeating) { var templateParts = value.Split("as{"); value = templateParts.First(); this.RepeatAsKey = templateParts.Last().TrimEnd(ValueStop); } var parts = new List <SegmentPart>(); var previousIndex = 0; var index = value.IndexOfAny(ValueBounds, 0); if (index == -1) { parts.Add(new SegmentPart(value, true)); } while (index != -1) { var isLiteral = value[index] != ValueStop;//if value bounds stop then it is a value segment if (index != previousIndex) { var part = new SegmentPart(value.Substring(previousIndex, index - previousIndex), isLiteral); if (parts.Any()) { parts.Last().Next = part; } parts.Add(part); } previousIndex = index + 1; index = previousIndex < value.Length ? value.IndexOfAny(ValueBounds, previousIndex) : -1; } this.Parts = parts.ToArray(); }
public override ObservableCollection<SegmentPart> CreateSegmentValues() { if(_objectNamePart == null) { _objectNamePart = new SegmentPart(); _objectNamePart.Caption = "Object name : "; _objectNamePart.Value = this.ObjectName; } _parts.Add(_objectNamePart); return _parts; }
public IEnumerable <ConnectedLinesEx> CleanupNotReportedPairs( ConnectedLinesEx errorCandidate) { if (_notReportedCondition == null) { yield return(errorCandidate); yield break; } AllNotReportedPairConditions notReportedCondition = _notReportedCondition; ConnectedLines subConnected = null; SegmentNeighbors subNeighbors = null; SegmentPairRelation subRelevantSegment = null; int minRelationIndex = SegmentRelationsToCheck.Count; foreach ( ConnectedSegmentsSubpart allParts in errorCandidate.Line.BaseSegments) { IEnumerable <SegmentPartWithNeighbor> neighbors; double limit; Func <SegmentPartWithNeighbor, double, bool> checkLimit; Func <SegmentPartWithNeighbor, double, double> getLimit; Func <double, bool> checkEndLimit; if (allParts.FullStartFraction > allParts.FullEndFraction) { var sorted = new List <SegmentPartWithNeighbor>(GetNeighbors(allParts)); sorted.Sort((x, y) => - x.FullMax.CompareTo(y.FullMax)); neighbors = sorted; limit = allParts.FullMaxFraction; checkLimit = (x, l) => x.FullMax < l; getLimit = (x, l) => Math.Min(l, x.FullMin); checkEndLimit = l => l > allParts.FullMinFraction; } else { neighbors = GetNeighbors(allParts); limit = allParts.FullMinFraction; checkLimit = (x, l) => x.FullMin > l; getLimit = (x, l) => Math.Max(l, x.FullMax); checkEndLimit = l => l < allParts.FullMaxFraction; } ConnectedSegmentsSubpart subSubparts = null; foreach (SegmentPartWithNeighbor segmentPart in neighbors) { if (notReportedCondition.IsFulfilled( allParts.BaseFeature, allParts.TableIndex, segmentPart.NeighborFeature, segmentPart.NeighborTableIndex)) { continue; } if (checkLimit(segmentPart, limit) && subConnected != null) { subConnected.RelevantSegment = errorCandidate.Line.RelevantSegment; yield return(GetClean(subConnected, errorCandidate)); subConnected = null; } if (subConnected == null) { subConnected = new ConnectedLines(new List <ConnectedSegmentsSubpart>()); subRelevantSegment = null; subSubparts = null; } if (subRelevantSegment == null || segmentPart.MinRelationIndex < subRelevantSegment.Segment.MinRelationIndex) { subRelevantSegment = new SegmentPairRelation( segmentPart, SegmentRelationsToCheck[segmentPart.MinRelationIndex]); } if (subSubparts == null) { subNeighbors = new SegmentNeighbors(new SegmentPartComparer()); var subCurve = new SubClosedCurve(allParts.ConnectedCurve.BaseGeometry, allParts.ConnectedCurve.PartIndex, segmentPart.FullMin, segmentPart.FullMax); subSubparts = new ConnectedSegmentsSubpart( allParts, subNeighbors, subCurve); subConnected.BaseSegments.Add(subSubparts); } SegmentParts parts; var key = new SegmentPart( Assert.NotNull(segmentPart.SegmentProxy), 0, 1, true); if (!subNeighbors.TryGetValue(key, out parts)) { parts = new SegmentParts(); subNeighbors.Add(key, parts); } parts.Add(segmentPart); int relationIndex = segmentPart.MinRelationIndex; if (relationIndex < minRelationIndex) { minRelationIndex = relationIndex; } limit = getLimit(segmentPart, limit); } if (checkEndLimit(limit) && subConnected != null) { subConnected.RelevantSegment = errorCandidate.Line.RelevantSegment; yield return(GetClean(subConnected, errorCandidate)); subConnected = null; } } if (subConnected != null) { subConnected.RelevantSegment = errorCandidate.Line.RelevantSegment; yield return(GetClean(subConnected, errorCandidate)); } }
private void FindDropParts(NeighboredSegmentsSubpart featurePart, HashSet <FeaturePoint> dropParts, List <NeighboredSegmentsSubpart> nonCoincidentParts, out int errorCount) { Dictionary <SegmentPartWithNeighbor, List <SegmentPartWithNeighbor> > coincidents = null; SegmentNeighbors segmentsNeighbors = featurePart.SegmentNeighbors; var first = true; NearDistanceProvider.GetRowsDistance(featurePart.BaseFeature, featurePart.TableIndex); for (int i = featurePart.FullMinFraction; i < featurePart.FullMaxFraction; i++) { if (!first && coincidents == null) { break; } var key = new SegmentPart(featurePart.PartIndex, i, 0, 1, true); SegmentParts segmentNeighbors; if (!segmentsNeighbors.TryGetValue(key, out segmentNeighbors)) { coincidents = null; break; } var remaining = new Dictionary <SegmentPartWithNeighbor, List <SegmentPartWithNeighbor> >(); foreach (SegmentPart segmentPart in segmentNeighbors) { var segmentNeighbor = (SegmentPartWithNeighbor)segmentPart; if (segmentNeighbor.NeighborIsCoincident) { if (first) { remaining.Add( segmentNeighbor, new List <SegmentPartWithNeighbor> { segmentNeighbor }); } else { int segmentIndex = i - featurePart.FullMinFraction; FindCoincident(coincidents, segmentNeighbor, segmentIndex, remaining); } } } coincidents = remaining; if (coincidents.Count == 0) { coincidents = null; } first = false; } if (coincidents == null) { nonCoincidentParts.Add(featurePart); errorCount = 0; return; } // Check if is lowest part bool keepPart = CheckKeepPart(featurePart, coincidents, out errorCount); if (keepPart) { DropCoincidentParts(featurePart, coincidents, dropParts, nonCoincidentParts); } }
private void AddSegment([NotNull] IFeature feature, [NotNull] IIndexedSegments geom, [NotNull] IList <Subcurve> standardConnectedList, [NotNull] IList <Subcurve> nearSelfConnectedList, [NotNull] SegmentPart segPart, double connectedMinLength, double nearSquared) { Subcurve current = null; IList <Subcurve> connectedList = standardConnectedList; SegmentProxy neighbor = segPart.NearSelf; if (neighbor != null) { // Get the distance between the parts that are near double d0 = double.MaxValue; int partIndex = segPart.PartIndex; if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex > neighbor.SegmentIndex) { if (segPart.PartIndex == neighbor.PartIndex) // TODO revise; workaround to avoid exception (invalid index) { // raw estimate for distance betwenn segPart and neighborPart // this estimate is too small, because not the entire part of neighbor is near segPart var curve = new SubClosedCurve(geom, partIndex, neighbor.SegmentIndex + 1, segPart.FullMin); d0 = curve.GetLength(); if (d0 < connectedMinLength) { double d0Max = d0 + neighbor.Length; if (d0Max > connectedMinLength) { // closer investigation necessary double min; double max; GetClosePart(neighbor, geom, segPart, nearSquared, Is3D, out min, out max); d0 = d0 + (1 - max) * neighbor.Length; } // else segPart is definitly near neighbor } //else segPart is definitly not near neighbor } } if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex < neighbor.SegmentIndex) { if (segPart.PartIndex == neighbor.PartIndex) // TODO revise; workaround to avoid exception (invalid index) { var curve = new SubClosedCurve(geom, partIndex, segPart.FullMax, neighbor.SegmentIndex); double d0Min = curve.GetLength(); if (d0Min < connectedMinLength) { double d0Max = d0Min + neighbor.Length; if (d0Max > connectedMinLength) { // closer investigation necessary double min; double max; GetClosePart(neighbor, geom, segPart, nearSquared, Is3D, out min, out max); d0Min = d0Min + min * neighbor.Length; } //else segPart is definitly near neighbor } // else segPart is definitly not near neighbor d0 = Math.Min(d0, d0Min); } } if (d0 < connectedMinLength) { connectedList = nearSelfConnectedList; } } if (connectedList.Count > 0) { current = connectedList[connectedList.Count - 1]; } if (current != null) { if (current.PartIndex != segPart.PartIndex) { current = null; } else if (current.EndFullIndex < segPart.FullMin) { current = null; } } if (current == null) { current = new Subcurve(geom, segPart.PartIndex, segPart.SegmentIndex, segPart.MinFraction, segPart.SegmentIndex, segPart.MaxFraction); connectedList.Add(current); } else { if (current.EndFullIndex < segPart.FullMax) { current.EndSegmentIndex = segPart.SegmentIndex; current.EndFraction = segPart.MaxFraction; } } }
private Dictionary <FeaturePoint, SegmentInfo> GetFlatEnds( [NotNull] Dictionary <FeaturePoint, List <NeighboredSegmentsSubpart> > splittedParts, [NotNull] ContinuationFinder continuationFinder, out int errorCount) { errorCount = 0; var flatEnds = new Dictionary <FeaturePoint, SegmentInfo>(new FeaturePointComparer()); foreach ( KeyValuePair <FeaturePoint, List <NeighboredSegmentsSubpart> > splitted in splittedParts) { foreach (NeighboredSegmentsSubpart segmentsSubpart in splitted.Value) { foreach ( KeyValuePair <SegmentPart, SegmentParts> neighboredSegmentPart in segmentsSubpart.SegmentNeighbors) { SegmentPart key = neighboredSegmentPart.Key; if (key.SegmentIndex > 0 && key.SegmentIndex < segmentsSubpart.FullMaxFraction - 1) { continue; } var flatStart = false; var flatEnd = false; foreach (SegmentPart segmentPart in neighboredSegmentPart.Value) { if (!flatStart && segmentPart.FullMin <= 0) { flatStart = HandleAsFlat(segmentsSubpart, segmentPart.FullMin, continuationFinder); } if (!flatEnd && segmentPart.FullMax >= segmentsSubpart.FullMaxFraction) { flatEnd = HandleAsFlat(segmentsSubpart, segmentPart.FullMax, continuationFinder); } } if (flatStart || flatEnd) { IFeatureRowsDistance rowsDistance = NearDistanceProvider.GetRowsDistance(splitted.Key.Feature, splitted.Key.TableIndex); double rowDistance = rowsDistance.GetRowDistance(); if (flatStart) { errorCount += CreateFlatEnds( segmentsSubpart, rowDistance, flatEnds, continuationFinder, atStart: true); } if (flatEnd) { errorCount += CreateFlatEnds( segmentsSubpart, rowDistance, flatEnds, continuationFinder, atStart: false); } if (flatStart && flatEnd) { double sumLength = 0; double limit = 2 * rowDistance; foreach (SegmentProxy segmentProxy in segmentsSubpart .GetSegments()) { sumLength += segmentProxy.Length; if (sumLength > limit) { break; } } if (sumLength < limit && ReportShortSubpartError != null) { errorCount += ReportShortSubpartError( new ShortSubpartError( segmentsSubpart, sumLength, limit)); } } } } } } return(flatEnds); }
public override void DestroySegmentValues() { _parts.Clear(); _declinationPart = null; _rightAscensionPart = null; }
public override ObservableCollection<SegmentPart> CreateSegmentValues() { if (_selectedItemPart == null) { _selectedItemPart = new SegmentPart(); _selectedItemPart.Caption = "Equinox : "; _selectedItemPart.Value = this.SelectedItem; } _parts.Add(_selectedItemPart); return _parts; }
public override void DestroySegmentValues() { _parts.Clear(); _radiusPart = null; }
public override ObservableCollection<SegmentPart> CreateSegmentValues() { if (_radiusPart == null) { _radiusPart = new SegmentPart(); _radiusPart.Caption = "Radius : "; _radiusPart.Value = this.Radius.ToString(); } _parts.Add(_radiusPart); return _parts; }
public override void DestroySegmentValues() { _parts.Clear(); _selectedItemPart = null; }
public override void DestroySegmentValues() { _parts.Clear(); _objectNamePart = null; }
private void CompleteJunctions() { foreach (KeyValuePair <RowKey, SegmentNeighbors> pair in ProcessedList) { RowKey key = pair.Key; if (_conflictTables.ContainsKey(key.TableIndex)) { continue; } // --> junction was not searched var thisFeature = (IFeature)key.Row; var thisCurve = (IGeometryCollection)thisFeature.Shape; IIndexedSegments thisGeom = IndexedSegmentUtils.GetIndexedGeometry(thisFeature, false); Dictionary <int, SegmentPart> handledParts = new Dictionary <int, SegmentPart>(); foreach (KeyValuePair <SegmentPart, SegmentParts> segmentPair in pair.Value) { if (segmentPair.Value.Count == 0) { continue; } SegmentPart segment = segmentPair.Key; if (handledParts.ContainsKey(segment.PartIndex)) { continue; } int segmentsCount = thisGeom.GetPartSegmentCount(segment.PartIndex); IEnvelope searchBox = thisCurve.Geometry[segment.PartIndex].Envelope; double tolerance = UsedJunctionCoincidenceTolerance; searchBox.Expand(tolerance, tolerance, asRatio: false); Pnt start = thisGeom.GetSegment(segment.PartIndex, 0).GetStart(false); IBox startBox = new Box(new Pnt2D(start.X - tolerance, start.Y - tolerance), new Pnt2D(start.X + tolerance, start.Y + tolerance)); Pnt end = thisGeom.GetSegment(segment.PartIndex, segmentsCount - 1) .GetEnd(false); IBox endBox = new Box(new Pnt2D(end.X - tolerance, end.Y - tolerance), new Pnt2D(end.X + tolerance, end.Y + tolerance)); foreach (KeyValuePair <int, IFeatureClass> topoPair in _topoTables) { int neighborTableIdx = topoPair.Key; ISpatialFilter filter = _topoFilters[neighborTableIdx]; filter.Geometry = searchBox; QueryFilterHelper helper = _topoHelpers[neighborTableIdx]; foreach (IRow neighborRow in Search((ITable)topoPair.Value, filter, helper) ) { if (neighborRow.OID == key.Row.OID && neighborTableIdx == key.TableIndex) { continue; } var neighborFeature = (IFeature)neighborRow; IIndexedSegments neighborGeom = IndexedSegmentUtils.GetIndexedGeometry(neighborFeature, false); int connectedPart; int connectedFraction; if (IsConnected(neighborGeom, startBox, start, JunctionCoincidenceToleranceSquare, out connectedPart, out connectedFraction)) { var jct = new Junction(thisFeature, key.TableIndex, segment.PartIndex, 0, neighborFeature, neighborTableIdx, connectedPart, connectedFraction); _junctions.Add(jct); } if (IsConnected(neighborGeom, endBox, end, JunctionCoincidenceToleranceSquare, out connectedPart, out connectedFraction)) { var jct = new Junction( thisFeature, key.TableIndex, segment.PartIndex, segmentsCount, neighborFeature, neighborTableIdx, connectedPart, connectedFraction); _junctions.Add(jct); } if (ConnectionMode == ConnectionMode.VertexOnVertex) { for (int iSegment = 1; iSegment < segmentsCount; iSegment++) { Pnt vertex = thisGeom .GetSegment(segment.PartIndex, iSegment) .GetStart(false); IBox vertexBox = new Box( new Pnt2D(vertex.X - tolerance, vertex.Y - tolerance), new Pnt2D(vertex.X + tolerance, vertex.Y + tolerance)); if (IsConnected(neighborGeom, vertexBox, vertex, JunctionCoincidenceToleranceSquare, out connectedPart, out connectedFraction)) { var jct = new Junction( thisFeature, key.TableIndex, segment.PartIndex, iSegment, neighborFeature, neighborTableIdx, connectedPart, connectedFraction); _junctions.Add(jct); } } } } } handledParts.Add(segment.PartIndex, segment); } } }