Commit 64ce9ba6e52557317eff516fd836701e40d19ad9
1 parent
d35d302a
Trip animation widget improvement:
-Added polygons -Included polygon tooltip functional(Standalone text)
Showing
4 changed files
with
762 additions
and
646 deletions
@@ -21,181 +21,181 @@ import tinycolor from "tinycolor2"; | @@ -21,181 +21,181 @@ import tinycolor from "tinycolor2"; | ||
21 | import {fillPatternWithActions, isNumber, padValue, processPattern} from "../widget-utils"; | 21 | import {fillPatternWithActions, isNumber, padValue, processPattern} from "../widget-utils"; |
22 | 22 | ||
23 | (function () { | 23 | (function () { |
24 | - // save these original methods before they are overwritten | ||
25 | - var proto_initIcon = L.Marker.prototype._initIcon; | ||
26 | - var proto_setPos = L.Marker.prototype._setPos; | ||
27 | - | ||
28 | - var oldIE = (L.DomUtil.TRANSFORM === 'msTransform'); | ||
29 | - | ||
30 | - L.Marker.addInitHook(function () { | ||
31 | - var iconOptions = this.options.icon && this.options.icon.options; | ||
32 | - var iconAnchor = iconOptions && this.options.icon.options.iconAnchor; | ||
33 | - if (iconAnchor) { | ||
34 | - iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px'); | ||
35 | - } | ||
36 | - this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom'; | ||
37 | - this.options.rotationAngle = this.options.rotationAngle || 0; | ||
38 | - | ||
39 | - // Ensure marker keeps rotated during dragging | ||
40 | - this.on('drag', function (e) { | ||
41 | - e.target._applyRotation(); | ||
42 | - }); | ||
43 | - }); | ||
44 | - | ||
45 | - L.Marker.include({ | ||
46 | - _initIcon: function () { | ||
47 | - proto_initIcon.call(this); | ||
48 | - }, | ||
49 | - | ||
50 | - _setPos: function (pos) { | ||
51 | - proto_setPos.call(this, pos); | ||
52 | - this._applyRotation(); | ||
53 | - }, | ||
54 | - | ||
55 | - _applyRotation: function () { | ||
56 | - if (this.options.rotationAngle) { | ||
57 | - this._icon.style[L.DomUtil.TRANSFORM + 'Origin'] = this.options.rotationOrigin; | ||
58 | - | ||
59 | - if (oldIE) { | ||
60 | - // for IE 9, use the 2D rotation | ||
61 | - this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)'; | ||
62 | - } else { | ||
63 | - // for modern browsers, prefer the 3D accelerated version | ||
64 | - let rotation = ' rotateZ(' + this.options.rotationAngle + 'deg)'; | ||
65 | - if (!this._icon.style[L.DomUtil.TRANSFORM].includes(rotation)) { | ||
66 | - this._icon.style[L.DomUtil.TRANSFORM] += rotation; | ||
67 | - } | ||
68 | - } | ||
69 | - } | ||
70 | - }, | ||
71 | - | ||
72 | - setRotationAngle: function (angle) { | ||
73 | - this.options.rotationAngle = angle; | ||
74 | - this.update(); | ||
75 | - return this; | ||
76 | - }, | ||
77 | - | ||
78 | - setRotationOrigin: function (origin) { | ||
79 | - this.options.rotationOrigin = origin; | ||
80 | - this.update(); | ||
81 | - return this; | ||
82 | - } | ||
83 | - }); | 24 | + // save these original methods before they are overwritten |
25 | + var proto_initIcon = L.Marker.prototype._initIcon; | ||
26 | + var proto_setPos = L.Marker.prototype._setPos; | ||
27 | + | ||
28 | + var oldIE = (L.DomUtil.TRANSFORM === 'msTransform'); | ||
29 | + | ||
30 | + L.Marker.addInitHook(function () { | ||
31 | + var iconOptions = this.options.icon && this.options.icon.options; | ||
32 | + var iconAnchor = iconOptions && this.options.icon.options.iconAnchor; | ||
33 | + if (iconAnchor) { | ||
34 | + iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px'); | ||
35 | + } | ||
36 | + this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom'; | ||
37 | + this.options.rotationAngle = this.options.rotationAngle || 0; | ||
38 | + | ||
39 | + // Ensure marker keeps rotated during dragging | ||
40 | + this.on('drag', function (e) { | ||
41 | + e.target._applyRotation(); | ||
42 | + }); | ||
43 | + }); | ||
44 | + | ||
45 | + L.Marker.include({ | ||
46 | + _initIcon: function () { | ||
47 | + proto_initIcon.call(this); | ||
48 | + }, | ||
49 | + | ||
50 | + _setPos: function (pos) { | ||
51 | + proto_setPos.call(this, pos); | ||
52 | + this._applyRotation(); | ||
53 | + }, | ||
54 | + | ||
55 | + _applyRotation: function () { | ||
56 | + if (this.options.rotationAngle) { | ||
57 | + this._icon.style[L.DomUtil.TRANSFORM + 'Origin'] = this.options.rotationOrigin; | ||
58 | + | ||
59 | + if (oldIE) { | ||
60 | + // for IE 9, use the 2D rotation | ||
61 | + this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)'; | ||
62 | + } else { | ||
63 | + // for modern browsers, prefer the 3D accelerated version | ||
64 | + let rotation = ' rotateZ(' + this.options.rotationAngle + 'deg)'; | ||
65 | + if (!this._icon.style[L.DomUtil.TRANSFORM].includes(rotation)) { | ||
66 | + this._icon.style[L.DomUtil.TRANSFORM] += rotation; | ||
67 | + } | ||
68 | + } | ||
69 | + } | ||
70 | + }, | ||
71 | + | ||
72 | + setRotationAngle: function (angle) { | ||
73 | + this.options.rotationAngle = angle; | ||
74 | + this.update(); | ||
75 | + return this; | ||
76 | + }, | ||
77 | + | ||
78 | + setRotationOrigin: function (origin) { | ||
79 | + this.options.rotationOrigin = origin; | ||
80 | + this.update(); | ||
81 | + return this; | ||
82 | + } | ||
83 | + }); | ||
84 | })(); | 84 | })(); |
85 | 85 | ||
86 | 86 | ||
87 | export default angular.module('thingsboard.widgets.tripAnimation', []) | 87 | export default angular.module('thingsboard.widgets.tripAnimation', []) |
88 | - .directive('tripAnimation', tripAnimationWidget) | ||
89 | - .filter('tripAnimation', function ($filter) { | ||
90 | - return function (label) { | ||
91 | - label = label.toString(); | 88 | + .directive('tripAnimation', tripAnimationWidget) |
89 | + .filter('tripAnimation', function ($filter) { | ||
90 | + return function (label) { | ||
91 | + label = label.toString(); | ||
92 | 92 | ||
93 | - let translateSelector = "widgets.tripAnimation." + label; | ||
94 | - let translation = $filter('translate')(translateSelector); | 93 | + let translateSelector = "widgets.tripAnimation." + label; |
94 | + let translation = $filter('translate')(translateSelector); | ||
95 | 95 | ||
96 | - if (translation !== translateSelector) { | ||
97 | - return translation; | ||
98 | - } | 96 | + if (translation !== translateSelector) { |
97 | + return translation; | ||
98 | + } | ||
99 | 99 | ||
100 | - return label; | ||
101 | - } | ||
102 | - }) | ||
103 | - .name; | 100 | + return label; |
101 | + } | ||
102 | + }) | ||
103 | + .name; | ||
104 | 104 | ||
105 | 105 | ||
106 | /*@ngInject*/ | 106 | /*@ngInject*/ |
107 | function tripAnimationWidget() { | 107 | function tripAnimationWidget() { |
108 | - return { | ||
109 | - restrict: "E", | ||
110 | - scope: true, | ||
111 | - bindToController: { | ||
112 | - ctx: '=', | ||
113 | - self: '=' | ||
114 | - }, | ||
115 | - controller: tripAnimationController, | ||
116 | - controllerAs: 'vm', | ||
117 | - templateUrl: template | ||
118 | - }; | 108 | + return { |
109 | + restrict: "E", | ||
110 | + scope: true, | ||
111 | + bindToController: { | ||
112 | + ctx: '=', | ||
113 | + self: '=' | ||
114 | + }, | ||
115 | + controller: tripAnimationController, | ||
116 | + controllerAs: 'vm', | ||
117 | + templateUrl: template | ||
118 | + }; | ||
119 | } | 119 | } |
120 | 120 | ||
121 | /*@ngInject*/ | 121 | /*@ngInject*/ |
122 | -function tripAnimationController($document, $scope, $http, $timeout, $filter, $sce) { | ||
123 | - let vm = this; | ||
124 | - | ||
125 | - vm.initBounds = true; | ||
126 | - | ||
127 | - vm.markers = []; | ||
128 | - vm.index = 0; | ||
129 | - vm.dsIndex = 0; | ||
130 | - vm.minTime = 0; | ||
131 | - vm.maxTime = 0; | ||
132 | - vm.isPlaying = false; | ||
133 | - vm.trackingLine = { | ||
134 | - "type": "FeatureCollection", | ||
135 | - features: [] | ||
136 | - }; | ||
137 | - vm.speeds = [1, 5, 10, 25]; | ||
138 | - vm.speed = 1; | ||
139 | - vm.trips = []; | ||
140 | - vm.activeTripIndex = 0; | ||
141 | - | ||
142 | - vm.showHideTooltip = showHideTooltip; | ||
143 | - vm.recalculateTrips = recalculateTrips; | ||
144 | - | ||
145 | - $scope.$watch('vm.ctx', function () { | ||
146 | - if (vm.ctx) { | ||
147 | - vm.utils = vm.ctx.$scope.$injector.get('utils'); | ||
148 | - vm.settings = vm.ctx.settings; | ||
149 | - vm.widgetConfig = vm.ctx.widgetConfig; | ||
150 | - vm.data = vm.ctx.data; | ||
151 | - vm.datasources = vm.ctx.datasources; | ||
152 | - configureStaticSettings(); | ||
153 | - initialize(); | ||
154 | - initializeCallbacks(); | ||
155 | - } | ||
156 | - }); | ||
157 | - | ||
158 | - | ||
159 | - function initializeCallbacks() { | ||
160 | - vm.self.onDataUpdated = function () { | ||
161 | - createUpdatePath(true); | ||
162 | - }; | ||
163 | - | ||
164 | - vm.self.onResize = function () { | ||
165 | - resize(); | ||
166 | - }; | ||
167 | - | ||
168 | - vm.self.typeParameters = function () { | ||
169 | - return { | ||
170 | - maxDatasources: 1, // Maximum allowed datasources for this widget, -1 - unlimited | ||
171 | - maxDataKeys: -1 //Maximum allowed data keys for this widget, -1 - unlimited | ||
172 | - } | ||
173 | - }; | ||
174 | - return true; | ||
175 | - } | ||
176 | - | ||
177 | - | ||
178 | - function resize() { | ||
179 | - if (vm.map) { | ||
180 | - vm.map.invalidateSize(); | ||
181 | - } | ||
182 | - } | ||
183 | - | ||
184 | - function initCallback() { | ||
185 | - //createUpdatePath(); | ||
186 | - //resize(); | ||
187 | - } | ||
188 | - | ||
189 | - vm.playMove = function (play) { | ||
190 | - if (play && vm.isPlaying) return; | ||
191 | - if (play || vm.isPlaying) vm.isPlaying = true; | ||
192 | - if (vm.isPlaying) { | 122 | +function tripAnimationController($document, $scope, $log, $http, $timeout, $filter, $sce) { |
123 | + let vm = this; | ||
124 | + | ||
125 | + vm.initBounds = true; | ||
126 | + | ||
127 | + vm.markers = []; | ||
128 | + vm.index = 0; | ||
129 | + vm.dsIndex = 0; | ||
130 | + vm.minTime = 0; | ||
131 | + vm.maxTime = 0; | ||
132 | + vm.isPlaying = false; | ||
133 | + vm.trackingLine = { | ||
134 | + "type": "FeatureCollection", | ||
135 | + features: [] | ||
136 | + }; | ||
137 | + vm.speeds = [1, 5, 10, 25]; | ||
138 | + vm.speed = 1; | ||
139 | + vm.trips = []; | ||
140 | + vm.activeTripIndex = 0; | ||
141 | + | ||
142 | + vm.showHideTooltip = showHideTooltip; | ||
143 | + vm.recalculateTrips = recalculateTrips; | ||
144 | + | ||
145 | + $scope.$watch('vm.ctx', function () { | ||
146 | + if (vm.ctx) { | ||
147 | + vm.utils = vm.ctx.$scope.$injector.get('utils'); | ||
148 | + vm.settings = vm.ctx.settings; | ||
149 | + vm.widgetConfig = vm.ctx.widgetConfig; | ||
150 | + vm.data = vm.ctx.data; | ||
151 | + vm.datasources = vm.ctx.datasources; | ||
152 | + configureStaticSettings(); | ||
153 | + initialize(); | ||
154 | + initializeCallbacks(); | ||
155 | + } | ||
156 | + }); | ||
157 | + | ||
158 | + | ||
159 | + function initializeCallbacks() { | ||
160 | + vm.self.onDataUpdated = function () { | ||
161 | + createUpdatePath(true); | ||
162 | + }; | ||
163 | + | ||
164 | + vm.self.onResize = function () { | ||
165 | + resize(); | ||
166 | + }; | ||
167 | + | ||
168 | + vm.self.typeParameters = function () { | ||
169 | + return { | ||
170 | + maxDatasources: 1, // Maximum allowed datasources for this widget, -1 - unlimited | ||
171 | + maxDataKeys: -1 //Maximum allowed data keys for this widget, -1 - unlimited | ||
172 | + } | ||
173 | + }; | ||
174 | + return true; | ||
175 | + } | ||
176 | + | ||
177 | + | ||
178 | + function resize() { | ||
179 | + if (vm.map) { | ||
180 | + vm.map.invalidateSize(); | ||
181 | + } | ||
182 | + } | ||
183 | + | ||
184 | + function initCallback() { | ||
185 | + //createUpdatePath(); | ||
186 | + //resize(); | ||
187 | + } | ||
188 | + | ||
189 | + vm.playMove = function (play) { | ||
190 | + if (play && vm.isPlaying) return; | ||
191 | + if (play || vm.isPlaying) vm.isPlaying = true; | ||
192 | + if (vm.isPlaying) { | ||
193 | moveInc(1); | 193 | moveInc(1); |
194 | - vm.timeout = $timeout(function () { | ||
195 | - vm.playMove(); | ||
196 | - }, 1000 / vm.speed) | ||
197 | - } | ||
198 | - }; | 194 | + vm.timeout = $timeout(function () { |
195 | + vm.playMove(); | ||
196 | + }, 1000 / vm.speed) | ||
197 | + } | ||
198 | + }; | ||
199 | 199 | ||
200 | vm.moveNext = function () { | 200 | vm.moveNext = function () { |
201 | vm.stopPlay(); | 201 | vm.stopPlay(); |
@@ -217,12 +217,12 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | @@ -217,12 +217,12 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | ||
217 | moveToIndex(vm.maxTime); | 217 | moveToIndex(vm.maxTime); |
218 | } | 218 | } |
219 | 219 | ||
220 | - vm.stopPlay = function () { | 220 | + vm.stopPlay = function () { |
221 | if (vm.isPlaying) { | 221 | if (vm.isPlaying) { |
222 | vm.isPlaying = false; | 222 | vm.isPlaying = false; |
223 | $timeout.cancel(vm.timeout); | 223 | $timeout.cancel(vm.timeout); |
224 | } | 224 | } |
225 | - }; | 225 | + }; |
226 | 226 | ||
227 | function moveInc(inc) { | 227 | function moveInc(inc) { |
228 | let newIndex = vm.index + inc; | 228 | let newIndex = vm.index + inc; |
@@ -235,436 +235,504 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | @@ -235,436 +235,504 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | ||
235 | recalculateTrips(); | 235 | recalculateTrips(); |
236 | } | 236 | } |
237 | 237 | ||
238 | - function recalculateTrips() { | ||
239 | - vm.trips.forEach(function (value) { | ||
240 | - moveMarker(value); | ||
241 | - }) | ||
242 | - } | ||
243 | - | ||
244 | - function findAngle(lat1, lng1, lat2, lng2) { | ||
245 | - let angle = Math.atan2(0, 0) - Math.atan2(lat2 - lat1, lng2 - lng1); | ||
246 | - angle = angle * 180 / Math.PI; | ||
247 | - return parseInt(angle.toFixed(2)); | ||
248 | - } | ||
249 | - | ||
250 | - function initialize() { | ||
251 | - $scope.currentDate = $filter('date')(0, "yyyy.MM.dd HH:mm:ss"); | ||
252 | - | ||
253 | - vm.self.actionSources = [vm.searchAction]; | ||
254 | - vm.endpoint = vm.ctx.settings.endpointUrl; | ||
255 | - $scope.title = vm.ctx.widgetConfig.title; | ||
256 | - vm.utils = vm.self.ctx.$scope.$injector.get('utils'); | ||
257 | - | ||
258 | - vm.showTimestamp = vm.settings.showTimestamp !== false; | ||
259 | - vm.ctx.$element = angular.element("#trip-animation-map", vm.ctx.$container); | ||
260 | - vm.defaultZoomLevel = 2; | ||
261 | - if (vm.ctx.settings.defaultZoomLevel) { | ||
262 | - if (vm.ctx.settings.defaultZoomLevel > 0 && vm.ctx.settings.defaultZoomLevel < 21) { | ||
263 | - vm.defaultZoomLevel = Math.floor(vm.ctx.settings.defaultZoomLevel); | ||
264 | - } | ||
265 | - } | ||
266 | - vm.dontFitMapBounds = vm.ctx.settings.fitMapBounds === false; | ||
267 | - vm.map = new TbOpenStreetMap(vm.ctx.$element, vm.utils, initCallback, vm.defaultZoomLevel, vm.dontFitMapBounds, null, vm.staticSettings.mapProvider); | ||
268 | - vm.map.bounds = vm.map.createBounds(); | ||
269 | - vm.map.invalidateSize(true); | ||
270 | - vm.map.bounds = vm.map.createBounds(); | ||
271 | - | ||
272 | - vm.tooltipActionsMap = {}; | ||
273 | - var descriptors = vm.ctx.actionsApi.getActionDescriptors('tooltipAction'); | ||
274 | - descriptors.forEach(function (descriptor) { | ||
275 | - if (descriptor) vm.tooltipActionsMap[descriptor.name] = descriptor; | ||
276 | - }); | ||
277 | - } | ||
278 | - | ||
279 | - function configureStaticSettings() { | ||
280 | - let staticSettings = {}; | ||
281 | - vm.staticSettings = staticSettings; | ||
282 | - //Calculate General Settings | 238 | + function recalculateTrips() { |
239 | + vm.trips.forEach(function (value) { | ||
240 | + moveMarker(value); | ||
241 | + }) | ||
242 | + } | ||
243 | + | ||
244 | + function findAngle(lat1, lng1, lat2, lng2) { | ||
245 | + let angle = Math.atan2(0, 0) - Math.atan2(lat2 - lat1, lng2 - lng1); | ||
246 | + angle = angle * 180 / Math.PI; | ||
247 | + return parseInt(angle.toFixed(2)); | ||
248 | + } | ||
249 | + | ||
250 | + function initialize() { | ||
251 | + $scope.currentDate = $filter('date')(0, "yyyy.MM.dd HH:mm:ss"); | ||
252 | + | ||
253 | + vm.self.actionSources = [vm.searchAction]; | ||
254 | + vm.endpoint = vm.ctx.settings.endpointUrl; | ||
255 | + $scope.title = vm.ctx.widgetConfig.title; | ||
256 | + vm.utils = vm.self.ctx.$scope.$injector.get('utils'); | ||
257 | + | ||
258 | + vm.showTimestamp = vm.settings.showTimestamp !== false; | ||
259 | + vm.ctx.$element = angular.element("#trip-animation-map", vm.ctx.$container); | ||
260 | + vm.defaultZoomLevel = 2; | ||
261 | + if (vm.ctx.settings.defaultZoomLevel) { | ||
262 | + if (vm.ctx.settings.defaultZoomLevel > 0 && vm.ctx.settings.defaultZoomLevel < 21) { | ||
263 | + vm.defaultZoomLevel = Math.floor(vm.ctx.settings.defaultZoomLevel); | ||
264 | + } | ||
265 | + } | ||
266 | + vm.dontFitMapBounds = vm.ctx.settings.fitMapBounds === false; | ||
267 | + vm.map = new TbOpenStreetMap(vm.ctx.$element, vm.utils, initCallback, vm.defaultZoomLevel, vm.dontFitMapBounds, null, vm.staticSettings.mapProvider); | ||
268 | + vm.map.bounds = vm.map.createBounds(); | ||
269 | + vm.map.invalidateSize(true); | ||
270 | + vm.map.bounds = vm.map.createBounds(); | ||
271 | + | ||
272 | + vm.tooltipActionsMap = {}; | ||
273 | + var descriptors = vm.ctx.actionsApi.getActionDescriptors('tooltipAction'); | ||
274 | + descriptors.forEach(function (descriptor) { | ||
275 | + if (descriptor) vm.tooltipActionsMap[descriptor.name] = descriptor; | ||
276 | + }); | ||
277 | + } | ||
278 | + | ||
279 | + function configureStaticSettings() { | ||
280 | + let staticSettings = {}; | ||
281 | + vm.staticSettings = staticSettings; | ||
282 | + //Calculate General Settings | ||
283 | staticSettings.buttonColor = tinycolor(vm.widgetConfig.color).setAlpha(0.54).toRgbString(); | 283 | staticSettings.buttonColor = tinycolor(vm.widgetConfig.color).setAlpha(0.54).toRgbString(); |
284 | staticSettings.disabledButtonColor = tinycolor(vm.widgetConfig.color).setAlpha(0.3).toRgbString(); | 284 | staticSettings.disabledButtonColor = tinycolor(vm.widgetConfig.color).setAlpha(0.3).toRgbString(); |
285 | - staticSettings.mapProvider = vm.ctx.settings.mapProvider || "OpenStreetMap.Mapnik"; | ||
286 | - staticSettings.latKeyName = vm.ctx.settings.latKeyName || "latitude"; | ||
287 | - staticSettings.lngKeyName = vm.ctx.settings.lngKeyName || "longitude"; | ||
288 | - staticSettings.rotationAngle = vm.ctx.settings.rotationAngle || 0; | ||
289 | - staticSettings.displayTooltip = vm.ctx.settings.showTooltip || false; | ||
290 | - staticSettings.defaultZoomLevel = vm.ctx.settings.defaultZoomLevel || true; | ||
291 | - staticSettings.showTooltip = false; | ||
292 | - staticSettings.label = vm.ctx.settings.label || "${entityName}"; | ||
293 | - staticSettings.useLabelFunction = vm.ctx.settings.useLabelFunction || false; | ||
294 | - staticSettings.showLabel = vm.ctx.settings.showLabel || false; | ||
295 | - staticSettings.useTooltipFunction = vm.ctx.settings.useTooltipFunction || false; | ||
296 | - staticSettings.tooltipPattern = vm.ctx.settings.tooltipPattern || "<span style=\"font-size: 26px; color: #666; font-weight: bold;\">${entityName}</span>\n" + | 285 | + staticSettings.polygonColor = tinycolor(vm.ctx.settings.polygonColor).toHexString(); |
286 | + staticSettings.polygonStrokeColor = tinycolor(vm.ctx.settings.polygonStrokeColor).toHexString(); | ||
287 | + staticSettings.mapProvider = vm.ctx.settings.mapProvider || "OpenStreetMap.Mapnik"; | ||
288 | + staticSettings.latKeyName = vm.ctx.settings.latKeyName || "latitude"; | ||
289 | + staticSettings.lngKeyName = vm.ctx.settings.lngKeyName || "longitude"; | ||
290 | + staticSettings.polKeyName = vm.ctx.settings.polKeyName || "coordinates"; | ||
291 | + staticSettings.rotationAngle = vm.ctx.settings.rotationAngle || 0; | ||
292 | + staticSettings.polygonOpacity = vm.ctx.settings.polygonOpacity || 0.5; | ||
293 | + staticSettings.polygonStrokeOpacity = vm.ctx.settings.polygonStrokeOpacity || 1; | ||
294 | + staticSettings.polygonStrokeWeight = vm.ctx.settings.polygonStrokeWeight || 1; | ||
295 | + staticSettings.showPolygon = vm.ctx.settings.showPolygon || false; | ||
296 | + staticSettings.usePolygonColorFunction = vm.ctx.settings.usePolygonColorFunction || false; | ||
297 | + staticSettings.usePolygonTooltipFunction = vm.ctx.settings.usePolygonTooltipFunction || false; | ||
298 | + staticSettings.displayTooltip = vm.ctx.settings.showTooltip || false; | ||
299 | + staticSettings.defaultZoomLevel = vm.ctx.settings.defaultZoomLevel || true; | ||
300 | + staticSettings.showTooltip = false; | ||
301 | + staticSettings.label = vm.ctx.settings.label || "${entityName}"; | ||
302 | + staticSettings.useLabelFunction = vm.ctx.settings.useLabelFunction || false; | ||
303 | + staticSettings.showLabel = vm.ctx.settings.showLabel || false; | ||
304 | + staticSettings.useTooltipFunction = vm.ctx.settings.useTooltipFunction || false; | ||
305 | + staticSettings.tooltipPattern = vm.ctx.settings.tooltipPattern || "<span style=\"font-size: 26px; color: #666; font-weight: bold;\">${entityName}</span>\n" + | ||
297 | "<br/>\n" + | 306 | "<br/>\n" + |
298 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Time:</span><span style=\"font-size: 12px;\"> ${formattedTs}</span>\n" + | 307 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Time:</span><span style=\"font-size: 12px;\"> ${formattedTs}</span>\n" + |
299 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Latitude:</span> ${latitude:7}\n" + | 308 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Latitude:</span> ${latitude:7}\n" + |
300 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Longitude:</span> ${longitude:7}"; | 309 | "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Longitude:</span> ${longitude:7}"; |
301 | - staticSettings.tooltipOpacity = angular.isNumber(vm.ctx.settings.tooltipOpacity) ? vm.ctx.settings.tooltipOpacity : 1; | ||
302 | - staticSettings.tooltipColor = vm.ctx.settings.tooltipColor ? tinycolor(vm.ctx.settings.tooltipColor).toRgbString() : "#ffffff"; | ||
303 | - staticSettings.tooltipFontColor = vm.ctx.settings.tooltipFontColor ? tinycolor(vm.ctx.settings.tooltipFontColor).toRgbString() : "#000000"; | ||
304 | - staticSettings.pathColor = vm.ctx.settings.color ? tinycolor(vm.ctx.settings.color).toHexString() : "#ff6300"; | ||
305 | - staticSettings.pathWeight = vm.ctx.settings.strokeWeight || 1; | ||
306 | - staticSettings.pathOpacity = vm.ctx.settings.strokeOpacity || 1; | ||
307 | - staticSettings.usePathColorFunction = vm.ctx.settings.useColorFunction || false; | ||
308 | - staticSettings.showPoints = vm.ctx.settings.showPoints || false; | ||
309 | - staticSettings.pointSize = vm.ctx.settings.pointSize || 1; | ||
310 | - staticSettings.markerImageSize = vm.ctx.settings.markerImageSize || 20; | ||
311 | - staticSettings.useMarkerImageFunction = vm.ctx.settings.useMarkerImageFunction || false; | ||
312 | - staticSettings.pointColor = vm.ctx.settings.pointColor ? tinycolor(vm.ctx.settings.pointColor).toHexString() : "#ff6300"; | ||
313 | - staticSettings.markerImages = vm.ctx.settings.markerImages || []; | ||
314 | - staticSettings.icon = L.icon({ | ||
315 | - iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAACqCAYAAAA9dtSCAAAAhnpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjadY7LDcAwCEPvTNERCBA+40RVI3WDjl+iNMqp7wCWBZbheu4Ox6AggVRzDVVMJCSopXCcMGIhLGPnnHybSyraNjBNoeGGsg/l8xeV1bWbmGnVU0/KdLqY2HPmH4xUHDVih7S2Gv34q8ULVzos2Vmq5r4AAAoGaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iMTcwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTcwIgogICB0aWZmOkltYWdlV2lkdGg9IjE3MCIKICAgdGlmZjpJbWFnZUhlaWdodD0iMTcwIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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", | ||
316 | - iconSize: [30, 30], | ||
317 | - iconAnchor: [15, 15] | ||
318 | - }); | ||
319 | - if (angular.isDefined(vm.ctx.settings.markerImage)) { | ||
320 | - staticSettings.icon = L.icon({ | ||
321 | - iconUrl: vm.ctx.settings.markerImage, | ||
322 | - iconSize: [staticSettings.markerImageSize, staticSettings.markerImageSize], | ||
323 | - iconAnchor: [(staticSettings.markerImageSize / 2), (staticSettings.markerImageSize / 2)] | ||
324 | - }) | ||
325 | - } | ||
326 | - | ||
327 | - if (staticSettings.usePathColorFunction && angular.isDefined(vm.ctx.settings.colorFunction)) { | ||
328 | - staticSettings.colorFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.colorFunction); | ||
329 | - } | ||
330 | - | ||
331 | - if (staticSettings.useLabelFunction && angular.isDefined(vm.ctx.settings.labelFunction)) { | ||
332 | - staticSettings.labelFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.labelFunction); | ||
333 | - } | ||
334 | - | ||
335 | - if (staticSettings.useTooltipFunction && angular.isDefined(vm.ctx.settings.tooltipFunction)) { | ||
336 | - staticSettings.tooltipFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.tooltipFunction); | ||
337 | - } | ||
338 | - | ||
339 | - if (staticSettings.useMarkerImageFunction && angular.isDefined(vm.ctx.settings.markerImageFunction)) { | ||
340 | - staticSettings.markerImageFunction = new Function('data, images, dsData, dsIndex', vm.ctx.settings.markerImageFunction); | ||
341 | - } | ||
342 | - | ||
343 | - if (!staticSettings.useMarkerImageFunction && | ||
344 | - angular.isDefined(vm.ctx.settings.markerImage) && | ||
345 | - vm.ctx.settings.markerImage.length > 0) { | ||
346 | - staticSettings.useMarkerImage = true; | ||
347 | - let url = vm.ctx.settings.markerImage; | ||
348 | - let size = staticSettings.markerImageSize || 20; | ||
349 | - staticSettings.currentImage = { | ||
350 | - url: url, | ||
351 | - size: size | ||
352 | - }; | ||
353 | - vm.utils.loadImageAspect(staticSettings.currentImage.url).then( | ||
354 | - (aspect) => { | ||
355 | - if (aspect) { | ||
356 | - let width; | ||
357 | - let height; | ||
358 | - if (aspect > 1) { | ||
359 | - width = staticSettings.currentImage.size; | ||
360 | - height = staticSettings.currentImage.size / aspect; | ||
361 | - } else { | ||
362 | - width = staticSettings.currentImage.size * aspect; | ||
363 | - height = staticSettings.currentImage.size; | ||
364 | - } | ||
365 | - staticSettings.icon = L.icon({ | ||
366 | - iconUrl: staticSettings.currentImage.url, | ||
367 | - iconSize: [width, height], | ||
368 | - iconAnchor: [width / 2, height / 2] | ||
369 | - }); | ||
370 | - } | ||
371 | - if (vm.trips) { | ||
372 | - vm.trips.forEach(function (trip) { | ||
373 | - if (trip.marker) { | ||
374 | - trip.marker.setIcon(staticSettings.icon); | ||
375 | - } | ||
376 | - }); | ||
377 | - } | ||
378 | - } | ||
379 | - ) | ||
380 | - } | ||
381 | - } | ||
382 | - | ||
383 | - function configureTripSettings(trip, index, apply) { | ||
384 | - trip.settings = {}; | ||
385 | - trip.settings.color = calculateColor(trip); | ||
386 | - trip.settings.strokeWeight = vm.staticSettings.pathWeight; | ||
387 | - trip.settings.strokeOpacity = vm.staticSettings.pathOpacity; | ||
388 | - trip.settings.pointColor = vm.staticSettings.pointColor; | ||
389 | - trip.settings.pointSize = vm.staticSettings.pointSize; | ||
390 | - trip.settings.icon = calculateIcon(trip); | ||
391 | - if (apply) { | 310 | + staticSettings.polygonTooltipPattern = vm.ctx.settings.polygonTooltipPattern || "<span style=\"font-size: 26px; color: #666; font-weight: bold;\">${entityName}</span>\n" + |
311 | + "<br/>\n" + | ||
312 | + "<span style=\"font-size: 12px; color: #666; font-weight: bold;\">Time:</span><span style=\"font-size: 12px;\"> ${formattedTs}</span>\n"; | ||
313 | + staticSettings.tooltipOpacity = angular.isNumber(vm.ctx.settings.tooltipOpacity) ? vm.ctx.settings.tooltipOpacity : 1; | ||
314 | + staticSettings.tooltipColor = vm.ctx.settings.tooltipColor ? tinycolor(vm.ctx.settings.tooltipColor).toRgbString() : "#ffffff"; | ||
315 | + staticSettings.tooltipFontColor = vm.ctx.settings.tooltipFontColor ? tinycolor(vm.ctx.settings.tooltipFontColor).toRgbString() : "#000000"; | ||
316 | + staticSettings.pathColor = vm.ctx.settings.color ? tinycolor(vm.ctx.settings.color).toHexString() : "#ff6300"; | ||
317 | + staticSettings.pathWeight = vm.ctx.settings.strokeWeight || 1; | ||
318 | + staticSettings.pathOpacity = vm.ctx.settings.strokeOpacity || 1; | ||
319 | + staticSettings.usePathColorFunction = vm.ctx.settings.useColorFunction || false; | ||
320 | + staticSettings.showPoints = vm.ctx.settings.showPoints || false; | ||
321 | + staticSettings.pointSize = vm.ctx.settings.pointSize || 1; | ||
322 | + staticSettings.markerImageSize = vm.ctx.settings.markerImageSize || 20; | ||
323 | + staticSettings.useMarkerImageFunction = vm.ctx.settings.useMarkerImageFunction || false; | ||
324 | + staticSettings.pointColor = vm.ctx.settings.pointColor ? tinycolor(vm.ctx.settings.pointColor).toHexString() : "#ff6300"; | ||
325 | + staticSettings.markerImages = vm.ctx.settings.markerImages || []; | ||
326 | + staticSettings.icon = L.icon({ | ||
327 | + iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAACqCAYAAAA9dtSCAAAAhnpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjadY7LDcAwCEPvTNERCBA+40RVI3WDjl+iNMqp7wCWBZbheu4Ox6AggVRzDVVMJCSopXCcMGIhLGPnnHybSyraNjBNoeGGsg/l8xeV1bWbmGnVU0/KdLqY2HPmH4xUHDVih7S2Gv34q8ULVzos2Vmq5r4AAAoGaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iMTcwIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTcwIgogICB0aWZmOkltYWdlV2lkdGg9IjE3MCIKICAgdGlmZjpJbWFnZUhlaWdodD0iMTcwIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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", | ||
328 | + iconSize: [30, 30], | ||
329 | + iconAnchor: [15, 15] | ||
330 | + }); | ||
331 | + if (angular.isDefined(vm.ctx.settings.markerImage)) { | ||
332 | + staticSettings.icon = L.icon({ | ||
333 | + iconUrl: vm.ctx.settings.markerImage, | ||
334 | + iconSize: [staticSettings.markerImageSize, staticSettings.markerImageSize], | ||
335 | + iconAnchor: [(staticSettings.markerImageSize / 2), (staticSettings.markerImageSize / 2)] | ||
336 | + }) | ||
337 | + } | ||
338 | + | ||
339 | + if (staticSettings.usePathColorFunction && angular.isDefined(vm.ctx.settings.colorFunction)) { | ||
340 | + staticSettings.colorFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.colorFunction); | ||
341 | + } | ||
342 | + | ||
343 | + if (staticSettings.usePolygonTooltipFunction && angular.isDefined(vm.ctx.settings.polygonTooltipFunction)) { | ||
344 | + staticSettings.polygonTooltipFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.polygonTooltipFunction); | ||
345 | + } | ||
346 | + | ||
347 | + if (staticSettings.useLabelFunction && angular.isDefined(vm.ctx.settings.labelFunction)) { | ||
348 | + staticSettings.labelFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.labelFunction); | ||
349 | + } | ||
350 | + | ||
351 | + if (staticSettings.useTooltipFunction && angular.isDefined(vm.ctx.settings.tooltipFunction)) { | ||
352 | + staticSettings.tooltipFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.tooltipFunction); | ||
353 | + } | ||
354 | + | ||
355 | + if (staticSettings.usePolygonColorFunction && angular.isDefined(vm.ctx.settings.polygonColorFunction)) { | ||
356 | + staticSettings.polygonColorFunction = new Function('data, dsData, dsIndex', vm.ctx.settings.polygonColorFunction); | ||
357 | + } | ||
358 | + | ||
359 | + if (staticSettings.useMarkerImageFunction && angular.isDefined(vm.ctx.settings.markerImageFunction)) { | ||
360 | + staticSettings.markerImageFunction = new Function('data, images, dsData, dsIndex', vm.ctx.settings.markerImageFunction); | ||
361 | + } | ||
362 | + | ||
363 | + if (!staticSettings.useMarkerImageFunction && | ||
364 | + angular.isDefined(vm.ctx.settings.markerImage) && | ||
365 | + vm.ctx.settings.markerImage.length > 0) { | ||
366 | + staticSettings.useMarkerImage = true; | ||
367 | + let url = vm.ctx.settings.markerImage; | ||
368 | + let size = staticSettings.markerImageSize || 20; | ||
369 | + staticSettings.currentImage = { | ||
370 | + url: url, | ||
371 | + size: size | ||
372 | + }; | ||
373 | + vm.utils.loadImageAspect(staticSettings.currentImage.url).then( | ||
374 | + (aspect) => { | ||
375 | + if (aspect) { | ||
376 | + let width; | ||
377 | + let height; | ||
378 | + if (aspect > 1) { | ||
379 | + width = staticSettings.currentImage.size; | ||
380 | + height = staticSettings.currentImage.size / aspect; | ||
381 | + } else { | ||
382 | + width = staticSettings.currentImage.size * aspect; | ||
383 | + height = staticSettings.currentImage.size; | ||
384 | + } | ||
385 | + staticSettings.icon = L.icon({ | ||
386 | + iconUrl: staticSettings.currentImage.url, | ||
387 | + iconSize: [width, height], | ||
388 | + iconAnchor: [width / 2, height / 2] | ||
389 | + }); | ||
390 | + } | ||
391 | + if (vm.trips) { | ||
392 | + vm.trips.forEach(function (trip) { | ||
393 | + if (trip.marker) { | ||
394 | + trip.marker.setIcon(staticSettings.icon); | ||
395 | + } | ||
396 | + }); | ||
397 | + } | ||
398 | + } | ||
399 | + ) | ||
400 | + } | ||
401 | + } | ||
402 | + | ||
403 | + function configureTripSettings(trip, index, apply) { | ||
404 | + trip.settings = {}; | ||
405 | + trip.settings.color = calculateColor(trip); | ||
406 | + trip.settings.polygonColor = calculatePolygonColor(trip); | ||
407 | + trip.settings.strokeWeight = vm.staticSettings.pathWeight; | ||
408 | + trip.settings.strokeOpacity = vm.staticSettings.pathOpacity; | ||
409 | + trip.settings.pointColor = vm.staticSettings.pointColor; | ||
410 | + trip.settings.polygonStrokeColor = vm.staticSettings.polygonStrokeColor; | ||
411 | + trip.settings.polygonStrokeOpacity = vm.staticSettings.polygonStrokeOpacity; | ||
412 | + trip.settings.polygonOpacity = vm.staticSettings.polygonOpacity; | ||
413 | + trip.settings.polygonStrokeWeight = vm.staticSettings.polygonStrokeWeight; | ||
414 | + trip.settings.pointSize = vm.staticSettings.pointSize; | ||
415 | + trip.settings.icon = calculateIcon(trip); | ||
416 | + if (apply) { | ||
392 | $timeout(() => { | 417 | $timeout(() => { |
393 | trip.settings.labelText = calculateLabel(trip); | 418 | trip.settings.labelText = calculateLabel(trip); |
394 | trip.settings.tooltipText = $sce.trustAsHtml(calculateTooltip(trip)); | 419 | trip.settings.tooltipText = $sce.trustAsHtml(calculateTooltip(trip)); |
395 | - },0,true); | 420 | + trip.settings.polygonTooltipText = $sce.trustAsHtml(calculatePolygonTooltip(trip)); |
421 | + }, 0, true); | ||
396 | } else { | 422 | } else { |
397 | trip.settings.labelText = calculateLabel(trip); | 423 | trip.settings.labelText = calculateLabel(trip); |
398 | trip.settings.tooltipText = $sce.trustAsHtml(calculateTooltip(trip)); | 424 | trip.settings.tooltipText = $sce.trustAsHtml(calculateTooltip(trip)); |
425 | + trip.settings.polygonTooltipText = $sce.trustAsHtml(calculatePolygonTooltip(trip)); | ||
426 | + } | ||
427 | + } | ||
428 | + | ||
429 | + function calculateLabel(trip) { | ||
430 | + let label = ''; | ||
431 | + if (vm.staticSettings.showLabel) { | ||
432 | + let labelReplaceInfo; | ||
433 | + let labelText = vm.staticSettings.label; | ||
434 | + if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { | ||
435 | + try { | ||
436 | + labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dsIndex); | ||
437 | + } catch (e) { | ||
438 | + labelText = null; | ||
439 | + } | ||
440 | + } | ||
441 | + labelText = vm.utils.createLabelFromDatasource(trip.dataSource, labelText); | ||
442 | + labelReplaceInfo = processPattern(labelText, vm.ctx.datasources, trip.dSIndex); | ||
443 | + label = fillPattern(labelText, labelReplaceInfo, trip.timeRange[vm.index]); | ||
444 | + if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { | ||
445 | + try { | ||
446 | + labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
447 | + } catch (e) { | ||
448 | + labelText = null; | ||
449 | + } | ||
450 | + } | ||
399 | } | 451 | } |
400 | - } | ||
401 | - | ||
402 | - function calculateLabel(trip) { | ||
403 | - let label = ''; | ||
404 | - if (vm.staticSettings.showLabel) { | ||
405 | - let labelReplaceInfo; | ||
406 | - let labelText = vm.staticSettings.label; | ||
407 | - if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { | ||
408 | - try { | ||
409 | - labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dsIndex); | ||
410 | - } catch (e) { | ||
411 | - labelText = null; | ||
412 | - } | ||
413 | - } | ||
414 | - labelText = vm.utils.createLabelFromDatasource(trip.dataSource, labelText); | ||
415 | - labelReplaceInfo = processPattern(labelText, vm.ctx.datasources, trip.dSIndex); | ||
416 | - label = fillPattern(labelText, labelReplaceInfo, trip.timeRange[vm.index]); | ||
417 | - if (vm.staticSettings.useLabelFunction && angular.isDefined(vm.staticSettings.labelFunction)) { | ||
418 | - try { | ||
419 | - labelText = vm.staticSettings.labelFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
420 | - } catch (e) { | ||
421 | - labelText = null; | ||
422 | - } | ||
423 | - } | ||
424 | - } | ||
425 | - return label; | ||
426 | - } | ||
427 | - | ||
428 | - function calculateTooltip(trip) { | ||
429 | - let tooltip = ''; | ||
430 | - if (vm.staticSettings.displayTooltip) { | ||
431 | - let tooltipReplaceInfo; | ||
432 | - let tooltipText = vm.staticSettings.tooltipPattern; | ||
433 | - if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) { | ||
434 | - try { | ||
435 | - tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
436 | - } catch (e) { | ||
437 | - tooltipText = null; | ||
438 | - } | ||
439 | - } | ||
440 | - tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); | ||
441 | - tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); | ||
442 | - tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[vm.index]); | ||
443 | - tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); | ||
444 | - | ||
445 | - } | ||
446 | - return tooltip; | ||
447 | - } | ||
448 | - | ||
449 | - function calculateColor(trip) { | ||
450 | - let color = vm.staticSettings.pathColor; | ||
451 | - let colorFn; | ||
452 | - if (vm.staticSettings.usePathColorFunction && angular.isDefined(vm.staticSettings.colorFunction)) { | ||
453 | - try { | ||
454 | - colorFn = vm.staticSettings.colorFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
455 | - } catch (e) { | ||
456 | - colorFn = null; | ||
457 | - } | ||
458 | - } | ||
459 | - if (colorFn && colorFn !== color && trip.polyline) { | ||
460 | - trip.polyline.setStyle({color: colorFn}); | ||
461 | - } | ||
462 | - return colorFn || color; | ||
463 | - } | ||
464 | - | ||
465 | - function calculateIcon(trip) { | ||
466 | - let icon = vm.staticSettings.icon; | ||
467 | - if (vm.staticSettings.useMarkerImageFunction && angular.isDefined(vm.staticSettings.markerImageFunction)) { | ||
468 | - let rawIcon; | ||
469 | - try { | ||
470 | - rawIcon = vm.staticSettings.markerImageFunction(vm.ctx.data, vm.staticSettings.markerImages, trip.timeRange[vm.index], trip.dSIndex); | ||
471 | - } catch (e) { | ||
472 | - rawIcon = null; | ||
473 | - } | ||
474 | - if (rawIcon) { | ||
475 | - vm.utils.loadImageAspect(rawIcon).then( | ||
476 | - (aspect) => { | ||
477 | - if (aspect) { | ||
478 | - let width; | ||
479 | - let height; | ||
480 | - if (aspect > 1) { | ||
481 | - width = rawIcon.size; | ||
482 | - height = rawIcon.size / aspect; | ||
483 | - } else { | ||
484 | - width = rawIcon.size * aspect; | ||
485 | - height = rawIcon.size; | ||
486 | - } | ||
487 | - icon = L.icon({ | ||
488 | - iconUrl: rawIcon, | ||
489 | - iconSize: [width, height], | ||
490 | - iconAnchor: [width / 2, height / 2] | ||
491 | - }); | ||
492 | - } | ||
493 | - if (trip.marker) { | ||
494 | - trip.marker.setIcon(icon); | ||
495 | - } | ||
496 | - } | ||
497 | - ) | ||
498 | - } | ||
499 | - } | ||
500 | - return icon; | ||
501 | - } | ||
502 | - | ||
503 | - function createUpdatePath(apply) { | ||
504 | - if (vm.trips && vm.map) { | ||
505 | - vm.trips.forEach(function (trip) { | ||
506 | - if (trip.marker) { | ||
507 | - trip.marker.remove(); | ||
508 | - delete trip.marker; | ||
509 | - } | ||
510 | - if (trip.polyline) { | ||
511 | - trip.polyline.remove(); | ||
512 | - delete trip.polyline; | ||
513 | - } | ||
514 | - if (trip.points && trip.points.length) { | ||
515 | - trip.points.forEach(function (point) { | ||
516 | - point.remove(); | ||
517 | - }); | ||
518 | - delete trip.points; | ||
519 | - } | ||
520 | - }); | ||
521 | - vm.initBounds = true; | ||
522 | - } | ||
523 | - let normalizedTimeRange = createNormalizedTime(vm.data, 1000); | ||
524 | - createNormalizedTrips(normalizedTimeRange, vm.datasources); | ||
525 | - createTripsOnMap(apply); | ||
526 | - if (vm.initBounds && !vm.initTrips) { | ||
527 | - vm.trips.forEach(function (trip) { | ||
528 | - vm.map.extendBounds(vm.map.bounds, trip.polyline); | ||
529 | - vm.initBounds = !vm.datasources.every( | ||
530 | - function (ds) { | ||
531 | - return ds.dataReceived === true; | ||
532 | - }); | ||
533 | - vm.initTrips = vm.trips.every(function (trip) { | ||
534 | - return angular.isDefined(trip.marker) && angular.isDefined(trip.polyline); | ||
535 | - }); | ||
536 | - }); | ||
537 | - | ||
538 | - vm.map.fitBounds(vm.map.bounds); | ||
539 | - } | ||
540 | - } | ||
541 | - | ||
542 | - function fillPattern(pattern, replaceInfo, currentNormalizedValue) { | ||
543 | - let text = angular.copy(pattern); | ||
544 | - let reg = /\$\{([^\}]*)\}/g; | ||
545 | - if (replaceInfo) { | ||
546 | - for (let v = 0; v < replaceInfo.variables.length; v++) { | ||
547 | - let variableInfo = replaceInfo.variables[v]; | ||
548 | - let label = reg.exec(pattern)[1].split(":")[0]; | ||
549 | - let txtVal = ''; | ||
550 | - if (label.length > -1 && angular.isDefined(currentNormalizedValue[label])) { | ||
551 | - let varData = currentNormalizedValue[label]; | ||
552 | - if (isNumber(varData)) { | ||
553 | - txtVal = padValue(varData, variableInfo.valDec, 0); | ||
554 | - } else { | ||
555 | - txtVal = varData; | ||
556 | - } | ||
557 | - } | ||
558 | - text = text.split(variableInfo.variable).join(txtVal); | ||
559 | - } | ||
560 | - } | ||
561 | - return text; | ||
562 | - } | ||
563 | - | ||
564 | - function createNormalizedTime(data, step) { | ||
565 | - if (!step) step = 1000; | ||
566 | - let max_time = null; | ||
567 | - let min_time = null; | ||
568 | - let normalizedArray = []; | ||
569 | - if (data && data.length > 0) { | ||
570 | - vm.data.forEach(function (data) { | ||
571 | - if (data.data.length > 0) { | ||
572 | - data.data.forEach(function (sData) { | ||
573 | - if (max_time === null) { | ||
574 | - max_time = sData[0]; | ||
575 | - } else if (max_time < sData[0]) { | ||
576 | - max_time = sData[0] | ||
577 | - } | ||
578 | - if (min_time === null) { | ||
579 | - min_time = sData[0]; | ||
580 | - } else if (min_time > sData[0]) { | ||
581 | - min_time = sData[0]; | ||
582 | - } | ||
583 | - }) | ||
584 | - } | ||
585 | - }); | ||
586 | - for (let i = min_time; i < max_time; i += step) { | ||
587 | - normalizedArray.push({ts: i, formattedTs: $filter('date')(i, 'medium')}); | ||
588 | - | ||
589 | - } | ||
590 | - if (normalizedArray[normalizedArray.length - 1] && normalizedArray[normalizedArray.length - 1].ts !== max_time) { | 452 | + return label; |
453 | + } | ||
454 | + | ||
455 | + function calculateTooltip(trip) { | ||
456 | + let tooltip = ''; | ||
457 | + if (vm.staticSettings.displayTooltip) { | ||
458 | + let tooltipReplaceInfo; | ||
459 | + let tooltipText = vm.staticSettings.tooltipPattern; | ||
460 | + if (vm.staticSettings.useTooltipFunction && angular.isDefined(vm.staticSettings.tooltipFunction)) { | ||
461 | + try { | ||
462 | + tooltipText = vm.staticSettings.tooltipFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
463 | + } catch (e) { | ||
464 | + tooltipText = null; | ||
465 | + } | ||
466 | + } | ||
467 | + tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); | ||
468 | + tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); | ||
469 | + tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[vm.index]); | ||
470 | + tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); | ||
471 | + | ||
472 | + } | ||
473 | + return tooltip; | ||
474 | + } | ||
475 | + | ||
476 | + function calculatePolygonTooltip(trip) { | ||
477 | + let tooltip = ''; | ||
478 | + if (vm.staticSettings.displayTooltip) { | ||
479 | + let tooltipReplaceInfo; | ||
480 | + let tooltipText = vm.staticSettings.polygonTooltipPattern; | ||
481 | + if (vm.staticSettings.usePolygonTooltipFunction && angular.isDefined(vm.staticSettings.polygonTooltipFunction)) { | ||
482 | + try { | ||
483 | + tooltipText = vm.staticSettings.polygonTooltipFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
484 | + } catch (e) { | ||
485 | + tooltipText = null; | ||
486 | + } | ||
487 | + } | ||
488 | + tooltipText = vm.utils.createLabelFromDatasource(trip.dataSource, tooltipText); | ||
489 | + tooltipReplaceInfo = processPattern(tooltipText, vm.ctx.datasources, trip.dSIndex); | ||
490 | + tooltip = fillPattern(tooltipText, tooltipReplaceInfo, trip.timeRange[vm.index]); | ||
491 | + tooltip = fillPatternWithActions(tooltip, 'onTooltipAction', null); | ||
492 | + | ||
493 | + } | ||
494 | + return tooltip; | ||
495 | + } | ||
496 | + | ||
497 | + function calculateColor(trip) { | ||
498 | + let color = vm.staticSettings.pathColor; | ||
499 | + let colorFn; | ||
500 | + if (vm.staticSettings.usePathColorFunction && angular.isDefined(vm.staticSettings.colorFunction)) { | ||
501 | + try { | ||
502 | + colorFn = vm.staticSettings.colorFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
503 | + } catch (e) { | ||
504 | + colorFn = null; | ||
505 | + } | ||
506 | + } | ||
507 | + if (colorFn && colorFn !== color && trip.polyline) { | ||
508 | + trip.polyline.setStyle({color: colorFn}); | ||
509 | + } | ||
510 | + return colorFn || color; | ||
511 | + } | ||
512 | + | ||
513 | + function calculatePolygonColor(trip) { | ||
514 | + let color = vm.staticSettings.polygonColor; | ||
515 | + let colorFn; | ||
516 | + if (vm.staticSettings.usePolygonColorFunction && angular.isDefined(vm.staticSettings.polygonColorFunction)) { | ||
517 | + try { | ||
518 | + colorFn = vm.staticSettings.polygonColorFunction(vm.ctx.data, trip.timeRange[vm.index], trip.dSIndex); | ||
519 | + } catch (e) { | ||
520 | + colorFn = null; | ||
521 | + } | ||
522 | + } | ||
523 | + if (colorFn && colorFn !== color && trip.polygon) { | ||
524 | + trip.polygon.setStyle({fillColor: colorFn}); | ||
525 | + } | ||
526 | + return colorFn || color; | ||
527 | + } | ||
528 | + | ||
529 | + function calculateIcon(trip) { | ||
530 | + let icon = vm.staticSettings.icon; | ||
531 | + if (vm.staticSettings.useMarkerImageFunction && angular.isDefined(vm.staticSettings.markerImageFunction)) { | ||
532 | + let rawIcon; | ||
533 | + try { | ||
534 | + rawIcon = vm.staticSettings.markerImageFunction(vm.ctx.data, vm.staticSettings.markerImages, trip.timeRange[vm.index], trip.dSIndex); | ||
535 | + } catch (e) { | ||
536 | + rawIcon = null; | ||
537 | + } | ||
538 | + if (rawIcon) { | ||
539 | + vm.utils.loadImageAspect(rawIcon).then( | ||
540 | + (aspect) => { | ||
541 | + if (aspect) { | ||
542 | + let width; | ||
543 | + let height; | ||
544 | + if (aspect > 1) { | ||
545 | + width = rawIcon.size; | ||
546 | + height = rawIcon.size / aspect; | ||
547 | + } else { | ||
548 | + width = rawIcon.size * aspect; | ||
549 | + height = rawIcon.size; | ||
550 | + } | ||
551 | + icon = L.icon({ | ||
552 | + iconUrl: rawIcon, | ||
553 | + iconSize: [width, height], | ||
554 | + iconAnchor: [width / 2, height / 2] | ||
555 | + }); | ||
556 | + } | ||
557 | + if (trip.marker) { | ||
558 | + trip.marker.setIcon(icon); | ||
559 | + } | ||
560 | + } | ||
561 | + ) | ||
562 | + } | ||
563 | + } | ||
564 | + return icon; | ||
565 | + } | ||
566 | + | ||
567 | + function createUpdatePath(apply) { | ||
568 | + if (vm.trips && vm.map) { | ||
569 | + vm.trips.forEach(function (trip) { | ||
570 | + if (trip.marker) { | ||
571 | + trip.marker.remove(); | ||
572 | + delete trip.marker; | ||
573 | + } | ||
574 | + if (trip.polyline) { | ||
575 | + trip.polyline.remove(); | ||
576 | + delete trip.polyline; | ||
577 | + } | ||
578 | + if (trip.polygon) { | ||
579 | + trip.polygon.remove(); | ||
580 | + delete trip.polygon; | ||
581 | + } | ||
582 | + if (trip.points && trip.points.length) { | ||
583 | + trip.points.forEach(function (point) { | ||
584 | + point.remove(); | ||
585 | + }); | ||
586 | + delete trip.points; | ||
587 | + } | ||
588 | + }); | ||
589 | + vm.initBounds = true; | ||
590 | + } | ||
591 | + let normalizedTimeRange = createNormalizedTime(vm.data, 1000); | ||
592 | + createNormalizedTrips(normalizedTimeRange, vm.datasources); | ||
593 | + createTripsOnMap(apply); | ||
594 | + if (vm.initBounds && !vm.initTrips) { | ||
595 | + vm.trips.forEach(function (trip) { | ||
596 | + vm.map.extendBounds(vm.map.bounds, trip.polyline); | ||
597 | + vm.initBounds = !vm.datasources.every( | ||
598 | + function (ds) { | ||
599 | + return ds.dataReceived === true; | ||
600 | + }); | ||
601 | + vm.initTrips = vm.trips.every(function (trip) { | ||
602 | + return angular.isDefined(trip.marker) && angular.isDefined(trip.polyline); | ||
603 | + }); | ||
604 | + }); | ||
605 | + | ||
606 | + vm.map.fitBounds(vm.map.bounds); | ||
607 | + } | ||
608 | + } | ||
609 | + | ||
610 | + function fillPattern(pattern, replaceInfo, currentNormalizedValue) { | ||
611 | + let text = angular.copy(pattern); | ||
612 | + let reg = /\$\{([^\}]*)\}/g; | ||
613 | + if (replaceInfo) { | ||
614 | + for (let v = 0; v < replaceInfo.variables.length; v++) { | ||
615 | + let variableInfo = replaceInfo.variables[v]; | ||
616 | + let label = reg.exec(pattern)[1].split(":")[0]; | ||
617 | + let txtVal = ''; | ||
618 | + if (label.length > -1 && angular.isDefined(currentNormalizedValue[label])) { | ||
619 | + let varData = currentNormalizedValue[label]; | ||
620 | + if (isNumber(varData)) { | ||
621 | + txtVal = padValue(varData, variableInfo.valDec, 0); | ||
622 | + } else { | ||
623 | + txtVal = varData; | ||
624 | + } | ||
625 | + } | ||
626 | + text = text.split(variableInfo.variable).join(txtVal); | ||
627 | + } | ||
628 | + } | ||
629 | + return text; | ||
630 | + } | ||
631 | + | ||
632 | + function createNormalizedTime(data, step) { | ||
633 | + if (!step) step = 1000; | ||
634 | + let max_time = null; | ||
635 | + let min_time = null; | ||
636 | + let normalizedArray = []; | ||
637 | + if (data && data.length > 0) { | ||
638 | + vm.data.forEach(function (data) { | ||
639 | + if (data.data.length > 0) { | ||
640 | + data.data.forEach(function (sData) { | ||
641 | + if (max_time === null) { | ||
642 | + max_time = sData[0]; | ||
643 | + } else if (max_time < sData[0]) { | ||
644 | + max_time = sData[0] | ||
645 | + } | ||
646 | + if (min_time === null) { | ||
647 | + min_time = sData[0]; | ||
648 | + } else if (min_time > sData[0]) { | ||
649 | + min_time = sData[0]; | ||
650 | + } | ||
651 | + }) | ||
652 | + } | ||
653 | + }); | ||
654 | + for (let i = min_time; i < max_time; i += step) { | ||
655 | + normalizedArray.push({ts: i, formattedTs: $filter('date')(i, 'medium')}); | ||
656 | + | ||
657 | + } | ||
658 | + if (normalizedArray[normalizedArray.length - 1] && normalizedArray[normalizedArray.length - 1].ts !== max_time) { | ||
591 | normalizedArray.push({ts: max_time, formattedTs: $filter('date')(max_time, 'medium')}); | 659 | normalizedArray.push({ts: max_time, formattedTs: $filter('date')(max_time, 'medium')}); |
592 | } | 660 | } |
593 | - } | ||
594 | - vm.maxTime = normalizedArray.length - 1; | ||
595 | - vm.minTime = vm.maxTime > 1 ? 1 : 0; | ||
596 | - if (vm.index < vm.minTime) { | 661 | + } |
662 | + vm.maxTime = normalizedArray.length - 1; | ||
663 | + vm.minTime = vm.maxTime > 1 ? 1 : 0; | ||
664 | + if (vm.index < vm.minTime) { | ||
597 | vm.index = vm.minTime; | 665 | vm.index = vm.minTime; |
598 | } else if (vm.index > vm.maxTime) { | 666 | } else if (vm.index > vm.maxTime) { |
599 | vm.index = vm.maxTime; | 667 | vm.index = vm.maxTime; |
600 | } | 668 | } |
601 | - return normalizedArray; | ||
602 | - } | ||
603 | - | ||
604 | - function createNormalizedTrips(timeRange, dataSources) { | ||
605 | - vm.trips = []; | ||
606 | - if (timeRange && timeRange.length > 0 && dataSources && dataSources.length > 0 && vm.data && vm.data.length > 0) { | ||
607 | - dataSources.forEach(function (dS, index) { | ||
608 | - vm.trips.push({ | ||
609 | - dataSource: dS, | ||
610 | - dSIndex: index, | ||
611 | - timeRange: angular.copy(timeRange) | ||
612 | - }) | ||
613 | - }); | ||
614 | - | ||
615 | - vm.data.forEach(function (data) { | ||
616 | - let ds = data.datasource; | ||
617 | - let tripIndex = vm.trips.findIndex(function (el) { | ||
618 | - return el.dataSource.entityId === ds.entityId; | ||
619 | - }); | ||
620 | - | ||
621 | - if (tripIndex > -1) { | ||
622 | - createNormalizedValue(data.data, data.dataKey.label, vm.trips[tripIndex].timeRange); | ||
623 | - } | ||
624 | - }) | ||
625 | - } | ||
626 | - | ||
627 | - createNormalizedLatLngs(); | ||
628 | - } | ||
629 | - | ||
630 | - function createNormalizedValue(dataArray, dataKey, timeRangeArray) { | ||
631 | - timeRangeArray.forEach(function (timeStamp) { | ||
632 | - let targetTDiff = null; | ||
633 | - let value = null; | ||
634 | - for (let i = 0; i < dataArray.length; i++) { | ||
635 | - let tDiff = dataArray[i][0] - timeStamp.ts; | ||
636 | - if (targetTDiff === null || (tDiff <= 0 && targetTDiff < tDiff)) { | ||
637 | - targetTDiff = tDiff; | ||
638 | - value = dataArray[i][1]; | ||
639 | - | ||
640 | - } | ||
641 | - } | ||
642 | - if (value !== null) timeStamp[dataKey] = value; | ||
643 | - }); | ||
644 | - } | ||
645 | - | ||
646 | - function createNormalizedLatLngs() { | ||
647 | - vm.trips.forEach(function (el) { | ||
648 | - el.latLngs = []; | ||
649 | - el.timeRange.forEach(function (data) { | ||
650 | - let lat = data[vm.staticSettings.latKeyName]; | ||
651 | - let lng = data[vm.staticSettings.lngKeyName]; | ||
652 | - if (lat && lng && vm.map) { | ||
653 | - data.latLng = vm.map.createLatLng(lat, lng); | ||
654 | - } | ||
655 | - el.latLngs.push(data.latLng); | ||
656 | - }); | ||
657 | - addAngleForTrip(el); | ||
658 | - }) | ||
659 | - } | ||
660 | - | ||
661 | - function addAngleForTrip(trip) { | ||
662 | - if (trip.timeRange && trip.timeRange.length > 0) { | ||
663 | - trip.timeRange.forEach(function (point, index) { | ||
664 | - let nextPoint, prevPoint; | ||
665 | - nextPoint = index === (trip.timeRange.length - 1) ? trip.timeRange[index] : trip.timeRange[index + 1]; | ||
666 | - prevPoint = index === 0 ? trip.timeRange[0] : trip.timeRange[index - 1]; | ||
667 | - let nextLatLng = { | 669 | + return normalizedArray; |
670 | + } | ||
671 | + | ||
672 | + function createNormalizedTrips(timeRange, dataSources) { | ||
673 | + vm.trips = []; | ||
674 | + if (timeRange && timeRange.length > 0 && dataSources && dataSources.length > 0 && vm.data && vm.data.length > 0) { | ||
675 | + dataSources.forEach(function (dS, index) { | ||
676 | + vm.trips.push({ | ||
677 | + dataSource: dS, | ||
678 | + dSIndex: index, | ||
679 | + timeRange: angular.copy(timeRange) | ||
680 | + }) | ||
681 | + }); | ||
682 | + | ||
683 | + vm.data.forEach(function (data) { | ||
684 | + let ds = data.datasource; | ||
685 | + let tripIndex = vm.trips.findIndex(function (el) { | ||
686 | + return el.dataSource.entityId === ds.entityId; | ||
687 | + }); | ||
688 | + | ||
689 | + if (tripIndex > -1) { | ||
690 | + createNormalizedValue(data.data, data.dataKey.label, vm.trips[tripIndex].timeRange); | ||
691 | + } | ||
692 | + }) | ||
693 | + } | ||
694 | + | ||
695 | + createNormalizedLatLngs(); | ||
696 | + } | ||
697 | + | ||
698 | + function createNormalizedValue(dataArray, dataKey, timeRangeArray) { | ||
699 | + timeRangeArray.forEach(function (timeStamp) { | ||
700 | + let targetTDiff = null; | ||
701 | + let value = null; | ||
702 | + for (let i = 0; i < dataArray.length; i++) { | ||
703 | + let tDiff = dataArray[i][0] - timeStamp.ts; | ||
704 | + if (targetTDiff === null || (tDiff <= 0 && targetTDiff < tDiff)) { | ||
705 | + targetTDiff = tDiff; | ||
706 | + value = dataArray[i][1]; | ||
707 | + | ||
708 | + } | ||
709 | + } | ||
710 | + if (value !== null) timeStamp[dataKey] = value; | ||
711 | + }); | ||
712 | + } | ||
713 | + | ||
714 | + function createNormalizedLatLngs() { | ||
715 | + vm.trips.forEach(function (el) { | ||
716 | + el.latLngs = []; | ||
717 | + el.timeRange.forEach(function (data) { | ||
718 | + let lat = data[vm.staticSettings.latKeyName]; | ||
719 | + let lng = data[vm.staticSettings.lngKeyName]; | ||
720 | + if (lat && lng && vm.map) { | ||
721 | + data.latLng = vm.map.createLatLng(lat, lng); | ||
722 | + } | ||
723 | + el.latLngs.push(data.latLng); | ||
724 | + }); | ||
725 | + addAngleForTrip(el); | ||
726 | + }) | ||
727 | + } | ||
728 | + | ||
729 | + function addAngleForTrip(trip) { | ||
730 | + if (trip.timeRange && trip.timeRange.length > 0) { | ||
731 | + trip.timeRange.forEach(function (point, index) { | ||
732 | + let nextPoint, prevPoint; | ||
733 | + nextPoint = index === (trip.timeRange.length - 1) ? trip.timeRange[index] : trip.timeRange[index + 1]; | ||
734 | + prevPoint = index === 0 ? trip.timeRange[0] : trip.timeRange[index - 1]; | ||
735 | + let nextLatLng = { | ||
668 | lat: nextPoint[vm.staticSettings.latKeyName], | 736 | lat: nextPoint[vm.staticSettings.latKeyName], |
669 | lng: nextPoint[vm.staticSettings.lngKeyName] | 737 | lng: nextPoint[vm.staticSettings.lngKeyName] |
670 | }; | 738 | }; |
@@ -682,78 +750,125 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | @@ -682,78 +750,125 @@ function tripAnimationController($document, $scope, $http, $timeout, $filter, $s | ||
682 | point.h = findAngle(prevLatLng.lat, prevLatLng.lng, nextLatLng.lat, nextLatLng.lng); | 750 | point.h = findAngle(prevLatLng.lat, prevLatLng.lng, nextLatLng.lat, nextLatLng.lng); |
683 | point.h += vm.staticSettings.rotationAngle; | 751 | point.h += vm.staticSettings.rotationAngle; |
684 | } | 752 | } |
685 | - }); | ||
686 | - } | ||
687 | - } | ||
688 | - | ||
689 | - function createTripsOnMap(apply) { | ||
690 | - if (vm.trips.length > 0) { | ||
691 | - vm.trips.forEach(function (trip) { | ||
692 | - if (trip.timeRange.length > 0 && trip.latLngs.every(el => angular.isDefined(el))) { | ||
693 | - configureTripSettings(trip, vm.index, apply); | ||
694 | - if (vm.staticSettings.showPoints) { | ||
695 | - trip.points = []; | ||
696 | - trip.latLngs.forEach(function (latLng) { | ||
697 | - let point = L.circleMarker(latLng, { | ||
698 | - color: trip.settings.pointColor, | ||
699 | - radius: trip.settings.pointSize | ||
700 | - }).addTo(vm.map.map); | ||
701 | - trip.points.push(point); | ||
702 | - }); | ||
703 | - } | ||
704 | - | ||
705 | - if (angular.isUndefined(trip.marker)) { | ||
706 | - trip.polyline = vm.map.createPolyline(trip.latLngs, trip.settings); | ||
707 | - } | ||
708 | - | ||
709 | - if (trip.timeRange && trip.timeRange.length && angular.isUndefined(trip.marker)) { | ||
710 | - trip.marker = L.marker(trip.timeRange[vm.index].latLng); | ||
711 | - trip.marker.setZIndexOffset(1000); | ||
712 | - trip.marker.setIcon(vm.staticSettings.icon); | ||
713 | - trip.marker.setRotationOrigin('center center'); | 753 | + }); |
754 | + } | ||
755 | + } | ||
756 | + | ||
757 | + function createTripsOnMap(apply) { | ||
758 | + if (vm.trips.length > 0) { | ||
759 | + vm.trips.forEach(function (trip) { | ||
760 | + configureTripSettings(trip, vm.index, apply); | ||
761 | + if (trip.timeRange.length > 0 && trip.latLngs.every(el => angular.isDefined(el))) { | ||
762 | + if (vm.staticSettings.showPoints) { | ||
763 | + trip.points = []; | ||
764 | + trip.latLngs.forEach(function (latLng) { | ||
765 | + let point = L.circleMarker(latLng, { | ||
766 | + color: trip.settings.pointColor, | ||
767 | + radius: trip.settings.pointSize | ||
768 | + }).addTo(vm.map.map); | ||
769 | + trip.points.push(point); | ||
770 | + }); | ||
771 | + } | ||
772 | + | ||
773 | + if (angular.isUndefined(trip.marker)) { | ||
774 | + trip.polyline = vm.map.createPolyline(trip.latLngs, trip.settings); | ||
775 | + } | ||
776 | + | ||
777 | + | ||
778 | + if (trip.timeRange && trip.timeRange.length && angular.isUndefined(trip.marker)) { | ||
779 | + trip.marker = L.marker(trip.timeRange[vm.index].latLng); | ||
780 | + trip.marker.setZIndexOffset(1000); | ||
781 | + trip.marker.setIcon(vm.staticSettings.icon); | ||
782 | + trip.marker.setRotationOrigin('center center'); | ||
714 | trip.marker.on('click', function () { | 783 | trip.marker.on('click', function () { |
715 | showHideTooltip(trip); | 784 | showHideTooltip(trip); |
716 | }); | 785 | }); |
717 | - trip.marker.addTo(vm.map.map); | ||
718 | - moveMarker(trip); | ||
719 | - } | ||
720 | - } | ||
721 | - }); | ||
722 | - } | ||
723 | - } | ||
724 | - | ||
725 | - function moveMarker(trip) { | ||
726 | - if (angular.isDefined(trip.marker)) { | ||
727 | - trip.markerAngleIsSet = true; | ||
728 | - trip.marker.setLatLng(trip.timeRange[vm.index].latLng); | ||
729 | - trip.marker.setRotationAngle(trip.timeRange[vm.index].h); | ||
730 | - trip.marker.update(); | ||
731 | - } else { | ||
732 | - if (trip.timeRange && trip.timeRange.length) { | ||
733 | - trip.marker = L.marker(trip.timeRange[vm.index].latLng); | ||
734 | - trip.marker.setZIndexOffset(1000); | ||
735 | - trip.marker.setIcon(vm.staticSettings.icon); | ||
736 | - trip.marker.setRotationOrigin('center center'); | ||
737 | - trip.marker.on('click', function () { | ||
738 | - showHideTooltip(trip); | ||
739 | - }); | ||
740 | - trip.marker.addTo(vm.map.map); | ||
741 | - trip.marker.update(); | ||
742 | - } | ||
743 | - | ||
744 | - } | ||
745 | - configureTripSettings(trip); | ||
746 | - } | ||
747 | - | ||
748 | - | ||
749 | - function showHideTooltip(trip) { | ||
750 | - if (vm.staticSettings.displayTooltip) { | ||
751 | - if (vm.staticSettings.showTooltip && trip && vm.activeTripIndex !== trip.dSIndex) { | ||
752 | - vm.staticSettings.showTooltip = true; | ||
753 | - } else { | ||
754 | - vm.staticSettings.showTooltip = !vm.staticSettings.showTooltip; | ||
755 | - } | ||
756 | - } | ||
757 | - if (trip && vm.activeTripIndex !== trip.dSIndex) vm.activeTripIndex = trip.dSIndex; | ||
758 | - } | 786 | + trip.marker.addTo(vm.map.map); |
787 | + moveMarker(trip); | ||
788 | + } | ||
789 | + } | ||
790 | + | ||
791 | + if (vm.staticSettings.showPolygon && angular.isDefined(trip.timeRange[vm.index][vm.staticSettings.polKeyName])) { | ||
792 | + let polygonSettings = { | ||
793 | + fill: true, | ||
794 | + fillColor: trip.settings.polygonColor, | ||
795 | + color: trip.settings.polygonStrokeColor, | ||
796 | + weight: trip.settings.polygonStrokeWeight, | ||
797 | + fillOpacity: trip.settings.polygonOpacity, | ||
798 | + opacity: trip.settings.polygonStrokeOpacity | ||
799 | + }; | ||
800 | + let polygonLatLngsRaw = mapPolygonArray(angular.fromJson(trip.timeRange[vm.index][vm.staticSettings.polKeyName])); | ||
801 | + trip.polygon = L.polygon(polygonLatLngsRaw, polygonSettings).addTo(vm.map.map); | ||
802 | + trip.polygon.on('click',function(){showHidePolygonTooltip(trip)}); | ||
803 | + } | ||
804 | + }); | ||
805 | + } | ||
806 | + } | ||
807 | + | ||
808 | + function mapPolygonArray(rawArray) { | ||
809 | + return rawArray.map(function (el) { | ||
810 | + if (el.length === 2) { | ||
811 | + if (!angular.isNumber(el[0]) && !angular.isNumber(el[1])) { | ||
812 | + return el.map(function (subEl) { | ||
813 | + return mapPolygonArray(subEl); | ||
814 | + }) | ||
815 | + } else { | ||
816 | + return vm.map.createLatLng(el[0], el[1]); | ||
817 | + } | ||
818 | + } else if (el.length > 2) { | ||
819 | + return mapPolygonArray(el); | ||
820 | + } else { | ||
821 | + return vm.map.createLatLng(false); | ||
822 | + } | ||
823 | + }); | ||
824 | + } | ||
825 | + | ||
826 | + function moveMarker(trip) { | ||
827 | + if (angular.isDefined(trip.timeRange[vm.index].latLng)) { | ||
828 | + if (angular.isDefined(trip.marker)) { | ||
829 | + trip.markerAngleIsSet = true; | ||
830 | + trip.marker.setLatLng(trip.timeRange[vm.index].latLng); | ||
831 | + trip.marker.setRotationAngle(trip.timeRange[vm.index].h); | ||
832 | + trip.marker.update(); | ||
833 | + } else { | ||
834 | + if (trip.timeRange && trip.timeRange.length) { | ||
835 | + trip.marker = L.marker(trip.timeRange[vm.index].latLng); | ||
836 | + trip.marker.setZIndexOffset(1000); | ||
837 | + trip.marker.setIcon(vm.staticSettings.icon); | ||
838 | + trip.marker.setRotationOrigin('center center'); | ||
839 | + trip.marker.on('click', function () { | ||
840 | + showHideTooltip(trip); | ||
841 | + }); | ||
842 | + trip.marker.addTo(vm.map.map); | ||
843 | + trip.marker.update(); | ||
844 | + } | ||
845 | + } | ||
846 | + } | ||
847 | + configureTripSettings(trip); | ||
848 | + } | ||
849 | + | ||
850 | + | ||
851 | + function showHideTooltip(trip) { | ||
852 | + if (vm.staticSettings.displayTooltip) { | ||
853 | + if (vm.staticSettings.showTooltip && trip && (vm.activeTripIndex !== trip.dSIndex || vm.staticSettings.tooltipMarker !== 'marker')) { | ||
854 | + vm.staticSettings.showTooltip = true; | ||
855 | + } else { | ||
856 | + vm.staticSettings.showTooltip = !vm.staticSettings.showTooltip; | ||
857 | + } | ||
858 | + vm.staticSettings.tooltipMarker = 'marker'; | ||
859 | + } | ||
860 | + if (trip && vm.activeTripIndex !== trip.dSIndex) vm.activeTripIndex = trip.dSIndex; | ||
861 | + } | ||
862 | + | ||
863 | + function showHidePolygonTooltip(trip) { | ||
864 | + if (vm.staticSettings.displayTooltip) { | ||
865 | + if (vm.staticSettings.showTooltip && trip && (vm.activeTripIndex !== trip.dSIndex || vm.staticSettings.tooltipMarker !== 'polygon')) { | ||
866 | + vm.staticSettings.showTooltip = true; | ||
867 | + } else { | ||
868 | + vm.staticSettings.showTooltip = !vm.staticSettings.showTooltip; | ||
869 | + } | ||
870 | + vm.staticSettings.tooltipMarker = 'polygon'; | ||
871 | + } | ||
872 | + if (trip && vm.activeTripIndex !== trip.dSIndex) vm.activeTripIndex = trip.dSIndex; | ||
873 | + } | ||
759 | } | 874 | } |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | <ng-md-icon icon="info_outline"></ng-md-icon> | 27 | <ng-md-icon icon="info_outline"></ng-md-icon> |
28 | </md-button> | 28 | </md-button> |
29 | </div> | 29 | </div> |
30 | - <div class="trip-animation-tooltip md-whiteframe-z4" layout="column" ng-class="!vm.staticSettings.showTooltip ? 'trip-animation-tooltip-hidden':''" ng-bind-html="vm.trips[vm.activeTripIndex].settings.tooltipText" | 30 | + <div class="trip-animation-tooltip md-whiteframe-z4" layout="column" ng-class="!vm.staticSettings.showTooltip ? 'trip-animation-tooltip-hidden':''" ng-bind-html="vm.staticSettings.tooltipMarker === 'polygon' ? vm.trips[vm.activeTripIndex].settings.polygonTooltipText : vm.trips[vm.activeTripIndex].settings.tooltipText" |
31 | ng-style="{'background-color': vm.staticSettings.tooltipColor, 'opacity': vm.staticSettings.tooltipOpacity, 'color': vm.staticSettings.tooltipFontColor}"> | 31 | ng-style="{'background-color': vm.staticSettings.tooltipColor, 'opacity': vm.staticSettings.tooltipOpacity, 'color': vm.staticSettings.tooltipFontColor}"> |
32 | </div> | 32 | </div> |
33 | </div> | 33 | </div> |
@@ -210,7 +210,7 @@ export function arraysEqual(a, b) { | @@ -210,7 +210,7 @@ export function arraysEqual(a, b) { | ||
210 | if (a.length != b.length) return false; | 210 | if (a.length != b.length) return false; |
211 | 211 | ||
212 | for (var i = 0; i < a.length; ++i) { | 212 | for (var i = 0; i < a.length; ++i) { |
213 | - if (!a[i].equals(b[i])) return false; | 213 | + if (!arraysEqual(a[i],b[i])) return false; |
214 | } | 214 | } |
215 | return true; | 215 | return true; |
216 | } | 216 | } |