Search code examples
angularjsgoogle-maps-api-3ionic-frameworkcordova-3angular-google-maps

angular-google-maps center zoom multiple markers


I'm using AngularJS for Google Maps and want to dynamically center and zoom a map based on multiple markers that are dynamically loaded. This is for a Cordova app using the Ionic Framework.

Here's my view:

<ion-view title="" ng-controller="MapCtrl as vm">
 <ion-content class="padding">
  <google-map id="mainMap" control="vm.googleMap" draggable="true" center="vm.map.center" zoom="vm.map.zoom" mark-click="false">
      <markers idKey="mainMap" fit="vm.map.fit">
          <marker idKey="marker.id" ng-repeat="marker in vm.map.markers" coords="marker.coords" options="marker.options">
              <marker-label content="marker.name" anchor="2 0" class="marker-labels"/>
          </marker>
      </markers>
  </google-map>
 </ion-content>
</ion-view>

Here's my controller:

angular.module('myApp.controllers', [])

.controller('MapCtrl', function($scope, $ionicPlatform) {
 var vm = this;
 vm.googleMap = {}; // this is filled when google map is initialized, but it's too late
 vm.mapMarkers = [];

 vm.arrMarkers = [
    {
        id: "home",
        name: "home",
        coords: {
            latitude:xxxxxxx, //valid coords
            longitude:xxxxxxx //valid coords
        },
        options: {
            animation: google.maps.Animation.BOUNCE
        }
    },
    {
        id: "placeAId",
        name: "Place A",
        coords: {
            latitude:xxxxxxx, //valid coords
            longitude:xxxxxxx //valid coords
        }
    },
    {
        id: "placeBId",
        name: "Place B",
        coords: {
            latitude:xxxxxxx, //valid coords
            longitude:xxxxxxx //valid coords
        }
    }
];
vm.map = {
    center: { //how to determine where to center???
        latitude: xxxxxxx, //valid coords
        longitude: xxxxxxx //valid coords
    },
    zoom: 12, //how to determine zoom dynamically???
    fit: true,
    markers: vm.arrMarkers
};

var setMapBounds = function () {
    var bounds = new google.maps.LatLngBounds();
    createMarkers();
    var markers = vm.mapMarkers;
    for(var i=0; i<markers.length; i++) {
        bounds.extend(markers[i].getPosition());
    }
    var map = vm.googleMap.control.getGMap();
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds);
    //remove one zoom level to ensure no marker is on the edge.
    map.setZoom(map.getZoom()-1);

    // set a minimum zoom
    // if you got only 1 marker or all markers are on the same address map will be zoomed too much.
    if(map.getZoom()> 15){
        map.setZoom(15);
    }
};

var createMarkers = function() {
    var map = vm.googleMap.control.getGMap(); //vm.googleMap.control is undefined because this fire before map is initialized
    angular.forEach(vm.restaurants, function(restaurant, index) {
        var marker = new google.maps.Marker({
            map: map,
            position: new google.maps.LatLng(restaurant.coords.latitude, restaurant.coords.longitude),
            title: restaurant.name
        });
        vm.mapMarkers.push(marker);
    });
};

$ionicPlatform.ready(function() {
    setMapBounds();
});

})

So, my question is how do I center and zoom the map using multiple dynamically loaded markers? Also, how do I get an instance of googleMap.control (vm.googleMap.control) before the map is loaded?


Solution

  • Here's my code just in case anyone was wondering how to do this locally. This is a simple solution for what I needed and my indeed go back to angualr-google maps, but as of now this works fine in my application.

    angular.module('myApp.controllers', [])
    .controller('MapCtrl', function($scope) {
        var vm = this;
        vm.googleMap = null; 
        vm.mapMarkers = [];
    
        var onSuccess = function(position) {
            vm.userLocation.coords.latitude = position.coords.latitude;
            vm.userLocation.coords.longitude = position.coords.longitude;
    
            initializeMap();
        };
    
        var onError = function(error) {
            alert('code: ' + error.code + '\n' + 'message: ' + error.message);
        };
    
        vm.userLocation = {
            id: "home",
            title: "home",
            coords: {
                latitude: 33.636727,
                longitude: -83.920702
            },
            options: {
                animation: google.maps.Animation.BOUNCE
            }
        };
    
        vm.places = [
            {
                id: "78869C43-C694-40A5-97A0-5E709AA6CE51",
                title: "Place A",
                coords: {
                    latitude: 33.625296,
                    longitude: -83.976206
                }
            },
            {
                id: "52319278-83AA-46D4-ABA6-307EAF820E77",
                title: "Place B",
                coords: {
                    latitude: 33.576522,
                    longitude: -83.964981
                }
            }
        ];
    
        var addMarkers = function() {
            var userLocation = new google.maps.Marker({
                map: vm.googleMap,
                position: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude),
                //animation: vm.userLocation.options.animation,
                title: vm.userLocation.title
            });
    
            vm.mapMarkers.push(userLocation);
    
            angular.forEach(vm.places, function(location, index) {
                var marker = new google.maps.Marker({
                    map: vm.googleMap,
                    position: new google.maps.LatLng(location.coords.latitude, location.coords.longitude),
                    title: location.title
                });
                vm.mapMarkers.push(marker);
            });
    
            var bounds = new google.maps.LatLngBounds();
    
            for (var i = 0; i < vm.mapMarkers.length; i++) {
                bounds.extend(vm.mapMarkers[i].getPosition());
            }
            vm.googleMap.setCenter(bounds.getCenter());
            vm.googleMap.fitBounds(bounds);
            //remove one zoom level to ensure no marker is on the edge.
            vm.googleMap.setZoom(vm.googleMap.getZoom() - 1);
    
            // set a minimum zoom
            // if you got only 1 marker or all markers are on the same address map will be zoomed too much.
            if (vm.googleMap.getZoom() > 15) {
                vm.googleMap.setZoom(15);
            }
        };
    
        var initializeMap = function() {
            var mapOptions = {
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                zoom: 12,
                center: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude)
            };
            var div = document.getElementById("map_canvas");
            //var map = plugin.google.maps.Map.getMap(div, mapOptions);
            vm.googleMap = new google.maps.Map(div, mapOptions);
            addMarkers();
    
            var width = screen.width;
            var height = screen.height;
        };
    
        navigator.geolocation.getCurrentPosition(onSuccess, onError);
    
    })