В этом уроке мы пройдем процесс создания небольшого виджета, который позволит пользователям извлекать пошаговые инструкции в указанное место. Мы будем использовать API Карт Google через JavaScript, чтобы обеспечить эту довольно продвинутую функциональность.
Получение ключа API
Единственное предостережение при использовании Карт Google — мы должны подать заявку на ключ API , но это довольно тривиальный процесс, если у вас уже есть учетная запись Google / GMail. К сожалению, из-за требований Google мы должны разрабатывать на домене, который мы предоставляем Google, т.е. мы не можем разрабатывать на локальном сервере. К счастью для нас, процесс будет быстрым, и мы не будем тратить много времени на живой сервер. Кроме того, обязательно храните ваш ключ API в безопасном месте, потому что я не смог найти способ восстановить их после того, как он был сгенерирован, хотя, думаю, вы могли бы просто восстановить его.
Состояние дел
Прежде чем мы углубимся в код, позвольте мне обсудить причину этой идеи. Как большинство разработчиков я провожу много времени в сети. Одним из определенных подмножеств веб-сайтов, которые я посещаю, являются местные компании, которые, конечно, не располагают большими ресурсами, чтобы посвятить себя веб-дизайну, но, надеюсь, люди, разрабатывающие эти сайты, увидят подобные статьи и поймут, как легко включить полнофункциональный Карта на любую веб-страницу. Практически на любом веб-сайте, представляющем малый бизнес, есть страница, на которой рассказывается, как найти свое физическое местоположение. Часто вы получаете карту с привязанным к ней местоположением, что не помогает пользователям, которые не знают окрестности. В этом уроке мы собираемся изменить это и позволить пользователям вводить свой адрес и получать пошаговые инструкции по любому желаемому адресу.
Включая библиотеку JavaScript Карт Google
Теперь, когда мыльница вне пути, давайте рассмотрим код. Первое, что нам нужно сделать, это включить библиотеку Javascript, которая содержит все методы Google Maps. Google, вероятно, сгенерировал этот код, когда вы создали свой ключ API, но это могло указывать на API версии 3, который все еще находится на стадии бета-тестирования. Вот ссылка на API версии 2, обязательно вставьте свой ключ API. Мы также собираемся включить файл application.js, в котором будут храниться наши пользовательские функции, я хранил мой в каталоге на корневом уровне, который называется js . Следующий код находится в разделе заголовка вашей страницы.
1
2
|
<script src=»http://maps.google.com/?file=api&v=2&key=INSERT_API_KEY_HERE» type=»text/javascript»></script>
<script src=»./js/application.js» type=»text/javascript»></script>
|
HTML-код
В разделе тела нашей страницы нам нужна ограниченная разметка. Я кратко расскажу о необходимых битах, и вы можете посмотреть исходный код, чтобы увидеть пух, который я включил в мою демонстрацию. Первый элемент — это пустой div с идентификатором map_canvas , это местозаполнитель, на который мы указываем вызовы Google Maps, и он будет генерировать всю разметку карты в этом элементе.
1
|
<div id=»map_canvas»></div>
|
Затем я создал div для хранения адреса организации и формы для ввода пользователем своего адреса. Вы можете просмотреть этот код, но он довольно прост, и не очень трудно разглядеть его встречу. Обязательно посмотрите на мой CSS, чтобы увидеть, как он оформлен в моей демонстрации.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<div id=»addresses»>
<div class=»address-panel»>
<h2>Our Address</h2>
<address>
1450 Jayhawk Blvd #223<br />
Lawrence, KS<br />
66045
</address>
</div>
<div class=»address-panel»>
<h2>Your Address</h2>
<form action=»./index.php» onsubmit=»overlayDirections();return false;»
<div>
<label for=»street»>Street Address</label>
<input id=»street» name=»street_address» type=»text» />
</div>
<div>
<div class=»address-form-column»>
<label for=»city»>City</label>
<input id=»city» name=»city» type=»text» />
</div>
<div class=»address-form-column»>
<label for=»state»>State</label>
<select id=»state» name=»state»>
<option value=»AL»>Alabama</option>
<option value=»AK»>Alaska</option>
<option value=»AZ»>Arizona</option>
<option value=»AR»>Arkansas</option>
<option value=»CA»>California</option>
<option value=»CO»>Colorado</option>
…
</select>
</div>
<div class=»address-form-column»>
<label for=»zip»>Zip Code</label>
<input id=»zip» name=»zip_code» type=»text» maxlength=»5″ size=»5″ />
</div>
</div>
<div class=»button»>
<input name=»submit» type=»submit» value=»Get Directions» />
</div>
</form>
</div>
</div>
|
Обратите внимание, что мы отправляем эту страницу себе, чтобы мы могли обрабатывать страницу с помощью PHP, если у пользователя отключен JS. Если у них включен JS, мы хотим выполнить функцию overlayDirections (), которую мы рассмотрим чуть позже. Большая часть этого кода идет в поле выбора, которое позволяет пользователю выбирать свое состояние, я сократил его ради тех, кто печатает эту статью, но вы можете получить полный код из загрузки. Другие интересные примечания: мы устанавливаем размер и максимальную длину текстового поля почтового индекса равным 5. Последнее, что нужно отметить, — это то, что мы присвоили идентификаторы и имена всем элементам формы.
Начальная загрузка и объявление переменных
Хорошо, теперь мы можем перейти к сути этого урока, коду JavaScript. Почти все звонки, которые мы собираемся сделать, поступают из API Карт Google, на который мы ссылались ранее. Google предоставляет отличную документацию и пример кода на своем веб-сайте, поэтому обязательно ознакомьтесь с ним . Я постараюсь ссылаться на соответствующие страницы по мере их использования.
Во-первых, пока у нас открыта HTML-страница, мы можем загрузить функцию инициализации, установив атрибут onload . Примечание : это можно сделать в jQuery с помощью функции $ (document) .ready () .
1
|
<body onload=»initialize()»>
|
Теперь перейдем к файлу js / appication.js . Самое первое, что нам нужно сделать, это установить некоторые переменные. Некоторый евангелист кода, вероятно, выследит меня за объявление глобальных переменных, но я верю, что в этом случае у нас все будет хорошо. Я дам вам код, а затем объясню, как мы будем использовать каждый из них.
1
|
var gdir, fromAddress, toAddress;
|
- gdir : содержит объект GDirections, используемый для получения результатов проезда и отображения их на карте и / или текстовой панели.
- fromAddress : строка, содержащая полный адрес пользователя.
- toAddress : строка, содержащая адрес организации / организации
Функция initialize ()
Функция initialize (), которую мы вызывали ранее, будет использоваться для создания карты на странице и размещения собственного маркера нашего местоположения.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*
**
* Bootstrap function to setup map and apply
* custom company marker
*/
function initialize() {
if (GBrowserIsCompatible()) {
//settings
var companyMarkerImage= «./images/jayhawk.gif»;
var companyLatLng = new GLatLng(38.957101, -95.251469);
var companyMarkerSize = new GSize(55, 52);
toAddress = «1450 Jayhawk Blvd #223 Lawrence, KS 66045»;
var defaultZoomLevel = 13;
//end settings
//setup elements
map = new GMap2(document.getElementById(«map_canvas»));
gdir = new GDirections(map, document.getElementById(«directions»));
//error handler
GEvent.addListener(gdir, «error», handleErrors);
//set company marker
var companyMarker = createMarker(companyLatLng, companyMarkerImage, companyMarkerSize);
//set map center
map.setCenter(companyLatLng, defaultZoomLevel);
map.addOverlay(companyMarker);
}
}
|
Первое, что нам нужно сделать, это проверить, совместим ли браузер с Google Maps, и для этого Google предоставляет GBrowserIsCompatible () в своем API. По сути, он возвращает true, если браузер совместим, и позволяет нам перейти к остальной части нашей функции. Я решил абстрагировать некоторые значения от переменных в верхней части функции, чтобы их можно было легко перенести во многие приложения.
1
2
3
4
5
6
7
8
9
|
//settings
var companyMarkerImage= «./images/jayhawk.gif»;
var companyLatLng = new GLatLng(38.957101, -95.251469);
var companyMarkerSize = new GSize(55, 52);
toAddress = «1450 Jayhawk Blvd #223 Lawrence, KS 66045»;
var defaultZoomLevel = 13;
//end settings
|
CompanyMarkerImage — это строка местоположения небольшого изображения, которое мы разместим в нашем месте на карте. Это то, что я считаю приятным, чтобы иметь собственный значок, представляющий вашу компанию, который персонализирует общий вид карты Google. Затем companyLatLng содержит объект GLatLng, соответствующий точке широты и долготы в мире. Не выбегайте и купите устройство GPS, чтобы получить эти цифры, мы можем использовать maps.google.com . В поле поиска введите свой адрес, и когда он найдет местоположение, нажмите кнопку « Ссылка» в правом верхнем углу карты. Прокрутите первое текстовое поле в модальном окне и найдите & sll = ….
Вы можете скопировать и вставить эти координаты в параметры нашего конструктора GLatLng. Это точка на карте, где мы разместим наше собственное изображение. Следующая переменная, companyMarkerSize , содержит объект GSize, который представляет ширину и высоту вашего пользовательского изображения маркера. Затем мы устанавливаем адрес, который является адресом компании. Последняя переменная, defaultZoomLevel , просто сообщает карте, какой уровень масштабирования по умолчанию должен быть в диапазоне от 1 до 18.
1
2
3
|
//setup elements
map = new GMap2(document.getElementById(«map_canvas»));
gdir = new GDirections(map, document.getElementById(«directions»));
|
Следующая строка кода создает объект GMap2 . Google описывает это как «центральный класс в API». Это загружает данные карты и позволяет нам манипулировать тем, что отображается в области карты. Он принимает один аргумент объекта DOM, указывающего на элемент, содержащий карту, #map_canvas . Затем мы устанавливаем gdir для хранения объекта GDirections . Это интерфейс, который мы используем для запроса Google Maps о направлениях. Конструктор принимает два аргумента: объект карты и объект DOM, куда мы хотим поместить пошаговые указания. Я решил создать пустой div под адресами #dadctions .
1
2
|
//error handler
GEvent.addListener(gdir, «error», handleErrors);
|
При использовании веб-сервисов мы всегда рискуем получить ошибку. Мы можем сделать это максимально безболезненно, используя класс GEvent . В этом фрагменте кода мы говорим, что если у нас есть ошибка при получении инструкций по выполнению пользовательской функции обратного вызова, то в нашем случае handleErrors . Мы напрямую вызываем функцию addListener (), которая регистрирует обратный вызов. Он принимает 3 аргумента исходного объекта, строку, ссылающуюся на тип события, для которого мы хотим выполнить обратный вызов, и обработчик, который указывает на функцию, которую мы хотим выполнить. Функция handleErrors будет рассмотрена позже.
1
2
3
4
5
6
|
//set company marker
var companyMarker = createMarker(companyLatLng, companyMarkerImage, companyMarkerSize);
//set map center
map.setCenter(companyLatLng, defaultZoomLevel);
map.addOverlay(companyMarker);
|
Последние несколько строк в initialize () используются для создания нашего пользовательского маркера, я выбрал Jayhawk, найденный на домашней странице KU . createMarker — это функция-обертка, которую я написал, чтобы абстрагировать код, необходимый для создания пользовательского маркера. Он принимает три аргумента: ссылку на объект GLatLng, в которую мы хотим поместить изображение, строку, представляющую путь к изображению, и ссылку на объект GSize, который представляет размер изображения. Далее мы используем метод setCenter () класса GMap2, который принимает два аргумента : объект GLatLng с координатами для центрирования и целое число для уровня масштабирования. Обратите внимание, что мы передаем переменные, которые мы установили в блоке настроек в верхней части функции initialize () . В последней строке кода используется метод addOverlay () . Это то, что на самом деле добавляет пользовательское изображение на карту.
Функция initialize () выполняет тяжелую работу, но она, безусловно, может показать это. После того, как мы напишем функцию createMarker (), вы сможете загрузить приложение и увидеть некоторый прогресс. Но сначала давайте вспомним функцию initialize () .
Функция createMarker ()
Далее мы создадим функцию-обертку, которая избавит вас от необходимости создавать маркер с пользовательским изображением. Причина, по которой я решил абстрагироваться, заключается в том, что это сложный процесс, который еще больше загромождает нашу функцию initialize () . Еще одним дополнительным преимуществом является то, что мы можем очень быстро добавить несколько маркеров, не повторяя много кода.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
/*
**
* Wrapper function to create/return a marker object
* with custom image
*/
function createMarker(latlng, imageURL, imageSize)
{
var marker = new GIcon(G_DEFAULT_ICON, imageURL);
marker.iconSize = imageSize;
return new GMarker(latlng, { icon: marker });
}
|
Значительно меньше нашей первой функции, но не менее важно. Сначала мы объявляем новую переменную, маркер и сохраняем объект GIcon . Он может принимать два аргумента copy, который является объектом GIcon, из которого он будет копировать свойства, и image, который является строкой, представляющей путь к пользовательскому изображению. G_DEFAULT_ICON — это константа, представляющая маркер по умолчанию, а imageURL происходит из блока настроек в initialize () . Нам нужно только установить еще одно свойство, iconSize, которое имеет тип GSize , оно представляет размер нашего пользовательского изображения и также происходит из блока настроек. Последняя строка кода возвращает объект GMarker, который принимает два аргумента latlng и значок. Первый, latlng — это ссылка на объект GLatLng, который мы объявили в блоке настроек. Следующий аргумент — для объекта GIcon, который мы только что создали. Это все, что нам нужно сделать, чтобы часть нашего приложения работала с картой. Теперь вы можете загрузить страницу и посмотреть, как легко получить красивую карту на нашем сайте.
Добавление направлений
Это, безусловно, моя любимая часть этого урока, позволяющая пользователям вводить адрес и получать обратно карту с выделенным маршрутом и пошаговыми указаниями. Используя этот API, мы можем сконцентрировать то, что потребовало бы тысяч строк кода и невероятного количества ресурсов обработки, до всего лишь небольшого количества кода.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
/*
**
* Looks up the directions, overlays route on map,
* and prints turn-by-turn to #directions.
*/
function overlayDirections()
{
fromAddress =
document.getElementById(«street»).value
+ » » + document.getElementById(«city»).value
+ » » + document.getElementById(«state»).options[document.getElementById(«state»).selectedIndex].value
+ » » + document.getElementById(«zip»).value;
gdir.load(«from: » + fromAddress + » to: » + toAddress);
}
|
Первую строку я фактически расширил на пять строк для ясности. По сути это захватывает все значения из формы и помещает пробел между каждой частью. Я подумал, что это лучше, чем просить пользователя ввести весь адрес в одно текстовое поле, потому что это может сбить с толку.
Вторая строка использует gdir, который мы установили в initialize () . Мы вызываем метод load () и передаем один строковый аргумент, который, по сути, мы передаем maps.google.com через окно поиска. Ключевые слова from: и to: помогают Google указать, какой адрес должен быть отправной точкой, а какой — конечной. Это все, что нам нужно сделать для направления, да, я тоже был в шоке! Если вы посетите свою страницу еще раз, вы можете увидеть это в действии.
Обработка ошибок
Далее мы собираемся объявить функцию handleErrors () . Я взял это из примера кода Google на их веб-сайте API. Я не буду вдаваться в подробности, потому что это довольно просто.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
function handleErrors(){
if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
alert(«No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: » + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
alert(«A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: » + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
alert(«The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: » + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_BAD_KEY)
alert(«The given key is either invalid or does not match the domain for which it was given. \n Error code: » + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
alert(«A directions request could not be successfully parsed.\n Error code: » + gdir.getStatus().code);
else alert(«An unknown error occurred.»);
}
|
Он имеет длинный оператор if … elseif … else, который проверяет множество типов ошибок и предупреждает пользователя, если таковые возникают. Вы можете изменить это, если хотите сделать предупреждение менее техническим.
Degradable
Как хорошие веб-разработчики, мы должны убедиться, что наш веб-сайт работает для максимально возможного числа пользователей, в том числе с отключенным JavaScript. В этой ситуации я решил перенаправить тех, у кого JS отключен, в Карты Google с выполненным поиском, чтобы они все еще получали указания. Это делается с помощью PHP для оценки формы и перенаправления в Google Maps. Вверху вашей HTML-страницы вставьте этот код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<?php
//settings
$TO = «1450 Jayhawk Blvd #223 Lawrence, KS 66045»;
//end settings
//they seem to have JS disabled, let’s redirect them to
//Google Maps and prefill the query
if($_POST[‘submit’]) {
$FROM = $_POST[‘street’] .
$LOC = $_POST[‘language’];
$url = «http://maps.google.com/maps?hl=».urlencode($LOC).»&q=from:».urlencode($FROM).»+to:».urlencode($TO).»&ie=UTF8″;
header(«Location: » . $url);
}
?>
…
|
Сначала у нас снова есть блок настроек, в котором нужно установить только одну переменную, $ TO . Это похоже на то, что мы сделали в JavaScript для toAddress , но нам нужна та же строка в PHP. Далее у нас есть оператор if для проверки данных POSTed, что означает, что наша форма была отправлена. Теперь мы берем значения формы и помещаем их в строку с пробелами и сохраняем их в переменной $ FROM . Затем мы сохраняем значение языка в $ LOC , подробнее об этом позже. Переменная $ url будет содержать строку, представляющую URL-адрес запроса к Google. Обратите внимание, что мы кодируем наши значения url, чтобы они безопасно перемещались при перенаправлении. Последняя строка кода использует PHP-заголовки для перенаправления пользователя в Google.
Необязательно: добавьте поддержку нескольких языков
Как бизнес, вы хотите охватить как можно больше людей, и частью этого процесса является поддержка нескольких языков. В Google Maps поддержка других языков предоставляется нам без дополнительной оплаты.
Сначала откройте HTML-страницу и вставьте следующий код между тегами формы.
1
2
3
4
5
6
7
8
9
|
…
<select id=»language» name=»language»>
<option value=»en» selected>English</option>
<option value=»fr»>French</option>
<option value=»de»>German</option>
<option value=»ja»>Japanese</option>
<option value=»es»>Spanish</option>
</select>
…
|
Конечно, если вы хотите удалить какие-либо языки, просто удалите тег опции для него, вы также можете изменить значение по умолчанию, переместив выбранный атрибут.
Переходя к js / application.js , нам нужно сделать всего два изменения. Начиная с функции overlayDirections () после создания строки fromAddress, добавьте ее, чтобы получить выбранное значение из поля выбора языка и сохранить его в нашей языковой переменной.
1
2
3
|
…
var language = document.getElementById(«language»).options[document.getElementById(«language»).selectedIndex].value;
…
|
Затем добавьте аргумент в функцию gdir.load () , для этого потребуется набор опций. В нашем случае нам нужно только объявить локаль, чтобы она знала правильный язык и единицы измерения для пошаговых указаний.
1
2
3
|
…
gdir.load(«from: » + fromAddress + » to: » + toAddress, { «locale»: language });
…
|
Примечание : мы уже включили это в редирект PHP, и если вы хотите отключить это, просто статически установите $ LOC .
1
2
3
|
…
$LOC = ‘en’
…
|
Вывод
Это все, что нам нужно для этой удивительной функции, и я надеюсь, что вы немного узнали о Google Maps. Я призываю вас как разработчиков продолжать находить интересные способы интеграции карт в ваши приложения. Каждый раз, когда модель распознает местоположение, вы должны спросить, есть ли в вашем проекте визуальное представление на карте. Спасибо за прочтение; как всегда, я здесь, чтобы помочь в комментариях или в Твиттере ( @noahhendrix ).
- Подпишитесь на нас в Твиттере или подпишитесь на RSS-канал NETTUTS, чтобы получать ежедневные обзоры и статьи о веб-разработке.