Skip to content

Instantly share code, notes, and snippets.

@bdon
Created June 6, 2021 06:00
Show Gist options
  • Save bdon/594f05e6137c12b12e76a0aac3d6be8e to your computer and use it in GitHub Desktop.
Save bdon/594f05e6137c12b12e76a0aac3d6be8e to your computer and use it in GitHub Desktop.
MapLibre Protocol: PMTiles implementation
<!DOCTYPE html>
<html lang="en">
<head>
<title>MapLibre GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='../dist/maplibre-gl.css' />
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>
<body>
<div id='map'></div>
<script src='../dist/maplibre-gl-dev.js'></script>
<script src="https://unpkg.com/pmtiles@latest/index.js"></script>
<script>
// protocol issues
// zxy issues
var style = {
"version": 8,
"sources": {
"tpe_sample": {
"type": "vector",
"tiles": ["pmtiles://https://protomaps-static.sfo3.digitaloceanspaces.com/tpe_sample.pmtiles/{z}/{x}/{y}"],
"maxzoom":14
}
},
"layers": [
{
"id": "buildings",
"type": "fill",
"source":"tpe_sample",
"source-layer":"buildings",
"paint": {
"fill-color":"black"
}
},
{
"id": "roads",
"type": "line",
"source":"tpe_sample",
"source-layer":"roads",
"paint": {
"line-color":"red"
}
},
{
"id": "mask",
"type": "fill",
"source":"tpe_sample",
"source-layer":"mask",
"paint": {
"fill-color":"white"
}
}
]
};
let re = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/)
let pmtiles_instances = new Map()
maplibregl.addProtocol('pmtiles', (params, callback) => {
let result = params.url.match(re)
let pmtiles_url = result[1]
if (!pmtiles_instances.has(pmtiles_url)) {
pmtiles_instances.set(pmtiles_url,new pmtiles.PMTiles(pmtiles_url))
}
let instance = pmtiles_instances.get(pmtiles_url)
let z = result[2]
let x = result[3]
let y = result[4]
instance.getZxy(+z,+x,+y).then(val => {
if (val) {
let headers = {'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}
fetch(pmtiles_url,{headers:headers}).then(resp => {
return resp.arrayBuffer()
}).then(arr => {
callback(null,arr,null,null)
})
} else {
callback(null,new Uint8Array(),null,null)
}
})
return { cancel: () => { console.log("Cancel not implemented") } };
});
var map = new maplibregl.Map({
container: 'map',
center: [121.5177,25.0412],
zoom: 14,
style: style
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment