diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f90ce1f..16986c795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## ALPR camera locations - Label the loaded camera count as nearby, show a purple-dot legend, and add - SHOW NEAREST to frame and select a loaded camera when none are on screen. + SHOW NEAREST to frame and select a loaded camera when none are on screen, + using the available 3D-tile or globe terrain height. - Keep nearby camera markers and selection stable during rotation, use bounded ground-centered coverage instead of the horizon rectangle, and reuse in-flight queries. diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index d6b753e17..3e4455ab3 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -13,7 +13,8 @@ The row count explicitly says **nearby**: loaded records can be outside the screen. A purple-dot legend identifies the fixed 8-pixel markers (12 pixels when selected). **SHOW NEAREST** frames and selects the nearest loaded camera; it is disabled with no loaded cameras or while following a tracked entity. This action -chooses from the current source snapshot. +chooses from the current source snapshot and uses rendered surface height from +3D tiles or globe terrain when available. Coverage follows a bounded neighborhood around the screen-center ground point, with a radius of twice the camera-to-ground range (at least 1 km), rather than extending to the horizon. Sky, dateline-crossing and wider-than-city views do not diff --git a/src/data/alprCameras.test.mjs b/src/data/alprCameras.test.mjs index d758f7060..ff24e3159 100644 --- a/src/data/alprCameras.test.mjs +++ b/src/data/alprCameras.test.mjs @@ -1093,6 +1093,8 @@ test('nearby count and discovery control frame a real loaded camera without fetc ); h.viewer.camera.flyToBoundingSphere = (sphere, options) => flights.push({ sphere, options }); + h.viewer.scene.globe.show = true; + h.viewer.scene.globe.getHeight = () => 312; try { assert.equal(alprCamerasLayer.getRowControls().chips[0].disabled, true); await alprCamerasLayer.update(); @@ -1106,6 +1108,10 @@ test('nearby count and discovery control frame a real loaded camera without fetc assert.ok( Math.abs(Cesium.Math.toDegrees(center.latitude) - 30.2672) < 1e-9, ); + assert.ok( + Math.abs(center.height - 312) < 1e-6, + 'use the rendered globe floor on keyless basemaps', + ); assert.equal(flights[0].options.offset.range, 800); assert.equal(h.requests.length, 1); h.viewer.trackedEntity = {}; diff --git a/src/layers/alpr/presentation.js b/src/layers/alpr/presentation.js index 89b6c6735..f56787c79 100644 --- a/src/layers/alpr/presentation.js +++ b/src/layers/alpr/presentation.js @@ -276,6 +276,8 @@ export function createAlprPresentation({ state, services, source }) { /* tiles may still be streaming */ } } + if (!Number.isFinite(height) && state.viewer.scene.globe.show) + height = state.viewer.scene.globe.getHeight?.(location); if (!Number.isFinite(height) || height < -500 || height > 10000) height = cachedGroundFloor(record.latitude, record.longitude); const center = Cesium.Cartesian3.fromDegrees(