Public
Edited
Nov 27, 2023
Insert cell
Insert cell
measurements_export.json
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/**
* Fetches OpenStreetMap ways for a specified node.
* @async
* @param {string | number} nodeId
*/
async function fetchOsmWaysForNode(nodeId) {
const osmApiResult = await fetch(
`https://api.openstreetmap.org/api/0.6/node/${nodeId}/ways`
)
.then((response) => response.text())
.then((str) => new window.DOMParser().parseFromString(str, "text/xml"));

const ways = [];

for (let way of osmApiResult.getElementsByTagName("way")) {
const tags = {};
const tagNodes = way.getElementsByTagName("tag");

for (let tagNode of tagNodes) {
tags[tagNode.getAttribute("k")] = tagNode.getAttribute("v");
}

ways.push({
id: way.getAttribute("id"),
timestamp: way.getAttribute("timestamp"),
tags: tags
});
}

return ways;
}
Insert cell
exampleWays = fetchOsmWaysForNode(11079698224)
Insert cell
function totalLanes(ways) {
const lanes = ways
.map((way) => way.tags.lanes)
.filter((d) => d !== undefined)
.map((n) => Number(n))
.reduce((a, b) => a + b, 0);

if (lanes === 0) {
return undefined;
}

return lanes;
}
Insert cell
exampleTotalLanes = totalLanes(exampleWays)
Insert cell
Insert cell
tidyData = Promise.all(
table.map(async (d) => {
const ways = await fetchOsmWaysForNode(d.osm_node_id);
const neighbouring_lanes = totalLanes(ways);

return [
// the order in which these are created dictates
{
...d,
signal: "solid red",
duration: d[RED_COLUMN_NAME],
ways,
neighbouring_lanes
},
{
...d,
signal: "green",
duration: d[GREEN_COLUMN_NAME],
ways,
neighbouring_lanes
},
{
...d,
signal: "flashing red",
duration: d[FLASHING_RED_COLUMN_NAME],
ways,
neighbouring_lanes
}
];
})
).then((d) => d.flat())
Insert cell
Insert cell
Insert cell
Insert cell
SIGNAL_SCHEME = ({
domain: ["solid red", "green", "flashing red"],
range: ["rgb(218,55,50)", "rgb(80,174,87)", "rgb(238,85,80)"],
type: "categorical"
})
Insert cell
TIP_CHANNELS = ({
Location: LOCATION_COLUMN_NAME,
Timestamp: TIMESTAMP_COLUMN_NAME,
"Solid red duration": RED_COLUMN_NAME,
"Green duration": GREEN_COLUMN_NAME,
"Red flashing duration": FLASHING_RED_COLUMN_NAME,
"Cycle duration": "cycle_duration"
})
Insert cell
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