tilemaker generates degenerate polygons not present in source
Given this way in version 1 as input: https://www.openstreetmap.org/way/1422845261/history (a thin, L-shaped, valid polygon)
as source files for convenience:
and this very minimal configuration:
config.json
{
"layers": {
"building": {
"minzoom": 14,
"maxzoom": 14
}
},
"settings": {
"minzoom": 14,
"maxzoom": 14,
"basezoom": 14,
"include_ids": true,
"name": "debug",
"version": "3.0",
"description": "",
"compress": "gzip"
}
}
process.lua
function way_function()
Layer("building", true)
end
and generating tiles from it:
./tilemaker \
--input bug.osm.pbf \
--output bug.mbtiles \
--config ./config.json \
--process ./process.lua \
--bbox 10.0534129,53.6191617,10.0544429,53.619693 # same as from bug.osm
sqlite3 \
bug.mbtiles \
'select quote(tile_data) from tiles where zoom_level=14 and tile_column=8649 and tile_row=11094' \
| cut -d\' -f2 \
| xxd -r -p > bug.mvt
vt2geojson -z 14 -y 5289 -x 8649 bug.mvt
yields a degenerate polygon:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
10.053927898406982,
53.61927620546507
],
[
10.053858160972595,
53.61927620546507
],
[
10.053799152374268,
53.61927620546507
],
[
10.053927898406982,
53.61927620546507
]
]
]
},
"properties": {},
"id": 1422845261
}
]
}
The spec technically allows degenerate polygons, but discourages them:
A linear ring SHOULD NOT have an area calculated by the surveyor's formula equal to zero, as this would signify a ring with anomalous geometric points.
It also includes wording like
An exterior ring is DEFINED as a linear ring having a positive area as calculated by applying the surveyor's formula to the vertices of the polygon in tile coordinates.
where it depends on your definition of zero if this is valid or not.
Practically speaking this causes issues in reading libraries like java-vector-tile which skip such polygons and return an empty GeometryCollection instead.
It's unexpected to me that tilemaker:
- modifies the polygon at all. I expected it to be kept 1:1 with the configuration given.
- includes degenerated polygons. If this is the result of a simplification algorithm, excluding the polygon seem sensible as it can't be rendered sensibly anyway.
- modifies the polygon at all. I expected it to be kept 1:1 with the configuration given.
Modifying geometries is core to what tilemaker does. OSM geometries need to be reprojected to web mercator then placed on the tile grid.
yields a degenerate polygon:
Can you check what the geometry is on the tile's coordinate grid? I think vt2geojson will give these to you if you don't specify an z,x,y
Can you check what the geometry is on the tile's coordinate grid? I think vt2geojson will give these to you if you don't specify an z,x,y
It doesn't out of the box. I added some debug output, does this answer your question?
VectorTileFeature {
properties: {},
extent: 4096,
type: 3,
_pbf: {
buf: <Buffer 1a 26 78 02 0a 08 62 75 69 6c 64 69 6e 67 28 80 20 12 15 18 03 08 cd ca bb a6 05 22 0b 09 98 24 ca 3c 12 19 00 15 00 0f>,
pos: 40,
length: 40
},
_geometry: 28,
_keys: [],
_values: [],
_id: 1422845261
}
// loadGeometry() output
[
{ x: 2316, y: 3877 },
{ x: 2303, y: 3877 },
{ x: 2292, y: 3877 },
{ x: 2316, y: 3877 }
]
The height and width of the narrow parts are 17cm and 29cm (mercator). The grid size for that vector tile is 60cm. So, the correct response is to drop the feature.