ПОДСВЕЧИВАЕМ МАРКЕРЫ

Итак, сокрытия элементов управления картой мы коснулись, равно как и создания собственных элементов управления, и создания более функционального инфо-окна. Теперь пришло время поговорить о подсветке маркеров, ведь часто возникает ситуация, когда маркеров много и все они расположены очень близко друг к другу. И чтобы их различать, удобнее всего пользоваться механизмом подсветки, основанным на CSS-свойстве Z-index. Смысл заключается в следующем: сбоку от карты есть список объектов; эти объекты находятся очень близко друг к другу; при наведении курсора мыши на какой-нибудь пункт из списка, соответствующий объект подсвечивается, т.е. цвет его маркера меняется; наоборот, при наведении на какой-нибудь маркер на карте, подсвечивается соответствующий пункт списка; если же мы кликнем на пункт списка или на сам маркер, то из маркера «вылезет» инфо-окно, а сам он станет другого (третьего) цвета. Думаю, что объяснил доходчиво. :)

Итак, приступим!

Начнем с объявления переменных. Первой будет переменная map, в которой будет храниться экземпляр класса GMap2(), т.е. в ней будет храниться сама карта. Сразу за ней следует переменная list, в которой будет храниться список объектов. Потом идет массив marker, в котором будут храниться данные о маркерах. Далее идет переменная bounds, которая является объектом класса GLatLngBounds(), т.е. хранит в себе координаты двух вершин (северо-восточной и юго-западной) прямоугольника. И заканчивает список переменных массив markerImage, содержащий пути к различным маркерам. За все это отвечает такой вот код:

var map;
var list = "";
var marker = [];
var bounds = new GLatLngBounds();
var markerImage = [
"images/blank.png",
"images/blank[3].png",
"images/blank[4].png"
];

Вслед за переменными идет функция загрузки карты. Выглядит она вот так:

function init() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.addControl(new GMapTypeControl());
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(60.253442, 25.006256), 7);
parseXml("XML/z_markers.xml");
}
}

Как Вы уже могли догадаться, функция parseXML(), указанная в init(), отвечает за парсинг XML-файла. В качестве формального параметра мы передаем имя XML-файла. А вот и эта функция, которая идет сразу вслед за предыдущей:

function parseXml(fileName) {
GDownloadUrl(fileName, function(data, responseCode) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
var list;
for (var i = 0; i < markers.length; i++) {
var latlng = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
listMake(markers[i].getAttribute("name"),i);
ZMarker(latlng,markers[i].getAttribute("name"),1,0,i,null);
}
});
}

Функция GDownloadURL() подгружает заданный URL (в данном случае, указанный в параметре fileName). Далее мы создаем объект класса GXml() в переменной xml и парсим наш файл при помощи метода parse(). Полученные значения координат сохраняем в переменной latlng, предварительно сконвертировав в формат с плавающей точкой функцией parseFloat(). После конвертации координат вызывается функция listMake(), которая отвечает за создание списка объектов в боковом меню. В качестве формальных параметров в нее передаются название объекта и его порядковый номер. Выглядит функция следующим образом:

function listMake(line,j) {
list += "<span class='sidebar'";
list += "onclick='GEvent.trigger(marker["+j+"],\"click\")' ";
list += "onmouseover='GEvent.trigger(marker["+j+"],\"mouseover\")' ";
list += "onmouseout='GEvent.trigger(marker["+j+"],\"mouseout\")' ";
list += ">";
list += line;
list += "<\/span><br\/>";
document.getElementById("list").innerHTML = list;
}

Связь между пунктами списка и объектами на карте осуществляется посредством пространства имен GEvent, которое включает в себя функции, необходимые для регистрации обработчиков событий. Для всего этого безобразия используется метод trigger(), с указанными в качестве параметров событием (click, mouseover, mouseout) и объектом, над которым это событие происходит.

И затем все данные (координаты, название объекта, т.д.) передаем в качестве параметров в главную функцию сегодняшней статьи - ZMarker().

Выглядит она следующим образом:

var n=1;
function count(){
n++;
return n;
}
function ZMarker(point,label,n,imInd,i,visited) {
function sendBack(marker,b) {
return GOverlay.getZIndex(marker.getPoint().lat())-n*10000;
}
marker[i] = new GMarker(point,{title:label, zIndexProcess:sendBack});
map.addOverlay(marker[i]);
marker[i].setImage(markerImage[imInd]);
marker[i].visited = visited;

GEvent.addListener(marker[i], "click", function() {
marker[i].openInfoWindowHtml(label);
marker[i].visited = true;
GEvent.trigger(marker[i],"mouseout");
});
GEvent.addListener(marker[i],'mouseover',function(){
marker[i].setImage(markerImage[1]);
document.getElementById("list").getElementsByTagName("span")[i].style.background ="yellow";
});
GEvent.addListener(marker[i],'mouseout',function(){
if(marker[i].visited){
marker[i].setImage(markerImage[2]);
document.getElementById("list").getElementsByTagName("span")[i].style.color ="gray";
}
else{
marker[i].setImage(markerImage[0]);
document.getElementById("list").getElementsByTagName("span")[i].style.color ="black";
}
document.getElementById("list").getElementsByTagName("span")[i].style.background ="white";
});
GEvent.addListener(marker[i], "infowindowclose", function() {
map.removeOverlay(marker[i]);
ZMarker(point,label,count(), 2,i,marker[i].visited);
})
}

Логика работы этой функции описана в самом начале статьи, так что, думаю, нет нужды повторно ее описывать. Как видно, все изменения маркеров происходят при определенных событиях. Подсветка элементов списка осуществлена при помощи DOM-модели.

Подсветка же маркеров сделана при помощи метода setImage() класса GMarker(). Вот, наверное, и все по части JavaScript.

Ах да, чуть не забыл две финальные строчки:

window.onload = init;
window.onunload = GUnload;