Eu sei que esse método existe e está documentado, mas não sei como obter um object MapCanvasProjection.
Olhe para http://qfox.nl/notes/116
var overlay = new google.maps.OverlayView(); overlay.draw = function() {}; overlay.setMap(map); var point = overlay.getProjection().fromLatLngToDivPixel(latLng);
Feio mesmo. Muito mais fácil em v2 – outra falha do google api v3!
Acho que a maneira mais fácil é ignorar o desejo do Google de tornar nossa vida mais difícil removendo e ocultando funções úteis em vez de adicionar novas funções, e apenas escrever seus próprios methods que fazem a mesma coisa.
Aqui está uma versão de uma function que alguém postou em outro lugar (não consigo encontrá-la agora), que funcionou para mim:
fromLatLngToPixel: function (position) { var scale = Math.pow(2, Map.getZoom()); var proj = Map.getProjection(); var bounds = Map.getBounds(); var nw = proj.fromLatLngToPoint( new google.maps.LatLng( bounds.getNorthEast().lat(), bounds.getSouthWest().lng() )); var point = proj.fromLatLngToPoint(position); return new google.maps.Point( Math.floor((point.x - nw.x) * scale), Math.floor((point.y - nw.y) * scale)); },
Agora você pode ligar a qualquer momento e onde quiser. Eu especialmente precisava de menus de contexto personalizados, e faz o trabalho perfeitamente.
EDIT : Eu também escrevi uma function inversa, fromPixelToLatLng que faz exatamente o oposto. É simplesmente baseado no primeiro, com alguma matemática aplicada:
fromPixelToLatLng: function (pixel) { var scale = Math.pow(2, Map.getZoom()); var proj = Map.getProjection(); var bounds = Map.getBounds(); var nw = proj.fromLatLngToPoint( new google.maps.LatLng( bounds.getNorthEast().lat(), bounds.getSouthWest().lng() )); var point = new google.maps.Point(); point.x = pixel.x / scale + nw.x; point.y = pixel.y / scale + nw.y; return proj.fromPointToLatLng(point); }
Eu não estava satisfeito com as respostas aqui. Então, fiz alguns experimentos e encontrei a solução de trabalho “mais simples”, que está próxima da resposta de Ralph, mas espero que seja mais compreensível. (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.
var map; // Create your map MyOverlay.prototype = new google.maps.OverlayView(); MyOverlay.prototype.onAdd = function() { } MyOverlay.prototype.onRemove = function() { } MyOverlay.prototype.draw = function() { } function MyOverlay(map) { this.setMap(map); } var overlay = new MyOverlay(map); var projection = overlay.getProjection();
Para obter um MapCanvasProjection, você pode derivar uma class do OverlayView e chamar o método getProjection () que retorna um tipo MapCanvasProjection
onAdd (), draw () e onRemove () devem ser implementados para derivar de OverlayView.
function MyOverlay(options) { this.setValues(options); var div = this.div_= document.createElement('div'); div.className = "overlay"; }; // MyOverlay is derived from google.maps.OverlayView MyOverlay.prototype = new google.maps.OverlayView; MyOverlay.prototype.onAdd = function() { var pane = this.getPanes().overlayLayer; pane.appendChild(this.div_); } MyOverlay.prototype.onRemove = function() { this.div_.parentNode.removeChild(this.div_); } MyOverlay.prototype.draw = function() { var projection = this.getProjection(); var position = projection.fromLatLngToDivPixel(this.getMap().getCenter()); var div = this.div_; div.style.left = position.x + 'px'; div.style.top = position.y + 'px'; div.style.display = 'block'; };
então quando você está criando seu mapa
var OverLayMap = new MyOverlay( { map: map } );
Para a V2, você deve poder chamar fromLatLngToDivPixel da sua instância do GMap2
var centerPoint = map.fromLatLngToDivPixel(map.getCenter());