22 декабря 2015
3 октября 2008
125
Google Maps
Все вы, наверное, знаете, что совсем недавно мы запустили свой новый проект. Это карта Wi-Fi точек по городам России. В качестве API для карты мы выбрали google карты (конкурентов у него не было и нет). Так вот, сегодня я расскажу некоторые о некоторых полезных / сложных / интересных моментах, с которыми я столкнулся при использовании Google Maps. В общем, начинаем.
Думаю, стоит заметить, что до написания этого проекта я ни разу не использовал карты google в работе. Я, конечно же, работал с сервисами на их основе, но никогда не использовал их сам.
Начало работы
Прежде всего идем на домашнюю страницу 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 картам на русском (перевод официальных мануалов от гугла):
Документация по Google Maps на русском
PDF, 960КБ
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 деление и центр карты ставится на центр группы.
Ссылки в тему
- Mapki.com — вики по google картам;
- Уроки от Майка Вильямса — куча интересных примеров;
- Блог Андре — много интересных записей.
Спасибо за внимание и до новых встреч!
Кстати, про доавбление точки пользователя по-моему вы занули с центрами... Нельзя разве по клику на карте в любом месте обрабатывать координаты точки? У меня сделано так - при редактировании профиля клик по карте заносит значения широты и долготы в тексбоксы, а при сохранении они пишутся в базу.
[quote]есть карта и пользователь может себя добавить на нее и для этого точку своего местоположения он должен разместить в центре окна карты, что понятно не очень удобно и наглядно, вот и нужно как-то прорисовать этот центр.[/quote]
Так вот, это как-то неудобно заставлять пользователя размещать карту по центру, чтобы обозначить его местоположение... Гораздо проще обрабатывать событие клика по карте и с получеными координатами работать, не?
Спасибо за статью.
Конечно, пользуйся на здоровье
http://mistakes.ru/files/images/wi.png
И здесь в статье:
(миникальное кол-во в группе...
Может, поставите какую-нибудь систему проверки: Orpus или эту. Я бы с удовольствием поучаствовал в исправлении, а то в комментариях как-то не очень приятно об ошибках писать.
Merci!
www.citynavigator-spb.ru/karta.htm
кажется я нашел ответ по этому адресу http://otvety.google.ru/otvety/thread?tid=2b3966d66d6e29db а именно: надо добавить следующее: <script src="http://maps.google.com/maps..." type="text/javascript" charset="utf-8">
Спасибо вам всем! и извинте, что беспокоил
Не знаете с чем может быть связан баг ( "GIcon" - определение отсутствует ) в Explorer.v6xx..Пример брал с сайта http://econym.org.uk/ ?
«не объявлен» означает, что ты применяешь действия к объекту, который еще не был определен.
Для этого нужно иметь GPS
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(59.94, 30.3), 13);
}
map.addEvent('click',function(event){
event.stop();
map.zoomIn();
});
}
m.openInfoWindowHtml("Адрес: ул. Авиамоторная, д.4");
});
map.addOverlay(m);
Как можно в окне, при клике, которое открывает, сделать ссылку
Я пытаюсь сделать вот так
m.openInfoWindowHtml("Адрес: ул. Авиамоторная, д.4");
он ругается и не работает.
justcms, проверь правильность всех кодировок.
type="text/javascript" charset="utf-8"
IE стал правильно отображать названия системных кнопок, но содержимое не отображает
В XML добавил
?xml version="1.0" encoding="windows-1251"?
FF стал все отображать замечательно, IE пустые поля
вот пример http://service01.ru/map/1.html
http://service01.ru/map/example.xml
FF - все ок, IE - кнопки русские, данные из XML НЕ отображаются
в XML если меняю Windows-1251 на utf-8
FF - иероглифы, IE - кнопки русские, данные из XML НЕ отображаются
Вне зависимости от кодировке в XML файле, IE не отображает русский текст
function goooogle() {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(55.75, 37.62), 10);
moscow1 = new GMarker(new GLatLng(55.753576, 37.716450));
GEvent.addListener(moscow1, "click", function() {
moscow1.openInfoWindowHtml('text');
});
map.addOverlay(moscow1);
moscow2 = new GMarker(new GLatLng(55.686899, 37.573349));
GEvent.addListener(moscow2, "click", function() {
moscow2.openInfoWindowHtml('text');
});
map.addOverlay(moscow2);
moscow3 = new GMarker(new GLatLng(55.689620, 37.602767));
GEvent.addListener(moscow3, "click", function() {
moscow3.openInfoWindowHtml('text');
});
map.addOverlay(moscow3);
}
_________________________
Как можно метки отдельно описать например
var metky{opisivaem ih tyt}
function goooogle() {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(55.75, 37.62), 10);
tyt vivodim nyjnie metki k primery metky 1, 5, 10.
}
давно хотел что-то подобное прикрутить у себя на сайте, теперь, вы это найдете, через некоторое время, у меня на сайте в разделе каталог !!!
огромное спасибо!!!
вместо этого
в IE же почему-то не грузится правый кусок карты то есть карта есть, но она грузится не целиком и центровка выполняется не корректно.
//
if (GBrowserIsCompatible()) {
var town_names_html = "";
var gmarkers = [];
var htmls = [];
var i = 0;
var zIcon = new GIcon();
zIcon.image = "gmapicon1.png";
zIcon.iconSize = new GSize(20, 20);
zIcon.shadowSize = new GSize(25, 25);
zIcon.iconAnchor = new GPoint(9, 34);
zIcon.infoWindowAnchor = new GPoint(9, 2);
zIcon.infoShadowAnchor = new GPoint(18, 25);
zIcon.printImage = "gmapicon1.gif";
zIcon.mozPrintImage = "gmapicon1.gif";
var zIcon2 = new GIcon();
zIcon2.image = "gmapicon1.png";
zIcon2.iconSize = new GSize(20, 20);
zIcon2.shadowSize = new GSize(25, 25);
zIcon2.iconAnchor = new GPoint(9, 34);
zIcon2.infoWindowAnchor = new GPoint(9, 2);
zIcon2.infoShadowAnchor = new GPoint(18, 25);
zIcon2.printImage = "gmapicon1.gif";
zIcon2.mozPrintImage = "gmapicon1.gif";
var icons = [];
icons[0] = zIcon;
icons[1] = zIcon2;
function createMarker(point,name,html,icontype) {
var marker = new GMarker(point,icons[icontype]);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
gmarkers[i] = marker;
htmls[i] = html;
town_names_html += '' + name + '
';
i++;
return marker;
}
function myclick(i) {
gmarkers[i].openInfoWindowHtml(htmls[i]);
}
var map = new GMap2(document.getElementById("map"));
var center = new GLatLng(58, 39);
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(center, 15);
var request = GXmlHttp.create();
request.open("GET", "gmaps.xml", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var xmlDoc = GXml.parse(request.responseText);
var markers = xmlDoc.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("lat"));
var lng = parseFloat(markers[i].getAttribute("lng"));
var point = new GLatLng(lat,lng);
var html = markers[i].getAttribute("html");
var label = markers[i].getAttribute("label");
var icontype = parseInt(markers[i].getAttribute("icontype"));
var marker = createMarker(point,label,html,icontype);
map.addOverlay(marker);
}
document.getElementById("town_names").innerHTML = town_names_html;
}
}
request.send(null);
}
else {
alert("Извините, карта Google не работает с данным браузером.");
}
//]]>
некорректно только в IE работает (((( как починить незнаю..
Короче - спасибо за статью.
Подскажите, пожалуйста, как можно работать с google maps локально? Я так понимаю, необходимо скачать дистрибутив, поставить...или нет? Заранее спасибо!
Дистрибутив ставить тоже не надо, нужно просто подключить файл к странице как сказано в статье.
Спасибо.
http://www.extjs.com/deploy/dev/examples/message-box/msg-box.html
У меня сайт, каталог организации в моем городе. Сам сайт большой. Но хотелось бы чтобы на сайте показывался адрес от гуглмапс... Я так понял что из поля с адресом организации, должен быть как бы импорт адреса для карты?
Как это можно сделать?
www.spravkatver.ru - вот идем к любой организации, просматриваем её подробнее... на странице с просмотром должна быть карта с самим адресом.
Друзья подскажите как сделать с самого начала, как для самого нуба...
Спасибо большое за урок. Привязал карту к сайту, п-ли добавляют метки - все хорошо. Но есть одна проблема. Как можно сделать изменение масштаба по клику на ссылке. Т.е. у меня стоит по умолчанию показ АЗС по городу, а я хочу добавить кнопку (ссылку) при клике на которой просто бы изменялся масштаб, чтобы видеть АЗС по области.
Если у нас есть сервер с внешним статическим ip и открытым доступом к веб-серверу извне - можем ли мы получить API ключ ?
При запросе на получение API ключа и вводе ссылки на сайт в виде http://x.x.x.x получаем сообщение что запрашиваемая страница не найдена :(
просто боюсь моих познаний не хватит найти на ftp тот файл который отвечает за отдельную (нужную мне)страничку.
наверно придется смотреть в сторону яндекс.карт ибо найти таких файло в шаблоне я не смог(
там можно такое прописывать?
Тема такая, есть жд портал, нужно сделать прорисовку пути по жд дорогам как на http://ati.su (не рекламирую не пиннайте, привожу как пример)
Считываю XML ответ определяю координаты и вывожу карты. Загвoздка в том, что в Донецке (Украина) все русско говорящие, а адреса на украинском, но когда я ввожу в гугле адресс на карте он отображае его и на русском и на украинском, я немогу понять, как искать по русским названиям улиц.
не могу нигде найти инфо о способах оплаты гугль карт для организаций (ну, чтобы не было ограничений по использованию). Цену таки удалось найти, а вот как оплатить - нет.
Хелп!