Maplibre adapter should pass along attribution
https://github.com/protomaps/PMTiles/blob/17583ae19dba1392f48e63a12669f834064e797e/js/adapters.ts#L129-L134
Should also include: attribution: m.attribution,, where m is the result of instance.getMetadata(). Or the TileJSON could be the entire metadata verbatim, plus the fields from the header.
Maplibre would then be able to show the attribution automatically.
I'm a bit torn on this because the size of metadata is unbounded. This is not a theoretical concern - tippecanoe automatically produces a tilestats key with info on column values, which can easily be 30 kb compressed - making the map load block on that to load a single sentence, by default, seems bad.
Yes, that's unfortunate.
For some numbers:
- The planet at tile.ourmap.us contains (approximately) 39,359 bytes of json, or 2,893 gzipped, which I expect should be typical of any users of the OpenMapTiles schema.
- The pmtiles from alltheplaces.xyz contains 37,636 bytes of gzipped json, which decompresses to 141,885 bytes. (Since this is produced by throwing a huge amount of nonsense at tippecanoe without care for how big the tilejson becomes.)
On the one hand, fetching the first 64 KiB should therefore allow reading the complete metadata in many situations. On the other hand, the current spec and implementation only fetch the first 16 KiB in order to read the header and root. So this could be achieved by increasing the length of this initial read.
(The metadata could also be treated as a potentially-truncated JSON document to find the attribution, but that seems foolhardy.)
Manipulating the attribution of the maplibre source after it has loaded is … sort of possible but feels hacky. If maplibre had native pmtiles support it would be more plausible for the source to quickly read the root to determine the extents and format, and then lazily fetch the metadata.
@jleedev the 16kb was intentionally chosen to be conservative - we can expand this to 32kb or 64kb if we discover that's a better default, while remaining backwards compatible with old archives for "free". The reverse is not true (if we started with a 32kb fetch, and later changed it to be 16kb, we'd have to add logic and extra requests to deal with old archives)
However, I don't think making predictions on metadata size to include them in the first 64kb is reliable. @acalcutt needs the vector_layers key to power maplibre-gl-inspect - I suggested we can add a ?metadata=true to the URL that would block on fetching metadata before returning the TileJSON to maplibre.
That would give you automatic attribution in the case you pass ?metadata=true (default false).
Regarding the API design, a hash parameter would be better than a query parameter (#metadata=true), since this is not being passed to the server.
Or we could add options to the Protocol constructor, e.g. protocol = new pmtiles.Protocol({ metadata: true }).
Is your goal to make attribution appear automatically for all archives within a given application, or for a specific one?
The Protocol constructor would work globally, the hash parameter would be specific to one (but could support all if it's a URL template)
That's the question, isn't it.
I think anyone who is loading some sort of dynamic data, or implementing an inspect control, would prefer to see the metadata. In alltheplaces we've encoded the build date into the attribution string; Americana has the planetiler replication timestamp in the metadata (at least in principle); an inspect control would like to get at the vector_layers array.
Anyone who is using this protocol as a basemap for something else probably does not require it. For instance, they would hardcode the attribution string alongside the URL to their tiles, in their map style.
This adapter currently has no options. Being able to specify options both globally and on a per-source basis sounds reasonable to me and would meet unanticipated use cases.
It appears that passing along the vector_layers also allows maplibre-gl-js to validate that each style layer refers to something that exists.
Here's what it would look like for #metadata=true as a URL option
https://github.com/protomaps/PMTiles/commit/8127188258fb93ee60b5cc2cb3fed316e2687c0c
Adding a API surface to addProtocol seems worse than extending an "API"(URLs) that we're already using.
Also related to https://github.com/protomaps/PMTiles/issues/239
Nice, I think that looks pretty sensible.
Looks nice, can't wait to try it :-)
I honestly hadn't even thought of the attribution. I include a datastamp in my generated files too, since it helps to just look and see a new map generated that day.
TODO: confirm that the above works with non-remote URL sources, like a local FileSource.
I changed my mind and will make it a protocol level option: https://github.com/protomaps/PMTiles/pull/461
This means you cannot control the loading of metadata/attribution per source. That required using a #metadata=true in the URL which can break a lot of other things because internally the source is keyed via its URL.
It seems like the applications that are "inspectors" like https://github.com/maplibre/maplibre-gl-inspect will want to use metadata: true, as well as if you want the automatic attribution on your map, but the default is to avoid the extra metadata request.
Required for https://github.com/maplibre/maputnik/issues/807
Released in 3.2.0. See example: https://github.com/protomaps/PMTiles/blob/main/js/examples/maplibre.html#L23