@motionstudies/core 0.1.0-alpha.24 → 0.1.0-alpha.25

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.
@@ -0,0 +1,24 @@
1
+ /** Renderer-independent hierarchy shared by station and airport map labels. */
2
+ export interface MapLabelPriority {
3
+ readonly name: string;
4
+ readonly rank: number;
5
+ readonly priority: number;
6
+ readonly retained: boolean;
7
+ readonly distance: number;
8
+ }
9
+ export interface MapLabelBox {
10
+ readonly left: number;
11
+ readonly right: number;
12
+ readonly top: number;
13
+ readonly bottom: number;
14
+ }
15
+ export interface MapLabelCandidate extends MapLabelPriority {
16
+ readonly box: MapLabelBox;
17
+ }
18
+ export declare function compareMapLabelCandidates(first: MapLabelPriority, second: MapLabelPriority): number;
19
+ export declare function mapLabelBudget(cameraHeight: number): number;
20
+ export declare function mapLabelRankLimit(cameraHeight: number): number;
21
+ export declare function mapLabelBoxesOverlap(box: MapLabelBox, other: MapLabelBox, horizontalGap?: number, verticalGap?: number): boolean;
22
+ /** Candidate boxes include the edition's full hit area. Selected candidates must
23
+ * already have their higher priority; all labels respect viewport and obstacles. */
24
+ export declare function selectMapLabels<T extends MapLabelCandidate>(candidates: readonly T[], budget: number, viewport: MapLabelBox, obstacles?: readonly MapLabelBox[]): T[];
package/map-labels.js ADDED
@@ -0,0 +1,48 @@
1
+ export function compareMapLabelCandidates(first, second) {
2
+ return first.priority - second.priority || Number(second.retained) - Number(first.retained)
3
+ || first.rank - second.rank || first.distance - second.distance || first.name.localeCompare(second.name, 'de-CH');
4
+ }
5
+ export function mapLabelBudget(cameraHeight) {
6
+ if (cameraHeight >= 30)
7
+ return 8;
8
+ if (cameraHeight >= 22)
9
+ return 20;
10
+ if (cameraHeight >= 15)
11
+ return 48;
12
+ return 96;
13
+ }
14
+ export function mapLabelRankLimit(cameraHeight) {
15
+ if (cameraHeight >= 30)
16
+ return 8;
17
+ if (cameraHeight >= 22)
18
+ return 20;
19
+ if (cameraHeight >= 15)
20
+ return 48;
21
+ if (cameraHeight >= 14)
22
+ return 96;
23
+ return Number.POSITIVE_INFINITY;
24
+ }
25
+ export function mapLabelBoxesOverlap(box, other, horizontalGap = 5, verticalGap = 4) {
26
+ return box.left < other.right + horizontalGap && box.right > other.left - horizontalGap
27
+ && box.top < other.bottom + verticalGap && box.bottom > other.top - verticalGap;
28
+ }
29
+ /** Candidate boxes include the edition's full hit area. Selected candidates must
30
+ * already have their higher priority; all labels respect viewport and obstacles. */
31
+ export function selectMapLabels(candidates, budget, viewport, obstacles = []) {
32
+ const selected = [], occupied = [...obstacles];
33
+ const limit = Number.isFinite(budget) ? Math.max(0, Math.floor(budget)) : 0;
34
+ for (const candidate of [...candidates].sort(compareMapLabelCandidates)) {
35
+ if (selected.length >= limit)
36
+ break;
37
+ const box = candidate.box;
38
+ if (![box.left, box.right, box.top, box.bottom].every(Number.isFinite) || box.right <= box.left || box.bottom <= box.top)
39
+ continue;
40
+ if (box.left < viewport.left || box.right > viewport.right || box.top < viewport.top || box.bottom > viewport.bottom)
41
+ continue;
42
+ if (occupied.some(other => mapLabelBoxesOverlap(box, other)))
43
+ continue;
44
+ selected.push(candidate);
45
+ occupied.push(box);
46
+ }
47
+ return selected;
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motionstudies/core",
3
- "version": "0.1.0-alpha.24",
3
+ "version": "0.1.0-alpha.25",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Transport contracts and motion primitives for Motion Studies.",
@@ -224,6 +224,11 @@
224
224
  "types": "./render-frame.d.ts",
225
225
  "import": "./render-frame.js",
226
226
  "default": "./render-frame.js"
227
+ },
228
+ "./map-labels": {
229
+ "types": "./map-labels.d.ts",
230
+ "import": "./map-labels.js",
231
+ "default": "./map-labels.js"
227
232
  }
228
233
  },
229
234
  "files": [