From f7470348ff26c79afe3a1782050de0e50e1dad61 Mon Sep 17 00:00:00 2001 From: Adsumus Date: Fri, 20 Mar 2020 02:23:53 +0200 Subject: [PATCH] add marker creation --- .../components/widget/lib/maps/leaflet-map.ts | 66 ++++++++++++------- .../components/widget/lib/maps/map-models.ts | 10 +-- .../components/widget/lib/maps/map-widget2.ts | 45 +++++++------ .../components/widget/lib/maps/maps-utils.ts | 9 +++ .../components/widget/lib/maps/markers.ts | 7 +- .../widget/lib/maps/providers/image-map.ts | 2 +- 6 files changed, 85 insertions(+), 54 deletions(-) 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 3178c78b96..4daaf47e60 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 @@ -21,7 +21,7 @@ import 'leaflet.markercluster/dist/MarkerCluster.css' import 'leaflet.markercluster/dist/MarkerCluster.Default.css' import 'leaflet.markercluster/dist/leaflet.markercluster' -import { MapSettings, MarkerSettings, FormattedData } from './map-models'; +import { MapSettings, MarkerSettings, FormattedData, UnitedMapSettings, PolygonSettings } from './map-models'; import { Marker } from './markers'; import { Observable, of, BehaviorSubject, Subject } from 'rxjs'; import { filter } from 'rxjs/operators'; @@ -31,18 +31,18 @@ import { Polygon } from './polygon'; export default abstract class LeafletMap { markers: Map = new Map(); - dragMode = false; + dragMode = true; tooltips = []; poly: Polyline; polygon: Polygon; map: L.Map; map$: BehaviorSubject = new BehaviorSubject(null); ready$: Observable = this.map$.pipe(filter(map => !!map)); - options: MapSettings & MarkerSettings; + options: UnitedMapSettings; isMarketCluster: boolean; bounds: L.LatLngBounds; - constructor($container: HTMLElement, options: MapSettings & MarkerSettings) { + constructor(public $container: HTMLElement, options: UnitedMapSettings) { this.options = options; } @@ -55,7 +55,7 @@ export default abstract class LeafletMap { mapProvider, credentials, defaultCenterPosition, - draggebleMarker, + draggableMarker, markerClusteringSetting }: MapSettings = options; if (disableScrollZooming) { this.map.scrollWheelZoom.disable(); @@ -66,7 +66,19 @@ export default abstract class LeafletMap { } addMarkerControl() { - if (this.options.draggebleMarker) + if (this.options.draggableMarker) { + let mousePositionOnMap: L.LatLng; + let addMarker: L.Control; + this.map.on('mouseup', (e: L.LeafletMouseEvent) => { + mousePositionOnMap = e.latlng + }) + const dragListener = (e: L.DragEndEvent) => { + if (e.type === 'dragend' && mousePositionOnMap) { + L.marker(mousePositionOnMap, { + }).addTo(this.map); + } + addMarker.setPosition('topright') + } L.Control.AddMarker = L.Control.extend({ onAdd(map) { const img = L.DomUtil.create('img') as any; @@ -74,22 +86,27 @@ export default abstract class LeafletMap { img.style.width = '32px'; img.style.height = '32px'; img.onclick = this.dragMarker; + img.draggable = true; + const draggableImg = new L.Draggable(img); + draggableImg.enable(); + draggableImg.on('dragend', dragListener) return img; }, addHooks() { - L.DomEvent.on(window as any, 'onclick', this.enableDragMode, this); + // L.DomEvent.on(window as any, 'onmousedown', this.dragMarker, this); }, onRemove(map) { }, - dragMarker: ($event) => { - this.dragMode = !this.dragMode; - } + dragMarker: this.dragMarker + } as any); - L.control.addMarker = (opts) => { - return new L.Control.AddMarker(opts); + L.control.addMarker = (opts) => { + return new L.Control.AddMarker(opts); + } + + addMarker = L.control.addMarker({ position: 'topright' }).addTo(this.map); } - L.control.addMarker({ position: 'topright' }).addTo(this.map); } public setMap(map: L.Map) { @@ -99,12 +116,12 @@ export default abstract class LeafletMap { this.bounds = map.getBounds(); } else this.bounds = new L.LatLngBounds(null, null); - if (this.options.draggebleMarker) { + if (this.options.draggableMarker) { this.addMarkerControl(); - this.map.on('click', (e: L.LeafletMouseEvent) => { - if (this.dragMode) - this.saveMarkerLocation(this.convertToCustomFormat(e.latlng)); - }) + /* this.map.on('click', (e: L.LeafletMouseEvent) => { + if (this.dragMode) + this.saveMarkerLocation(this.convertToCustomFormat(e.latlng)); + })*/ } this.map$.next(this.map); } @@ -177,9 +194,14 @@ export default abstract class LeafletMap { }); } - private createMarker(key, data: FormattedData, dataSources, settings: MarkerSettings) { + dragMarker = (e, data?) => { + if (e.type !== 'dragend') return; + this.saveMarkerLocation({ ...data, ...this.convertToCustomFormat(e.target._latlng) }); + } + + private createMarker(key, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings) { this.ready$.subscribe(() => { - const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources); + const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources, () => { }, this.dragMarker); this.map.fitBounds(this.bounds.extend(newMarker.leafletMarker.getLatLng())); this.markers.set(key, newMarker); }); @@ -239,7 +261,7 @@ export default abstract class LeafletMap { // Polygon - updatePolygons(polyData: Array>) { + updatePolygons(polyData: any[]) { polyData.forEach((data: any) => { if (data.data.length && data.dataKey.name === this.options.polygonKeyName) { if (typeof (data?.data[0][1]) === 'string') { @@ -255,7 +277,7 @@ export default abstract class LeafletMap { }); } - createPolygon(data, dataSources, settings) { + createPolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) { this.ready$.subscribe(() => { this.polygon = new Polygon(this.map, data, dataSources, settings); const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds()); 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 9f9a637122..6f337b51e5 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 @@ -21,7 +21,7 @@ export type MarkerImageFunction = (data: FormattedData, dsData: FormattedData[], export type MapSettings = { polygonKeyName: any; - draggebleMarker: any; + draggableMarker: boolean; initCallback?: () => any; defaultZoomLevel?: number; dontFitMapBounds?: boolean; @@ -58,7 +58,7 @@ export type MarkerSettings = { labelColor: string; labelText: string; useLabelFunction: boolean; - draggable?: boolean; + draggableMarker: boolean; showTooltip?: boolean; color?: string; autocloseTooltip: boolean; @@ -110,9 +110,9 @@ export type PolylineSettings = { decoratorCustomColor: any; - colorFunction(colorFunction: any, arg1: any[]): string; - strokeOpacityFunction(strokeOpacityFunction: any, arg1: any[]): number; - strokeWeightFunction(strokeWeightFunction: any, arg1: any[]): number; + colorFunction: GenericFunction; + strokeOpacityFunction: GenericFunction; + strokeWeightFunction: GenericFunction; } export interface HistorySelectSettings { 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 d47915f03e..a21b85afb2 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 @@ -32,10 +32,14 @@ import { MapWidgetStaticInterface, MapWidgetInterface } from './map-widget.inter import { OpenStreetMap, TencentMap, GoogleMap, HEREMap, ImageMap } from './providers'; import { parseFunction, parseArray, parseData } from '@app/core/utils'; import { initSchema, addToSchema, mergeSchemes, addCondition, addGroupInfo } from '@app/core/schema-utils'; -import { AttributeScope, EntityId } from '@app/shared/public-api'; +import { AttributeScope, EntityId, JsonSettingsSchema } from '@app/shared/public-api'; import { forkJoin } from 'rxjs'; import { WidgetContext } from '@app/modules/home/models/widget-component.models'; import { AttributeService } from '@app/core/public-api'; +import { getDefCenterPosition } from './maps-utils'; + +let providerSets; +let defaultSettings; export class MapWidgetController implements MapWidgetInterface { @@ -63,19 +67,19 @@ export class MapWidgetController implements MapWidgetInterface { provider: MapProviders; schema; data; - settings:UnitedMapSettings; + settings: UnitedMapSettings; - public static dataKeySettingsSchema(): Object { + public static dataKeySettingsSchema(): object { return {}; } public static getProvidersSchema() { return mergeSchemes([mapProviderSchema, ...Object.values(providerSets)?.map( - setting => addCondition(setting?.schema, `model.provider === '${setting.name}'`))]); + (setting: IProvider) => addCondition(setting?.schema, `model.provider === '${setting.name}'`))]); } - public static settingsSchema(mapProvider, drawRoutes): Object { + public static settingsSchema(mapProvider, drawRoutes): object { const schema = initSchema(); addToSchema(schema, this.getProvidersSchema()); addGroupInfo(schema, 'Map Provider Settings'); @@ -93,7 +97,7 @@ export class MapWidgetController implements MapWidgetInterface { return schema; } - public static actionSources(): Object { + public static actionSources(): object { return { markerClick: { name: 'widget-action.marker-click', @@ -114,9 +118,7 @@ export class MapWidgetController implements MapWidgetInterface { } setMarkerLocation = (e) => { - const s = this.ctx.$injector.get(AttributeService); - console.log('MapWidgetController -> setMarkerLocation -> s', s, s.saveEntityAttributes) - const attributeService = this.ctx.$scope.$injector.get(this.ctx.servicesMap.get('attributeService')); + const attributeService = this.ctx.$injector.get(AttributeService); forkJoin( this.data.filter(data => !!e[data.dataKey.name]) .map(data => { @@ -140,15 +142,7 @@ export class MapWidgetController implements MapWidgetInterface { initSettings(settings: any) { const functionParams = ['data', 'dsData', 'dsIndex']; this.provider = settings.provider ? settings.provider : this.mapProvider; - - function getDefCenterPosition(position) { - if (typeof (position) === 'string') - return position.split(','); - if (typeof (position) === 'object') - return position; - return [0, 0]; - } - + console.log(settings.draggableMarker); const customOptions = { provider: this.provider, mapUrl: settings?.mapImageUrl, @@ -159,9 +153,9 @@ export class MapWidgetController implements MapWidgetInterface { markerImageFunction: parseFunction(settings.markerImageFunction, ['data', 'images', 'dsData', 'dsIndex']), labelColor: this.ctx.widgetConfig.color, tooltipPattern: settings.tooltipPattern || - '${entityName}

Latitude: ${' + settings.latKeyName + ':7}
Longitude: ${' + settings.lngKeyName + ':7}', + '${entityName}

Latitude: ${' + + settings.latKeyName + ':7}
Longitude: ${' + settings.lngKeyName + ':7}', defaultCenterPosition: getDefCenterPosition(settings?.defaultCenterPosition), - useDraggableMarker: true, currentImage: (settings.useMarkerImage && settings.markerImage?.length) ? { url: settings.markerImage, size: settings.markerImageSize || 34 @@ -197,8 +191,13 @@ export class MapWidgetController implements MapWidgetInterface { export let TbMapWidgetV2: MapWidgetStaticInterface = MapWidgetController; +interface IProvider { + MapClass: LeafletMap, + schema: JsonSettingsSchema, + name: string +} -const providerSets = { +providerSets = { 'openstreet-map': { MapClass: OpenStreetMap, schema: openstreetMapSettingsSchema, @@ -226,7 +225,7 @@ const providerSets = { } } -const defaultSettings = { +defaultSettings = { xPosKeyName: 'xPos', yPosKeyName: 'yPos', markerOffsetX: 0.5, @@ -259,5 +258,5 @@ const defaultSettings = { minZoomLevel: 16, credentials: '', markerClusteringSetting: null, - draggebleMarker: false + draggableMarker: false } \ No newline at end of file diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts index f705d1ac57..7af0828891 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts @@ -44,3 +44,12 @@ export function findAngle(startPoint, endPoint) { return parseInt(angle.toFixed(2), 10); } + +export function getDefCenterPosition(position) { + if (typeof (position) === 'string') + return position.split(','); + if (typeof (position) === 'object') + return position; + return [0, 0]; +} + 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 365a09c0bd..ca5400d4f6 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 @@ -28,10 +28,11 @@ export class Marker { data: FormattedData; dataSources: FormattedData[]; - constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data?, dataSources?, onClickListener?, onDragendListener?) { + constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, + data?, dataSources?, onClickListener?, onDragendListener?) { this.setDataSources(data, dataSources); this.leafletMarker = L.marker(location, { - draggable: settings.draggable + draggable: settings.draggableMarker }); this.createMarkerIcon((iconInfo) => { @@ -51,7 +52,7 @@ export class Marker { } if (onDragendListener) { - this.leafletMarker.on('dragend', onDragendListener); + this.leafletMarker.on('dragend', (e) => onDragendListener(e, this.data)); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts index 6796604c3f..d90bb42db3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts @@ -28,7 +28,7 @@ export class ImageMap extends LeafletMap { width = 0; height = 0; - constructor(private $container: HTMLElement, options: UnitedMapSettings) { + constructor($container: HTMLElement, options: UnitedMapSettings) { super($container, options); aspectCache(options.mapUrl).subscribe(aspect => { this.aspect = aspect;