Commit 9e6acb7edeebbdf76905d343acbb1d589a7c1699

Authored by Igor Kulikov
1 parent 3e25997b

Map widgets improvements.

@@ -77,7 +77,7 @@ @@ -77,7 +77,7 @@
77 </td> 77 </td>
78 <td md-cell ng-if="vm.displayDetails" class="tb-action-cell"> 78 <td md-cell ng-if="vm.displayDetails" class="tb-action-cell">
79 <md-button class="md-icon-button" aria-label="{{ 'alarm.details' | translate }}" 79 <md-button class="md-icon-button" aria-label="{{ 'alarm.details' | translate }}"
80 - ng-click="vm.openAlarmDetails($event, alarm)"> 80 + ng-click="vm.openAlarmDetails($event, alarm)" ng-disabled="$root.loading">
81 <md-icon aria-label="{{ 'alarm.details' | translate }}" class="material-icons">more_horiz</md-icon> 81 <md-icon aria-label="{{ 'alarm.details' | translate }}" class="material-icons">more_horiz</md-icon>
82 <md-tooltip md-direction="top"> 82 <md-tooltip md-direction="top">
83 {{ 'alarm.details' | translate }} 83 {{ 'alarm.details' | translate }}
@@ -90,7 +90,7 @@ @@ -90,7 +90,7 @@
90 width: vm.actionCellDescriptors.length*36+'px'}"> 90 width: vm.actionCellDescriptors.length*36+'px'}">
91 <md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors" 91 <md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors"
92 aria-label="{{ actionDescriptor.displayName }}" 92 aria-label="{{ actionDescriptor.displayName }}"
93 - ng-click="vm.onActionButtonClick($event, alarm, actionDescriptor)"> 93 + ng-click="vm.onActionButtonClick($event, alarm, actionDescriptor)" ng-disabled="$root.loading">
94 <md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon> 94 <md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon>
95 <md-tooltip md-direction="top"> 95 <md-tooltip md-direction="top">
96 {{ actionDescriptor.displayName }} 96 {{ actionDescriptor.displayName }}
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 width: vm.actionCellDescriptors.length*36+'px'}"> 63 width: vm.actionCellDescriptors.length*36+'px'}">
64 <md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors" 64 <md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors"
65 aria-label="{{ actionDescriptor.displayName }}" 65 aria-label="{{ actionDescriptor.displayName }}"
66 - ng-click="vm.onActionButtonClick($event, entity, actionDescriptor)"> 66 + ng-click="vm.onActionButtonClick($event, entity, actionDescriptor)" ng-disabled="$root.loading">
67 <md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon> 67 <md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon>
68 <md-tooltip md-direction="top"> 68 <md-tooltip md-direction="top">
69 {{ actionDescriptor.displayName }} 69 {{ actionDescriptor.displayName }}
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
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 -  
17 var gmGlobals = { 16 var gmGlobals = {
18 loadingGmId: null, 17 loadingGmId: null,
19 gmApiKeys: {} 18 gmApiKeys: {}
@@ -151,80 +150,100 @@ export default class TbGoogleMap { @@ -151,80 +150,100 @@ export default class TbGoogleMap {
151 150
152 /* eslint-disable no-undef */ 151 /* eslint-disable no-undef */
153 updateMarkerColor(marker, color) { 152 updateMarkerColor(marker, color) {
154 - var pinColor = color.substr(1);  
155 - var pinImage = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColor,  
156 - new google.maps.Size(21, 34),  
157 - new google.maps.Point(0,0),  
158 - new google.maps.Point(10, 34));  
159 - marker.setIcon(pinImage); 153 + this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
  154 + marker.setIcon(iconInfo.icon);
  155 + });
160 } 156 }
161 /* eslint-enable no-undef */ 157 /* eslint-enable no-undef */
162 158
163 /* eslint-disable no-undef */ 159 /* eslint-disable no-undef */
164 - updateMarkerImage(marker, settings, image, maxSize) {  
165 - var testImage = document.createElement('img'); // eslint-disable-line  
166 - testImage.style.visibility = 'hidden';  
167 - testImage.onload = function() {  
168 - var width;  
169 - var height;  
170 - var aspect = testImage.width / testImage.height;  
171 - document.body.removeChild(testImage); //eslint-disable-line  
172 - if (aspect > 1) {  
173 - width = maxSize;  
174 - height = maxSize / aspect;  
175 - } else {  
176 - width = maxSize * aspect;  
177 - height = maxSize;  
178 - }  
179 - var pinImage = {  
180 - url: image,  
181 - scaledSize : new google.maps.Size(width, height)  
182 - }  
183 - marker.setIcon(pinImage); 160 + updateMarkerIcon(marker, settings) {
  161 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  162 + marker.setIcon(iconInfo.icon);
184 if (settings.showLabel) { 163 if (settings.showLabel) {
185 - marker.set('labelAnchor', new google.maps.Point(100, height + 20)); 164 + marker.set('labelAnchor', new google.maps.Point(100, iconInfo.size[1] + 20));
186 } 165 }
  166 + });
  167 + }
  168 + /* eslint-disable no-undef */
  169 +
  170 + /* eslint-disable no-undef */
  171 + createMarkerIcon(marker, settings, onMarkerIconReady) {
  172 + var currentImage = settings.currentImage;
  173 + var gMap = this;
  174 + if (currentImage && currentImage.url) {
  175 + var testImage = document.createElement('img'); // eslint-disable-line
  176 + testImage.style.visibility = 'hidden';
  177 + testImage.onload = function() {
  178 + var width;
  179 + var height;
  180 + var aspect = testImage.width / testImage.height;
  181 + document.body.removeChild(testImage); //eslint-disable-line
  182 + if (aspect > 1) {
  183 + width = currentImage.size;
  184 + height = currentImage.size / aspect;
  185 + } else {
  186 + width = currentImage.size * aspect;
  187 + height = currentImage.size;
  188 + }
  189 + var icon = {
  190 + url: currentImage.url,
  191 + scaledSize : new google.maps.Size(width, height)
  192 + };
  193 + var iconInfo = {
  194 + size: [width, height],
  195 + icon: icon
  196 + };
  197 + onMarkerIconReady(iconInfo);
  198 + };
  199 + testImage.onerror = function() {
  200 + gMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  201 + };
  202 + document.body.appendChild(testImage); //eslint-disable-line
  203 + testImage.src = currentImage.url;
  204 + } else {
  205 + this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
187 } 206 }
188 - document.body.appendChild(testImage); //eslint-disable-line  
189 - testImage.src = image;  
190 } 207 }
191 /* eslint-enable no-undef */ 208 /* eslint-enable no-undef */
192 209
193 /* eslint-disable no-undef */ 210 /* eslint-disable no-undef */
194 - createMarker(location, settings, onClickListener, markerArgs) {  
195 - var height = 34;  
196 - var pinColor = settings.color.substr(1);  
197 - var pinImage = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColor,  
198 - new google.maps.Size(21, 34),  
199 - new google.maps.Point(0,0),  
200 - new google.maps.Point(10, 34));  
201 - var pinShadow = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_shadow", 211 + createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
  212 + var pinColor = color.substr(1);
  213 + var icon = new google.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=%E2%80%A2|" + pinColor,
202 new google.maps.Size(40, 37), 214 new google.maps.Size(40, 37),
203 - new google.maps.Point(0, 0),  
204 - new google.maps.Point(12, 35)); 215 + new google.maps.Point(0,0),
  216 + new google.maps.Point(10, 37));
  217 + var iconInfo = {
  218 + size: [40, 37],
  219 + icon: icon
  220 + };
  221 + onMarkerIconReady(iconInfo);
  222 + }
  223 + /* eslint-enable no-undef */
  224 +
  225 + /* eslint-disable no-undef */
  226 + createMarker(location, settings, onClickListener, markerArgs) {
205 var marker; 227 var marker;
206 if (settings.showLabel) { 228 if (settings.showLabel) {
207 marker = new MarkerWithLabel({ 229 marker = new MarkerWithLabel({
208 position: location, 230 position: location,
209 - map: this.map,  
210 - icon: pinImage,  
211 - shadow: pinShadow,  
212 labelContent: '<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>', 231 labelContent: '<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
213 - labelClass: "tb-labels",  
214 - labelAnchor: new google.maps.Point(100, height + 20) 232 + labelClass: "tb-labels"
215 }); 233 });
216 } else { 234 } else {
217 marker = new google.maps.Marker({ 235 marker = new google.maps.Marker({
218 position: location, 236 position: location,
219 - map: this.map,  
220 - icon: pinImage,  
221 - shadow: pinShadow  
222 }); 237 });
223 } 238 }
224 -  
225 - if (settings.useMarkerImage) {  
226 - this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34);  
227 - } 239 + var gMap = this;
  240 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  241 + marker.setIcon(iconInfo.icon);
  242 + if (settings.showLabel) {
  243 + marker.set('labelAnchor', new google.maps.Point(100, iconInfo.size[1] + 20));
  244 + }
  245 + marker.setMap(gMap.map);
  246 + });
228 247
229 if (settings.displayTooltip) { 248 if (settings.displayTooltip) {
230 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs); 249 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs);
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
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 -  
17 import 'leaflet/dist/leaflet.css'; 16 import 'leaflet/dist/leaflet.css';
18 import * as L from 'leaflet'; 17 import * as L from 'leaflet';
19 18
@@ -229,20 +228,12 @@ export default class TbImageMap { @@ -229,20 +228,12 @@ export default class TbImageMap {
229 } 228 }
230 229
231 updateMarkerColor(marker, color) { 230 updateMarkerColor(marker, color) {
232 - var pinColor = color.substr(1);  
233 - var icon = L.icon({  
234 - iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,  
235 - iconSize: [21, 34],  
236 - iconAnchor: [10, 34],  
237 - popupAnchor: [0, -34],  
238 - shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',  
239 - shadowSize: [40, 37],  
240 - shadowAnchor: [12, 35] 231 + this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
  232 + marker.setIcon(iconInfo.icon);
241 }); 233 });
242 - marker.setIcon(icon);  
243 } 234 }
244 235
245 - updateMarkerImage(marker, settings, image, maxSize) { 236 + /*updateMarkerImage(marker, settings, image, maxSize) {
246 var testImage = document.createElement('img'); // eslint-disable-line 237 var testImage = document.createElement('img'); // eslint-disable-line
247 testImage.style.visibility = 'hidden'; 238 testImage.style.visibility = 'hidden';
248 testImage.onload = function() { 239 testImage.onload = function() {
@@ -273,39 +264,97 @@ export default class TbImageMap { @@ -273,39 +264,97 @@ export default class TbImageMap {
273 } 264 }
274 document.body.appendChild(testImage); //eslint-disable-line 265 document.body.appendChild(testImage); //eslint-disable-line
275 testImage.src = image; 266 testImage.src = image;
  267 + }*/
  268 +
  269 + updateMarkerIcon(marker, settings) {
  270 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  271 + marker.setIcon(iconInfo.icon);
  272 + if (settings.showLabel) {
  273 + marker.unbindTooltip();
  274 + marker.tooltipOffset = [0, -iconInfo.size[1] * marker.offsetY + 10];
  275 + marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
  276 + { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
  277 + }
  278 + });
276 } 279 }
277 280
278 - createMarker(position, settings, onClickListener, markerArgs) {  
279 - var height = 34;  
280 - var pinColor = settings.color.substr(1); 281 + createMarkerIcon(marker, settings, onMarkerIconReady) {
  282 + var currentImage = settings.currentImage;
  283 + var opMap = this;
  284 + if (currentImage && currentImage.url) {
  285 + var testImage = document.createElement('img'); // eslint-disable-line
  286 + testImage.style.visibility = 'hidden';
  287 + testImage.onload = function() {
  288 + var width;
  289 + var height;
  290 + var aspect = testImage.width / testImage.height;
  291 + document.body.removeChild(testImage); //eslint-disable-line
  292 + if (aspect > 1) {
  293 + width = currentImage.size;
  294 + height = currentImage.size / aspect;
  295 + } else {
  296 + width = currentImage.size * aspect;
  297 + height = currentImage.size;
  298 + }
  299 + var icon = L.icon({
  300 + iconUrl: currentImage.url,
  301 + iconSize: [width, height],
  302 + iconAnchor: [marker.offsetX * width, marker.offsetY * height],
  303 + popupAnchor: [0, -height]
  304 + });
  305 + var iconInfo = {
  306 + size: [width, height],
  307 + icon: icon
  308 + };
  309 + onMarkerIconReady(iconInfo);
  310 + };
  311 + testImage.onerror = function() {
  312 + opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  313 + };
  314 + document.body.appendChild(testImage); //eslint-disable-line
  315 + testImage.src = currentImage.url;
  316 + } else {
  317 + this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  318 + }
  319 + }
  320 +
  321 + createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
  322 + var pinColor = color.substr(1);
281 var icon = L.icon({ 323 var icon = L.icon({
282 iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor, 324 iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
283 iconSize: [21, 34], 325 iconSize: [21, 34],
284 - iconAnchor: [21 * settings.markerOffsetX, 34 * settings.markerOffsetY], 326 + iconAnchor: [21 * marker.offsetX, 34 * marker.offsetY],
285 popupAnchor: [0, -34], 327 popupAnchor: [0, -34],
286 shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow', 328 shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
287 shadowSize: [40, 37], 329 shadowSize: [40, 37],
288 shadowAnchor: [12, 35] 330 shadowAnchor: [12, 35]
289 }); 331 });
  332 + var iconInfo = {
  333 + size: [21, 34],
  334 + icon: icon
  335 + };
  336 + onMarkerIconReady(iconInfo);
  337 + }
290 338
  339 + createMarker(position, settings, onClickListener, markerArgs) {
291 var pos = this.posFunction(position.x, position.y); 340 var pos = this.posFunction(position.x, position.y);
292 var x = pos.x * this.width; 341 var x = pos.x * this.width;
293 var y = pos.y * this.height; 342 var y = pos.y * this.height;
294 var location = this.pointToLatLng(x, y); 343 var location = this.pointToLatLng(x, y);
295 - var marker = L.marker(location, {icon: icon}).addTo(this.map); 344 + var marker = L.marker(location, {});//.addTo(this.map);
296 marker.position = position; 345 marker.position = position;
297 marker.offsetX = settings.markerOffsetX; 346 marker.offsetX = settings.markerOffsetX;
298 marker.offsetY = settings.markerOffsetY; 347 marker.offsetY = settings.markerOffsetY;
299 -  
300 - if (settings.showLabel) {  
301 - marker.tooltipOffset = [0, -height * marker.offsetY + 10];  
302 - marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',  
303 - { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });  
304 - }  
305 -  
306 - if (settings.useMarkerImage) {  
307 - this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34);  
308 - } 348 + var opMap = this;
  349 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  350 + marker.setIcon(iconInfo.icon);
  351 + if (settings.showLabel) {
  352 + marker.tooltipOffset = [0, -iconInfo.size[1] * marker.offsetY + 10];
  353 + marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
  354 + { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
  355 + }
  356 + marker.addTo(opMap.map);
  357 + });
309 358
310 if (settings.displayTooltip) { 359 if (settings.displayTooltip) {
311 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs); 360 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs);
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
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 -  
17 import tinycolor from 'tinycolor2'; 16 import tinycolor from 'tinycolor2';
18 17
19 import TbGoogleMap from './google-map'; 18 import TbGoogleMap from './google-map';
@@ -274,9 +273,13 @@ export default class TbMapWidget { @@ -274,9 +273,13 @@ export default class TbMapWidget {
274 if (!this.locationsSettings[i].useMarkerImageFunction && 273 if (!this.locationsSettings[i].useMarkerImageFunction &&
275 angular.isDefined(configuredLocationsSettings[i].markerImage) && 274 angular.isDefined(configuredLocationsSettings[i].markerImage) &&
276 configuredLocationsSettings[i].markerImage.length > 0) { 275 configuredLocationsSettings[i].markerImage.length > 0) {
277 - this.locationsSettings[i].markerImage = configuredLocationsSettings[i].markerImage;  
278 this.locationsSettings[i].useMarkerImage = true; 276 this.locationsSettings[i].useMarkerImage = true;
279 - this.locationsSettings[i].markerImageSize = configuredLocationsSettings[i].markerImageSize || 34; 277 + var url = this.ctx.settings.markerImage;
  278 + var size = this.ctx.settings.markerImageSize || 34;
  279 + this.locationSettings.currentImage = {
  280 + url: url,
  281 + size: size
  282 + };
280 } 283 }
281 284
282 if (this.drawRoutes) { 285 if (this.drawRoutes) {
@@ -380,17 +383,41 @@ export default class TbMapWidget { @@ -380,17 +383,41 @@ export default class TbMapWidget {
380 } 383 }
381 } 384 }
382 385
383 - function updateLocationMarkerImage(location, dataMap) { 386 + function updateLocationMarkerIcon(location, dataMap) {
384 var image = calculateLocationMarkerImage(location, dataMap); 387 var image = calculateLocationMarkerImage(location, dataMap);
385 - if (image != null && (!location.settings.calculatedImage || !angular.equals(location.settings.calculatedImage, image))) {  
386 - tbMap.map.updateMarkerImage(location.marker, location.settings, image.url, image.size);  
387 - location.settings.calculatedImage = image; 388 + if (image && (!location.settings.currentImage || !angular.equals(location.settings.currentImage, image))) {
  389 + location.settings.currentImage = image;
  390 + tbMap.map.updateMarkerIcon(location.marker, location.settings);
388 } 391 }
389 } 392 }
390 393
391 function updateLocationStyle(location, dataMap) { 394 function updateLocationStyle(location, dataMap) {
392 updateLocationColor(location, dataMap); 395 updateLocationColor(location, dataMap);
393 - updateLocationMarkerImage(location, dataMap); 396 + updateLocationMarkerIcon(location, dataMap);
  397 + }
  398 +
  399 + function createOrUpdateLocationMarker(location, markerLocation, dataMap) {
  400 + var changed = false;
  401 + if (!location.marker) {
  402 + var image = calculateLocationMarkerImage(location, dataMap);
  403 + if (image && (!location.settings.currentImage || !angular.equals(location.settings.currentImage, image))) {
  404 + location.settings.currentImage = image;
  405 + }
  406 + location.marker = tbMap.map.createMarker(markerLocation, location.settings,
  407 + function() {
  408 + tbMap.callbacks.onLocationClick(location);
  409 + }
  410 + );
  411 + tbMap.markers.push(location.marker);
  412 + changed = true;
  413 + } else {
  414 + var prevPosition = tbMap.map.getMarkerPosition(location.marker);
  415 + if (!prevPosition.equals(markerLocation)) {
  416 + tbMap.map.setMarkerPosition(location.marker, markerLocation);
  417 + changed = true;
  418 + }
  419 + }
  420 + return changed;
394 } 421 }
395 422
396 function updateLocation(location, data, dataMap) { 423 function updateLocation(location, data, dataMap) {
@@ -413,15 +440,7 @@ export default class TbMapWidget { @@ -413,15 +440,7 @@ export default class TbMapWidget {
413 } 440 }
414 if (latLngs.length > 0) { 441 if (latLngs.length > 0) {
415 var markerLocation = latLngs[latLngs.length-1]; 442 var markerLocation = latLngs[latLngs.length-1];
416 - if (!location.marker) {  
417 - location.marker = tbMap.map.createMarker(markerLocation, location.settings,  
418 - function() {  
419 - tbMap.callbacks.onLocationClick(location);  
420 - }  
421 - );  
422 - } else {  
423 - tbMap.map.setMarkerPosition(location.marker, markerLocation);  
424 - } 443 + createOrUpdateLocationMarker(location, markerLocation, dataMap);
425 } 444 }
426 if (!location.polyline) { 445 if (!location.polyline) {
427 location.polyline = tbMap.map.createPolyline(latLngs, location.settings); 446 location.polyline = tbMap.map.createPolyline(latLngs, location.settings);
@@ -439,18 +458,8 @@ export default class TbMapWidget { @@ -439,18 +458,8 @@ export default class TbMapWidget {
439 lat = latData[latData.length-1][1]; 458 lat = latData[latData.length-1][1];
440 lng = lngData[lngData.length-1][1]; 459 lng = lngData[lngData.length-1][1];
441 latLng = tbMap.map.createLatLng(lat, lng); 460 latLng = tbMap.map.createLatLng(lat, lng);
442 - if (!location.marker) {  
443 - location.marker = tbMap.map.createMarker(latLng, location.settings, function() {  
444 - tbMap.callbacks.onLocationClick(location);  
445 - });  
446 - tbMap.markers.push(location.marker); 461 + if (createOrUpdateLocationMarker(location, latLng, dataMap)) {
447 locationChanged = true; 462 locationChanged = true;
448 - } else {  
449 - var prevPosition = tbMap.map.getMarkerPosition(location.marker);  
450 - if (!prevPosition.equals(latLng)) {  
451 - tbMap.map.setMarkerPosition(location.marker, latLng);  
452 - locationChanged = true;  
453 - }  
454 } 463 }
455 } 464 }
456 updateLocationStyle(location, dataMap); 465 updateLocationStyle(location, dataMap);
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
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 -  
17 import tinycolor from 'tinycolor2'; 16 import tinycolor from 'tinycolor2';
18 17
19 import TbGoogleMap from './google-map'; 18 import TbGoogleMap from './google-map';
@@ -159,9 +158,13 @@ export default class TbMapWidgetV2 { @@ -159,9 +158,13 @@ export default class TbMapWidgetV2 {
159 if (!this.locationSettings.useMarkerImageFunction && 158 if (!this.locationSettings.useMarkerImageFunction &&
160 angular.isDefined(this.ctx.settings.markerImage) && 159 angular.isDefined(this.ctx.settings.markerImage) &&
161 this.ctx.settings.markerImage.length > 0) { 160 this.ctx.settings.markerImage.length > 0) {
162 - this.locationSettings.markerImage = this.ctx.settings.markerImage;  
163 this.locationSettings.useMarkerImage = true; 161 this.locationSettings.useMarkerImage = true;
164 - this.locationSettings.markerImageSize = this.ctx.settings.markerImageSize || 34; 162 + var url = this.ctx.settings.markerImage;
  163 + var size = this.ctx.settings.markerImageSize || 34;
  164 + this.locationSettings.currentImage = {
  165 + url: url,
  166 + size: size
  167 + };
165 } 168 }
166 169
167 if (this.drawRoutes) { 170 if (this.drawRoutes) {
@@ -235,10 +238,10 @@ export default class TbMapWidgetV2 { @@ -235,10 +238,10 @@ export default class TbMapWidgetV2 {
235 } 238 }
236 } 239 }
237 240
238 - function updateLocationMarkerImage(location, image) {  
239 - if (image && (!location.settings.calculatedImage || !angular.equals(location.settings.calculatedImage, image))) {  
240 - tbMap.map.updateMarkerImage(location.marker, location.settings, image.url, image.size);  
241 - location.settings.calculatedImage = image; 241 + function updateLocationMarkerIcon(location, image) {
  242 + if (image && (!location.settings.currentImage || !angular.equals(location.settings.currentImage, image))) {
  243 + location.settings.currentImage = image;
  244 + tbMap.map.updateMarkerIcon(location.marker, location.settings);
242 } 245 }
243 } 246 }
244 247
@@ -247,7 +250,31 @@ export default class TbMapWidgetV2 { @@ -247,7 +250,31 @@ export default class TbMapWidgetV2 {
247 var color = calculateLocationColor(location, dataMap); 250 var color = calculateLocationColor(location, dataMap);
248 var image = calculateLocationMarkerImage(location, dataMap); 251 var image = calculateLocationMarkerImage(location, dataMap);
249 updateLocationColor(location, color, image); 252 updateLocationColor(location, color, image);
250 - updateLocationMarkerImage(location, image); 253 + updateLocationMarkerIcon(location, image);
  254 + }
  255 +
  256 + function createOrUpdateLocationMarker(location, markerLocation, dataMap) {
  257 + var changed = false;
  258 + if (!location.marker) {
  259 + var image = calculateLocationMarkerImage(location, dataMap);
  260 + if (image && (!location.settings.currentImage || !angular.equals(location.settings.currentImage, image))) {
  261 + location.settings.currentImage = image;
  262 + }
  263 + location.marker = tbMap.map.createMarker(markerLocation, location.settings,
  264 + function (event) {
  265 + tbMap.callbacks.onLocationClick(location);
  266 + locationRowClick(event, location);
  267 + }, [location.dsIndex]);
  268 + tbMap.markers.push(location.marker);
  269 + changed = true;
  270 + } else {
  271 + var prevPosition = tbMap.map.getMarkerPosition(location.marker);
  272 + if (!prevPosition.equals(markerLocation)) {
  273 + tbMap.map.setMarkerPosition(location.marker, markerLocation);
  274 + changed = true;
  275 + }
  276 + }
  277 + return changed;
251 } 278 }
252 279
253 function locationRowClick($event, location) { 280 function locationRowClick($event, location) {
@@ -284,16 +311,7 @@ export default class TbMapWidgetV2 { @@ -284,16 +311,7 @@ export default class TbMapWidgetV2 {
284 } 311 }
285 if (latLngs.length > 0) { 312 if (latLngs.length > 0) {
286 var markerLocation = latLngs[latLngs.length - 1]; 313 var markerLocation = latLngs[latLngs.length - 1];
287 - if (!location.marker) {  
288 - location.marker = tbMap.map.createMarker(markerLocation, location.settings,  
289 - function (event) {  
290 - tbMap.callbacks.onLocationClick(location);  
291 - locationRowClick(event, location);  
292 - }, [location.dsIndex]  
293 - );  
294 - } else {  
295 - tbMap.map.setMarkerPosition(location.marker, markerLocation);  
296 - } 314 + createOrUpdateLocationMarker(location, markerLocation, dataMap);
297 } 315 }
298 if (!location.polyline) { 316 if (!location.polyline) {
299 location.polyline = tbMap.map.createPolyline(latLngs, location.settings); 317 location.polyline = tbMap.map.createPolyline(latLngs, location.settings);
@@ -312,20 +330,8 @@ export default class TbMapWidgetV2 { @@ -312,20 +330,8 @@ export default class TbMapWidgetV2 {
312 lng = lngData[lngData.length - 1][1]; 330 lng = lngData[lngData.length - 1][1];
313 if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) { 331 if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) {
314 latLng = tbMap.map.createLatLng(lat, lng); 332 latLng = tbMap.map.createLatLng(lat, lng);
315 - if (!location.marker) {  
316 - location.marker = tbMap.map.createMarker(latLng, location.settings,  
317 - function (event) {  
318 - tbMap.callbacks.onLocationClick(location);  
319 - locationRowClick(event, location);  
320 - }, [location.dsIndex]);  
321 - tbMap.markers.push(location.marker); 333 + if (createOrUpdateLocationMarker(location, latLng, dataMap)) {
322 locationChanged = true; 334 locationChanged = true;
323 - } else {  
324 - var prevPosition = tbMap.map.getMarkerPosition(location.marker);  
325 - if (!prevPosition.equals(latLng)) {  
326 - tbMap.map.setMarkerPosition(location.marker, latLng);  
327 - locationChanged = true;  
328 - }  
329 } 335 }
330 } 336 }
331 } 337 }
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
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 -  
17 import 'leaflet/dist/leaflet.css'; 16 import 'leaflet/dist/leaflet.css';
18 import * as L from 'leaflet'; 17 import * as L from 'leaflet';
19 import 'leaflet-providers'; 18 import 'leaflet-providers';
@@ -54,55 +53,65 @@ export default class TbOpenStreetMap { @@ -54,55 +53,65 @@ export default class TbOpenStreetMap {
54 } 53 }
55 54
56 updateMarkerColor(marker, color) { 55 updateMarkerColor(marker, color) {
57 - var pinColor = color.substr(1);  
58 - var icon = L.icon({  
59 - iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,  
60 - iconSize: [21, 34],  
61 - iconAnchor: [10, 34],  
62 - popupAnchor: [0, -34],  
63 - shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',  
64 - shadowSize: [40, 37],  
65 - shadowAnchor: [12, 35] 56 + this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
  57 + marker.setIcon(iconInfo.icon);
66 }); 58 });
67 - marker.setIcon(icon);  
68 - }  
69 -  
70 - updateMarkerImage(marker, settings, image, maxSize) {  
71 - var testImage = document.createElement('img'); // eslint-disable-line  
72 - testImage.style.visibility = 'hidden';  
73 - testImage.onload = function() {  
74 - var width;  
75 - var height;  
76 - var aspect = testImage.width / testImage.height;  
77 - document.body.removeChild(testImage); //eslint-disable-line  
78 - if (aspect > 1) {  
79 - width = maxSize;  
80 - height = maxSize / aspect;  
81 - } else {  
82 - width = maxSize * aspect;  
83 - height = maxSize;  
84 - }  
85 - var icon = L.icon({  
86 - iconUrl: image,  
87 - iconSize: [width, height],  
88 - iconAnchor: [width/2, height],  
89 - popupAnchor: [0, -height]  
90 - });  
91 - marker.setIcon(icon); 59 + }
  60 +
  61 + updateMarkerIcon(marker, settings) {
  62 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  63 + marker.setIcon(iconInfo.icon);
92 if (settings.showLabel) { 64 if (settings.showLabel) {
93 marker.unbindTooltip(); 65 marker.unbindTooltip();
94 - marker.tooltipOffset = [0, -height + 10]; 66 + marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
95 marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>', 67 marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
96 { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset }); 68 { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
97 } 69 }
  70 + });
  71 + }
  72 +
  73 + createMarkerIcon(marker, settings, onMarkerIconReady) {
  74 + var currentImage = settings.currentImage;
  75 + var opMap = this;
  76 + if (currentImage && currentImage.url) {
  77 + var testImage = document.createElement('img'); // eslint-disable-line
  78 + testImage.style.visibility = 'hidden';
  79 + testImage.onload = function() {
  80 + var width;
  81 + var height;
  82 + var aspect = testImage.width / testImage.height;
  83 + document.body.removeChild(testImage); //eslint-disable-line
  84 + if (aspect > 1) {
  85 + width = currentImage.size;
  86 + height = currentImage.size / aspect;
  87 + } else {
  88 + width = currentImage.size * aspect;
  89 + height = currentImage.size;
  90 + }
  91 + var icon = L.icon({
  92 + iconUrl: currentImage.url,
  93 + iconSize: [width, height],
  94 + iconAnchor: [width/2, height],
  95 + popupAnchor: [0, -height]
  96 + });
  97 + var iconInfo = {
  98 + size: [width, height],
  99 + icon: icon
  100 + };
  101 + onMarkerIconReady(iconInfo);
  102 + };
  103 + testImage.onerror = function() {
  104 + opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
  105 + };
  106 + document.body.appendChild(testImage); //eslint-disable-line
  107 + testImage.src = currentImage.url;
  108 + } else {
  109 + this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
98 } 110 }
99 - document.body.appendChild(testImage); //eslint-disable-line  
100 - testImage.src = image;  
101 } 111 }
102 112
103 - createMarker(location, settings, onClickListener, markerArgs) {  
104 - var height = 34;  
105 - var pinColor = settings.color.substr(1); 113 + createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
  114 + var pinColor = color.substr(1);
106 var icon = L.icon({ 115 var icon = L.icon({
107 iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor, 116 iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
108 iconSize: [21, 34], 117 iconSize: [21, 34],
@@ -112,18 +121,25 @@ export default class TbOpenStreetMap { @@ -112,18 +121,25 @@ export default class TbOpenStreetMap {
112 shadowSize: [40, 37], 121 shadowSize: [40, 37],
113 shadowAnchor: [12, 35] 122 shadowAnchor: [12, 35]
114 }); 123 });
  124 + var iconInfo = {
  125 + size: [21, 34],
  126 + icon: icon
  127 + };
  128 + onMarkerIconReady(iconInfo);
  129 + }
115 130
116 - var marker = L.marker(location, {icon: icon}).addTo(this.map);  
117 -  
118 - if (settings.showLabel) {  
119 - marker.tooltipOffset = [0, -height + 10];  
120 - marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',  
121 - { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });  
122 - }  
123 -  
124 - if (settings.useMarkerImage) {  
125 - this.updateMarkerImage(marker, settings, settings.markerImage, settings.markerImageSize || 34);  
126 - } 131 + createMarker(location, settings, onClickListener, markerArgs) {
  132 + var marker = L.marker(location, {});
  133 + var opMap = this;
  134 + this.createMarkerIcon(marker, settings, (iconInfo) => {
  135 + marker.setIcon(iconInfo.icon);
  136 + if (settings.showLabel) {
  137 + marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
  138 + marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
  139 + { className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
  140 + }
  141 + marker.addTo(opMap.map);
  142 + });
127 143
128 if (settings.displayTooltip) { 144 if (settings.displayTooltip) {
129 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs); 145 this.createTooltip(marker, settings.tooltipPattern, settings.tooltipReplaceInfo, settings.autocloseTooltip, markerArgs);