无论地图视图/缩放如何,如何使用 Google Maps API 一次只能看到 10 个标记

Posted

技术标签:

【中文标题】无论地图视图/缩放如何,如何使用 Google Maps API 一次只能看到 10 个标记【英文标题】:How to only see 10 markers at a time with Google Maps API regardless of map view/zoom 【发布时间】:2020-07-15 01:07:30 【问题描述】:

我希望改进我的网络应用程序中的 Google 地图。我在地图上有大约 200 个标记,但显然这在视觉上并不吸引人。我想知道是否有一种方法可以根据变量摄氏度只显示 10 个标记?因此,如果地图基于整个世界视图,您会看到记录了 10 个最高温度的标记。如果您移动到世界地图上的另一部分或放大,我希望标记更新。

这可能吗?我试图通过包含最多 10 个标记来做到这一点,但我无法让它成为动态的,因为当我添加标记时,我会通过 JSON 文件进行解析。输出如下 "AA": "celsius": 32.27777777777778, "country": "AA", "day": "25", "lat": 12.5, "lon": -70.017, "month": “03”。

这是我最后一个功能齐全的代码..

    // Declare map and markers array globally
    var map, markers = [];

    function initMap() 

      var myLatLng = 
        lat: 0,
    lng: 0
  ;

  map = new google.maps.Map(document.getElementById('map'), 
    zoom: 2,
    center: myLatLng,
    zoomControl: true
  );

  // Moved this out of the AJAX success and declared variable correctly
  var infowindow = new google.maps.InfoWindow();

  // Listen for zoom change event
  google.maps.event.addListener(map, 'zoom_changed', function() 

    // Handle markers display
    handleMarkersDisplay();
  );

  $.ajax(
    type: 'GET',
    url: 'https://us-central1-cloud-calendar-project.cloudfunctions.net/InfoWindow',
    success: function(data) 

      data = JSON.parse(data);

      for (var element in data) 

       var marker = new google.maps.Marker(
         position: 
           lat: data[element].lat,
           lng: data[element].lon
         ,
         map: map,
         title: element,
         visible: false, // Default visibility is false
         marker_celsius: data[element].celsius // Add celsius as marker property
       );

       // Push this marker to the markers array
       markers.push(marker);

       google.maps.event.addListener(marker, 'click', (function(marker, element) 

         return function() 

           var content = 'Country: ' + data[element].country;
           content += '<br>Temperature (°C): ' + data[element].celsius;

           infowindow.setContent(content);
           infowindow.open(map, marker);
          

        )(marker, element));
      

      // All markers have been added, sort the markers array by celsius value
      markers.sort(function(a, b) 
        return b.marker_celsius - a.marker_celsius;
      );

      // Handle markers display
      handleMarkersDisplay();
    
  );


function handleMarkersDisplay() 

  // Check if map current zoom <= 2
  if (map.getZoom() <= 2) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 3) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 4) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 5) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 6) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 7) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 8 ) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 9) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else if (map.getZoom() == 10) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else 

    // Zoom is greater than 3, show all markers
    for (var i = 0; i < markers.length; i++) 

      markers[i].setVisible(true);
    
  

【问题讨论】:

【参考方案1】:

你需要两件事:

    将摄氏度值作为属性添加到每个 Marker 对象 将每个 Marker 对象添加到标记数组中,以便保留它们的引用

Google Maps API 提供多个events 供您收听。其中之一是zoom_changed 事件。有了这个你可以遵循这个逻辑:

    使用 AJAX 请求数据 创建每个标记对象并将其可见性设置为false 将摄氏度值添加为标记属性 将每个标记添加到标记数组中

完成此操作并创建所有标记后:

    按摄氏度对标记数组进行排序 检查当前缩放级别 如果缩放级别低于 n,则循环遍历标记并仅显示 n 个项目 如果缩放级别高于 n,则循环显示标记并全部显示

并在用户通过监听zoom_changed 事件更改缩放级别时重复该逻辑。

如果缩放

// Declare map and markers array globally
var map, markers = [];

function initMap() 

  var myLatLng = 
    lat: 0,
    lng: 0
  ;

  map = new google.maps.Map(document.getElementById('map'), 
    zoom: 2,
    center: myLatLng,
    zoomControl: true
  );
  
  // Moved this out of the AJAX success and declared variable correctly
  var infowindow = new google.maps.InfoWindow();

  // Listen for zoom change event
  google.maps.event.addListener(map, 'zoom_changed', function() 

    // Handle markers display
    handleMarkersDisplay();
  );

  $.ajax(
    type: 'GET',
    url: 'https://us-central1-cloud-calendar-project.cloudfunctions.net/InfoWindow',
    success: function(data) 

      data = JSON.parse(data);

      for (var element in data) 

        var marker = new google.maps.Marker(
          position: 
            lat: data[element].lat,
            lng: data[element].lon
          ,
          map: map,
          title: element,
          visible: false, // Default visibility is false
          marker_celsius: data[element].celsius // Add celsius as marker property
        );

        // Push this marker to the markers array
        markers.push(marker);

        google.maps.event.addListener(marker, 'click', (function(marker, element) 

          return function() 

            var content = 'Country: ' + data[element].country;
            content += '<br>Temperature (°C): ' + data[element].celsius;

            infowindow.setContent(content);
            infowindow.open(map, marker);
          

        )(marker, element));
      

      // All markers have been added, sort the markers array by celsius value
      markers.sort(function(a, b) 
        return b.marker_celsius - a.marker_celsius;
      );

      // Handle markers display
      handleMarkersDisplay();
    
  );


function handleMarkersDisplay() 

  // Check if map current zoom <= 2
  if (map.getZoom() <= 2) 

    // Loop through markers array
    for (var i = 0; i < markers.length; i++) 

      // Only show the first 10 markers
      if (i < 10) 
        markers[i].setVisible(true);
       else 
        markers[i].setVisible(false);
      
    
   else 

    // Zoom is greater than 2, show all markers
    for (var i = 0; i < markers.length; i++) 

      markers[i].setVisible(true);
    
  
#map 
  height: 180px;
<div id="map"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>

【讨论】:

用你的尝试更新你的问题。我不知道你把这段代码放在哪里,它作为评论是不可读的。 我不明白你想要达到什么目的。您添加的每个else if 都完全相同:它仅显示具有最高摄氏度值的 10 个标记。有什么意义? 目前,如果我放大标记只会消失。似乎没有新的标记可以使视图中始终有 10 个标记。因此,如果我从缩放 2 移动到缩放 3,我有 8 个标记洞察而不是 10 个。我还希望代码根据该特定视图的前 10 个最高温度添加标记。目前它只是将它们删除,直到最后一个。 这并不能解释您想要实现的目标 + 也许您看到 8 个标记,但地图上总是有 10 个可见(只是四处走动)。 MrUpsidDown,非常感谢您对这个问题(也是我的最后一个问题)的帮助和支持。在一个很难联系我的教授的时候,你让我更容易学习。我想承认这一点,所以谢谢!

以上是关于无论地图视图/缩放如何,如何使用 Google Maps API 一次只能看到 10 个标记的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 的 Google 地图中显示路线时缩放到源点。

如何设置谷歌地图缩放级别以显示所有标记?

如何在谷歌地图中找到当前的缩放级别?

如何在Google地图中查找当前缩放级别?

使用 kml 文件时,Google 地图缩放被覆盖

如何使用滑块更改 mapkit 地图视图缩放级别?