Я знаю, что этот метод существует и задокументирован, но я не знаю, как получить объект MapCanvasProjection.
Как вызвать fromLatLngToDivPixel в Google Maps API V3?
Ответы (5)
Посмотрите на http://qfox.nl/notes/116
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var point = overlay.getProjection().fromLatLngToDivPixel(latLng);
Действительно уродливо. В v2 намного проще - еще один недостаток google api v3!
google.maps.MapCanvasProjection
спецификация объекта, которая включает метод fromLatLngToContainerPixel(latLng:LatLng)
- person user664833; 22.06.2014
Я думаю, что самый простой способ - игнорировать желание Google усложнить нашу жизнь, удаляя и скрывая полезные функции вместо добавления новых, и просто написать свои собственные методы, которые делают то же самое.
Вот версия функции, которую кто-то опубликовал где-то еще (я не могу ее сейчас найти), которая сработала для меня:
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));
},
Теперь вы можете звонить в любое время и в любом месте. Мне он особенно нужен для настраиваемых контекстных меню, и он отлично справляется со своей задачей.
ИЗМЕНИТЬ: я также написал обратную функцию fromPixelToLatLng, которая делает прямо противоположное. Он просто основан на первом, с применением некоторых математических вычислений:
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);
}
Ответы здесь меня не удовлетворили. Поэтому я провел несколько экспериментов и нашел «простейшее» рабочее решение, близкое к ответу Ральфа, но, надеюсь, более понятное. (Я хочу, чтобы Google сделал эту функцию более доступной!)
Сначала вы объявляете подкласс 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
карты, я предлагаю создать логический флаг «mapInitialized», установив для него значение true в первом обратном вызове карты idle
. И только после этого делайте то, что вам нужно.
Чтобы получить MapCanvasProjection, вы можете унаследовать класс от OverlayView. и вызовите метод getProjection (), который возвращает MapCanvasProjection тип
onAdd (), draw () и onRemove () должны быть реализованы, чтобы быть производными от 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';
};
тогда, когда вы создаете свою карту
var OverLayMap = new MyOverlay( { map: map } );
Для V2 вы должны иметь возможность вызывать fromLatLngToDivPixel из экземпляра GMap2.
var centerPoint = map.fromLatLngToDivPixel(map.getCenter());