tile38 icon indicating copy to clipboard operation
tile38 copied to clipboard

Filter with distance

Open vuchau opened this issue 4 years ago • 3 comments

I have a list of offers with format

    "offers": [
    {
      "lat": "33.66209712",
      "lng": "-84.1817986",
      "name": "offer_1",
      "allow_distance": 10
    },
    {
        "lat": "33.69103912",
        "lng": "-84.24225095",
        "name": "offer_2",
        "allow_distance": 5
      },

    ....
  ]
}

User need to filter the offers within radius on current location. eg. 6km. The big problem is to see the offers, the distance from user to offers must be lest than or equal with value of field allow_distance. I can combine multiple query and code to filter, but I want to know tile38 has any query statement to solve this case. Currently, I put data with command:

SET offers offer_n FIELD allow_distance n POINT x y

Filter command

NEARBY offers DISTANCE POINT lat long radius

Thanks,

vuchau avatar Mar 17 '20 10:03 vuchau

You could represent your offers as GeoJSON objects that approximate the offers range as a polygon then use the INTERSECTS command with a point.

e.g.

> SET offers offer_1 OBJECT {"type":"Polygon","coordinates":[[[-84.1817986,33.75192864841195],[-84.22314112812471,33.74508375080194],[-84.25817229604576,33.72559412355786],[-84.28155178555076,33.69643409967211],[-84.28972750872953,33.6620502220315],[-84.28147210031605,33.627680080450254],[-84.25805960392128,33.59855321839846],[-84.22306144262863,33.57909675306351],[-84.1817986,33.57226559158804],[-84.14053575737135,33.57909675306351],[-84.1055375960787,33.59855321839846],[-84.08212509968394,33.627680080450254],[-84.07386969127045,33.6620502220315],[-84.08204541444923,33.69643409967211],[-84.10542490395423,33.72559412355786],[-84.14045607187526,33.74508375080194],[-84.1817986,33.75192864841195]]]}
{"ok":true,"elapsed":"68.6µs"}
> SET offers offer_2 OBJECT {"type":"Polygon","coordinates":[[[-84.24225095,33.73595488420598],[-84.26291919527999,33.73253415489009],[-84.28043655529918,33.72279348898564],[-84.2921343812964,33.70821761686156],[-84.29623358567402,33.6910273826622],[-84.29211443143649,33.67384058624713],[-84.28040834192508,33.65927301367186],[-84.26289924540367,33.64954064732091],[-84.24225095,33.646123355794025],[-84.22160265459632,33.64954064732091],[-84.2040935580749,33.65927301367186],[-84.19238746856352,33.67384058624713],[-84.18826831432597,33.6910273826622],[-84.19236751870358,33.70821761686156],[-84.20406534470084,33.72279348898564],[-84.22158270472,33.73253415489009],[-84.24225095,33.73595488420598]]]}
{"ok":true,"elapsed":"20µs"}
> INTERSECTS offers OBJECT {"type":"Point","coordinates":[-84.28075790405273,33.70320652139349]
{"ok":true,"objects":[{"id":"offer_2","object":{"type":"Polygon","coordinates":[[[-84.24225095,33.73595488420598],[-84.26291919527999,33.73253415489009],[-84.28043655529918,33.72279348898564],[-84.2921343812964,33.70821761686156],[-84.29623358567402,33.6910273826622],[-84.29211443143649,33.67384058624713],[-84.28040834192508,33.65927301367186],[-84.26289924540367,33.64954064732091],[-84.24225095,33.646123355794025],[-84.22160265459632,33.64954064732091],[-84.2040935580749,33.65927301367186],[-84.19238746856352,33.67384058624713],[-84.18826831432597,33.6910273826622],[-84.19236751870358,33.70821761686156],[-84.20406534470084,33.72279348898564],[-84.22158270472,33.73253415489009],[-84.24225095,33.73595488420598]]]}}],"count":1,"cursor":0,"elapsed":"33µs"}

ghost avatar Mar 20 '20 19:03 ghost

{"ok":true,"objects":[{"id":"offer_2","object":{"type":"Polygon","coordinates":[[[-84.24225095,33.73595488420598],[-84.26291919527999,33.73253415489009],[-84.28043655529918,33.72279348898564],[-84.2921343812964,33.70821761686156],[-84.29623358567402,33.6910273826622],[-84.29211443143649,33.67384058624713],[-84.28040834192508,33.65927301367186],[-84.26289924540367,33.64954064732091],[-84.24225095,33.646123355794025],[-84.22160265459632,33.64954064732091],[-84.2040935580749,33.65927301367186],[-84.19238746856352,33.67384058624713],[-84.18826831432597,33.6910273826622],[-84.19236751870358,33.70821761686156],[-84.20406534470084,33.72279348898564],[-84.22158270472,33.73253415489009],[-84.24225095,33.73595488420598]]]}}],"count":1,"cursor":0,"elapsed":"33µs"}

Thanks for your help. It's means, need to generate Polygon base on location and allow_distance for each offer when saving to tile38? Could you help explain more?. Thanks

vuchauthanh-agilityio avatar Mar 23 '20 10:03 vuchauthanh-agilityio

For this example I just used the JS library 'circle-to-polygon'

The algorithm is pretty straight forward, as long as your circles don't cross the poles or the meridian. You find the points that are 'allowed_distance' away, going counter-clockwise in the number of steps that you want in your polygon.

The few things to keep in mind is:

  • GeoJSON follows the right-hand rule, so you need to specify your points counter-clockwise. If you specify clockwise then the area you want will be outside the shape while the rest of the world inside.
  • The first point and last point in your polygon must be the same, this is how you close the shape.
  • GeoJSON requires your coordinates pairs to defined as longitude, latitude, in that order.

ghost avatar Mar 23 '20 14:03 ghost