Overview
The training code uses Delphi's TGeocoder component for reverse geocoding (converting GPS coordinates to a human-readable address). TGeocoder is documented as not available on Android, making the feature iOS-only. A REST-based approach using the OpenStreetMap Nominatim API (free, no API key required) provides consistent behavior on both platforms and is a better teaching example for HTTP client usage.
Background
Current Approach
{$IFNDEF ANDROID}
TGeocoder.Current.GeocodeReverse(Coord, OnGeocodeReverse);
{$ELSE}
lblAddress.Text := 'Geocoding not available on Android';
{$ENDIF}
TGeocoder wraps the native platform geocoder:
- iOS:
CLGeocoder — works well, but is rate-limited and requires an active internet connection routed through Apple's servers.
- Android: Not implemented in Delphi's FMX layer (
TGeocoder.Current returns nil).
Proposed Replacement
Use the OpenStreetMap Nominatim reverse geocoding REST API:
GET https://nominatim.openstreetmap.org/reverse?format=json&lat={lat}&lon={lon}
- Free, no API key
- Returns JSON with full address breakdown
- Works identically on iOS and Android
- Uses
TNetHTTPClient (already in the project)
- Good training example for JSON parsing with
System.JSON
The call should be made asynchronously via TTask.Run to avoid blocking the UI thread.
Files Affected
lab-src/Lab04.../frames/uEntryDetailsFrame.pas
lab-src/Lab05.../frames/uEntryDetailsFrame.pas
... (all labs with entry details, Lab04–Lab12)
lab-src/Lab*/forms/formMain.pas (if geocoder is wired there)
Steps to Address
- Remove all
{$IFNDEF ANDROID} / {$ENDIF} blocks around TGeocoder calls.
- Remove
System.Sensors geocoder-related imports (TGeocoder, TCivicAddress).
- Implement an async reverse geocoding function:
procedure ReverseGeocode(Lat, Lon: Double; Callback: TProc<string>);
begin
TTask.Run(procedure
var
HTTP: THTTPClient;
URL, Address: string;
JSON: TJSONObject;
begin
HTTP := THTTPClient.Create;
try
URL := Format('https://nominatim.openstreetmap.org/reverse?format=json&lat=%g&lon=%g', [Lat, Lon]);
HTTP.CustomHeaders['User-Agent'] := 'FieldLogger-Training/1.0';
var Resp := HTTP.Get(URL);
JSON := TJSONObject.ParseJSONValue(Resp.ContentAsString) as TJSONObject;
try
Address := JSON.GetValue<string>('display_name', 'Address unavailable');
finally
JSON.Free;
end;
finally
HTTP.Free;
end;
TThread.Synchronize(nil, procedure begin Callback(Address) end);
end);
end;
- Call this function from
uEntryDetailsFrame.pas when coordinates are available.
- Display a "Looking up address…" placeholder while the async call is in progress.
- Handle the no-internet case gracefully (catch exception, show "Address unavailable").
- Note the Nominatim usage policy in lab instructions (max 1 req/sec, must include User-Agent).
Test Plan
Overview
The training code uses Delphi's
TGeocodercomponent for reverse geocoding (converting GPS coordinates to a human-readable address).TGeocoderis documented as not available on Android, making the feature iOS-only. A REST-based approach using the OpenStreetMap Nominatim API (free, no API key required) provides consistent behavior on both platforms and is a better teaching example for HTTP client usage.Background
Current Approach
TGeocoderwraps the native platform geocoder:CLGeocoder— works well, but is rate-limited and requires an active internet connection routed through Apple's servers.TGeocoder.Currentreturnsnil).Proposed Replacement
Use the OpenStreetMap Nominatim reverse geocoding REST API:
TNetHTTPClient(already in the project)System.JSONThe call should be made asynchronously via
TTask.Runto avoid blocking the UI thread.Files Affected
Steps to Address
{$IFNDEF ANDROID}/{$ENDIF}blocks aroundTGeocodercalls.System.Sensorsgeocoder-related imports (TGeocoder,TCivicAddress).uEntryDetailsFrame.paswhen coordinates are available.Test Plan
{$IFDEF}/{$IFNDEF}blocks related toTGeocoderremain in the source.TGeocoderandTCivicAddressidentifiers are no longer referenced anywhere in the codebase.