private string GetErrorMessage([NotNull] ZMonotonicitySequence sequence) { var sb = new StringBuilder(); string segmentInfo = sequence.SegmentCount == 1 ? "one segment" : string.Format("{0} segments", sequence.SegmentCount); sb.AppendFormat("Z values are {0} for {1}", GetMonotonicityTypeString(sequence.MonotonicityType, sequence.FeatureIsFlipped), segmentInfo); if (sequence.MonotonicityType == esriMonotinicityEnum.esriValueDecreases || sequence.MonotonicityType == esriMonotinicityEnum.esriValueIncreases) { sb.AppendFormat(". {0}", GetExpectedMonotonicityString(sequence, ExpectedMonotonicity)); if (sequence.FeatureIsFlipped != null && sequence.FeatureIsFlipped.Value) { sb.Append(" (against the feature orientation)"); } } return(sb.ToString()); }
private static string GetExpectedMonotonicityString( [NotNull] ZMonotonicitySequence sequence, MonotonicityDirection expectedMonotonicity) { switch (expectedMonotonicity) { case MonotonicityDirection.Decreasing: return("The Z values should be decreasing"); case MonotonicityDirection.Increasing: return("The Z values should be increasing"); case MonotonicityDirection.Any: return(string.Format("The Z value trend for the line is {0}", GetMonotonicityTypeString( sequence.FeatureMonotonicityTrend, sequence.FeatureIsFlipped))); default: throw new ArgumentException( string.Format("Unexpected monotonicity direction: {0}", expectedMonotonicity)); } }
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(); } }