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

Import/Export

you are here :TECNativeMap

TECNativeMap allows to save and reload all of its data in a simple text file, this includes not only the component settings and views but also the map data

Alternatively, you can import/export your data in formats GPX , GeoJSON and KML

Backup/restore

function SaveToFile(const filename:string):boolean;

Saves the map to a text file.

Use extensions .gpx, .json, .kml to specify a format, otherwise it is the internal format of ECNativeMap that will be used

function LoadFromFile(const filename:string):boolean;

Charge la carte avec un fichier texte

Use extensions .osm, .olt, .gpx, .json , .kml or .csv to specify a format, otherwise it is the internal format of ECNativeMap that will be used

 

LoadFromFile can download files on internet

1

 

property toGPX : string;

Property read/write which gives access to the data of the card in GPX format.

property toTxt : string;

Property read/write which gives access to the data of the card in a text format.

property ToKml : string;

Property in reading / writing which returns the geographical elements of the map in Kml format

property toGeoJson : string;

Property read/write which gives access to the data of the card in the GeoJson format.

You access to the "properties" with TECShape.Properties field data, see chapter on the vector tiles to learn how to styling your items.

This property is used by SaveToFile, LoadFromFile.

Events

When the loading of a file (.csv, .kml, .geojson, .gpx or .txt) is finished the event OnLoad(sender: TObject; const GroupName: string; const FinishLoading: Boolean); is fired.

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;

During loading the map the event OnLoadShapes(sender: TObject; const ShapeType:string; const index, max: integer; var cancel: boolean) fires for each item added.

ShapeType can have the values 'TECShapePOI', 'TECShapeMarker', 'TECShapeLine' , 'TECShapePolygone' and 'TECShapeInfoWindow'.

Index indicates the number of the currently loaded element and Max the total number of items to be loaded.

You can cancel the load switching cancel to true

When the file was loaded event OnLoad(sender: TObject;const GroupName:string;const FinishLoading : boolean) is triggered

GroupName contains the name of the Group that has been loaded, empty for direct loading of the map (default group)

FinishLoading true if the file has been loaded in totality and false if it was abandoned by switching cancel to true


OSM XML

You can directly load a file to the OSM XML format or olt with LoadFromFile.
The groups also have the functions LoadFromOSMStream and LoadFromOSMString.

1

TOSMFile (uecOSM unit) allows you to work with files in the OSM XML format (base format of OpenStreetMap)

You can download parts of the world in this format on geofabrik.de, take .osm.bz2 and unzip them

But you can also get these data directly from TECNativeMap using OverPass API

OverPassApi

The OverPassApi property allows you to use the Overpass API to get data from OpenStreetMap.

A layer is available to simplify the use

1

By default the server used is https://overpass-api.de/api/interpreter, use the Url property to change it


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

Queries are nonblocking, plug on the event onData to recover data when available.

Use Query to run your request.

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;

You can use {{bbox}} to limit the search to the visible area of your map, and {{center}} to indicate the focal point of your map.

2

Fig. 1 OverPassApi query highway

See for more information on the scripting language of OverPassAPI :

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

Some queries are available as standard


StreetNames returns just a list containing the name of the streets

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

Use this version to set a different search in the current view box

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

map.OverPassApi.StreetNames;

Streets Returns the OSM data for the chosen area streets (it is equivalent to the example above)

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

Amenity to find specific points

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 is the generic procedure to search through all the keys, not just 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 Returns the set of OSM data for the specified area

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 allows you to use a polygon to limit the search area

For example, you can use a 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 shows you how to extract data from OpenStreetMap.

Fig. 2 DemoOverPassApi

OSM XML is large, some files are several Giga, TOSMFile can use an internal format (.olt) up to 19 times lighter, 10 times faster to process.

To convert a .osm file in .olt use the procedure OSMFileToOLT(const OSMFilename:string;const Notify:TNOtifyEvent=nil);

The conversion is performed in a thread and Notify is called when the work is complete.

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;

Use TOSMFile to convert portions of OSM files

2

TOMSFile

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

Loads a OSM or OLT file, the treatment takes place in a Thread so it does not block your program

property FilterPrimitive : TSetPrimitiveOSM ;

There are nodes, ways and relations.

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

If you want to know simply the area geographical covered by the file without loading the data, filter all !

4
FOSMFile.FilterPrimitive := [];

property FilterBounds : TFilterBounds;

Determines the geographical areas that interest us, data outside are ignored.

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;

Filters items based on their keys and values, filters down from the class TFilterOSM

ExcludeKeyValue(const Key, Value : string), OnlyKeyValue(const Key, Value : string), ExcludeIfKeyExist(const Key:string) and OnlyIfKeyExist(const Key:string) simplifies the creation of filters.

3
FOSMFile.FilterWay.clear;
FOSMFile.FilterWay.ExcludeIfKeyExist('building');
FOSMFile.FilterWay.ExcludeKeyValue('leisure','park');
FOSMFile.FilterWay.ExcludeKeyValue('natural','coastline');
function ReLoad : boolean;
Reload a file after changing the filters, the keys and values are not recharged allows to earn a few seconds.

procedure saveToFile(const Filename : string; NotifyEvent : TNotifyEvent = nil);
You can save in the proprietary .olt format or in GeoJSON format
// save in geojson
FOSMFile.SaveToFile('path_myfile.geojson');
// save in olt
FOSMFile.SaveToFile('path_myfile.olt');

To save in a thread add a 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;

Lists of the elements contained in the file after filtering.

Each list has functions for performing research on these items.

Find(idElement) Returns an item based on its id

The various Search functions fill the SearchResult list with the elements eligible

function Search(const Lat, Lng, radiusKM : double) : integer; overload;
Find all items located in an area centered around the point Lat, Lng and radius radiusKM

function Search(const SWLat, SWLng, NELat, NELng : double) : integer; overload;
Finds all elements in the area.

function Search(const SWLat, SWLng, NELat, NELng : double; const Key, Values : string) : integer; overload;
Finds all elements in the area with Key containing the specified values.

function Search(const Key, Values : string) : integer; overload;
Find all items whose key contains values.

// 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;
Find all items with this key, regardless of the value.



procedure Clear;

procedure Abort;
Abandons a loading

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

Loads data into a group.

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

Loads the search data in a group.

// 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;
Returns the number of tag for an element

function getKey(Node:TBaseOSM;const index:integer):string;
Returns the key which is the index

function ReadKey(Node : TBaseOSM; const KeyName : string) : string; overload;
Returns the value of the Key

function ReadKey(Node : TBaseOSM) : string; overload;
Returns the set of key/value pairs in the form: Key1=value1#13#10Key2=value2#13#10Keyx=ValueX

function ReadValuesForKey(const KeyName : string; valuesList : TStringList): integer;
ValuesList filled with all of the values for a Key


property Aborted : boolean;
Indicates if loading has been interrupted by Abort

property Bounds : TBoundsLatLng ;
Contains the geographical area covered by the file


property FileFormat: TFileTypeOSM;
Returns the file type (ftOSM ou ftOLT)

property Filename : string ;
property FileSize : int64;

property Keys : TUniqueStringList;
List of all of the Key from the file

property Values : TUniqueStringList;
List of all the Value of the file

property Role[Member : TMemberOSM]:string;
Returns the role of a member of a relation

property Timestamp : string ;
Returns the date of the last update of the file



property OnRead : TOnOSMBlockRead;
To be able to process files of several Giga reading is made by block, this event is raised every time a block is read.

property OnLoaded : TNotifyEvent;
Raised when the entire file has been processed.

Check out DemoOSMViewer to see how to use TOSMFile

2

OSMViewer

Fig. 3 Demo OSMViewer

Convert OSM in OLT

Open the osm file in OSMviewer, the area covered is displayed on the map

Check the primitives that you want to export (nodes, ways and relations), and then click Save OLT to start the conversion


Fig. 4 Select nodes

Depending on the size of the OSM file work may take several minutes.

5

To export the ways all the nodes are kept in memory , you need 1 MB of memory per Giga of file.

If you convert only the nodes you can work with 100 Giga files even if you have only 8 MB of memory.

1
Click right and while holding the button move the mouse to define an area to explore.

Fig. 5 Selecting an area

Once the loaded zone you will have the choice between displayed data on the map or save them in .olt

By loading data you can search according to key/value pairs

Fig. 6 search highway=residential

Download OSMViewer

You can download an apk for android to a mini demo that displays a small area OSM data.

Fig. 7 Android Test OLT

Image capture

You can save the viewable area of the screen with the ScreenShot property that is an TBitmap

// Delphi map component TECNativeMap

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

Alternatively, you can capture any geographic area, even off screen, with the property 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;

The Photographer demo for Firemonkey shows you an example of using, you run 8 "drones" to photograph the ground every x meters.

Fig. 8 Photographer

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