I want to write a geospatial view that takes searches for the following document within a one mile radius from a given latitude and longitude. How do I do this?
{
"agree_allowed":true,
"assigned_by":"",
"assigned_to":"",
"comments_allowed":true,
"location": {
"coordinates": [
"-74.168868",
"40.854655"
],
"type": "Point"
},
"subscribed":{
"user_cfd29b81f0263a380507":true,
"user_cfd29b81f0263a3805010":true
},
"type":"report",
"user_id":"user_cfd29b81f0263a380507",
"username":"test17"
}
Because you can only use bounding-box queries with Couchbase spatial views, you will have to split your distance query into two steps:
For the first step, you'll need to write a spatial view as follows:
function(doc, meta)
{
if (doc.location)
emit(doc.location, [meta.id, doc.location]);
}
Note: this is the Couchbase 3.0 version of the view, in Couchbase 4 you don't need to emit the meta.id and doc.location in the value anymore.
Now, given a starting point (lat,lon) and radius r, you need to calculate a bounding box [lat1,lon1, lat2,lon2] to query the view for a list of documents whose coordinates potentially fall within the radius you want. The bounding box query in Couchbase specifies the bottom-left and top-right coordinates.
Next, in your application, iterate over all the results and check whether they really do fall within R distance of your starting point.
Depending on how much accuracy you need, you can either assume the Earth is flat and just do the calculations on a 2D plane, which will be inaccurate but not terribly so for a distance of 1 mile. Or alternatively, use the actually accurate formulae to calculate everything, as described in this excellent article: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
Or better yet, you can use a geolocation library for the language of your choice to calculate the bounding box and the distances. Here's one for C# and one for Java.
Check out the GeoSpatial views documentation in Couchbase: http://docs.couchbase.com/4.0/views/spatial-views.html
One approach you could take is to index all of your documents with a 1 mile bounding box around their location.
Then you would query that view with the start_range and end_range being the same range, which would be just the location of the of your document above. This would return to you all the documents where the point falls within its 1 mile bounding box.
You can use GeoJSON for more precise bounding boxes, unfortunately they don't have a circle in the Specs, so depending on how advanced you made your bounding box, you could get results that are not exactly within a mile from your query location.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With