mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
Main gained three imagery providers (Google Street View, KartaView,
Panoramax), shared line-coverage, cone and photo-viewer modules, one source
lit at a time and the translated interface. Their shared modules still
carried what this branch removes, so the merge ports them onto it:
- lineCoverage.js is this branch's coverage.js made provider-neutral
(draped lines near the ground only, the selection drawn over them, key
and rate-limit blocking); sequenceCones.js is sequences.js the same way.
Mapillary, KartaView and Panoramax all build on them; Mapillary moves
back to providers/mapillary/ beside the others.
- No ground casting, mesh sampling, surface modes, FOLLOW, legend, prewarm,
orbit overview points (Panoramax's density dots included), stale-tile
swaps or water-filled point budget come back.
- Kept from main because the new providers need them: requiresMapStack and
attachMapStackController (Street View on Google 3D only), ground clicks,
openNearest with an optional provider nearestImage, openImage {frame},
reportError, the view-cone marker (now an SVG glyph), filters /
coverageLabel / sinceBasis, OPEN STREET VIEW, keyAlternatives and i18n.
- photoViewer.js treats the viewer as expanded when its wrap is full screen
or the iPhone popover, as EXPAND now is.
- The fixture browser gate keeps its 8 steps and adds one each for
KartaView and Panoramax; catalogs, docs, boundaries and format scope
follow.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
93 lines
3.1 KiB
JavaScript
93 lines
3.1 KiB
JavaScript
import * as Cesium from 'cesium';
|
|
import { CLICK_PICK_WINDOW_PX, STREET_LEVEL_LAYER_ID } from './policy.js';
|
|
|
|
/** One click handler for every provider's lines and cones, and the marker. */
|
|
export function createSelection({ state, parts }) {
|
|
const { picking, input } = state.services;
|
|
|
|
/** The id carries a provider's prefix: that provider handles the pick. */
|
|
function onClick(click) {
|
|
const viewer = state.viewer;
|
|
if (!viewer || !state.enabled) return;
|
|
if (input?.isPointerFree && !input.isPointerFree()) return;
|
|
const picked = viewer.scene.pick(
|
|
click.position,
|
|
CLICK_PICK_WINDOW_PX,
|
|
CLICK_PICK_WINDOW_PX,
|
|
);
|
|
const id = picking?.resolvePickId
|
|
? picking.resolvePickId(picked)
|
|
: picked?.id;
|
|
const route = parts.router.resolve(id);
|
|
// Not ours: the ground handler decides whether it is the map itself.
|
|
if (!route) {
|
|
parts.openAtGround?.(click.position, picked);
|
|
return;
|
|
}
|
|
// The position marker is the core's own: nothing to select.
|
|
if (!route.instance) return;
|
|
route.instance.handlePick(route.id, {
|
|
groundPoint: () => groundPointAt(viewer, click.position),
|
|
});
|
|
}
|
|
|
|
/** Lon/lat of the ground under a screen point, or null (sky, no picker). */
|
|
function groundPointAt(viewer, screenPosition) {
|
|
const position = state.services.scenePick?.pickGroundPosition?.(
|
|
viewer,
|
|
screenPosition,
|
|
);
|
|
const carto = position && Cesium.Cartographic.fromCartesian(position);
|
|
return carto
|
|
? {
|
|
lon: Cesium.Math.toDegrees(carto.longitude),
|
|
lat: Cesium.Math.toDegrees(carto.latitude),
|
|
}
|
|
: null;
|
|
}
|
|
|
|
/**
|
|
* Esc clears the selected sequence, but only once nothing closer to the
|
|
* user wants it: an expanded viewer, an open panel or a text field.
|
|
*/
|
|
function onKeyDown(event) {
|
|
if (event.key !== 'Escape' || event.defaultPrevented) return;
|
|
// A text field keeps its Esc, rich-text editors (contenteditable) included.
|
|
const target = event.target;
|
|
if (
|
|
target?.isContentEditable === true ||
|
|
target?.closest?.(
|
|
'.panel-collapsible, [role="dialog"], input, textarea, select',
|
|
)
|
|
)
|
|
return;
|
|
if (!parts.hasSelectedSequence()) return;
|
|
event.preventDefault();
|
|
parts.clearSequences();
|
|
}
|
|
|
|
function install(viewer) {
|
|
if (state.clickHandler) return;
|
|
state.clickHandler = new Cesium.ScreenSpaceEventHandler(
|
|
viewer.scene.canvas,
|
|
);
|
|
state.clickHandler.setInputAction(
|
|
onClick,
|
|
Cesium.ScreenSpaceEventType.LEFT_CLICK,
|
|
);
|
|
document.addEventListener('keydown', onKeyDown);
|
|
picking?.registerPickOwner?.(STREET_LEVEL_LAYER_ID, parts.router.ownsPick);
|
|
}
|
|
|
|
function uninstall() {
|
|
// Nothing to undo for a layer that was never enabled.
|
|
if (!state.clickHandler) return;
|
|
if (!state.clickHandler.isDestroyed()) state.clickHandler.destroy();
|
|
state.clickHandler = null;
|
|
document.removeEventListener('keydown', onKeyDown);
|
|
picking?.unregisterPickOwner?.(STREET_LEVEL_LAYER_ID);
|
|
}
|
|
|
|
return { install, uninstall, ownsPick: parts.router.ownsPick };
|
|
}
|