Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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


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'}

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


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.


I've used Geocoder, a good Python library that supports multiple providers, including Google, Geonames, and OpenStreetMaps, to mention just a few. I've tried using the GeoPy library, and it often gets timeouts. Developing your own code for GeoNames is not the best use of your time and you may end up getting unstable code. Geocoder is very simple to use in my experience, and has good enough documentation. Below is some sample code for looking up city by latitude and longitude, or finding latitude/longitude by city name.

import geocoder

g = geocoder.osm([53.5343609, -113.5065084], method='reverse')
print g.json['city'] # Prints Edmonton

g = geocoder.osm('Edmonton, Canada')
print g.json['lat'], g.json['lng'] # Prints 53.5343609, -113.5065084

I know this question is really old, but I have been working on the same issue and I found an extremely efficient and convenient package, reverse_geocoder, built by Ajay Thampi. The code is available here. It based on a parallelised implementation of K-D trees which is extremely efficient for large amounts of points (it took me few seconds to get 100,000 points.

It is based on this database, already highlighted by @turgos.

If your task is to quickly find the country and city of a list of coordinates, this is a great tool.