@motionstudies/core 0.1.0-alpha.23 → 0.1.0-alpha.24
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/air-continents.d.ts +63 -0
- package/air-continents.js +43 -0
- package/domain/air.d.ts +4 -0
- package/package.json +6 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Geographic continents from the airport reference; EU is not European Union membership. */
|
|
2
|
+
export declare const AIR_CONTINENTS: {
|
|
3
|
+
readonly AF: 'Africa';
|
|
4
|
+
readonly AN: 'Antarctica';
|
|
5
|
+
readonly AS: 'Asia';
|
|
6
|
+
readonly EU: 'Europe';
|
|
7
|
+
readonly NA: 'North America';
|
|
8
|
+
readonly OC: 'Oceania';
|
|
9
|
+
readonly SA: 'South America';
|
|
10
|
+
};
|
|
11
|
+
export type AirContinent = keyof typeof AIR_CONTINENTS;
|
|
12
|
+
export type AirContinentSource = 'ourairports' | 'override';
|
|
13
|
+
export type AirContinentStatus = 'known' | 'unknown-endpoint' | 'unknown-continent';
|
|
14
|
+
export interface AirContinentLabel {
|
|
15
|
+
readonly continent: AirContinent | null;
|
|
16
|
+
readonly status: AirContinentStatus;
|
|
17
|
+
}
|
|
18
|
+
export declare function isAirContinent(value: unknown): value is AirContinent;
|
|
19
|
+
/** Older releases and unobserved endpoints remain explicitly unknown. */
|
|
20
|
+
export declare function classifyAirEndpoint(endpoint?: {
|
|
21
|
+
readonly continent?: unknown;
|
|
22
|
+
} | null): AirContinentLabel;
|
|
23
|
+
/** Pass the canonical track index, never overlapping playback chunks. Counts are track segments, not flights. */
|
|
24
|
+
export declare function summarizeAirContinents(tracks: Iterable<{
|
|
25
|
+
readonly origin?: {
|
|
26
|
+
readonly continent?: unknown;
|
|
27
|
+
};
|
|
28
|
+
readonly destination?: {
|
|
29
|
+
readonly continent?: unknown;
|
|
30
|
+
};
|
|
31
|
+
}>): {
|
|
32
|
+
trackSegments: number;
|
|
33
|
+
origin: {
|
|
34
|
+
known: number;
|
|
35
|
+
unknownEndpoint: number;
|
|
36
|
+
unknownContinent: number;
|
|
37
|
+
continents: {
|
|
38
|
+
AF: number;
|
|
39
|
+
AN: number;
|
|
40
|
+
AS: number;
|
|
41
|
+
EU: number;
|
|
42
|
+
NA: number;
|
|
43
|
+
OC: number;
|
|
44
|
+
SA: number;
|
|
45
|
+
};
|
|
46
|
+
knownFraction: number | null;
|
|
47
|
+
};
|
|
48
|
+
destination: {
|
|
49
|
+
known: number;
|
|
50
|
+
unknownEndpoint: number;
|
|
51
|
+
unknownContinent: number;
|
|
52
|
+
continents: {
|
|
53
|
+
AF: number;
|
|
54
|
+
AN: number;
|
|
55
|
+
AS: number;
|
|
56
|
+
EU: number;
|
|
57
|
+
NA: number;
|
|
58
|
+
OC: number;
|
|
59
|
+
SA: number;
|
|
60
|
+
};
|
|
61
|
+
knownFraction: number | null;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Geographic continents from the airport reference; EU is not European Union membership. */
|
|
2
|
+
export const AIR_CONTINENTS = {
|
|
3
|
+
AF: 'Africa', AN: 'Antarctica', AS: 'Asia', EU: 'Europe',
|
|
4
|
+
NA: 'North America', OC: 'Oceania', SA: 'South America',
|
|
5
|
+
};
|
|
6
|
+
export function isAirContinent(value) {
|
|
7
|
+
return typeof value === 'string' && Object.hasOwn(AIR_CONTINENTS, value);
|
|
8
|
+
}
|
|
9
|
+
/** Older releases and unobserved endpoints remain explicitly unknown. */
|
|
10
|
+
export function classifyAirEndpoint(endpoint) {
|
|
11
|
+
if (!endpoint)
|
|
12
|
+
return { continent: null, status: 'unknown-endpoint' };
|
|
13
|
+
if (!isAirContinent(endpoint.continent))
|
|
14
|
+
return { continent: null, status: 'unknown-continent' };
|
|
15
|
+
return { continent: endpoint.continent, status: 'known' };
|
|
16
|
+
}
|
|
17
|
+
/** Pass the canonical track index, never overlapping playback chunks. Counts are track segments, not flights. */
|
|
18
|
+
export function summarizeAirContinents(tracks) {
|
|
19
|
+
const empty = () => ({
|
|
20
|
+
known: 0, unknownEndpoint: 0, unknownContinent: 0,
|
|
21
|
+
continents: { AF: 0, AN: 0, AS: 0, EU: 0, NA: 0, OC: 0, SA: 0 },
|
|
22
|
+
});
|
|
23
|
+
const counts = { origin: empty(), destination: empty() };
|
|
24
|
+
let trackSegments = 0;
|
|
25
|
+
for (const track of tracks) {
|
|
26
|
+
trackSegments++;
|
|
27
|
+
for (const side of ['origin', 'destination']) {
|
|
28
|
+
const label = classifyAirEndpoint(track[side]), count = counts[side];
|
|
29
|
+
if (label.continent) {
|
|
30
|
+
count.known++;
|
|
31
|
+
count.continents[label.continent]++;
|
|
32
|
+
}
|
|
33
|
+
else if (label.status === 'unknown-endpoint')
|
|
34
|
+
count.unknownEndpoint++;
|
|
35
|
+
else
|
|
36
|
+
count.unknownContinent++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const coverage = (side) => ({
|
|
40
|
+
...counts[side], knownFraction: trackSegments ? counts[side].known / trackSegments : null,
|
|
41
|
+
});
|
|
42
|
+
return { trackSegments, origin: coverage('origin'), destination: coverage('destination') };
|
|
43
|
+
}
|
package/domain/air.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AirContinent, AirContinentSource } from '../air-continents.ts';
|
|
1
2
|
export type AirSample = readonly [
|
|
2
3
|
time: number,
|
|
3
4
|
longitude: number,
|
|
@@ -13,6 +14,9 @@ export interface AirEndpoint {
|
|
|
13
14
|
/** Study-local seconds at the observed approach/departure boundary; not a scheduled time. */
|
|
14
15
|
readonly time: number;
|
|
15
16
|
readonly evidence: 'observed-endpoint';
|
|
17
|
+
/** Airport geography, separate from the inferred route evidence. Absent in older releases. */
|
|
18
|
+
readonly continent?: AirContinent;
|
|
19
|
+
readonly continentSource?: AirContinentSource;
|
|
16
20
|
}
|
|
17
21
|
export interface AirTrack {
|
|
18
22
|
readonly id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motionstudies/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.24",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Transport contracts and motion primitives for Motion Studies.",
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"tag": "next"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
|
+
"./air-continents": {
|
|
24
|
+
"types": "./air-continents.d.ts",
|
|
25
|
+
"import": "./air-continents.js",
|
|
26
|
+
"default": "./air-continents.js"
|
|
27
|
+
},
|
|
23
28
|
"./air-search": {
|
|
24
29
|
"types": "./air-search.d.ts",
|
|
25
30
|
"import": "./air-search.js",
|