Статьи

Создание мобильного приложения на основе местоположения с использованием HTML5 и Javascript: часть 4

В предыдущей части нашей серии вы видели, как настроить «Где я припарковал свой автомобиль», чтобы настроить тему, изменить переходы страниц и использовать параметр для отображения текста при отображении виджета загрузчика страниц. Благодаря API веб-хранилища мы теперь можем хранить позиции автомобиля для будущего использования и видеть историю позиций в любое время, когда захотим. В этой статье объясняется, как я использовал API Карт Google для отображения сохраненных местоположений на карте и построения маршрута от текущего местоположения пользователя до автомобиля. Мы также углубимся в служебные функции, которые мы будем использовать для объединения всех компонентов приложения.

API Карт Google

Подробное описание API Карт Google выходит за рамки этой статьи, но если вы хотите познакомиться с API, вы можете прочитать серию статей, которые я работаю на JSPro.com о работе с геолокацией и API Карт Google .

Приложение, которое мы создаем, выполняет три различных запроса к API Карт: отображает положение автомобиля, находит маршрут от текущего положения пользователя до автомобиля и получает адрес местоположения автомобиля. Как вы видели для класса Position в предыдущей части серии , я создам класс Map для всех связанных с ним методов. Этот класс, который вы найдете внутри файла maps.js , на самом деле не нуждается в свойствах. Все методы будут статическими, поэтому начальная точка класса Map просто следующая:

 function Map() { } 

Отображение карты

Метод отображения карты, называемый displayMap() , будет принимать два аргумента: положение пользователя ( userPosition ) и положение автомобиля ( carPosition ). Если указан только первый аргумент (когда пользователь вызвал метод для установки своего начального положения парковки), значок будет отображаться соответствующим образом. Первый класс API Карт Google, который вы увидите, это google.maps.LatLng , который представляет географические координаты по широте и долготе. Я буду использовать этот класс для преобразования координат, полученных с помощью API геолокации, в то, что API Карт может понять и работать с ним. displayMap() покажет карту с помощью класса google.maps.Map а затем установит маркер для назначения позиции пользователя с помощью класса google.maps.Marker . После установки правильного значка, как описано выше, функция рисует круг с классом google.maps.Circle вокруг позиции, чтобы отобразить точность определения местоположения. Если заданы оба аргумента, будут показаны обе позиции, а затем будет вызвана функция для расчета маршрута между двумя точками.

Полный источник этой функции приведен ниже.

 /** * Display the map showing the user position or the latter and the car position */ Map.displayMap = function(userPosition, carPosition) { var userLatLng = null; var carLatLng = null; if (userPosition != null) userLatLng = new google.maps.LatLng(userPosition.coords.latitude, userPosition.coords.longitude); if (carPosition != null) carLatLng = new google.maps.LatLng(carPosition.position.latitude, carPosition.position.longitude); var options = { zoom: 20, disableDefaultUI: true, streetViewControl: true, center: userLatLng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('map'), options); var marker = new google.maps.Marker({ position: userLatLng, map: map, title: 'Your position' }); // If carLatLng is null means that the function has been called when the // user set his current position and that is when he parked the car so the // icon will be shown accordingly. if (carLatLng == null) marker.setIcon('images/car-marker.png'); else marker.setIcon('images/user-marker.png'); var circle = new google.maps.Circle({ center: userLatLng, radius: userPosition.coords.accuracy, map: map, fillColor: '#70E7FF', fillOpacity: 0.2, strokeColor: '#0000FF', strokeOpacity: 1.0 }); map.fitBounds(circle.getBounds()); if (carLatLng != null) { marker = new google.maps.Marker({ position: carLatLng, map: map, icon: 'images/car-marker.png', title: 'Car position' }); circle = new google.maps.Circle({ center: carLatLng, radius: carPosition.position.accuracy, map: map, fillColor: '#70E7FF', fillOpacity: 0.2, strokeColor: '#0000FF', strokeOpacity: 1.0 }); // Display route to the car options = { suppressMarkers: true, map: map, preserveViewport: true } this.setRoute(new google.maps.DirectionsRenderer(options), userLatLng, carLatLng); } $.mobile.loading('hide'); } 

Получить маршрут

Как только пользователь установит свою позицию, он может ходить в любое место, которое он хочет. После этого ему нужно будет вернуться к своей машине, и там будет использоваться следующая функция. Чтобы найти маршрут от текущей позиции пользователя до автомобиля, я создам функцию setRoute() . Он будет использовать google.maps.DirectionsService и класс google.maps.DirectionsRequest чтобы попросить Google рассчитать маршрут. Используя google.maps.DirectionsTravelMode и google.maps.UnitSystem , я попрошу Google найти пешеходную дорожку (мы знаем, что пользователь будет идти пешком), чтобы пользователь мог также использовать улицы с односторонним движением и просматривать пешком в метрах. В заключение, функция будет использовать класс google.maps.DirectionsStatus для проверки, найден ли хотя бы один результат, и будет использовать класс google.maps.DirectionsRenderer для фактического отображения маршрута.

Полный код метода приведен ниже.

 /** * Calculate the route from the user to his car */ Map.setRoute = function(directionsDisplay, userLatLng, carLatLng) { var directionsService = new google.maps.DirectionsService(); var request = { origin: userLatLng, destination: carLatLng, travelMode: google.maps.DirectionsTravelMode.WALKING, unitSystem: google.maps.UnitSystem.METRIC }; directionsService.route( request, function(response, status) { if (status == google.maps.DirectionsStatus.OK) directionsDisplay.setDirections(response); else { navigator.notification.alert( 'Unable to retrieve a route to your car. However, you can still find it by your own.', function(){}, 'Warning' ); } } ); } 

Получить адрес

Последний метод, который я опишу, это requestLocation() , который будет использоваться для получения адреса позиции автомобиля и обновления сохраненного сохраненного объекта, который содержит последнюю позицию, так что, когда пользователь увидит историю позиций, он увидит значимый текст вместо GPS-координат. Для достижения этой цели я буду использовать класс google.maps.Geocoder который позволяет вам преобразовывать объект LatLng в адрес и наоборот. Последний имеет только один метод, называемый geocode() , который принимает объект GeocoderRequest в качестве параметра и функцию обратного вызова, которая используется для чтения результатов.

Код иллюстрируемой функции следующий.

 /** * Request the address of the retrieved location */ Map.requestLocation = function(position) { new google.maps.Geocoder().geocode( { 'location': new google.maps.LatLng(position.coords.latitude, position.coords.longitude) }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { var positions = new Position(); positions.updatePosition(0, positions.getPositions()[0].coords, results[0].formatted_address); } } ); } 

Сервисные функции

В этом разделе описываются некоторые функции в файле с именем functions.js , последним файлом JavaScript, который поддерживает наше мобильное приложение.

Тестирование на требования

«Где я припарковал свой автомобиль» не требует особых требований для правильной работы — только работающее подключение к Интернету, чтобы иметь возможность использовать API Карт Google для выполнения функций, описанных в предыдущих разделах. Если соединение недоступно, мы покажем пользователю предупреждающее сообщение, используя Cordova Notification API, проиллюстрированный в третьей части серии , и остановим выполнение метода. Этот тест выполняется с использованием Cordova Connection API , объекта, который предоставляет доступ к информации сотовой связи и Wi-Fi устройства. Этот API имеет только одно свойство с именем type которое проверяет активное используемое сетевое соединение и может принимать следующие (постоянные) значения:

  • Connection.UNKNOWN
  • Connection.ETHERNET
  • Connection.WIFI
  • Connection.CELL_2G
  • Connection.CELL_3G
  • Connection.CELL_4G
  • Connection.NONE

Как вы видели, когда мы говорили об API веб-хранилища, свойство type имеет несколько особенностей, которые подробно описаны в официальной документации API-интерфейса .

Теперь, когда вы узнали, как будет использоваться API, я могу показать вам, как выглядит функция проверки требований (проверка подключения к Интернету).

 function checkRequirements() { if (navigator.network.connection.type == Connection.NONE) { navigator.notification.alert( 'To use this app you must enable your internet connection', function(){}, 'Warning' ); return false; } return true; } 

Обновление значков в зависимости от размера экрана

Одна из самых горячих тем за последние несколько лет, безусловно, отзывчивый веб-дизайн. Ссылаясь на Википедию, Responsive Web Design — это подход к веб-дизайну, при котором сайт создается для обеспечения оптимального удобства просмотра — удобного чтения и навигации с минимальным изменением размера, панорамированием и прокруткой — на широком диапазоне устройств. Я не буду вдаваться в детали RWD, но, используя jQuery Mobile для создания интерфейсов мобильных приложений, я знаком с этой концепцией. Я попытался улучшить интерфейс приложения по умолчанию, используя простой метод, который проверяет размер экрана устройства и решает, должны ли кнопки внутри заголовка и нижнего колонтитула отображать текст кнопок. Это делается с помощью атрибута data-iconpos="notext" . В первом случае текст скрыт, а во втором — отображается. По умолчанию я notext значение notext ко всем кнопкам верхнего или notext колонтитула. В качестве точки останова экрана я использовал значение 480px, поэтому устройства с шириной экрана менее 480 пикселей не будут отображать текст кнопок.

Код показанной функции приведен ниже.

 function updateIcons() { if ($(window).width() > 480) { $('a[data-icon], button[data-icon]').each( function() { $(this).removeAttr('data-iconpos'); } ); } else { $('a[data-icon], button[data-icon]').each( function() { $(this).attr('data-iconpos', 'notext'); } ); } } 

Вывод

В этой четвертой части серии вы научились использовать API Карт Google для отображения карты и получения маршрута между положением пользователя и его машиной. Мы использовали класс google.maps.Geocoder для обновления последнего сохраненного объекта. Во втором разделе этой статьи мы изучили некоторые функции, которые вы увидите в файле function.js . В следующей статье я объясню и покажу остальные методы этого файла.