Rory McCann www.technomancy.org
Geofabrik geofabrik.de
Same output (raster images over HTTP), but served behind with vector tiles
Not client side JS / Open GL rendering
To allow one to make minor tweaks to the style without having to host a whole new style
Kosmtik can render a vector tiles project into images-over-HTTP
tilelive
- collection of libraries for rendering & serving tiles
tessera
- command line tilelive-based tool for serving tiles.
OSM-carto is just one project with a project.yaml
Vector tiles are 2 projects, source and style
osm-carto.tm2
and osm-carto.tm2source
osm-carto.tm2source
One data.yml
(NB: .yml
not .yaml
)
Remove the top level source
and styles
keys
Set maxzoom: 14
osm-carto.tm2
One project.yml
(NB: .yml
not .yaml
)
All .mss
style files.
source
is URLish to you tm2source project
All Layer
s only have the id
Vector tiles are 2 projects, source and style
osm-carto.tm2
and osm-carto.tm2source
osm-carto.tm2source
One data.yml
(NB: .yml
not .yaml
)
Remove the top level source
and styles
keys
Set maxzoom: 14
osm-carto.tm2
One project.yml
(NB: .yml
not .yaml
)
All .mss
style files.
source
is URLish to you tm2source project
All Layer
s only have the id
ha!
sadface
You can't use carto classes - only ids - to filter
Rewrite style to only use #id
instead of .class
filters
Not so bad for osm-carto
Lots of classes map 1:1 to layer ids anyway
Solved!
Common problem in vector tiles
Each vector tile data has a clipped polygon/line for each object
Can only see data inside your tile
Except sometimes you need to see outside your tile
Or you can't render properly
It's a polygon (green). We want to draw a border.
It is spread across many vtiles (black)
Polygon is cut. 4 new polygons
Border of the polygon is rendered at tile borders
buffer-size
Add buffer-size: $PIXELS
to each data layer properties
Value can be small (~4) for polygon boundaries
Large (~128) for label placement
buffer-size
Polygon now goes outside the image, border still draw.
But results are clipped out of final image
e.g. Labels for names, addresses, icons.
In raster tiles, using meta tiles, mapnik has the polygon, and can place the centroid once
Vector tiles: Each tile is separate render, each tile has its own polygon
Problem: Each tile will have a label in the middle
i.e. Have PostgreSQL, not Mapnik, convert the polygon to a point
You now have a point layer, and mapnik puts the label there
Only one point per polygon, regardless of how many v. tiles the polygon is on
ST_Centroid(way) AS way
: Geometic centroid
ST_PointOnSurface(way) AS way
: Point will be inside polygon
Centroid is about 4 times faster, but PointOnSurface is more "correct"
"Give me buildings in this bbox" → PostgreSQL can use geom index
"Give me ST_Centroid(way) in this bbox" → PostgreSQL cannot use index
Add AND way && !bbox!
to WHERE
clauses
Makes PostgreSQL filter based on the way column, and use the geom index
Or you can CREATE INDEX
on ST_Centroid(way)
Fine for normal zoom level, but z15+ uses z14 data
Simplification is too much
maxzoom
maxzoom: 14
in tm2source
mapnik won't do simplication for z14 tiles
Initially I tried to use symlinks as a hack to vector-tile-ify this and use the same project.yaml for both the source & style
But source and style need different maxzoom
.
Source needs maxzoom: 14
to prevent simplification
Style with maxzoom: 14
means no z15+ tiles
Each layer in the source has a minzoom
Needs to be minimum of 14
Otherwise data won't be included in z14 tile, which is uses to render z15+ tiles
Style can still filter on zoom for display purposes ([zoom>16]
)
With default osm2pgsql database, node-mapnik will do something strange and silly
Tries to autodetect geometry type by running the query and looking at first few rows
No bbox filtering, runs query globally
SELECT all buildings ORDER BY way_area DESC LIMIT 5
This is slow
ALTER TABLE planet_osm_polygon ALTER COLUMN way TYPE geometry(MultiPolygon, 900913) USING ST_Multi(way);
Have a osm2pgsql fork which imports as MULITPOLYGON
Code has been released on GitHub
Will try to keep it updated with upstream style (no guarantees)