Commit f12ecdb11be2a9a16edb8f98c9be239951400504

Authored by Artem Halushko
1 parent 235b41c6

marker dropping support

... ... @@ -498,7 +498,7 @@ export function safeExecute(func: Function, params = []) {
498 498 res = func(...params);
499 499 }
500 500 catch (err) {
501   - console.error(err);
  501 + console.log(err);
502 502 res = null;
503 503 }
504 504 }
... ...
... ... @@ -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
... ...
... ... @@ -17,6 +17,7 @@
17 17 import { LatLngExpression, LatLngTuple } from 'leaflet';
18 18
19 19 export interface MapOptions {
  20 + draggebleMarker: any;
20 21 initCallback?: Function,
21 22 defaultZoomLevel?: number,
22 23 dontFitMapBounds?: boolean,
... ...
... ... @@ -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"
... ...
  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
... ...