如何访问Google Maps API v3标记的DIV及其像素位置?
我将使用其他jQuery工具提示插件而不是Google Maps API的默认信息窗口。 所以我需要得到标记的DIV和它的像素位置。
但不能得到它,因为没有特定标记的id或类。 只有我可以从标记对象和未logging的pixelBounds对象访问地图canvas div。
- 我如何访问标记的DIV?
- 我在哪里可以得到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 + ")"); });
我真的不明白你为什么要获得标记的特定div? 如果你想显示工具提示,那么你所需要的只是标记锚点的像素位置(以及有关标记大小和锚点位置的知识),而不是div元素。 当google.maps端发生事件时,您可以随时触发开启和closures工具提示。
为了获得给定标记的锚点的像素位置,您可以使用以下代码:
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
您可以从地图的左上angular计算特定标记锚点的偏移量(您可以从map.getDiv()
div)获取它的位置。 为什么它像这样工作(还是有更好的方法?)你可以阅读谷歌地图覆盖文件 。
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来访问像素坐标
后续添加发表评论:
叠加投影的失败是,直到它的地图canvas完成加载它不被初始化。 我有下面的监听器,将强制任何方法我需要触发时,地图完成加载。
google.maps.event.addListener(map, 'idle', functionName());
同时,我使用以下检查来避免在绘制之前发生任何错误。
if(overlay.getProjection()) { // code here }
使用MBO代码时要记住的一件事情是:当地图切片重复时, map.getBounds().getSouthWest()
返回“-180”,与地图位置无关。 在这种情况下,我使用的备用方法是计算到中心的像素距离而不是左上angular,因为在任何情况下, 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) );
任何人仍然在寻找这个答案,看看这里: http : //code.google.com/p/google-maps-utility-library-v3/wiki/Libraries之间的一些其他有用的谷歌地图的东西有RichMarker它允许您可以将您select的DOM元素添加为可拖动标记。 只需添加class / id来处理jQuery。
雷内的答案只给你“世界坐标”(即,独立于缩放级别和视口的坐标)。 然而,MBO的答案似乎是正确的,所以这是你应该接受和投票的人(我不能像刚刚注册的那样),否则这个解决scheme很容易被忽略。
对于“更简单”的版本,您可以使用MapCanvasProjection中的方法,但是这意味着您必须创build自己的叠加层。 看这里的例子。 :P
MapCanvasProjection的fromLatLngToContainerPixel()
可能是作者的fromLatLngToContainerPixel()
。 它会给你相对于地图的容器的像素偏移量。 我做了一些实验,find了“最简单”的工作解决scheme。 (我希望谷歌使这个function更容易访问!)
首先,你可以像这样声明一个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
之前的某个时间,所以我build议创build一个布尔型“mapInitialized”标志,并在第一个地图idle
callback中将其设置为true。 然后在那之后做你需要做的事情。
那么,如果你必须访问DIV,这里是一些代码。 注意,这只能使用标准标记(20x34px),它会find所有的标记。 你可能想要改进这个黑客来满足你的需求…
谨防! 这是一个黑客
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 } } }
准备复制/粘贴的工作片段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 }
正如你所看到的,更低的variables映射前面没有VAR,因为它应该是全局的,因为我们使用另一个函数来获取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>
我发现分配自定义图标最简单,并使用img src属性来获取元素。 您仍然可以使用默认的Google地图图标,只需将其保存在本地即可。
$("#map img[src='my_marker.png']").getBoundingClientRect();
在许多情况下,复杂的math计算和更改接受的答案中的销位置可能是适当的。
为了我的特殊用途,我创build了一个透明的PNG,canvas比我需要的图标大得多。 然后,我只是尝试在透明背景中移动引脚,并将新图像应用到地图上。
以下是添加自定义图片的规范,其中包含以下示例: https : //developers.google.com/maps/documentation/javascript/examples/icon-simple
这种方法肯定会缩放为像素的偏移量,而不是实际的不同长/纬度,即使放大时也是如此。