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.
///
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<HTMLElement>;
loading = false;
replaceInfoLabelMarker: Array<ReplaceInfo> = [];
@ -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: `<div class="arrow"
style="transform: translate(-10px, -10px)
rotate(${data.rotationAngle}deg);
${style}"><div>`
});
style="transform: translate(-10px, -10px)
rotate(${data.rotationAngle}deg);
${style}"><div>`
}), size: [30, 30]};
} else {
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 { 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<BaseIconOptions>;
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;

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];
}
}
const customOptions = {
const customOptions: Partial<UnitedMapSettings> = {
provider: this.provider,
mapUrl: settings?.mapImageUrl,
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 { 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({

Loading…
Cancel
Save