Создайте службу поиска предприятий поблизости с помощью платформы Google Maps (JavaScript)
О практической работе
1. Прежде чем вы начнете
Научитесь использовать Google Maps Platform Maps и Places API для создания локального поиска компаний, который определяет геолокацию пользователя и показывает интересные места поблизости. Приложение объединяет геолокацию, сведения о месте, фотографии места и многое другое.
Предпосылки
- Базовые знания HTML, CSS и JavaScript
- Проект с платежным аккаунтом (следуйте инструкциям на следующем шаге, если у вас его нет).
- Для описанного ниже шага включения вам потребуется включить Maps JavaScript API и Places API .
- Ключ API для вышеуказанного проекта.
Начало работы с платформой Google Карт
Если вы еще не использовали платформу Google Maps, следуйте руководству по началу работы с платформой Google Maps или просмотрите список воспроизведения Начало работы с платформой Google Maps , чтобы выполнить следующие шаги:
- Создайте платежный аккаунт.
- Создайте проект.
- Включите 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>
.
шаг1/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 -->
скопируйте и замените значение параметра ключа в исходном URL-адресе скрипта на ключ API, созданный во время предварительных требований.
шаг1/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 вашего браузера вместе с Maps JavaScript API.
Вот пример карты, которая отображает ваше географическое положение, если вы просматривали из Маунтин-Вью, Калифорния:
Что такое геолокация?
Геолокация относится к идентификации географического местоположения пользователя или вычислительного устройства с помощью различных механизмов сбора данных. Как правило, большинство служб геолокации используют сетевые адреса маршрутизации или внутренние устройства GPS для определения этого местоположения. Это приложение использует стандартное свойство геолокации W3C веб-браузера navigator.geolocation
для определения местоположения пользователя.
Попробуй сам
Замените код между комментариями TODO: Step 2, Geolocate your user
и END TODO: Step 2, Geolocate your user
следующим кодом:
шаг2/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()
службы PlacesService, который вернет массив объектов PlaceResult
.
А. Загрузите библиотеку мест
Во-первых, чтобы получить доступ к службам библиотеки мест, обновите исходный URL-адрес сценария, чтобы ввести параметр libraries
и добавить places
в качестве значения.
шаг3/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
приведен в следующем разделе.
шаг3/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
, чтобы убедиться, что центр и все маркеры видны на карте.
шаг3/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. Показать информацию о месте по запросу
Получив идентификатор места (введенный в качестве одного из полей в результатах поиска поблизости), вы можете запросить дополнительные сведения о месте, например его полный адрес, номер телефона, рейтинги и отзывы пользователей. В этой кодовой лаборатории вы создадите боковую панель для отображения подробных сведений о месте и сделаете маркеры интерактивными, чтобы пользователь мог выбирать места для просмотра сведений.
A. Сделайте общую боковую панель
Вам нужно место для отображения сведений о месте, поэтому вот простой код для боковой панели, которую вы можете использовать для выдвижения и отображения сведений о месте, когда пользователь нажимает на маркер.
- Добавьте следующий код в тег
style
после комментарияTODO: Step 4A1
:
шаг4/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');
B. Добавьте прослушиватели кликов к маркерам
- В функции
createMarkers
добавьте прослушиватель кликов к каждому маркеру по мере их создания.
Слушатель кликов извлекает сведения о месте, связанном с этим маркером, и вызывает функцию для отображения сведений.
- Вставьте следующий код в функцию
createMarkers
в комментарии к кодуTODO: Step 4B
.
Метод showDetails
реализуется в следующем разделе.
шаг4/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
в следующем разделе для отображения сведений на боковой панели.
шаг4/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
.
шаг4/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
, если вы хотите, чтобы фотография отображалась в верхней части боковой панели.
шаг4/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, дополнительные примеры кода и каналы поддержки. Некоторые популярные функции включают импорт данных в карты , начало оформления карты и добавление службы просмотра улиц .
Какой тип кодовой лаборатории вы больше всего хотели бы, чтобы мы построили в следующий раз?
Нужная вам кодовая лаборатория не указана выше? Запросите его с новым выпуском здесь .