Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.02.2016, 19:08
dikiy_o dikiy_o вне форума
Прохожий
 
Регистрация: 14.02.2016
Сообщения: 2
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Картография

Доброго времени суток.
Суть задачи: Работа с картой. максимальный размер карты: 16160х14140 пикселей. вывод топоосновы и рисование на ней, разного типа обьектов.
Реализация: Карта разбита на квадраты 8х7, в макимальном разрешении размер квадрата 2020х2020пик. в минимальном 202х202. Для масштабирования созданы карты разной степени детализации размерами 202, 404, 606, 808, 1010, 1212, 1414, 1616, 1818, 2020 пикселей, помещены в соотвествующие папки на диске. По скольку грузить целую картинку очень ресурсозатратно реализован вывод только видимой области. Прокрутка реализована посредством scrollbar получаем позицию ползунка и вычисляем диапазон видимой области.

Код:
procedure Tform1.ris(Sender: TObject; x1,y1,x2,y2,xs,ys:integer); //получаем картинку по ширине имейджа
var polosa,ykt,xp,yp,sdx,sdy,y,x,kvadrat,xr1,yr1,xr2,yr2:integer;
rx1,rx2,ry1,ry2,nx1,nx2,ny1,ny2:integer;
JpegIm: TJpegImage;
bm_razova,bm_razova1:tbitmap;
begin
  polosa:=round(2020*combobox1.Tag/100);  //в комбобоксе текущий масштаб и соответственно имя папки где лежат карты (10,20. //..90,100)

  bm_razova := TBitmap.Create;
  bm_razova.PixelFormat:=pf24Bit;
  bm_razova.Width:=image1.Width;
  bm_razova.Height:=image1.Height;


  ykt:=0;
  xp:=x1;
  yp:=y1;
  sdx:=0;
  sdy:=0;

  for y:=((y1 div polosa)+1) to ((y2 div polosa)+1) do
  begin
    xp:=x1;
    sdx:=0;
    for x:=((x1 div polosa)+1) to ((x2 div polosa)+1) do
    begin
      kvadrat:=N_kvadrat(x,y);//получаем номер квадрата который попадает в видимый диапазон
      xr1:=xp;
      yr1:=yp;
      if x2<mass[kvadrat].xk2 then xr2:=x2
      else xr2:=mass[kvadrat].xk2;
      if y2<mass[kvadrat].yk2 then yr2:=y2
      else yr2:=mass[kvadrat].yk2;
      xp:=xr2;
      ykt:=yr2;
      karta.Close;
      karta.SQL.Clear;
      karta.SQL.Add('select * from karta where x=:x and y=:y');
      karta.ParamByName('x').Asinteger:=x;
      karta.ParamByName('y').Asinteger:=y;
      karta.Open;
      bm_razova1 := TBitMap.Create;
      JpegIm := TJpegImage.Create;
      JpegIm.LoadFromFile(ini.readstring('base','karta','no')+'/'+inttostr(combobox1.tag)+'/'+karta.Fields[3].asstring+'.jpg');
      bm_razova1.Assign(JpegIm);
      JpegIm.Destroy;
      if xr1>=polosa then xr1:=xr1-mass[kvadrat].xk1;
      if yr1>=polosa then yr1:=yr1-mass[kvadrat].yk1;
      if xr2>=polosa then xr2:=xr2-mass[kvadrat].xk1;
      if yr2>=polosa then yr2:=yr2-mass[kvadrat].yk1;
      // область вырезания
      rx1:=xr1;
      ry1:=yr1;
      rx2:=xr2-xr1;
      ry2:=yr2-yr1;

      // область в которую помещаем
      nx1:=sdx;
      ny1:=sdy;
      nx2:=xr2-xr1;
      ny2:=yr2-yr1;

      bm_razova.Canvas.CopyRect(bounds(nx1,ny1,nx2,ny2),bm_razova1.Canvas,bounds(rx1,ry1,rx2,ry2));
      bm_razova1.Free;
      sdx:=sdx+(xr2-xr1);
    end;
    yp:=ykt;
    sdy:=sdy+(yr2-yr1);
  end;
  image1.Picture.Assign(bm_razova);
  bm_razova.Free;
end;
Админ: Пользуемся тегами для оформления кода!

Все работает, но не удовлетворяет скорость отображения и прокрутки карты.

Вопрос: В каком направлении копать для оптимизации, или может стоит выбрать совсем другой подход?

Последний раз редактировалось Admin, 14.02.2016 в 19:13.
Ответить с цитированием
  #2  
Старый 15.02.2016, 12:37
Аватар для cotseec
cotseec cotseec вне форума
Активный
 
Регистрация: 16.07.2008
Сообщения: 353
Версия Delphi: D7,TDE06,RAD09
Репутация: 1443
По умолчанию

можно хранить в память сформированный участок карты, по размерам превосходящий видимый участок, например в два раза (по ширине и высоте), при перемещении вырезать из этого участка выводимый кусок и его отображать, а в памяти формировать новый участок, содержащий выводимый участок и также его превосходящий по размерам, в этом случае отображение фактически занимает время копирования из памяти на канву + формирование участка в памяти, что значительно меньше, чем напрямую отображать
__________________
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard
Ответить с цитированием
  #3  
Старый 15.02.2016, 12:44
dikiy_o dikiy_o вне форума
Прохожий
 
Регистрация: 14.02.2016
Сообщения: 2
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Если в видимую область попало схождение 4 квадратов 2020х2020 пикс. то прийдется в памяти держать 4 полновесные картинки, в bmp формате которые занимают порядка 50 mb каждая - для слабых компютеров - оч ресурсозатратно
Ответить с цитированием
  #4  
Старый 15.02.2016, 17:13
Аватар для cotseec
cotseec cotseec вне форума
Активный
 
Регистрация: 16.07.2008
Сообщения: 353
Версия Delphi: D7,TDE06,RAD09
Репутация: 1443
По умолчанию

а если при текущем положении дел в выводимую область попало это же самое вхождение?
я писал о том, чтобы то, что делается сейчас строить предварительно в памяти и затем выводить
__________________
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:09.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter