private static void CompareSegmentAngles( [NotNull] IList <double> sourceAngles, [NotNull] IList <double> transformedAngles, double maxSegmentAngleDifferenceRadians, double ignoredAngleValue, [NotNull] IFeature transformedFeature, [NotNull] IPointCollection transformedPoints, [NotNull] IIssueReporter issueReporter) { Assert.AreEqual(sourceAngles.Count, transformedAngles.Count, "Differing number of segment angles. Source: {0} Transformed: {1}", sourceAngles.Count, transformedAngles.Count); var ignoredVertices = new List <int>(); var isClosedEvaluator = new IsClosedEvaluator(transformedPoints); int lastVertexIndex = sourceAngles.Count - 1; for (var vertexIndex = 0; vertexIndex <= lastVertexIndex; vertexIndex++) { double sourceAngle = sourceAngles[vertexIndex]; double transformedAngle = transformedAngles[vertexIndex]; if (Math.Abs(sourceAngle - ignoredAngleValue) < double.Epsilon) { ignoredVertices.Add(vertexIndex); continue; } double difference = Math.Abs(sourceAngle - transformedAngle); if (difference > maxSegmentAngleDifferenceRadians) { // ignore the angle difference if this is the last vertex, and its angle is // equal to the first vertex, and the points form a closed loop bool ignoreDifference = vertexIndex == lastVertexIndex && Math.Abs(transformedAngle - transformedAngles[0]) < double.Epsilon && isClosedEvaluator.IsClosed; if (!ignoreDifference) { IGeometry errorGeometry = GetErrorGeometry( vertexIndex, ignoredVertices, transformedPoints, isClosedEvaluator, sourceAngles, ignoredAngleValue); string description = string.Format( "Segment angle difference exceeds limit: {0}°", MathUtils.ToDegrees(difference)); issueReporter.Report(transformedFeature, errorGeometry, description); } } if (ignoredVertices.Count > 0) { ignoredVertices.Clear(); } } }
private static IGeometry GetErrorGeometry( int vertexIndex, [NotNull] ICollection <int> ignoredVertices, [NotNull] IPointCollection transformedPoints, [NotNull] IsClosedEvaluator isClosedEvaluator, IList <double> sourceAngles, double ignoredAngleValue) { if (ignoredVertices.Count <= 0) { return(transformedPoints.Point[vertexIndex]); } List <IPoint> points = ignoredVertices.Select( index => transformedPoints.Point[index]) .ToList(); if (ignoredVertices.Contains(0) && isClosedEvaluator.IsClosed) { // the first vertex is ignored, and the path is closed // --> check if there are ignored vertices at the end of the path which should be added int lastVertexIndexBeforeEndpoint = transformedPoints.PointCount - 2; if (Math.Abs(sourceAngles[lastVertexIndexBeforeEndpoint] - ignoredAngleValue) < double.Epsilon) { // the vertex before the end vertex is also ignored // --> add the ending sequence of ignored vertices to the list for (int vertexIndexFromEnd = lastVertexIndexBeforeEndpoint; vertexIndexFromEnd >= 0; vertexIndexFromEnd--) { if (Math.Abs(sourceAngles[vertexIndexFromEnd] - ignoredAngleValue) > double.Epsilon) { // the vertex is not ignored --> stop here break; } if (ignoredVertices.Contains(vertexIndexFromEnd)) { // the end sequence overlaps the start sequence // --> apparently all vertices are ignored break; } // add the ignored vertex from the end sequence points.Add(transformedPoints.Point[vertexIndexFromEnd]); } } } points.Add(transformedPoints.Point[vertexIndex]); return(GeometryFactory.CreateMultipoint(points)); }