Работая с Geolocation и API Карт Google, вы узнали, как определить физическое местоположение пользователя и отобразить его на карте. В этой статье вы создадите сервис, который позволит пользователю получать указания от одного адреса к другому. Для повышения удобства пользования сервис также позволит пользователю автоматически использовать свою текущую позицию в качестве отправной точки.
Эта статья предполагает, что читатель знаком с содержанием из предыдущего поста . С этим сказал — давайте начнем.
Изучение API Карт Google далее
В демоверсии вы познакомитесь со своими старыми друзьями Map
, LatLng
и Geocoder
. Вы также найдете новых друзей. Первым из них является google.maps.DirectionsService
, который вычисляет направления (или маршруты) между двумя или более местоположениями. Этот класс очень прост. Его конструктор не принимает параметров и имеет только один метод route()
, который вычисляет направления. Этот метод принимает два параметра: объект google.maps.DirectionsRequest
и функцию обратного вызова.
Объект google.maps.DirectionsRequest
используется для установки параметров, которым должен удовлетворять запрос маршрута. Единственными обязательными свойствами этого объекта являются origin
, destination
и travelMode
. Первые два свойства определяют начало и конец пути, а travelMode
определяет ваш способ транспортировки. Возможные значения: велосипед, вождение, ходьба и транзит (на общественном транспорте). Важно отметить, что origin
и destination
могут использовать либо экземпляр LatLng
либо строку, содержащую адрес.
Как я уже сказал, запрос также может включать несколько опций, таких как unitSystem
которые запрашивают возврат расстояний с использованием определенной системы единиц. Возможные значения: метрические ( google.maps.UnitSystem.METRIC
) и британские ( google.maps.UnitSystem.IMPERIAL
). Значение по умолчанию выбирается в зависимости от страны происхождения. Вы также можете указать набор промежуточных точек для прохождения, используя свойство waypoints
. Кроме того, вы можете ограничить направления. Например, вы можете запросить маршрут, который не использует автомагистрали, если это возможно, установив для свойства avoidHighways
значение true
. Вы также можете попытаться избежать платных дорог, установив для свойства avoidTolls
значение true
.
Функция обратного вызова DirectionsService
возвращает два значения: объект google.maps.DirectionsResult
и одно из возможных значений (фактически свойств) класса google.maps.DirectionsStatus
. Первый имеет только одно свойство, routes
, который является массивом DirectionsRoute
и содержит информацию для каждого рассчитанного пути. DirectionsStatus
представляет конечное состояние запроса и может указывать на успех ( DirectionsStatus.OK
), отсутствие результатов ( DirectionsStatus.ZERO_RESULTS
) или ошибку (например, DirectionsStatus.INVALID_REQUEST
или DirectionsStatus.REQUEST_DENIED
).
Еще один из наших новых друзей — класс google.maps.DirectionsRenderer
. Он отображает направления, полученные в форме объекта
DirectionsResult
полученного из DirectionsService
.
Этот класс содержит только геттеры и сеттеры, поэтому мы не будем его изучать.
Единственная замечательная вещь — это ее конструктор, который принимает объект
google.maps.DirectionsRendererOptions
который позволяет вам установить несколько параметров.Ключевыми свойствами последних являются
directions
и map
, которые устанавливают отображаемые маршруты (полученные с использованием DirectionsService
) и объект карты, используемый для отображения маршрутов.
Начнем кодирование
Теперь, когда вы увидели все новые классы, используемые в этой статье, пришло время погрузиться в код. Чтобы позволить пользователю запрашивать путь от источника к месту назначения, в первую очередь вам нужна форма. Это будет очень просто, потому что для этого нужны всего два элемента <input>
и кнопка отправки. Однако для улучшения взаимодействия с пользователем на странице также будет возможность автоматически заполнить <input>
текущей позицией пользователя. Чтобы достичь этой цели, я поставлю ссылку под каждым <input>
который после нажатия будет извлекать адрес пользователя с помощью геолокации и API Карт Google. Форма для реализации этой функции показана ниже.
<form id="calculate-route" name="calculate-route" action="#" method="get"> <label for="from">From:</label> <input type="text" id="from" name="from" required="required" placeholder="An address" size="30" /> <a id="from-link" href="#">Get my position</a> <br /> <label for="to">To:</label> <input type="text" id="to" name="to" required="required" placeholder="Another address" size="30" /> <a id="to-link" href="#">Get my position</a> <br /> <input type="submit" /> <input type="reset" /> </form>
Теперь перейдем к бизнес-логике демо. В отличие от первой статьи, мы воспользуемся преимуществом jQuery для быстрого выбора элементов в DOM и присоединения обработчиков кросс-браузерным способом. Поскольку вся работа выполняется на стороне клиента, в первую очередь нам нужно заблокировать поведение формы по умолчанию и запустить дополнительный JavaScript, который мы рассмотрим позже. Для достижения этой цели мы прикрепим обработчик к событию submit
формы. Обработчик использует метод jQuery preventDefault()
а затем вызывает функцию preventDefault()
. Код, который реализует это, показан ниже.
$("#calculate-route").submit(function(event) { event.preventDefault(); calculateRoute($("#from").val(), $("#to").val()); });
Самый важный код содержится в функции calculateRoute()
. Функция будет принимать два параметра, from
и to
, которые представляют адрес отправителя и адрес назначения соответственно. Первым шагом является создание экземпляра map
, как показано в следующем коде.
// Center initialized to Naples, Italy var myOptions = { zoom: 10, center: new google.maps.LatLng(40.84, 14.25), mapTypeId: google.maps.MapTypeId.ROADMAP }; // Draw the map var mapObject = new google.maps.Map(document.getElementById("map"), myOptions);
Прежде чем мы пойдем дальше, я хотел бы обсудить некоторые соображения. Как вы уже видели, я использовал статическое положение, чтобы изначально центрировать карту. Как вы узнали из предыдущей статьи, свойство center
обязательно. В этой демонстрации может возникнуть искушение пропустить его, потому что, если запрос маршрута выполнен успешно, карта перерисовывается и центрируется соответственно. Вы не должны этого делать, потому что если запрос не удастся, вы увидите заполненную серым цветом область. Альтернативой может быть первоначальное центрирование карты на основе текущего положения пользователя. Это требует дополнительного поиска геолокации, так что вы можете считать это пустой тратой ресурсов.
Затем вам нужно создать экземпляр DirectionsService
и объект directionsRequest
, как показано ниже. В этой демонстрации используется unitSystem
опция unitSystem
, но вы можете расширить ее.
var directionsService = new google.maps.DirectionsService(); var directionsRequest = { origin: from, destination: to, travelMode: google.maps.DirectionsTravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC };
Последний шаг — использование метода route()
для запуска запроса. Мы также должны написать функцию обратного вызова, которая использует ответ, чтобы установить и показать рассчитанный путь. В функции обратного вызова мы проверим, был ли запрос успешным, в этом случае мы отобразим маршрут, или нет, в этом случае мы отобразим ошибку. Это реализуется кодом ниже.
directionsService.route( directionsRequest, function(response, status) { if (status == google.maps.DirectionsStatus.OK) { new google.maps.DirectionsRenderer({ map: mapObject, directions: response }); } else $("#error").append("Unable to retrieve your route<br />"); } );
Собираем все вместе
В предыдущем разделе объяснялись ключевые компоненты демо. Теперь пришло время соединить эти кусочки в конечный результат, который показан ниже.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Find a route using Geolocation and Google Maps API</title> <script src="http://maps.google.com/maps/api/js?sensor=true"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script> function calculateRoute(from, to) { // Center initialized to Naples, Italy var myOptions = { zoom: 10, center: new google.maps.LatLng(40.84, 14.25), mapTypeId: google.maps.MapTypeId.ROADMAP }; // Draw the map var mapObject = new google.maps.Map(document.getElementById("map"), myOptions); var directionsService = new google.maps.DirectionsService(); var directionsRequest = { origin: from, destination: to, travelMode: google.maps.DirectionsTravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC }; directionsService.route( directionsRequest, function(response, status) { if (status == google.maps.DirectionsStatus.OK) { new google.maps.DirectionsRenderer({ map: mapObject, directions: response }); } else $("#error").append("Unable to retrieve your route<br />"); } ); } $(document).ready(function() { // If the browser supports the Geolocation API if (typeof navigator.geolocation == "undefined") { $("#error").text("Your browser doesn't support the Geolocation API"); return; } $("#from-link, #to-link").click(function(event) { event.preventDefault(); var addressId = this.id.substring(0, this.id.indexOf("-")); navigator.geolocation.getCurrentPosition(function(position) { var geocoder = new google.maps.Geocoder(); geocoder.geocode({ "location": new google.maps.LatLng(position.coords.latitude, position.coords.longitude) }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) $("#" + addressId).val(results[0].formatted_address); else $("#error").append("Unable to retrieve your address<br />"); }); }, function(positionError){ $("#error").append("Error: " + positionError.message + "<br />"); }, { enableHighAccuracy: true, timeout: 10 * 1000 // 10 seconds }); }); $("#calculate-route").submit(function(event) { event.preventDefault(); calculateRoute($("#from").val(), $("#to").val()); }); }); </script> <style type="text/css"> #map { width: 500px; height: 400px; margin-top: 10px; } </style> </head> <body> <h1>Calculate your route</h1> <form id="calculate-route" name="calculate-route" action="#" method="get"> <label for="from">From:</label> <input type="text" id="from" name="from" required="required" placeholder="An address" size="30" /> <a id="from-link" href="#">Get my position</a> <br /> <label for="to">To:</label> <input type="text" id="to" name="to" required="required" placeholder="Another address" size="30" /> <a id="to-link" href="#">Get my position</a> <br /> <input type="submit" /> <input type="reset" /> </form> <div id="map"></div> <p id="error"></p> </body> </html>
Вывод
Эта статья познакомила вас с несколькими новыми классами и свойствами из API Карт Google. Вы использовали эти классы для разработки базового сервиса, который позволяет пользователю получать указания от одного адреса к другому. В следующей статье вы узнаете, как создать ломаную линию, чтобы соединить несколько точек на карте.