protected override int FindErrors(IRow row1, int tableIndex1, IRow row2, int tableIndex2) { if (row1 == row2) { return(NoError); } var polyline1 = (IPolyline)((IFeature)row1).Shape; var polyline2 = (IPolyline)((IFeature)row2).Shape; if (((IRelationalOperator)polyline1).Disjoint(polyline2)) { return(NoError); } var errorCount = 0; foreach ( LineIntersection intersection in LineIntersectionUtils.GetIntersections(polyline1, polyline2, _is3D)) { if (Math.Abs(intersection.DistanceAlongA) < double.Epsilon || Math.Abs(intersection.DistanceAlongA - 1.0) < double.Epsilon) { continue; } if (Math.Abs(intersection.DistanceAlongB) < double.Epsilon || Math.Abs(intersection.DistanceAlongB - 1.0) < double.Epsilon) { continue; } double angleRadians = intersection.Angle; if (angleRadians >= _limit) { // angle is allowed continue; } // The angle is smaller than limit. Report error string description = string.Format("Intersect angle {0} < {1}", FormatAngle(angleRadians, "N2"), FormatAngle(_limit, "N2")); errorCount += ReportError(description, GeometryFactory.Clone(intersection.At), Codes[Code.IntersectionAngleSmallerThanLimit], TestUtils.GetShapeFieldName(row1), new object[] { MathUtils.ToDegrees(angleRadians) }, row1, row2); } return(errorCount); }
protected override int FindErrors(IRow row1, int tableIndex1, IRow row2, int tableIndex2) { if (row1 == row2) { // self intersections are better tested with QaSimpleGeometry return(NoError); } var polyline1 = (IPolyline)((IFeature)row1).Shape; var polyline2 = (IPolyline)((IFeature)row2).Shape; double vertexIntersectionTolerance = GetVertexIntersectionTolerance( tableIndex1, tableIndex2, _allowedEndpointInteriorIntersections); IPoint knownInvalidIntersection = null; if (_allowedEndpointInteriorIntersections != AllowedEndpointInteriorIntersections.All) { if (!LineIntersectionUtils.HasInvalidIntersection( polyline1, polyline2, _allowedEndpointInteriorIntersections, _reportOverlaps, _pointTemplate1, _pointTemplate2, vertexIntersectionTolerance, out knownInvalidIntersection)) { return(NoError); } } const string description = "Intersection"; string formattedMessage; if (HasFulfilledConstraint(row1, tableIndex1, row2, tableIndex2, description, out formattedMessage)) { return(NoError); } IGeometry errorGeometry = LineIntersectionUtils.GetInvalidIntersections( polyline1, polyline2, _allowedEndpointInteriorIntersections, AllowedInteriorIntersections, _reportOverlaps, vertexIntersectionTolerance); if (errorGeometry.IsEmpty && knownInvalidIntersection != null) { errorGeometry = knownInvalidIntersection; } IssueCode issueCode = _validRelationConstraintSql == null ? Codes[Code.InvalidLineIntersection] : Codes[Code.InvalidLineIntersection_ConstraintNotFulfilled]; return(ReportIntersections(formattedMessage, errorGeometry, issueCode, row1, row2)); }