Exemplo n.º 1
0
        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;
                }
            }
        }
Exemplo n.º 2
0
        private int PartCoincidenceErrors([NotNull] IRow row0,
                                          [NotNull] IRow row1,
                                          [NotNull] SubClosedCurve connected,
                                          double near,
                                          double minLength,
                                          bool isDisjoint = false)
        {
            double length = connected.GetLength();

            if (length <= minLength)
            {
                return(NoError);
            }

            IGeometry shape0 = ((IFeature)row0).Shape;
            IGeometry shape1 = ((IFeature)row1).Shape;

            bool isWithinFeature = row0 == row1;
            bool zAware          = ((IZAware)shape0).ZAware &&
                                   ((IZAware)shape1).ZAware;

            IPolyline errorGeometry = CreatePolyline(connected, zAware);

            // NOTE there can be multiple paths in the error geometry, when the curve touches itself
            // see https://issuetracker02.eggits.net/browse/COM-47

            var errorCount = 0;

            string shapeFieldName = ((IFeatureClass)((IFeature)row0).Class).ShapeFieldName;

            foreach (IPath errorPath in GeometryUtils.GetPaths(errorGeometry))
            {
                if (errorPath.Length < minLength)
                {
                    continue;
                }

                IPolyline errorPartGeometry = CreateErrorGeometry(errorPath, zAware);

                ISpatialReference    spatialReference = shape0.SpatialReference;
                ICollection <object> values;
                string description = UsesConstantNearTolerance
                                                             ? GetShortDescription(minLength, errorPartGeometry,
                                                                                   spatialReference, out values)
                                                             : GetExtendedDescription(minLength, near,
                                                                                      errorPartGeometry,
                                                                                      spatialReference,
                                                                                      shape0, shape1,
                                                                                      isDisjoint, isWithinFeature,
                                                                                      out values);

                errorCount += isWithinFeature
                                                      ? ReportError(description, errorGeometry,
                                                                    Codes[Code.NearlyCoincidentSection_WithinFeature],
                                                                    shapeFieldName, values,
                                                                    row0)
                                                      : ReportError(description, errorGeometry,
                                                                    Codes[Code.NearlyCoincidentSection_BetweenFeatures],
                                                                    shapeFieldName, values,
                                                                    row0, row1);
            }

            return(errorCount);
        }
Exemplo n.º 3
0
        private int CheckPartCoincidence([NotNull] IRow row0, [NotNull] IRow row1,
                                         [NotNull] IList <SubClosedCurve> nearCurves,
                                         [NotNull] IList <SubClosedCurve> coincidentCurves,
                                         bool nearSelf,
                                         double near,
                                         double connectedMinLength, double disjointMinLength)
        {
            if (nearCurves.Count == 0)
            {
                return(NoError);
            }

            IList <SubClosedCurve> disjointCurves  = new List <SubClosedCurve>(nearCurves.Count);
            IList <SubClosedCurve> connectedCurves = new List <SubClosedCurve>(nearCurves.Count);

            // Find and handle disjoint subcurves
            foreach (SubClosedCurve nearCurve in nearCurves)
            {
                if (nearSelf)
                {
                    connectedCurves.Add(nearCurve);
                    continue;
                }

                SubClosedCurve within = null;
                foreach (SubClosedCurve candidate in coincidentCurves)
                {
                    if (nearCurve.IsWithin(candidate))
                    {
                        within = candidate;
                        break;
                    }
                }

                if (within == null)
                {
                    disjointCurves.Add(nearCurve);
                }
                else
                {
                    connectedCurves.Add(nearCurve);
                }
            }

            var errorCount = 0;

            foreach (SubClosedCurve disjointCurve in disjointCurves)
            {
                errorCount += PartCoincidenceErrors(row0, row1, disjointCurve,
                                                    near, disjointMinLength,
                                                    true);
            }

            // Handle connected curves

            double coincidenceMinLength = _coincidenceTolerance * connectedMinLength / near;

            coincidentCurves = GetLongSubcurves(coincidentCurves, coincidenceMinLength);
            foreach (SubClosedCurve coincidentCurve in coincidentCurves)
            {
                SubClosedCurve surround = null;
                foreach (SubClosedCurve candidate in connectedCurves)
                {
                    if (candidate.IsWithin(coincidentCurve))
                    {
                        surround = candidate;
                        break;
                    }
                }

                if (surround == null)
                {
                    // surrounding curve is < _connectedMinLength and was filtered away.
                    continue;
                }

                connectedCurves.Remove(surround);

                if (surround.IsCompleteClosedPart())
                {
                    if (coincidentCurve.IsCompleteClosedPart())
                    {
                        continue;
                    }

                    var rest = new SubClosedCurve(surround.BaseGeometry,
                                                  surround.PartIndex, coincidentCurve.EndFullIndex,
                                                  coincidentCurve.StartFullIndex);
                    if (rest.GetLength() >= connectedMinLength)
                    {
                        connectedCurves.Add(rest);
                    }

                    continue;
                }

                var pre = new SubClosedCurve(surround.BaseGeometry,
                                             surround.PartIndex, surround.StartFullIndex,
                                             coincidentCurve.StartFullIndex);
                if (pre.GetLength() >= connectedMinLength)
                {
                    connectedCurves.Add(pre);
                }

                var post = new SubClosedCurve(surround.BaseGeometry,
                                              surround.PartIndex, coincidentCurve.EndFullIndex,
                                              surround.EndFullIndex);
                if (post.GetLength() >= connectedMinLength)
                {
                    connectedCurves.Add(post);
                }
            }

            foreach (SubClosedCurve connectedCurve in connectedCurves)
            {
                errorCount += PartCoincidenceErrors(row0, row1, connectedCurve,
                                                    near, connectedMinLength);
            }

            return(errorCount);
        }