Работа с API геокодирования Google и GMap

      Геокодирование – процесс преобразования адресов (таких как Москва, Охотный Ряд, 2) в географические координаты (такие как широта 55.7570051 и долгота -37.6164606), которые можно использовать для размещения маркеров или позиционирования карты. API геокодирования Google предоставляет через HTTP-запрос прямой доступ к геокодеру. Эта служба позволяет выполнять также обратное действие (перевод координат в адреса). Этот процесс называется "обратным геокодированием".
      На использование API геокодирования Google накладывается ограничение, составляющее 2500 запросов геопозиционирования в день. (Пользователи API Google Карт для организаций могут выполнять до 100 000 запросов в день.) Это ограничение предотвращает злоупотребление интерфейсом API геокодирования и его использование в иных целях. Ограничение может быть изменено в будущем без предварительного уведомления. Кроме того, для предотвращения злоупотреблений службой существует ограничение на количество запросов. Если превышено суточное (24 часа) ограничение или имеет место злоупотребление другого рода, API геокодирования может временно прекратить работу. При неоднократных нарушениях доступ к нему может быть заблокирован.
Обязательные параметры при формировании запроса к службе API геокодирования Google.
  • address – адрес, который требуется геокодировать. 
  • latlng – текстовое значение широты/долготы, для которого требуется получить ближайший адрес в удобочитаемом виде. 
  • components – фильтр компонентов, для которых требуется выполнить геокодирование. Если указан параметр address, фильтр компонентов также может приниматься в качестве необязательного параметра.
  • sensor, указывающий, исходит ли запрос на геокодирование от устройства с датчиком местоположения. Допустимые значения – true или false.
Необязательные параметры являются:
  • bounds– ограничивающий прямоугольник для области просмотра, внутри которого должно быть задано более четкое предпочтение для результатов геокодирования. Этот параметр может влиять на результаты геокодера, но не ограничивает их в полной мере. 
  • language – язык, на котором следует возвращать результаты. Имейте в виду, что список языков постоянно пополняется и не является исчерпывающим. Если какое-то значение language отсутствует, геокодер пытается использовать базовый язык домена, из которого запрос отправляется куда угодно.
  • region – код региона, указанный в виде двузначного числа ccTLD (домен верхнего уровня). Этот параметр может влиять на результаты геокодера, но не ограничивает их в полной мере. 
  • components – разделенные символами вертикальной черты (|) фильтры компонентов. Каждый из них представляет собой пару component:value и накладывает на результаты геокодера четкое ограничение. 
      Рассмотрим пример полученного ответа на отправленный запрос в формате XML, для адреса "Москва, Охотный Ряд, 2":
http://maps.googleapis.com/maps/api/geocode/xml?address=Москва, Охотный Ряд, 2&sensor=true_or_false
Ниже показаны результаты (в формате XML) ответа на отправленный запрос.

This XML file does not appear to have any style information associated with it. The document tree is shown below.

OK

street_address
улица Охотный Ряд, 2, Москва, Россия, 109012

2
2
street_number


улица Охотный Ряд
ул. Охотный Ряд
route


Центральный административный округ
Центральный административный округ
sublocality_level_1
sublocality
political


Москва
Москва
locality
political


город Москва
г. Москва
administrative_area_level_2
political


город Москва
г. Москва
administrative_area_level_1
political


Россия
RU
country
political


109012
109012
postal_code



55.7570051
37.6164606

ROOFTOP


55.7556561
37.6151116


55.7583541
37.6178096




     Обратите внимание, что ответ в формате XML состоит из одного элемента «geocoderesponse» и следующих двух элементов верхнего уровня:
  • «status», содержащий метаданные по запросу. 
  • Ноль или более элементов «result», каждый из которых содержит один массив геокодированной адресной и геометрической информации.
      Поле «status», входящее в объект ответа службы геокодирования, содержит статус запроса и может включать в себя отладочную информацию для отслеживания сбоев службы. Поле «status» может содержать следующие значения:
  • «OK», указывает на отсутствие ошибок. Синтаксический анализ адреса выполнен успешно и был возвращен, по крайней мере, один геокод.
  • «ZERO_RESULTS», указывает, что геокодирование выполнено успешно, но не возвратило никаких результатов. Это может произойти, если геокодеру был передан несуществующий элемент «address» или координаты «latlng» в удаленной точке.
  • «OVER_QUERY_LIMIT», указывает на превышение квоты.
  • «REQUEST_DENIED», означает, что запрос отклонен, обычно из-за отсутствия параметра sensor.
  • «INVALID_REQUEST», обычно указывает, что запрос (address или latlng) отсутствует.
Дополнительную информацию по работе с API геокодирования Google вы можете получить с сайта https://developers.google.com.
      Рассмотрим основные пункты, возвращаемые геокодером, размещенные в массиве «results». Даже если результаты не были получены (например, при отсутствии адреса), геокодер возвращает пустой массив «results». (Число элементов в ответах службы в формате XML больше или равно нулю «result».)
  1. location, содержащее геокодированное значение широты/долготы. При поиске обычных адресов это поле, как правило, является наиболее важным.
    
    55.7570051
    37.6164606
    
  2. location_type, содержащее дополнительные данные об указанном местоположении. В настоящее время поддерживаются следующие значения:
    • "ROOFTOP", указывающее, что возвращенный результат является точным геокодом с соответствующей информацией о местоположении, которая была определена с точностью до адреса улицы.
    • "RANGE_INTERPOLATED", указывающее, что возвращенный результат содержит приблизительное значение (обычно на дороге), полученное в результате интерполяции с использованием двух точно определенных точек (например, перекрестков). Приблизительные результаты обычно возвращаются, когда для адреса недоступен геокод конкретного дома.
    • "GEOMETRIC_CENTER", указывающее, что возвращенный результат является геометрическим центром результата, такого как полилиния (например, улица) или полигон (регион).
    • "APPROXIMATE", указывающее, что возвращенный результат является приблизительным.
    ROOFTOP
  3. formatted_address – строка, содержащая удобочитаемый адрес этого места. Часто этот адрес эквивалентен почтовому адресу, который может выглядеть по-разному в зависимости от страны. (Следует отметить, что в некоторых странах, например, в Великобритании, использование настоящих почтовых адресов не разрешается в силу лицензионных ограничений.) Адрес обычно состоит из одного или нескольких компонентов адреса. Например, адрес "улица Охотный Ряд, 2, Москва, Россия, 109012" содержит отдельные компоненты "2" (номер дома), "Охотный Ряд "(улица), "Москва" (город) и "Россия".
    улица Охотный Ряд, 2, Москва, Россия, 109012
      Массив types[] в возвращенных результатах указывает тип адреса. Эти типы могут возвращаться также в массивах address_components[] для указания типа определенного компонента адреса. У адресов в геокодере может быть несколько типов; эти типы можно считать "тегами". Например, многие города помечаются тегами типов political и locality.

Геокодер HTTP поддерживает и возвращает следующие типы:

  • street_address, обозначающий подробные адреса.
  • route, обозначающий трассы, имеющие код (например, "US 101").
  • intersection, обозначающий крупные перекрестки, обычно двух главных дорог.
  • political, обозначающий политические образования. Последний тип обычно обозначает многоугольник, включающий местную административно-территориальную единицу.
  • country, обозначающий страны и обычно являющийся типом высшего порядка, возвращаемым геокодером.
  • administrative_area_level_1, обозначающий административно-территориальную единицу первого уровня в пределах страны. В США это – штаты. Административные единицы такого уровня существуют не во всех странах.
  • administrative_area_level_2, обозначающий административно-территориальную единицу второго уровня в пределах страны. В США это – округа. Административные единицы такого уровня существуют не во всех странах.
  • administrative_area_level_3, обозначающий административно-территориальную единицу третьего уровня в пределах страны. Этот тип указывает мелкие административные единицы. Административные единицы такого уровня существуют не во всех странах.
  • colloquial_area, обозначающий распространенное альтернативное название для политической или административной единицы.
  • locality, обозначающий города, являющиеся политическими или административными единицами.
  • sublocality, обозначающий районы города.
  • neighborhood, обозначающий микрорайоны и кварталы с собственными названиями.
  • premise, обозначающий поименованные местоположения, обычно строения или группы строений с общим именем.
  • subpremise, обозначающий единицы, на которые делится предыдущая категория, обычно отдельные строения внутри групп строений с общим названием.
  • postal_code, обозначающий почтовый индекс, используемый для почтовых адресов внутри страны.
  • natural_feature, обозначающий главные природные достопримечательности.
  • airport, обозначающий аэропорты.
  • park, обозначающий парки, имеющие названия.
  • point_of_interest, обозначающий достопримечательности, имеющие названия. Обычно главные местные достопримечательности (POI) представляют собой местные объекты, отмеченные на карте, такие как Эмпайр-стейт-билдинг или статуя Свободы, которые не могут быть однозначно отнесены к другой категории.
postal_code
      Данные типы могут вам помочь при установке различных маркеров на объекты (инструкцию по установке различных типов маркеров вы можете посмотреть в инструкции «Работа с картами в Windows Form с использованием GMap.NET. Часть 5»).
Запустите Microsoft Visual Studio и создайте новый проект Windows Form.

      Добавьте на форму следующие элементы управления:
  • button1 – кнопка запуска процесса формирования и отправки запроса к API геокодирования Google;
  • textBox1 - текстовое поле для ввода адреса.
      А так же в соответствии с инструкцией «Работа с картами в Windows Form с использованием GMap.NET» , добавьте визуальный компонент «GMap.NET». У вас получится приведенный ниже пример.
      Сделайте двойной клик по пустому пространству главной формы, вы перейдете в автоматически созданный метод загрузки главной формы «Form1_Load». Добавьте в него приведенный ниже код установки настроек для элемента управления «gMapControl1».
//Настройки для компонента GMap.
gMapControl1.Bearing = 0;

//CanDragMap - Если параметр установлен в True,
//пользователь может перетаскивать карту 
///с помощью правой кнопки мыши. 
gMapControl1.CanDragMap = true;

//Указываем, что перетаскивание карты осуществляется 
//с использованием левой клавишей мыши.
//По умолчанию - правая.
gMapControl1.DragButton = MouseButtons.Left;

gMapControl1.GrayScaleMode = true;

//MarkersEnabled - Если параметр установлен в True,
//любые маркеры, заданные вручную будет показаны.
//Если нет, они не появятся.
gMapControl1.MarkersEnabled = true;

//Указываем значение максимального приближения.
gMapControl1.MaxZoom = 18;

//Указываем значение минимального приближения.
gMapControl1.MinZoom = 2;

//Устанавливаем центр приближения/удаления
//курсор мыши.
gMapControl1.MouseWheelZoomType =
    GMap.NET.MouseWheelZoomType.MousePositionAndCenter;

//Отказываемся от негативного режима.
gMapControl1.NegativeMode = false;

//Разрешаем полигоны.
gMapControl1.PolygonsEnabled = true;

//Разрешаем маршруты
gMapControl1.RoutesEnabled = true;

//Скрываем внешнюю сетку карты
//с заголовками.
gMapControl1.ShowTileGridLines = false;

//Указываем, что при загрузке карты будет использоваться 
//2х кратное приближение.
gMapControl1.Zoom = 2;

//Указываем что будем использовать карты Yandex.
gMapControl1.MapProvider =
    GMap.NET.MapProviders.GMapProviders.YandexMap;
GMap.NET.GMaps.Instance.Mode =
    GMap.NET.AccessMode.ServerOnly;

//Если вы используете интернет через прокси сервер,
//указываем свои учетные данные.
GMap.NET.MapProviders.GMapProvider.WebProxy =
    System.Net.WebRequest.GetSystemWebProxy();
GMap.NET.MapProviders.GMapProvider.WebProxy.Credentials =
    System.Net.CredentialCache.DefaultCredentials;
      Перейдите в Конструктор главной формы и сделайте двойной клик левой клавишей мыши по элементу управления «button1». Вы перейдете в автоматически созданный метод «button1_Click», события «Click», возникающего при нажатии на данный элемент управления. Добавьте приведенный ниже код реализующего отправку запроса и чтения ответа службы API геокодирования Google, в тело данного метода.
//Запрос к API геокодирования Google.
string url =string.Format(
    "http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=true_or_false&language=ru",
    Uri.EscapeDataString(textBox1.Text));

//Выполняем запрос к универсальному коду ресурса (URI).
System.Net.HttpWebRequest request = 
    (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);

//Получаем ответ от интернет-ресурса.
System.Net.WebResponse response = 
    request.GetResponse();

//Экземпляр класса System.IO.Stream 
//для чтения данных из интернет-ресурса.
System.IO.Stream dataStream = 
    response.GetResponseStream();

//Инициализируем новый экземпляр класса 
//System.IO.StreamReader для указанного потока.
System.IO.StreamReader sreader = 
    new System.IO.StreamReader(dataStream);

//Считывает поток от текущего положения до конца.            
string responsereader = sreader.ReadToEnd();

//Закрываем поток ответа.
response.Close();

System.Xml.XmlDocument xmldoc =
    new System.Xml.XmlDocument();

xmldoc.LoadXml(responsereader);

if (xmldoc.GetElementsByTagName("status")[0].ChildNodes[0].InnerText == "OK")
{

    //Получение широты и долготы.
    System.Xml.XmlNodeList nodes = 
        xmldoc.SelectNodes("//location");

    //Переменные широты и долготы.
    double latitude = 0.0;
    double longitude = 0.0; 

    //Получаем широту и долготу.
    foreach (System.Xml.XmlNode node in nodes)
    {
        latitude = 
           System.Xml.XmlConvert.ToDouble(node.SelectSingleNode("lat").InnerText.ToString());
        longitude = 
           System.Xml.XmlConvert.ToDouble(node.SelectSingleNode("lng").InnerText.ToString());
    }
    
    //Варианты получения информации о найденном объекте.
    //Вариант 1.
    string formatted_address = 
       xmldoc.SelectNodes("//formatted_address").Item(0).InnerText.ToString();

    //Вариант 2.
    //Массив, элементы которого содержат подстроки данного экземпляра, разделенные
    //одним или более знаками из separator. 
    string[] words = formatted_address.Split(',');
    string dataMarker = string.Empty;
    foreach (string word in words)
    {
        dataMarker += word +";"+ Environment.NewLine;
    }

    //Вариант 3.
    //string[] words = formatted_address.Split(',');                
    ////Дом.
    //string house = words[1].Trim();
    ////Улица.
    //string Street = words[0].Trim();
    ////Город.
    //string City = words[2].Trim();
    ////Область.
    //string Region = words[3].Trim();                
    ////Страна.
    //string Country = words[4].Trim(); 
    ////Почтовый индекс.
    //string PostalCode = words[5].Trim();

    //Вариант 4
    ////Дом.
    //string house = xmldoc.SelectNodes("//address_component").Item(0).SelectNodes("short_name").Item(0).InnerText.ToString();
    ////Улица.
    //string Street = xmldoc.SelectNodes("//address_component").Item(1).SelectNodes("short_name").Item(0).InnerText.ToString();
    ////Область.
    //string Region = xmldoc.SelectNodes("//address_component").Item(2).SelectNodes("short_name").Item(0).InnerText.ToString();
    ////Город.
    //string City = xmldoc.SelectNodes("//address_component").Item(3).SelectNodes("short_name").Item(0).InnerText.ToString();
    ////Страна.
    //string Country = xmldoc.SelectNodes("//address_component").Item(6).SelectNodes("long_name").Item(0).InnerText.ToString();
    ////Почтовый индекс.
    //string PostalCode = xmldoc.SelectNodes("//address_component").Item(7).SelectNodes("short_name").Item(0).InnerText.ToString();

    //Создаем новый список маркеров, с указанием компонента 
    //в котором они будут использоваться и названием списка.
    GMap.NET.WindowsForms.GMapOverlay markersOverlay =
        new GMap.NET.WindowsForms.GMapOverlay(gMapControl1, "marker");

    //Инициализация нового ЗЕЛЕНОГО маркера, с указанием его координат.
    GMap.NET.WindowsForms.Markers.GMapMarkerGoogleGreen markerG =
        new GMap.NET.WindowsForms.Markers.GMapMarkerGoogleGreen(
        new GMap.NET.PointLatLng(latitude, longitude));
    markerG.ToolTip =
        new GMap.NET.WindowsForms.ToolTips.GMapRoundedToolTip(markerG);

    //Указываем, что подсказку маркера, необходимо отображать всегда.
    markerG.ToolTipMode = GMap.NET.WindowsForms.MarkerTooltipMode.Always; 

    //Текст подсказки маркера.
    //Для Варианта 1,2.
    markerG.ToolTipText = dataMarker; 

    //Для Варианта 3,4.
    //markerG.ToolTipText =
    //   "Почтовый ин.: "+PostalCode + Environment.NewLine+
    //   "Страна: " + Country + Environment.NewLine +
    //   "Город: " + City + Environment.NewLine +
    //   "Область: " + Region + Environment.NewLine +
    //   "Улица: " + Street + Environment.NewLine +
    //   "Номер дома: " + house + Environment.NewLine;

    //Добавляем маркеры в список маркеров.
    markersOverlay.Markers.Add(markerG);

    //Очищаем список маркеров компонента.
    gMapControl1.Overlays.Clear();
    
    //Добавляем в компонент, список маркеров.
    gMapControl1.Overlays.Add(markersOverlay);

    //Устанавливаем позицию карты.
    gMapControl1.Position = new GMap.NET.PointLatLng(latitude, longitude);  

    //Указываем, что при загрузке карты будет использоваться 
    //17ти кратное приближение.
    gMapControl1.Zoom = 17;
   
    //Обновляем карту.
    gMapControl1.Refresh();
}
      Запустите проект, нажав на клавиатуре клавишу «F5». После полной загрузки вашего проекта, вы увидите в минимальном масштабе карту.
      Введите в текстовое поле объект для поиска, например: «Санкт-Петербург, Дворцовая набережная, 38». У вас откроется карта с найденным объектом и установленной подсказкой. Ниже представлены примеры работы тестового проекта.

Кроме ввода полного адреса, вы также можете указать название объекта поиска.

Ссылка для скачивания примера: Яндекс.Диск


Комментариев нет:

Отправить комментарий

Большая просьба, не писать в комментариях всякую ерунду не по теме!