"use strict"; (function () { 'use strict'; /** * @ngdoc object * @name myitsmApp.googleMapService * @requires $rootScope * @requires $resource * @requires $q * @description * Contains all utility methods used for building custom google maps in application */ angular.module('myitsmApp') .factory('googleMapService', ['$resource', '$rootScope', '$q', function ($resource, $rootScope, $q) { var self = { isAvailable: angular.mapsAvailable }; var mapOptionsDefault = !self.isAvailable ? {} : { zoom: 15, minZoom: 15, maxZoom: 15, mapTypeId: bmcMaps.MapTypeId.ROADMAP, mapTypeControl: false, disableDefaultUI: true, panControl: false, zoomControl: false, draggable: false }, floormapOptions = !self.isAvailable ? {} : { center: new bmcMaps.LatLng(78.740, -65.18), radius: 360, zoom: 10, draggable: true, mapTypeId: 'floormap', mapTypeControl: false, disableDefaultUI: true, panControl: true, panControlOptions: { position: bmcMaps.ControlPosition.LEFT_BOTTOM }, zoomControl: true, zoomControlOptions: { style: bmcMaps.ZoomControlStyle.LARGE, position: bmcMaps.ControlPosition.LEFT_BOTTOM } }, mapInitDefer, mapData = {}; self.initLocationMapWithUserMarker = function (mapContainer, mapOptions, userLocation) { var initDefer = $q.defer(), map = self.initLocationMap(mapContainer, mapOptions); bmcMaps.event.addListenerOnce(map, 'idle', function () { var marker = self.addLocationMarker(map, userLocation); initDefer.resolve({ map: map, marker: marker }); }); return initDefer.promise; }; self.getLocationCoordinatesByAdress = function (address, successCb, failCB) { var addr = address.replace(/(?:\r\n|\r|\n)/g, ', '); bmcMaps.geocoder.geocode(addr, successCb, failCB); }; self.initLocationMap = function (mapContainer, mapOptions) { var options = _.extend(mapOptionsDefault, mapOptions); return new bmcMaps.Map(mapContainer, options); }; self.addLocationMarker = function (map, location) { return map.addMarker(location, 'styles/img/marker.png'); }; self.initFloorMap = function (settings) { mapInitDefer = $q.defer(); mapData = {}; mapData.floormap = new bmcMaps.Map(settings.mapContainer, floormapOptions); bmcMaps.event.addListenerOnce(mapData.floormap, 'idle', function () { mapData.floormapBounds = self.generateFloorMapType(settings.tiles, mapData.floormap, '', '', settings.scale); }); return mapInitDefer.promise; }; self.generateFloorMapType = function (tilesData, map, maxZoom, minZoom, scale) { var FloorMapType = function () { }; FloorMapType.prototype = { tileSize: new bmcMaps.Size(LocationVO.GMAP_TILE_SIZE, LocationVO.GMAP_TILE_SIZE), maxZoom: maxZoom || LocationVO.GMAP_MAX_ZOOM, minZoom: minZoom || LocationVO.GMAP_MIN_ZOOM, tileBounds: [], getTile: function (coord, zoom, ownerDocument) { var index = parseInt(this.maxZoom - zoom), zoomRatio = scale ? scale : LocationVO.SCALE_LEVELS[index]; var tile = tilesData[zoomRatio][coord.x + '_' + coord.y] || {}, div = ownerDocument.createElement('div'); div.style.width = this.tileSize.width + 'px'; div.style.height = this.tileSize.height + 'px'; div.style.fontSize = '10'; if (tile.id) { div.style.backgroundImage = 'url(data:image/png;base64,' + tile.tile + ')'; div.style.backgroundRepeat = 'no-repeat'; } div.style.backgroundColor = '#FFFFFF'; return div; }, name: 'floormap' }; var floorMapType = new FloorMapType(); map.mapTypes.set('floormap', floorMapType); mapData.mapType = floorMapType; return self.calculateBounds(map, tilesData); }; self.calculateBounds = function (map, tiles, scale) { var zoom = map.getZoom(), maxZoom = map.mapTypes[map.mapTypeId].maxZoom || 100, position = parseInt(maxZoom - zoom), zoomRatio = scale ? scale : LocationVO.SCALE_LEVELS[position], currentZoomTiles = tiles[zoomRatio], leftBottomX = _.min(currentZoomTiles, function (tile) { return tile.column; }).column || 0, leftBottomY = _.max(currentZoomTiles, function (tile) { return tile.row; }).row || 0, rightTopX = _.max(currentZoomTiles, function (tile) { return tile.column; }).column || 0, rightTopY = _.min(currentZoomTiles, function (tile) { return tile.row; }).row || 0, leftBottomTile = currentZoomTiles[leftBottomX + '_' + leftBottomY], rightTopTile = currentZoomTiles[rightTopX + '_' + rightTopY]; var proj = map.getProjection(), coordRatio = Math.pow(2, zoom), tileSize = 256 / coordRatio, /*Floormap Image bounds calculations*/ rightTopXPoint = (rightTopTile.column) * tileSize + rightTopTile.width / coordRatio, rightTopYPoint = rightTopTile.row * tileSize, rightTopGpoint = new bmcMaps.Point(rightTopXPoint, rightTopYPoint), rightTopLatLng = proj.fromPointToLatLng(rightTopGpoint), leftBottomXPoint = (leftBottomTile.column) * tileSize + ((leftBottomTile.width !== 256) ? (leftBottomTile.width / coordRatio) : 0), leftBottomYPoint = (leftBottomTile.row * tileSize) + (leftBottomTile.height / coordRatio), leftBottomGpoint = new bmcMaps.Point(leftBottomXPoint, leftBottomYPoint), leftBottomLatLng = proj.fromPointToLatLng(leftBottomGpoint); var tileBounds = new bmcMaps.LatLngBounds(); tileBounds.extend(leftBottomLatLng); tileBounds.extend(rightTopLatLng); var center = tileBounds.getCenter(); map.panToBounds(tileBounds); map.setCenter(center); var floormapBounds = { tileBounds: tileBounds }; mapData.floormapBounds = floormapBounds; self.limitFloorMapBounds(map, floormapBounds); mapInitDefer.resolve(mapData); return floormapBounds; }; self.limitFloorMapBounds = function (map, bounds) { var initalCenter = map.getCenter(), allowedBounds = bounds.tileBounds, lastValidCenter = map.getCenter(); map.setCenter(initalCenter); bmcMaps.event.addListener(map, 'center_changed', function () { var mCenter = map.getCenter(); if (allowedBounds.contains(mCenter)) { lastValidCenter = map.getCenter(); return; } // not valid anymore => return to last valid position map.panTo(lastValidCenter); }); map.panToBounds(bounds.tileBounds); }; self.getCurrentScaleLevel = function (map) { var zoom = map.getZoom(), maxZoom = map.mapTypes[map.mapTypeId].maxZoom, index = parseInt(maxZoom - zoom); return LocationVO.SCALE_LEVELS[index] || 100; }; /** * @ngdoc method * @name myitsmApp.googleMapService#panAssetOnMap * @methodOf myitsmApp.googleMapService * * @description * Converts x,y position to Google Maps Position object and places styled marker in this position * * @param {Object.} map Instance of Google map , where asset should be added * @param {Object} asset Data object, which holds asset position information * @returns {Object} Modified asset object */ self.panAssetOnMap = function (map, asset) { var proj = map.getProjection(), zoom = map.getZoom(), scale = self.getCurrentScaleLevel(map), coordRatio = Math.pow(2, zoom), assetX = (scale !== 100) ? (parseFloat((asset.xPos * scale) / 100) / coordRatio) : (asset.xPos / coordRatio), assetY = (scale !== 100) ? (parseFloat((asset.yPos * scale) / 100) / coordRatio) : (asset.yPos / coordRatio), assetMapPoint = new bmcMaps.Point(assetX, assetY), assetLatLng = proj.fromPointToLatLng(assetMapPoint), assetHtml = $("
")[0]; var marker = self.addMarkerOnMap({ position: assetLatLng, map: map, draggable: false, content: assetHtml, data: asset, desc: asset.desc, name: asset.name }, asset, assetLatLng); asset.marker = marker; return asset; }; self.addMarkerOnMap = function (markerConfig) { markerConfig.flat = true; var assetPin = new bmcMaps.RichMarker(markerConfig); markerConfig.map.setCenter(markerConfig.position); return assetPin; }; self.fromPointToLatLng = function (map, x, y, overlay) { var latLng = overlay.getProjection().fromContainerPixelToLatLng(new bmcMaps.Point(x, y)); map.addMarker(latLng, 'styles/img/marker.png'); }; self.createInfoBubble = function (bubblePosition, content) { var infoBubble = new bmcMaps.InfoBubble({ content: content, position: bubblePosition, shadowStyle: 0, borderWidth: 0, padding: 0, backgroundColor: '#fff', borderRadius: 4, arrowSize: 10, hideCloseButton: true, arrowPosition: 50, minWidth: 192, minHeight: 52, arrowStyle: 0 }); return infoBubble; }; self.getDirectionUrl = function (address) { var addr = address.replace(/(?:\r\n|\r|\n)/g, ', '); return bmcMaps.getDirectionUrl(addr); }; return self; }]); })();