diff --git a/src/scene/CesiumGlobe.js b/src/scene/CesiumGlobe.js index 77b8b94..4dc03ad 100644 --- a/src/scene/CesiumGlobe.js +++ b/src/scene/CesiumGlobe.js @@ -299,6 +299,7 @@ export class CesiumGlobe { viewer.clock.shouldAnimate = false; this._buildMarkers(); + this._clampMarkersToTerrain(); this._setupPick(); this._setupRightRestore(); this._loadBoundaries(); @@ -327,6 +328,8 @@ export class CesiumGlobe { const noteNormal = makeStickyNote(entry.name, 16, false); const noteSelected = makeStickyNote(entry.name, 16, true); this.markers.push({ + lng: entry.lng, + lat: entry.lat, position, r2: Cesium.Cartesian3.magnitudeSquared(position), noteNormal, @@ -337,6 +340,29 @@ export class CesiumGlobe { this._initMarkerLayer(); } + // 把便签锚点贴到地形表面(否则在椭球面高度 0 上,放大旋转时会飘) + async _clampMarkersToTerrain() { + const scene = this.viewer.scene; + if (!scene || !scene.globe) return; + const cartos = this.markers.map((m) => + Cesium.Cartographic.fromDegrees(m.lng, m.lat), + ); + try { + await scene.sampleHeightMostDetailed(cartos); + } catch (err) { + console.warn('[CesiumGlobe] 地形高度采样失败,便签保持椭球面高度:', err); + return; + } + for (let i = 0; i < this.markers.length; i++) { + const h = cartos[i] && cartos[i].height; + if (h != null && isFinite(h)) { + const m = this.markers[i]; + m.position = Cesium.Cartesian3.fromDegrees(m.lng, m.lat, h); + m.r2 = Cesium.Cartesian3.magnitudeSquared(m.position); + } + } + } + // 便签用 DOM 覆盖层渲染:始终在城市/国家名上层,且缩放到最近也不会漂移 _initMarkerLayer() { const container = document.getElementById('cesium-container');