becomap-v2 2.0.0-alpha.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/LICENSE +15 -0
- package/README.md +119 -0
- package/dist/becomap.umd.js +329 -0
- package/dist/becomap.umd.js.map +1 -0
- package/dist/index.d.ts +603 -0
- package/dist/index.js +6970 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
import maplibregl from 'maplibre-gl';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Venue data types.
|
|
5
|
+
*
|
|
6
|
+
* `Raw*` types are the provider output contract (`VenueData`) — a neutral,
|
|
7
|
+
* JSON-friendly shape both the REST adapter (editor protobuf) and the mock
|
|
8
|
+
* generator produce. The built model types add derived links and O(1)
|
|
9
|
+
* indexes and are what the rest of the SDK consumes.
|
|
10
|
+
*
|
|
11
|
+
* This module is renderer-agnostic: no three.js, no maplibre imports.
|
|
12
|
+
*/
|
|
13
|
+
/** [lng, lat] */
|
|
14
|
+
type LngLat = [number, number];
|
|
15
|
+
/** GeoJSON polygon geometry as produced by the editor (shape.json_data). */
|
|
16
|
+
interface PolygonGeometry {
|
|
17
|
+
type: 'Polygon';
|
|
18
|
+
/** Outer ring first, holes after; rings are [lng, lat] positions. */
|
|
19
|
+
coordinates: LngLat[][];
|
|
20
|
+
}
|
|
21
|
+
/** GeoJSON line geometry — the editor emits INNER_WALL shapes as centerlines. */
|
|
22
|
+
interface LineStringGeometry {
|
|
23
|
+
type: 'LineString';
|
|
24
|
+
coordinates: LngLat[];
|
|
25
|
+
}
|
|
26
|
+
type ShapeGeometryData = PolygonGeometry | LineStringGeometry;
|
|
27
|
+
interface RawSite {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
/** Initial map center; venue bounds refine this later. */
|
|
31
|
+
center: LngLat;
|
|
32
|
+
}
|
|
33
|
+
interface RawFloor {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
/** Vertical ordering within its building (0 = ground). */
|
|
37
|
+
level: number;
|
|
38
|
+
buildingId: string;
|
|
39
|
+
}
|
|
40
|
+
interface RawBuilding {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
floors: RawFloor[];
|
|
44
|
+
}
|
|
45
|
+
interface RawNode {
|
|
46
|
+
id: string;
|
|
47
|
+
lat: number;
|
|
48
|
+
lng: number;
|
|
49
|
+
floorId: string;
|
|
50
|
+
accessible: boolean;
|
|
51
|
+
privateNode: boolean;
|
|
52
|
+
/** Adjacent node ids (same-floor walkable links). */
|
|
53
|
+
siblings: string[];
|
|
54
|
+
}
|
|
55
|
+
/** Per-shape styling authored in the editor (Feature.properties.shapeProperties). */
|
|
56
|
+
interface ShapeStyle {
|
|
57
|
+
/** Extrusion height in meters (0/0.1 = flat base, walls ~2-4.1, stores ~4). */
|
|
58
|
+
height?: number;
|
|
59
|
+
/** Wall/stroke color. */
|
|
60
|
+
color?: string;
|
|
61
|
+
/** Fill/top color. */
|
|
62
|
+
fillColor?: string;
|
|
63
|
+
/** 0..1; walls are sometimes translucent (0.6-0.8). */
|
|
64
|
+
opacity?: number;
|
|
65
|
+
/** Editor label font size. */
|
|
66
|
+
labelSize?: number;
|
|
67
|
+
/** Editor label rotation (radians). */
|
|
68
|
+
labelRotation?: number;
|
|
69
|
+
}
|
|
70
|
+
interface RawShape {
|
|
71
|
+
id: string;
|
|
72
|
+
floorId: string;
|
|
73
|
+
layerId: string;
|
|
74
|
+
/** Editor shape type: 'WALL' | 'INNER_WALL' | 'POLYGON' (mock uses 'polygon'). */
|
|
75
|
+
type: string;
|
|
76
|
+
geometry: ShapeGeometryData;
|
|
77
|
+
style?: ShapeStyle;
|
|
78
|
+
}
|
|
79
|
+
interface RawLocation {
|
|
80
|
+
id: string;
|
|
81
|
+
name: string;
|
|
82
|
+
/** Editor location type, e.g. 'tenant' | 'amenities' | 'entrance'. */
|
|
83
|
+
type: string;
|
|
84
|
+
description?: string;
|
|
85
|
+
nodeId?: string;
|
|
86
|
+
shapeId?: string;
|
|
87
|
+
amenity?: string;
|
|
88
|
+
categoryIds: string[];
|
|
89
|
+
logoUrl?: string;
|
|
90
|
+
hidden: boolean;
|
|
91
|
+
sortOrder: number;
|
|
92
|
+
}
|
|
93
|
+
interface RawCategory {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
icon?: string;
|
|
97
|
+
sortOrder: number;
|
|
98
|
+
colorHex?: string;
|
|
99
|
+
}
|
|
100
|
+
interface RawMapObject {
|
|
101
|
+
id: string;
|
|
102
|
+
nodeId: string;
|
|
103
|
+
modelUrl: string;
|
|
104
|
+
scale: number;
|
|
105
|
+
rotation: number;
|
|
106
|
+
altitude: number;
|
|
107
|
+
light: number;
|
|
108
|
+
}
|
|
109
|
+
type FloorConnectionKind = 'elevator' | 'escalator' | 'stairs' | 'passage' | 'door' | 'ramp' | 'other';
|
|
110
|
+
/**
|
|
111
|
+
* Joins two nodes (typically on different floors): elevator shafts,
|
|
112
|
+
* escalators, stairs. Mirrors the editor's connection semantics:
|
|
113
|
+
* cost = (weight > 0 ? weight : 100) * (multiplier || 1), applied per
|
|
114
|
+
* direction.
|
|
115
|
+
*/
|
|
116
|
+
interface RawFloorConnection {
|
|
117
|
+
id: string;
|
|
118
|
+
kind: FloorConnectionKind;
|
|
119
|
+
name?: string;
|
|
120
|
+
accessible: boolean;
|
|
121
|
+
/** 0 means "use the default cost of 100". */
|
|
122
|
+
weight: number;
|
|
123
|
+
/** 0/absent means 1. */
|
|
124
|
+
multiplier: number;
|
|
125
|
+
direction: 'both' | 'startToEnd' | 'endToStart';
|
|
126
|
+
startNodeId: string;
|
|
127
|
+
endNodeId: string;
|
|
128
|
+
}
|
|
129
|
+
/** Everything a provider returns; input to {@link buildVenue}. */
|
|
130
|
+
interface VenueData {
|
|
131
|
+
site: RawSite;
|
|
132
|
+
buildings: RawBuilding[];
|
|
133
|
+
nodes: RawNode[];
|
|
134
|
+
shapes: RawShape[];
|
|
135
|
+
locations: RawLocation[];
|
|
136
|
+
categories: RawCategory[];
|
|
137
|
+
mapObjects: RawMapObject[];
|
|
138
|
+
floorConnections: RawFloorConnection[];
|
|
139
|
+
/** Default icon set: key (e.g. RESTROOM) -> CDN SVG url. Category
|
|
140
|
+
* `iconFromDefaultList` keys and amenity names resolve through this. */
|
|
141
|
+
iconset?: Record<string, string>;
|
|
142
|
+
}
|
|
143
|
+
interface GraphEdge {
|
|
144
|
+
toNodeId: string;
|
|
145
|
+
/** Walk cost: meters for sibling edges; editor weight rule for connections. */
|
|
146
|
+
cost: number;
|
|
147
|
+
/** Whether this edge is usable on accessible routes. */
|
|
148
|
+
accessible: boolean;
|
|
149
|
+
/** Set for connection (cross-floor) edges. */
|
|
150
|
+
connectionKind?: FloorConnectionKind;
|
|
151
|
+
}
|
|
152
|
+
interface GraphNode {
|
|
153
|
+
id: string;
|
|
154
|
+
lng: number;
|
|
155
|
+
lat: number;
|
|
156
|
+
floorId: string;
|
|
157
|
+
accessible: boolean;
|
|
158
|
+
privateNode: boolean;
|
|
159
|
+
edges: GraphEdge[];
|
|
160
|
+
}
|
|
161
|
+
interface Category {
|
|
162
|
+
id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
icon?: string;
|
|
165
|
+
sortOrder: number;
|
|
166
|
+
colorHex?: string;
|
|
167
|
+
}
|
|
168
|
+
interface Shape {
|
|
169
|
+
id: string;
|
|
170
|
+
floorId: string;
|
|
171
|
+
layerId: string;
|
|
172
|
+
type: string;
|
|
173
|
+
geometry: ShapeGeometryData;
|
|
174
|
+
style?: ShapeStyle;
|
|
175
|
+
}
|
|
176
|
+
interface VenueLocation {
|
|
177
|
+
id: string;
|
|
178
|
+
name: string;
|
|
179
|
+
type: string;
|
|
180
|
+
description?: string;
|
|
181
|
+
nodeId?: string;
|
|
182
|
+
shapeId?: string;
|
|
183
|
+
/** Derived from its node's (preferred) or shape's floor. */
|
|
184
|
+
floorId?: string;
|
|
185
|
+
amenity?: string;
|
|
186
|
+
categories: Category[];
|
|
187
|
+
logoUrl?: string;
|
|
188
|
+
hidden: boolean;
|
|
189
|
+
sortOrder: number;
|
|
190
|
+
}
|
|
191
|
+
interface MapObjectDef {
|
|
192
|
+
id: string;
|
|
193
|
+
nodeId: string;
|
|
194
|
+
modelUrl: string;
|
|
195
|
+
scale: number;
|
|
196
|
+
rotation: number;
|
|
197
|
+
altitude: number;
|
|
198
|
+
light: number;
|
|
199
|
+
}
|
|
200
|
+
interface Floor {
|
|
201
|
+
id: string;
|
|
202
|
+
name: string;
|
|
203
|
+
level: number;
|
|
204
|
+
buildingId: string;
|
|
205
|
+
locations: VenueLocation[];
|
|
206
|
+
shapes: Shape[];
|
|
207
|
+
nodes: GraphNode[];
|
|
208
|
+
}
|
|
209
|
+
interface Building {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
/** Sorted by level ascending. */
|
|
213
|
+
floors: Floor[];
|
|
214
|
+
}
|
|
215
|
+
interface VenueStats {
|
|
216
|
+
buildings: number;
|
|
217
|
+
floors: number;
|
|
218
|
+
locations: number;
|
|
219
|
+
shapes: number;
|
|
220
|
+
nodes: number;
|
|
221
|
+
edges: number;
|
|
222
|
+
categories: number;
|
|
223
|
+
mapObjects: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The built, indexed venue model. Instance-scoped (never a singleton),
|
|
228
|
+
* immutable by convention after {@link buildVenue} returns.
|
|
229
|
+
*/
|
|
230
|
+
declare class Venue {
|
|
231
|
+
#private;
|
|
232
|
+
readonly id: string;
|
|
233
|
+
readonly name: string;
|
|
234
|
+
readonly center: [number, number];
|
|
235
|
+
readonly buildings: Building[];
|
|
236
|
+
readonly categories: Category[];
|
|
237
|
+
readonly mapObjects: MapObjectDef[];
|
|
238
|
+
/** Default icon set (key -> SVG url) — markers resolve amenity icons here. */
|
|
239
|
+
readonly iconset: Record<string, string>;
|
|
240
|
+
constructor(data: {
|
|
241
|
+
id: string;
|
|
242
|
+
name: string;
|
|
243
|
+
center: [number, number];
|
|
244
|
+
buildings: Building[];
|
|
245
|
+
categories: Category[];
|
|
246
|
+
mapObjects: MapObjectDef[];
|
|
247
|
+
iconset?: Record<string, string>;
|
|
248
|
+
nodes: GraphNode[];
|
|
249
|
+
shapes: Shape[];
|
|
250
|
+
locations: VenueLocation[];
|
|
251
|
+
edgeCount: number;
|
|
252
|
+
});
|
|
253
|
+
getBuilding(id: string): Building | undefined;
|
|
254
|
+
getFloor(id: string): Floor | undefined;
|
|
255
|
+
getLocation(id: string): VenueLocation | undefined;
|
|
256
|
+
getShape(id: string): Shape | undefined;
|
|
257
|
+
getNode(id: string): GraphNode | undefined;
|
|
258
|
+
getCategory(id: string): Category | undefined;
|
|
259
|
+
get locations(): IterableIterator<VenueLocation>;
|
|
260
|
+
get nodes(): IterableIterator<GraphNode>;
|
|
261
|
+
stats(): VenueStats;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Build the indexed venue model from raw provider data: derive location
|
|
265
|
+
* floors, group entities per floor, and assemble the routing graph (sibling
|
|
266
|
+
* edges with haversine costs; cross-floor edges from floor connections with
|
|
267
|
+
* kind penalties).
|
|
268
|
+
*/
|
|
269
|
+
declare function buildVenue(data: VenueData): Venue;
|
|
270
|
+
|
|
271
|
+
/** What happens AT a step. Mirrors the v1 SDK's step-action semantics. */
|
|
272
|
+
type StepAction = 'depart' | 'turn' | 'continue' | 'floorChange' | 'exitBuilding' | 'enterBuilding' | 'arrive';
|
|
273
|
+
/** Which way to go at a step. `up`/`down` accompany a floor change. */
|
|
274
|
+
type StepDirection = 'none' | 'straight' | 'slightLeft' | 'left' | 'uTurnLeft' | 'slightRight' | 'right' | 'uTurnRight' | 'up' | 'down';
|
|
275
|
+
interface RouteStep {
|
|
276
|
+
lng: number;
|
|
277
|
+
lat: number;
|
|
278
|
+
floorId: string;
|
|
279
|
+
buildingId: string | null;
|
|
280
|
+
segmentIndex: number;
|
|
281
|
+
/** Cumulative meters from the route start (matches ribbon arc length). */
|
|
282
|
+
cumMeters: number;
|
|
283
|
+
/** Ready-to-show English instruction, built from the fields below. */
|
|
284
|
+
label: string;
|
|
285
|
+
/** Structured action, so hosts can localise or draw their own UI. */
|
|
286
|
+
action: StepAction;
|
|
287
|
+
/** Structured direction — the turn this step calls for. */
|
|
288
|
+
direction: StepDirection;
|
|
289
|
+
/** Meters covered from THIS step to the next (0 at the destination). */
|
|
290
|
+
distanceMeters: number;
|
|
291
|
+
/** Graph node this step sits on. */
|
|
292
|
+
nodeId: string;
|
|
293
|
+
/** Named location at this step, for "turn right at Zara" (null when none). */
|
|
294
|
+
landmark: string | null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* All events a {@link BecoMap} instance can emit, with their payload types.
|
|
299
|
+
* Payload shapes are placeholders in the foundation phase and are refined as
|
|
300
|
+
* features land (venue selection in Phase 5, routing in Phase 6).
|
|
301
|
+
*/
|
|
302
|
+
interface BecoMapEvents {
|
|
303
|
+
/** Fired once the underlying map has loaded and the SDK is ready. */
|
|
304
|
+
load: undefined;
|
|
305
|
+
/** Fired when a location is selected. */
|
|
306
|
+
select: {
|
|
307
|
+
locationId: string;
|
|
308
|
+
};
|
|
309
|
+
/** Fired when the visible floor of a building changes. */
|
|
310
|
+
floorChange: {
|
|
311
|
+
floorId: string;
|
|
312
|
+
};
|
|
313
|
+
/** Fired when the active route changes (null = route cleared). */
|
|
314
|
+
routeChange: {
|
|
315
|
+
routeId: string | null;
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* Fired when the route preview reaches a floor connection (null = card
|
|
319
|
+
* should hide). Apps can consume this to render their OWN instruction UI —
|
|
320
|
+
* the built-in card can be disabled via `ui.transitionCard: false`.
|
|
321
|
+
*/
|
|
322
|
+
transition: {
|
|
323
|
+
kind: string;
|
|
324
|
+
toFloorId: string;
|
|
325
|
+
toFloorName: string;
|
|
326
|
+
direction: 'up' | 'down';
|
|
327
|
+
label: string;
|
|
328
|
+
} | null;
|
|
329
|
+
/**
|
|
330
|
+
* Fired whenever the active turn-by-turn step changes (null = route
|
|
331
|
+
* cleared). Carries STRUCTURED data — `action`, `direction`, `distanceMeters`
|
|
332
|
+
* — so apps can localise the instruction or render their own nav UI instead
|
|
333
|
+
* of parsing `label`.
|
|
334
|
+
*/
|
|
335
|
+
step: {
|
|
336
|
+
index: number;
|
|
337
|
+
total: number;
|
|
338
|
+
label: string;
|
|
339
|
+
action: StepAction;
|
|
340
|
+
direction: StepDirection;
|
|
341
|
+
distanceMeters: number;
|
|
342
|
+
floorId: string;
|
|
343
|
+
landmark: string | null;
|
|
344
|
+
isFirst: boolean;
|
|
345
|
+
isLast: boolean;
|
|
346
|
+
} | null;
|
|
347
|
+
/** Fired on recoverable SDK errors. */
|
|
348
|
+
error: {
|
|
349
|
+
message: string;
|
|
350
|
+
cause?: unknown;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
/** A listener for a single event's payload. */
|
|
354
|
+
type Listener<T> = (payload: T) => void;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Source of venue data. The REST provider talks to the beCoMap backend
|
|
358
|
+
* (editor-generated protobuf + JSON metadata); the mock provider generates a
|
|
359
|
+
* venue procedurally. Both return the same {@link VenueData} contract.
|
|
360
|
+
*/
|
|
361
|
+
interface VenueProvider {
|
|
362
|
+
/**
|
|
363
|
+
* Fetch everything needed to build the venue model.
|
|
364
|
+
*
|
|
365
|
+
* @param signal Abort to cancel in-flight work (the owning BecoMap aborts
|
|
366
|
+
* this on destroy()).
|
|
367
|
+
*/
|
|
368
|
+
fetchVenue(signal?: AbortSignal): Promise<VenueData>;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Named colour themes for store polygons.
|
|
373
|
+
*
|
|
374
|
+
* The palettes follow what the market leaders actually ship (values read from
|
|
375
|
+
* Mappedin's own `styles.json` and Place Vendôme's abuzz scene): a very TIGHT,
|
|
376
|
+
* HIGH-KEY value range — whites and near-whites within a few percent of each
|
|
377
|
+
* other — with structure carried by soft tonal steps and one or two desaturated
|
|
378
|
+
* accents, never by dark grey. Mappedin's walls are `#ffffff`, its rooms
|
|
379
|
+
* `#f5f5f5`, its hallways `#FCFCFC`; the only saturated notes are a pale blue
|
|
380
|
+
* (`#E6F4FB`) and a warm cream (`#F5EFE0`). Heavy mid-greys are what made the
|
|
381
|
+
* earlier themes read as muddy, so nothing here goes below ~75% lightness.
|
|
382
|
+
*
|
|
383
|
+
* Every palette stays in a WARM hue family. A cool blue-grey of the same
|
|
384
|
+
* lightness reads as an untextured CAD default rather than a material: the
|
|
385
|
+
* leaders' only saturated notes are warm ones (Mappedin's `#F5EFE0` desks,
|
|
386
|
+
* Place Vendôme's `#34230e` wood), because a map surface has to suggest
|
|
387
|
+
* plaster, stone or timber to look designed rather than unfinished.
|
|
388
|
+
*
|
|
389
|
+
* - `ivory` — the DEFAULT: warm greige directory panels
|
|
390
|
+
* - `data` — the venue's real editor colours for tops, walls and inner walls
|
|
391
|
+
*/
|
|
392
|
+
type PolygonThemeName = 'ivory' | 'data' | 'neutral';
|
|
393
|
+
|
|
394
|
+
/** Options accepted by {@link createMap}. All fields are optional. */
|
|
395
|
+
interface BecoMapOptions {
|
|
396
|
+
/**
|
|
397
|
+
* Store-polygon colour theme. `ivory` (default) is the warm directory-panel
|
|
398
|
+
* look; `data` uses the venue's real editor / category colours. `neutral`
|
|
399
|
+
* is a back-compat alias for `ivory`.
|
|
400
|
+
*/
|
|
401
|
+
polygonTheme?: PolygonThemeName;
|
|
402
|
+
/** Initial map center as [lng, lat]. Defaults to [0, 0] until venue data provides one. */
|
|
403
|
+
center?: [number, number];
|
|
404
|
+
/** Initial zoom level. Defaults to 15. */
|
|
405
|
+
zoom?: number;
|
|
406
|
+
/** Initial pitch in degrees. Defaults to 0. */
|
|
407
|
+
pitch?: number;
|
|
408
|
+
/** Initial bearing in degrees. Defaults to 0. */
|
|
409
|
+
bearing?: number;
|
|
410
|
+
/** Venue data source. Without it, `map.venue.load()` rejects. */
|
|
411
|
+
venue?: {
|
|
412
|
+
provider: VenueProvider;
|
|
413
|
+
};
|
|
414
|
+
/** Built-in UI controls. */
|
|
415
|
+
ui?: {
|
|
416
|
+
/** Floor switcher control (default true). */
|
|
417
|
+
floorSwitcher?: boolean;
|
|
418
|
+
/** Route navigation bar (default true). */
|
|
419
|
+
routeBar?: boolean;
|
|
420
|
+
/** Built-in floor-connection instruction card (default true). Disable to
|
|
421
|
+
* render your own HTML from the `transition` event. */
|
|
422
|
+
transitionCard?: boolean;
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
interface FrameStats {
|
|
427
|
+
drawCalls: number;
|
|
428
|
+
triangles: number;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
interface BuildingView {
|
|
432
|
+
open: boolean;
|
|
433
|
+
floorId: string;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
interface SearchResult {
|
|
437
|
+
location: VenueLocation;
|
|
438
|
+
/** Higher is better: matched tokens + full-prefix bonuses. */
|
|
439
|
+
score: number;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
interface NavStepInfo {
|
|
443
|
+
index: number;
|
|
444
|
+
total: number;
|
|
445
|
+
label: string;
|
|
446
|
+
isFirst: boolean;
|
|
447
|
+
isLast: boolean;
|
|
448
|
+
/** Structured action — localise or draw your own UI from this, not the label. */
|
|
449
|
+
action: StepAction;
|
|
450
|
+
/** Structured direction (turn / up / down). */
|
|
451
|
+
direction: StepDirection;
|
|
452
|
+
/** Meters covered from this step to the next (0 at the destination). */
|
|
453
|
+
distanceMeters: number;
|
|
454
|
+
/** Floor this step is on. */
|
|
455
|
+
floorId: string;
|
|
456
|
+
/** Named location at this step, when the step sits on one. */
|
|
457
|
+
landmark: string | null;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Namespaced facade stubs. Each facade is a typed surface whose methods are
|
|
462
|
+
* filled in by later phases; until then they throw a descriptive error so
|
|
463
|
+
* consumers get a clear signal instead of silent no-ops.
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
/** Venue data access: loading and model lookups. */
|
|
467
|
+
interface VenueFacade {
|
|
468
|
+
/** Fetch venue data via the configured provider and build the model. */
|
|
469
|
+
load(): Promise<VenueStats>;
|
|
470
|
+
/** The built venue model, or null before {@link VenueFacade.load} resolves. */
|
|
471
|
+
current(): Venue | null;
|
|
472
|
+
/** Convenience: model stats, or null before load. */
|
|
473
|
+
stats(): VenueStats | null;
|
|
474
|
+
}
|
|
475
|
+
/** Floor visibility and selection (live since Phase 4). */
|
|
476
|
+
interface FloorsFacade {
|
|
477
|
+
/** Show a floor (opens its building if sealed, focuses it). */
|
|
478
|
+
select(floorId: string): void;
|
|
479
|
+
/** Building whose floors the built-in switcher controls. */
|
|
480
|
+
focusedBuildingId(): string | null;
|
|
481
|
+
/** Current LOD view of a building (sealed vs open + visible floor). */
|
|
482
|
+
viewOf(buildingId: string): BuildingView | undefined;
|
|
483
|
+
}
|
|
484
|
+
/** Location search (live since Phase 5). */
|
|
485
|
+
interface SearchFacade {
|
|
486
|
+
/** Token-prefix search over names and categories (diacritic-insensitive, non-blocking). */
|
|
487
|
+
query(text: string): Promise<SearchResult[]>;
|
|
488
|
+
/** All visible locations in a category, sorted. */
|
|
489
|
+
byCategory(categoryId: string): VenueLocation[];
|
|
490
|
+
}
|
|
491
|
+
interface RouteInfo {
|
|
492
|
+
/** Total walking distance in meters. */
|
|
493
|
+
distanceMeters: number;
|
|
494
|
+
/** Number of turn-by-turn steps. */
|
|
495
|
+
stepCount: number;
|
|
496
|
+
}
|
|
497
|
+
/** Routing and navigation (live since Phase 6). */
|
|
498
|
+
interface RoutingFacade {
|
|
499
|
+
/** Compute + render + preview a route between two locations. */
|
|
500
|
+
route(fromLocationId: string, toLocationId: string, options?: {
|
|
501
|
+
accessibleOnly?: boolean;
|
|
502
|
+
}): Promise<RouteInfo>;
|
|
503
|
+
/** Clear the active route (the ONLY way besides the route bar ✕). */
|
|
504
|
+
clear(): void;
|
|
505
|
+
/** Replay the runner preview along the active route. */
|
|
506
|
+
preview(): void;
|
|
507
|
+
/** Step navigation (mirrors the built-in route bar). */
|
|
508
|
+
next(): void;
|
|
509
|
+
previous(): void;
|
|
510
|
+
stepInfo(): NavStepInfo | null;
|
|
511
|
+
active(): boolean;
|
|
512
|
+
}
|
|
513
|
+
/** Camera control helpers (live since Phase 5). */
|
|
514
|
+
interface CameraFacade {
|
|
515
|
+
/** Fit the camera to the loaded venue's extents. */
|
|
516
|
+
focusVenue(options?: {
|
|
517
|
+
pitch?: number;
|
|
518
|
+
duration?: number;
|
|
519
|
+
}): void;
|
|
520
|
+
/** Fly to a location, opening its building/floor if needed. */
|
|
521
|
+
focusTo(locationId: string): void;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* The public handle returned by {@link createMap}. Everything a consumer can
|
|
526
|
+
* do goes through this interface — the implementing class is internal.
|
|
527
|
+
*/
|
|
528
|
+
interface BecoMap {
|
|
529
|
+
/** Subscribe to an SDK event. Subscribing to `load` after the map has loaded fires immediately. */
|
|
530
|
+
on<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void;
|
|
531
|
+
/** Unsubscribe a listener previously passed to {@link BecoMap.on}. */
|
|
532
|
+
off<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void;
|
|
533
|
+
/** Tear down the map, its WebGL context, and all listeners. */
|
|
534
|
+
destroy(): void;
|
|
535
|
+
/** Debug: last frame's draw calls/triangles from the unified 3D layer. */
|
|
536
|
+
getFrameStats(): FrameStats;
|
|
537
|
+
/** The underlying MapLibre GL map, for advanced camera/interaction control. */
|
|
538
|
+
getMapLibreMap(): maplibregl.Map;
|
|
539
|
+
/**
|
|
540
|
+
* Switch the store-polygon colour theme at runtime: `ivory` (the default
|
|
541
|
+
* warm directory panels) or `data` (the venue's real editor / category
|
|
542
|
+
* colours). `neutral` is a back-compat alias for `ivory`.
|
|
543
|
+
*/
|
|
544
|
+
setPolygonTheme(theme: PolygonThemeName): void;
|
|
545
|
+
/** Select a location programmatically (highlight + popup + `select` event). */
|
|
546
|
+
selectLocation(locationId: string): void;
|
|
547
|
+
/** Clear the current selection (no event; deselect event may come later). */
|
|
548
|
+
clearSelection(): void;
|
|
549
|
+
/** Venue data access (Phase 2). */
|
|
550
|
+
readonly venue: VenueFacade;
|
|
551
|
+
/** Floor selection and LOD views (Phase 4). */
|
|
552
|
+
readonly floors: FloorsFacade;
|
|
553
|
+
/** Location search (Phase 5). */
|
|
554
|
+
readonly search: SearchFacade;
|
|
555
|
+
/** Routing and navigation (Phase 6). */
|
|
556
|
+
readonly routing: RoutingFacade;
|
|
557
|
+
/** Camera helpers. */
|
|
558
|
+
readonly camera: CameraFacade;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Create a beCoMap instance inside the given container element.
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* ```ts
|
|
565
|
+
* import { createMap } from 'becomap';
|
|
566
|
+
* const map = createMap(document.getElementById('map')!, { zoom: 16 });
|
|
567
|
+
* map.on('load', () => console.log('ready'));
|
|
568
|
+
* ```
|
|
569
|
+
*/
|
|
570
|
+
declare function createMap(container: HTMLElement, options?: BecoMapOptions): BecoMap;
|
|
571
|
+
|
|
572
|
+
declare class MockVenueProvider implements VenueProvider {
|
|
573
|
+
#private;
|
|
574
|
+
/**
|
|
575
|
+
* @param options.stress Tile the campus stress×stress (default 1). Used to
|
|
576
|
+
* exceed venue-scale polygon counts for performance verification.
|
|
577
|
+
*/
|
|
578
|
+
constructor(options?: {
|
|
579
|
+
seed?: number;
|
|
580
|
+
stress?: number;
|
|
581
|
+
});
|
|
582
|
+
fetchVenue(): Promise<VenueData>;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
interface RestVenueProviderOptions {
|
|
586
|
+
baseUrl: string;
|
|
587
|
+
siteId: string;
|
|
588
|
+
clientId: string;
|
|
589
|
+
clientSecret: string;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Loads a venue from the beCoMap backend: token auth, site + floors + floor
|
|
593
|
+
* connections via JSON, and the five editor-generated protobuf binaries via
|
|
594
|
+
* the absolute URLs the site payload provides. Produces the same `VenueData`
|
|
595
|
+
* contract as the mock provider.
|
|
596
|
+
*/
|
|
597
|
+
declare class RestVenueProvider implements VenueProvider {
|
|
598
|
+
#private;
|
|
599
|
+
constructor(options: RestVenueProviderOptions);
|
|
600
|
+
fetchVenue(signal?: AbortSignal): Promise<VenueData>;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
export { type BecoMap, type BecoMapEvents, type BecoMapOptions, type Building, type CameraFacade, type Category, type Floor, type FloorConnectionKind, type FloorsFacade, type GraphEdge, type GraphNode, type Listener, type LngLat, type MapObjectDef, MockVenueProvider, type NavStepInfo, type PolygonGeometry, type PolygonThemeName, RestVenueProvider, type RestVenueProviderOptions, type RouteStep, type RoutingFacade, type SearchFacade, type Shape, type StepAction, type StepDirection, Venue, type VenueData, type VenueFacade, type VenueLocation, type VenueProvider, type VenueStats, buildVenue, createMap };
|