@maptiler/geocoding-control 2.0.0 → 2.1.0-rc1

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 (118) hide show
  1. package/MapLibreBasedGeocodingControl.d.ts +3027 -27
  2. package/icons/10pin.svg +4 -1
  3. package/icons/9pin.svg +4 -1
  4. package/icons/alcohol.svg +1 -1
  5. package/icons/alpine_hut.svg +1 -1
  6. package/icons/apartment.svg +4 -1
  7. package/icons/area.svg +1 -5
  8. package/icons/artwork.svg +4 -1
  9. package/icons/beauty.svg +14 -1
  10. package/icons/bicycle_repair_station.svg +18 -1
  11. package/icons/biergarten.svg +4 -1
  12. package/icons/books.svg +14 -1
  13. package/icons/bowl.svg +4 -1
  14. package/icons/bowling_alley.svg +4 -1
  15. package/icons/bus_station.svg +1 -1
  16. package/icons/camping.svg +1 -1
  17. package/icons/car_repair.svg +14 -1
  18. package/icons/car_wash.svg +19 -1
  19. package/icons/cave_entrance.svg +15 -1
  20. package/icons/chalet.svg +1 -1
  21. package/icons/chemist.svg +14 -1
  22. package/icons/church.svg +4 -1
  23. package/icons/community_centre.svg +20 -1
  24. package/icons/firestation.svg +4 -1
  25. package/icons/guest_house.svg +29 -8
  26. package/icons/hotel.svg +1 -1
  27. package/icons/housenumber.svg +19 -14
  28. package/icons/hut.svg +1 -4
  29. package/icons/medical_supply.svg +20 -1
  30. package/icons/memorial.svg +14 -1
  31. package/icons/motel.svg +19 -1
  32. package/icons/post.svg +1 -1
  33. package/icons/post_office.svg +1 -1
  34. package/icons/postal_code.svg +1 -23
  35. package/icons/public_bookcase.svg +14 -1
  36. package/icons/public_building.svg +4 -1
  37. package/icons/shintoist.svg +1 -1
  38. package/icons/street.svg +11 -14
  39. package/icons/vehicle_inspection.svg +18 -1
  40. package/icons/wilderness_hut.svg +1 -1
  41. package/leaflet-controller.d.ts +1 -1
  42. package/leaflet-controller.js +113 -110
  43. package/leaflet-controller.js.map +1 -1
  44. package/leaflet-controller.umd.js +2 -2
  45. package/leaflet-controller.umd.js.map +1 -1
  46. package/leaflet.d.ts +58 -5
  47. package/leaflet.js +1438 -1265
  48. package/leaflet.js.map +1 -1
  49. package/leaflet.umd.js +3 -3
  50. package/leaflet.umd.js.map +1 -1
  51. package/maplibregl-controller.d.ts +1 -1
  52. package/maplibregl-controller.js +483 -469
  53. package/maplibregl-controller.js.map +1 -1
  54. package/maplibregl-controller.umd.js +3 -3
  55. package/maplibregl-controller.umd.js.map +1 -1
  56. package/maplibregl.d.ts +2499 -13
  57. package/maplibregl.js +2435 -2139
  58. package/maplibregl.js.map +1 -1
  59. package/maplibregl.umd.js +3 -3
  60. package/maplibregl.umd.js.map +1 -1
  61. package/maptilersdk.d.ts +2499 -13
  62. package/maptilersdk.js +2432 -2139
  63. package/maptilersdk.js.map +1 -1
  64. package/maptilersdk.umd.js +3 -3
  65. package/maptilersdk.umd.js.map +1 -1
  66. package/openlayers-controller.d.ts +1 -1
  67. package/openlayers-controller.js +66 -63
  68. package/openlayers-controller.js.map +1 -1
  69. package/openlayers-controller.umd.js +2 -2
  70. package/openlayers-controller.umd.js.map +1 -1
  71. package/openlayers.d.ts +53 -1
  72. package/openlayers.js +2046 -1902
  73. package/openlayers.js.map +1 -1
  74. package/openlayers.umd.js +3 -3
  75. package/openlayers.umd.js.map +1 -1
  76. package/package.json +28 -28
  77. package/react.d.ts +31 -5
  78. package/react.js +1252 -1096
  79. package/react.js.map +1 -1
  80. package/react.umd.js +1 -1
  81. package/react.umd.js.map +1 -1
  82. package/style.css +1 -1
  83. package/svelte/FeatureItem.svelte +60 -13
  84. package/svelte/FeatureItem.svelte.d.ts +4 -4
  85. package/svelte/GeocodingControl.svelte +166 -98
  86. package/svelte/GeocodingControl.svelte.d.ts +36 -16
  87. package/svelte/MapLibreBasedGeocodingControl.d.ts +3027 -27
  88. package/svelte/MapLibreBasedGeocodingControl.js +154 -21
  89. package/svelte/leaflet-controller.d.ts +1 -1
  90. package/svelte/leaflet-controller.js +6 -3
  91. package/svelte/leaflet.d.ts +58 -5
  92. package/svelte/leaflet.js +52 -21
  93. package/svelte/maplibregl-controller.d.ts +1 -1
  94. package/svelte/maplibregl-controller.js +47 -38
  95. package/svelte/maplibregl.d.ts +2499 -13
  96. package/svelte/maplibregl.js +11 -3
  97. package/svelte/maptilersdk.d.ts +2499 -13
  98. package/svelte/maptilersdk.js +11 -3
  99. package/svelte/openlayers-controller.d.ts +1 -1
  100. package/svelte/openlayers-controller.js +7 -4
  101. package/svelte/openlayers.d.ts +53 -1
  102. package/svelte/openlayers.js +66 -48
  103. package/svelte/react.d.ts +31 -5
  104. package/svelte/react.js +21 -9
  105. package/svelte/types.d.ts +106 -35
  106. package/svelte/vanilla.d.ts +46 -2
  107. package/svelte/vanilla.js +66 -10
  108. package/types.d.ts +106 -35
  109. package/vanilla.d.ts +46 -2
  110. package/vanilla.js +1260 -1057
  111. package/vanilla.js.map +1 -1
  112. package/vanilla.umd.js +1 -1
  113. package/vanilla.umd.js.map +1 -1
  114. package/icons/aerodrome.12.svg +0 -1
  115. package/icons/bus_stop.12.svg +0 -1
  116. package/icons/elevator.12.svg +0 -1
  117. /package/icons/{helipad.16.svg → helipad.svg} +0 -0
  118. /package/icons/{traffic_light.13.svg → traffic_light.svg} +0 -0
@@ -1,8 +1,75 @@
1
1
  import GeocodingControlComponent from "./GeocodingControl.svelte";
2
2
  import { createMapLibreGlMapController, } from "./maplibregl-controller";
3
3
  export { createMapLibreGlMapController, } from "./maplibregl-controller";
4
- export function crateBaseClass(Evented, maplibreGl, getExtraProps) {
5
- return class MapLibreBasedGeocodingControl extends Evented {
4
+ export function crateClasses(Evented, maplibreGl, getExtraProps) {
5
+ // NOTE We can't use Maplibre `Event` - see https://github.com/maplibre/maplibre-gl-js/issues/5015
6
+ class Event {
7
+ type;
8
+ target;
9
+ constructor(target, type) {
10
+ this.type = type;
11
+ this.target = target;
12
+ }
13
+ }
14
+ class SelectEvent extends Event {
15
+ feature;
16
+ constructor(target, details) {
17
+ super(target, "select");
18
+ Object.assign(this, details);
19
+ }
20
+ }
21
+ class FeaturesListedEvent extends Event {
22
+ features;
23
+ constructor(target, features) {
24
+ super(target, "featureslisted");
25
+ this.features = features;
26
+ }
27
+ }
28
+ class FeaturesMarkedEvent extends Event {
29
+ features;
30
+ constructor(target, features) {
31
+ super(target, "featuresmarked");
32
+ this.features = features;
33
+ }
34
+ }
35
+ class OptionsVisibilityChangeEvent extends Event {
36
+ optionsVisible;
37
+ constructor(target, optionsVisible) {
38
+ super(target, "optionsvisibilitychange");
39
+ this.optionsVisible = optionsVisible;
40
+ }
41
+ }
42
+ class PickEvent extends Event {
43
+ feature;
44
+ constructor(target, feature) {
45
+ super(target, "pick");
46
+ this.feature = feature;
47
+ }
48
+ }
49
+ class QueryChangeEvent extends Event {
50
+ query;
51
+ constructor(target, query) {
52
+ super(target, "querychange");
53
+ this.query = query;
54
+ }
55
+ }
56
+ class ResponseEvent extends Event {
57
+ url;
58
+ featureCollection;
59
+ constructor(target, url, featureCollection) {
60
+ super(target, "response");
61
+ this.url = url;
62
+ this.featureCollection = featureCollection;
63
+ }
64
+ }
65
+ class ReverseToggleEvent extends Event {
66
+ reverse;
67
+ constructor(target, reverse) {
68
+ super(target, "reversetoggle");
69
+ this.reverse = reverse;
70
+ }
71
+ }
72
+ class MapLibreBasedGeocodingControl extends Evented {
6
73
  #gc;
7
74
  #options;
8
75
  constructor(options = {}) {
@@ -27,47 +94,113 @@ export function crateBaseClass(Evented, maplibreGl, getExtraProps) {
27
94
  throw new Error("no apiKey provided");
28
95
  }
29
96
  this.#gc = new GeocodingControlComponent({ target: div, props });
30
- for (const eventName of [
31
- "select",
32
- "pick",
33
- "featuresListed",
34
- "featuresMarked",
35
- "response",
36
- "optionsVisibilityChange",
37
- "reverseToggle",
38
- "queryChange",
39
- ]) {
40
- this.#gc.$on(eventName, (event) => {
41
- this.fire(eventName, event.detail);
42
- });
43
- }
97
+ this.#gc.$on("select", (event) => {
98
+ this.fire(new SelectEvent(this, event.detail));
99
+ });
100
+ this.#gc.$on("pick", (event) => {
101
+ this.fire(new PickEvent(this, event.detail.feature));
102
+ });
103
+ this.#gc.$on("featureslisted", (event) => {
104
+ this.fire(new FeaturesListedEvent(this, event.detail.features));
105
+ });
106
+ this.#gc.$on("featuresmarked", (event) => {
107
+ this.fire(new FeaturesMarkedEvent(this, event.detail.features));
108
+ });
109
+ this.#gc.$on("response", (event) => {
110
+ this.fire(new ResponseEvent(this, event.detail.url, event.detail.featureCollection));
111
+ });
112
+ this.#gc.$on("optionsvisibilitychange", (event) => {
113
+ this.fire(new OptionsVisibilityChangeEvent(this, event.detail.optionsVisible));
114
+ });
115
+ this.#gc.$on("reversetoggle", (event) => {
116
+ this.fire(new ReverseToggleEvent(this, event.detail.reverse));
117
+ });
118
+ this.#gc.$on("querychange", (event) => {
119
+ this.fire(new QueryChangeEvent(this, event.detail.query));
120
+ });
44
121
  return div;
45
122
  }
123
+ on(type, listener) {
124
+ return super.on(type, listener);
125
+ }
126
+ once(type, listener) {
127
+ return super.once(type, listener);
128
+ }
129
+ off(type, listener) {
130
+ return super.off(type, listener);
131
+ }
132
+ listens(type) {
133
+ return super.listens(type);
134
+ }
135
+ /**
136
+ * Update the control options.
137
+ *
138
+ * @param options options to update
139
+ */
46
140
  setOptions(options) {
47
- this.#options = options;
141
+ Object.assign(this.#options, options);
48
142
  const { marker, showResultMarkers, flyTo, fullGeometryStyle, ...restOptions } = this.#options;
49
143
  this.#gc?.$set(restOptions);
50
144
  }
145
+ /**
146
+ * Set the content of search input box.
147
+ *
148
+ * @param value text to set
149
+ * @param submit perform the search
150
+ */
51
151
  setQuery(value, submit = true) {
52
152
  this.#gc?.setQuery(value, submit);
53
153
  }
154
+ /**
155
+ * Clear geocoding search results from the map.
156
+ */
54
157
  clearMap() {
55
158
  this.#gc?.clearMap();
56
159
  }
160
+ /**
161
+ * Clear search result list.
162
+ */
57
163
  clearList() {
58
164
  this.#gc?.clearList();
59
165
  }
60
- setReverseMode(value) {
61
- this.#gc?.$set({ reverseActive: value });
166
+ /**
167
+ * Set reverse geocoding mode.
168
+ *
169
+ * @param reverseActive reverse geocoding active
170
+ */
171
+ setReverseMode(reverseActive) {
172
+ this.#gc?.$set({ reverseActive });
62
173
  }
63
- focus() {
64
- this.#gc?.focus();
174
+ /**
175
+ * Focus the search input box.
176
+ *
177
+ * @param options [FocusOptions](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
178
+ */
179
+ focus(options) {
180
+ this.#gc?.focus(options);
65
181
  }
182
+ /**
183
+ * Blur the search input box.
184
+ */
66
185
  blur() {
67
186
  this.#gc?.blur();
68
187
  }
69
188
  onRemove() {
70
189
  this.#gc?.$destroy();
71
190
  }
191
+ }
192
+ const events = {
193
+ SelectEvent,
194
+ FeaturesListedEvent,
195
+ FeaturesMarkedEvent,
196
+ OptionsVisibilityChangeEvent,
197
+ PickEvent,
198
+ QueryChangeEvent,
199
+ ResponseEvent,
200
+ ReverseToggleEvent,
201
+ };
202
+ return {
203
+ MapLibreBasedGeocodingControl,
204
+ events,
72
205
  };
73
206
  }
@@ -6,7 +6,7 @@ export declare function createLeafletMapController(map: L.Map, marker?: boolean
6
6
  fitBounds(bbox: BBox, padding: number, maxZoom?: number): void;
7
7
  indicateReverse(reverse: boolean): void;
8
8
  setReverseMarker(coordinates?: Position): void;
9
- setMarkers(markedFeatures: Feature[] | undefined, picked: Feature | undefined): void;
9
+ setFeatures(markedFeatures: Feature[] | undefined, picked: Feature | undefined, showPolygonMarker: boolean): void;
10
10
  setSelectedMarker(index: number): void;
11
11
  getCenterAndZoom(): [number, number, number];
12
12
  };
@@ -109,7 +109,7 @@ export function createLeafletMapController(map, marker = true, showResultMarkers
109
109
  }
110
110
  }
111
111
  },
112
- setMarkers(markedFeatures, picked) {
112
+ setFeatures(markedFeatures, picked, showPolygonMarker) {
113
113
  function setData(data) {
114
114
  resultLayer.clearLayers();
115
115
  if (data) {
@@ -121,7 +121,7 @@ export function createLeafletMapController(map, marker = true, showResultMarkers
121
121
  }
122
122
  markers.length = 0;
123
123
  setData();
124
- if (picked) {
124
+ block: if (picked) {
125
125
  let handled = false;
126
126
  if (picked.geometry.type === "GeometryCollection") {
127
127
  const geoms = picked.geometry.geometries.filter((geometry) => geometry.type === "Polygon" || geometry.type === "MultiPolygon");
@@ -175,7 +175,10 @@ export function createLeafletMapController(map, marker = true, showResultMarkers
175
175
  else if (picked.geometry.type === "LineString" ||
176
176
  picked.geometry.type === "MultiLineString") {
177
177
  setData(picked);
178
- return; // no pin for (multi)linestrings
178
+ break block; // no pin for (multi)linestrings
179
+ }
180
+ if (!showPolygonMarker && picked.geometry.type !== "Point") {
181
+ break block;
179
182
  }
180
183
  if (marker instanceof Function) {
181
184
  const m = marker(map, picked);
@@ -1,5 +1,5 @@
1
1
  import * as L from "leaflet";
2
- import type { ControlOptions, Feature } from "./types";
2
+ import type { ControlOptions, DispatcherType, Feature } from "./types";
3
3
  export { createLeafletMapController } from "./leaflet-controller";
4
4
  type LeafletControlOptions = ControlOptions & L.ControlOptions & {
5
5
  /**
@@ -54,25 +54,78 @@ type LeafletControlOptions = ControlOptions & L.ControlOptions & {
54
54
  */
55
55
  fullGeometryStyle?: null | boolean | L.PathOptions | L.StyleFunction;
56
56
  };
57
+ type LeafletEvent<T> = {
58
+ type: T;
59
+ target: GeocodingControl;
60
+ sourceTarget: GeocodingControl;
61
+ };
62
+ type CustomEventMap = {
63
+ [T in keyof DispatcherType]: DispatcherType[T] & LeafletEvent<T>;
64
+ };
57
65
  /**
58
66
  * Leaflet mixins https://leafletjs.com/reference.html#class
59
67
  * for TypeScript https://www.typescriptlang.org/docs/handbook/mixins.html
60
68
  * @internal
61
69
  */
62
- declare class EventedControl {
63
- constructor(...args: unknown[]);
70
+ declare class EventedControl extends L.Control {
64
71
  }
65
- interface EventedControl extends L.Control, L.Evented {
72
+ interface EventedControl extends L.Control {
73
+ on<T extends keyof CustomEventMap>(type: T, fn: (event: CustomEventMap[T]) => void, context?: unknown): this;
74
+ addEventListener<T extends keyof CustomEventMap>(type: T, fn: (event: CustomEventMap[T]) => void, context?: unknown): this;
75
+ once<T extends keyof CustomEventMap>(type: T, fn: (event: CustomEventMap[T]) => void, context?: unknown): this;
76
+ addOneTimeEventListener<T extends keyof CustomEventMap>(type: T, fn: (event: CustomEventMap[T]) => void, context?: unknown): this;
77
+ off<T extends keyof CustomEventMap>(type?: T, fn?: (event: CustomEventMap[T]) => void, context?: unknown): this;
78
+ off(eventMap?: {
79
+ [T in keyof CustomEventMap]?: (event: CustomEventMap[T]) => void;
80
+ }): this;
81
+ removeEventListener<T extends keyof CustomEventMap>(type?: T, fn?: (event: CustomEventMap[T]) => void, context?: unknown): this;
82
+ listens<T extends keyof CustomEventMap>(type: T, fn: (event: CustomEventMap[T]) => void, context?: unknown, propagate?: boolean): boolean;
83
+ fire(type: string, data?: unknown, propagate?: boolean): this;
84
+ addEventParent(obj: L.Evented): this;
85
+ removeEventParent(obj: L.Evented): this;
86
+ fireEvent(type: string, data?: unknown, propagate?: boolean): this;
87
+ hasEventListeners<T extends keyof CustomEventMap>(type: T): boolean;
66
88
  }
67
89
  export declare class GeocodingControl extends EventedControl {
68
90
  #private;
69
91
  constructor(options: LeafletControlOptions);
70
92
  onAdd(map: L.Map): HTMLDivElement;
93
+ /**
94
+ * Update the control options.
95
+ *
96
+ * @param options options to update
97
+ */
71
98
  setOptions(options: LeafletControlOptions): void;
99
+ /**
100
+ * Set the content of search input box.
101
+ *
102
+ * @param value text to set
103
+ * @param submit perform the search
104
+ */
72
105
  setQuery(value: string, submit?: boolean): void;
106
+ /**
107
+ * Clear geocoding search results from the map.
108
+ */
73
109
  clearMap(): void;
110
+ /**
111
+ * Clear search result list.
112
+ */
74
113
  clearList(): void;
75
- focus(): void;
114
+ /**
115
+ * Set reverse geocoding mode.
116
+ *
117
+ * @param reverseActive reverse geocoding active
118
+ */
119
+ setReverseMode(reverseActive: boolean): void;
120
+ /**
121
+ * Focus the search input box.
122
+ *
123
+ * @param options [FocusOptions](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
124
+ */
125
+ focus(options?: FocusOptions): void;
126
+ /**
127
+ * Blur the search input box.
128
+ */
76
129
  blur(): void;
77
130
  onRemove(): void;
78
131
  }
package/svelte/leaflet.js CHANGED
@@ -7,18 +7,15 @@ export { createLeafletMapController } from "./leaflet-controller";
7
7
  * for TypeScript https://www.typescriptlang.org/docs/handbook/mixins.html
8
8
  * @internal
9
9
  */
10
- // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/no-extraneous-class
11
- class EventedControl {
12
- // eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-unused-vars
13
- constructor(...args) { }
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
11
+ class EventedControl extends L.Control {
14
12
  }
15
- L.Util.extend(EventedControl.prototype, L.Control.prototype);
16
13
  L.Util.extend(EventedControl.prototype, L.Evented.prototype);
17
14
  export class GeocodingControl extends EventedControl {
18
15
  #gc;
19
16
  #options;
20
17
  constructor(options) {
21
- super();
18
+ super(options);
22
19
  this.#options = options;
23
20
  }
24
21
  onAdd(map) {
@@ -26,7 +23,7 @@ export class GeocodingControl extends EventedControl {
26
23
  div.className = "leaflet-ctrl-geocoder";
27
24
  L.DomEvent.disableClickPropagation(div);
28
25
  L.DomEvent.disableScrollPropagation(div);
29
- const { marker, showResultMarkers, flyTo, fullGeometryStyle, ...restOptions } = this.#options;
26
+ const { marker, showResultMarkers, flyTo, fullGeometryStyle, position, ...restOptions } = this.#options;
30
27
  const flyToOptions = typeof flyTo === "boolean" ? {} : flyTo;
31
28
  const mapController = createLeafletMapController(map, marker, showResultMarkers, flyToOptions, flyToOptions, fullGeometryStyle);
32
29
  this.#gc = new GeocodingControlComponent({
@@ -37,37 +34,71 @@ export class GeocodingControl extends EventedControl {
37
34
  ...restOptions,
38
35
  },
39
36
  });
40
- for (const eventName of [
41
- "select",
42
- "pick",
43
- "featuresListed",
44
- "featuresMarked",
45
- "response",
46
- "optionsVisibilityChange",
47
- "reverseToggle",
48
- "queryChange",
49
- ]) {
50
- this.#gc.$on(eventName, (event) => this.fire(eventName.toLowerCase(), event.detail));
37
+ const eventNames = {
38
+ select: undefined,
39
+ pick: undefined,
40
+ featureslisted: undefined,
41
+ featuresmarked: undefined,
42
+ response: undefined,
43
+ optionsvisibilitychange: undefined,
44
+ reversetoggle: undefined,
45
+ querychange: undefined,
46
+ };
47
+ for (const eventName in eventNames) {
48
+ this.#gc.$on(eventName, (event) => this.fire(eventName, event.detail));
51
49
  }
52
50
  return div;
53
51
  }
52
+ /**
53
+ * Update the control options.
54
+ *
55
+ * @param options options to update
56
+ */
54
57
  setOptions(options) {
55
- this.#options = options;
58
+ Object.assign(this.#options, options);
56
59
  const { marker, showResultMarkers, flyTo, fullGeometryStyle, ...restOptions } = this.#options;
57
60
  this.#gc?.$set(restOptions);
58
61
  }
62
+ /**
63
+ * Set the content of search input box.
64
+ *
65
+ * @param value text to set
66
+ * @param submit perform the search
67
+ */
59
68
  setQuery(value, submit = true) {
60
69
  this.#gc?.setQuery(value, submit);
61
70
  }
71
+ /**
72
+ * Clear geocoding search results from the map.
73
+ */
62
74
  clearMap() {
63
75
  this.#gc?.clearMap();
64
76
  }
77
+ /**
78
+ * Clear search result list.
79
+ */
65
80
  clearList() {
66
81
  this.#gc?.clearList();
67
82
  }
68
- focus() {
69
- this.#gc?.focus();
83
+ /**
84
+ * Set reverse geocoding mode.
85
+ *
86
+ * @param reverseActive reverse geocoding active
87
+ */
88
+ setReverseMode(reverseActive) {
89
+ this.#gc?.$set({ reverseActive });
90
+ }
91
+ /**
92
+ * Focus the search input box.
93
+ *
94
+ * @param options [FocusOptions](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
95
+ */
96
+ focus(options) {
97
+ this.#gc?.focus(options);
70
98
  }
99
+ /**
100
+ * Blur the search input box.
101
+ */
71
102
  blur() {
72
103
  this.#gc?.blur();
73
104
  }
@@ -13,7 +13,7 @@ export declare function createMapLibreGlMapController(map: Map, maplibregl?: Map
13
13
  fitBounds(bbox: BBox, padding: number, maxZoom?: number): void;
14
14
  indicateReverse(reverse: boolean): void;
15
15
  setReverseMarker(coordinates?: Position): void;
16
- setMarkers(markedFeatures: Feature[] | undefined, picked: Feature | undefined): void;
16
+ setFeatures(markedFeatures: Feature[] | undefined, picked: Feature | undefined, showPolygonMarker: boolean): void;
17
17
  setSelectedMarker(index: number): void;
18
18
  getCenterAndZoom(): [number, number, number];
19
19
  };
@@ -2,7 +2,6 @@ import { feature, featureCollection } from "@turf/helpers";
2
2
  import union from "@turf/union";
3
3
  import MarkerIcon from "./MarkerIcon.svelte";
4
4
  import { setMask } from "./mask";
5
- const emptyGeojson = featureCollection([]);
6
5
  const defaultGeometryStyle = {
7
6
  fill: {
8
7
  paint: {
@@ -23,55 +22,69 @@ const defaultGeometryStyle = {
23
22
  filter: ["!", ["has", "isMask"]],
24
23
  },
25
24
  };
25
+ const RESULT_SOURCE = "mtlr-gc-full-geom";
26
+ const RESULT_LAYER_FILL = "mtlr-gc-full-geom-fill";
27
+ const RESULT_LAYER_LINE = "mtlr-gc-full-geom-line";
26
28
  export function createMapLibreGlMapController(map, maplibregl, marker = true, showResultMarkers = true, flyToOptions = {}, fitBoundsOptions = {}, fullGeometryStyle = defaultGeometryStyle) {
27
29
  let eventHandler;
28
30
  const markers = [];
29
31
  let selectedMarker;
30
32
  let reverseMarker;
31
33
  let savedData; // used to restore features on style switch
32
- function addFullGeometryLayer() {
34
+ function syncFullGeometryLayer() {
35
+ if (!map.loaded) {
36
+ map.once("load", syncFullGeometryLayer);
37
+ return;
38
+ }
33
39
  const effFullGeometryStyle = !fullGeometryStyle
34
40
  ? undefined
35
41
  : fullGeometryStyle === true
36
42
  ? defaultGeometryStyle
37
43
  : fullGeometryStyle;
38
- if (!map.getSource("full-geom") &&
39
- (effFullGeometryStyle?.fill || effFullGeometryStyle?.line)) {
40
- map.addSource("full-geom", {
44
+ if (!effFullGeometryStyle?.fill && !effFullGeometryStyle?.line) {
45
+ return;
46
+ }
47
+ const source = map.getSource(RESULT_SOURCE);
48
+ if (source) {
49
+ source.setData(savedData ?? featureCollection([]));
50
+ }
51
+ else if (savedData) {
52
+ map.addSource(RESULT_SOURCE, {
41
53
  type: "geojson",
42
- data: emptyGeojson,
54
+ data: savedData,
43
55
  });
44
56
  }
45
- if (!map.getLayer("full-geom-fill") && effFullGeometryStyle?.fill) {
57
+ else {
58
+ return;
59
+ }
60
+ if (!map.getLayer(RESULT_LAYER_FILL) && effFullGeometryStyle?.fill) {
46
61
  map.addLayer({
47
62
  ...effFullGeometryStyle?.fill,
48
- id: "full-geom-fill",
63
+ id: RESULT_LAYER_FILL,
49
64
  type: "fill",
50
- source: "full-geom",
65
+ source: RESULT_SOURCE,
51
66
  });
52
67
  }
53
- if (!map.getLayer("full-geom-line") && effFullGeometryStyle?.line) {
68
+ if (!map.getLayer(RESULT_LAYER_LINE) && effFullGeometryStyle?.line) {
54
69
  map.addLayer({
55
70
  ...effFullGeometryStyle?.line,
56
- id: "full-geom-line",
71
+ id: RESULT_LAYER_LINE,
57
72
  type: "line",
58
- source: "full-geom",
73
+ source: RESULT_SOURCE,
59
74
  });
60
75
  }
61
- if (savedData) {
62
- setData(savedData);
63
- }
64
- }
65
- if (map.loaded()) {
66
- addFullGeometryLayer();
67
76
  }
68
- else {
69
- map.once("load", () => {
70
- addFullGeometryLayer();
71
- });
77
+ function setAndSaveData(data) {
78
+ savedData = data;
79
+ syncFullGeometryLayer();
72
80
  }
73
81
  map.on("styledata", () => {
74
- addFullGeometryLayer();
82
+ // timeout prevents collision with svelte-maplibre library
83
+ setTimeout(() => {
84
+ if (savedData) {
85
+ syncFullGeometryLayer();
86
+ }
87
+ });
75
88
  });
76
89
  const handleMapClick = (e) => {
77
90
  eventHandler?.({
@@ -93,13 +106,6 @@ export function createMapLibreGlMapController(map, maplibregl, marker = true, sh
93
106
  });
94
107
  return new maplibregl.Marker({ element, offset: [1, -13] });
95
108
  }
96
- function setData(data) {
97
- savedData = data;
98
- if (!data) {
99
- return;
100
- }
101
- map.getSource("full-geom")?.setData(data);
102
- }
103
109
  return {
104
110
  setEventHandler(handler) {
105
111
  if (handler) {
@@ -150,16 +156,16 @@ export function createMapLibreGlMapController(map, maplibregl, marker = true, sh
150
156
  }
151
157
  }
152
158
  },
153
- setMarkers(markedFeatures, picked) {
159
+ setFeatures(markedFeatures, picked, showPolygonMarker) {
154
160
  for (const marker of markers) {
155
161
  marker.remove();
156
162
  }
157
163
  markers.length = 0;
158
- setData(emptyGeojson);
164
+ setAndSaveData(undefined);
159
165
  if (!maplibregl) {
160
166
  return;
161
167
  }
162
- if (picked) {
168
+ block: if (picked) {
163
169
  let handled = false;
164
170
  if (picked.geometry.type === "GeometryCollection") {
165
171
  const geoms = picked.geometry.geometries.filter((geometry) => geometry.type === "Polygon" || geometry.type === "MultiPolygon");
@@ -171,14 +177,14 @@ export function createMapLibreGlMapController(map, maplibregl, marker = true, sh
171
177
  setMask({
172
178
  ...picked,
173
179
  geometry: unioned.geometry,
174
- }, setData);
180
+ }, setAndSaveData);
175
181
  handled = true;
176
182
  }
177
183
  else {
178
184
  const geometries = picked.geometry.geometries.filter((geometry) => geometry.type === "LineString" ||
179
185
  geometry.type === "MultiLineString");
180
186
  if (geometries.length > 0) {
181
- setData({
187
+ setAndSaveData({
182
188
  ...picked,
183
189
  geometry: { type: "GeometryCollection", geometries },
184
190
  });
@@ -191,12 +197,15 @@ export function createMapLibreGlMapController(map, maplibregl, marker = true, sh
191
197
  }
192
198
  else if (picked.geometry.type === "Polygon" ||
193
199
  picked.geometry.type === "MultiPolygon") {
194
- setMask(picked, setData);
200
+ setMask(picked, setAndSaveData);
195
201
  }
196
202
  else if (picked.geometry.type === "LineString" ||
197
203
  picked.geometry.type === "MultiLineString") {
198
- setData(picked);
199
- return; // no pin for (multi)linestrings
204
+ setAndSaveData(picked);
205
+ break block; // no pin for (multi)linestrings
206
+ }
207
+ if (!showPolygonMarker && picked.geometry.type !== "Point") {
208
+ break block;
200
209
  }
201
210
  if (marker instanceof Function) {
202
211
  const m = marker(map, picked);