diff --git a/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp b/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp index 24655ab3d..221dbe030 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp @@ -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. diff --git a/test/algorithms/buffer/linestring_buffer.cpp b/test/algorithms/buffer/linestring_buffer.cpp index ca117bb5c..1b5ed0354 100644 --- a/test/algorithms/buffer/linestring_buffer.cpp +++ b/test/algorithms/buffer/linestring_buffer.cpp @@ -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("aimes181", aimes181, join_round_by_divide, end_round, 2.57415564419716247e-08, 0.000036, 0.000036, true, tolerance); } - test_one("crossing", crossing, join_round32, end_flat, 1702.119, 20.0); - test_one("crossing", crossing, join_round32, end_round32, 2140.450, 20.0); + // On one compiler 1702.56530051454502 2140.78725663358819 + // so we increase tolerance + test_one("crossing", crossing, join_round32, end_flat, 1702.1, 20.0, 20.0, true, 0.5); + test_one("crossing", crossing, join_round32, end_round32, 2140.4, 20.0, 20.0, true, 0.5); test_one("mikado1", mikado1, join_round32, end_round32, 5441135039.0979, 41751.0); +} +template +void test_invalid() +{ + typedef bg::model::linestring

linestring; + typedef bg::model::polygon 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("mysql_report_2015_04_10a", mysql_report_2015_04_10a, join_round32, end_round32, 86496.5005, 100.0); + test_one("mysql_report_2015_04_10b", mysql_report_2015_04_10b, join_round32, end_round32, 86496.5005, 100.0); + test_one("mysql_report_2015_04_10c", mysql_report_2015_04_10c, join_round32, end_round32, 86496.5005, 100.0); + test_one("mysql_report_2015_04_10d", mysql_report_2015_04_10d, join_round32, end_round32, 86496.5005, 100.0); + test_one("mysql_report_2015_04_10e", mysql_report_2015_04_10e, join_round32, end_round32, 86496.5005, 100.0); + test_one("mysql_report_2015_04_10f", mysql_report_2015_04_10f, join_round32, end_round32, 86496.5005, 100.0); +#endif - // The equivalent case - test_one("mysql_report_2015_04_10b", mysql_report_2015_04_10b, join_round32, end_round32, 86531.4817, 100.0); + // The equivalent, valid, case + test_one("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 #endif @@ -260,5 +283,8 @@ int test_main(int, char* []) test_all >(); test_all >(); //test_all >(); + + test_invalid >(); +// test_invalid >(); return 0; } diff --git a/test/algorithms/buffer/multi_linestring_buffer.cpp b/test/algorithms/buffer/multi_linestring_buffer.cpp index 46431c18c..c48127164 100644 --- a/test/algorithms/buffer/multi_linestring_buffer.cpp +++ b/test/algorithms/buffer/multi_linestring_buffer.cpp @@ -99,10 +99,12 @@ void test_all() test_one("mikado4_small", mikado4, join_round32, end_round32, 2103.686, 10.0); test_one("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("mysql_2015_04_10", mysql_2015_04_10, join_round32, end_round32, 15471237017.3871, 0.98); +#endif }