Published
Edited
May 26, 2020
25 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
tileGeoJson = mvtToGeoJson(tileMVT)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
styleDoc
Insert cell
Insert cell
styleDoc.layers.find(highwayFinder)
Insert cell
Insert cell
Insert cell
Insert cell
parsedStyle = tileStencil.parseStyle(styleDoc)
Insert cell
highwayStyles = parsedStyle.layers.find(highwayFinder)
Insert cell
Insert cell
Insert cell
highwayStyles.paint["line-width"](tileCoords.z)
Insert cell
Insert cell
Insert cell
Insert cell
{
const ctx = DOM.context2d(tileSize, tileSize);
const path = d3.geoPath(null, ctx);

// Select the highway features
let highwayData = {
type: "FeatureCollection",
features: tileGeoJson.transportation.features.filter(highwayStyles.filter)
};

// Fill in the background color (necessary if highways are white)
let bgStyle = parsedStyle.layers.find(layer => layer.type === "background");
ctx.fillStyle = bgStyle.paint["background-color"](tileCoords.z);
ctx.fillRect(0, 0, tileSize, tileSize);

// Set the highway styles: translate style properties to Canvas2D settings
ctx.miterLimit = highwayStyles.layout["line-miter-limit"](tileCoords.z);
ctx.lineWidth = highwayStyles.paint["line-width"](tileCoords.z);
ctx.strokeStyle = highwayStyles.paint["line-color"](tileCoords.z);

// Draw the highways
ctx.beginPath();
path(highwayData);
ctx.stroke();

return ctx.canvas;
}
Insert cell
Insert cell
painterFuncs = tilePainter
.addPainters(parsedStyle, tileSize)
.layers.map(layer => layer.painter)
Insert cell
Insert cell
function drawTile(geoJson) {
// Start a cumulative list of label bounding boxes to check for collisions
const labelBoxes = [];
// Wrap the GeoJSON in an object to match the structure of style.sources
const sources = { openmaptiles: geoJson };
// Paint all the layers to the Canvas, in order
let t0 = performance.now();
painterFuncs.forEach(painter =>
painter(mapContext, tileCoords.z, sources, labelBoxes)
);
let t1 = performance.now();
return (t1 - t0).toFixed(3);
}
Insert cell
drawTile(tileGeoJson)
Insert cell
Insert cell
Insert cell
maptilerKey = "mrAq6zQEFxOkanukNbGm" // Get your own key: maptiler.com
Insert cell
Insert cell
tileURL = endpoint
.replace(/{z}/, tileCoords.z)
.replace(/{y}/, tileCoords.y)
.replace(/{x}/, tileCoords.x)
Insert cell
Insert cell
Insert cell
Insert cell
styleDoc = {
let doc = await styleChoice.file.json();
Object.values(doc.sources).forEach(src => {
if (src.url) src.url = src.url.replace(/{key}/, maptilerKey);
});
return doc;
}
Insert cell
Insert cell
tileBuf = new Protobuf(await d3.buffer(tileURL))
Insert cell
tileMVT = new vectorTileEsm.VectorTile(tileBuf)
Insert cell
Object.values(tileMVT.layers).map(l => l.length)
Insert cell
function mvtToGeoJson(mvt) {
let layers = {};
Object.values(mvt.layers).forEach(layer => {
layers[layer.name] = layer.toGeoJSON(tileSize);
});
return layers;
}
Insert cell
Insert cell
Insert cell
Insert cell
tilePainter = import('tile-painter@0.1.2')
Insert cell
tileStencil = import('tile-stencil@0.1.2')
Insert cell
vectorTileEsm = import('vector-tile-esm@2.1.0')
Insert cell
Protobuf = require('pbf')
Insert cell
d3 = require("d3-fetch@1", "d3-geo@1")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more