diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts index c67801d85b..c332ed5765 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts @@ -14,25 +14,32 @@ /// limitations under the License. /// -import L, { FeatureGroup, LatLngBounds, LatLngTuple, markerClusterGroup, MarkerClusterGroupOptions, MarkerClusterGroup } from 'leaflet'; +import L, { + FeatureGroup, + LatLngBounds, + LatLngTuple, + markerClusterGroup, + MarkerClusterGroup, + MarkerClusterGroupOptions +} from 'leaflet'; import 'leaflet-providers'; import 'leaflet.markercluster/dist/leaflet.markercluster'; import { - FormattedData, - MapSettings, - MarkerSettings, - PolygonSettings, - PolylineSettings, - UnitedMapSettings + FormattedData, + MapSettings, + MarkerSettings, + PolygonSettings, + PolylineSettings, + UnitedMapSettings } from './map-models'; import { Marker } from './markers'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { filter } from 'rxjs/operators'; import { Polyline } from './polyline'; import { Polygon } from './polygon'; -import { createTooltip, parseArray, parseData, safeExecute } from '@home/components/widget/lib/maps/maps-utils'; +import { createTooltip, parseArray, safeExecute } from '@home/components/widget/lib/maps/maps-utils'; import { WidgetContext } from '@home/models/widget-component.models'; import { DatasourceData } from '@shared/models/widget.models'; @@ -246,6 +253,12 @@ export default abstract class LeafletMap { return L.latLng(lat, lng) as L.LatLng; } + convertPositionPolygon(expression: Array<[number, number]>): L.LatLngExpression[] { + return expression.map((el) => { + return el.length === 2 && !el.some(isNaN) ? el : null + }).filter(el => !!el) + } + convertToCustomFormat(position: L.LatLng): object { return { [this.options.latKeyName]: position.lat % 90, @@ -465,31 +478,33 @@ export default abstract class LeafletMap { // Polygon - updatePolygons(polyData: FormattedData[], updateBounds = true) { - const keys: string[] = []; - polyData.forEach((data: FormattedData) => { - if (data && data.hasOwnProperty(this.options.polygonKeyName)) { - if (typeof (data[this.options.polygonKeyName]) === 'string') { - data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]) as LatLngTuple[]; - } - if (this.polygons.get(data.entityName)) { - this.updatePolygon(data, polyData, this.options, updateBounds); - } else { - this.createPolygon(data, polyData, this.options, updateBounds); - } - keys.push(data.entityName); - } - }); - const toDelete: string[] = []; - this.polygons.forEach((v, mKey) => { - if (!keys.includes(mKey)) { - toDelete.push(mKey); - } - }); - toDelete.forEach((key) => { - this.removePolygon(key); - }); - } + updatePolygons(polyData: FormattedData[], updateBounds = true) { + const keys: string[] = []; + polyData.forEach((data: FormattedData) => { + if (data && data.hasOwnProperty(this.options.polygonKeyName) && data[this.options.polygonKeyName] !== null) { + if (typeof (data[this.options.polygonKeyName]) === 'string') { + data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]); + } + data[this.options.polygonKeyName] = this.convertPositionPolygon(data[this.options.polygonKeyName]); + + if (this.polygons.get(data.entityName)) { + this.updatePolygon(data, polyData, this.options, updateBounds); + } else { + this.createPolygon(data, polyData, this.options, updateBounds); + } + keys.push(data.entityName); + } + }); + const toDelete: string[] = []; + this.polygons.forEach((v, mKey) => { + if (!keys.includes(mKey)) { + toDelete.push(mKey); + } + }); + toDelete.forEach((key) => { + this.removePolygon(key); + }); + } createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) { this.ready$.subscribe(() => { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts index 9d73be1c13..99c22eeb6e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts @@ -16,7 +16,8 @@ import { DEFAULT_MAP_PAGE_SIZE, - defaultSettings, FormattedData, + defaultSettings, + FormattedData, hereProviders, MapProviders, providerSets, @@ -34,7 +35,7 @@ import { import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; import { WidgetContext } from '@app/modules/home/models/widget-component.models'; -import { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils'; +import { getDefCenterPosition, parseData, parseFunction, parseWithTranslation } from './maps-utils'; import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models'; import { EntityId } from '@shared/models/id/entity-id'; import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; @@ -65,10 +66,7 @@ export class MapWidgetController implements MapWidgetInterface { if (!$element) { $element = ctx.$container[0]; } - this.settings = this.initSettings(ctx.settings); - if (isEdit) { - this.settings.draggableMarker = true; - } + this.settings = this.initSettings(ctx.settings, isEdit); this.settings.tooltipAction = this.getDescriptors('tooltipAction'); this.settings.markerClick = this.getDescriptors('markerClick'); this.settings.polygonClick = this.getDescriptors('polygonClick'); @@ -241,7 +239,7 @@ export class MapWidgetController implements MapWidgetInterface { } } - initSettings(settings: UnitedMapSettings): UnitedMapSettings { + initSettings(settings: UnitedMapSettings, isEditMap?: boolean): UnitedMapSettings { const functionParams = ['data', 'dsData', 'dsIndex']; this.provider = settings.provider || this.mapProvider; if (this.provider === MapProviders.here && !settings.mapProviderHere) { @@ -269,6 +267,9 @@ export class MapWidgetController implements MapWidgetInterface { size: settings.markerImageSize || 34 } : null } + if (isEditMap && !settings.hasOwnProperty('draggableMarker')) { + settings.draggableMarker = true; + } return { ...defaultSettings, ...settings, ...customOptions, } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts index 576e594df6..51fdef7075 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts @@ -249,8 +249,8 @@ export function parseData(input: DatasourceData[]): FormattedData[] { deviceType: null }; entityArray.filter(el => el.data.length).forEach(el => { - obj[el?.dataKey?.label] = el?.data[0][1]; - obj[el?.dataKey?.label + '|ts'] = el?.data[0][0]; + obj[el?.dataKey?.label] = el?.data[0][0] ? el?.data[0][1] : null; + obj[el?.dataKey?.label + '|ts'] = el?.data[0][0] || null; if (el?.dataKey?.label === 'type') { obj.deviceType = el?.data[0][1]; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts index 7d38477f14..9f97aed2ac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts @@ -215,6 +215,17 @@ export class ImageMap extends LeafletMap { expression.y * this.height); } + convertPositionPolygon(expression: Array<[number, number]>): L.LatLngExpression[] { + return expression.map((el) => { + if (el.length === 2 && !el.some(isNaN)) { + return this.pointToLatLng( + el[0] * this.width, + el[1] * this.height) + } + return null; + }).filter(el => !!el) + } + pointToLatLng(x, y): L.LatLng { return L.CRS.Simple.pointToLatLng({ x, y } as L.PointExpression, maxZoom - 1); }