Максим Мазитов дата публикации 19-04-2009 11:38 API статических карт Google
Уже продолжительное время Google предоставляет отличное картографическое средство — Google Maps. У него открытый API интерфейс, много волшебных возможностей, удобный интерфейс пользователя, покрыт весь мир и что самое главное — использование карт условно бесплатное. Один минус — всё это счастье работает под Java машиной в браузерах. В сети много инфы по включению гуглокарт в состав виндового приложения через использование компонента TWebBrowser. Если вы знакомы с JavaScript и объектной моделью Internet Explorer, то построение такого приложения после танцев с бубнами, копания в и-нете и комментирования в коде ненормативной лексики — задача вполне реализуемая. Однако я хочу рассмотреть другой вариант получения картографической информации от гугля — статические карты.
Статические карты Google представляют собой обычный битмап. Такая карта не имеет никаких интерактивных возможностей по взаимодействию с пользователем. Положительным моментом является то, что не нужно использовать TWebBrowser — источник постоянного пожирания оперативной памяти и раздувания размера приложения.
Информация по использованию API статических карт доступна на русском языке по этой ссылке http://code.google.com/intl/ru-RU/apis/maps/documentation/staticmaps/. Рекомендуется к обязательному прочтению после статьи.
Я построю простое приложение, отображающее на карте заданную по широте и долготе точку с требуемым масштабом.
Для получения картинки с картой требуется совершить следующие действия:
- Знать координаты отображаемой точки и масштаб карты вокруг точки. Для этого нарисуем простейший интерфейс пользователя.
- Передать http запрос серверу в определенном формате, содержащий параметры картинки и получить ответ от сервера в виде блока бинарных данных.
- Преобразовать данные в принимаемый Delphi графический формат.
- Нарисовать картинку на форме.
Действие 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
Обращу внимание на три момента:
- Координаты принимаются в формате "значение с плавающей точкой" не более 6-ти знаков после точки. Значения задаются в десятичных долях градуса. Для перевода из формата секунд вспоминаем, сколько секунд в минутах.
- Google заверяет, что максимальный размер картинки 512х512. Опытным путем вычислено, что максимальный размер 640x640.
- С ключом карты ситуация не вполне ясная. Я не использовал ключ, получаемый у Google, т.к. ключ генерируется для конкретного сайта, а карта отображается в приложении. Я взял ключ из примера на сайте. Пока он работает, а что будет дальше, я не знаю.
Итак, url сформирован, и его нужно заслать в Google. Для передачи http запроса и получения ответа я использовал слегка подправленный код с этого сайта. Так что на авторство не претендую :). Интересующиеся могут поискать по круглому столу по слову "GetInetFile".
Смотрим код:
function GetMap(Latitude:Double;Longitude:Double;Scale:Integer):TOleGraphic;
var
FileOnNet: String;
Stream:TMemoryStream;
begin
Stream:=TMemoryStream.Create;
try
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 Earth: ххх: Привет, участники форума! Не могли бы вы дать координаты Google Earth военных портов в США? ууу: Совсем ракетчики обленились!
К статье прилагается пример
[Сетевые службы и протоколы] [HTTP/HTTPS] [Взаимодействие с ГИС]
Обсуждение материала [ 29-01-2010 03:42 ] 14 сообщений |