fix(preview): derive signals from OSM controls
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const { parseOsm } = require("./osm");
|
||||
|
||||
const MAX_ROUTES = 5;
|
||||
const MAX_PATH_EDGES = 7;
|
||||
@@ -26,49 +27,6 @@ function buildVehicleRoute(osmPath) {
|
||||
};
|
||||
}
|
||||
|
||||
function parseOsm(xml) {
|
||||
const boundsMatch = xml.match(/<bounds\b([^>]*)\/?\s*>/);
|
||||
const boundsAttrs = boundsMatch ? xmlAttrs(boundsMatch[1]) : {};
|
||||
const bounds = {
|
||||
minLon: Number(boundsAttrs.minlon), minLat: Number(boundsAttrs.minlat),
|
||||
maxLon: Number(boundsAttrs.maxlon), maxLat: Number(boundsAttrs.maxlat),
|
||||
};
|
||||
const validBounds = Object.values(bounds).every(Number.isFinite) ? bounds : null;
|
||||
const nodes = new Map();
|
||||
for (const match of xml.matchAll(/<node\b([^>]*)\/?\s*>/g)) {
|
||||
const attrs = xmlAttrs(match[1]);
|
||||
if (!attrs.id || attrs.lon === undefined || attrs.lat === undefined) continue;
|
||||
const coord = [Number(attrs.lon), Number(attrs.lat)];
|
||||
if (coord.every(Number.isFinite)) nodes.set(attrs.id, coord);
|
||||
}
|
||||
const ways = [];
|
||||
for (const match of xml.matchAll(/<way\b([^>]*)>([\s\S]*?)<\/way>/g)) {
|
||||
const attrs = xmlAttrs(match[1]);
|
||||
const body = match[2];
|
||||
const tags = {};
|
||||
for (const tagMatch of body.matchAll(/<tag\b([^>]*)\/?\s*>/g)) {
|
||||
const tag = xmlAttrs(tagMatch[1]);
|
||||
if (tag.k) tags[tag.k] = tag.v || "";
|
||||
}
|
||||
if (!isCruiseHighway(tags)) continue;
|
||||
const refs = [];
|
||||
for (const ndMatch of body.matchAll(/<nd\b([^>]*)\/?\s*>/g)) {
|
||||
const ref = xmlAttrs(ndMatch[1]).ref;
|
||||
if (ref && nodes.has(ref)) refs.push(ref);
|
||||
}
|
||||
if (refs.length >= 2) ways.push({ id: attrs.id || `way-${ways.length + 1}`, refs, tags });
|
||||
}
|
||||
return { bounds: validBounds, nodes, ways };
|
||||
}
|
||||
|
||||
function xmlAttrs(text) {
|
||||
const attrs = {};
|
||||
for (const match of text.matchAll(/([:\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g)) {
|
||||
attrs[match[1]] = match[2] !== undefined ? match[2] : match[3];
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
function isCruiseHighway(tags) {
|
||||
const highway = tags.highway || "";
|
||||
if (!highway || tags.area === "yes") return false;
|
||||
@@ -81,6 +39,7 @@ function isCruiseHighway(tags) {
|
||||
function directedRoadEdges(ways, nodes, bounds) {
|
||||
const edges = [];
|
||||
for (const way of ways) {
|
||||
if (!isCruiseHighway(way.tags)) continue;
|
||||
const refs = compactRefs(way.refs);
|
||||
if (refs.length < 2) continue;
|
||||
const coords = refs.map((ref) => nodes.get(ref));
|
||||
|
||||
Reference in New Issue
Block a user