Показать сообщение отдельно
  #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;
Админ: Пользуемся тегами для оформления кода!

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

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