Input: { lat, lng } → output: structured address + formatted for the UI. Complements geolocation. Google HTTP: google-maps-apis. Do not confuse with forward geocoding (address → coordinate) or with Places Details.
Providers
| Provider | When |
|---|---|
| Google Geocoding API | White-label precision/consistency; server key |
expo-location reverseGeocodeAsync |
Fast on device; quality varies by OS |
| Apple / Android Geocoder | No Google billing; local results |
Prefer the provider already adopted by the project. In transportation (taxi-machine), Google is usually the canonical source on the backend.
Non-negotiable rules
- Debounce reverse when the user drags the pin (300–500 ms).
- Cache by short geohash/grid (e.g., ~30–100 m) to avoid API spam.
- Locale (
language) aligned with the user/tenant. - UI: loading state on the address label; do not show raw coordinate as the final destination.
- Handle ZERO_RESULTS with a fallback (“Location selected on the map”).
Output model
Address {
formatted: string
street?, number?, district?, city?, state?, postalCode?, country?
placeId? // se vier de Google
lat, lng
}
- Display
formattedin the list; use components for analytics/freight zones if needed. - Persistence: save lat/lng + formatted + placeId when available.
Pin-on-map flow
onRegionChangeComplete / onDragEnd
→ debounce
→ reverseGeocode(center)
→ setAddress label
- Do not fire on every
onRegionChange(only at the end). - Initial seed: reverse of the current position (
geolocation).
Anti-patterns
- Reverse on every drag frame
- Concatenating null fields into empty commas
- Mixing forward and reverse in the same helper without clarity
- Exposing the Google key in the app for bulk reverse (use the backend)
Completion criteria
- Pin drag → stable and readable address
- Loading and zero-results handled
- Cache/debounce reduce calls
- Correct locale in the tenant's market
- Typed structure consumable by the UI and the backend