Opened 6 years ago

Last modified 6 years ago

#12197 new Bugs

is_valid returns self-intersection error for multipolygons with many decimal

Reported by: jean.sebastien.carrier@… Owned by: Barend Gehrels
Milestone: To Be Determined Component: geometry
Version: Boost 1.59.0 Severity: Problem
Keywords: Cc:

Description

The following code:

typedef boost::geometry::model::polygon<Point> Polygon;
typedef boost::geometry::model::multi_polygon<Polygon> MultiPolygon;

Polygon outer1{ {
   { 2753.82399, 22518.895 },
   { 2790.93453, 22448.2618 },
   { 14793.2302, 27809.5376 },
   { 14590.7789, 28141.4075 },
   { 16120.2042, 25634.299 },
   { 16830.1157, 23682.3504 },
   { 3698, 17280.4245 },
   { 3698, 20053 },
   { 3290.86756, 20924.5835 },
   { 3140.68998, 21523.9236 },
   { 2753.82399, 22518.895 }
} };

Polygon outer2{ {
   { -4891.23816, 18463.1873 },
   { -5184.20528, 17101.1945 },
   { -5793.67689, 15410.9396 },
   { -6670.90183, 13924.6072 },
   { -7655.52041, 12671.2939 },
   { -8707.48466, 11854.286 },
   { -9810.20847, 11342.7777 },
   { -11002.6639, 11255.3896 },
   { -12121.6054, 11341.764 },
   { -13226.5153, 11854.286 },
   { -14278.4796, 12671.2939 },
   { -14967.9231, 13548.8837 },
   { -4891.23816, 18463.1873 }
} };

Polygon outer3{ {
   { -15799.8356, 25348.5883 },
   { -15939.2155, 25634.3426 },
   { -14410.8012, 28141.3084 },
   { -12165.7175, 30390.1272 },
   { -9561.60646, 32349.5454 },
   { -6622.17286, 33700.601 },
   { -3329.74574, 34602.3629 },
   { -0.657491358, 34754.8041 },
   { 3511.98218, 34602.0035 },
   { 3199.23919, 34615.6034 },
   { -15799.8356, 25348.5883 }
} };

MultiPolygon multiPolygon;
multiPolygon.push_back(outer1);
multiPolygon.push_back(outer2);
multiPolygon.push_back(outer3);

std::cout << (boost::geometry::is_valid(outer1) ? "outer1 is valid" : "outer1 is invalid") << std::endl;
std::cout << (boost::geometry::is_valid(outer2) ? "outer2 is valid" : "outer2 is invalid") << std::endl;
std::cout << (boost::geometry::is_valid(outer3) ? "outer3 is valid" : "outer3 is invalid") << std::endl;
std::cout << (boost::geometry::intersects(outer1, outer2) ? "1 and 2 intersects" : "1 and 2 do not intersects") << std::endl;
std::cout << (boost::geometry::intersects(outer1, outer3) ? "1 and 3 intersects" : "1 and 3 do not intersects") << std::endl;
std::cout << (boost::geometry::intersects(outer3, outer2) ? "3 and 2 intersects" : "3 and 2 do not intersects") << std::endl;
boost::geometry::validity_failure_type failure;
auto test = boost::geometry::is_valid(multiPolygon, failure);
std::cout << (test ? "multiPolygon is valid " : "multiPolygon is invalid ") << failure << std::endl;

will fail (and show error code 21), but keep the same values, shorten every number by a few decimals, and all of a sudden, is_valid starts working again

typedef boost::geometry::model::polygon<Point> Polygon;
typedef boost::geometry::model::multi_polygon<Polygon> MultiPolygon;

Polygon outer1{ {
{2753.82, 22518.9},
{2790.93, 22448.3},
{14793.2, 27809.5},
{14590.8, 28141.4},
{16120.2, 25634.3},
{16830.1, 23682.4},
{3698, 17280.4}   ,
{3698, 20053}     ,
{3290.87, 20924.6},
{3140.69, 21523.9},
{2753.82, 22518.9}
} };

Polygon outer2{ {
{-4891.24, 18463.2},
{-5184.21, 17101.2},
{-5793.68, 15410.9},
{-6670.9, 13924.6} ,
{-7655.52, 12671.3},
{-8707.48, 11854.3},
{-9810.21, 11342.8},
{-11002.7, 11255.4},
{-12121.6, 11341.8},
{-13226.5, 11854.3},
{-14278.5, 12671.3},
{-14967.9, 13548.9},
{-4891.24, 18463.2}
} };

Polygon outer3{ {
{-15799.8, 25348.6},
{-15939.2, 25634.3},
{-14410.8, 28141.3},
{-12165.7, 30390.1},
{-9561.61, 32349.5},
{-6622.17, 33700.6},
{-3329.75, 34602.4},
{-0.657491, 34754.8},
{3511.98, 34602},
{3199.24, 34615.6},
{-15799.8, 25348.6}
} };

MultiPolygon multiPolygon;
multiPolygon.push_back(outer1);
multiPolygon.push_back(outer2);
multiPolygon.push_back(outer3);

std::cout << (boost::geometry::is_valid(outer1) ? "1 is valid" : "1 is invalid") << std::endl;
std::cout << (boost::geometry::is_valid(outer2) ? "2 is valid" : "2 is invalid") << std::endl;
std::cout << (boost::geometry::is_valid(outer3) ? "3 is valid" : "3 is invalid") << std::endl;
std::cout << (boost::geometry::intersects(outer1, outer2) ? "1 and 2 intersects" : "1 and 2 do not intersects") << std::endl;
std::cout << (boost::geometry::intersects(outer1, outer3) ? "1 and 3 intersects" : "1 and 3 do not intersects") << std::endl;
std::cout << (boost::geometry::intersects(outer3, outer2) ? "3 and 2 intersects" : "3 and 2 do not intersects") << std::endl;
std::cout << (boost::geometry::is_valid(multiPolygon) ? "multiPolygon is valid" : "multiPolygon is invalid") << std::endl;

Change History (1)

comment:1 by John Maddock, 6 years ago

Component: Nonegeometry
Owner: set to Barend Gehrels
Note: See TracTickets for help on using tickets.