@superrouteca/smap 1.1.7 → 1.2.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superrouteca/smap",
3
- "version": "1.1.7",
3
+ "version": "1.2.1",
4
4
  "description": "sMap for the web: maps from Superroute's sMap service, the Web SDK (map view) and the JS client (tokens, nearest node, styles, tiles).",
5
5
  "license": "MIT",
6
6
  "author": "Goodneo Solutions",
package/types/smap.d.cts CHANGED
@@ -166,6 +166,66 @@ interface CommonLayerOptions {
166
166
  /** In 3D, W / S tilt and A / D turn the view while the map has focus (default true). */
167
167
  keyboard3D?: boolean;
168
168
  onClick?: (feature: GeoJSONFeature, event: LayerClickEvent) => void;
169
+ /**
170
+ * The map's one tooltip while the pointer is over a feature of this layer: beside a point (or custom marker), at the
171
+ * pointer on lines and areas. A string is a template as for `popup`; a function returns trusted HTML or a node.
172
+ */
173
+ tooltip?: string | ((properties: Record<string, unknown>, feature: GeoJSONFeature) => string | Node | null | undefined);
174
+ tooltipOptions?: TooltipOptions;
175
+ }
176
+
177
+ export interface TooltipOptions {
178
+ /** Where the tooltip sits (default 'top'). */
179
+ direction?: 'top' | 'bottom' | 'left' | 'right';
180
+ /** [x, y] pixels added to its place. */
181
+ offset?: [number, number];
182
+ className?: string;
183
+ }
184
+
185
+ /** Where a dragged feature is: [lng, lat], the point in the map in pixels, and the pointer event. */
186
+ export interface DragEvent {
187
+ lngLat: [number, number];
188
+ point: { x: number; y: number };
189
+ originalEvent?: Event;
190
+ }
191
+
192
+ /** Dragging points and custom markers (G2). The map does not pan while a feature is dragged. */
193
+ interface DragOptions {
194
+ /** true, or per feature (a function of the properties, or `{ property }`). Default false. */
195
+ draggable?: boolean | ((properties: Record<string, unknown>, feature: GeoJSONFeature) => boolean) | { property: string; default?: boolean };
196
+ onDragStart?: (feature: GeoJSONFeature, event: DragEvent) => void;
197
+ onDrag?: (feature: GeoJSONFeature, event: DragEvent) => void;
198
+ /** After the release: the layer's data holds the new position (a copy; the objects you gave are not changed). */
199
+ onDragEnd?: (feature: GeoJSONFeature, event: DragEvent) => void;
200
+ }
201
+
202
+ /** A value read per feature in JavaScript: a constant, a function of the properties, or `{ property, default }`. */
203
+ export type FeatureValue<T> = T | ((properties: Record<string, unknown>, feature: GeoJSONFeature) => T) | { property: string; default?: T };
204
+
205
+ /** Custom markers (G1): the caller's own element at each point, laid out above the drawn layers while in view. */
206
+ export interface CustomMarkerOptions extends DragOptions {
207
+ /** The element of one feature: an element, or trusted HTML (inserted as is, never sanitized). Called when the feature first comes into view and again when its properties change. */
208
+ render: (properties: Record<string, unknown>, feature: GeoJSONFeature) => Node | string;
209
+ /** Which point of the element is at the position (default 'center'). */
210
+ anchor?: 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
211
+ /** [x, y] pixels added to the place. */
212
+ offset?: [number, number];
213
+ /** Classes added to every marker's element (each sits in a `div.smap-marker`). */
214
+ className?: string;
215
+ opacity?: FeatureValue<number>;
216
+ /** Higher draws on top within the layer; layers draw in their own order. */
217
+ zIndex?: FeatureValue<number>;
218
+ /** The property naming each feature (getMarker, and keeping elements across setData); else the feature's id, else '#<index>'. */
219
+ idProperty?: string;
220
+ /** The marker under the pointer comes to the front. */
221
+ riseOnHover?: boolean;
222
+ minzoom?: number;
223
+ maxzoom?: number;
224
+ onClick?: (feature: GeoJSONFeature, event: { originalEvent: Event; lngLat: [number, number] }) => void;
225
+ popup?: CommonLayerOptions['popup'];
226
+ popupOptions?: PopupOptions;
227
+ tooltip?: CommonLayerOptions['tooltip'];
228
+ tooltipOptions?: TooltipOptions;
169
229
  }
170
230
 
171
231
  /**
@@ -197,7 +257,7 @@ export interface MarkerOptions {
197
257
  scale?: number | unknown[];
198
258
  /** The pin under the pointer comes to the front (default true). */
199
259
  hoverRaise?: boolean;
200
- /** From this zoom on (default 13) the number is drawn into the pin, so an upper pin covers a lower one completely; false keeps it a separate layer. */
260
+ /** Numbers and badges are drawn into each pin, so an upper pin covers a lower one with them. A zoom keeps them their own layers above the pins further out (fewer images where thousands of pins are in view); false keeps them apart at every zoom. */
201
261
  bakeZoom?: number | false;
202
262
  /**
203
263
  * Pins piled up under a click (default on): with `threshold` (4) or more within `radius` (12 px) the map zooms in by
@@ -212,11 +272,164 @@ export interface MarkerOptions {
212
272
  badgeMinzoom?: number;
213
273
  }
214
274
 
215
- export interface PointOptions extends CommonLayerOptions {
275
+ export type DrawShape = 'polygon' | 'rectangle' | 'circle' | 'line' | 'point';
276
+
277
+ export interface DrawToolOptions {
278
+ /** Shapes to start from (each keeps its id, or gets one). */
279
+ features?: LayerData;
280
+ /** The shapes offered (default all). */
281
+ modes?: DrawShape[];
282
+ /** A new or moved vertex within 10 px of another shape's vertex takes its place (default true). */
283
+ snap?: boolean;
284
+ /** The toolbar's corner, or false for none (default 'top-left'). */
285
+ toolbar?: false | Exclude<ToolPosition, 'none'>;
286
+ /** The toolbar's texts (English by default). */
287
+ labels?: Partial<Record<DrawShape | 'hole' | 'delete' | 'undo' | 'redo' | 'finish' | 'cancel', string>>;
288
+ /** Colour of the shapes (default '#2563eb'); a shape's own `fill` / `stroke` properties win. */
289
+ color?: string;
290
+ onChange?: (event: DrawEvent) => void;
291
+ }
292
+
293
+ export interface DrawEvent {
294
+ type: 'created' | 'edited' | 'deleted';
295
+ feature: GeoJSONFeature | null;
296
+ /** Every shape after the change. */
297
+ features: GeoJSONFeatureCollection;
298
+ }
299
+
300
+ /**
301
+ * Click to add vertices (a click on the first, a double click or Enter finishes; Backspace removes the last; Escape
302
+ * cancels); drag for rectangles and circles. A selected shape: drag a vertex, drag a midpoint to add one, drag the
303
+ * shape to move it, Delete removes the selected vertex or shape; Ctrl/⌘+Z undoes, with Shift redoes. A circle is kept
304
+ * as a 64-point polygon with properties { shape: 'circle', center, radius (metres) }, a rectangle with { shape: 'rectangle' }.
305
+ */
306
+ export interface DrawTool {
307
+ readonly id: string;
308
+ start(shape: DrawShape | 'hole'): this;
309
+ cancel(): this;
310
+ select(id: string | number | null): this;
311
+ selection(): string | number | null;
312
+ delete(id?: string | number): this;
313
+ undo(): this;
314
+ redo(): this;
315
+ getAll(): GeoJSONFeatureCollection;
316
+ get(id: string | number): GeoJSONFeature | null;
317
+ /** Replaces every shape (clears undo). */
318
+ set(data: LayerData): this;
319
+ on(type: 'created' | 'edited' | 'deleted' | 'change', handler: (event: DrawEvent) => void): this;
320
+ off(type: 'created' | 'edited' | 'deleted' | 'change', handler: (event: DrawEvent) => void): this;
321
+ destroy(): void;
322
+ }
323
+
324
+ export interface GoogleBaseOptions {
325
+ /** A Map Tiles API session your server made with your Google key, and that key. */
326
+ session?: string;
327
+ key?: string;
328
+ /** Or the tile URL template and the viewport address (both carrying session and key). */
329
+ tiles?: string;
330
+ viewport?: string;
331
+ type?: 'roadmap' | 'satellite';
332
+ /** Highest zoom of Google's tiles (default 22). */
333
+ maxzoom?: number;
334
+ /** Keep the street map's labels over Google's imagery (default false). */
335
+ labels?: boolean;
336
+ /** Called when Google's first tiles fail and none loads. */
337
+ onFail?: () => void;
338
+ }
339
+
340
+ export interface ModelOptions extends Placement {
341
+ /** A .glb or .gltf URL. */
342
+ model: string;
343
+ /** Metres per model unit (default 1), or per feature. */
344
+ size?: FeatureValue<number>;
345
+ /** Degrees clockwise from north (default 0), or per feature. */
346
+ heading?: FeatureValue<number>;
347
+ /** Metres above the ground (default 0), or per feature. */
348
+ altitude?: FeatureValue<number>;
349
+ /** [x, y, z] degrees turning the model upright and to face north (default [90, 0, 180]: up +Y, front +Z). */
350
+ rotate?: [number, number, number];
351
+ idProperty?: string;
352
+ minzoom?: number;
353
+ zIndex?: number;
354
+ }
355
+
356
+ export interface HeatmapOptions extends Placement {
357
+ /** A number, or per feature ({ property } or an expression). Default 1. */
358
+ weight?: StyleValue<number>;
359
+ /** Pixels (default 20), or an expression of the zoom. */
360
+ radius?: number | unknown[];
361
+ intensity?: number | unknown[];
362
+ opacity?: number;
363
+ /** Colours from low to high, or [[density 0–1, colour], …]. */
364
+ colors?: string[] | Array<[number, string]>;
365
+ minzoom?: number;
366
+ maxzoom?: number;
367
+ zIndex?: number;
368
+ }
369
+
370
+ export interface TerrainOptions {
371
+ /** Elevation tile URLs with {z}, {x}, {y}. */
372
+ tiles: string[];
373
+ /** How heights are packed into the tiles (default 'terrarium'). */
374
+ encoding?: 'terrarium' | 'mapbox';
375
+ tileSize?: number;
376
+ /** The highest zoom of the tiles (default 15). */
377
+ maxzoom?: number;
378
+ attribution?: string;
379
+ /** Heights times this (default 1). */
380
+ exaggeration?: number;
381
+ /** Shading of slopes, under the roads (default on). */
382
+ hillshade?: boolean | { exaggeration?: number; shadow?: string; highlight?: string };
383
+ }
384
+
385
+ /** Geometry helpers (G14). Positions are [lng, lat], {lng, lat} or a Point. */
386
+ export interface Geo {
387
+ distance(a: unknown, b: unknown): number;
388
+ length(line: Array<[number, number]> | GeoJSONFeature | Record<string, unknown>): number;
389
+ bounds(geojson: unknown): [[number, number], [number, number]] | null;
390
+ pointInPolygon(point: unknown, polygon: unknown): boolean;
391
+ nearestPointOnLine(line: unknown, point: unknown): { point: [number, number]; distance: number; index: number; along: number } | null;
392
+ distanceToLine(line: unknown, point: unknown): number;
393
+ decodePolyline(encoded: string, precision?: number): Array<[number, number]>;
394
+ encodePolyline(coordinates: Array<[number, number]>, precision?: number): string;
395
+ }
396
+
397
+ /** A cluster as `cluster.html` and `cluster.tooltip` see it. */
398
+ export interface ClusterInfo {
399
+ id: number;
400
+ count: number;
401
+ /** The engine's cluster properties (cluster_id, point_count, point_count_abbreviated, …). */
402
+ properties: Record<string, unknown>;
403
+ lngLat: [number, number];
404
+ /** The points inside the cluster (all of them, or the first `limit`). */
405
+ leaves(limit?: number): Promise<GeoJSONFeature[]>;
406
+ }
407
+
408
+ export interface ClusterOptions {
409
+ /** Pixels within which points are grouped (default 50). */
410
+ radius?: number;
411
+ /** The last zoom with clusters (default 14); from the next zoom on every point is drawn on its own. */
412
+ maxZoom?: number;
413
+ ring?: string | { property: string; limit?: number; color?: string };
414
+ html?: (cluster: ClusterInfo) => Node | string;
415
+ /** Classes of each cluster element (with ring or html). */
416
+ className?: string;
417
+ /** A click on a cluster zooms in to where it splits (default true). */
418
+ zoomOnClick?: boolean;
419
+ onClick?: (feature: GeoJSONFeature, event: { originalEvent: Event; lngLat: [number, number] }) => void;
420
+ tooltip?: (cluster: ClusterInfo) => string | Node | null | undefined;
421
+ }
422
+
423
+ export interface PointOptions extends CommonLayerOptions, DragOptions {
216
424
  /** Route-map pins instead of circles or an icon. */
217
425
  marker?: MarkerOptions;
218
- /** Groups nearby points into circles sized by their count; a click zooms in to split them. */
219
- cluster?: boolean | { radius?: number; maxZoom?: number };
426
+ /**
427
+ * Groups nearby points into circles sized by their count; a click zooms in to split them. With `ring` or `html` the
428
+ * clusters are drawn as elements: `ring` (a property name, or `{ property, limit, color }`) draws the count inside a
429
+ * ring of the points' colours, each colour's share of the points (read from at most `limit`, default 500); `html`
430
+ * draws each cluster yourself.
431
+ */
432
+ cluster?: boolean | ClusterOptions;
220
433
  clusterColor?: string;
221
434
  color?: string;
222
435
  radius?: number;
@@ -245,6 +458,10 @@ export interface LineOptions extends CommonLayerOptions {
245
458
  shadow?: boolean | { color?: StyleValue; width?: number; opacity?: number };
246
459
  /** Arrowheads along the line in its direction (true: every 80 px, 14 px, the line's colour, opacity 0.8). */
247
460
  arrows?: boolean | { spacing?: number; size?: number; color?: StyleValue; opacity?: number };
461
+ /** A property written along each line as a permanent label (repeated every `labelSpacing` px, default 250). */
462
+ label?: string;
463
+ labelSpacing?: number;
464
+ labelColor?: StyleValue;
248
465
  }
249
466
 
250
467
  export interface PolygonOptions extends CommonLayerOptions {
@@ -265,6 +482,13 @@ export interface BuildingsOptions {
265
482
  export interface MapOptions {
266
483
  /** The element (or its id) the map is drawn in. */
267
484
  container: string | HTMLElement;
485
+ /**
486
+ * 'auto' (default): the WebGL map, or the canvas map where the browser has no WebGL 2 (or refuses a WebGL context):
487
+ * sMap's raster tiles of the same scheme with every layer drawn in 2D, through the same calls. 'webgl' never falls
488
+ * back; 'canvas' always draws in 2D. Without WebGL the map does not tilt or turn and has no 3D buildings, terrain,
489
+ * hillshade or 3D models; the map fires 'smap.unsupported' with { feature } for each of them that is asked for.
490
+ */
491
+ renderer?: 'auto' | 'webgl' | 'canvas';
268
492
  /** A map token; or */
269
493
  token?: string;
270
494
  /** Called at start and again two minutes before each token expires. */
@@ -301,13 +525,40 @@ export interface MapOptions {
301
525
  /** A corner of the map, or 'none' for an element that stays where the page put it. */
302
526
  export type ToolPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';
303
527
  /** The tools the SDK makes by name. */
304
- export type ToolKind = 'navigation' | 'geolocate' | 'fullscreen' | 'scale' | 'zoom' | 'compass' | 'locate';
528
+ export type ToolKind = 'navigation' | 'geolocate' | 'fullscreen' | 'scale' | 'zoom' | 'compass' | 'locate' | 'layers';
305
529
  export interface ToolOptions {
306
530
  /** Shown on the tool's button in the tools control and read by screen readers. */
307
531
  label?: string;
308
532
  position?: ToolPosition;
309
- /** Options of a kind's engine control (e.g. `{ showCompass: false }` for navigation). */
310
- options?: Record<string, unknown>;
533
+ /**
534
+ * Options of a kind's control: the engine control's (e.g. `{ showCompass: false }` for navigation, `{ container }`
535
+ * for full screen of a page element), or `LayersControlOptions` for 'layers'.
536
+ */
537
+ options?: Record<string, unknown> | LayersControlOptions;
538
+ }
539
+
540
+ /** Imagery in place of the street map (G8): drawn over land, water and roads, under the labels. */
541
+ export interface BaseImagery {
542
+ /** Tile URLs with {z}, {x}, {y}. */
543
+ tiles: string[];
544
+ tileSize?: number;
545
+ minzoom?: number;
546
+ maxzoom?: number;
547
+ attribution?: string;
548
+ scheme?: 'xyz' | 'tms';
549
+ /** Keep the street map's labels on top (a hybrid map). Default false. */
550
+ labels?: boolean;
551
+ }
552
+
553
+ /** The layer switcher ('layers' tool): base maps one at a time, overlays each on or off. */
554
+ export interface LayersControlOptions {
555
+ base?: Array<{ id: string; label?: string; style?: StyleFlavor | CustomStyleName | string | Record<string, unknown>; imagery?: BaseImagery }>;
556
+ overlays?: Array<{ id: string; label?: string; layers: string[]; visible?: boolean }>;
557
+ /** The base shown at first (default the first). */
558
+ value?: string;
559
+ /** The button's label (default 'Layers'). */
560
+ title?: string;
561
+ onChange?: (state: { base: string | null; overlays: string[] }) => void;
311
562
  }
312
563
  /** A data-layer tool: one or more layer ids (yours, or the basemap's) shown and hidden with the tool. */
313
564
  export interface ToolLayers { layer: string | string[] }
@@ -463,6 +714,8 @@ export declare class Map {
463
714
  readonly ready: Promise<Map>;
464
715
  /** The rendering engine's map, for anything the SDK does not wrap (set once `ready` resolves). */
465
716
  readonly engine: any;
717
+ /** The renderer in use: 'webgl', or 'canvas' without WebGL 2. */
718
+ readonly renderer: 'webgl' | 'canvas';
466
719
  setStyle(style: StyleFlavor | CustomStyleName | string | Record<string, unknown>): this;
467
720
  setLanguage(language: string): this;
468
721
  setProjection(projection: 'mercator' | 'globe'): this;
@@ -470,6 +723,26 @@ export declare class Map {
470
723
  addPoints(id: string, data: LayerData, options?: PointOptions): this;
471
724
  addLines(id: string, data: LayerData, options?: LineOptions): this;
472
725
  addPolygons(id: string, data: LayerData, options?: PolygonOptions): this;
726
+ /** A drawing and editing tool (G3): polygons, rectangles, circles, lines and points, holes, snapping, undo. */
727
+ drawTool(options?: DrawToolOptions): DrawTool;
728
+ /** Selects features by drawing a box or a lasso (G4); null when Escape cancels. */
729
+ selectArea(options?: { mode?: 'box' | 'lasso'; layers?: string[] }): Promise<{ features: Record<string, GeoJSONFeature[]>; geometry: Record<string, unknown> } | null>;
730
+ /** Google's base maps read straight from Google with your Map Tiles session (G10); null takes them off. */
731
+ setGoogleBase(google: GoogleBaseOptions | null): this;
732
+ /** glTF models at points, turned to each feature's heading (G12); needs sMap.useThree first. */
733
+ addModels(id: string, data: LayerData, options: ModelOptions): this;
734
+ /** A heat map of points (G7). */
735
+ addHeatmap(id: string, data: LayerData, options?: HeatmapOptions): this;
736
+ /** Relief over elevation tiles with hillshading (G11); null takes it off. */
737
+ setTerrain(terrain: TerrainOptions | null): this;
738
+ /** Keeps another sMap map on this map's view, both ways (G13); returns a function that ends it. */
739
+ syncWith(other: Map, options?: { offsetZoom?: number }): () => void;
740
+ /** Raster tiles drawn by the page (G14): draw paints one tile on a 2D context scaled to `size` CSS pixels. */
741
+ addCanvasTiles(id: string, draw: (ctx: CanvasRenderingContext2D, z: number, x: number, y: number, tile: { size: number; canvas: HTMLCanvasElement }) => void | Promise<void>, options?: RasterLayerOptions): this;
742
+ /** The caller's own element at each point (G1); setData keeps the element of every feature still there. */
743
+ addCustomMarkers(id: string, data: LayerData, options: CustomMarkerOptions): this;
744
+ /** The element of one custom marker (made now if it was not in view yet), or null. */
745
+ getMarker(id: string, key: string | number): HTMLElement | null;
473
746
  setData(id: string, data: LayerData): this;
474
747
  setVisible(id: string, visible: boolean): this;
475
748
  /** Removes a layer of any kind (an addData group whole, a helper layer with its source), or a source of addSource. */
@@ -538,6 +811,12 @@ export declare class Map {
538
811
  * added later under a hidden tool's id starting hidden and an id without a layer left alone. Adding an id again
539
812
  * replaces the first. The map data credit, the sMap badge and the tools control are never tools.
540
813
  */
814
+ /** An element or engine control in a corner, not a tool (never hidden by the tools control). */
815
+ addControl(target: HTMLElement | { onAdd(map: any): HTMLElement; onRemove?(map: any): void }, position?: Exclude<ToolPosition, 'none'>): this;
816
+ removeControl(target: HTMLElement | { onAdd(map: any): HTMLElement; onRemove?(map: any): void }): this;
817
+ /** Imagery (satellite, aerial) in place of the street map; null goes back to the street map. */
818
+ setBaseImagery(imagery: BaseImagery | null): this;
819
+ baseImagery(): BaseImagery | null;
541
820
  addTool(id: string, target: HTMLElement | { onAdd(map: any): HTMLElement; onRemove?(map: any): void } | ToolKind | ToolLayers, options?: ToolOptions): this;
542
821
  /** Removes a tool: an engine control leaves the map, a page element is shown again where the page put it. */
543
822
  removeTool(id: string): this;
@@ -595,6 +874,8 @@ export interface Formats {
595
874
  export declare const formats: Formats;
596
875
  /** Converts a file on sMap (POST /v1/convert). */
597
876
  export declare function convert(input: FileInput | Blob, options?: ConvertOptions): Promise<GeoJSONFeatureCollection>;
877
+ /** Geometry helpers: distance, length, bounds, point in polygon, nearest point on a line, encoded polylines. */
878
+ export declare const geo: Geo;
598
879
  /** sMap's raster tiles of a style as an XYZ template, for tools without vector tiles. */
599
880
  export declare function rasterUrl(style: StyleFlavor | CustomStyleName, options?: RasterUrlOptions): string;
600
881
  /** The TileJSON address of sMap's raster tiles of a style. */
@@ -623,6 +904,8 @@ export declare class PMTilesArchive {
623
904
  tileJSON(): Promise<Record<string, unknown>>;
624
905
  }
625
906
  /** Registers deck.gl's map overlay module (`@deck.gl/mapbox`) for addDeckLayer. */
907
+ /** Hands three.js and its GLTFLoader to the SDK for addModels (never bundled). */
908
+ export declare function useThree(THREE: any, GLTFLoader: any): { THREE: any; GLTFLoader: any };
626
909
  export declare function useDeck(module: { MapboxOverlay: any } | { default: { MapboxOverlay: any } }): any;
627
910
 
628
911
  // ------------------------------------------------------------------ plan editor (OPEN-ROUTE-EDIT E10)
@@ -1017,6 +1300,7 @@ declare const sMap: {
1017
1300
  slots: Slot[];
1018
1301
  formats: Formats;
1019
1302
  convert: typeof convert;
1303
+ geo: Geo;
1020
1304
  rasterUrl: typeof rasterUrl;
1021
1305
  rasterTileJsonUrl: typeof rasterTileJsonUrl;
1022
1306
  styleUrl: typeof styleUrl;
@@ -1026,6 +1310,7 @@ declare const sMap: {
1026
1310
  parseWmtsCapabilities: typeof parseWmtsCapabilities;
1027
1311
  PMTilesArchive: typeof PMTilesArchive;
1028
1312
  useDeck: typeof useDeck;
1313
+ useThree: typeof useThree;
1029
1314
  PlanEditor: typeof PlanEditor;
1030
1315
  planTexts: typeof planTexts;
1031
1316
  planEditorParts: typeof planEditorParts;