Given the lat/long coordinates, how can we find out the city/country?

241,299

Solution 1

The free Google Geocoding API provides this service via a HTTP REST API. Note, the API is usage and rate limited, but you can pay for unlimited access.

Try this link to see an example of the output (this is in json, output is also available in XML)

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true

Solution 2

Another option:

  • Download the cities database from http://download.geonames.org/export/dump/
  • Add each city as a lat/long -> City mapping to a spatial index such as an R-Tree (some DBs also have the functionality)
  • Use nearest-neighbour search to find the closest city for any given point

Advantages:

  • Does not depend on an external server to be available
  • Very fast (easily does thousands of lookups per second)

Disadvantages:

  • Not automatically up to date
  • Requires extra code if you want to distinguish the case where the nearest city is dozens of miles away
  • May give weird results near the poles and the international date line (though there aren't any cities in those places anyway

Solution 3

You need geopy

pip install geopy

and then:

from geopy.geocoders import Nominatim
geolocator = Nominatim()
location = geolocator.reverse("48.8588443, 2.2943506")

print(location.address)

to get more information:

print (location.raw)

{'place_id': '24066644', 'osm_id': '2387784956', 'lat': '41.442115', 'lon': '-8.2939909', 'boundingbox': ['41.442015', '41.442215', '-8.2940909', '-8.2938909'], 'address': {'country': 'Portugal', 'suburb': 'Oliveira do Castelo', 'house_number': '99', 'city_district': 'Oliveira do Castelo', 'country_code': 'pt', 'city': 'Oliveira, São Paio e São Sebastião', 'state': 'Norte', 'state_district': 'Ave', 'pedestrian': 'Rua Doutor Avelino Germano', 'postcode': '4800-443', 'county': 'Guimarães'}, 'osm_type': 'node', 'display_name': '99, Rua Doutor Avelino Germano, Oliveira do Castelo, Oliveira, São Paio e São Sebastião, Guimarães, Braga, Ave, Norte, 4800-443, Portugal', 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'}

Solution 4

An Open Source alternative is Nominatim from Open Street Map. All you have to do is set the variables in an URL and it returns the city/country of that location. Please check the following link for official documentation: Nominatim

Solution 5

I was searching for a similar functionality and I saw the data "http://download.geonames.org/export/dump/" shared on earlier reply (thank you for sharing, it is an excellent source), and implemented a service based on the cities1000.txt data.

You can see it running at http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (broken link) Just change the latitude and longitude for your locations.

It is deployed on OpenShift (RedHat Platform). First call after a long idle period may take sometime, but usually performance is satisfactory. Feel free to use this service as you like...

Also, you can find the project source at https://github.com/turgos/Location.

Share:
241,299

Related videos on Youtube

meow
Author by

meow

Updated on January 05, 2021

Comments

  • meow
    meow over 3 years

    For example if we have these set of coordinates

    "latitude": 48.858844300000001,
    "longitude": 2.2943506,
    

    How can we find out the city/country?

    • beatgammit
      beatgammit almost 13 years
      You'll probably need a database of some sort. I'd try playing with the Google Maps API myself... it supports lat/long.
    • hippietrail
      hippietrail almost 12 years
  • meow
    meow almost 13 years
    accepting this because this is the one i end up going for :) Michael's answer is certainly a great option tho!
  • James D
    James D almost 12 years
    Google's reverse geocoding is only allowed in conjunction with a Google Map. If you want a solution that has no such restrictions (though it is commercial and only has US cities), check out: askgeo.com
  • Noel Abrahams
    Noel Abrahams almost 12 years
    Will also give weird results for cities within cities, for example certain locations in Rome may return "Vatican City" - depending on the lat/lon specified in the database for each.
  • Tom
    Tom over 9 years
    mapquest api is another option here as it has no rate limits in some cases and very high rate limits for various geocoding needs.
  • jeudyx
    jeudyx almost 9 years
    They also have a REST api and looks pretty decent: api.geonames.org/…
  • smartmouse
    smartmouse over 8 years
    It doesn't work propertly. If it can't get city it searches for a nearest known city. Here is an example: scatter-otl.rhcloud.com/… It says "Basseterre" instead of "Saint John"...
  • turgos
    turgos over 8 years
    That's correct. the algorithm searches the closest city available in the dataset. For above deployed server, I used "cities1000.txt". It has only the major cities. Source code is available at github.com/turgos/Location. You can start your own with more detailed data from "download.geonames.org/export/dump".
  • smartmouse
    smartmouse about 8 years
    It seems cities1000.txt is the more detailed data available. Am i right?
  • Hack-R
    Hack-R almost 8 years
    An example would've been invaluable
  • mcont
    mcont over 7 years
    GeoNames also offers a free web service which is simply awesome!
  • August
    August over 7 years
    if I want only administrative_area_level_ 3 or locality (if administrative_area_level_ 3 not available), which one should I modify? new to php..
  • Petah
    Petah over 6 years
    free is debatable, it is only free under certain limits.
  • Matthew Wise
    Matthew Wise almost 6 years
    Note that the Nominatim usage policy operations.osmfoundation.org/policies/nominatim states a maximum rate of one request per second so is only really suitable for ad-hoc queries.
  • Satys
    Satys about 5 years
    Are there any limits to this one? This seems to be the quickest approach. Could there be any reason not to use this over @Michael's approach?
  • user276648
    user276648 about 5 years
    @JamesD: the API policies states that if you display the data on a map, then it must be a Google Map, but you don't have to display it on a map (or at all).
  • maxbachmann
    maxbachmann over 4 years
    well it requires a external service
  • Fatemeh Asgarinejad
    Fatemeh Asgarinejad over 4 years
    Thanks for sharing this but it doesn't work for all coordinates. Do coordinates' number of digits need to be in a specific size?
  • Fatemeh Asgarinejad
    Fatemeh Asgarinejad over 4 years
    It's a great approach, however I just need the counties, so I need to refine the address. I wish there was a way which gave back the counties.
  • Hamman Samuel
    Hamman Samuel over 4 years
    The only rule for coordinates I know is that the latitude is first, and second is the longitude. Could you provide the value of the coordinates that this doesn't work for?
  • Fatemeh Asgarinejad
    Fatemeh Asgarinejad over 4 years
    I believe I chose longitude and latitude correctly. I have thousands of coordinates from which a random coordinate didn't work. It's fine now. I used another approach. Thanks for your response.
  • Hamman Samuel
    Hamman Samuel over 4 years
    Welcome. Curious to know what approach worked for you? If it's better than geocoder, I'd like to try it myself too!
  • Fatemeh Asgarinejad
    Fatemeh Asgarinejad over 4 years
    I used this: from geopy.geocoders import Nominatim geolocator = Nominatim() location = geolocator.reverse("41.4721, -72.6311") print(location.address) It gives the whole address and then I filter the county from it.
  • Hamman Samuel
    Hamman Samuel over 4 years
    Thanks, I worked with a large dataset and in 2017, using GeoPy got me many timeouts. Maybe 3 years later they've relaxed their restrictions, so that's great to know!
  • joedotnot
    joedotnot almost 4 years
    In 2020, GeoNames.org looks pretty much inactive, does anyone know if it's even current ? Problem is nowhere do they mention dates of last update on the site.
  • Michael Borgwardt
    Michael Borgwardt almost 4 years
    @joedotnot: how does it possibly look "inactive" to you? The forum has discussions with comments from yesterday, there is a blog entry from March, and there is a link "recent modifications" right there on the homepage which is full of updates from today.
  • joedotnot
    joedotnot almost 4 years
    @michael-borgwardt I landed on the home page, no dates anywhere to be seen. Look in the blog the history of posts is June 26, 2013, APRIL 3, 2018, MARCH 8, 2020 (3 articles within 7 years), The forums for discussion can be 'alive' forever, without the actual thing being discussed being active. But if you are telling me it's active, I accept - just wanted to be re-assured by someone who is more familiar.
  • GuidoG
    GuidoG about 3 years
    How about a small example on how to do this search
  • Sridhar Sarnobat
    Sridhar Sarnobat almost 3 years
    Damn, I was hoping this was a CLI program rather than a server.