Commit fc597f2c0bc25bbcf39f72f516ef8d4cd5a27f3c

Authored by Igor Kulikov
Committed by GitHub
2 parents b8da6330 cb6a21fe

Merge pull request #3110 from vvlladd28/bug/map

[3.0] Improvment map
@@ -14,25 +14,32 @@ @@ -14,25 +14,32 @@
14 /// limitations under the License. 14 /// limitations under the License.
15 /// 15 ///
16 16
17 -import L, { FeatureGroup, LatLngBounds, LatLngTuple, markerClusterGroup, MarkerClusterGroupOptions, MarkerClusterGroup } from 'leaflet'; 17 +import L, {
  18 + FeatureGroup,
  19 + LatLngBounds,
  20 + LatLngTuple,
  21 + markerClusterGroup,
  22 + MarkerClusterGroup,
  23 + MarkerClusterGroupOptions
  24 +} from 'leaflet';
18 25
19 import 'leaflet-providers'; 26 import 'leaflet-providers';
20 import 'leaflet.markercluster/dist/leaflet.markercluster'; 27 import 'leaflet.markercluster/dist/leaflet.markercluster';
21 28
22 import { 29 import {
23 - FormattedData,  
24 - MapSettings,  
25 - MarkerSettings,  
26 - PolygonSettings,  
27 - PolylineSettings,  
28 - UnitedMapSettings 30 + FormattedData,
  31 + MapSettings,
  32 + MarkerSettings,
  33 + PolygonSettings,
  34 + PolylineSettings,
  35 + UnitedMapSettings
29 } from './map-models'; 36 } from './map-models';
30 import { Marker } from './markers'; 37 import { Marker } from './markers';
31 import { BehaviorSubject, Observable, of } from 'rxjs'; 38 import { BehaviorSubject, Observable, of } from 'rxjs';
32 import { filter } from 'rxjs/operators'; 39 import { filter } from 'rxjs/operators';
33 import { Polyline } from './polyline'; 40 import { Polyline } from './polyline';
34 import { Polygon } from './polygon'; 41 import { Polygon } from './polygon';
35 -import { createTooltip, parseArray, parseData, safeExecute } from '@home/components/widget/lib/maps/maps-utils'; 42 +import { createTooltip, parseArray, safeExecute } from '@home/components/widget/lib/maps/maps-utils';
36 import { WidgetContext } from '@home/models/widget-component.models'; 43 import { WidgetContext } from '@home/models/widget-component.models';
37 import { DatasourceData } from '@shared/models/widget.models'; 44 import { DatasourceData } from '@shared/models/widget.models';
38 45
@@ -246,6 +253,12 @@ export default abstract class LeafletMap { @@ -246,6 +253,12 @@ export default abstract class LeafletMap {
246 return L.latLng(lat, lng) as L.LatLng; 253 return L.latLng(lat, lng) as L.LatLng;
247 } 254 }
248 255
  256 + convertPositionPolygon(expression: Array<[number, number]>): L.LatLngExpression[] {
  257 + return expression.map((el) => {
  258 + return el.length === 2 && !el.some(isNaN) ? el : null
  259 + }).filter(el => !!el)
  260 + }
  261 +
249 convertToCustomFormat(position: L.LatLng): object { 262 convertToCustomFormat(position: L.LatLng): object {
250 return { 263 return {
251 [this.options.latKeyName]: position.lat % 90, 264 [this.options.latKeyName]: position.lat % 90,
@@ -465,31 +478,33 @@ export default abstract class LeafletMap { @@ -465,31 +478,33 @@ export default abstract class LeafletMap {
465 478
466 // Polygon 479 // Polygon
467 480
468 - updatePolygons(polyData: FormattedData[], updateBounds = true) {  
469 - const keys: string[] = [];  
470 - polyData.forEach((data: FormattedData) => {  
471 - if (data && data.hasOwnProperty(this.options.polygonKeyName)) {  
472 - if (typeof (data[this.options.polygonKeyName]) === 'string') {  
473 - data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]) as LatLngTuple[];  
474 - }  
475 - if (this.polygons.get(data.entityName)) {  
476 - this.updatePolygon(data, polyData, this.options, updateBounds);  
477 - } else {  
478 - this.createPolygon(data, polyData, this.options, updateBounds);  
479 - }  
480 - keys.push(data.entityName);  
481 - }  
482 - });  
483 - const toDelete: string[] = [];  
484 - this.polygons.forEach((v, mKey) => {  
485 - if (!keys.includes(mKey)) {  
486 - toDelete.push(mKey);  
487 - }  
488 - });  
489 - toDelete.forEach((key) => {  
490 - this.removePolygon(key);  
491 - });  
492 - } 481 + updatePolygons(polyData: FormattedData[], updateBounds = true) {
  482 + const keys: string[] = [];
  483 + polyData.forEach((data: FormattedData) => {
  484 + if (data && data.hasOwnProperty(this.options.polygonKeyName) && data[this.options.polygonKeyName] !== null) {
  485 + if (typeof (data[this.options.polygonKeyName]) === 'string') {
  486 + data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]);
  487 + }
  488 + data[this.options.polygonKeyName] = this.convertPositionPolygon(data[this.options.polygonKeyName]);
  489 +
  490 + if (this.polygons.get(data.entityName)) {
  491 + this.updatePolygon(data, polyData, this.options, updateBounds);
  492 + } else {
  493 + this.createPolygon(data, polyData, this.options, updateBounds);
  494 + }
  495 + keys.push(data.entityName);
  496 + }
  497 + });
  498 + const toDelete: string[] = [];
  499 + this.polygons.forEach((v, mKey) => {
  500 + if (!keys.includes(mKey)) {
  501 + toDelete.push(mKey);
  502 + }
  503 + });
  504 + toDelete.forEach((key) => {
  505 + this.removePolygon(key);
  506 + });
  507 + }
493 508
494 createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) { 509 createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) {
495 this.ready$.subscribe(() => { 510 this.ready$.subscribe(() => {
@@ -16,7 +16,8 @@ @@ -16,7 +16,8 @@
16 16
17 import { 17 import {
18 DEFAULT_MAP_PAGE_SIZE, 18 DEFAULT_MAP_PAGE_SIZE,
19 - defaultSettings, FormattedData, 19 + defaultSettings,
  20 + FormattedData,
20 hereProviders, 21 hereProviders,
21 MapProviders, 22 MapProviders,
22 providerSets, 23 providerSets,
@@ -34,7 +35,7 @@ import { @@ -34,7 +35,7 @@ import {
34 import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; 35 import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface';
35 import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; 36 import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils';
36 import { WidgetContext } from '@app/modules/home/models/widget-component.models'; 37 import { WidgetContext } from '@app/modules/home/models/widget-component.models';
37 -import { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils'; 38 +import { getDefCenterPosition, parseData, parseFunction, parseWithTranslation } from './maps-utils';
38 import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models'; 39 import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models';
39 import { EntityId } from '@shared/models/id/entity-id'; 40 import { EntityId } from '@shared/models/id/entity-id';
40 import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; 41 import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models';
@@ -65,10 +66,7 @@ export class MapWidgetController implements MapWidgetInterface { @@ -65,10 +66,7 @@ export class MapWidgetController implements MapWidgetInterface {
65 if (!$element) { 66 if (!$element) {
66 $element = ctx.$container[0]; 67 $element = ctx.$container[0];
67 } 68 }
68 - this.settings = this.initSettings(ctx.settings);  
69 - if (isEdit) {  
70 - this.settings.draggableMarker = true;  
71 - } 69 + this.settings = this.initSettings(ctx.settings, isEdit);
72 this.settings.tooltipAction = this.getDescriptors('tooltipAction'); 70 this.settings.tooltipAction = this.getDescriptors('tooltipAction');
73 this.settings.markerClick = this.getDescriptors('markerClick'); 71 this.settings.markerClick = this.getDescriptors('markerClick');
74 this.settings.polygonClick = this.getDescriptors('polygonClick'); 72 this.settings.polygonClick = this.getDescriptors('polygonClick');
@@ -241,7 +239,7 @@ export class MapWidgetController implements MapWidgetInterface { @@ -241,7 +239,7 @@ export class MapWidgetController implements MapWidgetInterface {
241 } 239 }
242 } 240 }
243 241
244 - initSettings(settings: UnitedMapSettings): UnitedMapSettings { 242 + initSettings(settings: UnitedMapSettings, isEditMap?: boolean): UnitedMapSettings {
245 const functionParams = ['data', 'dsData', 'dsIndex']; 243 const functionParams = ['data', 'dsData', 'dsIndex'];
246 this.provider = settings.provider || this.mapProvider; 244 this.provider = settings.provider || this.mapProvider;
247 if (this.provider === MapProviders.here && !settings.mapProviderHere) { 245 if (this.provider === MapProviders.here && !settings.mapProviderHere) {
@@ -269,6 +267,9 @@ export class MapWidgetController implements MapWidgetInterface { @@ -269,6 +267,9 @@ export class MapWidgetController implements MapWidgetInterface {
269 size: settings.markerImageSize || 34 267 size: settings.markerImageSize || 34
270 } : null 268 } : null
271 } 269 }
  270 + if (isEditMap && !settings.hasOwnProperty('draggableMarker')) {
  271 + settings.draggableMarker = true;
  272 + }
272 return { ...defaultSettings, ...settings, ...customOptions, } 273 return { ...defaultSettings, ...settings, ...customOptions, }
273 } 274 }
274 275
@@ -249,8 +249,8 @@ export function parseData(input: DatasourceData[]): FormattedData[] { @@ -249,8 +249,8 @@ export function parseData(input: DatasourceData[]): FormattedData[] {
249 deviceType: null 249 deviceType: null
250 }; 250 };
251 entityArray.filter(el => el.data.length).forEach(el => { 251 entityArray.filter(el => el.data.length).forEach(el => {
252 - obj[el?.dataKey?.label] = el?.data[0][1];  
253 - obj[el?.dataKey?.label + '|ts'] = el?.data[0][0]; 252 + obj[el?.dataKey?.label] = el?.data[0][0] ? el?.data[0][1] : null;
  253 + obj[el?.dataKey?.label + '|ts'] = el?.data[0][0] || null;
254 if (el?.dataKey?.label === 'type') { 254 if (el?.dataKey?.label === 'type') {
255 obj.deviceType = el?.data[0][1]; 255 obj.deviceType = el?.data[0][1];
256 } 256 }
@@ -215,6 +215,17 @@ export class ImageMap extends LeafletMap { @@ -215,6 +215,17 @@ export class ImageMap extends LeafletMap {
215 expression.y * this.height); 215 expression.y * this.height);
216 } 216 }
217 217
  218 + convertPositionPolygon(expression: Array<[number, number]>): L.LatLngExpression[] {
  219 + return expression.map((el) => {
  220 + if (el.length === 2 && !el.some(isNaN)) {
  221 + return this.pointToLatLng(
  222 + el[0] * this.width,
  223 + el[1] * this.height)
  224 + }
  225 + return null;
  226 + }).filter(el => !!el)
  227 + }
  228 +
218 pointToLatLng(x, y): L.LatLng { 229 pointToLatLng(x, y): L.LatLng {
219 return L.CRS.Simple.pointToLatLng({ x, y } as L.PointExpression, maxZoom - 1); 230 return L.CRS.Simple.pointToLatLng({ x, y } as L.PointExpression, maxZoom - 1);
220 } 231 }