dylanfprice / angular-gm

AngularJS Google Maps Directives
MIT License
198 stars 47 forks source link

Set center and zoom based on list of lats/longs #53

Closed Bhaall closed 10 years ago

Bhaall commented 10 years ago

I'm having much difficulty dynamically setting the center and zoom level based on a list of lats/longs. I can't find a good example of this using AngularGM, and being such a noob with Google Maps I could definitely use some help.

I also see that there are similar questions asked here - about gm-bounds and fitBounds - but none of these have any example code.

The map's controller code:

var lats = [], longs = [], latlng = [];

// get list of lats/longs
for (i = 0; i < $scope.markersProperty.length; i++) {
    lats[i] = $scope.markersProperty[i].latitude;
    longs[i] = $scope.markersProperty[i].longitude;
    latlng.push(new google.maps.LatLng(lats[i], longs[i]));
}

$scope.bounds = new google.maps.LatLngBounds();

for (var i = 0, i < latlng.length; i++) {
    $scope.bounds.extend(latlng[i]);
}

$scope.options = {
    map: {
        center: $scope.bounds.getCenter(), // this seems to work
        //zoom: 10, // how to set this dynamically based on bounds?
        mapTypeId: google.maps.MapTypeId.ROADMAP
    },
};

The 'center' setting seems to work.

Any help with setting the zoom (and center, if I'm doing it incorrectly here) would be greatly appreciated.

Bhaall commented 10 years ago

OK I think I've found a solution.

var lats = [], longs = [], latlng = [];
for(i=0; i<$scope.markersProperty.length; i++) {
    if ($scope.markersProperty[i].latitude != null && $scope.markersProperty[i].latitude !== undefined) {
        lats[i] = $scope.markersProperty[i].latitude;
        longs[i] = $scope.markersProperty[i].longitude;
        latlng.push(new google.maps.LatLng(lats[i], longs[i]));
    }
}
// get bounds to calc map center
$scope.bounds = new google.maps.LatLngBounds();
for (var i = 0, LtLgLen = latlng.length; i < LtLgLen; i++) {
    $scope.bounds.extend (latlng[i]);
}
// function to calc zoom level
var mapDim = {height: 400, width: 560};
function getBoundsZoomLevel(bounds, mapDim) {
        var WORLD_DIM = { height: 256, width: 256 };
        var ZOOM_MAX = 21;
        function latRad(lat) {
        var sin = Math.sin(lat * Math.PI / 180);
        var radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
        return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
        }
        function zoom(mapPx, worldPx, fraction) {
        return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
        }
        var ne = bounds.getNorthEast();
        var sw = bounds.getSouthWest();
        var latFraction = (latRad(ne.lat()) - latRad(sw.lat())) / Math.PI;
        var lngDiff = ne.lng() - sw.lng();
        var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
        var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
        var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);
        return Math.min(latZoom, lngZoom, ZOOM_MAX);
}
$scope.options = {
    map: {
        center: $scope.bounds.getCenter(),
        zoom: getBoundsZoomLevel($scope.bounds, mapDim),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    },
};
trippingtarballs commented 9 years ago

:+1: nice one @Bhaall, this post has helped me a lot.