terrain-height-frame.mjs 1.2 KB

1234567891011121314151617181920212223
  1. // Original DEM ellipsoid heights must be converted before use as ENU mesh Z.
  2. import assert from 'node:assert/strict'
  3. import { Cartesian3, Matrix4 } from 'cesium'
  4. export function terrainInLocalFrame(transform, samples, heights) {
  5. assert.equal(samples.length, heights.length, 'terrain point/height mismatch')
  6. const inverse = Matrix4.inverseTransformation(Matrix4.fromArray(transform), new Matrix4())
  7. return samples.map((sample, index) => {
  8. assert.ok(Number.isFinite(heights[index]) && heights[index] > 1, 'invalid original DEM height')
  9. const local = Matrix4.multiplyByPoint(inverse,
  10. Cartesian3.fromDegrees(sample.lon, sample.lat, heights[index]), new Cartesian3())
  11. return [local.x, local.y, local.z]
  12. })
  13. }
  14. export function localSeatingLevels(transform, samples, heights) {
  15. const points = terrainInLocalFrame(transform, samples, heights)
  16. const minimum = Math.min(...points.map(p => p[2])), maximum = Math.max(...points.map(p => p[2]))
  17. return { minimum, maximum, relief: maximum - minimum,
  18. floorZ: maximum - .25, foundationBottom: minimum - 3,
  19. ellipsoidMinimum: Math.min(...heights), ellipsoidMaximum: Math.max(...heights),
  20. heightFrame: 'project-local-ENU-up' }
  21. }