feat: add native lane separator style overrides
This commit is contained in:
@@ -63,6 +63,7 @@ let manualFromEndpoint = null;
|
||||
let diagnosticFilter = "all";
|
||||
let scenePreview = false;
|
||||
let selectedCenterLineSegment = null;
|
||||
let selectedLaneSeparator = null;
|
||||
const source = () => new VectorSource();
|
||||
const layers = {
|
||||
reference: new VectorLayer({ source: source(), visible: false, style: new Style({ fill: new Fill({ color: "rgba(123, 140, 148, .28)" }), stroke: new Stroke({ color: "#8999a0", width: 1 }) }) }),
|
||||
@@ -99,7 +100,7 @@ select.on("select", ({ selected }) => {
|
||||
const stopLine = provenance === "native-road-stop-line/v1";
|
||||
const markingType = centerLine ? "道路中心虚线" : crosswalk ? "斑马线" : stopLine ? "停止线" : directionArrow ? "道路方向箭头" : turnArrow ? "路口转向箭头" : "车道分隔线";
|
||||
selectRoad(road);
|
||||
if (centerLine) selectCenterLine(feature); else clearCenterLineSelection();
|
||||
if (centerLine) selectCenterLine(feature); else if (provenance === "native-road-lane-separator/v1") selectLaneSeparator(feature); else clearCenterLineSelection();
|
||||
evidence.textContent = JSON.stringify({
|
||||
标线类型: markingType,
|
||||
人行横道节点: crosswalk || stopLine ? feature.get("crossing_node_id") : null,
|
||||
@@ -135,7 +136,7 @@ function roadIdFromLane(laneId) { return typeof laneId === "string" ? laneId.sli
|
||||
function laneIndex(laneId) { return Number(String(laneId).split(":").at(-1)); }
|
||||
function lanePositionLabel(road, index) { return road?.laneCount === 1 ? "唯一车道" : `左起第 ${index} 车道`; }
|
||||
function laneStyle(feature) { const selected = feature.get("road_id") === selectedRoad?.id; return new Style({ stroke: new Stroke({ color: selected ? "#006e91" : "#f5f6ee", width: selected ? 3 : 1.3, lineDash: [5, 4] }) }); }
|
||||
function markingStyle() { return new Style({ fill: new Fill({ color: "#f5f6ee" }), stroke: new Stroke({ color: "#d9dacf", width: 1 }) }); }
|
||||
function markingStyle(feature) { const yellow = feature?.get("color") === "yellow"; return new Style({ fill: new Fill({ color: yellow ? "#f5be2a" : "#f5f6ee" }), stroke: new Stroke({ color: yellow ? "#d29d16" : "#d9dacf", width: 1 }) }); }
|
||||
function centerLineStyle(feature) { const white = feature.get("color") === "white"; const color = white ? "#faf9ee" : "#f5be2a"; return new Style({ fill: new Fill({ color }), stroke: new Stroke({ color: feature.get("pattern") === "solid" ? color : white ? "#aeb0aa" : "#d29d16", width: feature.get("pattern") === "solid" ? .25 : .8 }) }); }
|
||||
function nativeSurfaceStyle(feature) {
|
||||
// Split road features meet at OSM junction nodes. Their per-feature outlines
|
||||
@@ -251,10 +252,11 @@ function renderSummary() {
|
||||
}
|
||||
function stageRoadOverride(road, changes) { const id = `道路:${road.id}`; const existing = staged.find((item) => item.id === id) || state.overrides.overrides.find((item) => item.id === id); staged = staged.filter((item) => item.id !== id); staged.push({ ...existing, id, kind: "road", roadId: road.id, ...changes }); }
|
||||
function selectCenterLine(feature) { selectedCenterLineSegment = feature.get("segment_id"); centerLineForm.hidden = false; centerLineSegment.textContent = `道路段:${selectedCenterLineSegment}`; centerLineStyleInput.value = feature.get("effective_style") || "yellow-dashed"; }
|
||||
function clearCenterLineSelection() { selectedCenterLineSegment = null; centerLineForm.hidden = true; }
|
||||
function selectLaneSeparator(feature) { selectedCenterLineSegment = null; selectedLaneSeparator = feature.getProperties(); centerLineForm.hidden = false; centerLineSegment.textContent = `车道分隔线:第 ${selectedLaneSeparator.left_lane_index} 与第 ${selectedLaneSeparator.right_lane_index} 车道之间`; centerLineStyleInput.value = selectedLaneSeparator.effective_style || "white-dashed"; }
|
||||
function clearCenterLineSelection() { selectedCenterLineSegment = null; selectedLaneSeparator = null; centerLineForm.hidden = true; }
|
||||
function stageCenterLineStyle(segmentId, style) { const [color, pattern] = style.split("-"); const id = `道路中心线:${segmentId}`; const existing = staged.find((item) => item.id === id) || state.overrides.overrides.find((item) => item.id === id); staged = staged.filter((item) => item.id !== id); staged.push({ ...existing, id, kind: "center-line-style", segmentId, color, pattern }); }
|
||||
form.onsubmit = (event) => { event.preventDefault(); const roadChanges = { widthMeters: Number(widthInput.value), laneCount: Number(lanesInput.value), sidewalkLeft: leftInput.checked, sidewalkRight: rightInput.checked }; stageRoadOverride(selectedRoad, roadChanges); const opposite = state.compiled.model.roads.find((road) => road.id !== selectedRoad.id && road.segmentId === selectedRoad.segmentId); if (opposite) stageRoadOverride(opposite, { sidewalkLeft: rightInput.checked, sidewalkRight: leftInput.checked }); updateDirtyState(); message(opposite ? "有未保存修改:双向道路的路缘与步行带已按实际侧边同步" : "有未保存修改"); };
|
||||
function stageSelectedCenterLineStyle() { if (!selectedCenterLineSegment) return; stageCenterLineStyle(selectedCenterLineSegment, centerLineStyleInput.value); updateDirtyState(); message("有未保存修改:道路中心线样式"); }
|
||||
function stageSelectedCenterLineStyle() { if (!selectedCenterLineSegment && !selectedLaneSeparator) return; if (selectedCenterLineSegment) stageCenterLineStyle(selectedCenterLineSegment, centerLineStyleInput.value); else { const [color, pattern] = centerLineStyleInput.value.split("-"); const item = selectedLaneSeparator; const id = `车道分隔线:${item.road_id}:${item.left_lane_index}-${item.right_lane_index}`; staged = staged.filter((change) => change.id !== id); staged.push({ id, kind: "lane-separator-style", roadId: item.road_id, leftLaneIndex: item.left_lane_index, rightLaneIndex: item.right_lane_index, color, pattern }); } updateDirtyState(); message("有未保存修改:线样式"); }
|
||||
centerLineForm.onsubmit = (event) => { event.preventDefault(); stageSelectedCenterLineStyle(); };
|
||||
centerLineStyleInput.onchange = stageSelectedCenterLineStyle;
|
||||
async function saveStagedChanges() { if (!staged.length) return true; const existing = state.overrides.overrides.filter((item) => !staged.some((change) => change.id === item.id)); const response = await fetch("/api/overrides", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ schema: "native-road-overrides/v1", overrides: [...existing, ...staged] }) }); const result = await response.json(); if (!result.ok) { message(result.error); return false; } state.overrides = result.overrides; staged = []; updateDirtyState(); return true; }
|
||||
|
||||
Reference in New Issue
Block a user