paulmach / orb

Types and utilities for working with 2d geometry in Golang
MIT License
886 stars 103 forks source link

Tilecover returns adjacent / touching tiles #138

Closed jo-me closed 6 months ago

jo-me commented 9 months ago

Hi,

it seems there are some rounding issues causing (at least for me) unexpected results in the tilecover module. I would expect that the tileset of a maptile's bounds would return a set with exactly that maptile, but it returns 4 maptiles:

bound := maptile.New(4304, 2821, 13).Bound()
tileset := tilecover.Bound(bound, 13)

Expected:

{X: 4304, Y: 2821, Z: 13}

Actual:

{X: 4304, Y: 2821, Z: 13}
{X: 4304, Y: 2822, Z: 13}
{X: 4305, Y: 2821, Z: 13}
{X: 4305, Y: 2822, Z: 13}

Is this as designed?

Similar unexpected results also appear in clip module: When clipping two of those neighboring bounds above, it does not return a bound that has IsEmpty=true (even though comment says "IsEmpty returns true if it contains zero area"). The area of the resulting (clipped) bound is 0, though.

Thanks for any hints,

Jochen Mehlhorn jochen.mehlhorn@mercedes-benz.com, Mercedes-Benz Tech Innovation GmbH

Provider Information

paulmach commented 8 months ago

The Tile -> Bound -> 4 Tiles problem is expected. A tile is "closed" on 2 sides and "open" on the others (I think it's the top and left that are closed). Said another way, a point on a boundary or intersection of tiles should only be in 1 tile, or things get more complicated.

For example the point (0, 0) is at the intersection of 4 tiles, but is only in 1.

A bound however is closed on all 4 sides. 2 sides (edges, lines) are in the bound but not in the original tile. Extra tiles are add to cover those lines.

For the second question about intersecting bounds. I think it's the same issue, the new bound represents the boundary, a line, not empty.

Not sure what the solution is, maybe update the bound to support open and closed boundaries?

jo-me commented 5 months ago

Oh, I completely forgot about this issue.

Yes, having an option to specify open/closed boundaries sounds like it could help. But I have no idea how much of the code base would be affected by this ;)