Previously, we have covered how to identify where the user is, based upon navigator.geolocation and based upon their IP address (there are definitely ways to make IP-based geolocation suck less). I figured that in today’s post, we would look at how to go from an arbitrary physical location (zip code or city name) to latitude and longitude coordinates.
So, let’s start with sourcing the actual data. The United States census bureau has a website for their U.S. Gazetteer Files (a listing of all geographic areas for selected geographic area types). Using the places dataset and the ZIP code tabulation areas dataset, I was able to build a city/state to latitude/longitude CSV file and a zip code to latitude/longitude CSV file.
Now that we have data, we can start to build an API to go from an arbitrary place to latitude/longitude coordinates. Let’s start by converting the CSV files to JSON files. The result is zipCodeToLatLong.json and cityStateToLatLong.json. We’ve explored Cloudflare Workers a bit lately and I figured that we could use it again for this.
If we are going to take a common query string and check against both data sets, we should start by tackling the questions of whether the input is a city or if it is a zip code. Luckily, regex can handle that for us.
Now that we know how to figure out if the user is providing a zip code or if they are providing a city / town / village name, let’s write a quick API in Cloudflare Workers.
Now, the idea is that the user can go directly to the record for a zip code or the record for a municipality but since the script is using string.startsWith(), this should work well with an autocomplete input field.
See the Pen
Search for zip code or city/village/town using unified field by Joe Steinbring (@steinbring)
In the above pen, we are watching the input field, rerunning the query when the value changes, and then we are just dumping the result onto the screen. In a future post, we may need to go a step or two further.
Have any questions, comments, etc? Feel free to drop a comment, below.