понедельник, 18 января 2010 г.

jQuery и Google Maps API №1: Основы

jQuery и Google Maps API №1: Основы

А вот здесь-то мы и начнем использовать jQuery и Google Maps вместе. Очень сильно извращаться не станем, но будем использовать jQuery там, где это даст максимальную выгоду.

Вот, например, при помощи jQuery очень удобно создавать маркеры и обходить их массив, используя метод each(). Для начала расставим маркеры на карте:

// Устанавливаем 10 произвольных маркеров
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
var markers = [];
for (var i = 0; i < 10; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random());
marker = new GMarker(point);
map.addOverlay(marker);
markers[i] = marker;
}

А теперь – обойдем их и добавим к каждому обработчик события click: при щелчке левой кнопкой мыши по маркеру карта будет отцентрирована на этот маркер. Сначала мы получаем координаты маркера при помощи метода getLatLng(), а затем – центрируем карту по этим координатам при помощи метода panTo().

$(markers).each(function(i,marker){
GEvent.addListener(marker, "click", function(){
map.panTo(marker.getLatLng());
});
});

Далее, сделаем список, связанный с расставленными по карте маркерами. Добавляем список:

<ul id="list"></ul>

Теперь стилизуем его: он будет расположен справа от карты (для этого используем для блока с картой и списка float: left), когда мы будем наводить указатель на элемент списка, то тот будет подсвечиваться:

<style type="text/css" media="screen">
#map { float:left; width:500px; height:500px; }
#list { float:left; width:200px; background:#eee; list-style:none; padding:0; }
#list li { padding:10px; }
#list li:hover { background:#555; color:#fff; cursor:pointer; cursor:hand; }
</style>

Пришло время вспомнить про цикл, который мы организовали при помощи метода each(). Добавляем в его нутро следующий код:

$("<li />")
.html("Маркер №"+i)
.click(function(){
map.panTo(marker.getLatLng());
})
.appendTo("#list");

Код этот отвечает вот за что: делает элемент списка кликабельным и при клике центрирует карту по соответствующему элементу списка маркеру.

Теперь – выводим симпатичное сообщение вместо стандартного инфо-окна. Для начала создадим блок с текстом сообщения:

<div id="message" style="display:none;">
Какое-то сообщение тут.
</div>

Далее, слегка его стилизуем:

#message { position:absolute; padding:10px; background:#555; color:#fff; width:75px; }

Теперь бы нужно как-то поместить этот div с сообщением на карту. Вообще, карта представляет собой кучу слоев, которые также являются div’ами. Для того, чтобы узнать, в каком div’е на карте содержится маркер, мы будем использовать метод getPane() с параметром G_MAP_FLOAT_SHADOW_PANE, который лучше всего подходит для наших целей.

$("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));

Далее, для того, чтобы корректно отображалось наше самопальное информационное окно, нам необходимо заменить строчку map.panTo(marker.getLatLng(); на displayPoint(marker, i);, вызывающую функцию displayPoint(), код которой показан ниже.

function displayPoint(marker, i){
map.panTo(marker.getPoint());

var markerOffset = map.fromLatLngToDivPixel(marker.getPoint());
$("#message").show().css({ top:markerOffset.y, left:markerOffset.x });
}

Мы переложили функционал метода panTo() на плечи новой, самописной функции, главной изюминкой которой является метод fromLatLngToDivPixel(), который конвертирует значение координат маркера в его положение в пикселях относительно слоя с картой.

Нужно же как-то закончить нашу свистопляску? Закончим мы ее путем добавления обработчика события "moveend" для карты: после того, как карта закончит свое движение в направлении маркера, по которому был совершен клик, сработает jQuery-метод fadeIn() для блока с сообщением.

function displayPoint(marker, index){
$("#message").hide();

var moveEnd = GEvent.addListener(map, "moveend", function(){
var markerOffset = map.fromLatLngToDivPixel(marker.getLatLng());
$("#message")
.fadeIn()
.css({ top:markerOffset.y, left:markerOffset.x });

GEvent.removeListener(moveEnd);
});
map.panTo(marker.getLatLng());
}

Ну вот: что хотели, то и получили. :) Тут - работающий пример.

1 коммент.:

Анонимный комментирует...

Как програмно узнать предыдущий и следующий маркер?