Composant Delphi / Google Maps / OpenStreetMap / Leaflet  / Mappilary / Native Maps 100% Delphi 0% WebBrowser 0% Javascript

Mode hors-ligne

Vous êtes ici :TECNativeMap

Les tuiles sont d'abord recherchées dans le cache mémoire (les tuiles affichées il y a peu), le cache local, l'archive locale puis sur internet si besoin.

Cache local

En attribuant un répertoire à la propriété LocalCache les tuiles téléchargées depuis internet sont enregistrées en local et sont disponibles hors connexion.

Sous android vous allez devoir demander la permission pour lire et écrire vos données.

1
uses
...
System.Permissions,
{$IFDEF ANDROID}
Androidapi.Jni.Os,
Androidapi.jni.javatypes,
Androidapi.Helpers,
{$ENDIF}
...
{$IFDEF ANDROID}
PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE),
JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)],
procedure(const APermissions: TArray< string >;
const AGrantResults: TArray<TPermissionStatus>)
begin
if (Length(AGrantResults) = 2) and
(AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted)
then map.LocalCache := TPath.Combine(TPath.GetSharedDocumentsPath, 'cache')
else
map.LocalCache := '';
end)
{$ELSE}
map.LocalCache := TPath.Combine(TPath.GetSharedDocumentsPath, 'cache');
{$ENDIF}

Fig. 1 My local tiles

Utilisez la propriété MaxDayInCache pour spécifier la durée de retention dans le cache, 0 pour un cache infini, par défaut 30 jours.

map.MaxDayInCache := 7; // max 7 days

LocalTileCache

Cette propriété de type TCustomTileCache vous permet de prendre en charge le stockage et la lecture des tuiles locales, au lieu de les placer dans un sous-répertoire vous pouvez par exemple les stocker dans une base de donnée.

Vous devez donc vous créer une classe descende de TCustomTileCache et redéfinir certaines méthodes.

Par exemple l'unité TileCacheSQLite.FireDAC contient TTileCacheSQLite qui stocke vos tuiles dans une base SQLite enregistrée dans votre répertoire LocalCache.

uses ..., TileCacheSQLite.FireDac;
...
//Define a local directory in which to store the database
map.LocalCache := ExtractfilePath(ParamStr(0)) + 'cache' ;
// Create TTileCacheSQLite,
// which handles DB creation on server changeover,
// and tile saving and reading on demand
map.LocalTileCache := TTileCacheSQLite.create(map);


TTileCacheSQLite = class(TCustomTileCache)
private
...
protected
// overload to react to server changes,
// here we'll open a database with the server's name
procedure doChangeTileServer(sender: TObject); override;

// override to save the XYZ tile contained in Stream,
// AHandle must be True if registration is ok
procedure doSaveLocalStream(const sender: TObject; const x, y, z: Integer;
const stream: TMemoryStream; var AHandled: boolean); override;

// override to load the XYZ tile in Stream,
// AHandle must be True if is ok

procedure doLoadLocalStream(const sender: TObject; const x, y, z: Integer;
const stream: TMemoryStream; var AHandled: boolean); override;

LocalTileCache est automatiquement libéré à la destruction de la map ou lorsque vous le changez, mettez le à nil pour revenir au stockage classique dans les répertoires.

MBTiles

Un fichier MBTiles est un format de fichier pour stocker des tuiles de carte dans un seul fichier, c'est techniquement une base de données SQLite.

Pour l'utiliser rajoutez le fichier uecMBTiles.FireDAC (FMX.uecMBTiles.FireDAC sous Firemonkey) dans vos uses

FireDAC est utilisé pour accéder à la base SQLite, donc cela n'est compatible qu'avec les versions récentes de Delphi

1
uses
... System.Permissions,System.IOUtils,
FMX.uecNativeMapControl,FMX.uecMBTiles.FireDAC;
{$IFDEF ANDROID}
const
PermissionReadExternalStorage = 'android.permission.READ_EXTERNAL_STORAGE';
PermissionWriteExternalStorage = 'android.permission.WRITE_EXTERNAL_STORAGE';
{$ENDIF}

procedure TForm23.FormCreate(Sender: TObject);
begin
{$IFDEF ANDROID} // android permissions management
PermissionsService.RequestPermissions
([PermissionReadExternalStorage,
PermissionWriteExternalStorage],
nil);
{$ENDIF}

{$IF DEFINED(iOS) or DEFINED(ANDROID)}
FDataBase := TPath.Combine(TPath.GetSharedDocumentsPath, 'countries-raster.mbtiles');
{$ELSE}
FDataBase := 'H:\#DATA\MBTiles\countries-raster.mbtiles';
{$ENDIF}
// connect the component Map to the MBTiles server
FecMBTiles := TecMBTiles.Create(Map);
// open DataBase, true if ok
if not FecMBTiles.Connect(FDataBase) then
begin
ShowMessage(FecMBTiles.MessageError);
end;
// call FecMBTiles.Disconnect for disconnect
end;

procedure TForm23.FormDestroy(Sender: TObject);
begin
FecMBTiles.Free;
end;

Fig. 2 MBTiles Firemonkey

La démo utilise le fichier MBTiles raster que vous pourrez trouver sur //github.com/klokantech/vector-tiles-sample

1

Archive Locale

Un fichier MBTiles sera bien plus efficace qu'un simple zip.

2

Une archive locale correspond au cache local mis dans un Zip, cela simplifie le déploiement des tuiles et des autres fichiers.


Pour améliorer la vitesse les tuiles sont extraites de l'archive et placées dans le cache locale lors de la première demande, vous devez donc définir un cache local pour utiliser une archive.

Fig. 3 Archive ile de ré

map.LocalCache := TPath.Combine(TPath.GetSharedDocumentsPath, 'cache');
map.TileServer := tsOSM;
map.LocalArchive := ExtractfilePath(ParamStr(0))+'ile_de_re.zip';

Si des routes ou des géolocations d'adresses sont enregistrées dans l'archive la récupération est totalement transparente

2
map.Routing.engine(reMapBox);
// if an archive is connected and contains the route, no internet connection is made to return the way
map.Routing.Request('saint-martin de ré', 'la couarde sur mer');

Vous pouvez y stocker vos images ou des fichiers de données (kml, geojson etc...), pour les charger il suffira de faire débuter le nom du fichier par /

// load data
map.Shapes.LoadFromFile('/DATA/tdf.kml');
map.LoadFromFile('/DATA/tarbes.txt');
// load image in marker
marker.filename := '/IMAGE/node.png';

Utilisez MapArchive pour manipuler directement votre archive et extraire vos autres données.

m := TMemoryStream.Create;
try

map.MapArchive.ReadStream('DATA/mydata.txt',m);

memo1.Lines.LoadFromStream(m);

finally
m.Free;
end;

MapArchiveCreator

Ce petit utilitaire permet de créer vos archives, vous pouvez télécharger des zones de tuiles, enregistrer des routes, ajouter des images et des fichiers.

Fig. 4 MapArchiveCreator

Vous pouvez interdire toute connexion internet pour les tuiles et le geocodage en utilisant la propriété OnlyLocal

3
// tiles and geocoding only uses local cache and local archive
map.onlyLocal := true;

Téléchager une zone complète

La classe TECDownLoadTiles vous permet de télécharger en arrière-plan une zone complète, la demo EcNativeMapFiremonkeyDemo vous montre comment précharger la zone visible à l'écran.

FECDownLoadTiles:=TECDownLoadTiles.create;

FECDownLoadTiles.OnDownLoad := doDownLoadtiles;
FECDownLoadTiles.OnEndDownLoad := doEndDownLoadtiles;

// tiles are saved in DirectoryTiles
FECDownLoadTiles.DirectoryTiles := map.LocalCache;

FECDownLoadTiles.TileServer := map.TileServer;
FECDownLoadTiles.TileSize := map.TileSize;

// download visible area from zoom+1 to MaxZoom

FECDownLoadTiles.DownLoadTiles(map.Zoom+1,map.MaxZoom,
map.NorthEastLatitude,map.NorthEastLongitude,
map.SouthWestLatitude,map.SouthWestLongitude);

...


// for abort
FECDownLoadTiles.Cancel;

// for pause
FECDownLoadTiles.Pause := true;
// restart
FECDownLoadTiles.Pause := false;

// see ECNativeMapFiremokeyDemo for complete use

Assurez-vous que votre fournisseur de tuiles autorise cela !

3

Reprendre le téléchargement ultérieument

Vous devez sauvegarder les propriétés suivantes pour pouvoir reprendre le téléchargement à une position spécifique.

property StartX : integer
property StartY : integer
property StartZoom : byte
property StartCountTiles : integer
property StartDownLoadTiles : integer
property FromZoom : integer
property ToZoom : Integer
property NorthEastLatitude : double
property NorthEastLongitude : double
property SouthWestLatitude : double
property SouthWestLongitude : double

Pour la reprise il faudra appeler cette version de DownLoadTiles

procedure TECDownLoadTiles.DownLoadTiles(const FromZoom, ToZoom: Integer;
const NorthEastLatitude, NorthEastLongitude,
SouthWestLatitude,SouthWestLongitude: double;
const StartX,StartY:integer;
const StartZoom:byte;
const StartCountTiles,
StartDownLoadtiles:integer);

Remplir le Stream des tuiles

Vous pouvez aussi directement retourner un stream contenant le jpeg ou le png de vos tuiles, utile si vous avez vos tuiles dans une base de données.

// manual management tiles as stream
map.TileServerInfo.getTileStream := getTileStream;
// the name will be uses as subdirectory in cache
map.TileServerInfo.Name := 'MyMAP';
// important to specify a manual management tiles
map.TileServer := tsOwnerDraw;



// asks for a tile
procedure TForm2.getTileStream(const ThreadIndex:integer;var TileStream: TMemoryStream;
const x, y, z: integer);
begin
// here fill tileStream with tileXYZ
end;


Vous pouvez aussi vous en servir pour utiliser un serveur de tuiles distant.

1
Aller à la page
Réalisé avec la version gratuite pour les particuliers d'Help&Web