MapWindowGIS-Yandex-Static4Всем доброго времени суток. В этой статье, мы возвращаемся к нашему проекту MapWindow GIS, и сегодня мы будем его рассматривать вместе с геокодированием Яндекс.Карт. Это, довольно, популярно сейчас, в свой проект, включать другие ГИС, которые обладают более точными и красочными данными. К ним можно отнести не только Яндекс.Карты, но и тот же самый Google Maps, и многие другие.

В проект, я включил статические Яндекс.Карты, но это вовсе не означает, что они не будут масштабироваться. Да, мы получим карту в виде картинки, но масштабировать ее буде, при помощи MapWindow GIS (компонента TMap).

Я уже рассказывал о работе TClientSocket и TServerSocket на примере MapWindow GIS, в той статье мы рассмотрели: как можно передавать файлы по сети, то есть сервер запрашивает карту у Яндекса, затем отправляет ее клиенту, а в клиенте уже отображается, полученная карта (в компоненте TMap). Но мы не рассмотрели сам механизм, как запрашивает программа-сервер карты у Яндекса.

Данная статья, будет посвящена следующему:

  • Настройки, для получения статических карт от Яндекса
  • Сохранение статических карт локально на компьютере
  • Работа с картами Яндекс локально
  • Работа с картами Яндекс, через сеть Интернет

С первым пунктом, я думаю, что Вам понятно. То есть, создается форма с настройками, для получения статической карты. К настройкам можно отнести: работу через прокси; размер, получаемой карты; центр карты; работа с БД (для локальных карт) и другое.

Что касается второго пункта, то тут тоже, должно быть все понятно, то есть, каждую карту, которую мы получаем от Яндекса, мы сохраняем локально на компьютере, чтобы в дальнейшем, можно было с ними работать, без доступа в сеть Интернет (если, конечно, такая функция включена в настройках программы – сохранять карты локально).

Работа с картами Яндекс локально – это возможность, загружать в свой проект, сохраненные карты от Яндекса.

Работа с картами Яндекс, через Интернет – это возможность загружать в свой проект, карты от Яндекса, работать с ними в дальнейшем, при этом ее не сохранять локально, для дальнейшей работы.

В своем проекте, я создал окно с настройками, а также окно для работы с Яндекс.Картами. Окно настроек, у меня, выглядит следующим образом:

MapWindowGIS-Yandex-Static1

Я разделил настройки на 3 подгруппы:

  • Настройки сети
  • Настройки БД (для локальных карт)
  • Настройки, получаемых карт

Все настройки я храню в ini-файле. Работать с данным типом файла очень просто. Пример о том, как работать с ini, я уже немного рассказывал в блоге.

Что касается первого блока – настроек прокси, то здесь необходимо указать, нужные данные для прокси, если карты запрашиваем у Яндекса, через прокси.

Что касается второго блока – настройка БД, то это я сделал для того, чтобы можно было работать с картами локально. В БД сохраняю название улиц, городов, чтобы в дальнейшем, можно было удобно искать локальные (сохраненные) карты от Яндекса.

Программа работает с базой MS Access (по технологии ADO), ее можно подключить самому, либо же создать при помощи программы.

Что касается третьей подгруппы, то там мы просто указываем небольшие настройки, статических карт от Яндекса. Мы уже рассматривали Static API Яндекс.Карт.

Сама форма для работы с Яндекс.Картами, у меня, выглядит следующим образом:

MapWindowGIS-Yandex-Static2

Из данного окна можно запрашивать необходимо информацию у Яндекса, затем занести ее в БД и по нажатию на кнопку «Показать», она отображается в компоненте TMap, с размером, который указан в настройках и, конечно же, с дальнейшим масштабированием.

Кстати, программа может получить еще похожие результаты на Ваш, а Вы из выпадающего списка, можете выбрать нужный:

MapWindowGIS-Yandex-Static3

Как видите, это очень удобно. Давайте посмотрим на то, как я получаю карты от Яндекса, на событие onClick я написал следующий код:

procedure TGeoCoderYandex.Button1Click(Sender: TObject);
var
 html,l,query:WideString;
 ParsClass:TParserXML;
 i:integer;
begin
 try
  //если выбрана не работа с БД, то запрашиваем у Яндекса данные
  if CheckBox1.Checked=False then
   begin
    //проверяем чтобы пользователь не ввел пустой запрос
    if Trim(Edit1.Text)='' then
     begin
      Application.MessageBox('Введите запрос','Внимание',MB_OK+MB_ICONINFORMATION);
      exit;
     end;
    //загружаем настройки из Setting.ini
    if Ini.ReadString('GeoYandex','Proxy','')='True' then
     begin
      IdHTTP1.ProxyParams.ProxyPort:=Ini.ReadInteger('GeoYandex','ProxyPort',0);
      IdHTTP1.ProxyParams.ProxyServer:=Ini.ReadString('GeoYandex','ProxyIP','');
      IdHTTP1.ProxyParams.ProxyUsername:=Ini.ReadString('GeoYandex','ProxyUsername','');
      IdHTTP1.ProxyParams.ProxyPassword:=Ini.ReadString('GeoYandex','ProxyPassword','');
     end;
    if Ini.ReadString('GeoYandex','Log','')='True' then
     begin
      IdHTTP1.Intercept:=IdLogFile1;
      IdLogFile1.Filename:=Ini.ReadString('GeoYandex','LogFile','');
      IdLogFile1.Active:=True;
     end;
    Coord:=TStrings.Create;
    query:=Edit1.Text;
    while (pos(' ',query)<>0) do
     begin
      Insert('%20',query,pos(' ',query));
      Delete(query,pos(' ',query),1);
     end;
    html:=IdHTTP1.Get('http://geocode-maps.yandex.ru/1.x/?geocode='+AnsiToUtf8(query));
    ParsClass:=TParserXML.Create;
    ComboBox1.Items:=ParsClass.ParsXMLArr(html,'text');
    Coord:=ParsClass.ParsXMLArr(html,'pos');
    ComboBox1.ItemIndex:=0;
    if ComboBox1.Items.Count<>0 then
     begin
      ComboBox1.Enabled:=True;
      Button2.Enabled:=True;
      Button3.Enabled:=True;
     end
    else
     Application.MessageBox('По Вашему запросу ничего не найдено','Внимание',MB_OK+MB_ICONINFORMATION);
   end;
  //работа с БД а не онлайн
  if CheckBox1.Checked=True then
   begin
   //проверяем чтобы пользователь не ввел пустой запрос
    if Trim(Edit1.Text)='' then
     begin
      Application.MessageBox('Введите запрос','Внимание',MB_OK+MB_ICONINFORMATION);
      exit;
     end;
    ADOQuery1.SQL.Clear;
    ADOQuery1.SQL.Add('SELECT * FROM Yandex WHERE name LIKE ''%'+Edit1.Text+'%''');
    ADOQuery1.Active:=True;
    if ADOQuery1.RecordCount=0 then
     begin
      Application.MessageBox('По Вашему запросу ничего не найдено','Внимание',MB_OK+MB_ICONINFORMATION);
      exit;
     end;
    Coord2:=TStringList.Create;
    ADOQuery1.First;
    for i:=0 to ADOQuery1.RecordCount-1 do
     begin
      ComboBox1.Items.Add(ADOQuery1.Fields.Fields[1].AsString);
      Coord2.Add('31.010895 52.431881');
      ADOQuery1.Next;
     end;
     ComboBox1.ItemIndex:=0;
     ComboBox1.Enabled:=True;
     Button2.Enabled:=True;
   end;
  except
   on e:Exception do
    begin
     FreeAndNil(Coord2);
    end;
  end;
end;

Здесь, у меня идет различие – пользователь работает с картами локально или же через Интернет.

Также я использую две функции для парсинга данных, я их сам написал, можно было по-другому, но каждому свое:

function TParserXML.ParsXML(XML,tag: WideString): WideString;
begin
   Delete(XML,1,pos('<'+tag+'>',XML)+length('<'+tag+'>')-1);
   Delete(XML,pos('+tag+'>',XML),length(XML));
   Result:=XML;
end;
 
function TParserXML.ParsXMLArr(XML, tag: WideString): TStrings;
var
 ParsTag:TParserXML;
 i:integer;
begin
   try
    Result:=TStringList.Create;
    ParsTag:=TParserXML.Create;
    i:=1;
    while (i<=length(XML)) do
     begin
      if pos('<'+tag+'>',XML)<>0 then
       begin
        Result.Add(Utf8ToAnsi(ParsTag.ParsXML(XML,tag)));
        Delete(XML,1,pos('+tag+'>',XML));
        i:=0;
       end;
      inc(i);
     end;
    ParsTag.Free;
   finally
   end;
end;

После того, как мы получили url на наше изображение (на нашу карту), то нам необходимо создать само изображение. Я выбрал формат png, так как он лучше всего сжимается и получаю карту следующим образом:

procedure TGeoCoderYandex.Button2Click(Sender: TObject);
var
 img:TStringStream;
 crd,zoom,pixel:String;
 png:TPNGObject;
 i:Image;
begin
 if CheckBox1.Checked=False then
  begin
   //создаем PNG-изображение, которое будем грузить с Яндекса
   png:=TPNGObject.Create;
   //формируем координаты картинки
   crd:=Coord.Strings[ComboBox1.ItemIndex];
   Insert(',',crd,pos(' ',crd));
   Delete(crd,pos(' ',crd),1);
   //считываем из INI-файла настройки масштаба и размера картинки
   zoom:=Ini.ReadString('GeoYandex','ZoomSize2','');
   pixel:=Ini.ReadString('GeoYandex','PixelSize2','');
   //запрашиваем картинку на Яндексе
   img:=TStringStream.Create(IdHTTP1.Get('http://static-maps.yandex.ru/1.x/?ll='+crd+'&spn='+zoom+'&size='+pixel+'&l=map'));
   //загружаем в PNG наш стрим
   png.LoadFromStream(img);
   //временно его сохраняем
   png.SaveToFile(ExtractFilePath(ParamStr(0))+'Yandex\'+crd+'.png');
   i:=CoImage.Create;
   i.Open(ExtractFilePath(ParamStr(0))+'Yandex\'+crd+'.png',PNG_FILE,False,nil);
   //отображаем наше изображение в TMap
   Form1.Map1.AddLayer(i,True);
   //если пользователем выствалена настройка не хранить все изображения с Яндекса локально, то удаляем их
   if Ini.ReadString('GeoYandex','SaveMap','')<>'True' then
    begin
     //очищаем папку с изображением, кроме последнего, так как он будет в TMap
     ClearDir(ExtractFilePath(ParamStr(0))+'Yandex\');
    end;
   FreeAndNil(png);
   FreeAndNil(Coord);
   Close;
  end;
 if CheckBox1.Checked=True then
  begin
   try
    //формируем координаты картинки
    crd:=Coord2.Strings[ComboBox1.ItemIndex];
    Insert(',',crd,pos(' ',crd));
    Delete(crd,pos(' ',crd),1);
    i:=CoImage.Create;
    i.Open(ExtractFilePath(ParamStr(0))+'Yandex\'+crd+'.png',PNG_FILE,False,nil);
    //отображаем наше изображение в TMap
    Form1.Map1.AddLayer(i,True);
    FreeAndNil(Coord);
    Close;
   except
    on e:Exception do
     Application.MessageBox('Не удается отобразить файл','Внимание',MB_OK+MB_ICONINFORMATION);
   end;
  end;
end;

В итоге, это будет выглядеть следующим образом:

MapWindowGIS-Yandex-Static4

Конечно, отрывки кода из проекта, могут быть не понятны, но смысл должен стать понятным, поэтому подробно, можно почитать, про данную функции, а также сам проект на странице проекта MapWindow GIS в Delphi.

Также хочется внести в проект, еще статические карты Google, ведь у каждого свои предпочтения, правда ведь?

Метки: , , ,




К записи “Работа с MapWindow GIS. Статические карты Яндекс” оставлено комментариев: 2.

  1. Валишок:

    очень хорошо описан. Я уже начал понимать принцип. А где могу скачать Вашу программу?

    • Andrey:

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

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

Вы можете использовать следующие теги:

*