Exemple #1
0
        private int CheckPathEndPoints([NotNull] IFeature feature, [NotNull] IPath path)
        {
            var vertices = (IPointCollection)path;

            // TODO should use segment-based angle calculation (only for non-linear segments)

            int pointCount = vertices.PointCount;

            vertices.QueryPoint(0, _firstSegmentStartPoint);
            vertices.QueryPoint(1, _firstSegmentEndPoint);

            double firstSegmentSquaredLength =
                GeometryMathUtils.GetDistanceSquared(_firstSegmentEndPoint,
                                                     _firstSegmentStartPoint, _is3D);

            vertices.QueryPoint(pointCount - 2, _lastSegmentStartPoint);
            vertices.QueryPoint(pointCount - 1, _lastSegmentEndPoint);

            double lastSegmentSquaredLength =
                GeometryMathUtils.GetDistanceSquared(_lastSegmentStartPoint, _lastSegmentEndPoint,
                                                     _is3D);

            int  errorCount        = 0;
            int  compareTableIndex = -1;
            bool skip = IgnoreUndirected;

            foreach (var table in InvolvedTables)
            {
                var compareFeatureClass = (IFeatureClass)table;
                compareTableIndex++;
                _helper[compareTableIndex].MinimumOID = -1;

                if (feature.Table == compareFeatureClass)
                {
                    skip = false;
                    if (IgnoreUndirected)
                    {
                        _helper[compareTableIndex].MinimumOID = feature.OID;
                    }
                }

                if (skip)
                {
                    continue;
                }

                errorCount += ExecutePoint(_firstSegmentStartPoint, _firstSegmentEndPoint,
                                           firstSegmentSquaredLength,
                                           compareFeatureClass, compareTableIndex, feature);

                errorCount += ExecutePoint(_lastSegmentEndPoint, _lastSegmentStartPoint,
                                           lastSegmentSquaredLength,
                                           compareFeatureClass, compareTableIndex, feature);
            }

            return(errorCount);
        }
Exemple #2
0
        private int CheckSegments([NotNull] ISegmentCollection segments,
                                  [NotNull] IRow row)
        {
            IEnumSegment enumSegments = segments.EnumSegments;

            enumSegments.Reset();

            ISegment segment;
            int      partIndex    = -1;
            int      segmentIndex = -1;

            enumSegments.Next(out segment, ref partIndex, ref segmentIndex);
            bool recycling = enumSegments.IsRecycling;

            int errorCount = 0;

            while (segment != null)
            {
                double slopeRadians = GeometryMathUtils.CalculateSlope(segment);

                if (slopeRadians > _limit)
                {
                    string description = string.Format(
                        "Slope angle {0} > {1}", FormatAngle(slopeRadians, "N2"),
                        FormatAngle(_limit, "N2"));

                    IPolyline errorGeometry = GeometryFactory.CreatePolyline(segment);

                    errorCount += ReportError(description, errorGeometry,
                                              Codes[Code.SlopeTooSteep],
                                              TestUtils.GetShapeFieldName(row),
                                              new object[] { MathUtils.ToDegrees(slopeRadians) },
                                              row);
                }

                if (recycling)
                {
                    // release the segment, otherwise "pure virtual function call" occurs
                    // when there are certain circular arcs (IsLine == true ?)
                    Marshal.ReleaseComObject(segment);
                }

                enumSegments.Next(out segment, ref partIndex, ref segmentIndex);
            }

            return(errorCount);
        }
Exemple #3
0
        /// <summary>
        /// looks if the three input segments are smooth
        /// </summary>
        /// <param name="threeSegments">Input segments. Only the first three segments will be used.</param>
        /// <param name="row"></param>
        /// <returns>Are segments smooth?</returns>
        private int CheckThreeSegments([NotNull] IList <ISegment> threeSegments,
                                       [NotNull] IRow row)
        {
            double anglechange = GeometryMathUtils.CalculateSmoothness(threeSegments[0],
                                                                       threeSegments[1],
                                                                       threeSegments[2]);

            if (Math.Abs(anglechange) <= _limit)
            {
                return(NoError);
            }

            string description = string.Format("Smoothness parameter {0:N4} > {1:N4}",
                                               Math.Abs(anglechange), _limit);

            IGeometry errorGeometry = GetErrorGeometry(threeSegments[1]);

            return(ReportError(description, errorGeometry,
                               Codes[Code.AbruptChangeInSlopeAngle],
                               TestUtils.GetShapeFieldName(row),
                               row));
        }
Exemple #4
0
        private int CheckDistance([NotNull] IPoint p0, [NotNull] IPoint p1,
                                  [NotNull] IRow row0, int tableIndex0,
                                  [NotNull] IRow row1, int tableIndex1,
                                  bool coincidentIsError,
                                  out bool validRelationConstraintFulfilled)
        {
            double pointDistanceSquared = GeometryMathUtils.GetDistanceSquared(p0, p1, _is3D);

            validRelationConstraintFulfilled = false;

            bool isCoincident = pointDistanceSquared <= _toleranceSquared;

            if ((coincidentIsError || !isCoincident) &&
                pointDistanceSquared < _searchDistanceSquared)
            {
                if (_validRelationConstraint.IsFulfilled(row0, tableIndex0,
                                                         row1, tableIndex1))
                {
                    validRelationConstraintFulfilled = true;
                    return(NoError);
                }

                IGeometry errorGeometry = CreateErrorGeometry(p0, p1);

                double dist        = Math.Sqrt(pointDistanceSquared);
                string description = string.Format("Nodedistance {0}",
                                                   FormatLengthComparison(dist, "<",
                                                                          SearchDistance,
                                                                          p0.SpatialReference));

                IssueCode issueCode = _validRelationConstraintSql == null
                                                              ? Codes[Code.NodeDistanceTooSmall]
                                                              : Codes[Code.NodeDistanceTooSmall_ConstraintNotFulfilled];

                // TODO differentiate issue code if exactly coincident?
                return(ReportError(description, errorGeometry,
                                   issueCode, TestUtils.GetShapeFieldName(row0),
                                   InvolvedRowUtils.GetInvolvedRows(row0, row1),
                                   new object[] { dist }));
            }

            if (_maxZDifference >= 0 && pointDistanceSquared < _searchDistanceSquared)
            {
                double z0 = p0.Z;
                double z1 = p1.Z;

                double absZDifference = Math.Abs(z0 - z1);

                if (absZDifference > _maxZDifference)
                {
                    if (MathUtils.AreSignificantDigitsEqual(absZDifference, _maxZDifference))
                    {
                        // difference is not significant
                        return(NoError);
                    }

                    if (_validRelationConstraint.IsFulfilled(row0, tableIndex0,
                                                             row1, tableIndex1))
                    {
                        validRelationConstraintFulfilled = true;
                        return(NoError);
                    }

                    IGeometry errorGeometry = CreateErrorGeometry(p0, p1);

                    string description = string.Format("Z-Difference {0}",
                                                       FormatComparison(absZDifference, ">",
                                                                        _maxZDifference, "N1"));
                    IssueCode issueCode = _validRelationConstraintSql == null
                                                                      ? Codes[Code.ZDifferenceTooLarge]
                                                                      : Codes[
                        Code.ZDifferenceTooLarge_ConstraintNotFulfilled];

                    return(ReportError(description, errorGeometry,
                                       issueCode, TestUtils.GetShapeFieldName(row0),
                                       InvolvedRowUtils.GetInvolvedRows(row0, row1),
                                       new object[] { absZDifference }));
                }
            }

            return(NoError);
        }