Showing
8 changed files
with
127 additions
and
38 deletions
... | ... | @@ -31,6 +31,7 @@ import { Polygon } from './polygon'; |
31 | 31 | export default abstract class LeafletMap { |
32 | 32 | |
33 | 33 | markers: Map<string, Marker> = new Map(); |
34 | + dragMode = false; | |
34 | 35 | tooltips = []; |
35 | 36 | poly: Polyline; |
36 | 37 | polygon: Polygon; |
... | ... | @@ -55,6 +56,7 @@ export default abstract class LeafletMap { |
55 | 56 | mapProvider, |
56 | 57 | credentials, |
57 | 58 | defaultCenterPosition, |
59 | + draggebleMarker, | |
58 | 60 | markerClusteringSetting }: MapOptions = options; |
59 | 61 | if (disableScrollZooming) { |
60 | 62 | this.map.scrollWheelZoom.disable(); |
... | ... | @@ -64,6 +66,33 @@ export default abstract class LeafletMap { |
64 | 66 | } |
65 | 67 | } |
66 | 68 | |
69 | + addMarkerControl() { | |
70 | + if (this.options.draggebleMarker) | |
71 | + L.Control['AddMarker'] = L.Control.extend({ | |
72 | + onAdd: function (map) { | |
73 | + let img = L.DomUtil.create('img') as any; | |
74 | + img.src = `assets/add_location.svg`; | |
75 | + img.style.width = '32px'; | |
76 | + img.style.height = '32px'; | |
77 | + img.onclick = this.dragMarker; | |
78 | + return img; | |
79 | + }, | |
80 | + addHooks: function () { | |
81 | + L.DomEvent.on(window as any, 'onclick', this.enableDragMode, this); | |
82 | + }, | |
83 | + onRemove: function (map) { | |
84 | + }, | |
85 | + dragMarker: ($event) => { | |
86 | + this.dragMode = !this.dragMode; | |
87 | + } | |
88 | + }); | |
89 | + | |
90 | + L.control['addmarker'] = function (opts) { | |
91 | + return new L.Control['AddMarker'](opts); | |
92 | + } | |
93 | + L.control['addmarker']({ position: 'topright' }).addTo(this.map); | |
94 | + } | |
95 | + | |
67 | 96 | inited() { |
68 | 97 | return !!this.map; |
69 | 98 | } |
... | ... | @@ -74,10 +103,21 @@ export default abstract class LeafletMap { |
74 | 103 | this.map.panTo(this.options.defaultCenterPosition); |
75 | 104 | this.bounds = map.getBounds(); |
76 | 105 | } |
77 | - else this.bounds = new L.LatLngBounds(null, null) | |
106 | + else this.bounds = new L.LatLngBounds(null, null); | |
107 | + if (this.options.draggebleMarker) { | |
108 | + this.addMarkerControl(); | |
109 | + this.map.on('click', (e: L.LeafletMouseEvent) => { | |
110 | + if (this.dragMode) | |
111 | + this.saveMarkerLocation(this.convertToCustomFormat(e.latlng)); | |
112 | + }) | |
113 | + } | |
78 | 114 | this.map$.next(this.map); |
79 | 115 | } |
80 | 116 | |
117 | + public saveMarkerLocation(e) { | |
118 | + | |
119 | + } | |
120 | + | |
81 | 121 | getContainer() { |
82 | 122 | return this.map; |
83 | 123 | } |
... | ... | @@ -117,6 +157,13 @@ export default abstract class LeafletMap { |
117 | 157 | return L.latLng(expression[this.options.latKeyName], expression[this.options.lngKeyName]) as L.LatLng; |
118 | 158 | } |
119 | 159 | |
160 | + convertToCustomFormat(position: L.LatLng): object { | |
161 | + return { | |
162 | + [this.options.latKeyName]: position.lat, | |
163 | + [this.options.lngKeyName]: position.lng | |
164 | + } | |
165 | + } | |
166 | + | |
120 | 167 | ////Markers |
121 | 168 | updateMarkers(markersData) { |
122 | 169 | markersData.forEach(data => { |
... | ... | @@ -179,33 +226,34 @@ export default abstract class LeafletMap { |
179 | 226 | } |
180 | 227 | |
181 | 228 | createPolyline(data, dataSources, settings) { |
182 | - this.ready$.subscribe(() => { | |
183 | - this.poly = new Polyline(this.map, data.map(data => this.convertPosition(data)), data, dataSources, settings); | |
184 | - const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds()); | |
185 | - if (bounds.isValid()) { | |
186 | - this.map.fitBounds(bounds); | |
187 | - this.bounds = bounds; | |
188 | - } | |
189 | - }); | |
229 | + if (data.length) | |
230 | + this.ready$.subscribe(() => { | |
231 | + this.poly = new Polyline(this.map, data.map(data => this.convertPosition(data)), data, dataSources, settings); | |
232 | + const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds()); | |
233 | + if (bounds.isValid()) { | |
234 | + this.map.fitBounds(bounds); | |
235 | + this.bounds = bounds; | |
236 | + } | |
237 | + }); | |
190 | 238 | } |
191 | 239 | |
192 | 240 | updatePolyline(data, dataSources, settings) { |
193 | 241 | this.ready$.subscribe(() => { |
194 | - this.poly.updatePolyline(settings, data, dataSources); | |
242 | + this.poly.updatePolyline(settings, data, dataSources); | |
195 | 243 | }); |
196 | - } | |
244 | + } | |
197 | 245 | |
198 | - //polygon | |
246 | + //polygon | |
199 | 247 | |
200 | - updatePolygon(polyData: Array<Array<any>>) { | |
201 | - polyData.forEach(data => { | |
202 | - if (data.length) { | |
248 | + updatePolygons(polyData: Array<Array<any>>) { | |
249 | + polyData.forEach((data: any) => { | |
250 | + if (data.data.length) { | |
203 | 251 | let dataSource = polyData.map(arr => arr[0]); |
204 | - if (this.poly) { | |
205 | - this.updatePolyline(data, dataSource, this.options); | |
252 | + if (this.polygon) { | |
253 | + this.updatePolygon(data, dataSource, this.options); | |
206 | 254 | } |
207 | 255 | else { |
208 | - this.createPolyline(data, dataSource, this.options); | |
256 | + this.createPolygon(data, dataSource, this.options); | |
209 | 257 | } |
210 | 258 | } |
211 | 259 | }) |
... | ... | @@ -214,7 +262,7 @@ export default abstract class LeafletMap { |
214 | 262 | createPolygon(data, dataSources, settings) { |
215 | 263 | this.ready$.subscribe(() => { |
216 | 264 | this.polygon = new Polygon(this.map, data.map(data => this.convertPosition(data)), data, dataSources, settings); |
217 | - const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds()); | |
265 | + const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds()); | |
218 | 266 | if (bounds.isValid()) { |
219 | 267 | this.map.fitBounds(bounds); |
220 | 268 | this.bounds = bounds; |
... | ... | @@ -222,9 +270,9 @@ export default abstract class LeafletMap { |
222 | 270 | }); |
223 | 271 | } |
224 | 272 | |
225 | - updatePolygons(data, dataSources, settings) { | |
273 | + updatePolygon(data, dataSources, settings) { | |
226 | 274 | this.ready$.subscribe(() => { |
227 | - this.poly.updatePolyline(settings, data, dataSources); | |
275 | + this.poly.updatePolyline(settings, data, dataSources); | |
228 | 276 | }); |
229 | - } | |
277 | + } | |
230 | 278 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -32,6 +32,8 @@ import { MapWidgetStaticInterface, MapWidgetInterface } from './map-widget.inter |
32 | 32 | import { OpenStreetMap, TencentMap, GoogleMap, HEREMap, ImageMap } from './providers'; |
33 | 33 | import { parseFunction, parseArray, parseData } from '@app/core/utils'; |
34 | 34 | import { initSchema, addToSchema, mergeSchemes, addCondition, addGroupInfo } from '@app/core/schema-utils'; |
35 | +import { AttributeScope, EntityId } from '@app/shared/public-api'; | |
36 | +import { forkJoin } from 'rxjs'; | |
35 | 37 | |
36 | 38 | export class MapWidgetController implements MapWidgetInterface { |
37 | 39 | |
... | ... | @@ -58,11 +60,43 @@ export class MapWidgetController implements MapWidgetInterface { |
58 | 60 | return; |
59 | 61 | } |
60 | 62 | this.map = new MapClass($element, this.settings); |
63 | + this.map.saveMarkerLocation = this.setMarkerLocation; | |
61 | 64 | } |
62 | 65 | |
63 | 66 | onInit() { |
64 | 67 | } |
65 | 68 | |
69 | + setMarkerLocation = (e) => { | |
70 | + console.log("MapWidgetController -> setMarkerLocation -> e", e) | |
71 | + console.log(this.data); | |
72 | + | |
73 | + let attributeService = this.ctx.$scope.$injector.get(this.ctx.servicesMap.get('attributeService')); | |
74 | + | |
75 | + | |
76 | + let attributesLocation = []; | |
77 | + let timeseriesLocation = []; | |
78 | + let promises = []; | |
79 | + forkJoin( | |
80 | + this.data.filter(data => !!e[data.dataKey.name]) | |
81 | + .map(data => { | |
82 | + const entityId: EntityId = { | |
83 | + entityType: data.datasource.entityType, | |
84 | + id: data.datasource.entityId | |
85 | + }; | |
86 | + return attributeService.saveEntityAttributes( | |
87 | + entityId, | |
88 | + AttributeScope.SHARED_SCOPE, | |
89 | + [{ | |
90 | + key: data.dataKey.name, | |
91 | + value: e[data.dataKey.name] | |
92 | + }] | |
93 | + ); | |
94 | + })).subscribe(res => { | |
95 | + console.log("MapWidgetController -> setMarkerLocation -> res", res) | |
96 | + | |
97 | + }); | |
98 | + } | |
99 | + | |
66 | 100 | initSettings(settings: any) { |
67 | 101 | const functionParams = ['data', 'dsData', 'dsIndex']; |
68 | 102 | this.provider = settings.provider ? settings.provider : this.mapProvider; |
... | ... | @@ -78,6 +112,7 @@ export class MapWidgetController implements MapWidgetInterface { |
78 | 112 | tooltipPattern: settings.tooltipPattern || |
79 | 113 | "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${" + settings.latKeyName + ":7}<br/><b>Longitude:</b> ${" + settings.lngKeyName + ":7}", |
80 | 114 | defaultCenterPosition: settings?.defaultCenterPosition?.split(',') || [0, 0], |
115 | + useDraggableMarker: true, | |
81 | 116 | currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? { |
82 | 117 | url: settings.markerImage, |
83 | 118 | size: settings.markerImageSize || 34 |
... | ... | @@ -89,20 +124,16 @@ export class MapWidgetController implements MapWidgetInterface { |
89 | 124 | update() { |
90 | 125 | if (this.drawRoutes) |
91 | 126 | this.map.updatePolylines(parseArray(this.data)); |
92 | - if(this.settings.showPolygon) | |
93 | - { | |
94 | - console.log(this.data); | |
95 | - | |
96 | - let dummy = [[37.771121,-22.510761],[37.774581,-22.454885],[37.766575,-22.453683],[37.764268,-22.509945]]; | |
97 | - this.map.updatePolygon(dummy); | |
127 | + if (this.settings.showPolygon) { | |
128 | + //console.log(this.data, this.ctx); | |
129 | + | |
130 | + // let dummy = [[37.771121,-22.510761],[37.774581,-22.454885],[37.766575,-22.453683],[37.764268,-22.509945]]; | |
131 | + //this.data[0].data = dummy | |
132 | + //this.map.updatePolygons(this.data); | |
98 | 133 | } |
99 | 134 | this.map.updateMarkers(parseData(this.data)); |
100 | 135 | } |
101 | 136 | |
102 | - public updateHistoryData(dataSources) { | |
103 | - dataSources.map() | |
104 | - } | |
105 | - | |
106 | 137 | onDataUpdated() { |
107 | 138 | } |
108 | 139 | |
... | ... | @@ -119,15 +150,15 @@ export class MapWidgetController implements MapWidgetInterface { |
119 | 150 | return {}; |
120 | 151 | } |
121 | 152 | |
122 | - public static getProvidersSchema(){ | |
123 | - return mergeSchemes([mapProviderSchema, | |
153 | + public static getProvidersSchema() { | |
154 | + return mergeSchemes([mapProviderSchema, | |
124 | 155 | ...Object.values(providerSets)?.map( |
125 | 156 | setting => addCondition(setting?.schema, `model.provider === '${setting.name}'`))]); |
126 | - } | |
157 | + } | |
127 | 158 | |
128 | 159 | public static settingsSchema(mapProvider, drawRoutes): Object { |
129 | 160 | let schema = initSchema(); |
130 | - addToSchema(schema,this.getProvidersSchema()); | |
161 | + addToSchema(schema, this.getProvidersSchema()); | |
131 | 162 | addGroupInfo(schema, "Map Provider Settings"); |
132 | 163 | addToSchema(schema, commonMapSettingsSchema); |
133 | 164 | addGroupInfo(schema, "Common Map Settings"); |
... | ... | @@ -228,4 +259,5 @@ const defaultSettings = { |
228 | 259 | minZoomLevel: 16, |
229 | 260 | credentials: '', |
230 | 261 | markerClusteringSetting: null, |
262 | + draggebleMarker: true | |
231 | 263 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -29,7 +29,7 @@ export class Marker { |
29 | 29 | data; |
30 | 30 | dataSources; |
31 | 31 | |
32 | - constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data, dataSources, onClickListener?, onDragendListener?) { | |
32 | + constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data?, dataSources?, onClickListener?, onDragendListener?) { | |
33 | 33 | //this.map = map; |
34 | 34 | this.location = location; |
35 | 35 | this.setDataSources(data, dataSources); | ... | ... |
... | ... | @@ -24,6 +24,7 @@ export class Polyline { |
24 | 24 | data; |
25 | 25 | |
26 | 26 | constructor(private map: L.Map, locations, data, dataSources, settings) { |
27 | + console.log("Polyline -> constructor -> data", data) | |
27 | 28 | this.dataSources = dataSources; |
28 | 29 | this.data = data; |
29 | 30 | this.leafletPoly = L.polyline(locations, | ... | ... |
... | ... | @@ -371,6 +371,11 @@ export const commonMapSettingsSchema = |
371 | 371 | "title": "Polygon Color function: f(data, dsData, dsIndex)", |
372 | 372 | "type": "string" |
373 | 373 | }, |
374 | + "draggableMarker": { | |
375 | + "title": "Draggable Marker", | |
376 | + "type": "boolean", | |
377 | + "default": false | |
378 | + }, | |
374 | 379 | "markerImage": { |
375 | 380 | "title": "Custom marker image", |
376 | 381 | "type": "string" |
... | ... | @@ -411,6 +416,7 @@ export const commonMapSettingsSchema = |
411 | 416 | "showLabel", |
412 | 417 | "label", |
413 | 418 | "useLabelFunction", |
419 | + "draggableMarker", | |
414 | 420 | { |
415 | 421 | "key": "labelFunction", |
416 | 422 | "type": "javascript" | ... | ... |
ui-ngx/src/assets/add_location.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path d="M24 4c-7.72 0-14 6.28-14 14 0 10.5 14 26 14 26s14-15.5 14-26c0-7.72-6.28-14-14-14zm8 16h-6v6h-4v-6h-6v-4h6v-6h4v6h6v4z"/></svg> | |
\ No newline at end of file | ... | ... |