2010-04-20 9 views
20

En lugar de la ventana de información predeterminada de la API de Google Maps, voy a utilizar otro plugin de jQuery tooltip sobre el marcador. Entonces necesito obtener el DIV del marcador y su posición de píxel.¿Cómo acceder al DIV del marcador de Google Maps API v3 y su posición de píxel?

Pero no pude conseguirlo porque no hay identificación o clase para cierto marcador. Solo yo puedo acceder a la div del lienzo del mapa desde el objeto marcador y el objeto pixelBounds no documentado.

  1. ¿Cómo puedo acceder al marcador DIV?
  2. ¿Dónde puedo obtener la posición de píxel de DIV? ¿Puedo convertir la posición lat-lng en valores de píxel?

== anexa:

que también trató con código de abajo, pero no cambia cuando me desplazarse por el mapa.

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

¿No debería aceptarse esta pregunta? Parece que tu pregunta fue dirigida. –

+0

@jeff: estás editando preguntas que tienen más de 2 años de antigüedad, y continuamente las encuentras en la parte superior de la lista de Activos. El código ya está formateado correctamente, lo que hace que los colores sean bonitos es un cambio menor y no es necesario. – LittleBobbyTables

+8

@LittleBobbyTables - Esta pregunta ha sido vista casi 19,000 veces. Creo que alguien finalmente encontrará útil el resaltado de sintaxis. – jeff

Respuesta

45

Realmente no entiendo por qué querrías obtener div específico para marcador? Si desea visualizar la información sobre herramientas, todo lo que necesita es la posición de píxeles del delimitador de marcadores (y el conocimiento sobre el tamaño del marcador y la ubicación del anclaje), no del elemento div. Siempre puede activar la información de apertura y cierre a mano cuando ocurre un evento en google.maps.

Para conseguir la posición de píxel de anclaje del marcador dado se puede utilizar este código:

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) 
); 

En pixelDistance te desplazamiento de anclaje marcador específico contados a partir de la esquina superior izquierda del mapa (y se puede obtener su posición de map.getDiv() div). Por qué funciona así (o hay una mejor manera?) Puede leer en documentation of google maps overlays.

+0

Además de información sobre herramientas, quiero animar marcador con jQuery y es por eso que necesito acceder al DIV del marcador. Ahora sé que no puedo acceder a él a través de Maps API v3 y necesito volver a implementar la clase de marcador con OverlayView. :( –

+0

¿Alguien tiene una función inversa decente? –

+0

@AnkitAggarwal Lamentablemente, mi trabajo actual no implica trabajar con Google Maps. Esta respuesta fue solo lo que tuve que desarrollar en un proyecto, pero además de esto, no tengo mucha experiencia con Maps. – MBO

1

La respuesta de Rene solo le proporciona las "coordenadas mundiales" (es decir, coordenadas independientes del nivel de zoom y la ventana gráfica). Sin embargo, la respuesta de MBO parece correcta, así que esa es la que debes aceptar y votar (no puedo, ya que acabo de registrarme) ya que de lo contrario la solución podría pasarse por alto.

En cuanto a una versión "más fácil", puede utilizar los métodos en MapCanvasProjection en su lugar, pero eso significa que tendrá que hacer su propia superposición. Ver here para un ejemplo. : P

9
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); 

Ahora puede acceder a las coordenadas de su píxel a través de p.x. y p.y.

siguiente comentario añadidos posteriormente:

La caída de la proyección de superposición es que hasta que su vista del mapa se termina la carga, no se ha inicializado. Tengo el siguiente oyente que forzará cualquier método que necesite desencadenar cuando el mapa termine de cargarse.

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

Por el momento utilizo la siguiente comprobación para evitar cualquier error antes de que no dibujar.

if(overlay.getProjection()) { 
    // code here 
} 
+2

Si esto funcionara, sería increíble. 'overlay.getProjection()' devuelve 'undefined'. – designermonkey

+2

overlay.getProjection se inicializa solo después de que el mapa se haya cargado

Para eludir esto y para inicializarlo, tengo un oyente que llama a la función que lo usa. Agregaré el código a mi comentario arriba. – Flarex

+0

¡Muchas gracias por actualizar esto para mí! Ya uso el detector de eventos, ¡así que lo implementaré lo antes posible! – designermonkey

1

MapCanvasProjection de fromLatLngToContainerPixel() es probablemente lo que el autor de después. Le dará la compensación de píxeles relativa al contenedor del mapa. Hice algunos experimentos y encontré la solución de trabajo "más simple". (¡Ojalá Google haga que esta característica sea más accesible!)

En primer lugar se declara una subclase de OverlayView algún lugar de este modo:

function CanvasProjectionOverlay() {} 
CanvasProjectionOverlay.prototype = new google.maps.OverlayView(); 
CanvasProjectionOverlay.prototype.constructor = CanvasProjectionOverlay; 
CanvasProjectionOverlay.prototype.onAdd = function(){}; 
CanvasProjectionOverlay.prototype.draw = function(){}; 
CanvasProjectionOverlay.prototype.onRemove = function(){}; 

Entonces en otro lugar en su código en el que ejemplariza el mapa, también ejecutar este OverlayView y establecer su mapa, así:

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); 

Entonces, cada vez que necesite utilizar fromLatLngToContainerPixel, que acaba de hacer esto:

canvasProjectionOverlay.getProjection().fromLatLngToContainerPixel(myLatLng); 

Tenga en cuenta que debido a que el objeto MapCanvasProjection sólo estará disponible una vez draw() se llama, que es en algún momento antes idle, Sugiero crear un valor lógico "mapInitialized" bandera del mapa, ponemos a true en el primer mapa idle de devolución de llamada. Y luego haz lo que tienes que hacer solo después de eso.

3

Una cosa a recordar cuando se utiliza el código de MBO: Cuando se repiten los mosaicos del mapa, map.getBounds().getSouthWest() devuelve "-180" independientemente de la posición del mapa. Un repliegue que estoy usando en este caso es el cálculo de la distancia de píxeles para el centro en lugar de la esquina superior izquierda, ya que map.getCenter() parece volver al punto actualmente centrada en ningún caso. P.ej. (usando 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) 
); 
+0

Esto debería estar cerca de la parte superior, una característica extremadamente importante para los mapas de estilo internacional. Este fragmento fue el que finalmente corrigió todos mis problemas de posicionamiento. – KoldBane

1

Bueno, si DEBE acceder al DIV, aquí hay un código. Tenga en cuenta que esto solo funcionará con el marcador estándar (20x34px), y encontrará todos los marcadores. Es posible que desee mejorar este truco para satisfacer sus necesidades ...

¡Ten cuidado! Este es un truco

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 

    } 
    } 
} 
0

Un estilo de trabajo jQuery fragmento de código listo para copiar/pegar:

paso 1 - inicializar el mapa y las opciones

<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 
} 

Como se puede ver, más bajo, el mapa variable no está precedido por VAR, porque debe ser global ya que utilizamos otra función para obtener el fromLatLngToContainerPixel. Para más detalles, consulte 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> 
0

He encontrado que es más fácil de asignar un icono personalizado y utilizar el atributo src img para llegar al elemento. Todavía puede usar el ícono predeterminado de google maps, solo guárdelo localmente.

$("#map img[src='my_marker.png']").getBoundingClientRect(); 
0

Para muchas circunstancias el complejo matemáticas utilizaron el calcule y cambie la posición del pin en la respuesta aceptada puede ser apropiado.

Para mi uso particular que acabo de crear un PNG transparente con un lienzo significativamente mayor de lo que necesitaba para el icono. Luego experimenté moviendo el pin dentro del fondo transparente y aplicando la nueva imagen al mapa.

adjusting the pin offset in photoshop

Aquí es la especificación para añadir la imagen Contacto de costumbre, con ejemplos: https://developers.google.com/maps/documentation/javascript/examples/icon-simple

Este método sin duda escalar como un desplazamiento en píxeles en lugar de un verdadero diferente longitud/latitud, incluso cuando acercar el zoom

Cuestiones relacionadas