Public
Edited
Dec 9, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/**
Extract widths per zoom for line layers. Returns an object with keys 0-22 with a linewidth for each zoom level.
Todo: interpolate for single integers and match expressions.
*/
function extractWidths(exp, id, minZoom, color) {;
if (!exp) return;
const obj = {}
if ((exp[0]) === 'interpolate') {
exp.splice(0, 3);

const zooms = exp.filter((e, idx) => idx % 2 === 0);
const values = exp.filter((e, idx) => idx % 2 !== 0).map(value => {
if (Array.isArray(value)) {
return value[3]
}
return value
});
const obj = {}

let currentVal = values[0];
let currentZoom = zooms[0];
let currentPos = 0;

obj.name = id;
obj.minzoom = minZoom;
obj.color = color;

// for zoom level 0 - 22
for (const i of d3.range(23)) {
if (i < minZoom) {
obj[`z${i}`] = 0;
} else {
if (zooms.indexOf(i) === -1) { // zoom does not exist

if (i > currentZoom && i < zooms[currentPos + 1] ) {
const inputs = {
zoom0: currentZoom,
zoom1: zooms[currentPos + 1],
width0: currentVal,
width1: values[currentPos + 1]
}
obj[`z${i}`] = getWidthFromZoom('linear', inputs, i);
} else {
obj[`z${i}`] = currentVal
}
} else { // zoom exists
currentVal = values[zooms.indexOf(i)]
currentZoom = i;
currentPos = zooms.indexOf(i);
obj[`z${i}`] = currentVal
}
}

}
return obj

} else {
return exp
}
}

Insert cell
/**
* Helper function to interpolate between input numbers. Currently only does linear interpolations.
*/
function getWidthFromZoom(type, inputs, zoom) {
const { width0, width1, zoom0, zoom1 } = inputs;

if (type === 'linear') {
const slope = (width1 - width0) / (zoom1 - zoom0)
const intercept = width0 - slope * zoom0;
return slope * zoom + intercept;
}
}
Insert cell
getStyle = {
const url = style.replace('mapbox://styles/','')
const response = await fetch(`https://api.mapbox.com/styles/v1/${url}?access_token=${accessToken}`)
const json = await response.json()

if (json.message === 'Not Found') return {data: 'Not Found'}
if (json.message === 'Style not found') return {data: 'Style Not Found'}

const data = json.layers.reduce(
( acc, currentValue ) => {
const { id, minzoom, type, paint } = currentValue;
console.log(currentValue.paint['line-color']);
return ["line"].indexOf(type)!== 0 ? acc : acc.concat(
extractWidths(paint['line-width'] || 1, id, minzoom || 0, currentValue.paint['line-color'])
)
},
[]
)

return data
}
Insert cell
// reshape
data = getStyle
.map((d) =>
fields.map((field) => ({
name: d.name,
color: d.color,
minzoom: d.minzoom,
value: d[field],
field
}))
)
.flat()
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