简体   繁体   中英

How to update my function so that there are always 10 markers on Google Maps regardless of zoom and view (Mashup used CS50)

This is the updated final code that I got it to work. I use the get.zoom and center.change to ensure that no matter the view of the map, there will always be 10 markers on the map! (original question below

'''


    // 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
  // Handle markers display
  google.maps.event.addListener(map, 'zoom_changed', 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
        });
        console.log("marker@" + marker.getPosition().toUrlValue());
        // 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;
            content += '<br>Day: ' + data[element].day;
            content += '<br>Month: ' + data[element].month;

            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;
      });
      map.addListener('center_changed', function() {
      window.setTimeout(handleMarkersDisplay() , 3000);
      });

      // Handle markers display
      handleMarkersDisplay();
    }
  });
}



function handleMarkersDisplay() {
  console.log("handleMarkerDisplay zoom=" + map.getZoom());
  // Check if map current zoom <= 2
  if (map.getZoom() <= 2) {
    hideAllMarkers();
    displayMarkers();
  } else if (map.getZoom() == 3) {
    hideAllMarkers();
    displayMarkers();
  } else if (map.getZoom() == 4) {
    hideAllMarkers();
    displayMarkers();
  } else if (map.getZoom() == 5) {
    hideAllMarkers();
    displayMarkers();
  }
}

function hideAllMarkers() {
  for (i = 0; i < markers.length; i++) {
    markers[i].setVisible(false);
  }
}

function displayMarkers() {
  // add new markers to map
  var shownMarkers = 10;
  for (var i = 0; i < markers.length; i++) {
    // Only show the first 10 markers in the viewport
    if (shownMarkers > 0) {
      if (map.getBounds().contains(markers[i].getPosition())) {
        markers[i].setVisible(true);
        shownMarkers--;
      }
    } else {
      markers[i].setVisible(false);
    }
  }
}

function displayAllMarkers() {
  // Zoom is greater than 3, show all markers
  for (var i = 0; i < markers.length; i++) {
    markers[i].setVisible(true);
  }
}

'''

I am working on a web application whereby I want to show markers on a map based on the highest temperature recorded (from a JSON file I parse through). Currently, I am able to get the 10 highest temperatures markers on the map but when I zoom in it does not get updated to add new markers. So when I zoom in one I go from 10 markers to 8 markers in view(you need to scroll to see the other two markers). I would like to add two new markers that correspond to the next highest markers for that view so that whatever view/zoom you have you always see 10 markers, (probably not possible at some level. eg only see one country), The picture below demonstrates that at zoom 3. two markers are left out of view. I found this implementation ( https://github.com/endiliey/cs50/blob/master/pset8/mashup/static/scripts.js ) by endiliey. However the implementation is not working..

If you want to show the highest 10 markers in the viewport, you need to count those:

function displayMarkers() {
  // add new markers to map
  var shownMarkers = 10;
  for (var i = 0; i < markers.length; i++) {
    // Only show the first 10 markers in the viewport
    if (shownMarkers > 0) {
      if (map.getBounds().contains(markers[i].getPosition())) {
        markers[i].setVisible(true);
        shownMarkers--;
      } else {
        markers[i].setVisible(false);
      }
    } else {
      markers[i].setVisible(false);
    }
  }
}

Then call that function, when you load new markers or update the zoom:

proof of concept fiddle

结果地图的屏幕截图

code snippet:

 // 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 // Handle markers display google.maps.event.addListener(map, 'zoom_changed', handleMarkersDisplay); $.ajax({ type: 'GET', url: 'https://us-central1-cloud-calendar-project.cloudfunctions.net/InfoWindow', success: function(data) { removeMarkers(); 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 }); console.log("marker@" + marker.getPosition().toUrlValue()); // 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; content += '<br>Day: ' + data[element].day; content += '<br>Month: ' + data[element].month; 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; }); console.log("loaded "+markers.length+" markers"); // Handle markers display handleMarkersDisplay(); } }); } function handleMarkersDisplay() { console.log("handleMarkerDisplay zoom=" + map.getZoom()); // Check if map current zoom <= 2 if (map.getZoom() <= 5) { displayMarkers(); } else { displayAllMarkers(); } } function removeMarkers() { for (i = 0; i < markers.length; i++) { markers[i].setMap(null); } markers = []; } function hideAllMarkers() { for (i = 0; i < markers.length; i++) { markers[i].setVisible(false); } } function displayMarkers() { // add new markers to map var shownMarkers = 10; for (var i = 0; i < markers.length; i++) { // Only show the first 10 markers in the viewport if (shownMarkers > 0) { if (map.getBounds().contains(markers[i].getPosition())) { markers[i].setVisible(true); shownMarkers--; } else { markers[i].setVisible(false); } } else { markers[i].setVisible(false); } } } function displayAllMarkers() { // Zoom is greater than 3, show all markers for (var i = 0; i < markers.length; i++) { markers[i].setVisible(true); } }
 /* Always set the map height explicitly to define the size of the div * element that contains the map. */ #map { height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="map"></div> <.-- 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM