[buffer] stop in case of numeric errors in side strategy

This commit is contained in:
barendgehrels 2015-05-24 11:22:45 +02:00
parent 62fa2ccc59
commit ad088fcf02
3 changed files with 46 additions and 7 deletions

View File

@ -73,6 +73,17 @@ public :
// For normalization [0,1] (=dot product d.d, sqrt)
promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
if (! boost::math::isfinite(length))
{
// In case of coordinates differences of e.g. 1e300, length
// will overflow and we should not generate output
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
std::cout << "Length not calculated for points " << geometry::wkt(input_p1)
<< " " << geometry::wkt(input_p2) << " " << length << std::endl;
#endif
return;
}
if (geometry::math::equals(length, 0))
{
// Coordinates are simplified and therefore most often not equal.

View File

@ -64,8 +64,14 @@ static std::string const mysql_report_2015_03_02b = "LINESTRING(0 1,0 5,5 5,5 0,
static std::string const mysql_report_2015_03_02c = "LINESTRING(0 2,0 5,5 5,5 0,2 0)"; // not closed, 2 difference
static std::string const mysql_report_2015_04_01 = "LINESTRING(103 5,107 2,111 4,116 -1,115 0,112 4)";
static std::string const mysql_report_2015_04_10a = "LINESTRING(1.922421e+307 1.520384e+308, 15 42, 89 -93,-89 -22)";
static std::string const mysql_report_2015_04_10b = "LINESTRING(0 0, 15 42, 89 -93,-89 -22)";
static std::string const mysql_report_2015_04_10b = "LINESTRING(15 42, 89 -93,-89 -22, 1.922421e+307 1.520384e+308)";
static std::string const mysql_report_2015_04_10c = "LINESTRING(15 42, 1.922421e+307 1.520384e+308, 89 -93,-89 -22)";
static std::string const mysql_report_2015_04_10d = "LINESTRING(1.922421e+307 1.520384e+308, 1.923421e+307 1.521384e+308, 15 42, 89 -93,-89 -22)";
static std::string const mysql_report_2015_04_10e = "LINESTRING(15 42, 89 -93,-89 -22, 1.922421e+307 1.520384e+308, 1.923421e+307 1.521384e+308)";
static std::string const mysql_report_2015_04_10f = "LINESTRING(15 42, 1.922421e+307 1.520384e+308, 1.923421e+307 1.521384e+308, 89 -93,-89 -22)";
static std::string const mysql_report_2015_04_10g = "LINESTRING(15 42, 89 -93,-89 -22)";
@ -235,21 +241,38 @@ void test_all()
test_one<linestring, polygon>("aimes181", aimes181, join_round_by_divide, end_round, 2.57415564419716247e-08, 0.000036, 0.000036, true, tolerance);
}
test_one<linestring, polygon>("crossing", crossing, join_round32, end_flat, 1702.119, 20.0);
test_one<linestring, polygon>("crossing", crossing, join_round32, end_round32, 2140.450, 20.0);
// On one compiler 1702.56530051454502 2140.78725663358819
// so we increase tolerance
test_one<linestring, polygon>("crossing", crossing, join_round32, end_flat, 1702.1, 20.0, 20.0, true, 0.5);
test_one<linestring, polygon>("crossing", crossing, join_round32, end_round32, 2140.4, 20.0, 20.0, true, 0.5);
test_one<linestring, polygon>("mikado1", mikado1, join_round32, end_round32, 5441135039.0979, 41751.0);
}
template <bool Clockwise, typename P>
void test_invalid()
{
typedef bg::model::linestring<P> linestring;
typedef bg::model::polygon<P, Clockwise> polygon;
bg::strategy::buffer::end_round end_round32(32);
bg::strategy::buffer::join_round join_round32(32);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
// Though the generated buffer of this linestring, containing extreme differences, is not correct, it resembles
// the equivalent (where the coordinates are set to 0). Both SQL Server and POSTGIS do not output anything for this case
test_one<linestring, polygon>("mysql_report_2015_04_10a", mysql_report_2015_04_10a, join_round32, end_round32, 86496.5005, 100.0);
test_one<linestring, polygon>("mysql_report_2015_04_10b", mysql_report_2015_04_10b, join_round32, end_round32, 86496.5005, 100.0);
test_one<linestring, polygon>("mysql_report_2015_04_10c", mysql_report_2015_04_10c, join_round32, end_round32, 86496.5005, 100.0);
test_one<linestring, polygon>("mysql_report_2015_04_10d", mysql_report_2015_04_10d, join_round32, end_round32, 86496.5005, 100.0);
test_one<linestring, polygon>("mysql_report_2015_04_10e", mysql_report_2015_04_10e, join_round32, end_round32, 86496.5005, 100.0);
test_one<linestring, polygon>("mysql_report_2015_04_10f", mysql_report_2015_04_10f, join_round32, end_round32, 86496.5005, 100.0);
#endif
// The equivalent case
test_one<linestring, polygon>("mysql_report_2015_04_10b", mysql_report_2015_04_10b, join_round32, end_round32, 86531.4817, 100.0);
// The equivalent, valid, case
test_one<linestring, polygon>("mysql_report_2015_04_10g", mysql_report_2015_04_10g, join_round32, end_round32, 86527.871, 100.0);
}
//#define HAVE_TTMATH
#ifdef HAVE_TTMATH
#include <ttmath_stub.hpp>
#endif
@ -260,5 +283,8 @@ int test_main(int, char* [])
test_all<true, bg::model::point<double, 2, bg::cs::cartesian> >();
test_all<false, bg::model::point<double, 2, bg::cs::cartesian> >();
//test_all<bg::model::point<tt, 2, bg::cs::cartesian> >();
test_invalid<true, bg::model::point<double, 2, bg::cs::cartesian> >();
// test_invalid<true, bg::model::point<long double, 2, bg::cs::cartesian> >();
return 0;
}

View File

@ -99,10 +99,12 @@ void test_all()
test_one<multi_linestring_type, polygon>("mikado4_small", mikado4, join_round32, end_round32, 2103.686, 10.0);
test_one<multi_linestring_type, polygon>("mikado4_small", mikado4, join_round32, end_flat, 1930.785, 10.0);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
// Coordinates vary so much that
// length = geometry::math::sqrt(dx * dx + dy * dy); returns a value of inf for length
// Buffer is still generated though (see also linestring.cpp)
test_one<multi_linestring_type, polygon>("mysql_2015_04_10", mysql_2015_04_10, join_round32, end_round32, 15471237017.3871, 0.98);
#endif
}