@fieldia/map 0.14.1 → 0.16.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 +103 -10
- package/package.json +5 -4
- package/src/index.d.mts +5 -1
- package/src/index.d.ts +5 -1
- package/src/index.js +7 -1
- package/src/index.js.map +1 -1
- package/src/index.mjs +3 -0
- package/src/index.mjs.map +1 -1
- package/src/lib/answers.d.mts +17 -0
- package/src/lib/answers.d.ts +17 -0
- package/src/lib/answers.js +27 -0
- package/src/lib/answers.js.map +1 -0
- package/src/lib/answers.mjs +21 -0
- package/src/lib/answers.mjs.map +1 -0
- package/src/lib/area.js +29 -246
- package/src/lib/area.js.map +1 -1
- package/src/lib/area.mjs +29 -246
- package/src/lib/area.mjs.map +1 -1
- package/src/lib/card.d.mts +53 -0
- package/src/lib/card.d.ts +53 -0
- package/src/lib/card.js +98 -0
- package/src/lib/card.js.map +1 -0
- package/src/lib/card.mjs +94 -0
- package/src/lib/card.mjs.map +1 -0
- package/src/lib/cluster.d.mts +12 -0
- package/src/lib/cluster.d.ts +12 -0
- package/src/lib/cluster.js +60 -0
- package/src/lib/cluster.js.map +1 -0
- package/src/lib/cluster.mjs +57 -0
- package/src/lib/cluster.mjs.map +1 -0
- package/src/lib/drawing.d.mts +36 -0
- package/src/lib/drawing.d.ts +36 -0
- package/src/lib/drawing.js +267 -0
- package/src/lib/drawing.js.map +1 -0
- package/src/lib/drawing.mjs +263 -0
- package/src/lib/drawing.mjs.map +1 -0
- package/src/lib/form-map.d.mts +16 -0
- package/src/lib/form-map.d.ts +16 -0
- package/src/lib/form-map.js +525 -0
- package/src/lib/form-map.js.map +1 -0
- package/src/lib/form-map.mjs +522 -0
- package/src/lib/form-map.mjs.map +1 -0
- package/src/lib/kinds.js +9 -2
- package/src/lib/kinds.js.map +1 -1
- package/src/lib/kinds.mjs +9 -2
- package/src/lib/kinds.mjs.map +1 -1
- package/src/lib/labels.d.mts +41 -0
- package/src/lib/labels.d.ts +41 -0
- package/src/lib/labels.js +87 -1
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +84 -0
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/list-view.d.mts +13 -0
- package/src/lib/list-view.d.ts +13 -0
- package/src/lib/list-view.js +464 -0
- package/src/lib/list-view.js.map +1 -0
- package/src/lib/list-view.mjs +461 -0
- package/src/lib/list-view.mjs.map +1 -0
- package/src/lib/map-core.d.mts +2 -2
- package/src/lib/map-core.d.ts +2 -2
- package/src/lib/map-core.js +23 -3
- package/src/lib/map-core.js.map +1 -1
- package/src/lib/map-core.mjs +23 -3
- package/src/lib/map-core.mjs.map +1 -1
- package/src/lib/map-icons.d.mts +8 -0
- package/src/lib/map-icons.d.ts +8 -0
- package/src/lib/map-icons.js +21 -0
- package/src/lib/map-icons.js.map +1 -0
- package/src/lib/map-icons.mjs +18 -0
- package/src/lib/map-icons.mjs.map +1 -0
- package/src/lib/marks.d.mts +34 -0
- package/src/lib/marks.d.ts +34 -0
- package/src/lib/marks.js +56 -0
- package/src/lib/marks.js.map +1 -0
- package/src/lib/marks.mjs +49 -0
- package/src/lib/marks.mjs.map +1 -0
- package/src/lib/pins.d.mts +58 -0
- package/src/lib/pins.d.ts +58 -0
- package/src/lib/pins.js +165 -0
- package/src/lib/pins.js.map +1 -0
- package/src/lib/pins.mjs +156 -0
- package/src/lib/pins.mjs.map +1 -0
- package/src/lib/providers.d.mts +27 -3
- package/src/lib/providers.d.ts +27 -3
- package/src/lib/providers.js +69 -67
- package/src/lib/providers.js.map +1 -1
- package/src/lib/providers.mjs +17 -15
- package/src/lib/providers.mjs.map +1 -1
- package/src/lib/route-line.d.mts +34 -0
- package/src/lib/route-line.d.ts +34 -0
- package/src/lib/route-line.js +53 -0
- package/src/lib/route-line.js.map +1 -0
- package/src/lib/route-line.mjs +47 -0
- package/src/lib/route-line.mjs.map +1 -0
- package/src/lib/routes.d.mts +28 -0
- package/src/lib/routes.d.ts +28 -0
- package/src/lib/routes.js +112 -0
- package/src/lib/routes.js.map +1 -0
- package/src/lib/routes.mjs +105 -0
- package/src/lib/routes.mjs.map +1 -0
- package/src/lib/settings.d.mts +8 -3
- package/src/lib/settings.d.ts +8 -3
- package/src/lib/styles.d.mts +16 -0
- package/src/lib/styles.d.ts +16 -0
- package/src/lib/styles.js +181 -1
- package/src/lib/styles.js.map +1 -1
- package/src/lib/styles.mjs +178 -0
- package/src/lib/styles.mjs.map +1 -1
package/src/lib/card.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.drawCard = drawCard;
|
|
4
|
+
exports.drawCrowd = drawCrowd;
|
|
5
|
+
const labels_1 = require("./labels");
|
|
6
|
+
const pins_1 = require("./pins");
|
|
7
|
+
function make(doc, tag, className, ...children) {
|
|
8
|
+
const element = doc.createElement(tag);
|
|
9
|
+
element.className = className;
|
|
10
|
+
element.append(...children);
|
|
11
|
+
return element;
|
|
12
|
+
}
|
|
13
|
+
function closeButton(doc, labels, close) {
|
|
14
|
+
const button = make(doc, 'button', 'fd-map-card-close', '×');
|
|
15
|
+
button.type = 'button';
|
|
16
|
+
button.setAttribute('aria-label', labels.closeCard);
|
|
17
|
+
button.title = labels.closeCard;
|
|
18
|
+
button.addEventListener('click', close);
|
|
19
|
+
return button;
|
|
20
|
+
}
|
|
21
|
+
function drawCard(options) {
|
|
22
|
+
const { document: doc, page, locale, labels, record } = options;
|
|
23
|
+
const title = (0, pins_1.shown)(page, options.title, record.values, locale) || String(record.id);
|
|
24
|
+
const element = make(doc, 'div', 'fd-map-card');
|
|
25
|
+
element.dir = options.dir;
|
|
26
|
+
element.setAttribute('role', 'group');
|
|
27
|
+
element.setAttribute('aria-label', title);
|
|
28
|
+
element.dataset['id'] = String(record.id);
|
|
29
|
+
const picture = options.card.image ? (0, pins_1.imageSource)(record.values[options.card.image]) : '';
|
|
30
|
+
if (picture) {
|
|
31
|
+
const img = make(doc, 'img', 'fd-map-card-image');
|
|
32
|
+
img.alt = '';
|
|
33
|
+
img.decoding = 'async';
|
|
34
|
+
img.src = picture;
|
|
35
|
+
element.append(img);
|
|
36
|
+
}
|
|
37
|
+
const body = make(doc, 'div', 'fd-map-card-body');
|
|
38
|
+
const close = closeButton(doc, labels, options.close);
|
|
39
|
+
body.append(make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', title), close));
|
|
40
|
+
const lines = options.fields
|
|
41
|
+
.map((name) => [page.fields[name]?.label ?? name, (0, pins_1.shown)(page, name, record.values, locale)])
|
|
42
|
+
.filter(([, value]) => value !== '');
|
|
43
|
+
if (lines.length)
|
|
44
|
+
body.append(make(doc, 'dl', 'fd-map-card-fields', ...lines.map(([label, value]) => make(doc, 'div', '', make(doc, 'dt', '', label), make(doc, 'dd', '', value)))));
|
|
45
|
+
const box = make(doc, 'input', 'fd-map-card-check');
|
|
46
|
+
box.type = 'checkbox';
|
|
47
|
+
box.checked = !!options.chosen;
|
|
48
|
+
box.addEventListener('change', () => options.choose?.(box.checked));
|
|
49
|
+
const actions = make(doc, 'div', 'fd-map-card-actions', ...(options.choose ? [make(doc, 'label', 'fd-map-card-choose', box, labels.choose)] : []));
|
|
50
|
+
let first = close;
|
|
51
|
+
for (const action of options.actions ?? []) {
|
|
52
|
+
const button = make(doc, 'button', `fd-button fd-button-${action.style ?? 'secondary'} fd-map-card-act`, action.label);
|
|
53
|
+
button.type = 'button';
|
|
54
|
+
button.dataset['action'] = action.id;
|
|
55
|
+
button.addEventListener('click', () => options.act?.(action.id, button));
|
|
56
|
+
actions.append(button);
|
|
57
|
+
first = button;
|
|
58
|
+
}
|
|
59
|
+
if (options.open && options.card.open !== false) {
|
|
60
|
+
const open = make(doc, 'button', 'fd-button fd-button-primary fd-map-card-open', labels.openRecord);
|
|
61
|
+
open.type = 'button';
|
|
62
|
+
open.addEventListener('click', () => options.open?.());
|
|
63
|
+
actions.append(open);
|
|
64
|
+
first = open;
|
|
65
|
+
}
|
|
66
|
+
if (actions.childElementCount)
|
|
67
|
+
body.append(actions);
|
|
68
|
+
element.append(body);
|
|
69
|
+
return {
|
|
70
|
+
element,
|
|
71
|
+
setChosen: (on) => (box.checked = on),
|
|
72
|
+
focus: () => first.focus(),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Pins on one spot that no zoom parts: a list of them, each opening its own card. */
|
|
76
|
+
function drawCrowd(options) {
|
|
77
|
+
const { document: doc, labels } = options;
|
|
78
|
+
const heading = (0, labels_1.fill)(labels.crowd, { n: options.records.length });
|
|
79
|
+
const element = make(doc, 'div', 'fd-map-card fd-map-crowd');
|
|
80
|
+
element.dir = options.dir;
|
|
81
|
+
element.setAttribute('role', 'group');
|
|
82
|
+
element.setAttribute('aria-label', heading);
|
|
83
|
+
const close = closeButton(doc, labels, options.close);
|
|
84
|
+
const items = options.records.map(({ record, name }) => {
|
|
85
|
+
const button = make(doc, 'button', 'fd-map-crowd-item', name);
|
|
86
|
+
button.type = 'button';
|
|
87
|
+
button.dataset['id'] = String(record.id);
|
|
88
|
+
button.addEventListener('click', () => options.pick(record));
|
|
89
|
+
return make(doc, 'li', '', button);
|
|
90
|
+
});
|
|
91
|
+
element.append(make(doc, 'div', 'fd-map-card-body', make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', heading), close), make(doc, 'ul', 'fd-map-crowd-list', ...items)));
|
|
92
|
+
return {
|
|
93
|
+
element,
|
|
94
|
+
setChosen: () => undefined,
|
|
95
|
+
focus: () => (items[0]?.querySelector('button') ?? close).focus(),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}
|
package/src/lib/card.mjs
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { fill } from './labels.mjs';
|
|
2
|
+
import { imageSource, shown } from './pins.mjs';
|
|
3
|
+
function make(doc, tag, className, ...children) {
|
|
4
|
+
const element = doc.createElement(tag);
|
|
5
|
+
element.className = className;
|
|
6
|
+
element.append(...children);
|
|
7
|
+
return element;
|
|
8
|
+
}
|
|
9
|
+
function closeButton(doc, labels, close) {
|
|
10
|
+
const button = make(doc, 'button', 'fd-map-card-close', '×');
|
|
11
|
+
button.type = 'button';
|
|
12
|
+
button.setAttribute('aria-label', labels.closeCard);
|
|
13
|
+
button.title = labels.closeCard;
|
|
14
|
+
button.addEventListener('click', close);
|
|
15
|
+
return button;
|
|
16
|
+
}
|
|
17
|
+
export function drawCard(options) {
|
|
18
|
+
const { document: doc, page, locale, labels, record } = options;
|
|
19
|
+
const title = shown(page, options.title, record.values, locale) || String(record.id);
|
|
20
|
+
const element = make(doc, 'div', 'fd-map-card');
|
|
21
|
+
element.dir = options.dir;
|
|
22
|
+
element.setAttribute('role', 'group');
|
|
23
|
+
element.setAttribute('aria-label', title);
|
|
24
|
+
element.dataset['id'] = String(record.id);
|
|
25
|
+
const picture = options.card.image ? imageSource(record.values[options.card.image]) : '';
|
|
26
|
+
if (picture) {
|
|
27
|
+
const img = make(doc, 'img', 'fd-map-card-image');
|
|
28
|
+
img.alt = '';
|
|
29
|
+
img.decoding = 'async';
|
|
30
|
+
img.src = picture;
|
|
31
|
+
element.append(img);
|
|
32
|
+
}
|
|
33
|
+
const body = make(doc, 'div', 'fd-map-card-body');
|
|
34
|
+
const close = closeButton(doc, labels, options.close);
|
|
35
|
+
body.append(make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', title), close));
|
|
36
|
+
const lines = options.fields
|
|
37
|
+
.map((name) => [page.fields[name]?.label ?? name, shown(page, name, record.values, locale)])
|
|
38
|
+
.filter(([, value]) => value !== '');
|
|
39
|
+
if (lines.length)
|
|
40
|
+
body.append(make(doc, 'dl', 'fd-map-card-fields', ...lines.map(([label, value]) => make(doc, 'div', '', make(doc, 'dt', '', label), make(doc, 'dd', '', value)))));
|
|
41
|
+
const box = make(doc, 'input', 'fd-map-card-check');
|
|
42
|
+
box.type = 'checkbox';
|
|
43
|
+
box.checked = !!options.chosen;
|
|
44
|
+
box.addEventListener('change', () => options.choose?.(box.checked));
|
|
45
|
+
const actions = make(doc, 'div', 'fd-map-card-actions', ...(options.choose ? [make(doc, 'label', 'fd-map-card-choose', box, labels.choose)] : []));
|
|
46
|
+
let first = close;
|
|
47
|
+
for (const action of options.actions ?? []) {
|
|
48
|
+
const button = make(doc, 'button', `fd-button fd-button-${action.style ?? 'secondary'} fd-map-card-act`, action.label);
|
|
49
|
+
button.type = 'button';
|
|
50
|
+
button.dataset['action'] = action.id;
|
|
51
|
+
button.addEventListener('click', () => options.act?.(action.id, button));
|
|
52
|
+
actions.append(button);
|
|
53
|
+
first = button;
|
|
54
|
+
}
|
|
55
|
+
if (options.open && options.card.open !== false) {
|
|
56
|
+
const open = make(doc, 'button', 'fd-button fd-button-primary fd-map-card-open', labels.openRecord);
|
|
57
|
+
open.type = 'button';
|
|
58
|
+
open.addEventListener('click', () => options.open?.());
|
|
59
|
+
actions.append(open);
|
|
60
|
+
first = open;
|
|
61
|
+
}
|
|
62
|
+
if (actions.childElementCount)
|
|
63
|
+
body.append(actions);
|
|
64
|
+
element.append(body);
|
|
65
|
+
return {
|
|
66
|
+
element,
|
|
67
|
+
setChosen: (on) => (box.checked = on),
|
|
68
|
+
focus: () => first.focus(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Pins on one spot that no zoom parts: a list of them, each opening its own card. */
|
|
72
|
+
export function drawCrowd(options) {
|
|
73
|
+
const { document: doc, labels } = options;
|
|
74
|
+
const heading = fill(labels.crowd, { n: options.records.length });
|
|
75
|
+
const element = make(doc, 'div', 'fd-map-card fd-map-crowd');
|
|
76
|
+
element.dir = options.dir;
|
|
77
|
+
element.setAttribute('role', 'group');
|
|
78
|
+
element.setAttribute('aria-label', heading);
|
|
79
|
+
const close = closeButton(doc, labels, options.close);
|
|
80
|
+
const items = options.records.map(({ record, name }) => {
|
|
81
|
+
const button = make(doc, 'button', 'fd-map-crowd-item', name);
|
|
82
|
+
button.type = 'button';
|
|
83
|
+
button.dataset['id'] = String(record.id);
|
|
84
|
+
button.addEventListener('click', () => options.pick(record));
|
|
85
|
+
return make(doc, 'li', '', button);
|
|
86
|
+
});
|
|
87
|
+
element.append(make(doc, 'div', 'fd-map-card-body', make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', heading), close), make(doc, 'ul', 'fd-map-crowd-list', ...items)));
|
|
88
|
+
return {
|
|
89
|
+
element,
|
|
90
|
+
setChosen: () => undefined,
|
|
91
|
+
focus: () => (items[0]?.querySelector('button') ?? close).focus(),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins that crowd, gathered: each point in turn takes every point not yet
|
|
3
|
+
* gathered within `radius` pixels of it. A bubble stands in the middle of
|
|
4
|
+
* its points, so two bubbles' middles can fall near each other: those are
|
|
5
|
+
* gathered again, until no two lie nearer than `radius`. Points are looked
|
|
6
|
+
* up in a grid of `radius` squares, nine squares around each: thousands in a
|
|
7
|
+
* few milliseconds. Returns the groups as indexes into `points`, each in order.
|
|
8
|
+
*/
|
|
9
|
+
export declare function clusterPoints(points: readonly {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}[], radius: number): number[][];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins that crowd, gathered: each point in turn takes every point not yet
|
|
3
|
+
* gathered within `radius` pixels of it. A bubble stands in the middle of
|
|
4
|
+
* its points, so two bubbles' middles can fall near each other: those are
|
|
5
|
+
* gathered again, until no two lie nearer than `radius`. Points are looked
|
|
6
|
+
* up in a grid of `radius` squares, nine squares around each: thousands in a
|
|
7
|
+
* few milliseconds. Returns the groups as indexes into `points`, each in order.
|
|
8
|
+
*/
|
|
9
|
+
export declare function clusterPoints(points: readonly {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}[], radius: number): number[][];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clusterPoints = clusterPoints;
|
|
4
|
+
/**
|
|
5
|
+
* Pins that crowd, gathered: each point in turn takes every point not yet
|
|
6
|
+
* gathered within `radius` pixels of it. A bubble stands in the middle of
|
|
7
|
+
* its points, so two bubbles' middles can fall near each other: those are
|
|
8
|
+
* gathered again, until no two lie nearer than `radius`. Points are looked
|
|
9
|
+
* up in a grid of `radius` squares, nine squares around each: thousands in a
|
|
10
|
+
* few milliseconds. Returns the groups as indexes into `points`, each in order.
|
|
11
|
+
*/
|
|
12
|
+
function clusterPoints(points, radius) {
|
|
13
|
+
let groups = gather(points, radius);
|
|
14
|
+
for (;;) {
|
|
15
|
+
const middles = groups.map((group) => ({
|
|
16
|
+
x: group.reduce((sum, i) => sum + points[i].x, 0) / group.length,
|
|
17
|
+
y: group.reduce((sum, i) => sum + points[i].y, 0) / group.length,
|
|
18
|
+
}));
|
|
19
|
+
const merged = gather(middles, radius);
|
|
20
|
+
if (merged.length === groups.length)
|
|
21
|
+
return groups;
|
|
22
|
+
groups = merged.map((parts) => parts.flatMap((part) => groups[part]).sort((a, b) => a - b)).sort((a, b) => a[0] - b[0]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** One pass: each point in turn takes every point not yet taken within `radius` of it. */
|
|
26
|
+
function gather(points, radius) {
|
|
27
|
+
const cell = (n) => Math.floor(n / radius);
|
|
28
|
+
const grid = new Map();
|
|
29
|
+
points.forEach((p, i) => {
|
|
30
|
+
const key = `${cell(p.x)}:${cell(p.y)}`;
|
|
31
|
+
const list = grid.get(key);
|
|
32
|
+
if (list)
|
|
33
|
+
list.push(i);
|
|
34
|
+
else
|
|
35
|
+
grid.set(key, [i]);
|
|
36
|
+
});
|
|
37
|
+
const taken = new Uint8Array(points.length);
|
|
38
|
+
const groups = [];
|
|
39
|
+
points.forEach((p, i) => {
|
|
40
|
+
if (taken[i])
|
|
41
|
+
return;
|
|
42
|
+
taken[i] = 1;
|
|
43
|
+
const group = [i];
|
|
44
|
+
const cx = cell(p.x);
|
|
45
|
+
const cy = cell(p.y);
|
|
46
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
47
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
48
|
+
for (const j of grid.get(`${cx + dx}:${cy + dy}`) ?? []) {
|
|
49
|
+
if (taken[j] || Math.hypot(points[j].x - p.x, points[j].y - p.y) > radius)
|
|
50
|
+
continue;
|
|
51
|
+
taken[j] = 1;
|
|
52
|
+
group.push(j);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
groups.push(group.sort((a, b) => a - b));
|
|
57
|
+
});
|
|
58
|
+
return groups;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=cluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/cluster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins that crowd, gathered: each point in turn takes every point not yet
|
|
3
|
+
* gathered within `radius` pixels of it. A bubble stands in the middle of
|
|
4
|
+
* its points, so two bubbles' middles can fall near each other: those are
|
|
5
|
+
* gathered again, until no two lie nearer than `radius`. Points are looked
|
|
6
|
+
* up in a grid of `radius` squares, nine squares around each: thousands in a
|
|
7
|
+
* few milliseconds. Returns the groups as indexes into `points`, each in order.
|
|
8
|
+
*/
|
|
9
|
+
export function clusterPoints(points, radius) {
|
|
10
|
+
let groups = gather(points, radius);
|
|
11
|
+
for (;;) {
|
|
12
|
+
const middles = groups.map((group) => ({
|
|
13
|
+
x: group.reduce((sum, i) => sum + points[i].x, 0) / group.length,
|
|
14
|
+
y: group.reduce((sum, i) => sum + points[i].y, 0) / group.length,
|
|
15
|
+
}));
|
|
16
|
+
const merged = gather(middles, radius);
|
|
17
|
+
if (merged.length === groups.length)
|
|
18
|
+
return groups;
|
|
19
|
+
groups = merged.map((parts) => parts.flatMap((part) => groups[part]).sort((a, b) => a - b)).sort((a, b) => a[0] - b[0]);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** One pass: each point in turn takes every point not yet taken within `radius` of it. */
|
|
23
|
+
function gather(points, radius) {
|
|
24
|
+
const cell = (n) => Math.floor(n / radius);
|
|
25
|
+
const grid = new Map();
|
|
26
|
+
points.forEach((p, i) => {
|
|
27
|
+
const key = `${cell(p.x)}:${cell(p.y)}`;
|
|
28
|
+
const list = grid.get(key);
|
|
29
|
+
if (list)
|
|
30
|
+
list.push(i);
|
|
31
|
+
else
|
|
32
|
+
grid.set(key, [i]);
|
|
33
|
+
});
|
|
34
|
+
const taken = new Uint8Array(points.length);
|
|
35
|
+
const groups = [];
|
|
36
|
+
points.forEach((p, i) => {
|
|
37
|
+
if (taken[i])
|
|
38
|
+
return;
|
|
39
|
+
taken[i] = 1;
|
|
40
|
+
const group = [i];
|
|
41
|
+
const cx = cell(p.x);
|
|
42
|
+
const cy = cell(p.y);
|
|
43
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
44
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
45
|
+
for (const j of grid.get(`${cx + dx}:${cy + dy}`) ?? []) {
|
|
46
|
+
if (taken[j] || Math.hypot(points[j].x - p.x, points[j].y - p.y) > radius)
|
|
47
|
+
continue;
|
|
48
|
+
taken[j] = 1;
|
|
49
|
+
group.push(j);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
groups.push(group.sort((a, b) => a - b));
|
|
54
|
+
});
|
|
55
|
+
return groups;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=cluster.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/cluster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Area, type Shape } from './geo.mjs';
|
|
2
|
+
import { type MapLabels } from './labels.mjs';
|
|
3
|
+
import type { MapBox } from './map-core.mjs';
|
|
4
|
+
/**
|
|
5
|
+
* A shape drawn on a map: a polygon point by point, a box or a circle by a
|
|
6
|
+
* drag, by a mouse, a finger, a pen or the keys. A bar over the map says what
|
|
7
|
+
* to do, with Finish and Cancel. While a tool is in hand the ground holds
|
|
8
|
+
* still: a press is a point, never a pan. Shared by the area field and a
|
|
9
|
+
* list's map, which hand it what is drawn.
|
|
10
|
+
*/
|
|
11
|
+
/** Each tool's drawing, for its button. */
|
|
12
|
+
export declare const SHAPE_ICONS: Record<Shape, string>;
|
|
13
|
+
export interface ShapeDrawingOptions {
|
|
14
|
+
box: MapBox;
|
|
15
|
+
labels: MapLabels;
|
|
16
|
+
/** Where the drawing's keys are heard, wherever the focus is inside it: a field, or a list's map. */
|
|
17
|
+
keys: HTMLElement;
|
|
18
|
+
announce(words: string): void;
|
|
19
|
+
/** The tool in hand changed, or was put down. */
|
|
20
|
+
armed(mode: Shape | null): void;
|
|
21
|
+
/** A shape is drawn: the tool is put down first. */
|
|
22
|
+
done(area: Area): void;
|
|
23
|
+
/** Escape put the tool down: where the focus goes. */
|
|
24
|
+
escaped(): void;
|
|
25
|
+
/** Whether Enter on this part finishes a polygon, besides the map and Finish (the Polygon button). */
|
|
26
|
+
finishesOn?(target: EventTarget | null): boolean;
|
|
27
|
+
/** Parts over the map a press on is no point: the bar's own, the zoom, the credits, and the caller's. */
|
|
28
|
+
over?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ShapeDrawing {
|
|
31
|
+
/** The tool in hand, or none. */
|
|
32
|
+
readonly mode: Shape | null;
|
|
33
|
+
/** Take a tool, or put it down (null). */
|
|
34
|
+
arm(next: Shape | null): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function shapeDrawing(options: ShapeDrawingOptions): ShapeDrawing;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Area, type Shape } from './geo';
|
|
2
|
+
import { type MapLabels } from './labels';
|
|
3
|
+
import type { MapBox } from './map-core';
|
|
4
|
+
/**
|
|
5
|
+
* A shape drawn on a map: a polygon point by point, a box or a circle by a
|
|
6
|
+
* drag, by a mouse, a finger, a pen or the keys. A bar over the map says what
|
|
7
|
+
* to do, with Finish and Cancel. While a tool is in hand the ground holds
|
|
8
|
+
* still: a press is a point, never a pan. Shared by the area field and a
|
|
9
|
+
* list's map, which hand it what is drawn.
|
|
10
|
+
*/
|
|
11
|
+
/** Each tool's drawing, for its button. */
|
|
12
|
+
export declare const SHAPE_ICONS: Record<Shape, string>;
|
|
13
|
+
export interface ShapeDrawingOptions {
|
|
14
|
+
box: MapBox;
|
|
15
|
+
labels: MapLabels;
|
|
16
|
+
/** Where the drawing's keys are heard, wherever the focus is inside it: a field, or a list's map. */
|
|
17
|
+
keys: HTMLElement;
|
|
18
|
+
announce(words: string): void;
|
|
19
|
+
/** The tool in hand changed, or was put down. */
|
|
20
|
+
armed(mode: Shape | null): void;
|
|
21
|
+
/** A shape is drawn: the tool is put down first. */
|
|
22
|
+
done(area: Area): void;
|
|
23
|
+
/** Escape put the tool down: where the focus goes. */
|
|
24
|
+
escaped(): void;
|
|
25
|
+
/** Whether Enter on this part finishes a polygon, besides the map and Finish (the Polygon button). */
|
|
26
|
+
finishesOn?(target: EventTarget | null): boolean;
|
|
27
|
+
/** Parts over the map a press on is no point: the bar's own, the zoom, the credits, and the caller's. */
|
|
28
|
+
over?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ShapeDrawing {
|
|
31
|
+
/** The tool in hand, or none. */
|
|
32
|
+
readonly mode: Shape | null;
|
|
33
|
+
/** Take a tool, or put it down (null). */
|
|
34
|
+
arm(next: Shape | null): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function shapeDrawing(options: ShapeDrawingOptions): ShapeDrawing;
|