Автор: Максим Мазитов
Google Maps API. Геокодирование
Источник статьи: Ссылка
В предыдущей статье я рассматривал API статических карт Google. Рядом с этой темой, буквально "впритык", располагается геокодирование. Что это за зверь? Цитирую:
"Geocoding is the process of converting addresses (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (like latitude 37.423021 and longitude -122.083739), which you can use to place markers or position the map"
А если нормальным языком, то геокодирование — процесс превращения строкового почтового (не путать с электронной почтой :) ) адреса в координаты. А также, обратный процесс.
Описание API лежит на гугле, к сожалению, пока не переведенное, хотя в адресе присутствует код языка.
Итак, приступим.
Прямое геокодирование
Идем по этой ссылке. Результатом оказывается XML документ. Смотрим на него внимательно. Ветки документа содержат информацию о найденных объектах и их координатах. Дело за малым — сформировать URL, закинуть запрос, считать ответ и разобрать XML. "За чем же дело встало?" (жизненная цитата)
Строка запроса состоит из трех параметров:
- q — собственно текст запроса. Разделитель слов запроса знак "+".
- output — тип возвращаемых данных. Возможные значения xml, kml, csv, или json. Описание сморим на сайте указанной ссылке. CSV не рассматриваем, т.к. в этом случае выдается мало информации. KML используется в Google Earth. Json внутренний формат Google Map. XML нам наиболее близок и сердцу дорог, так что берем его.
- key — ключ карт. Как себя ведет не ясно, смотрим предыдущую статью. Пусть живет как есть.
- gl — код страны. Необходимо устанавливать в соответствии с доменами первого уровня страны проживания. В нашем случае — "ru". Для Украины, например, "ua".
Скачиваем пример и смотрим в код:
|
Для хранения результатов обработки XML я создал класс.
|
И складировал результаты в TObjectList. Если уж совсем заморачиваться, то "по уму" нужно написать хранилище для результатов, но почему то мне было лень.
Надеюсь, я достаточно подробно прокомментировал код, и нет необходимости его расписывать. В результате, мы имеем список точек с координатами и подробным адресом. Если кому-то понадобится точное разложение по городам, улицам и домам, то не составляет большого труда разобрать подчиненные ветки документа, детализация достаточно подробная.
Со списком точек я поступил следующим образом — вывел в ListView и отобразил на карте. Если кто-нибудь ковырял самостоятельно описание статических карт на сайте гугла, приведенное в предыдущей статье, то там есть возможность вывода нескольких точек на одной карте. Я добавил следующую функцию:
|
Почему-то я всегда думал, что улиц Ленина в России больше. И знаю пару неотмеченных городов на карте в которых она есть. Кстати, это отличный тест гугла на наличие карт городов — есть улица/проспект Ленина, Октября, Революции и ещё немного названий — есть и подробная карта. И следствие — Сибирь у гугла не отобразилась, значит городов там нет!
Кстати, а есть ли жизнь за МКАДом? :)
Танцы с бубнами вокруг кодировок
Гугл принимает и отдает данные в формате UTF-8. Этот факт упомянут в описании. К сожалению, не всё так просто. При посылке запроса с указанием языка в URL возвращаемые данные не принимаются в TXMLDocument, русские символы ему, видите ли, не нравятся. Если перевести URL в UTF-8, тогда документ принимается. Но в большинстве случаев часть адресных строк содержат английские названия. Так Дворцовая площадь становится Palace Embankment. Не вполне допустимая ситуация для использования софта пользователями, не знакомыми с языком потенциального противника. При этом, посылая аналогичный запрос из любого браузера, данные приходят по-русски. Приходит мысль, что собачко порылось в HTTP заголовках. Т.к. гугль знает всё (чё, правда? :), решение найдено в добавлении заголовка "Accept-Language: ru" в вызов функции InternetOpenURL. Тогда гугль начинает присылать данные по-русски, НО! в виндовой кодировке. Тут опять больше всех надо становится TXMLDocument-у. В XML указано UTF-8, а реально 1251. Ну, наше дело маленькое, пользуем функцию AnsiToUtf8, и будет нам счастье. Результаты танцев смотрим в функциях GetInetFile и StreamToUtf8Stream.
Обратное геокодирование
Допустим, что у нас есть мобильный объект и нам известны его координаты. Необходимо получить ближайший адрес к точке, по возможности конечно. Адрес "Баренцево море", например, несет слабую смысловую нагрузку, поэтому не для любой точки можно провести процедуру обратного геокодирования с получением почтового адреса.
Обратное геокодирование возможно построением двух типов запросов. В запросе можно указывать координаты в параметре "q" и запрос не отличается от вышеописанного. Но эта функция не документирована. Честный же способ заключается в использовании параметра ll — "latitude, longitude". Пробуем следующую ссылку. Мы видим данные адреса по координатам.
Получение данных выглядит следующим образом:
|
Отобразим полученное дерево на TreeView. Чтобы не перегружать статью, я не буду приводить заполнение дерева, можно посмотреть исходники.
Структура XML документа содержит узлы "Placemark". Узлы содержат информацию о точке по слоям карты. Самый первый узел "Placemark" содержит наиболее подробную информацию об адресе точки (верхний слой). Прикрутим получение адреса к примеру получения картинки карты из предыдущей статьи.
|
That's all, folks! Пользуйтесь :)