feat: generate direct edit handle manifest

This commit is contained in:
2026-08-27 12:09:11 +08:00
parent 3297d0c97a
commit ab63d23896
6 changed files with 501 additions and 35 deletions

View File

@@ -50,6 +50,52 @@ const withContext = resolveDirectEditConstraints(model, null, { revisionId: 'rev
assert.equal(withContext.handles.revisionId, 'rev-0007');
assert.equal(withContext.handles.previewSeq, 42);
// A small ordinary junction exercises the step-two manifest contract without
// depending on the full OSM parser. Three approaches produce one reserve each,
// all six kinds, and native feature links for the downstream map highlighter.
const junctionRoads = ['a', 'b', 'c'].map((id, index) => ({
id: `road:${id}`,
segmentId: `segment:${id}`,
direction: 'forward',
centerline: [
[113 + index * 0.001, 30],
[113 + index * 0.001 + (index === 1 ? 0.001 : 0), 30 + (index === 1 ? 0.001 : 0.001)],
],
sourceNodeIds: ['junction', `end-${id}`],
osmWayIds: [id],
widthMeters: 6,
laneCount: 2,
sidewalkLeft: true,
sidewalkRight: true,
}));
const junctionModel = {
roads: junctionRoads,
endpoints: junctionRoads.map((road) => ({
id: `endpoint:${road.id}:start`,
roadId: road.id,
side: 'start',
nodeId: 'junction',
coordinate: road.centerline[0],
})),
connections: [],
};
const junctionResolution = resolveDirectEditConstraints(junctionModel, document([]), { revisionId: 'rev-junction' });
assert.equal(junctionResolution.handles.reserves.length, 3);
assert.equal(new Set(junctionResolution.handles.handles.map((handle) => handle.kind)).size, 6);
assert.ok(junctionResolution.handles.handles.every((handle) => handle.position.every(Number.isFinite)));
assert.ok(junctionResolution.handles.handles.every((handle) => Number.isFinite(handle.axisAzimuth)));
assert.ok(junctionResolution.handles.handles.some((handle) => handle.affects.includes('junction:node/junction')));
const anchored = constraint({
id: 'edge-on-road-a',
anchor: { type: 'road-interval', roadId: 'road:a', startStation: 0.2, endStation: 0.8, side: 'left' },
});
const anchoredResolution = resolveDirectEditConstraints(junctionModel, document([anchored]));
const anchoredHandle = anchoredResolution.handles.handles.find(
(handle) => handle.kind === 'road-edge-offset' && handle.anchor.roadId === 'road:a' && handle.anchor.side === 'left',
);
assert.equal(anchoredHandle.constraintId, 'edge-on-road-a');
// A disabled constraint is reported, never applied, and produces no diagnostic:
// the user turned it off deliberately, so it is not a problem to report.
const disabled = resolveDirectEditConstraints(model, document([constraint({ enabled: false })]));