这是我用来显示一个有3个针/标记的地图:

<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>

我正在寻找的是一种避免必须“手动”找到地图中心的方法:new google.maps.LatLng(41.923, 12.513)。是否有一种方法可以自动将地图置于三个坐标的中心?


当前回答

为了找到地图的准确中心,你需要将纬度/经度坐标转换为像素坐标,然后找到像素中心并将其转换回纬度/经度坐标。

你可能不会注意到或介意这种漂移,这取决于你在赤道以北或以南多远。你可以通过在setInterval中执行map.setCenter(map.getBounds(). getcenter())来看到漂移,漂移会在接近赤道时慢慢消失。

您可以使用以下代码在纬度/长度和像素坐标之间进行转换。像素坐标是基于完全放大的整个世界的平面,但你可以找到它的中心,并将其切换回纬度/长度。

   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;
   }

其他回答

我有一个情况,我不能改变旧的代码,所以添加了这个javascript函数来计算中心点和缩放级别:

//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; }

我认为你必须计算纬度和经度最小值: 下面是一个示例函数,用来集中你的观点:

//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)
));

另一个实现,基于前面的答案,但更精简:

export class MapComponent {
    @ViewChild(GoogleMap) map: GoogleMap;

    markerList = [
        {
            lat: 41.926979,
            lng: 12.517385
        },
        {
            lat: 41.914873,
            lng: 12.506486
        },
        {
            lat: 41.918574, 
            lng: 12.507201
        }
    ]

    centralize() {
        const bounds = new google.maps.LatLngBounds();
        this.markerList.forEach((marker) => {
            bounds.extend(new google.maps.LatLng(marker.lat, marker.lng))
        })
        this.map.fitBounds(bounds)
    }
}

你不需要创建一个“google.maps”。标记”,你可以从LatLng创建一个实例,并直接将其作为参数传递给边界扩展函数。

我已经尝试了这个主题的所有答案,但下面这个在我的项目中工作得很好。

Angular 7和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>

属性[agmFitBounds]="true"在agm-marker和[fitBounds]="true"在agm-map做这项工作

有一个更简单的方法,通过扩展一个空的LatLngBounds,而不是显式地从两个点创建一个。(详见这个问题)

应该是这样的,添加到你的代码:

//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);
});

这样,您可以使用任意数量的点,并且不需要事先知道顺序。

演示jsFiddle在这里:http://jsfiddle.net/x5R63/