2

I want to create a CouchDB database with some POI's. Is there a way/query to get poi's within a certain radius (lets say 50 meters) from a given lat/long position?

I saw an extension https://github.com/couchbase/geocouch , but this means I have to recompile CouchDB, but at this moment I don't have admin access to do that.

Gagravarr
  • 47,320
  • 10
  • 111
  • 156
fransyozef
  • 544
  • 2
  • 7
  • 18
  • I don't think you can get around the need for Geocouch. Maybe if you have Docker installed you can obtain a Docker image with Geocouch and run it that way. – Matthew Daly Apr 07 '18 at 09:26
  • hmm .. I used to to this in PHP/Mysql : https://stackoverflow.com/questions/37159089/php-radius-search can this be translated to a CouchDB query? – fransyozef Apr 07 '18 at 10:45

2 Answers2

0

Solved it and made a map function:

function (doc) {

// Leidse plein
latitude = 52.3648111;
longitude = 4.8810906;

distance = Math.acos(
  Math.sin(doc.latitude * Math.PI / 180) * 
  Math.sin(latitude * Math.PI / 180) 
  + 
  Math.cos(doc.latitude * Math.PI / 180) * 
  Math.cos(latitude * Math.PI / 180) * 
  Math.cos((doc.longitude - longitude) * Math.PI / 180)) * 6371;

  // all poi's within 5km radius
  if(distance <= 5 ) {
      emit([doc.title,doc.latitude,doc.longitude], distance);
  }

 }
fransyozef
  • 544
  • 2
  • 7
  • 18
  • I'm curious, what is the `6371` constant value you are multiplying? – Megidd Apr 09 '18 at 02:22
  • The earth radius in KM – fransyozef Apr 09 '18 at 05:54
  • Are the values `latitude = 52.3648111;` and `longitude = 4.8810906;` always constant? Don't you need to change them? – Megidd Apr 09 '18 at 06:22
  • No it's just for testing only ;) So let's say I want to get all the poi's within 5km radius from centerpoint. – fransyozef Apr 09 '18 at 07:59
  • So, I wonder how you want to develop a map function when `latitude` and `longitude` are variables. I mean, how would the map function be in that case? – Megidd Apr 09 '18 at 08:11
  • 1
    I'm still figuring that out ;) . will post here when I have a working example – fransyozef Apr 09 '18 at 08:27
  • 1
    Yeah so just figured out, the map function doesn't accept custom GET uri variables :( So I cannot set the centerpoint – fransyozef Apr 10 '18 at 08:21
  • If one of the answers below answered your question, the way this site works works, you'd "accept" the answer, more here: [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) . But only if your question really has been answered. If not, consider adding more details to the question. – Juanjo Rodriguez Apr 11 '18 at 19:41
0

I have an alternative proposal for your use case. The proposal is to use geohashes.

You can store the position in the document as a geohash. The lenght of the geohash will depends on the precission you would like to store.

Let consider that you stored the position with around 150 meters precession. In this case, you'll have a geohash of 7 characters like 'gbsukp7'. Check this for testing.

Then your map function can be redefined in this way:

function (doc) {
 emit([doc.geohash.substr(0,4), /* 39.1km × 19.5km bounding box */
      doc.geohash.substr(0,5), /* 4.89km ×  4.89km bounding box */
      doc.geohash.substr(0,6), /* 1.22km ×  0.61km bounding box */
      doc.geohash /* 153m × 153m bounding box */
      ],null)
}

With this approach you can have a simple mechanism to get the documents located in the same bounding box than the point of refrence.

It is not perfect but could be an option

Juanjo Rodriguez
  • 2,103
  • 8
  • 19
  • Hmm .. But I dont understand how to set the box dynamicly. I mean, this would be like an app that would get the poi's within the box, so I need to supply the box data each time. So the box is not hardcoded. – fransyozef Apr 10 '18 at 08:20
  • oh wait .. I just realised .. I can calculate the centerpoint geohash and send that to the view. Then in my couchDB I already have documents with calculated geohashes and then match that – fransyozef Apr 10 '18 at 08:24
  • You don't need to calculate the center point, just encode the reference position as a geohash with the precission you require. Then use it in the view filtering: ...?startkey=["gbsu"]&endkey=["gbsu",{}] – Juanjo Rodriguez Apr 10 '18 at 15:07
  • Yeah .. that's what I meant :) – fransyozef Apr 10 '18 at 17:56