Merge pull request #780 from barendgehrels/fix/sort-by-side-point-at-turn

Fix/sort by side point at turn
This commit is contained in:
Barend Gehrels
2020-12-30 11:37:24 +01:00
committed by GitHub
17 changed files with 283 additions and 83 deletions

View File

@@ -346,7 +346,8 @@ static std::string const nores_wn_2
// Other cases with wrong turn information
static std::string const nores_wt_1
= "MULTIPOLYGON(((0 4,0 5,1 4,0 4)),((9 3,9 4,10 4,9 3)),((9 7,10 8,10 7,9 7)),((6 7,7 8,7 7,6 7)),((0 7,0 8,1 8,0 7)),((3 6,4 6,4 5,3 4,3 6)),((3 7,2 6,2 7,3 7)),((3 7,3 8,4 8,4 7,3 7)),((3 3,4 4,4 3,3 3)),((3 3,3 2,2 2,2 3,3 3)),((2 6,2 5,1 5,1 6,2 6)),((6 4,6 3,5 3,5 4,6 4)),((6 4,7 5,7 4,6 4)),((5 1,4 0,4 1,5 1)),((5 1,5 2,6 2,6 1,5 1)))";
static std::string const nores_wt_2
= "MULTIPOLYGON(((1 1,2 2,2 1,1 1)),((0 2,0 3,1 3,0 2)),((4 3,5 4,5 3,4 3)),((4 3,3 3,4 4,4 3)))";
static std::string const neighbouring
= "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((10 10,10 20,20 20,20 10,10 10)))";
@@ -558,23 +559,18 @@ void test_all()
test_one<multi_polygon_type, polygon_type>("nores_mt_6", nores_mt_6, join_round32, end_flat, 16.9018, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_1", nores_et_1, join_round32, end_flat, 18.9866, 1.0);
#if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
test_one<multi_polygon_type, polygon_type>("nores_et_2", nores_et_2, join_round32, end_flat, 23.8389, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_3", nores_et_3, join_round32, end_flat, 26.9030, 1.0);
#endif
test_one<multi_polygon_type, polygon_type>("nores_et_4", nores_et_4, join_round32, end_flat, 19.9626, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_5", nores_et_5, join_round32, end_flat, 19.9615, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_6", nores_et_6, join_round32, end_flat, 96.1795, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_7", nores_et_7, join_round32, end_flat, 105.9577, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_wn_1", nores_wn_1, join_round32, end_flat, 23.7659, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_wn_2", nores_wn_2, join_round32, end_flat, 18.2669, 1.0);
#if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
test_one<multi_polygon_type, polygon_type>("nores_et_6", nores_et_6, join_round32, end_flat, 96.1795, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_et_7", nores_et_7, join_round32, end_flat, 105.9577, 1.0);
test_one<multi_polygon_type, polygon_type>("nores_wt_1", nores_wt_1, join_round32, end_flat, 80.1609, 1.0);
#endif
test_one<multi_polygon_type, polygon_type>("nores_wt_2", nores_wt_2, join_round32, end_flat, 22.1102, 1.0);
test_one<multi_polygon_type, polygon_type>("neighbouring_small",
neighbouring,
@@ -619,7 +615,7 @@ int test_main(int, char* [])
#endif
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
BoostGeometryWriteExpectedFailures(1, 8, 2, 7);
BoostGeometryWriteExpectedFailures(1, 1, 2, 3);
#endif
return 0;

View File

@@ -207,7 +207,7 @@ private :
}
#endif
bg::model::ring<point_type> const& corner = piece.m_piece_border.get_full_ring();
auto const& corner = piece.m_piece_border.get_full_ring();
if (m_zoom && do_pieces)
{

View File

@@ -16,6 +16,7 @@
test-suite boost-geometry-algorithms-overlay
:
[ run assemble.cpp : : : : algorithms_assemble ]
[ run copy_segment_point.cpp : : : : algorithms_copy_segment_point ]
[ run get_turn_info.cpp : : : : algorithms_get_turn_info ]
[ run get_turns.cpp : : : : algorithms_get_turns ]
[ run get_turns_areal_areal.cpp : : : : algorithms_get_turns_areal_areal ]

View File

@@ -0,0 +1,132 @@
// Boost.Geometry
// Unit Test
// Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <geometry_test_common.hpp>
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
template <typename Geometry, typename GetRing>
void test_basic(GetRing get_ring, std::string const& case_id, int line,
std::string const& wkt, bg::segment_identifier const& id,
int offset, std::size_t expected_index)
{
using point_type = typename bg::point_type<Geometry>::type;
Geometry geometry;
bg::read_wkt(wkt, geometry);
// Check the result
auto ring = get_ring(geometry);
point_type point;
bg::copy_segment_point<false>(geometry, id, offset, point);
// Sanity check
bool const expectation_in_range = expected_index < ring.size();
BOOST_CHECK_MESSAGE(expectation_in_range, "Expectation out of range " << expected_index);
if (! expectation_in_range)
{
return;
}
point_type const expected_point = ring[expected_index];
bool const equal = ! bg::disjoint(point, expected_point);
BOOST_CHECK_MESSAGE(equal, "copy_segment_point: " << case_id
<< " line " << line << " at index " << expected_index
<< " not as expected: "
<< bg::wkt(point) << " vs " << bg::wkt(expected_point));
}
template <typename Geometry, typename GetRing>
void test_geometry(std::string const& case_id, std::string const& wkt, GetRing get_ring)
{
// Check zero offset, all segment ids
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, {0, 0, -1, 0}, 0, 0);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, {0, 0, -1, 1}, 0, 1);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, {0, 0, -1, 2}, 0, 2);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, {0, 0, -1, 3}, 0, 3);
// Check positive offsets, it should endlessly loop around, regardless of direction or closure
bg::segment_identifier const start{0, 0, -1, 0};
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 1, 1);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 2, 2);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 3, 3);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 4, 0);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 5, 1);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 6, 2);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, 7, 3);
// Check negative offsets
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -1, 3);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -2, 2);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -3, 1);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -4, 0);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -5, 3);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -6, 2);
test_basic<Geometry>(get_ring, case_id, __LINE__, wkt, start, -7, 1);
}
template <typename T, bool Closed>
void test_all(std::string const& case_id, std::string const& wkt)
{
using point_type = bg::model::point<T, 2, bg::cs::cartesian>;
using polygon_type = bg::model::polygon<point_type, true, Closed>;
test_geometry<polygon_type>(case_id, wkt, [](polygon_type const& polygon)
{
return bg::exterior_ring(polygon);
});
}
template <typename T>
void test_box(std::string const& case_id, std::string const& wkt)
{
using point_type = bg::model::point<T, 2, bg::cs::cartesian>;
using box_type = bg::model::box<point_type>;
test_geometry<box_type>(case_id, wkt, [](box_type const& box)
{
boost::array<point_type, 4> ring;
bg::detail::assign_box_corners_oriented<false>(box, ring);
return ring;
});
}
void test_circular_offset()
{
BOOST_CHECK_EQUAL(3, bg::detail::copy_segments::circular_offset(4, 0, -1));
BOOST_CHECK_EQUAL(2, bg::detail::copy_segments::circular_offset(4, 0, -2));
BOOST_CHECK_EQUAL(1, bg::detail::copy_segments::circular_offset(4, 0, -3));
BOOST_CHECK_EQUAL(6, bg::detail::copy_segments::circular_offset(10, 5, 1));
BOOST_CHECK_EQUAL(6, bg::detail::copy_segments::circular_offset(10, 5, 11));
BOOST_CHECK_EQUAL(6, bg::detail::copy_segments::circular_offset(10, 5, 21));
BOOST_CHECK_EQUAL(4, bg::detail::copy_segments::circular_offset(10, 5, -1));
BOOST_CHECK_EQUAL(4, bg::detail::copy_segments::circular_offset(10, 5, -11));
BOOST_CHECK_EQUAL(4, bg::detail::copy_segments::circular_offset(10, 5, -21));
}
int test_main(int, char* [])
{
test_circular_offset();
test_all<double, true>("closed", "POLYGON((0 2,1 2,1 1,0 1,0 2))");
test_all<double, false>("open", "POLYGON((0 2,1 2,1 1,0 1))");
test_box<double>("box", "BOX(0 0,5 5)");
return 0;
}

View File

@@ -101,7 +101,7 @@ std::vector<std::size_t> gather_cluster_properties(
for (int i = 0; i < 2; i++)
{
turn_operation_type const& op = turn.operations[i];
sbs.add(op, turn_index, i, geometry1, geometry2, first);
sbs.add(turn, op, turn_index, i, geometry1, geometry2, first);
first = false;
}
}

View File

@@ -120,7 +120,7 @@ std::vector<std::size_t> apply_get_turns(std::string const& case_id,
has_origin = true;
}
sbs.add(turn.operations[i], turn_index, i,
sbs.add(turn, turn.operations[i], turn_index, i,
geometry1, geometry2, is_origin);
}

View File

@@ -624,7 +624,7 @@ int test_main(int, char* [])
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
// Not yet fully tested for float and long double.
// The difference algorithm can generate (additional) slivers
BoostGeometryWriteExpectedFailures(10, 11, 24, 15);
BoostGeometryWriteExpectedFailures(10, 11, 24, 16);
#endif
return 0;

View File

@@ -524,7 +524,7 @@ int test_main(int, char* [])
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
// Not yet fully tested for float.
// The difference algorithm can generate (additional) slivers
BoostGeometryWriteExpectedFailures(22, 13, 19, 7);
BoostGeometryWriteExpectedFailures(22, 9, 20, 7);
#endif
return 0;

View File

@@ -499,7 +499,7 @@ int test_main(int, char* [])
#endif
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
BoostGeometryWriteExpectedFailures(9, 3, 2, 1);
BoostGeometryWriteExpectedFailures(9, 1, 2, 1);
#endif
return 0;

View File

@@ -489,7 +489,7 @@ int test_main(int, char* [])
#endif
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
BoostGeometryWriteExpectedFailures(9, 2, 1, 0);
BoostGeometryWriteExpectedFailures(9, 0, 3, 0);
#endif
return 0;

View File

@@ -29,10 +29,6 @@ struct count_set
{
m_values.insert(static_cast<std::size_t>(value));
}
else
{
std::cout << "EMPTY" << std::endl;
}
}
count_set(std::size_t value1, std::size_t value2)