Ejemplo n.º 1
0
        public static int ReportDuplicates(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [NotNull] IErrorReporting errorReporting,
            [CanBeNull] IssueCode issueCode,
            [CanBeNull] IValidRelationConstraint validRelationConstraint)
        {
            Assert.ArgumentNotNull(row1, nameof(row1));
            Assert.ArgumentNotNull(row2, nameof(row2));
            Assert.ArgumentNotNull(errorReporting, nameof(errorReporting));

            string errorDescription;

            if (!AreDuplicates(row1, tableIndex1,
                               row2, tableIndex2,
                               validRelationConstraint,
                               out errorDescription))
            {
                return(_noError);
            }

            IGeometry errorGeometry = ((IFeature)row1).ShapeCopy;

            const bool reportIndividualParts = false;

            return(errorReporting.Report(errorDescription,
                                         errorGeometry, issueCode,
                                         reportIndividualParts,
                                         row1, row2));
        }
Ejemplo n.º 2
0
        public static bool AreDuplicates(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [CanBeNull] IValidRelationConstraint validRelationConstraint,
            [NotNull] out string errorDescription)
        {
            Assert.ArgumentNotNull(row1, nameof(row1));
            Assert.ArgumentNotNull(row2, nameof(row2));

            if (row1 == row2)
            {
                errorDescription = string.Empty;
                return(false);
            }

            IGeometry g1 = ((IFeature)row1).Shape;
            IGeometry g2 = ((IFeature)row2).Shape;

            // equal if all corresponding vertices are within xy tolerance - z is ignored
            if (!GeometryUtils.AreEqualInXY(g1, g2))
            {
                errorDescription = string.Empty;
                return(false);
            }

            return(!HasFulfilledConstraint(row1, tableIndex1,
                                           row2, tableIndex2,
                                           validRelationConstraint, "Geometries are equal",
                                           out errorDescription));
        }
Ejemplo n.º 3
0
        private static bool HasFulfilledConstraint(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [CanBeNull] IValidRelationConstraint validRelationConstraint,
            [NotNull] string message,
            [NotNull] out string formattedMessage)
        {
            Assert.ArgumentNotNull(row1, nameof(row1));
            Assert.ArgumentNotNull(row2, nameof(row2));
            Assert.ArgumentNotNullOrEmpty(message, nameof(message));

            if (validRelationConstraint == null || !validRelationConstraint.HasConstraint)
            {
                formattedMessage = message;
                return(false);
            }

            string conditionMessage;

            if (validRelationConstraint.IsFulfilled(row1, tableIndex1,
                                                    row2, tableIndex2,
                                                    out conditionMessage))
            {
                formattedMessage = string.Empty;
                return(true);
            }

            formattedMessage =
                $"{message} and constraint is not fulfilled: {conditionMessage}";

            return(false);
        }
Ejemplo n.º 4
0
        private int ReportError([NotNull] IFeature pointFeature,
                                [NotNull] IFeature referenceFeature,
                                [NotNull] IPoint point,
                                [NotNull] IPoint nearPoint,
                                double distance,
                                double minimumDistance, bool isWithinPolygon,
                                GeometryComponent geometryComponent,
                                [CanBeNull] IValidRelationConstraint validConstraint)
        {
            IssueCode issueCode;
            string    description;
            IGeometry errorGeometry;

            if (isWithinPolygon)
            {
                description   = "Point lies within polygon";
                errorGeometry = GeometryFactory.Clone(point);

                issueCode = validConstraint == null
                                                    ? Codes[Code.PointWithin]
                                                    : Codes[Code.PointWithin_ConstraintNotFulfilled];
            }
            else
            {
                if (geometryComponent == GeometryComponent.EntireGeometry)
                {
                    description =
                        string.Format(
                            "Point is too close to reference feature: {0}",
                            FormatLengthComparison(distance, "<", minimumDistance,
                                                   _spatialReference));
                }
                else
                {
                    description =
                        string.Format(
                            "Point is too close to {0} of reference feature: {1}",
                            GeometryComponentUtils.GetDisplayText(geometryComponent),
                            FormatLengthComparison(distance, "<", minimumDistance,
                                                   _spatialReference));
                }

                bool reportAsConnectionLine = MinimumErrorLineLength >= 0 &&
                                              distance >= MinimumErrorLineLength;

                errorGeometry =
                    GetErrorGeometry(point, nearPoint, reportAsConnectionLine);

                issueCode = validConstraint == null
                                                    ? Codes[Code.PointTooClose]
                                                    : Codes[Code.PointTooClose_ConstraintNotFulfilled];
            }

            return(ReportError(description, errorGeometry,
                               issueCode, _shapeFieldName,
                               pointFeature, referenceFeature));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        protected override int FindErrors(IRow row1, int tableIndex1,
                                          IRow row2, int tableIndex2)
        {
            var feature1 = row1 as IFeature;
            var feature2 = row2 as IFeature;

            if (feature1 == null || feature2 == null)
            {
                return(NoError);
            }

            if (!_vertexCoincidenceChecker.VerifyWithinFeature && (feature1 == feature2))
            {
                return(NoError);
            }

            if (_allowedNonCoincidenceConditionSql != null && (feature1 != feature2))
            {
                if (_allowedNonCoincidenceCondition == null)
                {
                    const bool constraintIsDirected = false;
                    _allowedNonCoincidenceCondition = new ValidRelationConstraint(
                        _allowedNonCoincidenceConditionSql,
                        constraintIsDirected,
                        GetSqlCaseSensitivity());
                }

                string conditionMessage;
                if (_allowedNonCoincidenceCondition.IsFulfilled(row1, tableIndex1,
                                                                row2, tableIndex2,
                                                                out conditionMessage))
                {
                    // non-coincidence is allowed between these two features
                    return(NoError);
                }
            }

            if (_pointsEnumerator == null || _pointsEnumerator.Feature != feature1)
            {
                _pointsEnumerator = PointsEnumeratorFactory.Create(feature1,
                                                                   _pointSearchEnvelope);
            }

            return(_vertexCoincidenceChecker.CheckCoincidence(_pointsEnumerator, feature2));
        }
Ejemplo n.º 7
0
        protected override int FindErrors(IRow row1, int tableIndex1, IRow row2,
                                          int tableIndex2)
        {
            if (_validRelationConstraint == null)
            {
                const bool constraintIsDirected = true;
                _validRelationConstraint = new ValidRelationConstraint(
                    _validRelationConstraintSql,
                    constraintIsDirected,
                    GetSqlCaseSensitivity());
            }

            return(QaSpatialRelationUtils.ReportTouches(row1, tableIndex1,
                                                        row2, tableIndex2,
                                                        this, GetIssueCode(),
                                                        _validRelationConstraint,
                                                        _validTouchGeometryConstraint,
                                                        reportIndividualParts: true));
        }
Ejemplo n.º 8
0
        protected override int FindErrors(IRow row1, int tableIndex1,
                                          IRow row2, int tableIndex2)
        {
            if (_validRelationConstraint == null)
            {
                const bool constraintIsDirected = true;
                _validRelationConstraint = new ValidRelationConstraint(
                    _validRelationConstraintSql, constraintIsDirected,
                    GetSqlCaseSensitivity());
            }

            return(QaSpatialRelationUtils.ReportIntersections(
                       row1, tableIndex1,
                       row2, tableIndex2,
                       this, GetIssueCode(),
                       _validRelationConstraint,
                       !ReportIntersectionsAsMultipart,
                       _validIntersectionGeometryConstraint));
        }
Ejemplo n.º 9
0
        public static int ReportOverlaps(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [NotNull] IErrorReporting errorReporting,
            [CanBeNull] IssueCode issueCode,
            [CanBeNull] IValidRelationConstraint validRelationConstraint,
            bool reportIndividualParts)
        {
            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, "Features overlap",
                                       out errorDescription))
            {
                return(_noError);
            }

            IGeometry intersection = TestUtils.GetOverlap(g1, g2);

            if (intersection.IsEmpty)
            {
                Marshal.ReleaseComObject(intersection);
                return(_noError);
            }

            return(errorReporting.Report(errorDescription,
                                         intersection, issueCode,
                                         reportIndividualParts,
                                         row1, row2));
        }
Ejemplo n.º 10
0
        protected override int FindErrors(IRow row1, int tableIndex1,
                                          IRow row2, int tableIndex2)
        {
            if (_validRelationConstraint == null)
            {
                const bool constraintIsDirected = true;
                _validRelationConstraint = new ValidRelationConstraint(
                    _validRelationConstraintSql,
                    constraintIsDirected,
                    GetSqlCaseSensitivity());
            }

            const bool reportIndividualErrors = false;

            return(QaSpatialRelationUtils.ReportOverlaps(row1, tableIndex1,
                                                         row2, tableIndex2,
                                                         this, GetIssueCode(),
                                                         _validRelationConstraint,
                                                         reportIndividualErrors));
        }
Ejemplo n.º 11
0
        protected override int FindErrors(IRow row1, int tableIndex1,
                                          IRow row2, int tableIndex2)
        {
            if (_validRelationConstraint == null)
            {
                const bool constraintIsDirected = false;
                _validRelationConstraint = new ValidRelationConstraint(
                    _validRelationConstraintSql, constraintIsDirected,
                    GetSqlCaseSensitivity());
            }

            if (!_reportSingleErrorPerDuplicateSet)
            {
                return(QaSpatialRelationUtils.ReportDuplicates(row1, tableIndex1,
                                                               row2, tableIndex2,
                                                               this, GetIssueCode(),
                                                               _validRelationConstraint));
            }

            int oid1 = row1.OID;
            int oid2 = row2.OID;

            if (!IsKnownDuplicate(oid1, oid2))
            {
                string errorDescription;
                if (QaSpatialRelationUtils.AreDuplicates(
                        row1, tableIndex1,
                        row2, tableIndex2,
                        _validRelationConstraint,
                        out errorDescription))
                {
                    AddDuplicate(oid1, oid2);
                }
            }

            // duplicates will be reported at end
            return(NoError);
        }
Ejemplo n.º 12
0
        private bool HasFulfilledConstraint([NotNull] IRow row1, int tableIndex1,
                                            [NotNull] IRow row2, int tableIndex2,
                                            [NotNull] string description,
                                            [NotNull] out string formattedMessage)
        {
            // TODO consider consolidating with QaSpatialRelationUtils.HasFulfilledConstraint()

            if (_validRelationConstraintSql == null)
            {
                formattedMessage = description;
                return(false);
            }

            if (_validRelationConstraint == null)
            {
                const bool constraintIsDirected = false;
                _validRelationConstraint =
                    new ValidRelationConstraint(_validRelationConstraintSql,
                                                constraintIsDirected,
                                                GetSqlCaseSensitivity());
            }

            string conditionMessage;

            if (_validRelationConstraint.IsFulfilled(row1, tableIndex1,
                                                     row2, tableIndex2,
                                                     out conditionMessage))
            {
                formattedMessage = string.Empty;
                return(true);
            }

            formattedMessage = string.Format("{0} and constraint is not fulfilled: {1}",
                                             description, conditionMessage);
            return(false);
        }
Ejemplo n.º 13
0
        private int CheckTable([NotNull] IFeature feature,
                               [NotNull] IFeatureClass referenceClass,
                               int referenceClassIndex)
        {
            GeometryComponent geometryComponent =
                GetGeometryComponent(referenceClassIndex);

            IValidRelationConstraint validConstraint =
                GetValidRelationConstraint(referenceClassIndex);

            if (_pointTemplate == null)
            {
                _pointTemplate = new PointClass();
            }

            var errorCount = 0;

            foreach (IPoint point in GetNodes(feature.Shape, _pointTemplate))
            {
                ISpatialFilter    filter = PrepareSpatialFilter(point, referenceClassIndex);
                QueryFilterHelper helper = _helper[referenceClassIndex];

                const int pointClassIndex = 0;
                foreach (IRow referenceRow in Search((ITable)referenceClass,
                                                     filter, helper, point))
                {
                    if (TestUtils.IsSameRow(feature, referenceRow))
                    {
                        continue;
                    }

                    var referenceFeature = (IFeature)referenceRow;

                    string conditionMessage;
                    if (validConstraint != null &&
                        validConstraint.HasConstraint &&
                        validConstraint.IsFulfilled(feature, pointClassIndex,
                                                    referenceFeature, referenceClassIndex,
                                                    out conditionMessage))
                    {
                        continue;
                    }

                    double standardDistance;
                    double?rightSideDistance;
                    double maxNeededDistance = GetMaxNeededDistance(
                        feature, referenceFeature, referenceClassIndex,
                        out standardDistance, out rightSideDistance);
                    maxNeededDistance = Math.Max(maxNeededDistance, _pointClassXyTolerance);

                    bool   isWithinPolygon;
                    bool   onRightSide;
                    double distance = GetDistance(point, referenceFeature, _nearPoint,
                                                  geometryComponent, maxNeededDistance,
                                                  out isWithinPolygon, out onRightSide);

                    if (AllowCoincidentPoints &&
                        IsSmallerThanXyTolerance(distance, referenceClassIndex))
                    {
                        continue;
                    }

                    if (distance > maxNeededDistance)
                    {
                        continue;
                    }

                    double minimumDistance = maxNeededDistance;
                    if (rightSideDistance.HasValue)
                    {
                        if (_referenceFlipConditions == null)
                        {
                            _referenceFlipConditions =
                                CreateFlipConditions(_referenceFlipExpressions);
                        }

                        bool flip = _referenceFlipConditions.Count > 0
                                                                    ? _referenceFlipConditions[
                            referenceClassIndex -
                            _firstReferenceClassIndex].IsFulfilled(
                            referenceFeature)
                                                                    : false;

                        double useDistance = (onRightSide == flip)
                                                                             ? standardDistance
                                                                             : rightSideDistance.Value;
                        if (distance > useDistance)
                        {
                            continue;
                        }

                        minimumDistance = useDistance;
                    }

                    errorCount += ReportError(feature, referenceFeature,
                                              point, _nearPoint,
                                              distance, minimumDistance,
                                              isWithinPolygon, geometryComponent,
                                              validConstraint);
                }
            }

            return(errorCount);
        }
Ejemplo n.º 14
0
        public static int ReportCrossings(
            [NotNull] IRow row1, int tableIndex1,
            [NotNull] IRow row2, int tableIndex2,
            [NotNull] IErrorReporting errorReporting,
            [CanBeNull] IssueCode issueCode,
            [CanBeNull] IValidRelationConstraint validRelationConstraint,
            bool reportIndividualParts)
        {
            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, "Features cross",
                                       out errorDescription))
            {
                return(_noError);
            }

            var errorCount = 0;

            foreach (IGeometry errorGeometry in GetCrossings(g1, g2))
            {
                if (errorGeometry.IsEmpty)
                {
                    continue;
                }

                errorCount += errorReporting.Report(errorDescription,
                                                    errorGeometry, issueCode,
                                                    reportIndividualParts,
                                                    row1, row2);
            }

            return(errorCount);

            //const bool overlap = false;
            //IGeometry intersection = TestUtils.GetIntersection(g1, g2, overlap);

            //// TODO remove boundary

            //try
            //{
            //    if (intersection.IsEmpty)
            //    {
            //        return _noError;
            //    }

            //    return errorReporting.Report("Features cross",
            //                                 intersection, reportIndividualParts,
            //                                 row1, row2);
            //}
            //finally
            //{
            //    Marshal.ReleaseComObject(intersection);
            //}
        }
Ejemplo n.º 15
0
        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);
        }