mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 15:22:21 +00:00
feat(street-level): "show me X on Street View" action, street_level view field and sl= links
show_street_level (voice and typed) flies to a place and opens its nearest street-level photo from Google Street View, Mapillary, KartaView or Panoramax; Street View switches to Google 3D first. The view model gains a street_level field, share links carry sl=<source>,<lat>,<lon>, and show_in_gods_eye_view can open a photo. A plain sl=google link only arms the point and waits for OPEN, so it never bills a key without a click. Embed pages show an open photo in an overlay that Esc closes. On-screen strings are translated into es, ru, zh-CN and zh-Hant. Covered by unit tests and three new steps in the Street Level browser suite.
This commit is contained in:
1 parent
f3adccd01a
commit
98de41c94a
64 files changed
+4147
-66
No files matched your search
@@ -489,6 +489,154 @@ test('labels are bounded and cleaned before they are spoken', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('street-level speech names the source and the place, and says which step failed', () => {
|
||||
const ok = envelope('show_street_level', {
|
||||
ok: true,
|
||||
action: 'show_street_level',
|
||||
provider: 'google',
|
||||
providerName: 'Google Street View',
|
||||
label: '10th Street, Sacramento',
|
||||
title: '1000 10th St, Sacramento, CA',
|
||||
capturedAt: Date.UTC(2024, 4, 1), // Google dates: the first of the month, UTC
|
||||
});
|
||||
assert.equal(ok.say, 'Google Street View at 1000 10th St, Sacramento, CA.');
|
||||
assertSpeakable(ok.say);
|
||||
assert.equal(ok.display.title, 'Google Street View');
|
||||
assert.equal(ok.display.lines[1], 'Captured May 2024');
|
||||
|
||||
const stages = {
|
||||
location: "Couldn't find Nowhere.",
|
||||
map: "Google Street View needs the Google 3D map, which isn't available.",
|
||||
key: 'Google Street View needs its key.',
|
||||
layer: "Couldn't turn on Street Level.",
|
||||
imagery: 'No Google Street View imagery near Nowhere.',
|
||||
};
|
||||
for (const [stage, say] of Object.entries(stages)) {
|
||||
const out = envelope('show_street_level', {
|
||||
ok: false,
|
||||
stage,
|
||||
label: 'Nowhere',
|
||||
providerName: 'Google Street View',
|
||||
error: 'detail',
|
||||
});
|
||||
assert.equal(out.say, say, stage);
|
||||
assertSpeakable(out.say);
|
||||
assert.deepEqual(out.display.lines, ['detail']);
|
||||
}
|
||||
const armed = envelope('show_street_level', {
|
||||
ok: true,
|
||||
armed: true,
|
||||
providerName: 'Google Street View',
|
||||
label: '10th St, Sacramento',
|
||||
});
|
||||
assert.equal(armed.say, 'Google Street View is ready at 10th St, Sacramento: press OPEN to load it.');
|
||||
assertSpeakable(armed.say);
|
||||
assert.deepEqual(armed.display.lines, ['10th St, Sacramento', 'Press OPEN to load the photo']);
|
||||
const unfound = envelope('show_street_level', {
|
||||
ok: false,
|
||||
stage: 'location',
|
||||
location: { ok: false, action: 'fly_to_location', label: 'Nowhere Town' },
|
||||
});
|
||||
assert.equal(unfound.say, "Couldn't find Nowhere Town.");
|
||||
assert.equal(unfound.display.title, 'Street Level');
|
||||
const refused = envelope('show_street_level', {
|
||||
ok: false,
|
||||
stage: 'key',
|
||||
keyRejected: true,
|
||||
providerName: 'Google Street View',
|
||||
});
|
||||
assert.equal(refused.say, 'Google Street View refused its key.');
|
||||
assert.equal(
|
||||
envelope('show_street_level', { ok: false, cancelled: true }).say,
|
||||
undefined,
|
||||
);
|
||||
assert.equal(
|
||||
planStepLabel('show_street_level', {
|
||||
query: 'Eiffel Tower',
|
||||
provider: 'google',
|
||||
}),
|
||||
'Street View at Eiffel Tower',
|
||||
);
|
||||
assert.equal(
|
||||
planStepLabel('show_street_level', {
|
||||
query: 'Times Square',
|
||||
provider: 'mapillary',
|
||||
}),
|
||||
'Mapillary at Times Square',
|
||||
);
|
||||
assert.equal(
|
||||
progressStepLabel('imagery', 'Eiffel Tower'),
|
||||
'Opening imagery: Eiffel Tower',
|
||||
);
|
||||
assert.equal(progressLine('map', 'photoreal'), 'Switching to Google 3D.');
|
||||
assert.equal(
|
||||
progressLine('imagery', 'Eiffel Tower'),
|
||||
'Looking for imagery at Eiffel Tower.',
|
||||
);
|
||||
});
|
||||
|
||||
test('the capture month is a UTC month whatever the timezone, and labels name the place', async () => {
|
||||
const { execFileSync } = await import('node:child_process');
|
||||
const speech = new URL('./speech.js', import.meta.url).href;
|
||||
// Google dates a panorama 2024-05 as the first of the month, UTC. West of
|
||||
// Greenwich that instant is still April; the card must still say May.
|
||||
const out = execFileSync(
|
||||
process.execPath,
|
||||
[
|
||||
'--input-type=module',
|
||||
'-e',
|
||||
`import { attachVoiceResult } from ${JSON.stringify(speech)};
|
||||
const r = attachVoiceResult('show_street_level', { ok: true, providerName: 'Google Street View', label: 'x', capturedAt: Date.UTC(2024, 4, 1) });
|
||||
process.stdout.write(r.display.lines[1]);`,
|
||||
],
|
||||
{ env: { ...process.env, TZ: 'America/Los_Angeles' }, encoding: 'utf8' },
|
||||
);
|
||||
assert.equal(out, 'Captured May 2024');
|
||||
const { narrationLabel } = await import('./speech.js');
|
||||
assert.equal(narrationLabel('show_street_level', { query: 'Eiffel Tower' }), 'Eiffel Tower');
|
||||
assert.equal(narrationLabel('show_street_level', {}), '');
|
||||
assert.equal(
|
||||
planStepLabel('show_street_level', { latitude: 1, longitude: 2 }),
|
||||
'Street level at this spot',
|
||||
);
|
||||
assert.equal(planStepLabel('show_street_level', {}), 'Street level at the view centre');
|
||||
});
|
||||
|
||||
test('the plan step names KartaView as a source', () => {
|
||||
assert.equal(
|
||||
planStepLabel('show_street_level', {
|
||||
query: 'Alexanderplatz',
|
||||
provider: 'kartaview',
|
||||
}),
|
||||
'KartaView at Alexanderplatz',
|
||||
);
|
||||
});
|
||||
|
||||
test('an empty street-level search names the imagery filter that hid the photos', () => {
|
||||
const out = envelope('show_street_level', {
|
||||
ok: false,
|
||||
stage: 'imagery',
|
||||
label: 'Alexanderplatz',
|
||||
providerName: 'KartaView',
|
||||
filter: { pano: 'pano', label: '360° filter' },
|
||||
});
|
||||
assert.equal(
|
||||
out.say,
|
||||
'No KartaView imagery near Alexanderplatz with the 360° filter on.',
|
||||
);
|
||||
assertSpeakable(out.say);
|
||||
});
|
||||
|
||||
test('the plan step names Panoramax as a source', () => {
|
||||
assert.equal(
|
||||
planStepLabel('show_street_level', {
|
||||
query: 'Montmartre',
|
||||
provider: 'panoramax',
|
||||
}),
|
||||
'Panoramax at Montmartre',
|
||||
);
|
||||
});
|
||||
|
||||
test('progress step labels join through the catalog colon', () => {
|
||||
setLocale('fr');
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user