Google Maps API v3中包含多个标记的自动中心地图

时间:2013-03-30 15:03:34

标签: javascript google-maps google-maps-api-3 google-maps-markers

这是我用来显示带有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>

我正在寻找的是避免使用center: new google.maps.LatLng(41.923, 12.513)“手动”找到地图中心的方法。有没有办法让地图自动以三个坐标为中心?

9 个答案:

答案 0 :(得分:404)

通过扩展空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); }); ,有一种更简单的方法。 (有关详细信息,请参阅this question

应该看起来像这样,添加到您的代码中:

{{1}}

这样,您可以使用任意数量的点,而不需要事先知道订单。

演示jsFiddle:http://jsfiddle.net/x5R63/

答案 1 :(得分:24)

我认为你必须计算纬度最小和经度min: 下面是一个示例,其中包含用于使您的观点居中的功能:

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

答案 2 :(得分:1)

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

你可能没有注意到或想到漂移取决于赤道北部或南部的距离。您可以通过在setInterval中执行map.setCenter(map.getBounds()。getCenter())来查看漂移,漂移将在接近赤道时慢慢消失。

您可以使用以下内容在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;
   }

答案 3 :(得分:1)

此功能适用于 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)
  }

它会根据指示的位置自动将地图居中。

结果:

enter image description here

答案 4 :(得分:1)

我已经尝试了该主题的所有答案,但是下面的内容在我的项目中工作正常。

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完成工作

答案 5 :(得分:1)

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

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.Marker”,您只需从 LatLng 创建一个实例,然后直接将其作为参数传递给边界扩展函数即可。

答案 6 :(得分:0)

我使用上面的方法设置地图边界,然后,而不是重置缩放级别,我 只需计算平均LAT和平均LON,并将中心点设置为该位置。 我将所有lat值加到latTotal中,将所有lon值加到lontotal中,然后除以标记数。然后我将地图中心点设置为这些平均值。

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

答案 7 :(得分:0)

我遇到了无法更改旧代码的情况,因此添加了此javascript函数来计算中心点和缩放级别:

SELECT  t1.code as code1, t1.value as value1,
        t2.code as code2, t2.value as value2, 
        t3.code as code3, t3.value as value3 
FROM tab as t1
    left join tab as t2
        ON t1.id = t2.id - 1
    left join  tab as t3
        ON t2.id = t3.id - 1
where ((t1.id-1) % 3) = 0           

答案 8 :(得分:0)

这是我对此的看法,万一有人遇到这个帖子:

这有助于防止非数字数据破坏决定latlng的最终变量。

它的工作原理是接收所有坐标,将它们解析为数组的单独latlng元素,然后确定每个坐标的平均值。该平均值应该是中心(并且在我的测试用例中证明是正确的。)

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