couchbase/couchbase-lite-ios — pull request #126 by jchris (2013-09-16 18:19:23+00:00)
Title: experimental geo query

I doubt this is ready to merge yet, but I am ready for feedback, especially from @snej and @vmx.

Jens I'll be surprised if there are no type checking errors. Although there's nothing I know of that feels wrong to me.

Volker, I want your feedback on this API. Also I'd be surprised if I didn't transpose my lat and lon somewhere along the way. The mapping between geoJSON coordinates and the locations on wikipedia was also confusing to me, which is why I didn't write more tests yet.

About the patch - at the hackathon on Thursday I was lamenting how every consumer startup app idea I came up with required a geo query capability on the device. Essentially, I just want to be able to show the right points on a map screen. I was also insisting it would be trivial to implement, so Jens challenged me to hack it together. Done.

The API is different from geocouch in a few ways. The big one is that there are not separate map and geomap functions, instead in the regular map functions there is emit(key, value) and geoemit(geoJSON, key, value).

This difference gets even bigger because (following the existing implementation) I was able to just add x and y columns to the maps table, and added an additional where `AND` clause to the view queries. This means that indexes built with geoemit() can be queried with a combination of `bbox` and `startkey` / `endkey` etc. Eg so you can paginate through results in a geographic area, by key. (I'm especially interested in this as it seems like it could be harder to implement without SQLite, but that it is also the direction we are going with multi-dimensional geo indexes anyway.)

Like geocouch, I require that the geoJSON elements be valid GeoJSON, but for now I'm only accepting geometries with type Point. It should be easy to extend it to support bounding box geometries, and eventually we can translate complex geometries to their containing bounding box on insert. But I wanted to implement it with Points first because bounding boxes require twice as many indexes and a more complex where clause. So once the current patch passes muster we can extend it to bounding boxes and see what the performance hit is.

One consequence of the current implementation is that you should be able to get the full query API of map reduce, within a bounding box. I haven't extended the tests yet but I'm expecting to be able to reduce and everything, and have setting the `bbox` parameter just restrict the result set like any other key.