コード例 #1
0
        private static IEnumerable <esriMonotinicityEnum> GetInvalidMonotonicityTypes(
            [NotNull] IPolyline polyline)
        {
            esriMonotinicityEnum trend = MeasureUtils.GetMonotonicityTrend(polyline);

            switch (trend)
            {
            case esriMonotinicityEnum.esriValueIncreases:
                yield return(esriMonotinicityEnum.esriValueDecreases);

                break;

            case esriMonotinicityEnum.esriValueDecreases:
                yield return(esriMonotinicityEnum.esriValueIncreases);

                break;

            case esriMonotinicityEnum.esriValueLevel:
                yield return(esriMonotinicityEnum.esriValueIncreases);

                yield return(esriMonotinicityEnum.esriValueDecreases);

                break;

            case esriMonotinicityEnum.esriValuesEmpty:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #2
0
        protected override int ExecuteCore(IRow row, int tableIndex)
        {
            if (!_hasM)
            {
                return(NoError);
            }

            var feature = row as IFeature;

            if (feature == null)
            {
                return(NoError);
            }

            var polyline = feature.Shape as IPolyline;

            if (polyline == null)
            {
                return(NoError);
            }

            if (_flipCondition == null)
            {
                const bool undefinedConstraintIsFulfilled = false;
                _flipCondition = new RowCondition((ITable)_lineClass, _flipExpression,
                                                  undefinedConstraintIsFulfilled,
                                                  GetSqlCaseSensitivity(tableIndex));
            }

            var mAware = (IMAware)polyline;

            Assert.True(mAware.MAware, "The geometry is not M-aware");

            IEnumerable <MMonotonicitySequence> errorSequences = MeasureUtils.GetErrorSequences(
                polyline, _expectedMonotonicity,
                () => _flipCondition.IsFulfilled(feature),
                _allowConstantValues);

            return(errorSequences.Sum(errorSequence => ReportError(
                                          GetErrorMessage(errorSequence),
                                          errorSequence.CreatePolyline(),
                                          Codes[Code.MeasuresNotMonotonic],
                                          TestUtils.GetShapeFieldName(feature),
                                          row)));
        }
コード例 #3
0
        private int ReportInvalidSequence([NotNull] ICollection <ISegment> invalidMSegments,
                                          [NotNull] IRow row,
                                          double invalidValue)
        {
            Assert.ArgumentNotNull(invalidMSegments, nameof(invalidMSegments));
            Assert.ArgumentCondition(invalidMSegments.Count > 0, "Empty sequence");

            const bool cloneSegments = false;
            IPolyline  errorGeometry = MeasureUtils.GetErrorGeometry(invalidMSegments,
                                                                     cloneSegments);

            IssueCode issueCode;
            string    errorDescription = GetErrorDescription(invalidValue, invalidMSegments,
                                                             out issueCode);

            return(ReportError(errorDescription, errorGeometry,
                               issueCode, _shapeFieldName,
                               row));
        }
コード例 #4
0
        private int ReportNonUniqueMeasuresWithinFeature([NotNull] IFeature feature)
        {
            IGeometry geometry = feature.Shape;

            if (geometry == null || geometry.IsEmpty)
            {
                return(NoError);
            }

            var polyline = geometry as IPolyline;

            if (polyline == null)
            {
                return(NoError);
            }

            var errorCount = 0;

            if (MeasureUtils.ContainsAllMonotonicityTypes(
                    polyline,
                    esriMonotinicityEnum.esriValueDecreases,
                    esriMonotinicityEnum.esriValueIncreases))
            {
                IEnumerable <esriMonotinicityEnum> invalidTypes =
                    GetInvalidMonotonicityTypes(polyline);

                const string description =
                    "Measures are not unique due to non-monotonicity within feature";

                errorCount += MeasureUtils.GetMonotonicitySequences(polyline, invalidTypes)
                              .Sum(sequence => ReportError(
                                       description,
                                       sequence.CreatePolyline(),
                                       Codes[Code.MeasuresNotUnique_WithinFeature],
                                       TestUtils.GetShapeFieldName(feature),
                                       feature));
            }

            return(errorCount);
        }
コード例 #5
0
        private ICollection <InvolvedRow> GetInvolvedRows(
            [NotNull] OverlappingMeasures overlap,
            [CanBeNull] out IPolyline lineErrorGeometry,
            [CanBeNull] out IMultipoint pointErrorGeometry)
        {
            Assert.ArgumentNotNull(overlap, nameof(overlap));

            var involvedRows = new List <InvolvedRow>();
            var polylines    = new List <IPolyline>();
            var allPoints    = new List <IPoint>();

            foreach (TestRowReference testRowReference in overlap.Features)
            {
                IFeature feature = GetFeature(testRowReference);

                involvedRows.Add(new InvolvedRow(feature));

                var polyline = (IPolyline)feature.Shape;

                IList <IPoint> points;
                IPolyline      subcurves = MeasureUtils.GetSubcurves(polyline,
                                                                     overlap.MMin,
                                                                     overlap.MMax,
                                                                     out points);

                allPoints.AddRange(points);
                if (subcurves != null)
                {
                    polylines.Add(subcurves);
                }
            }

            lineErrorGeometry  = GetErrorGeometry(polylines);
            pointErrorGeometry = allPoints.Count > 0
                                                     ? GeometryFactory.CreateMultipoint(allPoints)
                                                     : null;

            return(involvedRows);
        }
コード例 #6
0
        private int CheckFeatures(
            [NotNull] IEnumerable <KeyValuePair <int, IFeature> > features)
        {
            Assert.ArgumentNotNull(features, nameof(features));

            var routeMeasures = new RouteMeasures(_mTolerances, _xyTolerances);

            var errorCount = 0;

            foreach (KeyValuePair <int, IFeature> pair in features)
            {
                int      tableIndex = pair.Key;
                IFeature feature    = pair.Value;

                if (CancelTestingRow(feature))
                {
                    continue;
                }

                object routeId = feature.Value[_routeIdFieldIndexes[tableIndex]];

                if (routeId == null || routeId is DBNull)
                {
                    continue;
                }

                foreach (CurveMeasureRange range in
                         MeasureUtils.GetMeasureRanges(feature, tableIndex))
                {
                    routeMeasures.Add(routeId, range);
                }

                errorCount += ReportNonUniqueMeasuresWithinFeature(feature);
            }

            errorCount += routeMeasures.GetOverlaps().Sum(overlap => ReportOverlap(overlap));

            return(errorCount);
        }
コード例 #7
0
        protected virtual bool IsInvalidValue(double m,
                                              [NotNull] IRow row,
                                              bool isNewRow,
                                              [CanBeNull] out string error,
                                              [CanBeNull] out IssueCode issueCode)
        {
            error     = string.Empty;
            issueCode = null;
            if (MeasureUtils.IsInvalidValue(m, _invalidValue))
            {
                if (double.IsNaN(_invalidValue))
                {
                    issueCode = Codes[Code.UndefinedMValues];
                }
                else
                {
                    issueCode = Codes[Code.InvalidMValues];
                }

                return(true);
            }

            return(false);
        }
コード例 #8
0
        private static IEnumerable <ZMonotonicitySequence> GetErrorSequencesFromSinglePart(
            [NotNull] IPolyline singlePartPolyline,
            MonotonicityDirection expectedMonotonicity,
            [NotNull] Func <bool> isFeatureFlipped,
            bool allowConstantValues)
        {
            bool?featureFlipped = null;

            var points       = (IPointCollection4)singlePartPolyline;
            int segmentCount = points.PointCount - 1;

            WKSPointZ[] wksPointZs = new WKSPointZ[points.PointCount];

            GeometryUtils.QueryWKSPointZs(points, wksPointZs);

            ZMonotonicitySequence currentSequence = null;

            double trend = wksPointZs[segmentCount].Z - wksPointZs[0].Z;
            esriMonotinicityEnum monotonicityTrend =
                MeasureUtils.GetMonotonicityType(trend);

            var checkedMonotonicity = GetCheckedMonotonicityDirection(
                expectedMonotonicity,
                monotonicityTrend);

            esriMonotinicityEnum?preMonotonicity = null;
            IEnumSegment         enumSegments    = null;
            bool?recycling = null;

            for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++)
            {
                double dz = wksPointZs[segmentIndex + 1].Z - wksPointZs[segmentIndex].Z;

                esriMonotinicityEnum monotonicity = MeasureUtils.GetMonotonicityType(dz);

                if (monotonicity == esriMonotinicityEnum.esriValueDecreases ||
                    monotonicity == esriMonotinicityEnum.esriValueIncreases)
                {
                    if (!featureFlipped.HasValue)
                    {
                        featureFlipped = isFeatureFlipped();
                    }

                    if (featureFlipped.Value)
                    {
                        monotonicity =
                            monotonicity == esriMonotinicityEnum.esriValueDecreases
                                                                ? esriMonotinicityEnum.esriValueIncreases
                                                                : esriMonotinicityEnum.esriValueDecreases;
                    }
                }

                if (monotonicity != preMonotonicity)
                {
                    if (currentSequence != null)
                    {
                        yield return(currentSequence);
                    }

                    preMonotonicity = monotonicity;
                    currentSequence = null;
                }

                if (currentSequence == null)
                {
                    if (monotonicity == esriMonotinicityEnum.esriValueLevel &&
                        allowConstantValues)
                    {
                        // ok
                    }
                    else if (monotonicity == esriMonotinicityEnum.esriValueIncreases &&
                             checkedMonotonicity == MonotonicityDirection.Increasing)
                    {
                        // ok
                    }
                    else if (monotonicity == esriMonotinicityEnum.esriValueDecreases &&
                             checkedMonotonicity == MonotonicityDirection.Decreasing)
                    {
                        // ok
                    }
                    else if (checkedMonotonicity == MonotonicityDirection.Any)
                    {
                        if (monotonicity == esriMonotinicityEnum.esriValueIncreases)
                        {
                            checkedMonotonicity = MonotonicityDirection.Increasing;
                        }
                        else if (monotonicity == esriMonotinicityEnum.esriValueDecreases)
                        {
                            checkedMonotonicity = MonotonicityDirection.Decreasing;
                        }
                    }
                    else
                    {
                        currentSequence =
                            new ZMonotonicitySequence(monotonicity,
                                                      singlePartPolyline.SpatialReference)
                        {
                            FeatureMonotonicityTrend = monotonicityTrend,
                            FeatureIsFlipped         = featureFlipped
                        };
                    }
                }

                if (currentSequence != null)
                {
                    if (enumSegments == null)
                    {
                        enumSegments = ((ISegmentCollection)singlePartPolyline)
                                       .EnumSegments;
                    }

                    var segment = GetSegment(enumSegments, segmentIndex);
                    if (!recycling.HasValue)
                    {
                        recycling = enumSegments.IsRecycling;
                    }

                    currentSequence.Add(recycling.Value
                                                                    ? GeometryFactory.Clone(segment)
                                                                    : segment);

                    if (recycling.Value)
                    {
                        Marshal.ReleaseComObject(segment);
                    }
                }
            }

            if (currentSequence != null)
            {
                yield return(currentSequence);
            }

            if (enumSegments != null)
            {
                enumSegments.Reset();
            }
        }
コード例 #9
0
        private int ReportInvalidSegments([NotNull] ISegmentCollection segments,
                                          [NotNull] IRow row)
        {
            var errorCount = 0;

            List <ISegment> currentInvalidSequence = null;
            int             currentPartIndex       = -1;

            IEnumSegment enumSegment = segments.EnumSegments;

            int      partIndex    = -1;
            int      segmentIndex = -1;
            ISegment segment;

            enumSegment.Next(out segment, ref partIndex, ref segmentIndex);

            while (segment != null)
            {
                if (currentInvalidSequence != null && partIndex != currentPartIndex)
                {
                    // report sequence from previous part
                    errorCount            += ReportInvalidSequence(currentInvalidSequence, row, _invalidValue);
                    currentInvalidSequence = null;
                    currentPartIndex       = -1;
                }

                if (MeasureUtils.HasInvalidMValue(segment, _queryPoint, _invalidValue))
                {
                    if (currentInvalidSequence == null)
                    {
                        // initialize sequence
                        currentInvalidSequence = new List <ISegment>();
                        currentPartIndex       = partIndex;
                    }

                    currentInvalidSequence.Add(GeometryFactory.Clone(segment));
                }
                else
                {
                    if (currentInvalidSequence != null)
                    {
                        errorCount +=
                            ReportInvalidSequence(currentInvalidSequence, row, _invalidValue);
                        currentInvalidSequence = null;
                        currentPartIndex       = -1;
                    }
                }

                // release the segment, otherwise "pure virtual function call" occurs
                // when there are certain circular arcs (IsLine == true ?)
                Marshal.ReleaseComObject(segment);

                enumSegment.Next(out segment, ref partIndex, ref segmentIndex);
            }

            if (currentInvalidSequence != null)
            {
                // report sequence at end of segment collection
                errorCount += ReportInvalidSequence(currentInvalidSequence, row, _invalidValue);
            }

            return(errorCount);
        }