Статьи

Целевая геолокация с Geonames

Основанные на местоположении приложения — все в моде. То, что раньше было непомерно дорогими 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