2016-07-04 31 views
7

Mam zapisaną trasę w ElasticSearch jako wielokąta. Teraz mam okrąg (punkt i promień), jestem w stanie sprawdzić, czy punkty koła przecinają wielokąt, czy nie (poniżej jest kod, którego użyłem).Jak uzyskać punkty przecięcia z kształtu w ElasticSearch

Pytanie: Jak mogę zdobyć punkty na trasie przecinającej okrąg?

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; 
} 
+1

Ponieważ masz wielokąt, masz kilka linii, które możesz sprawdzić na przecięciu. Powinieneś być w stanie znaleźć całkiem sporo metod, jak to zrobić w wyszukiwaniu w Internecie (szukałem albo "przecięcia linii okręgu", albo "skrzyżowania wielokąta"). – Thomas

+0

@Thomas Próbowałem już. Nie mogę iść i ręcznie zastosować żadnej formuły we wszystkich tych punktach. Mam dużo danych. Więc nie szukam rozwiązania out of box. Sprawdziłem ES API i nie znalazłem żadnego .... –

+0

Nie rozumiem dlaczego nie powinno to być możliwe. Wystarczy przekazać punkty i powtórzyć je, budując odcinek linii od i oraz i + 1 i sprawdzając, czy na skrzyżowaniu. Wydajność może być problemem, jeśli masz dużo punktów, ale jest kilka opcji, które przyspieszają, ale które będą miały zastosowanie, zależy od okoliczności. – Thomas

Odpowiedz

0

Chyba zdajesz sobie sprawę, że z elasticsearch, można zapytać o wielokątów, które przecinają dany krąg? Zobacz https://www.elastic.co/guide/en/elasticsearch/guide/current/querying-geo-shapes.html.

Istnieją dwa powody, dla których nie może pomóc:

  1. Twoje trasy nie są wielokąty, ale linie.
  2. Chcesz poznać dokładne punkty przecięcia, jeśli poprawnie przeczytam twoje pytanie.

Elasticsearch prawdopodobnie nie rozwiąże tego problemu wygodnie. Może być możliwe rozwiązanie, jeśli chcesz przechowywać wszystkie swoje segmenty liniowe oddzielnie, zamiast w jednym wielkim wielokącie na trasie. Każdy segment linii musiałby wówczas mieć atrybut, który odwołuje się do trasy, do której należy. Czy to podejście brzmi dla ciebie wykonalne?

W każdym razie, polecam zapoznać się z tematem "baz danych przestrzennych": Przestrzenne bazy danych są zoptymalizowane do indeksowania i wyszukiwania w przestrzeni geometrycznej. Dobrze znane bazy danych, takie jak PostgreSQL i MongoDB, zawierają wtyczki/rozszerzenia do indeksowania przestrzennego. Nie jestem pewien, co polecić, ale na przykład MongoDB geospatial API wygląda obiecująco, ponieważ pozwala na zapytanie o skrzyżowanie - i obsługuje zarówno linie, jak i wielokąty.

+0

Nawet jeśli jest to wielokąt/linia, czy jakakolwiek, jest po prostu ustawiona na prawo? Jeśli ES jest w stanie porównywać punkty, powinny być również w stanie je odzyskać. Widzę to jako projektowe zagadnienie API. Wartość true/false zwrócona z magazynu danych jest bezużyteczna. –