Planetiler (pla·nuh·tai·lr, formerly named "Flatmap") is a tool that generates Vector Tiles from geographic data sources like OpenStreetMap. Planetiler aims to be fast and memory-efficient so that you can build a map of the world in a few hours on a single machine without any external tools or database.
Vector tiles contain raw point, line, and polygon geometries that clients like MapLibre can use to render custom maps in the browser, native apps, or on a server. Planetiler packages tiles into an MBTiles (sqlite) or PMTiles file that can be served using tools like TileServer GL or Martin or even queried directly from the browser. See awesome-vector-tiles for more projects that work with data in this format.
Planetiler works by mapping input elements to vector tile features, flattening them into a big list, then sorting by tile ID to group into tiles. See ARCHITECTURE.md for more details or this blog post for more of the backstory.
See the live demo of vector tiles created by Planetiler and hosted by the OpenStreetMap Americana Project.
© OpenMapTiles © OpenStreetMap contributors
To generate a map of an area using the OpenMapTiles profile, you will need:
- Java 21+ (see CONTRIBUTING.md) or Docker
- at least 1GB of free disk space plus 5-10x the size of the
.osm.pbf
file - at least 0.5x as much free RAM as the input
.osm.pbf
file size
Using Java, download planetiler.jar
from
the latest release
and run it:
wget https://github.com/onthegomap/planetiler/releases/latest/download/planetiler.jar
java -Xmx1g -jar planetiler.jar --download --area=monaco
Or using Docker:
docker run -e JAVA_TOOL_OPTIONS="-Xmx1g" -v "$(pwd)/data":/data ghcr.io/onthegomap/planetiler:latest --download --area=monaco
To download smaller extracts just for Monaco:
Java:
java -Xmx1g -jar planetiler.jar --download --area=monaco \
--water-polygons-url=https://github.com/onthegomap/planetiler/raw/main/planetiler-core/src/test/resources/water-polygons-split-3857.zip \
--natural-earth-url=https://github.com/onthegomap/planetiler/raw/main/planetiler-core/src/test/resources/natural_earth_vector.sqlite.zip
Docker:
docker run -e JAVA_TOOL_OPTIONS="-Xmx1g" -v "$(pwd)/data":/data ghcr.io/onthegomap/planetiler:latest --download --area=monaco \
--water-polygons-url=https://github.com/onthegomap/planetiler/raw/main/planetiler-core/src/test/resources/water-polygons-split-3857.zip \
--natural-earth-url=https://github.com/onthegomap/planetiler/raw/main/planetiler-core/src/test/resources/natural_earth_vector.sqlite.zip
You will need the full data sources to run anywhere besides Monaco.
Using Node.js:
npm install -g tileserver-gl-light
tileserver-gl-light data/output.mbtiles
Or using Docker:
docker run --rm -it -v "$(pwd)/data":/data -p 8080:8080 maptiler/tileserver-gl -p 8080
Then open http://localhost:8080 to view tiles.
Some common arguments:
--output
tells planetiler where to write output to, and what format to write it in. For example--output=australia.pmtiles
creates a pmtiles archive namedaustralia.pmtiles
.--download
downloads input sources automatically and--only-download
exits after downloading--area=monaco
downloads a.osm.pbf
extract from Geofabrik--osm-path=path/to/file.osm.pbf
points Planetiler at an existing OSM extract on disk-Xmx1g
controls how much RAM to give the JVM (recommended: 0.5x the input .osm.pbf file size to leave room for memory-mapped files)--force
overwrites the output file--help
shows all of the options and exits
Planetiler has a submodule dependency
on planetiler-openmaptiles. Add --recurse-submodules
to git clone
, git pull
, or git checkout
commands to also update submodule dependencies.
To clone the repo with submodules:
git clone --recurse-submodules https://github.com/onthegomap/planetiler.git
If you already pulled the repo, you can initialize submodules with:
git submodule update --init
To force git to always update submodules (recommended), run this command in your local repo:
git config --local submodule.recurse true
Learn more about working with submodules here.
See PLANET.md.
If you want to customize the OpenMapTiles schema or generate an mbtiles file with OpenMapTiles + extra layers, then fork https://github.com/openmaptiles/planetiler-openmaptiles make changes there, and run directly from that repo. It is a standalone Java project with a dependency on Planetiler.
If you want to generate a separate mbtiles file with overlay layers or a full custom basemap, then:
- For simple schemas, run a recent planetiler jar or docker image with a custom schema defined in a yaml configuration file. See planetiler-custommap for details.
- For complex schemas (or if you prefer working in Java), create a new Java project that depends on Planetiler. See the planetiler-examples project for a working example.
If you want to customize how planetiler works internally, then fork this project, build from source, and consider contributing your change back for others to use!
Some example runtimes for the OpenMapTiles profile (excluding downloading resources):
Input | Version | Machine | Time | mbtiles size | Logs |
---|---|---|---|---|---|
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c2d-standard-112 (112cpu/448GB) | 37m cpu:48h5m gc:3m45s avg:76.9 | 79GB | logs |
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c6gd.16xlarge (64cpu/128GB) | 53m cpu:41h58m avg:47.1 | 79GB | logs, VisualVM Profile |
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c6gd.8xlarge (32cpu/64GB) | 1h27m cpu:37h55m avg:26.1 | 79GB | logs |
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c6gd.4xlarge (16cpu/32GB) | 2h38m cpu:34h3m avg:12.9 | 79GB | logs |
s3://osm-pds/2021/planet-211011.osm.pbf (65GB) | 0.1.0 | DO 16cpu 128GB | 3h9m cpu:42h1m avg:13.3 | 99GB | logs, VisualVM Profile |
Daylight Distribution v1.6 with ML buildings and admin boundaries (67GB) | 0.1.0 | DO 16cpu 128GB | 3h13m cpu:43h40m avg:13.5 | 101GB | logs |
Merging nearby buildings at z13 is very expensive, when run with --building-merge-z13=false
:
Input | Version | Machine | Time | mbtiles size | Logs |
---|---|---|---|---|---|
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c2d-standard-112 (112cpu/448GB) | 26m cpu:27h47m avg:63.9 | 79GB | logs |
s3://osm-pds/2022/planet-220530.osm.pbf (69GB) | 0.5.0 | c6gd.16xlarge (64cpu/128GB) | 39m cpu:27h4m avg:42.1 | 79GB | logs, VisualVM Profile |
s3://osm-pds/2021/planet-220214.osm.pbf (67GB) | 0.3.0 | r6g.16xlarge (64cpu/512GB) with ramdisk and write to EFS | 1h1m cpu:24h33m avg:24.3 | 104GB | logs |
s3://osm-pds/2021/planet-211011.osm.pbf (65GB) | 0.1.0 | Linode 50cpu 128GB | 1h9m cpu:24h36m avg:21.2 | 97GB | logs, VisualVM Profile |
Some other tools that generate vector tiles from OpenStreetMap data:
- OpenMapTiles is the reference implementation of
the OpenMapTiles schema that
the OpenMapTiles profile
is based on. It uses an intermediate postgres database and operates in two modes:
- Import data into database (~1 day) then serve vector tiles directly from the database. Tile serving is slower and requires bigger machines, but lets you easily incorporate realtime updates
- Import data into database (~1 day) then pregenerate every tile for the planet into an mbtiles file which takes over 100 days or a cluster of machines, but then tiles can be served faster on smaller machines
- Tilemaker uses a similar approach to Planetiler (no intermediate database), is more mature, and has a convenient lua API for building custom profiles without recompiling the tool, but takes about a day to generate a map of the world
Some companies that generate and host tiles for you:
- Mapbox - data from the pioneer of vector tile technologies
- Maptiler - data from the creator of OpenMapTiles schema
- Stadia Maps - what onthegomap.com uses in production
If you want to host tiles yourself but have someone else generate them for you, those companies also offer plans to download regularly-updated tilesets.
- Supports Natural Earth,
OpenStreetMap .osm.pbf,
geopackage
, and Esri Shapefiles data sources - Writes to MBTiles or or PMTiles output.
- Java-based Profile API to customize how source elements map to vector tile features, and post-process generated tiles using JTS geometry utilities
- YAML config file format that lets you create custom schemas without writing Java code
- Merge nearby lines or polygons with the same tags before emitting vector tiles
- Automatically fixes self-intersecting polygons
- Built-in OpenMapTiles profile based on OpenMapTiles v3.13.1
- Optionally download additional name translations for elements from Wikidata
- Export real-time stats to a prometheus push gateway using
--pushgateway=http://user:password@ip
argument (and a grafana dashboard for viewing) - Automatically downloads region extracts from Geofabrik
using
geofabrik:australia
shortcut as a source URL - Unit-test profiles to verify mapping logic, or integration-test to verify the actual contents of a generated mbtiles file (example)
- It is harder to join and group data than when using database. Planetiler automatically groups features into tiles, so you can easily post-process nearby features in the same tile before emitting, but if you want to group or join across features in different tiles, then you must explicitly store data when processing a feature to use with later features or store features and defer processing until an input source is finished (boundary layer example)
- Planetiler only does full imports from
.osm.pbf
snapshots, there is no way to incorporate real-time updates.
Planetiler can be used as a maven-style dependency in a Java project using the settings below:
Add this repository block to your pom.xml
:
<repositories>
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
Then add the following dependency:
<dependency>
<groupId>com.onthegomap.planetiler</groupId>
<artifactId>planetiler-core</artifactId>
<version>${planetiler.version}</version>
</dependency>
Set up your repositories block::
mavenCentral()
maven {
url "https://repo.osgeo.org/repository/release/"
}
Set up your dependencies block:
implementation 'com.onthegomap.planetiler:planetiler-core:<version>'
Pull requests are welcome! See CONTRIBUTING.md for details.
For general questions, check out the #planetiler channel on OSM-US Slack (get an invite here), or start a GitHub discussion.
Found a bug or have a feature request? Open a GitHub issue to report.
This is a side project, so support is limited. If you have the time and ability, feel free to open a pull request to fix issues or implement new features.
Planetiler is made possible by these awesome open source projects:
- OpenMapTiles for the schema and reference implementation that the openmaptiles profile is based on
- Graphhopper for basis of utilities to process OpenStreetMap data in Java
- JTS Topology Suite for working with vector geometries
- Geotools for shapefile processing
- SQLite JDBC Driver for reading Natural Earth data and writing MBTiles files
- MessagePack for compact binary encoding of intermediate map features
- geojson-vt for the basis of the stripe clipping algorithm that planetiler uses to slice geometries into tiles
- java-vector-tile for the basis of the vector tile encoder
- imposm3 for the basis of OSM multipolygon processing and tag parsing utilities
- HPPC for high-performance primitive Java collections
- Osmosis for Java utilities to parse OpenStreetMap data
- JNR-FFI for utilities to access low-level system utilities to improve memory-mapped file performance.
- cel-java for the Java implementation of Google's Common Expression Language that powers dynamic expressions embedded in schema config files.
- PMTiles optimized tile storage format
See NOTICE.md for a full list and license details.
Planetiler was created by Michael Barry for future use generating custom basemaps or overlays for On The Go Map.
Planetiler source code is licensed under the Apache 2.0 License, so it can be used and modified in commercial or other open source projects according to the license guidelines.
Maps built using planetiler do not require any special attribution, but the data or schema used might. Any maps generated from OpenStreetMap data must visibly credit OpenStreetMap contributors. Any map generated with the profile based on OpenMapTiles or a derivative must visibly credit OpenMapTiles as well.