Skip to main content

Building an Overture Map

Step 1: Download only what you need

Overture Maps data is released in the cloud-native format GeoParquet. It is further partitioned by theme and type. Downloading the data through a tool like DuckDB can take advantage of these properties, giving the best performance. After downloading and converting the data to GeoJSON, we can use tippecanoe to create a PMTiles archive for each theme.

The places data theme represents business and points of interest in the real world. Read more about the places data schema in the documentation.

  1. The following DuckDB query downloads places data within a specific bounding box and writes a GeoJSON file.

    LOAD spatial;
    LOAD httpfs;
    -- Access the data on AWS in this example
    SET s3_region='us-west-2';

    COPY (
    SELECT
    names.primary AS name,
    categories.primary as category,
    ROUND(confidence,2) as confidence,
    ST_GeomFromWKB(geometry) as geometry
    FROM read_parquet('s3://overturemaps-us-west-2/release/2024-07-22.0/theme=places/*/*')
    WHERE
    -- Point geometry doesn't require looking at both min and max:
    bbox.xmin BETWEEN -122.68 AND -121.98 AND
    bbox.ymin BETWEEN 47.36 AND 47.79
    ) TO 'seattle_places.geojson' WITH (FORMAT GDAL, DRIVER 'GeoJSON', SRS 'EPSG:4326');

  2. Next, create a pmtiles archive from seattle_places.geojson with tippecanoe.

    tippecanoe -fo places.pmtiles -Z13 -z13 -l places seattle_places.geojson
    Tippecanoe flag explanation
    • -fo places.pmtiles The output file will be places.pmtiles. It will be overwritten if it exists.
    • -Z13 and -z13 will produce a tileset starting at zoom 13 and going up to zoom 13 (only 1 zoom level).
    • -l places names the layer "places"

Step 2: Creating a map with Maplibre + PMTiles

At this point, we have created five PMTiles archives from the five Overture themes:

  1. places.pmtiles
  2. placenames.pmtiles
  3. buildings.pmtiles
  4. roads.pmtiles
  5. base.pmtiles

The map on this page combines a react maplibre example with PMTiles. You can view the source for the above map on github for a complete example using react, or, check out the map based on July's release for a non-react implementation of PMTiles.

Using PMTiles with react requires adding the PMtiles protocol:

import maplibregl from 'maplibre-gl';
import { Protocol } from 'pmtiles';

useEffect(() => {
let protocol = new Protocol();
maplibregl.addProtocol("pmtiles",protocol.tile);

... initialize your map here ...

return () => {
maplibregl.removeProtocol("pmtiles");
}
}, []);

Then, reference the tile archives with a relative path when initializing the map:

  style: {
sources: {
roads: {
type: "vector",
url: "pmtiles://../example-map/tiles/roads.pmtiles"
},
places: {
type: "vector",
url: "pmtiles://../example-map/tiles/places.pmtiles"
},
...

Step 3: Styling the layers

Each tab below contains the complete styles in the Maplibre Style Spec for the map on this page.

{
"id": "placesLabel",
"type": "symbol",
"source": "places",
"source-layer": "places",
"filter": [
"all",
[
"has",
"name"
],
[
">",
[
"get",
"confidence"
],
0.75
]
],
"minzoom": 15,
"maxzoom": 24,
"layout": {
"text-field": [
"concat",
"■\n",
[
"get",
"name"
]
],
"text-font": [
"Noto Sans Bold"
],
"text-max-width": 5,
"text-size": 10,
"text-line-height": 1,
"text-justify": "center",
"text-anchor": "center",
"text-radial-offset": 0.8,
"text-padding": 4
},
"paint": {
"text-color": "#071F3F",
"text-halo-color": "#dce6ef",
"text-halo-width": 1
}
}