7

I have stored a route in ElasticSearch as a Polygon. Now I have a circle (A point and a radius), I'am able to check the circle points intersects the polygon or not (Below is the code I used).

Question: How can I get the points in the route which intersects the circle ?

Route and Circle

public Boolean isMatchingDoc(Long elasticDocId, Double latitude, Double longitude, Long radius) {
    Coordinate origin = new Coordinate(latitude, longitude);
    ShapeBuilder circleShapeBuilder = ShapeBuilder.newCircleBuilder().center(origin).radius(radius,
            DistanceUnit.METERS);
    GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("route", circleShapeBuilder);
    SearchRequestBuilder finalQuery = client.prepareSearch(INDEX).setTypes(TYPE)
            .setQuery(QueryBuilders.termQuery("_id", elasticDocId)).setPostFilter(geoShapeQueryBuilder);
    SearchResponse searchResponse = finalQuery.execute().actionGet();
    SearchHits searchHits = searchResponse.getHits();
    if (searchHits.getTotalHits() > 0) {
        return true;
    }
    return false;
}
Viswanath Lekshmanan
  • 9,945
  • 1
  • 40
  • 64
  • 1
    Since you have a polygon you have a bunch of lines that you can check for intersection. You should be able to find quite a lot of methods on how to do that in a web search (I'd search for either "circle line intersection" or "circle polygon intersection") – Thomas Jul 04 '16 at 07:44
  • @Thomas I tried those already. I can't go and manually apply any formula over all these points. I have lot of data. So I'am not looking for an out of box solution. I checked the ES API and didn't find any .... – Viswanath Lekshmanan Jul 04 '16 at 11:00
  • I don't quite get on why it shouldn't be possible. Just pass in the points and iterate over them, building a line segment from i and i + 1 and checking that for intersection. Performance might be an issue if you have a lot of points but there are some options to speed things up, though which would be applicable depends on the circumstances. – Thomas Jul 04 '16 at 11:37
  • @Thomas Each route contains 1000 - 15000 points and there may be atmost 10 routes. Surely it will lead me to a performance issue. That is why iam looking for a ES API – Viswanath Lekshmanan Jul 04 '16 at 17:09
  • There probably is no direct API to do that. You could try some screen space collision detection based approach though. Or create a hierarchy of approximations (bounding spheres, bounding boxes etc.) to narrow down the line segments that could possibly intersect. – Thomas Jul 05 '16 at 07:15
  • Would you be able to post the code of the data you store in your ElasticSearch and how you use it to paint on the container so that I may give you a more direct answer? – Dan Jul 12 '16 at 13:57
  • I store it as a polygon (An array of LatLng). No customized data schema there. – Viswanath Lekshmanan Jul 16 '16 at 14:13

1 Answers1

0

I guess you are aware that with elasticsearch, you can query for polygons that intersect a given circle? See https://www.elastic.co/guide/en/elasticsearch/guide/current/querying-geo-shapes.html.

There are two reasons why this may not help you:

  1. Your routes are not polygons, but lines.
  2. You want to know the exact points of the intersection, if I read your question correctly.

Elasticsearch probably cannot solve this problem for you conveniently. It might be possible to solve if you would store all of your line-segments separately instead of in one huge polygon per route. Each line-segment then would have to bear an attribute that references the route it belongs to. Does that approach sound feasible to you?

Anyways, I would recommend you to look into the topic of "spatial databases": Spatial databases are optimized for indexing and searching in a geometric space. Well-know databases such as PostgreSQL and MongoDB feature plugins/extensions for spatial indexing. I'm not sure what to recommend, but the MongoDB geospatial API looks promising for example, as it allows querying for intersection - and it supports lines as well as polygons.

Andreas Vogl
  • 1,776
  • 1
  • 14
  • 18
  • Even its a polygon/line or whatever , it is simply set of latlng right? If ES is able to compare points, they should be able to retrieve it as well. I can see that as a design issue of the API. True/false returned from a datastore is useless. – Viswanath Lekshmanan Jul 14 '16 at 04:52