boost::geometry::distance compile errors with 3D primitives

719 views Asked by At

I am trying to calculate the nearest segment from another segment in a 3-dimensional space using the boost::geometry::index::nearest query on a boost:: boost::geometry::index::rtree but I get the following compilation error:

error C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************(__cdecl boost::geometry::nyi::not_implemented_error::THIS_OPERATION_IS_NOT_OR_NOT_YET_IMPLEMENTED::* ***********)(boost::mpl::assert_::types)' to 'boost::mpl::assert::type'

I have managed to narrow down the same issue to using just the boost::geometry::distance function:

typedef boost::geometry::model::point <float, 3, boost::geometry::cs::cartesian> point;
typedef boost::geometry::model::segment <point> segment;

point pa = point(x1, y1, z1);
point pc = point(x2, y2, z2);
point pb = point(x3, y3, z3);

float dist = boost::geometry::distance(segment(pa, pb), segment(pa, pc));

According to the documentation of the version of Boost I'm using (1.60) this should be supported, however it works just fine when using two dimensions.

http://www.boost.org/doc/libs/1_60_0/libs/geometry/doc/html/geometry/reference/algorithms/distance/distance_2.html#geometry.reference.algorithms.distance.distance_2.supported_geometries

I could not find anything in the docs either about how to extend the functionality or whether it's possible at all.

1

There are 1 answers

0
Artoo On BEST ANSWER

After exchanging a few messages with @awulkiew from Boost development you can see the current workarounds in this ticket.

At this point there's no implementation for a few internal functions for N-dimensional segments:

Yes, it seems that disjoint/intersects is not yet implemented for N-dimensional segments. And distance() calls this algorithm.

As a workaround you could store bounding boxes of segments in the R-tree, then search for Boxes nearest to some query Box using iterative query, in each iteration check the actual distance between segments using your own implementation and stop if your k-th found segment is closer than the distance between the bounding box passed into the query and the bounding box found in the current iteration. So basically use the index how you'd use it for any other Geometry.

There's also another workaround involving overriding internal Boost functions, but it's been discouraged as those may change in the future:

I'd discourage you from hooking in your own functions in case something changed in the future internally in the rtree (e.g. different functions were used). But if you'd like to try it you could overload bg::comparable_distance(segment, segment) and bg::comparable_distance(segment, box), e.g. like that:

namespace boost { namespace geometry {
    template <typename Box>
    float comparable_distance(segment const& s, Box const& b) { return 0; }
    float comparable_distance(segment const& s1, segment const& s2) { return 0; }
}}

Box would be of type internally used in the R-tree to represent nodes, so bg::model::box<...>.

Also, there's no ETA for adding support for this feature at the moment.

No ETA, currently we're adding support for 2d geographic CS.

In my case the solution would be to implement my own distance functions and use an algorithm like the proposed in the first workaround.