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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more