Допустим вы решили в качестве API для карты выбрать google карты. В этой статье вы узнаете о сложностях и тонкостях использования Google Maps в качестве API-карты.
Начало работы
Прежде всего идем на домашнюю страницу api гуглокарт. Чтобы использовать карты на своем сайте, вам необходимо зарегистрироваться и получить специальный ключ (он уникален для каждого домена). Стоит отметить, что если вы пока работаете на локалхосте, то ключ необязателен.Далее нужно подключить скрипт google карт к вашей странице и вывести карту в определенный блок. Делается это следующим образом:
<!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Гугокарты</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(59.94, 30.3), 13);
}
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width: 500px; height: 300px"></div>
</body>
</html>
Функция initialize() проверяет, справится ли браузер с картами, и, если да, то помещает карту в блок с id=»map_canvas». Далее центр карты(map.setCenter(…)) ставится в точку c широтой 59.94 и долготой 30.3. Масштаб карты — 13.
Еще парочка моментов. На google картах есть подписи, язык которых по умолчанию зависит от языка вашего браузера. Если вы хотите, чтобы карты всегда были на каком-то одном языке и не зависили от языка браузера, то подключать google карту к странице нужно вот так (параметр hl отвечает за язык):
<script type="text/javascript" src="http://maps.google.com/maps?file=api&v=2&key=abcdef&hl=ru"></script>
Контролы
Есть дефолтные (их положение и внешний вид фиксированы), а есть свои.
Дефолтные можно подключить вот так (модифицированная функция initialize()):
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl()); // масштаб и перемещение карты
map.addControl(new GMapTypeControl()); // переключение типов карты
map.setCenter(new GLatLng(59.94, 30.3), 13);
}
}
Дефолтные контролы нас не устраивали, поэтому я стал искать, как сделать свои. В итоге я нашел вот такой клевый мануал по google картам на русском (перевод официальных мануалов от гугла):
PDF, 960КБ
Среди методов изменения google карты есть и нужные нам:
- map.getZoom() — значение текущего зума;
- map.setZoom(zoomVal) — уставливает значение зума google карты равным zoomVal;
- map.zoomIn() и map.zoomOut() соответственно приближают и удаляют карту.
Эти действия можно повесить на любой элемент вашей страницы, который потом можно стилизовать по своему вкусу.
Маркеры и иконки
Это отметки на карте. На любой маркер можно повесить любой действие. Вот так добавляется маркер на google карту:
var point = new GLatLng(point_lat, point_long);
var marker = new GMarker(point);
map.addOverlay(marker);
Если вы хотите, чтобы ваш маркер можно было перетаскивать, то добавляйте маркер на карту вот так:
var point = new GLatLng(point_lat, point_long);
var marker = new GMarker(point, {draggable: true});
GEvent.addListener(marker, "dragstart", function() {
alert('Начали перетаскивать')
});
GEvent.addListener(marker, "dragend", function() {
alert('Перетащили');
});
map.addOverlay(marker);
На месте алертов можно вставить свои функции.
Теперь будем ставить свои иконки на маркеры (гугловские тоже ничего, но свои-то лучше ;-). Определяем объект tinyIcon, который и будет отвечать за иконку маркера:
var tinyIcon = new GIcon();
tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png"; // путь к иконке
tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png"; // к тени (если она вам нужна)
tinyIcon.iconSize = new GSize(12, 20); //размеры иконки
tinyIcon.shadowSize = new GSize(22, 20); // размеры тени
tinyIcon.iconAnchor = new GPoint(6, 20); // "центр" иконки
tinyIcon.infoWindowAnchor = new GPoint(5, 1); // точка привязки инфоокна
И чтобы сделать маркер с иконкой tinyIcon:
markerOptions = { icon:tinyIcon };
var marker = new GMarker(point, markerOptions);
Инфоокна
Опять же, можно использовать встроенные инфоокна (что проще) и свои (которые можно сделать по своему вкусу). Стандартные инфоокна вызываются вот так:
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml("Здесь текст окна в HTML");
});
Мы решили пойти сложным и красивым путем и начали искать библиотеки для реализации собственных окон. В итоге нашли набор вспомогательных утилит для google карт и среди них ExtInfoWindow.
Штука довольно хорошая (хотя тяжелая) — все просто и понятно. После подключения скрипта к странице само окошко вызывается вот так:
GEvent.addListener(marker, 'click', function(){
marker.openExtInfoWindow(
map,
"simple_example_window", // это префикс классов css элементов инфоокна
"Опять же ваш html.",
{beakOffset: 3}
);
});
А что делать, если много маркеров
Мы задали себе этот вопрос когда на карте Москвы у нас было около 700 точек. При таких количествах Ослик (и 6-ой, и 7-ой) вис в лучшем случае минуты на 2 (в худшем вис намертво), после чего дико тормозил. Сначала мы попробовали выводить точки по очереди (по несколько штук с таймаутом). Получилось красиво, но так же долго и фатально для Осла.
Для решения этого вопроса есть отличный скрипт под названием кластерер. Вот, что умеет эта хитрая штука:
- группировка близко расположенных маркеров в один (миникальное кол-во в группе можно установить самому);
- показ только тех точек, которые находятся в зоне видимости.
Посмотрим, как это добро использовать:
var clusterer = new Clusterer(map);
clusterer.AddMarker(marker, title); // это вместо map.addOverlay(marker);
Да, это все. Вы просто добавляете маркер не сразу на карту, а пропускаете его через кластерер.
Единственное, что я переделал в скрипте кластерера это событие при клике на сгруппированный маркер. По умолчанию выводится окошко со списком маркеров в этой группе. Это мне показалось не очень удобным, поэтому я сделал так, что при клике карта увеличивается на 1 деление и центр карты ставится на центр группы.