// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2016, 2017, 2019.
-// Modifications copyright (c) 2016-2019, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016-2020.
+// Modifications copyright (c) 2016-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
#include "../setop_output_type.hpp"
#include <boost/core/ignore_unused.hpp>
-#include <boost/foreach.hpp>
#include <boost/range/algorithm/copy.hpp>
+#include <boost/range/size.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/difference.hpp>
# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
#endif
+enum difference_type
+{
+ difference_a, difference_b, difference_sym
+};
struct ut_settings : ut_base_settings
{
double percentage;
bool sym_difference;
- bool remove_spikes;
-
- explicit ut_settings(double p = 0.0001, bool tv = true, bool sd = true)
- : ut_base_settings(tv)
+ bool validity_of_sym = true;
+ bool remove_spikes = false;
+
+ // The validity check gives sometimes false negatives.
+ // boost::geometry::is_valid can return FALSE while it is valid.
+ // (especially at touch in combination with a u/u turn)
+ // For now, the cases where this is the case are skipped for validity check.
+ bool validity_false_negative_a = false;
+ bool validity_false_negative_b = false;
+ bool validity_false_negative_sym = false;
+
+ explicit ut_settings(double p = 0.0001, bool validity = true, bool sd = true)
+ : ut_base_settings(validity)
, percentage(p)
, sym_difference(sd)
- , remove_spikes(false)
{}
+ bool test_validity_of_diff(difference_type dtype) const
+ {
+ bool const sym = dtype == difference_sym;
+ bool const a = dtype == difference_a;
+ bool const b = dtype == difference_b;
+
+ return sym && validity_false_negative_sym ? false
+ : a && validity_false_negative_a ? false
+ : b && validity_false_negative_b ? false
+ : sym ? (validity_of_sym || BG_IF_TEST_FAILURES)
+ : test_validity();
+ }
+
};
inline ut_settings tolerance(double percentage)
const count_set& expected_count,
int expected_rings_count, int expected_point_count,
expectation_limits const& expected_area,
- bool sym,
+ difference_type dtype,
ut_settings const& settings)
{
typedef typename bg::coordinate_type<G1>::type coordinate_type;
bg::model::multi_polygon<OutputType> result;
-
- if (sym)
+ if (dtype == difference_sym)
{
bg::sym_difference(g1, g2, result);
}
<
G1, G2
>::type strategy_type;
- if (sym)
+ if (dtype == difference_sym)
{
bg::sym_difference(g1, g2, result_s, strategy_type());
}
typename bg::default_area_result<G1>::type const area = bg::area(result);
#if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST)
- if (settings.test_validity())
+ if (settings.test_validity_of_diff(dtype))
{
// std::cout << bg::dsv(result) << std::endl;
typedef bg::model::multi_polygon<OutputType> result_type;
typename setop_output_type<OutputType>::type
inserted, array_with_one_empty_geometry;
array_with_one_empty_geometry.push_back(OutputType());
- if (sym)
+ if (dtype == difference_sym)
{
boost::copy(array_with_one_empty_geometry,
bg::detail::sym_difference::sym_difference_insert<OutputType>
std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g2,
const count_set& expected_count, int expected_point_count,
expectation_limits const& expected_area,
- bool sym,
+ difference_type dtype,
ut_settings const& settings)
{
return test_difference<OutputType>(caseid, g1, g2,
expected_count, -1, expected_point_count, expected_area,
- sym, settings);
+ dtype, settings);
}
#ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS
bg::correct(g1);
bg::correct(g2);
- std::string result = test_difference<OutputType>(caseid + "_a", g1, g2,
- expected_count1, expected_rings_count1, expected_point_count1,
- expected_area1, false, settings);
+ std::string result;
-#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+#if ! defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B)
+ result = test_difference<OutputType>(caseid + "_a", g1, g2,
+ expected_count1, expected_rings_count1, expected_point_count1,
+ expected_area1, difference_a, settings);
+#endif
+#if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_A)
return result;
#endif
test_difference<OutputType>(caseid + "_b", g2, g1,
expected_count2, expected_rings_count2, expected_point_count2,
- expected_area2, false, settings);
+ expected_area2, difference_b, settings);
+
+#if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B)
+ return result;
+#endif
#if ! defined(BOOST_GEOMETRY_TEST_ALWAYS_CHECK_SYMDIFFERENCE)
if (settings.sym_difference)
expected_rings_count_s,
expected_point_count_s,
expected_area_s,
- true, settings);
+ difference_sym, settings);
}
return result;
}
settings);
}
+// Version with expectations of symmetric: all specified
template <typename OutputType, typename G1, typename G2>
std::string test_one(std::string const& caseid,
std::string const& wkt1, std::string const& wkt2,
settings);
}
+// Version with expectations of symmetric: specify only count
+template <typename OutputType, typename G1, typename G2>
+std::string test_one(std::string const& caseid,
+ std::string const& wkt1, std::string const& wkt2,
+ const count_set& expected_count1,
+ int expected_point_count1,
+ expectation_limits const& expected_area1,
+ const count_set& expected_count2,
+ int expected_point_count2,
+ expectation_limits const& expected_area2,
+ const count_set& expected_count_s,
+ ut_settings const& settings = ut_settings())
+{
+ return test_one<OutputType, G1, G2>(caseid, wkt1, wkt2,
+ expected_count1, -1, expected_point_count1, expected_area1,
+ expected_count2, -1, expected_point_count2, expected_area2,
+ expected_count_s, -1,
+ expected_point_count1 >= 0 && expected_point_count2 >= 0
+ ? (expected_point_count1 + expected_point_count2) : -1,
+ expected_area1 + expected_area2,
+ settings);
+}
+
+// Version with expectations of symmetric: all automatically
template <typename OutputType, typename G1, typename G2>
std::string test_one(std::string const& caseid,
std::string const& wkt1, std::string const& wkt2,