@fieldia/map 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/package.json +4 -4
- package/src/lib/area-count.d.mts +6 -4
- package/src/lib/area-count.d.ts +6 -4
- package/src/lib/area-count.js +8 -5
- package/src/lib/area-count.js.map +1 -1
- package/src/lib/area-count.mjs +8 -5
- package/src/lib/area-count.mjs.map +1 -1
- package/src/lib/card.d.mts +2 -0
- package/src/lib/card.d.ts +2 -0
- package/src/lib/card.js +1 -1
- package/src/lib/card.js.map +1 -1
- package/src/lib/card.mjs +1 -1
- package/src/lib/card.mjs.map +1 -1
- package/src/lib/cluster.d.mts +4 -2
- package/src/lib/cluster.d.ts +4 -2
- package/src/lib/cluster.js +6 -3
- package/src/lib/cluster.js.map +1 -1
- package/src/lib/cluster.mjs +6 -3
- package/src/lib/cluster.mjs.map +1 -1
- package/src/lib/labels.d.mts +2 -0
- package/src/lib/labels.d.ts +2 -0
- package/src/lib/labels.js +4 -0
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +4 -0
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/list-view.d.mts +3 -1
- package/src/lib/list-view.d.ts +3 -1
- package/src/lib/list-view.js +185 -43
- package/src/lib/list-view.js.map +1 -1
- package/src/lib/list-view.mjs +185 -43
- package/src/lib/list-view.mjs.map +1 -1
- package/src/lib/server-clusters.d.mts +66 -0
- package/src/lib/server-clusters.d.ts +66 -0
- package/src/lib/server-clusters.js +117 -0
- package/src/lib/server-clusters.js.map +1 -0
- package/src/lib/server-clusters.mjs +113 -0
- package/src/lib/server-clusters.mjs.map +1 -0
package/src/lib/labels.mjs
CHANGED
|
@@ -272,6 +272,7 @@ export const LIST_MAP_LABELS = {
|
|
|
272
272
|
cluster: '{n} here. Zoom in to see them.',
|
|
273
273
|
legendBubble: 'How many are close together: zoom in to part them',
|
|
274
274
|
crowd: '{n} in one place',
|
|
275
|
+
crowdMore: 'And {n} more here',
|
|
275
276
|
notOnMap: '{n} without a place, not on the map',
|
|
276
277
|
mapShowsFirst: 'The map shows {n} of {total}. Zoom in and search this area for the rest.',
|
|
277
278
|
mapFailed: 'The map could not load the records.',
|
|
@@ -294,6 +295,7 @@ export const LIST_MAP_LABELS = {
|
|
|
294
295
|
cluster: '{n} هنا. كبّر الخريطة لرؤيتها.',
|
|
295
296
|
legendBubble: 'كم منها متقارب: كبّر الخريطة لتفريقها',
|
|
296
297
|
crowd: '{n} في مكان واحد',
|
|
298
|
+
crowdMore: 'و{n} غيرها هنا',
|
|
297
299
|
notOnMap: '{n} بلا مكان، ليست على الخريطة',
|
|
298
300
|
mapShowsFirst: 'تعرض الخريطة {n} من {total}. كبّر الخريطة وابحث في هذه المنطقة لرؤية البقية.',
|
|
299
301
|
mapFailed: 'تعذّر تحميل السجلات على الخريطة.',
|
|
@@ -315,6 +317,7 @@ export const LIST_MAP_LABELS = {
|
|
|
315
317
|
cluster: '{n} ici. Zoomez pour les voir.',
|
|
316
318
|
legendBubble: 'Combien sont proches : zoomez pour les séparer',
|
|
317
319
|
crowd: '{n} au même endroit',
|
|
320
|
+
crowdMore: 'Et {n} de plus ici',
|
|
318
321
|
notOnMap: '{n} sans lieu, absents de la carte',
|
|
319
322
|
mapShowsFirst: 'La carte en montre {n} sur {total}. Zoomez et recherchez dans cette zone pour voir les autres.',
|
|
320
323
|
mapFailed: 'La carte n’a pas pu charger les enregistrements.',
|
|
@@ -337,6 +340,7 @@ export const LIST_MAP_LABELS = {
|
|
|
337
340
|
cluster: '{n} hier. Hineinzoomen, um sie zu sehen.',
|
|
338
341
|
legendBubble: 'Wie viele dicht beieinander liegen: hineinzoomen, um sie zu trennen',
|
|
339
342
|
crowd: '{n} an einem Ort',
|
|
343
|
+
crowdMore: 'Und {n} weitere hier',
|
|
340
344
|
notOnMap: '{n} ohne Ort, nicht auf der Karte',
|
|
341
345
|
mapShowsFirst: 'Die Karte zeigt {n} von {total}. Hineinzoomen und in diesem Gebiet suchen, um die übrigen zu sehen.',
|
|
342
346
|
mapFailed: 'Die Karte konnte die Datensätze nicht laden.',
|
package/src/lib/labels.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labels.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/labels.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"labels.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/labels.ts"],"names":[],"mappings":"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"}
|
package/src/lib/list-view.d.mts
CHANGED
|
@@ -9,7 +9,9 @@ import { type Box } from './view-box.mjs';
|
|
|
9
9
|
* and a row its pin; a pin opens a card with the record's picture, a few of
|
|
10
10
|
* its fields, a box to choose it and a button to open it. Pins that crowd
|
|
11
11
|
* become a bubble with their count. After the map is moved, "Search this
|
|
12
|
-
* area" puts the area into the search bar, as the person's own search.
|
|
12
|
+
* area" puts the area into the search bar, as the person's own search. A
|
|
13
|
+
* source that gathers them itself (`clusters`) is asked for the view's
|
|
14
|
+
* bubbles instead of loading the records: every record a search finds.
|
|
13
15
|
*
|
|
14
16
|
* mountViewer(host, { page, listViews: mapListViews({ provider }) })
|
|
15
17
|
*/
|
package/src/lib/list-view.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ import { type Box } from './view-box';
|
|
|
9
9
|
* and a row its pin; a pin opens a card with the record's picture, a few of
|
|
10
10
|
* its fields, a box to choose it and a button to open it. Pins that crowd
|
|
11
11
|
* become a bubble with their count. After the map is moved, "Search this
|
|
12
|
-
* area" puts the area into the search bar, as the person's own search.
|
|
12
|
+
* area" puts the area into the search bar, as the person's own search. A
|
|
13
|
+
* source that gathers them itself (`clusters`) is asked for the view's
|
|
14
|
+
* bubbles instead of loading the records: every record a search finds.
|
|
13
15
|
*
|
|
14
16
|
* mountViewer(host, { page, listViews: mapListViews({ provider }) })
|
|
15
17
|
*/
|
package/src/lib/list-view.js
CHANGED
|
@@ -19,7 +19,9 @@ const view_box_1 = require("./view-box");
|
|
|
19
19
|
* and a row its pin; a pin opens a card with the record's picture, a few of
|
|
20
20
|
* its fields, a box to choose it and a button to open it. Pins that crowd
|
|
21
21
|
* become a bubble with their count. After the map is moved, "Search this
|
|
22
|
-
* area" puts the area into the search bar, as the person's own search.
|
|
22
|
+
* area" puts the area into the search bar, as the person's own search. A
|
|
23
|
+
* source that gathers them itself (`clusters`) is asked for the view's
|
|
24
|
+
* bubbles instead of loading the records: every record a search finds.
|
|
23
25
|
*
|
|
24
26
|
* mountViewer(host, { page, listViews: mapListViews({ provider }) })
|
|
25
27
|
*/
|
|
@@ -32,6 +34,10 @@ const ROOM = 40;
|
|
|
32
34
|
const PINS_FROM = 15;
|
|
33
35
|
/** A place as an arrow points it out: "Nearest first". */
|
|
34
36
|
const NEAREST_ICON = '<path d="M3 11l18-8-8 18-2-8z"/>';
|
|
37
|
+
/** How long after the map stops its source is asked for the view's bubbles: a run of moves asks once. */
|
|
38
|
+
const ASK_AFTER = 250;
|
|
39
|
+
/** How near, in pixels, the source's bubbles may come: they count hundreds and thousands, drawn large (48, 58 with their ring). */
|
|
40
|
+
const GATHERED = 60;
|
|
35
41
|
function listMap(settings, context) {
|
|
36
42
|
const { page, node, document: doc, locale } = context;
|
|
37
43
|
// The viewer asks for a map only for a list with `map`.
|
|
@@ -205,13 +211,14 @@ function listMap(settings, context) {
|
|
|
205
211
|
return ['--fd-accent', '--fd-warning', '--fd-error'].map((name) => style?.getPropertyValue(name).trim() || '#2563eb');
|
|
206
212
|
},
|
|
207
213
|
}));
|
|
208
|
-
const points =
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return [];
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
const points = [
|
|
215
|
+
...records.flatMap((record, i) => {
|
|
216
|
+
const at = places[i];
|
|
217
|
+
return at ? [{ lat: at.lat, lng: at.lng, weight: heatSpec.weight ? Number(record.values[heatSpec.weight]) : 1 }] : [];
|
|
218
|
+
}),
|
|
219
|
+
// The source's bubbles, each weighing its records: their count, or its weight field added up.
|
|
220
|
+
...(served?.clusters ?? []).map((cluster) => ({ lat: cluster.lat, lng: cluster.lng, weight: heatSpec.weight ? Number(cluster.weight) : cluster.count })),
|
|
221
|
+
].filter((point) => Number.isFinite(point.weight) && point.weight > 0);
|
|
215
222
|
void heat.then((layer) => !destroyed && layer.draw(points, heatShown(map)));
|
|
216
223
|
}
|
|
217
224
|
let records = [];
|
|
@@ -234,6 +241,16 @@ function listMap(settings, context) {
|
|
|
234
241
|
/** The search changed by the map's own "Search this area": the view stays where the person put it. */
|
|
235
242
|
let ownSearch = false;
|
|
236
243
|
let moving = false;
|
|
244
|
+
// ---- records gathered by the source: its bubbles for each view, their code with the first map whose source gathers ----
|
|
245
|
+
/** Whether the source is asked for the view's bubbles: it gathers (`clusters`), and the page gathers crowded pins. */
|
|
246
|
+
const gathers = spec.cluster !== false && !context.given && typeof context.dataSource?.clusters === 'function';
|
|
247
|
+
let gatherer = null;
|
|
248
|
+
/** The same, once its code has come. */
|
|
249
|
+
let made = null;
|
|
250
|
+
/** The source's answer for the view, while it gathers this search's records: its bubbles, and `records` those standing alone. */
|
|
251
|
+
let served = null;
|
|
252
|
+
/** The search the source gathers none for (it answered false): its records loaded and gathered here, as without `clusters`. */
|
|
253
|
+
let gatheredHere = null;
|
|
237
254
|
const dir = () => (doc.defaultView?.getComputedStyle(element).direction === 'rtl' ? 'rtl' : 'ltr');
|
|
238
255
|
const placeOf = (values) => {
|
|
239
256
|
if (spec.point)
|
|
@@ -285,7 +302,9 @@ function listMap(settings, context) {
|
|
|
285
302
|
? (filter, signal) => source.list({ model, fields: [], filter, sort: [], offset: 0, limit: 1, signal }).then((r) => r.total)
|
|
286
303
|
: null;
|
|
287
304
|
counter ??= Promise.resolve().then(() => require('./area-count')).then(({ areaCounter }) => areaCounter(spec, ask, (n) => !here.hidden && !destroyed && sayHere(n)));
|
|
288
|
-
|
|
305
|
+
// The source's bubbles for this very view say how many it holds, with no question of their own.
|
|
306
|
+
const inView = served?.bbox && JSON.stringify(served.bbox) === JSON.stringify(view) ? { inView: served.count } : {};
|
|
307
|
+
void counter.then((made) => !destroyed && !here.hidden && made.count(view, { filter: shownFilter, all: allShown, places, ...inView }));
|
|
289
308
|
}
|
|
290
309
|
/** Where the map stands, once it stops: said to the app, once for each new view. */
|
|
291
310
|
let lastView = '';
|
|
@@ -343,10 +362,15 @@ function listMap(settings, context) {
|
|
|
343
362
|
function closeCard(map, back) {
|
|
344
363
|
if (!open)
|
|
345
364
|
return;
|
|
346
|
-
const { popup, back: to } = open;
|
|
365
|
+
const { popup, back: to, id } = open;
|
|
347
366
|
open = null;
|
|
348
367
|
map.closePopup(popup);
|
|
349
|
-
if (back)
|
|
368
|
+
if (!back)
|
|
369
|
+
return;
|
|
370
|
+
// Its mark drawn again meanwhile, with the source's bubbles for a view the card panned to: the record's new one, or the map.
|
|
371
|
+
if (served && !to?.isConnected)
|
|
372
|
+
((id !== null && drawnOf.get(id)?.marker.getElement()) || box.element).focus();
|
|
373
|
+
else
|
|
350
374
|
to?.focus();
|
|
351
375
|
}
|
|
352
376
|
function showCard(map, L, at, height, card, id, back, keys) {
|
|
@@ -376,29 +400,48 @@ function listMap(settings, context) {
|
|
|
376
400
|
}
|
|
377
401
|
// ---- the pins -------------------------------------------------------------------
|
|
378
402
|
function draw(map, L) {
|
|
379
|
-
layer ??= L.layerGroup().addTo(map);
|
|
380
|
-
layer.clearLayers();
|
|
381
|
-
drawn = [];
|
|
382
|
-
drawnOf.clear();
|
|
403
|
+
const marks = (layer ??= L.layerGroup().addTo(map));
|
|
383
404
|
drawHeat(map, L);
|
|
384
405
|
drawNote(map);
|
|
385
406
|
// From afar, the heat map in place of the pins.
|
|
386
407
|
if (heatShown(map)) {
|
|
408
|
+
marks.clearLayers();
|
|
409
|
+
drawn = [];
|
|
410
|
+
drawnOf.clear();
|
|
387
411
|
ghost?.remove();
|
|
388
412
|
ghost = null;
|
|
389
413
|
return;
|
|
390
414
|
}
|
|
391
415
|
const placed = records.flatMap((record, i) => (places[i] ? [{ record, at: places[i] }] : []));
|
|
416
|
+
// The source's bubbles, gathered again here with the records standing alone where they come too close.
|
|
417
|
+
const theirs = served?.clusters ?? [];
|
|
392
418
|
const zoom = map.getZoom();
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
419
|
+
const spots = [
|
|
420
|
+
...placed.map(({ at }) => map.project([at.lat, at.lng], zoom)),
|
|
421
|
+
...theirs.map((cluster) => ({ ...map.project([cluster.lat, cluster.lng], zoom), weighs: cluster.count })),
|
|
422
|
+
];
|
|
423
|
+
const groups = spec.cluster === false ? spots.map((_, i) => [i]) : (0, cluster_1.clusterPoints)(spots, served ? GATHERED : marks_1.CROWD);
|
|
424
|
+
// A mark the keys were on, drawn again with the source's next answer: the keys stay on its record.
|
|
425
|
+
const kept = served ? drawn.find((entry) => entry.marker.getElement()?.contains(doc.activeElement))?.ids[0] : undefined;
|
|
426
|
+
marks.clearLayers();
|
|
427
|
+
drawn = [];
|
|
428
|
+
drawnOf.clear();
|
|
396
429
|
for (const group of groups) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
430
|
+
const mine = group.filter((i) => i < placed.length).map((i) => placed[i]);
|
|
431
|
+
const gathered = group.filter((i) => i >= placed.length).map((i) => theirs[i - placed.length]);
|
|
432
|
+
// The record whose card is open keeps its own pin while it is read, the source's next bubbles beside it.
|
|
433
|
+
const reading = served && open && mine.length + gathered.length > 1 ? mine.findIndex((p) => p.record.id === open?.id) : -1;
|
|
434
|
+
if (reading >= 0) {
|
|
435
|
+
const [own] = mine.splice(reading, 1);
|
|
436
|
+
single(map, L, own.record, own.at);
|
|
437
|
+
}
|
|
438
|
+
if (mine.length === 1 && !gathered.length)
|
|
439
|
+
single(map, L, mine[0].record, mine[0].at);
|
|
440
|
+
else if (mine.length || gathered.length)
|
|
441
|
+
bubble(map, L, mine, gathered);
|
|
401
442
|
}
|
|
443
|
+
if (kept !== undefined)
|
|
444
|
+
drawnOf.get(kept)?.marker.getElement()?.focus({ preventScroll: true });
|
|
402
445
|
restyle();
|
|
403
446
|
light(map, L);
|
|
404
447
|
}
|
|
@@ -430,51 +473,73 @@ function listMap(settings, context) {
|
|
|
430
473
|
element?.addEventListener('focus', () => context.highlight(record.id));
|
|
431
474
|
element?.addEventListener('blur', () => context.highlight(null));
|
|
432
475
|
}
|
|
433
|
-
|
|
434
|
-
|
|
476
|
+
/** A bubble: records close together — those on hand, and those of the source's bubbles (`gathered`), counted where they stand. */
|
|
477
|
+
function bubble(map, L, members, gathered = []) {
|
|
478
|
+
const n = members.length + gathered.reduce((sum, cluster) => sum + cluster.count, 0);
|
|
435
479
|
const face = (0, marks_1.bubbleFace)(doc, n, locale);
|
|
436
|
-
|
|
480
|
+
// Their middle, a bubble of the source's weighing as many as it holds.
|
|
481
|
+
const middle = (of) => (members.reduce((sum, p) => sum + p.at[of], 0) + gathered.reduce((sum, cluster) => sum + cluster[of] * cluster.count, 0)) / n;
|
|
482
|
+
const centre = { lat: middle('lat'), lng: middle('lng') };
|
|
437
483
|
const icon = L.divIcon({ className: 'fd-map-mark fd-map-middle', html: face, iconSize: marks_1.SIZED_BY_FACE });
|
|
438
484
|
const marker = L.marker([centre.lat, centre.lng], { icon, keyboard: true, riseOnHover: true }).addTo(layer);
|
|
439
485
|
const element = mark({ marker, face, ids: members.map((p) => p.record.id) }, (0, labels_1.fill)(labels.cluster, { n: count(n) }));
|
|
486
|
+
// Where its records are: each on hand, and where the source's bubbles say theirs are (the chunk is in: they came through it).
|
|
487
|
+
const theirs = gathered.length ? made : null;
|
|
488
|
+
const spots = [...members.map((p) => p.at), ...(theirs?.corners(gathered) ?? [])];
|
|
440
489
|
(0, marks_1.onPress)(marker, (event) => {
|
|
441
490
|
const fromKeys = (0, marks_1.byKeys)(event);
|
|
442
491
|
// Closer, until they part (the person's own move); on one spot (a tower's flats), a list of them.
|
|
443
492
|
moving = true;
|
|
444
|
-
if ((0, marks_1.zoomToPart)(map, L,
|
|
493
|
+
if ((0, marks_1.zoomToPart)(map, L, spots, ROOM) || theirs?.closer(map, gathered, centre)) {
|
|
445
494
|
if (fromKeys)
|
|
446
495
|
box.element.focus();
|
|
447
496
|
return;
|
|
448
497
|
}
|
|
449
498
|
moving = false;
|
|
450
|
-
const crowd = (0, card_1.drawCrowd)({
|
|
499
|
+
const crowd = (listed, total) => showCard(map, L, centre, 20, (0, card_1.drawCrowd)({
|
|
451
500
|
document: doc,
|
|
452
501
|
labels,
|
|
453
502
|
dir: dir(),
|
|
454
|
-
|
|
503
|
+
count: total,
|
|
504
|
+
records: [
|
|
505
|
+
...listed.map((p) => ({ record: p.record, name: pins.name(p.record) })),
|
|
506
|
+
// More on the spot than a card lists: how many, said.
|
|
507
|
+
...(total > listed.length ? [{ record: { id: '', values: {} }, name: (0, labels_1.fill)(labels.crowdMore, { n: count(total - listed.length) }), plain: true }] : []),
|
|
508
|
+
],
|
|
455
509
|
pick: (record) => {
|
|
456
|
-
const at =
|
|
510
|
+
const at = listed.find((p) => p.record.id === record.id)?.at ?? centre;
|
|
457
511
|
openCard(map, L, record, at, 20, element ?? null, true);
|
|
458
512
|
},
|
|
459
513
|
close: () => closeCard(map, true),
|
|
460
|
-
});
|
|
461
|
-
|
|
514
|
+
}), null, element ?? null, fromKeys);
|
|
515
|
+
// The source's records on that spot, asked for: the first of them listed.
|
|
516
|
+
if (theirs)
|
|
517
|
+
theirs.crowd(shownFilter, spots, context.sort(), (found, total) => !destroyed && crowd(found, total));
|
|
518
|
+
else
|
|
519
|
+
crowd(members, members.length);
|
|
462
520
|
});
|
|
463
521
|
}
|
|
464
522
|
/** A lit record that is in a bubble shows where it is: its own pin, over the bubble. */
|
|
465
523
|
function light(map, L) {
|
|
466
524
|
ghost?.remove();
|
|
467
525
|
ghost = null;
|
|
468
|
-
const
|
|
469
|
-
|
|
526
|
+
const lit = hot;
|
|
527
|
+
const entry = lit === null ? undefined : drawnOf.get(lit);
|
|
528
|
+
if (entry?.ids.length === 1 || lit === null)
|
|
470
529
|
return;
|
|
471
|
-
const i = records.findIndex((record) => record.id ===
|
|
472
|
-
|
|
530
|
+
const i = records.findIndex((record) => record.id === lit);
|
|
531
|
+
if (entry)
|
|
532
|
+
return ghostOf(map, L, records[i], places[i]);
|
|
533
|
+
// In one of the source's bubbles: where it is, asked once.
|
|
534
|
+
if (served && made && !heatShown(map))
|
|
535
|
+
void made.place(lit).then((found) => found && hot === lit && !ghost && !destroyed && served && ghostOf(map, L, found.record, found.at));
|
|
536
|
+
}
|
|
537
|
+
function ghostOf(map, L, record, at) {
|
|
473
538
|
if (!at)
|
|
474
539
|
return;
|
|
475
|
-
const face = pins.face(
|
|
540
|
+
const face = pins.face(record);
|
|
476
541
|
face.element.toggleAttribute('data-hot', true);
|
|
477
|
-
face.element.toggleAttribute('data-chosen', context.isChosen(
|
|
542
|
+
face.element.toggleAttribute('data-chosen', context.isChosen(record.id));
|
|
478
543
|
const icon = L.divIcon({ className: `fd-map-mark fd-map-ghost ${(0, marks_1.anchor)(face)}`, html: face.element, iconSize: marks_1.SIZED_BY_FACE });
|
|
479
544
|
ghost = L.marker([at.lat, at.lng], { icon, interactive: false, keyboard: false, zIndexOffset: 2000 }).addTo(map);
|
|
480
545
|
ghost.getElement()?.setAttribute('aria-hidden', 'true');
|
|
@@ -496,8 +561,8 @@ function listMap(settings, context) {
|
|
|
496
561
|
note.textContent = words.join(' ');
|
|
497
562
|
note.hidden = !words.length;
|
|
498
563
|
}
|
|
499
|
-
|
|
500
|
-
|
|
564
|
+
/** The map moved to show the records — those on hand, or where the source's are (`at`). */
|
|
565
|
+
function fit(map, at = places.filter((p) => !!p)) {
|
|
501
566
|
if (!at.length)
|
|
502
567
|
return;
|
|
503
568
|
fitted = true;
|
|
@@ -534,6 +599,9 @@ function listMap(settings, context) {
|
|
|
534
599
|
if (!here.hidden)
|
|
535
600
|
countHere(map);
|
|
536
601
|
tellView(map, byPerson);
|
|
602
|
+
// The source's bubbles for where it stopped.
|
|
603
|
+
if (served && !fitting)
|
|
604
|
+
void askView(ASK_AFTER, false);
|
|
537
605
|
});
|
|
538
606
|
// An open card is what the person is reading: Search this area steps out of its way (on a phone the card
|
|
539
607
|
// fills the map's height, and the button sat over its picture) and is back when the card closes.
|
|
@@ -545,13 +613,84 @@ function listMap(settings, context) {
|
|
|
545
613
|
delete box.element.dataset['card'];
|
|
546
614
|
});
|
|
547
615
|
});
|
|
616
|
+
const mapFailed = () => {
|
|
617
|
+
note.textContent = (0, core_1.recordSentence)(page.records, labels.mapFailedNoun, labels.mapFailed, locale);
|
|
618
|
+
note.hidden = false;
|
|
619
|
+
};
|
|
620
|
+
/** The map moving itself to show a new search's records, as the source says where they are: no ask of its own as it stops. */
|
|
621
|
+
let fitting = false;
|
|
622
|
+
/**
|
|
623
|
+
* The source's bubbles for the search and the view, `wait` milliseconds from now, the last ask winning: for a
|
|
624
|
+
* search (`search`), its areas drawn and a card whose record it no longer finds closed, and first the map fitted to
|
|
625
|
+
* where its records are (`refit`). True once answered or replaced; false when the source gathers none for this search.
|
|
626
|
+
*/
|
|
627
|
+
function askView(wait, search, refit = false) {
|
|
628
|
+
gatherer ??= Promise.resolve().then(() => require('./server-clusters')).then(({ serverClusters }) => (made = serverClusters({ source: context.dataSource, model, spec, fields, radius: GATHERED, ...(heatSpec?.weight ? { weight: heatSpec.weight } : {}), placeOf })));
|
|
629
|
+
const filter = shownFilter;
|
|
630
|
+
let none = false;
|
|
631
|
+
return gatherer
|
|
632
|
+
.then((gathering) => new Promise((done) => box.ready((map, L) => {
|
|
633
|
+
if (destroyed)
|
|
634
|
+
return done();
|
|
635
|
+
const fitTo = (spots) => {
|
|
636
|
+
fitting = true;
|
|
637
|
+
fit(map, spots);
|
|
638
|
+
fitting = false;
|
|
639
|
+
here.hidden = true;
|
|
640
|
+
};
|
|
641
|
+
void gathering
|
|
642
|
+
.ask({ filter, map, wait, ...(refit ? { fit: fitTo } : {}) }, (answer) => (answer === false ? (none = true) : lay(answer, map, L, search)), () => !destroyed && mapFailed())
|
|
643
|
+
.then(done);
|
|
644
|
+
})))
|
|
645
|
+
.then(() => !none);
|
|
646
|
+
}
|
|
647
|
+
/** The source's answer for the view, drawn: its bubbles, the records standing alone, those it says have no place. */
|
|
648
|
+
function lay(answer, map, L, search) {
|
|
649
|
+
if (destroyed)
|
|
650
|
+
return;
|
|
651
|
+
served = answer;
|
|
652
|
+
records = answer.points;
|
|
653
|
+
places = records.map((record) => placeOf(record.values));
|
|
654
|
+
allShown = false;
|
|
655
|
+
noteWords = answer.unplaced ? [(0, labels_1.fill)(labels.notOnMap, { n: count(answer.unplaced) })] : [];
|
|
656
|
+
draw(map, L);
|
|
657
|
+
if (search)
|
|
658
|
+
drawSearched(map, L, shownFilter);
|
|
659
|
+
if (search && open?.id !== null && open && !records.some((r) => r.id === open?.id))
|
|
660
|
+
closeCard(map, false);
|
|
661
|
+
else
|
|
662
|
+
open?.card.setChosen(open.id !== null && context.isChosen(open.id));
|
|
663
|
+
if (!here.hidden)
|
|
664
|
+
countHere(map);
|
|
665
|
+
}
|
|
548
666
|
async function reload() {
|
|
549
667
|
const source = context.dataSource;
|
|
550
|
-
if (!source?.list)
|
|
668
|
+
if (!source?.list && !gathers)
|
|
551
669
|
return;
|
|
552
670
|
const asked = ++asking;
|
|
553
671
|
const filter = context.filter();
|
|
554
672
|
const key = JSON.stringify(filter);
|
|
673
|
+
if (gathers && gatheredHere !== key) {
|
|
674
|
+
// Gathered by the source: its bubbles for the view, the map first fitted to a new search's records.
|
|
675
|
+
const before = { lastFilter, ownSearch };
|
|
676
|
+
const refit = !fitted || (lastFilter !== null && key !== lastFilter && !ownSearch);
|
|
677
|
+
lastFilter = key;
|
|
678
|
+
ownSearch = false;
|
|
679
|
+
shownFilter = filter;
|
|
680
|
+
nearest?.setAttribute('aria-pressed', String(isNearest()));
|
|
681
|
+
void shadeRegions(filter, asked);
|
|
682
|
+
made?.forget();
|
|
683
|
+
if ((await askView(0, true, refit)) || asked !== asking || destroyed)
|
|
684
|
+
return;
|
|
685
|
+
// It gathers none for this search: its records loaded and gathered here, as without `clusters`.
|
|
686
|
+
gatheredHere = key;
|
|
687
|
+
({ lastFilter, ownSearch } = before);
|
|
688
|
+
}
|
|
689
|
+
if (!source?.list)
|
|
690
|
+
return;
|
|
691
|
+
// The records on hand from here on: no bubble of the source's drawn with them, none asked for.
|
|
692
|
+
served = null;
|
|
693
|
+
made?.stop();
|
|
555
694
|
let result;
|
|
556
695
|
try {
|
|
557
696
|
// The list's order, so the map shows the same first records: nearest first, when asked.
|
|
@@ -560,8 +699,7 @@ function listMap(settings, context) {
|
|
|
560
699
|
catch {
|
|
561
700
|
if (asked !== asking || destroyed)
|
|
562
701
|
return;
|
|
563
|
-
|
|
564
|
-
note.hidden = false;
|
|
702
|
+
mapFailed();
|
|
565
703
|
return;
|
|
566
704
|
}
|
|
567
705
|
if (asked !== asking || destroyed)
|
|
@@ -615,13 +753,17 @@ function listMap(settings, context) {
|
|
|
615
753
|
box.refresh();
|
|
616
754
|
box.ready((map) => {
|
|
617
755
|
map.invalidateSize({ pan: false });
|
|
618
|
-
|
|
756
|
+
// The source's records: asked again, to fit to where they are.
|
|
757
|
+
if (!fitted && served)
|
|
758
|
+
void reload();
|
|
759
|
+
else if (!fitted)
|
|
619
760
|
fit(map);
|
|
620
761
|
});
|
|
621
762
|
},
|
|
622
763
|
destroy() {
|
|
623
764
|
destroyed = true;
|
|
624
765
|
stopCount();
|
|
766
|
+
made?.stop();
|
|
625
767
|
void regions?.then((made) => made?.destroy());
|
|
626
768
|
void heat?.then((layer) => layer.destroy());
|
|
627
769
|
box.element.removeEventListener('pointerdown', pressed, { capture: true });
|