Commit 97e99dc338b2b6088af753a1319e0eaa34185a7a

Authored by Adsumus
1 parent f064f280

add typing

@@ -21,7 +21,7 @@ import 'leaflet.markercluster/dist/MarkerCluster.css' @@ -21,7 +21,7 @@ import 'leaflet.markercluster/dist/MarkerCluster.css'
21 import 'leaflet.markercluster/dist/MarkerCluster.Default.css' 21 import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
22 import 'leaflet.markercluster/dist/leaflet.markercluster' 22 import 'leaflet.markercluster/dist/leaflet.markercluster'
23 23
24 -import { MapOptions, MarkerSettings } from './map-models'; 24 +import { MapSettings, MarkerSettings, FormattedData } from './map-models';
25 import { Marker } from './markers'; 25 import { Marker } from './markers';
26 import { Observable, of, BehaviorSubject, Subject } from 'rxjs'; 26 import { Observable, of, BehaviorSubject, Subject } from 'rxjs';
27 import { filter } from 'rxjs/operators'; 27 import { filter } from 'rxjs/operators';
@@ -38,15 +38,15 @@ export default abstract class LeafletMap { @@ -38,15 +38,15 @@ export default abstract class LeafletMap {
38 map: L.Map; 38 map: L.Map;
39 map$: BehaviorSubject<L.Map> = new BehaviorSubject(null); 39 map$: BehaviorSubject<L.Map> = new BehaviorSubject(null);
40 ready$: Observable<L.Map> = this.map$.pipe(filter(map => !!map)); 40 ready$: Observable<L.Map> = this.map$.pipe(filter(map => !!map));
41 - options: MapOptions; 41 + options: MapSettings & MarkerSettings;
42 isMarketCluster: boolean; 42 isMarketCluster: boolean;
43 bounds: L.LatLngBounds; 43 bounds: L.LatLngBounds;
44 44
45 - constructor($container: HTMLElement, options: MapOptions) { 45 + constructor($container: HTMLElement, options: MapSettings & MarkerSettings) {
46 this.options = options; 46 this.options = options;
47 } 47 }
48 48
49 - public initSettings(options: MapOptions) { 49 + public initSettings(options: MapSettings) {
50 const { initCallback, 50 const { initCallback,
51 defaultZoomLevel, 51 defaultZoomLevel,
52 dontFitMapBounds, 52 dontFitMapBounds,
@@ -56,7 +56,7 @@ export default abstract class LeafletMap { @@ -56,7 +56,7 @@ export default abstract class LeafletMap {
56 credentials, 56 credentials,
57 defaultCenterPosition, 57 defaultCenterPosition,
58 draggebleMarker, 58 draggebleMarker,
59 - markerClusteringSetting }: MapOptions = options; 59 + markerClusteringSetting }: MapSettings = options;
60 if (disableScrollZooming) { 60 if (disableScrollZooming) {
61 this.map.scrollWheelZoom.disable(); 61 this.map.scrollWheelZoom.disable();
62 } 62 }
@@ -86,16 +86,12 @@ export default abstract class LeafletMap { @@ -86,16 +86,12 @@ export default abstract class LeafletMap {
86 } 86 }
87 } as any); 87 } as any);
88 88
89 - L.control.addMarker = function (opts) { 89 + L.control.addMarker = (opts) => {
90 return new L.Control.AddMarker(opts); 90 return new L.Control.AddMarker(opts);
91 } 91 }
92 L.control.addMarker({ position: 'topright' }).addTo(this.map); 92 L.control.addMarker({ position: 'topright' }).addTo(this.map);
93 } 93 }
94 94
95 - /*inited() {/// !!!!  
96 - return !!this.map;  
97 - }*/  
98 -  
99 public setMap(map: L.Map) { 95 public setMap(map: L.Map) {
100 this.map = map; 96 this.map = map;
101 if (this.options.useDefaultCenterPosition) { 97 if (this.options.useDefaultCenterPosition) {
@@ -117,10 +113,6 @@ export default abstract class LeafletMap { @@ -117,10 +113,6 @@ export default abstract class LeafletMap {
117 113
118 } 114 }
119 115
120 - getContainer() {  
121 - return this.map;  
122 - }  
123 -  
124 createLatLng(lat: number, lng: number): L.LatLng { 116 createLatLng(lat: number, lng: number): L.LatLng {
125 return L.latLng(lat, lng); 117 return L.latLng(lat, lng);
126 } 118 }
@@ -147,8 +139,13 @@ export default abstract class LeafletMap { @@ -147,8 +139,13 @@ export default abstract class LeafletMap {
147 return this.map.getCenter(); 139 return this.map.getCenter();
148 } 140 }
149 141
150 - convertPosition(expression: any): L.LatLng {  
151 - return L.latLng(expression[this.options.latKeyName], expression[this.options.lngKeyName]) as L.LatLng; 142 + convertPosition(expression: object): L.LatLng {
  143 + const lat = expression[this.options.latKeyName];
  144 + const lng = expression[this.options.lngKeyName];
  145 + if (isNaN(lat) || isNaN(lng))
  146 + return null;
  147 + else
  148 + return L.latLng(lat, lng) as L.LatLng;
152 } 149 }
153 150
154 convertToCustomFormat(position: L.LatLng): object { 151 convertToCustomFormat(position: L.LatLng): object {
@@ -161,24 +158,26 @@ export default abstract class LeafletMap { @@ -161,24 +158,26 @@ export default abstract class LeafletMap {
161 // Markers 158 // Markers
162 updateMarkers(markersData) { 159 updateMarkers(markersData) {
163 markersData.forEach(data => { 160 markersData.forEach(data => {
164 - if (data.rotationAngle) {  
165 - this.options.icon = L.divIcon({  
166 - html: `<div class="arrow" style="transform: rotate(${data.rotationAngle}deg)"><div>`  
167 - })  
168 - }  
169 - else {  
170 - this.options.icon = null;  
171 - }  
172 - if (this.markers.get(data.aliasName)) {  
173 - this.updateMarker(data.aliasName, data, markersData, this.options as MarkerSettings)  
174 - }  
175 - else {  
176 - this.createMarker(data.aliasName, data, markersData, this.options as MarkerSettings); 161 + if (this.convertPosition(data)) {
  162 + if (data.rotationAngle) {
  163 + this.options.icon = L.divIcon({
  164 + html: `<div class="arrow" style="transform: rotate(${data.rotationAngle}deg)"><div>`
  165 + })
  166 + }
  167 + else {
  168 + this.options.icon = null;
  169 + }
  170 + if (this.markers.get(data.aliasName)) {
  171 + this.updateMarker(data.aliasName, data, markersData, this.options)
  172 + }
  173 + else {
  174 + this.createMarker(data.aliasName, data, markersData, this.options as MarkerSettings);
  175 + }
177 } 176 }
178 }); 177 });
179 } 178 }
180 179
181 - private createMarker(key, data, dataSources, settings: MarkerSettings) { 180 + private createMarker(key, data: FormattedData, dataSources, settings: MarkerSettings) {
182 this.ready$.subscribe(() => { 181 this.ready$.subscribe(() => {
183 const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources); 182 const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources);
184 this.map.fitBounds(this.bounds.extend(newMarker.leafletMarker.getLatLng())); 183 this.map.fitBounds(this.bounds.extend(newMarker.leafletMarker.getLatLng()));
@@ -219,10 +218,11 @@ export default abstract class LeafletMap { @@ -219,10 +218,11 @@ export default abstract class LeafletMap {
219 }) 218 })
220 } 219 }
221 220
222 - createPolyline(data, dataSources, settings) { 221 + createPolyline(data: any[], dataSources, settings) {
223 if (data.length) 222 if (data.length)
224 this.ready$.subscribe(() => { 223 this.ready$.subscribe(() => {
225 - this.poly = new Polyline(this.map, data.map(data => this.convertPosition(data)), data, dataSources, settings); 224 + this.poly = new Polyline(this.map,
  225 + data.map(el => this.convertPosition(el)).filter(el => !!el), data, dataSources, settings);
226 const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds()); 226 const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds());
227 if (bounds.isValid()) { 227 if (bounds.isValid()) {
228 this.map.fitBounds(bounds); 228 this.map.fitBounds(bounds);
@@ -237,7 +237,7 @@ export default abstract class LeafletMap { @@ -237,7 +237,7 @@ export default abstract class LeafletMap {
237 }); 237 });
238 } 238 }
239 239
240 - // polygon 240 + // Polygon
241 241
242 updatePolygons(polyData: Array<Array<any>>) { 242 updatePolygons(polyData: Array<Array<any>>) {
243 polyData.forEach((data: any) => { 243 polyData.forEach((data: any) => {
@@ -268,7 +268,7 @@ export default abstract class LeafletMap { @@ -268,7 +268,7 @@ export default abstract class LeafletMap {
268 268
269 updatePolygon(data, dataSources, settings) { 269 updatePolygon(data, dataSources, settings) {
270 this.ready$.subscribe(() => { 270 this.ready$.subscribe(() => {
271 - // this.polygon.updatePolygon(settings, data, dataSources); 271 + // this.polygon.updatePolygon(settings, data, dataSources);
272 }); 272 });
273 } 273 }
274 } 274 }
1 /// 1 ///
2 /// Copyright © 2016-2020 The Thingsboard Authors 2 /// Copyright © 2016-2020 The Thingsboard Authors
3 /// 3 ///
4 -/// Licensed under the Apache License, Version 2.0 (the "License"); 4 +/// Licensed under the Apache License; Version 2.0 (the "License");
5 /// you may not use this file except in compliance with the License. 5 /// you may not use this file except in compliance with the License.
6 /// You may obtain a copy of the License at 6 /// You may obtain a copy of the License at
7 /// 7 ///
8 /// http://www.apache.org/licenses/LICENSE-2.0 8 /// http://www.apache.org/licenses/LICENSE-2.0
9 /// 9 ///
10 -/// Unless required by applicable law or agreed to in writing, software  
11 -/// distributed under the License is distributed on an "AS IS" BASIS,  
12 -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 +/// Unless required by applicable law or agreed to in writing; software
  11 +/// distributed under the License is distributed on an "AS IS" BASIS;
  12 +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND; either express or implied.
13 /// See the License for the specific language governing permissions and 13 /// See the License for the specific language governing permissions and
14 /// limitations under the License. 14 /// limitations under the License.
15 /// 15 ///
16 16
17 -import { LatLngExpression, LatLngTuple } from 'leaflet'; 17 +import { LatLngTuple } from 'leaflet';
18 18
19 -export interface MapOptions { 19 +export type GenericFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string;
  20 +export type MarkerImageFunction = (data: FormattedData, dsData: FormattedData[], dsIndex: number) => string;
  21 +
  22 +export type MapSettings = {
20 polygonKeyName: any; 23 polygonKeyName: any;
21 draggebleMarker: any; 24 draggebleMarker: any;
22 - initCallback?: Function,  
23 - defaultZoomLevel?: number,  
24 - dontFitMapBounds?: boolean,  
25 - disableScrollZooming?: boolean,  
26 - minZoomLevel?: number,  
27 - latKeyName?: string,  
28 - lngKeyName?: string,  
29 - xPosKeyName?: string,  
30 - yPosKeyName?: string,  
31 - mapProvider: MapProviders, 25 + initCallback?: () => any;
  26 + defaultZoomLevel?: number;
  27 + dontFitMapBounds?: boolean;
  28 + disableScrollZooming?: boolean;
  29 + minZoomLevel?: number;
  30 + latKeyName?: string;
  31 + lngKeyName?: string;
  32 + xPosKeyName?: string;
  33 + yPosKeyName?: string;
  34 + mapProvider: MapProviders;
32 mapUrl?: string; 35 mapUrl?: string;
33 - credentials?: any, // declare credentials format  
34 - defaultCenterPosition?: LatLngTuple,  
35 - markerClusteringSetting?,  
36 - useDefaultCenterPosition?: boolean,  
37 - gmDefaultMapType?: string, 36 + credentials?: any; // declare credentials format
  37 + defaultCenterPosition?: LatLngTuple;
  38 + markerClusteringSetting?;
  39 + useDefaultCenterPosition?: boolean;
  40 + gmDefaultMapType?: string;
38 useLabelFunction: string; 41 useLabelFunction: string;
39 icon?: any; 42 icon?: any;
40 } 43 }
@@ -47,15 +50,73 @@ export enum MapProviders { @@ -47,15 +50,73 @@ export enum MapProviders {
47 tencent = 'tencent-map' 50 tencent = 'tencent-map'
48 } 51 }
49 52
50 -export interface MarkerSettings extends MapOptions { 53 +export type MarkerSettings = {
51 tooltipPattern?: any; 54 tooltipPattern?: any;
52 icon?: any; 55 icon?: any;
53 - showLabel?: boolean,  
54 - draggable?: boolean,  
55 - showTooltip?: boolean,  
56 - color?: string, 56 + showLabel?: boolean;
  57 + label: string;
  58 + labelColor: string;
  59 + labelText: string;
  60 + useLabelFunction: boolean;
  61 + draggable?: boolean;
  62 + showTooltip?: boolean;
  63 + color?: string;
  64 + autocloseTooltip: boolean;
  65 + displayTooltipAction: string;
57 currentImage?: string; 66 currentImage?: string;
58 - useMarkerImageFunction?: boolean,  
59 - markerImages?: string[],  
60 - markerImageFunction?: Function;  
61 -}  
  67 + useMarkerImageFunction?: boolean;
  68 + markerImages?: string[];
  69 +
  70 + labelFunction: GenericFunction;
  71 + markerImageFunction?: MarkerImageFunction;
  72 +}
  73 +
  74 +export interface FormattedData {
  75 + aliasName: string;
  76 + entityName: string;
  77 + $datasource: string;
  78 + dsIndex: number;
  79 + deviceType: string
  80 +}
  81 +
  82 +export type PolygonSettings = {
  83 + showPolygon: boolean;
  84 + showTooltip: any;
  85 + polygonStrokeOpacity: number;
  86 + polygonOpacity: number;
  87 + polygonStrokeWeight: number;
  88 + polygonStrokeColor: string;
  89 + polygonColor: string;
  90 + autocloseTooltip: boolean;
  91 + displayTooltipAction: string;
  92 +}
  93 +
  94 +export type PolylineSettings = {
  95 + usePolylineDecorator: any;
  96 + autocloseTooltip: boolean;
  97 + displayTooltipAction: string;
  98 + useColorFunction: any;
  99 + color: string;
  100 + useStrokeOpacityFunction: any;
  101 + strokeOpacity: number;
  102 + useStrokeWeightFunction: any;
  103 + strokeWeight: number;
  104 + decoratorOffset: string | number;
  105 + endDecoratorOffset: string | number;
  106 + decoratorRepeat: string | number;
  107 + decoratorSymbol: any;
  108 + decoratorSymbolSize: any;
  109 + useDecoratorCustomColor: any;
  110 + decoratorCustomColor: any;
  111 +
  112 +
  113 + colorFunction(colorFunction: any, arg1: any[]): string;
  114 + strokeOpacityFunction(strokeOpacityFunction: any, arg1: any[]): number;
  115 + strokeWeightFunction(strokeWeightFunction: any, arg1: any[]): number;
  116 +}
  117 +
  118 +export interface HistorySelectSettings {
  119 + buttonColor: string;
  120 +}
  121 +
  122 +export type UnitedMapSettings = MapSettings & PolygonSettings & MarkerSettings & PolygonSettings;
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 /// limitations under the License. 14 /// limitations under the License.
15 /// 15 ///
16 16
17 -import { MapProviders, MapOptions } from './map-models'; 17 +import { MapProviders, MapSettings, MarkerSettings, PolygonSettings, UnitedMapSettings } from './map-models';
18 import LeafletMap from './leaflet-map'; 18 import LeafletMap from './leaflet-map';
19 import { 19 import {
20 openstreetMapSettingsSchema, 20 openstreetMapSettingsSchema,
@@ -63,7 +63,7 @@ export class MapWidgetController implements MapWidgetInterface { @@ -63,7 +63,7 @@ export class MapWidgetController implements MapWidgetInterface {
63 provider: MapProviders; 63 provider: MapProviders;
64 schema; 64 schema;
65 data; 65 data;
66 - settings; 66 + settings:UnitedMapSettings;
67 67
68 public static dataKeySettingsSchema(): Object { 68 public static dataKeySettingsSchema(): Object {
69 return {}; 69 return {};
@@ -16,12 +16,13 @@ @@ -16,12 +16,13 @@
16 16
17 import L from 'leaflet'; 17 import L from 'leaflet';
18 import _ from 'lodash'; 18 import _ from 'lodash';
  19 +import { MarkerSettings, PolylineSettings, PolygonSettings } from './map-models';
19 20
20 -export function createTooltip(target: L.Layer, settings): L.Popup { 21 +export function createTooltip(target: L.Layer, settings: MarkerSettings | PolylineSettings | PolygonSettings): L.Popup {
21 const popup = L.popup(); 22 const popup = L.popup();
22 popup.setContent(''); 23 popup.setContent('');
23 target.bindPopup(popup, { autoClose: settings.autocloseTooltip, closeOnClick: false }); 24 target.bindPopup(popup, { autoClose: settings.autocloseTooltip, closeOnClick: false });
24 - if (settings.displayTooltipAction == 'hover') { 25 + if (settings.displayTooltipAction === 'hover') {
25 target.off('click'); 26 target.off('click');
26 target.on('mouseover', function () { 27 target.on('mouseover', function () {
27 this.openPopup(); 28 this.openPopup();
@@ -40,6 +41,6 @@ export function getRatio(firsMoment: number, secondMoment: number, intermediateM @@ -40,6 +41,6 @@ export function getRatio(firsMoment: number, secondMoment: number, intermediateM
40 export function findAngle(startPoint, endPoint) { 41 export function findAngle(startPoint, endPoint) {
41 let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude); 42 let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude);
42 angle = angle * 180 / Math.PI; 43 angle = angle * 180 / Math.PI;
43 - return parseInt(angle.toFixed(2)); 44 + return parseInt(angle.toFixed(2), 10);
44 } 45 }
45 46
@@ -15,23 +15,20 @@ @@ -15,23 +15,20 @@
15 /// 15 ///
16 16
17 import L from 'leaflet'; 17 import L from 'leaflet';
18 -import { MarkerSettings } from './map-models'; 18 +import { MarkerSettings, FormattedData } from './map-models';
19 import { aspectCache, safeExecute, parseTemplate } from '@app/core/utils'; 19 import { aspectCache, safeExecute, parseTemplate } from '@app/core/utils';
20 import { createTooltip } from './maps-utils'; 20 import { createTooltip } from './maps-utils';
21 21
22 export class Marker { 22 export class Marker {
23 23
24 leafletMarker: L.Marker; 24 leafletMarker: L.Marker;
25 -  
26 - tooltipOffset;  
27 - tooltip;  
28 - location;  
29 - data;  
30 - dataSources; 25 + tooltipOffset: [number, number];
  26 + tooltip: L.Popup;
  27 + location: L.LatLngExpression;
  28 + data: FormattedData;
  29 + dataSources: FormattedData[];
31 30
32 constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data?, dataSources?, onClickListener?, onDragendListener?) { 31 constructor(private map: L.Map, location: L.LatLngExpression, public settings: MarkerSettings, data?, dataSources?, onClickListener?, onDragendListener?) {
33 - // this.map = map;  
34 - this.location = location;  
35 this.setDataSources(data, dataSources); 32 this.setDataSources(data, dataSources);
36 this.leafletMarker = L.marker(location, { 33 this.leafletMarker = L.marker(location, {
37 draggable: settings.draggable 34 draggable: settings.draggable
@@ -58,12 +55,12 @@ export class Marker { @@ -58,12 +55,12 @@ export class Marker {
58 } 55 }
59 } 56 }
60 57
61 - setDataSources(data, dataSources) { 58 + setDataSources(data: FormattedData, dataSources: FormattedData[]) {
62 this.data = data; 59 this.data = data;
63 this.dataSources = dataSources; 60 this.dataSources = dataSources;
64 } 61 }
65 62
66 - updateMarkerTooltip(data) { 63 + updateMarkerTooltip(data: FormattedData) {
67 this.tooltip.setContent(parseTemplate(this.settings.tooltipPattern, data)); 64 this.tooltip.setContent(parseTemplate(this.settings.tooltipPattern, data));
68 } 65 }
69 66
@@ -71,7 +68,7 @@ export class Marker { @@ -71,7 +68,7 @@ export class Marker {
71 this.leafletMarker.setLatLng(position); 68 this.leafletMarker.setLatLng(position);
72 } 69 }
73 70
74 - updateMarkerLabel(settings) { 71 + updateMarkerLabel(settings: MarkerSettings) {
75 this.leafletMarker.unbindTooltip(); 72 this.leafletMarker.unbindTooltip();
76 73
77 if (settings.showLabel) { 74 if (settings.showLabel) {
@@ -90,7 +87,7 @@ export class Marker { @@ -90,7 +87,7 @@ export class Marker {
90 }); 87 });
91 } 88 }
92 89
93 - updateMarkerIcon(settings) { 90 + updateMarkerIcon(settings: MarkerSettings) {
94 this.createMarkerIcon((iconInfo) => { 91 this.createMarkerIcon((iconInfo) => {
95 this.leafletMarker.setIcon(iconInfo.icon); 92 this.leafletMarker.setIcon(iconInfo.icon);
96 this.tooltipOffset = [0, -iconInfo.size[1] + 10]; 93 this.tooltipOffset = [0, -iconInfo.size[1] + 10];
@@ -14,15 +14,16 @@ @@ -14,15 +14,16 @@
14 /// limitations under the License. 14 /// limitations under the License.
15 /// 15 ///
16 16
17 -import L from 'leaflet'; 17 +import L, { LatLngExpression } from 'leaflet';
18 import { createTooltip } from './maps-utils'; 18 import { createTooltip } from './maps-utils';
  19 +import { PolygonSettings } from './map-models';
19 20
20 export class Polygon { 21 export class Polygon {
21 22
22 leafletPoly: L.Polygon; 23 leafletPoly: L.Polygon;
23 tooltip; 24 tooltip;
24 25
25 - constructor(public map, coordinates, dataSources, settings, onClickListener?) { 26 + constructor(public map, coordinates, dataSources, settings: PolygonSettings, onClickListener?) {
26 this.leafletPoly = L.polygon(coordinates, { 27 this.leafletPoly = L.polygon(coordinates, {
27 fill: true, 28 fill: true,
28 fillColor: settings.polygonColor, 29 fillColor: settings.polygonColor,
@@ -33,7 +34,7 @@ export class Polygon { @@ -33,7 +34,7 @@ export class Polygon {
33 }).addTo(this.map); 34 }).addTo(this.map);
34 35
35 if (settings.showTooltip) { 36 if (settings.showTooltip) {
36 - this.tooltip = createTooltip(this.leafletPoly, settings); 37 + this.tooltip = createTooltip(this.leafletPoly, settings);
37 } 38 }
38 if (onClickListener) { 39 if (onClickListener) {
39 this.leafletPoly.on('click', onClickListener); 40 this.leafletPoly.on('click', onClickListener);
@@ -44,11 +45,13 @@ export class Polygon { @@ -44,11 +45,13 @@ export class Polygon {
44 this.map.removeLayer(this.leafletPoly); 45 this.map.removeLayer(this.leafletPoly);
45 } 46 }
46 47
47 - updatePolygonColor(settings, color) {  
48 - const style = { 48 + updatePolygonColor(settings) {
  49 + console.log('Polygon -> updatePolygonColor -> settings', settings)
  50 + const style: L.PathOptions = {
  51 +
49 fill: true, 52 fill: true,
50 - fillColor: color,  
51 - color, 53 + fillColor: settings.color,
  54 + color: settings.color,
52 weight: settings.polygonStrokeWeight, 55 weight: settings.polygonStrokeWeight,
53 fillOpacity: settings.polygonOpacity, 56 fillOpacity: settings.polygonOpacity,
54 opacity: settings.polygonStrokeOpacity 57 opacity: settings.polygonStrokeOpacity
@@ -60,7 +63,7 @@ export class Polygon { @@ -60,7 +63,7 @@ export class Polygon {
60 return this.leafletPoly.getLatLngs(); 63 return this.leafletPoly.getLatLngs();
61 } 64 }
62 65
63 - setPolygonLatLngs(latLngs) { 66 + setPolygonLatLngs(latLngs: LatLngExpression[]) {
64 this.leafletPoly.setLatLngs(latLngs); 67 this.leafletPoly.setLatLngs(latLngs);
65 this.leafletPoly.redraw(); 68 this.leafletPoly.redraw();
66 } 69 }
@@ -18,51 +18,62 @@ import L, { PolylineDecoratorOptions } from 'leaflet'; @@ -18,51 +18,62 @@ import L, { PolylineDecoratorOptions } from 'leaflet';
18 import 'leaflet-polylinedecorator'; 18 import 'leaflet-polylinedecorator';
19 19
20 import { safeExecute } from '@app/core/utils'; 20 import { safeExecute } from '@app/core/utils';
  21 +import { PolylineSettings, PolygonSettings } from './map-models';
21 22
22 export class Polyline { 23 export class Polyline {
23 24
24 leafletPoly: L.Polyline; 25 leafletPoly: L.Polyline;
  26 + polylineDecorator: L.PolylineDecorator;
25 dataSources; 27 dataSources;
26 data; 28 data;
27 29
28 - constructor(private map: L.Map, locations, data, dataSources, settings) { 30 + constructor(private map: L.Map, locations, data, dataSources, settings: PolylineSettings) {
29 this.dataSources = dataSources; 31 this.dataSources = dataSources;
30 this.data = data; 32 this.data = data;
31 33
32 this.leafletPoly = L.polyline(locations, 34 this.leafletPoly = L.polyline(locations,
33 - this.getPolyStyle(settings, data, dataSources) 35 + this.getPolyStyle(settings)
34 ).addTo(this.map); 36 ).addTo(this.map);
35 if (settings.usePolylineDecorator) { 37 if (settings.usePolylineDecorator) {
36 - L.polylineDecorator(this.leafletPoly, {  
37 - patterns: [  
38 - {  
39 - offset: settings.decoratorOffset,  
40 - endOffset: settings.endDecoratorOffset,  
41 - repeat: settings.decoratorRepeat,  
42 - symbol: L.Symbol[settings.decoratorSymbol]({  
43 - pixelSize: settings.decoratorSymbolSize,  
44 - polygon: false,  
45 - pathOptions: {  
46 - color: settings.useDecoratorCustomColor ? settings.decoratorCustomColor : this.getPolyStyle(settings, data, dataSources).color,  
47 - stroke: true  
48 - }  
49 - })  
50 - }  
51 - ],  
52 - interactive: false,  
53 - } as PolylineDecoratorOptions).addTo(this.map); 38 + this.polylineDecorator = L.polylineDecorator(this.leafletPoly, this.getDecoratorSettings(settings)).addTo(this.map);
54 } 39 }
55 } 40 }
56 41
  42 + getDecoratorSettings(settings: PolylineSettings): PolylineDecoratorOptions {
  43 + return {
  44 + patterns: [
  45 + {
  46 + offset: settings.decoratorOffset,
  47 + endOffset: settings.endDecoratorOffset,
  48 + repeat: settings.decoratorRepeat,
  49 + symbol: L.Symbol[settings.decoratorSymbol]({
  50 + pixelSize: settings.decoratorSymbolSize,
  51 + polygon: false,
  52 + pathOptions: {
  53 + color: settings.useDecoratorCustomColor ? settings.decoratorCustomColor : this.getPolyStyle(settings).color,
  54 + stroke: true
  55 + }
  56 + })
  57 + }
  58 + ],
  59 + interactive: false,
  60 + } as PolylineDecoratorOptions
  61 + }
  62 +
57 updatePolyline(settings, data, dataSources) { 63 updatePolyline(settings, data, dataSources) {
58 - this.leafletPoly.setStyle(this.getPolyStyle(settings, data, dataSources)); 64 + this.leafletPoly.setStyle(this.getPolyStyle(settings));
  65 + this.setPolylineLatLngs(data);
  66 + this.polylineDecorator.setPaths(this.leafletPoly);
59 } 67 }
60 68
61 - getPolyStyle(settings, data, dataSources): L.PolylineOptions { 69 + getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
62 return { 70 return {
63 - color: settings.useColorFunction ? safeExecute(settings.colorFunction, [data, dataSources, data[0]?.dsIndex]) : settings.color,  
64 - opacity: settings.useStrokeOpacityFunction ? safeExecute(settings.strokeOpacityFunction, [data, dataSources, data[0]?.dsIndex]) : settings.strokeOpacity,  
65 - weight: settings.useStrokeWeightFunction ? safeExecute(settings.strokeWeightFunction, [data, dataSources, data[0]?.dsIndex]) : settings.strokeWeight, 71 + color: settings.useColorFunction ?
  72 + safeExecute(settings.colorFunction, [this.data, this.dataSources, this.data[0]?.dsIndex]) : settings.color,
  73 + opacity: settings.useStrokeOpacityFunction ?
  74 + safeExecute(settings.strokeOpacityFunction, [this.data, this.dataSources, this.data[0]?.dsIndex]) : settings.strokeOpacity,
  75 + weight: settings.useStrokeWeightFunction ?
  76 + safeExecute(settings.strokeWeightFunction, [this.data, this.dataSources, this.data[0]?.dsIndex]) : settings.strokeWeight,
66 } 77 }
67 } 78 }
68 79
@@ -17,14 +17,14 @@ @@ -17,14 +17,14 @@
17 17
18 import L from 'leaflet'; 18 import L from 'leaflet';
19 import LeafletMap from '../leaflet-map'; 19 import LeafletMap from '../leaflet-map';
20 -import { MapOptions } from '../map-models'; 20 +import { MapSettings, UnitedMapSettings } from '../map-models';
21 import 'leaflet.gridlayer.googlemutant'; 21 import 'leaflet.gridlayer.googlemutant';
22 22
23 let googleLoaded = false; 23 let googleLoaded = false;
24 24
25 25
26 export class GoogleMap extends LeafletMap { 26 export class GoogleMap extends LeafletMap {
27 - constructor($container, options: MapOptions) { 27 + constructor($container, options: UnitedMapSettings) {
28 28
29 super($container, options); 29 super($container, options);
30 this.loadGoogle(() => { 30 this.loadGoogle(() => {
@@ -16,11 +16,10 @@ @@ -16,11 +16,10 @@
16 16
17 import L from 'leaflet'; 17 import L from 'leaflet';
18 import LeafletMap from '../leaflet-map'; 18 import LeafletMap from '../leaflet-map';
19 -import { MapOptions } from '../map-models'; 19 +import { MapSettings, UnitedMapSettings } from '../map-models';
20 20
21 export class HEREMap extends LeafletMap { 21 export class HEREMap extends LeafletMap {
22 - constructor($container, options: MapOptions) {  
23 - console.log('HEREMap -> constructor -> options', options) 22 + constructor($container, options: UnitedMapSettings) {
24 const defaultCredentials = 23 const defaultCredentials =
25 { 24 {
26 app_id: 'AhM6TzD9ThyK78CT3ptx', 25 app_id: 'AhM6TzD9ThyK78CT3ptx',
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 16
17 import L from 'leaflet'; 17 import L from 'leaflet';
18 import LeafletMap from '../leaflet-map'; 18 import LeafletMap from '../leaflet-map';
19 -import { MapOptions } from '../map-models'; 19 +import { MapSettings, UnitedMapSettings } from '../map-models';
20 import { aspectCache } from '@app/core/utils'; 20 import { aspectCache } from '@app/core/utils';
21 21
22 const maxZoom = 4;// ? 22 const maxZoom = 4;// ?
@@ -28,7 +28,7 @@ export class ImageMap extends LeafletMap { @@ -28,7 +28,7 @@ export class ImageMap extends LeafletMap {
28 width = 0; 28 width = 0;
29 height = 0; 29 height = 0;
30 30
31 - constructor(private $container: HTMLElement, options: MapOptions) { 31 + constructor(private $container: HTMLElement, options: UnitedMapSettings) {
32 super($container, options); 32 super($container, options);
33 aspectCache(options.mapUrl).subscribe(aspect => { 33 aspectCache(options.mapUrl).subscribe(aspect => {
34 this.aspect = aspect; 34 this.aspect = aspect;
@@ -16,10 +16,10 @@ @@ -16,10 +16,10 @@
16 16
17 import L from 'leaflet'; 17 import L from 'leaflet';
18 import LeafletMap from '../leaflet-map'; 18 import LeafletMap from '../leaflet-map';
19 -import { MapOptions } from '../map-models'; 19 +import { MapSettings, UnitedMapSettings } from '../map-models';
20 20
21 export class OpenStreetMap extends LeafletMap { 21 export class OpenStreetMap extends LeafletMap {
22 - constructor($container, options: MapOptions) { 22 + constructor($container, options: UnitedMapSettings) {
23 super($container, options); 23 super($container, options);
24 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); 24 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
25 const tileLayer = (L.tileLayer as any).provider('OpenStreetMap.Mapnik'); 25 const tileLayer = (L.tileLayer as any).provider('OpenStreetMap.Mapnik');
@@ -17,10 +17,10 @@ @@ -17,10 +17,10 @@
17 17
18 import L from 'leaflet'; 18 import L from 'leaflet';
19 import LeafletMap from '../leaflet-map'; 19 import LeafletMap from '../leaflet-map';
20 -import { MapOptions } from '../map-models'; 20 +import { MapSettings, UnitedMapSettings } from '../map-models';
21 21
22 export class TencentMap extends LeafletMap { 22 export class TencentMap extends LeafletMap {
23 - constructor($container, options: MapOptions) { 23 + constructor($container, options: UnitedMapSettings) {
24 super($container, options); 24 super($container, options);
25 const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0'; 25 const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0';
26 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); 26 const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
@@ -97,7 +97,6 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -97,7 +97,6 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
97 timeUpdated(time: number) { 97 timeUpdated(time: number) {
98 const currentPosition = this.interpolatedData.map(dataSource => dataSource[time]); 98 const currentPosition = this.interpolatedData.map(dataSource => dataSource[time]);
99 this.activeTrip = currentPosition[0]; 99 this.activeTrip = currentPosition[0];
100 - console.log("TripAnimationComponent -> timeUpdated -> this.interpolatedData", this.interpolatedData)  
101 if (this.settings.showPolygon) { 100 if (this.settings.showPolygon) {
102 this.mapWidget.map.updatePolygons(this.interpolatedData); 101 this.mapWidget.map.updatePolygons(this.interpolatedData);
103 } 102 }
@@ -120,11 +119,11 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -120,11 +119,11 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
120 } 119 }
121 120
122 showHideTooltip() { 121 showHideTooltip() {
123 - const tooltipText: string = this.settings.useTooltipFunction ? safeExecute(this.settings.tooolTipFunction, [this.activeTrip, this.historicalData, 0]) 122 + const tooltipText: string = this.settings.useTooltipFunction ?
  123 + safeExecute(this.settings.tooolTipFunction, [this.activeTrip, this.historicalData, 0])
124 : this.settings.tooltipPattern; 124 : this.settings.tooltipPattern;
125 125
126 this.mainTooltip = this.sanitizer.sanitize(SecurityContext.HTML, parseTemplate(tooltipText, this.activeTrip)) 126 this.mainTooltip = this.sanitizer.sanitize(SecurityContext.HTML, parseTemplate(tooltipText, this.activeTrip))
127 - console.log("TripAnimationComponent -> showHideTooltip -> this.mainTooltip", this.mainTooltip)  
128 this.visibleTooltip = !this.visibleTooltip; 127 this.visibleTooltip = !this.visibleTooltip;
129 } 128 }
130 129
@@ -132,7 +131,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { @@ -132,7 +131,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
132 131
133 const result = {}; 132 const result = {};
134 133
135 - for (let i = 1, j = 0; i < originData.length, j < interpolatedIntervals.length;) { 134 + for (let i = 1, j = 0; i < originData.length && j < interpolatedIntervals.length;) {
136 const currentTime = interpolatedIntervals[j]; 135 const currentTime = interpolatedIntervals[j];
137 while (originData[i].time < currentTime) i++; 136 while (originData[i].time < currentTime) i++;
138 const before = originData[i - 1]; 137 const before = originData[i - 1];
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 import { Component, OnInit, OnChanges, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core'; 17 import { Component, OnInit, OnChanges, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
18 import { interval, Subscription, Subscriber, SubscriptionLike, Observer } from 'rxjs'; 18 import { interval, Subscription, Subscriber, SubscriptionLike, Observer } from 'rxjs';
19 import { filter, tap } from 'rxjs/operators'; 19 import { filter, tap } from 'rxjs/operators';
  20 +import { HistorySelectSettings } from '@app/modules/home/components/widget/lib/maps/map-models';
20 21
21 @Component({ 22 @Component({
22 selector: 'tb-history-selector', 23 selector: 'tb-history-selector',
@@ -25,10 +26,10 @@ import { filter, tap } from 'rxjs/operators'; @@ -25,10 +26,10 @@ import { filter, tap } from 'rxjs/operators';
25 }) 26 })
26 export class HistorySelectorComponent implements OnInit, OnChanges { 27 export class HistorySelectorComponent implements OnInit, OnChanges {
27 28
28 - @Input() settings 29 + @Input() settings: HistorySelectSettings
29 @Input() intervals = []; 30 @Input() intervals = [];
30 31
31 - @Output() onTimeUpdated: EventEmitter<number> = new EventEmitter(); 32 + @Output() timeUpdated: EventEmitter<number> = new EventEmitter();
32 33
33 animationTime; 34 animationTime;
34 minTimeIndex = 0; 35 minTimeIndex = 0;
@@ -58,7 +59,7 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -58,7 +59,7 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
58 tap(() => this.index++)).subscribe(() => { 59 tap(() => this.index++)).subscribe(() => {
59 if (this.index < this.maxTimeIndex) { 60 if (this.index < this.maxTimeIndex) {
60 this.cd.detectChanges(); 61 this.cd.detectChanges();
61 - this.onTimeUpdated.emit(this.intervals[this.index]); 62 + this.timeUpdated.emit(this.intervals[this.index]);
62 } 63 }
63 else { 64 else {
64 this.interval.complete(); 65 this.interval.complete();
@@ -70,12 +71,12 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -70,12 +71,12 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
70 this.playing = false; 71 this.playing = false;
71 this.interval = null; 72 this.interval = null;
72 this.cd.detectChanges(); 73 this.cd.detectChanges();
73 - }); 74 + });
74 } 75 }
75 76
76 reeneble() { 77 reeneble() {
77 if (this.playing) { 78 if (this.playing) {
78 - let position = this.index; 79 + const position = this.index;
79 this.interval.complete(); 80 this.interval.complete();
80 this.index = position; 81 this.index = position;
81 this.play(); 82 this.play();
@@ -85,7 +86,7 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -85,7 +86,7 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
85 pause() { 86 pause() {
86 this.playing = false; 87 this.playing = false;
87 this.cd.detectChanges(); 88 this.cd.detectChanges();
88 - this.onTimeUpdated.emit(this.intervals[this.index]); 89 + this.timeUpdated.emit(this.intervals[this.index]);
89 } 90 }
90 91
91 moveNext() { 92 moveNext() {
@@ -113,6 +114,6 @@ export class HistorySelectorComponent implements OnInit, OnChanges { @@ -113,6 +114,6 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
113 } 114 }
114 115
115 changeIndex() { 116 changeIndex() {
116 - this.onTimeUpdated.emit(this.intervals[this.index]); 117 + this.timeUpdated.emit(this.intervals[this.index]);
117 } 118 }
118 } 119 }