# Address Geocoding

Auto-geocode addresses using OpenStreetMap Nominatim (free, no API key required)

<cfscript> function geocodeAddress(addressString) { var result = { "success": false, "error": "" }; if (len(trim(addressString)) EQ 0) { result.error = "Empty address"; return result; } try { var httpService = new http(); httpService.setMethod("GET"); httpService.setUrl("https://nominatim.openstreetmap.org/search?q=" & urlEncodedFormat(addressString) & "&format=json&limit=1"); httpService.addParam(type="header", name="User-Agent", value="Payfrit/1.0"); httpService.setTimeout(10); var httpResult = httpService.send().getPrefix(); if (httpResult.statusCode CONTAINS "200") { var data = deserializeJSON(httpResult.fileContent); if (arrayLen(data) GT 0) { result.success = true; result.lat = data[1].lat; result.lng = data[1].lon; return result; } result.error = "No results found"; return result; } result.error = "HTTP " & httpResult.statusCode; return result; } catch (any e) { result.error = e.message; return result; } } function buildAddressString(line1, line2, city, zipCode) { var parts = []; if (len(trim(line1))) arrayAppend(parts, trim(line1)); if (len(trim(line2))) arrayAppend(parts, trim(line2)); if (len(trim(city))) arrayAppend(parts, trim(city)); if (len(trim(zipCode))) arrayAppend(parts, trim(zipCode)); return arrayToList(parts, ", "); } </cfscript> <cfif structKeyExists(url, "geocode") AND structKeyExists(url, "addressId")> SELECT Line1, Line2, City, ZIPCode FROM Addresses WHERE ID = <cfif addr.recordCount GT 0> <cfif geo.success> UPDATE Addresses SET Lat = , Lng = WHERE ID = <cfoutput>
Geocoded Address ID #addressId#: #geo.lat#, #geo.lng#
</cfoutput> <cfelse> <cfoutput>
Failed: #geo.error#
</cfoutput> </cfif> </cfif> </cfif> <cfif structKeyExists(url, "geocodeAll")> SELECT ID, Line1, Line2, City, ZIPCode FROM Addresses WHERE (Lat IS NULL OR Lat = 0) AND Line1 IS NOT NULL AND Line1 != '' <cfif geo.success> UPDATE Addresses SET Lat = , Lng = WHERE ID = <cfelse> </cfif> <cfset sleep(1100)> <cfoutput>
Geocoded #successCount# addresses. #failCount# failed.
</cfoutput> </cfif> SELECT b.ID AS BusinessID, b.Name, a.ID AS AddressID, a.Line1, a.Line2, a.City, a.ZIPCode, a.Lat AS Latitude, a.Lng AS Longitude FROM Businesses b LEFT JOIN Addresses a ON b.AddressID = a.ID ORDER BY b.Name <cfif (NOT len(addresses.Latitude) OR val(addresses.Latitude) EQ 0) AND len(addresses.Line1)> </cfif> <cfoutput>

#missingCount# addresses missing coordinates. <cfif missingCount GT 0>
(~#missingCount# seconds due to rate limiting) </cfif>

Business | Address | Coordinates | Action
--- | --- | --- | ---

#addresses.Name# <cfif len(addresses.Latitude) AND val(addresses.Latitude) NEQ 0> #chr(10003)# <cfelseif len(addresses.Line1)> #chr(9679)# </cfif>

<cfif len(addresses.Line1)> #addresses.Line1#<cfif len(addresses.Line2)>, #addresses.Line2#</cfif>
#addresses.City# #addresses.ZIPCode# <cfelse> No address </cfif>

<cfif len(addresses.Latitude) AND val(addresses.Latitude) NEQ 0> #numberFormat(addresses.Latitude, "_.______")#
#numberFormat(addresses.Longitude, "_.______")# <cfelse> - </cfif>

<cfif len(addresses.Line1) AND len(addresses.AddressID)>
</cfif>

</cfoutput>