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