thingsboard-aplcache

Details

diff --git a/ui/src/app/common/utils.service.js b/ui/src/app/common/utils.service.js
index 9d99781..085a28b 100644
--- a/ui/src/app/common/utils.service.js
+++ b/ui/src/app/common/utils.service.js
@@ -134,6 +134,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
         defaultAlarmDataKeys.push(dataKey);
     }
 
+    var imageAspectMap = {};
+
     var service = {
         getDefaultDatasource: getDefaultDatasource,
         generateObjectFromJsonSchema: generateObjectFromJsonSchema,
@@ -159,7 +161,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
         insertVariable: insertVariable,
         customTranslation: customTranslation,
         objToBase64: objToBase64,
-        base64toObj: base64toObj
+        base64toObj: base64toObj,
+        loadImageAspect: loadImageAspect
     }
 
     return service;
@@ -543,4 +546,34 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
         return obj;
     }
 
+    function loadImageAspect(imageUrl) {
+        var deferred = $q.defer();
+        if (imageUrl && imageUrl.length) {
+            var urlHashCode = hashCode(imageUrl);
+            var aspect = imageAspectMap[urlHashCode];
+            if (angular.isUndefined(aspect)) {
+                var testImage = document.createElement('img'); // eslint-disable-line
+                testImage.style.visibility = 'hidden';
+                testImage.onload = function() {
+                    aspect = testImage.width / testImage.height;
+                    document.body.removeChild(testImage); //eslint-disable-line
+                    imageAspectMap[urlHashCode] = aspect;
+                    deferred.resolve(aspect);
+                };
+                testImage.onerror = function() {
+                    aspect = 0;
+                    imageAspectMap[urlHashCode] = aspect;
+                    deferred.resolve(aspect);
+                };
+                document.body.appendChild(testImage); //eslint-disable-line
+                testImage.src = imageUrl;
+            } else {
+                deferred.resolve(aspect);
+            }
+        } else {
+            deferred.resolve(0);
+        }
+        return deferred.promise;
+    }
+
 }
diff --git a/ui/src/app/widget/lib/google-map.js b/ui/src/app/widget/lib/google-map.js
index 48900bd..af11ac3 100644
--- a/ui/src/app/widget/lib/google-map.js
+++ b/ui/src/app/widget/lib/google-map.js
@@ -19,9 +19,10 @@ var gmGlobals = {
 }
 
 export default class TbGoogleMap {
-    constructor($containerElement, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, gmApiKey, gmDefaultMapType) {
+    constructor($containerElement, utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, gmApiKey, gmDefaultMapType) {
 
         var tbMap = this;
+        this.utils = utils;
         this.defaultZoomLevel = defaultZoomLevel;
         this.dontFitMapBounds = dontFitMapBounds;
         this.minZoomLevel = minZoomLevel;
@@ -172,35 +173,32 @@ export default class TbGoogleMap {
         var currentImage = settings.currentImage;
         var gMap = this;
         if (currentImage && currentImage.url) {
-            var testImage = document.createElement('img'); // eslint-disable-line
-            testImage.style.visibility = 'hidden';
-            testImage.onload = function() {
-                var width;
-                var height;
-                var aspect = testImage.width / testImage.height;
-                document.body.removeChild(testImage); //eslint-disable-line
-                if (aspect > 1) {
-                    width = currentImage.size;
-                    height = currentImage.size / aspect;
-                } else {
-                    width = currentImage.size * aspect;
-                    height = currentImage.size;
+            this.utils.loadImageAspect(currentImage.url).then(
+                (aspect) => {
+                    if (aspect) {
+                        var width;
+                        var height;
+                        if (aspect > 1) {
+                            width = currentImage.size;
+                            height = currentImage.size / aspect;
+                        } else {
+                            width = currentImage.size * aspect;
+                            height = currentImage.size;
+                        }
+                        var icon = {
+                            url: currentImage.url,
+                            scaledSize : new google.maps.Size(width, height)
+                        };
+                        var iconInfo = {
+                            size: [width, height],
+                            icon: icon
+                        };
+                        onMarkerIconReady(iconInfo);
+                    } else {
+                        gMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
+                    }
                 }
-                var icon = {
-                    url: currentImage.url,
-                    scaledSize : new google.maps.Size(width, height)
-                };
-                var iconInfo = {
-                    size: [width, height],
-                    icon: icon
-                };
-                onMarkerIconReady(iconInfo);
-            };
-            testImage.onerror = function() {
-                gMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
-            };
-            document.body.appendChild(testImage); //eslint-disable-line
-            testImage.src = currentImage.url;
+            );
         } else {
             this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
         }
diff --git a/ui/src/app/widget/lib/image-map.js b/ui/src/app/widget/lib/image-map.js
index 746d571..c130539 100644
--- a/ui/src/app/widget/lib/image-map.js
+++ b/ui/src/app/widget/lib/image-map.js
@@ -20,9 +20,10 @@ const maxZoom = 4;
 
 export default class TbImageMap {
 
-    constructor(ctx, $containerElement, initCallback, imageUrl, posFunction, imageEntityAlias, imageUrlAttribute) {
+    constructor(ctx, $containerElement, utils, initCallback, imageUrl, posFunction, imageEntityAlias, imageUrlAttribute) {
 
         this.ctx = ctx;
+        this.utils = utils;
         this.tooltips = [];
 
         this.$containerElement = $containerElement;
@@ -116,18 +117,15 @@ export default class TbImageMap {
         }
         this.imageUrl = imageUrl;
         var imageMap = this;
-        var testImage = document.createElement('img'); // eslint-disable-line
-        testImage.style.visibility = 'hidden';
-        testImage.onload = function() {
-            imageMap.aspect = testImage.width / testImage.height;
-            document.body.removeChild(testImage); //eslint-disable-line
-            imageMap.onresize(updateImage);
-            if (initCallback) {
-                setTimeout(initCallback, 0); //eslint-disable-line
+        this.utils.loadImageAspect(imageUrl).then(
+            (aspect) => {
+                imageMap.aspect = aspect;
+                imageMap.onresize(updateImage);
+                if (initCallback) {
+                    setTimeout(initCallback, 0); //eslint-disable-line
+                }
             }
-        }
-        document.body.appendChild(testImage); //eslint-disable-line
-        testImage.src = imageUrl;
+        );
     }
 
     onresize(updateImage) {
@@ -249,37 +247,34 @@ export default class TbImageMap {
         var currentImage = settings.currentImage;
         var opMap = this;
         if (currentImage && currentImage.url) {
-            var testImage = document.createElement('img'); // eslint-disable-line
-            testImage.style.visibility = 'hidden';
-            testImage.onload = function() {
-                var width;
-                var height;
-                var aspect = testImage.width / testImage.height;
-                document.body.removeChild(testImage); //eslint-disable-line
-                if (aspect > 1) {
-                    width = currentImage.size;
-                    height = currentImage.size / aspect;
-                } else {
-                    width = currentImage.size * aspect;
-                    height = currentImage.size;
+            this.utils.loadImageAspect(currentImage.url).then(
+                (aspect) => {
+                    if (aspect) {
+                        var width;
+                        var height;
+                        if (aspect > 1) {
+                            width = currentImage.size;
+                            height = currentImage.size / aspect;
+                        } else {
+                            width = currentImage.size * aspect;
+                            height = currentImage.size;
+                        }
+                        var icon = L.icon({
+                            iconUrl: currentImage.url,
+                            iconSize: [width, height],
+                            iconAnchor: [marker.offsetX * width, marker.offsetY * height],
+                            popupAnchor: [0, -height]
+                        });
+                        var iconInfo = {
+                            size: [width, height],
+                            icon: icon
+                        };
+                        onMarkerIconReady(iconInfo);
+                    } else {
+                        opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
+                    }
                 }
-                var icon = L.icon({
-                    iconUrl: currentImage.url,
-                    iconSize: [width, height],
-                    iconAnchor: [marker.offsetX * width, marker.offsetY * height],
-                    popupAnchor: [0, -height]
-                });
-                var iconInfo = {
-                    size: [width, height],
-                    icon: icon
-                };
-                onMarkerIconReady(iconInfo);
-            };
-            testImage.onerror = function() {
-                opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
-            };
-            document.body.appendChild(testImage); //eslint-disable-line
-            testImage.src = currentImage.url;
+            );
         } else {
             this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
         }
diff --git a/ui/src/app/widget/lib/map-widget.js b/ui/src/app/widget/lib/map-widget.js
index 53e6ada..ef86381 100644
--- a/ui/src/app/widget/lib/map-widget.js
+++ b/ui/src/app/widget/lib/map-widget.js
@@ -74,7 +74,7 @@ export default class TbMapWidget {
         if (!$element) {
             $element = ctx.$container;
         }
-
+        this.utils = ctx.$scope.$injector.get('utils');
         this.drawRoutes = drawRoutes;
         this.markers = [];
         if (this.drawRoutes) {
@@ -109,9 +109,9 @@ export default class TbMapWidget {
         };
 
         if (mapProvider === 'google-map') {
-            this.map = new TbGoogleMap($element, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType);
+            this.map = new TbGoogleMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType);
         } else if (mapProvider === 'openstreet-map') {
-            this.map = new TbOpenStreetMap($element, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel);
+            this.map = new TbOpenStreetMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel);
         }
 
     }
diff --git a/ui/src/app/widget/lib/map-widget2.js b/ui/src/app/widget/lib/map-widget2.js
index db880ca..6b589aa 100644
--- a/ui/src/app/widget/lib/map-widget2.js
+++ b/ui/src/app/widget/lib/map-widget2.js
@@ -74,11 +74,11 @@ export default class TbMapWidgetV2 {
         });
 
         if (mapProvider === 'google-map') {
-            this.map = new TbGoogleMap($element, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType);
+            this.map = new TbGoogleMap($element, this.utils, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.gmApiKey, settings.gmDefaultMapType);
         } else if (mapProvider === 'openstreet-map') {
-            this.map = new TbOpenStreetMap($element, initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.mapProvider);
+            this.map = new TbOpenStreetMap($element, this.utils,  initCallback, this.defaultZoomLevel, this.dontFitMapBounds, minZoomLevel, settings.mapProvider);
         } else if (mapProvider === 'image-map') {
-            this.map = new TbImageMap(this.ctx, $element, initCallback,
+            this.map = new TbImageMap(this.ctx, $element, this.utils, initCallback,
                 settings.mapImageUrl,
                 settings.posFunction,
                 settings.imageEntityAlias,
diff --git a/ui/src/app/widget/lib/openstreet-map.js b/ui/src/app/widget/lib/openstreet-map.js
index 3403acf..8aafe69 100644
--- a/ui/src/app/widget/lib/openstreet-map.js
+++ b/ui/src/app/widget/lib/openstreet-map.js
@@ -19,8 +19,9 @@ import 'leaflet-providers';
 
 export default class TbOpenStreetMap {
 
-    constructor($containerElement, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, mapProvider) {
+    constructor($containerElement, utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, mapProvider) {
 
+        this.utils = utils;
         this.defaultZoomLevel = defaultZoomLevel;
         this.dontFitMapBounds = dontFitMapBounds;
         this.minZoomLevel = minZoomLevel;
@@ -74,37 +75,34 @@ export default class TbOpenStreetMap {
         var currentImage = settings.currentImage;
         var opMap = this;
         if (currentImage && currentImage.url) {
-            var testImage = document.createElement('img'); // eslint-disable-line
-            testImage.style.visibility = 'hidden';
-            testImage.onload = function() {
-                var width;
-                var height;
-                var aspect = testImage.width / testImage.height;
-                document.body.removeChild(testImage); //eslint-disable-line
-                if (aspect > 1) {
-                    width = currentImage.size;
-                    height = currentImage.size / aspect;
-                } else {
-                    width = currentImage.size * aspect;
-                    height = currentImage.size;
+            this.utils.loadImageAspect(currentImage.url).then(
+                (aspect) => {
+                    if (aspect) {
+                        var width;
+                        var height;
+                        if (aspect > 1) {
+                            width = currentImage.size;
+                            height = currentImage.size / aspect;
+                        } else {
+                            width = currentImage.size * aspect;
+                            height = currentImage.size;
+                        }
+                        var icon = L.icon({
+                            iconUrl: currentImage.url,
+                            iconSize: [width, height],
+                            iconAnchor: [width/2, height],
+                            popupAnchor: [0, -height]
+                        });
+                        var iconInfo = {
+                            size: [width, height],
+                            icon: icon
+                        };
+                        onMarkerIconReady(iconInfo);
+                    } else {
+                        opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
+                    }
                 }
-                var icon = L.icon({
-                    iconUrl: currentImage.url,
-                    iconSize: [width, height],
-                    iconAnchor: [width/2, height],
-                    popupAnchor: [0, -height]
-                });
-                var iconInfo = {
-                    size: [width, height],
-                    icon: icon
-                };
-                onMarkerIconReady(iconInfo);
-            };
-            testImage.onerror = function() {
-                opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
-            };
-            document.body.appendChild(testImage); //eslint-disable-line
-            testImage.src = currentImage.url;
+            );
         } else {
             this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
         }