25

我将在标记上使用其他 jQuery 工具提示插件,而不是 Google Maps API 的默认信息窗口。所以我需要获取标记的 DIV 及其像素位置。

但无法得到它,因为某些标记没有 id 或 class。只有我可以从标记对象和未记录的 pixelBounds 对象访问地图画布 div。

  1. 如何访问标记的 DIV?
  2. 我在哪里可以获得 DIV 的像素位置?我可以将 lat-lng 位置转换为像素值吗?

== 附加:

我也尝试了下面的代码,但是当我滚动地图时它并没有改变。

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 + ")");
});
4

11 回答 11

52

我真的不明白为什么要为标记获取特定的 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 获取它的位置)。为什么它会这样工作(或者有更好的方法吗?)您可以阅读google maps overlays 的文档

于 2010-04-22T16:22:22.397 回答
11
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);

您现在可以通过 px 和 py 访问您的像素坐标

以下添加的帖子评论:

叠加投影的缺点是,在您的地图画布完成加载之前,它不会被初始化。我有以下侦听器,它将在地图完成加载时强制我需要触发的任何方法。

google.maps.event.addListener(map, 'idle', functionName());

同时,我使用以下检查来避免在绘制之前出现任何错误。

if(overlay.getProjection()) {
  // code here
}
于 2011-07-12T21:13:16.223 回答
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)
);
于 2011-09-07T06:27:30.583 回答
2

任何仍在寻找答案的人,请看这里:http ://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries 在其他一些有用的谷歌地图中,​​还有 RichMarker 允许您可以添加您选择的 DOM 元素作为可拖动标记。只需添加 class/id 以使用 jQuery 处理。

于 2012-12-13T22:43:30.490 回答
1

好吧,如果您必须访问 DIV,这里有一些代码。请注意,这只适用于标准标记 (20x34px),它会找到所有标记。您可能希望改进此 hack 以满足您的需求...

谨防!这是一个黑客

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

    }
  }
}
于 2012-05-22T06:39:10.860 回答
1

Rene 的回答只为您提供“世界坐标”(即独立于缩放级别和视口的坐标)。不过,MBO 的答案似乎是正确的,所以这是您应该接受并投票赞成的答案(我不能,因为我刚刚注册过),否则该解决方案可能很容易被忽略。

至于“更简单”的版本,您可以改用 MapCanvasProjection 中的方法,但这意味着您必须自己制作叠加层。有关示例,请参见此处。:P

于 2010-08-22T20:18:26.327 回答
1

MapCanvasProjection 的fromLatLngToContainerPixel()可能是作者所追求的。它将为您提供相对于地图容器的像素偏移量。我做了一些实验,找到了“最简单”的工作解决方案。(我希望谷歌让这个功能更容易访问!)

首先,您声明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(),即在 map 之前的某个时间idle,我建议创建一个布尔“mapInitialized”标志,在第一个地图idle回调时将其设置为 true。然后只做你需要做的事。

于 2011-08-10T22:29:14.217 回答
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 
}

如你所见,lower,变量 map 前面没有 VAR,因为它应该是 Global,因为我们使用另一个函数来获取 fromLatLngToContainerPixel。有关更多详细信息,请查看闭包

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>
于 2012-05-28T14:35:55.607 回答
0

我发现分配自定义图标并使用 img src 属性获取元素是最简单的。您仍然可以使用默认的谷歌地图图标,只需将其保存在本地即可。

$("#map img[src='my_marker.png']").getBoundingClientRect();
于 2014-07-02T14:58:44.930 回答
0

试试这种方式,按事件获得 div。

marker.addListener("click", markerClicked);

function markerClicked(event) {
    // here you can get the marker div by event.currentTarget
}
于 2020-08-15T15:14:49.750 回答
0

在许多情况下,使用复杂数学计算并更改已接受答案中的引脚位置可能是合适的。

对于我的特殊用途,我刚刚创建了一个透明的 PNG,其画布比我需要的图标大得多。然后我只是尝试在透明背景中移动图钉并将新图像应用到地图上。

在 Photoshop 中调整引脚偏移

以下是添加自定义图钉图像的规范,并附有示例: https ://developers.google.com/maps/documentation/javascript/examples/icon-simple

即使放大,此方法也肯定会缩放为像素偏移量,而不是实际不同的经度/纬度。

于 2016-05-06T20:02:18.343 回答