private void ProcessFeature(Feature feature, [CanBeNull] Polygon perimeter) { Polyline curve; var shape = feature.GetShape(); if (shape is Polygon polygon) { var before = GetPointIDs(polygon); // TODO DEBUG DROP curve = GeometryUtils.Boundary(polygon); } else if (shape is Polyline polyline) { var before = GetPointIDs(polyline); // TODO DEBUG DROP curve = polyline; } else { curve = null; Assert.Fail("Input shape is neither Polyline nor Polygon"); } if (_simplificationTolerance > 0) { curve = GeometryUtils.Generalize(curve, _simplificationTolerance); curve = GeometryUtils.Simplify(curve); } var builder = new PolylineBuilder(curve) { HasID = true }; builder.SetEmpty(); int controlPointsAdded = 0; int controlPointsRemoved = 0; // Things to watch out: // - preserve non-linear segments // - process each part separately // - remember Start/EndPoint or rings foreach (var part in curve.Parts) { var numSegments = part.Count; if (numSegments < 1) { continue; } bool startNewPart = true; var one = part[0]; for (int i = 1; i < numSegments; i++) { var two = part[i]; var centerPoint = two.StartPoint; if (ProcessingUtils.WithinPerimeter(centerPoint, perimeter)) { DoVertex(ref one, ref two, ref controlPointsAdded, ref controlPointsRemoved); } builder.AddSegment(one, startNewPart); startNewPart = false; one = two; } // For polygons (closed rings), also look at Start/EndPoint if (shape is Polygon) { var two = part[0]; var centerPoint = two.StartPoint; if (ProcessingUtils.WithinPerimeter(centerPoint, perimeter)) { DoVertex(ref one, ref two, ref controlPointsAdded, ref controlPointsRemoved); } } builder.AddSegment(one, startNewPart); } if (controlPointsAdded > 0 || controlPointsRemoved > 0) { bool wantPolygon = shape is Polygon; if (wantPolygon) { var polyline = builder.ToGeometry(); shape = PolygonBuilder.CreatePolygon(polyline); } else { shape = builder.ToGeometry(); } var after = GetPointIDs((Multipart)shape); feature.SetShape(shape); feature.Store(); // TODO requires an edit session _msg.DebugFormat("Feature {0}: {1} control points added", ProcessingUtils.Format(feature), controlPointsAdded); ControlPointsAdded += controlPointsAdded; ControlPointsRemoved += controlPointsRemoved; } }