From debbcc89c0e24c13f63e8d059ae7c39ee6f50e5f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 3 Jan 2018 15:51:45 +0200 Subject: [PATCH] Map Markers images load improvements. --- ui/src/app/common/utils.service.js | 35 ++++++++++- ui/src/app/widget/lib/google-map.js | 56 +++++++++--------- ui/src/app/widget/lib/image-map.js | 79 ++++++++++++------------- ui/src/app/widget/lib/map-widget.js | 6 +- ui/src/app/widget/lib/map-widget2.js | 6 +- ui/src/app/widget/lib/openstreet-map.js | 60 +++++++++---------- 6 files changed, 133 insertions(+), 109 deletions(-) diff --git a/ui/src/app/common/utils.service.js b/ui/src/app/common/utils.service.js index 9d997816f6..085a28bad5 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 48900bd078..af11ac36fd 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 746d571668..c130539f6e 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 53e6ada781..ef86381438 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 db880ca96d..6b589aa13a 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 3403acfe99..8aafe69a7a 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); }