TMS FNC Places — Guides
Keyword and nearby search
Set Request.Query for keyword searches. Set Request.Coordinate and Request.Radius for nearby searches. Call GetPlaces and handle OnGetPlaces to receive results.
Controlling the nearby search radius
A nearby search normally returns every match around a center coordinate using
the backend's default radius. When the Google backend is switched to the
Places API (New) (see Google Places (New) API
below), the nearby search call accepts an explicit ARadius parameter, in
meters, so you can widen or narrow the search area for the use case — a small
radius for "coffee shops within walking distance", a large one for "hospitals
in the region".
ARadius is passed to SearchNearby (and its SearchNearbyResult /
SearchNearbySync overloads) as the last parameter. Passing 0, or omitting
it, falls back to a 50000 meter default. The parameter only affects requests
made through the Places API (New) — the legacy Google Places nearby search
always applies its own fixed radius regardless of the value passed.
procedure TForm1.SearchNearbyWithRadius;
var
Location: TTMSFNCMapsCoordinateRec;
begin
Location.Latitude := 51.5074;
Location.Longitude := -0.1278;
{ TMSFNCGooglePlaces1 is a TTMSFNCGooglePlaces component with
UseGooglePlacesNew set to True (see places-google-places-new.pas).
The ARadius parameter (in meters) is sent as the "radius" value of
the locationRestriction circle in the searchNearby JSON request body.
When ARadius is 0 or omitted, the component defaults to 50000 meters.
ARadius has no effect when UseGooglePlacesNew is False: the legacy
Google Places nearby search always uses a fixed radius. }
TMSFNCGooglePlaces1.SearchNearby(Location, 'cafe', nil, '', nil, '', mlmDefault, 1500);
end;
procedure TForm1.TMSFNCGooglePlaces1SearchNearby(Sender: TObject;
const ARequest: TTMSFNCPlacesRequest;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
var
I: Integer;
begin
{ Every item in ARequest.Items now falls within the requested
1500 meter radius of Location. }
for I := 0 to ARequest.Items.Count - 1 do
begin
{ Inspect ARequest.Items[I].Description, .Vicinity, .Coordinate, ... }
end;
end;
Place details
To retrieve detailed information about a specific place, call GetPlaceDetails with the place identifier returned in a previous search result.
Place photos
Place results include Photos (TTMSFNCPlacesPhotoItems). Each TTMSFNCPlacesPhotoItem contains a photo reference that can be used to retrieve the image URL via GetPhotoURL.
Service backends
Set the Service property to switch between available places providers:
Google (psGoogle, the default), Here (psHere), Geo Apify (psGeoApify),
Azure (psAzure), Bing (psBing), and TomTom (psTomTom). See
ITMSFNCPlacesService for the interface implemented by each backend.
{ Switch the places component to the TomTom backend: }
TMSFNCPlaces1.Service := psTomTom;
TMSFNCPlaces1.APIKey := 'YOUR-TOMTOM-API-KEY';
Each backend has its own API key format and its own quota/pricing model, so
changing Service typically also means updating APIKey for the newly
selected provider. Changing Service re-initializes the underlying service
instance; issue any pending request again after switching backends.
Google Places (New) API
The Google backend supports two generations of the Google Places REST API:
the original Google Places API (query-string requests against
maps.googleapis.com), and the newer Google Places API (New) (JSON POST
requests against places.googleapis.com, with the API key and a field mask
sent as request headers instead of URL parameters). Set
UseGooglePlacesNew to True to opt into the newer API — it changes the
host, endpoint paths, and request/response shape used for text search,
nearby search, autocomplete, and place-detail lookups, while keeping the same
TTMSFNCPlacesRequest / TTMSFNCPlacesItem result shape your event handlers
already consume. UseGooglePlacesNew is False by default, so existing
projects keep using the original Google Places API until they opt in.
UseGooglePlacesNew is available on TTMSFNCPlaces for the psGoogle
backend, but the request methods that use it (SearchByText, SearchNearby,
GetPlaceDetail) are only published on the Google-specific
TTMSFNCGooglePlaces component. Use
TTMSFNCGooglePlaces when you need to call these methods directly; use
TTMSFNCPlaces with Service := psGoogle when GetAutoComplete is enough,
or when you only need to select a backend for another workflow that drives
requests internally.
procedure TForm1.EnableGooglePlacesNew;
begin
{ TMSFNCGooglePlaces1 is a TTMSFNCGooglePlaces component (unit
FMX.TMSFNCGooglePlaces), the Google-specific places component whose
search methods are public. TTMSFNCPlaces also exposes
UseGooglePlacesNew, but only TTMSFNCGooglePlaces publishes the
SearchByText/SearchNearby methods used to issue requests. }
TMSFNCGooglePlaces1.APIKey := 'YOUR-GOOGLE-API-KEY';
{ UseGooglePlacesNew switches the component from the legacy REST
endpoints (maps.googleapis.com, query-string parameters, API key in
the URL) to the Places API (New): places.googleapis.com, JSON POST
bodies, and the API key plus a field mask sent as request headers
(X-Goog-Api-Key, X-Goog-FieldMask). Set it once before issuing any
request; changing it later re-initializes the underlying service. }
TMSFNCGooglePlaces1.UseGooglePlacesNew := True;
end;
procedure TForm1.SearchByTextGooglePlacesNew(const AQuery: string);
var
Location: TTMSFNCMapsCoordinateRec;
begin
Location.Latitude := 51.5074;
Location.Longitude := -0.1278;
{ With UseGooglePlacesNew enabled, this call posts a JSON body to
/v1/places:searchText on places.googleapis.com instead of issuing a
GET request to the legacy textsearch endpoint. The result shape
returned to OnSearchByText / OnSearchByTextResult is unchanged. }
TMSFNCGooglePlaces1.SearchByText(AQuery, Location);
end;
procedure TForm1.TMSFNCGooglePlaces1SearchByText(Sender: TObject;
const ARequest: TTMSFNCPlacesRequest;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
var
I: Integer;
begin
for I := 0 to ARequest.Items.Count - 1 do
begin
{ Inspect ARequest.Items[I].Description, .Address, .Coordinate, ... }
end;
end;