fix(preview): derive signals from OSM controls
This commit is contained in:
@@ -10,6 +10,7 @@ const { makeVehicleGltf } = require("./lib/vehicle-model");
|
||||
const { VEHICLE_IDS, REVERSED_MODEL_IDS, writePreviewVehicleLibrary } = require("./lib/vehicle-library");
|
||||
const { allowedTurns, buildVehicleRoute, classifyConnection } = require("./lib/vehicle-route");
|
||||
const { buildTrafficSignals } = require("./lib/traffic-signals");
|
||||
const { parseOsm } = require("./lib/osm");
|
||||
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "preview-assets-"));
|
||||
const osmPath = path.join(tempDir, "fixture.osm");
|
||||
@@ -144,24 +145,53 @@ assert.match(previewRuntime, /scene\.requestRender/);
|
||||
assert.doesNotMatch(previewRuntime, /function addTrafficSignals\(viewer, signalData, start, placement\)/);
|
||||
assert.doesNotMatch(previewRuntime, /ellipsoid:/);
|
||||
|
||||
const signals = buildTrafficSignals(
|
||||
const trafficIntersection = { type: "FeatureCollection", features: [
|
||||
{ type: "Feature", geometry: { type: "Polygon", coordinates: [[
|
||||
[119.9998, 29.9998], [120.0004, 29.9998], [120.0004, 30.0003], [119.9998, 30.0003], [119.9998, 29.9998],
|
||||
]] } },
|
||||
] };
|
||||
const tStopLines = { type: "FeatureCollection", features: [
|
||||
rectangle(119.99995, 30.00005, 0.00003, 0.000006),
|
||||
rectangle(120.00010, 30.00025, 0.00003, 0.000006),
|
||||
rectangle(120.00035, 30.00005, 0.00003, 0.000006),
|
||||
] };
|
||||
const control = {
|
||||
id: "traffic-t", longitude: 120.0001, latitude: 30.00005,
|
||||
arms: [{ headingDegrees: 270 }, { headingDegrees: 0 }, { headingDegrees: 90 }],
|
||||
};
|
||||
const noControlSignals = buildTrafficSignals(tStopLines, trafficIntersection);
|
||||
assert.equal(noControlSignals.signals.length, 0, "untagged intersections must not create traffic signals");
|
||||
|
||||
const tSignals = buildTrafficSignals(tStopLines, trafficIntersection, [control]);
|
||||
assert.equal(tSignals.version, 3);
|
||||
assert.equal(tSignals.signals.length, 3, "a tagged T junction has one signal per physical approach");
|
||||
assert.deepEqual(tSignals.signals.map((signal) => signal.phaseGroup).sort(), [0, 0, 1]);
|
||||
assert.ok(tSignals.signals.every((signal) => Number.isFinite(signal.headingDegrees)));
|
||||
assert.equal(tSignals.layout.countdownLateralMeters, 1.15);
|
||||
assert.equal(tSignals.layout.countdownWidthMeters, 0.82);
|
||||
assert.ok(tSignals.signals.every((signal) => signal.pose?.head && signal.pose.lenses.length === 3));
|
||||
|
||||
const crossSignals = buildTrafficSignals(
|
||||
{ type: "FeatureCollection", features: [
|
||||
rectangle(120.0000, 30.0000, 0.00003, 0.000006),
|
||||
rectangle(120.0002, 30.0000, 0.00003, 0.000006),
|
||||
] },
|
||||
{ type: "FeatureCollection", features: [
|
||||
{ type: "Feature", geometry: { type: "Polygon", coordinates: [[
|
||||
[119.9998, 29.9998], [120.0004, 29.9998], [120.0004, 30.0003], [119.9998, 30.0003], [119.9998, 29.9998],
|
||||
]] } },
|
||||
rectangle(119.99995, 30.00005, 0.00003, 0.000006),
|
||||
rectangle(120.00010, 30.00025, 0.00003, 0.000006),
|
||||
rectangle(120.00035, 30.00005, 0.00003, 0.000006),
|
||||
rectangle(120.00010, 29.99985, 0.00003, 0.000006),
|
||||
] },
|
||||
trafficIntersection,
|
||||
[{ ...control, arms: [{ headingDegrees: 270 }, { headingDegrees: 0 }, { headingDegrees: 90 }, { headingDegrees: 180 }] }],
|
||||
);
|
||||
assert.equal(signals.version, 3);
|
||||
assert.equal(signals.signals.length, 2);
|
||||
assert.deepEqual(signals.signals.map((signal) => signal.phaseGroup), [0, 1]);
|
||||
assert.ok(signals.signals.every((signal) => Number.isFinite(signal.headingDegrees)));
|
||||
assert.equal(signals.layout.countdownLateralMeters, 1.15);
|
||||
assert.equal(signals.layout.countdownWidthMeters, 0.82);
|
||||
assert.ok(signals.signals.every((signal) => signal.pose?.head && signal.pose.lenses.length === 3));
|
||||
assert.equal(crossSignals.signals.length, 4, "a tagged cross junction retains all four approaches");
|
||||
assert.deepEqual(crossSignals.signals.map((signal) => signal.phaseGroup).sort(), [0, 0, 1, 1]);
|
||||
|
||||
const parsedSignalControls = parseOsm(`
|
||||
<osm><bounds minlon="119" minlat="29" maxlon="121" maxlat="31" />
|
||||
<node id="active" lon="120" lat="30"><tag k="highway" v="traffic_signals" /><tag k="traffic_signals:direction" v="both" /></node>
|
||||
<node id="directionless" lon="120" lat="30"><tag k="highway" v="traffic_signals" /></node>
|
||||
<node id="deleted" lon="120" lat="30" action="delete"><tag k="highway" v="traffic_signals" /></node>
|
||||
<node id="crossing" lon="120" lat="30"><tag k="highway" v="crossing" /><tag k="crossing" v="traffic_signals" /></node>
|
||||
</osm>`).trafficSignalControls;
|
||||
assert.deepEqual(parsedSignalControls.map((entry) => entry.id), ["active", "directionless"], "only active highway=traffic_signals nodes control vehicle signals");
|
||||
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
console.log("Preview asset tests passed.");
|
||||
|
||||
Reference in New Issue
Block a user