Статьи

Правильное использование JavaScript API Карт Google

Эта статья была рецензирована Тимом Севериеном , Нурией Суазо и Мэллори ван Ачтербергом. Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Значок Google Maps

Карты Google — это онлайн-картографическая служба, предоставляющая современные дорожные карты, списки предприятий, маршруты, фотографии на уровне улиц и многое другое.

Существуют заметные альтернативы Google Maps, такие как Mapbox и Open Street Map . Но, на мой взгляд, ни один из конкурентов не может сравниться с Google Maps по единственной причине полноты его бизнес-каталога. Google может представить полную и обширную карту, содержащую самые последние данные о бизнесе, в основном благодаря перекрестному поисковому предложению.

Существуют различные API для взаимодействия с Картами, от простого Static API до мощного JavaScript API , о котором пойдет речь в этой статье.

Конечно, вы можете разместить Карты Google на своем сайте, не используя различные предлагаемые API. Конечно, это облегчает жизнь и по-прежнему предлагает множество полезных функций. Но API Карт JavaScript дает нам полный контроль над нашей картой в целях повышения производительности и настройки.

Использование JavaScript API Карт Google

В этой статье я хотел бы показать вам, как максимально использовать API JavaScript Карт — используя его правильно .

Для этого уже есть множество учебных пособий и примеров, но слишком часто, без акцента на наилучшем способе достижения желаемого результата. Они делают вещи быстро, но без продуманного подхода или объяснения того, почему были предприняты определенные шаги.

Полный исходный код этой статьи можно найти в нашем репозитории GitHub .

Создание холста базовой карты

Первое, что нам нужно сделать, — это настроить простой интерфейсный интерфейс для построения картографического приложения.

Создать HTML

Давайте создадим HTML-файл со следующей разметкой:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Google Maps API Template</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="map"></div> <script src="script.js" defer></script> </body> </html> 

Это дает нам надежную платформу для создания полного картографического приложения.

Обратите внимание, как мы использовали атрибут defer для нашего скрипта. Это говорит браузеру загрузить указанные сценарии как можно скорее, но дождаться окончания анализа HTML, прежде чем выполнять их. По возможности важно использовать defer , так как он предотвратит остановку рендеринга страницы до ее завершения, чтобы выполнить код JavaScript — предоставляя пользователю неудобные возможности загрузки. Читатель с острым взглядом может заметить, что мы не включили JavaScript на Google Картах: это намеренно и будет объяснено в ближайшее время!

Создайте готовый обратный вызов

Теперь давайте document.addEventListener('DOMContentLoaded', function () {}) наш исходный файл JavaScript, script.js , начиная с document.addEventListener('DOMContentLoaded', function () {}) :

 document.addEventListener('DOMContentLoaded', function () { if (document.querySelectorAll('#map').length > 0) { if (document.querySelector('html').lang) lang = document.querySelector('html').lang; else lang = 'en'; var js_file = document.createElement('script'); js_file.type = 'text/javascript'; js_file.src = 'https://maps.googleapis.com/maps/api/js?callback=initMap&signed_in=true&language=' + lang; document.getElementsByTagName('head')[0].appendChild(js_file); } }); 

Проверка длины #map — это быстрый способ узнать, присутствует ли определенный элемент на текущей странице. Довольно часто один и тот же внешний файл JavaScript будет включен на весь веб-сайт, и довольно часто некоторые части кода требуются только для определенных страниц. В этом случае мы только хотим выполнить этот код, только если представляем холст карты пользователю. Это предотвращает появление ненужного кода на страницах, которые этого не требуют. (Производительность имеет значение!)

Как только мы убедимся, что на странице есть холст карты, мы можем подумать, что готовы продолжить, но нам нужно выполнить еще одну проверку. По умолчанию JavaScript API Google Карт загружается на английском языке, независимо от того, на каком языке запрашивающая страница. Отличный способ противостоять этому — установить переменную lang на основе атрибута lang в элементе <html> . Это позволит нам включить Google Maps JS на правильном языке для нашего пользователя. Это особенно полезно для многоязычных (i18n) веб-сайтов, которые содержат один и тот же файл script.js на всех языках.

Захват файла Google с JavaScript

Теперь пришло время загрузить внешний файл Google Maps JS. Причина, по которой мы оставили его до сих пор, вместо того, чтобы включать его в качестве обычного <script> в HTML, состоит в том, чтобы предотвратить ненужное увеличение кода на страницах, на которых нет холста карты. Чтобы загрузить файл, мы создаем новый элемент <script> и внедряем его в <head> DOM. Поскольку API Google обрабатывает обратные вызовы для нас, нам не нужно делать что-то более причудливое, чем это:

 var js_file = document.createElement('script'); js_file.type = 'text/javascript'; js_file.src = 'https://maps.googleapis.com/maps/api/js?callback=initMap&signed_in=true&key=YOUR_API_KEY&language=' + lang; document.getElementsByTagName('head')[0].appendChild(js_file); 

В параметрах строки запроса, передаваемых API, есть несколько интересных моментов.

Во-первых, мы передаем нашу переменную lang в качестве параметра language чтобы указать Google, на каком языке мы хотим, чтобы карта была.

Во-вторых, мы предоставляем параметр signed_in как true . Это сделано для того, чтобы повысить персонализацию карты (например, на ней будут видны ваши помеченные места).

Далее, мы передаем параметр key с нашим ключом API (подробнее об этом позже).

Наконец, и самое главное, мы указываем нашу функцию обратного вызова, используя параметр callback . Это сообщает Google, какие из наших функций он должен запускать после успешного извлечения файла.

API Google Maps JS по-прежнему будет работать без действительного параметра key . Однако нам будет выдано предупреждение об ошибке консоли JavaScript. Поэтому мы должны убедиться, что получили бесплатный API-ключ, следуя руководству Google .

Инициализация холста карты

Теперь, когда у нас настроен вызов функции инициализации, мы можем перейти к определению нашей функции обратного вызова initMap() . Эта функция будет активирована API Google Maps JS после ее успешной загрузки.

 var map; function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } 

При создании новой карты Google лучше всего создавать переменную для карты в глобальной области видимости (вне каких-либо функций), чтобы впоследствии было легче взаимодействовать с картой. Вот почему мы определяем map вне initMap() .

Теперь, когда у нас есть пустая переменная map для работы, мы можем пойти дальше и назначить ей объект Google Map внутри функции initMap . Это в точности как пример Google Simple Map . Важно отметить, что мы должны указать как center и zoom , иначе карта не будет инициализироваться вообще. Там нет по умолчанию!

Не забывайте CSS

Последний важный шаг к началу работы с базовым базовым холстом карты заключается в предоставлении CSS в нашем файле style.css :

 html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; } 

Самая распространенная ошибка, о которой мы #canvas сегодня, — это забыть установить атрибут height для элемента #canvas . Независимо от всего остального, описанного в этой статье, если не задан атрибут CSS height (или min-height ), мы вообще не увидим карту. Стили, примененные к <html> и <body> предназначены только для полноэкранного режима холста.

Гугл карта без маркеров

Добавление маркеров на холст карты

После того как у нас будет отображен базовый холст карты, наиболее распространенной следующей задачей является нанесение маркеров на карту. Один совет, который я всегда даю в большинстве контекстов программирования, — это по возможности отделять данные от логики. В этом случае это иллюстрируется сохранением ваших данных маркера в отдельном файле JSON.

Создайте файл JSON для маркеров

Создайте файл JSON с именем markers.json :

 [ { "lat": 53.817680, "lng": -1.537657 }, { "lat": 53.790123, "lng": -1.53243 }, { "lat": 53.756745, "lng": -1.5309087 }, { "lat": 53.6474675, "lng": -1.49564554 }, { "lat": 53.69123456, "lng": -1.6545466 } ] 

Всегда полезно хранить маркеры Карт Google в виде значений широты и долготы, а не адресов. В противном случае мы должны использовать сервис геокодирования Google во время выполнения. Это отдельный API со строгими ограничениями использования, который также добавит еще один внешний объект в процесс инициализации карты, увеличив задержку.

Теперь, когда наш JSON-файл настроен, нам нужно использовать его при инициализации нашей карты.

Построить маркеры

Начните с изменения функции initMap() чтобы markers.json файл markers.json после инициализации карты, используя новый API Fetch , передавая обратный вызов новой функции plotMarkers() . Мы также используем здесь обещания, чтобы гарантировать, что ответ анализируется в JSON перед передачей в функцию обратного вызова:

 fetch('markers.json') .then(function(response){return response.json()}) .then(plotMarkers); 

Тогда давайте продолжим и определим plotMarkers() :

 var markers; var bounds; function plotMarkers(m) { markers = []; bounds = new google.maps.LatLngBounds(); m.forEach(function (marker) { var position = new google.maps.LatLng(marker.lat, marker.lng); markers.push( new google.maps.Marker({ position: position, map: map, animation: google.maps.Animation.DROP }) ); bounds.extend(position); }); map.fitBounds(bounds); } 

Как и в случае с нашей переменной map , мы хотим определить еще несколько переменных вне функции в глобальной области видимости. В этой функции мы будем работать с markers и bounds , которые позже могут быть полезны в других местах, поэтому желательно иметь их в глобальной области видимости.

plotMarkers функции plotMarkers первое, что нам нужно сделать, — установить для нашей переменной markers пустой массив, а для нашей переменной bounds — пустой объект Google LatLngBounds . Мы будем использовать объект LatLngBounds чтобы отслеживать область, которая должна быть видимой на нашем холсте, чтобы соответствовать всем нашим маркерам.

Теперь нам нужно перебрать каждый маркер, предоставив анонимную функцию обратного вызова, которая создает новый объект позиции Google из параметров lat и lng доступных в нашем файле JSON. Как только мы получим это, мы создадим новый объект маркера карты Google и вставим его в наш массив markers . Наконец, мы расширим наши границы, используя новую позицию:

 var position = new google.maps.LatLng(this.lat, this.lng); markers.push( new google.maps.Marker({ position: position, map: map, animation: google.maps.Animation.DROP }) ); bounds.extend(position); 

Стоит отметить: при создании нового объекта маркера карты Google единственными обязательными параметрами являются position и map . Параметр position может быть либо объектом, содержащим параметры lat и lng , либо объектом позиции Google (как показано здесь). Параметр map — это просто объект карты Google, на котором мы хотим нанести маркер. Мы также предоставляем параметр animation : это не обязательно, но так просто реализовать — и всем нравится немного анимации!

Перецентрировать холст карты

Теперь, когда мы перебрали все наши маркеры, добавили их на карту и построили границы холста, мы вызовем map.fitBounds() чтобы map.fitBounds() холст карты вокруг нанесенных маркеров, переопределив начальный center и zoom Параметры, которые мы указали при инициализации объекта карты. Это очень полезно, так как позволяет нам обновлять файл markers.json не беспокоясь о нашем center или параметрах zoom .

Заключительные замечания

Теперь у нас должно быть работающее приложение, которое может отображать полноэкранный холст Google Maps и наносить на карту маркеры из файла JSON.

Если вы хотите продолжить, следующим логическим шагом будет внедрение InfoWindows , которые появляются при нажатии на маркер.

Если вы заинтересованы в использовании функциональности, уже представленной в этой статье, хорошей отправной точкой будет возможность настроить значки, нанесенные на карту. Это можно сделать, просто передав URL-адрес в качестве параметра icon новому объекту маркера.

Если у вас есть какие-либо другие улучшения или предложения, пожалуйста, не стесняйтесь добавлять их в комментариях.

И не забывайте, полный исходный код доступен через наше GitHub репо .