Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Handle country code geocoding errors #1619

Merged
merged 1 commit into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Fixed

- Handle country code geocoding errors [#1619](https://github.com/open-apparel-registry/open-apparel-registry/pull/1619)

### Security

## [55] 2022-01-27
Expand Down
55 changes: 42 additions & 13 deletions src/django/api/geocoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def create_geocoding_params(address, country_code):
}


def format_geocoded_address_data(data):
first_result, *_ = data["results"]

geocoded_point = first_result["geometry"]["location"]
geocoded_address = first_result["formatted_address"]
def format_geocoded_address_data(data, result=None):
if result is None:
result = data['results'][0]
geocoded_point = result["geometry"]["location"]
geocoded_address = result["formatted_address"]

return {
"result_count": len(data["results"]),
Expand All @@ -38,12 +38,41 @@ def format_no_geocode_results(data):
}


def validate_country_code(data, country_code):
address_components = data["results"][0]['address_components']
for component in address_components:
if component['short_name'] == country_code:
return True
raise ValueError("Geocoding results did not match provided country code.")
# Results are valid if they contain a matching country-code.
# If no results with matching country codes are found,
# a result with no country-code will be accepted.
# If all results contain non-matching country codes, throw an error.
def find_valid_country_code(data, country_code):
TaiWilkin marked this conversation as resolved.
Show resolved Hide resolved
first_inexact_result = None
country_codes = list()

for result in data["results"]:
address_components = result['address_components']
is_inexact = True
for component in address_components:
short_name = component.get('short_name', '')
# If a result with a matching country code is found
if short_name == country_code:
return result
# If the component is a non-matching country code
if 'country' in component.get('types', []):
country_codes.append(short_name)
is_inexact = False
# Save the first result with no country code
if first_inexact_result is None and is_inexact:
first_inexact_result = result

# If there were no results with matching country codes
# but there is a result with no country code, return it
if first_inexact_result is not None:
return first_inexact_result

# There were no results matching country codes
# and no results with no country code; throw an error
error = "Geocoding results of " + \
"{} did not match provided country code of {}.".format(
', '.join(country_codes), country_code)
raise ValueError(error)


def geocode_address(address, country_code):
Expand All @@ -59,6 +88,6 @@ def geocode_address(address, country_code):
if data["status"] == ZERO_RESULTS or len(data["results"]) == 0:
return format_no_geocode_results(data)

validate_country_code(data, country_code)
valid_result = find_valid_country_code(data, country_code)

return format_geocoded_address_data(data)
return format_geocoded_address_data(data, valid_result)