Add PMTiles post

This commit is contained in:
Tom 2023-10-30 21:13:50 +00:00
parent 26963c64a8
commit fec73b85b5
7 changed files with 12942 additions and 1 deletions

View File

@ -0,0 +1,81 @@
---
title: "Interactive web maps from a static file"
layout: post
excerpt: |
PMTiles is a cool new technology to serve interactive vector maps from a static file.
image:
thumbnail:
head: |
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@3.3.1/dist/maplibre-gl.css" crossorigin="anonymous">
<script src="https://unpkg.com/maplibre-gl@3.3.1/dist/maplibre-gl.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/pmtiles@2.11.0/dist/index.js"></script>
---
PMTiles is a new project that lets you serve vector map data from static files through the magic of HTTP range requests.
By following this [blog post][blog] and throwing in a bit of code from [the official examples][official_examples] I've put together this little map below. The vector data is entirely served from a static file on this server. Most interactive web maps work by constantly requesting little map images from an external server at different zoom levels. This approach uses much less data and doesn't require an external server to host all the map data.
[blog]: https://til.simonwillison.net/gis/pmtiles
[official_examples]: https://github.com/protomaps/PMTiles/blob/main/js/examples/maplibre.html
<figure id="map" style="width:100%; height:500px;"></figure>
<script type="text/javascript">
async function main() {
// add the PMTiles plugin to the maplibregl global.
let protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles",protocol.tile);
let PMTILES_URL = "/assets/blog/pmtiles/hackney.pmtiles";
const p = new pmtiles.PMTiles(PMTILES_URL);
// this is so we share one instance across the JS code and the map renderer
protocol.add(p);
let isDark = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
async function getLayers(isDark) {
let style_name = isDark ? "/dark.json" : "/light.json";
const base = '{{"/assets/blog/pmtiles/" | relative_url}}';
let resp = await fetch(base + style_name);
let layers = await resp.json();
return layers;
}
let style = {
version:8,
glyphs: "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf",
sources: {
"static_hackney": {
type: "vector",
url: "pmtiles://" + PMTILES_URL,
attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a>'
}
},
layers: await getLayers(isDark),
}
let map = new maplibregl.Map({
container: 'map',
style: style,
});
// map.showTileBoundaries = true;
map.on("load", () => {
const myBounds = map.getSource("static_hackney").bounds;
map.setMaxBounds(myBounds);
});
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', async event => {
let isDark = event.matches;
console.log(isDark);
style.layers = await getLayers(isDark);
console.log(style);
map.setStyle(style);
});
};
main();
</script>

View File

@ -123,7 +123,7 @@ figure > img, figure > svg, figure > canvas {
padding-top: 10px;
padding-left: 20px;
padding-right: 20px;
margin: 0px;
margin: auto;
justify-content: flex-start;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff