SASGIS

Веб-картография и навигация

GeoCacher

Обсуждение различной информации связанной с картографией в САСе, а также сторонние программные продукты для связки с САСом

Модератор: Tolik

GeoCacher

Сообщение elf » 16 май 2009, 20:27

Изображение

GeoCacher - небольшой кэширующий прокси-сервер, предназначенный для эффективного он-лайн кэширования запросов GoogleEarth. Особенность запросов GE, которая заключается в объединении в одном запросе до 4-х различных файлов в произвольном порядке, не позволяла обычным кэширующим прокси-серверам (к примеру, HandyCache) что-либо отдавать из накопленного кэша. С GeoCacher-ом ситуация кардинально противоположная: накопленный кэш эффективен на 100% - то что однажды было выкачано и попало в кэш, при повторном запросе будет отдано клиенту GE из кэша, и повторной закачки того же самого файла из интернета не будет.

GeoCacher не создавался и не тестировался на нормальную обработку запросов браузеров, и стабильная работа браузера через GeoCacher не гарантируется. Ну а всё, что касается GE - железная гарантия :)

То, куда будут сохраняться кэшированные файлы, и будут ли они как-то сортироваться, настраивается правкой регулярных выражений в файлах из папки RegExpr (которая находится в директории с программой). Для тестирования и отладки регулярных выражений можно воспользоваться небольшой утилиткой или встроенным тренажёром (вкладка Настройки -> Тренажёр). По-умолчанию, кэш будет создан в папке GC_CachePath (в папке с программой)

По-умолчанию, программа настроена на прослушку порта 8081 (ip 127.0.0.1) - так что, вбив эти настройки в InternetExploer и запустив GeoCacher можно забыть обо всём и бороздить просторы любимой Планеты с GoogleEarth, а обо всём остальном позаботится GeoCacher.

Версия 1.3.2:
- функция сервера: теперь, по определённому URL, геокэшер будет выдавать картинки из своего кэша, любому, запросившему этот URL. Теперь возможен просмотр кэша GC в программе SAS.Планета; - режим работы "Только из кэша" (кроме авторизации); - включение ведения лога ошибок больше не приводит к нагрузке на процессор.

Сводная информация:

Операционная система: Windows All
Язык: Русский
Условия лицензии: FreeWare
Дата выпуска: 15 мая 2009 г.
Размер файла (rar) 1.55 МБ

Для загрузки программы нажмите: Скачать

Программа распрастраняется с исходным кодом, исходники лежат внутри архива с программой.

Вопросы и комментарии, как всегда, на форуме: forum.Ru-Board.com

Внимание, на сайте будут выкладываться ссылки только на последнюю стабильную версию. Объявления о промежуточных, тестовых версиях - на форуме Ru-Board.


Описание взято с сайта автора - http://starmen.at.tut.by/geocacher.html
Аватара пользователя
elf
Новичок
 
Сообщения: 37
Зарегистрирован: 12 июл 2008, 19:31
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: GeoCacher

Сообщение zed » 21 май 2009, 18:49

GeoCacher - тестовая версия (исходники внутри), что нужно потестировать читаем ниже.

feya писал(а):zed
Иногда тайлы возвращаются с белым участком снизу. Думал сначала просто нет к-либо тайла, но после повторной загрузки отображает нормально.

Нашёл в чём проблема: Tbitmap в потоке отваливался... вдруг посреди цикла канва не отвечала на чтение/запись пикселей. Вот тут подробнее про эту проблему было, собственно, и решение проблемы оттуда - использование Canvas.Lock/UnLock - на одноядерном проце работает отлично, на много-ядерном проверить негде, у кого есть возможность - потестируйте.

Переделал алгоритм генерации меркаторовских тайлов. Алгоритм состоит из 2-х частей:
- заполнение болванки оригинальными строками из исходных GE тайлов;
- дорисовка изображения на болванке (заполнение пустых строк сгенерированными пикселями).

После первой части алгоритма имеем, например, такой битмап:
X_281623_Y_171947.JPG

Затем идёт вторая часть алгоритма - генерация недостающих строк, после чего, получаем тайл:
y171946.jpg

А вот тайл гугл мапс (для сравнения):
GM_y171946.jpg

Вот этот алгоритм:
Код: Выделить всё
procedure FillBitmap(var FillingLines: array of byte; var FillCount:byte; var bitmap:TBitmap);
var
i,j,z,k,n,_R,_G,_B : byte;
StepCount:smallint;
clr1,clr2:array [0..255] of TColor;
R,G,B,r1,g1,b1,r2,g2,b2:array [0..255] of smallint;
begin
   n:=FillCount;
   for j := 0 to FillCount-1 do
   begin
      z:=1;
      for k:=FillingLines[j]+1 to FillingLines[j+1]-1 do
      begin
         if FillingLines[j]<=254 then
         begin
             StepCount:=abs(FillingLines[j+1]-FillingLines[j]);

             for i := 0 to 255 do
             begin
               Clr1[i]:=bitmap.Canvas.Pixels[i,FillingLines[j]];
               Clr2[i]:=bitmap.Canvas.Pixels[i,FillingLines[j+1]];

               R1[i]:=GetRvalue(Clr1[i]);
               G1[i]:=GetGvalue(Clr1[i]);
               B1[i]:=GetBvalue(Clr1[i]);

               R2[i]:=GetRvalue(Clr2[i]);
               G2[i]:=GetGvalue(Clr2[i]);
               B2[i]:=GetBvalue(Clr2[i]);

               R[i]:=(R2[i]-R1[i]) div (StepCount);
               G[i]:=(G2[i]-G1[i]) div (StepCount);
               B[i]:=(B2[i]-B1[i]) div (StepCount);
             end;

             for i := 1 to 254 do
             begin
              _R:=((R1[i-1]+R[i-1]*z)+(R1[i]+R[i]*z)+(R1[i+1]+R[i+1]*z)) div 3;
              _G:=((G1[i-1]+G[i-1]*z)+(G1[i]+G[i]*z)+(G1[i+1]+G[i+1]*z)) div 3;
              _B:=((B1[i-1]+B[i-1]*z)+(B1[i]+B[i]*z)+(B1[i+1]+B[i+1]*z)) div 3;

              bitmap.Canvas.Pixels[i,(FillingLines[j]+z)]:=RGB(_r,_g,_b); // записали сгенерированный пиксель
             end;

              _R:=((R1[0]+R[0]*z)+(R1[0+1]+R[0+1]*z)) div 2;
              _G:=((G1[0]+G[0]*z)+(G1[0+1]+G[0+1]*z)) div 2;
              _B:=((B1[0]+B[0]*z)+(B1[0+1]+B[0+1]*z)) div 2;

              bitmap.Canvas.Pixels[0,(FillingLines[j]+z)]:=RGB(_r,_g,_b); // записали сгенерированный (нулевой) пиксель

              _R:=((R1[255-1]+R[255-1]*z)+(R1[255]+R[255]*z)) div 2;
              _G:=((G1[255-1]+G[255-1]*z)+(G1[255]+G[255]*z)) div 2;
              _B:=((B1[255-1]+B[255-1]*z)+(B1[255]+B[255]*z)) div 2;

              bitmap.Canvas.Pixels[255,(FillingLines[j]+z)]:=RGB(_r,_g,_b); // записали сгенерированный (последний) пиксель

             inc(z);
             inc(n);
         end;
      end;

   end;

   while n<>0 do
   begin
     Bitmap.Canvas.CopyRect( rect(0,n,256,n+1), Bitmap.Canvas, rect(0,n-1,256,n) );
     inc(n);
   end;

end;

передаваемые параметры:
FillingLines: array [0..255] of byte - номера строк, содержащих изображение;
FillCount:byte - число сторк содержащих изображение;
bitmap:TBitmap - изображение, после первого этапа.
В этом алгоритме рассчитывается среднее значение цвета пикселя, по значениям соседних (как по горизонтали, так и по вертикали).

К чему я всё это? К тому, что хотелось бы это дело оптимизировать, как по скорости работы, так и по качеству изображения (опять же, не в ущерб скорости). В этой версии GC (ссылка вверху), он может сохранять BMP после первого этапа (те, что полосатые), это чтоб была возможность потренироваться на разных тайлах. Чтобы включить сохранение этих BMP нужно в config.ini написать SaveBMP=1 (секция main). Сохранение будет производится в папку с программой.
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 525 раз.

Re: GeoCacher

Сообщение feya » 21 май 2009, 23:17

По скорости оптимизировал:
Код: Выделить всё
procedure FillBitmap(var FillingLines: array of byte; var FillCount:byte; var bitmap:TBitmap);
var i,j,z,k,n:byte;
    StepCount:smallint;
    Pclr0,Pclr1,Pclr2:PRGBTriple;
    BGR:TRGBTriple;
    R,G,B,r1,g1,b1,r2,g2,b2:array [0..255] of smallint;
begin
   n:=FillCount;
   for j := 0 to FillCount-1 do
    begin
     z:=1;
     if FillingLines[j]<=254 then
      begin
       Pclr0:=bitmap.ScanLine[FillingLines[j]+z];
       for k:=FillingLines[j]+1 to FillingLines[j+1]-1 do
        begin
         StepCount:=abs(FillingLines[j+1]-FillingLines[j]);
         Pclr1:=bitmap.ScanLine[FillingLines[j]];
         Pclr2:=bitmap.ScanLine[FillingLines[j+1]];
         for i := 0 to 255 do
          begin
           R1[i]:=Pclr1.rgbtRed;
           G1[i]:=Pclr1.rgbtGreen;
           B1[i]:=Pclr1.rgbtBlue;
           R2[i]:=Pclr2.rgbtRed;
           G2[i]:=Pclr2.rgbtGreen;
           B2[i]:=Pclr2.rgbtBlue;
           R[i]:=(R2[i]-R1[i]) div StepCount;
           G[i]:=(G2[i]-G1[i]) div StepCount;
           B[i]:=(B2[i]-B1[i]) div StepCount;
           inc(Pclr1);
           inc(Pclr2);
          end;
         Pclr1:=bitmap.ScanLine[FillingLines[j]+z];
         inc(Pclr1);
         for i := 1 to 254 do
          begin
           BGR.rgbtRed:=(R1[i-1]+R1[i]+R1[i+1]+(R[i]+R[i-1]+R[i+1])*z) div 3;
           BGR.rgbtGreen:=(G1[i-1]+G1[i]+G1[i+1]+(G[i]+G[i-1]+G[i+1])*z) div 3;
           BGR.rgbtBlue:=(B1[i-1]+B1[i]+B1[i+1]+(B[i]+B[i-1]+B[i+1])*z) div 3;
           CopyMemory(Pclr1,@BGR,SizeOf(TRGBTriple));
           inc(Pclr1);
          end;
         BGR.rgbtRed:=(R1[0]+R1[1]+(R[0]+R[1])*z) shr 1;
         BGR.rgbtGreen:=(G1[0]+G1[1]+(G[0]+G[1])*z) shr 1;
         BGR.rgbtBlue:=(B1[0]+B1[1]+(B[0]+B[1])*z) shr 1;
         CopyMemory(Pclr0,@BGR,SizeOf(TRGBTriple));
         inc(Pclr0,255);
         BGR.rgbtRed:=(R1[254]+R1[255]+(R[254]+R[255])*z) shr 1;
         BGR.rgbtGreen:=(G1[254]+G1[255]+(G[254]+G[255])*z) shr 1;
         BGR.rgbtBlue:=(B1[254]+B1[255]+(B[254]+B[255])*z) shr 1;
         CopyMemory(Pclr0,@BGR,SizeOf(TRGBTriple));
         inc(Pclr0);
         inc(z);
         inc(n);
        end;
      end;
    end;
   while n<>0 do
   begin
     Bitmap.Canvas.CopyRect( rect(0,n,256,n+1), Bitmap.Canvas, rect(0,n-1,256,n) );
     inc(n);
   end;
end;

До было ~140мс, сейчас ~0-15мс.
http://sasgis.org | SAS.Планета | SASPlanet
Аватара пользователя
feya
Гуру
 
Сообщения: 2034
Зарегистрирован: 13 июл 2008, 10:45
Благодарил (а): 5 раз.
Поблагодарили: 32 раз.

Re: GeoCacher

Сообщение feya » 21 май 2009, 23:27

А качество думаю сильно не улучшиш. У GE также немного расплывчато выглядят тайлы.
http://sasgis.org | SAS.Планета | SASPlanet
Аватара пользователя
feya
Гуру
 
Сообщения: 2034
Зарегистрирован: 13 июл 2008, 10:45
Благодарил (а): 5 раз.
Поблагодарили: 32 раз.

Re: GeoCacher

Сообщение zed » 22 май 2009, 02:14

До было ~140мс, сейчас ~0-15мс.

Супер! Спасибо:)
P.S. Сейчас проверил алгоритм - не пошло :( Ошибок нет, но и тайл не рисуется... так полосатый и выходит. Может я не понимаю, но что-то я не вижу, где пиксели на битмап пишутся?
А качество думаю сильно не улучшиш. У GE также немного расплывчато выглядят тайлы.

Да, GE в плане качества, если говорить строго, проигрывает GM - снимки более замылены, и чем дальше от экватора, тем сильнее замыленость. А на экваторе примерно одинаковые. Но зато нет копирайтев...
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 525 раз.

Re: GeoCacher

Сообщение feya » 22 май 2009, 07:50

Странно что не работает, я вот так тестил:
Код: Выделить всё
var i:integer;
    FillingLines:array of byte;
    Btm:TBitmap;
    FillCount:byte;
begin
for i:=1 to 255 do if (i mod 4)=0 then
  begin
   SetLength(FillingLines,length(FillingLines)+1);
   FillingLines[length(FillingLines)-1]:=i;
  end;
Btm:=TBitmap.Create;
Btm.LoadFromFile('c:\y0.bmp');
FillCount:=length(FillingLines);
tic:=GetTickCount;
FillBitmap1(FillingLines, FillCount, Btm);
ShowMessage(inttostr(GetTickCount-tic));
Image2.Canvas.Draw(0,0,btm);
Btm.Free;


А пиксели вот здесь пишем:
CopyMemory(Pclr0,@BGR,SizeOf(TRGBTriple));
http://sasgis.org | SAS.Планета | SASPlanet
Аватара пользователя
feya
Гуру
 
Сообщения: 2034
Зарегистрирован: 13 июл 2008, 10:45
Благодарил (а): 5 раз.
Поблагодарили: 32 раз.

Re: GeoCacher

Сообщение azya » 22 май 2009, 09:31

Немного подправил
Код: Выделить всё
procedure FillBitmap1(var FillingLines: array of byte; var FillCount:byte; var bitmap:TBitmap);
var i,j,z,k,n:byte;
    StepCount:smallint;
    Pclr0,Pclr1,Pclr2:PRGBTriple;
    BGR:TRGBTriple;
    R,G,B,r1,g1,b1,r2,g2,b2:array [0..255] of smallint;
begin
   n:=FillCount;
   for j := 0 to FillCount-1 do
    begin
     z:=1;
     for k:=FillingLines[j]+1 to FillingLines[j+1]-1 do
      if FillingLines[j]<=254 then
       begin
        StepCount:=abs(FillingLines[j+1]-FillingLines[j]);
        Pclr1:=bitmap.ScanLine[FillingLines[j]];
        Pclr2:=bitmap.ScanLine[FillingLines[j+1]];
        for i := 0 to 255 do
         begin
          R1[i]:=Pclr1.rgbtRed;
          G1[i]:=Pclr1.rgbtGreen;
          B1[i]:=Pclr1.rgbtBlue;
          R2[i]:=Pclr2.rgbtRed;
          G2[i]:=Pclr2.rgbtGreen;
          B2[i]:=Pclr2.rgbtBlue;
          R[i]:=(R2[i]-R1[i]) div StepCount;
          G[i]:=(G2[i]-G1[i]) div StepCount;
          B[i]:=(B2[i]-B1[i]) div StepCount;
          inc(Pclr1);
          inc(Pclr2);
         end;
        Pclr0:=Pointer(integer(bitmap.ScanLine[FillingLines[j]+z])+3);
        for i := 1 to 254 do
         begin
          BGR.rgbtRed:=(R1[i-1]+R1[i]+R1[i+1]+(R[i]+R[i-1]+R[i+1])*z) div 3;
          BGR.rgbtGreen:=(G1[i-1]+G1[i]+G1[i+1]+(G[i]+G[i-1]+G[i+1])*z) div 3;
          BGR.rgbtBlue:=(B1[i-1]+B1[i]+B1[i+1]+(B[i]+B[i-1]+B[i+1])*z) div 3;
          Pclr0^:=BGR;
          inc(Pclr0);
         end;
        BGR.rgbtRed:=(R1[254]+R1[255]+(R[254]+R[255])*z) shr 1;
        BGR.rgbtGreen:=(G1[254]+G1[255]+(G[254]+G[255])*z) shr 1;
        BGR.rgbtBlue:=(B1[254]+B1[255]+(B[254]+B[255])*z) shr 1;
        Pclr0^:=BGR;
        BGR.rgbtRed:=(R1[0]+R1[1]+(R[0]+R[1])*z) shr 1;
        BGR.rgbtGreen:=(G1[0]+G1[1]+(G[0]+G[1])*z) shr 1;
        BGR.rgbtBlue:=(B1[0]+B1[1]+(B[0]+B[1])*z) shr 1;
        dec(Pclr0,255);
        Pclr0^:=BGR;
        inc(z);
        inc(n);
       end;
    end;
   while n<>0 do
   begin
     Bitmap.Canvas.CopyRect( rect(0,n,256,n+1), Bitmap.Canvas, rect(0,n-1,256,n) );
     inc(n);
   end;
end;
azya
Новичок
 
Сообщения: 26
Зарегистрирован: 24 окт 2008, 15:09
Благодарил (а): 0 раз.
Поблагодарили: 3 раз.

Re: GeoCacher

Сообщение zed » 25 май 2009, 17:41

У меня эта процедура работает в потоке, может из-за этого не хочет работать? Сейчас у меня нет доступа к компу, поэксперементировать не могу...
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 525 раз.

Re: GeoCacher

Сообщение feya » 25 май 2009, 18:05

У меня эта процедура работает в потоке, может из-за этого не хочет работать?

Да не должно.
Мож я просто не так понял задачу? Есть полосатый битмап, есть массив содержащий имеющиеся полосы мы его пропускаем через ф-ю и получаем растянутый битмап, так?
http://sasgis.org | SAS.Планета | SASPlanet
Аватара пользователя
feya
Гуру
 
Сообщения: 2034
Зарегистрирован: 13 июл 2008, 10:45
Благодарил (а): 5 раз.
Поблагодарили: 32 раз.

Re: GeoCacher

Сообщение zed » 25 май 2009, 21:23

Да, всё верно. Однако у меня, на выходе, так и остался полосатый битмап - заполнения не произошло. Через пару дней доберусь до компа, буду ловить глюка :(
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 525 раз.

След.

Вернуться в Другие программы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0