Overture data themes include transportation
, buildings
, places
, and admins
. A complete basemap, however, will need additional context layers, such as land and water.
For these context layers, we can look to the Daylight Earth Table. This dataset is published alongside the Daylight Map Distribution, and is created by extracting relevant features from Daylight and organizing them into theme
, class
, and subclass
. If, for example, you are looking for all of the water in the world, you can query the water
theme. If you only want oceans, there is an ocean
class. Similarly, there is a land
theme that includes natural landcover and a landuse
theme with features relating to land developed by humans.
Watch our Daylight Earth Table presentation at NACIS 2022.
This sample will focus on the Pacific Northwest in the United States. Our bounding box is:
POLYGON((-126.7952 50.4344, -118.5453 50.4344, -118.5453 43.5453, -126.7952 43.5453, -126.7952 50.4344))
.
We can start by extracting all of the road segments
from the transportation theme using Amazon Athena.
SELECT
subtype,
JSON_EXTRACT_SCALAR(road,'$.class') as class,
JSON_EXTRACT_SCALAR(road,'$.roadNames.common[0].value') AS name,
level,
ST_ASTEXT(ST_GeomFromBinary(geometry)) as wkt
FROM
transportation
WHERE type = 'segment' AND
bbox.minX > -126.7952
AND bbox.maxX < -118.5453
AND bbox.minY > 43.5453
AND bbox.maxY < 50.4344
This produces a 630 mb CSV file with 2M rows.
Next, we can use DuckDB to turn this CSV into GeoJSONSeq. We could do additional processing here if we wanted, such as renaming columns.
COPY (
SELECT
subtype, class, name, level,
ST_GeomFromText(wkt) as geometry
FROM 'csv/pnw_segments.csv'
) TO 'roads.geojsonseq'
WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq');
All of the DuckDB queries used in this example are recorded in conversion.sql
. The queries require that the spatial DuckDB extension is installed.
Use Tippecanoe to turn the geojson features into a pmtiles
archive:
tippecanoe -fo tiles/roads.pmtiles -Z11 -z11 -l roads roads.geojsonseq
In this example, we will only render the tiles at zoom-level 11 and overzoom from there. A more efficient approach would be to separate different classes of roads to different zoom levels, which could be done with some additional post-processing.
Maplibre can read pmtiles directly with the pmtiles protocol.
<head>
<script src="https://unpkg.com/pmtiles@2.5.0/dist/index.js"></script>
</head>
Add the protcol to the map:
let protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile);
and then reference the tileset in the source:
style: {
sources: {
roads: {
type: "vector",
url: "pmtiles://tiles/roads.pmtiles"
}
}
}
Read the full source here: https://github.com/OvertureMaps/overture-with-daylight/blob/main/docs/index.html.
This demo uses pmtiles, so you will need a local HTTP server that can support byte-range requests with CORS.
On a Mac, you can run http-server --cors .
from the docs
directory after installing http-server:
brew install http-server
). Then open http://127.0.0.1.
This example is licensed under CC-BY 4.0.