如何更新我的功能,以便无论缩放和视图如何,谷歌地图上总是有 10 个标记(混搭使用 CS50)
Posted
技术标签:
【中文标题】如何更新我的功能,以便无论缩放和视图如何,谷歌地图上总是有 10 个标记(混搭使用 CS50)【英文标题】:How to update my function so that there are always 10 markers on Google Maps regardless of zoom and view (Mashup used CS50) 【发布时间】:2020-07-22 23:33:18 【问题描述】:这是我让它工作的更新后的最终代码。我使用 get.zoom 和 center.change 来确保无论地图视图如何,地图上都会有 10 个标记! (下面的原始问题
'''
// 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);
'''
我正在开发一个 Web 应用程序,我想根据记录的最高温度(来自我解析的 JSON 文件)在地图上显示标记。目前,我能够在地图上获得 10 个最高温度标记,但是当我放大时,它不会更新以添加新标记。因此,当我放大一个标记时,我会在视图中从 10 个标记变为 8 个标记(您需要滚动才能看到其他两个标记)。我想添加两个新标记,它们对应于该视图的下一个最高标记,这样无论您使用何种视图/缩放,您总能看到 10 个标记! (在某种程度上可能是不可能的,例如只看到一个国家)。下图展示了在缩放 3 时,两个标记不在视野范围内。 我通过 endiliey 找到了这个实现 (https://github.com/endiliey/cs50/blob/master/pset8/mashup/static/scripts.js)。但是,实施不起作用..
【问题讨论】:
您应该将原始代码留在出现问题的问题中(供未来的读者使用)。 【参考方案1】:如果要在视口中显示最高的 10 个标记,则需要计算这些标记:
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);
然后在加载新标记或更新缩放时调用该函数:
proof of concept fiddle
代码 sn-p:
// 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>
【讨论】:
以上是关于如何更新我的功能,以便无论缩放和视图如何,谷歌地图上总是有 10 个标记(混搭使用 CS50)的主要内容,如果未能解决你的问题,请参考以下文章