Browse Source

Merge pull request #3331 from vvlladd28/bugs/map/polygon

Fixed map-widget
pull/3353/head
Igor Kulikov 6 years ago
committed by GitHub
parent
commit
d8f6d91fa4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 118
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  2. 17
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts
  3. 8
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts
  4. 40
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts
  5. 36
      ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts
  6. 4
      ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts
  7. 21
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts
  8. 7
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts
  9. 2
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts
  10. 121
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts
  11. 8
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts
  12. 9
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts
  13. 56
      ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts

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

@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster';
import {
defaultSettings,
FormattedData,
MapProviders,
MapSettings,
MarkerSettings,
PolygonSettings,
@ -74,6 +75,8 @@ export default abstract class LeafletMap {
drawRoutes: boolean;
showPolygon: boolean;
updatePending = false;
addMarkers: L.Marker[] = [];
addPolygons: L.Polygon[] = [];
protected constructor(public ctx: WidgetContext,
public $container: HTMLElement,
@ -133,6 +136,7 @@ export default abstract class LeafletMap {
shadowSize: [41, 41]
});
const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
this.addMarkers.push(newMarker);
const datasourcesList = document.createElement('div');
const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
const header = document.createElement('p');
@ -147,10 +151,14 @@ export default abstract class LeafletMap {
const updatedEnttity = { ...ds, ...customLatLng };
this.saveMarkerLocation(updatedEnttity).subscribe(() => {
this.map.removeLayer(newMarker);
const markerIndex = this.addMarkers.indexOf(newMarker);
if (markerIndex > -1) {
this.addMarkers.splice(markerIndex, 1);
}
this.deleteMarker(ds.entityName);
this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
});
}
};
datasourcesList.append(dsItem);
});
datasourcesList.append(document.createElement('br'));
@ -158,14 +166,18 @@ export default abstract class LeafletMap {
deleteBtn.appendChild(document.createTextNode('Discard changes'));
deleteBtn.onclick = () => {
this.map.removeLayer(newMarker);
}
const markerIndex = this.addMarkers.indexOf(newMarker);
if (markerIndex > -1) {
this.addMarkers.splice(markerIndex, 1);
}
};
datasourcesList.append(deleteBtn);
const popup = L.popup();
popup.setContent(datasourcesList);
newMarker.bindPopup(popup).openPopup();
}
addMarker.setPosition('topright')
}
addMarker.setPosition('topright');
};
L.Control.AddMarker = L.Control.extend({
onAdd() {
const img = L.DomUtil.create('img') as any;
@ -177,7 +189,7 @@ export default abstract class LeafletMap {
img.draggable = true;
const draggableImg = new L.Draggable(img);
draggableImg.enable();
draggableImg.on('dragend', dragListener)
draggableImg.on('dragend', dragListener);
return img;
},
onRemove() {
@ -186,7 +198,7 @@ export default abstract class LeafletMap {
} as any);
L.control.addMarker = (opts) => {
return new L.Control.AddMarker(opts);
}
};
addMarker = L.control.addMarker({ position: 'topright' }).addTo(this.map);
}
}
@ -196,14 +208,16 @@ export default abstract class LeafletMap {
let mousePositionOnMap: L.LatLng[];
let addPolygon: L.Control;
this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
const latlng1 = e.latlng;
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10);
const latlng3 = L.latLng(e.latlng.lat-10, e.latlng.lng);
mousePositionOnMap = [latlng1,latlng2, latlng3 ];
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
mousePositionOnMap = [latlng1, latlng2, latlng3];
});
const dragListener = (e: L.DragEndEvent) => {
if (e.type === 'dragend' && mousePositionOnMap) {
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
this.addPolygons.push(newPolygon);
const datasourcesList = document.createElement('div');
const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
const header = document.createElement('p');
@ -218,9 +232,13 @@ export default abstract class LeafletMap {
const updatedEnttity = { ...ds, ...customLatLng };
this.savePolygonLocation(updatedEnttity).subscribe(() => {
this.map.removeLayer(newPolygon);
const polygonIndex = this.addPolygons.indexOf(newPolygon);
if (polygonIndex > -1) {
this.addPolygons.splice(polygonIndex, 1);
}
this.deletePolygon(ds.entityName);
});
}
};
datasourcesList.append(dsItem);
});
datasourcesList.append(document.createElement('br'));
@ -228,14 +246,18 @@ export default abstract class LeafletMap {
deleteBtn.appendChild(document.createTextNode('Discard changes'));
deleteBtn.onclick = () => {
this.map.removeLayer(newPolygon);
}
const polygonIndex = this.addPolygons.indexOf(newPolygon);
if (polygonIndex > -1) {
this.addPolygons.splice(polygonIndex, 1);
}
};
datasourcesList.append(deleteBtn);
const popup = L.popup();
popup.setContent(datasourcesList);
newPolygon.bindPopup(popup).openPopup();
}
addPolygon.setPosition('topright')
}
addPolygon.setPosition('topright');
};
L.Control.AddPolygon = L.Control.extend({
onAdd() {
const img = L.DomUtil.create('img') as any;
@ -247,7 +269,7 @@ export default abstract class LeafletMap {
img.draggable = true;
const draggableImg = new L.Draggable(img);
draggableImg.enable();
draggableImg.on('dragend', dragListener)
draggableImg.on('dragend', dragListener);
return img;
},
onRemove() {
@ -256,7 +278,7 @@ export default abstract class LeafletMap {
} as any);
L.control.addPolygon = (opts) => {
return new L.Control.AddPolygon(opts);
}
};
addPolygon = L.control.addPolygon({ position: 'topright' }).addTo(this.map);
}
}
@ -280,10 +302,11 @@ export default abstract class LeafletMap {
public setMap(map: L.Map) {
this.map = map;
if (this.options.useDefaultCenterPosition) {
this.map.panTo(this.options.defaultCenterPosition);
this.bounds = map.getBounds();
this.map.panTo(this.options.defaultCenterPosition);
this.bounds = map.getBounds();
} else {
this.bounds = new L.LatLngBounds(null, null);
}
else this.bounds = new L.LatLngBounds(null, null);
if (this.options.draggableMarker) {
this.addMarkerControl();
}
@ -299,11 +322,11 @@ export default abstract class LeafletMap {
}
}
public saveMarkerLocation(_e: FormattedData, lat?: number, lng?: number): Observable<any> {
public saveMarkerLocation(datasource: FormattedData, lat?: number, lng?: number): Observable<any> {
return of(null);
}
public savePolygonLocation(_e: FormattedData, coordinates?: Array<[number, number]>): Observable<any> {
public savePolygonLocation(datasource: FormattedData, coordinates?: Array<[number, number]>): Observable<any> {
return of(null);
}
@ -364,7 +387,9 @@ export default abstract class LeafletMap {
}
convertPosition(expression: object): L.LatLng {
if (!expression) return null;
if (!expression) {
return null;
}
const lat = expression[this.options.latKeyName];
const lng = expression[this.options.lngKeyName];
if (!isDefinedAndNotNull(lat) || isString(lat) || isNaN(lat) || !isDefinedAndNotNull(lng) || isString(lng) || isNaN(lng)) {
@ -382,35 +407,35 @@ export default abstract class LeafletMap {
} else {
return null;
}
}).filter(el => !!el)
}).filter(el => !!el);
}
convertToCustomFormat(position: L.LatLng): object {
return {
[this.options.latKeyName]: position.lat % 90,
[this.options.lngKeyName]: position.lng % 180
}
};
}
convertToPolygonFormat(points: Array<any>): Array<any> {
if (points.length) {
return points.map(point=> {
if (point.length) {
return this.convertToPolygonFormat(point);
} else {
return [point.lat, point.lng];
}
})
} else {
return []
convertToPolygonFormat(points: Array<any>): Array<any> {
if (points.length) {
return points.map(point => {
if (point.length) {
return this.convertToPolygonFormat(point);
} else {
return [point.lat, point.lng];
}
});
} else {
return [];
}
}
}
convertPolygonToCustomFormat(expression: any[][]): object {
return {
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
convertPolygonToCustomFormat(expression: any[][]): object {
return {
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
};
}
}
updateData(drawRoutes: boolean, showPolygon: boolean) {
this.drawRoutes = drawRoutes;
@ -509,7 +534,7 @@ export default abstract class LeafletMap {
this.markersCluster.addLayers(createdMarkers.map(marker => marker.leafletMarker));
}
if (updatedMarkers.length) {
this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker))
this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker));
}
if (deletedMarkers.length) {
this.markersCluster.removeLayers(deletedMarkers.map(marker => marker.leafletMarker));
@ -518,7 +543,9 @@ export default abstract class LeafletMap {
}
dragMarker = (e, data = {} as FormattedData) => {
if (e.type !== 'dragend') return;
if (e.type !== 'dragend') {
return;
}
this.saveMarkerLocation({ ...data, ...this.convertToCustomFormat(e.target._latlng) }).subscribe();
}
@ -527,7 +554,7 @@ export default abstract class LeafletMap {
const newMarker = new Marker(this, this.convertPosition(data), settings, data, dataSources, this.dragMarker);
if (callback) {
newMarker.leafletMarker.on('click', () => {
callback(data, true)
callback(data, true);
});
}
if (this.bounds && updateBounds && !(this.options as MarkerSettings).useClusterMarkers) {
@ -565,11 +592,10 @@ export default abstract class LeafletMap {
}
deletePolygon(key: string) {
let polygon = this.polygons.get(key)?.leafletPoly;
const polygon = this.polygons.get(key)?.leafletPoly;
if (polygon) {
this.map.removeLayer(polygon);
this.polygons.delete(key);
polygon = null;
}
return polygon;
}
@ -684,7 +710,9 @@ export default abstract class LeafletMap {
}
dragPolygonVertex = (e?, data = {} as FormattedData) => {
if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) return;
if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) {
return;
}
this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe();
}

17
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts

@ -62,7 +62,7 @@ export type MapSettings = {
useCustomProvider: boolean,
customProviderTileUrl: string;
mapPageSize: number;
}
};
export enum MapProviders {
google = 'google-map',
@ -103,7 +103,7 @@ export type MarkerSettings = {
markerImageFunction?: MarkerImageFunction;
markerOffsetX: number;
markerOffsetY: number;
}
};
export interface FormattedData {
$datasource: Datasource;
@ -112,19 +112,19 @@ export interface FormattedData {
entityType: EntityType;
dsIndex: number;
deviceType: string;
[key: string]: any
[key: string]: any;
}
export interface ReplaceInfo {
variable: string;
valDec?: number;
dataKeyName: string
dataKeyName: string;
}
export type PolygonSettings = {
showPolygon: boolean;
polygonKeyName: string;
polKeyName: string;// deprecated
polKeyName: string; // deprecated
polygonStrokeOpacity: number;
polygonOpacity: number;
polygonStrokeWeight: number;
@ -141,7 +141,7 @@ export type PolygonSettings = {
polygonTooltipFunction: GenericFunction;
polygonColorFunction?: GenericFunction;
editablePolygon: boolean;
}
};
export type PolylineSettings = {
usePolylineDecorator: any;
@ -166,7 +166,7 @@ export type PolylineSettings = {
colorFunction: GenericFunction;
strokeOpacityFunction: GenericFunction;
strokeWeightFunction: GenericFunction;
}
};
export interface HistorySelectSettings {
buttonColor: string;
@ -244,4 +244,5 @@ export const hereProviders = [
'HERE.normalDay',
'HERE.normalNight',
'HERE.hybridDay',
'HERE.terrainDay']
'HERE.terrainDay'
];

8
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts

@ -18,15 +18,15 @@ import { JsonSettingsSchema } from '@shared/models/widget.models';
import { MapProviders } from './map-models';
export interface MapWidgetInterface {
resize(),
update(),
onInit(),
resize();
update();
onInit();
onDestroy();
}
export interface MapWidgetStaticInterface {
settingsSchema(mapProvider?: MapProviders, drawRoutes?: boolean): JsonSettingsSchema;
getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema
getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema;
dataKeySettingsSchema(): object;
actionSources(): object;
}

40
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts

@ -33,7 +33,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, parseData, parseFunction, parseWithTranslation } from './maps-utils';
import { getDefCenterPosition, 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';
@ -102,8 +102,9 @@ export class MapWidgetController implements MapWidgetInterface {
public static getProvidersSchema(mapProvider: MapProviders, ignoreImageMap = false) {
const providerSchema = _.cloneDeep(mapProviderSchema);
if (mapProvider)
providerSchema.schema.properties.provider.default = mapProvider;
if (mapProvider) {
providerSchema.schema.properties.provider.default = mapProvider;
}
if (ignoreImageMap) {
providerSchema.form[0].items = providerSchema.form[0]?.items.filter(item => item.value !== 'image-map');
}
@ -129,7 +130,7 @@ export class MapWidgetController implements MapWidgetInterface {
} else {
const clusteringSchema = mergeSchemes([markerClusteringSettingsSchema,
addCondition(markerClusteringSettingsSchemaLeaflet,
`model.useClusterMarkers === true && model.provider !== "image-map"`)])
`model.useClusterMarkers === true && model.provider !== "image-map"`)]);
addToSchema(schema, clusteringSchema);
addGroupInfo(schema, 'Markers Clustering Settings');
}
@ -154,10 +155,11 @@ export class MapWidgetController implements MapWidgetInterface {
}
translate = (key: string, defaultTranslation?: string): string => {
if (key)
return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key)
|| this.ctx.$injector.get(TranslateService).instant(key));
else return '';
if (key) {
return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key)
|| this.ctx.$injector.get(TranslateService).instant(key));
}
return '';
}
getDescriptors(name: string): { [name: string]: ($event: Event, datasource: Datasource) => void } {
@ -211,10 +213,10 @@ export class MapWidgetController implements MapWidgetInterface {
}
if (value) {
if (key.type === DataKeyType.attribute) {
attributes.push(value)
attributes.push(value);
}
if (key.type === DataKeyType.timeseries) {
timeseries.push(value)
timeseries.push(value);
}
}
});
@ -253,7 +255,7 @@ export class MapWidgetController implements MapWidgetInterface {
const coordinatesProperties = this.settings.polygonKeyName;
e.$datasource.dataKeys.forEach(key => {
let value;
if (coordinatesProperties == key.name) {
if (coordinatesProperties === key.name) {
value = {
key: key.name,
value: isDefined(coordinates) ? coordinates : e[key.name]
@ -261,10 +263,10 @@ export class MapWidgetController implements MapWidgetInterface {
}
if (value) {
if (key.type === DataKeyType.attribute) {
attributes.push(value)
attributes.push(value);
}
if (key.type === DataKeyType.timeseries) {
timeseries.push(value)
timeseries.push(value);
}
}
});
@ -294,9 +296,11 @@ export class MapWidgetController implements MapWidgetInterface {
const functionParams = ['data', 'dsData', 'dsIndex'];
this.provider = settings.provider || this.mapProvider;
if (this.provider === MapProviders.here && !settings.mapProviderHere) {
if (settings.mapProvider && hereProviders.includes(settings.mapProvider))
settings.mapProviderHere = settings.mapProvider
else settings.mapProviderHere = hereProviders[0];
if (settings.mapProvider && hereProviders.includes(settings.mapProvider)) {
settings.mapProviderHere = settings.mapProvider;
} else {
settings.mapProviderHere = hereProviders[0];
}
}
const customOptions = {
provider: this.provider,
@ -317,14 +321,14 @@ export class MapWidgetController implements MapWidgetInterface {
url: settings.markerImage,
size: settings.markerImageSize || 34
} : null
}
};
if (isEditMap && !settings.hasOwnProperty('draggableMarker')) {
settings.draggableMarker = true;
}
if (isEditMap && !settings.hasOwnProperty('editablePolygon')) {
settings.editablePolygon = true;
}
return { ...defaultSettings, ...settings, ...customOptions, }
return { ...defaultSettings, ...settings, ...customOptions, };
}
update() {

36
ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts

@ -31,9 +31,9 @@ import {
} from '@core/utils';
export function createTooltip(target: L.Layer,
settings: MarkerSettings | PolylineSettings | PolygonSettings,
datasource: Datasource,
content?: string | HTMLElement
settings: MarkerSettings | PolylineSettings | PolygonSettings,
datasource: Datasource,
content?: string | HTMLElement
): L.Popup {
const popup = L.popup();
popup.setContent(content);
@ -87,7 +87,7 @@ export function interpolateOnLineSegment(
}
export function findAngle(startPoint: FormattedData, endPoint: FormattedData, latKeyName: string, lngKeyName: string): number {
if(isUndefined(startPoint) || isUndefined(endPoint)){
if (isUndefined(startPoint) || isUndefined(endPoint)) {
return 0;
}
let angle = -Math.atan2(endPoint[latKeyName] - startPoint[latKeyName], endPoint[lngKeyName] - startPoint[lngKeyName]);
@ -97,11 +97,13 @@ export function findAngle(startPoint: FormattedData, endPoint: FormattedData, la
export function getDefCenterPosition(position) {
if (typeof (position) === 'string')
return position.split(',');
if (typeof (position) === 'object')
return position;
return [0, 0];
if (typeof (position) === 'string') {
return position.split(',');
}
if (typeof (position) === 'object') {
return position;
}
return [0, 0];
}
@ -123,7 +125,7 @@ function imageLoader(imageUrl: string): Observable<HTMLImageElement> {
document.body.removeChild(image);
observer.complete();
};
document.body.appendChild(image)
document.body.appendChild(image);
image.src = imageUrl;
});
}
@ -135,11 +137,11 @@ export function aspectCache(imageUrl: string): Observable<number> {
if (aspect) {
return of(aspect);
}
else return imageLoader(imageUrl).pipe(map(image => {
return imageLoader(imageUrl).pipe(map(image => {
aspect = image.width / image.height;
imageAspectMap[hash] = aspect;
return aspect;
}))
}));
}
}
@ -221,7 +223,7 @@ function parseTemplate(template: string, data: { $datasource?: Datasource, [key:
// res = compiled(data);
res = template;
} catch (ex) {
console.log(ex, template)
console.log(ex, template);
}
return res;
}
@ -263,7 +265,7 @@ export function processPattern(template: string, data: { $datasource?: Datasourc
match = reg.exec(template);
}
} catch (ex) {
console.log(ex, template)
console.log(ex, template);
}
return replaceInfo;
}
@ -271,7 +273,7 @@ export function processPattern(template: string, data: { $datasource?: Datasourc
export function fillPattern(markerLabelText: string, replaceInfoLabelMarker: Array<ReplaceInfo>, data: FormattedData) {
let text = createLabelFromDatasource(data.$datasource, markerLabelText);
if (replaceInfoLabelMarker) {
for(const variableInfo of replaceInfoLabelMarker) {
for (const variableInfo of replaceInfoLabelMarker) {
let txtVal = '';
if (variableInfo.dataKeyName && isDefinedAndNotNull(data[variableInfo.dataKeyName])) {
const varData = data[variableInfo.dataKeyName];
@ -334,7 +336,7 @@ export const parseWithTranslation = {
setTranslate(translateFn: TranslateFunc) {
this.translateFn = translateFn;
}
}
};
export function parseData(input: DatasourceData[]): FormattedData[] {
return _(input).groupBy(el => el?.datasource?.entityName)
@ -361,7 +363,7 @@ export function parseData(input: DatasourceData[]): FormattedData[] {
export function parseArray(input: DatasourceData[]): FormattedData[][] {
return _(input).groupBy(el => el?.datasource?.entityName)
.values().value().map((entityArray, dsIndex) =>
.values().value().map((entityArray) =>
entityArray[0].data.map((el, i) => {
const obj: FormattedData = {
entityName: entityArray[0]?.datasource?.entityName,

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

@ -81,7 +81,7 @@ export class Marker {
}
updateMarkerTooltip(data: FormattedData) {
if(!this.map.markerTooltipText || this.settings.useTooltipFunction) {
if (!this.map.markerTooltipText || this.settings.useTooltipFunction) {
const pattern = this.settings.useTooltipFunction ?
safeExecute(this.settings.tooltipFunction, [this.data, this.dataSources, this.data.dsIndex]) : this.settings.tooltipPattern;
this.map.markerTooltipText = parseWithTranslation.prepareProcessPattern(pattern, true);
@ -103,7 +103,7 @@ export class Marker {
updateMarkerLabel(settings: MarkerSettings) {
this.leafletMarker.unbindTooltip();
if (settings.showLabel) {
if(!this.map.markerLabelText || settings.useLabelFunction) {
if (!this.map.markerLabelText || settings.useLabelFunction) {
const pattern = settings.useLabelFunction ?
safeExecute(settings.labelFunction, [this.data, this.dataSources, this.data.dsIndex]) : settings.label;
this.map.markerLabelText = parseWithTranslation.prepareProcessPattern(pattern, true);

21
ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts

@ -55,7 +55,7 @@ export class Polygon {
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.settings.polygonClick[action](event.originalEvent, polyData.$datasource);
}
}
});
@ -70,18 +70,19 @@ export class Polygon {
}
updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) {
this.data = data;
this.dataSources = dataSources;
if (settings.editablePolygon) {
this.leafletPoly.disableEdit();
}
this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]);
this.data = data;
this.dataSources = dataSources;
if (settings.editablePolygon) {
this.leafletPoly.disableEdit();
}
this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]);
if (settings.editablePolygon) {
this.leafletPoly.enableEdit(this.map);
}
if (settings.showPolygonTooltip)
this.updateTooltip(this.data);
this.updatePolygonColor(settings);
if (settings.showPolygonTooltip) {
this.updateTooltip(this.data);
}
this.updatePolygonColor(settings);
}
removePolygon() {

7
ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts

@ -57,7 +57,7 @@ export class Polyline {
})
}
]
}
};
}
updatePolyline(locations: L.LatLng[], data: FormattedData, dataSources: FormattedData[], settings: PolylineSettings) {
@ -65,8 +65,9 @@ export class Polyline {
this.dataSources = dataSources;
this.leafletPoly.setLatLngs(locations);
this.leafletPoly.setStyle(this.getPolyStyle(settings));
if (this.polylineDecorator)
if (this.polylineDecorator) {
this.polylineDecorator.setPaths(this.leafletPoly);
}
}
getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
@ -78,7 +79,7 @@ export class Polyline {
[this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity),
weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction,
[this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight)
}
};
}
removePolyline() {

2
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts

@ -49,7 +49,7 @@ export class GoogleMap extends LeafletMap {
private loadGoogle(callback, apiKey = 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q') {
if (gmGlobals[apiKey]) {
callback()
callback();
} else {
this.resource.loadResource(`https://maps.googleapis.com/maps/api/js?key=${apiKey}`).subscribe(
() => {

121
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts

@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
const maxZoom = 4;// ?
const maxZoom = 4; // ?
export class ImageMap extends LeafletMap {
@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap {
}
onResize(updateImage?: boolean) {
let width = this.$container.clientWidth;
if (width > 0 && this.aspect) {
let height = width / this.aspect;
const imageMapHeight = this.$container.clientHeight;
if (imageMapHeight > 0 && height > imageMapHeight) {
height = imageMapHeight;
width = height * this.aspect;
let width = this.$container.clientWidth;
if (width > 0 && this.aspect) {
let height = width / this.aspect;
const imageMapHeight = this.$container.clientHeight;
if (imageMapHeight > 0 && height > imageMapHeight) {
height = imageMapHeight;
width = height * this.aspect;
}
width *= maxZoom;
const prevWidth = this.width;
const prevHeight = this.height;
if (this.width !== width || updateImage) {
this.width = width;
this.height = width / this.aspect;
if (!this.map) {
this.initMap(updateImage);
} else {
const lastCenterPos = this.latLngToPoint(this.map.getCenter());
lastCenterPos.x /= prevWidth;
lastCenterPos.y /= prevHeight;
this.updateBounds(updateImage, lastCenterPos);
this.map.invalidateSize(true);
this.updateMarkers(this.markersData);
if (this.options.draggableMarker && this.addMarkers.length) {
this.addMarkers.forEach((marker) => {
const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight);
marker.setLatLng(this.convertPosition(prevPoint));
});
}
width *= maxZoom;
const prevWidth = this.width;
const prevHeight = this.height;
if (this.width !== width || updateImage) {
this.width = width;
this.height = width / this.aspect;
if (!this.map) {
this.initMap(updateImage);
} else {
const lastCenterPos = this.latLngToPoint(this.map.getCenter());
lastCenterPos.x /= prevWidth;
lastCenterPos.y /= prevHeight;
this.updateBounds(updateImage, lastCenterPos);
this.map.invalidateSize(true);
this.updateMarkers(this.markersData);
this.updatePolygons(this.polygonsData);
}
this.updatePolygons(this.polygonsData);
if (this.options.showPolygon && this.options.editablePolygon && this.addPolygons.length) {
this.addPolygons.forEach((polygon) => {
const prevPolygonPoint = this.convertToPolygonFormat(polygon.getLatLngs(), prevWidth, prevHeight);
polygon.setLatLngs(this.convertPositionPolygon(prevPolygonPoint));
});
}
}
}
}
}
fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { }
initMap(updateImage?: boolean) {
if (!this.map && this.aspect > 0) {
const center = this.pointToLatLng(this.width / 2, this.height / 2);
this.map = L.map(this.$container, {
minZoom: 1,
maxZoom,
scrollWheelZoom: !this.options.disableScrollZooming,
center,
zoom: 1,
crs: L.CRS.Simple,
attributionControl: false,
editable: !!this.options.editablePolygon
});
this.updateBounds(updateImage);
}
if (!this.map && this.aspect > 0) {
const center = this.pointToLatLng(this.width / 2, this.height / 2);
this.map = L.map(this.$container, {
minZoom: 1,
maxZoom,
scrollWheelZoom: !this.options.disableScrollZooming,
center,
zoom: 1,
crs: L.CRS.Simple,
attributionControl: false,
editable: !!this.options.editablePolygon
});
this.updateBounds(updateImage);
}
}
convertPosition(expression): L.LatLng {
@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap {
if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
return this.pointToLatLng(
el[0] * this.width,
el[1] * this.height)
el[1] * this.height
);
} else if (Array.isArray(el) && el.length) {
return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
} else {
return null;
}
}).filter(el => !!el)
}).filter(el => !!el);
}
pointToLatLng(x, y): L.LatLng {
@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap {
return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
}
convertToCustomFormat(position: L.LatLng): object {
const point = this.latLngToPoint(position);
return {
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width),
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height)
}
convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object {
const point = this.latLngToPoint(position);
return {
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width),
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height)
};
}
convertToPolygonFormat(points: Array<any>): Array<any> {
convertToPolygonFormat(points: Array<any>, width = this.width, height = this.height): Array<any> {
if (points.length) {
return points.map(point=> {
return points.map(point => {
if (point.length) {
return this.convertToPolygonFormat(point);
return this.convertToPolygonFormat(point, width, height);
} else {
const pos = this.latLngToPoint(point);
return [calculateNewPointCoordinate(pos.x, this.width), calculateNewPointCoordinate(pos.y, this.height)];
return [calculateNewPointCoordinate(pos.x, width), calculateNewPointCoordinate(pos.y, height)];
}
})
});
} else {
return []
return [];
}
}
convertPolygonToCustomFormat(expression: any[][]): object {
return {
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
}
};
}
}

8
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts

@ -29,16 +29,16 @@ import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
import { JsonSettingsSchema } from '@shared/models/widget.models';
interface IProvider {
MapClass: Type<LeafletMap>,
schema: JsonSettingsSchema,
name: string
MapClass: Type<LeafletMap>;
schema: JsonSettingsSchema;
name: string;
}
export const providerSets: { [key: string]: IProvider } = {
'openstreet-map': {
MapClass: OpenStreetMap,
schema: openstreetMapSettingsSchema,
name: 'openstreet-map',
name: 'openstreet-map'
},
'tencent-map': {
MapClass: TencentMap,

9
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts

@ -26,10 +26,11 @@ export class OpenStreetMap extends LeafletMap {
editable: !!options.editablePolygon
}).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
let tileLayer;
if (options.useCustomProvider)
tileLayer = L.tileLayer(options.customProviderTileUrl);
else
tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik');
if (options.useCustomProvider) {
tileLayer = L.tileLayer(options.customProviderTileUrl);
} else {
tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik');
}
tileLayer.addTo(map);
super.initSettings(options);
super.setMap(map);

56
ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts

@ -1068,31 +1068,31 @@ export const tripAnimationSchema = {
key: 'labelFunction',
type: 'javascript'
}, 'showTooltip', {
key: 'tooltipColor',
type: 'color'
}, {
key: 'tooltipFontColor',
type: 'color'
}, 'tooltipOpacity', {
key: 'tooltipPattern',
type: 'textarea'
}, 'useTooltipFunction', {
key: 'tooltipFunction',
type: 'javascript'
}, 'autocloseTooltip', {
key: 'markerImage',
type: 'image'
}, 'markerImageSize', 'rotationAngle', 'useMarkerImageFunction',
{
key: 'markerImageFunction',
type: 'javascript'
}, {
key: 'markerImages',
items: [
{
key: 'markerImages[]',
type: 'image'
}
]
}]
}
key: 'tooltipColor',
type: 'color'
}, {
key: 'tooltipFontColor',
type: 'color'
}, 'tooltipOpacity', {
key: 'tooltipPattern',
type: 'textarea'
}, 'useTooltipFunction', {
key: 'tooltipFunction',
type: 'javascript'
}, 'autocloseTooltip', {
key: 'markerImage',
type: 'image'
}, 'markerImageSize', 'rotationAngle', 'useMarkerImageFunction',
{
key: 'markerImageFunction',
type: 'javascript'
}, {
key: 'markerImages',
items: [
{
key: 'markerImages[]',
type: 'image'
}
]
}]
};

Loading…
Cancel
Save