按类别选择标记和适合可见标记的范围
Posted
技术标签:
【中文标题】按类别选择标记和适合可见标记的范围【英文标题】:select markers by category AND fitbounds to visible markers 【发布时间】:2016-04-30 16:37:31 【问题描述】:我有一个代码用于按类别切换标记的可见性,效果很好(见下面的代码)。
我现在想添加但不知道如何添加:
每次显示/隐藏标记组后,我希望调整地图的缩放和中心以显示所有可见标记。
我找到了fitBounds()
的另一个代码,但没有设法让两者一起工作(我对javascript
完全陌生)。
我发现了仅将边界拟合到可见标记的示例,但没有与按类别显示/隐藏标记结合使用。 (例如Center/Set Zoom of Map to cover all visible Markers?)
这里是两个代码示例:
按类别显示/隐藏标记:
function xmlParse(str)
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined')
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
if (typeof DOMParser != 'undefined')
return (new DOMParser()).parseFromString(str, 'text/xml');
return createElement('div', null);
var infoWindow = new google.maps.InfoWindow();
var customIcons =
monumento:
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png'
,
hotel:
icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
,
restaurantes:
icon: 'http://maps.google.com/mapfiles/ms/icons/yellow.png'
,
museus:
icon: 'http://maps.google.com/mapfiles/ms/icons/purple.png'
;
var markerGroups =
"museus": [],
"monumentos": [],
"restaurantes": [],
"hotel": []
;
function load()
var map = new google.maps.Map(document.getElementById("mapCanvas"),
center: new google.maps.LatLng(38.639104, -8.210413),
zoom: 12,
mapTypeId: 'satellite'
);
var infoWindow = new google.maps.InfoWindow();
map.set('styles', [
zoomControl: false
,
featureType: "road.highway",
elementType: "geometry.fill",
stylers: [
color: "#ffd986"
]
,
featureType: "road.arterial",
elementType: "geometry.fill",
stylers: [
color: "#9e574f"
]
,
featureType: "road.local",
elementType: "geometry.fill",
stylers: [
color: "#d0cbc0"
,
weight: 1.1
]
,
featureType: 'road',
elementType: 'labels',
stylers: [
saturation: -100
]
,
featureType: 'landscape',
elementType: 'geometry',
stylers: [
hue: '#ffff00'
,
gamma: 1.4
,
saturation: 82
,
lightness: 96
]
,
featureType: 'poi.school',
elementType: 'geometry',
stylers: [
hue: '#fff700'
,
lightness: -15
,
saturation: 99
]
]);
// downloadUrl("markers.xml", function (data)
var xml = xmlParse('<markers><marker name="Castelo" address="Rua da Condessa de Valença" lat="38.64351973190569" lng="-8.216521812152905" type="monumento" /><marker name="Anta 1 de Tourais" address="Estrada Nacional 114" lat="38.64260059929888" lng="-8.159376865959189" type="monumento" /><marker name="Hotel da Ameira" address="Herdade da Ameira" lat="38.64109640475479" lng="-8.180432206726096" type="hotel" /><marker name="Hotel Montemor" address="Avenida Gago Coutinho 8, 7050-248 Montemor-o-Novo" lat="38.64925541964039" lng="-8.216489625644726" type="hotel" /><marker name="Restaurante Monte Alentejano" address="Av. Gago Coutinho 8" lat="38.6492329" lng="-8.216665" type="restaurantes" /><marker name="Restaurante A Ribeira" address="Rua de São Domingos" lat="38.6347498199708" lng="-8.206468892765088" type="restaurantes" /><marker name="Núcleo Museológico do Convento de S. Domingos" address="" lat="38.643139" lng="-8.212732" type="museus" /><marker name="Centro Interpretativo do Castelo de Montemor-o-Novo" address="Rua Condessa de Valença" lat="38.64258748216167" lng="-8.21467108793263" type="museus" /></markers>');
// var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++)
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
// var icon = customIcons[type] || ;
var marker = createMarker(point, name, address, type, map);
bindInfoWindow(marker, map, infoWindow, html);
// );
function createMarker(point, name, address, type, map)
var icon = customIcons[type] || ;
var marker = new google.maps.Marker(
map: map,
position: point,
icon: icon.icon,
// shadow: icon.shadow,
type: type
);
if (!markerGroups[type]) markerGroups[type] = [];
markerGroups[type].push(marker);
var html = "<b>" + name + "</b> <br/>" + address;
bindInfoWindow(marker, map, infoWindow, html);
return marker;
function toggleGroup(type)
for (var i = 0; i < markerGroups[type].length; i++)
var marker = markerGroups[type][i];
if (!marker.getVisible())
marker.setVisible(true);
else
marker.setVisible(false);
function bindInfoWindow(marker, map, infoWindow, html)
google.maps.event.addListener(marker, 'click', function()
infoWindow.setContent(html);
infoWindow.open(map, marker);
);
function downloadUrl(url, callback)
var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
request.onreadystatechange = function()
if (request.readyState == 4)
request.onreadystatechange = doNothing;
callback(request, request.status);
;
request.open('GET', url, true);
request.send(null);
function doNothing()
google.maps.event.addDomListener(window, 'load', load);
fitBounds()
到可见标记:
function fitBoundsToVisibleMarkers()
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++)
if (markers[i].getVisible())
bounds.extend(markers[i].getPosition());
map.fitBounds(bounds);
【问题讨论】:
Center/Set Zoom of Map to cover all markers visible Markers? 的可能重复项。另外,您能否使用这些示例创建一个 sn-p 或 bin,以便我们为您提供帮助? 嗨 Mosh Feu,谢谢您的评论!这是第一个代码的 jsfiddle:jsfiddle.net/YEPB7/6 这有帮助吗? 【参考方案1】:你的代码有问题:
-
您遇到错误:
Uncaught TypeError: map.fitBounds is not a function
。那是因为您需要在函数load
之外设置map
变量。
您需要收集所有可见标记,然后对它们运行map.fitBounds
。
工作代码:
function xmlParse(str)
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined')
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
if (typeof DOMParser != 'undefined')
return (new DOMParser()).parseFromString(str, 'text/xml');
return createElement('div', null);
var infoWindow = new google.maps.InfoWindow();
var customIcons =
monumento:
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png'
,
hotel:
icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
,
restaurantes:
icon: 'http://maps.google.com/mapfiles/ms/icons/yellow.png'
,
museus:
icon: 'http://maps.google.com/mapfiles/ms/icons/purple.png'
;
var markerGroups =
"museus": [],
"monumentos": [],
"restaurantes": [],
"hotel": []
;
var ctr = new google.maps.LatLng(38.639104, -8.210413),
zoom = 12;
var map;
function load()
map = new google.maps.Map(document.getElementById("map"),
center: ctr,
zoom: zoom,
mapTypeId: 'roadmap'
);
var infoWindow = new google.maps.InfoWindow();
map.set('styles', [
zoomControl: false
,
featureType: "road.highway",
elementType: "geometry.fill",
stylers: [
color: "#ffd986"
]
,
featureType: "road.arterial",
elementType: "geometry.fill",
stylers: [
color: "#9e574f"
]
,
featureType: "road.local",
elementType: "geometry.fill",
stylers: [
color: "#d0cbc0"
,
weight: 1.1
]
,
featureType: 'road',
elementType: 'labels',
stylers: [
saturation: -100
]
,
featureType: 'landscape',
elementType: 'geometry',
stylers: [
hue: '#ffff00'
,
gamma: 1.4
,
saturation: 82
,
lightness: 96
]
,
featureType: 'poi.school',
elementType: 'geometry',
stylers: [
hue: '#fff700'
,
lightness: -15
,
saturation: 99
]
]);
// downloadUrl("markers.xml", function (data)
var xml = xmlParse('<markers><marker name="Castelo" address="Rua da Condessa de Valença" lat="38.64351973190569" lng="-8.216521812152905" type="monumento" /><marker name="Anta 1 de Tourais" address="Estrada Nacional 114" lat="38.64260059929888" lng="-8.159376865959189" type="monumento" /><marker name="Hotel da Ameira" address="Herdade da Ameira" lat="38.64109640475479" lng="-8.180432206726096" type="hotel" /><marker name="Hotel Montemor" address="Avenida Gago Coutinho 8, 7050-248 Montemor-o-Novo" lat="38.64925541964039" lng="-8.216489625644726" type="hotel" /><marker name="Restaurante Monte Alentejano" address="Av. Gago Coutinho 8" lat="38.6492329" lng="-8.216665" type="restaurantes" /><marker name="Restaurante A Ribeira" address="Rua de São Domingos" lat="38.6347498199708" lng="-8.206468892765088" type="restaurantes" /><marker name="Núcleo Museológico do Convento de S. Domingos" address="" lat="38.643139" lng="-8.212732" type="museus" /><marker name="Centro Interpretativo do Castelo de Montemor-o-Novo" address="Rua Condessa de Valença" lat="38.64258748216167" lng="-8.21467108793263" type="museus" /></markers>');
// var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++)
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
// var icon = customIcons[type] || ;
var marker = createMarker(point, name, address, type, map);
bindInfoWindow(marker, map, infoWindow, html);
// );
//fitMap();
function createMarker(point, name, address, type, map)
var icon = customIcons[type] || ;
var marker = new google.maps.Marker(
map: map,
position: point,
icon: icon.icon,
// shadow: icon.shadow,
type: type,
visible:false
);
if (!markerGroups[type]) markerGroups[type] = [];
markerGroups[type].push(marker);
var html = "<b>" + name + "</b> <br/>" + address;
bindInfoWindow(marker, map, infoWindow, html);
return marker;
function toggleGroup(type)
for (var i = 0; i < markerGroups[type].length; i++)
var marker = markerGroups[type][i];
if (!marker.getVisible())
marker.setVisible(true);
else
marker.setVisible(false);
if (document.querySelectorAll(':checked').length == 0)
map.setCenter(ctr);
map.setZoom(zoom);
else
fitMap();
function fitMap()
var visibleMarkers = [];
for (var i in markerGroups)
for (var j = 0; j < markerGroups[i].length; j++)
var marker = markerGroups[i][j];
if (marker.getVisible())
visibleMarkers.push(marker);
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < visibleMarkers.length; i++)
bounds.extend(visibleMarkers[i].getPosition());
map.fitBounds(bounds);
function bindInfoWindow(marker, map, infoWindow, html)
google.maps.event.addListener(marker, 'click', function ()
infoWindow.setContent(html);
infoWindow.open(map, marker);
);
function downloadUrl(url, callback)
var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
request.onreadystatechange = function ()
if (request.readyState == 4)
request.onreadystatechange = doNothing;
callback(request, request.status);
;
request.open('GET', url, true);
request.send(null);
function doNothing()
google.maps.event.addDomListener(window, 'load', load);
html, body, #map, #map_wrap
height: 100%;
width:100%;
<script src="https://maps.googleapis.com/maps/api/js?v=3&ext=.js"></script>
<div class="map_wrap">
<div class="siderbarmap">
<ul>
<input id="monumentoCheckbox" type="checkbox" onclick="toggleGroup('monumento')" />
<input id="museusCheckbox" type="checkbox" onclick="toggleGroup('museus')" />
<input id="restaurantesCheckbox" type="checkbox" onclick="toggleGroup('restaurantes')" />
<input id="hotelCheckbox" type="checkbox" onclick="toggleGroup('hotel')" />
</ul>
</div>
<div id="map" style="width:100%;height:585px; z-index: 1;"></div>
</div>
更新:
-
我稍微更改了代码,所以现在找到可见标记的函数是独立的,因此我们可以在页面加载和复选框更改后调用它(现在在对要求 2 的注释中。要使用它,只需删除评论
//
)。
在用户单击checkbox
之后,在开始时没有一个markers
可见
如果所有复选框都不是:checked
,则地图将重置为起点zoom
和center
。
【讨论】:
我的荣幸!祝你好运! 嗨 Mosh Feu,另一个问题:现在它仅在第一次单击类别后才适合可见标记的边界,而不是在页面加载时。我需要改变什么才能在一开始就调整地图大小?也许您可以帮助我添加另一个小补充:如果我希望标记在开始时隐藏并且仅在选中复选框时切换可见,我需要添加/更改什么? 我刚刚更新了我的答案。一个思考点:第一个请求与第二个冲突。因为如果没有任何标记可见,您将无法根据它们将map
居中。
谢谢,我现在看到了问题。另外,如果我取消选中所有这些,地图以海洋为中心......你认为当所有标记都不可见时,是否可以将起始缩放和中心设置为 latlang?【参考方案2】:
它只需要对您的 toggleGroup 功能稍作调整。此时您已经设置了标记的可见性;只需在此处添加几行即可将这些可见标记添加到 LatLngBounds 对象。然后在调整完所有标记后,更新地图以适应新的边界。
function toggleGroup(type)
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerGroups[type].length; i++)
var marker = markerGroups[type][i];
if (!marker.getVisible())
marker.setVisible(true);
bounds.extend(marker.getPosition());
else
marker.setVisible(false);
map.fitBounds(bounds);
您唯一需要做的另一件事是使您的 map
变量成为全局变量;现在它只是 load()
函数的本地函数。
【讨论】:
以上是关于按类别选择标记和适合可见标记的范围的主要内容,如果未能解决你的问题,请参考以下文章