public void CanDetectBorderGapBackslashed() { IFeatureClass fcArea1; IFeatureClass fcArea2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcArea1, out fcArea2, out fcBorder1, out fcBorder2); // border lines are not coincident AddLineFeature(fcBorder1, -2, 2, 1, -2, stateId: "A"); AddLineFeature(fcBorder2, 1.01, -2, -1.99, 2, stateId: "B"); AddFeature(fcArea1, CurveConstruction.StartPoly(-2, 2) .LineTo(1, -2) .LineTo(-5, -10) .ClosePolygon(), stateId: "A"); // connected AddFeature(fcArea2, CurveConstruction.StartPoly(1.01, -2) .LineTo(-1.99, 2) .LineTo(5, 10) .ClosePolygon(), stateId: "B"); // connected var test = new QaEdgeMatchCrossingAreas(fcArea1, fcBorder1, fcArea2, fcBorder2, searchDistance: 0.2, boundingClasses1: null, boundingClasses2: null) { AreaClass1BorderMatchCondition = "AREA.STATE = BORDER.STATE", AreaClass2BorderMatchCondition = "AREA.STATE = BORDER.STATE", CrossingAreaMatchCondition = "AREA1.STATE <> AREA2.STATE" }; AssertUtils.ExpectedErrors(3, Run(test, 1000)); AssertUtils.ExpectedErrors(3, Run(test, 1)); var runner = new QaContainerTestRunner(1, test) { KeepGeometry = true }; runner.Execute(GeometryFactory.CreateEnvelope(-9, -4, 9, 8)); AssertUtils.ExpectedErrors(3, runner.Errors); }
public void CanDetectConnectedAndMissing() { IFeatureClass fcArea1; IFeatureClass fcArea2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcArea1, out fcArea2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 100, 0, stateId: "A"); AddLineFeature(fcBorder2, 100, 0, 0, 0, stateId: "B"); // connected to border: AddAreaFeature(fcArea1, 10, 0, 90, 5, stateId: "A"); AddAreaFeature(fcArea2, 15, -5, 30, 0, stateId: "B"); // connected AddAreaFeature(fcArea2, 30, -5, 50, 0, stateId: "B"); // connected AddAreaFeature(fcArea2, 50, -5, 80, 0, stateId: "B"); // connected var test = new QaEdgeMatchCrossingAreas(fcArea1, fcBorder1, fcArea2, fcBorder2, searchDistance: 0.5, boundingClasses1: null, boundingClasses2: null) { AreaClass1BorderMatchCondition = "AREA.STATE = BORDER.STATE", AreaClass2BorderMatchCondition = "AREA.STATE = BORDER.STATE", CrossingAreaMatchCondition = "AREA1.STATE <> AREA2.STATE" }; var expectedErrors = new Predicate <QaError>[] { e => HasCode(e, "NoMatch.NoCandidate") && HasLength(e, 10) && HasEnvelope(e, xmin: 80, xmax: 90), e => HasCode(e, "NoMatch.NoCandidate") && HasLength(e, 5) && HasEnvelope(e, xmin: 10, xmax: 15) }; AssertUtils.ExpectedErrors(2, Run(test, 1000), expectedErrors); AssertUtils.ExpectedErrors(2, Run(test, 10), expectedErrors); }
public void CanAttributeConstraintErrorsIndividually() { IFeatureClass fcPoint1; IFeatureClass fcPoint2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcPoint1, out fcPoint2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 10, 0, stateId: "A"); AddLineFeature(fcBorder2, 10, 0, 0, 0, stateId: "B"); DateTime dateValue = new DateTime(2000, 12, 31); // point on border: AddPointFeature(fcPoint1, 5, 0, "A", "Y#X", 10.001, dateValue); // point on border, exact match: AddPointFeature(fcPoint2, 5, 0, "B", "X#Y", 10.002, dateValue + TimeSpan.FromDays(1)); using (AssertUtils.UseInvariantCulture()) { var test = new QaEdgeMatchBorderingPoints(fcPoint1, fcBorder1, fcPoint2, fcBorder2, searchDistance: 0.5) { PointClass1BorderMatchCondition = "POINT.STATE = BORDER.STATE", PointClass2BorderMatchCondition = "POINT.STATE = BORDER.STATE", BorderingPointMatchCondition = "POINT1.STATE <> POINT2.STATE", BorderingPointEqualAttributes = "FLD_TEXT:#, FLD_DOUBLE, FLD_DATE", ReportIndividualAttributeConstraintViolations = true }; AssertUtils.ExpectedErrors( 2, Run(test), e => e.Description == "Values are not equal (FLD_DOUBLE:10.001,10.002)" && e.AffectedComponent == "FLD_DOUBLE" && e.IssueCode?.ID == "BorderingPoints.Match.ConstraintsNotFulfilled", e => e.Description == "Values are not equal (FLD_DATE:01/01/2001 00:00:00,12/31/2000 00:00:00)" && e.AffectedComponent == "FLD_DATE" && e.IssueCode?.ID == "BorderingPoints.Match.ConstraintsNotFulfilled"); } }
CanIgnoreWhenAllowDisjointCandidateFeatureIfAttributeConstraintsAreFulfilled() { IFeatureClass fcArea1; IFeatureClass fcArea2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcArea1, out fcArea2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 100, 0, stateId: "A"); AddLineFeature(fcBorder2, 100, -0.1, 0, -0.1, stateId: "B"); // connected to border: AddAreaFeature(fcArea1, 10, 0, 30, 5, stateId: "A", textFieldValue: "Y"); AddAreaFeature(fcArea1, 30, 0, 70, 5, stateId: "A", textFieldValue: "Y"); AddAreaFeature(fcArea1, 70, 0, 90, 5, stateId: "A", textFieldValue: "Y"); AddAreaFeature(fcArea2, 10, -5, 15, -0.1, stateId: "B", textFieldValue: "Y"); // not connected AddAreaFeature(fcArea2, 15, -5, 50, -0.1, stateId: "B", textFieldValue: "Y"); // not connected AddAreaFeature(fcArea2, 50, -5, 55, -0.1, stateId: "B", textFieldValue: "Y"); // not connected AddAreaFeature(fcArea2, 55, -5, 90, -0.1, stateId: "B", textFieldValue: "Y"); // not connected var test = new QaEdgeMatchCrossingAreas(fcArea1, fcBorder1, fcArea2, fcBorder2, 0.5, boundingClasses1: null, boundingClasses2: null) { AreaClass1BorderMatchCondition = "AREA.STATE = BORDER.STATE", AreaClass2BorderMatchCondition = "AREA.STATE = BORDER.STATE", CrossingAreaMatchCondition = "AREA1.STATE <> AREA2.STATE", CrossingAreaEqualAttributes = "FLD_TEXT", AllowDisjointCandidateFeatureIfAttributeConstraintsAreFulfilled = true }; AssertUtils.ExpectedErrors(0, Run(test, 1000)); AssertUtils.ExpectedErrors(0, Run(test, 2)); }
public void CanDetectBorderGapVertical() { IFeatureClass fcArea1; IFeatureClass fcArea2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcArea1, out fcArea2, out fcBorder1, out fcBorder2); // border lines are not coincident AddLineFeature(fcBorder1, 0, 0, 0, 10, stateId: "A"); AddLineFeature(fcBorder1, 0.7, -0.3, 10, -0.3, stateId: "A"); AddLineFeature(fcBorder2, 0.3, 10, 0.3, 0, stateId: "B"); AddLineFeature(fcBorder2, 10, 0, 0.7, 0, stateId: "B"); AddAreaFeature(fcArea1, -10, 0, 0, 10, stateId: "A"); // connected AddAreaFeature(fcArea1, 0.7, -5, 10, -0.3, stateId: "A"); // connected AddAreaFeature(fcArea2, 0.3, 0, 10, 10, stateId: "B"); // connected var test = new QaEdgeMatchCrossingAreas(fcArea1, fcBorder1, fcArea2, fcBorder2, searchDistance: 0.5, boundingClasses1: null, boundingClasses2: null) { AreaClass1BorderMatchCondition = "AREA.STATE = BORDER.STATE", AreaClass2BorderMatchCondition = "AREA.STATE = BORDER.STATE", CrossingAreaMatchCondition = "AREA1.STATE <> AREA2.STATE" }; AssertUtils.ExpectedErrors(2, Run(test, 1000)); AssertUtils.ExpectedErrors(2, Run(test, 3)); var runner = new QaContainerTestRunner(3, test) { KeepGeometry = true }; runner.Execute(GeometryFactory.CreateEnvelope(-9, -4, 9, 8)); AssertUtils.ExpectedErrors(2, runner.Errors); }
CanIgnoreWhenAllowDisjointCandidateFeatureIfAttributeConstraintsAreFulfilled() { IFeatureClass fcLine1; IFeatureClass fcLine2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; int ticks = CreateFeatureClasses(out fcLine1, out fcLine2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 100, 0, stateId: "A"); AddLineFeature(fcBorder2, 100, -0.1, 0, -0.1, stateId: "B"); // connected to border: AddLineFeature(fcLine1, 10, 0, 30, 0, stateId: "A", textFieldValue: "Y"); AddLineFeature(fcLine1, 30, 0, 70, 0, stateId: "A", textFieldValue: "Y"); AddLineFeature(fcLine1, 70, 0, 90, 0, stateId: "A", textFieldValue: "Y"); AddLineFeature(fcLine2, 10, -0.1, 15, -0.1, stateId: "B", textFieldValue: "Y"); AddLineFeature(fcLine2, 15, -0.1, 50, -0.1, stateId: "B", textFieldValue: "Y"); AddLineFeature(fcLine2, 50, -0.1, 55, -0.1, stateId: "B", textFieldValue: "Y"); AddLineFeature(fcLine2, 55, -0.1, 90, -0.1, stateId: "B", textFieldValue: "Y"); var test = new QaEdgeMatchBorderingLines(fcLine1, fcBorder1, fcLine2, fcBorder2, 0.5) { LineClass1BorderMatchCondition = "LINE.STATE = BORDER.STATE", LineClass2BorderMatchCondition = "LINE.STATE = BORDER.STATE", BorderingLineMatchCondition = "LINE1.STATE <> LINE2.STATE", BorderingLineEqualAttributes = "FLD_TEXT", AllowDisjointCandidateFeatureIfAttributeConstraintsAreFulfilled = true }; AssertUtils.ExpectedErrors(0, Run(test, 1000)); AssertUtils.ExpectedErrors(0, Run(test, 2)); }
public void CanDetectMissingPart() { IFeatureClass fcLine1; IFeatureClass fcLine2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcLine1, out fcLine2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 10, 0, stateId: "A"); AddLineFeature(fcBorder2, 10, 0, 0, 0, stateId: "B"); // connected to border: AddFeature(fcLine1, CurveConstruction.StartLine(4, 2).LineTo(4, 0) .LineTo(7, 0).LineTo(7, 2).Curve, stateId: "A"); // connected to border, exact match: AddFeature(fcLine2, CurveConstruction.StartLine(8, -2).LineTo(8, 0) .LineTo(5, 0).LineTo(5, -2).Curve, stateId: "B"); var test = new QaEdgeMatchBorderingLines(fcLine1, fcBorder1, fcLine2, fcBorder2, 0) { LineClass1BorderMatchCondition = "LINE.STATE = BORDER.STATE", LineClass2BorderMatchCondition = "LINE.STATE = BORDER.STATE", BorderingLineMatchCondition = "LINE1.STATE <> LINE2.STATE" }; AssertUtils.ExpectedErrors(2, Run(test, 1000)); AssertUtils.ExpectedErrors(2, Run(test, 5)); }
public void CanReportWithinFeature() { const string testName = "CanReportWithinFeature"; IFeatureClass lineClass = CreateFeatureClass(string.Format("{0}_near", testName), esriGeometryType.esriGeometryPolyline); var nearClasses = new List <IFeatureClass> { lineClass }; IPolycurve multipartLine = CurveConstruction.StartLine(0, 0) .LineTo(100, 0) .LineTo(101, 0) .LineTo(100, 0) .LineTo(100, 100) .Curve; GeometryUtils.Simplify(multipartLine, true, true); IFeature nearRow = lineClass.CreateFeature(); nearRow.Shape = multipartLine; nearRow.Store(); IEnvelope verificationEnvelope = GeometryFactory.CreateEnvelope(0, 0, 500, 500); var test = new QaNodeLineCoincidence(lineClass, nearClasses, 2); var runner = new QaContainerTestRunner(200, test); runner.Execute(verificationEnvelope); AssertUtils.ExpectedErrors(2, runner.Errors, "NodeLineCoincidence.NodeTooCloseToLine.WithinFeature"); }
public void CanDetectConnectedAndNotConnected() { IFeatureClass fcArea1; IFeatureClass fcArea2; IFeatureClass fcBorder1; IFeatureClass fcBorder2; CreateFeatureClasses(out fcArea1, out fcArea2, out fcBorder1, out fcBorder2); // border lines are coincident AddLineFeature(fcBorder1, 0, 0, 100, 0, stateId: "A"); AddLineFeature(fcBorder2, 40, 0, 0, 0, stateId: "B"); AddFeature(fcBorder2, CurveConstruction.StartLine(100, 0.2) .LineTo(50, 0.2) .LineTo(50, 0) .LineTo(40, 0) .Curve, stateId: "B"); // connected to border: AddAreaFeature(fcArea1, 10, 0, 90, 5, stateId: "A"); AddAreaFeature(fcArea2, 15, -5, 30, 0, stateId: "B"); // connected AddAreaFeature(fcArea2, 30, -5, 50, 0, stateId: "B"); // connected AddAreaFeature(fcArea2, 50, -5, 80, 0.2, stateId: "B"); // not connected var test = new QaEdgeMatchCrossingAreas(fcArea1, fcBorder1, fcArea2, fcBorder2, searchDistance: 0.5, boundingClasses1: null, boundingClasses2: null) { AreaClass1BorderMatchCondition = "AREA.STATE = BORDER.STATE", AreaClass2BorderMatchCondition = "AREA.STATE = BORDER.STATE", CrossingAreaMatchCondition = "AREA1.STATE <> AREA2.STATE" }; // 10-15: missing // 50-80: not coincident // 80-90: missing // TODO currently fails, revise subtraction of buffer from remainder: // When search distance is large compared to offset between borders, error // geometry of "NoCandidate" is significantly reduced, to the point that // it can become empty. // (expected values may have to be adapted, maybe not achievable as defined below) var expectedErrors = new Predicate <QaError>[] { e => HasCode(e, "NoMatch.NoCandidate") && HasLength(e, 5) && HasEnvelope(e, xmin: 10, xmax: 15), e => HasCode( e, "NoMatch.CandidateExists.BordersNotCoincident.ConstraintsFulfilled") && HasLength(e, 30 + 30.2 + 0.5) && HasEnvelope(e, xmin: 49.5, xmax: 80, ymax: 0.2), e => HasCode(e, "NoMatch.NoCandidate") && HasLength(e, 10) && HasEnvelope(e, xmin: 80, xmax: 90) }; AssertUtils.ExpectedErrors(3, Run(test, 1000), expectedErrors); AssertUtils.ExpectedErrors(3, Run(test, 10), expectedErrors); }