Hi
I am adapted a function you describe here
https://support.tmssoftware.com/t/geocoding-with-callback-not-processed-into-datamodule/14166/6
My function returns a TTMSFNCGeocodingItems variable.
Thus I created a variable and destroy it later following this way, is it correct ?
procedure TfMigration.Button27Click(Sender: TObject);
var
coor: TTMSFNCMapsCoordinate;
Infos: string;
Georefs: TTMSFNCGeocodingItems;
Succes : Boolean;
begin
TRY
TRY
fPrincipal.FNCGeocoding.service := gsHere;
fPrincipal.FNCGeocoding.APIKey := 'xxxxxx';
Georefs := TTMSFNCGeocodingItems.Create(NIL);
Georefs := FPrincipal.GetGeocoding('london', Succes, Infos);
IF Succes THEN
Edit1.Text := Georefs.Items[0].Address;
EXCEPT
ON E: System.SysUtils.Exception DO
BEGIN
END;
END; // Fin de EXCEPT
FINALLY
Georefs.Free;
END; // Fin de FINALLY
end;
regards
Hi,
You need to destroy the variable inside the callback or event, because the request is asynchronous:
Latitude := '';
Longitude:= '';
geocoder := TTMSFNCGeocoding.Create(ServerContainer); //<== ServerContainer = DataModule
geocoder.Service := gsGoogle;
geocoder.APIKey := 'zzzzzzz';
// Check if CodePostal is ... a CodePOstal
// Retrieve Lat, Long from ZIP code
sTempAdr := CodePostal+',France';
geocoder.GetGeocoding(sTempAdr,
procedure(const ARequest: TTMSFNCGeocodingRequest; const ARequestResult: TTMSFNCCloudBaseRequestResult)
begin
Longitude := ARequest.Items[0].Coordinate.longitude.ToString;
Latitude := ARequest.Items[0].Coordinate.Latitude.ToString;
FreeAndNil(geocoder);
end
);
..
What you can do as well is converting the method into a synchronous implementation with the following code:
unit Unit10;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.TMSFNCCustomComponent, FMX.TMSFNCCloudBase, FMX.TMSFNCGeocoding, FMX.TMSFNCMapsCommonTypes,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm10 = class(TForm)
TMSFNCGeocoding1: TTMSFNCGeocoding;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
FRequestResult: string;
function GetGeocoding(AAddress: string): TTMSFNCMapsCoordinateRec;
procedure DoRequestAddress(
const ARequestResult: TTMSFNCCloudBaseRequestResult);
{ Private declarations }
public
{ Public declarations }
end;
var
Form10: TForm10;
implementation
{$R *.fmx}
uses
FMX.TMSFNCUtils;
procedure TForm10.Button1Click(Sender: TObject);
var
c: TTMSFNCMapsCoordinateRec;
begin
c := GetGeocoding('MyAddress');
end;
procedure TForm10.DoRequestAddress(const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
FRequestResult := ARequestResult.ResultString;
end;
function TForm10.GetGeocoding(AAddress: string): TTMSFNCMapsCoordinateRec;
var
req: TTMSFNCGeocodingRequest;
lon, lat: Double;
begin
Result := DefaultCoordinate;
TMSFNCGeocoding1.APIKey := '';
TMSFNCGeocoding1.Service := gsHere;
TMSFNCGeocoding1.Request.Clear;
TMSFNCGeocoding1.Request.ClearHeaders;
TMSFNCGeocoding1.Request.Name := 'GET GEOCODING';
TMSFNCGeocoding1.Request.Method := TMSFNCGeocoding1.GeocodingInstance.GetRequestMethod;
TMSFNCGeocoding1.Request.Host := TMSFNCGeocoding1.GeocodingInstance.GetHost;
TMSFNCGeocoding1.Request.Path := TMSFNCGeocoding1.GeocodingInstance.GetPath(TTMSFNCUtils.URLEncode(AAddress));
TMSFNCGeocoding1.Request.Query := TMSFNCGeocoding1.GeocodingInstance.GetQuery(TTMSFNCUtils.URLEncode(AAddress));
TMSFNCGeocoding1.Request.PostData := TMSFNCGeocoding1.GeocodingInstance.GetPostData;
TMSFNCGeocoding1.ExecuteRequest(DoRequestAddress, nil, False);
if FRequestResult <> '' then
begin
req := TMSFNCGeocoding1.GeocodingRequests.Add;
TMSFNCGeocoding1.GeocodingInstance.Parse(req, FRequestResult);
lon := req.Items[0].Coordinate.longitude;
lat := req.Items[0].Coordinate.Latitude;
Result := CreateCoordinate(lat, lon);
end;
end;
end.
Thanks a lot
This is the solution I flinally used. I found it in an other post.
Possible to add this info into the PDF ?
regards
olivier
Well, this is a solution, but not the ideal one, we'll probably add a synchronous function that does the same thing instead, so before we update the documentation we'll need more time to investigate a permanent & more elegant solution to retrieve the coordinates in a synchronous way.
Of course, That will be a major improvement (at least for me) ;)
regards
I second this, adding a synchronous method to do geocoding would be really useful.
In the latest version, there is a sync version added. Use GetGeocodingSync to retrieve the value without needing a callback.