Commit 5d33da4b09eb578649081e069bc750d56f996e81

Authored by Artem Halushko
1 parent 9eb68670

labels support

@@ -61,24 +61,8 @@ export default abstract class LeafletMap { @@ -61,24 +61,8 @@ export default abstract class LeafletMap {
61 } 61 }
62 62
63 getContainer() { 63 getContainer() {
64 - return /* this.isMarketCluster ? this.markersCluster :*/ this.map; 64 + return this.map;
65 } 65 }
66 - /*  
67 - fitBounds(bounds, useDefaultZoom) {  
68 - if (bounds.isValid()) {  
69 - if ((this.dontFitMapBounds || useDefaultZoom) && this.defaultZoomLevel) {  
70 - this.map.setZoom(this.defaultZoomLevel, { animate: false });  
71 - this.map.panTo(bounds.getCenter(), { animate: false });  
72 - } else {  
73 - this.map.once('zoomend', () => {  
74 - if (!this.defaultZoomLevel && this.map.getZoom() > this.minZoomLevel) {  
75 - this.map.setZoom(this.minZoomLevel, { animate: false });  
76 - }  
77 - });  
78 - this.map.fitBounds(bounds, { padding: [50, 50], animate: false });  
79 - }  
80 - }  
81 - }*/  
82 66
83 createLatLng(lat, lng) { 67 createLatLng(lat, lng) {
84 return L.latLng(lat, lng); 68 return L.latLng(lat, lng);
@@ -161,7 +145,8 @@ export default abstract class LeafletMap { @@ -161,7 +145,8 @@ export default abstract class LeafletMap {
161 if (!location.equals(marker.location)) { 145 if (!location.equals(marker.location)) {
162 marker.updateMarkerPosition(location); 146 marker.updateMarkerPosition(location);
163 } 147 }
164 - marker.updateMarkerIcon(settings, data, dataSources); 148 + marker.setDataSources(data, dataSources);
  149 + marker.updateMarkerIcon(settings);
165 } 150 }
166 151
167 private deleteMarker() { 152 private deleteMarker() {
@@ -173,7 +158,7 @@ export default abstract class LeafletMap { @@ -173,7 +158,7 @@ export default abstract class LeafletMap {
173 updatePolylines(polyData: Array<Array<any>>) { 158 updatePolylines(polyData: Array<Array<any>>) {
174 polyData.forEach(data => { 159 polyData.forEach(data => {
175 if (data.length) { 160 if (data.length) {
176 - let dataSource = polyData.map(arr=>arr[0]); 161 + let dataSource = polyData.map(arr => arr[0]);
177 if (this.poly) { 162 if (this.poly) {
178 this.updatePolyline(data, dataSource, this.options); 163 this.updatePolyline(data, dataSource, this.options);
179 } 164 }
@@ -15,7 +15,9 @@ export interface MapOptions { @@ -15,7 +15,9 @@ export interface MapOptions {
15 credentials?: any, // declare credentials format 15 credentials?: any, // declare credentials format
16 defaultCenterPosition?: LatLngTuple, 16 defaultCenterPosition?: LatLngTuple,
17 markerClusteringSetting?, 17 markerClusteringSetting?,
18 - useDefaultCenterPosition?: boolean 18 + useDefaultCenterPosition?: boolean,
  19 + gmDefaultMapType?: string,
  20 + useLabelFunction: string;
19 } 21 }
20 22
21 export enum MapProviders { 23 export enum MapProviders {
@@ -50,7 +50,7 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface { @@ -50,7 +50,7 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
50 const functionParams = ['data', 'dsData', 'dsIndex']; 50 const functionParams = ['data', 'dsData', 'dsIndex'];
51 this.provider = settings.provider ? settings.provider : this.mapProvider; 51 this.provider = settings.provider ? settings.provider : this.mapProvider;
52 const customOptions = { 52 const customOptions = {
53 - mapProvider: this.provider, 53 + provider: this.provider,
54 mapUrl: settings?.mapImageUrl, 54 mapUrl: settings?.mapImageUrl,
55 labelFunction: parseFunction(settings.labelFunction, functionParams), 55 labelFunction: parseFunction(settings.labelFunction, functionParams),
56 tooltipFunction: parseFunction(settings.tooltipFunction, functionParams), 56 tooltipFunction: parseFunction(settings.tooltipFunction, functionParams),
@@ -59,8 +59,7 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface { @@ -59,8 +59,7 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
59 markerImageFunction: parseFunction(settings.markerImageFunction, ['data', 'images', 'dsData', 'dsIndex']), 59 markerImageFunction: parseFunction(settings.markerImageFunction, ['data', 'images', 'dsData', 'dsIndex']),
60 tooltipPattern: settings.tooltipPattern || 60 tooltipPattern: settings.tooltipPattern ||
61 "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${" + settings.latKeyName + ":7}<br/><b>Longitude:</b> ${" + settings.lngKeyName + ":7}", 61 "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${" + settings.latKeyName + ":7}<br/><b>Longitude:</b> ${" + settings.lngKeyName + ":7}",
62 - label: settings.label || "${entityName}",  
63 - defaultCenterPosition: settings?.defaultCenterPosition?.split(',') || [0,0], 62 + defaultCenterPosition: settings?.defaultCenterPosition?.split(',') || [0, 0],
64 currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? { 63 currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? {
65 url: settings.markerImage, 64 url: settings.markerImage,
66 size: settings.markerImageSize || 34 65 size: settings.markerImageSize || 34
@@ -82,7 +81,6 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface { @@ -82,7 +81,6 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
82 this.map.onResize();//not work 81 this.map.onResize();//not work
83 } 82 }
84 83
85 -  
86 resize() { 84 resize() {
87 this.map?.invalidateSize(); 85 this.map?.invalidateSize();
88 this.map.onResize(); 86 this.map.onResize();
@@ -239,7 +237,8 @@ const defaultSettings = { @@ -239,7 +237,8 @@ const defaultSettings = {
239 latKeyName: 'latitude', 237 latKeyName: 'latitude',
240 lngKeyName: 'longitude', 238 lngKeyName: 'longitude',
241 polygonKeyName: 'coordinates', 239 polygonKeyName: 'coordinates',
242 - showLabel: false, 240 + showLabel: true,
  241 + label: "${entityName}",
243 showTooltip: false, 242 showTooltip: false,
244 useDefaultCenterPosition: false, 243 useDefaultCenterPosition: false,
245 showTooltipAction: "click", 244 showTooltipAction: "click",
@@ -252,7 +251,7 @@ const defaultSettings = { @@ -252,7 +251,7 @@ const defaultSettings = {
252 polygonOpacity: 0.5, 251 polygonOpacity: 0.5,
253 polygonStrokeOpacity: 1, 252 polygonStrokeOpacity: 1,
254 polygonStrokeWeight: 1, 253 polygonStrokeWeight: 1,
255 - useLabelFunction: true, 254 + useLabelFunction: false,
256 markerImages: [], 255 markerImages: [],
257 strokeWeight: 2, 256 strokeWeight: 2,
258 strokeOpacity: 1.0, 257 strokeOpacity: 1.0,
@@ -34,6 +34,9 @@ export function parseArray(input: any[]): any[] { @@ -34,6 +34,9 @@ export function parseArray(input: any[]): any[] {
34 alliasArray.forEach(el => { 34 alliasArray.forEach(el => {
35 obj[el?.dataKey?.label] = el?.data[i][1]; 35 obj[el?.dataKey?.label] = el?.data[i][1];
36 obj[el?.dataKey?.label + '|ts'] = el?.data[0][0]; 36 obj[el?.dataKey?.label + '|ts'] = el?.data[0][0];
  37 + if (el?.dataKey?.label == 'type') {
  38 + obj['deviceType'] = el?.data[0][1];
  39 + }
37 }); 40 });
38 return obj; 41 return obj;
39 }) 42 })
@@ -44,18 +47,22 @@ export function parseData(input: any[]): any[] { @@ -44,18 +47,22 @@ export function parseData(input: any[]): any[] {
44 return _(input).groupBy(el => el?.datasource?.aliasName).values().value().map((alliasArray, i) => { 47 return _(input).groupBy(el => el?.datasource?.aliasName).values().value().map((alliasArray, i) => {
45 const obj = { 48 const obj = {
46 aliasName: alliasArray[0]?.datasource?.aliasName, 49 aliasName: alliasArray[0]?.datasource?.aliasName,
  50 + entityName: alliasArray[0]?.datasource?.entityName,
47 $datasource: alliasArray[0]?.datasource, 51 $datasource: alliasArray[0]?.datasource,
48 dsIndex: i 52 dsIndex: i
49 }; 53 };
50 alliasArray.forEach(el => { 54 alliasArray.forEach(el => {
51 obj[el?.dataKey?.label] = el?.data[0][1]; 55 obj[el?.dataKey?.label] = el?.data[0][1];
52 obj[el?.dataKey?.label + '|ts'] = el?.data[0][0]; 56 obj[el?.dataKey?.label + '|ts'] = el?.data[0][0];
  57 + if (el?.dataKey?.label == 'type') {
  58 + obj['deviceType'] = el?.data[0][1];
  59 + }
53 }); 60 });
54 return obj; 61 return obj;
55 }); 62 });
56 } 63 }
57 64
58 -export function safeExecute(func: Function, params = []) { 65 +export function safeExecute(func: Function, params = []) {
59 let res = null; 66 let res = null;
60 if (func && typeof (func) == "function") { 67 if (func && typeof (func) == "function") {
61 try { 68 try {
1 import L from 'leaflet'; 1 import L from 'leaflet';
2 -import { createTooltip, safeExecute } from './maps-utils'; 2 +import { createTooltip, safeExecute, parseFunction } from './maps-utils';
3 import { MarkerSettings } from './map-models'; 3 import { MarkerSettings } from './map-models';
4 import { aspectCache } from '@app/core/utils'; 4 import { aspectCache } from '@app/core/utils';
5 5
@@ -16,13 +16,12 @@ export class Marker { @@ -16,13 +16,12 @@ export class Marker {
16 constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data, dataSources, onClickListener?, markerArgs?, onDragendListener?) { 16 constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data, dataSources, onClickListener?, markerArgs?, onDragendListener?) {
17 //this.map = map; 17 //this.map = map;
18 this.location = location; 18 this.location = location;
19 - this.data = data;  
20 - this.dataSources = dataSources; 19 + this.setDataSources(data, dataSources)
21 this.leafletMarker = L.marker(location, { 20 this.leafletMarker = L.marker(location, {
22 draggable: settings.draggable 21 draggable: settings.draggable
23 }); 22 });
24 23
25 - this.createMarkerIcon(dataSources, (iconInfo) => { 24 + this.createMarkerIcon((iconInfo) => {
26 this.leafletMarker.setIcon(iconInfo.icon); 25 this.leafletMarker.setIcon(iconInfo.icon);
27 if (settings.showLabel) { 26 if (settings.showLabel) {
28 this.tooltipOffset = [0, -iconInfo.size[1] + 10]; 27 this.tooltipOffset = [0, -iconInfo.size[1] + 10];
@@ -47,15 +46,45 @@ export class Marker { @@ -47,15 +46,45 @@ export class Marker {
47 46
48 } 47 }
49 48
  49 + setDataSources(data, dataSources) {
  50 + this.data = data;
  51 + this.dataSources = dataSources;
  52 + }
  53 +
50 updateMarkerPosition(position: L.LatLngExpression) { 54 updateMarkerPosition(position: L.LatLngExpression) {
51 this.leafletMarker.setLatLng(position); 55 this.leafletMarker.setLatLng(position);
52 } 56 }
53 57
  58 +
  59 +
54 updateMarkerLabel(settings) { 60 updateMarkerLabel(settings) {
  61 +
  62 + function getText(template, data) {
  63 + let res = null;
  64 + try {
  65 + let variables = '';
  66 + for (let key in data) {
  67 + if (!key.includes('|'))
  68 + variables += `var ${key} = '${data[key]}';`;
  69 + }
  70 + res = safeExecute(parseFunction(variables + 'return' + '`' + template + '`'));
  71 + }
  72 + catch (ex) {
  73 + }
  74 + return res;
  75 + }
  76 +
  77 +
55 this.leafletMarker.unbindTooltip(); 78 this.leafletMarker.unbindTooltip();
56 - if (settings.showLabel) 79 + if (settings.showLabel) {
  80 + if (settings.useLabelFunction) {
  81 + settings.labelText = safeExecute(settings.labelFunction, [this.data, this.dataSources, this.data.dsIndex])
  82 + }
  83 + else settings.labelText = getText(settings.label, this.data);
  84 +
57 this.leafletMarker.bindTooltip(`<div style="color: ${settings.labelColor};"><b>${settings.labelText}</b></div>`, 85 this.leafletMarker.bindTooltip(`<div style="color: ${settings.labelColor};"><b>${settings.labelText}</b></div>`,
58 { className: 'tb-marker-label', permanent: true, direction: 'top', offset: this.tooltipOffset }); 86 { className: 'tb-marker-label', permanent: true, direction: 'top', offset: this.tooltipOffset });
  87 + }
59 } 88 }
60 89
61 updateMarkerColor(color) { 90 updateMarkerColor(color) {
@@ -64,9 +93,8 @@ export class Marker { @@ -64,9 +93,8 @@ export class Marker {
64 }); 93 });
65 } 94 }
66 95
67 - updateMarkerIcon(settings, data, dataSources) {  
68 - this.data = data;  
69 - this.createMarkerIcon(dataSources, (iconInfo) => { 96 + updateMarkerIcon(settings) {
  97 + this.createMarkerIcon((iconInfo) => {
70 this.leafletMarker.setIcon(iconInfo.icon); 98 this.leafletMarker.setIcon(iconInfo.icon);
71 if (settings.showLabel) { 99 if (settings.showLabel) {
72 this.tooltipOffset = [0, -iconInfo.size[1] + 10]; 100 this.tooltipOffset = [0, -iconInfo.size[1] + 10];
@@ -75,9 +103,9 @@ export class Marker { @@ -75,9 +103,9 @@ export class Marker {
75 }); 103 });
76 } 104 }
77 105
78 - createMarkerIcon(dataSources, onMarkerIconReady) { 106 + createMarkerIcon(onMarkerIconReady) {
79 const currentImage = this.settings.useMarkerImageFunction ? 107 const currentImage = this.settings.useMarkerImageFunction ?
80 - safeExecute(this.settings.markerImageFunction, [this.data, this.settings.markerImages, dataSources, this.data.dsIndex]) : this.settings.currentImage; 108 + safeExecute(this.settings.markerImageFunction, [this.data, this.settings.markerImages, this.dataSources, this.data.dsIndex]) : this.settings.currentImage;
81 // var opMap = this; 109 // var opMap = this;
82 if (currentImage && currentImage.url) { 110 if (currentImage && currentImage.url) {
83 aspectCache(currentImage.url).subscribe( 111 aspectCache(currentImage.url).subscribe(
@@ -14,7 +14,7 @@ export class GoogleMap extends LeafletMap { @@ -14,7 +14,7 @@ export class GoogleMap extends LeafletMap {
14 this.loadGoogle(() => { 14 this.loadGoogle(() => {
15 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); 15 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
16 var roads = (L.gridLayer as any).googleMutant({ 16 var roads = (L.gridLayer as any).googleMutant({
17 - type: 'roadmap' // valid values are 'roadmap', 'satellite', 'terrain' and 'hybrid' 17 + type: options?.gmDefaultMapType || 'roadmap' // valid values are 'roadmap', 'satellite', 'terrain' and 'hybrid'
18 }).addTo(map); 18 }).addTo(map);
19 super.setMap(map); 19 super.setMap(map);
20 }, options.credentials.apiKey); 20 }, options.credentials.apiKey);