Open Street Integration Guide
This guide explains how to enable OpenStreetMap Nominatim (aka “OpenStreet”) geocoding for facilities in Salesforce using the provided Apex classes and Visualforce page.
Scope: Single‑record geocoding for FreightTM__Facility__c. No batch geocoding is performed.
Overview
The integration calls Nominatim Search API to convert a facility’s address into latitude and longitude, then writes the values to Coordinates__Latitude__s and Coordinates__Longitude__s. If a match isn’t found, the system emails country‑specific contacts (from Country_Email_Mapping__mdt) to request a manual fix.
Key components
- Apex: GeocodingService (core logic) and GeocodingServiceExtension (VF controller extension)
- Visualforce page: Triggers geocoding on page load and redirects back when done
- Custom metadata: Country_Email_Mapping__mdt with an Email_List__c per country
What This Integration Does
- Builds a single search query from Street, City, State/Province, Zip, Country
- Sends an HTTP GET request to Nominatim (/search?format=json&limit=1&addressdetails=1)
- Parses the first result and updates the facility’s coordinate fields
- If no result: sends an alert email to a configured list for that facility’s country
- Displays status messages in the page and auto‑redirects back to the Facility record on success
Setup Requirements
- Allow the external callout
- Remote Site Settings (quick & simple):
- Name: Nominatim_OSM
- URL: https://nominatim.openstreetmap.org
- Or Named Credential (recommended):
- Named Credential URL: https://nominatim.openstreetmap.org
- No auth needed; use it for cleaner code & admin control.
- Remote Site Settings (quick & simple):
- User-Agent header
- In GeocodingService.getGeolocation, set a clear User‑Agent that identifies your app and contact:
- Example: FTM/1.0 (contact: [email protected])
- In GeocodingService.getGeolocation, set a clear User‑Agent that identifies your app and contact:
- Permissions
- Users need read/write access to FreightTM__Facility__c and the coordinate fields
- Apex Class Access for both classes
- Visualforce page access
- Email Deliverability set to All email (for alert emails)
- Custom Metadata — Alert recipients
- Create Country_Email_Mapping__mdt records
- Master Label / Developer Name: match the Country stored on the Facility
- Email_List__c: comma/semicolon‑separated list of recipient emails
- Create Country_Email_Mapping__mdt records
- Page Layout Button
- Add a button or quick action to open the VF page (e.g., Update Geolocation) on Facility.
- Attribution
- Ensure your UI (e.g., help text or a footer in the VF page) includes proper OpenStreetMap attribution per licensing.
How It Works
- User opens the Update Geolocation VF page from a Facility record.
- On page load, GeocodingServiceExtension.init() calls GeocodingService.processFacilitiesGeolocation(recordId).
- processFacilitiesGeolocation reads the facility address, calls getGeolocation(…) and receives a JSON array.
- If a result exists, the code writes:
- Coordinates__Latitude__s = lat
- Coordinates__Longitude__s = lon
- updates the record and returns a success message.
- If no result, it builds an email from Country_Email_Mapping__mdt and sends a notification.
- The page shows status text and auto‑redirects back to the record when successful.
Notes
- State/Province is read from State_Province__c (fallback logic is present in code). Ensure this field carries clean values (e.g., BRASOV not Brașov), especially for countries with diacritics.
- The integration targets single‑record usage to respect public Nominatim limits.
Field Mapping
Outbound (Facility → Nominatim query)
| Facility field | Example | Included in query |
| FreightTM__Street__c | Str. Lunga 10 | ✓ |
| FreightTM__City__c | Brasov | ✓ |
| State_Province__c | BRASOV | ✓ if not blank |
| FreightTM__Zip_Code__c | 500123 | ✓ if not blank |
| FreightTM__Country__c | Romania | ✓ if not blank |
The fields are URL‑encoded and concatenated into one q= parameter.
Inbound (Nominatim → Facility)
| Nominatim field | Facility field |
| lat | Coordinates__Latitude__s |
| lon | Coordinates__Longitude__s |


Implementation
- Deploy the Apex & VF
- GeocodingService (Apex)
- GeocodingServiceExtension (Apex)
- Visualforce page (uses standardController=”FreightTM__Facility__c” and extension)
- Configure callout access
- Add Remote Site Setting or Named Credential for https://nominatim.openstreetmap.org.
- Set the User‑Agent
- Update request.setHeader(‘User-Agent’, ‘FTM/1.0 (contact: [email protected])’);
- Create alert recipients
- Populate Country_Email_Mapping__mdt rows for each active country (e.g., Romania, Greece, Denmark, etc.).
- Add a UI entry point
- Create a Detail Page Button or Quick Action to open the VF page.
- Place it on the FreightTM__Facility__c layout (e.g., in the Buttons section).
- Test
- Open a Facility with a complete address and click Update Geolocation.
- Confirm success message, redirect, and coordinates populated.
- Try a deliberately bad address to verify the email notification path.
- (Optional) Named Credential refactor
- Replace the hardcoded URL with callout:Your_Named_Credential/… for cleaner governance.

Common Issues
1) 429 / Rate limited or 403 errors
- Cause: Exceeding public service policy or missing/invalid User-Agent.
- Fix: Ensure a descriptive User-Agent with contact info. Avoid rapid repeated calls. Do not batch on the public endpoint.
2) Empty result (no match)
- Check address quality: street, city, country.
- Normalize State/Province (e.g., use ASCII uppercase like BRASOV).
- Confirm postal code format (leading zeros preserved).
- Fallback emails will be sent if configured.
3) Callout not allowed
- Add the Remote Site Setting / Named Credential for https://nominatim.openstreetmap.org.
4) Emails not sending
- Check Email Deliverability = All email.
- Ensure Country_Email_Mapping__mdt exists for that country and Email_List__c is populated.
5) Field permissions
- Make sure users can edit Coordinates__Latitude__s and Coordinates__Longitude__s.
6) Timeouts
- The request timeout is 60 seconds. Try again or verify address correctness.
Limitations
- Throughput: Public Nominatim is intended for light, interactive use. Heavy/batch geocoding is not supported.
- Accuracy: Results depend on OpenStreetMap data quality; rural/ambiguous addresses may fail or be off.
- Coverage: Some regions have inconsistent state/province names or diacritics; normalization may be required.
- Attribution: When showing results or using OSM‑derived data in UI, you must display proper OSM attribution.
If you need batch or higher SLAs: consider hosting your own Nominatim or using a commercial geocoding service.
FAQs
Q1: Do we need an API key?
No. Public Nominatim doesn’t require keys, but it does require a proper User-Agent and adherence to usage limits.
Q2: Can I geocode hundreds of facilities at once?
Not with the public endpoint. Use one‑off, on‑demand lookups only. For bulk needs, use a dedicated/hosted instance or a paid provider.
Q3: What should the User‑Agent look like?
Identify your app and include a contact, e.g. FTM/1.0 (contact: [email protected]).
Q4: How do I add recipients for “not found” emails?
Create a Country_Email_Mapping__mdt record whose name matches the Facility’s country, and fill Email_List__c with recipients.
Q5: Why is state/province ignored sometimes?
If blank, the code omits it. Ensure State_Province__c is populated with clean, standardized values (ASCII uppercase is safest).