Como acessar o DIV do marcador da API do Google Maps v3 e sua posição de pixel?

Em vez da janela de informações padrão da API do Google Maps, usarei outro plug-in jQuery tooltip over marker. Então eu preciso obter o DIV do marcador e sua posição de pixel.

Mas não consegui porque não há id ou class para determinado marcador. Só consigo acessar a div da canvas de mapa do object de marcador e do object pixelBounds não documentado.

  1. Como posso acessar o DIV do marcador?
  2. Onde posso obter a posição de pixel do DIV? Posso converter a posição lat-lng em valores de pixel?

== acrescentado:

Eu também tentei com código abaixo, mas isso não muda quando eu rolar o 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 + ")"); }); 

Eu realmente não entendo porque você deseja obter um div específico para o marcador? Se você quiser exibir a dica de ferramenta, então tudo que você precisa é a posição de pixel da âncora de marcadores (e o conhecimento sobre o tamanho do marcador e a colocação da âncora), não o elemento div. Você sempre pode acionar a dica de abertura e de fechamento manualmente quando o evento ocorrer no lado do google.maps.

Para obter a posição de pixel da âncora de determinado marcador, você pode usar 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) ); 

Em pixelDistance você obtém um deslocamento da âncora de marcador específica contada a partir do canto superior esquerdo do mapa (e você pode obter sua posição a partir de map.getDiv() div). Por que funciona assim (ou há uma maneira melhor?) Você pode ler na documentação de sobreposições de mapas do Google .

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

Agora você pode acessar suas coordenadas de pixel por meio de px e py

SEGUINTE ADICIONADO POST COMENTÁRIO:

A queda da projeção de sobreposição é que, até que a canvas do seu mapa termine de carregar, ela não será inicializada. Eu tenho o seguinte ouvinte que forçará qualquer método que eu preciso para acionar quando o mapa terminar de carregar.

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

Nesse meio tempo eu uso a seguinte verificação para evitar erros antes de desenhar.

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

Uma coisa a ser lembrada ao usar o código do MBO: Quando os blocos do mapa são repetidos, map.getBounds().getSouthWest() retorna “-180” independente da posição do mapa. Um fallback que estou usando neste caso é calcular a distância do pixel para o centro em vez do canto superior esquerdo, já que map.getCenter() parece retornar o ponto atualmente centrado em qualquer caso. Por exemplo (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) ); 

qualquer um que ainda esteja procurando uma resposta para isso, dê uma olhada aqui: http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries entre alguns outros resources úteis do Google Maps, há o RichMarker que permite você adicionar elementos DOM de sua escolha como marcadores arrastáveis. basta adicionar class / id para manipular com jQuery.

A resposta de René só lhe dá as “coordenadas mundiais” (isto é, coordena independentemente do nível de zoom e da janela de visualização). A resposta da MBO parece certa, então essa é a que você deve aceitar e votar (eu não posso, como acabei de registrar), pois a solução poderia ser facilmente ignorada de outra forma.

Quanto a uma versão “mais fácil”, você pode usar os methods no MapCanvasProjection, mas isso significa que você terá que fazer sua própria sobreposição. Veja aqui um exemplo. : P

O fromLatLngToContainerPixel() do fromLatLngToContainerPixel() é provavelmente o que o autor está fromLatLngToContainerPixel() . Ele fornecerá o deslocamento do pixel em relação ao contêiner do mapa. Eu fiz alguns experimentos e encontrei a solução de trabalho “mais simples”. (Eu desejo que o Google torne esse recurso mais acessível!)

Primeiro você declara uma subclass de OverlayView algum lugar assim:

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

Em seguida, em outro lugar no seu código em que você instancia o mapa, você também instancia este OverlayView e define seu mapa, da seguinte forma:

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

Então, sempre que você precisar usar fromLatLngToContainerPixel , basta fazer isso:

 canvasProjectionOverlay.getProjection().fromLatLngToContainerPixel(myLatLng); 

Observe que, como o object MapCanvasProjection só estará disponível depois que draw() for chamado, o que é algum tempo antes do idle do mapa, sugiro criar um sinalizador booleano “mapInitialized” e defini-lo como true no primeiro retorno de chamada idle mapa. E então faça o que você precisa fazer somente depois disso.

Bem, se você deve acessar o DIV, aqui está um código. Tenha em atenção que isto só funcionará com o marcador padrão (20x34px) e encontrará todos os marcadores. Você pode querer melhorar este hack para atender às suas necessidades …

CUIDADO! ESTE É UM HACK

 var a=document.getElementById('map_canvas'); var b=a.getElementsByTagName('img'); var i, j=b.length; for (i=0; i 

Um trecho de trabalho do jQuery de trechos pronto para copiar / colar:

passo 1 – inicialize seu mapa e opções

      

Como você pode ver, menor, o mapa de variables ​​não é precedido por VAR, porque deve ser Global, já que usamos outra function para obter o fromLatLngToContainerPixel. Para mais detalhes, verifique os fechamentos .

 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'}); } //-->    
Here I am!

Achei mais fácil atribuir um ícone personalizado e usar o atributo img src para acessar o elemento. Você ainda pode usar o ícone padrão do google maps, apenas salve-o localmente.

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

Para muitas circunstâncias, a matemática complexa usada para calcular e alterar a posição do pino na resposta aceita pode ser apropriada.

Para o meu uso em particular, acabei de criar um PNG transparente com uma canvas significativamente maior do que a necessária para o ícone. Então experimentei mover o alfinete dentro do fundo transparente e aplicar a nova imagem no mapa.

ajustando o deslocamento do pino no photoshop

Estas são as especificações para adicionar a imagem de alfinete personalizada, com exemplos: https://developers.google.com/maps/documentation/javascript/examples/icon-simple

Esse método será escalonado como um deslocamento em pixels em vez de um real / latente diferente mesmo quando você aumentar o zoom.