@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.
Files changed (61) hide show
  1. package/dist/base-map-builder.d.ts.map +1 -1
  2. package/dist/gs-model.d.ts +6 -0
  3. package/dist/gs-model.d.ts.map +1 -1
  4. package/dist/index.d.ts +3 -5
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +890 -288
  7. package/dist/index.js.map +1 -1
  8. package/dist/map-renderer.d.ts +94 -0
  9. package/dist/map-renderer.d.ts.map +1 -0
  10. package/dist/ml/gs-gs2ml.d.ts +96 -0
  11. package/dist/ml/gs-gs2ml.d.ts.map +1 -0
  12. package/dist/ml/gs-ml-adapters.d.ts +41 -0
  13. package/dist/ml/gs-ml-adapters.d.ts.map +1 -0
  14. package/dist/ml/gs-ml-lib.d.ts +17 -0
  15. package/dist/ml/gs-ml-lib.d.ts.map +1 -0
  16. package/dist/ml/gs-ml2gs.d.ts +10 -0
  17. package/dist/ml/gs-ml2gs.d.ts.map +1 -0
  18. package/dist/ml/gs-mlns.d.ts +10 -0
  19. package/dist/ml/gs-mlns.d.ts.map +1 -0
  20. package/dist/ml/index.d.ts +9 -0
  21. package/dist/ml/index.d.ts.map +1 -0
  22. package/dist/ml/maplibre-map-renderer.d.ts +66 -0
  23. package/dist/ml/maplibre-map-renderer.d.ts.map +1 -0
  24. package/dist/{gs-gs2ol.d.ts → ol/gs-gs2ol.d.ts} +2 -2
  25. package/dist/ol/gs-gs2ol.d.ts.map +1 -0
  26. package/dist/ol/gs-ol-adapters.d.ts.map +1 -0
  27. package/dist/{gs-lib.d.ts → ol/gs-ol-lib.d.ts} +4 -4
  28. package/dist/ol/gs-ol-lib.d.ts.map +1 -0
  29. package/dist/{gs-ol2gs.d.ts → ol/gs-ol2gs.d.ts} +1 -1
  30. package/dist/ol/gs-ol2gs.d.ts.map +1 -0
  31. package/dist/ol/gs-olns.d.ts.map +1 -0
  32. package/dist/ol/index.d.ts +9 -0
  33. package/dist/ol/index.d.ts.map +1 -0
  34. package/dist/ol/openlayers-map-renderer.d.ts +68 -0
  35. package/dist/ol/openlayers-map-renderer.d.ts.map +1 -0
  36. package/package.json +6 -2
  37. package/src/base-map-builder.ts +8 -9
  38. package/src/gs-model.ts +7 -1
  39. package/src/index.ts +12 -7
  40. package/src/map-renderer.ts +115 -0
  41. package/src/ml/gs-gs2ml.ts +717 -0
  42. package/src/ml/gs-ml-adapters.ts +134 -0
  43. package/src/ml/gs-ml-lib.ts +124 -0
  44. package/src/ml/gs-ml2gs.ts +66 -0
  45. package/src/ml/gs-mlns.ts +50 -0
  46. package/src/ml/index.ts +41 -0
  47. package/src/ml/maplibre-map-renderer.ts +428 -0
  48. package/src/{gs-gs2ol.ts → ol/gs-gs2ol.ts} +10 -4
  49. package/src/{gs-lib.ts → ol/gs-ol-lib.ts} +7 -6
  50. package/src/{gs-ol2gs.ts → ol/gs-ol2gs.ts} +1 -1
  51. package/src/ol/index.ts +21 -0
  52. package/src/ol/openlayers-map-renderer.ts +719 -0
  53. package/dist/gs-gs2ol.d.ts.map +0 -1
  54. package/dist/gs-lib.d.ts.map +0 -1
  55. package/dist/gs-ol-adapters.d.ts.map +0 -1
  56. package/dist/gs-ol2gs.d.ts.map +0 -1
  57. package/dist/gs-olns.d.ts.map +0 -1
  58. /package/dist/{gs-ol-adapters.d.ts → ol/gs-ol-adapters.d.ts} +0 -0
  59. /package/dist/{gs-olns.d.ts → ol/gs-olns.d.ts} +0 -0
  60. /package/src/{gs-ol-adapters.ts → ol/gs-ol-adapters.ts} +0 -0
  61. /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
+
@@ -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
+