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


you are here :TECNativeMap

API Keys

TECNativeMap uses OpenStreetMap.

If you want to use these services of TomTom or MapBox you must register on their site to obtain a user key .

Offline mode

If you specify a directory in the LocalCache property, all datas will be cached and can be reused in offline mode.


Managing Routes and turn by turn navigation.

procedure Request(const StartAdress, EndAdress: string;const params: string = '';const FutureRoute:TECShapeline=nil); overload;

procedure Request(const dLatLngs: array of double;const params: string = '';const FutureRoute:TECShapeLine=nil); overload;

Calculate a route between addresses or points
map.Routing.routeType := rtCar;
// get data road between Tarbes and Paris
// get data road between Tarbes and Lourdes via Aureilhan
// you can also pass a array of coordinate pairs
Params allows you to pass additional parameters to the routing engine

Attention for OpenStreetMap and OSRM you must make sure to pass valid settings, see the documentation (identical for both because the engine is the same)

FutureRoute is an empty line that will be initialized with the data returned by the routing engine, this allows you to attach parameters that can be used when the route is finalized in OnAddRoute;

property routeType: TMQRouteType

Type of route ( rtCar, rtFastest, rtShortest , rtPedestrian, rtBicycle )

property OptimizeRoute : boolean

Calculation optimization, only MapBox and TomTom engines support this feature

property GroupName : string

Name of the group which will own the new road (TECShapeLine), default empty

function FutureRoute:TECShapeLine;

returns an empty line that you can pass to Request
We will directly pass a line to the routing engine
so that we can attach parameters to it
that will be used when the route is calculated,
here we store the speed of our mobile according to the type of route desired
RouteLine := map.routing.futureRoute; // return a empty line
// fired when route is ready
map.Routing.OnAddRoute := doOnAddRoute;

if rbWalking.ischecked then
map.Routing.RouteType := rtPedestrian ;
else if rbBicycling.ischecked then
map.Routing.RouteType := rtBicycle ;
map.Routing.RouteType := rtCar;

// then empty string is for optionnal params, here none
map.Routing.Request(RouteStart.Text, RouteEnd.Text,'',RouteLine);
(* attention by default the request is asynchronous,
so your route is not yet ready just after the request,
connect to OnAddRoute to react when it is ready *
procedure TForm.doOnAddRoute(sender: TECShapeLine;const params:string);
// sender is the route (TECShapeLine)
// params this is the URL sent to the routing engine

property Color : TColor

Color of the road

property Weight: integer

Thickness of the road

property StartMarkerFilename: string

Image used to mark the start, default

property EndMarkerFilename: string

Image used to mark the arrival, by default

property RouteDrawingTime: integer

Time (in MS) to display the route, allows to realize an animation for a progressive display.
Default 0, the road appears only once.

property EditRoute: TECShapeLine

To edit the route with the mouse

property EditOnClick : boolean

By default a click on a route makes switch to edit mode, simply click on the points A or B to exit this mode

Routing engine

procedure Engine(value:TRoutingEngine;const ApiKey:string='');

Allows you to choose a routing engine, OpenStreetMap (default choice), Valhalla, TomTom, OSRM or MapBox


Use EngineValidUrl to change the url before is sent to the engine

This is recommended for Valhalla which by default is connected to a demo server.

procedure doUrl(sender:TECThreadDataRoute);
// Here you can change the url
// ! your are not in main thread
sender.Url := ...;

procedure TFDemoNativeRoute.FormCreate(Sender: TObject);
// setup routing
// intercept url before engine
map.Routing.EngineValidUrl := doUrl;


Define its own engine

Use EngineUrl and EngineExcute to edit your own engine.

property EngineUrl : TECThreadRoutingUrl

property EngineExecute : TECThreadRoutingExecute

map.Routing.TurnByTurn.OnInstruction := doOnTurnByTurnInstruction;
map.Routing.TurnByTurn.OnAfterInstruction := doOnTurnByTurnInstruction;
map.Routing.TurnByTurn.OnAlert := doOnTurnByTurnAlert;
map.Routing.TurnByTurn.OnArrival := doOnTurnByTurnArrival;
map.Routing.TurnByTurn.OnError := doOnTurnByTurnError;

procedure TFDemoNativeRoute.doOnTurnByTurnAlert(sender : TECTurnByTurn;const Instruction:string;const Distance:double);
// alert is fired before OnInstruction

procedure TFDemoNativeRoute.doOnTurnByTurnInstruction(sender : TECTurnByTurn;const Instruction:string;const Distance:double);
// execute instruction in Distance (km)

EngineUrl and EngineExecute are executed in another thread !


property EngineName : string

Gives a name to the engine, used for local storage

property EngineKey : string

Key to use the engine, you get yours from TomTom or MapBox

property TurnByTurn: TECTurnByTurn

The turn by turn navigation management

4 events are available

property OnAddRoute : TOnAddRoute
Raised when the road has been created
property OnChangeRoute : TOnChangeRoute
Raised when the road has changed
property OnErrorRoute : TOnErrorRoute
Raised if the road has not been created
property OnDrawRoute : TOnDrawRoute
Raised when the road was fully displayed (useful if RouteDrawingTime > 0)
map.Routing.OnAddRoute := doOnAddRoute;
map.routing.OnErrorRoute := doOnErrorRoute ;
map.Routing.OnChangeRoute:= doOnChangeRoute;

procedure TFDemoNativeRoute.doOnAddRoute(sender: TECShapeLine;const params:string);
// sender is the route (TECShapeLine)
// params this is the URL sent to the routing engine

procedure TFDemoNativeRoute.doOnErrorRoute(sender: TObject;const params:string);
// sender is a TECThreadDataRoute
ShowMessage('Route not found !');

procedure TFDemoNativeRoute.doOnChangeRoute(sender: TECShapeLine;const params:string);
if not assigned(sender) then exit;

showMessage ( doubleToStrDigit(sender.Distance, 2) + 'km - ' +
doubleToStrDigit(sender.Duration / 3600, 2)+'h' ) ;


property line: TECShapeLine

The way ahead

function Position(const Lat, Lng: double):boolean

Specify your GPS position

property AlertDistance: integer

By default 300 meters

property ExecutionDistance: integer

Default 100 meters

property ErrorDistance: integer

Default 30 meters

property NextInstruction:string

Next statement to follow

Available in the OnInstruction event


property NextManeuver: string ;

List of operations (in the form of a json string containing various parameters depending on the engine used)

Available in the OnInstruction event


property NextInstructionInKm: double ;

Distance in KM for the next instruction

Available in the OnInstruction event


property NextInstructionPosition: TLatLng ;

Geographical position of the next instruction

Available in the OnInstruction event


available events

property OnAlert: TOnTurnByTurnAlert

Triggered when you arrive less than AlertDistance meters from the target

property OnInstruction: TOnTurnByTurnInstruction

Triggered when you arrive less than ExecutionDistance meters from the target

property OnArrival: TNotifyEvent

property OnError: TOnTurnByTurnError

property OnAfterInstruction: TOnTurnByTurnInstruction

property OnConnectRoute: TNotifyEvent

Triggered by a road connection

property OnDeconnectRoute: TNotifyEvent

Triggered by the disconnection of a road

Fig. 1 DemoNativeRoute

The DemoNativeRoute demo has been rewritten to use the new feature.


Old methods, use new features available since version 2.7


Search for routes

You have at your disposal 4 routines (2 synchronous et 2 asynchronous) to calculate a route.

function GetRoutePathByAddress(const StartAdress, EndAdress: string;const routeType:TMQRouteType = rtFastest const params: string = '' ): TECRoutePath

function GetRoutePathFrom(const dLatLngs: array of double;const routeType:TMQRouteType = rtFastest ;const params: string = '' ): TECRoutePath

procedure GetASyncRoutePathByAddress(const StartAdress, EndAdress: string;const routeType:TMQRouteType = rtFastest ;const params: string = '' )

procedure GetASyncRoutePathFrom(const dLatLngs: array of double;const routeType:TMQRouteType = rtFastest ;const params: string = '' )

These functions allow to obtain information from a route without trace, asynchronous procedures will run in background and raise the OnRoutePath event when the data are available.

See for the parameter Params


If you do not release the TECMapRoutePath obtained, it will be automatically during the destruction of TECNativeMap


Display the route

You can create a TECShapeLine from one TECMapRoutePath with the function AddRoute

// Delphi map component ECMap

var line : TECShapeLine;
// ge data road between Tarbes and Lourdes via Aureilhan
routePath := map.GetRoutePathByAddress('Tarbes','Aureilhan|Lourdes');
// draw polyline from routePath
if routePath<>nil then

// change line 0 with new data
if map.shapes.lines.count>0 then
// see the entire route

You can also directly edit a TECShapeLine with the procedure setRoutePath

// Delphi map component ECMap

var line : TECShapeLine;
// ge data road between Tarbes and Lourdes via Aureilhan
routePath := map.GetRoutePathByAddress('Tarbes','Aureilhan|Lourdes');
// draw polyline from routePath
if routePath<>nil then

// change line 0 with new data
if map.shapes.lines.count>0 then
// see the entire route

Edit the road with the mouse

For this you will need to add the unit uecEditNativeLine (FMX.uecEditNativeLine under FireMonkey)

You can then use the TecNativeLineToRoute class to be able to dynamically change the route.

property Line : TECShapeLine
TECShapeLine to modify
property RouteType : TMQRouteType
type of road ( rtFastest, rtShortest, rtPedestrian, rtBicycle )
property Modified : boolean
Indicates if the road was amended
property OnClick : TOnShapeMousePoint
To respond to the click on the road
property OnMouseOver : TOnShapeMousePoint
Can respond to the overview of the road
property OnChange : TNotifyEvent
Triggered event has each modification of the road

Example of use

// Delphi map component ECMap

var ecNativeLineToRoute : TecNativeLineToRoute;
ecNativeLineToRoute := TecNativeLineToRoute.create;

// edit route
ecNativeLineToRoute.Line := map.shapes.Lines[0];

// end edit route
ecNativeLineToRoute.Line := nil;


A demonstration is available to understand the management of roads.

Fig. 2 DemoNativeRoute

Draw a path with the mouse or finger

TECNativeMap has a wizard that allows you to draw your paths in a few clicks, the route will automatically follow the road between your points.

Fig. 3 DrawPath

property Activate: boolean
Activate / Deactivate the tracing assistant.
procedure AddPoint;
Add the central point, the trace will be calculated between this one and the previous point

By clicking directly in the center of the screen on the target you also trigger this action.


property AddPointOnClick : boolean

Allows you to choose a point simply by clicking on the map and not just in the center.
function GetPath(const Line: TECShapeLine): boolean;
Retrieves the plot in a TECShapeLine and exits the wizard.
procedure Undo;
Cancels the last segment, you can cancel all the segments one after the other.
map.DrawPath.Activate := true;
map.DrawPath.AddPointOnClick := true;

var line : TECShapeLine;
line := map.shapes.AddLine;
map.DrawPath.GetPath(Line) ;

property PathType: TECDrawPathType

You can either directly draw line segments between your points, or have them follow a pedestrian, bicycle or car route.
map.DrawPath.PathType := dptStraight;
map.DrawPath.PathType := dptPedestrian;
map.DrawPath.PathType := dptBicycle;
map.DrawPath.PathType := dptCar;

property CursorData : string

Allows to define the central target through a string containing graphic instructions, it is the equivalent of TPathData.Data

Available only under Firemonkey.


property Name: string

Name of the group containing the trace, you can use it to define its style.
// You can redefine all the properties of the lines,
// here we will change the color
// add unit uecMapUtil for use ColorToHTML
Map.Styles.addRule('#' + map.DrawPath.Name + '.line {color:'+ColorToHTML(ColorPathLine.Color)+ '}');

property isReady: boolean

Indicates if the wizard has finished calculating a route, you cannot quit or delete a segment while a trace is pending in a secondary thread.
property isUndo: boolean
Indicates if you can cancel the last segment

property OnPaintCursor: TECDrawPathPaintCursor

You can take over the entire design of the central target.
map.DrawPath.OnPaintCursor := doPaintCursor;
// We draw a simple cross in the center of the map,
// the same as in VCL mode
// add unit uecGraphics for TECCanvas
procedure TForm7.doPaintCursor(const canvas:TECCanvas);
var X, Y: integer;

// convert center position to local X,Y
Map.FromLatLngToXY(Map.Center, X, Y);


canvas.Polyline([Point(X, Y - 10), Point(X, Y + 10)]);
canvas.Polyline([Point(X - 10, Y), Point(X + 10, Y)]);


property OnActivate : TECDrawPathActivate

The event is triggered when the assistant is activated or deactivated

property OnReady: TECDrawPathReady

Triggered before the road calculation request and once it is completed
map.DrawPath.OnActivate := doOnActivate;
map.DrawPath.OnReady := doOnReady;

// This event occurs before and after the calculation
// of the route in a thread,
// while the segment is being calculated
// you can neither validate the route
// nor cancel the last segment
procedure TForm7.doOnReady(const Ready:boolean);
Validate.Enabled := Ready and map.DrawPath.activate;
Undo.Enabled := Ready and map.DrawPath.isUndo;

// Activation / deactivation of route tracing
procedure TForm7.doOnActivate(const Activate:boolean);
AddPoint.Enabled := Activate;
Guidance.Enabled := Activate;

if Activate then
Active_deactive.Text := 'Deactivate' ;
Guidance.ItemIndex := integer(map.DrawPath.PathType);
Active_deactive.Text := 'Activate'


property OnError : TNotifyEvent ;

Triggered if the calculation of the route could not take place.


The isochrone service calculates the areas that are reachable within specified time or distance intervals from a location, and returns the reachable regions as polygon or line contours.

Fig. 4 zones accessibles à 5, 10, 15 et 20 minutes à bicyclette

Only Valhalla and MapBox have this service, note that MapBox uses Valhalla and as it is an opensource software you can also build your own server.


You can request up to 4 isochrones per call, and the maximum distance is 100km.

// To use your own Valhalla server set ServerURL
map.Routing.IsoChrone.ServerURL := 'xxx';
// 5, 10, 15 and 20 minutes by bicycle
map.routing.IsoChrone.Time(map.latitude,map.longitude,map.shapes.Polygones,[ 5,10,15,20],rtbicycle) ;
// delineate the 2 and 4.5 km walkable areas
map.routing.IsoChrone.Distance(map.latitude,map.longitude,map[ 'isoGroup'].lines,[2,4.5],rtPedestrian) ;
// other syntax by passing directly the polygons and lines
var P,P1:TECShapePolygone;
P := map.addPolygone;
P1:= map.addPolygones;
map.routing.IsoChrone.Time(map.latitude,map.longitude,[P,P1],[ 5,10],rtCar) ;

L := map.addLine('your_group');
map.routing.IsoChrone.Distance(map.latitude,map.longitude,[L],[ 80],rtPedestrian) ;

The returned polygons and lines have isoTime and isoDistance properties that contain the requested values, you can use them to style your elements.

// styles used in the image above
go to page
Réalisé avec la version gratuite pour les particuliers d'Help&Web