Как получить доступ к DIV маркера Google Maps API v3 и его позиции в пикселях? - PullRequest
22 голосов
/ 20 апреля 2010

Вместо информационного окна API Карт Google по умолчанию я собираюсь использовать другой плагин подсказки jQuery над маркером. Поэтому мне нужно получить DIV маркера и его положение в пикселях.

Но не смог получить его, потому что для определенного маркера нет идентификатора или класса. Только я могу получить доступ к div холста карты из объекта маркера и недокументированного объекта pixelBounds.

  1. Как я могу получить доступ к DIV маркера?
  2. Где я могу получить положение пикселя в DIV? Могу ли я преобразовать координаты широты в значения в пикселях?

== добавлена:

Я также пытался использовать приведенный ниже код, но он не меняется при прокрутке карты.

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 + ")");
});

Ответы [ 10 ]

48 голосов
/ 22 апреля 2010

Я действительно не понимаю, почему вы хотите получить конкретный div для маркера? Если вы хотите отобразить всплывающую подсказку, все, что вам нужно, это положение пикселя привязки маркеров (и знание размера маркера и размещения привязки), а не элемент div. Вы всегда можете вручную открыть и закрыть всплывающую подсказку, когда событие происходит на стороне google.maps.

Для получения позиции якоря данного маркера в пикселях вы можете использовать этот код:

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

В pixelDistance вы получаете смещение конкретной привязки маркера, подсчитанной от левого верхнего угла карты (и вы можете получить ее положение из map.getDiv() div). Почему это работает так (или есть лучший способ?), Вы можете прочитать в документации наложения карт Google .

10 голосов
/ 13 июля 2011
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);

Теперь вы можете получить доступ к своим координатам пикселей через p.x и p.y.

СЛЕДУЕТ ДОБАВИТЬ КОММЕНТАРИЙ ПОЧТЫ:

Недостаток оверлейной проекции состоит в том, что до завершения загрузки холста карты он не инициализируется. У меня есть следующий слушатель, который заставит любой метод, который мне нужно вызвать, когда карта завершит загрузку.

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

В то же время я использую следующую проверку, чтобы избежать ошибок до того, как она начнёт рисовать.

if(overlay.getProjection()) {
  // code here
}
3 голосов
/ 07 сентября 2011

Одна вещь, которую следует помнить при использовании кода MBO: Когда плитки карты повторяются, map.getBounds().getSouthWest() возвращает «-180» независимо от положения карты. Откат, который я использую в этом случае, - это вычисление расстояния в пикселях до центра вместо левого верхнего угла, поскольку map.getCenter(), похоже, возвращает центрированную точку в любом случае. Например. (используя 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)
);
2 голосов
/ 14 декабря 2012

кто-нибудь еще ищет ответ на этот вопрос, посмотрите здесь: http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries среди некоторых других полезных материалов для карт Google есть RichMarker, который позволяет добавлять выбранные вами элементы DOM в качестве перетаскиваемых маркеров. просто добавьте class / id для обработки с помощью jQuery.

1 голос
/ 22 мая 2012

Хорошо, если вы ДОЛЖНЫ получить доступ к DIV, вот код. Помните, что это будет работать только со стандартным маркером (20x34px), и он найдет все маркеры. Возможно, вы захотите улучшить этот хак в соответствии с вашими потребностями ...

BEWARE! ЭТО ХАК

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

    }
  }
}
1 голос
/ 11 августа 2011

MapCanvasProjection fromLatLngToContainerPixel(), вероятно, то, что автор после. Это даст вам смещение в пикселях относительно контейнера карты. Я провел несколько экспериментов и нашел «простейшее» рабочее решение. (Я бы хотел, чтобы 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 Перезвоните. А потом делай то, что тебе нужно, только после этого.

1 голос
/ 23 августа 2010

Ответ Рене дает вам только «мировые координаты» (то есть, координаты, не зависящие от уровня масштабирования и области просмотра).Однако ответ MBO кажется правильным, поэтому вы должны принять и проголосовать за него (я не могу, как я только что зарегистрировался), так как в противном случае решение может быть упущено.вместо этого вы можете использовать методы в MapCanvasProjection, но это означает, что вам придется создавать собственное наложение.См. здесь для примера.: P

0 голосов
/ 06 мая 2016

Для многих обстоятельств сложная математика, использующая вычисление и изменение положения штифта в принятом ответе, может быть подходящей.

Для моего конкретного использования я только что создала прозрачный PNG с холстом, значительно большим, чем мне нужно длязначокЗатем я просто экспериментировал с перемещением булавки внутри прозрачного фона и применением нового изображения к карте.

adjusting the pin offset in photoshop

Вот спецификация для добавления пользовательскихизображение с примерами: https://developers.google.com/maps/documentation/javascript/examples/icon-simple

Этот метод определенно будет масштабироваться как смещение в пикселях вместо фактического другого long / lat даже при увеличении.

0 голосов
/ 02 июля 2014

Я обнаружил, что проще всего назначить пользовательский значок и использовать атрибут img src для доступа к элементу. Вы по-прежнему можете использовать значок Google Maps по умолчанию, просто сохраните его локально.

$("#map img[src='my_marker.png']").getBoundingClientRect();
0 голосов
/ 28 мая 2012

Рабочий фрагмент стиля jQuery, готовый для копирования / вставки:

шаг 1 - инициализируйте вашу карту и опции

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

Как вы можете видеть ниже, карте переменных не предшествует VAR, поскольку она должна быть глобальной, поскольку мы используем другую функцию для получения fromLatLngToContainerPixel. Для более подробной информации проверьте закрытия .

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...