web-dev-qa-db-fra.com

Comment appeler fromLatLngToDivPixel dans Google Maps API V3?

Je sais que cette méthode existe et est documentée, mais je ne sais pas comment obtenir un objet MapCanvasProjection.

33
Jader Dias

Regardez http://qfox.nl/notes/116

var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var point = overlay.getProjection().fromLatLngToDivPixel(latLng); 

Laid en effet. Beaucoup plus facile en v2 - une autre faille de google api v3!

31
TMS

Je pense que le moyen le plus simple est d'ignorer le désir de Google de rendre notre vie plus difficile en supprimant et en masquant des fonctions utiles au lieu d'en ajouter de nouvelles, et simplement d'écrire vos propres méthodes qui font la même chose.

Voici une version d'une fonction que quelqu'un a publiée ailleurs (je ne la trouve pas pour le moment), qui a fonctionné pour moi:

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

Vous pouvez désormais l'appeler à tout moment et où vous le souhaitez. J'en avais particulièrement besoin pour les menus contextuels personnalisés, et il fait parfaitement son travail.

EDIT : J'ai aussi écrit une fonction inverse, fromPixelToLatLng qui fait exactement le contraire. Il est simplement basé sur le premier, avec quelques calculs appliqués:

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);
}
27
Tiborg

Je n'étais pas satisfait des réponses ici. J'ai donc fait quelques expériences et trouvé la solution de travail "la plus simple", qui est proche de la réponse de Ralph, mais je l'espère plus compréhensible. (Je souhaite que Google rende cette fonctionnalité plus accessible!)

Vous déclarez d'abord une sous-classe de OverlayView quelque part comme ceci:

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

Puis ailleurs dans votre code où vous instanciez la carte, vous instanciez également cette OverlayView et définissez sa carte, comme ceci:

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

Ensuite, chaque fois que vous devez utiliser fromLatLngToContainerPixel, il vous suffit de faire ceci:

canvasProjectionOverlay.getProjection().fromLatLngToContainerPixel(myLatLng);

Notez que parce que l'objet MapCanvasProjection ne sera disponible qu'une fois que draw() sera appelée, quelque temps avant le idle de la carte, je suggère de créer un drapeau booléen "mapInitialized", définissez-le sur true sur le première carte idle rappel. Et puis faites ce que vous devez faire seulement après cela.

21
pixelfreak
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();
13
stepanian

Pour obtenir un MapCanvasProjection, vous pouvez dériver une classe de OverlayView et appeler la méthode getProjection () qui renvoie un type MapCanvasProjection

onAdd (), draw () et onRemove () doivent être implémentés pour dériver d'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';
};

puis quand vous créez votre carte

var OverLayMap = new MyOverlay( { map: map } );

Pour V2 , vous devriez pouvoir appeler fromLatLngToDivPixel depuis votre instance GMap2

var centerPoint = map.fromLatLngToDivPixel(map.getCenter());
9
Michael G