Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/boost/geometry/algorithms/detail/overlay/overlay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,10 @@ struct overlay

// Select all rings which are NOT touched by any intersection point
std::map<ring_identifier, properties> selected_ring_properties;
// When the overlay produced no turns, allow a point on the boundary to
// count as within the other geometry (see issue 1471).
select_rings<OverlayType>(geometry1, geometry2, turn_info_per_ring,
selected_ring_properties, strategy);
selected_ring_properties, strategy, turns.empty());

// Add rings created during traversal
{
Expand Down
36 changes: 23 additions & 13 deletions include/boost/geometry/algorithms/detail/overlay/select_rings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ inline void update_ring_selection(Geometry1 const& geometry1,
TurnInfoMap const& turn_info_map,
RingPropertyMap const& all_ring_properties,
RingPropertyMap& selected_ring_properties,
Strategy const& strategy)
Strategy const& strategy,
bool include_on_boundary = false)
{
selected_ring_properties.clear();

Expand All @@ -261,23 +262,30 @@ inline void update_ring_selection(Geometry1 const& geometry1,
continue;
}

// Check if the ring is within the other geometry, by taking
// a point lying on the ring
// Check if the ring is within the other geometry, by using
// a point on the ring.
int code = 0;
switch(id.source_index)
{
// within
case 0 :
info.within_other = range_in_geometry(pair.second.point,
geometry1, geometry2,
strategy) > 0;
code = range_in_geometry(pair.second.point,
geometry1, geometry2, strategy);
break;
case 1 :
info.within_other = range_in_geometry(pair.second.point,
geometry2, geometry1,
strategy) > 0;
code = range_in_geometry(pair.second.point,
geometry2, geometry1, strategy);
break;
}

// Code 0: the point is located on the boundary. Normally such a
// situation is resolved by the turns (the rings are traversed).
// But if the overlay produced no turns at all, and the inputs are (nearly)
// coincident without any segment intersection being detected (such as
// issue 1471), then a point on the boundary should be counted as being
// within the other geometry.
info.within_other = include_on_boundary ? code >= 0 : code > 0;

if (decide<OverlayType>::include(id, info))
{
auto properties = pair.second; // Copy by value
Expand All @@ -303,7 +311,8 @@ template
inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
RingTurnInfoMap const& turn_info_per_ring,
RingPropertyMap& selected_ring_properties,
Strategy const& strategy)
Strategy const& strategy,
bool include_on_boundary = false)
{
using tag1 = geometry::tag_t<Geometry1>;
using tag2 = geometry::tag_t<Geometry2>;
Expand All @@ -318,7 +327,7 @@ inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,

update_ring_selection<OverlayType>(geometry1, geometry2, turn_info_per_ring,
all_ring_properties, selected_ring_properties,
strategy);
strategy, include_on_boundary);
}

template
Expand All @@ -332,7 +341,8 @@ template
inline void select_rings(Geometry const& geometry,
RingTurnInfoMap const& turn_info_per_ring,
RingPropertyMap& selected_ring_properties,
Strategy const& strategy)
Strategy const& strategy,
bool include_on_boundary = false)
{
RingPropertyMap all_ring_properties;
dispatch::select_rings<geometry::tag_t<Geometry>, Geometry>::apply(geometry,
Expand All @@ -341,7 +351,7 @@ inline void select_rings(Geometry const& geometry,

update_ring_selection<OverlayType>(geometry, geometry, turn_info_per_ring,
all_ring_properties, selected_ring_properties,
strategy);
strategy, include_on_boundary);
}


Expand Down
16 changes: 16 additions & 0 deletions test/algorithms/overlay/multi_overlay_cases.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,22 @@ static std::string issue_1354[2] =
"MULTIPOLYGON(((-161.64096882920154 -24.7006892825620064,-161.289685158351034 -24.4725629993453921,-160.946576972490334 -24.2323160611842638,-160.612062296092091 -23.9802411719655595,-160.286548683761538 -23.7166454461126293,-159.970432723693705 -23.4418500344136262,-159.664099554492026 -23.1561897327487074,-159.367922395936176 -22.8600125741928615,-159.082262094271272 -22.5536794049911933,-158.807466682572255 -22.2375634449233637,-158.543870956719331 -21.9120498325927926,-158.291796067500627 -21.5775351561945712,-158.051549129339492 -21.2344269703338533,-157.823422846122895 -20.8831432994833506,-157.607695154586736 -20.5241121286848909,-157.404628885692887 -20.1577708821155781,-157.21447144440998 -19.7845658901538215,-157.037454508288789 -19.4049518455944927,-156.873793745198554 -19.0193912496758344,-156.723688550569108 -18.6283538485929157,-156.587321804458156 -18.2323160611842603,-156.464859648740173 -17.8317603984888819,-156.356451284688035 -17.4271748758809046,-156.262228791194332 -17.0190524184980028,-156.182306963853506 -16.6078902606880554,-156.116783175101148 -16.1941893402056749,-156.065737255580729 -15.7784536878967323,-156.029231396882096 -15.361189813614395,-156.007310075770846 -14.9429060891149028,-156 -14.5241121286848909,-156 -0.659861765609321083,-156 -0.659861765609321083,-156.007310075770874 -0.24106780517901305,-156.029231396882125 0.177215919320473647,-156.065737255580757 0.594479793602806117,-156.116783175101205 1.01021544591174406,-156.182306963853563 1.42391636639411612,-156.262228791194389 1.8350785242040577,-156.35645128468812 2.24320098158695203,-156.464859648740259 2.64778650419492223,-156.587321804458242 3.04834216689029436,-156.723688550569193 3.44437995429894173,-156.87379374519864 3.83541735538185424,-157.037454508288874 4.22097795130050457,-157.214471444410094 4.6005919958598227,-157.404628885693 4.97379698782157575,-157.60769515458685 5.34013823439087876,-157.823422846123009 5.69916940518932957,-158.051549129339634 6.0504530760398243,-158.291796067500769 6.39356126190053153,-158.543870956719473 6.72807593829874495,-158.807466682572397 7.05358955062930804,-159.082262094271414 7.36970551069712698,-159.367922395936318 7.67603867989878808,-159.664099554492168 7.97221583845462689,-159.970432723693847 8.25787614011953508,-160.28654868376168 8.53267155181853276,-160.612062296092233 8.79626727767145233,-160.946576972490448 9.04834216689014958,-161.289685158351176 9.28858910505127255,-161.640968829201682 9.51671538826787611,-162.000000000000142 9.73244307980402112,-162.366341246569448 9.93550934869787383,-162.739546238531204 10.1256667899807482,-163.119160283090537 10.3026837261019484,-163.504720879009199 10.4663444891921795,-163.89575828009211 10.6164496838216245,-164.291796067500741 10.7528164299325617,-164.692351730196123 10.8752785856505412,-165.096937252804111 10.9836869497026655,-165.505059710186998 11.0779094431963721,-165.916221867996938 11.1578312705371943,-166.329922788479308 11.2233550592895384,-166.745658440788247 11.2744009788099682,-167.162922315070603 11.3109068375085773,-167.581206039570077 11.3328281586198312,-168.000000000000085 11.3401382343906789,-168.418793960430094 11.3328281586198258,-168.837077684929568 11.3109068375085648,-169.254341559211923 11.2744009788099522,-169.670077211520862 11.2233550592895135,-170.083778132003232 11.1578312705371641,-170.494940289813172 11.077909443196333,-170.90306274719606 10.9836869497026228,-171.307648269804048 10.8752785856504914,-171.708203932499401 10.7528164299325084,-172.10424171990806 10.6164496838215658,-172.495279120990972 10.4663444891921138,-172.880839716909634 10.3026837261018773,-173.260453761468966 10.1256667899806718,-173.633658753430694 9.93550934869779212,-174 9.73244307980393408,-174.35903117079846 9.51671538826778551,-174.710314841648966 9.28858910505117663,-175.053423027509666 9.04834216689004656,-175.387937703907909 8.79626727767134398,-175.713451316238462 8.53267155181842085,-176.029567276306295 8.25787614011941784,-176.335900445507946 7.97221583845450077,-176.632077604063795 7.67603867989865307,-176.917737905728728 7.36970551069698487,-177.192533317427717 7.05358955062915793,-177.456129043280669 6.72807593829858508,-177.708203932499373 6.39356126190036278,-177.948450870660508 6.05045307603964844,-178.176577153877105 5.69916940518914394,-178.392304845413264 5.34013823439068602,-178.595371114307113 4.97379698782137414,-178.785528555589991 4.60059199585961309,-178.962545491711211 4.22097795130028608,-179.126206254801446 3.83541735538162776,-179.276311449430892 3.44437995429870725,-179.412678195541844 3.04834216689005189,-179.535140351259827 2.64778650419467221,-179.643548715311965 2.24320098158669401,-179.737771208805668 1.83507852420379303,-179.817693036146494 1.42391636639384433,-179.883216824898852 1.01021544591146517,-179.934262744419271 0.59447979360252079,-179.970768603117904 0.177215919320182214,-179.992689924229154 -0.241067805179310257,-180 -0.659861765609321083,-180 -14.5241121286848909,-179.992689924229154 -14.942906089114862,-179.970768603117904 -15.3611898136143541,-179.9342627444193 -15.7784536878966932,-179.883216824898852 -16.1941893402056394,-179.817693036146494 -16.6078902606880163,-179.737771208805668 -17.0190524184979672,-179.643548715311965 -17.4271748758808691,-179.535140351259827 -17.8317603984888464,-179.412678195541844 -18.2323160611842248,-179.276311449430921 -18.6283538485928801,-179.126206254801474 -19.0193912496758024,-178.962545491711239 -19.4049518455944607,-178.78552855559002 -19.7845658901537895,-178.595371114307142 -20.1577708821155497,-178.392304845413292 -20.5241121286848625,-178.176577153877133 -20.8831432994833222,-177.948450870660508 -21.2344269703338284,-177.708203932499373 -21.5775351561945428,-177.456129043280669 -21.9120498325927642,-177.192533317427745 -22.2375634449233388,-176.917737905728757 -22.5536794049911684,-176.632077604063824 -22.8600125741928366,-176.335900445507974 -23.1561897327486861,-176.029567276306324 -23.4418500344136049,-175.713451316238491 -23.7166454461126079,-175.387937703907909 -23.9802411719655382,-175.053423027509695 -24.2323160611842425,-174.710314841648994 -24.4725629993453779,-174.359031170798488 -24.7006892825619886,-174.000000000000028 -24.9164169740981407,-173.633658753430723 -25.1194832429920041,-173.260453761468938 -25.3096406842748856,-172.880839716909634 -25.4866576203960911,-172.495279120990972 -25.6503183834863329,-172.104241719908032 -25.8004235781157831,-171.708203932499401 -25.9367903242267275,-171.307648269804019 -26.0592524799447105,-170.903062747196032 -26.1676608439968419,-170.494940289813144 -26.2618833374905556,-170.083778132003175 -26.3418051648313849,-169.670077211520805 -26.4073289535837326,-169.254341559211866 -26.4583748731041695,-168.837077684929511 -26.4948807318027804,-168.418793960430037 -26.5168020529140378,-168.000000000000028 -26.5241121286848909,-167.581206039569992 -26.5168020529140378,-167.162922315070517 -26.4948807318027804,-166.745658440788162 -26.4583748731041695,-166.329922788479223 -26.4073289535837361,-165.916221867996853 -26.341805164831392,-165.505059710186913 -26.2618833374905591,-165.096937252803997 -26.167660843996849,-164.692351730196009 -26.0592524799447212,-164.291796067500627 -25.9367903242267381,-163.895758280091997 -25.8004235781157938,-163.504720879009056 -25.6503183834863435,-163.119160283090395 -25.4866576203961053,-162.739546238531091 -25.3096406842748962,-162.366341246569306 -25.1194832429920183,-162 -24.9164169740981585,-161.64096882920154 -24.7006892825620064)))"
};

static std::string issue_1471[2] =
{
"MULTIPOLYGON((("
"20.0970444515398512 -0.3449179410282249,"
"21.9812157674818778 -0.3449179410282249,"
"21.9812157674818778 -2.2293927797379025,"
"20.0970444515398512 -2.2293927797379025,"
"20.0970444515398512 -0.3449179410282249)))",
"MULTIPOLYGON((("
"20.0970444515398476 -0.3449179410282246,"
"21.9812157674818813 -0.3449179410282246,"
"21.9812157674818813 -2.2293927797379034,"
"20.0970444515398476 -2.2293927797379034,"
"20.0970444515398476 -0.3449179410282246)))"
};

static std::string bug_21155501[2] =
{
"MULTIPOLYGON(((-8.3935546875 27.449790329784214,4.9658203125 18.729501999072138,11.8212890625 23.563987128451217,9.7119140625 25.48295117535531,9.8876953125 31.728167146023935,8.3056640625 32.99023555965106,8.5693359375 37.16031654673677,-1.8896484375 35.60371874069731,-0.5712890625 32.02670629333614,-8.9208984375 29.458731185355344,-8.3935546875 27.449790329784214)))",
Expand Down
12 changes: 12 additions & 0 deletions test/algorithms/set_operations/set_ops_areal_areal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ void test_detail(std::string const& name, std::string const& wkt1, std::string c

BOOST_CHECK_MESSAGE(bgeo::math::abs(balance) < eps,
"Case: " << name << " wrong union or intersection " << balance);

// The relate-based predicates do not depend on the overlay ring traversal
// If two geometries intersect but do not merely touch, their interiors overlap
// and the intersection cannot be empty. This catches cases such as issue 1471.
BOOST_CHECK_MESSAGE(
! (bgeo::intersects(geometry1, geometry2)
&& ! bgeo::touches(geometry1, geometry2)
&& result_intersection.empty()),
"Case: " << name << " geometries intersect (not touching) but the intersection is empty");

if (settings.test_difference)
{
BOOST_CHECK_MESSAGE(bgeo::math::abs(balance_d1) < eps,
Expand Down Expand Up @@ -318,5 +328,7 @@ int test_main(int, char* [])
TEST_CASE_WITH(issue_1354, 0, 1, ut_settings().ignore_validity_union().ignore_diff());
#endif

TEST_CASE(issue_1471);

return 0;
}
Loading