@maplibre-yaml/core 0.2.2 → 0.3.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.md +21 -0
- package/README.md +44 -16
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +197 -73
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +1 -9
- package/dist/index.js +207 -94
- package/dist/index.js.map +1 -1
- package/dist/{map-renderer-SjO3KQmx.d.ts → map-renderer-4FF3EmBO.d.ts} +130 -3
- package/dist/register.browser.js +6029 -7035
- package/dist/register.browser.js.map +1 -1
- package/dist/register.d.ts +1 -1
- package/dist/register.js +197 -73
- package/dist/register.js.map +1 -1
- package/dist/schemas/index.js +24 -2
- package/dist/schemas/index.js.map +1 -1
- package/package.json +17 -12
- package/register.js +8 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { ColorOrExpressionSchema, ColorSchema, ContentBlockSchema, ContentElementSchema, ContentItemSchema, ExpressionSchema, LatitudeSchema, LngLatBoundsSchema, LngLatSchema, LongitudeSchema, NumberOrExpressionSchema, ValidTagNames, ZoomLevelSchema } from './schemas/index.js';
|
|
2
2
|
import { L as LayerSchema, P as PopupContentSchema, C as ControlsConfigSchema, d as MapConfig, G as GlobalConfig, e as MapBlock } from './page.schema-Cad2FFqh.js';
|
|
3
3
|
export { t as BackgroundLayerSchema, B as BaseLayerPropertiesSchema, _ as Block, W as BlockSchema, N as Chapter, O as ChapterAction, E as ChapterActionSchema, Q as ChapterLayers, J as ChapterLayersSchema, K as ChapterSchema, n as CircleLayerSchema, y as ControlPosition, w as ControlPositionSchema, z as ControlsConfig, r as FillExtrusionLayerSchema, F as FillLayerSchema, h as GeoJSONSourceSchema, Y as GlobalConfigSchema, H as HeatmapLayerSchema, s as HillshadeLayerSchema, I as ImageSourceSchema, l as InteractiveConfigSchema, v as LayerOrReferenceSchema, u as LayerReferenceSchema, c as LayerSourceSchema, A as LegendConfig, a as LegendConfigSchema, m as LegendItemSchema, o as LineLayerSchema, g as LoadingConfigSchema, M as MapBlockSchema, b as MapConfigSchema, D as MapFullPageBlock, x as MapFullPageBlockSchema, Z as MixedBlock, U as MixedBlockSchema, $ as Page, X as PageSchema, k as PopupContentItemSchema, q as RasterLayerSchema, i as RasterSourceSchema, a0 as RootConfig, R as RootSchema, T as ScrollytellingBlock, S as ScrollytellingBlockSchema, f as StreamConfigSchema, p as SymbolLayerSchema, V as VectorSourceSchema, j as VideoSourceSchema } from './page.schema-Cad2FFqh.js';
|
|
4
|
-
export { L as LegendBuilder, M as MapRenderer,
|
|
4
|
+
export { L as LegendBuilder, M as MapRenderer, d as MapRendererEvents, c as MapRendererOptions, P as ParseError, b as ParseResult, S as SafeParseAnyResult, Y as YAMLParser, p as parseYAMLConfig, a as safeParseAny, s as safeParseYAMLConfig } from './map-renderer-4FF3EmBO.js';
|
|
5
5
|
import { Map, LngLat } from 'maplibre-gl';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { FeatureCollection } from 'geojson';
|
|
@@ -33,8 +33,6 @@ declare class LayerManager {
|
|
|
33
33
|
private loadingManager;
|
|
34
34
|
private sourceData;
|
|
35
35
|
private layerToSource;
|
|
36
|
-
private refreshIntervals;
|
|
37
|
-
private abortControllers;
|
|
38
36
|
constructor(map: Map, callbacks?: LayerManagerCallbacks);
|
|
39
37
|
addLayer(layer: Layer): Promise<void>;
|
|
40
38
|
private addSource;
|
|
@@ -66,12 +64,6 @@ declare class LayerManager {
|
|
|
66
64
|
removeLayer(layerId: string): void;
|
|
67
65
|
setVisibility(layerId: string, visible: boolean): void;
|
|
68
66
|
updateData(layerId: string, data: GeoJSON.GeoJSON): void;
|
|
69
|
-
/**
|
|
70
|
-
* @deprecated Legacy refresh method - use PollingManager instead
|
|
71
|
-
*/
|
|
72
|
-
startRefreshInterval(layer: Layer): void;
|
|
73
|
-
stopRefreshInterval(layerId: string): void;
|
|
74
|
-
clearAllIntervals(): void;
|
|
75
67
|
destroy(): void;
|
|
76
68
|
}
|
|
77
69
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z, ZodError } from 'zod';
|
|
2
2
|
import { parse } from 'yaml';
|
|
3
|
-
import
|
|
3
|
+
import * as maplibre from 'maplibre-gl';
|
|
4
4
|
|
|
5
5
|
// @maplibre-yaml/core - Declarative web maps with YAML
|
|
6
6
|
|
|
@@ -104,8 +104,30 @@ var GeoJSONSourceSchema = z.object({
|
|
|
104
104
|
generateId: z.boolean().optional(),
|
|
105
105
|
promoteId: z.union([z.string(), z.record(z.string())]).optional(),
|
|
106
106
|
attribution: z.string().optional()
|
|
107
|
-
}).passthrough().
|
|
108
|
-
|
|
107
|
+
}).passthrough().superRefine((d, ctx) => {
|
|
108
|
+
if (!d.url && !d.data && !d.prefetchedData) {
|
|
109
|
+
ctx.addIssue({
|
|
110
|
+
code: z.ZodIssueCode.custom,
|
|
111
|
+
message: 'GeoJSON source requires at least one of: url, data, or prefetchedData. Use "url" to fetch from an endpoint, "data" for inline GeoJSON, or "prefetchedData" for build-time fetched data.'
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (typeof d.data === "string" && /^(\.\.?|\/?src)\//.test(d.data)) {
|
|
116
|
+
ctx.addIssue({
|
|
117
|
+
code: z.ZodIssueCode.custom,
|
|
118
|
+
path: ["data"],
|
|
119
|
+
// Recommends `data: "/data/..."` rather than `url:` because the
|
|
120
|
+
// `url:` field is schema-validated with z.string().url(), which
|
|
121
|
+
// requires a fully-qualified URL (`https://...`) and rejects
|
|
122
|
+
// root-relative paths. MapLibre treats a string in `data:` as a
|
|
123
|
+
// URL and fetches it correctly. Until url: relaxes to accept
|
|
124
|
+
// root-relative paths (see follow-up), `data: "/path"` is the
|
|
125
|
+
// working pattern for files served from public/.
|
|
126
|
+
message: `GeoJSON source.data must be an inline GeoJSON object or a URL. "${d.data}" is a local source-directory path that won't resolve at runtime. Move the file to public/ and reference the public-served URL:
|
|
127
|
+
data: "/data/<filename>.geojson"
|
|
128
|
+
(\`url:\` requires a fully-qualified https:// URL and won't accept root-relative paths; use \`data:\` for runtime URLs to public assets.)`
|
|
129
|
+
});
|
|
130
|
+
}
|
|
109
131
|
});
|
|
110
132
|
var VectorSourceSchema = z.object({
|
|
111
133
|
type: z.literal("vector").describe("Source type"),
|
|
@@ -1014,6 +1036,95 @@ var YAMLParser = class {
|
|
|
1014
1036
|
};
|
|
1015
1037
|
}
|
|
1016
1038
|
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Detect the document type of a YAML string and validate it against the
|
|
1041
|
+
* matching schema
|
|
1042
|
+
*
|
|
1043
|
+
* @param yaml - YAML string to parse (a map block, a scrollytelling block, or a root document)
|
|
1044
|
+
* @returns Discriminated result with the detected block type and the corresponding safeParse result
|
|
1045
|
+
*
|
|
1046
|
+
* @remarks
|
|
1047
|
+
* Dispatches on the document's top-level `type:` field:
|
|
1048
|
+
*
|
|
1049
|
+
* - `type: map` → {@link safeParseMapBlock}
|
|
1050
|
+
* - `type: scrollytelling` → {@link safeParseScrollytellingBlock}
|
|
1051
|
+
* - no `type:` but a `pages:` key → {@link safeParse} (root document)
|
|
1052
|
+
*
|
|
1053
|
+
* Any other `type:` value produces a failure result listing the valid
|
|
1054
|
+
* values, as does a document that has neither `type:` nor `pages:`.
|
|
1055
|
+
* This method never throws.
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```typescript
|
|
1059
|
+
* const { blockType, result } = YAMLParser.safeParseAny(yamlString);
|
|
1060
|
+
* if (!result.success) {
|
|
1061
|
+
* result.errors.forEach(err => console.error(`${err.path}: ${err.message}`));
|
|
1062
|
+
* } else if (blockType === 'map') {
|
|
1063
|
+
* renderMap(result.data);
|
|
1064
|
+
* }
|
|
1065
|
+
* ```
|
|
1066
|
+
*/
|
|
1067
|
+
static safeParseAny(yaml) {
|
|
1068
|
+
let parsed;
|
|
1069
|
+
try {
|
|
1070
|
+
parsed = parse(yaml);
|
|
1071
|
+
} catch (error) {
|
|
1072
|
+
return {
|
|
1073
|
+
blockType: "unknown",
|
|
1074
|
+
result: {
|
|
1075
|
+
success: false,
|
|
1076
|
+
errors: [
|
|
1077
|
+
{
|
|
1078
|
+
path: "",
|
|
1079
|
+
message: `YAML syntax error: ${error instanceof Error ? error.message : String(error)}`
|
|
1080
|
+
}
|
|
1081
|
+
]
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
const doc = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
1086
|
+
const type = doc?.type;
|
|
1087
|
+
if (type === "map") {
|
|
1088
|
+
return { blockType: "map", result: this.safeParseMapBlock(yaml) };
|
|
1089
|
+
}
|
|
1090
|
+
if (type === "scrollytelling") {
|
|
1091
|
+
return {
|
|
1092
|
+
blockType: "scrollytelling",
|
|
1093
|
+
result: this.safeParseScrollytellingBlock(yaml)
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
if (type !== void 0) {
|
|
1097
|
+
return {
|
|
1098
|
+
blockType: "unknown",
|
|
1099
|
+
result: {
|
|
1100
|
+
success: false,
|
|
1101
|
+
errors: [
|
|
1102
|
+
{
|
|
1103
|
+
path: "type",
|
|
1104
|
+
message: `Unknown block type: ${JSON.stringify(
|
|
1105
|
+
type
|
|
1106
|
+
)}. Expected one of: map, scrollytelling. Root documents omit "type" and use a top-level "pages:" array instead.`
|
|
1107
|
+
}
|
|
1108
|
+
]
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
if (doc !== null && "pages" in doc) {
|
|
1113
|
+
return { blockType: "root", result: this.safeParse(yaml) };
|
|
1114
|
+
}
|
|
1115
|
+
return {
|
|
1116
|
+
blockType: "unknown",
|
|
1117
|
+
result: {
|
|
1118
|
+
success: false,
|
|
1119
|
+
errors: [
|
|
1120
|
+
{
|
|
1121
|
+
path: "",
|
|
1122
|
+
message: 'Unable to determine document type. Expected a block with "type: map" or "type: scrollytelling", or a root document with a top-level "pages:" array.'
|
|
1123
|
+
}
|
|
1124
|
+
]
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1017
1128
|
/**
|
|
1018
1129
|
* Resolve $ref references to global layers and sources
|
|
1019
1130
|
*
|
|
@@ -1179,6 +1290,14 @@ var YAMLParser = class {
|
|
|
1179
1290
|
};
|
|
1180
1291
|
var parseYAMLConfig = YAMLParser.parse.bind(YAMLParser);
|
|
1181
1292
|
var safeParseYAMLConfig = YAMLParser.safeParse.bind(YAMLParser);
|
|
1293
|
+
var safeParseAny = YAMLParser.safeParseAny.bind(YAMLParser);
|
|
1294
|
+
var gl = maplibre.default ?? maplibre;
|
|
1295
|
+
var Map2 = gl.Map;
|
|
1296
|
+
var Popup = gl.Popup;
|
|
1297
|
+
var NavigationControl = gl.NavigationControl;
|
|
1298
|
+
var GeolocateControl = gl.GeolocateControl;
|
|
1299
|
+
var ScaleControl = gl.ScaleControl;
|
|
1300
|
+
var FullscreenControl = gl.FullscreenControl;
|
|
1182
1301
|
|
|
1183
1302
|
// src/data/memory-cache.ts
|
|
1184
1303
|
var MemoryCache = class _MemoryCache {
|
|
@@ -1704,9 +1823,17 @@ var DataFetcher = class _DataFetcher {
|
|
|
1704
1823
|
* Perform the actual HTTP fetch
|
|
1705
1824
|
*/
|
|
1706
1825
|
async performFetch(url, options) {
|
|
1707
|
-
const controller =
|
|
1708
|
-
|
|
1709
|
-
|
|
1826
|
+
const controller = new AbortController();
|
|
1827
|
+
const externalSignal = options.signal;
|
|
1828
|
+
const onExternalAbort = () => controller.abort(externalSignal?.reason);
|
|
1829
|
+
if (externalSignal) {
|
|
1830
|
+
if (externalSignal.aborted) {
|
|
1831
|
+
controller.abort(externalSignal.reason);
|
|
1832
|
+
} else {
|
|
1833
|
+
externalSignal.addEventListener("abort", onExternalAbort, {
|
|
1834
|
+
once: true
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1710
1837
|
}
|
|
1711
1838
|
const timeoutId = setTimeout(() => {
|
|
1712
1839
|
controller.abort();
|
|
@@ -1764,6 +1891,7 @@ var DataFetcher = class _DataFetcher {
|
|
|
1764
1891
|
return data;
|
|
1765
1892
|
} finally {
|
|
1766
1893
|
clearTimeout(timeoutId);
|
|
1894
|
+
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
1767
1895
|
this.activeRequests.delete(url);
|
|
1768
1896
|
}
|
|
1769
1897
|
}
|
|
@@ -3545,9 +3673,6 @@ var LayerManager = class {
|
|
|
3545
3673
|
loadingManager;
|
|
3546
3674
|
sourceData;
|
|
3547
3675
|
layerToSource;
|
|
3548
|
-
// Legacy support (deprecated)
|
|
3549
|
-
refreshIntervals;
|
|
3550
|
-
abortControllers;
|
|
3551
3676
|
constructor(map, callbacks) {
|
|
3552
3677
|
this.map = map;
|
|
3553
3678
|
this.callbacks = callbacks || {};
|
|
@@ -3558,8 +3683,6 @@ var LayerManager = class {
|
|
|
3558
3683
|
this.loadingManager = new LoadingManager({ showUI: false });
|
|
3559
3684
|
this.sourceData = /* @__PURE__ */ new Map();
|
|
3560
3685
|
this.layerToSource = /* @__PURE__ */ new Map();
|
|
3561
|
-
this.refreshIntervals = /* @__PURE__ */ new Map();
|
|
3562
|
-
this.abortControllers = /* @__PURE__ */ new Map();
|
|
3563
3686
|
}
|
|
3564
3687
|
async addLayer(layer) {
|
|
3565
3688
|
const isSourceRef = typeof layer.source === "string";
|
|
@@ -3810,12 +3933,6 @@ var LayerManager = class {
|
|
|
3810
3933
|
this.pollingManager.stop(layerId);
|
|
3811
3934
|
this.streamManager.disconnect(layerId);
|
|
3812
3935
|
this.loadingManager.hideLoading(layerId);
|
|
3813
|
-
this.stopRefreshInterval(layerId);
|
|
3814
|
-
const controller = this.abortControllers.get(layerId);
|
|
3815
|
-
if (controller) {
|
|
3816
|
-
controller.abort();
|
|
3817
|
-
this.abortControllers.delete(layerId);
|
|
3818
|
-
}
|
|
3819
3936
|
if (this.map.getLayer(layerId)) this.map.removeLayer(layerId);
|
|
3820
3937
|
const sourceId = this.layerToSource.get(layerId) || `${layerId}-source`;
|
|
3821
3938
|
const isInlineSource = sourceId === `${layerId}-source`;
|
|
@@ -3838,61 +3955,12 @@ var LayerManager = class {
|
|
|
3838
3955
|
const source = this.map.getSource(sourceId);
|
|
3839
3956
|
if (source && source.setData) source.setData(data);
|
|
3840
3957
|
}
|
|
3841
|
-
/**
|
|
3842
|
-
* @deprecated Legacy refresh method - use PollingManager instead
|
|
3843
|
-
*/
|
|
3844
|
-
startRefreshInterval(layer) {
|
|
3845
|
-
if (typeof layer.source !== "object" || layer.source === null) {
|
|
3846
|
-
return;
|
|
3847
|
-
}
|
|
3848
|
-
const sourceObj = layer.source;
|
|
3849
|
-
if (sourceObj.type !== "geojson" || !sourceObj.url || !sourceObj.refreshInterval) {
|
|
3850
|
-
return;
|
|
3851
|
-
}
|
|
3852
|
-
const geojsonSource = layer.source;
|
|
3853
|
-
const interval = setInterval(async () => {
|
|
3854
|
-
const sourceId = `${layer.id}-source`;
|
|
3855
|
-
try {
|
|
3856
|
-
const cacheEnabled = geojsonSource.cache?.enabled ?? true;
|
|
3857
|
-
const cacheTTL = geojsonSource.cache?.ttl;
|
|
3858
|
-
const result = await this.dataFetcher.fetch(geojsonSource.url, {
|
|
3859
|
-
skipCache: !cacheEnabled,
|
|
3860
|
-
ttl: cacheTTL
|
|
3861
|
-
});
|
|
3862
|
-
const data = result.data;
|
|
3863
|
-
this.sourceData.set(sourceId, data);
|
|
3864
|
-
const source = this.map.getSource(sourceId);
|
|
3865
|
-
if (source?.setData) {
|
|
3866
|
-
source.setData(data);
|
|
3867
|
-
}
|
|
3868
|
-
this.callbacks.onDataLoaded?.(layer.id, data.features.length);
|
|
3869
|
-
} catch (error) {
|
|
3870
|
-
this.callbacks.onDataError?.(layer.id, error);
|
|
3871
|
-
}
|
|
3872
|
-
}, geojsonSource.refreshInterval);
|
|
3873
|
-
this.refreshIntervals.set(layer.id, interval);
|
|
3874
|
-
}
|
|
3875
|
-
stopRefreshInterval(layerId) {
|
|
3876
|
-
const interval = this.refreshIntervals.get(layerId);
|
|
3877
|
-
if (interval) {
|
|
3878
|
-
clearInterval(interval);
|
|
3879
|
-
this.refreshIntervals.delete(layerId);
|
|
3880
|
-
}
|
|
3881
|
-
}
|
|
3882
|
-
clearAllIntervals() {
|
|
3883
|
-
for (const interval of this.refreshIntervals.values())
|
|
3884
|
-
clearInterval(interval);
|
|
3885
|
-
this.refreshIntervals.clear();
|
|
3886
|
-
}
|
|
3887
3958
|
destroy() {
|
|
3888
3959
|
this.pollingManager.destroy();
|
|
3889
3960
|
this.streamManager.destroy();
|
|
3890
3961
|
this.loadingManager.destroy();
|
|
3891
3962
|
this.sourceData.clear();
|
|
3892
3963
|
this.layerToSource.clear();
|
|
3893
|
-
this.clearAllIntervals();
|
|
3894
|
-
for (const controller of this.abortControllers.values()) controller.abort();
|
|
3895
|
-
this.abortControllers.clear();
|
|
3896
3964
|
}
|
|
3897
3965
|
};
|
|
3898
3966
|
|
|
@@ -4029,7 +4097,7 @@ var EventHandler = class {
|
|
|
4029
4097
|
showPopup(content, feature, lngLat) {
|
|
4030
4098
|
this.activePopup?.remove();
|
|
4031
4099
|
const html = this.popupBuilder.build(content, feature.properties);
|
|
4032
|
-
this.activePopup = new
|
|
4100
|
+
this.activePopup = new Popup().setLngLat(lngLat).setHTML(html).addTo(this.map);
|
|
4033
4101
|
}
|
|
4034
4102
|
/**
|
|
4035
4103
|
* Detach events for a layer
|
|
@@ -4119,6 +4187,8 @@ var LegendBuilder = class {
|
|
|
4119
4187
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4120
4188
|
}
|
|
4121
4189
|
};
|
|
4190
|
+
|
|
4191
|
+
// src/renderer/controls-manager.ts
|
|
4122
4192
|
var ControlsManager = class {
|
|
4123
4193
|
map;
|
|
4124
4194
|
addedControls;
|
|
@@ -4134,14 +4204,14 @@ var ControlsManager = class {
|
|
|
4134
4204
|
if (config.navigation) {
|
|
4135
4205
|
const options = typeof config.navigation === "object" ? config.navigation : {};
|
|
4136
4206
|
const position = options.position || "top-right";
|
|
4137
|
-
const control = new
|
|
4207
|
+
const control = new NavigationControl();
|
|
4138
4208
|
this.map.addControl(control, position);
|
|
4139
4209
|
this.addedControls.push(control);
|
|
4140
4210
|
}
|
|
4141
4211
|
if (config.geolocate) {
|
|
4142
4212
|
const options = typeof config.geolocate === "object" ? config.geolocate : {};
|
|
4143
4213
|
const position = options.position || "top-right";
|
|
4144
|
-
const control = new
|
|
4214
|
+
const control = new GeolocateControl({
|
|
4145
4215
|
positionOptions: { enableHighAccuracy: true },
|
|
4146
4216
|
trackUserLocation: true
|
|
4147
4217
|
});
|
|
@@ -4151,14 +4221,14 @@ var ControlsManager = class {
|
|
|
4151
4221
|
if (config.scale) {
|
|
4152
4222
|
const options = typeof config.scale === "object" ? config.scale : {};
|
|
4153
4223
|
const position = options.position || "bottom-left";
|
|
4154
|
-
const control = new
|
|
4224
|
+
const control = new ScaleControl();
|
|
4155
4225
|
this.map.addControl(control, position);
|
|
4156
4226
|
this.addedControls.push(control);
|
|
4157
4227
|
}
|
|
4158
4228
|
if (config.fullscreen) {
|
|
4159
4229
|
const options = typeof config.fullscreen === "object" ? config.fullscreen : {};
|
|
4160
4230
|
const position = options.position || "top-right";
|
|
4161
|
-
const control = new
|
|
4231
|
+
const control = new FullscreenControl();
|
|
4162
4232
|
this.map.addControl(control, position);
|
|
4163
4233
|
this.addedControls.push(control);
|
|
4164
4234
|
}
|
|
@@ -4183,10 +4253,18 @@ var MapRenderer = class {
|
|
|
4183
4253
|
controlsManager;
|
|
4184
4254
|
eventListeners;
|
|
4185
4255
|
isLoaded;
|
|
4256
|
+
containerEl;
|
|
4257
|
+
controlsAdded;
|
|
4258
|
+
legendBuilt;
|
|
4259
|
+
autoLegendContainer;
|
|
4186
4260
|
constructor(container, config, layers = [], options = {}, sources) {
|
|
4187
4261
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
4188
4262
|
this.isLoaded = false;
|
|
4189
|
-
this.
|
|
4263
|
+
this.containerEl = typeof container === "string" ? document.getElementById(container) : container;
|
|
4264
|
+
this.controlsAdded = false;
|
|
4265
|
+
this.legendBuilt = false;
|
|
4266
|
+
this.autoLegendContainer = null;
|
|
4267
|
+
this.map = new Map2({
|
|
4190
4268
|
...config,
|
|
4191
4269
|
container: typeof container === "string" ? container : container,
|
|
4192
4270
|
style: config.mapStyle,
|
|
@@ -4218,6 +4296,12 @@ var MapRenderer = class {
|
|
|
4218
4296
|
}
|
|
4219
4297
|
}
|
|
4220
4298
|
}
|
|
4299
|
+
if (options.controls && !this.controlsAdded) {
|
|
4300
|
+
this.addControls(options.controls);
|
|
4301
|
+
}
|
|
4302
|
+
if (options.legend && !this.legendBuilt) {
|
|
4303
|
+
this.buildLegend(this.createLegendContainer(options.legend), layers, options.legend);
|
|
4304
|
+
}
|
|
4221
4305
|
Promise.all(layers.map((layer) => this.addLayer(layer))).then(() => {
|
|
4222
4306
|
this.emit("load", void 0);
|
|
4223
4307
|
options.onLoad?.();
|
|
@@ -4271,16 +4355,43 @@ var MapRenderer = class {
|
|
|
4271
4355
|
}
|
|
4272
4356
|
/**
|
|
4273
4357
|
* Add controls to the map
|
|
4358
|
+
*
|
|
4359
|
+
* @remarks
|
|
4360
|
+
* Called automatically on map load when a `controls:` config was passed via
|
|
4361
|
+
* {@link MapRendererOptions}. Calling it manually marks controls as added so
|
|
4362
|
+
* the automatic invocation is skipped (no double-add).
|
|
4274
4363
|
*/
|
|
4275
4364
|
addControls(config) {
|
|
4365
|
+
this.controlsAdded = true;
|
|
4276
4366
|
this.controlsManager.addControls(config);
|
|
4277
4367
|
}
|
|
4278
4368
|
/**
|
|
4279
4369
|
* Build legend in container
|
|
4370
|
+
*
|
|
4371
|
+
* @remarks
|
|
4372
|
+
* Called automatically on map load when a `legend:` config was passed via
|
|
4373
|
+
* {@link MapRendererOptions}. Calling it manually marks the legend as built
|
|
4374
|
+
* so the automatic invocation is skipped (no double-build).
|
|
4280
4375
|
*/
|
|
4281
4376
|
buildLegend(container, layers, config) {
|
|
4377
|
+
this.legendBuilt = true;
|
|
4282
4378
|
this.legendBuilder.build(container, layers, config);
|
|
4283
4379
|
}
|
|
4380
|
+
/**
|
|
4381
|
+
* Create a positioned container inside the map element for the auto legend
|
|
4382
|
+
*/
|
|
4383
|
+
createLegendContainer(config) {
|
|
4384
|
+
const el = document.createElement("div");
|
|
4385
|
+
el.className = "ml-map-legend";
|
|
4386
|
+
const position = config.position ?? "top-left";
|
|
4387
|
+
el.style.position = "absolute";
|
|
4388
|
+
el.style.zIndex = "1";
|
|
4389
|
+
el.style[position.includes("top") ? "top" : "bottom"] = "10px";
|
|
4390
|
+
el.style[position.includes("left") ? "left" : "right"] = "10px";
|
|
4391
|
+
(this.containerEl ?? this.map.getContainer()).appendChild(el);
|
|
4392
|
+
this.autoLegendContainer = el;
|
|
4393
|
+
return el;
|
|
4394
|
+
}
|
|
4284
4395
|
/**
|
|
4285
4396
|
* Get the legend builder instance
|
|
4286
4397
|
*/
|
|
@@ -4323,6 +4434,8 @@ var MapRenderer = class {
|
|
|
4323
4434
|
this.eventHandler.destroy();
|
|
4324
4435
|
this.layerManager.destroy();
|
|
4325
4436
|
this.controlsManager.removeAllControls();
|
|
4437
|
+
this.autoLegendContainer?.remove();
|
|
4438
|
+
this.autoLegendContainer = null;
|
|
4326
4439
|
this.eventListeners.clear();
|
|
4327
4440
|
this.map.remove();
|
|
4328
4441
|
}
|
|
@@ -4525,26 +4638,18 @@ var ConfigResolutionError = class extends Error {
|
|
|
4525
4638
|
function resolveMapConfig(mapConfig, globalConfig) {
|
|
4526
4639
|
const center = mapConfig.center ?? globalConfig?.defaultCenter;
|
|
4527
4640
|
const zoom = mapConfig.zoom ?? globalConfig?.defaultZoom;
|
|
4528
|
-
const
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
}
|
|
4541
|
-
if (resolved.center === void 0) {
|
|
4542
|
-
missingFields.push("center");
|
|
4543
|
-
}
|
|
4544
|
-
if (resolved.zoom === void 0) {
|
|
4545
|
-
missingFields.push("zoom");
|
|
4546
|
-
}
|
|
4547
|
-
if (missingFields.length > 0) {
|
|
4641
|
+
const mapStyle = mapConfig.mapStyle ?? globalConfig?.defaultMapStyle;
|
|
4642
|
+
if (!mapStyle || center === void 0 || zoom === void 0) {
|
|
4643
|
+
const missingFields = [];
|
|
4644
|
+
if (!mapStyle) {
|
|
4645
|
+
missingFields.push("mapStyle");
|
|
4646
|
+
}
|
|
4647
|
+
if (center === void 0) {
|
|
4648
|
+
missingFields.push("center");
|
|
4649
|
+
}
|
|
4650
|
+
if (zoom === void 0) {
|
|
4651
|
+
missingFields.push("zoom");
|
|
4652
|
+
}
|
|
4548
4653
|
throw new ConfigResolutionError(
|
|
4549
4654
|
`Map configuration is missing required fields: ${missingFields.join(
|
|
4550
4655
|
", "
|
|
@@ -4552,7 +4657,15 @@ function resolveMapConfig(mapConfig, globalConfig) {
|
|
|
4552
4657
|
missingFields
|
|
4553
4658
|
);
|
|
4554
4659
|
}
|
|
4555
|
-
return
|
|
4660
|
+
return {
|
|
4661
|
+
...mapConfig,
|
|
4662
|
+
center,
|
|
4663
|
+
zoom,
|
|
4664
|
+
mapStyle,
|
|
4665
|
+
interactive: mapConfig.interactive ?? true,
|
|
4666
|
+
pitch: mapConfig.pitch ?? 0,
|
|
4667
|
+
bearing: mapConfig.bearing ?? 0
|
|
4668
|
+
};
|
|
4556
4669
|
}
|
|
4557
4670
|
function resolveMapBlock(mapBlock, globalConfig) {
|
|
4558
4671
|
return {
|
|
@@ -4575,6 +4688,6 @@ function createSimpleMapConfig(options, globalConfig) {
|
|
|
4575
4688
|
return resolveMapConfig(config, globalConfig);
|
|
4576
4689
|
}
|
|
4577
4690
|
|
|
4578
|
-
export { BackgroundLayerSchema, BaseConnection, BaseLayerPropertiesSchema, BlockSchema, ChapterActionSchema, ChapterLayersSchema, ChapterSchema, CircleLayerSchema, ColorOrExpressionSchema, ColorSchema, ConfigResolutionError, ContentBlockSchema, ContentElementSchema, ContentItemSchema, ControlPositionSchema, ControlsConfigSchema, ControlsManager, DataFetcher, DataMerger, EventEmitter, EventHandler, ExpressionSchema, FillExtrusionLayerSchema, FillLayerSchema, GeoJSONSourceSchema, GlobalConfigSchema, HeatmapLayerSchema, HillshadeLayerSchema, ImageSourceSchema, InteractiveConfigSchema, LatitudeSchema, LayerManager, LayerOrReferenceSchema, LayerReferenceSchema, LayerSchema, LayerSourceSchema, LegendBuilder, LegendConfigSchema, LegendItemSchema, LineLayerSchema, LngLatBoundsSchema, LngLatSchema, LoadingConfigSchema, LoadingManager, LongitudeSchema, MapBlockSchema, MapConfigSchema, MapFullPageBlockSchema, MapRenderer, MaxRetriesExceededError, MemoryCache, MixedBlockSchema, NumberOrExpressionSchema, PageSchema, PollingManager, PopupBuilder, PopupContentItemSchema, PopupContentSchema, RasterLayerSchema, RasterSourceSchema, RetryManager, RootSchema, SSEConnection, ScrollytellingBlockSchema, StreamConfigSchema, StreamManager, SymbolLayerSchema, ValidTagNames, VectorSourceSchema, VideoSourceSchema, WebSocketConnection, YAMLParser, ZoomLevelSchema, createSimpleMapConfig, injectLoadingStyles, isMapConfigComplete, loadingStyles, parseYAMLConfig, resolveMapBlock, resolveMapConfig, safeParseYAMLConfig };
|
|
4691
|
+
export { BackgroundLayerSchema, BaseConnection, BaseLayerPropertiesSchema, BlockSchema, ChapterActionSchema, ChapterLayersSchema, ChapterSchema, CircleLayerSchema, ColorOrExpressionSchema, ColorSchema, ConfigResolutionError, ContentBlockSchema, ContentElementSchema, ContentItemSchema, ControlPositionSchema, ControlsConfigSchema, ControlsManager, DataFetcher, DataMerger, EventEmitter, EventHandler, ExpressionSchema, FillExtrusionLayerSchema, FillLayerSchema, GeoJSONSourceSchema, GlobalConfigSchema, HeatmapLayerSchema, HillshadeLayerSchema, ImageSourceSchema, InteractiveConfigSchema, LatitudeSchema, LayerManager, LayerOrReferenceSchema, LayerReferenceSchema, LayerSchema, LayerSourceSchema, LegendBuilder, LegendConfigSchema, LegendItemSchema, LineLayerSchema, LngLatBoundsSchema, LngLatSchema, LoadingConfigSchema, LoadingManager, LongitudeSchema, MapBlockSchema, MapConfigSchema, MapFullPageBlockSchema, MapRenderer, MaxRetriesExceededError, MemoryCache, MixedBlockSchema, NumberOrExpressionSchema, PageSchema, PollingManager, PopupBuilder, PopupContentItemSchema, PopupContentSchema, RasterLayerSchema, RasterSourceSchema, RetryManager, RootSchema, SSEConnection, ScrollytellingBlockSchema, StreamConfigSchema, StreamManager, SymbolLayerSchema, ValidTagNames, VectorSourceSchema, VideoSourceSchema, WebSocketConnection, YAMLParser, ZoomLevelSchema, createSimpleMapConfig, injectLoadingStyles, isMapConfigComplete, loadingStyles, parseYAMLConfig, resolveMapBlock, resolveMapConfig, safeParseAny, safeParseYAMLConfig };
|
|
4579
4692
|
//# sourceMappingURL=index.js.map
|
|
4580
4693
|
//# sourceMappingURL=index.js.map
|