13

I'm looking for the best/easiest way to programmatically grab the name of the US county a given US city resides in. It doesn't seem there's a straightforward API available for such a (seemingly simple) task?

Cucumber2
  • 153
  • 1
  • 1
  • 5
  • Louisiana is divided into parishes and Alaska into boroughs. So I guess only 48 out of 50 is valid in your question – Fredrik Pihl Jul 05 '11 at 21:10
  • I think that's fine as a limitation considering my focus is on Texas. – Cucumber2 Jul 05 '11 at 21:11
  • 1
    You should need a database in any case. So I think the question should be "What kind of database/data structure do I need?" – splash Jul 05 '11 at 21:13
  • Since the focus is on TX, why not just create a list of all the cities/towns in TX and match against that? wikipedias [entry](http://en.wikipedia.org/wiki/List_of_cities_in_Texas) is a good start... – Fredrik Pihl Jul 05 '11 at 21:15
  • I had no data source which contained the information I needed. English is the language I am using. – Cucumber2 Jul 05 '11 at 21:16
  • Some counties reside in cities...like New York City – Neil McGuigan Nov 29 '13 at 20:37

5 Answers5

12

You can download a freely-available database of county/city/zip code info such as this one: http://www.unitedstateszipcodes.org/zip-code-database/ (no need to register or pay)

Import it whole, or a subsection of it, into a local, persistent data store (such as a database) and query it whenever you need to look up a city's county

Note: County info has disappeared from the originally-linked .csv file since this answer was posted. This link no longer contains county information: http://federalgovernmentzipcodes.us/free-zipcode-database.csv

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • 2
    doesn't have the county in it.. why is this the accepted answer? – ladieu Dec 04 '14 at 16:05
  • @ladieu: It used to have county information. The file must've been updated and the county info dropped since I linked to it. Thanks for the heads up. I'll try and find a better resource to replace the linked one... – Paul Sasik Dec 04 '14 at 16:10
  • @ladieu: Found new link to resource which contains a county column as the original .csv had. – Paul Sasik Dec 04 '14 at 17:03
  • @ladieu I'm looking for that file. Can you share it ? Having trouble finding it. – Naveen Sep 11 '15 at 21:35
  • As of June 2016 counties are here: http://www.unitedstateszipcodes.org/zip_code_database.csv – David Vogel Jun 09 '16 at 19:05
  • County mapping from zips corrupts the result--zips span counties. The inaccuracy is often acceptable but you should go into it knowing. Also, those sites with names like "unitedstatesawesomefreezipcodes2000.biz" are actually just repackaging this Census data https://www.census.gov/geo/maps-data/data/zcta_rel_download.html\ – gss Jun 18 '18 at 13:02
9

1) Cities span counties

2) Zips span both cities and counties, not even on the same lines

Any solution that uses zip as an intermediary is going to corrupt your data (and no, "zip+4" won't usually fix it). You will find that a city-to-zip-to-county data map (#2) has a larger number of city-to-county matches than the more accurate model (#1)--these are all bad matches.

What you're looking for is free census data. The Federal Information Processing Standards (FIPS) dataset you need is called "2010 ANSI Codes for Places": https://www.census.gov/geographies/reference-files/time-series/geo/name-lookup-tables.2010.html

Census "places" are the "cities" for our question. These files map "places" to one or more county.

gss
  • 653
  • 8
  • 9
  • The "2010 ANSI Codes for Places" was what I needed but the census link above was broken and I couldn't find it anywhere at .gov sites. I did find it uploaded at https://data.world/nrippner/ansi-geographic-codes. I'd never heard of data.world but registered and was finally able to download the file easily. – Omar Wasow Jun 02 '19 at 03:59
2

Here is a bit of code to programmatically grab the name of a US county given a single US city/state using the Google Maps API. This code is slow/inefficient and does not have any error handling. However, it has worked reliably for me to match counties with a list of ~1,000 cities.

#Set up googlemaps API
import googlemaps
google_maps = googlemaps.Client(key='API_KEY_GOES_HERE')

#String of city/state
address_string = 'Atlanta, GA'

#Geocode
location = google_maps.geocode(address_string)

#Loop through the first dictionary within `location` and find the address component that contains the 'administrative_area_level_2' designator, which is the county level
target_string = 'administrative_area_level_2'
for item in location[0]['address_components']:     
    if target_string in item['types']: #Match target_string
        county_name = item['long_name'] #Or 'short_name'
        break #Break out once county is located
    else:
        #Some locations might not contain the expected information
        pass

This produces:

>>> county_name
Fulton County

Caveats:

  1. code will break if google_maps.geocode() is not passed a valid address
  2. certain addresses will not return data corresponding to 'administrative_area_level_2'
  3. this does not solve the problem of US cities that span multiple counties. Instead, I think the API simply returns the county associated with the single latitude/longitude associated with address_string
ted1918
  • 21
  • 2
2

It will not be easy to use geospace functions for this task because of the odd polygon shaped of counties and the point locations of cities.

Your best bet is to reference a database of cities and their respective counties, though I don't know where you could find one. Maybe Texas publishes one?
CommonDataHub doesn't contain this information.

Matthew
  • 10,244
  • 5
  • 49
  • 104
  • This is pretty much the issue I'm running into. Finding a reference for this information is proving difficult. – Cucumber2 Jul 05 '11 at 21:17
-1

The quickest and most non-evasive way might be to use a JSON/XML request from a free geolocation API (Easily found on Google). That way you don't need to create/host your own database.

Steve Robbins
  • 13,672
  • 12
  • 76
  • 124