feat: add OSM turn lane arrows
This commit is contained in:
@@ -51,6 +51,7 @@ cp config/examples/template.json config/areas/my-area.json
|
||||
| `blenderApp` | | `/Applications/Blender.app` | |
|
||||
| `stages` | | 见下 | 各阶段默认开关 |
|
||||
| `qgis` | | 见下 | QGIS/osm2streets 旋钮 |
|
||||
| `turnLaneArrows` | | 见下 | 从 OSM `turn:lanes:*` 生成自定义车道箭头的发布开关 |
|
||||
| `osm2streets` | | 见下 | 透传给 osm2streets 的选项 |
|
||||
| `blender` | | 见下 | Blender 侧选项 |
|
||||
| `compress` | | 见下 | 显式 `compress` 阶段的 GLB 压缩选项 |
|
||||
@@ -97,6 +98,15 @@ cp config/examples/template.json config/areas/my-area.json
|
||||
> 这四个 arrow/corner 旋钮的默认值都是调出来的,**改之前先看 README 里记的理由**。
|
||||
> 尤其 `arrowOutlineSimplifyMeters`——调大会开始削箭头头部。
|
||||
|
||||
### `turnLaneArrows`
|
||||
|
||||
| 字段 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `enabled` | `false` | 仅在样张经用户确认后启用。启用时从 `turn:lanes:forward` / `turn:lanes:backward` 追加经过测试的自定义箭头;未测试素材永不参与映射。 |
|
||||
|
||||
该开关经 `normalizeAreaConfig()` 和 `writeDerivedConfig()` 传入 intermediates 阶段。必须用
|
||||
`??` 保留 `false`;不要将它改为按隐式标签或环境变量自动启用。
|
||||
|
||||
### `osm2streets`
|
||||
|
||||
原样透传给 `JsStreetNetwork` 构造函数(`build-osm2streets-qgis.js:77`)。默认:
|
||||
|
||||
@@ -83,6 +83,18 @@ cesium-preview.js 浏览器
|
||||
|
||||
## 本项目真实踩过的坑
|
||||
|
||||
### 坑 0:用原始 OSM 节点度数代替归一化路网拓扑
|
||||
|
||||
OSM way 的端点不一定在原始 XML 中有三个以上相连 way;osm2streets 可能把相邻 way
|
||||
合并、切分或通过 `network.intersections[*].osm_ids` 表达路口。任何需要判断道路是否
|
||||
进入路口的中间层逻辑,都必须优先使用已经生成的 normalized `network.json` 事实源,
|
||||
原始节点度数只能作为没有 normalized network 的纯单元测试回退。
|
||||
|
||||
### 坑 0.1:普通 JSON 误走 FeatureCollection 写入器
|
||||
|
||||
`writeJson()` 的隐式契约是传入带 `features` 数组的图层集合;诊断 manifest、计数摘要等
|
||||
普通对象必须用显式 `JSON.stringify` 写入,不能为了复用日志代码把它们塞进图层写入器。
|
||||
|
||||
### 坑 1:同一份事实存了四份
|
||||
|
||||
九个图层的顺序曾同时存在于 z_index 表、样式 JSON、QGIS 工程、README。
|
||||
|
||||
@@ -189,6 +189,158 @@ const osm = parseOsm(fs.readFileSync(area.input, "utf8"));
|
||||
const preflight = analyzeOsmPreflight(osm);
|
||||
```
|
||||
|
||||
## OSM 转向车道箭头
|
||||
|
||||
### 1. 范围与触发条件
|
||||
|
||||
区域配置设为 `turnLaneArrows.enabled: true` 时,`intermediates` 阶段会将已支持的
|
||||
OSM `turn:lanes:forward` / `turn:lanes:backward` 标线追加到既有的
|
||||
`lane_arrows_webscale` 图层。这只是既有图层的新增数据来源,不能新增 QGIS、Blender
|
||||
或 Cesium 图层。
|
||||
|
||||
### 2. 调用形式
|
||||
|
||||
```json
|
||||
{
|
||||
"turnLaneArrows": { "enabled": true }
|
||||
}
|
||||
```
|
||||
|
||||
该字段由 `normalizeAreaConfig()` 归一化、`writeDerivedConfig()` 写入派生配置,
|
||||
并由 `build-osm2streets-qgis.js` 消费。
|
||||
|
||||
### 3. 契约
|
||||
|
||||
- 已支持且已测试的转向为:`through`、`left`、`right`、`through;left`、
|
||||
`through;right`、`through;left;right`。
|
||||
- `assets/lane-icons/manifest.json` 是上游 CC0 来源、原始 SVG、镜像规则、箭杆轴线、
|
||||
支持状态和测试状态的唯一事实源。未同时标记为 `supported` 和 `tested` 的素材不得写入
|
||||
生产 GeoJSON。
|
||||
- 自定义要素必须带有 `source="osm_turn_lanes"`、`osm_way_id`、`direction`、
|
||||
`lane_index`、`maneuver`、`source_asset`、`arrow_part` 与确定性的
|
||||
`custom_arrow_id`。
|
||||
- `turn_lane_arrow_diagnostics.json` 记录 `generated` 和结构化跳过原因;它是普通 JSON,
|
||||
不是 FeatureCollection。
|
||||
- 归一化后的 `network.intersections[*].osm_ids` 用来判断有效路口端点。只有单元测试中
|
||||
没有 network 时,才可退回原始 OSM 节点度数。
|
||||
- 可直接关联时,`Driving` 面通过 `osm_way_ids` 匹配,中心线取其相对两边的中点;闭合
|
||||
四边形车道面也必须有效。JOSM 拆分产生的临时 ID 未被渲染面保留时,只能匹配距离近且
|
||||
行驶方向一致的车道中心线,并按实际横向位置排序,不得单独依赖渲染器的 `index`。
|
||||
|
||||
### 4. 校验与错误矩阵
|
||||
|
||||
| 条件 | 结果 |
|
||||
|---|---|
|
||||
| 功能关闭 | 不生成自定义要素;诊断原因为 `disabled` |
|
||||
| 缺少车道数或无法判定路口端点 | 带原因跳过,不能猜测位置 |
|
||||
| 转向未支持或未测试 | 以 `unsupported_or_untested_maneuver` 跳过 |
|
||||
| SVG 缺少受支持路径命令或 manifest 锚点 | 写入 GeoJSON 前抛错 |
|
||||
| 合法且已支持的 OSM 车道 | 每个 SVG 填充或扩展描边部件追加一个 Polygon |
|
||||
|
||||
### 5. 正常、基础与错误示例
|
||||
|
||||
- 正常:`through;right` 生成多个合法 Polygon 部件,但共享同一 OSM 溯源元组,直行杆
|
||||
轴线与车道中心对齐。
|
||||
- 基础:`enabled: false` 保持 osm2streets 原有箭头输出不变。
|
||||
- 错误:将组合箭头写为一个 `MultiPolygon`。既有 QGIS 归一化器只接受逐个 Polygon。
|
||||
|
||||
### 6. 必需测试
|
||||
|
||||
- `npm run test:turn-lane-arrows`:覆盖转向归一化、正反向放置、确定性 ID、箭杆锚点、
|
||||
关闭行为及未测试素材排除。
|
||||
- 目标区域 `intermediates` 构建:确认 `lane_arrows_webscale.geojson` 含自定义 `source`
|
||||
要素,且诊断可读。
|
||||
- 用户确认样张后,运行完整目标区域构建和
|
||||
`npm run check:area -- --config <area>`。
|
||||
|
||||
### 7. 错误与正确写法
|
||||
|
||||
错误:
|
||||
|
||||
```js
|
||||
if ((roadCounts.get(endpoint.id) || 0) < 3) return null;
|
||||
writeJson(diagnosticsPath, diagnostics);
|
||||
```
|
||||
|
||||
正确:
|
||||
|
||||
```js
|
||||
const networkSaysIntersection = networkIntersectionNodes.has(endpoint.id);
|
||||
if (!networkSaysIntersection && (roadCounts.get(endpoint.id) || 0) < 3) return null;
|
||||
fs.writeFileSync(diagnosticsPath, `${JSON.stringify(diagnostics, null, 2)}\n`);
|
||||
```
|
||||
|
||||
## 斑马线与停止线来源
|
||||
|
||||
### 1. 范围与触发条件
|
||||
|
||||
`intermediates` 阶段从带标记的 OSM `highway=crossing` 节点生成路口标线,并独占
|
||||
`crosswalks` 与 `vehicle_stop_lines` 两个场景图层的数据来源。
|
||||
|
||||
### 2. 调用形式
|
||||
|
||||
```js
|
||||
const crosswalkData = buildCrosswalks(osm, lanePolygons.features);
|
||||
// split.vehicleStopLines === crosswalkData.stopLines
|
||||
// split.crosswalks === crosswalkData.stripes
|
||||
```
|
||||
|
||||
### 3. 契约
|
||||
|
||||
- `buildCrosswalks()` 是输出 `vehicle_stop_lines` 的唯一生产者。不得将 osm2streets
|
||||
`lane_markings` 中类型为 `vehicle stop line` 的要素追加回来,否则会产生位置不同的
|
||||
重复标线。
|
||||
- 每个输出的过街进口固定生成 6 条 `crosswalk stripe`,以及恰好 1 条带有
|
||||
`source="crosswalk"` 和 `crossing_node_id` 的 `vehicle stop line`。
|
||||
- 斑马线参考点先沿进口方向放在过街节点簇中心外 7 米处;再以相邻归一化 `Driving` 面
|
||||
修正横向中心和方向:取局部车道中心锚点的平均值,并使用方向一致的车道切线。只有没有
|
||||
匹配的渲染车道时,才回退到原始 OSM way 几何。
|
||||
- 停止线从同一校正后的斑马线坐标系,以外侧固定 1.2 米偏移推导。osm2streets 的道路
|
||||
横断面与原始 OSM 几何不同,斑马线与停止线也必须同步移动。
|
||||
|
||||
### 4. 校验与错误矩阵
|
||||
|
||||
| 条件 | 结果 |
|
||||
|---|---|
|
||||
| 有匹配渲染车道的标记过街 | 中心与方向跟随实际渲染道路横断面 |
|
||||
| 没有匹配渲染车道的标记过街 | 安全回退到原始 OSM 方向向量 |
|
||||
| 多个源节点投影到同一进口中心 | 写入斑马线和停止线前去重 |
|
||||
| 存在 osm2streets 原生停止线 | 忽略,不写入输出图层 |
|
||||
|
||||
### 5. 正常、基础与错误示例
|
||||
|
||||
- 正常:两个四向路口产生 48 条斑马线条带和 8 条停止线,全部为
|
||||
`source="crosswalk"`。
|
||||
- 基础:归一化 `Driving` 面之外的过街仍可按原始 way 方向渲染。
|
||||
- 错误:因为原生 `vehicle stop line` 与人工线相距数米就保留它;这会重新引入第二个
|
||||
生产者和视觉重复。
|
||||
|
||||
### 6. 必需测试
|
||||
|
||||
- 运行目标区域 `intermediates` 构建。
|
||||
- 断言 `vehicle_stop_lines.geojson` 每个要素的 `crossing_node_id` 均不重复,且所有要素
|
||||
都有 `source="crosswalk"`。
|
||||
- 检查四向路口的 QGIS 预览:条带必须横向居中于渲染道路宽度,每条停止线必须位于其
|
||||
对应斑马线之后。
|
||||
|
||||
### 7. 错误与正确写法
|
||||
|
||||
错误:
|
||||
|
||||
```js
|
||||
if (feature.properties.type === "vehicle stop line") {
|
||||
out.vehicleStopLines.features.push(feature);
|
||||
}
|
||||
```
|
||||
|
||||
正确:
|
||||
|
||||
```js
|
||||
const crosswalkData = buildCrosswalks(osm, lanePolygons.features);
|
||||
out.vehicleStopLines = crosswalkData.stopLines;
|
||||
// 原生 lane_markings 停止线不得复制到输出。
|
||||
```
|
||||
|
||||
## 区域诊断命令
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{"file":".trellis/spec/pipeline/index.md","reason":"Defines the expected intermediates artifacts and dependency boundaries."}
|
||||
{"file":".trellis/spec/pipeline/layer-registry.md","reason":"Requires preserving existing lane-arrow layer collection and order across QGIS and Blender."}
|
||||
{"file":".trellis/spec/pipeline/cli-and-stages.md","reason":"Defines quality-gate and target-area validation expectations."}
|
||||
{"file":".trellis/tasks/08-04-add-osm-turn-lane-arrows/research/lane-icons.md","reason":"Defines the source provenance and assertion that untested assets cannot be mapped."}
|
||||
74
.trellis/tasks/08-04-add-osm-turn-lane-arrows/design.md
Normal file
74
.trellis/tasks/08-04-add-osm-turn-lane-arrows/design.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Design: OSM turn-lane arrows
|
||||
|
||||
## Boundaries
|
||||
|
||||
- `scripts/build-osm2streets-qgis.js` remains the intermediates owner. It will
|
||||
append generated custom features to the existing in-memory `laneArrows`
|
||||
collection before it is written as `lane_arrows_webscale.geojson`.
|
||||
- No render layer, QGIS symbol, Blender material, or Cesium export contract
|
||||
changes. Existing `lane_arrows_webscale` styling and catalog ownership apply
|
||||
to generated features automatically.
|
||||
- Vendored upstream artwork lives under a dedicated repository-local asset
|
||||
directory with its CC0 license and a machine-readable manifest. The manifest
|
||||
is the source of truth for upstream path, source revision, local path,
|
||||
support status, and test status.
|
||||
|
||||
## Asset Contract
|
||||
|
||||
- Import every arrow SVG from `openstreetmap/lane-icons/docs/` that represents
|
||||
an arrow. Preserve the source bytes and retain `LICENSE.md` with the assets.
|
||||
- Mark only `through`, `left`, `right`, `through;left`, and `through;right` as
|
||||
`supported` and `tested` in the manifest. All remaining imported arrows are
|
||||
`unsupported` and `untested`; no production parser may select them.
|
||||
- The upstream repository has left-side examples only. Derive `right` and
|
||||
`through;right` through a deterministic horizontal mirror of the matching
|
||||
left-side geometry, recording `derived_from` in the manifest.
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. Parse OSM ways once using the existing OSM parser.
|
||||
2. Read `turn:lanes:forward` / `turn:lanes:backward`, split lane declarations
|
||||
by `|`, and map only the five supported normalized maneuvers to manifest
|
||||
entries.
|
||||
3. For each valid lane near a determinable intersection endpoint, calculate a
|
||||
stable lane center and road-local axis; transform the selected local arrow
|
||||
polygon into WGS84 coordinates.
|
||||
4. Add a GeoJSON feature with existing render-layer behavior and explicit
|
||||
provenance: custom source, OSM way id, direction, lane index, maneuver,
|
||||
source asset, and deterministic feature id/order.
|
||||
5. Record a structured skipped item when tags, lane geometry, or endpoint
|
||||
classification are insufficient. Do not invent a fallback location.
|
||||
6. Existing normalization, scene merge, GeoPackage import, Blender assembly,
|
||||
and Cesium export consume the expanded collection unchanged.
|
||||
|
||||
## Geometry and Compatibility
|
||||
|
||||
- Parse only the vendored SVG subset used by supported assets at build time:
|
||||
`line` elements and `path` commands are converted into local meter-scale
|
||||
polygons, with cubic curves sampled and SVG strokes expanded into outlines.
|
||||
The source SVG is the sole geometry authority; no hand-drawn replacement
|
||||
template is permitted. This stays dependency-free because the supported
|
||||
upstream syntax is intentionally small and covered by Node tests.
|
||||
- Use the upstream Standard Arrow shape as the geometry basis, but let the
|
||||
existing QGIS fill and outline preserve the project's visual language.
|
||||
- Preserve the existing osm2streets-generated arrow features. Custom features
|
||||
are additive and have provenance that distinguishes them from upstream
|
||||
osm2streets output.
|
||||
- Deterministic ordering is by way id, travel direction, and lane index.
|
||||
- Each asset manifest entry defines the source SVG's shaft-axis `anchor_x`.
|
||||
Placement aligns that axis, rather than the SVG viewBox center, with the
|
||||
lane centerline. Mirrored right-side variants mirror around the same axis.
|
||||
- Upstream SVG units are converted at `0.10 m` per unit. This calibrates their
|
||||
local extent against the existing approximately 1.4 m osm2streets arrows;
|
||||
do not use SVG display-pixel scale as road-marking scale.
|
||||
|
||||
## Risks and Rollback
|
||||
|
||||
- OSM lane counts, one-way semantics, or endpoint topology can be incomplete.
|
||||
These cases remain skipped with diagnostics rather than creating misleading
|
||||
markings.
|
||||
- Asset import is self-contained and CC0. Rollback removes the custom feature
|
||||
generation and local asset directory; the existing arrow layer remains
|
||||
unchanged.
|
||||
- User approval of the two initial visual samples is required before the
|
||||
feature is enabled in production output.
|
||||
@@ -0,0 +1,4 @@
|
||||
{"file":".trellis/spec/pipeline/index.md","reason":"Defines the intermediates data flow, CommonJS conventions, and existing layer ownership."}
|
||||
{"file":".trellis/spec/pipeline/layer-registry.md","reason":"The feature adds a source to an existing layer and must preserve the cross-language layer contract."}
|
||||
{"file":".trellis/spec/pipeline/cli-and-stages.md","reason":"Defines stage ownership and target-area validation commands."}
|
||||
{"file":".trellis/tasks/08-04-add-osm-turn-lane-arrows/research/lane-icons.md","reason":"Records the selected upstream SVG source, CC0 provenance, and supported-versus-untested asset policy."}
|
||||
39
.trellis/tasks/08-04-add-osm-turn-lane-arrows/implement.md
Normal file
39
.trellis/tasks/08-04-add-osm-turn-lane-arrows/implement.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Implementation Plan: OSM turn-lane arrows
|
||||
|
||||
## Steps
|
||||
|
||||
1. Add the complete lane-icons arrow asset set, upstream revision metadata,
|
||||
CC0 license text, and a manifest with the five supported/tested entries and
|
||||
explicit untested status for all other entries.
|
||||
2. Add a small CommonJS helper for asset-manifest loading, source-SVG path and
|
||||
stroke conversion, maneuver parsing, road-local placement, and diagnostic
|
||||
skip records. Keep it dependency-free and separately testable.
|
||||
3. Wire the helper into the intermediates build so custom features are merged
|
||||
into `laneArrows` before the existing GeoJSON write and normalization path.
|
||||
4. Add Node tests for the five supported maneuvers, forward/backward endpoint
|
||||
choice, lane index placement, deterministic order/id, and every required
|
||||
skip reason. Assert that untested manifest entries cannot be selected.
|
||||
5. Generate `right` and `through;right` inspection samples from the exact
|
||||
local templates and request user confirmation. Do not enable custom output
|
||||
until this gate is met.
|
||||
6. Run the focused tests, syntax checks, the Nantaizi intermediates build, the
|
||||
full Nantaizi chain, and `check:area`. Compare against a turn-tag-removed
|
||||
control to prove an observable GeoJSON difference.
|
||||
|
||||
## Validation
|
||||
|
||||
- `node --check` for changed CommonJS scripts.
|
||||
- New pure Node test script(s), invoked directly or through a package script.
|
||||
- `npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages intermediates`
|
||||
- Full target-area pipeline after visual approval.
|
||||
- `npm run check:area -- --config config/areas/nantaizi-lake-innovation-valley.json`
|
||||
|
||||
## Review Gates
|
||||
|
||||
- No generated custom feature may use an asset whose manifest status is not
|
||||
both supported and tested.
|
||||
- Samples must show the same fill/outline treatment as the existing lane-arrow
|
||||
layer.
|
||||
- Keep the existing layer registry unchanged; this is a new source for an
|
||||
existing layer, not a new layer.
|
||||
- Do not commit without the user's explicit confirmation.
|
||||
63
.trellis/tasks/08-04-add-osm-turn-lane-arrows/prd.md
Normal file
63
.trellis/tasks/08-04-add-osm-turn-lane-arrows/prd.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Add OSM turn lane arrows
|
||||
|
||||
## Goal
|
||||
|
||||
让 OSM `turn:lanes:forward` / `turn:lanes:backward` 在现有 QGIS -> Blender -> Cesium
|
||||
道路链中生成可辨识的 lane arrow,同时保持与 osm2streets 既有道路标线相同的视觉语言。
|
||||
|
||||
## Confirmed Facts
|
||||
|
||||
- 当前 `osm2streets-js-node@0.1.4` 生成 lane arrow,但纯内存移除 way `98607123`、
|
||||
`98607128`、`98607147` 的 `turn:lanes:*` 后,593 个原始箭头的 JSON 内容逐字一致;
|
||||
因此该依赖不消费这些 OSM 标签。
|
||||
- 当前南台子完整链已经通过:中间层落盘 580 个归一化箭头,Blender 装配 397 个,
|
||||
Cesium / preview / compress manifest 均 fresh,`check:area` PASS。
|
||||
- 现有 `lane_arrows_webscale` 已是 QGIS、Blender、Cesium 共用图层,样式为浅色填充
|
||||
`#fffff6`、深色描边 `#2b2b28`,正常外轮廓为七顶点箭头。
|
||||
- `turn:lanes:forward=right`、`turn:lanes:backward=through;right` 等标准标签已存在于
|
||||
南台子 OSM。
|
||||
- `openstreetmap/lane-icons` 是 OSM 官方组织发布的 CC0 SVG 图标集;其 `DESIGN.md`
|
||||
以 MUTCD Standard Arrow 为基准,并规定组合转向共享箭杆、箭头数量增加时缩小箭头。
|
||||
仓库只提供左侧转向示例,右转及 `through;right` 需在几何层对其镜像,不能直接作为
|
||||
当前 GeoJSON polygon 图层输入。
|
||||
- 用户已决定将该库中首版需要的转向图标作为本仓库维护的源素材,而不是只作为视觉参考。
|
||||
|
||||
## Requirements
|
||||
|
||||
1. 在写入 `lane_arrows_webscale.geojson` 前,从 OSM 标准 `turn:lanes:*` 生成自定义箭头
|
||||
polygon,并沿用既有图层、材质、QGIS/Blender/Cesium 路径。
|
||||
2. 支持首版实际需要的 `through`、`left`、`right`、`through;left`、`through;right`;
|
||||
同一 OSM 输入必须产生确定性结果。
|
||||
3. 自定义箭头必须使用现有道路标线的视觉语言,不新建一套颜色、描边或图标风格。
|
||||
4. 在 OSM way 进入路口的一端、按 forward/backward 和 lane index 放置;车道配置不完整或
|
||||
端点不是可判定路口时给出可诊断的跳过原因。
|
||||
5. 首先完成并获得用户对 `right` 和 `through;right` 轮廓样张的确认,之后才能将其接入
|
||||
GeoJSON / Blender 导出。
|
||||
6. 未经用户确认,不提交 Git。
|
||||
7. 将 `openstreetmap/lane-icons` 的全部箭头 SVG 和 CC0 许可证说明纳入本仓库维护;
|
||||
右转变体由左转源图镜像生成。生成的 polygon 仍由本仓库维护,并继续使用
|
||||
`lane_arrows_webscale` 的既有填充与描边样式。
|
||||
8. 素材清单必须逐项标记验证状态:仅 `through`、`left`、`right`、`through;left`、
|
||||
`through;right` 在首版具备 OSM 映射与自动化测试;其他已收录箭头明确标为未测试,
|
||||
且不得自动参与生产 GeoJSON 输出。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] 用户确认箭头样张的轮廓与视觉语言。
|
||||
- [ ] 目标 OSM 标签导致 lane-arrow GeoJSON 与移除这些标签的对照产生可观察差异。
|
||||
- [ ] 自定义 arrow properties 标识来源和 OSM way / direction / lane,便于诊断。
|
||||
- [ ] 纯 Node 测试覆盖标签解析、forward/backward、lane placement、组合转向和幂等排序。
|
||||
- [ ] 本地素材清单包含所有上游箭头,逐项标记 CC0 来源、支持状态和测试状态;未测试条目
|
||||
不会参与生产映射。
|
||||
- [ ] 仅南台子完整链和质量门验证通过。
|
||||
- [ ] 无 Git 提交,直到用户明确确认。
|
||||
|
||||
## Out Of Scope
|
||||
|
||||
- 修改 osm2streets 依赖、道路改为 Cesium 直渲染、增加新的道路渲染图层。
|
||||
- 支持首版范围之外的 OSM maneuver 词汇、匝道标线、文字或自行车专用箭头。
|
||||
|
||||
## Delivery Gate
|
||||
|
||||
在自定义箭头接入生产 GeoJSON / Blender 导出前,用户必须确认 `right` 与
|
||||
`through;right` 样张的轮廓和视觉语言。
|
||||
@@ -0,0 +1,40 @@
|
||||
# lane-icons research
|
||||
|
||||
Source: <https://github.com/openstreetmap/lane-icons>, inspected 2026-08-04.
|
||||
|
||||
## Provenance
|
||||
|
||||
- Owner: `openstreetmap` GitHub organization.
|
||||
- Repository tree revision: `db3cab321da93a757c2cf3cdb4f1f1db6b1a091c` (`master`).
|
||||
- License: `LICENSE.md` is CC0 1.0 Universal. Keep that text adjacent to any
|
||||
vendored source assets.
|
||||
|
||||
## Relevant Contents
|
||||
|
||||
- `docs/through.svg`
|
||||
- `docs/left.svg`
|
||||
- `docs/left-through.svg`
|
||||
- `docs/slight_left.svg`
|
||||
- `docs/slight_left-through.svg`
|
||||
- `docs/sharp_left.svg`
|
||||
- `docs/sharp_left-through.svg`
|
||||
- `docs/reverse_left.svg`
|
||||
- `docs/reverse_left-through.svg`
|
||||
- `docs/reverse_left-left-slight_left-through.svg`
|
||||
- `docs/left-slight_left-through.svg`
|
||||
|
||||
## Design Rules
|
||||
|
||||
`DESIGN.md` bases arrows on the MUTCD Standard Arrow. It specifies a shared
|
||||
shaft for compound arrows, smooth curves, aligned arrow bottoms, and reduced
|
||||
arrowhead scale as the number of directions grows. The upstream SVGs are
|
||||
single-color and stroke-free; our existing render layer supplies the project
|
||||
fill and outline treatment.
|
||||
|
||||
## Adoption Decision
|
||||
|
||||
Vendor all listed arrow SVGs with provenance and CC0 license text. The
|
||||
production mapping is initially restricted to `through`, `left`, `right`,
|
||||
`through;left`, and `through;right`. Right-side variants are deterministic
|
||||
mirrors of upstream left-side assets. Every other vendored arrow remains
|
||||
explicitly untested and unavailable to the production mapper.
|
||||
26
.trellis/tasks/08-04-add-osm-turn-lane-arrows/task.json
Normal file
26
.trellis/tasks/08-04-add-osm-turn-lane-arrows/task.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "add-osm-turn-lane-arrows",
|
||||
"name": "add-osm-turn-lane-arrows",
|
||||
"title": "Add OSM turn lane arrows",
|
||||
"description": "",
|
||||
"status": "in_progress",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "dingkang",
|
||||
"assignee": "dingkang",
|
||||
"createdAt": "2026-08-04",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user