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); }
protected override int ExecuteCore(IRow row, int tableIndex) { if (tableIndex > 0) { return(NoError); } if (_filter == null) { InitFilter(); } ISpatialFilter filter = Assert.NotNull(_filter, "_filter"); var processed0 = new SegmentNeighbors(new SegmentPartComparer()); IGeometry geom0 = ((IFeature)row).Shape; IEnvelope box0 = geom0.Envelope; box0.Expand(SearchDistance, SearchDistance, false); filter.Geometry = box0; var errorCount = 0; double maxNear = SearchDistance; const int neighborTableIndex = 1; IFeatureRowsDistance rowsDistance = NearDistanceProvider.GetRowsDistance(row, tableIndex); foreach (IRow neighborRow in Search((ITable)_reference, filter, _helper, geom0)) { var rowNeighbor = (IFeature)neighborRow; if (IgnoreNeighbor(row, neighborRow)) { continue; } SegmentNeighbors processed1; var neighborKey = new RowKey(rowNeighbor, neighborTableIndex); if (!ProcessedList.TryGetValue(neighborKey, out processed1)) { processed1 = new SegmentNeighbors(new SegmentPartComparer()); ProcessedList.Add(neighborKey, processed1); } NeighborhoodFinder finder = GetNeighborhoodFinder(rowsDistance, (IFeature)row, tableIndex, rowNeighbor, neighborTableIndex); errorCount += FindNeighborhood(finder, tableIndex, processed0, neighborTableIndex, processed1, maxNear); } 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); }
public NearNeighborhoodFinder( [NotNull] IFeatureRowsDistance rowsDistance, [NotNull] IFeature feature, int tableIndex, [CanBeNull] IFeature neighbor, int neighborTableIndex, SegmentNeighbors coincidentParts, double coincidenceTolerance, double coincidenceToleranceSquared, bool is3D) : base(rowsDistance, feature, tableIndex, neighbor, neighborTableIndex) { _coincidentParts = coincidentParts; _coincidenceTolerance = coincidenceTolerance; _coincidenceToleranceSquared = coincidenceToleranceSquared; _is3D = is3D; }
protected override int ExecuteCore(IRow row, int tableIndex) { if (tableIndex != 0) { return(NoError); } if (_spatialFilters == null) { InitFilter(); } IList <ISpatialFilter> filters = Assert.NotNull(_spatialFilters); // iterating over all needed tables int neighborTableIndex = -1; IGeometry geom0 = ((IFeature)row).Shape; geom0.QueryEnvelope(_queryBox); SegmentNeighbors processed0; var rowKey = new RowKey(row, tableIndex); if (!ProcessedList.TryGetValue(rowKey, out processed0)) { // add to process List processed0 = new SegmentNeighbors(new SegmentPartComparer()); ProcessedList.Add(rowKey, processed0); } _queryBox.Expand(SearchDistance, SearchDistance, false); double maxNear = SearchDistance; IFeatureRowsDistance rowsDistance = NearDistanceProvider.GetRowsDistance(row, tableIndex); foreach (IFeatureClass neighborFeatureClass in _referenceList) { neighborTableIndex++; ISpatialFilter spatialFilter = filters[neighborTableIndex]; spatialFilter.Geometry = _queryBox; var neighborTable = (ITable)neighborFeatureClass; foreach (IRow neighborRow in Search(neighborTable, spatialFilter, _helperList[neighborTableIndex], geom0)) { if (IgnoreNeighbor(row, neighborRow, neighborTableIndex)) { continue; } var neighborFeature = (IFeature)neighborRow; var processed1 = new SegmentNeighbors(new SegmentPartComparer()); var finder = new FullNeighborhoodFinder( rowsDistance, (IFeature)row, tableIndex, neighborFeature, neighborTableIndex); FindNeighborhood(finder, tableIndex, processed0, neighborTableIndex, processed1, maxNear); } } // Remark: here only the neighborhood properties are found // if these properties are correct is checked in OnProgressedChanged return(NoError); }
protected override bool VerifyContinue(SegmentProxy seg0, SegmentProxy seg1, SegmentNeighbors processed1, SegmentParts partsOfSeg0, bool coincident) { return(true); }
protected override int ExecuteCore(IRow row, int tableIndex) { if (tableIndex > 0) { return(NoError); } var feature = row as IFeature; if (feature == null) { return(NoError); } if (_filter == null) { InitFilter(); Assert.NotNull(_filter, "_filter"); } var processed0 = new SegmentNeighbors(new SegmentPartComparer()); IGeometry geom0 = feature.Shape; IEnvelope box0 = geom0.Envelope; const bool asRatio = false; box0.Expand(SearchDistance, SearchDistance, asRatio); ISpatialFilter filter = Assert.NotNull(_filter); filter.Geometry = box0; var errorCount = 0; double maxNear = SearchDistance; const int referenceTableIndex = 0; IFeatureRowsDistance rowsDistance = NearDistanceProvider.GetRowsDistance(feature, tableIndex); foreach (IRow neighborRow in Search((ITable)_reference, filter, _helper, geom0)) { var neighborFeature = (IFeature)neighborRow; if (neighborFeature == feature) { continue; } // TODO apply comparison condition to filter out irrelevant pairs if (IgnoreNeighbor(row, neighborRow)) { continue; } SegmentNeighbors processed1; var neighborKey = new RowKey(neighborFeature, referenceTableIndex); if (!ProcessedList.TryGetValue(neighborKey, out processed1)) { processed1 = new SegmentNeighbors(new SegmentPartComparer()); ProcessedList.Add(neighborKey, processed1); } NeighborhoodFinder finder = new NotNearNeighborhoodFinder( rowsDistance, feature, tableIndex, neighborFeature, referenceTableIndex); errorCount += FindNeighborhood(finder, tableIndex, processed0, referenceTableIndex, processed1, maxNear); } return(errorCount); }
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); } }