UNPKG

mohsen-angular-leaflet-directive

Version:

angular-leaflet-directive - An AngularJS directive to easily interact with Leaflet maps

217 lines (188 loc) 7.82 kB
angular.module('leaflet-directive').directive('lfCenter', function(leafletLogger, $q, $location, $timeout, leafletMapDefaults, leafletHelpers, leafletBoundsHelpers, leafletMapEvents) { var isDefined = leafletHelpers.isDefined; var isNumber = leafletHelpers.isNumber; var isSameCenterOnMap = leafletHelpers.isSameCenterOnMap; var safeApply = leafletHelpers.safeApply; var isValidCenter = leafletHelpers.isValidCenter; var isValidBounds = leafletBoundsHelpers.isValidBounds; var isUndefinedOrEmpty = leafletHelpers.isUndefinedOrEmpty; var shouldInitializeMapWithBounds = function(bounds, center) { return isDefined(bounds) && isValidBounds(bounds) && isUndefinedOrEmpty(center); }; var _leafletCenter; return { restrict: 'A', scope: false, replace: false, require: 'leaflet', controller: function() { _leafletCenter = $q.defer(); this.getCenter = function() { return _leafletCenter.promise; }; }, link: function(scope, element, attrs, controller) { var leafletScope = controller.getLeafletScope(); if (!isDefined(leafletScope.center)) { leafletLogger.error('The scope "center" variable is not defined', 'center'); leafletScope.center = {}; } var centerModel = leafletScope.center; controller.getMap().then(function(map) { var defaults = leafletMapDefaults.getDefaults(attrs.id); if (attrs.lfCenter.search('-') !== -1) { leafletLogger.error('The "center" variable can\'t use a "-" on its key name: "' + attrs.lfCenter, 'center'); map.setView([defaults.center.lat, defaults.center.lng], defaults.center.zoom); return; } else if (shouldInitializeMapWithBounds(leafletScope.bounds, centerModel)) { map.fitBounds(leafletBoundsHelpers.createLeafletBounds(leafletScope.bounds), leafletScope.bounds.options); safeApply(leafletScope, function(scope) { angular.extend(scope.center, { lat: map.getCenter().lat, lng: map.getCenter().lng, zoom: map.getZoom(), autoDiscover: false, }); }); safeApply(leafletScope, function(scope) { var mapBounds = map.getBounds(); scope.bounds = { northEast: { lat: mapBounds._northEast.lat, lng: mapBounds._northEast.lng, }, southWest: { lat: mapBounds._southWest.lat, lng: mapBounds._southWest.lng, }, }; }); } else if (!isDefined(centerModel)) { leafletLogger.error('The "center" property is not defined in the main scope', 'center'); map.setView([defaults.center.lat, defaults.center.lng], defaults.center.zoom); return; } else if (!(isDefined(centerModel.lat) && isDefined(centerModel.lng)) && !isDefined(centerModel.autoDiscover)) { angular.copy(defaults.center, centerModel); } var urlCenterHash; var mapReady; if (centerModel.allowUrlHashCenter === true) { var extractCenterFromUrl = function() { var search = $location.search(); var centerParam; if (isDefined(search.c)) { var cParam = search.c.split(':'); if (cParam.length === 3) { centerParam = { lat: parseFloat(cParam[0]), lng: parseFloat(cParam[1]), zoom: parseInt(cParam[2], 10), allowUrlHashCenter: centerModel.allowUrlHashCenter, }; } } return centerParam; }; urlCenterHash = extractCenterFromUrl(); leafletScope.$on('$locationChangeSuccess', function(event) { var scope = event.currentScope; var urlCenter = extractCenterFromUrl(); if (isDefined(urlCenter) && !isSameCenterOnMap(urlCenter, map)) { angular.extend(scope.center, { lat: urlCenter.lat, lng: urlCenter.lng, zoom: urlCenter.zoom, allowUrlHashCenter: centerModel.allowUrlHashCenter, }); } }); } leafletScope.$watch('center', function(center) { if (leafletScope.settingCenterFromLeaflet) { return; } // The center from the URL has priority if (isDefined(urlCenterHash)) { angular.copy(urlCenterHash, center); urlCenterHash = undefined; } if (!isValidCenter(center) && center.autoDiscover !== true) { leafletLogger.warn(' invalid \'center\'', 'center'); //map.setView([defaults.center.lat, defaults.center.lng], defaults.center.zoom); return; } if (center.autoDiscover === true) { if (!isNumber(center.zoom)) { map.setView([defaults.center.lat, defaults.center.lng], defaults.center.zoom); } if (isNumber(center.zoom) && center.zoom > defaults.center.zoom) { map.locate({ setView: true, maxZoom: center.zoom, }); } else if (isDefined(defaults.maxZoom)) { map.locate({ setView: true, maxZoom: defaults.maxZoom, }); } else { map.locate({ setView: true, }); } return; } if (mapReady && isSameCenterOnMap(center, map)) { return; } leafletScope.settingCenterFromScope = true; map.setView([center.lat, center.lng], center.zoom); leafletMapEvents.notifyCenterChangedToBounds(leafletScope, map); $timeout(function() { leafletScope.settingCenterFromScope = false; }); }, true); map.whenReady(function() { mapReady = true; }); map.on('moveend', function(/* event */) { // Resolve the center after the first map position _leafletCenter.resolve(); if (centerModel.allowUrlHashCenter === true) { leafletMapEvents.notifyCenterUrlHashChanged(leafletScope, map, $location.search()); } if (isSameCenterOnMap(centerModel, map) || leafletScope.settingCenterFromScope) { return; } leafletScope.settingCenterFromLeaflet = true; safeApply(leafletScope, function(scope) { if (!leafletScope.settingCenterFromScope) { angular.extend(scope.center, { lat: map.getCenter().lat, lng: map.getCenter().lng, zoom: map.getZoom(), autoDiscover: false, }); } leafletMapEvents.notifyCenterChangedToBounds(leafletScope, map); $timeout(function() { leafletScope.settingCenterFromLeaflet = false; }); }); }); if (centerModel.autoDiscover === true) { map.on('locationerror', function() { leafletLogger.warn('The Geolocation API is unauthorized on this page.', 'center'); if (isValidCenter(centerModel)) { map.setView([centerModel.lat, centerModel.lng], centerModel.zoom); leafletMapEvents.notifyCenterChangedToBounds(leafletScope, map); } else { map.setView([defaults.center.lat, defaults.center.lng], defaults.center.zoom); leafletMapEvents.notifyCenterChangedToBounds(leafletScope, map); } }); } }); }, }; });