OSM Asset Pipeline

把单个园区/片区 OSM XML 转为可消费的 Blender 场景和 Cesium GLB。osm2streets GeoJSON、GeoPackage、QGIS 工程和预览图都是中间资产,用来提供道路几何、调试标线效果,以及给 Blender/Cesium 生成提供输入。

目标产物

每个区域默认输出到 outputs/<area-id>/

  • <area-id>.blendBlender 场景,包含道路、建筑、水体、植被等
  • <area-id>.pngBlender 预览渲染
  • <area-id>.glbCesium 可加载的 3D 模型
  • <area-id>.jsonCesium 放置元数据和示例代码
  • <area-id>-cesium-preview.htmlCesium 本地预览页
  • osm2streets_web_out/osm2streets GeoJSON 中间层
  • <area-id>.gpkg / <area-id>.qgz / <area-id>-preview.pngQGIS 调试资产

环境

需要:

  • macOS QGIS默认 /Applications/QGIS.app
  • Blender默认 /Applications/Blender.app
  • Node.js / npm

首次使用:

cd /Users/que01/osm2streets-qgis-workflow
npm install

主流程

默认构建南台子湖创新谷样例:

npm run build

指定区域配置:

npm run build:area -- --config config/areas/hanyang-block.json

只跑部分阶段:

npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages intermediates
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages blender
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages cesium
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages preview
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages reimport

intermediates 会生成 osm2streets GeoJSON、GeoPackage、QGIS 工程和 QGIS 预览图。blender 使用 OSM 和 osm2streets GeoJSON 生成 .blend/.pngcesium.blend 导出 .glb/.json,并生成 Cesium 预览 HTML。preview 只在已有 .glb/.json 时补生成 HTML。reimport 把手工编辑过的 GeoPackage 回导为 GeoJSON不含在 all 里,详见 QGIS 手工修正工作流

区域配置

新区域从模板复制:

cp config/examples/template.json config/areas/my-area.json

核心配置:

{
  "id": "my-area",
  "input": "/absolute/path/to/input.osm",
  "outputRoot": "/absolute/path/to/outputs",
  "qgisApp": "/Applications/QGIS.app",
  "blenderApp": "/Applications/Blender.app",
  "stages": {
    "intermediates": true,
    "blender": true,
    "cesium": true
  },
  "qgis": {
    "arrowScale": 0.8,
    "arrowMergeTriangles": true,
    "arrowOutlineSimplifyMeters": 0.05,
    "intersectionCornerSourceMaxDimensionMeters": 2.6,
    "clipPad": 0.002,
    "canvasPad": 0.001,
    "previewPad": 0.0007,
    "canvasExtent": null,
    "previewExtent": null,
    "layerPrefix": "osm2streets"
  },
  "blender": {
    "treeStyle": "natural",
    "officeOverrides": ""
  }
}

QGIS road-layer knobs:

  • arrowScale: scales osm2streets lane-arrow polygons before export.
  • arrowMergeTriangles: merges each osm2streets lane-arrow triangle mesh into one valid polygon. This preserves the original arrow shape and turn direction while removing renderer gaps along shared triangle edges.
  • arrowOutlineSimplifyMeters: removes sub-decimeter kinks from the merged arrow exterior. The default 0.05 removes the two malformed tail vertices without changing the arrow head; the remaining tail edge is aligned perpendicular to the shaft.
  • intersectionCornerSourceMaxDimensionMeters: keeps only small osm2streets sidewalk corner polygons. Large intersection-marking polygons are not treated as sidewalk because they can cover the drivable junction.

scripts/build-area.js 会按 id 自动推导默认输出路径。确实需要定制时,可以增加 outputs 覆盖:

{
  "outputs": {
    "areaDir": "/absolute/path/to/custom-area",
    "blend": "/absolute/path/to/custom.blend",
    "glb": "/absolute/path/to/custom.glb",
    "cesiumPreview": "/absolute/path/to/custom-preview.html"
  }
}

预览 Cesium 页面时,需要在输出目录启动 HTTP 服务,避免浏览器拦截本地文件请求:

cd outputs/my-area
python3 -m http.server 8765

然后打开 http://localhost:8765/my-area-cesium-preview.html

实验:车辆巡航

previewcesium 阶段会额外生成 <area-id>-vehicle-route.json<area-id>-vehicle-car.gltf。路线文件从 OSM bounds 内的可行驶 highway way 提取道路中心线,并向右偏移约 1.3 米作为车辆行驶线避免车辆压道路中心线。Cesium 预览页会加载多条道路段并显示多辆实验车辆循环巡航;Vehicle 下拉框决定 Follow 跟随哪一辆车。

这是用于验证高精度巡航可用性的预览层功能,不会改变 Blender/GLB 主资产本身。车辆模型是无 logo 的轻量预览模型,生成在输出目录中。

已沉淀区域

  • config/areas/nantaizi-lake-innovation-valley.json
  • config/areas/hanyang-block.json

低层命令

通常优先使用 npm run build:area。如果只想调试旧 QGIS/osm2streets 阶段,可以直接运行:

npm run build:qgis -- --config config/hanyang-block.json

Blender 低层命令:

/Applications/Blender.app/Contents/MacOS/Blender \
  --background --factory-startup \
  --python blender/generate_scene.py -- \
  --osm "/path/to/input.osm" \
  --geojson "/path/to/osm2streets_web_out" \
  --output "/path/to/scene.blend" \
  --render "/path/to/preview.png" \
  --tree-style natural

--tree-style 可选 naturalproceduralshapesparkshapespark 使用 assets/models/custom/shapespark_plants/ 里的拆分低模植物资产;模型缺失时会回落到 natural

Cesium GLB 低层导出:

/Applications/Blender.app/Contents/MacOS/Blender \
  --background \
  --python blender/export_cesium.py -- \
  --blend "/path/to/scene.blend" \
  --glb "/path/to/scene.glb" \
  --metadata "/path/to/scene.json"

详见 blender/README.md

QGIS 手工修正工作流

如果已经在现成的 .qgz 项目里直接编辑了 gpkg 图层,不要再重跑 intermediates,否则会把手工修改覆盖掉。推荐流程是:

  1. 在 QGIS 中打开 outputs/<area-id>/<area-id>.qgz
  2. 直接编辑项目内关联的 gpkg 图层并保存
  3. reimport 回导 GeoJSON 并重建场景,再接 blender,cesium

南台子湖创新谷当前可直接使用下面这条命令:

npm run build -- --config config/areas/nantaizi-lake-innovation-valley.json --stages reimport,blender,cesium

reimport 阶段(scripts/reimport-gpkg.js)做两件事:

  • <area-id>.gpkg 里的 9 个图层逐个导出到 osm2streets_web_out/<layer>.geojson
  • scripts/lib/scene-layers.js 的图层表重建 osm2streets_scene.geojson(写入 render_layer / z_index)和 osm2streets_scene_style.json

说明:

  • 这套流程假设你的手工修改已经保存在 outputs/<area-id>/<area-id>.gpkg
  • 所有图层先导出到临时目录并校验通过后才写回 osm2streets_web_out/;任一图层缺失或导出结果不是合法 FeatureCollection整批都不落盘ogr2ogr 遇到不存在的图层会留下 0 字节文件,直接覆盖会静默损坏数据)
  • intermediatesreimport 互斥,同时指定会直接报错:前者用 OSM 重建 gpkg,正好会抹掉后者要读回的手工修改
  • blender,cesium 阶段读取的是 osm2streets_web_out/*.geojson,不是直接读取 gpkg
  • 如果 Blender 当前环境不稳定,先确认 geojson 已完成回导,再单独排查 Blender 本身
  • 增删图层或调整 z_index 只需改 scripts/lib/scene-layers.js构建、场景合并、场景样式、QGIS 工程会一并同步

文档

Description
No description provided
Readme 82 MiB
Languages
Python 60.9%
JavaScript 32%
HTML 6.7%
CSS 0.4%