1
votes

I get a Run-time error when using boost::geometry::intersects to judge if two geometries intersect each other, I get this errors:

test:/bigdisk/geo.algorithms/mason_packages/headers/boost/1.65.1/include/boost/geometry/policies/robustness/segment_ratio.hpp:54: static bool boost::geometry::detail::segment_ratio::less::apply(const Ratio&, const Ratio&) [with Ratio = boost::geometry::segment_ratio; Type = double]: Assertion `lhs.denominator() != 0' failed. line1 equals line2: Aborted

It's not obvious what the problem is to my naive eyes. If anyone has any suggestions I would be very grateful.

I have adapted boost geometry to my own geometry model and boost's intersects function just aborted in this case:

    point<double, GCJ02LL> pt11{118.8031, 32.10011};
    point<double, GCJ02LL> pt12{118.80297, 32.10016};
    point<double, GCJ02LL> pt13{118.80284, 32.10021};
    dataop::geometry::line_string<double, GCJ02LL> line1{pt11, pt12, pt13};
    dataop::geometry::line_string<double, GCJ02LL> line2{pt11, pt12, pt13};
    std::cout << "line1 intersects line2? : " << intersects(line1, line2) << std::endl;

you can see my two line_strings is same, but it is not the problem because in other cases it runs well.

Even more strange is that the boost::geometry::equal will also aborted in this case like this:

    point<double, GCJ02LL> pt11{118.8031, 32.10011};
    point<double, GCJ02LL> pt12{118.80297, 32.10016};
    point<double, GCJ02LL> pt13{118.80284, 32.10021};
    dataop::geometry::line_string<double, GCJ02LL> line1{pt11, pt12, pt13};
    std::cout << "line1 equal line1? " << equal(line1, line1) << std::endl;
1

1 Answers

0
votes

An assertion fires. Some of your data is invalid / not suited for the operation you're trying to perform.

Specifically, an internal calculation step encountered a fraction (p/q) where the denominator (q) is zero. That's not gonna fly.

Now, causes for this would be unmet pre-conditions.

Perhaps your geometries aren't valid (have you tried bg::is_valid()? have you looked at bg::correct()?).

If all pre-conditions have been met, the culprit could be in the adaptation of your custom types. If the adaptation invokes undefined behaviour (e.g. mistakenly returning a reference to temporaries) then all bets are off.

Test Bed

You can adapt this test bed to get some of the diagnostics:

Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

#include <iostream>

namespace bg = boost::geometry;
namespace bgm = bg::model;

int main() {
    using P = bgm::d2::point_xy<double>;
    P pt11{ 118.8031, 32.10011 };
    P pt12{ 118.80297, 32.10016 };
    P pt13{ 118.80284, 32.10021 };
    bgm::linestring<P> line1{ pt11, pt12, pt13 };
    bgm::linestring<P> line2{ pt11, pt12, pt13 };
    std::string reason;
    std::cout << std::boolalpha;
    std::cout << "line1 valid? " << bg::is_valid(line1, reason) << " (" << reason << ")\n";
    std::cout << "line2 valid? " << bg::is_valid(line2, reason) << " (" << reason << ")\n";
    std::cout << "line1 intersects line2? : " << bg::intersects(line1, line2) << std::endl;
}

Needless to say, the above succeeds with the clean output:

line1 valid? true (Geometry is valid)
line2 valid? true (Geometry is valid)
line1 intersects line2? : true