Table of Contents

TMS FNC Directions — Guides

Requests and multi-stop routes

Add intermediate stops by populating Request.WayPoints with TTMSFNCDirectionsWayPoint items before calling GetDirections.

Travel mode

Set Request.TravelMode to control whether directions are calculated for driving, walking, or cycling. Available values depend on the selected service backend.

Result handling

Handle OnGetDirections to receive route results. Each TTMSFNCDirectionsItem in the returned collection contains a list of TTMSFNCDirectionsLeg entries, each with Steps for turn-by-turn instructions.

Service backends

Set the Service property to select the routing engine. Different backends offer different travel modes, coverage areas, and truck-routing options. TTMSFNCDirectionsService currently supports dsGoogle, dsHere, dsBing, dsAzure, dsMapBox, dsTomTom, dsOpenRouteService, and dsGeoApify.

Reach for a specific backend based on coverage and pricing: dsOpenRouteService is a good option for an open-data routing engine without a commercial API key requirement for low volumes, and dsGeoApify bundles routing with the rest of the Geoapify location platform if the application already uses its geocoding or places APIs. Both are selected the same way as any other backend — set Service and APIKey before calling GetDirections.

For Google specifically, UseGoogleRoutes switches the request format from the legacy Google Directions API to the newer Google Routes API while keeping Service set to dsGoogle. Prefer UseGoogleRoutes := True for new projects — the Routes API is Google's actively developed routing surface — and keep it False only when an existing integration already depends on the legacy Directions response shape.

procedure TForm1.SelectGeoApifyService;
begin
  { Route through the Geoapify directions backend. }
  TMSFNCDirections1.Service := dsGeoApify;
  TMSFNCDirections1.APIKey := 'YOUR-GEOAPIFY-API-KEY';
end;

procedure TForm1.SelectOpenRouteServiceService;
begin
  { Route through the OpenRouteService directions backend. }
  TMSFNCDirections1.Service := dsOpenRouteService;
  TMSFNCDirections1.APIKey := 'YOUR-OPENROUTESERVICE-API-KEY';
end;

procedure TForm1.SelectGoogleRoutesService;
begin
  { Stay on the Google provider, but request routes through the newer
    Google Routes API instead of the legacy Google Directions API. }
  TMSFNCDirections1.Service := dsGoogle;
  TMSFNCDirections1.UseGoogleRoutes := True;
  TMSFNCDirections1.APIKey := 'YOUR-GOOGLE-API-KEY';
end;

Route options

Beyond the travel mode, a request can steer the route away from tolls or highways, and can be issued through progressively simpler call forms once the defaults fit.

AAvoidTolls and AAvoidHighWays are optional parameters on every GetDirections and GetDirectionsResult overload. Support depends on the selected backend; a provider that does not support one of the flags ignores it rather than raising an error. Pass them directly on the full overload, or set the equivalent AvoidTolls/AvoidHighways fields on a TTMSFNCDirectionsOptionsRec and use the simplified overload that takes only the origin, destination, and options record — DefaultDirectionsOptions returns a record pre-populated with the component's defaults so only the fields that need to change have to be set.

procedure TForm1.RequestAvoidingTollsAndHighways;
var
  Origin, Destination: TTMSFNCMapsCoordinateRec;
begin
  Origin.Latitude := 51.5074;
  Origin.Longitude := -0.1278;
  Destination.Latitude := 48.8566;
  Destination.Longitude := 2.3522;

  { AAvoidTolls and AAvoidHighWays are supported when the selected Service
    exposes them; unsupported providers ignore the flag. }
  TMSFNCDirections1.GetDirections(Origin, Destination, nil, '', nil, False,
    tmDriving, nil, False, '', mlmDefault, True { AvoidTolls }, True { AvoidHighWays });
end;

procedure TForm1.RequestWithOptionsRecord;
var
  Origin, Destination: TTMSFNCMapsCoordinateRec;
  Options: TTMSFNCDirectionsOptionsRec;
begin
  Origin.Latitude := 51.5074;
  Origin.Longitude := -0.1278;
  Destination.Latitude := 48.8566;
  Destination.Longitude := 2.3522;

  { DefaultDirectionsOptions returns a record pre-filled with the default
    travel mode and flags, so only the fields that differ need to be set. }
  Options := DefaultDirectionsOptions;
  Options.TravelMode := tmTruck;
  Options.AvoidTolls := True;
  Options.AvoidHighways := True;

  { Simplified overload: pass the coordinates and one options record instead
    of the full parameter list. }
  TMSFNCDirections1.GetDirections(Origin, Destination, Options);
end;

Multi-provider waypoints

Waypoints can be supplied and read back in more than one form depending on the backend and whether waypoint reordering was requested.

For Google, GetDirections/GetDirectionsResult accept plain address strings for AOrigin and ADestination — and for waypoints via the TStringList overload — as an alternative to TTMSFNCMapsCoordinateRec coordinates. This is convenient when the application already works with addresses and does not need to geocode them first. Other backends require coordinates; passing a string origin/destination to a non-Google service raises an exception.

When AOptimizeWayPoints is True and the backend is Google, HERE, or TomTom, each returned TTMSFNCDirectionsWayPoint.OptimizedIndex reports the position that waypoint was moved to in the provider-optimized visiting order, so the application can re-sort its own waypoint list or stop list to match the order actually driven.

procedure TForm1.TMSFNCDirections1GetDirectionsResult(Sender: TObject;
  const AResult: TTMSFNCDirectionsRequest);
var
  I: Integer;
begin
  { WayPoints.OptimizedIndex reports, per waypoint, its position in the
    provider-optimized visiting order (Google, HERE and TomTom only). }
  if AResult.Items.Count > 0 then
    for I := 0 to AResult.Items[0].WayPoints.Count - 1 do
      { AResult.Items[0].WayPoints[I].OptimizedIndex is the visiting order
        the provider computed for waypoint I. }
      ;
end;

procedure TForm1.RequestWithAddressStrings;
begin
  { Google Directions/Routes accept plain address strings for the origin
    and destination in addition to coordinates; other providers require
    coordinates and raise an exception if a string is passed. }
  TMSFNCDirections1.Service := dsGoogle;
  TMSFNCDirections1.GetDirectionsResult('London, United Kingdom', 'Paris, France',
    TMSFNCDirections1GetDirectionsResult, '', nil, False, tmDriving, nil,
    True { OptimizeWayPoints });
end;

Result details and GPX export

Every TTMSFNCDirectionsLeg exposes the resolved StartAddress and EndAddress for that leg (Google), which is useful for display when the request itself was built from coordinates or waypoints rather than typed addresses.

A route's coordinates can also be exported as a GPX track for use in mapping and navigation tools outside the application. SaveToGPXFile, SaveToGPXStream, and SaveToGPXText all accept the same coordinate array and optional TTMSFNCDirectionsSteps/TTMSFNCMapsGPXMetaData, and only differ in the destination — a file path, an open stream, or an in-memory string. Passing AInstructions includes the route's step instructions as GPX waypoint descriptions; passing AMetaData sets the GPX author and track information.

procedure TForm1.TMSFNCDirections1GetDirections(Sender: TObject;
  const ARequest: TTMSFNCDirectionsRequest; const ARequestResult: TTMSFNCCloudBaseRequestResult);
var
  Item: TTMSFNCDirectionsItem;
  Leg: TTMSFNCDirectionsLeg;
  MetaData: TTMSFNCMapsGPXMetaData;
begin
  if ARequest.Items.Count = 0 then
    Exit;

  Item := ARequest.Items[0];

  { Google reports the resolved street address for the start and end of
    each leg, useful when the request used coordinates or waypoints and
    the human-readable address is still needed for display. }
  for Leg in Item.Legs do
    { Leg.StartAddress and Leg.EndAddress hold the resolved addresses. }
    ;

  MetaData.AuthorName := 'My Application';
  MetaData.TrackName := 'Exported route';
  MetaData.TrackType := 'driving';

  { Export the route coordinates as GPX, either straight to a file, ... }
  TMSFNCDirections1.SaveToGPXFile(Item.Coordinates.ToArray, 'route.gpx', MetaData, Item.Steps);

  { ... or as text for further processing / upload without touching disk. }
  ShowMessage(TMSFNCDirections1.SaveToGPXText(Item.Coordinates.ToArray, MetaData, Item.Steps));
end;

procedure TForm1.ExportRouteToStream(AStream: TStream; Item: TTMSFNCDirectionsItem);
begin
  { A GPX stream export is also available for cases that write to a
    TFileStream, TMemoryStream, or a custom destination. }
  TMSFNCDirections1.SaveToGPXStream(Item.Coordinates.ToArray, AStream, Item.Steps);
end;

See also