How to Geocode Locations in ServiceNow with the US Census Bureau API
The default geocoding engine in ServiceNow is Google Maps, but I don’t have a subscription for that. One alternative is the Census Geocoder from the US Census Bureau. This article will provide brief implementation details.
(As a reminder, latitude is x and longitude is y. I always forget which is which.)
There are essentially two components to this build:
- The outbound REST process (REST Message + HTTP Method)
- A Business Rule to call it and write the data to the location
REST Message
Navigate to “System Web Service > Outbound > REST Message”. Click New. Update fields as follows:
- Name:
US Census Bureau
- Endpoint:
https://geocoding.geo.census.gov/
Save.
HTTP Method
Open the “Default Get” HTTP Method from the related list. Update fields as follows:
- Name:
Geocode
- HTTP Method:
GET
- Endpoint:
https://geocoding.geo.census.gov/geocoder/locations/address
Create the following HTTP Query Parameters in the “HTTP Request” tab:
Name | Value | Order |
---|---|---|
benchmark | ${benchmark} |
100 |
format | json |
200 |
street | ${street} |
300 |
city | ${city} |
400 |
state | ${state} |
500 |
zip | ${zip} |
600 |
Save.
In the Related Links, click “Auto-generate variables”.
In the “Variable Subtitutions” related list, provide test values. You can use whatever address you want, but I’m going to use a random hockey rink.
- benchmark:
Public_AR_Current
- city:
Minneapolis
- state:
MN
- street:
600 Kenwood Pkwy
- zip:
55403
In the Related Links, click “Test”. Validate that the test worked successfully.
Business Rule
Navigate to “System Definition > Business Rules”. Click New. Update fields as follows:
- Name:
Geocoding with US Census Bureau
- Table:
Location [cmn_location]
- Active:
true
- Advanced:
true
- When to run
- When:
async
- Insert:
true
- Update:
true
- When:
- Advanced:
- Script:
(see below)
- Script:
Script:
(function executeRule(current, previous /*null when async*/) {
var r = new sn_ws.RESTMessageV2("global.US Census Bureau", "Geocode");
r.setStringParameterNoEscape("benchmark", "Public_AR_Current");
r.setStringParameterNoEscape("street", current.street);
r.setStringParameterNoEscape("city", current.city);
r.setStringParameterNoEscape("state", current.state);
r.setStringParameterNoEscape("zip", current.zip);
var response = r.execute();
var httpStatus = response.getStatusCode();
var responseBody = response.getBody();
if (httpStatus == 200) {
var responseJSON = JSON.parse(responseBody);
if ("addressMatches" in responseJSON["result"]) {
if (responseJSON["result"]["addressMatches"].length > 0) {
current.setValue("latitude", responseJSON["result"]["addressMatches"][0]["coordinates"]["y"]);
current.setValue("longitude", responseJSON["result"]["addressMatches"][0]["coordinates"]["x"]);
current.update();
}
}
}
})(current, previous);
Save.