mapbox / tippecanoe

Build vector tilesets from large collections of GeoJSON features.
BSD 2-Clause "Simplified" License
2.73k stars 432 forks source link

Split polygon interiors into their own layer #414

Open e-n-f opened 7 years ago

e-n-f commented 7 years ago

It is hard to make polygons for entire countries or oceans with good detail on the coasts (to z13 or so) without also requiring the interiors to be represented by thousands of identical tiles that do nothing but cover the entire tile with a square.

I think the way to handle this is to provide a way to automatically split polygon layers into a detail layer and a fill layer.

At some particular zoom layer, say, 8, all the polygons whose interior contains one or more entire z8 tiles would have those interior tiles cut out into a separate layer. The remainder of the polygons would continue to be tiled down to the maxzoom, to provide coastal detail. The interiors would exist only at that one zoom level and would be overzoomed to fill in the polygon interiors at higher zooms. The division between the two layers would be in the tile buffer so the edge wouldn't be visible.

(When should the cutover be? The longer you put it off, the more area you cut out, reducing the ultimate number of detail tiles, but the more fill tiles you need to produce. It should be possible to calculate the optimal zoom level to switch over that will produce the smallest final tileset size.)

To be verified: can these be separate layers within the same tileset, or must they be entirely separate tilesets?

e-n-f commented 7 years ago

For Natural Earth countries:

zoom total tiles exact squares savings at zooms z+1 through 12
0 1
1 4
2 16
3 61 4 1398096
4 216 30 2621400
5 694 179 3910076
6 2311 924 5045040
7 8031 4472 6099808
8 29206 20340 6915600
9 109923 88730 7453320
10 423413 374339 7486780
11 1656278 1545837 6183348
12 6540964 6296817

Which suggests that z10 is the right place to output the filler squares, to save 7.486M total tiles at z11 and z12. For other maxzooms, it looks like the best cutover is:

maxzoom cutover
5 4
6 5
7 6
8 6
9 7
10 8
11 9

so always something like 80% of the maxzoom. There is enough edge detail required that getting that 4x or 20x multiplier for one or two zooms is always better than cutting somewhere deeper.

e-n-f commented 5 years ago

Finally a workable implementation of this in https://github.com/mapbox/tippecanoe/pull/808

geeknik commented 5 years ago

I assume that a command line such as tippecanoe -pF -f -o out_file geo.json will trigger this behavior from a testing standpoint?

e-n-f commented 5 years ago

Yes, that's how it works in the implementation I've been trying out.