From 6ec3feb6fdb279474de2be0e191791021396793b Mon Sep 17 00:00:00 2001 From: nfssfn Date: Tue, 13 Jun 2017 20:32:53 +0300 Subject: [PATCH 1/2] Added variant of automatic geopositioning --- README.md | 11 ++++- angular-ymaps.js | 112 ++++++++++++++++++++++++++++++----------------- 2 files changed, 81 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 6076325..3bcea57 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,15 @@ Yandex Maps API as an Angular JS direcitive. Добавляет Яндекс-карту на страницу. Размеры карты определяются размерами элемента, их можно задать в css. При создании нужно указать два обязательных атрибута: -* **center**(Array) - массив из двух чисел, широта и долгота центра карты -* **zoom**(Number) - число, от 0 до 23, масштаб карты. Во избежание ошибок нужно задавать разрешенный масштаб для +* **center**(Array / String) +В случае указания строки 'auto', будет произведено автоматическое определение месторасположения пользователя +В противном случае необходимо указать массив из двух чисел - широта и долгота центра карты + +* **zoom**(Number / String) +В случае указания строки 'auto' будет автоматически вычислен масштаб, которые необходимо установить карте +для того, чтобы полностью отобразить переданную область. Режим 'auto' работает исключительно в паре с +автоматическим получением center +В противном случае указывается число от 0 до 23 - масштаб карты. Во избежание ошибок нужно задавать разрешенный масштаб для указанной области ####Тег ymap-marker: diff --git a/angular-ymaps.js b/angular-ymaps.js index 7e0f066..88fb663 100644 --- a/angular-ymaps.js +++ b/angular-ymaps.js @@ -118,50 +118,82 @@ angular.module('ymaps', []) self.removeMarker = function (marker) { $scope.markers.remove(marker); }; - self.map = new ymaps.Map($element[0], { - center : $scope.center || [0, 0], - zoom : $scope.zoom || 0, - behaviors: config.mapBehaviors - }); - var collection = new ymaps.GeoObjectCollection({}, config.markerOptions); - if(config.clusterize) { - $scope.markers = new ymaps.Clusterer(config.clusterOptions); - collection.add($scope.markers); - } else { - $scope.markers = collection; - } - self.map.geoObjects.add(collection); - if(config.fitMarkers) { - initAutoFit(self.map, collection, ymaps); - } - var updatingBounds, moving; - $scope.$watch('center', function(newVal) { - if(updatingBounds) { - return; - } - moving = true; - self.map.panTo(newVal).always(function() { - moving = false; + + var mapParams = { + center: $scope.center || [0, 0], + zoom: $scope.zoom || 0 + }; + if (mapParams.center == 'auto') { + ymaps.geolocation.get({ timeout: 2000 }).then(function (res) { + mapParams = { + center: res.geoObjects.position, + bounds: res.geoObjects.get(0).properties.get('boundedBy'), + zoom: $scope.zoom + }; + if ($scope.zoom == 'auto') { + var mapContainer = $element[0].getBoundingClientRect(); + mapParams.zoom = ymaps.util.bounds + .getCenterAndZoom( + mapParams.bounds, + [mapContainer.width, mapContainer.height] + ).zoom; + } + mapApproved(mapParams); + }, function (e) { mapApproved(mapParams); }); + } else { mapApproved(mapParams); } + + + function mapApproved(mapParams) { + self.map = new ymaps.Map($element[0], { + center : mapParams.center, + zoom : mapParams.zoom, + behaviors: config.mapBehaviors }); - }, true); - $scope.$watch('zoom', function(zoom) { - if(updatingBounds) { - return; + + var collection = new ymaps.GeoObjectCollection({}, config.markerOptions); + if(config.clusterize) { + $scope.markers = new ymaps.Clusterer(config.clusterOptions); + collection.add($scope.markers); + } else { + $scope.markers = collection; } - self.map.setZoom(zoom, {checkZoomRange: true}); - }); - self.map.events.add('boundschange', function(event) { - if(moving) { - return; + self.map.geoObjects.add(collection); + if(config.fitMarkers) { + initAutoFit(self.map, collection, ymaps); } - //noinspection JSUnusedAssignment - updatingBounds = true; - $scope.$apply(function() { - $scope.center = event.get('newCenter'); - $scope.zoom = event.get('newZoom'); + var updatingBounds, moving; + $scope.$watch('center', function(newVal) { + if(updatingBounds) { + return; + } + moving = true; + self.map.panTo(newVal).always(function() { + moving = false; + }); + }, true); + $scope.$watch('zoom', function(zoom) { + if(updatingBounds) { + return; + } + self.map.setZoom(zoom, {checkZoomRange: true}); + }); + self.map.events.add('boundschange', function(event) { + if(moving) { + return; + } + //noinspection JSUnusedAssignment + updatingBounds = true; + $scope.$apply(function() { + $scope.center = event.get('newCenter'); + $scope.zoom = event.get('newZoom'); + }); + updatingBounds = false; }); - updatingBounds = false; - }); + } + + + + }); }]) From 8289245cfa1096fcb52afaca83ae1969f0c36bae Mon Sep 17 00:00:00 2001 From: nfssfn Date: Fri, 16 Jun 2017 11:52:50 +0300 Subject: [PATCH 2/2] Reworked code due scope hotfix --- angular-ymaps.js | 143 +++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/angular-ymaps.js b/angular-ymaps.js index 88fb663..b2633f8 100644 --- a/angular-ymaps.js +++ b/angular-ymaps.js @@ -107,6 +107,26 @@ angular.module('ymaps', []) } }, 100)); } + function locateAuto(ymaps, continueCallback) { + if ($scope.autocenter) { + ymaps.geolocation.get({ timeout: 2000 }).then(function (res) { + var mapParams = { + center: res.geoObjects.position, + bounds: res.geoObjects.get(0).properties.get('boundedBy'), + zoom: $scope.zoom + }; + if ($scope.autozoom) { + var mapContainer = $element[0].getBoundingClientRect(); + mapParams.zoom = ymaps.util.bounds + .getCenterAndZoom( + mapParams.bounds, + [mapContainer.width, mapContainer.height] + ).zoom; + } + continueCallback(mapParams); + }, function () {}); + } + } var self = this; ymapsLoader.ready(function(ymaps) { self.addMarker = function(coordinates, properties, options) { @@ -118,83 +138,59 @@ angular.module('ymaps', []) self.removeMarker = function (marker) { $scope.markers.remove(marker); }; - - var mapParams = { - center: $scope.center || [0, 0], - zoom: $scope.zoom || 0 - }; - if (mapParams.center == 'auto') { - ymaps.geolocation.get({ timeout: 2000 }).then(function (res) { - mapParams = { - center: res.geoObjects.position, - bounds: res.geoObjects.get(0).properties.get('boundedBy'), - zoom: $scope.zoom - }; - if ($scope.zoom == 'auto') { - var mapContainer = $element[0].getBoundingClientRect(); - mapParams.zoom = ymaps.util.bounds - .getCenterAndZoom( - mapParams.bounds, - [mapContainer.width, mapContainer.height] - ).zoom; - } - mapApproved(mapParams); - }, function (e) { mapApproved(mapParams); }); - } else { mapApproved(mapParams); } - - - function mapApproved(mapParams) { - self.map = new ymaps.Map($element[0], { - center : mapParams.center, - zoom : mapParams.zoom, - behaviors: config.mapBehaviors - }); - - var collection = new ymaps.GeoObjectCollection({}, config.markerOptions); - if(config.clusterize) { - $scope.markers = new ymaps.Clusterer(config.clusterOptions); - collection.add($scope.markers); - } else { - $scope.markers = collection; + self.map = new ymaps.Map($element[0], { + center : $scope.center || [0, 0], + zoom : $scope.zoom || 0, + behaviors: config.mapBehaviors + }); + var collection = new ymaps.GeoObjectCollection({}, config.markerOptions); + if(config.clusterize) { + $scope.markers = new ymaps.Clusterer(config.clusterOptions); + collection.add($scope.markers); + } else { + $scope.markers = collection; + } + self.map.geoObjects.add(collection); + if(config.fitMarkers) { + initAutoFit(self.map, collection, ymaps); + } + var updatingBounds, moving; + $scope.$watch('center', function(newVal) { + if(updatingBounds) { + return; } - self.map.geoObjects.add(collection); - if(config.fitMarkers) { - initAutoFit(self.map, collection, ymaps); + moving = true; + self.map.panTo(newVal).always(function() { + moving = false; + }); + }, true); + $scope.$watch('zoom', function(zoom) { + if(updatingBounds) { + return; } - var updatingBounds, moving; - $scope.$watch('center', function(newVal) { - if(updatingBounds) { - return; - } - moving = true; - self.map.panTo(newVal).always(function() { - moving = false; - }); - }, true); - $scope.$watch('zoom', function(zoom) { - if(updatingBounds) { + self.map.setZoom(zoom, {checkZoomRange: true}); + }); + self.map.events.add('boundschange', function(event) { + if(moving) { return; - } - self.map.setZoom(zoom, {checkZoomRange: true}); + } + //noinspection JSUnusedAssignment + updatingBounds = true; + $scope.$apply(function() { + $scope.center = event.get('newCenter'); + $scope.zoom = event.get('newZoom'); }); - self.map.events.add('boundschange', function(event) { - if(moving) { - return; - } - //noinspection JSUnusedAssignment - updatingBounds = true; - $scope.$apply(function() { - $scope.center = event.get('newCenter'); - $scope.zoom = event.get('newZoom'); - }); - updatingBounds = false; + updatingBounds = false; + }); + locateAuto(ymaps, function(mapParams) { + var lst = updatingBounds; + updatingBounds = false; + $scope.$apply(function() { + $scope.center = mapParams.center; + $scope.zoom = mapParams.zoom; }); - } - - - - - + updatingBounds = lst; + }); }); }]) .directive('yandexMap', ['ymapsLoader', function (ymapsLoader) { @@ -204,6 +200,9 @@ angular.module('ymaps', []) terminal: true, transclude: true, scope: { + autocenter: '=', + autozoom: '=', + center: '=', zoom: '=' },