feat(cli): add interactive area build menu
This commit is contained in:
@@ -37,12 +37,14 @@ npm install
|
|||||||
|
|
||||||
## 主流程
|
## 主流程
|
||||||
|
|
||||||
默认构建南台子湖创新谷样例:
|
交互式选择区域和构建阶段:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
使用方向键移动、空格多选阶段、回车开始构建;`intermediates` 与 `reimport` 不能同时选择。
|
||||||
|
|
||||||
指定区域配置:
|
指定区域配置:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -310,7 +312,7 @@ npm run compress:glb -- \
|
|||||||
南台子湖创新谷当前可直接使用下面这条命令:
|
南台子湖创新谷当前可直接使用下面这条命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build -- --config config/areas/nantaizi-lake-innovation-valley.json --stages reimport,blender,cesium
|
npm run build:area -- --config config/areas/nantaizi-lake-innovation-valley.json --stages reimport,blender,cesium
|
||||||
```
|
```
|
||||||
|
|
||||||
`reimport` 阶段(`scripts/reimport-gpkg.js`)做两件事:
|
`reimport` 阶段(`scripts/reimport-gpkg.js`)做两件事:
|
||||||
|
|||||||
411
package-lock.json
generated
411
package-lock.json
generated
@@ -8,14 +8,425 @@
|
|||||||
"name": "osm-asset-pipeline",
|
"name": "osm-asset-pipeline",
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/prompts": "^8.5.2",
|
||||||
"osm2streets-js-node": "0.1.4"
|
"osm2streets-js-node": "0.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@inquirer/ansi": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/ansi/-/ansi-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/checkbox": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/checkbox/-/checkbox-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/ansi": "^2.0.7",
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/figures": "^2.0.7",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/confirm": {
|
||||||
|
"version": "6.1.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/confirm/-/confirm-6.1.1.tgz",
|
||||||
|
"integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/core": {
|
||||||
|
"version": "11.2.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/core/-/core-11.2.1.tgz",
|
||||||
|
"integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/ansi": "^2.0.7",
|
||||||
|
"@inquirer/figures": "^2.0.7",
|
||||||
|
"@inquirer/type": "^4.0.7",
|
||||||
|
"cli-width": "^4.1.0",
|
||||||
|
"fast-wrap-ansi": "^0.2.0",
|
||||||
|
"mute-stream": "^3.0.0",
|
||||||
|
"signal-exit": "^4.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/editor": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/editor/-/editor-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/external-editor": "^3.0.3",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/expand": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/expand/-/expand-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/external-editor": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/external-editor/-/external-editor-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chardet": "^2.1.1",
|
||||||
|
"iconv-lite": "^0.7.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/figures": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/figures/-/figures-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/input": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/input/-/input-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/number": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/number/-/number-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/password": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/password/-/password-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/ansi": "^2.0.7",
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/prompts": {
|
||||||
|
"version": "8.5.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/prompts/-/prompts-8.5.2.tgz",
|
||||||
|
"integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/checkbox": "^5.2.1",
|
||||||
|
"@inquirer/confirm": "^6.1.1",
|
||||||
|
"@inquirer/editor": "^5.2.2",
|
||||||
|
"@inquirer/expand": "^5.1.1",
|
||||||
|
"@inquirer/input": "^5.1.2",
|
||||||
|
"@inquirer/number": "^4.1.1",
|
||||||
|
"@inquirer/password": "^5.1.1",
|
||||||
|
"@inquirer/rawlist": "^5.3.1",
|
||||||
|
"@inquirer/search": "^4.2.1",
|
||||||
|
"@inquirer/select": "^5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/rawlist": {
|
||||||
|
"version": "5.3.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/rawlist/-/rawlist-5.3.1.tgz",
|
||||||
|
"integrity": "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/search": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/search/-/search-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/figures": "^2.0.7",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/select": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/select/-/select-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/ansi": "^2.0.7",
|
||||||
|
"@inquirer/core": "^11.2.1",
|
||||||
|
"@inquirer/figures": "^2.0.7",
|
||||||
|
"@inquirer/type": "^4.0.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@inquirer/type": {
|
||||||
|
"version": "4.0.7",
|
||||||
|
"resolved": "http://172.16.1.86:4873/@inquirer/type/-/type-4.0.7.tgz",
|
||||||
|
"integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chardet": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "http://172.16.1.86:4873/chardet/-/chardet-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/cli-width": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "http://172.16.1.86:4873/cli-width/-/cli-width-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-string-truncated-width": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "http://172.16.1.86:4873/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/fast-string-width": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/fast-string-width/-/fast-string-width-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-string-truncated-width": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-wrap-ansi": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-string-width": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "http://172.16.1.86:4873/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mute-stream": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "http://172.16.1.86:4873/mute-stream/-/mute-stream-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.17.0 || >=22.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/osm2streets-js-node": {
|
"node_modules/osm2streets-js-node": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/osm2streets-js-node/-/osm2streets-js-node-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/osm2streets-js-node/-/osm2streets-js-node-0.1.4.tgz",
|
||||||
"integrity": "sha512-JjS6qJJjrrlEKEZxqV4s/N4qU0YfvdMUasdvfoyYCmZxEpNKAYjpuZeWJWeLEcGOqhu+YuV3YDIk9jgvMU0kKQ==",
|
"integrity": "sha512-JjS6qJJjrrlEKEZxqV4s/N4qU0YfvdMUasdvfoyYCmZxEpNKAYjpuZeWJWeLEcGOqhu+YuV3YDIk9jgvMU0kKQ==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "http://172.16.1.86:4873/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/signal-exit": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "http://172.16.1.86:4873/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node scripts/build-area.js",
|
"build": "node scripts/interactive-build.js",
|
||||||
"build:area": "node scripts/build-area.js",
|
"build:area": "node scripts/build-area.js",
|
||||||
"build:qgis": "node scripts/build-osm2streets-qgis.js",
|
"build:qgis": "node scripts/build-osm2streets-qgis.js",
|
||||||
"check:area": "node scripts/check-area.js",
|
"check:area": "node scripts/check-area.js",
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
"diagnose:area": "node scripts/diagnose-area.js",
|
"diagnose:area": "node scripts/diagnose-area.js",
|
||||||
"preflight:area": "node scripts/preflight-area.js",
|
"preflight:area": "node scripts/preflight-area.js",
|
||||||
"test:preflight": "node scripts/test-area-preflight.js",
|
"test:preflight": "node scripts/test-area-preflight.js",
|
||||||
|
"test:build-stages": "node scripts/test-build-stages.js",
|
||||||
"test:budgets": "node scripts/test-asset-budgets.js",
|
"test:budgets": "node scripts/test-asset-budgets.js",
|
||||||
"test:preview-assets": "node scripts/test-preview-assets.js",
|
"test:preview-assets": "node scripts/test-preview-assets.js",
|
||||||
"test:compress-glb": "node scripts/test-compress-glb.js",
|
"test:compress-glb": "node scripts/test-compress-glb.js",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"render:turn-lane-arrow-samples": "node scripts/render-turn-lane-arrow-samples.js"
|
"render:turn-lane-arrow-samples": "node scripts/render-turn-lane-arrow-samples.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/prompts": "^8.5.2",
|
||||||
"osm2streets-js-node": "0.1.4"
|
"osm2streets-js-node": "0.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const fs = require("fs");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { spawnSync } = require("child_process");
|
const { spawnSync } = require("child_process");
|
||||||
const { readAreaConfig } = require("./lib/area-config");
|
const { readAreaConfig } = require("./lib/area-config");
|
||||||
|
const { resolveStages } = require("./lib/build-stages");
|
||||||
const { blenderExecutable: resolveBlenderExecutable } = require("./lib/tool-paths");
|
const { blenderExecutable: resolveBlenderExecutable } = require("./lib/tool-paths");
|
||||||
const {
|
const {
|
||||||
SCENE_LAYERS,
|
SCENE_LAYERS,
|
||||||
@@ -41,15 +42,6 @@ const requestedStages = args.stages
|
|||||||
: null;
|
: null;
|
||||||
const stages = resolveStages(area.stages, requestedStages);
|
const stages = resolveStages(area.stages, requestedStages);
|
||||||
|
|
||||||
// intermediates deletes and rebuilds the GeoPackage from OSM, which is exactly
|
|
||||||
// the manual work reimport exists to recover. Refuse the combination instead of
|
|
||||||
// silently letting one undo the other.
|
|
||||||
if (stages.intermediates && stages.reimport) {
|
|
||||||
throw new Error(
|
|
||||||
"Stages 'intermediates' and 'reimport' are mutually exclusive: " +
|
|
||||||
"intermediates rebuilds the GeoPackage from OSM and would discard the QGIS edits reimport reads back.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Area: ${area.id}`);
|
console.log(`Area: ${area.id}`);
|
||||||
console.log(`Config: ${configPath}`);
|
console.log(`Config: ${configPath}`);
|
||||||
@@ -100,49 +92,6 @@ function splitList(value) {
|
|||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveStages(defaults, requested) {
|
|
||||||
if (!requested) return defaults;
|
|
||||||
// 'reimport' is deliberately absent from 'all': it is a recovery step for
|
|
||||||
// hand-edited GeoPackages, never part of a full build.
|
|
||||||
// 'compress' is also absent from 'all': it creates an alternate Cesium GLB,
|
|
||||||
// not the baseline asset.
|
|
||||||
const aliases = {
|
|
||||||
all: ["intermediates", "blender", "cesium"],
|
|
||||||
qgis: ["intermediates"],
|
|
||||||
osm2streets: ["intermediates"],
|
|
||||||
geojson: ["intermediates"],
|
|
||||||
intermediate: ["intermediates"],
|
|
||||||
intermediates: ["intermediates"],
|
|
||||||
reimport: ["reimport"],
|
|
||||||
gpkg: ["reimport"],
|
|
||||||
blender: ["blender"],
|
|
||||||
scene: ["blender"],
|
|
||||||
cesium: ["cesium"],
|
|
||||||
glb: ["cesium"],
|
|
||||||
preview: ["preview"],
|
|
||||||
html: ["preview"],
|
|
||||||
cesiumPreview: ["preview"],
|
|
||||||
compress: ["compress"],
|
|
||||||
compression: ["compress"],
|
|
||||||
compressedCesium: ["compress"],
|
|
||||||
};
|
|
||||||
const out = {
|
|
||||||
intermediates: false,
|
|
||||||
reimport: false,
|
|
||||||
blender: false,
|
|
||||||
cesium: false,
|
|
||||||
preview: false,
|
|
||||||
compress: false,
|
|
||||||
};
|
|
||||||
for (const stage of requested) {
|
|
||||||
const mapped = aliases[stage];
|
|
||||||
if (!mapped) {
|
|
||||||
throw new Error(`Unknown stage '${stage}'. Use intermediates, reimport, blender, cesium, preview, compress, or all.`);
|
|
||||||
}
|
|
||||||
for (const key of mapped) out[key] = true;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeDerivedConfig(area) {
|
function writeDerivedConfig(area) {
|
||||||
fs.mkdirSync(area.outputs.pipelineDir, { recursive: true });
|
fs.mkdirSync(area.outputs.pipelineDir, { recursive: true });
|
||||||
|
|||||||
49
scripts/interactive-build.js
Normal file
49
scripts/interactive-build.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { spawnSync } = require("child_process");
|
||||||
|
const { STAGES, resolveStages, canonicalStages } = require("./lib/build-stages");
|
||||||
|
|
||||||
|
const repoRoot = path.resolve(__dirname, "..");
|
||||||
|
|
||||||
|
function areaConfigs() {
|
||||||
|
return fs.readdirSync(path.join(repoRoot, "config", "areas"))
|
||||||
|
.filter((file) => file.endsWith(".json"))
|
||||||
|
.sort()
|
||||||
|
.map((file) => path.join(repoRoot, "config", "areas", file));
|
||||||
|
}
|
||||||
|
|
||||||
|
function requireTty(input = process.stdin, output = process.stdout) {
|
||||||
|
if (!input.isTTY || !output.isTTY) throw new Error("Interactive build requires a TTY. Use npm run build:area -- --config <area> --stages <stages> instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
requireTty();
|
||||||
|
const configs = areaConfigs();
|
||||||
|
if (!configs.length) throw new Error("No area configs found in config/areas.");
|
||||||
|
const { select, checkbox } = await import("@inquirer/prompts");
|
||||||
|
const config = await select({
|
||||||
|
message: "Choose an area",
|
||||||
|
choices: configs.map((file) => ({ name: path.basename(file, ".json"), value: file })),
|
||||||
|
});
|
||||||
|
const chosen = await checkbox({
|
||||||
|
message: "Choose build stages",
|
||||||
|
choices: STAGES.map((stage) => ({ name: `${stage.id} - ${stage.description}`, value: stage.id })),
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
if (!chosen.length) throw new Error("Choose at least one build stage.");
|
||||||
|
const stages = canonicalStages(resolveStages({}, chosen));
|
||||||
|
console.log(`Area: ${path.basename(config)}`);
|
||||||
|
console.log(`Stages: ${stages.join(", ")}`);
|
||||||
|
const result = spawnSync(process.execPath, [path.join(__dirname, "build-area.js"), "--config", config, "--stages", stages.join(",")], { stdio: "inherit" });
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
process.exitCode = result.status || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) main().catch((error) => {
|
||||||
|
if (error.name !== "ExitPromptError") console.error(`Error: ${error.message}`);
|
||||||
|
process.exitCode = error.name === "ExitPromptError" ? 0 : 1;
|
||||||
|
});
|
||||||
|
module.exports = { areaConfigs, requireTty };
|
||||||
41
scripts/lib/build-stages.js
Normal file
41
scripts/lib/build-stages.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const STAGES = [
|
||||||
|
{ id: "intermediates", label: "OSM / QGIS intermediates", description: "Rebuild GeoJSON and GeoPackage from OSM" },
|
||||||
|
{ id: "reimport", label: "Reimport QGIS edits", description: "Copy GeoPackage layers back to GeoJSON" },
|
||||||
|
{ id: "blender", label: "Blender scene", description: "Generate the editable scene and render" },
|
||||||
|
{ id: "cesium", label: "Cesium export", description: "Export GLB, metadata, and preview" },
|
||||||
|
{ id: "preview", label: "Preview refresh", description: "Regenerate preview HTML and vehicles" },
|
||||||
|
{ id: "compress", label: "Compressed preview", description: "Create optional compressed GLB artifacts" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const ALIASES = {
|
||||||
|
all: ["intermediates", "blender", "cesium"],
|
||||||
|
qgis: ["intermediates"], osm2streets: ["intermediates"], geojson: ["intermediates"], intermediate: ["intermediates"],
|
||||||
|
intermediates: ["intermediates"], reimport: ["reimport"], gpkg: ["reimport"], blender: ["blender"], scene: ["blender"],
|
||||||
|
cesium: ["cesium"], glb: ["cesium"], preview: ["preview"], html: ["preview"], cesiumPreview: ["preview"],
|
||||||
|
compress: ["compress"], compression: ["compress"], compressedCesium: ["compress"],
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveStages(defaults, requested) {
|
||||||
|
const selected = requested || Object.keys(defaults).filter((key) => defaults[key]);
|
||||||
|
const result = Object.fromEntries(STAGES.map(({ id }) => [id, false]));
|
||||||
|
for (const stage of selected) {
|
||||||
|
const mapped = ALIASES[stage];
|
||||||
|
if (!mapped) throw new Error(`Unknown stage '${stage}'. Use ${stageNames().join(", ")}, or all.`);
|
||||||
|
for (const id of mapped) result[id] = true;
|
||||||
|
}
|
||||||
|
assertCompatible(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertCompatible(stages) {
|
||||||
|
if (stages.intermediates && stages.reimport) {
|
||||||
|
throw new Error("Stages 'intermediates' and 'reimport' are mutually exclusive: intermediates rebuilds the GeoPackage from OSM and would discard the QGIS edits reimport reads back.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stageNames() { return STAGES.map(({ id }) => id); }
|
||||||
|
function canonicalStages(stages) { return stageNames().filter((id) => stages[id]); }
|
||||||
|
|
||||||
|
module.exports = { STAGES, resolveStages, canonicalStages, stageNames };
|
||||||
8
scripts/test-build-stages.js
Normal file
8
scripts/test-build-stages.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
"use strict";
|
||||||
|
const assert = require("assert");
|
||||||
|
const { resolveStages, canonicalStages } = require("./lib/build-stages");
|
||||||
|
assert.deepEqual(canonicalStages(resolveStages({}, ["compress", "blender", "preview"])), ["blender", "preview", "compress"]);
|
||||||
|
assert.deepEqual(canonicalStages(resolveStages({}, ["all"])), ["intermediates", "blender", "cesium"]);
|
||||||
|
assert.throws(() => resolveStages({}, ["intermediates", "reimport"]), /mutually exclusive/);
|
||||||
|
console.log("Build stage tests passed.");
|
||||||
Reference in New Issue
Block a user