I am trying to replicate the example from Mike Bostock: https://observablehq.com/@d3/mapbox-vector-tiles
Since the language of Observable is not native Javascript, I am unable to get the example running.
Especially, the following two functions I am unable to get to work:
VectorTile = (await require("https://bundle.run/@mapbox/vector-tile@1")).VectorTile
Protobuf = require("pbf@3/dist/pbf.js")
require()
is not a Javascript command. So, how can I get these two libraries?
What I tried:
<script></script>
tagsLoading with await
:
let VectorTile = await fetch('https://bundle.run/@mapbox/vector-tile@1.3.1'); let Protobuf = await fetch('https://unpkg.com/pbf@3.0.5/dist/pbf.js');
I am not sure if require()
comes from node.js. So I played around with node.js but did not find a working solution either.
So, my question is: How can I get the example from Mike Bostock to work? Or in more general manner: How should I load vector tiles from Mapbox that I can convert them to geojson format as Mike is it doing in this example?
Regarding your first question, in order to get Mike Bostock's example to work you can keep in mind considerations:
require()
comes from node.js)require().VectorTile
). You can see how I've done it below for JavaScript in htmlI can't really tell how you 'should' load vector tiles, as I don't have much expertise in this particular aria. However, below I converted Mike Bostock's example to javascript, so you can see how it works outside of Observable.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div> Map: <div id='map'></div> </div> <script src="https://d3js.org/d3-array.v2.min.js"></script> <script src="https://d3js.org/d3-geo.v2.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/d3-tile@1"></script> <script src="https://d3js.org/d3-dsv.v2.min.js"></script> <script src="https://d3js.org/d3-fetch.v2.min.js"></script> <script src="https://unpkg.com/pbf@3.0.5/dist/pbf.js"></script> <script src="https://bundle.run/@mapbox/vector-tile@1.3.1"></script> <script>let VectorTile = _mapbox_vectorTile.VectorTile</script> <script> height = 600; width = 954; API_KEY = 'cfNfEQR1Qkaz-6mvWl8cpw';// Sign up for an API key: https://www.nextzen.org projection = d3.geoMercator() .center([-122.4183, 37.7750]) .scale(Math.pow(2, 21) / (2 * Math.PI)) .translate([width / 2, height / 2]).precision(0); path = d3.geoPath(projection) tile = d3.tile() .size([width, height]) .scale(projection.scale() * 2 * Math.PI) .translate(projection([0, 0])); function filter({features}, test) { return {type: "FeatureCollection", features: features.filter(test)}; }; function geojson([x, y, z], layer, filter = () => true) { if (!layer) return; const features = []; for (let i = 0; i < layer.length; ++i) { const f = layer.feature(i).toGeoJSON(x, y, z); if (filter.call(null, f, i, features)) features.push(f); } return {type: "FeatureCollection", features}; } tiles_pr = Promise.all(tile().map(async d => { d.layers = new VectorTile(new Pbf(await d3.buffer(`https://tile.nextzen.org/tilezen/vector/v1/256/all/${d[2]}/${d[0]}/${d[1]}.mvt?api_key=${API_KEY}`))).layers; return d; })) tiles_pr.then( function(tiles){ //console.log(tiles) map = `<svg viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg">${tiles.map(d => ` <path fill="#eee" d="${path(geojson(d, d.layers.water, d => !d.properties.boundary))}"></path> <path fill="none" stroke="#aaa" d="${path(geojson(d, d.layers.water, d => d.properties.boundary))}"></path> <path fill="none" stroke="#000" stroke-width="0.75" d="${path(geojson(d, d.layers.roads))}"></path> `)} </svg>` document.getElementById('map').innerHTML=map; } ); </script> </body> </html>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.