Skip to content

Commit

Permalink
Merge pull request #22 from PDOK/fix-filter-after-dedupe
Browse files Browse the repository at this point in the history
fix filtering out small rings after deduping
  • Loading branch information
roelarents authored Dec 11, 2023
2 parents b528cc0 + 0e66c22 commit 424ca61
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
30 changes: 17 additions & 13 deletions snap/snap.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
14 changes: 13 additions & 1 deletion snap/snap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 424ca61

Please sign in to comment.