Y
Y
Yuri2018-11-14 08:47:34
Delphi
Yuri, 2018-11-14 08:47:34

How to solve the problem with rendering cartography?

Hello! I'm doing cartography. For how long I've been sitting I can not understand something.
There is Form create, Thread1, Thread 2:
Here an array of TPngobject object is created and the "no photo" image is uploaded,

procedure TForm1.FormCreate(Sender: TObject);
NoImage.LoadFromFile('Data\All\loading.png');
   for pii:=0 to 20 do
   for pj:=0 to 20 do
   BEGIN
   LoTiles[pj, pii]:=TPngobject.Create();
   LoTiles[pj, pii]:=NoImage;
   END;
end;

Here is the alignment of the image from the tiles, and the launch of the second thread
procedure TMyThread.Execute;
repeat
    tilesStartX:=deleX;
    tilesEndX:=RaidX[1];
    tilesStartY:=deleY;
    tilesEndY:=RaidY[1];
    for i:=deleY to RaidY[1] do
      begin
        for j:=deleX to RaidX[1] do //RaidX[1]
          begin
            try
            begin
            OneTileRead.Canvas.Draw(bezostX, bezostY, LoTiles[pj, pii]);
            end;
            except
             ShowMessage('Àëÿóëþ!: '+ intTostr(pj) + ':' + intTostr(pii) );
            end;
           bezostX:=bezostX+256;
            LoadRaid[a]:=0;
            LoadRaid[a]:=j;
            LoadRaid1[a]:=0;
            LoadRaid1[a]:=i;
            inc(a);
            inc(pj);
          end;
        inc(b);
        bezostX:=temp;
        bezostY:=bezostY+256;
        pj:=0;
        inc(pii);
      end;
      pii:=0;
      if oneRun=true then
      begin
           MyThread1:=TMyThread1.Create(False);
           MyThread1.Priority:=tpLowest;
      oneRun:=false;
      end;
end;
until false;

This is the second stream, it is included from the first stream.
procedure TMyThread1.Execute;
repeat
pii:=0;
for i:=tilesStartY to tilesEndY do begin
pj:=0;
  for j:= tilesStartX to tilesEndX do begin
try
  if FileExists('Data\MAPSIMAGE\' + intToStr(zoom) + '\' + IntToStr(j)  + 'x' +  IntToStr(i) + '.png')
  then
  begin
  LoTiles[pj, pii].LoadFromFile('Data\MAPSIMAGE\' + intToStr(zoom) + '\' + IntToStr(j)  + 'x' +  IntToStr(i) + '.png');
  end
  else
  begin
  LoTiles[pj, pii].canvas.Draw(0,0,NoImage);
  end;
  except
ShowMessage('Òóò åððîð!');
end;
    inc(pj);
  end;
  inc(pii);
end;
 
until false;
end;

Brief description: The LoTiles[pj, pii] variable has already been created and stores images, no photos when the form is loaded, then the first thread is turned on through the timer, the image is built through it in OneTileRead, because the second thread is not yet turned on, the image is visible, there is no photo. As the second thread is launched, in which the image update should take place, thanks to the loading of new images in LoTiles[pj, pii], an error pops up, an error that says absolutely nothing, Acess violation. My guess is that when an image is used in the first thread, the second can't upload a new file... Question: how to do it right?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
K
kalapanga, 2018-11-14
@kalapanga

To solve such problems, there is a debugger. The error occurs not anyhow where, but in a specific line. Find out where the error occurred, put a breakpoint in front of it, look at the values ​​of the variables when you come to this point. So you will understand what is causing the error.
An array violation error is even easier to catch. During development, enable the "Range checking" compiler option in the settings.

A
Alexander, 2018-11-14
@xpert13

It would not hurt you to learn a little Delphi. I skimmed through the code and saw a large amount of incorrect or erroneous code writing. For example:

LoTiles[pj, pii]:=TPngobject.Create();
LoTiles[pj, pii]:=NoImage;

In this piece, you first create a new object, write its reference to the variable LoTiles[pj, pii], and then write the reference to the NoImage object into the same variable. Firstly, this is clearly not what you want, and secondly, the reference to the previously created object is lost and you will not release it (consider a memory leak).

K
Kot-da-Vinci, 2018-11-23
@Kot-da-Vinci

Work with visual components should be only from the main (main) thread. If you really need to "touch" visual components from other threads, then you need to do this through the Synchronize method. You can read more about it in the help.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question