Search code examples
angularjsgoogle-mapsng-map

ng-map with multiple markers - only shows one marker with zoom


I am using ng-map and trying to show multiple markers on the google map. When the page loads I would like to see all the markers on the map scattered across countries.

The map is showing only a zoomed in portion of one marker. May be this is because I am assigning the map center to the last item in the array. When I scroll/zoom in and out of the map, I can then see all the markers.

I am not sure what the map center should be when there are multiple markers and how do I get a map view that will show all the markers when the map loads

Here is the code:

controller:

$scope.cityMetaData = [];
$scope.getCityInfo = function(){
    for(var i=0; i<$scope.cityIds.length; i++){
        var id = $scope.cityIds[i];
        GetCity.query({cityid: id}, function(data) { 
            if (data.status == "success") {
                var cityData = data;
                $scope.cityMetaData.push(cityData);
                $scope.addressMarker(cityData);
            }
        });
    }
}

$scope.addressMarker = function(cityItem) {
    var address = cityItem.cityName;
    geocoder = new google.maps.Geocoder();
    geocoder.geocode({
        'address' : address
    }, function(results, status) {
        if ( status == google.maps.GeocoderStatus.OK ) {
            $scope.lat = results[0].geometry.location.lat();
            $scope.lng = results[0].geometry.location.lng();
            $scope.markerData.push({
                "latitude" : results[0].geometry.location.lat(),
                "longitude" : results[0].geometry.location.lng(),
                "title" : results[0].formatted_address
            });
        } else {
            $log.info('Geocode was not successful for the following reason:' + status);
        }
    });
}
$scope.getCityInfo();

html:

<map center="[{{lat}},{{lng}}]" zoom="8" style="display:block; width:auto; height:auto;"> 
    <marker ng-repeat="pin in markerData" position="{{pin.latitude}},{{pin.longitude}}" title="{{pin.title}}"></marker>
</map>

sample $scope.markerData array :

[{"latitude":38.232417,"longitude":-122.6366524,"title":"Petaluma, CA, USA"},
{"latitude":34.1477849,"longitude":-118.14451550000001,"title":"Pasadena, CA, USA"},
{"latitude":40.7556818,"longitude":-73.8830701,"title":"Jackson Heights, Queens, NY, USA"},
{"latitude":32.7766642,"longitude":-96.79698789999998,"title":"Dallas, TX, USA"},
{"latitude":37.7974273,"longitude":-121.21605260000001,"title":"Manteca, CA, USA"},
{"latitude":37.48521520000001,"longitude":-122.23635480000002,"title":"Redwood City, CA, USA"}]

Solution

  • That's right, it occurs since the center and zoom properties are specified explicitly. In order to center and zoom automatically with respect to the markers fitBounds() function is intended.

    In angularjs-google-maps component you could specify zoom-to-include-markers attribute for that purpose:

    <map zoom-to-include-markers="true" style="display:block; width:auto; height:auto;">
        <marker ng-repeat="pin in markerData" position="{{pin.latitude}},{{pin.longitude}}" title="{{pin.title}}"></marker>
    </map>
    

    Modified example

    angular.module('mapApp', ['ngMap'])
        .controller('mapController', function (NgMap, $scope, $q, $log) {
    
            $scope.lat = 38.232417;
            $scope.lng = -122.6366524;
    
            $scope.markerData = [];
            $scope.cityMetaData = [];
            $scope.getCityInfo = function () {
                /*for (var i = 0; i < $scope.cityIds.length; i++) {
                    var id = $scope.cityIds[i];
                    GetCity.query({ cityid: id }, function (data) {
                        if (data.status == "success") {
                            var cityData = data;
                            $scope.cityMetaData.push(cityData);
                            $scope.addressMarker(cityData);
                        }
                    });
                }*/
    
                var data = [
                    { cityName: 'Petaluma, CA, USA' },
                    { cityName: 'Pasadena, CA, USA' },
                    { cityName: 'Jackson Heights, Queens, NY, USA' },
                    { cityName: 'Dallas, TX, USA' },
                    { cityName: 'Manteca, CA, USA' },
                    { cityName: 'Redwood City, CA, USA' },
                ];
                data.forEach(function (item) {
                    var cityData = item;
                    $scope.cityMetaData.push(cityData);
                    $scope.addressMarker(cityData);
                });
    
    
            }
    
            $scope.addressMarker = function (cityItem) {
                var deferred = $q.defer();
                var address = cityItem.cityName;
                var geocoder = new google.maps.Geocoder();
                geocoder.geocode({
                    'address': address
                }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        $scope.$apply(function () {
                            $scope.markerData.push({
                                "latitude": results[0].geometry.location.lat(),
                                "longitude": results[0].geometry.location.lng(),
                                "title": results[0].formatted_address
                            });
                        });
                    } else {
                        $log.info('Geocode was not successful for the following reason:' + status);
                    }
                });
            }
            $scope.getCityInfo();
        });
    <script src="https://maps.google.com/maps/api/js"></script>
    <script src="https://code.angularjs.org/1.3.15/angular.js"></script>
    <script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
    <div ng-app="mapApp" ng-controller="mapController">
     
        <map zoom-to-include-markers="true" style="display:block; width:auto; height:auto;">
            <marker ng-repeat="pin in markerData" position="{{pin.latitude}},{{pin.longitude}}" title="{{pin.title}}"></marker>
        </map>
    </div>

    Example 2

    angular.module('mapApp', ['ngMap'])
        .controller('mapController', function (NgMap, $scope, $q, $log) {
    
            NgMap.getMap().then(function(map) {
                $scope.map = map;
            });   
            
            $scope.currentPin = {title: ""};
            $scope.markerData = [];
            $scope.cityMetaData = [];
            $scope.getCityInfo = function () {
                
                var data = [
                    { cityName: 'Petaluma, CA, USA' },
                    { cityName: 'Pasadena, CA, USA' },
                    { cityName: 'Jackson Heights, Queens, NY, USA' },
                    { cityName: 'Dallas, TX, USA' },
                    { cityName: 'Manteca, CA, USA' },
                    { cityName: 'Redwood City, CA, USA' },
                ];
                data.forEach(function (item) {
                    var cityData = item;
                    $scope.cityMetaData.push(cityData);
                    $scope.addressMarker(cityData);
                });
            }
    
    
            $scope.showDetail = function (e, pin) {
              $scope.currentPin = pin;
              $scope.map.showInfoWindow('iw', this);
            };
    
            $scope.hideDetail = function () {
               $scope.map.hideInfoWindow('iw');
            };
    
            $scope.addressMarker = function (cityItem) {
                var deferred = $q.defer();
                var address = cityItem.cityName;
                var geocoder = new google.maps.Geocoder();
                geocoder.geocode({
                    'address': address
                }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        $scope.$apply(function () {
                            $scope.markerData.push({
                                "latitude": results[0].geometry.location.lat(),
                                "longitude": results[0].geometry.location.lng(),
                                "title": results[0].formatted_address
                            });
                        });
                    } else {
                        $log.info('Geocode was not successful for the following reason:' + status);
                    }
                });
            }
            $scope.getCityInfo();
        });
    <!--link href="style.css" rel="stylesheet"-->
    <script src="https://maps.google.com/maps/api/js"></script>
    <script src="https://code.angularjs.org/1.2.23/angular.js"></script>
    <script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
    <script src="map.js"></script>
    
    <div ng-app="mapApp" ng-controller="mapController">
        <map zoom-to-include-markers="true" style="display:block; width:auto; height:auto;">
            <marker ng-repeat="pin in markerData" position="{{pin.latitude}},{{pin.longitude}}" title="{{pin.title}}" on-click="showDetail(pin)"></marker>
            <info-window id="iw">
               <div ng-non-bindable="">
                    <!--h1>{{currentPin.title}}</h1--> 
               </div>
            </info-window>
        </map>
    </div>