public void CanCheckPolygonFastEnough() { IPolygon area = GeometryFactory.CreatePolygon(0, 0, 10, 10); var constraint = new GeometryConstraint("$AREA > 50 AND $LENGTH > 30 AND " + "$SLIVERRATIO < 100 AND NOT $ISMULTIPART AND " + "$PARTCOUNT = 1 AND $VERTEXCOUNT = 5 AND " + "$SEGMENTCOUNT = 4 AND $ELLIPTICARCCOUNT = 0"); var watch = new Stopwatch(); watch.Start(); const int count = 10000; for (var i = 0; i < count; i++) { Assert.True(constraint.IsFulfilled(area)); } watch.Stop(); long milliseconds = watch.ElapsedMilliseconds; Console.WriteLine(@"{0} s for {1:N0} operations", milliseconds / 1000d, count); double millisecondsPerOperation = (double)milliseconds / count; Console.WriteLine(@"{0} ms per operation", millisecondsPerOperation); const double maximumMilliseconds = 0.15; Assert.LessOrEqual(millisecondsPerOperation, maximumMilliseconds); }
public static int ReportIntersections( [NotNull] IRow row1, int tableIndex1, [NotNull] IRow row2, int tableIndex2, [NotNull] IErrorReporting errorReporting, [CanBeNull] IssueCode issueCode, [CanBeNull] IValidRelationConstraint validRelationConstraint, bool reportIndividualParts, [CanBeNull] GeometryConstraint validIntersectionGeometryConstraint = null, GeometryComponent geomComponent1 = GeometryComponent.EntireGeometry, GeometryComponent geomComponent2 = GeometryComponent.EntireGeometry) { Assert.ArgumentNotNull(row1, nameof(row1)); Assert.ArgumentNotNull(row2, nameof(row2)); Assert.ArgumentNotNull(errorReporting, nameof(errorReporting)); if (row1 == row2) { return(_noError); } string errorDescription; if (HasFulfilledConstraint(row1, tableIndex1, row2, tableIndex2, validRelationConstraint, "Features intersect", out errorDescription)) { return(_noError); } IGeometry shape1 = ((IFeature)row1).Shape; IGeometry shape2 = ((IFeature)row2).Shape; var g1 = GeometryComponentUtils.GetGeometryComponent(shape1, geomComponent1); var g2 = GeometryComponentUtils.GetGeometryComponent(shape2, geomComponent2); var errorCount = 0; if (g1 != null && g2 != null) { foreach (IGeometry errorGeometry in IntersectionUtils.GetAllIntersections(g1, g2)) { if (validIntersectionGeometryConstraint == null || !validIntersectionGeometryConstraint.IsFulfilled(errorGeometry)) { errorCount += errorReporting.Report(errorDescription, errorGeometry, issueCode, reportIndividualParts, row1, row2); } } } return(errorCount); }
private static bool IsFulfilled([NotNull] string expression, [CanBeNull] IGeometry geometry, [NotNull] out string values) { var constraint = new GeometryConstraint(expression); values = constraint.FormatValues(geometry, CultureInfo.InvariantCulture); return(constraint.IsFulfilled(geometry)); }
private int CheckParts([NotNull] IFeature feature, [NotNull] IGeometryCollection parts) { Assert.ArgumentNotNull(feature, nameof(feature)); Assert.ArgumentNotNull(parts, nameof(parts)); var errorCount = 0; foreach (IGeometry part in GeometryUtils.GetParts(parts)) { if (!_constraint.IsFulfilled(part)) { errorCount += ReportError(feature, part, isPart: true); } } return(errorCount); }
public int ReportErrors([NotNull] IFeature feature1, int tableIndex1, [NotNull] IFeature feature2, int tableIndex2, [NotNull] IErrorReporting reportError, [CanBeNull] IssueCode issueCode, bool reportIndividualErrors) { Assert.ArgumentNotNull(feature1, nameof(feature1)); Assert.ArgumentNotNull(feature2, nameof(feature2)); Assert.ArgumentNotNull(reportError, nameof(reportError)); if (feature1 == feature2) { return(0); } string conditionMessage; if (IsFulfilled(feature1, tableIndex1, feature2, tableIndex2, out conditionMessage)) { // currently: no error, even if intersection geometry constraint would be violated // (parameter for constraint combination operation could be added) return(0); } // geometries of multiple dimensions possible var errorCount = 0; foreach (IGeometry geometry in GetIntersections(feature1, feature2)) { foreach (IGeometry reportableGeometry in GetGeometries(geometry, reportIndividualErrors)) { if (_validIntersectionDimensions != null && _validIntersectionDimensions.Contains(reportableGeometry.Dimension)) { continue; } if (_intersectionGeometryConstraint != null) { if (_intersectionGeometryConstraint.IsFulfilled(reportableGeometry)) { continue; } string displayValues = _intersectionGeometryConstraint.FormatValues(reportableGeometry, CultureInfo.CurrentCulture) .Replace("$", string.Empty); string rawValues = _intersectionGeometryConstraint.FormatValues(reportableGeometry, CultureInfo .InvariantCulture); // format for display to the user (current culture) string description = GetErrorDescription( conditionMessage, _intersectionGeometryConstraint.Constraint.Replace("$", string.Empty), displayValues); errorCount += reportError.Report(description, reportableGeometry, issueCode, null, new object[] { rawValues }, feature1, feature2); } else { string description = GetErrorDescription(conditionMessage); errorCount += reportError.Report(description, reportableGeometry, issueCode, null, feature1, feature2); } } } return(errorCount); }
public static int ReportTouches( [NotNull] IRow row1, int tableIndex1, [NotNull] IRow row2, int tableIndex2, [NotNull] IErrorReporting errorReporting, [CanBeNull] IssueCode issueCode, [CanBeNull] IValidRelationConstraint validRelationConstraint, [CanBeNull] GeometryConstraint validTouchGeometryConstraint, bool reportIndividualParts = false) { Assert.ArgumentNotNull(row1, nameof(row1)); Assert.ArgumentNotNull(row2, nameof(row2)); Assert.ArgumentNotNull(errorReporting, nameof(errorReporting)); if (row1 == row2) { return(_noError); } IGeometry g1 = ((IFeature)row1).Shape; IGeometry g2 = ((IFeature)row2).Shape; string errorDescription; if (HasFulfilledConstraint(row1, tableIndex1, row2, tableIndex2, validRelationConstraint, "Geometries touch", out errorDescription)) { return(_noError); } var errorCount = 0; foreach (IGeometry geometry in GetTouches(g1, g2)) { if (geometry.IsEmpty) { continue; } if (reportIndividualParts) { foreach (IGeometry part in GeometryUtils.Explode(geometry)) { if (part.IsEmpty || validTouchGeometryConstraint != null && validTouchGeometryConstraint.IsFulfilled(part)) { continue; } errorCount += errorReporting.Report(errorDescription, part, issueCode, false, // already exploded row1, row2); } } else { if (validTouchGeometryConstraint != null && validTouchGeometryConstraint.IsFulfilled(geometry)) { continue; } errorCount += errorReporting.Report(errorDescription, geometry, issueCode, false, row1, row2); } } return(errorCount); }