Основанные на местоположении приложения — все в моде. То, что раньше было непомерно дорогими GPS-устройствами, теперь находится в карманах множества людей, встроенных в смартфоны и другие устройства в беспрецедентном масштабе, и сервисы, использующие информацию о местоположении, все время возникают. Социальная сеть, например, стала узнавать о местоположении с помощью существующих сервисов, таких как Facebook, следуя примеру таких лидеров, как Foursquare и Gowalla , представляя Places. Твиттер добавил информацию о местонахождении в твиты, все больше и больше служб приспосабливаются к месту, где вы находитесь, и, конечно, реклама начинает действовать с ориентацией на местоположение в зависимости от рекламы — прибыльной и расширяющейся области.
В дополнение к точному определению точности с помощью GPS на портативных устройствах, другие механизмы от геолокации на основе IP-адресов до триангуляции Wi-Fi становятся все более и более сложными, и благодаря W3C усиливается поддержка геолокации с его спецификацией API геолокации, возможности которой огромны.
В этой статье я поделюсь с вами одним важным аспектом геолокации — сопоставлением физического местоположения с описательным названием места. Я посмотрю, как вы можете использовать Geonames , онлайн-сервис, предлагающий бесплатный доступ к большому набору географических данных, чтобы помочь вам разрабатывать приложения, использующие информацию о местоположении.
Что такое геолокация?
Приложения, учитывающие местоположение, полагаются на возможность определить, где вы находитесь, и в этом суть геолокации. В конце концов, как только приложение узнает ваше местоположение, оно может продолжить поиск ближайшего магазина, провести вас по соответствующему маршруту до места назначения или направить вам соответствующую рекламу. Таким образом, геолокация — это просто механизм определения вашего географического местоположения.
Есть две проблемы с геолокации — выяснить, где кто-то находится, а затем описать это местоположение. Существует ряд методов определения чьего-либо местоположения, и они различаются по сложности и, что наиболее важно, по точности. Широта и долгота могут определить ваше местоположение с точностью до нескольких метров в любом месте на Земле, но сами значения не имеют большого значения для большинства людей. Иногда точное разрешение на самом деле не нужно, и этого достаточно, чтобы определить название ближайшего города или населенного пункта.
Служба Geonames
Geonames — это онлайн-ресурс, предлагающий загружаемые базы данных множества географической информации, включая сопоставления информации о широте и долготе с реальными местоположениями. Эти файлы, как вы можете себе представить, огромны и нестабильны. Вы можете загрузить и использовать эти файлы самостоятельно, но там Geonames также предоставляет веб-сервисы, одним из которых я буду здесь пользоваться.
Чтобы использовать веб-сервисы, вам нужно создать бесплатную учетную запись. Перейдите на www.geonames.org и нажмите ссылку «Вход» в правом верхнем углу страницы. Там вы сможете войти или создать новую учетную запись пользователя. Как только вы зарегистрируетесь, вам будет отправлено письмо со ссылкой для подтверждения; проверьте свою почту и подтвердите свой аккаунт.
После того, как вы подтвердили свою учетную запись, щелкните свое имя пользователя в правом верхнем углу страницы, чтобы перейти на страницу управления учетной записью и разрешить своей учетной записи использовать веб-службы.
Теперь у вас есть имя пользователя, которое разрешает вам доступ к веб-сервисам Geonames. Вы можете ознакомиться с условиями .
Конкретный сервис, который я продемонстрирую, — это findNearbyPlaceName , который делает именно это — находит имя ближайшей точки с заданной широтой и долготой. В документации говорится, что это REST-подобный сервис с данными, доступными в форматах XML и JSON (если вам не ясно, что такое REST-сервис, я рекомендую вам прочитать его перед тем, как продолжить). Решение о том, использовать ли XML или JSON, часто принимается лично. Я предпочитаю JSON, потому что его легче анализировать, он более легкий и прекрасно работает с JavaScript.
REST-подобный веб-сервис определения местоположения
Одна из замечательных особенностей использования веб-службы REST для извлечения информации заключается в том, что по самой своей природе вы можете выполнить простой запрос GET для его проверки — и вы можете сделать это, используя только веб-браузер! Все, что вам нужно сделать, это предоставить правильно отформатированный URL. В вашем браузере введите следующий URL:
http://api.geonames.org/findNearbyPlaceNameJSON?lat=53.4774&lng=-2.2381&username=yourusername
Давайте разберемся с этим:
-
http://
протокол передачи. Как правило, службы REST используют вездесущность и простоту HTTP. -
api.geonames.org
— это доменное имя, которое становится начальным сегментом конечной точки службы. -
findNearbyPlaceNameJSON
идентифицирует сервис. Часто запрашиваемый формат возврата передается в качестве параметра, расширения файла или даже с использованием заголовка ACCEPT, но эта конкретная служба включает его в название службы. -
lat=53.4774&lng=-2.2381
— параметры широты и долготы, для которых вы запрашиваете название ближайшегоlat=53.4774&lng=-2.2381
пункта. -
username=yourusername
— это имя пользователя, которое вы включили для использования сервиса. Эта служба принимает в качестве параметра, но другие службы REST могут реализовывать другие схемы авторизации, такие как HTTP-аутентификация.
Служба отвечает на запрос, отправляя обратно следующий JSON (я отформатировал его здесь для удобства чтения):
{"geonames": [{"countryName": "Великобритания", "AdminCode1": "ENG", "fclName": "город, деревня, ...", "COUNTRYCODE": "GB", "LNG": - +2,23743438720703, "fcodeName": "место административного деления второго порядка", «Расстояние»: «0,39678», "ToponymName": "Манчестер", "FCL": "P", «Название»: «Манчестер», "FCODE": "PPLA2", "GeonameId": 2643123, «Лат»: 53,4809464283615, "AdminName1": "Англия", "Население": 395515}]}
Как видите, результатом является объект со свойством geonames
который содержит массив из одного объекта с несколькими свойствами. Свойства lat
и lng
предоставляют географическое местоположение места, которое служба определила, distance
показывает вам, как далеко это место от предоставленной вами позиции, и наиболее полезным является свойство name
которое сообщает вам имя местоположения. свойство countryName
сообщает вам страну, в данном случае Великобританию.
Данные также предоставляют информацию об административных делениях. Точный характер такого разделения варьируется от страны к стране; в этом случае adminCode1
(административное деление первого уровня) идентифицирует «Англию»; если бы вы нашли Хьюстон в Соединенных Штатах с помощью этого сервиса, вы бы обнаружили, что adminCode1 показывает «TX» для штата Техас.
Кроме того, geonameId
содержит уникальный идентификатор, используемый в базе данных Geonames, который, как вы помните, можно загрузить. Вы можете использовать это в какой-то момент, если вы продолжите использовать данные для чего-то более существенного.
Targeted Prompting — практический пример
В качестве примера, давайте предположим, что на вашем веб-сайте есть функция, которая предлагает пользователю найти списки кинотеатров, и вы хотите персонализировать текст заголовка с названием ближайшего города пользователя — что-то вроде «Найти списки кинотеатров рядом с вами в Манчестере». , Сразу есть одно важное ограничение, о котором вы должны знать: в большинстве случаев геолокация выполняется на клиенте. Независимо от веб-браузера или самого устройства, эта информация должна быть отправлена обратно на сервер, если вы хотите использовать ее там. JavaScript на стороне клиента будет получать координаты пользователя и отправлять их на серверный скрипт через Ajax, который затем взаимодействует с веб-службой и возвращает имя местоположения.
Код на стороне сервера
Давайте начнем с написания серверного PHP-кода. Веб-сайт Geonames предоставляет пакет PEAR , а также библиотеки для фреймворков, в том числе Zend Framework и Yii , для упрощения доступа к их сервисам — однако для целей этого урока я буду использовать простой PHP.
Этот простой класс инкапсулирует вызов службы findNearbyPlaceName:
<?php class Geonames { protected $username; public function __construct($username) { $this->username = $username; } public function getPlaceName($lat, $lng) { $url = sprintf( "http://api.geonames.org/findNearbyPlaceNameJSON?lat=%f&lng=%f&username=%s", $lat, $lng, $this->username); $response = file_get_contents($url); if ($response === false) { throw new Exception("Failure to obtain data"); } $places = json_decode($response); if (!$places) { throw new Exception("Invalid JSON response"); } if (is_array($places->geonames) && count($places->geonames)) { return $places->geonames[0]->name; } else { return "Unknown"; } } }
Класс называется Geonames
, конструктор которого принимает в качестве аргумента один параметр — ранее зарегистрированное имя пользователя, которое затем сохраняется в защищенной переменной-члене.
Метод getPlaceName()
вызывает сервис findNearbyPlaceName. Поскольку это простой запрос GET к REST-подобному сервису, вы можете просто включить параметры в URL-адрес, как вы делали это при тестировании веб-сервиса через браузер ранее. Я использовал sprintf()
для создания URL-адреса, подход, который я считаю более чистым, чем конкатенация, а также позволяет мне указывать типы форматов для заполнителей; широта и долгота — это числа с плавающей точкой ( %f
), а имя пользователя — строка ( %s
). Затем URL передается в file_get_contents()
который получает ответ службы JSON. Ответ декодируется с использованием json_decode()
и первое имя места возвращается из метода.
Сценарий, вызванный Ajax, получит широтные и продольные координаты, использует их для запроса веб-службы Geonames через новый класс и возвращает имя ближайшего местоположения.
<?php require "../include/Geonames.php"; $lat = floatval($_GET["lat"]); $lng = floatval($_GET["lng"]); $geo = new Geonames("username"); $prompt = "Find cinema listings near you"; try { $place = $geo->getPlaceName($lat, $lng); if ($place != "Unknown") { $prompt .= " in " . $place; } } catch (Exception $e) { error_log("Error with web service: " . $e->getMessage()); } header("Content-Type: text/plain"); echo $prompt;
Код начинается с сообщения по умолчанию «Найти кинотеатр рядом с вами». Если вызов getPlaceName()
не вызывает исключение и возвращаемое имя не «Неизвестно», сообщение дополнительно персонализируется.
Код на стороне клиента
Теперь давайте обратим наше внимание на страницу HTML и код JavaScript, который будет вызывать PHP.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hello!</title> <script src="jquery.js"></script> <script> (function ($) { $(document).ready(function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function (position) { var lat = position.coords.latitude; var lng = position.coords.longitude; $("#banner").load("/prompt.php?lat="+lat+"&lng="+lng); }, function (error) { console.log("An error occurred obtaining position."); }); } else { $("#banner").html("Default content goes here"); } }); })(jQuery); </script> </head> <body> <div id="banner"></div> </body> </html>
Если геолокация поддерживается браузером, затем navigator.geolocation
вернет true, в противном случае некоторое содержимое по умолчанию будет вставлено в элемент с идентификатором banner
. Когда поддерживается геолокация, делается попытка получить местоположение пользователя с помощью navigator.geolocation.getCurrentPosition()
, которому передаются обратные вызовы success и error.
В этот момент браузер запросит у вас разрешения на передачу информации о вашем местонахождении на веб-страницу. Если вы дадите разрешение, то будет выполнен обратный вызов и, если приложению удастся получить имя местоположения, баннер будет содержать персональное приглашение для просмотра списков кинотеатров. Если вы отказываете в разрешении браузеру, вместо этого выполняется обратный вызов ошибки.
Резюме
В этой короткой статье я представил геолокацию и один способ, которым вы можете использовать ее прямо сейчас, чтобы персонализировать опыт посетителя на веб-сайте. Хотя пример, который я привел, несколько неуклюж в использовании AJAX для ретроспективной загрузки блока на страницу, он служит для иллюстрации одной из технических проблем геолокации — информация в основном получается на стороне клиента и, следовательно, существуют препятствия, которые вам нужны преодолеть, например, запросить разрешение на использование информации. Возможно, вы захотите попытаться сохранить информацию на стороне сервера в сеансе после ее получения, посмотреть на повышение производительности с помощью кэширования или поэкспериментировать с более сложным таргетингом. Следующим логическим шагом будет изучение того, как вы будете управлять отношениями между городами — что если в моей местной деревне нет кинотеатра, что делает ближайший город или город? Это в другой раз, но сейчас я рекомендую вам взглянуть на поддержку API для геолокации (вы могли бы даже взглянуть на спецификацию ), взглянуть на полностью серверное IP-решение или углубиться в математику геолокации. Больше всего я призываю вас повеселиться!
Изображение через Оливье Ле Моал / Shutterstock