206 lines
11 KiB
JavaScript
206 lines
11 KiB
JavaScript
"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 = _.minBy(currentZoomTiles, function (tile) {
|
|
return tile.column;
|
|
}).column || 0, leftBottomY = _.maxBy(currentZoomTiles, function (tile) {
|
|
return tile.row;
|
|
}).row || 0, rightTopX = _.maxBy(currentZoomTiles, function (tile) {
|
|
return tile.column;
|
|
}).column || 0, rightTopY = _.minBy(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.<google.maps.Map>} 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 = $("<div class='poi-location__pin' ng-click='openInfoBubble($event)'/>")[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;
|
|
}]);
|
|
})();
|