preview.html 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <meta charset="UTF-8" /><title>沅陵建模审查样片</title
  4. ><style>
  5. html,
  6. body,
  7. #map {
  8. margin: 0;
  9. width: 100%;
  10. height: 100%;
  11. overflow: hidden;
  12. background: #071019;
  13. }
  14. #caption {
  15. position: absolute;
  16. left: 18px;
  17. bottom: 28px;
  18. max-width: calc(100% - 48px);
  19. color: #eee;
  20. background: #102131d9;
  21. padding: 10px;
  22. font: 14px sans-serif;
  23. pointer-events: none;
  24. }
  25. </style>
  26. <body>
  27. <div id="map"></div>
  28. <div id="caption">建模审查样片,非测绘数据</div>
  29. <script type="module">
  30. window.CESIUM_BASE_URL = '/cesium/'
  31. const raw = await (await fetch('/src/modules/cockpit/services/cesiumEngine.js')).text()
  32. const url = raw.match(/from\s*["']([^"']*\/cesium\.js[^"']*)["']/)?.[1]
  33. const C = await import(url),
  34. E = await import('/src/modules/cockpit/services/cesiumEngine.js')
  35. window.startPreview = async ({ model, models, terrain = true, imagery = true }) => {
  36. const v = E.createViewer(document.querySelector('#map'), {
  37. ready: true,
  38. kind: 'tms',
  39. url: 'Assets/Textures/NaturalEarthII',
  40. })
  41. if (terrain) await E.applyTerrain(v, { url: '/gis/dem', requestVertexNormals: true })
  42. else v.terrainProvider = new C.EllipsoidTerrainProvider()
  43. if (imagery)
  44. E.applyOverlays(v, [
  45. {
  46. url: '/gis/pic3/{z}/{x}/{reverseY}.png',
  47. minimumLevel: 0,
  48. maximumLevel: 19,
  49. bounds: [109.962, 27.962, 111.046, 29.061],
  50. },
  51. ])
  52. const tileUrls = models || (model ? [model] : [])
  53. const t = await E.applyTilesets(v.scene, tileUrls.map(url => ({ url, lighting: true })))
  54. if (t.failed.length) throw Error(JSON.stringify(t.failed))
  55. v.scene.globe.maximumScreenSpaceError = 1
  56. v.scene.globe.enableLighting = false
  57. // A fixed local daylight is used for asset inspection; terrain imagery stays unlit.
  58. const frame = C.Transforms.eastNorthUpToFixedFrame(C.Cartesian3.fromDegrees(110.395, 28.454))
  59. const sunDir = C.Matrix4.multiplyByPointAsVector(
  60. frame,
  61. new C.Cartesian3(-0.4, -0.6, -1),
  62. new C.Cartesian3()
  63. )
  64. C.Cartesian3.normalize(sunDir, sunDir)
  65. v.scene.light = new C.DirectionalLight({ direction: sunDir, intensity: 3.0 })
  66. v.shadowMap.enabled = false // 避免当前审查场景阴影精度导致立面噪点;不影响地形深度遮挡。
  67. v.shadowMap.softShadows = true
  68. for (const tile of t.instances) {
  69. tile.imageBasedLighting = new C.ImageBasedLighting({
  70. imageBasedLightingFactor: new C.Cartesian2(1, 1),
  71. sphericalHarmonicCoefficients: [
  72. new C.Cartesian3(0.75, 0.75, 0.75),
  73. ...Array.from({ length: 8 }, () => new C.Cartesian3(0, 0, 0)),
  74. ],
  75. })
  76. }
  77. window.scene35 = { C, E, v, tiles: t.instances }
  78. window.frameCount = 0
  79. v.scene.postRender.addEventListener(() => window.frameCount++)
  80. return true
  81. }
  82. if (location.hash !== '#automation') {
  83. // 审查入口按 hash 选择模型组:#cad-bim 看测绘足印 BIM 批次,默认看旧三棵树。
  84. const hash = location.hash.replace('#', '')
  85. const groups = {
  86. 'cad-bim': {
  87. models: [
  88. '/review-assets/city/cad-bim/lod-pilot/tileset.json',
  89. '/review-assets/city/cad-bim/lod-batch-urban8000-dedup/tileset.json',
  90. '/review-assets/city/cad-bim/lod-batch-urban8000b/tileset.json',
  91. '/review-assets/city/cad-bim/lod-batch-urban8000c/tileset.json',
  92. '/review-assets/city/cad-bim/lod-batch-urban-final/tileset.json',
  93. '/review-assets/city/cad-bim/lod-batch-urban-tail/tileset.json',
  94. '/review-assets/city/cad-bim/lod-batch-rural1/tileset.json',
  95. '/review-assets/city/cad-bim/lod-batch-rural2/tileset.json',
  96. '/review-assets/city/cad-bim/lod-batch-rural3/tileset.json',
  97. '/review-assets/city/cad-bim/lod-batch-unfitted-fallback/tileset.json',
  98. ],
  99. home: [110.3965, 28.457],
  100. range: 1500,
  101. caption: '沅陵 1:500 测绘足印 BIM(城区+乡村,10 批 48,425 栋)· 体量按真实轮廓挤出 · 层高与立面为估计,非测绘数据',
  102. },
  103. }
  104. const group = groups[hash] || {
  105. models: [
  106. '/review-assets/district/lod-preview/tileset.json',
  107. '/review-assets/city/regular-estate/lod-preview/tileset.json',
  108. '/review-assets/city/oldtown/lod-preview/tileset.json',
  109. ],
  110. home: [110.395, 28.454],
  111. range: 1250,
  112. caption: '沅陵体育场附近示范街区 · 屋顶/立面样片 · 非全城覆盖,楼层与立面非测绘数据',
  113. }
  114. await startPreview({ models: group.models })
  115. const { v, C } = window.scene35
  116. v.scene.screenSpaceCameraController.enableRotate = true
  117. v.scene.screenSpaceCameraController.enableZoom = true
  118. v.scene.screenSpaceCameraController.enableTilt = true
  119. v.scene.screenSpaceCameraController.enableTranslate = true
  120. v.camera.lookAtTransform(
  121. C.Transforms.eastNorthUpToFixedFrame(C.Cartesian3.fromDegrees(group.home[0], group.home[1], 135)),
  122. new C.HeadingPitchRange(0, -0.85, group.range)
  123. )
  124. document.querySelector('#caption').textContent = group.caption
  125. }
  126. </script>
  127. </body>
  128. </html>