-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I've been geocoding a large number of Utah County addresses and have found a small percentage fail to return a match. This is a sample: geocoding_failures.csv
I can't find an obvious reason for the failures. The addresses exist, and I'm able to manually look them up here. I'm geocoding these addresses as the first step in looking up precincts, so I'm also open to suggestions about a different workflow for achieving that. Precinct lookups are working fine -- the problem is the geocoding step.
Below is the code I'm using, which works for the vast majority of addresses.
class Geocoder():
def __init__(self, api_key):
self._api_key = api_key
self._geocoding_url_template = "http://api.mapserv.utah.gov/api/v1/geocode/{}/{}"
self._precinct_url = "https://services1.arcgis.com/99lidPhWCzftIe9K/ArcGIS/rest/services/VistaBallotAreas/FeatureServer/0/query"
def get_coordinates(self, street, zone, **kwargs):
"""
street (str): a street number and name
zone (str): a city name or ZIP code in Utah
"""
kwargs["apiKey"] = self._api_key
kwargs["spatialReference"] = 4326
result = requests.get(self._geocoding_url_template.format(street, zone), params=kwargs)
if result.status_code != 200:
# if result isn't found, check for unit number, remove and retry
if "#" in street:
num_signs = street.count("#")
if num_signs == 1:
street = street.split("#")[0]
result = requests.get(self._geocoding_url_template.format(street, zone), params=kwargs)
elif num_signs > 1:
print("Messy address with two number signs, giving up: ", street)
return result
def get_precinct(self, long, lat):
"""
lat (int): latitude of location in EPSG:4326 coord system
long(int): longitude of location in EPSG:4326 coord system
"""
params = {
"geometry": f"{long},{lat}",
"geometryType": "esriGeometryPoint",
"inSR": 4326,
"spatialRel": "esriSpatialRelIntersects",
"outFields": "*",
"f": "json"
}
return requests.get(self._precinct_url, params=params)
def extract_coords(self, response):
long = response.json()['result']["location"]['x']
lat = response.json()['result']["location"]['y']
return (long, lat)
def extract_precinct_id(self, response):
return response.json()['features'][0]['attributes']['PrecinctID']
Example request:
geocoder.get_coordinates("1391 N Fox Borough Dr", "Lehi", **{"acceptScore": 90})
Returns:
{"status":404,"message":"No address candidates found with a score of 90 or better."}
(I've also tried a score threshold of 70, which doesn't improve results.)