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

后端 未结 8 995
梦如初夏
梦如初夏 2020-12-07 06:38

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



        
相关标签:
8条回答
  • 2020-12-07 07:09

    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;
       }
    
    0 讨论(0)
  • 2020-12-07 07:14

    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

    0 讨论(0)
  • 2020-12-07 07:18

    There's an easier way, by extending an empty LatLngBounds rather than creating one explicitly from two points. (See this question for more details)

    Should look something like this, added to your code:

    //create empty LatLngBounds object
    var bounds = new google.maps.LatLngBounds();
    var infowindow = new google.maps.InfoWindow();    
    
    for (i = 0; i < locations.length; i++) {  
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });
    
      //extend the bounds to include each marker's position
      bounds.extend(marker.position);
    
      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
    
    //now fit the map to the newly inclusive bounds
    map.fitBounds(bounds);
    
    //(optional) restore the zoom level after the map is done scaling
    var listener = google.maps.event.addListener(map, "idle", function () {
        map.setZoom(3);
        google.maps.event.removeListener(listener);
    });
    

    This way, you can use an arbitrary number of points, and don't need to know the order beforehand.

    Demo jsFiddle here: http://jsfiddle.net/x5R63/

    0 讨论(0)
  • 2020-12-07 07:19

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

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

    0 讨论(0)
  • 2020-12-07 07:31

    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;

    0 讨论(0)
  • 2020-12-07 07:33

    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)
    ));
    
    0 讨论(0)
提交回复
热议问题