From 0e66c22c462520e5af75a43248b142f7337f5951 Mon Sep 17 00:00:00 2001 From: Roel Arents Date: Mon, 11 Dec 2023 16:57:34 +0100 Subject: [PATCH] fix filtering out small rings after deduping --- snap/snap.go | 30 +++++++++++++++++------------- snap/snap_test.go | 14 +++++++++++++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/snap/snap.go b/snap/snap.go index c567b7b..89cf373 100644 --- a/snap/snap.go +++ b/snap/snap.go @@ -147,25 +147,30 @@ func cleanupNewRing(newRing [][2]float64, isOuter bool) [][2]float64 { // LinearRings(): "The last point in the linear ring will not match the first point." if newRingLen > 1 && newRing[0] == newRing[newRingLen-1] { newRing = newRing[:newRingLen-1] + newRingLen-- } - switch newRingLen { - case 0: + + // filter out too small rings + if newRingLen == 0 || newRingLen < 3 && !(isOuter && keepPointsAndLines) { return nil - case 1, 2: - if isOuter && keepPointsAndLines { - // keep outer ring as point or line - return newRing - } - default: + } + + if newRingLen > 2 { // deduplicate points in the ring, check winding order, then add to the polygon - deduplicatedRing := kmpDeduplicate(newRing) + newRing = kmpDeduplicate(newRing) // inner rings (ringIdx != 0) should be clockwise shouldBeClockwise := !isOuter // winding order is reversed if incorrect - ensureCorrectWindingOrder(deduplicatedRing, shouldBeClockwise) - return deduplicatedRing + ensureCorrectWindingOrder(newRing, shouldBeClockwise) + newRingLen = len(newRing) } - return nil + + // filter out too small rings again after deduping + if newRingLen == 0 || newRingLen < 3 && !(isOuter && keepPointsAndLines) { + return nil + } + + return newRing } func floatPolygonsToGeomPolygons(floaters map[Level][][][2]float64) map[Level]geom.Polygon { @@ -207,7 +212,6 @@ func isClockwise(points [3][2]float64, shouldBeClockwise bool) bool { } // deduplication using an implementation of the Knuth-Morris-Pratt algorithm -// function also determines the rightmost lowest point of the ring, which is used to ensure correct winding order // //nolint:cyclop,funlen func kmpDeduplicate(newRing [][2]float64) [][2]float64 { diff --git a/snap/snap_test.go b/snap/snap_test.go index 461330e..acef7b9 100644 --- a/snap/snap_test.go +++ b/snap/snap_test.go @@ -220,7 +220,19 @@ func Test_snapPolygon(t *testing.T) { {90673.689, 530324.552}, {90664.068, 530379.532}, }}, - want: nil, + want: map[tms20.TMID]geom.Polygon{0: nil}, + }, + { + name: "ring length < 3 _after_ deduping, also should be filtered out", + tms: loadEmbeddedTileMatrixSet(t, "NetherlandsRDNewQuad"), + tmIDs: []tms20.TMID{0}, + polygon: geom.Polygon{{ + {211124.566, 574932.941}, + {211142.954, 574988.796}, + {211059.858, 574971.321}, + {211163.163, 574994.581}, + }}, + want: map[tms20.TMID]geom.Polygon{0: nil}, }, } for _, tt := range tests {