Как запросить, находится ли поле в пределах дерева - PullRequest
0 голосов
/ 30 июня 2018

Вопрос

Почему мой запрос для определения, находится ли box в пределах rtree, возвращает пустой результат?

Объяснение

Возьми линейную линию

LINESTRING(1 1, 2 2)

и два полигона

POLYGON((0 0,0 1,1 1,1 0,0 0))
POLYGON((0 0,0 3,3 3,3 0,0 0))

Я могу использовать boost::geometry::witin(), чтобы запросить, находится ли линейная строка в любом полигоне (и это работает)

Однако, если я создаю rtree полигонов и помещаю box вокруг linestring, запрашивая, если box равен within, rtree возвращает пустой результат.

* +1025 * Пример

Вот пример, показывающий как рабочий bg::within(line, polygon), так и нерабочий rtree.query(bgi::within( line_box1 ), ...)

void rtree_within() {

  typedef bgm::point< double, 2, bg::cs::cartesian > point;
  typedef bgm::box<point> box;
  typedef bgm::linestring<point> line;
  typedef bgm::polygon<point> polygon;

  typedef std::pair<box, unsigned> value;

  bgi::rtree<value, bgi::quadratic<16> > rtree;
  std::vector<value> result_s;

  polygon poly1;
  polygon poly2;
  line line1;

  bg::read_wkt("POLYGON((0 0,0 1,1 1,1 0,0 0))", poly1);
  bg::read_wkt("POLYGON((0 0,0 3,3 3,3 0,0 0))", poly2);
  bg::read_wkt("LINESTRING(1 1, 2 2)", line1);

  std::cout << "line2 in poly1: " << bg::within(line1, poly1) << std::endl;
  std::cout << "line2 in poly3: " << bg::within(line1, poly2) << std::endl;

  // boxes to insert into rtree
  box poly_box1 = bg::return_envelope<box>( poly1 );
  rtree.insert(std::make_pair(poly_box1, 0));

  box poly_box2 = bg::return_envelope<box>( poly2 );
  rtree.insert(std::make_pair(poly_box2, 2));

  // box around the line
  box line_box1 = bg::return_envelope<box>( line1 );

  std::cout << "poly_box1: " << bg::wkt( poly_box1 ) << std::endl; // returns 0
  std::cout << "poly_box2: " << bg::wkt( poly_box2 ) << std::endl; // returns 1
  std::cout << "line_box1: " << bg::wkt( line_box1 ) << std::endl;

  rtree.query(bgi::within( line_box1 ), std::back_inserter( result_s ));
  std::cout << "line_box1 within rtree - size: " << result_s.size() << std::endl;
  // result_s is empty (size == 0)

}

1 Ответ

0 голосов
/ 30 июня 2018

Когда вы вызываете свободную функцию within(geom1,geom2), она возвращает TRUE, если geom1 находится внутри geom2. Но когда вы читаете ссылку на использование within в качестве предиката

Создание предиката, определяющего соотношение Значение и Геометрия. Значение будет возвращено запросом, если bg :: inside (Indexable, Geometry) вернет true.

поэтому вы пытаетесь проверить, находится ли indexable внутри geometry, и результат равен false [indexable является прямоугольным, геометрия является линейным]. Вы должны использовать предикат contains вместо within, используя rtree. contains предикат эквивалентен bg::within(Geometry, Indexable), тогда ваш код работает как положено.

...