1. Прежде чем начать
Научитесь использовать API Карт и Местоположений платформы Google Карт для создания локального поиска компаний, который определяет местоположение пользователя и показывает интересные места поблизости. Приложение интегрирует геолокацию, информацию о местах, фотографии мест и многое другое.
Предпосылки
- Базовые знания HTML, CSS и JavaScript
- Проект с платежным аккаунтом (если у вас его нет, следуйте инструкциям в следующем шаге).
- Для выполнения шага включения, описанного ниже, вам необходимо включить Maps JavaScript API и Places API .
- API-ключ для проекта, указанного выше.
Начните работу с платформой Google Карт
Если вы ранее не использовали платформу Google Карт, следуйте руководству «Начало работы с платформой Google Карт» или посмотрите плейлист «Начало работы с платформой Google Карт», чтобы выполнить следующие шаги:
- Создайте платежный аккаунт.
- Создать проект.
- Включите API и SDK платформы Google Карт (перечислены в предыдущем разделе).
- Сгенерируйте ключ API.
Что ты будешь делать?
- Создайте веб-страницу, отображающую карту Google
- Центрировать карту по местоположению пользователя
- Найдите близлежащие места и отобразите результаты в виде кликабельных маркеров.
- Получить и показать более подробную информацию о каждом месте
Что вам понадобится
- Веб-браузер, например Google Chrome (рекомендуется), Firefox, Safari или Internet Explorer
- Ваш любимый текстовый или кодовый редактор
Получить пример кода
- Откройте интерфейс командной строки (терминал в MacOS или командную строку в Windows) и загрузите пример кода с помощью этой команды:
git clone https://github.com/googlecodelabs/google-maps-nearby-search-js/
Если это не поможет, нажмите следующую кнопку, чтобы загрузить весь код для этой лабораторной работы, а затем разархивируйте файл:
- Перейдите в каталог, который вы только что клонировали или загрузили.
cd google-maps-nearby-search-js
Папки stepN
содержат желаемое конечное состояние каждого шага этой лабораторной работы. Они приведены для справки. Всю работу по кодированию выполняйте в каталоге work
.
2. Создайте карту с центром по умолчанию.
Создание карты Google на вашей веб-странице состоит из трех шагов:
- Создать HTML-страницу
- Добавить карту
- Вставьте свой ключ API
1. Создайте HTML-страницу
Ниже представлена карта, созданная на этом этапе. Центр карты расположен на Сиднейском оперном театре в Сиднее, Австралия. Если пользователь откажется от определения своего местоположения, карта по умолчанию будет использовать это местоположение и по-прежнему будет предоставлять интересные результаты поиска.
- Перейдите в папку
work/
. На протяжении всей оставшейся части работы над кодом вносите изменения в версию из папкиwork/
.
cd work
- В каталоге
work/
с помощью текстового редактора создайте пустой файл с именемindex.html
. - Скопируйте следующий код в
index.html
.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Sushi Finder</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
background-color: grey;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
/* TODO: Step 4A1: Make a generic sidebar. */
</style>
</head>
<body>
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- Map appears here -->
<div id="map"></div>
<!-- TODO: Step 1B, Add a map -->
</body>
</html>
- Откройте файл
index.html
в вашем веб-браузере.
open index.html
2. Добавить карту
В этом разделе показано, как загрузить API JavaScript Карт на вашу веб-страницу и написать собственный код JavaScript, который использует API для добавления карты на веб-страницу.
- Добавьте этот код скрипта туда, где вы видите
<!-- TODO: Step 1B, Add a map -->
после divmap
и перед закрывающим тегом</body>
.
step1/index.html
<!-- TODO: Step 1B, Add a map -->
<script>
/* Note: This example requires that you consent to location sharing when
* prompted by your browser. If you see the error "Geolocation permission
* denied.", it means you probably did not give permission for the browser * to locate you. */
/* TODO: Step 2, Geolocate your user
* Replace the code from here to the END TODO comment with new code from
* codelab instructions. */
let pos;
let map;
function initMap() {
// Set the default location and initialize all variables
pos = {lat: -33.857, lng: 151.213};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
}
/* END TODO: Step 2, Geolocate your user */
</script>
<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
3. Вставьте свой ключ API.
- В строке после
<!-- TODO: Step 1C, Get an API key -->
скопируйте и замените значение параметра key в исходном URL-адресе скрипта на ключ API, созданный вами во время выполнения предварительных требований.
step1/index.html
<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
- Сохраните HTML-файл, над которым вы работали.
Проверьте это
Перезагрузите в браузере файл, который вы редактировали. На месте серого прямоугольника должна появиться карта. Если вместо неё вы видите сообщение об ошибке, убедитесь, что вы заменили « YOUR_API_KEY
» в последнем теге <script>
на свой ключ API. См. выше, как получить ключ API, если у вас его ещё нет.
Полный пример кода
Полный код этого проекта на данный момент доступен на Github .
3. Геолокация пользователя
Далее вам необходимо отобразить географическое местоположение пользователя или устройства на карте Google, используя функцию геолокации HTML5 вашего браузера вместе с API Карт JavaScript.
Вот пример карты, которая отображает ваше географическое местоположение, если вы просматриваете страницу из Маунтин-Вью, Калифорния:
Что такое геолокация?
Геолокация — это определение географического местоположения пользователя или вычислительного устройства посредством различных механизмов сбора данных. Как правило, большинство геолокационных сервисов используют адреса сетевой маршрутизации или внутренние GPS-устройства для определения местоположения. Данное приложение использует свойство веб-браузера navigator.geolocation
соответствующее стандарту геолокации W3C, для определения местоположения пользователя.
Попробуйте сами.
Замените код между комментариями TODO: Step 2, Geolocate your user
и END TODO: Step 2, Geolocate your user
следующим кодом:
step2/index.html
/* TODO: Step 2, Geolocate your user
* Replace the code from here to the END TODO comment with this code
* from codelab instructions. */
let pos;
let map;
let bounds;
let infoWindow;
let currentInfoWindow;
let service;
let infoPane;
function initMap() {
// Initialize variables
bounds = new google.maps.LatLngBounds();
infoWindow = new google.maps.InfoWindow;
currentInfoWindow = infoWindow;
/* TODO: Step 4A3: Add a generic sidebar */
// Try HTML5 geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
bounds.extend(pos);
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
/* TODO: Step 3B2, Call the Places Nearby Search */
}, () => {
// Browser supports geolocation, but user has denied permission
handleLocationError(true, infoWindow);
});
} else {
// Browser doesn't support geolocation
handleLocationError(false, infoWindow);
}
}
// Handle a geolocation error
function handleLocationError(browserHasGeolocation, infoWindow) {
// Set default location to Sydney, Australia
pos = {lat: -33.856, lng: 151.215};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
// Display an InfoWindow at the map center
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Geolocation permissions denied. Using default location.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
currentInfoWindow = infoWindow;
/* TODO: Step 3B3, Call the Places Nearby Search */
}
/* END TODO: Step 2, Geolocate your user */
/* TODO: Step 3B1, Call the Places Nearby Search */
Проверьте это
- Сохраните файл.
- Перезагрузите страницу.
Теперь ваш браузер должен запросить разрешение на передачу вашего местоположения приложению.
- Нажмите кнопку «Заблокировать» один раз, чтобы увидеть, корректно ли система обработает ошибку и останется ли она центрированной на Сиднее.
- Перезагрузите страницу еще раз и нажмите « Разрешить» , чтобы проверить, работает ли геолокация и перемещает ли карта в ваше текущее местоположение.
Полный пример кода
Полный код этого проекта на данный момент доступен на Github .
4. Поиск мест поблизости
Поиск поблизости позволяет искать места в указанной области по ключевому слову или типу. Поиск поблизости всегда должен включать местоположение, которое можно указать одним из двух способов:
- Объект
LatLngBounds
, определяющий прямоугольную область поиска. - Круговая область, определяемая как комбинация свойства
location
(указывающего центр круга как объектLatLng
) и радиуса, измеряемого в метрах.
Инициируйте поиск поблизости, вызвав метод PlacesService
nearbySearch()
, который вернет массив объектов PlaceResult
.
А. Загрузить библиотеку мест
Во-первых, чтобы получить доступ к службам библиотеки Places, обновите URL-адрес источника скрипта, введя параметр libraries
и добавив places
в качестве значения.
step3/index.html
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
B. Вызовите запрос поиска мест поблизости и обработайте ответ.
Затем сформируйте запрос PlaceSearch. Минимальный набор обязательных полей:
Минимально необходимые поля:
-
bounds
, который должен быть объектомgoogle.maps.LatLngBounds
, определяющим прямоугольную область поиска, илиlocation
иradius
; первый принимает объектgoogle.maps.LatLng
, а второй — простое целое число, представляющее радиус круга в метрах. Максимально допустимый радиус составляет 50 000 метров. Обратите внимание, что еслиrankBy
установлен вDISTANCE
, необходимо указать местоположение, но нельзя указать радиус или границы. -
keyword
, которое будет сопоставляться со всеми доступными полями, включая, помимо прочего, имя, тип и адрес, а также отзывы клиентов и другой сторонний контент, илиtype
, ограничивающий результаты местами, соответствующими указанному типу. Можно указать только один тип (если указано несколько типов, все типы, следующие за первым, игнорируются). См. список поддерживаемых типов .
В этой лабораторной работе вы будете использовать текущее местоположение пользователя в качестве местоположения для поиска и ранжировать результаты по расстоянию.
- Добавьте следующее в комментарий
TODO: Step 3B1
, чтобы написать две функции для вызова поиска и обработки ответа.
В качестве поискового запроса используется ключевое слово sushi
, но вы можете изменить его. Код для определения функции createMarkers
приведён в следующем разделе.
step3/index.html
/* TODO: Step 3B1, Call the Places Nearby Search */
// Perform a Places Nearby Search Request
function getNearbyPlaces(position) {
let request = {
location: position,
rankBy: google.maps.places.RankBy.DISTANCE,
keyword: 'sushi'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, nearbyCallback);
}
// Handle the results (up to 20) of the Nearby Search
function nearbyCallback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
createMarkers(results);
}
}
/* TODO: Step 3C, Generate markers for search results */
- Добавьте эту строку в конец функции
initMap
в комментарииTODO: Step 3B2
.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
- Добавьте эту строку в конец функции
handleLocationError
в комментарииTODO: Step 3B3
.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);
C. Генерация маркеров для результатов поиска
Маркер обозначает местоположение на карте. По умолчанию маркер использует стандартное изображение. Информация о настройке изображений маркеров представлена в разделе «Маркеры» .
Конструктор google.maps.Marker
принимает один литерал объекта Marker options
, определяющий начальные свойства маркера.
Следующие поля особенно важны и обычно задаются при построении маркера:
-
position
(обязательно) указываетLatLng
, определяющий начальное местоположение маркера. -
map
(необязательно) определяет карту, на которой будет размещен маркер. Если карта не указана при создании маркера, маркер будет создан, но не будет прикреплён к карте (или отображен на ней). Вы можете добавить маркер позже, вызвав методsetMap()
маркера. - Добавьте следующий код после комментария
TODO: Step 3C
, чтобы задать положение, карту и название для одного маркера для каждого места, возвращаемого в ответе. Также используйте методextend
переменнойbounds
, чтобы обеспечить видимость центра и всех маркеров на карте.
step3/index.html
/* TODO: Step 3C, Generate markers for search results */
// Set markers at the location of each place result
function createMarkers(places) {
places.forEach(place => {
let marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title: place.name
});
/* TODO: Step 4B: Add click listeners to the markers */
// Adjust the map bounds to include the location of this marker
bounds.extend(place.geometry.location);
});
/* Once all the markers have been placed, adjust the bounds of the map to
* show all the markers within the visible area. */
map.fitBounds(bounds);
}
/* TODO: Step 4C: Show place details in an info window */
Проверьте это
- Сохраните и перезагрузите страницу, а затем нажмите «Разрешить» , чтобы предоставить разрешения на геолокацию.
Вокруг центра карты вы увидите до 20 красных маркеров.
- Перезагрузите страницу еще раз и на этот раз заблокируйте разрешения на геолокацию.
Вы по-прежнему получаете результаты в центре вашей карты по умолчанию (в примере центром по умолчанию является Сидней, Австралия)?
Полный пример кода
Полный код этого проекта на данный момент доступен на Github .
5. Показывать информацию о месте по запросу
Получив идентификатор места (который отображается в качестве одного из полей в результатах поиска поблизости), вы можете запросить дополнительную информацию о нём, например, полный адрес, номер телефона, а также оценки и отзывы пользователей. В этой лабораторной работе вы создадите боковую панель для отображения подробной информации о месте и сделаете маркеры интерактивными, чтобы пользователь мог выбирать места для просмотра подробной информации.
А. Создайте общую боковую панель
Вам нужно место для отображения сведений о месте, поэтому вот простой код для боковой панели, которую можно использовать для выдвижения и отображения сведений о месте, когда пользователь нажимает на маркер.
- Добавьте следующий код в тег
style
после комментарияTODO: Step 4A1
:
step4/index.html
/* TODO: Step 4A1: Make a generic sidebar */
/* Styling for an info pane that slides out from the left.
* Hidden by default. */
#panel {
height: 100%;
width: null;
background-color: white;
position: fixed;
z-index: 1;
overflow-x: hidden;
transition: all .2s ease-out;
}
.open {
width: 250px;
}
/* Styling for place details */
.hero {
width: 100%;
height: auto;
max-height: 166px;
display: block;
}
.place,
p {
font-family: 'open sans', arial, sans-serif;
padding-left: 18px;
padding-right: 18px;
}
.details {
color: darkslategrey;
}
a {
text-decoration: none;
color: cadetblue;
}
- В разделе
body
непосредственно перед блоком divmap
добавьте блок div для панели подробностей.
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- The slide-out panel for showing place details -->
<div id="panel"></div>
- В функции
initMap()
после комментарияTODO: Step 4A3
инициализируйте переменнуюinfoPane
следующим образом:
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');
Б. Добавьте прослушиватели щелчков к маркерам
- В функции
createMarkers
добавьте прослушиватель щелчков для каждого маркера по мере их создания.
Прослушиватель щелчков извлекает сведения о месте, связанном с этим маркером, и вызывает функцию для отображения сведений.
- Вставьте следующий код в функцию
createMarkers
в комментарий к кодуTODO: Step 4B
.
Метод showDetails
реализован в следующем разделе.
step4/index.html
/* TODO: Step 4B: Add click listeners to the markers */
// Add click listener to each marker
google.maps.event.addListener(marker, 'click', () => {
let request = {
placeId: place.place_id,
fields: ['name', 'formatted_address', 'geometry', 'rating',
'website', 'photos']
};
/* Only fetch the details of a place when the user clicks on a marker.
* If we fetch the details for all place results as soon as we get
* the search response, we will hit API rate limits. */
service.getDetails(request, (placeResult, status) => {
showDetails(placeResult, marker, status)
});
});
В запросе addListener
свойство placeId
указывает одно место для запроса сведений, а свойство fields
представляет собой массив имён полей с информацией, которую нужно вернуть об этом месте. Полный список полей, которые можно запросить, см. в разделе Интерфейс PlaceResult .
C. Показать сведения о месте в информационном окне
Информационное окно отображает содержимое (обычно текст или изображения) в диалоговом окне над заданным местом на карте. Информационное окно состоит из области содержимого и конической ножки. Кончик ножки прикреплён к указанному месту на карте. Обычно информационные окна прикрепляются к маркерам, но вы также можете прикрепить информационное окно к определённой широте/долготе.
- Добавьте следующий код в комментарий
TODO: Step 4C
, чтобы создатьInfoWindow
, отображающее название и рейтинг компании, и прикрепить это окно к маркеру.
В следующем разделе вы определяете showPanel
для отображения подробностей на боковой панели.
step4/index.html
/* TODO: Step 4C: Show place details in an info window */
// Builds an InfoWindow to display details above the marker
function showDetails(placeResult, marker, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
let placeInfowindow = new google.maps.InfoWindow();
placeInfowindow.setContent('<div><strong>' + placeResult.name +
'</strong><br>' + 'Rating: ' + placeResult.rating + '</div>');
placeInfowindow.open(marker.map, marker);
currentInfoWindow.close();
currentInfoWindow = placeInfowindow;
showPanel(placeResult);
} else {
console.log('showDetails failed: ' + status);
}
}
/* TODO: Step 4D: Load place details in a sidebar */
D. Загрузить информацию о месте на боковой панели
Используйте те же данные, возвращаемые объектом PlaceResult
, для заполнения другого элемента div. В этом примере используется infoPane
— произвольное имя переменной для элемента div с идентификатором « panel
». Каждый раз, когда пользователь нажимает на новый маркер, этот код закрывает боковую панель, если она уже открыта, стирает старые данные, добавляет новые и открывает боковую панель.
- Добавьте следующий код после комментария
TODO: Step 4D
.
step4/index.html
/* TODO: Step 4D: Load place details in a sidebar */
// Displays place details in a sidebar
function showPanel(placeResult) {
// If infoPane is already open, close it
if (infoPane.classList.contains("open")) {
infoPane.classList.remove("open");
}
// Clear the previous details
while (infoPane.lastChild) {
infoPane.removeChild(infoPane.lastChild);
}
/* TODO: Step 4E: Display a Place Photo with the Place Details */
// Add place details with text formatting
let name = document.createElement('h1');
name.classList.add('place');
name.textContent = placeResult.name;
infoPane.appendChild(name);
if (placeResult.rating != null) {
let rating = document.createElement('p');
rating.classList.add('details');
rating.textContent = `Rating: ${placeResult.rating} \u272e`;
infoPane.appendChild(rating);
}
let address = document.createElement('p');
address.classList.add('details');
address.textContent = placeResult.formatted_address;
infoPane.appendChild(address);
if (placeResult.website) {
let websitePara = document.createElement('p');
let websiteLink = document.createElement('a');
let websiteUrl = document.createTextNode(placeResult.website);
websiteLink.appendChild(websiteUrl);
websiteLink.title = placeResult.website;
websiteLink.href = placeResult.website;
websitePara.appendChild(websiteLink);
infoPane.appendChild(websitePara);
}
// Open the infoPane
infoPane.classList.add("open");
}
E. Отображение фотографии места с информацией о нем
Результат getDetails
возвращает массив, содержащий до 10 фотографий, связанных с placeId
. Здесь первая фотография отображается над названием места в боковой панели.
- Поместите этот код перед созданием элемента
name
, если вы хотите, чтобы фотография отображалась в верхней части боковой панели.
step4/index.html
/* TODO: Step 4E: Display a Place Photo with the Place Details */
// Add the primary photo, if there is one
if (placeResult.photos != null) {
let firstPhoto = placeResult.photos[0];
let photo = document.createElement('img');
photo.classList.add('hero');
photo.src = firstPhoto.getUrl();
infoPane.appendChild(photo);
}
Проверьте это
- Сохраните и перезагрузите страницу в браузере и разрешите доступ к геолокации.
- Щелкните по маркеру, чтобы увидеть всплывающее информационное окно с некоторыми подробностями, а также выдвижную боковую панель слева для отображения дополнительных сведений.
- Проверьте, работает ли поиск, если вы перезагрузите страницу и отмените доступ к геолокации. Измените ключевое слово поиска на другой запрос и изучите результаты.
Полный пример кода
Полный код этого проекта на данный момент доступен на Github .
6. Поздравления
Поздравляем! Вы использовали множество функций Maps JavaScript API, включая библиотеку Places
.
Что мы рассмотрели
- Создание карты с помощью класса google.maps.Map
- Использование браузера пользователя для геолокации и отображения результатов на карте
- Добавление маркеров на карту и реагирование на нажатия на них пользователем
- Добавление информационных окон для отображения дополнительной информации при нажатии пользователем на маркер
- Загрузка библиотеки мест и выполнение поиска поблизости
- Получение и отображение информации о месте и фотографий места
Узнать больше
Чтобы использовать карты ещё эффективнее, изучите документацию Maps JavaScript API и документацию Places Library . Обе эти книги содержат руководства, учебные материалы, справочник по API, дополнительные примеры кода и каналы поддержки. Среди популярных функций — импорт данных в карты , настройка стиля карты и добавление сервиса Street View .
Какую следующую лабораторную работу вы бы хотели, чтобы мы создали?
Нужная вам кодлаб-программа не указана выше? Запросите её в новом выпуске здесь .