@johnmorrisdotca/kyogijo-stadiums 0.27.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/CHANGELOG.md +23 -0
- package/NOTICE.md +13 -3
- package/README.md +65 -112
- package/dist/flythrough.dom.js +15 -5
- package/dist/flythrough.markup.d.ts +5 -0
- package/dist/flythrough.markup.js +1 -1
- package/dist/flythrough.path.d.ts +21 -8
- package/dist/flythrough.path.js +36 -11
- package/dist/flythrough.style.d.ts +1 -1
- package/dist/flythrough.style.js +2 -0
- package/dist/flythrough.words.d.ts +2 -2
- package/dist/flythrough.words.js +6 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/turn.dom.d.ts +8 -2
- package/dist/turn.dom.js +10 -4
- package/dist/venue.d.ts +2 -0
- package/dist/venue.js +3 -2
- package/dist/venue.real.d.ts +5 -2
- package/dist/venue.real.js +4 -4
- package/dist/venues-entry.d.ts +2 -2
- package/dist/venues-entry.js +1 -1
- package/dist/venues.d.ts +14 -3
- package/dist/venues.data.js +72 -0
- package/dist/venues.geo.d.ts +22 -0
- package/dist/venues.geo.js +28 -0
- package/dist/venues.js +9 -1
- package/dist/venues.osm.data.js +366 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/dist/flythrough.style.js
CHANGED
|
@@ -24,6 +24,8 @@ export const FLYTHROUGH_STYLE = `.kf{${LIGHT};color:var(--kf-ink);font:16px/1.45
|
|
|
24
24
|
.kf-3d .ky-turn{height:100%}
|
|
25
25
|
.kf-3d .ky-turn-view{aspect-ratio:auto;height:100%;min-height:0;border-radius:0;cursor:default;touch-action:auto}
|
|
26
26
|
.kf-3d .ky-turn-help,.kf-3d .ky-turn-live{display:none}
|
|
27
|
+
.kf-3d .ky-up-roof{filter:opacity(var(--kf-roof,1))}
|
|
28
|
+
.kf-3d[data-roof="0"] .ky-up-roof{visibility:hidden}
|
|
27
29
|
.kf-pin{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none}
|
|
28
30
|
.kf-pin::before{content:"";position:absolute;left:-7px;top:-7px;width:14px;height:14px;border-radius:50%;background:var(--kf-pin);border:2px solid var(--kf-bg);box-shadow:0 0 0 2px var(--kf-pin)}
|
|
29
31
|
.kf-scale{position:absolute;left:12px;bottom:12px;display:flex;flex-direction:column;gap:2px;align-items:flex-start;font-size:.8rem;color:var(--kf-ink);background:var(--kf-panel);padding:4px 8px;border-radius:8px;pointer-events:none}
|
|
@@ -8,7 +8,7 @@ export interface FlythroughWords {
|
|
|
8
8
|
region: string;
|
|
9
9
|
/** What a screen reader is told about the whole fly-through: `{arena}`, `{place}`. */
|
|
10
10
|
about: string;
|
|
11
|
-
/** The stages: their names and what is said of each (`{arena}`, `{place}`). */
|
|
11
|
+
/** The stages: their names and what is said of each (`{arena}`, `{place}`, `{seats}`, `{tiers}`). */
|
|
12
12
|
stage: Record<StageId, {
|
|
13
13
|
name: string;
|
|
14
14
|
text: string;
|
|
@@ -30,4 +30,4 @@ export interface FlythroughWords {
|
|
|
30
30
|
}
|
|
31
31
|
export declare const FLYTHROUGH_WORDS: Record<Language, FlythroughWords>;
|
|
32
32
|
/** A sentence with its `{name}` slots filled in. */
|
|
33
|
-
export declare const say: (text: string, values: Record<string, string | number>) => string;
|
|
33
|
+
export declare const say: (text: string, values: Record<string, string | number | undefined>) => string;
|
package/dist/flythrough.words.js
CHANGED
|
@@ -2,11 +2,13 @@ export const FLYTHROUGH_WORDS = {
|
|
|
2
2
|
en: {
|
|
3
3
|
title: "Fly-through: {arena}",
|
|
4
4
|
region: "fly-through",
|
|
5
|
-
about: "A fly-through from a map to {arena} in {place}: the map, the city
|
|
5
|
+
about: "A fly-through from a map to {arena} in {place}: the map, the city, the arena in 3D, the way in over the stands and the rink seen from a seat. Play, pause, step back or forward and choose a stage with the buttons or the keys.",
|
|
6
6
|
stage: {
|
|
7
7
|
map: { name: "Map", text: "{arena} stands in {place}." },
|
|
8
8
|
city: { name: "City", text: "The building of {arena} from above, as OpenStreetMap maps it." },
|
|
9
9
|
arena: { name: "Arena", text: "{arena} in 3D, turning." },
|
|
10
|
+
bowl: { name: "Bowl", text: "In over the stands, with the roof lifted away: a plausible bowl of {seats} seats in {tiers} tiers, not a seat map." },
|
|
11
|
+
rink: { name: "Rink", text: "A view across the ice from the stands, turning; the place and the height of the seat are ours, not a real seat's." },
|
|
10
12
|
},
|
|
11
13
|
announce: "Stage {n} of {total}: {name}. {text}",
|
|
12
14
|
play: "Play",
|
|
@@ -22,11 +24,13 @@ export const FLYTHROUGH_WORDS = {
|
|
|
22
24
|
ja: {
|
|
23
25
|
title: "フライスルー:{arena}",
|
|
24
26
|
region: "フライスルー",
|
|
25
|
-
about: "地図から{place}の{arena}まで進むフライスルーです。地図、都市、3D
|
|
27
|
+
about: "地図から{place}の{arena}まで進むフライスルーです。地図、都市、3Dのアリーナ、スタンドの上空から中へ入る場面、客席から見たリンクの順に見られます。ボタンまたはキーで、再生・一時停止、前後の場面への移動、場面の選択ができます。",
|
|
26
28
|
stage: {
|
|
27
29
|
map: { name: "地図", text: "{arena}は{place}にあります。" },
|
|
28
30
|
city: { name: "都市", text: "{arena}の建物を真上から見たところです(OpenStreetMapの記録による)。" },
|
|
29
31
|
arena: { name: "アリーナ", text: "{arena}を3Dで回転させて表示しています。" },
|
|
32
|
+
bowl: { name: "客席", text: "屋根を取り払い、スタンドの上空から中へ入ります。{seats}席・{tiers}層の推定のスタンドで、実際の座席表ではありません。" },
|
|
33
|
+
rink: { name: "リンク", text: "スタンドからリンクを見渡した眺めで、ゆっくり回転します。視点の位置と高さは仮のもので、実在の座席ではありません。" },
|
|
30
34
|
},
|
|
31
35
|
announce: "場面{n}/{total}:{name}。{text}",
|
|
32
36
|
play: "再生",
|
package/dist/index.d.ts
CHANGED
|
@@ -63,8 +63,8 @@ export { ERA_CURRENT, ERA_SOURCES, ERA_SPORTS, eraChanges, eraRange, eraStates,
|
|
|
63
63
|
export type { EraChange, EraRules, EraRulesOf, EraSource, EraSpan, EraSport, FootballRules, MlbRules, NbaRules, NhlRules } from "./eras.ts";
|
|
64
64
|
export { ARENA_IDS, ARENAS, arenaById, arenaByName, arenaByWikidata, arenaCourtIn, arenaNameIn, arenaOfficialName, arenaRinkIn, arenaSourceUrl, arenasByName } from "./arenas.ts";
|
|
65
65
|
export type { Arena, ArenaCapacity, ArenaData, ArenaName, ArenaSize, ArenaSource } from "./arenas.ts";
|
|
66
|
-
export { VENUE_ATTRIBUTION, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn } from "./venues.ts";
|
|
67
|
-
export type { RealVenue, RealVenueData, VenueBasis, VenueDivision, VenueOrientation, VenueOsm, VenuePlan, VenueRoof } from "./venues.ts";
|
|
66
|
+
export { VENUE_ATTRIBUTION, VENUE_CONFERENCES, VENUE_DIVISIONS, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, conferenceOf, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn, venuesInConference } from "./venues.ts";
|
|
67
|
+
export type { RealVenue, RealVenueData, VenueBasis, VenueConference, VenueDivision, VenueOrientation, VenueOsm, VenuePlan, VenueRoof } from "./venues.ts";
|
|
68
68
|
export { GROUND_IDS, GROUNDS, groundById, groundByName, groundByWikidata, groundNameIn, groundOfficialName, groundSourceUrl, groundsByName, groundsHosting } from "./grounds.ts";
|
|
69
69
|
export type { Ground, GroundCompetition, GroundData, GroundName, GroundSource, GroundTournament } from "./grounds.ts";
|
|
70
70
|
export { AFL_GROUNDS, FAMILY_OF, LEAGUES, LEAGUE_SOURCES, VARIANTS, chooseLeague, hasHistory, leagueAt, leagueById, leagueChanges, leagueFigures, leagueIds, leagueSeason, leagueSize } from "./leagues.ts";
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ export { PARKS, PARK_IDS, fenceFor, parkById, parkByName, parkByWikidata, parkNa
|
|
|
39
39
|
export { officialName, plainName } from "./names.js";
|
|
40
40
|
export { ERA_CURRENT, ERA_SOURCES, ERA_SPORTS, eraChanges, eraRange, eraStates, footballIn, rulesFor, seasonLabel } from "./eras.js";
|
|
41
41
|
export { ARENA_IDS, ARENAS, arenaById, arenaByName, arenaByWikidata, arenaCourtIn, arenaNameIn, arenaOfficialName, arenaRinkIn, arenaSourceUrl, arenasByName } from "./arenas.js";
|
|
42
|
-
export { VENUE_ATTRIBUTION, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn } from "./venues.js";
|
|
42
|
+
export { VENUE_ATTRIBUTION, VENUE_CONFERENCES, VENUE_DIVISIONS, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, conferenceOf, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn, venuesInConference } from "./venues.js";
|
|
43
43
|
export { GROUND_IDS, GROUNDS, groundById, groundByName, groundByWikidata, groundNameIn, groundOfficialName, groundSourceUrl, groundsByName, groundsHosting } from "./grounds.js";
|
|
44
44
|
export { AFL_GROUNDS, FAMILY_OF, LEAGUES, LEAGUE_SOURCES, VARIANTS, chooseLeague, hasHistory, leagueAt, leagueById, leagueChanges, leagueFigures, leagueIds, leagueSeason, leagueSize } from "./leagues.js";
|
|
45
45
|
export { SURFACE_UNITS, UNITS, convertLength, isUnit } from "./units.js";
|
package/dist/turn.dom.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type TurnPreset, type TurnView } from "./turn.camera.ts";
|
|
2
2
|
import { type TurnModel, type TurnSettings } from "./turn.model.ts";
|
|
3
3
|
import type { ScoreOptions, SurfaceOptions } from "./types.ts";
|
|
4
|
+
import type { VenueSettings } from "./venue.ts";
|
|
4
5
|
/** What `mountKyogijoTurn` gives back. `O` is what `update` takes: the options of a drawing, or (for `mountMultiTurn`) of a tournament layout. */
|
|
5
6
|
export interface KyogijoTurn<O = SurfaceOptions | ScoreOptions> {
|
|
6
7
|
/** `3d`, or `flat` where the browser cannot draw the 3D view (or there is nothing to turn): the flat drawing is shown and the rest of this does nothing. */
|
|
@@ -13,8 +14,13 @@ export interface KyogijoTurn<O = SurfaceOptions | ScoreOptions> {
|
|
|
13
14
|
preset(name: TurnPreset): void;
|
|
14
15
|
/** Back to the opening view. */
|
|
15
16
|
reset(): void;
|
|
16
|
-
/**
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Draw again with new options (a score that moved, a look that changed), keeping the view and the auto-turn: the view goes on turning. `change` alters what the venue's walls and roof stand on (the settings `venue` was
|
|
19
|
+
* mounted with, the parts given), so that a page can switch them on and off without mounting the view again.
|
|
20
|
+
*/
|
|
21
|
+
update(options: O, change?: {
|
|
22
|
+
venue?: VenueSettings;
|
|
23
|
+
}): void;
|
|
18
24
|
/** Whether the auto-turn is running. */
|
|
19
25
|
readonly playing: boolean;
|
|
20
26
|
/** Start the auto-turn, a slow turn of the whole view. It gives whether it is running (a surface that cannot turn gives `false`). Nothing turns by itself until this, the Play button or Space starts it, unless `autoPlay` asked. */
|
package/dist/turn.dom.js
CHANGED
|
@@ -40,6 +40,8 @@ export function mountKyogijoTurn(host, options, settings = {}) {
|
|
|
40
40
|
export function mountTurn(host, options, settings, build) {
|
|
41
41
|
const doc = host.ownerDocument;
|
|
42
42
|
const win = doc.defaultView;
|
|
43
|
+
/** The venue's settings as they are now: the mounted ones, altered by `update`. */
|
|
44
|
+
let venue = settings.venue;
|
|
43
45
|
let model = build(options, settings);
|
|
44
46
|
/** What names the four viewpoints: the model's own table (a tournament layout has one), else the sport's. */
|
|
45
47
|
const sport = () => model.presets ?? model.options.sport;
|
|
@@ -61,8 +63,10 @@ export function mountTurn(host, options, settings, build) {
|
|
|
61
63
|
play: () => false,
|
|
62
64
|
pause: () => undefined,
|
|
63
65
|
togglePlay: () => false,
|
|
64
|
-
update: (next) => {
|
|
65
|
-
|
|
66
|
+
update: (next, change) => {
|
|
67
|
+
if (change?.venue !== undefined)
|
|
68
|
+
venue = { ...(typeof venue === "object" ? venue : {}), ...change.venue };
|
|
69
|
+
model = build(next, { ...settings, id: settings.id ?? model.id, venue });
|
|
66
70
|
flat(next);
|
|
67
71
|
},
|
|
68
72
|
svg: () => (alive ? host.querySelector("svg.kyogijo") : null),
|
|
@@ -436,10 +440,12 @@ export function mountTurn(host, options, settings, build) {
|
|
|
436
440
|
},
|
|
437
441
|
preset: toPreset,
|
|
438
442
|
reset: toOpening,
|
|
439
|
-
update(next) {
|
|
443
|
+
update(next, change) {
|
|
440
444
|
if (!alive)
|
|
441
445
|
return;
|
|
442
|
-
|
|
446
|
+
if (change?.venue !== undefined)
|
|
447
|
+
venue = { ...(typeof venue === "object" ? venue : {}), ...change.venue };
|
|
448
|
+
model = build(next, { ...settings, id: settings.id ?? model.id, venue, preset: undefined, view });
|
|
443
449
|
view = clampView(view);
|
|
444
450
|
opening = openingView(settings, sport());
|
|
445
451
|
const layout = layoutOf(model, shown, stage.clientWidth || 960, stage.clientHeight || 600, settings.lens);
|
package/dist/venue.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface VenueSettings {
|
|
|
8
8
|
roof?: boolean;
|
|
9
9
|
/** A retractable roof (a real venue's: BC Place's) drawn open, the fabric gathered into its pod, instead of closed over the opening. Closed by default. */
|
|
10
10
|
roofOpen?: boolean;
|
|
11
|
+
/** The walls of a real venue's building (`crowd: { real: true }`), raised on its outline: they follow `roof` where left out (a roof and walls together, as before), and `walls: true` with `roof` off raises the walls alone, `roof: true` with `walls: false` the roof alone. */
|
|
12
|
+
walls?: boolean;
|
|
11
13
|
/** How finely the curves are cut: `low` a facet to each corner, `auto` (the default) three, `high` six; an oval is 12, 28 or 56 facets round. */
|
|
12
14
|
detail?: Cut;
|
|
13
15
|
}
|
package/dist/venue.js
CHANGED
|
@@ -150,8 +150,9 @@ export function standsVenueOf(stands, crowd, o, v, lift) {
|
|
|
150
150
|
if (wallSeats.length > 0)
|
|
151
151
|
items.push({ id: "wall-seats", kind: "wall-seats", at: centre, height: topOf(wallSeats), planes: wallSeats });
|
|
152
152
|
// The roof: a canopy over the back of the top tier, or a lid over it in a hall. A real venue has its own: the walls of its building and a roof of its kind over them.
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
const [walls, roof] = [v.walls ?? v.roof === true, v.roof === true];
|
|
154
|
+
if (stands.real !== undefined && (walls || roof))
|
|
155
|
+
items.push(...realBuilding(stands.real, topRing(stands), centre, lift, ARC_STEPS[cut].oval * 2, v.roofOpen === true, { walls, roof }));
|
|
155
156
|
const top = v.roof === true && crowd.roof && stands.real === undefined ? topRing(stands) : undefined;
|
|
156
157
|
if (top !== undefined) {
|
|
157
158
|
const lid = INDOOR.includes(String(o.sport));
|
package/dist/venue.real.d.ts
CHANGED
|
@@ -8,10 +8,13 @@ export declare function saddleAt(real: Pick<RealShell, "footprint">, [x, y]: Pt)
|
|
|
8
8
|
/** The height of the roof over a point of the building's edge, above the surface, in feet. */
|
|
9
9
|
export declare const roofAt: (real: RealShell, p: Pt) => number;
|
|
10
10
|
/**
|
|
11
|
-
* The walls and the roof of a real venue. The hall is the building's outline cut to the bowl's wall and a margin (`RealShell.hall`): its rim is where a ray from the middle meets the one or the other first, in `steps`
|
|
11
|
+
* The walls and the roof of a real venue (`parts` says which are made). The hall is the building's outline cut to the bowl's wall and a margin (`RealShell.hall`): its rim is where a ray from the middle meets the one or the other first, in `steps`
|
|
12
12
|
* rays. A wall stands on each stretch of the rim, up to the roof's height over it; the roof is a band from the rim in to the inner edge of the top tier (the middle stays open, as the 3D view's roofs are).
|
|
13
13
|
*/
|
|
14
|
-
export declare function realBuilding(real: RealShell, top: StandRing | undefined, centre: readonly [number, number], lift: number, steps: number, open?: boolean
|
|
14
|
+
export declare function realBuilding(real: RealShell, top: StandRing | undefined, centre: readonly [number, number], lift: number, steps: number, open?: boolean, parts?: {
|
|
15
|
+
walls: boolean;
|
|
16
|
+
roof: boolean;
|
|
17
|
+
}): Items;
|
|
15
18
|
/** The pod in the middle of a cable roof's opening, as a share of the opening's size, and how thick it is, in feet (ours: the article says the fabric gathers into a pod above the video board, not how large it is). */
|
|
16
19
|
export declare const POD: {
|
|
17
20
|
readonly share: 0.24;
|
package/dist/venue.real.js
CHANGED
|
@@ -52,10 +52,10 @@ function slopeThrough(points) {
|
|
|
52
52
|
return { x0: mx, y0: my, z0: mz, gx, gy };
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* The walls and the roof of a real venue. The hall is the building's outline cut to the bowl's wall and a margin (`RealShell.hall`): its rim is where a ray from the middle meets the one or the other first, in `steps`
|
|
55
|
+
* The walls and the roof of a real venue (`parts` says which are made). The hall is the building's outline cut to the bowl's wall and a margin (`RealShell.hall`): its rim is where a ray from the middle meets the one or the other first, in `steps`
|
|
56
56
|
* rays. A wall stands on each stretch of the rim, up to the roof's height over it; the roof is a band from the rim in to the inner edge of the top tier (the middle stays open, as the 3D view's roofs are).
|
|
57
57
|
*/
|
|
58
|
-
export function realBuilding(real, top, centre, lift, steps, open = false) {
|
|
58
|
+
export function realBuilding(real, top, centre, lift, steps, open = false, parts = { walls: true, roof: true }) {
|
|
59
59
|
const items = [];
|
|
60
60
|
const c = [centre[0], centre[1]];
|
|
61
61
|
const rim = Array.from({ length: steps }, (_, k) => {
|
|
@@ -73,10 +73,10 @@ export function realBuilding(real, top, centre, lift, steps, open = false) {
|
|
|
73
73
|
const high = lift + roofAt(real, [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2]);
|
|
74
74
|
planes.push({ ...shy(wall(`shell-${i}`, "wall", a[0], a[1], b[0], b[1], 0, high, `<rect class="u-shell" width="${n(long)}" height="${n(high)}"/>`), centre), fadeTo: 0.02 });
|
|
75
75
|
});
|
|
76
|
-
if (planes.length > 0)
|
|
76
|
+
if (parts.walls && planes.length > 0)
|
|
77
77
|
items.push({ id: "shell", kind: "walls", at: centre, height: Math.max(...planes.map((p) => p.o[2])), planes });
|
|
78
78
|
const crown = real.roof === "cable" ? real.crown : undefined;
|
|
79
|
-
if (top?.hole == null && crown === undefined)
|
|
79
|
+
if (!parts.roof || (top?.hole == null && crown === undefined))
|
|
80
80
|
return items;
|
|
81
81
|
const roof = [];
|
|
82
82
|
// A cable roof rises from the rim of the hall to the opening over the surface; any other is a band from the rim in to the inner edge of the top tier.
|
package/dist/venues-entry.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { VENUE_ATTRIBUTION, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn } from "./venues.ts";
|
|
2
|
-
export type { RealVenue, RealVenueData, VenueBasis, VenueDivision, VenueOrientation, VenueOsm, VenuePlan, VenueRoof } from "./venues.ts";
|
|
1
|
+
export { VENUE_ATTRIBUTION, VENUE_CONFERENCES, VENUE_DIVISIONS, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, conferenceOf, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn, venuesInConference } from "./venues.ts";
|
|
2
|
+
export type { RealVenue, RealVenueData, VenueBasis, VenueConference, VenueDivision, VenueOrientation, VenueOsm, VenuePlan, VenueRoof } from "./venues.ts";
|
package/dist/venues-entry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// The real venues of the NHL's arenas: the outline of each building and the way its rink lies (OpenStreetMap, ODbL 1.0) and a plausible bowl from the seats, tiers and roof the sources give (Wikidata, Wikipedia).
|
|
2
|
-
export { VENUE_ATTRIBUTION, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn } from "./venues.js";
|
|
2
|
+
export { VENUE_ATTRIBUTION, VENUE_CONFERENCES, VENUE_DIVISIONS, VENUE_IDS, VENUES, arenaOfVenue, bowlInside, conferenceOf, planVenue, venueBowl, venueById, venueByWikidata, venueOrientation, venueRink, venuesIn, venuesInConference } from "./venues.js";
|
package/dist/venues.d.ts
CHANGED
|
@@ -6,8 +6,15 @@ export { VENUE_ATTRIBUTION };
|
|
|
6
6
|
export type VenueBasis = "documented" | "plausible";
|
|
7
7
|
/** The kinds of roof the venues have: `fixed` is a lid over the bowl, `saddle` a roof that rises at the two ends and falls at the two sides (the Scotiabank Saddledome's). */
|
|
8
8
|
export type VenueRoof = "fixed" | "saddle";
|
|
9
|
-
/** The NHL's divisions
|
|
10
|
-
export
|
|
9
|
+
/** The NHL's divisions, in the order of the league's own listing: the Western Conference's two, then the Eastern's. A division none of whose arenas has a venue yet has no venues in `venuesIn`. */
|
|
10
|
+
export declare const VENUE_DIVISIONS: readonly ["pacific", "central", "atlantic", "metropolitan"];
|
|
11
|
+
export type VenueDivision = (typeof VENUE_DIVISIONS)[number];
|
|
12
|
+
/** The NHL's two conferences, and the divisions of each. */
|
|
13
|
+
export declare const VENUE_CONFERENCES: {
|
|
14
|
+
readonly western: readonly ["pacific", "central"];
|
|
15
|
+
readonly eastern: readonly ["atlantic", "metropolitan"];
|
|
16
|
+
};
|
|
17
|
+
export type VenueConference = keyof typeof VENUE_CONFERENCES;
|
|
11
18
|
/** The facts of a venue: the seats and the number of seating levels and the kind of roof, each with what a source says. No text of an article is kept. */
|
|
12
19
|
export interface RealVenueData {
|
|
13
20
|
/** The key of the arena in `ARENAS`: `honda-center`. */
|
|
@@ -82,7 +89,7 @@ export interface VenueOrientation {
|
|
|
82
89
|
basis: "mapped" | "building" | "none";
|
|
83
90
|
north: number;
|
|
84
91
|
}
|
|
85
|
-
/** The venues by key:
|
|
92
|
+
/** The venues by key: the arenas of the NHL's divisions that have been drawn, with their facts and their outlines. */
|
|
86
93
|
export declare const VENUES: Readonly<Record<string, RealVenue>>;
|
|
87
94
|
/** The keys of `VENUES`, in the order of the data. */
|
|
88
95
|
export declare const VENUE_IDS: readonly string[];
|
|
@@ -92,6 +99,10 @@ export declare const venueById: (id: string | undefined) => RealVenue | undefine
|
|
|
92
99
|
export declare const venueByWikidata: (wikidata: string | undefined) => RealVenue | undefined;
|
|
93
100
|
/** The venues of a division of the NHL, in the order of the data. */
|
|
94
101
|
export declare const venuesIn: (division: VenueDivision) => RealVenue[];
|
|
102
|
+
/** The conference a division of the NHL is in. */
|
|
103
|
+
export declare const conferenceOf: (division: VenueDivision) => VenueConference;
|
|
104
|
+
/** The venues of a conference of the NHL, division by division, in the order of the data. */
|
|
105
|
+
export declare const venuesInConference: (conference: VenueConference) => RealVenue[];
|
|
95
106
|
/** The arena a venue is of. */
|
|
96
107
|
export declare const arenaOfVenue: (venue: RealVenue) => Arena;
|
|
97
108
|
/** How the rink lies in a venue's building (see `VenueOsm.axis`). */
|
package/dist/venues.data.js
CHANGED
|
@@ -71,4 +71,76 @@ export const VENUE_DATA = [
|
|
|
71
71
|
"tiers": { "count": 2, "basis": "plausible", "read": "no source says how many seating levels there are: two bowls are drawn" },
|
|
72
72
|
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
"id": "united-center",
|
|
76
|
+
"wikidata": "Q639975",
|
|
77
|
+
"division": "central",
|
|
78
|
+
"en": { "title": "United Center", "revision": 1380672233 },
|
|
79
|
+
"seats": { "hockey": 19717, "source": "wikipedia", "wikidata": 23500, "read": "the article's seating line for ice hockey, 19,717 (22,428 with standing room), which the infobox gives too; Wikidata's one capacity (23,500) is the concert one" },
|
|
80
|
+
"tiers": { "count": 2, "basis": "documented", "read": "the article tells of the 300 level seating bowl and of three levels of suites (down from 216 sky-boxes to 169 executive suites after 2009-10): a lower bowl and the 300 level, with the suites between as walks" },
|
|
81
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise; the article says the building is 140 feet tall, of concrete and steel" },
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "ball-arena",
|
|
85
|
+
"wikidata": "Q795470",
|
|
86
|
+
"division": "central",
|
|
87
|
+
"en": { "title": "Ball Arena", "revision": 1379560431 },
|
|
88
|
+
"seats": { "hockey": 17809, "source": "wikipedia", "wikidata": 19155, "read": "the infobox's figure for hockey (given with lacrosse), 17,809; Wikidata's capacity without a sport is 19,155 and its other (17,417) is for futsal" },
|
|
89
|
+
"tiers": { "count": 2, "basis": "plausible", "read": "no source says how many seating levels there are: two bowls are drawn" },
|
|
90
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "american-airlines-center",
|
|
94
|
+
"wikidata": "Q463345",
|
|
95
|
+
"division": "central",
|
|
96
|
+
"en": { "title": "American Airlines Center", "revision": 1379833787 },
|
|
97
|
+
"seats": { "hockey": 18532, "source": "wikipedia", "wikidata": 19200, "read": "the infobox's figure for ice hockey, 18,532 (19,323 with standing room); Wikidata's one capacity (19,200) is the basketball one" },
|
|
98
|
+
"tiers": { "count": 2, "basis": "plausible", "read": "no source says how many seating levels there are: two bowls are drawn; the article speaks of retractable seating, which the bowl does not draw" },
|
|
99
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise; the article says the roof looks like a Quonset hut, a barrel vault, which the one kind of fixed roof does not draw" },
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "grand-casino-arena",
|
|
103
|
+
"wikidata": "Q1421388",
|
|
104
|
+
"division": "central",
|
|
105
|
+
"en": { "title": "Grand Casino Arena", "revision": 1379407082 },
|
|
106
|
+
"seats": { "hockey": 17954, "source": "wikidata", "wikidata": 17954, "read": "Wikidata's capacity for ice hockey from 2012 (P1083 with P641 ice hockey and P580 2012), the later of its two (18,064 from 2000); the article's lede and infobox give 17,954 too" },
|
|
107
|
+
"tiers": { "count": 3, "basis": "documented", "read": "the article says the arena has four spectator levels, one of suites and three for general seating: three seating bowls, with the suite level as a walk between them" },
|
|
108
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "bridgestone-arena",
|
|
112
|
+
"wikidata": "Q302869",
|
|
113
|
+
"division": "central",
|
|
114
|
+
"en": { "title": "Bridgestone Arena", "revision": 1380457078 },
|
|
115
|
+
"seats": { "hockey": 17510, "source": "wikidata", "wikidata": 17510, "read": "Wikidata's capacity for ice hockey (P1083 with P641 ice hockey); the article's own line gives 17,159, 2.0 percent fewer" },
|
|
116
|
+
"tiers": { "count": 2, "basis": "plausible", "read": "no source says how many seating levels there are everywhere in the building: two bowls are drawn; the article speaks of upper-level seats and, at the south end only, of no mid-level seating and one level of suites" },
|
|
117
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise; the article speaks of two round roof support columns at the south end, which are not drawn" },
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "enterprise-center",
|
|
121
|
+
"wikidata": "Q1067700",
|
|
122
|
+
"division": "central",
|
|
123
|
+
"en": { "title": "Enterprise Center", "revision": 1372086380 },
|
|
124
|
+
"seats": { "hockey": 18096, "source": "wikipedia", "wikidata": 18400, "read": "the infobox's figure for ice hockey, 18,096, which the article's first sentence gives too; Wikidata's one capacity (18,400) is not for hockey" },
|
|
125
|
+
"tiers": { "count": 2, "basis": "documented", "read": "the article tells of the replacement of all upper-tier seats and of the lower-tier seats in the 2017 to 2019 renovation: two seating tiers" },
|
|
126
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "delta-center",
|
|
130
|
+
"wikidata": "Q82294",
|
|
131
|
+
"division": "central",
|
|
132
|
+
"en": { "title": "Delta Center", "revision": 1379043310 },
|
|
133
|
+
"seats": { "hockey": 16020, "source": "wikipedia", "wikidata": 19911, "read": "the infobox's figure for ice hockey, 16,020, which the article's lede gives as the most for ice hockey; Wikidata's one capacity (19,911) is not for hockey" },
|
|
134
|
+
"tiers": { "count": 2, "basis": "plausible", "read": "no source says how many seating levels there are: two bowls are drawn; the article speaks of a lower bowl rebuilt in 2025 and of terrace-style ledges" },
|
|
135
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "canada-life-centre",
|
|
139
|
+
"wikidata": "Q656928",
|
|
140
|
+
"division": "central",
|
|
141
|
+
"en": { "title": "Canada Life Centre", "revision": 1379717047 },
|
|
142
|
+
"seats": { "hockey": 15225, "source": "wikipedia", "wikidata": 15004, "read": "the article's seating capacity for hockey games, 15,225, which the infobox gives as the top of 8,812 to 15,225; Wikidata's one capacity (15,004) is older, before 278 premium seats were added to the upper level in 2015" },
|
|
143
|
+
"tiers": { "count": 2, "basis": "documented", "lowerShare": 0.579, "read": "the article says the lower bowl holds 8,812 and that premium seats were added to the upper level: two seating levels, the lower with 8,812 of the 15,225" },
|
|
144
|
+
"roof": { "kind": "fixed", "basis": "plausible", "read": "an indoor arena: a fixed roof, as nothing says otherwise" },
|
|
145
|
+
},
|
|
74
146
|
];
|
package/dist/venues.geo.d.ts
CHANGED
|
@@ -5,6 +5,28 @@ export type LonLat = readonly [number, number];
|
|
|
5
5
|
export declare function metresFrom(origin: LonLat, ring: readonly LonLat[]): Pt[];
|
|
6
6
|
/** The inverse of `metresFrom`: a point given as east and north metres from `origin`, in degrees. */
|
|
7
7
|
export declare function lonLatFrom(origin: LonLat, [east, north]: Pt): LonLat;
|
|
8
|
+
/** A point as OpenStreetMap's Overpass API returns it. */
|
|
9
|
+
export interface OsmPoint {
|
|
10
|
+
lat: number;
|
|
11
|
+
lon: number;
|
|
12
|
+
}
|
|
13
|
+
/** An element as Overpass returns it with its geometry (`out geom`): a way's points, or a relation's members, each with theirs. */
|
|
14
|
+
export interface OsmElement {
|
|
15
|
+
type: string;
|
|
16
|
+
id: number;
|
|
17
|
+
geometry?: readonly OsmPoint[];
|
|
18
|
+
members?: readonly {
|
|
19
|
+
type: string;
|
|
20
|
+
ref: number;
|
|
21
|
+
role: string;
|
|
22
|
+
geometry?: readonly OsmPoint[];
|
|
23
|
+
}[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The closed outline an OpenStreetMap element is, as its points with the first repeated at the end, or `undefined`: a closed way is its own; a multipolygon relation is its outer members joined end to end into one
|
|
27
|
+
* ring (a building drawn in two or more ways); a relation with two outer rings or an outer way that does not close is not an outline (the caller says what rule it needs). Inner members are courtyards and are left out.
|
|
28
|
+
*/
|
|
29
|
+
export declare function outerRingOf(element: OsmElement): OsmPoint[] | undefined;
|
|
8
30
|
/** The mean of a ring's longitudes and latitudes: a point to measure from. */
|
|
9
31
|
export declare const middleOf: (ring: readonly LonLat[]) => LonLat;
|
|
10
32
|
/** The area of a polygon, unsigned. */
|
package/dist/venues.geo.js
CHANGED
|
@@ -9,6 +9,34 @@ export function metresFrom(origin, ring) {
|
|
|
9
9
|
export function lonLatFrom(origin, [east, north]) {
|
|
10
10
|
return [origin[0] + east / (RAD * EARTH * Math.cos(origin[1] * RAD)), origin[1] + north / (RAD * EARTH)];
|
|
11
11
|
}
|
|
12
|
+
const same = (a, b) => a.lat === b.lat && a.lon === b.lon;
|
|
13
|
+
/**
|
|
14
|
+
* The closed outline an OpenStreetMap element is, as its points with the first repeated at the end, or `undefined`: a closed way is its own; a multipolygon relation is its outer members joined end to end into one
|
|
15
|
+
* ring (a building drawn in two or more ways); a relation with two outer rings or an outer way that does not close is not an outline (the caller says what rule it needs). Inner members are courtyards and are left out.
|
|
16
|
+
*/
|
|
17
|
+
export function outerRingOf(element) {
|
|
18
|
+
if (element.type === "way") {
|
|
19
|
+
const g = element.geometry;
|
|
20
|
+
return g !== undefined && g.length > 3 && same(g[0], g[g.length - 1]) ? [...g] : undefined;
|
|
21
|
+
}
|
|
22
|
+
if (element.type !== "relation" || element.members === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
const parts = element.members.filter((m) => m.type === "way" && m.role === "outer" && m.geometry !== undefined && m.geometry.length > 1).map((m) => [...m.geometry]);
|
|
25
|
+
if (parts.length === 0)
|
|
26
|
+
return undefined;
|
|
27
|
+
const ring = parts.shift();
|
|
28
|
+
while (!same(ring[0], ring[ring.length - 1]) && parts.length > 0) {
|
|
29
|
+
const tail = ring[ring.length - 1];
|
|
30
|
+
const next = parts.findIndex((part) => same(part[0], tail) || same(part[part.length - 1], tail));
|
|
31
|
+
if (next < 0)
|
|
32
|
+
return undefined;
|
|
33
|
+
const [part] = parts.splice(next, 1);
|
|
34
|
+
if (!same(part[0], tail))
|
|
35
|
+
part.reverse();
|
|
36
|
+
ring.push(...part.slice(1));
|
|
37
|
+
}
|
|
38
|
+
return parts.length === 0 && ring.length > 3 && same(ring[0], ring[ring.length - 1]) ? ring : undefined;
|
|
39
|
+
}
|
|
12
40
|
/** The mean of a ring's longitudes and latitudes: a point to measure from. */
|
|
13
41
|
export const middleOf = (ring) => [ring.reduce((s, p) => s + p[0], 0) / ring.length, ring.reduce((s, p) => s + p[1], 0) / ring.length];
|
|
14
42
|
/** The area of a polygon, unsigned. */
|
package/dist/venues.js
CHANGED
|
@@ -9,7 +9,11 @@ import { boxOf, edgeDistance, inside, metresFrom, middleOf, northOn, turnedTo }
|
|
|
9
9
|
import { VENUE_DATA } from "./venues.data.js";
|
|
10
10
|
import { VENUE_ATTRIBUTION, VENUE_OSM } from "./venues.osm.data.js";
|
|
11
11
|
export { VENUE_ATTRIBUTION };
|
|
12
|
-
/** The
|
|
12
|
+
/** The NHL's divisions, in the order of the league's own listing: the Western Conference's two, then the Eastern's. A division none of whose arenas has a venue yet has no venues in `venuesIn`. */
|
|
13
|
+
export const VENUE_DIVISIONS = ["pacific", "central", "atlantic", "metropolitan"];
|
|
14
|
+
/** The NHL's two conferences, and the divisions of each. */
|
|
15
|
+
export const VENUE_CONFERENCES = { western: ["pacific", "central"], eastern: ["atlantic", "metropolitan"] };
|
|
16
|
+
/** The venues by key: the arenas of the NHL's divisions that have been drawn, with their facts and their outlines. */
|
|
13
17
|
export const VENUES = Object.freeze(Object.fromEntries(VENUE_DATA.map((data) => [data.id, Object.freeze({ ...data, osm: VENUE_OSM[data.id] })])));
|
|
14
18
|
/** The keys of `VENUES`, in the order of the data. */
|
|
15
19
|
export const VENUE_IDS = Object.freeze(VENUE_DATA.map((data) => data.id));
|
|
@@ -19,6 +23,10 @@ export const venueById = (id) => (id !== undefined && Object.prototype.hasOwnPro
|
|
|
19
23
|
export const venueByWikidata = (wikidata) => Object.values(VENUES).find((venue) => venue.wikidata === wikidata);
|
|
20
24
|
/** The venues of a division of the NHL, in the order of the data. */
|
|
21
25
|
export const venuesIn = (division) => Object.values(VENUES).filter((venue) => venue.division === division);
|
|
26
|
+
/** The conference a division of the NHL is in. */
|
|
27
|
+
export const conferenceOf = (division) => VENUE_CONFERENCES.western.includes(division) ? "western" : "eastern";
|
|
28
|
+
/** The venues of a conference of the NHL, division by division, in the order of the data. */
|
|
29
|
+
export const venuesInConference = (conference) => VENUE_CONFERENCES[conference].flatMap((division) => venuesIn(division));
|
|
22
30
|
/** The arena a venue is of. */
|
|
23
31
|
export const arenaOfVenue = (venue) => {
|
|
24
32
|
const arena = arenaById(venue.id);
|