@emuanalytics/flow-rdf-core 4.0.4 → 4.0.5

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 (89) hide show
  1. package/README.md +1 -64
  2. package/dist/index.d.mts +36 -31
  3. package/dist/index.d.ts +36 -31
  4. package/dist/index.mjs +20 -3249
  5. package/dist/lib/context/context-registry.mjs +63 -0
  6. package/dist/lib/context/debugger.mjs +240 -0
  7. package/dist/lib/context/flow-context.mjs +61 -0
  8. package/dist/lib/context/global-state.mjs +70 -0
  9. package/dist/lib/context/map-registry.mjs +59 -0
  10. package/dist/lib/context/query-registry.mjs +53 -0
  11. package/dist/lib/errors/flow-error.mjs +10 -0
  12. package/dist/lib/errors/flow-expression-error.mjs +14 -0
  13. package/dist/lib/errors/flow-map-error.mjs +9 -0
  14. package/dist/lib/expressions/expression-parser.mjs +198 -0
  15. package/dist/lib/expressions/functions/from-palette.mjs +75 -0
  16. package/dist/lib/expressions/functions/regex.mjs +25 -0
  17. package/dist/lib/expressions/functions/state.mjs +25 -0
  18. package/dist/lib/expressions/parser-helpers.mjs +37 -0
  19. package/dist/lib/expressions/reactive-expression.mjs +253 -0
  20. package/dist/lib/map/flow-core-map.mjs +749 -0
  21. package/dist/lib/map/plugins/annotations/annotation-layers.mjs +163 -0
  22. package/dist/lib/map/plugins/annotations/annotation.events.mjs +27 -0
  23. package/dist/lib/map/plugins/annotations/annotation.plugin.mjs +498 -0
  24. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DirectModeOverride.mjs +67 -0
  25. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/modes/DragCircleMode.mjs +65 -0
  26. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/create_supplementary_points_circle.mjs +15 -0
  27. package/dist/lib/map/plugins/annotations/maplibre-gl-draw-circle/lib/utils/drag_pan.mjs +20 -0
  28. package/dist/lib/map/plugins/data-join.plugin.mjs +173 -0
  29. package/dist/lib/map/plugins/export/export.plugin.mjs +21 -0
  30. package/dist/lib/map/plugins/export/map-exporter.mjs +177 -0
  31. package/dist/lib/map/plugins/hover-effect.plugin.mjs +58 -0
  32. package/dist/lib/map/plugins/index.d.mts +37 -72
  33. package/dist/lib/map/plugins/index.d.ts +37 -72
  34. package/dist/lib/map/plugins/index.mjs +11 -1810
  35. package/dist/lib/map/plugins/keyboard-shortcut-manager.mjs +120 -0
  36. package/dist/lib/map/plugins/map-plugin-base.mjs +25 -0
  37. package/dist/lib/map/plugins/plugin-manager.mjs +135 -0
  38. package/dist/lib/map/plugins/popup.plugin.mjs +55 -0
  39. package/dist/lib/map/plugins/selection/selection.events.mjs +21 -0
  40. package/dist/lib/map/plugins/selection/selection.plugin.mjs +136 -0
  41. package/dist/lib/map/plugins/selection/source-selection.mjs +156 -0
  42. package/dist/lib/map/plugins/url-sync.plugin.mjs +55 -0
  43. package/dist/lib/map/support/image-registry.mjs +82 -0
  44. package/dist/lib/map/support/map-events.mjs +71 -0
  45. package/dist/lib/map/support/map-feature-stream.mjs +158 -0
  46. package/dist/lib/map/support/map-popup.mjs +159 -0
  47. package/dist/lib/map/types.mjs +7 -0
  48. package/dist/lib/map-style/map-data-source.mjs +192 -0
  49. package/dist/lib/map-style/map-layer-style-builder-generated.mjs +1307 -0
  50. package/dist/lib/map-style/map-layer-style-builder.mjs +86 -0
  51. package/dist/lib/map-style/map-layer.mjs +223 -0
  52. package/dist/lib/map-style/map-style.mjs +178 -0
  53. package/dist/lib/queries/async-committer.mjs +30 -0
  54. package/dist/lib/queries/query.mjs +172 -0
  55. package/dist/lib/state-store/decorators.mjs +83 -0
  56. package/dist/lib/state-store/state-store.mjs +534 -0
  57. package/dist/lib/state-store/utils.mjs +7 -0
  58. package/dist/lib/utils/announce.mjs +12 -0
  59. package/dist/lib/utils/assert.mjs +12 -0
  60. package/dist/{shared/flow-rdf-core.187cb345.mjs → lib/utils/debounce.mjs} +3 -39
  61. package/dist/lib/utils/decorators.mjs +59 -0
  62. package/dist/lib/utils/deferred.mjs +11 -0
  63. package/dist/lib/utils/ensure-array.mjs +16 -0
  64. package/dist/{shared/flow-rdf-core.1f0901c5.mjs → lib/utils/feature-type-checks.mjs} +2 -2
  65. package/dist/lib/utils/functional.mjs +22 -0
  66. package/dist/lib/utils/global.mjs +18 -0
  67. package/dist/lib/utils/index.mjs +8 -5
  68. package/dist/lib/utils/random-id.mjs +9 -0
  69. package/dist/lib/utils/string-utils.mjs +3 -0
  70. package/dist/lib/utils/throttle.mjs +20 -0
  71. package/dist/{shared/flow-rdf-core.25e5f6d7.mjs → lib/utils/type-checks.mjs} +1 -26
  72. package/dist/lib/utils/watchable-promise.mjs +55 -0
  73. package/dist/package.json.mjs +3 -0
  74. package/dist/shared/{flow-rdf-core.4dde996e.d.cts → flow-rdf-core.8b5acf14.d.mts} +1315 -172
  75. package/dist/shared/{flow-rdf-core.4dde996e.d.ts → flow-rdf-core.8b5acf14.d.ts} +1315 -172
  76. package/package.json +4 -8
  77. package/dist/index.cjs +0 -3316
  78. package/dist/index.d.cts +0 -90
  79. package/dist/lib/map/plugins/index.cjs +0 -1850
  80. package/dist/lib/map/plugins/index.d.cts +0 -345
  81. package/dist/lib/utils/index.cjs +0 -48
  82. package/dist/lib/utils/index.d.cts +0 -160
  83. package/dist/shared/flow-rdf-core.06e85a6c.cjs +0 -1394
  84. package/dist/shared/flow-rdf-core.4dde996e.d.mts +0 -1916
  85. package/dist/shared/flow-rdf-core.55c169ca.cjs +0 -150
  86. package/dist/shared/flow-rdf-core.63162669.d.cts +0 -10
  87. package/dist/shared/flow-rdf-core.65045caf.mjs +0 -1360
  88. package/dist/shared/flow-rdf-core.a82b9be4.cjs +0 -34
  89. package/dist/shared/flow-rdf-core.f50908f0.cjs +0 -102
@@ -1,1810 +1,11 @@
1
- import { M as MapEvent, a as assert, b as MapFeatureStream, F as FlowError, c as FlowMapError, d as MapDataSource, e as MapLayer, R as ReactiveExpression } from '../../../shared/flow-rdf-core.65045caf.mjs';
2
- export { P as PluginManager } from '../../../shared/flow-rdf-core.65045caf.mjs';
3
- import MapboxDraw from '@emuanalytics/mapbox-gl-draw';
4
- import turfArea from '@turf/area';
5
- import turfBBox from '@turf/bbox';
6
- import turfBooleanEqual from '@turf/boolean-equal';
7
- import turfBuffer from '@turf/buffer';
8
- import turfLength from '@turf/length';
9
- import Debug from 'debug';
10
- import { c as isPolygon, i as isLineString, b as isPoint } from '../../../shared/flow-rdf-core.1f0901c5.mjs';
11
- import { d as isDefined, j as isArray, g as isStringFull, x as isFunction, f as isString, e as ensureArray, o as isNumber, A as randomId, z as isURL, k as isArrayFull, b as isNil, a as isNull, m as isObject } from '../../../shared/flow-rdf-core.25e5f6d7.mjs';
12
- import EventEmitter$1, { EventEmitter } from 'eventemitter3';
13
- import maplibre from '@emuanalytics/maplibre-gl';
14
- import * as lit from 'lit-html';
15
- import turfCircle from '@turf/circle';
16
- import turfDistance from '@turf/distance';
17
- import { point } from '@turf/helpers';
18
- import { autorun, toJS } from 'mobx';
19
- import saveAs from 'file-saver';
20
- // import '@emuanalytics/maplibre-gl-style-spec';
21
- // import 'mobx-utils';
22
- import 'parsimmon';
23
- import 'colorbrewer';
24
- import '@turf/invariant';
25
- // import 'nanoid';
26
-
27
- var __defProp$c = Object.defineProperty;
28
- var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
29
- var __publicField$c = (obj, key, value) => {
30
- __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
31
- return value;
32
- };
33
- class AnnotationEvent extends MapEvent {
34
- constructor(type, map, data) {
35
- super(type, map);
36
- __publicField$c(this, "mode");
37
- __publicField$c(this, "canUndo");
38
- __publicField$c(this, "canRedo");
39
- __publicField$c(this, "activeFeatureId");
40
- __publicField$c(this, "activeFeatureType");
41
- __publicField$c(this, "features");
42
- this.mode = data.mode;
43
- this.canUndo = data.canUndo;
44
- this.canRedo = data.canRedo;
45
- this.activeFeatureId = data.activeFeatureId;
46
- this.activeFeatureType = data.activeFeatureType;
47
- this.features = data.features;
48
- }
49
- }
50
-
51
- var __defProp$b = Object.defineProperty;
52
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
53
- var __publicField$b = (obj, key, value) => {
54
- __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
55
- return value;
56
- };
57
- class MapPluginBase extends EventEmitter {
58
- constructor(pluginManager, options) {
59
- super();
60
- __publicField$b(this, "_pluginManager");
61
- __publicField$b(this, "options");
62
- this._pluginManager = pluginManager;
63
- this.options = options ?? {};
64
- }
65
- get map() {
66
- return this._pluginManager.map;
67
- }
68
- get pluginManager() {
69
- return this._pluginManager;
70
- }
71
- }
72
-
73
- function isFeatureWithId(f) {
74
- return isDefined(f) && isDefined(f.source) && isDefined(f.id);
75
- }
76
-
77
- var __defProp$a = Object.defineProperty;
78
- var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
79
- var __publicField$a = (obj, key, value) => {
80
- __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
81
- return value;
82
- };
83
- Debug("flow:map-popup");
84
- class MapPopup extends EventEmitter$1 {
85
- /**
86
- * Constructs a new `MapPopup` instance.
87
- *
88
- * This is called by the `FlowMap::openPopup` method.
89
- *
90
- * @param map Parent Flo.w map.
91
- * @param options Popup options.
92
- */
93
- constructor(map, options) {
94
- super();
95
- this.map = map;
96
- this.options = options;
97
- __publicField$a(this, "_feature");
98
- __publicField$a(this, "_contentContainer");
99
- __publicField$a(this, "_featureStream", null);
100
- //private _featureStreamSubscription: ISubscription | null = null;
101
- __publicField$a(this, "_maplibrePopup", null);
102
- __publicField$a(this, "_featureStreamDisposer");
103
- this.options = {
104
- // Defaults
105
- closeButton: true,
106
- closeOnClick: false,
107
- closeOnMove: false,
108
- maxWidth: "300px",
109
- trackFeature: true,
110
- //
111
- ...this.options
112
- };
113
- }
114
- get feature() {
115
- return this._feature;
116
- }
117
- /**
118
- * Close the popup.
119
- */
120
- close() {
121
- if (this._maplibrePopup) {
122
- this._maplibrePopup.remove();
123
- this._maplibrePopup = null;
124
- }
125
- }
126
- /**
127
- * Move the popup to a new location.
128
- *
129
- * @param lngLat New location.
130
- */
131
- moveTo(lngLat) {
132
- this._maplibrePopup.setLngLat(lngLat);
133
- }
134
- open(eventOrLngLat, feature) {
135
- if (this._maplibrePopup) {
136
- return;
137
- }
138
- if (!isArray(eventOrLngLat)) {
139
- if (isFeatureWithId(eventOrLngLat.features[0])) {
140
- feature = eventOrLngLat.features[0];
141
- }
142
- eventOrLngLat = eventOrLngLat.lngLat;
143
- }
144
- if (feature) {
145
- assert(isFeatureWithId(feature), "MapPopup.open(): feature must have unique ID");
146
- }
147
- this._maplibrePopup = new maplibre.Popup({
148
- className: this.cssClasses().join(" "),
149
- closeButton: this.options.closeButton,
150
- closeOnClick: this.options.closeOnClick,
151
- closeOnMove: this.options.closeOnMove,
152
- maxWidth: this.options.maxWidth
153
- });
154
- this._maplibrePopup.once("close", this.popupCloseHandler.bind(this));
155
- this._contentContainer = document.createElement("div");
156
- this._contentContainer.classList.add("flow-map-popup-content");
157
- this._maplibrePopup.setLngLat(eventOrLngLat).setDOMContent(this._contentContainer).addTo(this.map.maplibreMap);
158
- if (feature) {
159
- this._feature = feature;
160
- this._featureStream = new MapFeatureStream({
161
- map: this.map,
162
- source: feature.source,
163
- sourceLayer: feature.sourceLayer,
164
- featureIds: [feature.id]
165
- });
166
- this._featureStreamDisposer = this.map.context.state.autorun(() => {
167
- const data = this._featureStream?.featureData;
168
- if (data) {
169
- this.handleFeatureUpdate(data[feature.id]);
170
- }
171
- });
172
- } else {
173
- this.moveTo(eventOrLngLat);
174
- this.renderContent(null);
175
- }
176
- }
177
- cssClasses() {
178
- const classes = ["flow-map-popup"];
179
- if (isStringFull(this.options.class)) {
180
- classes.push(this.options.class);
181
- }
182
- if (this.options.closeButton) {
183
- classes.push("flow-map-popup--with-close");
184
- }
185
- return classes;
186
- }
187
- handleFeatureUpdate(feature) {
188
- if (!feature) {
189
- this.close();
190
- return;
191
- }
192
- if (this.options.trackFeature) {
193
- switch (feature.geometry.type) {
194
- case "Point":
195
- this.moveTo(feature.geometry.coordinates);
196
- break;
197
- case "MultiPoint":
198
- this.moveTo(feature.geometry.coordinates[0]);
199
- break;
200
- }
201
- }
202
- this.renderContent(feature);
203
- }
204
- popupCloseHandler() {
205
- if (this._featureStreamDisposer) {
206
- this._featureStreamDisposer();
207
- this._featureStreamDisposer = void 0;
208
- }
209
- this.emit("closed", this);
210
- this.removeAllListeners();
211
- }
212
- renderContent(feature) {
213
- const state = this.map.context.state;
214
- const content = isFunction(this.options.content) ? this.options.content(feature, state) : this.options.content;
215
- if (isString(content)) {
216
- this._contentContainer.innerHTML = content;
217
- } else if (content instanceof Node) {
218
- this._contentContainer.innerHTML = "";
219
- this._contentContainer.appendChild(content);
220
- } else {
221
- lit.render(content, this._contentContainer);
222
- }
223
- }
224
- }
225
-
226
- var __defProp$9 = Object.defineProperty;
227
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
228
- var __publicField$9 = (obj, key, value) => {
229
- __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
230
- return value;
231
- };
232
- class PopupPlugin extends MapPluginBase {
233
- constructor(pluginManager) {
234
- super(pluginManager);
235
- __publicField$9(this, "_popupTemplates", /* @__PURE__ */ new Map());
236
- __publicField$9(this, "_popups", /* @__PURE__ */ new Set());
237
- __publicField$9(this, "name", "PopupPlugin");
238
- }
239
- registerPopup(id, options) {
240
- this._popupTemplates.set(id, options);
241
- }
242
- openPopup(id, eventOrLngLat, feature) {
243
- const popupOptions = this._popupTemplates.get(id);
244
- if (!popupOptions) {
245
- throw new FlowError(`MapPopup: no popup with id '${id}'`);
246
- }
247
- const popup = new MapPopup(this.map, popupOptions);
248
- this._popups.add(popup);
249
- popup.once("closed", () => {
250
- this._popups.delete(popup);
251
- });
252
- if (isArray(eventOrLngLat)) {
253
- popup.open(eventOrLngLat, feature);
254
- } else {
255
- popup.open(eventOrLngLat);
256
- }
257
- return popup;
258
- }
259
- closeAllPopups() {
260
- this._popups.forEach((popup) => popup.close());
261
- this._popups.clear();
262
- }
263
- closePopupsForSources(sources) {
264
- sources = ensureArray(sources);
265
- this._popups.forEach((popup) => {
266
- if (popup.feature?.source && sources.indexOf(popup.feature?.source) >= 0) {
267
- popup.close();
268
- this._popups.delete(popup);
269
- }
270
- });
271
- }
272
- }
273
-
274
- var __defProp$8 = Object.defineProperty;
275
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
276
- var __publicField$8 = (obj, key, value) => {
277
- __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
278
- return value;
279
- };
280
- class SelectionEvent extends MapEvent {
281
- constructor(type, map, sourceIdentifier, features) {
282
- super(type, map);
283
- __publicField$8(this, "source");
284
- __publicField$8(this, "sourceLayer");
285
- __publicField$8(this, "features");
286
- this.source = sourceIdentifier.source;
287
- this.sourceLayer = sourceIdentifier.sourceLayer;
288
- this.features = features;
289
- }
290
- }
291
-
292
- var __defProp$7 = Object.defineProperty;
293
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
294
- var __publicField$7 = (obj, key, value) => {
295
- __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
296
- return value;
297
- };
298
- class SourceSelection {
299
- constructor(plugin, source, options) {
300
- __publicField$7(this, "_featureStream");
301
- __publicField$7(this, "_map");
302
- __publicField$7(this, "_options");
303
- __publicField$7(this, "_plugin");
304
- __publicField$7(this, "_popups", /* @__PURE__ */ new Map());
305
- __publicField$7(this, "_selectedFeatureIds", /* @__PURE__ */ new Set());
306
- __publicField$7(this, "_sourceId");
307
- __publicField$7(this, "_stateSubscription", null);
308
- this._plugin = plugin;
309
- this._map = plugin.map;
310
- this._options = options;
311
- const sourceType = plugin.map.getSource(source).type;
312
- this._sourceId = {
313
- source,
314
- sourceLayer: sourceType === "vector" ? options.sourceLayer ?? "geometry" : void 0
315
- };
316
- this._featureStream = this._map.featureStream({
317
- source,
318
- sourceLayer: options.sourceLayer,
319
- featureIds: []
320
- });
321
- if (options.selectionState) {
322
- this._stateSubscription = this._map.context.state.toStream(options.selectionState, true).subscribe((val) => {
323
- val = new Set(ensureArray(val));
324
- this.updateSelection(val);
325
- });
326
- }
327
- }
328
- get options() {
329
- return this._options;
330
- }
331
- get selectedFeatureIds() {
332
- return this._selectedFeatureIds;
333
- }
334
- get selectedFeatureStream() {
335
- return this._featureStream;
336
- }
337
- destroy() {
338
- this._popups.forEach((popup) => popup.close());
339
- this._stateSubscription?.unsubscribe();
340
- this._selectedFeatureIds = /* @__PURE__ */ new Set();
341
- this.updateMapSelectionState();
342
- }
343
- handleClick(lngLat, feature, selectionOptions, multiSelect, enablePopups) {
344
- if (this._options.mode === "none") {
345
- return;
346
- }
347
- const selectedFeatureIDs = new Set(this._selectedFeatureIds);
348
- let clearSelection = false;
349
- let toggleFeature = false;
350
- let showPopup = false;
351
- if (feature && feature.source === this._sourceId.source) {
352
- if (this._options.mode === "single") {
353
- if (selectedFeatureIDs.has(feature.id)) {
354
- toggleFeature = true;
355
- } else {
356
- clearSelection = true;
357
- toggleFeature = true;
358
- }
359
- } else {
360
- if (!multiSelect) {
361
- clearSelection = true;
362
- }
363
- toggleFeature = true;
364
- }
365
- } else if (feature && feature.source !== this._sourceId.source) {
366
- clearSelection = this._options.clear === "group" ? selectionOptions?.group === this._options.group : !!this._options.clear;
367
- } else {
368
- clearSelection = !multiSelect;
369
- }
370
- if (clearSelection) {
371
- selectedFeatureIDs.clear();
372
- }
373
- if (toggleFeature) {
374
- assert(isFeatureWithId(feature));
375
- if (selectedFeatureIDs.has(feature.id) && multiSelect) {
376
- selectedFeatureIDs.delete(feature.id);
377
- if (this._popups.has(feature.id))
378
- this._popups.get(feature.id).close();
379
- } else {
380
- selectedFeatureIDs.add(feature.id);
381
- showPopup = true;
382
- }
383
- }
384
- this.updateSelection(selectedFeatureIDs);
385
- if (enablePopups && showPopup && this._options.popup) {
386
- assert(isFeatureWithId(feature));
387
- if (!this._popups.has(feature.id)) {
388
- const popup = this._map.getPlugin(PopupPlugin).openPopup(this._options.popup, lngLat, feature);
389
- if (popup) {
390
- popup.on("closed", () => {
391
- this._popups.delete(feature.id);
392
- });
393
- this._popups.set(feature.id, popup);
394
- }
395
- }
396
- }
397
- }
398
- updateSelection(featureIds) {
399
- if (!this.areSetsEqual(featureIds, this._selectedFeatureIds)) {
400
- this._selectedFeatureIds = featureIds;
401
- this.updateMapSelectionState();
402
- this.updateStateStore();
403
- this._featureStream.featureIds = Array.from(featureIds);
404
- this._popups.forEach((popup) => {
405
- assert(isFeatureWithId(popup.feature));
406
- if (popup.feature.id && !featureIds.has(popup.feature.id)) {
407
- popup.close();
408
- }
409
- });
410
- const event = new SelectionEvent(
411
- "selectionChanged",
412
- this._map,
413
- this._sourceId,
414
- Array.from(this._selectedFeatureIds)
415
- );
416
- this._plugin.emit(event.type, event);
417
- }
418
- }
419
- areSetsEqual(a, b) {
420
- return a.size === b.size && [...a].every((value) => b.has(value));
421
- }
422
- updateMapSelectionState() {
423
- this._map.removeFeatureState(this._sourceId, "selected", false);
424
- this._selectedFeatureIds.forEach(
425
- (id) => this._map.setFeatureState({ ...this._sourceId, id }, { selected: true }, false)
426
- );
427
- }
428
- updateStateStore() {
429
- if (isStringFull(this._options.selectionState)) {
430
- const selectedIds = Array.from(this._selectedFeatureIds);
431
- if (this._options.mode === "single") {
432
- this._map.context.state.set(this._options.selectionState, selectedIds[0]);
433
- } else if (this._options.mode === "multi") {
434
- this._map.context.state.set(this._options.selectionState, selectedIds);
435
- }
436
- }
437
- }
438
- }
439
-
440
- var __defProp$6 = Object.defineProperty;
441
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
442
- var __publicField$6 = (obj, key, value) => {
443
- __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
444
- return value;
445
- };
446
- class SelectionPlugin extends MapPluginBase {
447
- constructor(pluginManager) {
448
- super(pluginManager);
449
- __publicField$6(this, "_sourceSelections", /* @__PURE__ */ new Map());
450
- __publicField$6(this, "_enablePopups", true);
451
- __publicField$6(this, "name", "SelectionPlugin");
452
- }
453
- clearSelection(source) {
454
- const sourceSelection = this._sourceSelections.get(source);
455
- if (!sourceSelection) {
456
- return;
457
- }
458
- switch (sourceSelection.options.mode) {
459
- case "single":
460
- case "multi":
461
- sourceSelection.updateSelection(/* @__PURE__ */ new Set());
462
- }
463
- }
464
- deselectFeatures(source, features) {
465
- const sourceSelection = this._sourceSelections.get(source);
466
- if (!sourceSelection) {
467
- return;
468
- }
469
- features = ensureArray(features);
470
- const currentSelection = new Set(sourceSelection.selectedFeatureIds);
471
- switch (sourceSelection.options.mode) {
472
- case "single":
473
- case "multi":
474
- features.forEach((f) => currentSelection.delete(f));
475
- sourceSelection.updateSelection(currentSelection);
476
- }
477
- }
478
- destroy() {
479
- this._sourceSelections.forEach((sel) => sel.destroy());
480
- this._sourceSelections.clear();
481
- }
482
- disableSelection(source) {
483
- if (this._sourceSelections.has(source)) {
484
- this._sourceSelections.get(source).destroy();
485
- this._sourceSelections.delete(source);
486
- }
487
- }
488
- enableSelection(source, options) {
489
- if (options.popup) {
490
- try {
491
- this.map.getPlugin(PopupPlugin);
492
- } catch (e) {
493
- throw new FlowMapError(`enableSelection(): Popup plugin is required for automatic selection popups`);
494
- }
495
- }
496
- this.disableSelection(source);
497
- this._sourceSelections.set(source, new SourceSelection(this, source, options));
498
- }
499
- handleBeforeSourceRemoved(event) {
500
- if (this._sourceSelections.has(event.source)) {
501
- this._sourceSelections.get(event.source)?.destroy();
502
- this._sourceSelections.delete(event.source);
503
- }
504
- }
505
- handleClick(event) {
506
- const multiSelect = event.originalEvent.shiftKey || event.originalEvent.altKey || event.originalEvent.metaKey;
507
- const clickedFeature = event.features[0];
508
- const clickedSource = clickedFeature?.source;
509
- const selectionOptions = this._sourceSelections.get(clickedSource)?.options;
510
- this._sourceSelections.forEach(
511
- (sel) => sel.handleClick(event.lngLat, clickedFeature, selectionOptions, multiSelect, this._enablePopups)
512
- );
513
- }
514
- selectFeatures(source, features) {
515
- const sourceSelection = this._sourceSelections.get(source);
516
- if (!sourceSelection) {
517
- return;
518
- }
519
- features = ensureArray(features);
520
- if (features.length === 0) {
521
- this.clearSelection(source);
522
- return;
523
- }
524
- let currentSelection = new Set(sourceSelection.selectedFeatureIds);
525
- switch (sourceSelection.options.mode) {
526
- case "single":
527
- currentSelection = /* @__PURE__ */ new Set([features[0]]);
528
- sourceSelection.updateSelection(currentSelection);
529
- break;
530
- case "multi":
531
- features.forEach((f) => currentSelection.add(f));
532
- sourceSelection.updateSelection(currentSelection);
533
- break;
534
- }
535
- if (sourceSelection.selectedFeatureIds.size && isStringFull(sourceSelection.options.group)) {
536
- this._sourceSelections.forEach((s) => {
537
- if (s != sourceSelection && s.options.clear === "group" && s.options.group == sourceSelection.options.group) {
538
- s.updateSelection(/* @__PURE__ */ new Set());
539
- }
540
- });
541
- }
542
- }
543
- selectedFeatureIds(source) {
544
- const sourceSelection = this._sourceSelections.get(source);
545
- if (!sourceSelection) {
546
- return [];
547
- }
548
- return Array.from(sourceSelection.selectedFeatureIds);
549
- }
550
- selectedFeatureStream(source) {
551
- const sourceSelection = this._sourceSelections.get(source);
552
- if (!sourceSelection) {
553
- throw new FlowMapError("no source selection");
554
- }
555
- return sourceSelection.selectedFeatureStream;
556
- }
557
- enablePopups(enabled = true) {
558
- this._enablePopups = true;
559
- }
560
- disablePopups() {
561
- if (this._enablePopups) {
562
- this.map.getPlugin(PopupPlugin).closeAllPopups();
563
- this._enablePopups = false;
564
- }
565
- }
566
- }
567
-
568
- function addAnnotationLayers(map) {
569
- map.transaction(() => {
570
- const annotationSource = new MapDataSource({
571
- id: "map-annotations",
572
- type: "geojson",
573
- src: { type: "FeatureCollection", features: [] },
574
- featureId: "id"
575
- });
576
- map.addSource(annotationSource);
577
- const polygonFillLayer = new MapLayer({
578
- id: "map-annotations-polygon-fill",
579
- type: "fill",
580
- source: annotationSource.id,
581
- filter: `geometry-type() == 'Polygon' && coalesce(@visible, true)`,
582
- style: `
583
- fill-color: @fillColor;
584
- `
585
- });
586
- map.addLayer(polygonFillLayer);
587
- const polygonStrokeLayer = new MapLayer({
588
- id: "map-annotations-polygon-stroke",
589
- type: "line",
590
- source: annotationSource.id,
591
- filter: `geometry-type() == 'Polygon' && coalesce(@visible, true)`,
592
- style: `
593
- line-color: @strokeColor;
594
- line-width: @strokeWidth;
595
- `
596
- });
597
- map.addLayer(polygonStrokeLayer);
598
- const lineStrokeLayer = new MapLayer({
599
- id: "map-annotations-line-stroke",
600
- type: "line",
601
- source: annotationSource.id,
602
- filter: `geometry-type() == 'LineString' && coalesce(@visible, true)`,
603
- style: `
604
- line-color: @strokeColor;
605
- line-width: @strokeWidth;
606
- `
607
- });
608
- map.addLayer(lineStrokeLayer);
609
- const pointLayer = new MapLayer({
610
- id: "map-annotations-point",
611
- type: "circle",
612
- source: annotationSource.id,
613
- filter: `geometry-type() == 'Point' && coalesce(@visible, true)`,
614
- style: `
615
- circle-radius: @radius;
616
- circle-color: @fillColor;
617
- circle-stroke-color: @strokeColor;
618
- circle-stroke-width: @strokeWidth;
619
- `
620
- });
621
- map.addLayer(pointLayer);
622
- const polygonLabelsLayer = new MapLayer({
623
- id: "map-annotations-polygon-labels",
624
- type: "symbol",
625
- source: annotationSource.id,
626
- filter: `geometry-type() == 'Polygon' && to-boolean(@labelText) && coalesce(@visible, true)`,
627
- interactive: false,
628
- style: `
629
- symbol-placement: 'point';
630
- text-field: @labelText;
631
- text-color: @labelColor;
632
- text-size: @labelSize;
633
- text-anchor: @polygonLabelAnchor;
634
- /* text-offset: @labelOffset; */
635
- text-justify: @labelJustify;
636
- text-max-width: @labelMaxWidth;
637
- text-allow-overlap: true;
638
- `
639
- });
640
- map.addLayer(polygonLabelsLayer);
641
- const pointLabelsLayer = new MapLayer({
642
- id: "map-annotations-point-labels",
643
- type: "symbol",
644
- source: annotationSource.id,
645
- filter: `geometry-type() == 'Point' && to-boolean(@labelText) && coalesce(@visible, true)`,
646
- interactive: false,
647
- style: `
648
- symbol-placement: 'point';
649
- text-field: @labelText;
650
- text-color: @labelColor;
651
- text-size: @labelSize;
652
- text-anchor: @labelAnchor;
653
- text-offset: @labelOffset;
654
- /* text-radial-offset: (@radius + 8) / coalesce(@labelSize, {{annotationsStyleDefaults.labelSize}}); */
655
- text-justify: @labelJustify;
656
- text-max-width: @labelMaxWidth;
657
- text-allow-overlap: true;
658
- `
659
- });
660
- map.addLayer(pointLabelsLayer);
661
- const lineLabelsLayer = new MapLayer({
662
- id: "map-annotations-line-labels",
663
- type: "symbol",
664
- source: annotationSource.id,
665
- filter: `geometry-type() == 'LineString' && to-boolean(@labelText) && coalesce(@visible, true)`,
666
- interactive: false,
667
- style: `
668
- symbol-placement: 'line-center';
669
- text-field: @labelText;
670
- text-color: @labelColor;
671
- text-anchor: @labelAnchor;
672
- text-size: @labelSize;
673
- /* text-offset: @labelOffset; */
674
- text-justify: @labelJustify;
675
- text-max-width: @labelMaxWidth;
676
- text-allow-overlap: true;
677
- text-ignore-placement: true;
678
- `
679
- });
680
- map.addLayer(lineLabelsLayer);
681
- const polygonSelectionLayer = new MapLayer({
682
- id: "map-annotations-polygon-selection",
683
- type: "line",
684
- source: annotationSource.id,
685
- filter: `geometry-type() == 'Polygon' && coalesce(@visible, true)`,
686
- interactive: false,
687
- style: `
688
- line-color: @@selected ? @selectionStrokeColor : @@hover ? @hoverStrokeColor : transparent;
689
- line-width: @selectionWidth;
690
- line-opacity: @selectionStrokeOpacity;
691
- `
692
- });
693
- map.addLayer(polygonSelectionLayer);
694
- const pointSelectionLayer = new MapLayer({
695
- id: "map-annotations-point-selection",
696
- type: "circle",
697
- source: annotationSource.id,
698
- filter: `geometry-type() == 'Point' && coalesce(@visible, true)`,
699
- interactive: false,
700
- style: `
701
- circle-radius: @radius + 1;
702
- circle-color: transparent;
703
- circle-stroke-color: @@selected ? @selectionStrokeColor : @@hover ? @hoverStrokeColor : transparent;
704
- circle-stroke-width: @selectionWidth;
705
- circle-stroke-opacity: @selectionStrokeOpacity;
706
- `
707
- });
708
- map.addLayer(pointSelectionLayer);
709
- const lineSelectionLayer = new MapLayer({
710
- id: "map-annotations-line-selection",
711
- type: "line",
712
- source: annotationSource.id,
713
- filter: `geometry-type() == 'LineString' && coalesce(@visible, true)`,
714
- interactive: false,
715
- style: `
716
- line-color: @@selected ? @selectionStrokeColor : @@hover ? @hoverStrokeColor : transparent;
717
- line-opacity: @selectionStrokeOpacity;
718
- line-width: @selectionWidth/2;
719
- line-gap-width: @strokeWidth;
720
- `
721
- });
722
- map.addLayer(lineSelectionLayer);
723
- });
724
- return map.getSource("map-annotations");
725
- }
726
-
727
- function createSupplementaryPointsForCircle(geojson) {
728
- const { properties, geometry } = geojson;
729
- if (properties.user_type !== "Circle")
730
- return null;
731
- const supplementaryPoints = [];
732
- const vertices = geometry.coordinates[0].slice(0, -1);
733
- for (let index = 0; index < vertices.length; index += Math.round(vertices.length / 4)) {
734
- supplementaryPoints.push(MapboxDraw.lib.createVertex(properties.id, vertices[index], `0.${index}`, false));
735
- }
736
- return supplementaryPoints;
737
- }
738
-
739
- const DirectModeOverride = MapboxDraw.modes.direct_select;
740
- const moveFeatures = MapboxDraw.lib.moveFeatures;
741
- const constrainFeatureMovement = MapboxDraw.lib.constrainFeatureMovement;
742
- const createSupplementaryPoints = MapboxDraw.lib.createSupplementaryPoints;
743
- const Constants$1 = MapboxDraw.constants;
744
- DirectModeOverride.dragFeature = function(state, e, delta) {
745
- moveFeatures(this.getSelected(), delta);
746
- this.getSelected().filter((feature) => feature.properties.type === "Circle").map((circle) => circle.properties.circleCenter).forEach((center) => {
747
- center[0] += delta.lng;
748
- center[1] += delta.lat;
749
- });
750
- state.dragMoveLocation = e.lngLat;
751
- };
752
- DirectModeOverride.dragVertex = function(state, e, delta) {
753
- if (state.feature.properties.type === "Circle") {
754
- const center = state.feature.properties.circleCenter;
755
- const movedVertex = [e.lngLat.lng, e.lngLat.lat];
756
- const radius = turfDistance(point(center), point(movedVertex), { units: "kilometers" });
757
- const circleFeature = turfCircle(center, radius);
758
- state.feature.incomingCoords(circleFeature.geometry.coordinates);
759
- state.feature.properties.circleRadius = radius;
760
- } else {
761
- const selectedCoords = state.selectedCoordPaths.map((coord_path) => state.feature.getCoordinate(coord_path));
762
- const selectedCoordPoints = selectedCoords.map((coords) => ({
763
- type: Constants$1.geojsonTypes.FEATURE,
764
- properties: {},
765
- geometry: {
766
- type: Constants$1.geojsonTypes.POINT,
767
- coordinates: coords
768
- }
769
- }));
770
- const constrainedDelta = constrainFeatureMovement(selectedCoordPoints, delta);
771
- for (let i = 0; i < selectedCoords.length; i++) {
772
- const coord = selectedCoords[i];
773
- state.feature.updateCoordinate(state.selectedCoordPaths[i], coord[0] + constrainedDelta.lng, coord[1] + constrainedDelta.lat);
774
- }
775
- }
776
- };
777
- DirectModeOverride.toDisplayFeatures = function(state, geojson, push) {
778
- if (state.featureId === geojson.properties.id) {
779
- geojson.properties.active = Constants$1.activeStates.ACTIVE;
780
- push(geojson);
781
- const supplementaryPoints = geojson.properties.user_type === "Circle" ? createSupplementaryPointsForCircle(geojson) : createSupplementaryPoints(geojson, {
782
- map: this.map,
783
- midpoints: true,
784
- selectedPaths: state.selectedCoordPaths
785
- });
786
- supplementaryPoints.forEach(push);
787
- } else {
788
- geojson.properties.active = Constants$1.activeStates.INACTIVE;
789
- push(geojson);
790
- }
791
- this.fireActionable(state);
792
- };
793
- const DirectMode = DirectModeOverride;
794
-
795
- const dragPan = {
796
- enable(ctx) {
797
- setTimeout(() => {
798
- if (!ctx.map || !ctx.map.dragPan || !ctx._ctx || !ctx._ctx.store || !ctx._ctx.store.getInitialConfigValue)
799
- return;
800
- if (!ctx._ctx.store.getInitialConfigValue("dragPan"))
801
- return;
802
- ctx.map.dragPan.enable();
803
- }, 0);
804
- },
805
- disable(ctx) {
806
- setTimeout(() => {
807
- if (!ctx.map || !ctx.map.doubleClickZoom)
808
- return;
809
- ctx.map.dragPan.disable();
810
- }, 0);
811
- }
812
- };
813
-
814
- const DragCircleMode = { ...MapboxDraw.modes.draw_polygon };
815
- const Constants = MapboxDraw.constants;
816
- DragCircleMode.onSetup = function(opts) {
817
- const polygon = this.newFeature({
818
- type: Constants.geojsonTypes.FEATURE,
819
- properties: {
820
- type: "Circle",
821
- circleCenter: []
822
- },
823
- geometry: {
824
- type: Constants.geojsonTypes.POLYGON,
825
- coordinates: []
826
- }
827
- });
828
- this.addFeature(polygon);
829
- this.clearSelectedFeatures();
830
- dragPan.disable(this);
831
- this.updateUIClasses({ mouse: Constants.cursors.ADD });
832
- this.activateUIButton(Constants.types.POLYGON);
833
- this.setActionableState({
834
- trash: true
835
- });
836
- return {
837
- polygon,
838
- currentVertexPosition: 0
839
- };
840
- };
841
- DragCircleMode.onMouseDown = DragCircleMode.onTouchStart = function(state, e) {
842
- const currentCenter = state.polygon.properties.circleCenter;
843
- if (currentCenter.length === 0) {
844
- state.polygon.properties.circleCenter = [e.lngLat.lng, e.lngLat.lat];
845
- }
846
- };
847
- DragCircleMode.onDrag = DragCircleMode.onMouseMove = function(state, e) {
848
- const center = state.polygon.properties.circleCenter;
849
- if (center.length > 0) {
850
- const distanceInKm = turfDistance(
851
- point(center),
852
- point([e.lngLat.lng, e.lngLat.lat]),
853
- { units: "kilometers" }
854
- );
855
- const circleFeature = turfCircle(center, distanceInKm);
856
- state.polygon.incomingCoords(circleFeature.geometry.coordinates);
857
- state.polygon.properties.circleRadius = distanceInKm;
858
- }
859
- };
860
- DragCircleMode.onMouseUp = DragCircleMode.onTouchEnd = function(state) {
861
- dragPan.enable(this);
862
- return this.changeMode(Constants.modes.SIMPLE_SELECT, { featureIds: [state.polygon.id] });
863
- };
864
- DragCircleMode.onClick = DragCircleMode.onTap = function(state) {
865
- state.polygon.properties.circleCenter = [];
866
- };
867
- DragCircleMode.toDisplayFeatures = function(state, geojson, display) {
868
- const isActivePolygon = geojson.properties.id === state.polygon.id;
869
- geojson.properties.active = isActivePolygon ? Constants.activeStates.ACTIVE : Constants.activeStates.INACTIVE;
870
- return display(geojson);
871
- };
872
- const DragCircleMode$1 = DragCircleMode;
873
-
874
- var __defProp$5 = Object.defineProperty;
875
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
876
- var __publicField$5 = (obj, key, value) => {
877
- __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
878
- return value;
879
- };
880
- Debug("flow:annotation-plugin");
881
- const _AnnotationPlugin = class _AnnotationPlugin extends MapPluginBase {
882
- constructor(pluginManager, options) {
883
- super(pluginManager, options);
884
- __publicField$5(this, "name", "AnnotationPlugin");
885
- // Feature data model
886
- __publicField$5(this, "_features", /* @__PURE__ */ new Map());
887
- __publicField$5(this, "_featureIds", []);
888
- // Undo/redo stacks
889
- __publicField$5(this, "_undoStack", []);
890
- __publicField$5(this, "_redoStack", []);
891
- // Editing state
892
- __publicField$5(this, "_mode", "idle");
893
- __publicField$5(this, "_activeFeatureId", null);
894
- __publicField$5(this, "_activeFeatureType", null);
895
- __publicField$5(this, "_onCommitCleanup", []);
896
- __publicField$5(this, "_annotationDataSource");
897
- __publicField$5(this, "_drawControl", null);
898
- __publicField$5(this, "_removeKeyboardShortcuts", null);
899
- this.options = { ..._AnnotationPlugin._defaultOptions, ...options };
900
- this.options.defaultStyle = { ..._AnnotationPlugin._defaultOptions.defaultStyle, ...options?.defaultStyle };
901
- }
902
- initialize() {
903
- this._annotationDataSource = addAnnotationLayers(this.map);
904
- if (this.options.selectionOptions) {
905
- this.map.getPlugin(SelectionPlugin).enableSelection(this._annotationDataSource.id, this.options.selectionOptions);
906
- }
907
- if (this.options.interactive) {
908
- this._removeKeyboardShortcuts = this.pluginManager.addKeyboardShortcuts({
909
- "Enter,Escape": () => {
910
- this.commit();
911
- },
912
- "Delete,Backspace": () => this.deleteSelectedFeature(),
913
- "Ctrl+KeyZ": () => {
914
- this.undo();
915
- },
916
- "Ctrl+Shift+KeyZ": () => {
917
- this.redo();
918
- },
919
- KeyP: () => this.createFeature("Polygon"),
920
- KeyL: () => this.createFeature("LineString"),
921
- KeyM: () => this.createFeature("Point"),
922
- KeyC: () => this.createFeature("Circle")
923
- });
924
- }
925
- }
926
- destroy() {
927
- if (this._removeKeyboardShortcuts)
928
- this._removeKeyboardShortcuts();
929
- }
930
- clear() {
931
- this.commit();
932
- this._featureIds = [];
933
- this._features = /* @__PURE__ */ new Map();
934
- this._undoStack = [];
935
- this._redoStack = [];
936
- this._mode = "idle";
937
- this._activeFeatureId = null;
938
- this._activeFeatureType = null;
939
- this.render();
940
- return this;
941
- }
942
- undo() {
943
- const operation = this._undoStack.pop();
944
- if (operation) {
945
- operation.undo();
946
- this._redoStack.push(operation);
947
- this.render();
948
- }
949
- return this;
950
- }
951
- /**
952
- * Redo the last undone operation.
953
- */
954
- redo() {
955
- const operation = this._redoStack.pop();
956
- if (operation) {
957
- operation.do();
958
- this._undoStack.push(operation);
959
- this.render();
960
- }
961
- return this;
962
- }
963
- getFeature(featureId) {
964
- const feature = this._features.get(featureId);
965
- if (!feature) {
966
- throw new FlowError(`<AnnotationPlugin>: No feature with id '${featureId}'`);
967
- }
968
- return feature;
969
- }
970
- getFeatures() {
971
- return this._featureIds.map((id) => this._features.get(id));
972
- }
973
- setFeatures(features) {
974
- this.commit();
975
- const normalizedFeatures = features.map((f) => this.applyDefaults(f));
976
- const oldFeatures = this._features;
977
- const oldFeatureIds = this._featureIds;
978
- const operation = {
979
- do: () => {
980
- this._featureIds = normalizedFeatures.map((f) => f.id);
981
- this._features = new Map(normalizedFeatures.map((f) => [f.id, f]));
982
- },
983
- undo: () => {
984
- this._featureIds = oldFeatureIds;
985
- this._features = oldFeatures;
986
- }
987
- };
988
- this.performOperation(operation);
989
- return this;
990
- }
991
- addFeature(feature) {
992
- this.commit();
993
- const fullFeature = this.applyDefaults(feature);
994
- const operation = {
995
- do: () => {
996
- this._features.set(fullFeature.id, fullFeature);
997
- this._featureIds.push(fullFeature.id);
998
- },
999
- undo: () => {
1000
- this._features.delete(fullFeature.id);
1001
- const index = this._featureIds.indexOf(fullFeature.id);
1002
- if (index !== -1) {
1003
- this._featureIds.splice(index, 1);
1004
- }
1005
- }
1006
- };
1007
- this.performOperation(operation);
1008
- return fullFeature;
1009
- }
1010
- deleteFeature(featureId) {
1011
- this.commit();
1012
- if (!featureId) {
1013
- return this;
1014
- }
1015
- this.deselectFeature(featureId);
1016
- const feature = this.getFeature(featureId);
1017
- const operation = {
1018
- do: () => {
1019
- this._features.delete(featureId);
1020
- const index = this._featureIds.indexOf(featureId);
1021
- if (index !== -1) {
1022
- this._featureIds.splice(index, 1);
1023
- }
1024
- },
1025
- undo: () => {
1026
- this._features.set(featureId, feature);
1027
- this._featureIds.push(featureId);
1028
- }
1029
- };
1030
- this.performOperation(operation);
1031
- return this;
1032
- }
1033
- createFeature(featureType) {
1034
- this.commit();
1035
- this.startDrawing();
1036
- this._drawControl.changeMode(this.drawModeForFeatureType(featureType));
1037
- this._mode = "creating";
1038
- this._activeFeatureId = null;
1039
- this._activeFeatureType = featureType;
1040
- this.emitStateChange();
1041
- const commitChanges = () => {
1042
- setTimeout(() => this.commit(), 0);
1043
- };
1044
- this.map.maplibreMap.once("draw.create", commitChanges);
1045
- this.map.maplibreMap.once("draw.modechange", commitChanges);
1046
- this._onCommitCleanup.push(() => {
1047
- this.map.maplibreMap.off("draw.create", commitChanges);
1048
- this.map.maplibreMap.off("draw.modechange", commitChanges);
1049
- });
1050
- }
1051
- editFeature(featureId) {
1052
- const feature = this.getFeature(featureId);
1053
- this._mode = "editing";
1054
- this._activeFeatureId = featureId;
1055
- this._activeFeatureType = feature.properties.type;
1056
- const commitChanges = () => {
1057
- setTimeout(() => this.commit(), 0);
1058
- };
1059
- this.startDrawing();
1060
- this._drawControl.add(feature);
1061
- this.setFeatureProperty(featureId, "visible", false);
1062
- this.render();
1063
- switch (this.editModeForFeature(feature)) {
1064
- case "direct_select":
1065
- this._drawControl.changeMode("direct_select", {
1066
- featureId
1067
- });
1068
- this.map.maplibreMap.once("draw.modechange", commitChanges);
1069
- this._onCommitCleanup.push(() => this.map.maplibreMap.off("draw.modechange", commitChanges));
1070
- break;
1071
- case "simple_select":
1072
- this._drawControl.changeMode("simple_select", {
1073
- featureIds: [featureId]
1074
- });
1075
- this.map.maplibreMap.once("draw.selectionchange", commitChanges);
1076
- this._onCommitCleanup.push(() => this.map.maplibreMap.off("draw.selectionchange", commitChanges));
1077
- break;
1078
- }
1079
- }
1080
- zoomToFeature(featureId, animationOptions) {
1081
- const feature = this.getFeature(featureId);
1082
- if (!feature)
1083
- return this;
1084
- const bbox = feature.properties.type === "Point" ? turfBBox(turfBuffer(feature, 50)) : turfBBox(feature);
1085
- this.map.setBounds(bbox, animationOptions);
1086
- return this;
1087
- }
1088
- setFeatureProperty(featureId, property, value) {
1089
- const feature = this.getFeature(featureId);
1090
- const featureCopy = {
1091
- ...feature,
1092
- properties: { ...feature.properties, [property]: value }
1093
- };
1094
- this._features.set(featureId, featureCopy);
1095
- return this;
1096
- }
1097
- setFeatureProperties(featureId, properties) {
1098
- const feature = this.getFeature(featureId);
1099
- const featureCopy = {
1100
- ...feature,
1101
- properties: { ...feature.properties, ...properties }
1102
- };
1103
- this._features.set(featureId, featureCopy);
1104
- return this;
1105
- }
1106
- commit() {
1107
- this._onCommitCleanup.forEach((f) => f());
1108
- this._onCommitCleanup = [];
1109
- if (this._mode === "idle")
1110
- return this;
1111
- const drawControlFeature = this._drawControl.getAll().features[0];
1112
- let operation = null;
1113
- if (this._mode === "editing") {
1114
- const mapFeature = this.getFeature(this._activeFeatureId);
1115
- this.setFeatureProperty(mapFeature.id, "visible", true);
1116
- if (!turfBooleanEqual(mapFeature.geometry, drawControlFeature.geometry)) {
1117
- operation = {
1118
- do: () => {
1119
- this.setFeatureGeometry(mapFeature.id, drawControlFeature.geometry);
1120
- if (drawControlFeature.properties.type === "Circle") {
1121
- this.setFeatureProperty(mapFeature.id, "center", drawControlFeature.properties.circleCenter);
1122
- this.setFeatureProperty(mapFeature.id, "radiusInKm", drawControlFeature.properties.circleRadius);
1123
- }
1124
- },
1125
- undo: () => {
1126
- this.setFeatureGeometry(mapFeature.id, mapFeature.geometry);
1127
- if (mapFeature.properties.type === "Circle") {
1128
- this.setFeatureProperty(mapFeature.id, "center", mapFeature.properties.circleCenter);
1129
- this.setFeatureProperty(mapFeature.id, "radiusInKm", mapFeature.properties.circleRadius);
1130
- }
1131
- }
1132
- };
1133
- }
1134
- } else if (this._mode === "creating") {
1135
- if (this.isValidGeometry(drawControlFeature)) {
1136
- let createdFeature = drawControlFeature;
1137
- createdFeature.id = "";
1138
- this.applyDefaults(createdFeature);
1139
- operation = {
1140
- do: () => {
1141
- this._features.set(drawControlFeature.id, drawControlFeature);
1142
- this._featureIds.push(drawControlFeature.id);
1143
- if (this.options.selectionOptions?.mode === "single" || this.options.selectionOptions?.mode === "multi") {
1144
- this.map.getPlugin(SelectionPlugin).selectFeatures(this._annotationDataSource.id, drawControlFeature.id);
1145
- }
1146
- },
1147
- undo: () => {
1148
- createdFeature = this._features.get(createdFeature.id);
1149
- this._features.delete(createdFeature.id);
1150
- const index = this._featureIds.indexOf(createdFeature.id);
1151
- if (index !== -1) {
1152
- this._featureIds.splice(index, 1);
1153
- }
1154
- }
1155
- };
1156
- }
1157
- }
1158
- if (operation) {
1159
- this.performOperation(operation);
1160
- }
1161
- this._mode = "idle";
1162
- this._activeFeatureId = null;
1163
- this._activeFeatureType = null;
1164
- this.endDrawing();
1165
- this.render();
1166
- return this;
1167
- }
1168
- cancel() {
1169
- this._onCommitCleanup.forEach((f) => f());
1170
- this._onCommitCleanup = [];
1171
- if (this._mode === "idle")
1172
- return this;
1173
- if (this._mode === "editing") {
1174
- this.setFeatureProperty(this._activeFeatureId, "visible", true);
1175
- }
1176
- this._activeFeatureId = null;
1177
- this._activeFeatureType = null;
1178
- this._mode = "idle";
1179
- this.endDrawing();
1180
- this.render();
1181
- return this;
1182
- }
1183
- render() {
1184
- const renderedFeatures = {
1185
- type: "FeatureCollection",
1186
- features: this._featureIds.map((id) => this._features.get(id))
1187
- };
1188
- this._annotationDataSource.setSrc(renderedFeatures);
1189
- this.emitStateChange();
1190
- return this;
1191
- }
1192
- handleDblClick(event) {
1193
- if (!this.options.interactive) {
1194
- return;
1195
- }
1196
- const clickedFeature = event.features[0];
1197
- if (clickedFeature && clickedFeature.source === this._annotationDataSource.id) {
1198
- this.editFeature(clickedFeature.id.toString());
1199
- }
1200
- }
1201
- handleBeforeStyleChanged(event) {
1202
- const { oldStyle, newStyle } = event;
1203
- if (this._drawControl) {
1204
- if (oldStyle.sources["mapbox-gl-draw"]) {
1205
- newStyle.sources["mapbox-gl-draw"] = oldStyle.sources["mapbox-gl-draw"];
1206
- }
1207
- oldStyle.layers.filter((l) => l.id.startsWith("gl-draw")).forEach((l) => newStyle.layers.push(l));
1208
- }
1209
- return newStyle;
1210
- }
1211
- startDrawing() {
1212
- if (this._drawControl) {
1213
- return this._drawControl;
1214
- }
1215
- this.pluginManager.setExclusivePlugin(this);
1216
- this._drawControl = new MapboxDraw({
1217
- displayControlsDefault: false,
1218
- keybindings: false,
1219
- modes: {
1220
- ...MapboxDraw.modes,
1221
- drag_circle: DragCircleMode$1,
1222
- direct_select: DirectMode
1223
- //...options.modes
1224
- },
1225
- userProperties: true
1226
- });
1227
- this.map.maplibreMap.addControl(this._drawControl);
1228
- return this._drawControl;
1229
- }
1230
- endDrawing() {
1231
- this.pluginManager.removeExclusivePlugin(this);
1232
- if (this._drawControl) {
1233
- this.map.maplibreMap.removeControl(this._drawControl);
1234
- this._drawControl = null;
1235
- }
1236
- }
1237
- applyDefaults(feature) {
1238
- feature.id = feature.properties.id = this.generateFeatureId(feature);
1239
- feature.properties = {
1240
- id: this.generateFeatureId(feature),
1241
- name: this.generateFeatureName(feature),
1242
- type: feature.properties.type ?? feature.geometry.type,
1243
- selected: false,
1244
- ...this.options.defaultStyle,
1245
- ...feature.properties
1246
- };
1247
- feature.id = feature.properties.id;
1248
- return feature;
1249
- }
1250
- generateFeatureId(feature) {
1251
- if (isNumber(feature.id) || isStringFull(feature.id)) {
1252
- return feature.id.toString();
1253
- } else {
1254
- return randomId("feature");
1255
- }
1256
- }
1257
- generateFeatureName(feature) {
1258
- const type = feature.properties.type ?? feature.geometry.type;
1259
- return `${type} ${this._featureIds.length}`;
1260
- }
1261
- performOperation(operation) {
1262
- this._undoStack.push(operation);
1263
- this._redoStack.length = 0;
1264
- operation.do();
1265
- }
1266
- deselectFeature(featureId) {
1267
- if (this.options.selectionOptions?.mode === "single" || this.options.selectionOptions?.mode === "multi") {
1268
- this.map.getPlugin(SelectionPlugin).deselectFeatures(this._annotationDataSource.id, featureId);
1269
- }
1270
- }
1271
- deleteSelectedFeature() {
1272
- if (this.options.selectionOptions?.mode === "single" || this.options.selectionOptions?.mode === "multi") {
1273
- const selected = this.map.getPlugin(SelectionPlugin).selectedFeatureIds(this._annotationDataSource.id);
1274
- selected.forEach((id) => this.deleteFeature(id));
1275
- this.render();
1276
- }
1277
- }
1278
- editModeForFeature(feature) {
1279
- switch (feature.geometry.type) {
1280
- case "Point":
1281
- return "simple_select";
1282
- default:
1283
- return "direct_select";
1284
- }
1285
- }
1286
- drawModeForFeatureType(featureType) {
1287
- switch (featureType) {
1288
- case "Polygon":
1289
- return "draw_polygon";
1290
- case "LineString":
1291
- return "draw_line_string";
1292
- case "Point":
1293
- return "draw_point";
1294
- case "Circle":
1295
- return "drag_circle";
1296
- default:
1297
- throw new Error(`Unrecognized feature type: ${featureType}`);
1298
- }
1299
- }
1300
- setFeatureGeometry(featureId, geometry) {
1301
- const feature = this.getFeature(featureId);
1302
- const featureCopy = {
1303
- ...feature,
1304
- geometry
1305
- };
1306
- this._features.set(featureId, featureCopy);
1307
- return featureCopy;
1308
- }
1309
- isValidGeometry(feature) {
1310
- if (isPolygon(feature)) {
1311
- return feature.geometry.coordinates[0][0] !== null && feature.geometry.coordinates[0].length > 3 && turfArea(feature) > 0;
1312
- } else if (isLineString(feature)) {
1313
- return feature.geometry.coordinates.length > 1 && turfLength(feature) > 0;
1314
- } else if (isPoint(feature)) {
1315
- return feature.geometry.coordinates.length > 0;
1316
- }
1317
- return false;
1318
- }
1319
- emitStateChange() {
1320
- const eventData = {
1321
- mode: this._mode,
1322
- canUndo: this._undoStack.length > 0,
1323
- canRedo: this._redoStack.length > 0,
1324
- activeFeatureId: this._activeFeatureId,
1325
- activeFeatureType: this._activeFeatureType,
1326
- features: this._featureIds.map((id) => this._features.get(id))
1327
- };
1328
- this.emit("annotationStateChanged", new AnnotationEvent("annotationStateChanged", this.map, eventData));
1329
- }
1330
- };
1331
- __publicField$5(_AnnotationPlugin, "_defaultOptions", {
1332
- interactive: true,
1333
- defaultStyle: {
1334
- labelSize: 10,
1335
- labelColor: "#ffffff",
1336
- labelMaxWidth: 10,
1337
- labelOffset: [0, 0.5],
1338
- labelJustify: "auto",
1339
- labelAnchor: "top",
1340
- polygonLabelAnchor: "center",
1341
- radius: 5,
1342
- fillColor: "rgba(204,204,204,0.65)",
1343
- strokeWidth: 1,
1344
- strokeColor: "#ffffff",
1345
- selectionStrokeColor: "orange",
1346
- selectionStrokeOpacity: 0.5,
1347
- selectionWidth: 3,
1348
- hoverStrokeColor: "transparent"
1349
- }
1350
- });
1351
- let AnnotationPlugin = _AnnotationPlugin;
1352
-
1353
- var __defProp$4 = Object.defineProperty;
1354
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1355
- var __publicField$4 = (obj, key, value) => {
1356
- __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
1357
- return value;
1358
- };
1359
- const debug$1 = Debug("flow:data-join-map-plugin");
1360
- const _DataJoin = class _DataJoin {
1361
- constructor(id, map, options) {
1362
- this.id = id;
1363
- this.map = map;
1364
- __publicField$4(this, "autorunDisposer", null);
1365
- __publicField$4(this, "dataExpression", null);
1366
- __publicField$4(this, "options");
1367
- __publicField$4(this, "parameterExpressions", {});
1368
- this.options = {
1369
- ..._DataJoin.defaultOptions,
1370
- ...options
1371
- };
1372
- }
1373
- get source() {
1374
- return this.options.source;
1375
- }
1376
- start() {
1377
- this.stop();
1378
- if (isString(this.options.data)) {
1379
- if (isURL(this.options.data))
1380
- this.options.data = `'${this.options.data}'`;
1381
- this.dataExpression = new ReactiveExpression(this.options.data);
1382
- this.dataExpression.bindState(this.map.context.state);
1383
- } else {
1384
- this.dataExpression = null;
1385
- }
1386
- if (isArrayFull(this.options.parameters)) {
1387
- this.parameterExpressions = this.options.parameters.reduce((accum, param) => {
1388
- const expr = new ReactiveExpression(param.value.toString());
1389
- expr.bindState(this.map.context.state);
1390
- accum[param.name] = expr;
1391
- return accum;
1392
- }, {});
1393
- }
1394
- this.autorunDisposer = autorun(
1395
- async () => {
1396
- let data = this.dataExpression ? toJS(this.dataExpression.value) : this.options.data;
1397
- const missingParams = this.options.parameters.map((p) => p.required && isNil(this.parameterExpressions[p.name].value) ? p.name : void 0).filter((p) => !!p);
1398
- if (isNull(data)) {
1399
- debug$1(`FlowMap<${this.map.id}>: Skipping data join '${this.id}' (null data)`);
1400
- return;
1401
- }
1402
- if (missingParams.length) {
1403
- debug$1(
1404
- `FlowMap<${this.map.id}>: Skipping data join '${this.id}' (null required parameters: ${missingParams.join(
1405
- ", "
1406
- )})`
1407
- );
1408
- return;
1409
- }
1410
- debug$1(`FlowMap<${this.map.id}>: Performing data join '${this.id}'`);
1411
- if (isString(data)) {
1412
- try {
1413
- data = await this.loadData(data);
1414
- } catch (e) {
1415
- this.map.emitError(`Failed to load data for data join '${this.id}' - ${e.message}`, e);
1416
- data = [];
1417
- }
1418
- }
1419
- this.doDataJoin(data);
1420
- },
1421
- { name: `FlowDataJoin.${this.map.id}.${this.id})` }
1422
- );
1423
- }
1424
- stop() {
1425
- if (this.autorunDisposer) {
1426
- this.autorunDisposer();
1427
- this.autorunDisposer = null;
1428
- }
1429
- }
1430
- doDataJoin(data) {
1431
- const source = this.map.getSource(this.options.source);
1432
- const sourceLayer = source.type === "vector" ? this.options.sourceLayer || "geometry" : void 0;
1433
- if (this.options.clear) {
1434
- this.map.removeFeatureState({ source: source.id, sourceLayer }, this.id);
1435
- }
1436
- const featureData = data.reduce((accum, d) => {
1437
- accum[d[this.options.foreignKey]] = { [this.id]: d };
1438
- return accum;
1439
- }, {});
1440
- this.map.setFeatureStateBulk({ source: source.id, sourceLayer }, featureData);
1441
- }
1442
- loadData(datasetOrUrl) {
1443
- if (isURL(datasetOrUrl)) {
1444
- const url = new URL(datasetOrUrl);
1445
- const params = new URLSearchParams(url.searchParams);
1446
- if (isArrayFull(this.options.parameters)) {
1447
- this.options.parameters.forEach((p) => {
1448
- params.append(p.name, this.parameterExpressions[p.name].value);
1449
- });
1450
- }
1451
- url.search = params.toString();
1452
- const headers = new Headers({ Accept: "application/json" });
1453
- const request = new Request(url.toString(), {
1454
- method: "GET",
1455
- mode: "cors",
1456
- headers,
1457
- cache: "default"
1458
- });
1459
- return fetch(request).then((response) => {
1460
- if (!response.ok) {
1461
- throw new Error(`status=${response.status} ${response.statusText}`);
1462
- }
1463
- return response.json();
1464
- });
1465
- } else {
1466
- const params = {};
1467
- if (isArrayFull(this.options.parameters)) {
1468
- this.options.parameters.forEach((p) => {
1469
- params[p.name] = this.parameterExpressions[p.name].value;
1470
- });
1471
- }
1472
- return this.map.context.flowClient.datasets.query(datasetOrUrl, {}, params);
1473
- }
1474
- }
1475
- };
1476
- __publicField$4(_DataJoin, "defaultOptions", {
1477
- clear: false,
1478
- parameters: []
1479
- });
1480
- let DataJoin = _DataJoin;
1481
- class DataJoinPlugin extends MapPluginBase {
1482
- constructor(pluginManager) {
1483
- super(pluginManager);
1484
- __publicField$4(this, "_joins", /* @__PURE__ */ new Map());
1485
- __publicField$4(this, "name", "DataJoinPlugin");
1486
- }
1487
- addDataJoin(id, options) {
1488
- const dataJoin = new DataJoin(id, this.map, options);
1489
- this._joins.set(id, dataJoin);
1490
- dataJoin.start();
1491
- }
1492
- bindState(state) {
1493
- this._joins.forEach((join) => join.start());
1494
- }
1495
- destroy() {
1496
- this._joins.forEach((join) => join.stop());
1497
- this._joins.clear();
1498
- }
1499
- handleSourceRemoved(event) {
1500
- this._joins.forEach((join) => {
1501
- if (join.source === event.source) {
1502
- join.stop();
1503
- this._joins.delete(join.id);
1504
- }
1505
- });
1506
- }
1507
- removeDataJoin(id) {
1508
- const dataJoin = this._joins.get(id);
1509
- if (dataJoin) {
1510
- dataJoin.stop();
1511
- this._joins.delete(id);
1512
- } else {
1513
- throw new FlowError(`Cannot remove unrecognized data join '${id}'`);
1514
- }
1515
- }
1516
- }
1517
-
1518
- var __defProp$3 = Object.defineProperty;
1519
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1520
- var __publicField$3 = (obj, key, value) => {
1521
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
1522
- return value;
1523
- };
1524
- const _MapExporter = class _MapExporter {
1525
- constructor(map) {
1526
- this.map = map;
1527
- __publicField$3(this, "nativePixelRatio", window.devicePixelRatio);
1528
- }
1529
- async export(options) {
1530
- options = { ..._MapExporter.defaultOptions, ...options };
1531
- const [container, mapCopy] = await this.createMapCopy(options);
1532
- return new Promise((resolve, reject) => {
1533
- const fileName = `${options.name}.${options.format}`;
1534
- const mapCanvas = mapCopy.getCanvas();
1535
- const exportCanvas = this.createExportCanvas(container, mapCanvas);
1536
- const exportContext = exportCanvas.getContext("2d");
1537
- if (!exportContext) {
1538
- this.destroyMapCopy(container, mapCopy);
1539
- reject(new Error("Failed to create export canvas context"));
1540
- return;
1541
- }
1542
- const drawOverlayCallback = (err) => {
1543
- if (err) {
1544
- this.destroyMapCopy(container, mapCopy);
1545
- reject(err);
1546
- } else {
1547
- switch (options.format) {
1548
- case "png":
1549
- exportCanvas.toBlob((blob) => {
1550
- blob && saveAs(blob, fileName);
1551
- });
1552
- break;
1553
- case "pdf":
1554
- throw new Error("Export to PDF is not currently supported");
1555
- }
1556
- this.destroyMapCopy(container, mapCopy);
1557
- resolve(fileName);
1558
- }
1559
- };
1560
- const mapImage = new Image();
1561
- mapImage.onload = () => {
1562
- exportContext.drawImage(mapImage, 0, 0);
1563
- if (isFunction(options.drawOverlayFn)) {
1564
- options.drawOverlayFn(
1565
- exportContext,
1566
- exportCanvas.width,
1567
- exportCanvas.height,
1568
- options.dpmm,
1569
- drawOverlayCallback
1570
- );
1571
- } else {
1572
- drawOverlayCallback(null);
1573
- }
1574
- };
1575
- mapImage.src = mapCopy.getCanvas().toDataURL();
1576
- });
1577
- }
1578
- createMapCopy(options) {
1579
- const geoBounds = options.bounds || this.map.maplibreMap.getBounds().toArray().flat();
1580
- const geoBottomLeft = [geoBounds[0], geoBounds[1]];
1581
- const geoTopRight = [geoBounds[2], geoBounds[3]];
1582
- const geoCenter = [
1583
- (geoBottomLeft[0] + geoTopRight[0]) / 2,
1584
- (geoBottomLeft[1] + geoTopRight[1]) / 2
1585
- ];
1586
- const pxBottomLeft = this.map.maplibreMap.project(geoBottomLeft);
1587
- const pxTopRight = this.map.maplibreMap.project(geoTopRight);
1588
- const pxWidth = pxTopRight.x - pxBottomLeft.x;
1589
- const pxHeight = pxBottomLeft.y - pxTopRight.y;
1590
- const exportWidth = options.width * options.dpmm;
1591
- const exportHeight = options.height * options.dpmm;
1592
- const aspectRatios = {
1593
- width: pxWidth / exportWidth,
1594
- height: pxHeight / exportHeight
1595
- };
1596
- const coverRatio = Math.max(aspectRatios.width, aspectRatios.height);
1597
- const copyWidth = exportWidth * coverRatio;
1598
- const copyHeight = exportHeight * coverRatio;
1599
- const pixelRatio = exportWidth / copyWidth;
1600
- this.setDevicePixelRatio(pixelRatio);
1601
- const container = document.createElement("div");
1602
- container.id = randomId("export");
1603
- container.classList.add("maplibregl-export-container");
1604
- container.style.width = `${copyWidth}px`;
1605
- container.style.height = `${copyHeight}px`;
1606
- this.map.container.insertBefore(container, this.map.container.firstChild);
1607
- const mapCopy = new maplibre.Map({
1608
- container,
1609
- center: geoCenter,
1610
- zoom: this.map.maplibreMap.getZoom(),
1611
- style: { ...this.map.maplibreMap.getStyle(), transition: { delay: 0, duration: 0 } },
1612
- bearing: this.map.maplibreMap.getBearing(),
1613
- pitch: this.map.maplibreMap.getPitch(),
1614
- interactive: false,
1615
- attributionControl: false,
1616
- fadeDuration: 0,
1617
- preserveDrawingBuffer: true,
1618
- transformRequest: this.transformMapRequest.bind(this)
1619
- });
1620
- mapCopy.on("styleimagemissing", this.handleMissingImage.bind(this));
1621
- return new Promise((resolve) => {
1622
- mapCopy.once("load", () => {
1623
- Object.keys(this.map.maplibreMap.style.sourceCaches).forEach((sourceId) => {
1624
- mapCopy.style.sourceCaches[sourceId]._state.stateChanges = this.map.maplibreMap.style.sourceCaches[sourceId]._state.state;
1625
- });
1626
- mapCopy._update();
1627
- setTimeout(() => resolve([container, mapCopy]), 500);
1628
- });
1629
- });
1630
- }
1631
- destroyMapCopy(container, map) {
1632
- this.setDevicePixelRatio(this.nativePixelRatio);
1633
- map.remove();
1634
- container.parentNode.removeChild(container);
1635
- }
1636
- createExportCanvas(container, mapCanvas) {
1637
- const canvasContainer = container.getElementsByClassName("maplibregl-canvas-container")[0];
1638
- const overlayCanvas = document.createElement("canvas");
1639
- overlayCanvas.id = randomId("overlay");
1640
- overlayCanvas.width = mapCanvas.width;
1641
- overlayCanvas.height = mapCanvas.height;
1642
- overlayCanvas.style.position = "absolute";
1643
- overlayCanvas.style.width = mapCanvas.style.width;
1644
- overlayCanvas.style.height = mapCanvas.style.height;
1645
- canvasContainer.appendChild(overlayCanvas);
1646
- return overlayCanvas;
1647
- }
1648
- setDevicePixelRatio(pixelRatio) {
1649
- Object.defineProperty(window, "devicePixelRatio", {
1650
- get: () => pixelRatio
1651
- });
1652
- }
1653
- async handleMissingImage(e) {
1654
- const imageInfo = this.map.imageRegistry.getImage(e.id);
1655
- if (imageInfo === this.map.imageRegistry.unknownImage) {
1656
- console.error(`Map ${this.map.id}: Image '${e.id}' not registered`);
1657
- }
1658
- if (!imageInfo.image.complete) {
1659
- imageInfo.image.onload = () => {
1660
- this.map.maplibreMap.updateImage(e.id, imageInfo.image);
1661
- this.map.maplibreMap.redraw();
1662
- };
1663
- }
1664
- this.map.maplibreMap.addImage(e.id, imageInfo.image, {
1665
- pixelRatio: imageInfo.pixelDensity,
1666
- sdf: imageInfo.recolor
1667
- });
1668
- }
1669
- transformMapRequest(url, _resourceType) {
1670
- if (this.map.context.flowClient.accessToken && url.startsWith(this.map.context.flowClient.baseUrl)) {
1671
- return {
1672
- url,
1673
- headers: { Authorization: `Bearer ${this.map.context.flowClient.accessToken}` }
1674
- };
1675
- } else {
1676
- return { url };
1677
- }
1678
- }
1679
- };
1680
- __publicField$3(_MapExporter, "defaultOptions", {
1681
- name: "map",
1682
- width: 297,
1683
- height: 210,
1684
- dpmm: 12,
1685
- format: "png"
1686
- });
1687
- let MapExporter = _MapExporter;
1688
-
1689
- var __defProp$2 = Object.defineProperty;
1690
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1691
- var __publicField$2 = (obj, key, value) => {
1692
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
1693
- return value;
1694
- };
1695
- class ExportPlugin extends MapPluginBase {
1696
- constructor(pluginManager) {
1697
- super(pluginManager);
1698
- __publicField$2(this, "name", "ExportPlugin");
1699
- }
1700
- exportMap(options) {
1701
- const mapExporter = new MapExporter(this.map);
1702
- return mapExporter.export(options);
1703
- }
1704
- }
1705
-
1706
- var __defProp$1 = Object.defineProperty;
1707
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1708
- var __publicField$1 = (obj, key, value) => {
1709
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1710
- return value;
1711
- };
1712
- class HoverEffectPlugin extends MapPluginBase {
1713
- constructor(pluginManager) {
1714
- super(pluginManager);
1715
- __publicField$1(this, "hoveredFeature", null);
1716
- __publicField$1(this, "name", "HoverEffectPlugin");
1717
- }
1718
- handleMouseMove(event) {
1719
- const hoveredFeature = event.features[0];
1720
- if (hoveredFeature) {
1721
- this.map.maplibreMap._container.classList.add("feature-hovered");
1722
- } else {
1723
- this.map.maplibreMap._container.classList.remove("feature-hovered");
1724
- }
1725
- if (!this.compareFeatures(hoveredFeature, this.hoveredFeature)) {
1726
- this.clearHover();
1727
- if (isFeatureWithId(hoveredFeature) && isDefined(this.map.getSource(hoveredFeature.source)?.featureId)) {
1728
- this.map.setFeatureState(hoveredFeature, { hover: true }, false);
1729
- this.hoveredFeature = hoveredFeature;
1730
- }
1731
- }
1732
- }
1733
- handleMouseOut(event) {
1734
- this.clearHover();
1735
- }
1736
- handleSetExclusivePlugin(exclusivePlugins) {
1737
- if (exclusivePlugins.length) {
1738
- this.clearHover();
1739
- this.map.maplibreMap._container.classList.remove("feature-hovered");
1740
- }
1741
- }
1742
- compareFeatures(f1, f2) {
1743
- if (f1 === f2) {
1744
- return true;
1745
- }
1746
- if (isObject(f1) && isObject(f2)) {
1747
- return f1.id == f2.id && f1.source === f2.source && f1.sourceLayer == f2.sourceLayer;
1748
- }
1749
- return false;
1750
- }
1751
- clearHover() {
1752
- if (this.hoveredFeature && this.map.getSource(this.hoveredFeature.source)) {
1753
- this.map.removeFeatureState(this.hoveredFeature, "hover", false);
1754
- this.hoveredFeature = null;
1755
- }
1756
- }
1757
- }
1758
-
1759
- var __defProp = Object.defineProperty;
1760
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1761
- var __publicField = (obj, key, value) => {
1762
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1763
- return value;
1764
- };
1765
- const debug = Debug("flow:url-sync-plugin");
1766
- class UrlSyncPlugin extends MapPluginBase {
1767
- constructor(pluginManager) {
1768
- super(pluginManager);
1769
- __publicField(this, "name", "UrlSyncPlugin");
1770
- }
1771
- initialize() {
1772
- const searchParams = new URLSearchParams(window.location.search);
1773
- const hash = searchParams.get(this.map.id);
1774
- if (hash) {
1775
- const center = this.hashToMapState(hash);
1776
- debug("Setting map position from URL", center);
1777
- this.map.setCenter(center);
1778
- }
1779
- }
1780
- handleMoveEnd(event) {
1781
- const center = this.mapStateToHash(this.map.getCenter());
1782
- const searchParams = new URLSearchParams(window.location.search);
1783
- searchParams.set(this.map.id, center);
1784
- const newUrl = `${location.pathname}?${searchParams.toString()}`;
1785
- debug("Updating URL with map position", center);
1786
- window.history.replaceState({}, "", newUrl);
1787
- }
1788
- mapStateToHash(mapCenter) {
1789
- const state = {
1790
- z: mapCenter.zoom.toFixed(3),
1791
- x: mapCenter.lng.toFixed(3),
1792
- y: mapCenter.lat.toFixed(3),
1793
- pitch: mapCenter.pitch.toFixed(1),
1794
- bearing: mapCenter.bearing.toFixed(1)
1795
- };
1796
- return `${state.z}_${state.x}_${state.y}_${state.pitch}_${state.bearing}`;
1797
- }
1798
- hashToMapState(hash) {
1799
- const [zoom, x, y, pitch, bearing] = hash.split("_");
1800
- return {
1801
- lng: +x,
1802
- lat: +y,
1803
- zoom: +zoom,
1804
- pitch: +pitch,
1805
- bearing: +bearing
1806
- };
1807
- }
1808
- }
1809
-
1810
- export { AnnotationEvent, AnnotationPlugin, DataJoin, DataJoinPlugin, ExportPlugin, HoverEffectPlugin, MapPluginBase, PopupPlugin, SelectionEvent, SelectionPlugin, UrlSyncPlugin };
1
+ export { AnnotationEvent } from './annotations/annotation.events.mjs';
2
+ export { AnnotationPlugin } from './annotations/annotation.plugin.mjs';
3
+ export { DataJoin, DataJoinPlugin } from './data-join.plugin.mjs';
4
+ export { ExportPlugin } from './export/export.plugin.mjs';
5
+ export { HoverEffectPlugin } from './hover-effect.plugin.mjs';
6
+ export { MapPluginBase } from './map-plugin-base.mjs';
7
+ export { PluginManager } from './plugin-manager.mjs';
8
+ export { PopupPlugin } from './popup.plugin.mjs';
9
+ export { SelectionEvent } from './selection/selection.events.mjs';
10
+ export { SelectionPlugin } from './selection/selection.plugin.mjs';
11
+ export { UrlSyncPlugin } from './url-sync.plugin.mjs';