Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where can I find city/town location data for location-based searching?

I need to implement find entries with x miles of town function, so I have a town box with autosuggest attached. Currently I'm using Google's Geocoding API to get the data for the autosuggest results, but we obviously can't tune or alter this data and it doesn't always come up with sensible suggestions (even with a country hint). Are there any other sources of town/city location data? I've tried to see if perhaps an export was available from OpenStreetMap or something but I can only find map tiles or vector map data and not POI data for town/city names and locations.

Any suggestions appreciated. Thanks.

like image 258
NickG Avatar asked Mar 02 '12 11:03

NickG


People also ask

How do I find a geocode for a location?

One way to find your geolocation is to simply perform a lookup online. Melissa's Geocoder Lookup tool returns latitude, longitude, county, census tract and block data based on an address or ZIP Code. Simply enter the address or ZIP Code into the easy-to-use Lookups interface and submit.

What is location database?

Also known as geographic information or geospatial data, location data refers to information related to objects or elements present in a geographic space or horizon. There are two basic types of location data: vector data and raster data.


2 Answers

Geonames.org has a downloadable list of cities and even postal codes for many countries around the world along with their corresponding lat/lon point. It's under the Creative Commons Attribution 3.0 License which means that you can use it commercially, but you have to give attribution, among other things.

While having a downloadable list may mean more work on your end in terms of implementing all of the facets of the search algorithm, the silver lining is that you don't couple yourself to the uptime/availability of a 3rd-party web service.

The only other part that's missing is the distance-calculation formula. You can use the greater-circle distance formula to compute distance.

I've done this myself a number of times. The first time you write the code, it takes a little bit to wrap your head around everything, but once you do it's a piece of cake thereafter.

I should probably mention that I'm the founder of SmartyStreets. We do street-based address verification and not only can we tell you if an address is good or not (which helps in a significant number of ways), but we can also give you the lat/lon coordinate for a given street address which can then be plugged in to the above solution to determine proximity to nearby places.

like image 113
Jonathan Oliver Avatar answered Oct 19 '22 23:10

Jonathan Oliver


I would say you also have two other options to get the functionality you require.

Firstly, you can use a kludge to focus the results to more meaningful ones (although I would not strongly recommend this method it may suffice for your needs.)

Before your initial query to Google's Geocoding API to get the data for the autosuggest results, firstly determine the country the town is in. Then you can use the country string as a suffix to the Geocoding query.

Something like:

  var country = 'UK'; // from initial query, reverse geocode, etc.
  geocoder.geocode({
          'address': address + ', ' + country
       }, 

See the answer in this question for an example. Google's Geocoder returns wrong country, ignoring the region hint

Secondly, the premise that you "obviously can't tune or alter this data" is flawed. You can certainly filter the results based on the country. Something like the following snippet shows how to drill down the results.

   geocoder.geocode({
      'address': address
   }, 
   function(results, status) {
      if(status == google.maps.GeocoderStatus.OK) {
         for(var i = 0, l = results.length; i < l; i++)  {
          for (var j = 0, l2 = results[i].address_components.length; j < l2; j++) {
              for (var k = 0, l3 = results[i].address_components[j].types.length; k < l3; k++) {
                 if(results[i].address_components[j].types[k]=="country") {
                    var country = results[i].address_components[j].long_name;
                    // do stuff based on the country
                    // add the result to your auto-suggest, etc...
                 }
              }
         }
      }
    });
   }

Finally, if you implemented a CGI wrapper to do the geocoding you could cache the results. This way your application would automatically build your database for you. This would save actually having to perform geocoding at all for known results. I think this is almost what you are hinting at in your question, and there is no reason you could not pre-populate your cache with known results if you did find a reliable source of data.

Take a look at this document that outlines various Geocoding Strategies using the Maps Api - it discusses things like caching, etc. https://developers.google.com/maps/articles/geocodestrat

EDIT

You could use something like geoPlugin

http://www.geoplugin.com/webservices/php#php_class

Take a look at the nearby places features, this does exactly what you want.

http://www.geoplugin.com/webservices/extras

like image 39
Fraser Avatar answered Oct 20 '22 01:10

Fraser