beim lazMapViewer finde ich das "Flat-Earth" Verhalten ungünstig.
Eigentlich möchte man doch eher einen umlaufenden Zylinder abbilden, d.h. wenn man rechts (östlich) über die 180 Grad läuft, solle es nahtlos bei -180 Grad (westlich) weitergehen.
So wie der laMapViewer implementiert ist, geht es halt einfach nicht weiter.
Zum Glück sind die nötigen Änderungen nicht groß, so dass man das recht einfach umbauen kann.
Es sind nur Änderungen in der Datei "mvengine.pas" nötig.
In der Methode TMapViewerEngine.CalculateVisibleTiles muss Result.Left eins weniger sein. Ich denke, dass ist eher ein genereller Fehler.
Code: Alles auswählen
function TMapViewerEngine.CalculateVisibleTiles(const aWin: TMapWindow): TArea;
(...)
Result.Left := startX - 1; //EDo
Code: Alles auswählen
function TMapViewerEngine.MapPixelsToDegrees(const AWin: TMapWindow;
APoint: TPoint): TRealPoint;
(...)
// Statt: mPoint.X := EnsureRange(APoint.X - AWin.X, 0, iMapWidth);
//
mPoint.X := (APoint.X - AWin.X) mod iMapWidth;
while mPoint.X < 0 do
mPoint.X := mPoint.X + iMapWidth;
while mPoint.X >= iMapWidth do
mPoint.X := mPoint.X - iMapWidth;
Code: Alles auswählen
procedure TMapViewerEngine.Redraw(const aWin: TmapWindow);
(...)
numTiles : Integer; //EDo: Loop around
(...)
numTiles := 1 shl aWin.Zoom;
for y := TilesVis.Top to TilesVis.Bottom do
for X := TilesVis.Left to TilesVis.Right do
begin
// Statt: Tiles[iTile].X := X;
Tiles[iTile].X := X mod numTiles;
if Tiles[iTile].X < 0 then
Tiles[iTile].X := Tiles[iTile].X + numTiles;
In der Methode TMapViewerEngine.TileDownloaded müssen ggf Kacheln mehrfach gezeichnet werden, bzw. der Umlauf ausgeführt werden.
Dazu gibt es drei neue Lokale Variablen und zwei Schleifen, die jeweils nach rechts und links nachsehen, ob und ggf wieviele Kacheln in das Sichtfenster passen.
Code: Alles auswählen
procedure TMapViewerEngine.TileDownloaded(Data: PtrInt);
var
(...)
worldWidth : Integer;
numTiles : Integer;
baseX : Integer;
begin
(...)
// Y bleibt, tauscht aber die Zeile mit X, die
Y := EnvTile.Win.Y + EnvTile.Tile.Y * TILE_SIZE; // begin of Y
// Statt: X := EnvTile.Win.X + EnvTile.Tile.X * TILE_SIZE; // begin of X
// und DrawTile(EnvTile.Tile, X, Y, img);
baseX := EnvTile.Win.X + EnvTile.Tile.X * TILE_SIZE; // begin of X
numTiles := 1 shl EnvTile.Win.Zoom;
worldWidth := numTiles * TILE_SIZE;
// From the center to the left (western) hemisphere
X := baseX;
while (X+TILE_SIZE >= 0) do
begin
DrawTile(EnvTile.Tile, X, Y, img);
X := X - worldWidth;
end;
// From the center to the right (eastern) hemisphere
X := baseX + worldWidth;
while ((X-TILE_SIZE) <= EnvTile.Win.Width) do
begin
DrawTile(EnvTile.Tile, X, Y, img);
X := X + worldWidth;
end;
Gruß Ekkehard
PS: Es gibt noch ein weiteres Problem, was bisher nicht so auffiel. Da der Kartenhintergrund nie aktualisiert wird, ergeben sich unangenehme Dopplungen und Artefakte, insbesondere, wenn bei geringem Zoom die Karte verschoben wird. Ein einfache Lösung habe ich dazu noch nicht gefunden.