0

I have a location that I want to find the coordinates of. But my function gmaps_geoencoder is interpreting the address wrongly as belonging to a different country. So, my logic is, keep removing words one by one from the address until the latitudes and longitudes returned are in the correct range(i.e., until it interprets the address correctly).

To illustrate the issue, here's the code:

place = "*LORENZO GOMEZ & CO CPA'S RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
gmaps_geoencoder(place)

>>> "{'results': [{'address_components': [{'long_name': 'San Diego', `'short_name': 'San Diego', 'types': ['locality', 'political']}, {'long_name': 'California', 'short_name': 'CA', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'United States', 'short_name': 'US', 'types': ['country', 'political']}, {'long_name': '92123', 'short_name': '92123', 'types': ['postal_code']}], 'place_id': 'ChIJAy3bGzT-24ARmX-IpDjdadk', 'types': ['doctor', 'establishment', 'health', 'point_of_interest'], 'formatted_address': '4715 Viewridge Avenue Suite 230, San Diego, CA 92123, San Diego, CA 92123, United States', 'geometry': {'location': {'lat': 32.8238366, 'lng': -117.119949}, 'location_type': 'GEOMETRIC_CENTER', 'viewport': {'southwest': {'lat': 32.8224876197085, 'lng': -117.1212979802915}, 'northeast': {'lat': 32.8251855802915, 'lng': -117.1186000197085}}}}], 'status': 'OK'}"`

As we can see, its interpreting the address as belonging to the United States, when its actually in the Philippines.

When I remove the first few words from the address though, it interprets it correctly:

place = "RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
gmaps_geoencoder(place)

>>> "{'results': [{'address_components': [{'long_name': 'Rafael Castillo', 'short_name': 'Rafael Castillo', 'types': ['administrative_area_level_5', 'political']}, {'long_name': 'Agdao', 'short_name': 'Agdao', 'types': ['political', 'sublocality', 'sublocality_level_1']}, {'long_name': 'Davao City', 'short_name': 'Davao City', 'types': ['locality', 'political']}, {'long_name': 'Davao del Sur', 'short_name': 'Davao del Sur', 'types': ['administrative_area_level_2', 'political']}, {'long_name': 'Davao Region', 'short_name': 'Davao Region', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'Philippines', 'short_name': 'PH', 'types': ['country', 'political']}], 'partial_match': True, 'types': ['administrative_area_level_5', 'political'], 'place_id': 'ChIJi4qcxTBs-TIRfnWnF4MGzDE', 'formatted_address': 'Rafael Castillo, Agdao, Davao City, Davao del Sur, Philippines', 'geometry': {'location': {'lat': 7.100270999999999, 'lng': 125.6382528}, 'bounds': {'southwest': {'lat': 7.095814, 'lng': 125.6311701}, 'northeast': {'lat': 7.1040211, 'lng': 125.644075}}, 'location_type': 'APPROXIMATE', 'viewport': {'southwest': {'lat': 7.095814, 'lng': 125.6311701}, 'northeast': {'lat': 7.1040211, 'lng': 125.644075}}}}, {'address_components': [{'long_name': 'Pelayo Street', 'short_name': 'Pelayo St', 'types': ['route']}, {'long_name': 'Poblacion District', 'short_name': 'Poblacion District', 'types': ['political', 'sublocality', 'sublocality_level_1']}, {'long_name': 'Davao City', 'short_name': 'Davao City', 'types': ['locality', 'political']}, {'long_name': 'Davao del Sur', 'short_name': 'Davao del Sur', 'types': ['administrative_area_level_2', 'political']}, {'long_name': 'Davao Region', 'short_name': 'Davao Region', 'types': ['administrative_area_level_1', 'political']}, {'long_name': 'Philippines', 'short_name': 'PH', 'types': ['country', 'political']}], 'partial_match': True, 'types': ['route'], 'place_id': 'ChIJJaE5cndt-TIRqYbFlmdcZP4', 'formatted_address': 'Pelayo St, Poblacion District, Davao City, Davao del Sur, Philippines', 'geometry': {'location': {'lat': 7.0685545, 'lng': 125.6068616}, 'bounds': {'southwest': {'lat': 7.0662803, 'lng': 125.6049452}, 'northeast': {'lat': 7.0718272, 'lng': 125.6078379}}, 'location_type': 'GEOMETRIC_CENTER', 'viewport': {'southwest': {'lat': 7.0662803, 'lng': 125.6049452}, 'northeast': {'lat': 7.0718272, 'lng': 125.6078379}}}}], 'status': 'OK'}")

So, to automate this process (of how many words to remove) for other such misidentified addresses, my code is the following:

place = "*LORENZO GOMEZ & CO CPA'S RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"
lat = 0
lon = 0
while ((lat not in range(4,21)) or (lon not in range(116,128))): # Philippines' latitude and longitude range
    place = place.split(' ', 1)[1]
    try:
        lat, lon, res = gmaps_geoencoder(place)
    except: # This is because sometimes the gmaps API does not return any result for a given address. In that case, remove the word at the beginning and search again.
        place = place.split(' ', 1)[1]
        lat, lon, res = gmaps_geoencoder(place)

But this keeps stripping words until the last word is stripped and returns a list index out of range error. Why does the while condition not stop when lat and lon are in the desired range as indicated to it in the code?

EDIT: Modifying the while condition to always keep running, and adding an if ... break to stop the while loop when the desired condition is reached, solves the issue:

while True: 
    place = place.split(' ', 1)[1]
    try:
        lat, lon, res = gmaps_geoencoder(place)
    except:
        place = place.split(' ', 1)[1]
        lat, lon, res = gmaps_geoencoder(place)
    if (4<lat<21 or 116<lon<128):
        break
3
  • did you convert them into float? I saw your gmaps_geoencoder(place) is a long string. Commented Jul 23, 2018 at 3:44
  • Among the 3 variables returned by gmaps_geoencoder, lat and lon are floats, and res is the string returned by the API I showed in the 2 examples. Commented Jul 23, 2018 at 3:46
  • Why do you expect a second call to gmaps_geoencoder with the same place.split(' ', 1)[1] with the same literal constant place to give you any different results from the first one? Commented Jul 23, 2018 at 3:52

3 Answers 3

1

It seems like your lat and lon will not be int, but for x in range(4,8), it is similar to x in [4,5,6,7], it will only consider the equality between integer。

Maybe you want change the condition of while from lat not in range(4,21)to something likelat>21 or lat<4.

Sign up to request clarification or add additional context in comments.

2 Comments

I've added an edit to the question details, where I've shown a workaround solution for the issue. It doesn't seem like int or range is causing the problem here. What do you think? Or is it just one of those coincidences that just "happens to work"?
break is just another way to stop the while loop。 So your solution is basicly the same with change your while condition to while not(4<lat<21 or 116<lon<128),you fix this issue by replace x in range(a,b) to x<a and x>b, so the problem is still caused by int and range。
1

The reason why this is not working is because lat and lon can be non-integers, and you are only checking for integers. Try this:

while (not 4 <= lat <= 21) or (not 116 <= lon <= 128):
    ... 

The reason doesn't work is because range(4, 21) is generating this list(read EDIT for clarification):

[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

And if the latitude is a decimal number(which by the looks of it, it is), then it evaluates that decimal number is in that list, which it is not.

EDIT: Thank you to abanert for pointing this out to me. range() does not produce a list, but a range object. This acts very similarly to a list where you can check if something is one of the items it generates when using "x in range()". I still believe this is the right answer, but it was initially misleading. Part of it was my own fault thinking that range was a generator.

3 Comments

range doesn't produce a list (unless the OP is in Python 2.x), it produces a range object (which does still contain exactly those same values, but only lazily, and it can do in tests by just doing arithmetic instead of iterating all the values). The main point of the answer does seem right, but it would be better if it weren't phrased misleadingly.
I've added an edit to the question details, where I've shown a workaround solution for the issue. It doesn't seem like int or range is causing the problem here. What do you think? Or is it just one of those coincidences that just "happens to work"?
Well, what you're doing with the if statement is pretty much checking the condition which should have been put in the while loop. The while loop's job is to do exactly what you did with the if statement. With your if statement, the loop is basically like saying "while True:" and then relying on an if statement inside to break the loop. If the while loop was really working, then you wouldn't need to put the if statement there.
-1

Since there are only a couple of words in this case, maybe you should try to just print out the output from gmaps_encoder to see what's going on? I think you are removing the first word correctly, so what's the output of the loop when place = "RM 202 DON RAFAEL CASTILLO BLDG LEGASPI ST DAVAO CITY DAVAO DEL SUR PHILIPPINES"?

3 Comments

Just checked by making the function print the result. Its returning the correct address from Philippines, but somehow the while loop doesn't stop.
Maybe try to print out lat and lon variable to see if they fall in the range, and check the place variable to see if it changes?
Yeah, did that - it is in the correct range. And the place variable changes too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.