Spatial queries are getting more and more important e.g. if you want a query all restaurants in a distance of 5 kilometers around your actual position. This is not easy because our planet is a sphere (so this requires a projection of locations) and spatial calculations are very resource consuming. Thats why Lucene implemented a smart technical approach to realize that. It is based on so called “tiers” where a preselection of bounding boxes is possible. (-> If you want to know more read this)

I evaluated this to provide a fast way to find GeoTIFF images stored in a Hadoop HBase database based on the zoom extend of a Client GIS window. The first thing I did was to implement the usual distance exemple in (simple and as usual brief) Scala.

Here we go:

object MyMain { val s = new SpatialLuceneExample def main(a: Array[String]) = { addData s.forEachFindNear(null, 38.8725000, -77.3829000, 4) { (doc, latitude, longitude, distance) => val name = doc.get("name") printf(name + ": %.2f Miles

", distance) println("\t\t(" + latitude + "," + longitude + ")") } println for ((doc, latitude, longitude, distance) s += ("McCormick & Schmick's Seafood Restaurant", 38.9579000, -77.3572000) s += ("Jimmy's Old Town Tavern", 38.9690000, -77.862000) s += ("Ned Devine's", 38.9510000, -77.4107000) s += ("Old Brogue Irish Pub", 38.9955000, -77.2884000) s += ("Alf Laylah Wa Laylah", 38.8956000, -77.4258000) s += ("Sully's Restaurant & Supper", 38.9003000, -77.4467000) s += ("TGIFriday", 38.8725000, -77.3829000) s += ("Potomac Swing Dance Club", 38.9027000, -77.2639000) s += ("White Tiger Restaurant", 38.9027000, -77.2638000) s += ("Jammin' Java", 38.9039000, -77.2622000) s += ("Potomac Swing Dance Club", 38.9027000, -77.2639000) s += ("WiseAcres Comedy Club", 38.9248000, -77.2344000) s += ("Glen Echo Spanish Ballroom", 38.9691000, -77.1400000) s += ("Whitlow's on Wilson", 38.8889000, -77.0926000) s += ("Iota Club and Cafe", 38.8890000, -77.0923000) s += ("Hilton Washington Embassy Row", 38.9103000, -77.0451000) s += ("HorseFeathers, Bar & Grill", 39.01220000000001, -77.3942) s += ("Marshall Island Airfield", 7.06, 171.2) s += ("Wonga Wongue Reserve, Gabon", -0.546562, 9.459229) s += ("Midway Island", 25.7, -171.7) s += ("North Pole Way", 55.0, 4.0) } }

The MyMain object (complete code above) provides method addData to fill the spatial content, restaurants in this case. The main method itself does two distance queries, one using a closure and one using an Array as return value that is used in a for statement. Pretty convenient, isn’t it?