| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- // Seat estate modules on the original DEM; explicitly leave steep footprints for stepped construction.
- import { readFileSync, writeFileSync } from 'node:fs'
- import { Cartesian3, Matrix4 } from 'cesium'
- const dir = 'tools/city-massing/city/regular-estate/'
- const plan = JSON.parse(readFileSync(dir + 'plan.json'))
- const sampled = JSON.parse(readFileSync(dir + 'terrain-samples.json'))
- if (plan.samplesSha256 !== sampled.samplesSha256)
- throw new Error('DEM sample coordinates differ from the footprint plan')
- const inverse = Matrix4.inverseTransformation(Matrix4.fromArray(plan.transform), new Matrix4())
- const local = (lon, lat, height) =>
- Matrix4.multiplyByPoint(inverse, Cartesian3.fromDegrees(lon, lat, height), new Cartesian3())
- const buildings = [],
- excluded = []
- for (const module of plan.modules) {
- const heights = module.sampleIndices.map((i) => sampled.heights[i])
- if (heights.some((h) => !Number.isFinite(h))) throw new Error(`Missing original DEM sample: ${module.id}`)
- const min = Math.min(...heights),
- max = Math.max(...heights),
- relief = max - min
- if (relief > 2.5) {
- excluded.push({
- id: module.id,
- sourceId: module.sourceId,
- reason: 'DEM relief exceeds 2.5m; requires stepped construction',
- relief,
- })
- continue
- }
- const floorHeight = max - 0.25
- const floor = local(module.center.lon, module.center.lat, floorHeight)
- const bottom = local(module.center.lon, module.center.lat, min - 3)
- buildings.push({
- ...module,
- positionENU: [floor.x, floor.y, floor.z],
- foundationBottom: bottom.z,
- terrainMin: min,
- terrainMax: max,
- terrainRelief: relief,
- floorHeight,
- groundControls: module.sampleIndices.map((i) => [plan.samples[i].lon, plan.samples[i].lat, sampled.heights[i]]),
- })
- }
- const output = {
- ...plan,
- buildings,
- excluded,
- notice: plan.disclaimer + ' Steep modules are excluded from this straight-floor batch.',
- }
- writeFileSync(dir + 'seated-plan.json', JSON.stringify(output, null, 2))
- console.log(
- JSON.stringify({
- candidateModules: plan.modules.length,
- accepted: buildings.length,
- excluded: excluded.length,
- maxRelief: Math.max(...buildings.map((m) => m.terrainRelief), 0),
- })
- )
|