Planetiler
Flexible tool to build planet-scale vector tilesets from OpenStreetMap data fast
Install / Use
/learn @onthegomap/PlanetilerREADME
Planetiler
Planetiler 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.
Several full-featured basemaps are built using planetiler:
You can also create your own custom base maps or overlays using YAML or Java.
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.
Demo
See the live demo of vector tiles created by Planetiler and hosted by OpenStreetMap US.
© OpenMapTiles © OpenStreetMap contributors
Usage
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 SSD disk space plus 5-10x the size of the
.osm.pbffile - at least 0.5x as much free RAM as the input
.osm.pbffile size
To build the map:
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
:warning: This starts off by downloading about 1GB of data sources required by the OpenMapTiles profile including ~750MB for ocean polygons and ~240MB for Natural Earth Data.
<details> <summary>To download smaller extracts just for Monaco:</summary>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.
</details>To view tiles locally:
Generate a pmtiles tile archive by adding --output=data/output.pmtiles then
drag and drop output.pmtiles to pmtiles.io.
Or with the default mbtiles output format, use tileserver-gl-light:
npm install -g tileserver-gl-light
tileserver-gl-light data/output.mbtiles
Then open http://localhost:8080 to view tiles.
Some common arguments:
--outputtells planetiler where to write output to, and what format to write it in. For example--output=australia.pmtilescreates a pmtiles archive namedaustralia.pmtiles. It is best to specify the full path to the file. In docker image you should be using/data/australia.pmtilesto let the docker know where to write the file.--downloaddownloads input sources automatically and--only-downloadexits after downloading--area=monacodownloads a.osm.pbfextract from Geofabrik--osm-path=path/to/file.osm.pbfpoints Planetiler at an existing OSM extract on disk-Xmx1gcontrols how much RAM to give the JVM (recommended: 0.5x the input .osm.pbf file size to leave room for memory-mapped files)--forceoverwrites the output file--helpshows all of the options and exits
Generating a Map of the World
See PLANET.md.
Generating Custom Maps
Planetiler supports custom vector tile maps in two ways, depending on how much control you need:
- YAML configuration (no Java required) – for simple custom maps
- Java profiles – for advanced logic and full control
Both approaches generate standard Mapbox Vector Tiles (MVT) that can be used with MapLibre GL, Mapbox GL, and other vector-tile clients.
Option 1: Custom Maps Using YAML (No Java Required)
For many use cases, you can define a custom vector tile map using a YAML configuration file. This approach does not require writing Java code and is ideal for:
- Simple or moderately complex maps
- Prototyping
- Users who prefer declarative configuration
YAML-based maps are powered by the planetiler-custommap module. See examples and documentation:
https://github.com/onthegomap/planetiler/tree/main/planetiler-custommap.
Example YAML configuration
schema_name: Roads
attribution: <a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>
sources:
osm:
type: osm
url: geofabrik:rhode-island
layers:
- id: roads
features:
- source: osm
geometry: line
min_zoom: 6
include_when:
highway: [primary, secondary, tertiary]
attributes:
- key: class
tag_value: highway
To run:
java -jar planetiler.jar roads.yaml --download --output=roads.pmtiles
Option 2: Custom Maps Using Java Profiles
For more complex use cases, Planetiler supports custom Java profiles that allow full control over feature processing, attributes, zoom logic, and geometry handling. Java profiles are recommended when you need:
- Complex conditional logic
- Advanced attribute derivation
- Non-trivial feature interactions
- Maximum performance tuning
See examples and documentation: https://github.com/onthegomap/planetiler-examples/.
Example Java profile
import com.onthegomap.planetiler.*;
import com.onthegomap.planetiler.config.*;
import com.onthegomap.planetiler.reader.*;
import java.nio.file.Path;
public class Roads implements Profile {
@Override
public String attribution() {
return """
<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>
""".trim();
}
@Override
public void processFeature(SourceFeature feature, FeatureCollector features) {
if (feature.canBeLine() && feature.hasTag("highway", "primary", "secondary", "tertiary")) {
features.line("roads").setAttr("class", feature.getTag("highway"));
}
}
public static void main(String[] args) {
Planetiler.create(Arguments.fromArgs(args)).addOsmSource("osm", Path.of("ri.osm.pbf"), "geofabrik:rhode-island")
.overwriteOutput(Path.of("roads.pmtiles"))
.setProfile(new Roads())
.run();
}
}
This can be run with Java 22 or later without any compile step or build tools:
java -cp planetiler.jar Roads.java --download --output=roads.pmtiles
Use as a library
For larger projects with other dependencies, Planetiler can be used as a maven-style dependency in a Java project using the settings below:
Maven
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>
Gradle
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>'
Git submodules
Planetiler has a submodule dependency
on planetiler-openmaptiles. Add --recurse-submodules
to git clone, git pull, or git checkout commands to al
