Browse Source

Improve map widgets: ability to return marker and tooltip offset from marker image function

pull/5770/head
Igor Kulikov 5 years ago
parent
commit
0477e065d5
  1. 18
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  2. 21
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts
  3. 2
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts
  4. 46
      ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts

18
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts

@ -14,7 +14,7 @@
/// limitations under the License. /// 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 tinycolor from 'tinycolor2';
import 'leaflet-providers'; import 'leaflet-providers';
import { MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet.markercluster/dist/leaflet.markercluster'; import { MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet.markercluster/dist/leaflet.markercluster';
@ -24,7 +24,7 @@ import {
defaultSettings, defaultSettings,
FormattedData, FormattedData,
MapSettings, MapSettings,
MarkerSettings, MarkerSettings, MarkerIconInfo, MarkerImageInfo,
PolygonSettings, PolygonSettings,
PolylineSettings, PolylineSettings,
ReplaceInfo, ReplaceInfo,
@ -64,7 +64,7 @@ export default abstract class LeafletMap {
points: FeatureGroup; points: FeatureGroup;
markersData: FormattedData[] = []; markersData: FormattedData[] = [];
polygonsData: FormattedData[] = []; polygonsData: FormattedData[] = [];
defaultMarkerIconInfo: { size: number[], icon: Icon }; defaultMarkerIconInfo: MarkerIconInfo;
loadingDiv: JQuery<HTMLElement>; loadingDiv: JQuery<HTMLElement>;
loading = false; loading = false;
replaceInfoLabelMarker: Array<ReplaceInfo> = []; replaceInfoLabelMarker: Array<ReplaceInfo> = [];
@ -536,16 +536,16 @@ export default abstract class LeafletMap {
let m: Marker; let m: Marker;
rawMarkers.forEach(data => { rawMarkers.forEach(data => {
if (data.rotationAngle || data.rotationAngle === 0) { if (data.rotationAngle || data.rotationAngle === 0) {
const currentImage = this.options.useMarkerImageFunction ? const currentImage: MarkerImageInfo = this.options.useMarkerImageFunction ?
safeExecute(this.options.markerImageFunction, safeExecute(this.options.markerImageFunction,
[data, this.options.markerImages, markersData, data.dsIndex]) : this.options.currentImage; [data, this.options.markerImages, markersData, data.dsIndex]) : this.options.currentImage;
const style = currentImage ? 'background-image: url(' + currentImage.url + ');' : ''; const style = currentImage ? 'background-image: url(' + currentImage.url + ');' : '';
this.options.icon = L.divIcon({ this.options.icon = { icon: L.divIcon({
html: `<div class="arrow" html: `<div class="arrow"
style="transform: translate(-10px, -10px) style="transform: translate(-10px, -10px)
rotate(${data.rotationAngle}deg); rotate(${data.rotationAngle}deg);
${style}"><div>` ${style}"><div>`
}); }), size: [30, 30]};
} else { } else {
this.options.icon = null; this.options.icon = null;
} }

21
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 { Datasource } from '@app/shared/models/widget.models';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { BaseIconOptions, Icon } from 'leaflet';
export const DEFAULT_MAP_PAGE_SIZE = 16384; export const DEFAULT_MAP_PAGE_SIZE = 16384;
export const DEFAULT_ZOOM_LEVEL = 8; export const DEFAULT_ZOOM_LEVEL = 8;
export type GenericFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string; 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 PosFuncton = (origXPos, origYPos) => { x, y };
export type MarkerIconReadyFunction = (icon: MarkerIconInfo) => void;
export type MapSettings = { export type MapSettings = {
draggableMarker: boolean; draggableMarker: boolean;
@ -51,7 +53,6 @@ export type MapSettings = {
useDefaultCenterPosition?: boolean; useDefaultCenterPosition?: boolean;
gmDefaultMapType?: string; gmDefaultMapType?: string;
useLabelFunction: boolean; useLabelFunction: boolean;
icon?: any;
zoomOnClick: boolean, zoomOnClick: boolean,
maxZoom: number, maxZoom: number,
showCoverageOnHover: boolean, showCoverageOnHover: boolean,
@ -73,10 +74,22 @@ export enum MapProviders {
tencent = 'tencent-map' tencent = 'tencent-map'
} }
export type MarkerImageInfo = {
url: string;
size: number;
markerOffset?: [number, number];
tooltipOffset?: [number, number];
};
export type MarkerIconInfo = {
icon: Icon<BaseIconOptions>;
size: [number, number];
};
export type MarkerSettings = { export type MarkerSettings = {
tooltipPattern?: any; tooltipPattern?: any;
tooltipAction: { [name: string]: actionsHandler }; tooltipAction: { [name: string]: actionsHandler };
icon?: any; icon?: MarkerIconInfo;
showLabel?: boolean; showLabel?: boolean;
label: string; label: string;
labelColor: string; labelColor: string;
@ -91,7 +104,7 @@ export type MarkerSettings = {
autocloseTooltip: boolean; autocloseTooltip: boolean;
showTooltipAction: string; showTooltipAction: string;
useClusterMarkers: boolean; useClusterMarkers: boolean;
currentImage?: string; currentImage?: MarkerImageInfo;
useMarkerImageFunction?: boolean; useMarkerImageFunction?: boolean;
markerImages?: string[]; markerImages?: string[];
markerImageSize: number; markerImageSize: number;

2
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]; settings.mapProviderHere = hereProviders[0];
} }
} }
const customOptions = { const customOptions: Partial<UnitedMapSettings> = {
provider: this.provider, provider: this.provider,
mapUrl: settings?.mapImageUrl, mapUrl: settings?.mapImageUrl,
labelFunction: parseFunction(settings.labelFunction, functionParams), labelFunction: parseFunction(settings.labelFunction, functionParams),

46
ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts

@ -15,7 +15,7 @@
/// ///
import L, { Icon, LeafletMouseEvent } from 'leaflet'; import L, { Icon, LeafletMouseEvent } from 'leaflet';
import { FormattedData, MarkerSettings } from './map-models'; import { FormattedData, MarkerIconInfo, MarkerIconReadyFunction, MarkerImageInfo, MarkerSettings } from './map-models';
import { import {
bindPopupActions, bindPopupActions,
createTooltip, createTooltip,
@ -55,11 +55,7 @@ export class Marker {
isDefined(settings.tooltipOffsetY) ? settings.tooltipOffsetY : -1, isDefined(settings.tooltipOffsetY) ? settings.tooltipOffsetY : -1,
]; ];
this.createMarkerIcon((iconInfo) => { this.updateMarkerIcon(settings);
this.leafletMarker.setIcon(iconInfo.icon);
this.labelOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10];
this.updateMarkerLabel(settings);
});
if (settings.showTooltip) { if (settings.showTooltip) {
this.tooltip = createTooltip(this.leafletMarker, settings, data.$datasource); this.tooltip = createTooltip(this.leafletMarker, settings, data.$datasource);
@ -130,20 +126,22 @@ export class Marker {
updateMarkerIcon(settings: MarkerSettings) { updateMarkerIcon(settings: MarkerSettings) {
this.createMarkerIcon((iconInfo) => { this.createMarkerIcon((iconInfo) => {
this.leafletMarker.setIcon(iconInfo.icon); 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); this.updateMarkerLabel(settings);
}); });
} }
createMarkerIcon(onMarkerIconReady) { private createMarkerIcon(onMarkerIconReady: MarkerIconReadyFunction) {
if (this.settings.icon) { if (this.settings.icon) {
onMarkerIconReady({ onMarkerIconReady(this.settings.icon);
size: [30, 30], return;
icon: this.settings.icon,
});
return;
} }
const currentImage = this.settings.useMarkerImageFunction ? const currentImage: MarkerImageInfo = this.settings.useMarkerImageFunction ?
safeExecute(this.settings.markerImageFunction, safeExecute(this.settings.markerImageFunction,
[this.data, this.settings.markerImages, this.dataSources, this.data.dsIndex]) : this.settings.currentImage; [this.data, this.settings.markerImages, this.dataSources, this.data.dsIndex]) : this.settings.currentImage;
let currentColor = this.settings.tinyColor; let currentColor = this.settings.tinyColor;
@ -167,13 +165,21 @@ export class Marker {
width = currentImage.size * aspect; width = currentImage.size * aspect;
height = currentImage.size; 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({ const icon = L.icon({
iconUrl: currentImage.url, iconUrl: currentImage.url,
iconSize: [width, height], iconSize: [width, height],
iconAnchor: [width * this.markerOffset[0], height * this.markerOffset[1]], iconAnchor,
popupAnchor: [width * this.tooltipOffset[0], height * this.tooltipOffset[1]] popupAnchor
}); });
const iconInfo = { const iconInfo: MarkerIconInfo = {
size: [width, height], size: [width, height],
icon icon
}; };
@ -188,8 +194,8 @@ export class Marker {
} }
} }
createDefaultMarkerIcon(color: tinycolor.Instance, onMarkerIconReady) { createDefaultMarkerIcon(color: tinycolor.Instance, onMarkerIconReady: MarkerIconReadyFunction) {
let icon: { size: number[], icon: Icon }; let icon: MarkerIconInfo;
if (!tinycolor.equals(color, this.settings.tinyColor)) { if (!tinycolor.equals(color, this.settings.tinyColor)) {
icon = this.createColoredMarkerIcon(color); icon = this.createColoredMarkerIcon(color);
} else { } else {
@ -201,7 +207,7 @@ export class Marker {
onMarkerIconReady(icon); onMarkerIconReady(icon);
} }
createColoredMarkerIcon(color: tinycolor.Instance): { size: number[], icon: Icon } { createColoredMarkerIcon(color: tinycolor.Instance): MarkerIconInfo {
return { return {
size: [21, 34], size: [21, 34],
icon: L.icon({ icon: L.icon({

Loading…
Cancel
Save