Javascript 谷歌地图API V3-在完全相同的位置上有多个标记
这个有点卡住了。我正在通过JSON检索地理坐标列表,并将它们弹出到谷歌地图上。除了在同一个点上有两个或多个标记的情况外,其他情况都很好。API仅显示1个标记-顶部标记。我想这是很公平的,但我想找到一种方式来展示它们 我搜索过谷歌,找到了一些解决方案,但它们似乎大多是针对API的V2版本,或者只是不太好。理想情况下,我想要一个解决方案,您可以单击某种组标记,然后显示标记聚集在所有标记所在的点周围Javascript 谷歌地图API V3-在完全相同的位置上有多个标记,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,这个有点卡住了。我正在通过JSON检索地理坐标列表,并将它们弹出到谷歌地图上。除了在同一个点上有两个或多个标记的情况外,其他情况都很好。API仅显示1个标记-顶部标记。我想这是很公平的,但我想找到一种方式来展示它们 我搜索过谷歌,找到了一些解决方案,但它们似乎大多是针对API的V2版本,或者只是不太好。理想情况下,我想要一个解决方案,您可以单击某种组标记,然后显示标记聚集在所有标记所在的点周围 任何人都有这个问题或类似的问题,愿意分享解决方案吗?查看V3-此库将附近的点聚集到一个组标记中。单击簇
任何人都有这个问题或类似的问题,愿意分享解决方案吗?查看V3-此库将附近的点聚集到一个组标记中。单击簇时,贴图将放大。我可以想象,放大后,在同一地点的标记仍然存在同样的问题。对于同一建筑中有多个服务设施的情况,可以在距离实际点的半径内稍微偏移标记(例如0.001度)。这也会产生很好的视觉效果。如果标记位于同一建筑中,则偏移标记不是真正的解决方案。您可能需要修改markerclusterer.js,如下所示:
MarkerClusterer.prototype.onClick = function() {
return true;
};
// BEGIN MODIFICATION (around line 715)
MarkerClusterer.prototype.onClick = function() {
return true;
};
// END MODIFICATION
// Trigger the clusterclick event.
google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
var zoom = this.map_.getZoom();
var maxZoom = markerClusterer.getMaxZoom();
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && this.cluster_.markers_.length > 1) {
return markerClusterer.onClickZoom(this);
}
// EXISTING CODE (around line 143)
google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
// BEGIN MODIFICATION
var zoom = mc.getMap().getZoom();
// Trying to pull this dynamically made the more zoomed in clusters not render
// when then kind of made this useless. -NNC @ BNB
// var maxZoom = mc.getMaxZoom();
var maxZoom = 15;
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
return mc.onClick(cClusterIcon);
}
// END MODIFICATION
markerCluster = new MarkerClusterer(map, markers);
// onClickZoom OVERRIDE
markerCluster.onClickZoom = function() { return multiChoice(markerCluster); }
markerCluster = new MarkerClusterer(map, markers);
// onClick OVERRIDE
markerCluster.onClick = function(clickedClusterIcon) {
return multiChoice(clickedClusterIcon.cluster_);
}
其中multiChoice()是您(尚未编写)的函数,用于弹出一个包含选项列表的信息窗口。请注意,markerClusterer对象被传递给您的函数,因为您需要它来确定该集群中有多少标记。例如:
function multiChoice(mc) {
var cluster = mc.clusters_;
// if more than 1 point shares the same lat/long
// the size of the cluster array will be 1 AND
// the number of markers in the cluster will be > 1
// REMEMBER: maxZoom was already reached and we can't zoom in anymore
if (cluster.length == 1 && cluster[0].markers_.length > 1)
{
var markers = cluster[0].markers_;
for (var i=0; i < markers.length; i++)
{
// you'll probably want to generate your list of options here...
}
return false;
}
return true;
}
function multiChoice(clickedCluster) {
if (clickedCluster.getMarkers().length > 1)
{
// var markers = clickedCluster.getMarkers();
// do something creative!
return false;
}
return true;
};
new LatLng(getLat()+getMarkerOffset(), getLng()+getMarkerOffset()),
private static double getMarkerOffset(){
//add tiny random offset to keep markers from dropping on top of themselves
double offset =Math.random()/4000;
boolean isEven = ((int)(offset *400000)) %2 ==0;
if (isEven) return offset;
else return -offset;
}
功能多选(mc){
var cluster=mc.clusters;
//如果超过1个点共享同一lat/long
//群集阵列的大小将为1和
//群集中的标记数将大于1
//记住:maxZoom已经到达,我们不能再放大了
if(cluster.length==1&&cluster[0]。标记长度>1)
{
var markers=cluster[0]。markers\uux;
对于(var i=0;i
@Ignatius最优秀的答案,已更新为使用MarkerClustererPlus的v2.0.7
google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
// BEGIN MODIFICATION
var zoom = mc.getMap().getZoom();
// Trying to pull this dynamically made the more zoomed in clusters not render
// when then kind of made this useless. -NNC @ BNB
// var maxZoom = mc.getMaxZoom();
var maxZoom = 15;
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
var markers = cClusterIcon.cluster_.markers_;
var a = 360.0 / markers.length;
for (var i=0; i < markers.length; i++)
{
var pos = markers[i].getPosition();
var newLat = pos.lat() + -.00004 * Math.cos((+a*i) / 180 * Math.PI); // x
var newLng = pos.lng() + -.00004 * Math.sin((+a*i) / 180 * Math.PI); // Y
var finalLatLng = new google.maps.LatLng(newLat,newLng);
markers[i].setPosition(finalLatLng);
markers[i].setMap(cClusterIcon.cluster_.map_);
}
cClusterIcon.hide();
return ;
}
// END MODIFICATION
MarkerClusterer.prototype.onClick = function() {
return true;
};
// BEGIN MODIFICATION (around line 715)
MarkerClusterer.prototype.onClick = function() {
return true;
};
// END MODIFICATION
// Trigger the clusterclick event.
google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
var zoom = this.map_.getZoom();
var maxZoom = markerClusterer.getMaxZoom();
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && this.cluster_.markers_.length > 1) {
return markerClusterer.onClickZoom(this);
}
// EXISTING CODE (around line 143)
google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
// BEGIN MODIFICATION
var zoom = mc.getMap().getZoom();
// Trying to pull this dynamically made the more zoomed in clusters not render
// when then kind of made this useless. -NNC @ BNB
// var maxZoom = mc.getMaxZoom();
var maxZoom = 15;
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
return mc.onClick(cClusterIcon);
}
// END MODIFICATION
markerCluster = new MarkerClusterer(map, markers);
// onClickZoom OVERRIDE
markerCluster.onClickZoom = function() { return multiChoice(markerCluster); }
markerCluster = new MarkerClusterer(map, markers);
// onClick OVERRIDE
markerCluster.onClick = function(clickedClusterIcon) {
return multiChoice(clickedClusterIcon.cluster_);
}
其中multiChoice()是您(尚未编写)的函数,用于弹出一个包含选项列表的信息窗口。请注意,markerClusterer对象被传递给您的函数,因为您需要它来确定该集群中有多少标记。例如:
function multiChoice(mc) {
var cluster = mc.clusters_;
// if more than 1 point shares the same lat/long
// the size of the cluster array will be 1 AND
// the number of markers in the cluster will be > 1
// REMEMBER: maxZoom was already reached and we can't zoom in anymore
if (cluster.length == 1 && cluster[0].markers_.length > 1)
{
var markers = cluster[0].markers_;
for (var i=0; i < markers.length; i++)
{
// you'll probably want to generate your list of options here...
}
return false;
}
return true;
}
function multiChoice(clickedCluster) {
if (clickedCluster.getMarkers().length > 1)
{
// var markers = clickedCluster.getMarkers();
// do something creative!
return false;
}
return true;
};
new LatLng(getLat()+getMarkerOffset(), getLng()+getMarkerOffset()),
private static double getMarkerOffset(){
//add tiny random offset to keep markers from dropping on top of themselves
double offset =Math.random()/4000;
boolean isEven = ((int)(offset *400000)) %2 ==0;
if (isEven) return offset;
else return -offset;
}
lng
和lat
属性的对象)的情况下,将它们稍微移离原始位置(在适当的位置修改对象)。然后,它们围绕中心点形成一个漂亮的圆
我发现,对于我的纬度(北纬52度),0.0003度的圆半径效果最好,当换算成公里时,你必须弥补纬度和经度之间的差异。您可以找到纬度的近似换算
var correctLocList=函数(loclist){
var lng_半径=0.0003,//经度间隔
拉图至拉图液化天然气=111.23/71.7,//华沙拉图至拉长比例
角度=0.5,//起始角度,弧度
loclen=loclist.length,
步骤=2*Math.PI/loclen,
我
loc,
横向半径=液化天然气横向半径/横向至横向液化天然气;
对于(i=0;i
看一看。有一个演示页面,但他们没有显示完全在同一地点的标记,只有一些非常接近 但在上可以看到一个真实的例子,在同一个点上有标记(向下滚动地图,点击几个标记以查看蜘蛛效果) 这似乎是解决您问题的最佳方案。检查以下内容: 这是修改后的MarkerCluster,当在同一位置有多个标记时,它在簇标记中有一个信息窗口
您可以在这里看到它是如何工作的:展开上面给出的答案,只需确保在初始化地图对象时设置了maxZoom选项。已更新以使用MarkerClustererPlus
google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
// BEGIN MODIFICATION
var zoom = mc.getMap().getZoom();
// Trying to pull this dynamically made the more zoomed in clusters not render
// when then kind of made this useless. -NNC @ BNB
// var maxZoom = mc.getMaxZoom();
var maxZoom = 15;
// if we have reached the maxZoom and there is more than 1 marker in this cluster
// use our onClick method to popup a list of options
if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
var markers = cClusterIcon.cluster_.markers_;
var a = 360.0 / markers.length;
for (var i=0; i < markers.length; i++)
{
var pos = markers[i].getPosition();
var newLat = pos.lat() + -.00004 * Math.cos((+a*i) / 180 * Math.PI); // x
var newLng = pos.lng() + -.00004 * Math.sin((+a*i) / 180 * Math.PI); // Y
var finalLatLng = new google.maps.LatLng(newLat,newLng);
markers[i].setPosition(finalLatLng);
markers[i].setMap(cClusterIcon.cluster_.map_);
}
cClusterIcon.hide();
return ;
}
// END MODIFICATION
google.maps.event.trigger(mc,“click”,cClusterIcon.cluster);
google.maps.event.trigger(mc,“clusterclick”,cClusterIcon.cluster)//弃用名称
//开始修改
var zoom=mc.getMap().getZoom();
//尝试动态拉取此选项会使放大的簇无法渲染
//那是什么时候让这个没用了-NNC@BNB
//var maxZoom=mc.getMaxZoom();
var-maxZoom=15;
//如果我们已到达maxZoom,并且此群集中有多个标记
//使用onClick方法弹出选项列表
if(zoom>=maxZoom&&cClusterIcon.cluster\uu.markers\uu.length>1){
var marke
//Code
google.maps.event.addListener(cMarkerClusterer, "clusterclick", function (c) {
var markers = c.getMarkers();
//Check Markers array for duplicate position and offset a little
if (markers .length > 1) {
//Check if all markers are in the same position (with 4 significant digits)
if (markers .every((val, index, arr) => (val.getPosition().lat().toFixed(4) == arr[0].getPosition().lat().toFixed(4)) && (val.getPosition().lng().toFixed(4) == arr[0].getPosition().lng().toFixed(4)))) { /
//Don't modify first element
for (i = 1; i < markers.length; i++) {
var existingMarker = markers[i];
var pos = existingMarker.getPosition();
var quot = 360.0 / markers.length;
var newLat = pos.lat() + -.00008 * Math.cos(+quot * i); //+ -.00008 * Math.cos((+quot * i) / 180 * Math.PI); //x
var newLng = pos.lng() + -.00008 * Math.sin(+quot * i); //+ -.0008 * Math.sin((+quot * i) / 180 * Math.PI); //Y
existingMarker.setPosition(new google.maps.LatLng(newLat, newLng));
}
let cZoom = map.getZoom();
map.setZoom(cZoom-1);
map.setZoom(cZoom+1);
}
}
});