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);
        }
示例#3
0
        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);
        }
示例#6
0
        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));
        }
示例#7
0
        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));
        }
示例#8
0
        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);
        }