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