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

Routes

Clefs pour les API

Par défaut TECNativeMap utilise les services d'OpenStreetMap.

Si vous souhaitez utiliser PTV, TomTom ou MapBox vous devez vous enregistrer sur leur site pour obtenir une clef.

Mode hors-ligne

Si vous indiquez un répertoire dans la propriété LocalCache, toutes les données des routes seront mise en cache et pourront être réutilisées en mode hors-ligne.


TECRouting

Cette classe gère les routes ainsi que la navigation tour par tour.

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); overload;

Calculer une route entre des adresses ou des points
map.Routing.routeType := rtCar;
// get data road between Tarbes and Paris
map.Routing.Request('Tarbes','Paris');
// get data road between Tarbes and Lourdes via Aureilhan
map.Routing.Request('Tarbes','Aureilhan|Lourdes');
// you can also pass a array of coordinate pairs
map.Routing.Request([43.232858,0.0781021,43.2426749,0.0965226]);
Params vous permet de passer des paramètres supplémentaires au moteur de routage

Attention pour OpenStreetMap et OSRM vous devez vous assurez de passer des paramètres valides, voir la documentation (identique pour les deux car le moteur est le même)

1
FutureRoute est une ligne vide qui sera initialisée avec les données retournées par le moteur de routage, cela vous permet d'attacher des paramètres qui pourront vous servir lorsque la route sera finalisée dans OnAddRoute;

property routeType: TMQRouteType

Type de route ( rtCar,rtTruck,rtFastest, rtShortest , rtPedestrian, rtBicycle )

Seul PTV, TomTom et Valhalla supportent rtTruck

2

property OptimizeRoute : boolean

Optimisation du calcul, seul les moteurs de MapBox et TomTom supportent cette fonctionnalité

property GroupName : string

Nom du groupe auquel appartiendra la nouvelle route (TECShapeLine), par défaut vide

function FutureRoute:TECShapeLine;

retourne une ligne vide que vous pouvez passer à 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
begin
map.Routing.RouteType := rtPedestrian ;
RouteLine.propertyValue['speed']:='6';
end
else if rbBicycling.ischecked then
begin
map.Routing.RouteType := rtBicycle ;
RouteLine.propertyValue['speed']:='20';
end
else
begin
map.Routing.RouteType := rtCar;
RouteLine.propertyValue['speed']:='50';
end;

// 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);
begin
// sender is the route (TECShapeLine)
// params this is the URL sent to the routing engine
end;

property Color : TColor

Couleur de la route

property Weight: integer

Épaisseur de la route

property StartMarkerFilename: string

Image utilisée pour marquer le départ, par défaut

property EndMarkerFilename: string

Image utilisée pour marquer l'arrivée, par défaut

property RouteDrawingTime: integer

Temps (en milliseconde) pour afficher la route, permet de réaliser une animation pour un affichage progressif.
Par défaut 0, la route s'affiche en une seule fois.

property EditRoute: TECShapeLine

Permet de modifier la route avec la souris

property EditOnClick : boolean

Par défaut un clic sur une route la fait basculer en mode édition, il suffit de cliquer sur les points A ou B pour quitter ce mode

Moteur de routage

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

Permet de choisir un moteur de routage, au choix, OpenStreetMap, PTV, Valhalla, TomTom, OSRM ou MapBox

map.routing.Engine(reOpenStreetMap);
map.routing.Engine(reValhalla);
map.routing.Engine(reTomTom,'your_key');
map.routing.Engine(reOSRM);
map.routing.Engine(reMapBox,'your_token');
map.routing.Engine(rePTV,'your_key');

Utilisez EngineValidUrl pour modifier l'url avant quelle ne soit envoyée au moteur

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

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

end;

Définir son propre moteur

Utilisez EngineUrl, EngineExcute pour utiliser votre propre moteur.

property EngineUrl : TECThreadRoutingUrl

property EngineExecute : TECThreadRoutingExecute

Map.Routing.Engine(reCustom);
Map.Routing.EngineName := yourRouting_Name;
Map.Routing.EngineUrl := yourRouting_URL;
Map.Routing.EngineExecute := yourRouting_Execute;
...
procedure yourRouting_URL(sender: TECThreadDataRoute);
begin
//
end;

procedure yourRouting_Execute(sender: TECThreadDataRoute; var Valid: boolean);
begin
//
end;

EngineUrl et EngineExecute sont exécutés dans un autre thread !

1

property EngineName : string

Donne un nom au moteur, utilisé pour le stockage local

property EngineKey : string

Clef pour utiliser le moteur, vous devez obtenir les votres auprès de TomTom ou MapBox

property TurnByTurn: TECTurnByTurn

Gestion de la navigation tour par tour

4 événements sont disponibles

property OnAddRoute : TOnAddRoute
Déclenché lorsque la route a été crée
property OnChangeRoute : TOnChangeRoute
Déclenché lorsque la route a été modifiée
property OnErrorRoute : TOnErrorRoute
Déclenché si la route n'a pas été créée
property OnDrawRoute : TOnDrawRoute
Déclenché lorsque la route a été affichée intégralement (utile si RouteDrawingTime > 0)
map.Routing.OnAddRoute := doOnAddRoute;
map.routing.OnErrorRoute := doOnErrorRoute ;
map.Routing.OnChangeRoute:= doOnChangeRoute;

procedure TFDemoNativeRoute.doOnAddRoute(sender: TECShapeLine;const params:string);
var i:integer;
PLine : TECPointLine;
begin
// sender is the route (TECShapeLine)
// params this is the URL sent to the routing engine

for i := 0 to sender.Count-1 do
begin
// roadside information points
PLine := sender[i];
PLine.Latitude;
PLine.Longitude;
PLine.Distance; // meters
PLine.Tex;
PLine.Time; // TDateTime
PLine.Maneuver;
end;
end;

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

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

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


Itinerary

Cette propriétée permet de construire et gérer plus simplement l'itinéraire inclus dans la route.

Fig. 1 Demo Itinerary

procedure ShowInstruction(const index: integer);

Affiche une infoWindow contenant l'instruction numéro index

procedure ShowSegment(const index: integer);

Zoom sur le segment index

property Count: integer

Nombre total de segments

property Route: TECShapeLine

Connecter la route dont on veux gérer l'itinéraire.

property SegmentRoute: TECShapeLine

Contient une ligne représentant le segment sélectionné, vous pouvez y accéder pour gérer son apparence.

property Segment[const index: integer]: TECItinerarySegment

Tableau contenant l'ensemble des segments

TECItinerarySegment

property Instruction: string
Instruction à l'entrée du segment
property Manoeuver: string
chaine JSON retournée par le moteur de routage contenant l'ensemble des données de la manoeuvre
property DistanceKm: double
Distance en km du segment
property PointA : TLatLng
Latitude et longitude du début du segment
property PointB : TLatLng
Latitude et longitude de la fin du segment

property SegmentIndex: integer

Permet de sélectionner un segment

property OnSelectedItinerarySegment: TOnSelectedItinerarySegment

Événement déclenché lors d'un click sur la route dont on gère l'itinéraire

property OnChangeRoute : TNotifyEvent

Événement déclenché lors d'un click sur une route qui n'est pas celle de l'itinéraire
procedure TItineraryForm.FormCreate(Sender: TObject);
begin
Map.Routing.OnAddRoute := doOnAddRoute;
Map.Routing.itinerary.OnSelectedItinerarySegment :=
doOnSelectedItinerarySegment;

Map.Routing.Itinerary.OnChangeRoute := doChangeRoute;
end;

// request new route
procedure TItineraryForm.AddRouteClick(Sender: TObject);
begin
// select engine routing
case engine.ItemIndex of
0 : map.Routing.Engine(reOpenStreetMap);
1 : map.Routing.Engine(reValhalla);
end;
// select route type
case vehicle.ItemIndex of
0:
Map.Routing.routeType := rtPedestrian;
1:
Map.Routing.routeType := rtBicycle;
2:
Map.Routing.routeType := rtCar;
3:
Map.Routing.routeType := rtTruck;
end;

Map.Routing.Request(StartRoute.Text, EndRoute.Text);
end;

// event triggered when the route has been calculated and is available
procedure TItineraryForm.doOnAddRoute(Sender: TECShapeLine; const params: string);
begin
Sender.Focusable := false;
Sender.Color := GetRandomColor;
// show all road
Sender.fitBounds;
BuildItinerary(Sender);
end;

// build route planner
procedure TItineraryForm.BuildItinerary(const route: TECShapeLine);
var
i: integer;
d: double;
distance: string;
begin
// connect route
Map.Routing.itinerary.route := route;

itinerary.Items.Clear;
itinerary.Items.BeginUpdate;

for i := 0 to Map.Routing.itinerary.Count - 1 do
begin
// calculate distance
d := Map.Routing.itinerary[i].Distancekm;
if d < 1 then
distance := inttostr(round(d * 1000)) + 'm'
else
distance := DoubleToStrDigit(d, 2) + 'km' ;

itinerary.Items.Add(Map.Routing.itinerary[i].Instruction + ' (' +
distance + ')');

end;

itinerary.Items.EndUpdate;

itinerary.ItemIndex := Map.Routing.itinerary.SegmentIndex;
end;

// click on route planner
procedure TItineraryForm.itineraryClick(Sender: TObject);
begin
SelectSegment(itinerary.ItemIndex);
end;

// Triggered by Click on Map.Routing.itinerary.route
procedure TItineraryForm.doOnSelectedItinerarySegment(Sender: TECItinerary);
begin
SelectSegment(Sender.SegmentIndex);
end;

// Triggered by Click of a route <> Map.Routing.itinerary.route
procedure TItineraryForm.doChangeRoute(Sender: TObject);
begin
BuildItinerary(Sender as TECShapeLine)
end;


procedure TItineraryForm.SelectSegment(const index: integer);
var selected_segment: TECShapeLine;
begin

if index < 0 then
exit;

itinerary.ItemIndex := Index;

Map.Routing.itinerary.SegmentIndex := index;

selected_segment := Map.Routing.itinerary.SegmentRoute;

if not assigned(Map.Routing.itinerary.SegmentRoute) then
exit;

// move map for show segment
Map.Routing.itinerary.ShowSegment(index);

// you can also change color of selected_segment here

// Flash the segment 20 times per 250 ms period
// the animation will be automatically released when required
selected_segment.animation := TECAnimationShapeColor.create(20);
selected_segment.animation.Timing := 250;

// show infowindow with segment instruction
Map.Routing.itinerary.ShowInstruction(index);

end;

TECTurnByTurn

property line: TECShapeLine

Route à suivre

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

Indiquez votre position GPS

property AlertDistance: integer

Par défaut 300 mètres

property ExecutionDistance: integer

Par défaut 100 mètres

property ErrorDistance: integer

Par défaut 30 mètres

property NextInstruction:string

Prochaine instruction à suivre

Disponible dans l'événement OnInstruction

2

property NextManeuver: string ;

Liste des manoeuvres (sous la forme d'une chaine json contenant divers paramètres en fonction du moteur utilisé)

Disponible dans l'événement OnInstruction

3

property NextInstructionInKm: double ;

Distance en KM pour la prochaine instruction

Disponible dans l'événement OnInstruction

4

property NextInstructionPosition: TLatLng ;

Position géographique de la prochaine instruction

Disponible dans l'événement OnInstruction

5

événements disponibles

property OnAlert: TOnTurnByTurnAlert

Déclenché lorsque vous arrivez à moins de AlertDistance mètres de la cible

property OnInstruction: TOnTurnByTurnInstruction

Déclenché lorsque vous arrivez à moins de ExecutionDistance mètres de la cible

property OnArrival: TNotifyEvent

property OnError: TOnTurnByTurnError

property OnAfterInstruction: TOnTurnByTurnInstruction

property OnConnectRoute: TNotifyEvent

Déclenché par la connection d'une route

property OnDeconnectRoute: TNotifyEvent

Déclenché par la déconnection d'une route

Fig. 2 DemoNativeRoute

La demo DemoNativeRoute a été réécrite pour utiliser ces nouvelles fonctionnalité.

1

Anciennes méthodes, privilégiez les nouvelles fonctionnalités disponible depuis la version 2.7

1

Recherche de routes

Vous avez à votre disposition 4 routines (2 synchrones et 2 asynchrones) pour calculer un itinéraire.

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 = '' )


Ces fonctions permettent d'obtenir les informations d'une route sans effectuer de tracé, les procedures asynchrones vont s'exécuter en arrière-plan et déclencher l'évenement OnRoutePath lorsque les données sont disponibles.

Voir open.mapquestapi.com/directions/ pour le paramètre Params

6

Si vous ne libérez pas le TECMapRoutePath obtenu, il le sera automatiquement lors de la destruction de TECNativeMap

7

Afficher la route

Vous pouvez créer une TECShapeLine à partir d'un TECMapRoutePath avec la fonction 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
begin

// change line 0 with new data
if map.shapes.lines.count>0 then
map.shapes.lines[0].setRoutePath(routePath);
// see the entire route
map.fitBounds(line.NorthEastLatitude,line.NorthEastLongitude,line.SouthWestLatitude,line.SouthWestLongitude);

routePath.free;
end;

Vous pouvez aussi directement modifier une TECShapeLine avec la 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
begin

// change line 0 with new data
if map.shapes.lines.count>0 then
map.shapes.lines[0].setRoutePath(routePath);
// see the entire route
map.fitBounds(line.NorthEastLatitude,line.NorthEastLongitude,line.SouthWestLatitude,line.SouthWestLongitude);

routePath.free;
end;

Modifier la route à la souris

Pour cela vous allez devoir rajouter l'unité uecEditNativeLine ( FMX.uecEditNativeLine sous FireMonkey)

Vous pourrez alors utiliser la classe TecNativeLineToRoute pour pouvoir modifier dynamiquement le trajet.

property Line : TECShapeLine
TECShapeLine à modifier
property RouteType : TMQRouteType
type de route ( rtFastest, rtShortest, rtPedestrian, rtBicycle )
property Modified : boolean
Indique si la route à été modifié
property OnClick : TOnShapeMousePoint
Permet de réagir au clic sur la route
property OnMouseOver : TOnShapeMousePoint
Permet de réagir au survol de la route
property OnChange : TNotifyEvent
Évenement déclenché a chaque modification de la route

Exemple d'utilisation

// Delphi map component ECMap

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

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

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

DemoNativeRoute

Une démonstration est disponible pour bien comprendre la gestion des routes.

Fig. 3 DemoNativeRoute - Turn by turn

Tracer un chemin à la souris ou au doigt

TECNativeMap dispose d'un assistant qui vous permet de tracer vos chemins en quelques clics, le parcours suivra automatiquent la route entre vos points.

Fig. 4 DrawPath

property Activate: boolean
Activer / Désactiver l'assistant traçage.
procedure AddPoint;
Ajoute le point central, la trace va être calculée entre celui-ci et le point précédent
procedure AddPoint(const latitude,longitude);
Ajoute le point de votre choix, la trace va être calculée entre celui-ci et le point précédent

En cliquant directement au centre de l'écran sur la cible vous déclenchez aussi cette action.

2

property AddPointOnClick : boolean

Permet de choisir un point simplement en cliquant sur la carte et pas seulement au centre.
function GetPath(const Line: TECShapeLine): boolean;
Récupère le tracé dans une TECShapeLine et quitte l'assistant.
procedure Undo;
Annule le dernier segment, vous pouvez annuler l'ensemble des segments l'un après l'autre.
map.DrawPath.Activate := true;
map.DrawPath.AddPoint;
map.DrawPath.AddPointOnClick := true;
map.DrawPath.Undo;

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

property PathType: TECDrawPathType

Vous pouvez soit dessiner directement des segments de droite entre vos points, soit demander à ce qu'ils suivent une route pour piéton, bicyclette ou voiture.
map.DrawPath.PathType := dptStraight;
map.DrawPath.PathType := dptPedestrian;
map.DrawPath.PathType := dptBicycle;
map.DrawPath.PathType := dptCar;

property CursorData : string

Permet de définir la cible centrale au travers d'une chaine contenant des instructions graphique, c'est l'équivalent de TPathData.Data

Disponible uniquement sous Firemonkey.

3

property Name: string

Nom du groupe contenant la trace, vous pouvez l'utiliser pour définir son 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

Indique si l'assistant a terminé de calculer une route, vous ne pouvez pas quitter ou supprimer un segment tant qu'une trace est en attente dans un thread secondaire.
property isUndo: boolean
Indique si vous pouvez annuler le dernier segment

property OnPaintCursor: TECDrawPathPaintCursor

Vous pouvez prendre en charge intégralement le dessin de la cible centrale.
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;
begin

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

canvas.PenWidth(2);

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

end;

property OnActivate : TECDrawPathActivate

L'événement est déclenché lorsque l'assistant est activé ou désactivé

property OnReady: TECDrawPathReady

Déclenché avant la demande de calcul routier et une fois que celui-ci est terminé
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);
begin
Validate.Enabled := Ready and map.DrawPath.activate;
Undo.Enabled := Ready and map.DrawPath.isUndo;
end;

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

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

end;

property OnError : TNotifyEvent ;

Déclenché si le calcul de la route n'a pas pu avoir lieu.

IsoChrone

Le service isochrone calcule les zones qui sont accessibles dans des intervalles de temps ou de distances spécifiés à partir d'un emplacement, et renvoie les régions accessibles sous forme de contours de polygones ou de lignes.

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

Seul Valhalla et MapBox disposent de ce service, à noter que MapBox utilise Valhalla et comme c'est un logiciel opensource vous pouvez vous aussi vous monter votre propre serveur.

8

Vous pouvez demander jusqu'a 4 isochrones par appel, et la distance maximale est de 100km.

map.Routing.Engine(reValhalla);
// To use your own Valhalla server set ServerURL
map.Routing.IsoChrone.ServerURL := 'xxx';
map.Routing.engine(reMapBox,map.MapBoxToken);
// 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;
L:TECShapeLine;
...
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) ;


Les polygones et lignes retournées ont des propriétés isoTime et isoDistance qui contiennent les valeurs demandées, vous pouvez vous en servir pour styler vos éléments.

// styles used in the image above
map.styles.addRule('.polygone{if:isotime>0;color:dark(grey)}');
map.styles.addRule('.polygone{if:isotime<21;fcolor:red}');
map.styles.addRule('.polygone{if:isotime<16;fcolor:#d97200}');
map.styles.addRule('.polygone{if:isotime<11;fcolor:yellow}');
map.styles.addRule('.polygone{if:isotime<6;fcolor:green}');
Aller à la page
Réalisé avec la version gratuite pour les particuliers d'Help&Web