API статических карт Google

Источник: delphikingdom
Максим Мазитов

Автор: Максим Мазитов, Королевство Delphi

Уже продолжительное время Google предоставляет отличное картографическое средство - Google Maps. У него открытый API интерфейс, много волшебных возможностей, удобный интерфейс пользователя, покрыт весь мир и что самое главное - использование карт условно бесплатное. Один минус - всё это счастье работает под Java машиной в браузерах. В сети много инфы по включению гуглокарт в состав виндового приложения через использование компонента TWebBrowser. Если вы знакомы с JavaScript и объектной моделью Internet Explorer, то построение такого приложения после танцев с бубнами, копания в и-нете и комментирования в коде ненормативной лексики - задача вполне реализуемая. Однако я хочу рассмотреть другой вариант получения картографической информации от гугля - статические карты.

Статические карты Google представляют собой обычный битмап. Такая карта не имеет никаких интерактивных возможностей по взаимодействию с пользователем. Положительным моментом является то, что не нужно использовать TWebBrowser - источник постоянного пожирания оперативной памяти и раздувания размера приложения.

Информация по использованию API статических карт доступна на русском языке по этой ссылке http://code.google.com/intl/ru-RU/apis/maps/documentation/staticmaps/. Рекомендуется к обязательному прочтению после статьи.

Я построю простое приложение, отображающее на карте заданную по широте и долготе точку с требуемым масштабом.

Для получения картинки с картой требуется совершить следующие действия:

  1. Знать координаты отображаемой точки и масштаб карты вокруг точки. Для этого нарисуем простейший интерфейс пользователя.
  2. Передать http запрос серверу в определенном формате, содержащий параметры картинки и получить ответ от сервера в виде блока бинарных данных.
  3. Преобразовать данные в принимаемый Delphi графический формат.
  4. Нарисовать картинку на форме.

Действие 1 я расписывать не буду, скачиваем пример (Delphi 7), открываем и фтыкаем в Delphi IDE.

Действие 2. Как следует из инфы гугла (см. ссылку), формат запроса имеет следующий вид: http://maps.google.com/staticmap?parameters, где parameters - пары <параметр>=<значение>, разделенные знаком "&". В общем, обычный вид передачи параметров в url. Для запроса нам понадобятся следующие параметры:

  • Center;
  • Zoom;
  • Size;
  • Maptype;
  • Markers;
  • Key.

То есть все параметры, которые предоставляет гугль. Я не буду их расписывать, по названию параметров понятно, за что отвечает каждый параметр. Для подробного изучения рекомендую первоисточник. Ограничусь строкой для функции Format из исходников:

http://maps.google.com/staticmap?center=%.6f,%.6f&zoom=%d&size='&markers=%.6f,%.6f,blues&maptype=mobile&key=MAPS_API_KEY

Обращу внимание на три момента:

  1. Координаты принимаются в формате "значение с плавающей точкой" не более 6-ти знаков после точки. Значения задаются в десятичных долях градуса. Для перевода из формата секунд вспоминаем, сколько секунд в минутах.
  2. Google заверяет, что максимальный размер картинки 512х512. Опытным путем вычислено, что максимальный размер 640x640.
  3. С ключом карты ситуация не вполне ясная. Я не использовал ключ, получаемый у Google, т.к. ключ генерируется для конкретного сайта, а карта отображается в приложении. Я взял ключ из примера на сайте. Пока он работает, а что будет дальше, я не знаю.

Итак, url сформирован, и его нужно заслать в Google. Для передачи http запроса и получения ответа я использовал слегка подправленный код с этого сайта. Так что на авторство не претендую :). Интересующиеся могут поискать по круглому столу по слову "GetInetFile".

Смотрим код:

// получение карты с заданным центром, масштабом и с маркером в центре
function GetMap(Latitude:Double;Longitude:Double;Scale:Integer):TOleGraphic;
var
  FileOnNet: String;
  Stream:TMemoryStream;
begin
  // создаем поток
  Stream:=TMemoryStream.Create;
  try
    // формируем url для запроса
    FileOnNet:='http://maps.google.com/staticmap?center=%.6f,%.6f&zoom=%d&size=640x640'
      +'&markers=%.6f,%.6f,blues'
      +'&maptype=mobile&key=MAPS_API_KEY';
    FileOnNet:=Format(FileOnNet,[Latitude,Longitude,Scale,Latitude,Longitude]);
    // получение потока с данными ответа
    if GetInetFile(FileOnNet,Stream) = True then begin
      // создаем графический объект
      Stream.Position:=0;
      Result:=TOleGraphic.Create;
      Result.LoadFromStream(Stream);
    end else
      Result:=nil;
  finally
    Stream.Free;
  end;
end;

На выходе имеем заполненный класс TOleGraphic в случае успешного соединения или пустой указатель в случае отказа сервера или отсутствия связи с сервером.

Хочу пояснить мотивы использования TOleGraphic. При написании программы я сохранял промежуточные данные в файл Jpeg формата для просмотра результатов запроса. И файл просматривался с диска виндой безо всяких проблем. Но при попытке открыть его и загнать в Image на форму выдавалось исключение Jpeg. Аналогичная ситуация происходила при попытке передачи потока напрямую в Image. Решение было найдено в виде TOleGraphic, которому абсолютно параллельно, какие данные лежат в принимаемом потоке (если я не прав, пусть меня поправят). А данные то, оказывается, были в формате Gif. Воистину, если у вас что-то не получается, прочтите наконец инструкцию!

На этом действия 2 и 3 завершены. Битмап у нас на руках, рисуем его на форме кто как умеет.

Собственно всё.

А все вопросы - к гуглу, он знает ВСЁ!

И для тех, кто в танке - для правильной работы примера необходимо активное рабочее подключение к интернет.

Результат выглядит так:

Карты Google

В качестве эпилога цитата с баш.орга:

С форума, ветка про Google Earth:
ххх: Привет, участники форума! Не могли бы вы дать координаты Google Earth военных портов в США?
ууу: Совсем ракетчики обленились!


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=20507