LazMapViewer: Fix drawing of missing tiles. Issue #39111.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9682 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
a49a182aa2
commit
2eb97a3732
@ -234,7 +234,8 @@ end;
|
||||
|
||||
procedure TMvBGRADrawingEngine.FillRect(X1, Y1, X2, Y2: Integer);
|
||||
begin
|
||||
FBuffer.CanvasBGRA.FillRect(X1, Y1, X2, Y2);
|
||||
// FBuffer.CanvasBGRA.FillRect(X1, Y1, X2, Y2);
|
||||
FBuffer.FillRect(X1, Y1, X2, Y2, BrushColor);
|
||||
end;
|
||||
|
||||
function TMvBGRADrawingEngine.GetPenStyle: TPenStyle;
|
||||
|
@ -51,7 +51,7 @@ type
|
||||
procedure SetPosition(AValue: TTileInfoPosition);
|
||||
protected
|
||||
procedure AfterDrawTile(AMapView: TMapView; ADrawingEngine: TMvCustomDrawingEngine;
|
||||
ATileID: TTileID; ARect: TRect; var Handled: Boolean); override;
|
||||
ATileID: TTileID; ARect: TRect; var {%H-}Handled: Boolean); override;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
published
|
||||
|
@ -123,7 +123,7 @@ type
|
||||
function DegreesToPixelsEPSG3395(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
||||
function DegreesToPixelsEPSG3857(const AWin: TMapWindow; APt: TRealPoint): TPoint;
|
||||
procedure Redraw(const aWin: TMapWindow; const PaintOnly: Boolean = False);
|
||||
function CalculateVisibleTiles(const aWin: TMapWindow; out Area: TArea): Boolean;
|
||||
function CalculateVisibleTiles(const aWin: TMapWindow; out AFullyCovered: Boolean): TArea;
|
||||
function IsCurrentWin(const aWin: TMapWindow) : boolean;
|
||||
protected
|
||||
procedure AdjustZoomCenter(var AWin: TMapWindow);
|
||||
@ -355,36 +355,58 @@ begin
|
||||
CalculateWin(AWin);
|
||||
end;
|
||||
|
||||
// Returns whether the view area is not covered fully with a tiles
|
||||
function TMapViewerEngine.CalculateVisibleTiles(const aWin: TMapWindow; out
|
||||
Area: TArea): Boolean;
|
||||
{ Calculates the range of tile ids needed to cover the window with a map.
|
||||
Returns AFullyCovered=false when not the entire windows is covered by the
|
||||
map tiles. }
|
||||
function TMapViewerEngine.CalculateVisibleTiles(const AWin: TMapWindow;
|
||||
out AFullyCovered: Boolean): TArea;
|
||||
var
|
||||
MaxX, MaxY, startX, startY: int64;
|
||||
WorldMax: Int64;
|
||||
maxX, maxY, startX, startY: Int64;
|
||||
worldMax: Int64;
|
||||
begin
|
||||
Area := Default(TArea);
|
||||
Result := (aWin.X <= 0) and (aWin.Y <= 0);
|
||||
WorldMax := Int64(1) shl AWin.Zoom - 1;
|
||||
MaxX := Int64(aWin.Width) div TileSize.CX + 1;
|
||||
MaxY := Int64(aWin.Height) div TileSize.CY + 1;
|
||||
if (MaxX > WorldMax) or (MaxY > WorldMax) then
|
||||
Result := Default(TArea);
|
||||
|
||||
AFullyCovered := true;
|
||||
if (AWin.X > 0) or (AWin.Y > 0) then
|
||||
AFullyCovered := false;
|
||||
|
||||
worldMax := Int64(1) shl AWin.Zoom - 1;
|
||||
maxX := Int64(AWin.Width) div TileSize.CX + 1;
|
||||
maxY := Int64(AWin.Height) div TileSize.CY + 1;
|
||||
if maxY > worldMax then
|
||||
begin
|
||||
Result := False;
|
||||
MaxX := Min(WorldMax, MaxX);
|
||||
MaxY := Min(WorldMax, MaxY);
|
||||
maxY := worldMax;
|
||||
AFullyCovered := false;
|
||||
end;
|
||||
startX := -aWin.X div TileSize.CX;
|
||||
startY := -aWin.Y div TileSize.CY;
|
||||
if (startX < 0) or (startY < 0) then
|
||||
if (not Cyclic) and (maxX > worldMax) then
|
||||
begin
|
||||
startX := Max(0, startX);
|
||||
startY := Max(0, startY);
|
||||
Result := False;
|
||||
maxX := worldMax;
|
||||
AFullyCovered := false;
|
||||
end;
|
||||
|
||||
startX := Max(0, -AWin.X div TileSize.CX);
|
||||
startY := Max(0, -AWin.Y div TileSize.CY);
|
||||
|
||||
Result.Left := startX;
|
||||
if Cyclic then
|
||||
Result.Right := Result.Left + maxX
|
||||
else
|
||||
if startX + maxX < worldMax then
|
||||
Result.Right := startX + maxX
|
||||
else
|
||||
begin
|
||||
Result.Right := worldMax;
|
||||
AFullyCovered := false;
|
||||
end;
|
||||
|
||||
Result.Top := startY;
|
||||
if startY + maxY < worldMax then
|
||||
Result.Bottom := startY + maxY
|
||||
else
|
||||
begin
|
||||
Result.Bottom := worldMax;
|
||||
AFullyCovered := false;
|
||||
end;
|
||||
Area.Left := startX;
|
||||
Area.Right := startX + MaxX;
|
||||
Area.Top := startY;
|
||||
Area.Bottom := startY + MaxY;
|
||||
end;
|
||||
|
||||
procedure TMapViewerEngine.CalculateWin(var AWin: TMapWindow);
|
||||
@ -1096,6 +1118,7 @@ var
|
||||
iTile, numTiles, XShift: Integer;
|
||||
Tiles: TTileIdArray = nil;
|
||||
foundInCache: Boolean;
|
||||
fullyCovered: Boolean;
|
||||
|
||||
procedure AddJob;
|
||||
var
|
||||
@ -1112,6 +1135,34 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure EraseAround;
|
||||
var
|
||||
x, y: Integer;
|
||||
begin
|
||||
// Erase part above the map
|
||||
y := AWin.Y;
|
||||
if y > 0 then
|
||||
EraseBackground(Rect(0, 0, AWin.Width, y));
|
||||
|
||||
// Erase part below the map
|
||||
y := AWin.Y + (numTiles - 1 - TilesVis.Top) * TileSize.CX;
|
||||
if y < AWin.Height then
|
||||
EraseBackground(Rect(0, y, AWin.Width, AWin.Height));
|
||||
|
||||
if not Cyclic then
|
||||
begin
|
||||
// Erase part at the left of the map
|
||||
x := AWin.X;
|
||||
if x > 0 then
|
||||
EraseBackground(Rect(0, 0, x, AWin.Height));
|
||||
|
||||
// Erase part at the right of the map
|
||||
x := AWin.X + (numTiles - 1 - TilesVis.Left) * TileSize.CX;
|
||||
if x < AWin.Width then
|
||||
EraseBackground(Rect(x, 0, AWin.Width, AWin.Height));
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
procedure EraseAround;
|
||||
var
|
||||
T, L, B, R: Integer;
|
||||
@ -1144,6 +1195,7 @@ var
|
||||
AWin.Height)
|
||||
);
|
||||
end;
|
||||
*)
|
||||
|
||||
begin
|
||||
if not(Active) then
|
||||
@ -1154,12 +1206,15 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not CalculateVisibleTiles(AWin, TilesVis) then
|
||||
numTiles := 1 shl AWin.Zoom;
|
||||
TilesVis := CalculateVisibleTiles(AWin, fullyCovered);
|
||||
if not fullyCovered then
|
||||
EraseAround;
|
||||
// if not CalculateVisibleTiles(AWin, TilesVis) then
|
||||
// EraseAround;
|
||||
|
||||
SetLength(Tiles, (TilesVis.Bottom - TilesVis.Top + 1) * (TilesVis.Right - TilesVis.Left + 1));
|
||||
iTile := Low(Tiles);
|
||||
numTiles := 1 shl AWin.Zoom;
|
||||
XShift := IfThen(aWin.X > 0, numTiles - aWin.X div TileSize.CX - 1, 0);
|
||||
for Y := TilesVis.Top to TilesVis.Bottom do
|
||||
for X := TilesVis.Left to TilesVis.Right do
|
||||
|
@ -3116,11 +3116,10 @@ const
|
||||
Canvas.FillRect(0, 0, ClientWidth, ClientHeight);
|
||||
end;
|
||||
|
||||
procedure FullRedraw;
|
||||
procedure ObjectsDraw;
|
||||
var
|
||||
W: Integer;
|
||||
begin
|
||||
Engine.Redraw;
|
||||
W := ClientWidth;
|
||||
if Cyclic then
|
||||
W := Min(1 shl Zoom * TileSize.CX, W);
|
||||
@ -3129,13 +3128,20 @@ const
|
||||
if Assigned(FBeforeDrawObjectsEvent) then
|
||||
FBeforeDrawObjectsEvent(Self);
|
||||
|
||||
DrawObjects(Default(TTileId), 0, 0, W - 1, ClientHeight);
|
||||
DrawObjects(Default(TTileID), 0, 0, W - 1, ClientHeight);
|
||||
|
||||
GetPluginManager.AfterDrawObjects(Self);
|
||||
if Assigned(FAfterDrawObjectsEvent) then
|
||||
FAfterDrawObjectsEvent(Self);
|
||||
end;
|
||||
|
||||
procedure FullRedraw;
|
||||
begin
|
||||
Engine.Redraw;
|
||||
ObjectsDraw;
|
||||
|
||||
DrawingEngine.PaintToCanvas(Canvas);
|
||||
|
||||
if DebugTiles then // DebugTiles is deprecated
|
||||
DrawCenter;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user