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 1abd64093d..78f459990e 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,7 +14,7 @@ /// limitations under the License. /// -import L, { FeatureGroup, Icon, LatLngBounds, LatLngTuple, Projection } from 'leaflet'; +import L, { FeatureGroup, LatLngBounds, LatLngTuple, Projection } from 'leaflet'; import tinycolor from 'tinycolor2'; import 'leaflet-providers'; import { MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet.markercluster/dist/leaflet.markercluster'; @@ -24,7 +24,7 @@ import { defaultSettings, FormattedData, MapSettings, - MarkerSettings, + MarkerSettings, MarkerIconInfo, MarkerImageInfo, PolygonSettings, PolylineSettings, ReplaceInfo, @@ -64,7 +64,7 @@ export default abstract class LeafletMap { points: FeatureGroup; markersData: FormattedData[] = []; polygonsData: FormattedData[] = []; - defaultMarkerIconInfo: { size: number[], icon: Icon }; + defaultMarkerIconInfo: MarkerIconInfo; loadingDiv: JQuery; loading = false; replaceInfoLabelMarker: Array = []; @@ -536,16 +536,16 @@ export default abstract class LeafletMap { let m: Marker; rawMarkers.forEach(data => { if (data.rotationAngle || data.rotationAngle === 0) { - const currentImage = this.options.useMarkerImageFunction ? + const currentImage: MarkerImageInfo = this.options.useMarkerImageFunction ? safeExecute(this.options.markerImageFunction, [data, this.options.markerImages, markersData, data.dsIndex]) : this.options.currentImage; const style = currentImage ? 'background-image: url(' + currentImage.url + ');' : ''; - this.options.icon = L.divIcon({ + this.options.icon = { icon: L.divIcon({ html: `
` - }); + style="transform: translate(-10px, -10px) + rotate(${data.rotationAngle}deg); + ${style}">
` + }), size: [30, 30]}; } else { this.options.icon = null; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts index 981e71d787..e65479f588 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts @@ -17,13 +17,15 @@ import { Datasource } from '@app/shared/models/widget.models'; import { EntityType } from '@shared/models/entity-type.models'; import tinycolor from 'tinycolor2'; +import { BaseIconOptions, Icon } from 'leaflet'; export const DEFAULT_MAP_PAGE_SIZE = 16384; export const DEFAULT_ZOOM_LEVEL = 8; export type GenericFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string; -export type MarkerImageFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string; +export type MarkerImageFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => MarkerImageInfo; export type PosFuncton = (origXPos, origYPos) => { x, y }; +export type MarkerIconReadyFunction = (icon: MarkerIconInfo) => void; export type MapSettings = { draggableMarker: boolean; @@ -51,7 +53,6 @@ export type MapSettings = { useDefaultCenterPosition?: boolean; gmDefaultMapType?: string; useLabelFunction: boolean; - icon?: any; zoomOnClick: boolean, maxZoom: number, showCoverageOnHover: boolean, @@ -73,10 +74,22 @@ export enum MapProviders { tencent = 'tencent-map' } +export type MarkerImageInfo = { + url: string; + size: number; + markerOffset?: [number, number]; + tooltipOffset?: [number, number]; +}; + +export type MarkerIconInfo = { + icon: Icon; + size: [number, number]; +}; + export type MarkerSettings = { tooltipPattern?: any; tooltipAction: { [name: string]: actionsHandler }; - icon?: any; + icon?: MarkerIconInfo; showLabel?: boolean; label: string; labelColor: string; @@ -91,7 +104,7 @@ export type MarkerSettings = { autocloseTooltip: boolean; showTooltipAction: string; useClusterMarkers: boolean; - currentImage?: string; + currentImage?: MarkerImageInfo; useMarkerImageFunction?: boolean; markerImages?: string[]; markerImageSize: number; 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 f755754eca..565887b160 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 @@ -258,7 +258,7 @@ export class MapWidgetController implements MapWidgetInterface { settings.mapProviderHere = hereProviders[0]; } } - const customOptions = { + const customOptions: Partial = { provider: this.provider, mapUrl: settings?.mapImageUrl, labelFunction: parseFunction(settings.labelFunction, functionParams), diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts index f2fae19ab0..85020b7f33 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts @@ -15,7 +15,7 @@ /// import L, { Icon, LeafletMouseEvent } from 'leaflet'; -import { FormattedData, MarkerSettings } from './map-models'; +import { FormattedData, MarkerIconInfo, MarkerIconReadyFunction, MarkerImageInfo, MarkerSettings } from './map-models'; import { bindPopupActions, createTooltip, @@ -55,11 +55,7 @@ export class Marker { isDefined(settings.tooltipOffsetY) ? settings.tooltipOffsetY : -1, ]; - this.createMarkerIcon((iconInfo) => { - this.leafletMarker.setIcon(iconInfo.icon); - this.labelOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10]; - this.updateMarkerLabel(settings); - }); + this.updateMarkerIcon(settings); if (settings.showTooltip) { this.tooltip = createTooltip(this.leafletMarker, settings, data.$datasource); @@ -130,20 +126,22 @@ export class Marker { updateMarkerIcon(settings: MarkerSettings) { this.createMarkerIcon((iconInfo) => { this.leafletMarker.setIcon(iconInfo.icon); - this.labelOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10]; + const anchor = iconInfo.icon.options.iconAnchor; + if (anchor && Array.isArray(anchor)) { + this.labelOffset = [iconInfo.size[0] / 2 - anchor[0], 10 - anchor[1]]; + } else { + this.labelOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10]; + } this.updateMarkerLabel(settings); }); } - createMarkerIcon(onMarkerIconReady) { + private createMarkerIcon(onMarkerIconReady: MarkerIconReadyFunction) { if (this.settings.icon) { - onMarkerIconReady({ - size: [30, 30], - icon: this.settings.icon, - }); - return; + onMarkerIconReady(this.settings.icon); + return; } - const currentImage = this.settings.useMarkerImageFunction ? + const currentImage: MarkerImageInfo = this.settings.useMarkerImageFunction ? safeExecute(this.settings.markerImageFunction, [this.data, this.settings.markerImages, this.dataSources, this.data.dsIndex]) : this.settings.currentImage; let currentColor = this.settings.tinyColor; @@ -167,13 +165,21 @@ export class Marker { width = currentImage.size * aspect; height = currentImage.size; } + let iconAnchor = currentImage.markerOffset; + let popupAnchor = currentImage.tooltipOffset; + if (!iconAnchor) { + iconAnchor = [width * this.markerOffset[0], height * this.markerOffset[1]]; + } + if (!popupAnchor) { + popupAnchor = [width * this.tooltipOffset[0], height * this.tooltipOffset[1]]; + } const icon = L.icon({ iconUrl: currentImage.url, iconSize: [width, height], - iconAnchor: [width * this.markerOffset[0], height * this.markerOffset[1]], - popupAnchor: [width * this.tooltipOffset[0], height * this.tooltipOffset[1]] + iconAnchor, + popupAnchor }); - const iconInfo = { + const iconInfo: MarkerIconInfo = { size: [width, height], icon }; @@ -188,8 +194,8 @@ export class Marker { } } - createDefaultMarkerIcon(color: tinycolor.Instance, onMarkerIconReady) { - let icon: { size: number[], icon: Icon }; + createDefaultMarkerIcon(color: tinycolor.Instance, onMarkerIconReady: MarkerIconReadyFunction) { + let icon: MarkerIconInfo; if (!tinycolor.equals(color, this.settings.tinyColor)) { icon = this.createColoredMarkerIcon(color); } else { @@ -201,7 +207,7 @@ export class Marker { onMarkerIconReady(icon); } - createColoredMarkerIcon(color: tinycolor.Instance): { size: number[], icon: Icon } { + createColoredMarkerIcon(color: tinycolor.Instance): MarkerIconInfo { return { size: [21, 34], icon: L.icon({