Table of Contents

TMS FNC Geocoding — Guides

Forward geocoding

Set Request.Address to an address string and call GetGeocoding. Handle OnGetGeocoding to receive a list of matching coordinate results.

Reverse geocoding

Set Request.Coordinate and call GetReverseGeocoding. Handle OnGetReverseGeocoding to receive the corresponding address or place name.

Reading structured address components

A geocoding result item exposes more than the formatted Address string — TTMSFNCGeocodingItem breaks the address down into individual fields (City, Region, Country, PostalCode, and more) so an application can populate structured form fields or run validation without parsing the formatted address itself. Coverage of the more specific fields varies by Service, since not every backend returns the same level of address detail:

  • StreetName — the street name without the house number, populated by Google, HERE, Azure, GeoApify, and OpenStreetMap.
  • District — a sub-city/neighborhood-level area, populated by Google and HERE.
  • County — populated by HERE, GeoApify, OpenRouteService, and OpenStreetMap (Google does not report a separate county).
  • Intersection — the name of an intersecting street, populated only by Google when the result resolves to a street intersection rather than a single address.
  • Precision — a TTMSFNCGeocodingPrecision value indicating how exact the match is (gpRoofTop, gpRangeInterpolated, gpGeometricCenter, gpApproximate, or gpUnknown), reported only by Google.

Because these fields are provider-dependent, always check for an empty string (or gpUnknown for Precision) before relying on a value — a field left blank simply means the active Service did not return that piece of address detail for the given result.

procedure TForm1.TMSFNCGeocoding1GetGeocodingResult(Sender: TObject;
  const AResult: TTMSFNCGeocodingRequest);
var
  item: TTMSFNCGeocodingItem;
begin
  if AResult.Items.Count = 0 then
    Exit;

  item := AResult.Items[0];

  Memo1.Lines.Add('Address: ' + item.Address);
  Memo1.Lines.Add('Street: ' + item.StreetName + ' ' + item.StreetNumber);
  Memo1.Lines.Add('District: ' + item.District);
  Memo1.Lines.Add('County: ' + item.County);
  Memo1.Lines.Add('City: ' + item.City);
  Memo1.Lines.Add('Postal code: ' + item.PostalCode);
  Memo1.Lines.Add('Region: ' + item.Region);
  Memo1.Lines.Add('Country: ' + item.Country + ' (' + item.CountryCode + ')');

  if item.Intersection <> '' then
    Memo1.Lines.Add('Intersection: ' + item.Intersection);

  case item.Precision of
    gpRoofTop: Memo1.Lines.Add('Precision: rooftop / address-level');
    gpRangeInterpolated: Memo1.Lines.Add('Precision: interpolated across an address range');
    gpGeometricCenter: Memo1.Lines.Add('Precision: geometric center of the matched area');
    gpApproximate: Memo1.Lines.Add('Precision: approximate');
    gpUnknown: Memo1.Lines.Add('Precision: not reported by the provider');
  end;
end;

Service backends

Set the Service property to choose a backend. Different services vary in coverage, precision, and rate limits. See ITMSFNCGeocodingService for the interface all backends implement.

See also