@kispace-io/gs-lib 1.1.8 → 1.2.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/dist/base-map-builder.d.ts.map +1 -1
- package/dist/gs-model.d.ts +6 -0
- package/dist/gs-model.d.ts.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +890 -288
- package/dist/index.js.map +1 -1
- package/dist/map-renderer.d.ts +94 -0
- package/dist/map-renderer.d.ts.map +1 -0
- package/dist/ml/gs-gs2ml.d.ts +96 -0
- package/dist/ml/gs-gs2ml.d.ts.map +1 -0
- package/dist/ml/gs-ml-adapters.d.ts +41 -0
- package/dist/ml/gs-ml-adapters.d.ts.map +1 -0
- package/dist/ml/gs-ml-lib.d.ts +17 -0
- package/dist/ml/gs-ml-lib.d.ts.map +1 -0
- package/dist/ml/gs-ml2gs.d.ts +10 -0
- package/dist/ml/gs-ml2gs.d.ts.map +1 -0
- package/dist/ml/gs-mlns.d.ts +10 -0
- package/dist/ml/gs-mlns.d.ts.map +1 -0
- package/dist/ml/index.d.ts +9 -0
- package/dist/ml/index.d.ts.map +1 -0
- package/dist/ml/maplibre-map-renderer.d.ts +66 -0
- package/dist/ml/maplibre-map-renderer.d.ts.map +1 -0
- package/dist/{gs-gs2ol.d.ts → ol/gs-gs2ol.d.ts} +2 -2
- package/dist/ol/gs-gs2ol.d.ts.map +1 -0
- package/dist/ol/gs-ol-adapters.d.ts.map +1 -0
- package/dist/{gs-lib.d.ts → ol/gs-ol-lib.d.ts} +4 -4
- package/dist/ol/gs-ol-lib.d.ts.map +1 -0
- package/dist/{gs-ol2gs.d.ts → ol/gs-ol2gs.d.ts} +1 -1
- package/dist/ol/gs-ol2gs.d.ts.map +1 -0
- package/dist/ol/gs-olns.d.ts.map +1 -0
- package/dist/ol/index.d.ts +9 -0
- package/dist/ol/index.d.ts.map +1 -0
- package/dist/ol/openlayers-map-renderer.d.ts +68 -0
- package/dist/ol/openlayers-map-renderer.d.ts.map +1 -0
- package/package.json +6 -2
- package/src/base-map-builder.ts +8 -9
- package/src/gs-model.ts +7 -1
- package/src/index.ts +12 -7
- package/src/map-renderer.ts +115 -0
- package/src/ml/gs-gs2ml.ts +717 -0
- package/src/ml/gs-ml-adapters.ts +134 -0
- package/src/ml/gs-ml-lib.ts +124 -0
- package/src/ml/gs-ml2gs.ts +66 -0
- package/src/ml/gs-mlns.ts +50 -0
- package/src/ml/index.ts +41 -0
- package/src/ml/maplibre-map-renderer.ts +428 -0
- package/src/{gs-gs2ol.ts → ol/gs-gs2ol.ts} +10 -4
- package/src/{gs-lib.ts → ol/gs-ol-lib.ts} +7 -6
- package/src/{gs-ol2gs.ts → ol/gs-ol2gs.ts} +1 -1
- package/src/ol/index.ts +21 -0
- package/src/ol/openlayers-map-renderer.ts +719 -0
- package/dist/gs-gs2ol.d.ts.map +0 -1
- package/dist/gs-lib.d.ts.map +0 -1
- package/dist/gs-ol-adapters.d.ts.map +0 -1
- package/dist/gs-ol2gs.d.ts.map +0 -1
- package/dist/gs-olns.d.ts.map +0 -1
- /package/dist/{gs-ol-adapters.d.ts → ol/gs-ol-adapters.d.ts} +0 -0
- /package/dist/{gs-olns.d.ts → ol/gs-olns.d.ts} +0 -0
- /package/src/{gs-ol-adapters.ts → ol/gs-ol-adapters.ts} +0 -0
- /package/src/{gs-olns.ts → ol/gs-olns.ts} +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Map, Popup, IControl, LngLatLike } from 'maplibre-gl';
|
|
2
|
+
import { render as litRender } from "@kispace-io/appspace/externals/lit";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* MapLibre Control adapter for user modules
|
|
6
|
+
*/
|
|
7
|
+
export class GsMlControlAdapter {
|
|
8
|
+
private map: Map;
|
|
9
|
+
private container: HTMLElement;
|
|
10
|
+
private templateFunction?: Function;
|
|
11
|
+
|
|
12
|
+
constructor(map: Map) {
|
|
13
|
+
this.map = map;
|
|
14
|
+
this.container = document.createElement('div');
|
|
15
|
+
this.container.style.margin = '0';
|
|
16
|
+
this.container.style.padding = '0';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getMap(): Map {
|
|
20
|
+
return this.map;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getElement(): HTMLElement {
|
|
24
|
+
return this.container;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render(strings?: TemplateStringsArray | Function) {
|
|
28
|
+
if (strings === undefined && this.templateFunction) {
|
|
29
|
+
strings = this.templateFunction();
|
|
30
|
+
} else if (strings instanceof Function) {
|
|
31
|
+
this.templateFunction = strings as Function;
|
|
32
|
+
strings = this.templateFunction();
|
|
33
|
+
}
|
|
34
|
+
if (strings) {
|
|
35
|
+
litRender(strings, this.getElement());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
style(styleJson: any) {
|
|
40
|
+
const style = this.getElement().style;
|
|
41
|
+
for (const property in styleJson) {
|
|
42
|
+
const value = styleJson[property];
|
|
43
|
+
style.setProperty(property, value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* MapLibre IControl wrapper for user modules
|
|
50
|
+
*/
|
|
51
|
+
export class GsMlControl implements IControl {
|
|
52
|
+
private adapter: GsMlControlAdapter;
|
|
53
|
+
|
|
54
|
+
constructor(_position?: string) {
|
|
55
|
+
this.adapter = null as any; // Will be set in onAdd
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
onAdd(map: Map): HTMLElement {
|
|
59
|
+
this.adapter = new GsMlControlAdapter(map);
|
|
60
|
+
return this.adapter.getElement();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
onRemove(): void {
|
|
64
|
+
this.adapter.getElement().remove();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getAdapter(): GsMlControlAdapter {
|
|
68
|
+
return this.adapter;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* MapLibre Overlay adapter using Popup
|
|
74
|
+
*/
|
|
75
|
+
export class GsMlOverlayAdapter {
|
|
76
|
+
private map: Map;
|
|
77
|
+
private popup: Popup;
|
|
78
|
+
private container: HTMLElement;
|
|
79
|
+
private templateFunction?: Function;
|
|
80
|
+
|
|
81
|
+
constructor(map: Map) {
|
|
82
|
+
this.map = map;
|
|
83
|
+
this.container = document.createElement('div');
|
|
84
|
+
this.container.style.margin = '0';
|
|
85
|
+
this.container.style.padding = '0';
|
|
86
|
+
|
|
87
|
+
this.popup = new Popup({
|
|
88
|
+
closeButton: false,
|
|
89
|
+
closeOnClick: false,
|
|
90
|
+
maxWidth: 'none'
|
|
91
|
+
});
|
|
92
|
+
this.popup.setDOMContent(this.container);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getMap(): Map {
|
|
96
|
+
return this.map;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getElement(): HTMLElement {
|
|
100
|
+
return this.container;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
render(strings?: TemplateStringsArray | Function) {
|
|
104
|
+
if (strings === undefined && this.templateFunction) {
|
|
105
|
+
strings = this.templateFunction();
|
|
106
|
+
} else if (strings instanceof Function) {
|
|
107
|
+
this.templateFunction = strings as Function;
|
|
108
|
+
strings = this.templateFunction();
|
|
109
|
+
}
|
|
110
|
+
if (strings) {
|
|
111
|
+
litRender(strings, this.getElement());
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
style(styleJson: any) {
|
|
116
|
+
const style = this.getElement().style;
|
|
117
|
+
for (const property in styleJson) {
|
|
118
|
+
const value = styleJson[property];
|
|
119
|
+
style.setProperty(property, value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
show(coords: number[]) {
|
|
124
|
+
this.getElement().style.display = 'block';
|
|
125
|
+
this.popup.setLngLat([coords[0], coords[1]] as LngLatLike);
|
|
126
|
+
this.popup.addTo(this.map);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
hide() {
|
|
130
|
+
this.getElement().style.display = 'none';
|
|
131
|
+
this.popup.remove();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {GsMap} from "../gs-model";
|
|
2
|
+
import "maplibre-gl/dist/maplibre-gl.css";
|
|
3
|
+
import {
|
|
4
|
+
Map,
|
|
5
|
+
LngLatLike,
|
|
6
|
+
StyleSpecification
|
|
7
|
+
} from 'maplibre-gl';
|
|
8
|
+
import {
|
|
9
|
+
buildInitialStyle,
|
|
10
|
+
importMlControlSource,
|
|
11
|
+
importMlOverlaySource,
|
|
12
|
+
toWgs84,
|
|
13
|
+
EPSG_3857,
|
|
14
|
+
MlImporter
|
|
15
|
+
} from "./gs-gs2ml";
|
|
16
|
+
import {
|
|
17
|
+
GsMlControl,
|
|
18
|
+
GsMlOverlayAdapter
|
|
19
|
+
} from "./gs-ml-adapters";
|
|
20
|
+
import {GsLayerType, GsSourceType} from "../gs-model";
|
|
21
|
+
|
|
22
|
+
export * from "../gs-model";
|
|
23
|
+
export * from "./gs-gs2ml";
|
|
24
|
+
|
|
25
|
+
export interface MlLibOptions {
|
|
26
|
+
containerSelector: string | HTMLElement;
|
|
27
|
+
gsMap: GsMap;
|
|
28
|
+
env?: any;
|
|
29
|
+
modules?: any;
|
|
30
|
+
importer?: MlImporter;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Main entry point to create a MapLibre map from GsMap
|
|
35
|
+
*/
|
|
36
|
+
export async function mlLib(options: MlLibOptions): Promise<Map> {
|
|
37
|
+
const gsMap = options.gsMap;
|
|
38
|
+
|
|
39
|
+
// Check for GROUP layer with BM source (external style)
|
|
40
|
+
const bmLayer = gsMap.layers.find(
|
|
41
|
+
l => l.type === GsLayerType.GROUP && l.source.type === GsSourceType.BM
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
let style: StyleSpecification | string;
|
|
45
|
+
if (bmLayer?.source.url) {
|
|
46
|
+
// Use external style URL
|
|
47
|
+
style = bmLayer.source.url;
|
|
48
|
+
} else {
|
|
49
|
+
// Build style from GsMap
|
|
50
|
+
style = buildInitialStyle(gsMap);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Handle container
|
|
54
|
+
const container = typeof options.containerSelector === 'string'
|
|
55
|
+
? document.querySelector(options.containerSelector) as HTMLElement
|
|
56
|
+
: options.containerSelector;
|
|
57
|
+
|
|
58
|
+
if (!container) {
|
|
59
|
+
throw new Error('Container not found');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Convert center to WGS84 for MapLibre using the view's projection
|
|
63
|
+
const sourceProjection = gsMap.view.projection || EPSG_3857;
|
|
64
|
+
const centerWgs84 = toWgs84([gsMap.view.center[0], gsMap.view.center[1]], sourceProjection);
|
|
65
|
+
|
|
66
|
+
// Get pitch and bearing from view if available (for 3D viewing)
|
|
67
|
+
const pitch = gsMap.view.pitch || 0;
|
|
68
|
+
const bearing = gsMap.view.bearing || 0;
|
|
69
|
+
|
|
70
|
+
// Create map with 3D support
|
|
71
|
+
const map = new Map({
|
|
72
|
+
container,
|
|
73
|
+
style,
|
|
74
|
+
center: centerWgs84 as LngLatLike,
|
|
75
|
+
zoom: gsMap.view.zoom,
|
|
76
|
+
pitch,
|
|
77
|
+
bearing,
|
|
78
|
+
maxPitch: 85 // Allow steep viewing angles for 3D buildings
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Store environment
|
|
82
|
+
(map as any)._gsEnv = options.env;
|
|
83
|
+
(map as any)._gsMap = gsMap;
|
|
84
|
+
|
|
85
|
+
// Set up importer
|
|
86
|
+
let importer: MlImporter | undefined = options.importer;
|
|
87
|
+
if (!importer && options.modules) {
|
|
88
|
+
importer = async (src: string) => {
|
|
89
|
+
const module = options.modules[src];
|
|
90
|
+
if (module) {
|
|
91
|
+
if (typeof module === 'string') {
|
|
92
|
+
return import(module);
|
|
93
|
+
}
|
|
94
|
+
return module;
|
|
95
|
+
}
|
|
96
|
+
throw new Error(`Module not found: ${src}`);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Wait for map to load before adding controls/overlays
|
|
101
|
+
await new Promise<void>((resolve) => {
|
|
102
|
+
if (map.loaded()) {
|
|
103
|
+
resolve();
|
|
104
|
+
} else {
|
|
105
|
+
map.on('load', () => resolve());
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Add controls
|
|
110
|
+
for (const control of gsMap.controls || []) {
|
|
111
|
+
const mlControl = new GsMlControl();
|
|
112
|
+
map.addControl(mlControl, 'top-right');
|
|
113
|
+
await importMlControlSource(map, mlControl, control.src, options.env, importer);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Add overlays
|
|
117
|
+
for (const overlay of gsMap.overlays || []) {
|
|
118
|
+
const overlayAdapter = new GsMlOverlayAdapter(map);
|
|
119
|
+
await importMlOverlaySource(map, overlayAdapter, overlay.src, options.env, importer);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return map;
|
|
123
|
+
}
|
|
124
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GsFeature,
|
|
3
|
+
GsGeometry,
|
|
4
|
+
GsState,
|
|
5
|
+
KEY_UUID,
|
|
6
|
+
ensureUuid
|
|
7
|
+
} from "../gs-model";
|
|
8
|
+
import { toWebMercator, EPSG_4326 } from "./gs-gs2ml";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Convert coordinates from WGS84 to EPSG:3857 for any geometry type
|
|
12
|
+
*/
|
|
13
|
+
function convertCoordinatesToMercator(coords: any, geometryType: string): any {
|
|
14
|
+
switch (geometryType) {
|
|
15
|
+
case 'Point':
|
|
16
|
+
return toWebMercator(coords as [number, number], EPSG_4326);
|
|
17
|
+
case 'LineString':
|
|
18
|
+
case 'MultiPoint':
|
|
19
|
+
return (coords as [number, number][]).map(c => toWebMercator(c, EPSG_4326));
|
|
20
|
+
case 'Polygon':
|
|
21
|
+
case 'MultiLineString':
|
|
22
|
+
return (coords as [number, number][][]).map(ring => ring.map(c => toWebMercator(c, EPSG_4326)));
|
|
23
|
+
case 'MultiPolygon':
|
|
24
|
+
return (coords as [number, number][][][]).map(poly => poly.map(ring => ring.map(c => toWebMercator(c, EPSG_4326))));
|
|
25
|
+
default:
|
|
26
|
+
return coords;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convert GeoJSON geometry to GsGeometry (with coordinate conversion to EPSG:3857)
|
|
32
|
+
*/
|
|
33
|
+
export function toGsGeometry(geometry: GeoJSON.Geometry): GsGeometry {
|
|
34
|
+
if (geometry.type === 'GeometryCollection') {
|
|
35
|
+
throw new Error('GeometryCollection is not supported');
|
|
36
|
+
}
|
|
37
|
+
const geom = geometry as GeoJSON.Point | GeoJSON.LineString | GeoJSON.Polygon | GeoJSON.MultiPoint | GeoJSON.MultiLineString | GeoJSON.MultiPolygon;
|
|
38
|
+
const coordsMercator = convertCoordinatesToMercator(geom.coordinates, geom.type);
|
|
39
|
+
|
|
40
|
+
return ensureUuid({
|
|
41
|
+
type: geom.type,
|
|
42
|
+
coordinates: coordsMercator
|
|
43
|
+
} as GsGeometry);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert MapLibre/GeoJSON feature to GsFeature (with coordinate conversion to EPSG:3857)
|
|
48
|
+
*/
|
|
49
|
+
export function toGsFeature(feature: GeoJSON.Feature): GsFeature {
|
|
50
|
+
const geometry = feature.geometry;
|
|
51
|
+
if (geometry.type === 'GeometryCollection') {
|
|
52
|
+
throw new Error('GeometryCollection is not supported');
|
|
53
|
+
}
|
|
54
|
+
const geom = geometry as GeoJSON.Point | GeoJSON.LineString | GeoJSON.Polygon | GeoJSON.MultiPoint | GeoJSON.MultiLineString | GeoJSON.MultiPolygon;
|
|
55
|
+
const coordsMercator = convertCoordinatesToMercator(geom.coordinates, geom.type);
|
|
56
|
+
|
|
57
|
+
return ensureUuid({
|
|
58
|
+
geometry: ensureUuid({
|
|
59
|
+
type: geom.type,
|
|
60
|
+
coordinates: coordsMercator
|
|
61
|
+
} as GsGeometry),
|
|
62
|
+
state: feature.properties || {},
|
|
63
|
+
uuid: feature.properties?.[KEY_UUID] || feature.id?.toString()
|
|
64
|
+
} as GsFeature);
|
|
65
|
+
}
|
|
66
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MapLibre library re-exports
|
|
3
|
+
* Centralized re-exports for MapLibre to provide a single source of truth.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Re-export MapLibre GL
|
|
7
|
+
export {
|
|
8
|
+
Map,
|
|
9
|
+
Marker,
|
|
10
|
+
Popup,
|
|
11
|
+
NavigationControl,
|
|
12
|
+
GeolocateControl,
|
|
13
|
+
ScaleControl,
|
|
14
|
+
FullscreenControl,
|
|
15
|
+
AttributionControl,
|
|
16
|
+
LngLat,
|
|
17
|
+
LngLatBounds,
|
|
18
|
+
Point,
|
|
19
|
+
MercatorCoordinate
|
|
20
|
+
} from 'maplibre-gl';
|
|
21
|
+
|
|
22
|
+
// Re-export types
|
|
23
|
+
export type {
|
|
24
|
+
MapOptions,
|
|
25
|
+
StyleSpecification,
|
|
26
|
+
LayerSpecification,
|
|
27
|
+
SourceSpecification,
|
|
28
|
+
GeoJSONSourceSpecification,
|
|
29
|
+
RasterSourceSpecification,
|
|
30
|
+
VectorSourceSpecification,
|
|
31
|
+
MapMouseEvent,
|
|
32
|
+
MapLayerMouseEvent,
|
|
33
|
+
IControl,
|
|
34
|
+
MarkerOptions,
|
|
35
|
+
PopupOptions,
|
|
36
|
+
LngLatLike,
|
|
37
|
+
LngLatBoundsLike,
|
|
38
|
+
PointLike,
|
|
39
|
+
FitBoundsOptions,
|
|
40
|
+
CameraOptions,
|
|
41
|
+
AnimationOptions,
|
|
42
|
+
ExpressionSpecification,
|
|
43
|
+
FilterSpecification
|
|
44
|
+
} from 'maplibre-gl';
|
|
45
|
+
|
|
46
|
+
// Default export for convenience
|
|
47
|
+
import maplibregl from 'maplibre-gl';
|
|
48
|
+
export { maplibregl };
|
|
49
|
+
export default maplibregl;
|
|
50
|
+
|
package/src/ml/index.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// MapLibre renderer exports
|
|
2
|
+
// Import from '@kispace-io/gs-lib/ml' for MapLibre-specific functionality
|
|
3
|
+
|
|
4
|
+
// Core model (needed for types)
|
|
5
|
+
export * from "../gs-model"
|
|
6
|
+
|
|
7
|
+
// Renderer interface
|
|
8
|
+
export * from "../map-renderer"
|
|
9
|
+
|
|
10
|
+
// MapLibre-specific exports
|
|
11
|
+
export * from "./gs-ml-lib"
|
|
12
|
+
export * from "./gs-ml2gs"
|
|
13
|
+
export * from "./gs-ml-adapters"
|
|
14
|
+
export {
|
|
15
|
+
toGeoJsonFeature,
|
|
16
|
+
toGeoJsonFeatureCollection,
|
|
17
|
+
toMlSource,
|
|
18
|
+
toMlLayers,
|
|
19
|
+
toMlFillPaint,
|
|
20
|
+
toMlLinePaint,
|
|
21
|
+
toMlCirclePaint,
|
|
22
|
+
toMlFillExtrusionPaint,
|
|
23
|
+
buildInitialStyle,
|
|
24
|
+
toWgs84,
|
|
25
|
+
toWebMercator,
|
|
26
|
+
transformCoords,
|
|
27
|
+
EPSG_3857,
|
|
28
|
+
EPSG_4326,
|
|
29
|
+
importMlControlSource,
|
|
30
|
+
importMlOverlaySource,
|
|
31
|
+
ML_KEY_GS_LAYER_UUID,
|
|
32
|
+
ML_KEY_GS_SOURCE_UUID,
|
|
33
|
+
type MlImporter
|
|
34
|
+
} from "./gs-gs2ml"
|
|
35
|
+
|
|
36
|
+
// MapLibre namespace
|
|
37
|
+
export * as ml from "./gs-mlns"
|
|
38
|
+
|
|
39
|
+
// MapLibre renderer implementation
|
|
40
|
+
export { MapLibreMapRenderer } from "./maplibre-map-renderer"
|
|
41
|
+
|