Landcover
Description We want a landcover layer at low zooms from https://daylightmap.org/2023/10/11/landcover.html
Screenshots Here are some rough previews:
@nvkelso should we put the 7 daylight landcover classes into https://tilezen.readthedocs.io/en/latest/layers/ or invent new kind values?
Barren / Snow / Crop / Shrub / Grass / Forest / Urban
The more OSM-y / Tilezen-y kind values might be (which already in Tilezen have both detailed and generic aggregations and segmentations), where (data value), blog label > proposed Tilezen kind value:
- (urban) Urban >
urban_area - (crop) Crop >
farmland - (grass) Grass >
grassland - (shrub) Shrub >
scrub- note this is is slightly different than the remapping in queries.yaml, but is a good enhancement based on my experience the last 3 years
- (barren) Barren >
barren(was initially ~~desert~~, updated based on comments and further research)- based on the viewer link below, this is desert. An alternative value is
barren - Tilezen already uses
barrenfor low zoom consolidation of detailed classes, so fair game
- based on the viewer link below, this is desert. An alternative value is
- (trees) Forest >
forest - (snow) Snow >
glacier(these are glaciers and permanent snow fields)
Then on zoom-in, the OSM data can be used instead, with the current OSM derived value moving to kind_detail, and these rollup values used for kind?
In the blog post another class was also mentioned, but the download doesn't have it:
- Water > ¿¿¿
wetlandorwater???- based on the viewer link below, could be either...
- based on the download and closer reading of blog post, this was either NE or OSM water used as a masking knockout, so we ignore it.
- So if there isn't a polygon in the data layer, it's assumed to be water
See also:
- https://worldcover2021.esa.int/viewer (which has a legend for the original classes)
- https://github.com/tilezen/vector-datasource/blob/master/queries.yaml#L369C0-L450C0
- https://github.com/tilezen/vector-datasource/issues/2025
- https://github.com/tilezen/vector-datasource/issues/1905
@nvkelso desert might be not ideal for esa's "Bare / sparse vegetation" because this landcover type is not only used in real deserts like the Sahara, but also wet mountain areas. For example, the Alps go from "Grass" to "Bare / sparse vegetation" to "Snow and Ice" with increasing altitude...
Hey folks I gave the Daylight landcover data a try even before we have it integrated properly. If anyone wants to follow along, here's how to get it into a .pmtiles file and the cevtor tiles styled on a Maplibre map.
Download the shapefile
$ aws s3 sync s3://daylight-openstreetmap/landcover/ . --no-sign-request
Convert to GeoJSON to check it out and to convert it to a .pmtiles file later on
$ ogr2ogr -f GeoJSON landcover.geojson low.shp
$ jq '.features[].properties.class' landcover.geojson | sort | uniq
"barren"
"crop"
"grass"
"shrub"
"snow"
"trees"
"urban"
Use tippecanoe to convert the GeoJSON file to a .pmtiles file
$ tippecanoe -o landcover.pmtiles -zg -n "Daylight Landcover" -N "https://daylightmap.org/2023/10/11/landcover.html" landcover.geojson
Host the .pmtiles on a static host; I have S3 + Cloudfront set up but your use-case might differ
aws s3 cp --cache-control 'public, max-age=30758400, immutable' --content-type 'binary/octet-stream' landcover.pmtiles s3://.../20231024/landcover.pmtiles
Add the source to a Maplibre map and style the landcover layer based on the landcover classes from above.
sources: {
landcover: {
type: "vector",
url: "pmtiles://https://example.com/landcover.pmtiles",
attribution: "<a href='https://daylightmap.org/2023/10/11/landcover.html'>Daylight</a>" },
maxzoom: 8,
},
map.addLayer({
id: "landcover",
type: "fill",
source: "landcover",
"source-layer": "landcover",
maxzoom: 10,
layout: {},
paint: {
"fill-opacity": [
"interpolate",
["linear"],
["zoom"],
0, 0.5,
10, 0
],
"fill-color": ["case",
["==", ["get", "class"], "barren"], "#a48137",
["==", ["get", "class"], "crop"], "#efc52e",
["==", ["get", "class"], "grass"], "#afe57f",
["==", ["get", "class"], "shrub"], "#dbf4c2",
["==", ["get", "class"], "snow"], "#f1eff7",
["==", ["get", "class"], "trees"], "#1c4321",
["==", ["get", "class"], "urban"], "#f1eff7",
"#ffffff"]
},
}, "physical_line_waterway_label"); // before first label layer
Results look as follows - I'm not a designer tho, please no hate :stuck_out_tongue:
Our approach here will start small:
- Add a new
layercalledlandcover(that will complement the existinglanduselayer).- Relevant Tilezen issues include: https://github.com/tilezen/vector-datasource/issues/1905 and https://github.com/tilezen/vector-datasource/issues/1885
- We'll use this data from Daylight here
- Because this Daylight data doesn't change with each release
- We'll converted to GeoPackage format, and
- Posted to a public Protomaps web assets location to make use of that format's spatial indexing in Planetiler
- We'll do light mapping of the raw Daylight data values into the Tilezen values mentioned above.
- This will also make it more future proof if new data is sourced later and that new source has slightly different value conventions.
- This will yield low zoom coverage only (eg to zoom 6/7/8 before it looks chunky / pixelated.
- Styling should fade the layer out over those zooms.
- Styling should also consider the z-order of these new landcover feature versus landuse.
- At this time we won't be moving any existing OSM related features in the
landuselayer to the newlandcoverlayer as that would be a breaking change.- We may consider doing that in a later major version release; see https://github.com/tilezen/vector-datasource/issues/2025 for details of which features could move over later.
Other data reviewed include:
- @wipfli's ESA worldcover polygons which goes to a higher zoom detail, but at cost of much larger data size.
- Esri/NationalGeographic/Microsoft's Sentinel-2 10m Land Use/Land Cover Time Series which has better classification algo (like for for shrubland in US desert south-west) and goes to 10 meters, but would require a similar rasterization approach that @wipfli took and have large data size.
- If Planetiler adds GeoParque support, that could unblock this. Otherwise the build data dependencies would overwhelm making some cuts of say Monaco or Switzerland.
Tileset part merged in tiles 3.5.0; TODO style additions
Meta is sun-setting the Daylight distribution in favor of Overture Maps
https://daylightmap.org/2024/05/03/sunsetting-daylight.html
If we want to use their landcover data we now need to check out the Overture Maps data.
We have this mirrored at https://r2-public.protomaps.com/datasets/daylight-landcover.gpkg , and don't expect the data to change quickly, so we should be isolated from this deprecation for a while... if/when we need to improve the data we can use a from-scratch ESA generated tileset or Overture.