Map rectangles support

This commit is contained in:
Igor Kulikov 2021-12-20 17:52:19 +02:00
parent 7072713f12
commit 66d6b8d687
6 changed files with 179 additions and 26 deletions

View File

@ -69,6 +69,8 @@ export default abstract class LeafletMap {
loading = false;
replaceInfoLabelMarker: Array<ReplaceInfo> = [];
markerLabelText: string;
polygonLabelText: string;
replaceInfoLabelPolygon: Array<ReplaceInfo> = [];
replaceInfoTooltipMarker: Array<ReplaceInfo> = [];
markerTooltipText: string;
drawRoutes: boolean;
@ -248,8 +250,16 @@ export default abstract class LeafletMap {
this.saveLocation(this.selectedEntity, this.convertToCustomFormat(e.layer.getLatLng())).subscribe(() => {
});
} else if (e.shape === 'tbRectangle' || e.shape === 'tbPolygon') {
// @ts-ignore
this.saveLocation(this.selectedEntity, this.convertPolygonToCustomFormat(e.layer.getLatLngs()[0])).subscribe(() => {
let coordinates;
if (e.shape === 'tbRectangle') {
// @ts-ignore
const bounds: L.LatLngBounds = e.layer.getBounds();
coordinates = [bounds.getNorthWest(), bounds.getSouthEast()];
} else {
// @ts-ignore
coordinates = e.layer.getLatLngs()[0];
}
this.saveLocation(this.selectedEntity, this.convertPolygonToCustomFormat(coordinates)).subscribe(() => {
});
}
// @ts-ignore
@ -281,7 +291,7 @@ export default abstract class LeafletMap {
result = iterator.next();
}
this.saveLocation(result.value.data, this.convertToCustomFormat(null)).subscribe(() => {});
} else if (e.shape === 'Polygon') {
} else if (e.shape === 'Polygon' || e.shape === 'Rectangle') {
const iterator = this.polygons.values();
let result = iterator.next();
while (!result.done && e.layer !== result.value.leafletPoly) {
@ -333,6 +343,7 @@ export default abstract class LeafletMap {
this.map.scrollWheelZoom.disable();
}
if (this.options.draggableMarker || this.editPolygons) {
map.pm.setGlobalOptions({ snappable: false } as L.PM.GlobalOptions);
this.addEditControl();
} else {
this.map.pm.disableDraw();
@ -764,6 +775,14 @@ export default abstract class LeafletMap {
if (coordinates.length === 1) {
coordinates = coordinates[0];
}
if (e.shape === 'Rectangle') {
// @ts-ignore
const bounds: L.LatLngBounds = e.layer.getBounds();
const boundsArray = [bounds.getNorthWest(), bounds.getNorthEast(), bounds.getSouthWest(), bounds.getSouthEast()];
if (coordinates.every(point => boundsArray.find(boundPoint => boundPoint.equals(point)) !== undefined)) {
coordinates = [bounds.getNorthWest(), bounds.getSouthEast()];
}
}
this.saveLocation(data, this.convertPolygonToCustomFormat(coordinates)).subscribe(() => {});
}

View File

@ -131,6 +131,11 @@ export type PolygonSettings = {
polygonStrokeWeight: number;
polygonStrokeColor: string;
polygonColor: string;
showPolygonLabel?: boolean;
polygonLabel: string;
polygonLabelColor: string;
polygonLabelText: string;
usePolygonLabelFunction: boolean;
showPolygonTooltip: boolean;
autocloseTooltip: boolean;
showTooltipAction: string;
@ -139,8 +144,11 @@ export type PolygonSettings = {
usePolygonTooltipFunction: boolean;
polygonClick: { [name: string]: actionsHandler };
usePolygonColorFunction: boolean;
usePolygonStrokeColorFunction: boolean;
polygonTooltipFunction: GenericFunction;
polygonColorFunction?: GenericFunction;
polygonStrokeColorFunction?: GenericFunction;
polygonLabelFunction?: GenericFunction;
editablePolygon: boolean;
};
@ -227,8 +235,10 @@ export const defaultSettings: any = {
showPolygon: false,
labelColor: '#000000',
color: '#FE7569',
showPolygonLabel: false,
polygonColor: '#0000ff',
polygonStrokeColor: '#fe0001',
polygonLabelColor: '#000000',
polygonOpacity: 0.5,
polygonStrokeOpacity: 1,
polygonStrokeWeight: 1,

View File

@ -265,10 +265,13 @@ export class MapWidgetController implements MapWidgetInterface {
tooltipFunction: parseFunction(settings.tooltipFunction, functionParams),
colorFunction: parseFunction(settings.colorFunction, functionParams),
colorPointFunction: parseFunction(settings.colorPointFunction, functionParams),
polygonLabelFunction: parseFunction(settings.polygonLabelFunction, functionParams),
polygonColorFunction: parseFunction(settings.polygonColorFunction, functionParams),
polygonStrokeColorFunction: parseFunction(settings.polygonStrokeColorFunction, functionParams),
polygonTooltipFunction: parseFunction(settings.polygonTooltipFunction, functionParams),
markerImageFunction: parseFunction(settings.markerImageFunction, ['data', 'images', 'dsData', 'dsIndex']),
labelColor: this.ctx.widgetConfig.color,
polygonLabelColor: this.ctx.widgetConfig.color,
polygonKeyName: settings.polKeyName ? settings.polKeyName : settings.polygonKeyName,
tooltipPattern: settings.tooltipPattern ||
'<b>${entityName}</b><br/><br/><b>Latitude:</b> ${' +

View File

@ -29,6 +29,15 @@
box-shadow: none;
}
.tb-polygon-label {
border: none;
background: none;
box-shadow: none;
&:before {
content: none;
}
}
.leaflet-container {
background-color: white;
}

View File

@ -16,8 +16,14 @@
import L, { LatLngExpression, LeafletMouseEvent } from 'leaflet';
import { createTooltip } from './maps-utils';
import { functionValueCalculator, parseWithTranslation, safeExecute } from './common-maps-utils';
import { FormattedData, PolygonSettings } from './map-models';
import {
fillPattern,
functionValueCalculator,
parseWithTranslation,
processPattern,
safeExecute
} from './common-maps-utils';
import { FormattedData, MarkerSettings, PolygonSettings } from './map-models';
export class Polygon {
@ -26,38 +32,47 @@ export class Polygon {
data: FormattedData;
dataSources: FormattedData[];
constructor(public map, polyData: FormattedData, dataSources: FormattedData[], private settings: PolygonSettings, onDragendListener?) {
constructor(public map, data: FormattedData, dataSources: FormattedData[], private settings: PolygonSettings,
private onDragendListener?) {
this.dataSources = dataSources;
this.data = polyData;
this.data = data;
const polygonColor = this.getPolygonColor(settings);
this.leafletPoly = L.polygon(polyData[this.settings.polygonKeyName], {
const polygonStrokeColor = this.getPolygonStrokeColor(settings);
const polyData = data[this.settings.polygonKeyName];
const polyConstructor = polyData.length > 2 ? L.polygon : L.rectangle;
this.leafletPoly = polyConstructor(polyData, {
fill: true,
fillColor: polygonColor,
color: settings.polygonStrokeColor,
color: polygonStrokeColor,
weight: settings.polygonStrokeWeight,
fillOpacity: settings.polygonOpacity,
opacity: settings.polygonStrokeOpacity,
pmIgnore: !settings.editablePolygon
}).addTo(this.map);
if (settings.editablePolygon && onDragendListener) {
this.leafletPoly.on('pm:edit', (e) => onDragendListener(e, this.data));
}
this.updateLabel(settings);
if (settings.showPolygonTooltip) {
this.tooltip = createTooltip(this.leafletPoly, settings, polyData.$datasource);
this.updateTooltip(polyData);
}
if (settings.polygonClick) {
this.leafletPoly.on('click', (event: LeafletMouseEvent) => {
for (const action in this.settings.polygonClick) {
if (typeof (this.settings.polygonClick[action]) === 'function') {
this.settings.polygonClick[action](event.originalEvent, polyData.$datasource);
}
}
});
this.tooltip = createTooltip(this.leafletPoly, settings, data.$datasource);
this.updateTooltip(data);
}
this.createEventListeners();
}
private createEventListeners() {
if (this.settings.editablePolygon && this.onDragendListener) {
this.leafletPoly.on('pm:edit', (e) => this.onDragendListener(e, this.data));
}
if (this.settings.polygonClick) {
this.leafletPoly.on('click', (event: LeafletMouseEvent) => {
for (const action in this.settings.polygonClick) {
if (typeof (this.settings.polygonClick[action]) === 'function') {
this.settings.polygonClick[action](event.originalEvent, this.data.$datasource);
}
}
});
}
}
updateTooltip(data: FormattedData) {
@ -67,13 +82,54 @@ export class Polygon {
this.tooltip.setContent(parseWithTranslation.parseTemplate(pattern, data, true));
}
updateLabel(settings: PolygonSettings) {
this.leafletPoly.unbindTooltip();
if (settings.showPolygonLabel) {
if (!this.map.polygonLabelText || settings.usePolygonLabelFunction) {
const pattern = settings.usePolygonLabelFunction ?
safeExecute(settings.polygonLabelFunction, [this.data, this.dataSources, this.data.dsIndex]) : settings.polygonLabel;
this.map.polygonLabelText = parseWithTranslation.prepareProcessPattern(pattern, true);
this.map.replaceInfoLabelPolygon = processPattern(this.map.polygonLabelText, this.data);
}
settings.polygonLabelText = fillPattern(this.map.polygonLabelText, this.map.replaceInfoLabelPolygon, this.data);
this.leafletPoly.bindTooltip(`<div style="color: ${settings.polygonLabelColor};"><b>${settings.polygonLabelText}</b></div>`,
{ className: 'tb-polygon-label', permanent: true, sticky: true, direction: 'center' })
.openTooltip(this.leafletPoly.getBounds().getCenter());
}
}
updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) {
this.data = data;
this.dataSources = dataSources;
this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]);
const polyData = data[this.settings.polygonKeyName];
if (polyData.length > 2) {
if (this.leafletPoly instanceof L.Rectangle) {
this.map.removeLayer(this.leafletPoly);
const polygonColor = this.getPolygonColor(settings);
const polygonStrokeColor = this.getPolygonStrokeColor(settings);
this.leafletPoly = L.polygon(polyData, {
fill: true,
fillColor: polygonColor,
color: polygonStrokeColor,
weight: settings.polygonStrokeWeight,
fillOpacity: settings.polygonOpacity,
opacity: settings.polygonStrokeOpacity,
pmIgnore: !settings.editablePolygon
}).addTo(this.map);
} else {
this.leafletPoly.setLatLngs(polyData);
}
} else if (polyData.length === 2) {
const bounds = new L.LatLngBounds(polyData);
// @ts-ignore
this.leafletPoly.setBounds(bounds);
}
if (settings.showPolygonTooltip) {
this.updateTooltip(this.data);
}
if (settings.showPolygonLabel) {
this.updateLabel(settings);
}
this.updatePolygonColor(settings);
}
@ -83,10 +139,11 @@ export class Polygon {
updatePolygonColor(settings: PolygonSettings) {
const polygonColor = this.getPolygonColor(settings);
const polygonStrokeColor = this.getPolygonStrokeColor(settings);
const style: L.PathOptions = {
fill: true,
fillColor: polygonColor,
color: settings.polygonStrokeColor,
color: polygonStrokeColor,
weight: settings.polygonStrokeWeight,
fillOpacity: settings.polygonOpacity,
opacity: settings.polygonStrokeOpacity
@ -107,4 +164,9 @@ export class Polygon {
return functionValueCalculator(settings.usePolygonColorFunction, settings.polygonColorFunction,
[this.data, this.dataSources, this.data.dsIndex], settings.polygonColor);
}
private getPolygonStrokeColor(settings: PolygonSettings): string | null {
return functionValueCalculator(settings.usePolygonStrokeColorFunction, settings.polygonStrokeColorFunction,
[this.data, this.dataSources, this.data.dsIndex], settings.polygonStrokeColor);
}
}

View File

@ -556,6 +556,25 @@ export const mapPolygonSchema =
type: 'boolean',
default: false
},
showPolygonLabel: {
title: 'Show polygon label',
type: 'boolean',
default: false
},
polygonLabel: {
title: 'Polygon label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )',
type: 'string',
default: '${entityName}'
},
usePolygonLabelFunction: {
title: 'Use polygon label function',
type: 'boolean',
default: false
},
polygonLabelFunction: {
title: 'Polygon label function: f(data, dsData, dsIndex)',
type: 'string'
},
polygonColor: {
title: 'Polygon color',
type: 'string'
@ -607,6 +626,15 @@ export const mapPolygonSchema =
title: 'Polygon Color function: f(data, dsData, dsIndex)',
type: 'string'
},
usePolygonStrokeColorFunction: {
title: 'Use polygon stroke color function',
type: 'boolean',
default: false
},
polygonStrokeColorFunction: {
title: 'Polygon Stroke Color function: f(data, dsData, dsIndex)',
type: 'string'
}
},
required: []
},
@ -614,6 +642,21 @@ export const mapPolygonSchema =
'showPolygon',
'polygonKeyName',
'editablePolygon',
'showPolygonLabel',
{
key: 'usePolygonLabelFunction',
condition: 'model.showPolygonLabel === true'
},
{
key: 'polygonLabel',
condition: 'model.showPolygonLabel === true && model.usePolygonLabelFunction !== true'
},
{
key: 'polygonLabelFunction',
type: 'javascript',
helpId: 'widget/lib/map/label_fn',
condition: 'model.showPolygonLabel === true && model.usePolygonLabelFunction === true'
},
{
key: 'polygonColor',
type: 'color'
@ -630,6 +673,13 @@ export const mapPolygonSchema =
key: 'polygonStrokeColor',
type: 'color'
},
'usePolygonStrokeColorFunction',
{
key: 'polygonStrokeColorFunction',
helpId: 'widget/lib/map/polygon_color_fn',
type: 'javascript',
condition: 'model.usePolygonStrokeColorFunction === true'
},
'polygonStrokeOpacity',
'polygonStrokeWeight',
'showPolygonTooltip',