@fleetbase/fleetops-engine 0.6.45 → 0.6.47
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/addon/components/admin/map-settings.hbs +26 -0
- package/addon/components/admin/map-settings.js +46 -0
- package/addon/components/admin/routing-settings.hbs +11 -0
- package/addon/components/cell/order-route-type.hbs +46 -0
- package/addon/components/cell/order-route-type.js +90 -0
- package/addon/components/cell/place-address.hbs +1 -0
- package/addon/components/display-place.hbs +45 -56
- package/addon/components/display-place.js +21 -0
- package/addon/components/layout/fleet-ops-sidebar/driver-listing.js +5 -5
- package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +5 -5
- package/addon/components/layout/fleet-ops-sidebar.js +8 -0
- package/addon/components/maintenance-schedule/form.js +2 -1
- package/addon/components/map/drawer/driver-listing.js +5 -5
- package/addon/components/map/drawer/place-listing.js +5 -5
- package/addon/components/map/drawer/position-listing.js +102 -21
- package/addon/components/map/drawer/vehicle-listing.js +5 -5
- package/addon/components/map/google-live-map.hbs +9 -0
- package/addon/components/map/google-live-map.js +445 -0
- package/addon/components/map/leaflet-live-map.hbs +186 -142
- package/addon/components/map/leaflet-live-map.js +121 -41
- package/addon/components/map/toolbar/visibility-control-panel.js +2 -2
- package/addon/components/map/toolbar/zones-panel.hbs +9 -9
- package/addon/components/map/toolbar.hbs +3 -3
- package/addon/components/map/toolbar.js +9 -1
- package/addon/components/modals/map-layer-form.hbs +132 -63
- package/addon/components/modals/orchestrator-import.hbs +4 -11
- package/addon/components/modals/orchestrator-import.js +17 -1
- package/addon/components/modals/update-order-activity.hbs +1 -1
- package/addon/components/orchestrator/order-pool.js +3 -2
- package/addon/components/orchestrator-workbench.js +29 -41
- package/addon/components/order/details/detail.js +2 -2
- package/addon/components/order/details/payload.hbs +5 -5
- package/addon/components/order/details/payload.js +18 -1
- package/addon/components/order/details/route.hbs +2 -2
- package/addon/components/order/details/route.js +76 -3
- package/addon/components/order/form/details.hbs +1 -2
- package/addon/components/order/form/details.js +6 -0
- package/addon/components/order/form/payload.hbs +33 -0
- package/addon/components/order/form/payload.js +1 -0
- package/addon/components/order/form/route.hbs +8 -8
- package/addon/components/order/form/route.js +86 -18
- package/addon/components/order/form.js +2 -2
- package/addon/components/order/route-editor.hbs +209 -147
- package/addon/components/order/route-editor.js +143 -102
- package/addon/components/place/address.hbs +1 -0
- package/addon/components/place/address.js +12 -0
- package/addon/components/route-list.hbs +43 -55
- package/addon/components/route-list.js +47 -0
- package/addon/components/route-optimization-wizard-panel.js +3 -4
- package/addon/components/vehicle/card.hbs +4 -4
- package/addon/controllers/maintenance/schedules/index.js +2 -1
- package/addon/controllers/operations/orders/index/details.js +110 -37
- package/addon/controllers/operations/orders/index/new.js +1 -1
- package/addon/controllers/operations/orders/index.js +8 -1
- package/addon/controllers/settings/map.js +97 -0
- package/addon/controllers/settings/payments/index.js +1 -1
- package/addon/controllers/settings/routing.js +47 -12
- package/addon/extension.js +11 -0
- package/addon/helpers/place-address-html.js +6 -0
- package/addon/instance-initializers/register-google-routes.js +17 -0
- package/addon/instance-initializers/register-osrm.js +5 -0
- package/addon/routes/application.js +6 -0
- package/addon/routes/operations/orchestrator.js +13 -0
- package/addon/routes/operations/orders/index/details.js +29 -22
- package/addon/routes/operations/orders/index/new.js +9 -0
- package/addon/routes/operations/orders/index.js +0 -1
- package/addon/routes/settings/map.js +3 -0
- package/addon/routes.js +1 -0
- package/addon/services/entity-actions.js +1 -1
- package/addon/services/geofence-event-bus.js +2 -1
- package/addon/services/geofence.js +204 -168
- package/addon/services/google-routes.js +300 -0
- package/addon/services/leaflet-draw-restriction.js +2 -1
- package/addon/services/leaflet-map-manager.js +17 -0
- package/addon/services/map-adapter/google.js +2205 -0
- package/addon/services/map-adapter/leaflet.js +1042 -0
- package/addon/services/map-adapter-interface.js +551 -0
- package/addon/services/map-manager.js +768 -0
- package/addon/services/map-settings.js +75 -0
- package/addon/services/movement-tracker.js +83 -32
- package/addon/services/order-actions.js +11 -1
- package/addon/services/osrm.js +79 -6
- package/addon/services/position-playback.js +135 -62
- package/addon/services/route-engine.js +83 -0
- package/addon/services/service-areas.js +8 -1
- package/addon/styles/fleetops-engine.css +555 -0
- package/addon/templates/management/vehicles/index.hbs +0 -1
- package/addon/templates/operations/orders/index/details.hbs +0 -1
- package/addon/templates/settings/map.hbs +53 -0
- package/addon/templates/settings/routing.hbs +15 -4
- package/addon/utils/fleet-ops-options.js +1 -0
- package/addon/utils/has-valid-coordinates.js +6 -0
- package/addon/utils/map-provider-options.js +6 -0
- package/addon/utils/order-route-editing.js +86 -0
- package/addon/utils/order-route-summary.js +20 -0
- package/addon/utils/place-address-html.js +41 -0
- package/addon/utils/route-colors.js +43 -12
- package/addon/utils/route-visualization.js +93 -0
- package/addon/utils/vendor-integration.js +2 -1
- package/app/components/admin/map-settings.js +1 -0
- package/app/components/admin/routing-settings.js +1 -0
- package/app/components/cell/order-route-type.js +1 -0
- package/app/components/cell/place-address.js +1 -0
- package/app/components/map/google-live-map.js +1 -0
- package/app/components/place/address.js +1 -0
- package/app/controllers/settings/map.js +1 -0
- package/app/helpers/place-address-html.js +1 -0
- package/app/routes/settings/map.js +1 -0
- package/app/services/map-adapter/google.js +1 -0
- package/app/services/map-adapter/leaflet.js +1 -0
- package/app/services/map-adapter-interface.js +1 -0
- package/app/services/map-manager.js +1 -0
- package/app/services/map-settings.js +1 -0
- package/app/templates/settings/map.js +1 -0
- package/app/utils/has-valid-coordinates.js +1 -0
- package/app/utils/order-route-editing.js +2 -0
- package/app/utils/order-route-summary.js +1 -0
- package/app/utils/place-address-html.js +1 -0
- package/app/utils/route-colors.js +1 -1
- package/app/utils/route-visualization.js +1 -0
- package/assets/images/drawing-controls-spritesheet.svg +156 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/pnpm-workspace.yaml +7 -0
- package/server/src/Auth/Schemas/FleetOps.php +5 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +31 -3
- package/server/src/Http/Controllers/Api/v1/PayloadController.php +14 -1
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -0
- package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +3 -2
- package/server/src/Http/Controllers/Api/v1/ZoneController.php +2 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +7 -4
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +90 -34
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +3 -2
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +106 -3
- package/server/src/Http/Filter/OrderFilter.php +2 -1
- package/server/src/Http/Resources/v1/Index/Payload.php +9 -7
- package/server/src/Http/Resources/v1/Order.php +20 -1
- package/server/src/Models/Order.php +42 -1
- package/server/src/Models/OrderConfig.php +15 -0
- package/server/src/Models/Payload.php +131 -27
- package/server/src/Models/Place.php +182 -48
- package/server/src/Models/ServiceRate.php +4 -3
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +59 -23
- package/server/src/Support/Utils.php +36 -2
- package/server/src/routes.php +4 -0
- package/translations/en-us.yaml +1937 -1916
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MapAdapterInterface
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class that defines the standardized contract all map provider
|
|
5
|
+
* adapters must implement. This enables FleetOps to support multiple map
|
|
6
|
+
* providers (Leaflet, Google Maps, Mapbox, etc.) without changing any
|
|
7
|
+
* application-level business logic.
|
|
8
|
+
*
|
|
9
|
+
* To add a new map provider:
|
|
10
|
+
* 1. Create `addon/services/map-adapter/<provider-name>.js`
|
|
11
|
+
* 2. Extend this class and implement every method
|
|
12
|
+
* 3. Register the service in `app/services/map-adapter/<provider-name>.js`
|
|
13
|
+
* 4. Set `mapProvider: '<provider-name>'` in `config/environment.js`
|
|
14
|
+
*
|
|
15
|
+
* @module services/map-adapter-interface
|
|
16
|
+
*/
|
|
17
|
+
/* eslint-disable no-unused-vars */
|
|
18
|
+
import Service from '@ember/service';
|
|
19
|
+
|
|
20
|
+
export default class MapAdapterInterface extends Service {
|
|
21
|
+
// ─── Internal State ────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The raw underlying map instance (e.g. a Leaflet map or google.maps.Map).
|
|
25
|
+
* Consumers should never access this directly; use the adapter API instead.
|
|
26
|
+
* @type {*}
|
|
27
|
+
*/
|
|
28
|
+
_map = null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Internal marker registry: id → native marker object.
|
|
32
|
+
* @type {Map<string, *>}
|
|
33
|
+
*/
|
|
34
|
+
_markers = new Map();
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Internal overlay registry: id → native overlay object (polygon, polyline, circle).
|
|
38
|
+
* @type {Map<string, *>}
|
|
39
|
+
*/
|
|
40
|
+
_overlays = new Map();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Internal routing control registry: id → provider-neutral route handle.
|
|
44
|
+
* @type {Map<string, Object>}
|
|
45
|
+
*/
|
|
46
|
+
_routingControls = new Map();
|
|
47
|
+
|
|
48
|
+
// ─── Lifecycle ─────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Initialize the map inside the given DOM element.
|
|
52
|
+
*
|
|
53
|
+
* @param {HTMLElement} element - The container element for the map
|
|
54
|
+
* @param {Object} [options={}] - Provider-specific initialization options
|
|
55
|
+
* @returns {*} The native map instance
|
|
56
|
+
*/
|
|
57
|
+
initializeMap(element, options = {}) {
|
|
58
|
+
throw new Error(`${this.constructor.name} must implement initializeMap(element, options)`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Destroy the map and release all associated resources.
|
|
63
|
+
*/
|
|
64
|
+
destroyMap() {
|
|
65
|
+
throw new Error(`${this.constructor.name} must implement destroyMap()`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Bind an already-created native map instance to the adapter.
|
|
70
|
+
* Used by host components that own map creation but still route
|
|
71
|
+
* all behavior through the provider adapter.
|
|
72
|
+
*
|
|
73
|
+
* @param {*} mapInstance
|
|
74
|
+
*/
|
|
75
|
+
setMapInstance(mapInstance) {
|
|
76
|
+
this._map = mapInstance;
|
|
77
|
+
return mapInstance;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
showContextMenu(event, items = []) {
|
|
81
|
+
return { event, items };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
closeContextMenu() {}
|
|
85
|
+
|
|
86
|
+
removeLayer(layer) {
|
|
87
|
+
return layer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Called after the map container is resized. Implementations should
|
|
92
|
+
* trigger the provider's internal resize/invalidate logic.
|
|
93
|
+
*/
|
|
94
|
+
invalidateSize() {
|
|
95
|
+
throw new Error(`${this.constructor.name} must implement invalidateSize()`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ─── Viewport ──────────────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set the map center and zoom level immediately (no animation).
|
|
102
|
+
*
|
|
103
|
+
* @param {number} lat
|
|
104
|
+
* @param {number} lng
|
|
105
|
+
* @param {number} [zoom]
|
|
106
|
+
*/
|
|
107
|
+
setCenter(lat, lng, zoom) {
|
|
108
|
+
throw new Error(`${this.constructor.name} must implement setCenter(lat, lng, zoom)`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Animate the viewport to a new center and zoom level.
|
|
113
|
+
*
|
|
114
|
+
* @param {number} lat
|
|
115
|
+
* @param {number} lng
|
|
116
|
+
* @param {number} [zoom]
|
|
117
|
+
* @param {Object} [options={}]
|
|
118
|
+
*/
|
|
119
|
+
flyTo(lat, lng, zoom, options = {}) {
|
|
120
|
+
throw new Error(`${this.constructor.name} must implement flyTo(lat, lng, zoom, options)`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Fit the viewport to the given bounds.
|
|
125
|
+
*
|
|
126
|
+
* @param {Array} bounds - [[swLat, swLng], [neLat, neLng]]
|
|
127
|
+
* @param {Object} [options={}]
|
|
128
|
+
*/
|
|
129
|
+
fitBounds(bounds, options = {}) {
|
|
130
|
+
throw new Error(`${this.constructor.name} must implement fitBounds(bounds, options)`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Smoothly pan the map to a new center without changing zoom.
|
|
135
|
+
*
|
|
136
|
+
* @param {number} lat
|
|
137
|
+
* @param {number} lng
|
|
138
|
+
* @param {Object} [options={}]
|
|
139
|
+
*/
|
|
140
|
+
panTo(lat, lng, options = {}) {
|
|
141
|
+
throw new Error(`${this.constructor.name} must implement panTo(lat, lng, options)`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Increase the zoom level by one step.
|
|
146
|
+
*/
|
|
147
|
+
zoomIn() {
|
|
148
|
+
throw new Error(`${this.constructor.name} must implement zoomIn()`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Decrease the zoom level by one step.
|
|
153
|
+
*/
|
|
154
|
+
zoomOut() {
|
|
155
|
+
throw new Error(`${this.constructor.name} must implement zoomOut()`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get the current zoom level.
|
|
160
|
+
*
|
|
161
|
+
* @returns {number}
|
|
162
|
+
*/
|
|
163
|
+
getZoom() {
|
|
164
|
+
throw new Error(`${this.constructor.name} must implement getZoom()`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get the current map center as { lat, lng }.
|
|
169
|
+
*
|
|
170
|
+
* @returns {{ lat: number, lng: number }}
|
|
171
|
+
*/
|
|
172
|
+
getCenter() {
|
|
173
|
+
throw new Error(`${this.constructor.name} must implement getCenter()`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get the current viewport bounds as [[swLat, swLng], [neLat, neLng]].
|
|
178
|
+
*
|
|
179
|
+
* @returns {Array}
|
|
180
|
+
*/
|
|
181
|
+
getBounds() {
|
|
182
|
+
throw new Error(`${this.constructor.name} must implement getBounds()`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ─── Markers ───────────────────────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Add a marker to the map and register it by id.
|
|
189
|
+
*
|
|
190
|
+
* @param {string} id - Unique identifier for this marker
|
|
191
|
+
* @param {number} lat
|
|
192
|
+
* @param {number} lng
|
|
193
|
+
* @param {Object} [options={}] - May include: iconUrl, iconSize, title, content (HTML element), zIndexOffset
|
|
194
|
+
* @returns {*} The native marker object
|
|
195
|
+
*/
|
|
196
|
+
addMarker(id, lat, lng, options = {}) {
|
|
197
|
+
throw new Error(`${this.constructor.name} must implement addMarker(id, lat, lng, options)`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Update a registered marker's position, optionally with smooth animation.
|
|
202
|
+
*
|
|
203
|
+
* @param {string} id
|
|
204
|
+
* @param {number} lat
|
|
205
|
+
* @param {number} lng
|
|
206
|
+
* @param {boolean} [animated=true]
|
|
207
|
+
* @param {number} [duration=500] - Animation duration in ms
|
|
208
|
+
*/
|
|
209
|
+
updateMarkerPosition(id, lat, lng, animated = true, duration = 500) {
|
|
210
|
+
throw new Error(`${this.constructor.name} must implement updateMarkerPosition(id, lat, lng, animated, duration)`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Rotate a marker to the given heading in degrees.
|
|
215
|
+
*
|
|
216
|
+
* @param {string} id
|
|
217
|
+
* @param {number} degrees
|
|
218
|
+
*/
|
|
219
|
+
setMarkerRotation(id, degrees) {
|
|
220
|
+
throw new Error(`${this.constructor.name} must implement setMarkerRotation(id, degrees)`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Remove a registered marker from the map.
|
|
225
|
+
*
|
|
226
|
+
* @param {string} id
|
|
227
|
+
*/
|
|
228
|
+
removeMarker(id) {
|
|
229
|
+
throw new Error(`${this.constructor.name} must implement removeMarker(id)`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Retrieve the native marker object by id.
|
|
234
|
+
*
|
|
235
|
+
* @param {string} id
|
|
236
|
+
* @returns {*|null}
|
|
237
|
+
*/
|
|
238
|
+
getMarker(id) {
|
|
239
|
+
return this._markers.get(id) ?? null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check whether a marker with the given id exists.
|
|
244
|
+
*
|
|
245
|
+
* @param {string} id
|
|
246
|
+
* @returns {boolean}
|
|
247
|
+
*/
|
|
248
|
+
hasMarker(id) {
|
|
249
|
+
return this._markers.has(id);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ─── Overlays ──────────────────────────────────────────────────────────────
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Add a polygon overlay.
|
|
256
|
+
*
|
|
257
|
+
* @param {string} id
|
|
258
|
+
* @param {Array} coordinates - Array of [lat, lng] pairs
|
|
259
|
+
* @param {Object} [options={}]
|
|
260
|
+
* @returns {*} The native polygon object
|
|
261
|
+
*/
|
|
262
|
+
addPolygon(id, coordinates, options = {}) {
|
|
263
|
+
throw new Error(`${this.constructor.name} must implement addPolygon(id, coordinates, options)`);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Add a polyline overlay.
|
|
268
|
+
*
|
|
269
|
+
* @param {string} id
|
|
270
|
+
* @param {Array} coordinates - Array of [lat, lng] pairs
|
|
271
|
+
* @param {Object} [options={}]
|
|
272
|
+
* @returns {*} The native polyline object
|
|
273
|
+
*/
|
|
274
|
+
addPolyline(id, coordinates, options = {}) {
|
|
275
|
+
throw new Error(`${this.constructor.name} must implement addPolyline(id, coordinates, options)`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Add a circle overlay.
|
|
280
|
+
*
|
|
281
|
+
* @param {string} id
|
|
282
|
+
* @param {number} lat
|
|
283
|
+
* @param {number} lng
|
|
284
|
+
* @param {number} radiusMeters
|
|
285
|
+
* @param {Object} [options={}]
|
|
286
|
+
* @returns {*} The native circle object
|
|
287
|
+
*/
|
|
288
|
+
addCircle(id, lat, lng, radiusMeters, options = {}) {
|
|
289
|
+
throw new Error(`${this.constructor.name} must implement addCircle(id, lat, lng, radiusMeters, options)`);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Remove a registered overlay from the map.
|
|
294
|
+
*
|
|
295
|
+
* @param {string} id
|
|
296
|
+
*/
|
|
297
|
+
removeOverlay(id) {
|
|
298
|
+
throw new Error(`${this.constructor.name} must implement removeOverlay(id)`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Remove all registered overlays from the map.
|
|
303
|
+
*/
|
|
304
|
+
clearOverlays() {
|
|
305
|
+
for (const id of this._overlays.keys()) {
|
|
306
|
+
this.removeOverlay(id);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Retrieve the native overlay object by id.
|
|
312
|
+
*
|
|
313
|
+
* @param {string} id
|
|
314
|
+
* @returns {*|null}
|
|
315
|
+
*/
|
|
316
|
+
getOverlay(id) {
|
|
317
|
+
return this._overlays.get(id) ?? null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// ─── Routing Controls ─────────────────────────────────────────────────────
|
|
321
|
+
|
|
322
|
+
addRoutingControl(route, options = {}) {
|
|
323
|
+
throw new Error(`${this.constructor.name} must implement addRoutingControl(route, options)`);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
replaceRoutingControl(route, existingHandle, options = {}) {
|
|
327
|
+
if (existingHandle) {
|
|
328
|
+
this.removeRoutingControl(existingHandle, options.removeOptions ?? {});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return this.addRoutingControl(route, options);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
removeRoutingControl(handle, options = {}) {
|
|
335
|
+
throw new Error(`${this.constructor.name} must implement removeRoutingControl(handle, options)`);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
clearRoutingControls(filter) {
|
|
339
|
+
for (const handle of this._routingControls.values()) {
|
|
340
|
+
if (typeof filter === 'function' && filter(handle) === false) {
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
this.removeRoutingControl(handle);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
positionWaypoints(waypointsOrBounds, options = {}) {
|
|
348
|
+
return { waypointsOrBounds, options };
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ─── Drawing Tools ─────────────────────────────────────────────────────────
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Enable the drawing mode for the given shape type.
|
|
355
|
+
*
|
|
356
|
+
* @param {'polygon'|'circle'|'rectangle'|'polyline'|'marker'|null} type
|
|
357
|
+
*/
|
|
358
|
+
enableDrawingMode(type, options = {}) {
|
|
359
|
+
throw new Error(`${this.constructor.name} must implement enableDrawingMode(type)`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Disable drawing mode and return to normal interaction.
|
|
364
|
+
*/
|
|
365
|
+
disableDrawingMode() {
|
|
366
|
+
throw new Error(`${this.constructor.name} must implement disableDrawingMode()`);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Show the drawing toolbar UI control.
|
|
371
|
+
*/
|
|
372
|
+
showDrawControl(config = {}) {
|
|
373
|
+
throw new Error(`${this.constructor.name} must implement showDrawControl()`);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Hide the drawing toolbar UI control.
|
|
378
|
+
*/
|
|
379
|
+
hideDrawControl() {
|
|
380
|
+
throw new Error(`${this.constructor.name} must implement hideDrawControl()`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ─── Popups / Info Windows ─────────────────────────────────────────────────
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Open a popup at the given coordinates with HTML content.
|
|
387
|
+
*
|
|
388
|
+
* @param {string} id - Unique identifier for this popup
|
|
389
|
+
* @param {number} lat
|
|
390
|
+
* @param {number} lng
|
|
391
|
+
* @param {string|HTMLElement} htmlContent
|
|
392
|
+
* @returns {*} The native popup/info-window object
|
|
393
|
+
*/
|
|
394
|
+
openPopup(id, lat, lng, htmlContent) {
|
|
395
|
+
throw new Error(`${this.constructor.name} must implement openPopup(id, lat, lng, htmlContent)`);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Close and remove a popup by id.
|
|
400
|
+
*
|
|
401
|
+
* @param {string} id
|
|
402
|
+
*/
|
|
403
|
+
closePopup(id) {
|
|
404
|
+
throw new Error(`${this.constructor.name} must implement closePopup(id)`);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// ─── Context Menus ─────────────────────────────────────────────────────────
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Register a right-click context menu on the map or a specific marker.
|
|
411
|
+
*
|
|
412
|
+
* @param {'map'|string} target - 'map' or a marker id
|
|
413
|
+
* @param {Array<{label: string, action: Function, separator?: boolean}>} items
|
|
414
|
+
*/
|
|
415
|
+
registerContextMenu(target, items) {
|
|
416
|
+
throw new Error(`${this.constructor.name} must implement registerContextMenu(target, items)`);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Remove a previously registered context menu.
|
|
421
|
+
*
|
|
422
|
+
* @param {'map'|string} target
|
|
423
|
+
*/
|
|
424
|
+
removeContextMenu(target) {
|
|
425
|
+
throw new Error(`${this.constructor.name} must implement removeContextMenu(target)`);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// ─── Events ────────────────────────────────────────────────────────────────
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Register an event listener on the map.
|
|
432
|
+
* Normalized event names: 'click', 'dblclick', 'rightclick', 'moveend',
|
|
433
|
+
* 'zoomend', 'load', 'draw:created', 'draw:edited', 'draw:deleted'
|
|
434
|
+
*
|
|
435
|
+
* @param {string} event
|
|
436
|
+
* @param {Function} handler
|
|
437
|
+
*/
|
|
438
|
+
on(event, handler) {
|
|
439
|
+
throw new Error(`${this.constructor.name} must implement on(event, handler)`);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Remove an event listener from the map.
|
|
444
|
+
*
|
|
445
|
+
* @param {string} event
|
|
446
|
+
* @param {Function} handler
|
|
447
|
+
*/
|
|
448
|
+
off(event, handler) {
|
|
449
|
+
throw new Error(`${this.constructor.name} must implement off(event, handler)`);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Register a one-time event listener on the map.
|
|
454
|
+
*
|
|
455
|
+
* @param {string} event
|
|
456
|
+
* @param {Function} handler
|
|
457
|
+
*/
|
|
458
|
+
once(event, handler) {
|
|
459
|
+
throw new Error(`${this.constructor.name} must implement once(event, handler)`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// ─── Utilities ─────────────────────────────────────────────────────────────
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Calculate the distance in metres between two coordinates.
|
|
466
|
+
*
|
|
467
|
+
* @param {number} lat1
|
|
468
|
+
* @param {number} lng1
|
|
469
|
+
* @param {number} lat2
|
|
470
|
+
* @param {number} lng2
|
|
471
|
+
* @returns {number} Distance in metres
|
|
472
|
+
*/
|
|
473
|
+
distanceBetween(lat1, lng1, lat2, lng2) {
|
|
474
|
+
throw new Error(`${this.constructor.name} must implement distanceBetween(lat1, lng1, lat2, lng2)`);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Render a GeoJSON object onto the map.
|
|
479
|
+
*
|
|
480
|
+
* @param {string} id - Unique identifier for this GeoJSON layer
|
|
481
|
+
* @param {Object} geojson - A valid GeoJSON FeatureCollection or Feature
|
|
482
|
+
* @param {Object} [options={}]
|
|
483
|
+
* @returns {*} The native GeoJSON layer object
|
|
484
|
+
*/
|
|
485
|
+
addGeoJson(id, geojson, options = {}) {
|
|
486
|
+
throw new Error(`${this.constructor.name} must implement addGeoJson(id, geojson, options)`);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Remove a GeoJSON layer by id.
|
|
491
|
+
*
|
|
492
|
+
* @param {string} id
|
|
493
|
+
*/
|
|
494
|
+
removeGeoJson(id) {
|
|
495
|
+
throw new Error(`${this.constructor.name} must implement removeGeoJson(id)`);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Set the map's tile/base layer URL (for providers that support custom tiles).
|
|
500
|
+
*
|
|
501
|
+
* @param {string} url
|
|
502
|
+
* @param {Object} [options={}]
|
|
503
|
+
*/
|
|
504
|
+
setTileLayer(url, options = {}) {
|
|
505
|
+
// Optional — providers that don't support custom tiles can no-op this.
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
registerMarker(id, markerObject) {
|
|
509
|
+
this._markers.set(id, markerObject);
|
|
510
|
+
return markerObject;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
registerPolygon(id, polygonObject) {
|
|
514
|
+
this._overlays.set(id, polygonObject);
|
|
515
|
+
return polygonObject;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
showPolygon(id) {
|
|
519
|
+
const polygon = this.getOverlay(id);
|
|
520
|
+
if (polygon) {
|
|
521
|
+
this.showLayer?.(polygon);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return polygon ?? null;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
hidePolygon(id) {
|
|
528
|
+
const polygon = this.getOverlay(id);
|
|
529
|
+
if (polygon) {
|
|
530
|
+
this.hideLayer?.(polygon);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return polygon ?? null;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
getContextMenuItems() {
|
|
537
|
+
return [];
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
showCoordinates() {}
|
|
541
|
+
|
|
542
|
+
centerMap() {}
|
|
543
|
+
|
|
544
|
+
toggleDrawControl() {}
|
|
545
|
+
|
|
546
|
+
panBy() {}
|
|
547
|
+
|
|
548
|
+
editPolygon() {
|
|
549
|
+
return Promise.resolve({ type: 'unsupported' });
|
|
550
|
+
}
|
|
551
|
+
}
|