[javascript] Auto-center map with multiple markers in Google Maps API v3

This is what I use to display a map with 3 pins/markers:

<script>
  function initialize() {
    var locations = [
      ['DESCRIPTION', 41.926979, 12.517385, 3],
      ['DESCRIPTION', 41.914873, 12.506486, 2],
      ['DESCRIPTION', 41.918574, 12.507201, 1]
    ];

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 15,
      center: new google.maps.LatLng(41.923, 12.513),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) {
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
  }

  function loadScript() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&' + 'callback=initialize';
    document.body.appendChild(script);
  }

  window.onload = loadScript;
</script>

<div id="map" style="width: 900px; height: 700px;"></div>

What I’m looking for is a way to avoid having to “manually” find the center of the map with center: new google.maps.LatLng(41.923, 12.513). Is there a way to automatically have the map centered on the three coordinates?

The answer is


I've tryied all answers of this topic, but just this below worked fine on my project.

Angular 7 and AGM Core 1.0.0-beta.7

<agm-map [latitude]="lat" [longitude]="long" [zoom]="zoom" [fitBounds]="true">
  <agm-marker latitude="{{localizacao.latitude}}" longitude="{{localizacao.longitude}}" [agmFitBounds]="true"
    *ngFor="let localizacao of localizacoesTec">
  </agm-marker>
</agm-map>

The properties [agmFitBounds]="true" at agm-marker and [fitBounds]="true" at agm-map does the job


I think you have to calculate latitudine min and longitude min: Here is an Example with the function to use to center your point:

//Example values of min & max latlng values
var lat_min = 1.3049337;
var lat_max = 1.3053515;
var lng_min = 103.2103116;
var lng_max = 103.8400188;

map.setCenter(new google.maps.LatLng(
  ((lat_max + lat_min) / 2.0),
  ((lng_max + lng_min) / 2.0)
));
map.fitBounds(new google.maps.LatLngBounds(
  //bottom left
  new google.maps.LatLng(lat_min, lng_min),
  //top right
  new google.maps.LatLng(lat_max, lng_max)
));

To find the exact center of the map you'll need to translate the lat/lon coordinates into pixel coordinates and then find the pixel center and convert that back into lat/lon coordinates.

You might not notice or mind the drift depending how far north or south of the equator you are. You can see the drift by doing map.setCenter(map.getBounds().getCenter()) inside of a setInterval, the drift will slowly disappear as it approaches the equator.

You can use the following to translate between lat/lon and pixel coordinates. The pixel coordinates are based on a plane of the entire world fully zoomed in, but you can then find the center of that and switch it back into lat/lon.

   var HALF_WORLD_CIRCUMFERENCE = 268435456; // in pixels at zoom level 21
   var WORLD_RADIUS = HALF_WORLD_CIRCUMFERENCE / Math.PI;

   function _latToY ( lat ) {
      var sinLat = Math.sin( _toRadians( lat ) );
      return HALF_WORLD_CIRCUMFERENCE - WORLD_RADIUS * Math.log( ( 1 + sinLat ) / ( 1 - sinLat ) ) / 2;
   }

   function _lonToX ( lon ) {
      return HALF_WORLD_CIRCUMFERENCE + WORLD_RADIUS * _toRadians( lon );
   }

   function _xToLon ( x ) {
      return _toDegrees( ( x - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS );
   }

   function _yToLat ( y ) {
      return _toDegrees( Math.PI / 2 - 2 * Math.atan( Math.exp( ( y - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS ) ) );
   }

   function _toRadians ( degrees ) {
      return degrees * Math.PI / 180;
   }

   function _toDegrees ( radians ) {
      return radians * 180 / Math.PI;
   }

i had a situation where i can't change old code, so added this javascript function to calculate center point and zoom level:

_x000D_
_x000D_
//input_x000D_
var tempdata = ["18.9400|72.8200-19.1717|72.9560-28.6139|77.2090"];_x000D_
_x000D_
function getCenterPosition(tempdata){_x000D_
 var tempLat = tempdata[0].split("-");_x000D_
 var latitudearray = [];_x000D_
 var longitudearray = [];_x000D_
 var i;_x000D_
 for(i=0; i<tempLat.length;i++){_x000D_
  var coordinates = tempLat[i].split("|");_x000D_
  latitudearray.push(coordinates[0]);_x000D_
  longitudearray.push(coordinates[1]);_x000D_
 }_x000D_
 latitudearray.sort(function (a, b) { return a-b; });_x000D_
 longitudearray.sort(function (a, b) { return a-b; });_x000D_
 var latdifferenece = latitudearray[latitudearray.length-1] - latitudearray[0];_x000D_
 var temp = (latdifferenece / 2).toFixed(4) ;_x000D_
 var latitudeMid = parseFloat(latitudearray[0]) + parseFloat(temp);_x000D_
 var longidifferenece = longitudearray[longitudearray.length-1] - longitudearray[0];_x000D_
 temp = (longidifferenece / 2).toFixed(4) ;_x000D_
 var longitudeMid = parseFloat(longitudearray[0]) + parseFloat(temp);_x000D_
 var maxdifference = (latdifferenece > longidifferenece)? latdifferenece : longidifferenece;_x000D_
 var zoomvalue; _x000D_
 if(maxdifference >= 0 && maxdifference <= 0.0037)  //zoom 17_x000D_
  zoomvalue='17';_x000D_
 else if(maxdifference > 0.0037 && maxdifference <= 0.0070)  //zoom 16_x000D_
  zoomvalue='16';_x000D_
 else if(maxdifference > 0.0070 && maxdifference <= 0.0130)  //zoom 15_x000D_
  zoomvalue='15';_x000D_
 else if(maxdifference > 0.0130 && maxdifference <= 0.0290)  //zoom 14_x000D_
  zoomvalue='14';_x000D_
 else if(maxdifference > 0.0290 && maxdifference <= 0.0550)  //zoom 13_x000D_
  zoomvalue='13';_x000D_
 else if(maxdifference > 0.0550 && maxdifference <= 0.1200)  //zoom 12_x000D_
  zoomvalue='12';_x000D_
 else if(maxdifference > 0.1200 && maxdifference <= 0.4640)  //zoom 10_x000D_
  zoomvalue='10';_x000D_
 else if(maxdifference > 0.4640 && maxdifference <= 1.8580)  //zoom 8_x000D_
  zoomvalue='8';_x000D_
 else if(maxdifference > 1.8580 && maxdifference <= 3.5310)  //zoom 7_x000D_
  zoomvalue='7';_x000D_
 else if(maxdifference > 3.5310 && maxdifference <= 7.3367)  //zoom 6_x000D_
  zoomvalue='6';_x000D_
 else if(maxdifference > 7.3367 && maxdifference <= 14.222)  //zoom 5_x000D_
  zoomvalue='5';_x000D_
 else if(maxdifference > 14.222 && maxdifference <= 28.000)  //zoom 4_x000D_
  zoomvalue='4';_x000D_
 else if(maxdifference > 28.000 && maxdifference <= 58.000)  //zoom 3_x000D_
  zoomvalue='3';_x000D_
 else_x000D_
  zoomvalue='1';_x000D_
 return latitudeMid+'|'+longitudeMid+'|'+zoomvalue;_x000D_
}
_x000D_
_x000D_
_x000D_


This work for me in Angular 9:

  import {GoogleMap, GoogleMapsModule} from "@angular/google-maps";
  @ViewChild('Map') Map: GoogleMap; /* Element Map */

  locations = [
   { lat: 7.423568, lng: 80.462287 },
   { lat: 7.532321, lng: 81.021187 },
   { lat: 6.117010, lng: 80.126269 }
  ];

  constructor() {
   var bounds = new google.maps.LatLngBounds();
    setTimeout(() => {
     for (let u in this.locations) {
      var marker = new google.maps.Marker({
       position: new google.maps.LatLng(this.locations[u].lat, 
       this.locations[u].lng),
      });
      bounds.extend(marker.getPosition());
     }

     this.Map.fitBounds(bounds)
    }, 200)
  }

And it automatically centers the map according to the indicated positions.

Result:

enter image description here


Here's my take on this in case anyone comes across this thread:

This helps protect against non-numerical data destroying either of your final variables that determine lat and lng.

It works by taking in all of your coordinates, parsing them into separate lat and lng elements of an array, then determining the average of each. That average should be the center (and has proven true in my test cases.)

var coords = "50.0160001,3.2840073|50.014458,3.2778274|50.0169713,3.2750587|50.0180745,3.276742|50.0204038,3.2733474|50.0217796,3.2781737|50.0293064,3.2712542|50.0319918,3.2580816|50.0243287,3.2582281|50.0281447,3.2451177|50.0307925,3.2443178|50.0278165,3.2343882|50.0326574,3.2289809|50.0288569,3.2237612|50.0260081,3.2230589|50.0269495,3.2210104|50.0212645,3.2133541|50.0165868,3.1977592|50.0150515,3.1977341|50.0147901,3.1965286|50.0171915,3.1961636|50.0130074,3.1845098|50.0113267,3.1729483|50.0177206,3.1705726|50.0210692,3.1670394|50.0182166,3.158297|50.0207314,3.150927|50.0179787,3.1485753|50.0184944,3.1470782|50.0273077,3.149845|50.024227,3.1340514|50.0244172,3.1236235|50.0270676,3.1244474|50.0260853,3.1184879|50.0344525,3.113806";

var filteredtextCoordinatesArray = coords.split('|');    

    centerLatArray = [];
    centerLngArray = [];


    for (i=0 ; i < filteredtextCoordinatesArray.length ; i++) {

      var centerCoords = filteredtextCoordinatesArray[i]; 
      var centerCoordsArray = centerCoords.split(',');

      if (isNaN(Number(centerCoordsArray[0]))) {      
      } else {
        centerLatArray.push(Number(centerCoordsArray[0]));
      }

      if (isNaN(Number(centerCoordsArray[1]))) {
      } else {
        centerLngArray.push(Number(centerCoordsArray[1]));
      }                    

    }

    var centerLatSum = centerLatArray.reduce(function(a, b) { return a + b; });
    var centerLngSum = centerLngArray.reduce(function(a, b) { return a + b; });

    var centerLat = centerLatSum / filteredtextCoordinatesArray.length ; 
    var centerLng = centerLngSum / filteredtextCoordinatesArray.length ;                                    

    console.log(centerLat);
    console.log(centerLng);

    var mapOpt = {      
    zoom:8,
    center: {lat: centerLat, lng: centerLng}      
    };

I use the method above to set the map boundaries, then, instead of resetting the zoom level, I just calculate the average LAT and average LON and set the center point to that location. I add up all the lat values into latTotal and all the lon values into lontotal and then divide by the number of markers. I then set the map center point to those average values.

latCenter = latTotal / markercount; lonCenter = lontotal / markercount;


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to google-maps

GoogleMaps API KEY for testing Google Maps shows "For development purposes only" java.lang.NoClassDefFoundError:failed resolution of :Lorg/apache/http/ProtocolVersion How to import JSON File into a TypeScript file? Googlemaps API Key for Localhost Getting "Cannot call a class as a function" in my React Project ERROR: Google Maps API error: MissingKeyMapError This page didn't load Google Maps correctly. See the JavaScript console for technical details Google Maps API warning: NoApiKeys ApiNotActivatedMapError for simple html page using google-places-api

Examples related to google-maps-api-3

Google Maps shows "For development purposes only" Googlemaps API Key for Localhost ERROR: Google Maps API error: MissingKeyMapError Google Maps API warning: NoApiKeys Google Maps JavaScript API RefererNotAllowedMapError This API project is not authorized to use this API. Please ensure that this API is activated in the APIs Console TypeError: window.initMap is not a function Google maps Marker Label with multiple characters Google Maps how to Show city or an Area outline How to use SVG markers in Google Maps API v3

Examples related to google-maps-markers

How to change icon on Google map marker Auto-center map with multiple markers in Google Maps API v3 Resize Google Maps marker icon image How to create a custom-shaped bitmap marker with Android map API v2 Draw path between two points using Google Maps Android API v2 Google Maps API Multiple Markers with Infowindows Javascript, Change google map marker color How do you create a Marker with a custom icon for google maps API v3? Selecting last element in JavaScript array google maps v3 marker info window on mouseover