我将使用其他jQuery工具提示插件而不是Google Maps API的默认信息窗口。所以我需要得到标记的DIV及其像素位置。
但无法得到它,因为某些标记没有id或class。只有我可以从标记对象和未记录的pixelBounds对象访问地图画布div。
== 所附:
我也试过下面的代码,但滚动地图时它没有改变。
var marker = new google.maps.Marker({...});
google.maps.event.addListener(marker, 'click', function() {
var px = this.getMap().getProjection().fromLatLngToPoint(this.getPosition());
console.log("(" + px.x + "," + px.y + ")");
});
答案 0 :(得分:48)
我真的不明白你为什么要为标记获得特定的div?如果要显示工具提示,那么您需要的只是标记锚点的像素位置(以及有关标记大小和锚点位置的知识),而不是div元素。在google.maps端发生事件时,您可以随时手动触发打开和关闭工具提示。
要获取给定标记的锚点的像素位置,您可以使用以下代码:
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(marker.getPosition());
var pixelOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
在pixelDistance
中,您可以获得从地图左上角开始计算的特定标记锚点的偏移量(您可以从map.getDiv()
div获取它的位置)。为什么它会像这样工作(或者有更好的方法吗?),你可以阅读documentation of google maps overlays。
答案 1 :(得分:10)
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var proj = overlay.getProjection();
var pos = marker.getPosition();
var p = proj.fromLatLngToContainerPixel(pos);
您现在可以通过p.x和p.y访问像素坐标。
更新后评论:
叠加投影的下降是,在地图画布完成加载之前,它不会被初始化。我有以下监听器,它将强制在地图完成加载时触发我需要的任何方法。
google.maps.event.addListener(map, 'idle', functionName());
与此同时,我使用以下检查以避免在绘制之前出现任何错误。
if(overlay.getProjection()) {
// code here
}
答案 2 :(得分:3)
使用MBO代码时要记住的一件事:
重复地图图块时,map.getBounds().getSouthWest()
将返回“-180”,与地图的位置无关。我在这种情况下使用的后备是计算到中心而不是左上角的像素距离,因为map.getCenter()
似乎在任何情况下都返回当前居中的点。例如。 (使用jQuery):
// Calculate marker position in pixels form upper left corner
var pixelCoordsCenter = map.getProjection().fromLatLngToPoint(map.getCenter());
pixelOffset = new google.maps.Point(
Math.floor((pixelCoordsMarker.x - pixelCoordsCenter.x) * scale + $(container).width()/2),
Math.floor((pixelCoordsMarker.y - pixelCoordsCenter.y) * scale + $(container).height()/2)
);
答案 3 :(得分:2)
任何人仍在寻找答案,请看一下:http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries 在其他一些有用的谷歌地图中,RichMarker允许您添加您选择的DOM元素作为可拖动标记。只需使用jQuery添加class / id即可。
答案 4 :(得分:1)
Rene的答案仅为您提供“世界坐标”(即,与缩放级别和视口无关的坐标)。 MBO的回答似乎是正确的,所以这是你应该接受和投票的那个(我不能像我刚刚注册的那样)因为解决方案可能很容易被忽视。
对于“更简单”的版本,您可以使用MapCanvasProjection中的方法,但这意味着您必须制作自己的叠加层。有关示例,请参阅here。 :P
答案 5 :(得分:1)
MapCanvasProjection的fromLatLngToContainerPixel()
可能就是作者所追求的。它将为您提供相对于地图容器的像素偏移量。我做了一些实验,发现了“最简单”的工作解决方案。 (我希望Google能够更方便地使用此功能!)
首先在某处声明OverlayView
的子类:
function CanvasProjectionOverlay() {}
CanvasProjectionOverlay.prototype = new google.maps.OverlayView();
CanvasProjectionOverlay.prototype.constructor = CanvasProjectionOverlay;
CanvasProjectionOverlay.prototype.onAdd = function(){};
CanvasProjectionOverlay.prototype.draw = function(){};
CanvasProjectionOverlay.prototype.onRemove = function(){};
然后在你的代码中的其他地方,你实例化地图,你也实例化这个OverlayView并设置它的地图,如下所示:
var map = new google.maps.Map(document.getElementById('google-map'), mapOptions);
// Add canvas projection overlay so we can use the LatLng to pixel converter
var canvasProjectionOverlay = new CanvasProjectionOverlay();
canvasProjectionOverlay.setMap(map);
然后,只要您需要使用fromLatLngToContainerPixel
,就可以执行此操作:
canvasProjectionOverlay.getProjection().fromLatLngToContainerPixel(myLatLng);
请注意,因为MapCanvasProjection对象只有在调用draw()
时才可用,这是在地图的idle
之前的某个时间,我建议创建一个布尔“mapInitialized”标志,将其设置为true第一个地图idle
回调。然后在那之后做你需要做的事。
答案 6 :(得分:1)
好吧,如果你必须访问DIV,这里有一些代码。请注意,这只适用于标准标记(20x34px),并且它会找到所有标记。您可能希望改进此黑客以满足您的需求......
<强>小心!这是一个黑客
var a=document.getElementById('map_canvas');
var b=a.getElementsByTagName('img');
var i, j=b.length;
for (i=0; i<j; i++) {
if(b[i].src.match('marker_sprite.png')){
if(b[i].style.width=='20px' && b[i].style.height=='34px') {
c=b[i].parentElement;
console.log(c.style.top+":"+c.style.left);
// this is a marker's enclosing div
}
}
}
答案 7 :(得分:0)
准备复制/粘贴的工作代码段jQuery样式:
第1步 - 初始化您的地图和选项
<html>
<head>
<script src="get-your-jQuery" type="text/javascript"></script>
<script src="get-your-maps.API" type="text/javascript"></script>
<script type="text/javascript">
<!--
$(document).ready(function(){
var bucharest = new google.maps.LatLng(44.43552, 26.10250);
var options = {
zoom: 14,
center: bucharest,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
正如你所看到的那样,变量map之前没有VAR,因为它应该是Global,因为我们使用另一个函数来获取fromLatLngToContainerPixel。有关详细信息,请查看closures。
map = new google.maps.map($("#map_canvas")[0], options);
var marker = new google.maps.Marker({
position: google.maps.LatLng(44.4407,26.0864),
map: map
});
new google.maps.event.addListener(marker, 'mouseover', function(){
placeMarker( marker.getPosition(),'#tooltip');//param1: latlng, param2: container to place result
});
new google.maps.event.addListener(map, 'bounds_changed', function(){
$("#tooltip").css({display:'none'}); //this is just so you can see that all goes well ;)
});
overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
}); //here ends jQuery.ready
function placeMarker(location, ID){
var containerPixel = overlay.getProjection().fromLatLngToContainerPixel(location);
var divPixel = overlay.getProjection().fromLatLngToDivPixel(location);
$(ID).css({top:containerPixel.y, left:containerPixel.x, 'dislay':'block'});
}
//-->
</script>
</head>
<body>
<div id="tooltip" style="width:100px; height:100px; position:absolute; z-index:1; background:#fff">Here I am!</div>
<div id="map_canvas" style="width:300px; height:300px"></div>
</body>
</html>
答案 8 :(得分:0)
我发现最简单的方法是分配自定义图标并使用img src属性来获取元素。您仍然可以使用默认的Google地图图标,只需将其保存在本地。
$("#map img[src='my_marker.png']").getBoundingClientRect();
答案 9 :(得分:0)
对于许多情况,复杂的数学使用计算并在接受的答案中更改引脚位置可能是合适的。
对于我的特殊用途,我刚创建了一个透明的PNG,其画布明显大于我所需的图标。然后我只是尝试在透明背景中移动图钉并将新图像应用到地图上。
以下是添加自定义图片图片的规范,示例如下: https://developers.google.com/maps/documentation/javascript/examples/icon-simple
即使放大,此方法也会以像素为单位进行缩放,而不是实际不同的长/纬度。
答案 10 :(得分:0)
尝试这种方式,按事件获取div。
marker.addListener("click", markerClicked);
function markerClicked(event) {
// here you can get the marker div by event.currentTarget
}