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

Import/Export

Vous êtes ici :TECMap

TECNativeMap permet d'enregistrer et de recharger la totalité de ses données dans un simple fichier texte, cela comprend non seulement les paramètrages du composant et des vues mais aussi les données cartographiques

Vous pouvez aussi importer/exporter vos données aux formats GPX , GeoJSON et KML

Sauvegarde/Restauration

function SaveToFile(const filename:string):boolean;

Enregistre la carte dans un fichier texte.

Utilisez les extensions .gpx , .kml pour spécifier un format, autrement c'est le format interne d'ECNativeMap qui sera employé

function LoadFromFile(const filename:string):boolean;

Charge la carte avec un fichier texte

Utilisez les extensions .osm, .olt, .gpx, .json , .kml ou .csv pour spécifier un format, autrement c'est le format interne d'ECNativeMap qui sera employé

 

LoadFromFile peut télécharger les fichiers sur internet

1

 

property toGPX : string;

Propriété en lecture/écriture qui donne accès aux données de la carte dans le format GPX.

Cette propriété est utilisée par SaveToFile, LoadFromFile.

property toTxt : string;

Propriété en lecture/écriture qui donne accès aux données de la carte dans un format texte.

Cette propriété est utilisée par SaveToFile, LoadFromFile.

property ToKml : string;

Propriété en lecture / écriture qui retourne les éléments géographique de la carte au format Kml

property toGeoJson : string;

Propriété en lecture/écriture qui donne accès aux données de la carte dans le format GeoJson.

Vous accédez aux données du champ "properties" avec TECShape.Properties, reportez vous au chapitre sur les Tuiles vectorielles pour apprendre à styler vos éléments.

Cette propriété est utilisée par SaveToFile, LoadFromFile.

Évenements

Lorsque le chargement d'un fichier (.csv, .kml, .geojson, .gpx ou .txt) est terminé l'événement OnLoad(sender: TObject; const GroupName: string; const FinishLoading: Boolean); se déclenche.

map['group_name'].loadFromFile(filename);
...
// fired when load ready
procedure TForm.mapLoad(sender: TObject; const GroupName: string;
const FinishLoading: Boolean);
begin

// show all éléments
map.group[groupname].fitbounds;

end;

Pendant le chargement de la carte l'évenement OnLoadShapes(sender: TObject;const ShapeType:string;const index,max:integer;var cancel:boolean) se déclenche pour chaque élement ajouté.

ShapeType peut prendre les valeurs 'TECShapePOI', 'TECShapeMarker', 'TECShapeLine' , 'TECShapePolygone' et 'TECShapeInfoWindow'.

Index indique le numéro de l'élément actuellement chargé et Max le nombre total d'éléments à charger.

Vous pouvez abandonner le chargement en basculant cancel à true

Lorsque le fichier à été chargé l'événement OnLoad(sender: TObject;const GroupName:string;const FinishLoading : boolean)

GroupName contient le nom du groupe qui a été chargé, vide pour un chargement direct de la carte (groupe par défaut)

FinishLoading vaut true si le fichier a été chargé en totalité et false s'il a été abandonné en basculant cancel à true


OSM XML

Vous pouvez directement charger un fichier au format OSM XML ou olt avec LoadFromFile.
Les groupes disposent en plus des fonctions LoadFromOSMStream et LoadFromOSMString.

1

La classe TOSMFile de l'unité uecOSM vous permet de travailler avec des fichiers au format OSM XML ( format de base d'OpenStreetMap ).

Vous pouvez télécharger des régions du monde dans ce format sur le site geofabrik.de, prenez les fichiers .osm.bz2 et dézippez-les

Mais vous pouvez aussi obtenir ces données directement depuis TECNativeMap en utilisant OverPass API

OverPassApi

La propriété OverPassApi vous permet d'utiliser Overpass API pour obtenir des données d'OpenStreetMap

Un layer est aussi disponible pour simplifier l'utilisation

1

Par défaut le serveur utilisé est https://overpass-api.de/api/interpreter, pour le changer utilisez la propriété Url


map.OverPassApi.Url := 'https://overpass.kumi.systems/api/interpreter';

Les requêtes ne sont pas bloquantes, branchez vous sur l'événement OnData pour récupérer les données lorsqu'elles sont disponibles.

Utilisez Query pour lancer votre requête.

map.OverPassApi.OnData := doOverPass;
// get highway
map.OverPassApi.Query('way({{bbox}})[highway][name];(._;>;);out;)');

// the event is triggered when data is available
procedure TForm.doOverPass(const value:TECOverPassData);
begin
// load OSM data in your map
map.Shapes.LoadFromOSMString(value.Data);
end;

Vous pouvez utiliser {{bbox}} pour limiter la recherche à la zone visible de votre carte, et {{center}} pour indiquer le point central de votre carte.

2

Fig. 1 OverPassApi query highway

Pour plus d'information sur le langage de script d'OverPassAPI consultez :

wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide
wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL

Quelques requêtes sont disponibles en standard


StreetNames retourne juste une liste contenant le nom des rues

procedure StreetNames(const bbox:string='';const OnDataEvent:TECOnOverPass=nil); overload;

Utilisez cette version pour définir une zone de recherche différente de la vue actuelle

procedure StreetNames(const SWLatitude,SWLongitude,NELatitude,NELongitude:double;const OnDataEvent:TECOnOverPass=nil); overload;

map.OverPassApi.StreetNames;

Streets retourne les données OSM pour les rues de la zone choisi (c'est l'équivalent de l'exemple plus haut)

procedure Streets(const bbox:string='';const OnDataEvent:TECOnOverPass=nil); overload;
procedure Streets(const SWLatitude,SWLongitude,NELatitude,NELongitude:double;const OnDataEvent:TECOnOverPass=nil); overload;

Amenity permet de trouver des points spécifiques

procedure Amenity(const amenity_value: string = '';
const data:TSetOSMData=[odNode,odWay];
const bbox: string = '';
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Amenity(const SWLatitude, SWLongitude, NELatitude,NELongitude: double;
const amenity_value: string = '';
const data:TSetOSMData=[odNode,odWay];
const OnDataEvent: TECOnOverPass = nil); overload;


procedure Amenity( const amenity_values: array of string;
const data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const bbox: string = '';
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Amenity( const SWLatitude, SWLongitude, NELatitude,NELongitude: double;
const amenity_values: array of string;
const data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const OnDataEvent: TECOnOverPass = nil); overload;
map.OverPassApi.OnData := doOverPass;

// find all 'restaurant' (Node and Way) in visible area
map.OverPassApi.Amenity('restaurant');
// find all 'restaurant' (only Node) in visible area
map.OverPassApi.Amenity('restaurant',[odNode]);

// the event is triggered when data is available
// Set OnDataEvent to connect to a specific procedure
procedure TForm.doOverPass(const value:TECOverPassData);
begin
// load OSM data in your map
map.Shapes.LoadFromOSMString(value.Data);
end;

map.OverPassApi.Amenity('restaurant',[odNode],'',myEvent);
...
procedure TForm.myEvent(const value:TECOverPassData);
begin
// load OSM data in your map
map.Shapes.LoadFromOSMString(value.Data);
end;

Tag est la procedure générique pour chercher parmis l'ensemble des key pas seulement Amenity

procedure Tag(const tags: array of string;
const Data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const bbox: string = '';
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Tag(const tag_name:string;
const tag_values: array of string;
const data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const bbox: string = '';
const OnDataEvent: TECOnOverPass = nil); overload;


procedure Tag(const tag_name: string = '';
const tag_value: string = '';
const data:TSetOSMData=[odNode,odWay];
const bbox: string = '';
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Tag(const SWLatitude, SWLongitude, NELatitude,NELongitude: double;
const tag_name: string = '';
const tag_value: string = '';
const data:TSetOSMData=[odNode,odWay];
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Tag(const SWLatitude, SWLongitude, NELatitude,NELongitude: double;
const tags: array of string;
const Data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const OnDataEvent: TECOnOverPass = nil); overload;

procedure Tag(const SWLatitude, SWLongitude, NELatitude,NELongitude: double;
const tag_name:string;
const tag_values: array of string;
const data:TSetOSMData=[odNode,odWay];
const Op: TBinaryFilterOSM = bfAnd;
const OnDataEvent: TECOnOverPass = nil); overload;


// search Way 'highway'='residential
map.OverPass.Tag('highway','residential',[odWay]);
// search Way 'highway'='residential' OR 'highway'='primary'
map.OverPass.Tag('highway',['residential','primary'],[odWay],bfOr);
//search Way width highway=residential AND name='Park Avenue'
map.OverPass.Tag(['highway','residential','name','Park Avenue'],[odWay],bfAnd);

Data retourne l'ensemble des données OSM disponibles pour la zone spécifiée

procedure Data(const bbox:string='';const OnDataEvent:TECOnOverPass=nil); overload;
procedure Data(const SWLatitude,SWLongitude,NELatitude,NELongitude:double;const OnDataEvent:TECOnOverPass=nil); overload;

map.OverPassApi.data;

FilterPolygone vous permet d'utiliser un polygone pour limiter la zone de recherche

Vous pouvez par exemple utiliser un isoChrone

3
map['isochrone'].polygones.Clear;
// within 10 minutes walking distance
map.routing.IsoChrone.Time(map.latitude,map.longitude,map[ 'isochrone'].polygones,[10]) ;

if map['isochrone'].polygones.Count> 0 then
map.OverPassApi.FilterPolygone := map['isochrone'].polygones[0];

DemoNativeOverPassFiremonkey vous montre comment extraire des données de OpenStreetMap.

Fig. 2 DemoOverPassApi

OSM XML est volumineux, certains fichiers font plusieurs Giga, TOSMFile peut utiliser un format interne (.olt) jusqu'a 19 fois plus léger, 10 fois plus rapide à traiter.

Pour convertir simplement un fichier .osm en .olt utiliser la procedure OSMFileToOLT(const OSMFilename:string;const Notify:TNOtifyEvent=nil);

La conversion est effectuée dans un thread et Notify est appelé lorsque le travail est terminé.

rocedure TForm2.SaveOLTClick(Sender : TObject);
begin

// doEndSaveToOLT is call when file is saved
OSMFileToOLT(FOSMFile.filename, doEndSaveToOLT);

end;

procedure TForm2.doEndSaveToOLT(Sender : TObject);
begin
// here your osm file is savec in .olt

end;

Vous devez utiliser directement TOSMFile pour convertir des portions de fichiers OSM

2

TOMSFile

function LoadFromFile(const sFilename : string) : boolean;
function LoadFromStream(const OSMStream : TStream) : boolean;
function LoadFromString(const OSMData : string) : boolean;

Charge un fichier OSM ou OLT, le traitement a lieu dans un Thread donc il ne bloque pas votre programme

property FilterPrimitive : TSetPrimitiveOSM ;

Il y a 3 primitives, les nodes, les ways et les relations.

// handle all primitive
FOSMFile.FilterPrimitive := [poNode,poWay,poRelation];

Si vous souhaitez connaitre simplement la zone geographique couverte par le fichier sans charger les données, filtrez tout !

4
FOSMFile.FilterPrimitive := [];

property FilterBounds : TFilterBounds;

Détermine les zones géographiques qui nous intéressent, les données situées en dehors sont ignorées.

FOSMFile.FilterBounds.Clear;
FOSMFile.FilterBounds.Add(Area1_NorthEastLat, Area1_NorthEastLng, Area1_SouthWestLat, Area1_SouthWestLng);
FOSMFile.FilterBounds.Add(Area2_NorthEastLat, Area2_NorthEastLng, Area2_SouthWestLat, Area2_SouthWestLng);

property FilterNode : TListFilterOSM;
property FilterWay : TListFilterOSM;
property FilterRelation : TListFilterOSM;

Filtre les éléments en fonction de leur clefs et valeurs, les filtres descendent de la classe TFilterOSM

ExcludeKeyValue(const Key, Value : string), OnlyKeyValue(const Key, Value : string), ExcludeIfKeyExist(const Key:string) et OnlyIfKeyExist(const Key:string) vous simplifie la création de filtres.

3
FOSMFile.FilterWay.clear;
FOSMFile.FilterWay.ExcludeIfKeyExist('building');
FOSMFile.FilterWay.ExcludeKeyValue('leisure','park');
FOSMFile.FilterWay.ExcludeKeyValue('natural','coastline');
function ReLoad : boolean;
Retraite un fichier après avoir modifié les divers filtres, les clefs et les valeurs ne sont pas rechargées cela permet de gagnez quelques secondes.

procedure saveToFile(const Filename : string; NotifyEvent : TNotifyEvent = nil);
Vous pouvez sauvegarder dans le format propriétaire .olt ou au format GeoJSON
// save in geojson
FOSMFile.SaveToFile('path_myfile.geojson');
// save in olt
FOSMFile.SaveToFile('path_myfile.olt');

Pour sauvegarder dans un thread indiquez un NotifyEvent

4
procedure TForm2.SaveOLTClick(Sender : TObject);
begin
// doEndSaveToOLT is call when file is saved
FOSMFile.SaveToFile('path_myfile.olt',doEndSaveToOLT);
end;

procedure TForm2.doEndSaveToOLT(Sender : TObject);
begin
// here your osm file is savec in .olt
end;
property Nodes : TNodeList read FNodeList;
property Ways : TWayList read FWayList;
property Relations : TRelationList read FRelationList;

Listes des éléments contenu dans le fichier après filtrage.

Chaque liste dispose de fonctions permettant d'effectuer des recherches sur ces éléments.

Find(idElement) retourne un élément en fonction de son id

Les diverses fonctions Search remplisse la liste SearchResult avec les éléments remplissant les conditions

function Search(const Lat, Lng, radiusKM : double) : integer; overload;
Trouve tous les éléments situés dans une zone centrée sur le point Lat,Lng et de rayon radiusKM

function Search(const SWLat, SWLng, NELat, NELng : double) : integer; overload;
Trouve tous les éléments de la zone.

function Search(const SWLat, SWLng, NELat, NELng : double; const Key, Values : string) : integer; overload;
Trouve tous les éléments de la zone avec une Clef contenant les valeurs spécifiées.

function Search(const Key, Values : string) : integer; overload;
Trouve tous les éléments dont la clef contient les valeurs indiquées.

// search all nodes with amenity=car or amenity=bar or amenity=restaurant
FOSMFile.Nodes.Search('amenity','cafe|bar|restaurant');

// search all ways with highway=residential or highway=secondary
FOSMFile.Ways.Search('highway','residential|secondary');

function Search(const Key : string) : integer; overload;
Trouve tous les éléments possédant cette clef, quelque soit la valeur.



procedure Clear;

procedure Abort;
Abandonne un chargement

procedure ToShapes(Shapes:TECShapes;NotifyEvent:TNotifyEvent=nil);

Charge les données dans un groupe.

// load in default group
FOSMFile.ToShapes(map.Shapes);
procedure FindToShapes(Shapes:TECShapes;NotifyEvent:TNotifyEvent=nil);

Charge les données recherchées dans un groupe.

// search all nodes with amenity=car or amenity=bar or amenity=restaurant
FOSMFile.Nodes.Search('amenity','cafe|bar|restaurant');

// search all ways with highway=residential or highway=secondary
FOSMFile.Ways.Search('highway','residential|secondary');

// load in default group
FOSMFile.FindToShapes(map.Shapes);


function CountKey(Node: TBaseOSM):integer;
Retourne le nombre de tag pour un élément

function getKey(Node:TBaseOSM;const index:integer):string;
Retourne la key dont on passe l'index

function ReadKey(Node : TBaseOSM; const KeyName : string) : string; overload;
Retourne la valeur de la Key

function ReadKey(Node : TBaseOSM) : string; overload;
Retourne l'ensemble des paires key/value sous la forme : Key1=value1#13#10Key2=value2#13#10Keyx=ValueX

function ReadValuesForKey(const KeyName : string; valuesList : TStringList): integer;
Rempli ValuesList avec l'ensemble des valeurs pour une Key


property Aborted : boolean;
Indique si le chargement a été interrompu par Abort

property Bounds : TBoundsLatLng ;
Contient la zone géographique décrite par le fichier


property FileFormat: TFileTypeOSM;
Retourne le type de fichier (ftOSM ou ftOLT)

property Filename : string ;
property FileSize : int64;

property Keys : TUniqueStringList;
Liste de la totalité des Key du fichier

property Values : TUniqueStringList;
Liste de la totalité des Value du fichier

property Role[Member : TMemberOSM]:string;
Retourne le role d'un membre d'une relation

property Timestamp : string ;
Retourne la date de la dernière mise à jour du fichier



property OnRead : TOnOSMBlockRead;
Pour pouvoir traiter des fichiers de plusieurs Giga la lecture est faite par bloc, cet événement est déclenché à chaque chargement d'un bloc.

property OnLoaded : TNotifyEvent;
Déclenché lorsque la totalité du fichier a été traité.

Consultez DemoOSMViewer pour voir une utilisation réelle de TOSMFile

2

OSMViewer

Fig. 3 Demo OSMViewer

Convertir un fichier OSM en OLT

Ouvrez le fichier OSM dans OSMviewer, la zone couverte s'affiche sur la carte

Cochez les primitives que vous souhaitez exporter (nodes, ways et relation) puis cliquez sur Save OLT pour lancer la conversion


Fig. 4 Select nodes

Suivant la taille du fichier OSM le travail peut durer quelques minutes.

5

Pour exporter les ways toutes les nodes sont conservée en mémoire il faut avoir 1Mo de mémoire par Go de fichier.

Si vous ne convertissez que les nodes vous pourrez travailler avec des fichiers de 100 Go même si vous n'avez que 8Mo de mémoire.

1
Faites un clic droit et tout en maintenant le bouton enfoncé déplacez la souris pour définir une zone à explorer.

Fig. 5 Sélection d'une zone

Une fois la zone chargée vous aurez le choix entre affichée les données sur la carte ou les sauvegarder en .olt

En chargeant les données vous pouvez effectuer des recherches en fonction des paires key/value

Fig. 6 search highway=residential

Télécharger OSMViewer

Vous pouvez télécharger un apk pour android d'une mini demo qui affiche les données OSM d'une petite zone.

Fig. 7 Android Test OLT

Capture Image

Vous pouvez enregistrer la zone visible de l'écran avec la propriété ScreenShot qui est un TBitmap

// Delphi map component TECNativeMap

// save map to bmp file
map.Screenshot.SaveTofile('c:\mymap.bmp');

Vous pouvez aussi capturer n'importe quelle zone géographique, même hors-écran, avec la propriété ScreenShots

5

// procedure call when bitmap ready
map.ScreenShots.OnScreenShot := doScreenShot ;

// you can change the size of the bitmap between each capture (default 800x600)
map.ScreenShots.Width := 2000;
map.ScreenShots.Height:= 2000;

// you can change tileserver
map.ScreenShots.TileServer := tsOsmFr;

// capture area centered on a point with a specified zoom
map.ScreenShots.ScreenShot(latitude,longiture, 16,'optional_name_of_capture');

// you can take screenshots even if the previous is not over yet

// Take the best zoom to a specific area
map.ScreenShots.ScreenShot(NorthEastLat, NorthEastELng, SouthWestWLat, SouthWestLng,'optional_name_of_capture');

// Take the best zoom to an area defined by its center and radius in km
// CAUTION use double for the radius, here 1.0 km, otherwise it will be mistaken for a simple zoom

map.ScreenShots.ScreenShot(Latitude, Longitude, 1.0 ,'optional_name_of_capture');


// when capture is ready, you go here
procedure TForm.doScreenShot(const name:string;const Screenshot:TBitmap);
begin
// don't free ScreenShot !
screenshot.SaveToFile(YourPath+name+'.bmp');
end;

La demo Photographer pour Firemonkey vous montre un exemple d'utilisation, vous lancez 8 "drones" pour photographier le terrain tous les x mètres.

Fig. 8 Photographer

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