TTMSFNCGoogleMaps in a XData Service

I'm trying to create an xdata service that returns the distance and duration between 2 addresses, but I'm not succeeding. The way I tried to do the function stopped at "AddDirections" and did not return data.
Is there any other way to use TTMSFNCGoogleMaps in an XData Service?

Here is the code I used

unit Unit1;

interface

uses Classes, SysUtils, FireDAC.Comp.Client, FireDAC.DApt, IniFiles, Threading,
  VCL.TMSFNCTypes,
  VCL.TMSFNCUtils,
  VCL.TMSFNCGraphics,
  VCL.TMSFNCGraphicsTypes,
  VCL.TMSFNCCustomControl,
  VCL.TMSFNCMaps,
  VCL.TMSFNCGoogleMaps,
  VCL.TMSFNCGeoCoding,
  VCL.TMSFNCMapsCommonTypes,
  VCL.TMSFNCCloudBase;

type
  TModelMaps = class
  private
    FTMSFNCGoogleMaps: TTMSFNCGoogleMaps;
    FApiKey: string;
    FDistanceDescription: String;
    FDurationDescription: String;
    FRequestFinished: Boolean;
    procedure EventRetrievedDirectionsData(Sender: TObject;
      AEventData: TTMSFNCMapsEventData;
      ADirectionsData: TTMSFNCGoogleMapsDirectionsData);
  public
    constructor Create;
    destructor Destroy; override;
    function GetDistanceAndDuration(sDestination: string;
      AOrigin: string = ''): Integer;
  end;

implementation

{ TModelMaps }

constructor TModelMaps.Create;
begin
  FTMSFNCGoogleMaps := TTMSFNCGoogleMaps.Create(nil);
  FTMSFNCGoogleMaps.Options.Version := 'beta';
  FTMSFNCGoogleMaps.Options.DefaultLatitude := 40.689247000000000000;
  FTMSFNCGoogleMaps.Options.DefaultLongitude := -74.044501999999990000;
  FTMSFNCGoogleMaps.Options.DefaultZoomLevel := 12.000000000000000000;
  FTMSFNCGoogleMaps.Options.DisablePOI := False;
  FTMSFNCGoogleMaps.APIKey := 'MY_API_KEY';
end;

destructor TModelMaps.Destroy;
begin
  FTMSFNCGoogleMaps.Free;
  inherited;
end;

function TModelMaps.GetDistanceAndDuration(sDestination: string;
  AOrigin: string = ''): Integer;
begin
  FDistanceDescription := EmptyStr;
  FDurationDescription := EmptyStr;

  FRequestFinished := False;

  FTMSFNCGoogleMaps.OnRetrievedDirectionsData := EventRetrievedDirectionsData;
  FTMSFNCGoogleMaps.AddDirections(AOrigin, sDestination, False, False);

  while not FRequestFinished do
    sleep(100);

  result := 0;
end;

procedure TModelMaps.EventRetrievedDirectionsData(Sender: TObject;
  AEventData: TTMSFNCMapsEventData;
  ADirectionsData: TTMSFNCGoogleMapsDirectionsData);
begin
  if Length(ADirectionsData.Routes) > 0 then
  begin
    FDistanceDescription :=
      CurrToStr(ADirectionsData.Routes[0].Legs[0].Distance / 1000);
    FDurationDescription :=
      IntToStr(Round(ADirectionsData.Routes[0].Legs[0].Duration / 60)) + ' min';
  end;

  FRequestFinished := true;
end;

end.

I suppose the issue is that the map is not initialized because it has no parent. To retrieve directions I suggest to use the TTMSFNCDirections component instead which is a non visual. You can also use your Google API key for that component.

I had already read the documentation for this component and realized that it is only possible to use it by passing the origin and destination coordinates.

image

Is it possible to pass the origin and destination address as a string (the same way I tried to do in the TTMSFNCGoogleMaps component) to this TTMSFNCDirections component?

It's currently not supported to provide addresses as a string for TTMSFNCDirections.
However, it's on the planning to support this in a future version.

The workaround is using TTMSFNCGeocoding to convert your address strings to coordinates first.

Thank you guys for your help. I will implement this as soon as possible!

Happy to help!