mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
Merge origin/main: Google Street View, KartaView and Panoramax on the slim Street Level
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]>
This commit is contained in:
commit
6390a3346f
809 files changed
+81825
-6035
No files matched your search
@@ -46,6 +46,39 @@ test('the layer is key-gated only when every switched-on provider lacks its key'
|
||||
assert.equal(offOnly.keyRequired, false, 'nothing switched on to gate');
|
||||
});
|
||||
|
||||
test('the filter controls show only for a lit provider that honours them', () => {
|
||||
const streetView = provider({ id: 'google', groundClick: true, filters: [] });
|
||||
const controls = (providers) =>
|
||||
composeUIState({ ...base, providers }).filterControls;
|
||||
assert.deepEqual(controls([streetView]), { pano: false, since: false });
|
||||
assert.deepEqual(controls([provider(), streetView]), {
|
||||
pano: true,
|
||||
since: true,
|
||||
});
|
||||
assert.deepEqual(
|
||||
controls([provider({ on: false }), streetView]),
|
||||
{ pano: false, since: false },
|
||||
'Mapillary switched off',
|
||||
);
|
||||
assert.deepEqual(
|
||||
controls([provider({ on: false }), { ...streetView, on: false }]),
|
||||
{ pano: true, since: true },
|
||||
'nothing lit: both, ready for the first chip',
|
||||
);
|
||||
});
|
||||
|
||||
test('a lit provider that dates by upload puts a note under SINCE', () => {
|
||||
const kartaView = provider({
|
||||
id: 'kartaview',
|
||||
name: 'KartaView',
|
||||
sinceBasis: 'upload',
|
||||
});
|
||||
const note = (providers) => composeUIState({ ...base, providers }).sinceNote;
|
||||
assert.equal(note([provider()]), null, 'Mapillary: capture date');
|
||||
assert.equal(note([kartaView]), 'KartaView: by upload date');
|
||||
assert.equal(note([{ ...kartaView, on: false }]), null, 'only while lit');
|
||||
});
|
||||
|
||||
test('hint and error come from the first active provider that has one', () => {
|
||||
const ui = composeUIState({
|
||||
...base,
|
||||
@@ -72,6 +105,7 @@ test('summarizeCoverage is what getStats reports, without building a snapshot',
|
||||
loading: true,
|
||||
hint: 'Look down',
|
||||
error: 'boom',
|
||||
label: null,
|
||||
keyRequired: false,
|
||||
keyRejected: false,
|
||||
},
|
||||
@@ -98,3 +132,63 @@ test('a rejected key gates like a missing one and is named as rejected', () => {
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('every switched-on provider’s hint is kept, once each', async () => {
|
||||
const { summarizeCoverage } = await import('./uiState.js');
|
||||
const { providerSnapshot } =
|
||||
await import('../../testSupport/streetLevelFakes.mjs');
|
||||
const summary = summarizeCoverage([
|
||||
providerSnapshot({ hint: 'zoom in for sequences' }),
|
||||
providerSnapshot({
|
||||
id: 'google',
|
||||
hint: 'click a street to open Street View',
|
||||
}),
|
||||
providerSnapshot({ id: 'off', on: false, hint: 'not shown' }),
|
||||
providerSnapshot({ id: 'dup', hint: 'zoom in for sequences' }),
|
||||
]);
|
||||
assert.equal(
|
||||
summary.hint,
|
||||
'zoom in for sequences · click a street to open Street View',
|
||||
);
|
||||
});
|
||||
|
||||
test('a key-gated layer offers the switched-off sources that would draw with a key already set', async () => {
|
||||
const { keyAlternatives } = await import('./uiState.js');
|
||||
const mapillary = providerSnapshot({ keyRequired: true, configured: false });
|
||||
const streetView = providerSnapshot({
|
||||
id: 'google',
|
||||
label: 'STREET VIEW',
|
||||
on: false,
|
||||
configured: true,
|
||||
requiresKeyId: 'google-maps',
|
||||
});
|
||||
assert.deepEqual(keyAlternatives([mapillary, streetView]), [
|
||||
{ id: 'google', label: 'STREET VIEW', requiresKeyId: 'google-maps' },
|
||||
]);
|
||||
// Nothing to offer: Mapillary has its key, or Street View has none either.
|
||||
assert.deepEqual(keyAlternatives([providerSnapshot(), streetView]), []);
|
||||
assert.deepEqual(
|
||||
keyAlternatives([
|
||||
mapillary,
|
||||
{ ...streetView, configured: false, keyRequired: true },
|
||||
]),
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
test('a source names its own lines', () => {
|
||||
const kartaView = provider({
|
||||
id: 'kartaview',
|
||||
name: 'KartaView',
|
||||
color: '#635bff',
|
||||
coverageLabel: {
|
||||
noun: 'streets',
|
||||
action: 'click a line for its nearest photo',
|
||||
},
|
||||
});
|
||||
const ui = composeUIState({ ...base, providers: [kartaView] });
|
||||
assert.deepEqual(ui.coverage.label, {
|
||||
noun: 'streets',
|
||||
action: 'click a line for its nearest photo',
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user