Skip to content

Commit 6c9a7e0

Browse files
Merge pull request #613 from barendgehrels/feature/changes-for-selfturns-and-tests
Feature/changes for selfturns and tests
2 parents 0eb4d31 + b3686c9 commit 6c9a7e0

File tree

17 files changed

+306
-167
lines changed

17 files changed

+306
-167
lines changed

extensions/test/algorithms/dissolve.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,6 @@ void test_one(std::string caseid, std::string const& wkt,
576576
template <typename P, bool Clockwise>
577577
void test_all(ut_settings const& settings_for_sensitive_cases)
578578
{
579-
typedef bg::model::ring<P, Clockwise> ring;
580579
typedef bg::model::polygon<P, Clockwise> polygon;
581580
typedef bg::model::multi_polygon<polygon> multi_polygon;
582581

@@ -652,7 +651,9 @@ void test_all(ut_settings const& settings_for_sensitive_cases)
652651
TEST_DISSOLVE_WITH(dissolve_reallife, 91756.916526794434, 1, 0, 25,
653652
settings_for_sensitive_cases);
654653

654+
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
655655
TEST_DISSOLVE(gitter_2013_04_a, 3043.9181, 3, 0, 21);
656+
#endif
656657

657658
TEST_DISSOLVE(gitter_2013_04_b, 31210.429356259738, 1, 0, 11);
658659

include/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,13 @@ class has_valid_self_turns
8787
is_acceptable_turn<Geometry>
8888
> interrupt_policy;
8989

90+
// Calculate self-turns, skipping adjacent segments
9091
detail::self_get_turn_points::self_turns<false, turn_policy>(geometry,
9192
strategy,
9293
robust_policy,
9394
turns,
94-
interrupt_policy);
95+
interrupt_policy,
96+
0, true);
9597

9698
if (interrupt_policy.has_intersections)
9799
{

include/boost/geometry/algorithms/detail/overlay/overlay.hpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -318,15 +318,20 @@ std::cout << "get turns" << std::endl;
318318
visitor.visit_turns(1, turns);
319319

320320
#if ! defined(BOOST_GEOMETRY_NO_SELF_TURNS)
321-
if (needs_self_turns<Geometry1>::apply(geometry1))
321+
if (! turns.empty() || OverlayType == overlay_dissolve)
322322
{
323-
self_get_turn_points::self_turns<Reverse1, assign_null_policy>(geometry1,
324-
strategy, robust_policy, turns, policy, 0);
325-
}
326-
if (needs_self_turns<Geometry2>::apply(geometry2))
327-
{
328-
self_get_turn_points::self_turns<Reverse2, assign_null_policy>(geometry2,
329-
strategy, robust_policy, turns, policy, 1);
323+
// Calculate self turns if the output contains turns already,
324+
// and if necessary (e.g.: multi-geometry, polygon with interior rings)
325+
if (needs_self_turns<Geometry1>::apply(geometry1))
326+
{
327+
self_get_turn_points::self_turns<Reverse1, assign_null_policy>(geometry1,
328+
strategy, robust_policy, turns, policy, 0);
329+
}
330+
if (needs_self_turns<Geometry2>::apply(geometry2))
331+
{
332+
self_get_turn_points::self_turns<Reverse2, assign_null_policy>(geometry2,
333+
strategy, robust_policy, turns, policy, 1);
334+
}
330335
}
331336
#endif
332337

include/boost/geometry/extensions/algorithms/dissolve.hpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,9 @@ struct dissolve_ring
200200
cluster_type clusters;
201201

202202
// Enrich/traverse the polygons
203-
typename Strategy::side_strategy_type const
204-
side_strategy = strategy.get_side_strategy();
205-
206203
enrich_intersection_points<Reverse, Reverse, overlay_dissolve>(turns,
207204
clusters, input_ring, input_ring, rescale_policy,
208-
side_strategy);
205+
strategy);
209206

210207
visitor.visit_turns(2, turns);
211208

@@ -374,7 +371,7 @@ struct dissolve_polygon
374371
// expect - alternatively, difference could be used to have them pure
375372
// as interior rings only
376373
return detail::sym_difference::sym_difference_insert<GeometryOut>(
377-
exterior_out, interior_out, rescale_policy, out);
374+
exterior_out, interior_out, out);
378375
}
379376
};
380377

test/algorithms/check_validity.hpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Boost.Geometry
2+
3+
// Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands.
4+
5+
// Use, modification and distribution is subject to the Boost Software License,
6+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#ifndef BOOST_GEOMETRY_TEST_CHECK_VALIDITY_HPP
10+
#define BOOST_GEOMETRY_TEST_CHECK_VALIDITY_HPP
11+
12+
#include <boost/foreach.hpp>
13+
14+
#include <boost/geometry/algorithms/is_valid.hpp>
15+
16+
template<typename Geometry, typename G1, typename G2>
17+
inline bool is_output_valid(Geometry const& geometry,
18+
std::string const& case_id,
19+
G1 const& g1, G2 const& g2,
20+
std::string& message)
21+
{
22+
bool const result = bg::is_valid(geometry, message);
23+
if (! result)
24+
{
25+
// Check if input was valid. If not, do not report output validity
26+
if (! bg::is_valid(g1) || ! bg::is_valid(g2))
27+
{
28+
std::cout << "WARNING: Input is not considered as valid; "
29+
<< "this can cause that output is invalid: " << case_id
30+
<< std::endl;
31+
return true;
32+
}
33+
}
34+
return result;
35+
}
36+
37+
template
38+
<
39+
typename Geometry,
40+
typename Tag = typename bg::tag<Geometry>::type
41+
>
42+
struct check_validity
43+
{
44+
template <typename G1, typename G2>
45+
static inline
46+
bool apply(Geometry const& geometry,
47+
std::string const& case_id,
48+
G1 const& g1, G2 const& g2,
49+
std::string& message)
50+
{
51+
return is_output_valid(geometry, case_id, g1, g2, message);
52+
}
53+
};
54+
55+
// Specialization for vector of <geometry> (e.g. rings)
56+
template <typename Geometry>
57+
struct check_validity<Geometry, void>
58+
{
59+
template <typename G1, typename G2>
60+
static inline
61+
bool apply(Geometry const& geometry,
62+
std::string const& case_id,
63+
G1 const& g1, G2 const& g2,
64+
std::string& message)
65+
{
66+
typedef typename boost::range_value<Geometry>::type single_type;
67+
BOOST_FOREACH(single_type const& element, geometry)
68+
{
69+
if (! is_output_valid(element, case_id, g1, g2, message))
70+
{
71+
return false;
72+
}
73+
}
74+
return true;
75+
}
76+
};
77+
78+
79+
#endif // BOOST_GEOMETRY_TEST_CHECK_VALIDITY_HPP

test/algorithms/is_valid.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <boost/test/included/unit_test.hpp>
2020

2121
#include "test_is_valid.hpp"
22+
#include "overlay/overlay_cases.hpp"
2223

2324
#include <boost/geometry/core/coordinate_type.hpp>
2425

@@ -784,6 +785,7 @@ inline void test_open_polygons()
784785
false);
785786
}
786787

788+
787789
template <typename Point>
788790
inline void test_doc_example_polygon()
789791
{
@@ -794,13 +796,16 @@ inline void test_doc_example_polygon()
794796
std::cout << "************************************" << std::endl;
795797
#endif
796798

797-
typedef bg::model::polygon<Point> CCW_CG;
799+
typedef bg::model::polygon<Point> ClockwiseClosedPolygon;
798800
typedef validity_tester_areal<true> tester;
799-
typedef test_valid<tester, CCW_CG> test;
801+
typedef test_valid<tester, ClockwiseClosedPolygon> test;
800802

801803
test::apply("pg-doc",
802804
"POLYGON((0 0,0 10,10 10,10 0,0 0),(0 0,9 1,9 2,0 0),(0 0,2 9,1 9,0 0),(2 9,9 2,9 9,2 9))",
803805
false);
806+
807+
// Containing a self touching point, which should be valid
808+
test::apply("ggl_list_20190307_matthieu_2", ggl_list_20190307_matthieu_2[1], true);
804809
}
805810

806811
BOOST_AUTO_TEST_CASE( test_is_valid_polygon )

test/algorithms/overlay/overlay.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#endif
2626

2727
#include <geometry_test_common.hpp>
28-
28+
#include <algorithms/check_validity.hpp>
2929

3030
#include <boost/geometry.hpp>
3131
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
@@ -433,6 +433,12 @@ void test_overlay(std::string const& caseid,
433433
overlay::apply(g1, g2, robust_policy, std::back_inserter(result),
434434
strategy, visitor);
435435

436+
std::string message;
437+
bool const valid = check_validity<Geometry>::apply(result, caseid, g1, g2, message);
438+
BOOST_CHECK_MESSAGE(valid,
439+
"overlay: " << caseid << " not valid: " << message
440+
<< " type: " << (type_for_assert_message<Geometry, Geometry>()));
441+
436442
BOOST_CHECK_CLOSE(bg::area(result), expected_area, 0.001);
437443
BOOST_CHECK_MESSAGE((bg::num_interior_rings(result) == expected_hole_count),
438444
caseid

test/algorithms/overlay/overlay_cases.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,30 @@ static std::string case_precision_22[2] =
838838
"POLYGON((-1 -1,-1 8,8 8,8 -1,-1 -1),(2 7,2 3,4.00000000200000017 2.99999999000000006,4 7,2 7))"
839839
};
840840

841+
static std::string case_precision_23[2] =
842+
{
843+
"POLYGON((0 0,0 4,2 4,2 3,4 3,4 0,0 0))",
844+
"POLYGON((-1 -1,-1 8,8 8,8 -1,-1 -1),(2 7,2 3,3.99998999999999993 2.99998999999999993,4 7,2 7))"
845+
};
846+
847+
static std::string case_precision_24[2] =
848+
{
849+
"POLYGON((0 0,0 4,2 4,2 3,4 3,4 0,0 0))",
850+
"POLYGON((2 7,4 7,4 3.000001,2 3,2 7))"
851+
};
852+
853+
static std::string case_precision_25[2] =
854+
{
855+
"POLYGON((0 0,0 4,2 4,2 3,4 3,4 0,0 0))",
856+
"POLYGON((2 7,4 7,4 3.00001,2 3,2 7))"
857+
};
858+
859+
static std::string case_precision_26[2] =
860+
{
861+
"POLYGON((0 0,0 4,2 4,2 3,4 3,4 0,0 0))",
862+
"POLYGON((-1 -1,-1 8,8 8,8 -1,-1 -1),(2 7,2 3,3.999991 2.999991,4 7,2 7))"
863+
};
864+
841865

842866
// ticket_17 is keyholed, so has a hole formed by an deliberate intersection
843867
// This will fail the intersection/traversal process

test/algorithms/set_operations/check_validity.hpp

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)