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.
- Places
- Placenames
- Buildings
- Roads
- Base (Land, Land Use & Water)
The places data theme represents business and points of interest in the real world. Read more about the places data schema in the documentation.
-
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'); -
Next, create a
pmtiles
archive fromseattle_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"
The admins theme contains named localities and their administrative boundaries. To add labels for populated places to the map, we query the admins theme to get the primary name for each locality.
-
The following DuckDB queries downloads placenames from the admins theme within the bounding box and saves it as
seattle_placenames.geojson
LOAD spatial;
LOAD azure;
-- Access the data on Microsoft Azure in this example
SET azure_storage_connection_string = 'DefaultEndpointsProtocol=https;AccountName=overturemapswestus2;AccountKey=;EndpointSuffix=core.windows.net';
COPY (
SELECT
subtype,
locality_type,
names.primary as name,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('azure://release/2024-04-16-beta.0/theme=admins/type=locality/*',
filename=true, hive_partitioning=1)
WHERE bbox.xmin > -122.679404 AND bbox.xmax < -121.978275
AND bbox.ymin > 47.360619 AND bbox.ymax < 47.786336
) TO 'seattle_placenames.geojson'
WITH (FORMAT GDAL, DRIVER 'GeoJSON', SRS 'EPSG:4326'); -
Run tippecanoe to produce a
pmtiles
archive fromseattle_placenames.geojson
tippecanoe -fo placenames.pmtiles -Z5 -z10 -l placenames seattle_placenames.geojson
Tippecanoe flag explanation
-fo placenames.pmtiles
is our output file. It will be overwritten if it exists.-Z5
and-z10
will produce a tileset starting at zoom 5 and going up to zoom 10.-l placenames
names the layer "placenames"
Overture contains billions of buildings distirbuted across hundreds of geoparquet files.
-
The following DuckDB query reads only the metadata of each file and then downloads only the buildings within our bounding box to a line-delimited
GeoJSONSeq
file.LOAD spatial;
LOAD azure;
-- Access the data on Microsoft Azure in this example
SET azure_storage_connection_string = 'DefaultEndpointsProtocol=https;AccountName=overturemapswestus2;AccountKey=;EndpointSuffix=core.windows.net';
COPY (
SELECT
names.primary as name,
height,
level,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('azure://release/2024-07-22.0/theme=buildings/type=building/*', filename=true, hive_partitioning=1)
WHERE bbox.xmin > -122.68 AND bbox.xmax < -121.98
AND bbox.ymin > 47.36 AND bbox.ymax < 47.79
) TO 'seattle_buildings.geojsonseq'
WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq', SRS 'EPSG:4326'); -
Run tippecanoe to produce a
pmtiles
archive fromseattle_buildings.geojsonseq
tippecanoe -fo buildings.pmtiles -Z13 -z13 -l buildings -P seattle_buildings.geojsonseq
Tippecanoe flag explanation
-fo buildings.pmtiles
is our output file. It will be overwritten if it exists.-Z13
and-z13
will produce a tileset starting at zoom 13 and going up to zoom 13 (so only 1 zoom level).-l buildings
names the layer "buildings"-P
allows tippecanoe to read the file in parallel. Since we created a GeoJSON sequence file instead of a single GeoJSON Feature Collection, tippecanoe can process the input data more efficiently.
The Overture Maps transportation theme has two types: connectors
and segments
. Since we want to render the road lines, we will query for type=segment
.
-
This DuckDB query downloads road segments from Overture to a
GeoJSONSeq
file.LOAD spatial;
LOAD httpfs;
COPY (
SELECT
level,
names.primary AS name,
JSON_EXTRACT_STRING(road, '$.class') AS class,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/2024-07-22.0/theme=transportation/type=segment/*')
WHERE
subtype = 'road'
AND bbox.xmin > -122.68 AND bbox.xmax < -121.98
AND bbox.ymin > 47.36 AND bbox.ymax < 47.79
) TO 'seattle_roads.geojsonseq'
WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq', SRS 'EPSG:4326'); -
Run tippecanoe to produce a
pmtiles
archive fromseattle_roads.geojsonseq
tippecanoe -fo roads.pmtiles -Z10 -B10 -z13 -l roads -P seattle_roads.geojsonseq
Tippecanoe flag explanation
-fo roads.pmtiles
is our output file. It will be overwritten if it exists.-Z10
and-z13
will produce a tileset starting at zoom 10 and going up to zoom 13.-B10
will ensure that all featuers are present from zoom level 10.-l roads
names the layer "roads"-P
allows tippecanoe to read the file in parallel. Since we created a GeoJSON sequence file instead of a single GeoJSON Feature Collection, tippecanoe can process the input data more efficiently.
-
land
,land_use
, andwater
are the three types available in thebase
theme. We can use 3 separate queries to obtain the features and then we can combine them into a single pmtiles archive with different layers.1. DuckDB query to produce
land.geojsonseq
LOAD spatial;
LOAD httpfs;
COPY (
SELECT
subtype,
class,
names.primary AS name,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/2024-07-22.0/theme=base/type=land/*')
WHERE
bbox.xmin > -122.68 AND bbox.xmax < -121.98
AND bbox.ymin > 47.36 AND bbox.ymax < 47.79
)
TO 'seattle_land.geojsonseq'
WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq', SRS 'EPSG:4326');2. DuckDB query to produce
land_use.geojsonseq
LOAD spatial;
LOAD httpfs;
COPY (
SELECT
subtype,
class,
names.primary AS name,
surface,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/2024-07-22.0/theme=base/type=land_use/*')
WHERE
bbox.xmin > -122.68 AND bbox.xmax < -121.98
AND bbox.ymin > 47.36 AND bbox.ymax < 47.79
)
TO 'seattle_land_use.geojsonseq' WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq', SRS 'EPSG:4326');3. DuckDB query to produce
water.geojsonseq
LOAD spatial;
LOAD httpfs;
COPY (
SELECT
subtype,
class,
names.primary AS name,
ST_GeomFromWKB(geometry) as geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/2024-07-22.0/theme=base/type=water/*')
WHERE
subtype in ('ocean', 'lake', 'pond', 'reservoir', 'river', 'stream', 'water', 'canal')
AND bbox.xmin > -123 AND bbox.xmax < -122
AND bbox.ymin > 47 AND bbox.ymax < 48
) TO 'seattle_water.geojsonseq' WITH (FORMAT GDAL, DRIVER 'GeoJSONSeq', SRS 'EPSG:4326');Note: We use a slightly larger bounding box to capture the Ocean water polygons, too
-
Run tippecanoe to produce a
pmtiles
archive with threegeojsonseq
file as input:tippecanoe -fo base.pmtiles -Z8 -z13 -P \
--named-layer=land:seattle_land.geojsonseq \
--named-layer=landuse:seattle_land_use.geojsonseq \
--named-layer=water:seattle_water.geojsonseqTippecanoe flag explanation
-fo tiles/base.pmtiles
is our output file. It will be overwritten if it exists.-Z8
and-z13
will produce a tileset starting at zoom 8 going up to zoom 13.--named-layer=land:seattle_land.geojsonseq
creates theland
layer from the contents ofseattle_land.geojson
(and similarly for the other files)-P
allows tippecanoe to read the file in parallel. Since we created a GeoJSON sequence file instead of a single GeoJSON Feature Collection, tippecanoe can process the input data more efficiently.
Step 2: Creating a map with Maplibre + PMTiles
At this point, we have created five PMTiles archives from the five Overture themes:
places.pmtiles
placenames.pmtiles
buildings.pmtiles
roads.pmtiles
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.
- Places
- Placenames
- Buildings
- Roads
- Land
- Landuse
- Water
{
"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
}
}
{
"placeHighZoom": {
"id": "placeHighZoom",
"type": "symbol",
"source": "placenames",
"source-layer": "placenames",
"minzoom": 9,
"maxzoom": 24,
"layout": {
"text-field": [
"get",
"name"
],
"text-font": [
"Noto Sans Bold"
],
"text-size": [
"step",
[
"zoom"
],
14,
10,
[
"match",
[
"get",
"locality_type"
],
[
"borough"
],
14,
[
"suburb"
],
12,
0
],
12,
[
"match",
[
"get",
"locality_type"
],
[
"borough"
],
16,
[
"suburb"
],
14,
[
"neighborhood"
],
10,
0
],
14,
[
"match",
[
"get",
"locality_type"
],
[
"borough"
],
18,
[
"suburb"
],
16,
[
"neighborhood"
],
12,
0
],
15,
[
"match",
[
"get",
"locality_type"
],
[
"borough"
],
20,
[
"suburb"
],
18,
[
"neighborhood"
],
14,
0
],
16,
[
"match",
[
"get",
"locality_type"
],
[
"borough"
],
20,
[
"suburb"
],
18,
[
"neighborhood"
],
14,
[
"block"
],
12,
0
]
],
"text-transform": [
"step",
[
"zoom"
],
"none",
11,
"uppercase"
],
"text-max-width": 6,
"symbol-avoid-edges": true,
"text-padding": 10,
"text-justify": "auto"
},
"paint": {
"text-color": "#071F3F",
"text-halo-color": "#dce6ef",
"text-halo-width": 1
}
},
"placeMidZoom": {
"id": "placeMidZoom",
"type": "symbol",
"source": "placenames",
"source-layer": "placenames",
"minzoom": 8,
"maxzoom": 24,
"filter": [
"all",
[
"has",
"name"
],
[
"step",
[
"zoom"
],
[
"==",
"$type",
"Point"
],
8,
[
"match",
[
"get",
"localityType"
],
[
"settlement"
],
true,
false
],
9,
[
"match",
[
"get",
"localityType"
],
[
"urban",
"settlement"
],
true,
false
]
]
],
"layout": {
"text-field": [
"get",
"name"
],
"text-font": [
"Noto Sans Bold"
],
"text-size": [
"step",
[
"zoom"
],
10,
9,
[
"match",
[
"get",
"localityType"
],
[
"megacity"
],
20,
[
"metropolis"
],
18,
[
"city"
],
16,
[
"municipality"
],
14,
[
"town"
],
10,
0
],
10,
[
"match",
[
"get",
"localityType"
],
[
"megacity"
],
22,
[
"metropolis"
],
20,
[
"city"
],
18,
[
"municipality"
],
16,
[
"town"
],
12,
0
],
12,
[
"match",
[
"get",
"localityType"
],
[
"megacity"
],
22,
[
"metropolis"
],
20,
[
"city"
],
18,
[
"municipality"
],
16,
[
"town"
],
12,
[
"village"
],
10,
0
],
14,
[
"match",
[
"get",
"subclass"
],
[
"megacity"
],
22,
[
"metropolis"
],
20,
[
"city"
],
18,
[
"municipality"
],
16,
[
"town"
],
14,
[
"village",
"hamlet"
],
12,
0
],
15,
[
"match",
[
"get",
"subclass"
],
[
"megacity"
],
22,
[
"metropolis"
],
20,
[
"city"
],
18,
[
"municipality"
],
16,
[
"town"
],
14,
[
"village",
"hamlet"
],
14,
0
],
16,
[
"match",
[
"get",
"subclass"
],
[
"village",
"hamlet"
],
16,
0
]
],
"text-transform": [
"step",
[
"zoom"
],
"none",
11,
"uppercase"
],
"text-padding": [
"step",
[
"zoom"
],
10,
9,
8,
10,
5,
12,
3
],
"text-max-width": 6,
"symbol-avoid-edges": true,
"symbol-sort-key": [
"get",
"sort_key"
],
"text-justify": "auto"
},
"paint": {
"text-color": "#071F3F",
"text-halo-color": "#dce6ef",
"text-halo-width": 1
}
}
}
{
"id": "buildings",
"type": "fill-extrusion",
"minzoom": 12,
"maxzoom": 24,
"source": "buildings",
"source-layer": "buildings",
"paint": {
"fill-extrusion-color": "#dce6ef",
"fill-extrusion-opacity": 0.6,
"fill-extrusion-base": 0,
"fill-extrusion-height": [
"case",
[
"has",
"height"
],
[
"to-number",
[
"get",
"height"
]
],
3.2
]
}
}
{
"footwayCasing": {
"id": "footwayCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 15,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"footway"
],
true,
false
],
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.25,
20,
1.3
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.5,
16,
3,
22,
25
],
"line-color": "#dce6ef"
}
},
"footway": {
"id": "footway",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 15,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"footway"
],
true,
false
],
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.5,
16,
3,
22,
25
],
"line-color": "#b9ccdf"
}
},
"parkingAisleUnknownCasing": {
"id": "parkingAisleUnknownCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 14,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"parking_aisle",
"unknown"
],
true,
false
],
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.25,
20,
1.3
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.5,
16,
3.5,
22,
75
],
"line-color": "#dce6ef"
}
},
"residentialCasing": {
"id": "residentialCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 12,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"residential"
],
true,
false
],
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.75,
20,
1.3
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
1,
16,
6,
22,
125
],
"line-color": "#dce6ef"
}
},
"secondaryTertiaryCasing": {
"id": "secondaryTertiaryCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 11,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"secondary",
"tertiary"
],
true,
false
],
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
1,
20,
1.3
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
10,
0.5,
12,
2.2,
16,
6.6,
22,
160
],
"line-color": "#dce6ef"
}
},
"primaryCasing": {
"id": "primaryCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 8,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"primary"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
16,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
16,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
1,
20,
1.4
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
8,
0.5,
12,
3.1,
16,
9.3,
22,
175
],
"line-color": "#dce6ef"
}
},
"parkingAisleUnknown": {
"id": "parkingAisleUnknown",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 14,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"parking_aisle",
"unknown"
],
true,
false
],
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
0.5,
16,
3.5,
22,
75
],
"line-color": "#a7bfd7"
}
},
"residential": {
"id": "residential",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 12,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"residential"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
13,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
13,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
1,
16,
6,
22,
125
],
"line-color": "#a7bfd7"
}
},
"secondaryTertiary": {
"id": "secondaryTertiary",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 10,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"secondary",
"tertiary"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
13,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
13,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
10,
0.5,
12,
2.2,
16,
6.6,
22,
160
],
"line-color": "#a7bfd7"
}
},
"primary": {
"id": "primary",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 8,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"primary"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
13,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
13,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
8,
0.5,
12,
3.1,
16,
9.3,
22,
175
],
"line-color": "#a7bfd7"
}
},
"motorwayCasing": {
"id": "motorwayCasing",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 6,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"motorway"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
13,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
13,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
12,
1,
20,
1.4
],
"line-gap-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
6,
0.5,
12,
3.3,
16,
9.9,
22,
175
],
"line-color": "#dce6ef"
}
},
"motorway": {
"id": "motorway",
"type": "line",
"source": "roads",
"source-layer": "roads",
"minzoom": 6,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"motorway"
],
true,
false
],
"layout": {
"line-cap": [
"step",
[
"zoom"
],
"butt",
12,
"round"
],
"line-join": [
"step",
[
"zoom"
],
"miter",
12,
"round"
]
},
"paint": {
"line-width": [
"interpolate",
[
"exponential",
1.5
],
[
"zoom"
],
6,
0.5,
12,
3.3,
16,
9.9,
22,
175
],
"line-color": "#95b2d0"
}
},
"residentialLabel": {
"id": "residentialLabel",
"type": "symbol",
"source": "roads",
"source-layer": "roads",
"minzoom": 13,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"residential",
"unknown"
],
true,
false
],
"layout": {
"text-transform": "uppercase",
"text-size": [
"interpolate",
[
"linear"
],
[
"zoom"
],
13,
9,
18,
[
"match",
[
"get",
"class"
],
[
"access",
"path"
],
9,
12
]
],
"text-max-angle": 30,
"symbol-spacing": [
"interpolate",
[
"linear"
],
[
"zoom"
],
13,
200,
16,
400
],
"text-field": [
"get",
"name"
],
"text-font": [
"Noto Sans Bold"
],
"symbol-placement": "line",
"text-padding": 5
},
"paint": {
"text-color": "#071F3F",
"text-halo-color": "hsl(0,0%,100%)",
"text-halo-width": 1
}
},
"highwayLabel": {
"id": "highwayLabel",
"type": "symbol",
"source": "roads",
"source-layer": "roads",
"minzoom": 13,
"maxzoom": 24,
"filter": [
"match",
[
"get",
"class"
],
[
"motorway",
"primary",
"secondary",
"tertiary"
],
true,
false
],
"layout": {
"text-transform": "uppercase",
"text-size": [
"interpolate",
[
"linear"
],
[
"zoom"
],
13,
9,
18,
[
"match",
[
"get",
"class"
],
[
"access",
"path"
],
9,
12
]
],
"text-max-angle": 30,
"symbol-spacing": [
"interpolate",
[
"linear"
],
[
"zoom"
],
13,
200,
16,
400
],
"text-field": [
"get",
"name"
],
"text-font": [
"Noto Sans Bold"
],
"symbol-placement": "line"
},
"paint": {
"text-color": "#071F3F",
"text-halo-color": "hsl(0,0%,100%)",
"text-halo-width": 1
}
}
}
{
"land": {
"id": "land",
"type": "fill",
"source": "base",
"source-layer": "land",
"filter": [
"match",
[
"get",
"subtype"
],
[
"land"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#ccdae8"
}
},
"sand": {
"id": "sand",
"type": "fill",
"source": "base",
"source-layer": "land",
"filter": [
"match",
[
"get",
"subtype"
],
[
"sand"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#EBD5BD"
}
},
"wetland": {
"id": "wetland",
"type": "fill",
"source": "base",
"source-layer": "land",
"filter": [
"match",
[
"get",
"subtype"
],
[
"wetland"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#00A9BF"
}
},
"forest": {
"id": "forest",
"type": "fill",
"source": "base",
"source-layer": "land",
"filter": [
"match",
[
"get",
"subtype"
],
[
"forest",
"grass",
"scrub"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#09bac6"
}
}
}
{
"parks": {
"id": "parks",
"type": "fill",
"source": "base",
"source-layer": "landuse",
"filter": [
"match",
[
"get",
"subtype"
],
[
"park"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#09bac6"
}
},
"golfGreens": {
"id": "golfGreens",
"type": "fill",
"source": "base",
"source-layer": "landuse",
"filter": [
"==",
[
"get",
"class"
],
"fairway"
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#09bac6"
}
},
"recSand": {
"id": "golfBunker",
"type": "fill",
"source": "base",
"source-layer": "landuse",
"filter": [
"match",
[
"get",
"surface"
],
[
"recreation_sand"
],
true,
false
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#EBD5BD"
}
}
}
{
"waterPolygons": {
"id": "water-fill",
"type": "fill",
"source": "base",
"source-layer": "water",
"filter": [
"==",
[
"geometry-type"
],
"Polygon"
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"fill-color": "#3063d2"
}
},
"waterLinestrings": {
"id": "water-line",
"type": "line",
"source": "base",
"source-layer": "water",
"filter": [
"==",
[
"geometry-type"
],
"LineString"
],
"minzoom": 0,
"maxzoom": 24,
"paint": {
"line-width": 3,
"line-color": "#3063d2"
}
}
}