@symfony/ux-leaflet-map 2.27.0 → 2.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/map_controller.d.ts +12 -10
- package/dist/map_controller.js +345 -312
- package/package.json +19 -10
package/dist/map_controller.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import AbstractMapController from '@symfony/ux-map';
|
|
3
|
-
import 'leaflet/dist/leaflet.min.css';
|
|
4
|
-
import type { CircleOptions, ControlPosition, MapOptions as LeafletMapOptions, MarkerOptions, PolylineOptions as PolygonOptions, PolylineOptions, PopupOptions, PolylineOptions as RectangleOptions } from 'leaflet';
|
|
1
|
+
import AbstractMapController, { MapDefinition, MarkerDefinition, PolygonDefinition, PolylineDefinition, CircleDefinition, RectangleDefinition, InfoWindowDefinition, Icon } from '@symfony/ux-map';
|
|
5
2
|
import * as L from 'leaflet';
|
|
6
|
-
|
|
3
|
+
import { MapOptions as MapOptions$1, ControlPosition, MarkerOptions, PopupOptions, PolylineOptions, CircleOptions } from 'leaflet';
|
|
4
|
+
|
|
5
|
+
type MapOptions = Pick<MapOptions$1, 'attributionControl' | 'zoomControl'> & {
|
|
7
6
|
attributionControlOptions?: {
|
|
8
7
|
position: ControlPosition;
|
|
9
8
|
prefix: string | false;
|
|
@@ -21,21 +20,23 @@ type MapOptions = Pick<LeafletMapOptions, 'attributionControl' | 'zoomControl'>
|
|
|
21
20
|
options: Record<string, unknown>;
|
|
22
21
|
} | false;
|
|
23
22
|
};
|
|
24
|
-
|
|
23
|
+
declare class export_default extends AbstractMapController<MapOptions, MapOptions$1, L.Map, MarkerOptions, L.Marker, PopupOptions, L.Popup, PolylineOptions, L.Polygon, PolylineOptions, L.Polyline, CircleOptions, L.Circle, PolylineOptions, L.Rectangle> {
|
|
25
24
|
map: L.Map;
|
|
26
25
|
connect(): void;
|
|
27
26
|
centerValueChanged(): void;
|
|
28
27
|
zoomValueChanged(): void;
|
|
28
|
+
minZoomValueChanged(): void;
|
|
29
|
+
maxZoomValueChanged(): void;
|
|
29
30
|
protected dispatchEvent(name: string, payload?: Record<string, unknown>): void;
|
|
30
31
|
protected doCreateMap({ definition }: {
|
|
31
|
-
definition: MapDefinition<MapOptions,
|
|
32
|
+
definition: MapDefinition<MapOptions, MapOptions$1>;
|
|
32
33
|
}): L.Map;
|
|
33
34
|
protected doCreateMarker({ definition }: {
|
|
34
35
|
definition: MarkerDefinition<MarkerOptions, PopupOptions>;
|
|
35
36
|
}): L.Marker;
|
|
36
37
|
protected doRemoveMarker(marker: L.Marker): void;
|
|
37
38
|
protected doCreatePolygon({ definition }: {
|
|
38
|
-
definition: PolygonDefinition<
|
|
39
|
+
definition: PolygonDefinition<PolylineOptions, PopupOptions>;
|
|
39
40
|
}): L.Polygon;
|
|
40
41
|
protected doRemovePolygon(polygon: L.Polygon): void;
|
|
41
42
|
protected doCreatePolyline({ definition }: {
|
|
@@ -47,7 +48,7 @@ export default class extends AbstractMapController<MapOptions, LeafletMapOptions
|
|
|
47
48
|
}): L.Circle;
|
|
48
49
|
protected doRemoveCircle(circle: L.Circle): void;
|
|
49
50
|
protected doCreateRectangle({ definition }: {
|
|
50
|
-
definition: RectangleDefinition<
|
|
51
|
+
definition: RectangleDefinition<PolylineOptions, PopupOptions>;
|
|
51
52
|
}): L.Rectangle;
|
|
52
53
|
protected doRemoveRectangle(rectangle: L.Rectangle): void;
|
|
53
54
|
protected doCreateInfoWindow({ definition, element, }: {
|
|
@@ -61,4 +62,5 @@ export default class extends AbstractMapController<MapOptions, LeafletMapOptions
|
|
|
61
62
|
protected doFitBoundsToMarkers(): void;
|
|
62
63
|
private closePopups;
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
export { export_default as default };
|
package/dist/map_controller.js
CHANGED
|
@@ -1,341 +1,374 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Svg: 'svg',
|
|
8
|
-
UxIcon: 'ux-icon',
|
|
1
|
+
// ../../../../assets/dist/abstract_map_controller.js
|
|
2
|
+
import { Controller } from "@hotwired/stimulus";
|
|
3
|
+
var IconTypes = {
|
|
4
|
+
Url: "url",
|
|
5
|
+
Svg: "svg",
|
|
6
|
+
UxIcon: "ux-icon"
|
|
9
7
|
};
|
|
10
|
-
class
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
map: this.map,
|
|
46
|
-
markers: [...this.markers.values()],
|
|
47
|
-
polygons: [...this.polygons.values()],
|
|
48
|
-
polylines: [...this.polylines.values()],
|
|
49
|
-
circles: [...this.circles.values()],
|
|
50
|
-
rectangles: [...this.rectangles.values()],
|
|
51
|
-
infoWindows: this.infoWindows,
|
|
52
|
-
extra,
|
|
53
|
-
});
|
|
54
|
-
this.isConnected = true;
|
|
55
|
-
}
|
|
56
|
-
createInfoWindow({ definition, element, }) {
|
|
57
|
-
this.dispatchEvent('info-window:before-create', { definition, element });
|
|
58
|
-
const infoWindow = this.doCreateInfoWindow({ definition, element });
|
|
59
|
-
this.dispatchEvent('info-window:after-create', { infoWindow, definition, element });
|
|
60
|
-
this.infoWindows.push(infoWindow);
|
|
61
|
-
return infoWindow;
|
|
8
|
+
var abstract_map_controller_default = class extends Controller {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.markers = /* @__PURE__ */ new Map();
|
|
12
|
+
this.polygons = /* @__PURE__ */ new Map();
|
|
13
|
+
this.polylines = /* @__PURE__ */ new Map();
|
|
14
|
+
this.circles = /* @__PURE__ */ new Map();
|
|
15
|
+
this.rectangles = /* @__PURE__ */ new Map();
|
|
16
|
+
this.infoWindows = [];
|
|
17
|
+
this.isConnected = false;
|
|
18
|
+
}
|
|
19
|
+
connect() {
|
|
20
|
+
const extra = this.hasExtraValue ? this.extraValue : {};
|
|
21
|
+
const mapDefinition = {
|
|
22
|
+
center: this.hasCenterValue ? this.centerValue : null,
|
|
23
|
+
zoom: this.hasZoomValue ? this.zoomValue : null,
|
|
24
|
+
minZoom: this.hasMinZoomValue ? this.minZoomValue : null,
|
|
25
|
+
maxZoom: this.hasMaxZoomValue ? this.maxZoomValue : null,
|
|
26
|
+
options: this.optionsValue,
|
|
27
|
+
extra
|
|
28
|
+
};
|
|
29
|
+
this.dispatchEvent("pre-connect", mapDefinition);
|
|
30
|
+
this.createMarker = this.createDrawingFactory("marker", this.markers, this.doCreateMarker.bind(this));
|
|
31
|
+
this.createPolygon = this.createDrawingFactory("polygon", this.polygons, this.doCreatePolygon.bind(this));
|
|
32
|
+
this.createPolyline = this.createDrawingFactory("polyline", this.polylines, this.doCreatePolyline.bind(this));
|
|
33
|
+
this.createCircle = this.createDrawingFactory("circle", this.circles, this.doCreateCircle.bind(this));
|
|
34
|
+
this.createRectangle = this.createDrawingFactory("rectangle", this.rectangles, this.doCreateRectangle.bind(this));
|
|
35
|
+
this.map = this.doCreateMap({ definition: mapDefinition });
|
|
36
|
+
this.markersValue.forEach((definition) => this.createMarker({ definition }));
|
|
37
|
+
this.polygonsValue.forEach((definition) => this.createPolygon({ definition }));
|
|
38
|
+
this.polylinesValue.forEach((definition) => this.createPolyline({ definition }));
|
|
39
|
+
this.circlesValue.forEach((definition) => this.createCircle({ definition }));
|
|
40
|
+
this.rectanglesValue.forEach((definition) => this.createRectangle({ definition }));
|
|
41
|
+
if (this.fitBoundsToMarkersValue) {
|
|
42
|
+
this.doFitBoundsToMarkers();
|
|
62
43
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
44
|
+
this.dispatchEvent("connect", {
|
|
45
|
+
map: this.map,
|
|
46
|
+
markers: [...this.markers.values()],
|
|
47
|
+
polygons: [...this.polygons.values()],
|
|
48
|
+
polylines: [...this.polylines.values()],
|
|
49
|
+
circles: [...this.circles.values()],
|
|
50
|
+
rectangles: [...this.rectangles.values()],
|
|
51
|
+
infoWindows: this.infoWindows,
|
|
52
|
+
extra
|
|
53
|
+
});
|
|
54
|
+
this.isConnected = true;
|
|
55
|
+
}
|
|
56
|
+
//region Public API
|
|
57
|
+
createInfoWindow({
|
|
58
|
+
definition,
|
|
59
|
+
element
|
|
60
|
+
}) {
|
|
61
|
+
this.dispatchEvent("info-window:before-create", { definition, element });
|
|
62
|
+
const infoWindow = this.doCreateInfoWindow({ definition, element });
|
|
63
|
+
this.dispatchEvent("info-window:after-create", { infoWindow, definition, element });
|
|
64
|
+
this.infoWindows.push(infoWindow);
|
|
65
|
+
return infoWindow;
|
|
66
|
+
}
|
|
67
|
+
markersValueChanged() {
|
|
68
|
+
if (!this.isConnected) {
|
|
69
|
+
return;
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon);
|
|
71
|
+
this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker);
|
|
72
|
+
if (this.fitBoundsToMarkersValue) {
|
|
73
|
+
this.doFitBoundsToMarkers();
|
|
77
74
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
|
|
75
|
+
}
|
|
76
|
+
polygonsValueChanged() {
|
|
77
|
+
if (!this.isConnected) {
|
|
78
|
+
return;
|
|
83
79
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon);
|
|
81
|
+
}
|
|
82
|
+
polylinesValueChanged() {
|
|
83
|
+
if (!this.isConnected) {
|
|
84
|
+
return;
|
|
89
85
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
|
|
87
|
+
}
|
|
88
|
+
circlesValueChanged() {
|
|
89
|
+
if (!this.isConnected) {
|
|
90
|
+
return;
|
|
95
91
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (typeof definition.rawOptions !== 'undefined') {
|
|
102
|
-
console.warn(`[Symfony UX Map] The event "${eventBefore}" added a deprecated "rawOptions" property to the definition, it will be removed in a next major version, replace it with "bridgeOptions" instead.`, definition);
|
|
103
|
-
}
|
|
104
|
-
const drawing = factory({ definition });
|
|
105
|
-
this.dispatchEvent(eventAfter, { [type]: drawing, definition });
|
|
106
|
-
draws.set(definition['@id'], drawing);
|
|
107
|
-
return drawing;
|
|
108
|
-
};
|
|
92
|
+
this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle);
|
|
93
|
+
}
|
|
94
|
+
rectanglesValueChanged() {
|
|
95
|
+
if (!this.isConnected) {
|
|
96
|
+
return;
|
|
109
97
|
}
|
|
110
|
-
onDrawChanged(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
98
|
+
this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle);
|
|
99
|
+
}
|
|
100
|
+
createDrawingFactory(type, draws, factory) {
|
|
101
|
+
const eventBefore = `${type}:before-create`;
|
|
102
|
+
const eventAfter = `${type}:after-create`;
|
|
103
|
+
return ({ definition }) => {
|
|
104
|
+
this.dispatchEvent(eventBefore, { definition });
|
|
105
|
+
if (typeof definition.rawOptions !== "undefined") {
|
|
106
|
+
console.warn(
|
|
107
|
+
`[Symfony UX Map] The event "${eventBefore}" added a deprecated "rawOptions" property to the definition, it will be removed in a next major version, replace it with "bridgeOptions" instead.`,
|
|
108
|
+
definition
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const drawing = factory({ definition });
|
|
112
|
+
this.dispatchEvent(eventAfter, { [type]: drawing, definition });
|
|
113
|
+
draws.set(definition["@id"], drawing);
|
|
114
|
+
return drawing;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
onDrawChanged(draws, newDrawDefinitions, factory, remover) {
|
|
118
|
+
const idsToRemove = new Set(draws.keys());
|
|
119
|
+
newDrawDefinitions.forEach((definition) => {
|
|
120
|
+
idsToRemove.delete(definition["@id"]);
|
|
121
|
+
});
|
|
122
|
+
idsToRemove.forEach((id) => {
|
|
123
|
+
const draw = draws.get(id);
|
|
124
|
+
remover(draw);
|
|
125
|
+
draws.delete(id);
|
|
126
|
+
});
|
|
127
|
+
newDrawDefinitions.forEach((definition) => {
|
|
128
|
+
if (!draws.has(definition["@id"])) {
|
|
129
|
+
factory({ definition });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//endregion
|
|
134
|
+
};
|
|
135
|
+
abstract_map_controller_default.values = {
|
|
136
|
+
providerOptions: Object,
|
|
137
|
+
center: Object,
|
|
138
|
+
zoom: Number,
|
|
139
|
+
minZoom: Number,
|
|
140
|
+
maxZoom: Number,
|
|
141
|
+
fitBoundsToMarkers: Boolean,
|
|
142
|
+
markers: Array,
|
|
143
|
+
polygons: Array,
|
|
144
|
+
polylines: Array,
|
|
145
|
+
circles: Array,
|
|
146
|
+
rectangles: Array,
|
|
147
|
+
options: Object,
|
|
148
|
+
extra: Object
|
|
139
149
|
};
|
|
140
150
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
// src/map_controller.ts
|
|
152
|
+
import "leaflet/dist/leaflet.min.css";
|
|
153
|
+
import * as L from "leaflet";
|
|
154
|
+
var map_controller_default = class extends abstract_map_controller_default {
|
|
155
|
+
connect() {
|
|
156
|
+
L.Marker.prototype.options.icon = L.divIcon({
|
|
157
|
+
html: '<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linecap="round" clip-rule="evenodd" viewBox="0 0 500 820"><defs><linearGradient id="__sf_ux_map_gradient_marker_fill" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(0 -37.57 37.57 0 416.45 541)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#126FC6"/><stop offset="1" stop-color="#4C9CD1"/></linearGradient><linearGradient id="__sf_ux_map_gradient_marker_border" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(0 -19.05 19.05 0 414.48 522.49)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2E6C97"/><stop offset="1" stop-color="#3883B7"/></linearGradient></defs><circle cx="252.31" cy="266.24" r="83.99" fill="#fff"/><path fill="url(#__sf_ux_map_gradient_marker_fill)" stroke="url(#__sf_ux_map_gradient_marker_border)" stroke-width="1.1" d="M416.54 503.61c-6.57 0-12.04 5.7-12.04 11.87 0 2.78 1.56 6.3 2.7 8.74l9.3 17.88 9.26-17.88c1.13-2.43 2.74-5.79 2.74-8.74 0-6.18-5.38-11.87-11.96-11.87Zm0 7.16a4.69 4.69 0 1 1-.02 9.4 4.69 4.69 0 0 1 .02-9.4Z" transform="translate(-7889.1 -9807.44) scale(19.54)"/></svg>',
|
|
158
|
+
iconSize: [25, 41],
|
|
159
|
+
iconAnchor: [12.5, 41],
|
|
160
|
+
popupAnchor: [0, -41],
|
|
161
|
+
className: ""
|
|
162
|
+
// Adding an empty class to the icon to avoid the default Leaflet styles
|
|
163
|
+
});
|
|
164
|
+
super.connect();
|
|
165
|
+
}
|
|
166
|
+
centerValueChanged() {
|
|
167
|
+
if (this.map && this.hasCenterValue && this.centerValue && this.hasZoomValue && this.zoomValue) {
|
|
168
|
+
this.map.setView(this.centerValue, this.zoomValue);
|
|
151
169
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
170
|
+
}
|
|
171
|
+
zoomValueChanged() {
|
|
172
|
+
if (this.map && this.hasZoomValue && this.zoomValue) {
|
|
173
|
+
this.map.setZoom(this.zoomValue);
|
|
156
174
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
175
|
+
}
|
|
176
|
+
minZoomValueChanged() {
|
|
177
|
+
if (this.map && this.hasMinZoomValue && this.minZoomValue) {
|
|
178
|
+
this.map.setMinZoom(this.minZoomValue);
|
|
161
179
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
detail: payload,
|
|
167
|
-
});
|
|
180
|
+
}
|
|
181
|
+
maxZoomValueChanged() {
|
|
182
|
+
if (this.map && this.hasMaxZoomValue && this.maxZoomValue) {
|
|
183
|
+
this.map.setMaxZoom(this.maxZoomValue);
|
|
168
184
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
185
|
+
}
|
|
186
|
+
dispatchEvent(name, payload = {}) {
|
|
187
|
+
payload.L = L;
|
|
188
|
+
this.dispatch(name, {
|
|
189
|
+
prefix: "ux:map",
|
|
190
|
+
detail: payload
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
doCreateMap({ definition }) {
|
|
194
|
+
const { center, zoom, minZoom, maxZoom, options, bridgeOptions = {} } = definition;
|
|
195
|
+
const map2 = L.map(this.element, {
|
|
196
|
+
center: center === null ? void 0 : center,
|
|
197
|
+
zoom: zoom === null ? void 0 : zoom,
|
|
198
|
+
minZoom: minZoom === null ? void 0 : minZoom,
|
|
199
|
+
maxZoom: maxZoom === null ? void 0 : maxZoom,
|
|
200
|
+
attributionControl: false,
|
|
201
|
+
zoomControl: false,
|
|
202
|
+
...options,
|
|
203
|
+
...bridgeOptions
|
|
204
|
+
});
|
|
205
|
+
if (options.tileLayer) {
|
|
206
|
+
L.tileLayer(options.tileLayer.url, {
|
|
207
|
+
attribution: options.tileLayer.attribution,
|
|
208
|
+
...options.tileLayer.options
|
|
209
|
+
}).addTo(map2);
|
|
192
210
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const marker = L.marker(position, {
|
|
196
|
-
title: title || undefined,
|
|
197
|
-
...rawOptions,
|
|
198
|
-
...bridgeOptions,
|
|
199
|
-
riseOnHover: true,
|
|
200
|
-
}).addTo(this.map);
|
|
201
|
-
if (infoWindow) {
|
|
202
|
-
this.createInfoWindow({ definition: infoWindow, element: marker });
|
|
203
|
-
}
|
|
204
|
-
if (icon) {
|
|
205
|
-
this.doCreateIcon({ definition: icon, element: marker });
|
|
206
|
-
}
|
|
207
|
-
return marker;
|
|
211
|
+
if (typeof options.attributionControlOptions !== "undefined") {
|
|
212
|
+
L.control.attribution({ ...options.attributionControlOptions }).addTo(map2);
|
|
208
213
|
}
|
|
209
|
-
|
|
210
|
-
|
|
214
|
+
if (typeof options.zoomControlOptions !== "undefined") {
|
|
215
|
+
L.control.zoom({ ...options.zoomControlOptions }).addTo(map2);
|
|
211
216
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
return map2;
|
|
218
|
+
}
|
|
219
|
+
doCreateMarker({ definition }) {
|
|
220
|
+
const { "@id": _id, position, title, infoWindow, icon: icon2, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
221
|
+
const marker2 = L.marker(position, {
|
|
222
|
+
title: title || void 0,
|
|
223
|
+
...rawOptions,
|
|
224
|
+
...bridgeOptions,
|
|
225
|
+
riseOnHover: true
|
|
226
|
+
}).addTo(this.map);
|
|
227
|
+
if (infoWindow) {
|
|
228
|
+
this.createInfoWindow({ definition: infoWindow, element: marker2 });
|
|
222
229
|
}
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
if (icon2) {
|
|
231
|
+
this.doCreateIcon({ definition: icon2, element: marker2 });
|
|
225
232
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
return marker2;
|
|
234
|
+
}
|
|
235
|
+
doRemoveMarker(marker2) {
|
|
236
|
+
marker2.remove();
|
|
237
|
+
}
|
|
238
|
+
doCreatePolygon({ definition }) {
|
|
239
|
+
const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
240
|
+
const polygon2 = L.polygon(points, { ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
241
|
+
if (title) {
|
|
242
|
+
polygon2.bindPopup(title);
|
|
236
243
|
}
|
|
237
|
-
|
|
238
|
-
|
|
244
|
+
if (infoWindow) {
|
|
245
|
+
this.createInfoWindow({ definition: infoWindow, element: polygon2 });
|
|
239
246
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
return polygon2;
|
|
248
|
+
}
|
|
249
|
+
doRemovePolygon(polygon2) {
|
|
250
|
+
polygon2.remove();
|
|
251
|
+
}
|
|
252
|
+
doCreatePolyline({ definition }) {
|
|
253
|
+
const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
254
|
+
const polyline2 = L.polyline(points, { ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
255
|
+
if (title) {
|
|
256
|
+
polyline2.bindPopup(title);
|
|
250
257
|
}
|
|
251
|
-
|
|
252
|
-
|
|
258
|
+
if (infoWindow) {
|
|
259
|
+
this.createInfoWindow({ definition: infoWindow, element: polyline2 });
|
|
253
260
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this.createInfoWindow({ definition: infoWindow, element: rectangle });
|
|
265
|
-
}
|
|
266
|
-
return rectangle;
|
|
261
|
+
return polyline2;
|
|
262
|
+
}
|
|
263
|
+
doRemovePolyline(polyline2) {
|
|
264
|
+
polyline2.remove();
|
|
265
|
+
}
|
|
266
|
+
doCreateCircle({ definition }) {
|
|
267
|
+
const { "@id": _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
268
|
+
const circle2 = L.circle(center, { radius, ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
269
|
+
if (title) {
|
|
270
|
+
circle2.bindPopup(title);
|
|
267
271
|
}
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
if (infoWindow) {
|
|
273
|
+
this.createInfoWindow({ definition: infoWindow, element: circle2 });
|
|
270
274
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
return popup;
|
|
275
|
+
return circle2;
|
|
276
|
+
}
|
|
277
|
+
doRemoveCircle(circle2) {
|
|
278
|
+
circle2.remove();
|
|
279
|
+
}
|
|
280
|
+
doCreateRectangle({ definition }) {
|
|
281
|
+
const { "@id": _id, southWest, northEast, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
282
|
+
const rectangle2 = L.rectangle(
|
|
283
|
+
[
|
|
284
|
+
[southWest.lat, southWest.lng],
|
|
285
|
+
[northEast.lat, northEast.lng]
|
|
286
|
+
],
|
|
287
|
+
{ ...rawOptions, ...bridgeOptions }
|
|
288
|
+
).addTo(this.map);
|
|
289
|
+
if (title) {
|
|
290
|
+
rectangle2.bindPopup(title);
|
|
290
291
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
let icon;
|
|
294
|
-
if (type === IconTypes.Svg) {
|
|
295
|
-
icon = L.divIcon({
|
|
296
|
-
html: definition.html,
|
|
297
|
-
iconSize: [width, height],
|
|
298
|
-
className: '',
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
else if (type === IconTypes.UxIcon) {
|
|
302
|
-
icon = L.divIcon({
|
|
303
|
-
html: definition._generated_html,
|
|
304
|
-
iconSize: [width, height],
|
|
305
|
-
className: '',
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
else if (type === IconTypes.Url) {
|
|
309
|
-
icon = L.icon({
|
|
310
|
-
iconUrl: definition.url,
|
|
311
|
-
iconSize: [width, height],
|
|
312
|
-
className: '',
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
throw new Error(`Unsupported icon type: ${type}.`);
|
|
317
|
-
}
|
|
318
|
-
element.setIcon(icon);
|
|
292
|
+
if (infoWindow) {
|
|
293
|
+
this.createInfoWindow({ definition: infoWindow, element: rectangle2 });
|
|
319
294
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
295
|
+
return rectangle2;
|
|
296
|
+
}
|
|
297
|
+
doRemoveRectangle(rectangle2) {
|
|
298
|
+
rectangle2.remove();
|
|
299
|
+
}
|
|
300
|
+
doCreateInfoWindow({
|
|
301
|
+
definition,
|
|
302
|
+
element
|
|
303
|
+
}) {
|
|
304
|
+
const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
305
|
+
element.bindPopup([headerContent, content].filter((x) => x).join("<br>"), { ...rawOptions, ...bridgeOptions });
|
|
306
|
+
if (opened) {
|
|
307
|
+
if (autoClose) {
|
|
308
|
+
this.closePopups();
|
|
309
|
+
}
|
|
310
|
+
element.openPopup();
|
|
330
311
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
popup.close();
|
|
337
|
-
});
|
|
312
|
+
const popup = element.getPopup();
|
|
313
|
+
if (!popup) {
|
|
314
|
+
throw new Error("Unable to get the Popup associated with the element.");
|
|
338
315
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
316
|
+
popup.on("click", () => {
|
|
317
|
+
if (autoClose) {
|
|
318
|
+
this.closePopups({ except: popup });
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
return popup;
|
|
322
|
+
}
|
|
323
|
+
doCreateIcon({ definition, element }) {
|
|
324
|
+
const { type, width, height } = definition;
|
|
325
|
+
let icon2;
|
|
326
|
+
if (type === IconTypes.Svg) {
|
|
327
|
+
icon2 = L.divIcon({
|
|
328
|
+
html: definition.html,
|
|
329
|
+
iconSize: [width, height],
|
|
330
|
+
className: ""
|
|
331
|
+
// Adding an empty class to the icon to avoid the default Leaflet styles
|
|
332
|
+
});
|
|
333
|
+
} else if (type === IconTypes.UxIcon) {
|
|
334
|
+
icon2 = L.divIcon({
|
|
335
|
+
html: definition._generated_html,
|
|
336
|
+
iconSize: [width, height],
|
|
337
|
+
className: ""
|
|
338
|
+
// Adding an empty class to the icon to avoid the default Leaflet styles
|
|
339
|
+
});
|
|
340
|
+
} else if (type === IconTypes.Url) {
|
|
341
|
+
icon2 = L.icon({
|
|
342
|
+
iconUrl: definition.url,
|
|
343
|
+
iconSize: [width, height],
|
|
344
|
+
className: ""
|
|
345
|
+
// Adding an empty class to the icon to avoid the default Leaflet styles
|
|
346
|
+
});
|
|
347
|
+
} else {
|
|
348
|
+
throw new Error(`Unsupported icon type: ${type}.`);
|
|
349
|
+
}
|
|
350
|
+
element.setIcon(icon2);
|
|
351
|
+
}
|
|
352
|
+
doFitBoundsToMarkers() {
|
|
353
|
+
if (this.markers.size === 0) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const bounds = [];
|
|
357
|
+
this.markers.forEach((marker2) => {
|
|
358
|
+
const position = marker2.getLatLng();
|
|
359
|
+
bounds.push([position.lat, position.lng]);
|
|
360
|
+
});
|
|
361
|
+
this.map.fitBounds(bounds);
|
|
362
|
+
}
|
|
363
|
+
closePopups(options = {}) {
|
|
364
|
+
this.infoWindows.forEach((popup) => {
|
|
365
|
+
if (options.except && popup === options.except) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
popup.close();
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
export {
|
|
373
|
+
map_controller_default as default
|
|
374
|
+
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@symfony/ux-leaflet-map",
|
|
3
3
|
"description": "Leaflet bridge for Symfony UX Map, integrate interactive maps in your Symfony applications",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.28.2",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"symfony-ux",
|
|
8
8
|
"leaflet",
|
|
@@ -16,13 +16,6 @@
|
|
|
16
16
|
],
|
|
17
17
|
"main": "dist/map_controller.js",
|
|
18
18
|
"types": "dist/map_controller.d.ts",
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "node ../../../../../../bin/build_package.js .",
|
|
21
|
-
"watch": "node ../../../../../../bin/build_package.js . --watch",
|
|
22
|
-
"test": "../../../../../../bin/test_package.sh .",
|
|
23
|
-
"check": "biome check",
|
|
24
|
-
"ci": "biome ci"
|
|
25
|
-
},
|
|
26
19
|
"symfony": {
|
|
27
20
|
"controllers": {
|
|
28
21
|
"map": {
|
|
@@ -49,8 +42,24 @@
|
|
|
49
42
|
},
|
|
50
43
|
"devDependencies": {
|
|
51
44
|
"@hotwired/stimulus": "^3.0.0",
|
|
52
|
-
"@
|
|
45
|
+
"@testing-library/dom": "^10.4.0",
|
|
46
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
47
|
+
"@testing-library/user-event": "^14.6.1",
|
|
53
48
|
"@types/leaflet": "^1.9.12",
|
|
54
|
-
"
|
|
49
|
+
"@vitest/browser": "^3.2.4",
|
|
50
|
+
"jsdom": "^26.1.0",
|
|
51
|
+
"leaflet": "^1.9.4",
|
|
52
|
+
"tslib": "^2.8.1",
|
|
53
|
+
"tsx": "^4.20.3",
|
|
54
|
+
"typescript": "^5.8.3",
|
|
55
|
+
"vitest": "^3.2.4",
|
|
56
|
+
"@symfony/ux-map": "2.28.2"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsx ../../../../../../bin/build_package.ts .",
|
|
60
|
+
"watch": "tsx ../../../../../../bin/build_package.ts . --watch",
|
|
61
|
+
"test": "../../../../../../bin/test_package.sh .",
|
|
62
|
+
"check": "biome check",
|
|
63
|
+
"ci": "biome ci"
|
|
55
64
|
}
|
|
56
65
|
}
|