LazMapViewer: Fix incorrect painting of stretched and missing tiles when Cyclic is true.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9680 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
7cf32c3448
commit
870c3252cb
components/lazmapviewer/source
@ -498,7 +498,7 @@ end;
|
|||||||
the rectangle coordinates to get an upscaled preview of the originally
|
the rectangle coordinates to get an upscaled preview of the originally
|
||||||
requested tile. The function returns true in this case.
|
requested tile. The function returns true in this case.
|
||||||
If the requested tile already is in the cache, or no containing tile is found
|
If the requested tile already is in the cache, or no containing tile is found
|
||||||
the function returns false indicating that not preview image must be
|
the function returns false indicating that no preview image must be
|
||||||
generated. }
|
generated. }
|
||||||
function TPictureCache.GetPreviewFromCache(const MapProvider: TMapProvider;
|
function TPictureCache.GetPreviewFromCache(const MapProvider: TMapProvider;
|
||||||
var TileId: TTileId; out ARect: TRect): boolean;
|
var TileId: TTileId; out ARect: TRect): boolean;
|
||||||
|
@ -122,7 +122,7 @@ type
|
|||||||
procedure CalculateWin(var AWin: TMapWindow);
|
procedure CalculateWin(var AWin: TMapWindow);
|
||||||
function DegreesToPixelsEPSG3395(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
function DegreesToPixelsEPSG3395(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
||||||
function DegreesToPixelsEPSG3857(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
function DegreesToPixelsEPSG3857(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
||||||
procedure Redraw(const aWin: TMapWindow; const paintOnly: Boolean = False);
|
procedure Redraw(const aWin: TMapWindow; const PaintOnly: Boolean = False);
|
||||||
function CalculateVisibleTiles(const aWin: TMapWindow; out Area: TArea): Boolean;
|
function CalculateVisibleTiles(const aWin: TMapWindow; out Area: TArea): Boolean;
|
||||||
function IsCurrentWin(const aWin: TMapWindow) : boolean;
|
function IsCurrentWin(const aWin: TMapWindow) : boolean;
|
||||||
protected
|
protected
|
||||||
@ -132,7 +132,7 @@ type
|
|||||||
procedure evDownload(Data: TObject; Job: TJob);
|
procedure evDownload(Data: TObject; Job: TJob);
|
||||||
procedure TileDownloaded(Data: PtrInt);
|
procedure TileDownloaded(Data: PtrInt);
|
||||||
procedure EraseBackground(const R: TRect);
|
procedure EraseBackground(const R: TRect);
|
||||||
procedure DrawTileFromCache(constref ATile: TTileId; constref AWin: TMapWindow);
|
procedure DrawTileFromCache(constref ATile: TTileId; constref AWin: TMapWindow; out FoundInCache: Boolean);
|
||||||
procedure DrawStretchedTile(const TileId: TTileID; X, Y: Integer; TileImg: TPictureCacheItem; const R: TRect);
|
procedure DrawStretchedTile(const TileId: TTileID; X, Y: Integer; TileImg: TPictureCacheItem; const R: TRect);
|
||||||
Procedure DrawTile(const TileId: TTileId; X,Y: integer; TileImg: TPictureCacheItem);
|
Procedure DrawTile(const TileId: TTileId; X,Y: integer; TileImg: TPictureCacheItem);
|
||||||
Procedure DoDrag(Sender: TDragObj);
|
Procedure DoDrag(Sender: TDragObj);
|
||||||
@ -1089,12 +1089,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMapViewerEngine.Redraw(const aWin: TMapWindow;
|
procedure TMapViewerEngine.Redraw(const aWin: TMapWindow;
|
||||||
const paintOnly: Boolean);
|
const PaintOnly: Boolean);
|
||||||
var
|
var
|
||||||
TilesVis: TArea;
|
TilesVis: TArea;
|
||||||
x, y, px, py: Integer;
|
x, y, px, py: Integer;
|
||||||
iTile, numTiles, XShift: Integer;
|
iTile, numTiles, XShift: Integer;
|
||||||
Tiles: TTileIdArray = nil;
|
Tiles: TTileIdArray = nil;
|
||||||
|
foundInCache: Boolean;
|
||||||
tile: TTileID;
|
tile: TTileID;
|
||||||
previewDrawn: Boolean;
|
previewDrawn: Boolean;
|
||||||
previewImg: TPictureCacheItem;
|
previewImg: TPictureCacheItem;
|
||||||
@ -1105,8 +1106,8 @@ var
|
|||||||
lTile: TEnvTile;
|
lTile: TEnvTile;
|
||||||
lJob: TEventJob;
|
lJob: TEventJob;
|
||||||
begin
|
begin
|
||||||
lTile:=TEnvTile.Create(Tiles[iTile], aWin);
|
lTile := TEnvTile.Create(Tiles[iTile], aWin);
|
||||||
lJob := TEventJob.Create(@evDownload, lTile, False, // owns data
|
lJob := TEventJob.Create(@evDownload, lTile, False, // owns data
|
||||||
GetTileName(Tiles[iTile]));
|
GetTileName(Tiles[iTile]));
|
||||||
if not Queue.AddUniqueJob(lJob, Self) then
|
if not Queue.AddUniqueJob(lJob, Self) then
|
||||||
begin
|
begin
|
||||||
@ -1159,11 +1160,12 @@ begin
|
|||||||
|
|
||||||
if not CalculateVisibleTiles(AWin, TilesVis) then
|
if not CalculateVisibleTiles(AWin, TilesVis) then
|
||||||
EraseAround;
|
EraseAround;
|
||||||
|
|
||||||
SetLength(Tiles, (TilesVis.Bottom - TilesVis.Top + 1) * (TilesVis.Right - TilesVis.Left + 1));
|
SetLength(Tiles, (TilesVis.Bottom - TilesVis.Top + 1) * (TilesVis.Right - TilesVis.Left + 1));
|
||||||
iTile := Low(Tiles);
|
iTile := Low(Tiles);
|
||||||
numTiles := 1 shl AWin.Zoom;
|
numTiles := 1 shl AWin.Zoom;
|
||||||
XShift := IfThen(aWin.X > 0, numTiles - aWin.X div TileSize.CX - 1, 0);
|
XShift := IfThen(aWin.X > 0, numTiles - aWin.X div TileSize.CX - 1, 0);
|
||||||
for y := TilesVis.Top to TilesVis.Bottom do
|
for Y := TilesVis.Top to TilesVis.Bottom do
|
||||||
for X := TilesVis.Left to TilesVis.Right do
|
for X := TilesVis.Left to TilesVis.Right do
|
||||||
begin
|
begin
|
||||||
if FCyclic then
|
if FCyclic then
|
||||||
@ -1177,6 +1179,14 @@ begin
|
|||||||
Tiles[iTile].Y := Y;
|
Tiles[iTile].Y := Y;
|
||||||
Tiles[iTile].Z := AWin.Zoom;
|
Tiles[iTile].Z := AWin.Zoom;
|
||||||
|
|
||||||
|
DrawTileFromCache(Tiles[iTile], AWin, foundInCache);
|
||||||
|
if (not foundInCache) and (not PaintOnly) and IsValidTile(AWin, Tiles[iTile]) then
|
||||||
|
begin
|
||||||
|
AddJob;
|
||||||
|
inc(iTile);
|
||||||
|
end;
|
||||||
|
|
||||||
|
(*
|
||||||
if Cache.InCache(AWin.MapProvider, Tiles[iTile]) then
|
if Cache.InCache(AWin.MapProvider, Tiles[iTile]) then
|
||||||
DrawTileFromCache(Tiles[iTile], AWin)
|
DrawTileFromCache(Tiles[iTile], AWin)
|
||||||
else
|
else
|
||||||
@ -1202,12 +1212,15 @@ begin
|
|||||||
if not previewDrawn then
|
if not previewDrawn then
|
||||||
DrawTile(Tiles[iTile], px, py, nil); // Draw blank tile if preview cannot be generated
|
DrawTile(Tiles[iTile], px, py, nil); // Draw blank tile if preview cannot be generated
|
||||||
|
|
||||||
|
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!
|
||||||
if not paintOnly and IsValidTile(AWin, Tiles[iTile]) then
|
if not paintOnly and IsValidTile(AWin, Tiles[iTile]) then
|
||||||
begin
|
begin
|
||||||
AddJob;
|
AddJob;
|
||||||
inc(iTile);
|
inc(iTile);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
end;
|
end;
|
||||||
SetLength(Tiles, iTile);
|
SetLength(Tiles, iTile);
|
||||||
end;
|
end;
|
||||||
@ -1416,47 +1429,83 @@ end;
|
|||||||
procedure TMapViewerEngine.EraseBackground(const R: TRect);
|
procedure TMapViewerEngine.EraseBackground(const R: TRect);
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnEraseBackground) then
|
if Assigned(FOnEraseBackground) then
|
||||||
FOnEraseBackground(R);
|
FOnEraseBackground(R);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMapViewerEngine.DrawTileFromCache(constref ATile: TTileId; constref
|
procedure TMapViewerEngine.DrawTileFromCache(constref ATile: TTileID;
|
||||||
AWin: TMapWindow);
|
constref AWin: TMapWindow; out FoundInCache: Boolean);
|
||||||
var
|
var
|
||||||
img: TPictureCacheItem;
|
img: TPictureCacheItem;
|
||||||
X, Y: integer;
|
X, Y: Integer;
|
||||||
worldWidth : Integer;
|
worldWidth: Integer;
|
||||||
numTiles : Integer;
|
numTiles: Integer;
|
||||||
baseX : Integer;
|
baseX: Integer;
|
||||||
begin
|
tile: TTileID;
|
||||||
if IsCurrentWin(AWin)then
|
R: TRect;
|
||||||
|
normalDraw: Boolean = true;
|
||||||
|
|
||||||
|
procedure DrawTheTile(ATileID: TTileID; X, Y: Integer; AImg: TPictureCacheItem);
|
||||||
begin
|
begin
|
||||||
Cache.GetFromCache(AWin.MapProvider, ATile, img);
|
if normalDraw then
|
||||||
Y := AWin.Y + ATile.Y * TileSize.CY; // begin of Y
|
DrawTile(ATileID, X, Y, AImg) // Covers the "missing tile" case when AImg = nil
|
||||||
if Cyclic then
|
else
|
||||||
begin
|
DrawStretchedTile(ATileID, X, Y, AImg, R);
|
||||||
baseX := AWin.X + ATile.X * TileSize.CX; // begin of X
|
|
||||||
numTiles := 1 shl AWin.Zoom;
|
|
||||||
worldWidth := numTiles * TileSize.CX;
|
|
||||||
// From the center to the left (western) hemisphere
|
|
||||||
X := baseX;
|
|
||||||
while (X + TileSize.CX >= 0) do
|
|
||||||
begin
|
|
||||||
DrawTile(ATile, X, Y, img);
|
|
||||||
X := X - worldWidth;
|
|
||||||
end;
|
|
||||||
// From the center to the right (eastern) hemisphere
|
|
||||||
X := baseX + worldWidth;
|
|
||||||
while ((X - TileSize.CX) <= AWin.Width) do
|
|
||||||
begin
|
|
||||||
DrawTile(ATile, X, Y, img);
|
|
||||||
X := X + worldWidth;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
X := AWin.X + ATile.X * TileSize.CX; // begin of X
|
|
||||||
DrawTile(ATile, X, Y, img);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if not IsCurrentWin(AWin) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// When no cache image can be found (img = nil) we will have to draw a "missing tile"
|
||||||
|
img := nil;
|
||||||
|
FoundInCache := false;
|
||||||
|
|
||||||
|
if Cache.InCache(AWin.MapProvider, ATile) then
|
||||||
|
begin
|
||||||
|
// Image is found in cache: Load it into "img". It can be drawn directly.
|
||||||
|
Cache.GetFromCache(AWin.MapProvider, ATile, img);
|
||||||
|
FoundInCache := true;
|
||||||
|
end else
|
||||||
|
if FDrawPreviewTiles then
|
||||||
|
begin
|
||||||
|
// Image is not found in cache, but there is another one which can be
|
||||||
|
// scaled to fit. Find the cache parameters for this image.
|
||||||
|
tile := ATile;
|
||||||
|
if Cache.GetPreviewFromCache(AWin.MapProvider, tile, R) then
|
||||||
|
begin
|
||||||
|
// Load cache image into "img". It must be stretch-drawn.
|
||||||
|
Cache.GetFromCache(AWin.MapProvider, tile, img);
|
||||||
|
normalDraw := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
X := AWin.X + ATile.X * TileSize.CX; // begin of X
|
||||||
|
Y := AWin.Y + ATile.Y * TileSize.CY; // begin of Y
|
||||||
|
|
||||||
|
if Cyclic then
|
||||||
|
begin
|
||||||
|
baseX := X;
|
||||||
|
numTiles := 1 shl AWin.Zoom;
|
||||||
|
worldWidth := numTiles * TileSize.CX;
|
||||||
|
|
||||||
|
// Center, plus western hemisphere (left)
|
||||||
|
X := baseX;
|
||||||
|
while (X + TileSize.CX >= 0) do
|
||||||
|
begin
|
||||||
|
DrawTheTile(ATile, X, Y, img);
|
||||||
|
X := X - worldWidth;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// From the center to the right (eastern) hemisphere
|
||||||
|
X := baseX + worldWidth;
|
||||||
|
while (X <= AWin.Width) do
|
||||||
|
begin
|
||||||
|
DrawTheTile(ATile, X, Y, img);
|
||||||
|
X := X + worldWidth;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
DrawTheTile(ATile, X, Y, img);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMapViewerEngine.ValidProvider(const AProvider: String): Boolean;
|
function TMapViewerEngine.ValidProvider(const AProvider: String): Boolean;
|
||||||
|
@ -3098,7 +3098,7 @@ procedure TMapView.Paint;
|
|||||||
const
|
const
|
||||||
FREE_DRAG = 0; //(TILE_SIZE * TILE_SIZE) div 4;
|
FREE_DRAG = 0; //(TILE_SIZE * TILE_SIZE) div 4;
|
||||||
|
|
||||||
procedure DrawCenter;
|
procedure DrawCenter; deprecated 'Use plugin';
|
||||||
var
|
var
|
||||||
C: TPoint;
|
C: TPoint;
|
||||||
begin
|
begin
|
||||||
@ -3136,7 +3136,7 @@ const
|
|||||||
FAfterDrawObjectsEvent(Self);
|
FAfterDrawObjectsEvent(Self);
|
||||||
|
|
||||||
DrawingEngine.PaintToCanvas(Canvas);
|
DrawingEngine.PaintToCanvas(Canvas);
|
||||||
if DebugTiles then
|
if DebugTiles then // DebugTiles is deprecated
|
||||||
DrawCenter;
|
DrawCenter;
|
||||||
|
|
||||||
GetPluginManager.AfterPaint(Self);
|
GetPluginManager.AfterPaint(Self);
|
||||||
@ -3154,7 +3154,7 @@ const
|
|||||||
begin
|
begin
|
||||||
DrawingEngine.PaintToCanvas(Canvas);
|
DrawingEngine.PaintToCanvas(Canvas);
|
||||||
DrawingEngine.PaintToCanvas(Canvas, O);
|
DrawingEngine.PaintToCanvas(Canvas, O);
|
||||||
if DebugTiles then
|
if DebugTiles then // DebugTiles is deprecated
|
||||||
DrawCenter;
|
DrawCenter;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -3681,7 +3681,6 @@ begin
|
|||||||
DrawingEngine.FillPixels(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, InactiveColor);
|
DrawingEngine.FillPixels(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, InactiveColor);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMapView.DoDrawTileInfo(const TileID: TTileID; X, Y: Integer);
|
procedure TMapView.DoDrawTileInfo(const TileID: TTileID; X, Y: Integer);
|
||||||
begin
|
begin
|
||||||
DrawingEngine.PenColor := clGray;
|
DrawingEngine.PenColor := clGray;
|
||||||
|
Loading…
Reference in New Issue
Block a user