View on GitHub


A coarse forward & reverse geocoder in scala

Download this project as a .zip file Download this project as a tar.gz file


Twofishes is a


Please note that this is the unpolished developer debug interface for twofishes

Tech Specs

Getting started

Twofishes requires a relatively beefy box to build an index from scratch. For that reason, prebuilt indexes and binaries exist!
Prebuilt indexes
All indexes contain data from (light cc-by), flickr (public domain), and natural earth (public domain).

Download server binary (2016-08-21)

Download latest index (updated 2015-03-05)
Download previous index (updated 2014-08-13)
License: CC-BY as required by geonames, please link to somewhere on your site. For more information, see: (light cc-by) License for this data. You are required to include this information on your site if you use the twofishes index

Serving a prebuilt index
Download and unzip one of the indexes, download the server binary.
java -jar server-assembly-0.81.9.jar --hfile_basepath INDEX_DIRECTORY
The server's debug/json inteface will be accessible at http://localhost:8081/static/geocoder.html You can also serve a prebuilt binary by following the instructions below and skipping the index build step -- run with an argument of the index directory.

Building an index from scratch
See the documentation on github but, very very quickly:
 git clone
cd twofishes
./ [COUNTRY_CODE] or ./
./ -c [COUNTRY_CODE] or ./ -w 
# maybe you also want --output_prefix_index and/or --output_revgeo_index
./ latest

Mailing List

Sign up for the google group to get updates about new indexes, breaking changes, and, hopefully, discussion of features and development.


Why not street level geocoding?
Street level geocoding is hard. It's a lot of data (and as a result, the iteration speed is very slow -- a full osm geocoder build takes 1-2 weeks) and it requires a lot of per-country localization. Also, OSM data for address geocoding isn't quite there yet. Building a new OSM street geocoder is something I would like to do, but don't have the time or need for it right now.

Additionally, street level geocoding is a relatively solved problem by various commercial services, but coarse geocoding strangely isn't. Many of the coarse geocoders I found had poor ranking, no splitting, no autocomplete and no stable identifiers. And no polygons either.

Where did the name come from?

Twofishes started life as a 100 line python script serving out of mongo that I began writing one night in December 2011. December was cold. Our stove was being repaired. Still, there were fish to cook. Two fishes. Two fishes wrapped in bacon a la Papa Hemingway.

The fish up top are from a very dated 1950s cookbook called "Recipes from the East" by Irma Walker Ross.