Merge branch 'develop' into feature/rtree_nearest2

This commit is contained in:
Adam Wulkiewicz 2021-09-22 20:09:55 +02:00
commit e6dd5b7dd6
74 changed files with 1296 additions and 788 deletions

View File

@ -60,7 +60,7 @@ jobs:
git submodule update --init tools/build
git submodule update --init libs/config
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py geometry
python tools/boostdep/depinst/depinst.py geometry -I index/test
./bootstrap.sh
./b2 headers
- run: mkdir $COVERAGE_DIR

23
LICENSE_1_0.txt Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -3,6 +3,10 @@
// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -57,7 +61,7 @@ void test_connect(std::string const& caseid, Geometry const& geometry,
std::size_t count = boost::size(connected_vector);
std::size_t point_count = 0;
BOOST_FOREACH(GeometryOut& connected, connected_vector)
for (GeometryOut& connected : connected_vector)
{
bg::unique(connected);
length += bg::length(connected);
@ -99,7 +103,7 @@ void test_connect(std::string const& caseid, Geometry const& geometry,
mapper.map(geometry, "opacity:0.6;fill:rgb(0,0,255);stroke:rgb(0,0,0);stroke-width:1");
BOOST_FOREACH(GeometryOut& connected, connected_vector)
for (GeometryOut& connected : connected_vector)
{
mapper.map(connected, "opacity:0.6;fill:none;stroke:rgb(255,0,0);stroke-width:5");
}

View File

@ -6,6 +6,10 @@
// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2019 program.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -13,7 +17,7 @@
#include <geometry_test_common.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/extensions/triangulation/strategies/cartesian/in_circle_robust.hpp>
#include <boost/geometry/strategy/cartesian/in_circle_robust.hpp>
template <typename P>
void test_all()

View File

@ -24,7 +24,6 @@
#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/strategies/cartesian/turn_in_ring_winding.hpp>

View File

@ -39,7 +39,8 @@
#include <boost/geometry/views/detail/closed_clockwise_view.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/normalize.hpp>
@ -61,11 +62,11 @@ struct collected_vector
: nyi::not_implemented_tag
{};
// compatible with side_by_triangle cartesian strategy
// compatible with side_robust cartesian strategy
template <typename T, typename Geometry, typename CT, typename CSTag>
struct collected_vector
<
T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
T, Geometry, strategy::side::side_robust<CT>, CSTag
>
{
typedef T type;
@ -156,6 +157,14 @@ private:
//T dx_0, dy_0;
};
template <typename T, typename Geometry, typename CT, typename CSTag>
struct collected_vector
<
T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
>
: collected_vector<T, Geometry, strategy::side::side_robust<CT>, CSTag>
{};
// Compatible with spherical_side_formula which currently
// is the default spherical_equatorial and geographic strategy
// so CSTag is spherical_equatorial_tag or geographic_tag

View File

@ -0,0 +1,111 @@
// Boost.Geometry
// Copyright (c) 2021 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)
#ifndef BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP
#define BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP
#include <boost/geometry/core/coordinate_type.hpp>
// TODO: move this to a future headerfile implementing traits for these types
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
namespace boost { namespace geometry
{
namespace traits
{
// todo
} // namespace traits
/*!
\brief Meta-function converting, if necessary, to "a floating point" type
\details
- if input type is integer, type is double
- else type is input type
\ingroup utility
*/
// TODO: replace with, or call, promoted_to_floating_point
template <typename T, typename PromoteIntegerTo = double>
struct promote_floating_point
{
typedef std::conditional_t
<
std::is_integral<T>::value,
PromoteIntegerTo,
T
> type;
};
// TODO: replace with promoted_to_floating_point
template <typename Geometry>
struct fp_coordinate_type
{
typedef typename promote_floating_point
<
typename coordinate_type<Geometry>::type
>::type type;
};
namespace detail
{
// Promote any integral type to double. Floating point
// and other user defined types stay as they are, unless specialized.
// TODO: we shold add a coordinate_promotion traits for promotion to
// floating point or (larger) integer types.
template <typename Type>
struct promoted_to_floating_point
{
using type = std::conditional_t
<
std::is_integral<Type>::value, double, Type
>;
};
// Boost.Rational goes to double
template <typename T>
struct promoted_to_floating_point<boost::rational<T>>
{
using type = double;
};
// Any Boost.Multiprecision goes to double (for example int128_t),
// unless specialized
template <typename Backend>
struct promoted_to_floating_point<boost::multiprecision::number<Backend>>
{
using type = double;
};
// Boost.Multiprecision binary floating point numbers are used as FP.
template <unsigned Digits>
struct promoted_to_floating_point
<
boost::multiprecision::number
<
boost::multiprecision::cpp_bin_float<Digits>
>
>
{
using type = boost::multiprecision::number
<
boost::multiprecision::cpp_bin_float<Digits>
>;
};
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP

View File

@ -22,7 +22,6 @@
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/type_traits_std.hpp>
@ -94,15 +93,6 @@ struct coordinate_type
>::type type;
};
template <typename Geometry>
struct fp_coordinate_type
{
typedef typename promote_floating_point
<
typename coordinate_type<Geometry>::type
>::type type;
};
/*!
\brief assert_coordinate_type_equal, a compile-time check for equality of two coordinate types
\ingroup utility

View File

@ -27,8 +27,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/util/math.hpp>

View File

@ -5,8 +5,8 @@
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// This file was modified by Oracle on 2020-2021.
// Modifications copyright (c) 2020-2021, 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,
@ -30,10 +30,9 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/distance/cartesian.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/extensions/strategies/cartesian/distance_info.hpp>
#include <boost/geometry/util/math.hpp>

View File

@ -2,8 +2,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// This file was modified by Oracle on 2020-2021.
// Modifications copyright (c) 2020-2021, 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,
@ -31,7 +31,7 @@
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/endian.hpp>
#include <boost/predef/other/endian.h>
#if CHAR_BIT != 8
#error Platforms with CHAR_BIT != 8 are not supported
@ -50,10 +50,16 @@ namespace detail { namespace endian
struct big_endian_tag {};
struct little_endian_tag {};
#ifdef BOOST_BIG_ENDIAN
#if defined(BOOST_ENDIAN_BIG_BYTE_AVAILABLE)
typedef big_endian_tag native_endian_tag;
#else
#elif defined(BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE)
typedef little_endian_tag native_endian_tag;
#elif defined(BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE)
#error Word-swapped big-endian not supported
#elif defined(BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE)
#error Word-swapped little-endian not supported
#else
#error Unknown endian memory ordering
#endif
// Unrolled loops for loading and storing streams of bytes.

View File

@ -1,50 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, 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)
#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
#include <boost/geometry/geometries/concepts/check.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Geometry>
struct check<Geometry, nsphere_tag, true>
: detail::concept_check::check<concepts::ConstNsphere<Geometry> >
{};
template <typename Geometry>
struct check<Geometry, nsphere_tag, false>
: detail::concept_check::check<concepts::Nsphere<Geometry> >
{};
} // namespace dispatch
#endif
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP

View File

@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -117,6 +121,18 @@ public :
};
template <typename Geometry>
struct concept_type<Geometry, nsphere_tag>
{
using type = Nsphere<Geometry>;
};
template <typename Geometry>
struct concept_type<Geometry const, nsphere_tag>
{
using type = ConstNsphere<Geometry>;
};
}}} // namespace boost::geometry::concepts

View File

@ -5,6 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -22,7 +26,6 @@
#include <boost/geometry/extensions/nsphere/core/tags.hpp>
#include <boost/geometry/extensions/nsphere/core/topological_dimension.hpp>
#include <boost/geometry/extensions/nsphere/geometries/concepts/check.hpp>
#include <boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp>
#include <boost/geometry/extensions/nsphere/geometries/nsphere.hpp>

View File

@ -24,6 +24,7 @@
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/config.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
@ -37,7 +38,6 @@
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/policies/robustness/rescale_policy.hpp>
#include <boost/geometry/policies/robustness/robust_type.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/type_traits.hpp>
// TEMP

View File

@ -19,8 +19,8 @@
#include <boost/rational.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
namespace boost { namespace geometry
{
@ -135,11 +135,15 @@ struct possibly_collinear<Type, false>
template <typename Type>
class segment_ratio
{
public :
typedef Type numeric_type;
// Type used for the approximation (a helper value)
// and for the edge value (0..1) (a helper function).
using floating_point_type =
typename detail::promoted_to_floating_point<Type>::type;
// Type-alias for the type itself
typedef segment_ratio<Type> thistype;
using thistype = segment_ratio<Type>;
public :
inline segment_ratio()
: m_numerator(0)
@ -221,8 +225,8 @@ public :
m_approximation =
m_denominator == 0 ? 0
: (
boost::numeric_cast<fp_type>(m_numerator) * scale()
/ boost::numeric_cast<fp_type>(m_denominator)
boost::numeric_cast<floating_point_type>(m_numerator) * scale()
/ boost::numeric_cast<floating_point_type>(m_denominator)
);
}
@ -254,21 +258,16 @@ public :
return m_numerator > m_denominator;
}
inline bool near_end() const
//! Returns a value between 0.0 and 1.0
//! 0.0 means: exactly in the middle
//! 1.0 means: exactly on one of the edges (or even over it)
inline floating_point_type edge_value() const
{
if (left() || right())
{
return false;
}
static fp_type const small_part_of_scale = scale() / 100;
return m_approximation < small_part_of_scale
|| m_approximation > scale() - small_part_of_scale;
}
inline bool close_to(thistype const& other) const
{
return geometry::math::abs(m_approximation - other.m_approximation) < 50;
using fp = floating_point_type;
fp const one{1.0};
floating_point_type const result
= fp(2) * geometry::math::abs(fp(0.5) - m_approximation / scale());
return result > one ? one : result;
}
template <typename Threshold>
@ -313,19 +312,7 @@ public :
}
#endif
private :
// NOTE: if this typedef is used then fp_type is non-fundamental type
// if Type is non-fundamental type
//typedef typename promote_floating_point<Type>::type fp_type;
// TODO: What with user-defined numeric types?
// Shouldn't here is_integral be checked?
typedef std::conditional_t
<
std::is_floating_point<Type>::value, Type, double
> fp_type;
Type m_numerator;
Type m_denominator;
@ -335,12 +322,19 @@ private :
// Boost.Rational is used if the approximations are close.
// Reason: performance, Boost.Rational does a GCD by default and also the
// comparisons contain while-loops.
fp_type m_approximation;
floating_point_type m_approximation;
static inline fp_type scale()
inline bool close_to(thistype const& other) const
{
return 1000000.0;
static floating_point_type const threshold{50.0};
return geometry::math::abs(m_approximation - other.m_approximation)
< threshold;
}
static inline floating_point_type scale()
{
static floating_point_type const fp_scale{1000000.0};
return fp_scale;
}
};

View File

@ -20,12 +20,16 @@
#include <boost/array.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
@ -118,7 +122,7 @@ struct cartesian_point_box_by_side
<
within::detail::decide_within
>(point, box,
strategy::side::side_by_triangle<CalculationType>());
strategy::side::side_robust<CalculationType>());
}
};
@ -189,7 +193,7 @@ struct cartesian_point_box_by_side
<
within::detail::decide_covered_by
>(point, box,
strategy::side::side_by_triangle<CalculationType>());
strategy::side::side_robust<CalculationType>());
}
};

View File

@ -14,10 +14,10 @@
#include <cmath>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/strategies/azimuth.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry

View File

@ -17,7 +17,6 @@
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
namespace boost { namespace geometry
{

View File

@ -38,13 +38,13 @@
#include <boost/geometry/strategy/cartesian/envelope.hpp>
#include <boost/geometry/strategy/cartesian/expand_box.hpp>
#include <boost/geometry/strategy/cartesian/expand_segment.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
@ -68,6 +68,61 @@ namespace boost { namespace geometry
namespace strategy { namespace intersection
{
namespace detail_usage
{
// When calculating the intersection, the information of "a" or "b" can be used.
// Theoretically this gives equal results, but due to floating point precision
// there might be tiny differences. These are edge cases.
// This structure is to determine if "a" or "b" should be used.
// Prefer the segment closer to the endpoint.
// If both are about equally close, then prefer the longer segment
// To avoid hard thresholds, behavior is made fluent.
// Calculate comparable length indications,
// the longer the segment (relatively), the lower the value
// such that the shorter lengths are evaluated higher and will
// be preferred.
template <bool IsArithmetic>
struct use_a
{
template <typename Ct, typename Ev>
static bool apply(Ct const& cla, Ct const& clb, Ev const& eva, Ev const& evb)
{
auto const clm = (std::max)(cla, clb);
if (clm <= 0)
{
return true;
}
// Relative comparible length
auto const rcla = Ct(1.0) - cla / clm;
auto const rclb = Ct(1.0) - clb / clm;
// Multipliers for edgevalue (ev) and relative comparible length (rcl)
// They determine the balance between edge value (should be larger)
// and segment length. In 99.9xx% of the cases there is no difference
// at all (if either a or b is used). Therefore the values of the
// constants are not sensitive for the majority of the situations.
// One known case is #mysql_23023665_6 (difference) which needs mev >= 2
Ev const mev = 5;
Ev const mrcl = 1;
return mev * eva + mrcl * rcla > mev * evb + mrcl * rclb;
}
};
// Specialization for non arithmetic types. They will always use "a"
template <>
struct use_a<false>
{
template <typename Ct, typename Ev>
static bool apply(Ct const& , Ct const& , Ev const& , Ev const& )
{
return true;
}
};
}
/*!
\see http://mathworld.wolfram.com/Line-LineIntersection.html
@ -180,30 +235,12 @@ struct cartesian_segments
template <typename Point, typename Segment1, typename Segment2>
void calculate(Point& point, Segment1 const& a, Segment2 const& b) const
{
bool use_a = true;
// Prefer one segment if one is on or near an endpoint
bool const a_near_end = robust_ra.near_end();
bool const b_near_end = robust_rb.near_end();
if (a_near_end && ! b_near_end)
{
use_a = true;
}
else if (b_near_end && ! a_near_end)
{
use_a = false;
}
else
{
// Prefer shorter segment
promoted_type const len_a = comparable_length_a();
promoted_type const len_b = comparable_length_b();
if (len_b < len_a)
{
use_a = false;
}
// else use_a is true but was already assigned like that
}
bool const use_a
= detail_usage::use_a
<
std::is_arithmetic<CoordinateType>::value
>::apply(comparable_length_a(), comparable_length_b(),
robust_ra.edge_value(), robust_rb.edge_value());
if (use_a)
{
@ -402,7 +439,7 @@ struct cartesian_segments
return Policy::disjoint();
}
typedef side::side_by_triangle<CalculationType> side_strategy_type;
typedef side::side_robust<CalculationType> side_strategy_type;
side_info sides;
sides.set<0>(side_strategy_type::apply(q1, q2, p1),
side_strategy_type::apply(q1, q2, p2));

View File

@ -24,10 +24,10 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategy/cartesian/expand_point.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
@ -116,7 +116,7 @@ public:
else // count == 2 || count == -2
{
// 1 left, -1 right
typedef side::side_by_triangle<CalculationType> side_strategy_type;
typedef side::side_robust<CalculationType> side_strategy_type;
side = side_strategy_type::apply(s1, s2, point);
}

View File

@ -1,275 +1,21 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, 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)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#include <type_traits>
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategy/cartesian/envelope.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
namespace boost { namespace geometry
{
namespace strategy { namespace side
{
/*!
\brief Check at which side of a segment a point lies:
left of segment (> 0), right of segment (< 0), on segment (0)
\ingroup strategies
\tparam CalculationType \tparam_calculation
*/
template <typename CalculationType = void>
class side_by_triangle
{
template <typename Policy>
struct eps_policy
{
eps_policy() {}
template <typename Type>
eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
: policy(a, b, c, d)
{}
Policy policy;
};
struct eps_empty
{
eps_empty() {}
template <typename Type>
eps_empty(Type const&, Type const&, Type const&, Type const&) {}
};
public :
typedef cartesian_tag cs_tag;
// Template member function, because it is not always trivial
// or convenient to explicitly mention the typenames in the
// strategy-struct itself.
// Types can be all three different. Therefore it is
// not implemented (anymore) as "segment"
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P,
typename EpsPolicy
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
{
CoordinateType const x = get<0>(p);
CoordinateType const y = get<1>(p);
CoordinateType const sx1 = get<0>(p1);
CoordinateType const sy1 = get<1>(p1);
CoordinateType const sx2 = get<0>(p2);
CoordinateType const sy2 = get<1>(p2);
PromotedType const dx = sx2 - sx1;
PromotedType const dy = sy2 - sy1;
PromotedType const dpx = x - sx1;
PromotedType const dpy = y - sy1;
eps_policy = EpsPolicy(dx, dy, dpx, dpy);
return geometry::detail::determinant<PromotedType>
(
dx, dy,
dpx, dpy
);
}
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
{
eps_empty dummy;
return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
}
template
<
typename CoordinateType,
typename PromotedType,
bool AreAllIntegralCoordinates
>
struct compute_side_value
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
};
template <typename CoordinateType, typename PromotedType>
struct compute_side_value<CoordinateType, PromotedType, false>
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
// collinear
if (equals_point_point(p1, p2)
|| equals_point_point(p1, p)
|| equals_point_point(p2, p))
{
return PromotedType(0);
}
// The side_by_triangle strategy computes the signed area of
// the point triplet (p1, p2, p); as such it is (in theory)
// invariant under cyclic permutations of its three arguments.
//
// In the context of numerical errors that arise in
// floating-point computations, and in order to make the strategy
// consistent with respect to cyclic permutations of its three
// arguments, we cyclically permute them so that the first
// argument is always the lexicographically smallest point.
typedef compare::cartesian<compare::less> less;
if (less::apply(p, p1))
{
if (less::apply(p, p2))
{
// p is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
if (less::apply(p1, p2))
{
// p1 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
};
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
typedef typename coordinate_type<P1>::type coordinate_type1;
typedef typename coordinate_type<P2>::type coordinate_type2;
typedef typename coordinate_type<P>::type coordinate_type3;
typedef std::conditional_t
<
std::is_void<CalculationType>::value,
typename select_most_precise
<
coordinate_type1,
coordinate_type2,
coordinate_type3
>::type,
CalculationType
> coordinate_type;
// Promote float->double, small int->int
typedef typename select_most_precise
<
coordinate_type,
double
>::type promoted_type;
bool const are_all_integral_coordinates =
std::is_integral<coordinate_type1>::value
&& std::is_integral<coordinate_type2>::value
&& std::is_integral<coordinate_type3>::value;
eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
promoted_type s = compute_side_value
<
coordinate_type, promoted_type, are_all_integral_coordinates
>::apply(p1, p2, p, epsp);
promoted_type const zero = promoted_type();
return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
: s > zero ? 1
: -1;
}
private:
template <typename P1, typename P2>
static inline bool equals_point_point(P1 const& p1, P2 const& p2)
{
return strategy::within::cartesian_point_point::apply(p1, p2);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<cartesian_tag, CalculationType>
{
typedef side_by_triangle<CalculationType> type;
};
}
#endif
}} // namespace strategy::side
}} // namespace boost::geometry
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP

View File

@ -10,10 +10,10 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
namespace boost { namespace geometry
{

View File

@ -17,6 +17,7 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@ -32,7 +33,6 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

View File

@ -21,6 +21,7 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
@ -37,7 +38,6 @@
#include <boost/geometry/formulas/vincenty_direct.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>

View File

@ -13,6 +13,8 @@
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/strategies/distance.hpp>
@ -26,7 +28,6 @@
#include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry

View File

@ -17,10 +17,10 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/side.hpp>

View File

@ -16,6 +16,7 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@ -32,7 +33,6 @@
#include <boost/geometry/strategy/geographic/envelope.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry

View File

@ -19,12 +19,12 @@
#include <boost/geometry/policies/relate/intersection_policy.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/cartesian/intersection.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/spherical/intersection.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>

View File

@ -10,12 +10,14 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/convex_hull/cartesian.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/is_convex/services.hpp>
#include <boost/geometry/util/type_traits.hpp>

View File

@ -26,6 +26,8 @@
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategy/cartesian/area.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/area_box.hpp>
#include <boost/geometry/util/type_traits.hpp>
@ -156,7 +158,7 @@ public:
static auto side()
{
return strategy::side::side_by_triangle<CalculationType>();
return strategy::side::side_robust<CalculationType>();
}
// within
@ -381,6 +383,15 @@ struct strategy_converter<strategy::side::side_by_triangle<CalculationType>>
}
};
template <typename CalculationType>
struct strategy_converter<strategy::side::side_robust<CalculationType>>
{
static auto get(strategy::side::side_robust<CalculationType> const&)
{
return strategies::relate::cartesian<CalculationType>();
}
};
} // namespace services

View File

@ -24,6 +24,7 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
@ -36,7 +37,6 @@
#include <boost/geometry/strategies/spherical/intersection.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK

View File

@ -17,6 +17,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/radian_access.hpp>
@ -26,7 +27,6 @@
#include <boost/geometry/strategies/spherical/get_radius.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>

View File

@ -28,6 +28,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>

View File

@ -16,6 +16,7 @@
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/radian_access.hpp>
@ -26,7 +27,6 @@
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry

View File

@ -16,10 +16,10 @@
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategy/spherical/envelope.hpp>

View File

@ -67,7 +67,6 @@
#include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/line_interpolate.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/spherical/azimuth.hpp>
#include <boost/geometry/strategies/spherical/densify.hpp>
@ -135,6 +134,8 @@
#include <boost/geometry/strategy/cartesian/expand_box.hpp>
#include <boost/geometry/strategy/cartesian/expand_point.hpp>
#include <boost/geometry/strategy/cartesian/expand_segment.hpp>
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategy/geographic/area.hpp>
#include <boost/geometry/strategy/geographic/envelope.hpp>

View File

@ -30,10 +30,10 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
namespace boost { namespace geometry

View File

@ -33,9 +33,9 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>

View File

@ -0,0 +1,262 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, 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)
#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP
#include <type_traits>
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategy/cartesian/envelope.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace side
{
/*!
\brief Check at which side of a segment a point lies:
left of segment (> 0), right of segment (< 0), on segment (0)
\ingroup strategies
\tparam CalculationType \tparam_calculation
*/
template <typename CalculationType = void>
class side_by_triangle
{
template <typename Policy>
struct eps_policy
{
eps_policy() {}
template <typename Type>
eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
: policy(a, b, c, d)
{}
Policy policy;
};
struct eps_empty
{
eps_empty() {}
template <typename Type>
eps_empty(Type const&, Type const&, Type const&, Type const&) {}
};
public :
typedef cartesian_tag cs_tag;
// Template member function, because it is not always trivial
// or convenient to explicitly mention the typenames in the
// strategy-struct itself.
// Types can be all three different. Therefore it is
// not implemented (anymore) as "segment"
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P,
typename EpsPolicy
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
{
CoordinateType const x = get<0>(p);
CoordinateType const y = get<1>(p);
CoordinateType const sx1 = get<0>(p1);
CoordinateType const sy1 = get<1>(p1);
CoordinateType const sx2 = get<0>(p2);
CoordinateType const sy2 = get<1>(p2);
PromotedType const dx = sx2 - sx1;
PromotedType const dy = sy2 - sy1;
PromotedType const dpx = x - sx1;
PromotedType const dpy = y - sy1;
eps_policy = EpsPolicy(dx, dy, dpx, dpy);
return geometry::detail::determinant<PromotedType>
(
dx, dy,
dpx, dpy
);
}
template
<
typename CoordinateType,
typename PromotedType,
typename P1,
typename P2,
typename P
>
static inline
PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
{
eps_empty dummy;
return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
}
template
<
typename CoordinateType,
typename PromotedType,
bool AreAllIntegralCoordinates
>
struct compute_side_value
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
};
template <typename CoordinateType, typename PromotedType>
struct compute_side_value<CoordinateType, PromotedType, false>
{
template <typename P1, typename P2, typename P, typename EpsPolicy>
static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
{
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
// collinear
if (equals_point_point(p1, p2)
|| equals_point_point(p1, p)
|| equals_point_point(p2, p))
{
return PromotedType(0);
}
// The side_by_triangle strategy computes the signed area of
// the point triplet (p1, p2, p); as such it is (in theory)
// invariant under cyclic permutations of its three arguments.
//
// In the context of numerical errors that arise in
// floating-point computations, and in order to make the strategy
// consistent with respect to cyclic permutations of its three
// arguments, we cyclically permute them so that the first
// argument is always the lexicographically smallest point.
typedef compare::cartesian<compare::less> less;
if (less::apply(p, p1))
{
if (less::apply(p, p2))
{
// p is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
if (less::apply(p1, p2))
{
// p1 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
}
else
{
// p2 is the lexicographically smallest
return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
}
}
};
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
typedef typename coordinate_type<P1>::type coordinate_type1;
typedef typename coordinate_type<P2>::type coordinate_type2;
typedef typename coordinate_type<P>::type coordinate_type3;
typedef std::conditional_t
<
std::is_void<CalculationType>::value,
typename select_most_precise
<
coordinate_type1,
coordinate_type2,
coordinate_type3
>::type,
CalculationType
> coordinate_type;
// Promote float->double, small int->int
typedef typename select_most_precise
<
coordinate_type,
double
>::type promoted_type;
bool const are_all_integral_coordinates =
std::is_integral<coordinate_type1>::value
&& std::is_integral<coordinate_type2>::value
&& std::is_integral<coordinate_type3>::value;
eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
promoted_type s = compute_side_value
<
coordinate_type, promoted_type, are_all_integral_coordinates
>::apply(p1, p2, p, epsp);
promoted_type const zero = promoted_type();
return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
: s > zero ? 1
: -1;
}
private:
template <typename P1, typename P2>
static inline bool equals_point_point(P1 const& p1, P2 const& p2)
{
return strategy::within::cartesian_point_point::apply(p1, p2);
}
};
}} // namespace strategy::side
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP

View File

@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
@ -14,6 +14,8 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/precise_math.hpp>
#include <boost/geometry/arithmetic/determinant.hpp>
namespace boost { namespace geometry
{
@ -21,7 +23,7 @@ namespace strategy { namespace side
{
/*!
\brief Adaptive precision predicate to check at which side of a segment a point lies:
\brief Predicate to check at which side of a segment a point lies:
left of segment (>0), right of segment (< 0), on segment (0).
\ingroup strategies
\tparam CalculationType \tparam_calculation
@ -35,8 +37,6 @@ struct side_non_robust
{
public:
//! \brief Computes double the signed area of the CCW triangle p1, p2, p
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
<
typename P1,
@ -51,21 +51,44 @@ public:
P1,
P2,
P
>::type coordinate_type;
>::type CoordinateType;
typedef typename select_most_precise
<
coordinate_type,
CoordinateType,
double
>::type promoted_type;
>::type PromotedType;
auto detleft = (promoted_type(get<0>(p1)) - promoted_type(get<0>(p)))
* (promoted_type(get<1>(p2)) - promoted_type(get<1>(p)));
auto detright = (promoted_type(get<1>(p1)) - promoted_type(get<1>(p)))
* (promoted_type(get<0>(p2)) - promoted_type(get<0>(p)));
return detleft > detright ? 1 : (detleft < detright ? -1 : 0 );
CoordinateType const x = get<0>(p);
CoordinateType const y = get<1>(p);
CoordinateType const sx1 = get<0>(p1);
CoordinateType const sy1 = get<1>(p1);
CoordinateType const sx2 = get<0>(p2);
CoordinateType const sy2 = get<1>(p2);
//non-robust 1
//the following is 2x slower in some generic cases when compiled with g++
//(tested versions 9 and 10)
//
//auto detleft = (sx1 - x) * (sy2 - y);
//auto detright = (sy1 - y) * (sx2 - x);
//return detleft > detright ? 1 : (detleft < detright ? -1 : 0 );
//non-robust 2
PromotedType const dx = sx2 - sx1;
PromotedType const dy = sy2 - sy1;
PromotedType const dpx = x - sx1;
PromotedType const dpy = y - sy1;
PromotedType sv = geometry::detail::determinant<PromotedType>
(
dx, dy,
dpx, dpy
);
PromotedType const zero = PromotedType();
return sv == 0 ? 0 : sv > zero ? 1 : -1;
}
#endif
};

View File

@ -7,6 +7,7 @@
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -17,9 +18,14 @@
#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
#include <boost/geometry/strategy/cartesian/side_non_robust.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/precise_math.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
@ -27,6 +33,27 @@ namespace boost { namespace geometry
namespace strategy { namespace side
{
struct epsilon_equals_policy
{
public:
template <typename Policy, typename T1, typename T2>
static bool apply(T1 const& a, T2 const& b, Policy const& policy)
{
return boost::geometry::math::detail::equals_by_policy(a, b, policy);
}
};
struct fp_equals_policy
{
public:
template <typename Policy, typename T1, typename T2>
static bool apply(T1 const& a, T2 const& b, Policy const&)
{
return a == b;
}
};
/*!
\brief Adaptive precision predicate to check at which side of a segment a point lies:
left of segment (>0), right of segment (< 0), on segment (0).
@ -38,21 +65,52 @@ namespace strategy { namespace side
template
<
typename CalculationType = void,
typename EqualsPolicy = epsilon_equals_policy,
std::size_t Robustness = 3
>
struct side_robust
{
template <typename CT>
struct epsilon_policy
{
using Policy = boost::geometry::math::detail::equals_factor_policy<CT>;
epsilon_policy() {}
template <typename Type>
epsilon_policy(Type const& a, Type const& b, Type const& c, Type const& d)
: m_policy(a, b, c, d)
{}
Policy m_policy;
public:
template <typename T1, typename T2>
bool apply(T1 a, T2 b) const
{
return EqualsPolicy::apply(a, b, m_policy);
}
};
public:
//! \brief Computes double the signed area of the CCW triangle p1, p2, p
typedef cartesian_tag cs_tag;
//! \brief Computes the sign of the CCW triangle p1, p2, p
template
<
typename PromotedType,
typename P1,
typename P2,
typename P
typename P,
typename EpsPolicyInternal,
std::enable_if_t<std::is_fundamental<PromotedType>::value, int> = 0
>
static inline PromotedType side_value(P1 const& p1, P2 const& p2,
P const& p)
static inline PromotedType side_value(P1 const& p1,
P2 const& p2,
P const& p,
EpsPolicyInternal& eps_policy)
{
using vec2d = ::boost::geometry::detail::precise_math::vec2d<PromotedType>;
vec2d pa;
@ -65,7 +123,22 @@ public:
pc.x = get<0>(p);
pc.y = get<1>(p);
return ::boost::geometry::detail::precise_math::orient2d
<PromotedType, Robustness>(pa, pb, pc);
<PromotedType, Robustness>(pa, pb, pc, eps_policy);
}
template
<
typename PromotedType,
typename P1,
typename P2,
typename P,
typename EpsPolicyInternal,
std::enable_if_t<!std::is_fundamental<PromotedType>::value, int> = 0
>
static inline auto side_value(P1 const& p1, P2 const& p2, P const& p,
EpsPolicyInternal&)
{
return side_non_robust<>::apply(p1, p2, p);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@ -77,28 +150,48 @@ public:
>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
typedef typename select_calculation_type_alt
using coordinate_type = typename select_calculation_type_alt
<
CalculationType,
P1,
P2,
P
>::type coordinate_type;
typedef typename select_most_precise
>::type;
using promoted_type = typename select_most_precise
<
coordinate_type,
double
>::type promoted_type;
>::type;
promoted_type sv = side_value<promoted_type>(p1, p2, p);
return sv > 0 ? 1
: sv < 0 ? -1
: 0;
epsilon_policy<promoted_type> epsp;
promoted_type sv = side_value<promoted_type>(p1, p2, p, epsp);
promoted_type const zero = promoted_type();
return epsp.apply(sv, zero) ? 0
: sv > zero ? 1
: -1;
}
#endif
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<cartesian_tag, CalculationType>
{
typedef side_robust<CalculationType> type;
};
}
#endif
}} // namespace strategy::side
}} // namespace boost::geometry

View File

@ -5,6 +5,10 @@
// Contributed and/or modified by Tinko Bartels,
// as part of Google Summer of Code 2019 program.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// 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)
@ -157,7 +161,9 @@ inline int fast_expansion_sum_zeroelim(
int n = InSize2)
{
std::array<RealNumber, 2> Qh;
int i_e = 0, i_f = 0, i_h = 0;
int i_e = 0;
int i_f = 0;
int i_h = 0;
if (std::abs(f[0]) > std::abs(e[0]))
{
Qh[0] = e[i_e++];
@ -282,14 +288,16 @@ inline RealNumber orient2dtail(vec2d<RealNumber> const& p1,
std::array<RealNumber, 2>& t4,
std::array<RealNumber, 2>& t5_01,
std::array<RealNumber, 2>& t6_01,
RealNumber const& magnitude
)
RealNumber const& magnitude)
{
t5_01[1] = two_product_tail(t1[0], t2[0], t5_01[0]);
t6_01[1] = two_product_tail(t3[0], t4[0], t6_01[0]);
std::array<RealNumber, 4> tA_03 = two_two_expansion_diff(t5_01, t6_01);
RealNumber det = std::accumulate(tA_03.begin(), tA_03.end(), static_cast<RealNumber>(0));
if(Robustness == 1) return det;
if (Robustness == 1)
{
return det;
}
// see p.39, mind the different definition of epsilon for error bound
RealNumber B_relative_bound =
(1 + 3 * std::numeric_limits<RealNumber>::epsilon())
@ -347,29 +355,37 @@ inline RealNumber orient2dtail(vec2d<RealNumber> const& p1,
return(D[D_nz - 1]);
}
// see page 38, Figure 21 for the calculations, notation follows the notation in the figure.
// see page 38, Figure 21 for the calculations, notation follows the notation
// in the figure.
template
<
typename RealNumber,
std::size_t Robustness = 3
std::size_t Robustness = 3,
typename EpsPolicy
>
inline RealNumber orient2d(vec2d<RealNumber> const& p1,
vec2d<RealNumber> const& p2,
vec2d<RealNumber> const& p3)
vec2d<RealNumber> const& p3,
EpsPolicy& eps_policy)
{
if(Robustness == 0)
{
return (p1.x - p3.x) * (p2.y - p3.y) - (p1.y - p3.y) * (p2.x - p3.x);
}
std::array<RealNumber, 2> t1, t2, t3, t4;
t1[0] = p1.x - p3.x;
t2[0] = p2.y - p3.y;
t3[0] = p1.y - p3.y;
t4[0] = p2.x - p3.x;
eps_policy = EpsPolicy(t1[0], t2[0], t3[0], t4[0]);
std::array<RealNumber, 2> t5_01, t6_01;
t5_01[0] = t1[0] * t2[0];
t6_01[0] = t3[0] * t4[0];
RealNumber det = t5_01[0] - t6_01[0];
if (Robustness == 0)
{
return det;
}
RealNumber const magnitude = std::abs(t5_01[0]) + std::abs(t6_01[0]);
// see p.39, mind the different definition of epsilon for error bound
@ -388,7 +404,8 @@ inline RealNumber orient2d(vec2d<RealNumber> const& p1,
//obvious
return det;
}
return orient2dtail<RealNumber, Robustness>(p1, p2, p3, t1, t2, t3, t4, t5_01, t6_01, magnitude);
return orient2dtail<RealNumber, Robustness>(p1, p2, p3, t1, t2, t3, t4,
t5_01, t6_01, magnitude);
}
// This method adaptively computes increasingly precise approximations of the following

View File

@ -18,35 +18,9 @@
#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
#define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("boost/geometry/core/coordinate_promotion.hpp")
#include <type_traits>
namespace boost { namespace geometry
{
/*!
\brief Meta-function converting, if necessary, to "a floating point" type
\details
- if input type is integer, type is double
- else type is input type
\ingroup utility
*/
template <typename T, typename PromoteIntegerTo = double>
struct promote_floating_point
{
typedef std::conditional_t
<
std::is_integral<T>::value,
PromoteIntegerTo,
T
> type;
};
}} // namespace boost::geometry
#include <boost/geometry/core/coordinate_promotion.hpp>
#endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP

View File

@ -2,7 +2,8 @@
#
# Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
#
# Copyright (c) 2021, Oracle and/or its affiliates.
# This file was modified by Oracle on 2021.
# Modifications copyright (c) 2021 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,
@ -19,7 +20,6 @@ project boost-geometry-index-test
<toolset>msvc:<asynch-exceptions>on
<toolset>msvc:<cxxflags>/bigobj
<host-os>windows,<toolset>intel:<cxxflags>/bigobj
<define>BOOST_NO_AUTO_PTR # disable the deprecated std::auto_ptr support in SmartPtr and Core
<library>/boost/timer//boost_timer
;

View File

@ -3,6 +3,10 @@
// Copyright (c) 2016 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -101,7 +105,7 @@ void test_ticket_12413()
size_t num_removed = rtree.remove(std::make_pair(point_t(-0.127592, 51.503407), 796));
BOOST_CHECK_EQUAL(num_removed, 1);
BOOST_CHECK_EQUAL(num_removed, 1u);
}
template <typename Point>

View File

@ -3,6 +3,10 @@
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -10,7 +14,6 @@
#include <fstream>
#include <vector>
#include <string>
#include <boost/foreach.hpp>
#include <boost/assert.hpp>
#include <boost/tuple/tuple.hpp>
@ -46,13 +49,13 @@ int main()
testsets.push_back(std::make_pair("testset::queries", "que"));
testsets.push_back(std::make_pair("testset::additional", "add"));
BOOST_FOREACH(P const& p, parameters)
for (P const& p : parameters)
{
BOOST_FOREACH(TS const& ts, testsets)
for (TS const& ts : testsets)
{
BOOST_FOREACH(std::string const& i, indexables)
for (std::string const& i : indexables)
{
BOOST_FOREACH(std::string const& d, dimensions)
for (std::string const& d : dimensions)
{
// If the I is Segment, generate only for 2d
if ( i == "s" && d != "2" )
@ -60,7 +63,7 @@ int main()
continue;
}
BOOST_FOREACH(CT const& c, coordinate_types)
for (CT const& c : coordinate_types)
{
std::string filename = std::string() +
"rtree_" + boost::get<1>(p) + '_' + ts.second + '_' + i + d + boost::get<1>(c) + ".cpp";

View File

@ -14,7 +14,6 @@
#ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
#define BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
#include <boost/foreach.hpp>
#include <vector>
#include <algorithm>
@ -415,6 +414,8 @@ struct counting_value
counting_value(counting_value const& c) : indexable(c.indexable) { counter()++; }
~counting_value() { counter()--; }
counting_value& operator=(counting_value const& c) = default;
static size_t & counter() { static size_t c = 0; return c; }
Indexable indexable;
};
@ -681,15 +682,16 @@ void rtree(Rtree & tree, Elements & input, Box & qbox)
} // namespace generate
namespace basictest {
namespace basictest
{
// low level test functions
template <typename Rtree, typename Iter, typename Value>
Iter find(Rtree const& rtree, Iter first, Iter last, Value const& value)
{
for ( ; first != last ; ++first )
if ( rtree.value_eq()(value, *first) )
for (; first != last; ++first)
if (rtree.value_eq()(value, *first))
return first;
return first;
}
@ -698,12 +700,12 @@ template <typename Rtree, typename Value>
void compare_outputs(Rtree const& rtree, std::vector<Value> const& output, std::vector<Value> const& expected_output)
{
bool are_sizes_ok = (expected_output.size() == output.size());
BOOST_CHECK( are_sizes_ok );
if ( are_sizes_ok )
BOOST_CHECK(are_sizes_ok);
if (are_sizes_ok)
{
BOOST_FOREACH(Value const& v, expected_output)
for (Value const& v : expected_output)
{
BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end() );
BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end());
}
}
}
@ -715,13 +717,13 @@ void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 c
size_t s2 = std::distance(expected_output.begin(), expected_output.end());
BOOST_CHECK(s1 == s2);
if ( s1 == s2 )
if (s1 == s2)
{
typename Range1::const_iterator it1 = output.begin();
typename Range2::const_iterator it2 = expected_output.begin();
for ( ; it1 != output.end() && it2 != expected_output.end() ; ++it1, ++it2 )
for (; it1 != output.end() && it2 != expected_output.end(); ++it1, ++it2)
{
if ( !rtree.value_eq()(*it1, *it2) )
if (!rtree.value_eq()(*it1, *it2))
{
BOOST_CHECK(false && "rtree.translator().equals(*it1, *it2)");
break;
@ -734,7 +736,7 @@ void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 c
template <typename First, typename Last, typename Out>
void copy_alt(First first, Last last, Out out)
{
for ( ; first != last ; ++first, ++out )
for (; first != last; ++first, ++out)
*out = *first;
}
@ -759,7 +761,7 @@ void check_fwd_iterators(QItF first, QItL last)
#endif
QItF it = first;
for ( ; it != last && first != last ; ++it, ++first)
for (; it != last && first != last; ++it, ++first)
{
BOOST_CHECK(it == first);
@ -775,20 +777,20 @@ void check_fwd_iterators(QItF first, QItL last)
template <typename Rtree, typename Value, typename Predicates>
void spatial_query(Rtree & rtree, Predicates const& pred, std::vector<Value> const& expected_output)
{
BOOST_CHECK( bgi::detail::rtree::utilities::are_levels_ok(rtree) );
if ( !rtree.empty() )
BOOST_CHECK( bgi::detail::rtree::utilities::are_boxes_ok(rtree) );
BOOST_CHECK(bgi::detail::rtree::utilities::are_levels_ok(rtree));
if (!rtree.empty())
BOOST_CHECK(bgi::detail::rtree::utilities::are_boxes_ok(rtree));
std::vector<Value> output;
size_t n = rtree.query(pred, std::back_inserter(output));
BOOST_CHECK( expected_output.size() == n );
BOOST_CHECK(expected_output.size() == n);
compare_outputs(rtree, output, expected_output);
std::vector<Value> output2;
size_t n2 = query(rtree, pred, std::back_inserter(output2));
BOOST_CHECK( n == n2 );
BOOST_CHECK(n == n2);
exactly_the_same_outputs(rtree, output, output2);
exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(pred));
@ -827,9 +829,13 @@ void intersects(Rtree const& tree, std::vector<Value> const& input, Box const& q
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::intersects(tree.indexable_get()(v), qbox) )
for (Value const& v : input)
{
if (bg::intersects(tree.indexable_get()(v), qbox))
{
expected_output.push_back(v);
}
}
//spatial_query(tree, qbox, expected_output);
spatial_query(tree, bgi::intersects(qbox), expected_output);
@ -851,9 +857,13 @@ void disjoint(Rtree const& tree, std::vector<Value> const& input, Box const& qbo
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::disjoint(tree.indexable_get()(v), qbox) )
for (Value const& v : input)
{
if (bg::disjoint(tree.indexable_get()(v), qbox))
{
expected_output.push_back(v);
}
}
spatial_query(tree, bgi::disjoint(qbox), expected_output);
spatial_query(tree, !bgi::intersects(qbox), expected_output);
@ -875,9 +885,13 @@ struct contains_impl
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::within(qbox, tree.indexable_get()(v)) )
for (Value const& v : input)
{
if (bg::within(qbox, tree.indexable_get()(v)))
{
expected_output.push_back(v);
}
}
spatial_query(tree, bgi::contains(qbox), expected_output);
@ -912,7 +926,7 @@ void contains(Rtree const& tree, std::vector<Value> const& input, Box const& qbo
{
contains_impl<
typename bg::tag<
typename Rtree::indexable_type
typename Rtree::indexable_type
>::type
>::apply(tree, input, qbox);
}
@ -925,12 +939,12 @@ struct covered_by_impl
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
for (Value const& v : input)
{
if ( bgi::detail::covered_by_bounds(
tree.indexable_get()(v),
qbox,
bgi::detail::get_strategy(tree.parameters())) )
if (bgi::detail::covered_by_bounds(
tree.indexable_get()(v),
qbox,
bgi::detail::get_strategy(tree.parameters())))
{
expected_output.push_back(v);
}
@ -961,7 +975,7 @@ void covered_by(Rtree const& tree, std::vector<Value> const& input, Box const& q
{
covered_by_impl<
typename bg::tag<
typename Rtree::indexable_type
typename Rtree::indexable_type
>::type
>::apply(tree, input, qbox);
}
@ -974,9 +988,13 @@ struct covers_impl
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::covered_by(qbox, tree.indexable_get()(v)) )
for (Value const& v : input)
{
if (bg::covered_by(qbox, tree.indexable_get()(v)))
{
expected_output.push_back(v);
}
}
spatial_query(tree, bgi::covers(qbox), expected_output);
@ -1011,7 +1029,7 @@ void covers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
{
covers_impl<
typename bg::tag<
typename Rtree::indexable_type
typename Rtree::indexable_type
>::type
>::apply(tree, input, qbox);
}
@ -1024,9 +1042,13 @@ struct overlaps_impl
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::overlaps(tree.indexable_get()(v), qbox) )
for (Value const& v : input)
{
if (bg::overlaps(tree.indexable_get()(v), qbox))
{
expected_output.push_back(v);
}
}
spatial_query(tree, bgi::overlaps(qbox), expected_output);
@ -1061,7 +1083,7 @@ void overlaps(Rtree const& tree, std::vector<Value> const& input, Box const& qbo
{
overlaps_impl<
typename bg::tag<
typename Rtree::indexable_type
typename Rtree::indexable_type
>::type
>::apply(tree, input, qbox);
}
@ -1082,9 +1104,13 @@ void overlaps(Rtree const& tree, std::vector<Value> const& input, Box const& qbo
// {
// std::vector<Value> expected_output;
//
// BOOST_FOREACH(Value const& v, input)
// if ( bg::touches(tree.translator()(v), qbox) )
// for (Value const& v : input)
// {
// if (bg::touches(tree.translator()(v), qbox))
// {
// expected_output.push_back(v);
// }
// }
//
// spatial_query(tree, bgi::touches(qbox), expected_output);
// }
@ -1107,9 +1133,13 @@ struct within_impl
{
std::vector<Value> expected_output;
BOOST_FOREACH(Value const& v, input)
if ( bg::within(tree.indexable_get()(v), qbox) )
for (Value const& v : input)
{
if (bg::within(tree.indexable_get()(v), qbox))
{
expected_output.push_back(v);
}
}
spatial_query(tree, bgi::within(qbox), expected_output);
@ -1172,15 +1202,15 @@ inline void compare_nearest_outputs(Rtree const& rtree, std::vector<Value> const
{
// check output
bool are_sizes_ok = (expected_output.size() == output.size());
BOOST_CHECK( are_sizes_ok );
if ( are_sizes_ok )
BOOST_CHECK(are_sizes_ok);
if (are_sizes_ok)
{
BOOST_FOREACH(Value const& v, output)
for (Value const& v : output)
{
// TODO - perform explicit check here?
// should all objects which are closest be checked and should exactly the same be found?
if ( find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end() )
if (find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end())
{
Distance d = bg::comparable_distance(pt, rtree.indexable_get()(v));
BOOST_CHECK(d == greatest_distance);
@ -1195,7 +1225,7 @@ inline void check_sorted_by_distance(Rtree const& rtree, std::vector<Value> cons
typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
D prev_dist = 0;
BOOST_FOREACH(Value const& v, output)
for (Value const& v : output)
{
D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
BOOST_CHECK(prev_dist <= d);
@ -1214,25 +1244,31 @@ inline void nearest_query_k(Rtree const& rtree, std::vector<Value> const& input,
std::vector< std::pair<D, Value> > test_output;
// calculate test output - k closest values pairs
BOOST_FOREACH(Value const& v, input)
for (Value const& v : input)
{
D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
if ( test_output.size() < k )
if (test_output.size() < k)
{
test_output.push_back(std::make_pair(d, v));
}
else
{
std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
if ( d < test_output.back().first )
if (d < test_output.back().first)
{
test_output.back() = std::make_pair(d, v);
}
}
}
// caluclate biggest distance
std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
D greatest_distance = 0;
if ( !test_output.empty() )
if (! test_output.empty())
{
greatest_distance = test_output.back().first;
}
// transform test output to vector of values
std::vector<Value> expected_output(test_output.size(), generate::value_default<Value>::apply());
@ -1441,8 +1477,10 @@ void create_insert(Rtree const& tree, std::vector<Value> const& input, Box const
{
Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
BOOST_FOREACH(Value const& v, input)
for (Value const& v : input)
{
t.insert(v);
}
BOOST_CHECK(tree.size() == t.size());
std::vector<Value> output;
t.query(bgi::intersects(qbox), std::back_inserter(output));
@ -1490,8 +1528,10 @@ void create_insert(Rtree const& tree, std::vector<Value> const& input, Box const
{
Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
BOOST_FOREACH(Value const& v, input)
for (Value const& v : input)
{
bgi::insert(t, v);
}
BOOST_CHECK(tree.size() == t.size());
std::vector<Value> output;
bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
@ -1538,8 +1578,10 @@ void remove(Rtree const& tree, Box const& qbox)
{
Rtree t(tree);
size_t r = 0;
BOOST_FOREACH(Value const& v, values_to_remove)
for (Value const& v : values_to_remove)
{
r += t.remove(v);
}
BOOST_CHECK( r == expected_removed_count );
std::vector<Value> output;
t.query(bgi::disjoint(qbox), std::back_inserter(output));
@ -1571,8 +1613,10 @@ void remove(Rtree const& tree, Box const& qbox)
{
Rtree t(tree);
size_t r = 0;
BOOST_FOREACH(Value const& v, values_to_remove)
for (Value const& v : values_to_remove)
{
r += bgi::remove(t, v);
}
BOOST_CHECK( r == expected_removed_count );
std::vector<Value> output;
bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
@ -1643,7 +1687,7 @@ void range(Rtree & tree, std::vector<Value> const& input)
BOOST_CHECK(count == tree.size());
count = 0;
BOOST_FOREACH(Value const& v, tree)
for (Value const& v : tree)
{
boost::ignore_unused(v);
++count;
@ -1777,7 +1821,7 @@ void test_count_rtree_values(Parameters const& parameters, Allocator const& allo
size_t values_count = Value::counter();
BOOST_FOREACH(Value const& v, values_to_remove)
for (Value const& v : values_to_remove)
{
size_t r = t.remove(v);
--values_count;

View File

@ -4,6 +4,10 @@
// Copyright (c) 2012-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2013 Andrew Hundt.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -55,11 +59,11 @@ void test_ctor_nc(size_t n)
if ( 1 < n )
{
T val10(10);
s[0] = val10;
s[0] = std::move(val10);
BOOST_CHECK(T(10) == s[0]);
BOOST_CHECK(T(10) == s.at(0));
T val20(20);
s.at(1) = val20;
s.at(1) = std::move(val20);
BOOST_CHECK(T(20) == s[1]);
BOOST_CHECK(T(20) == s.at(1));
}
@ -103,11 +107,11 @@ void test_resize_nc(size_t n)
if ( 1 < n )
{
T val10(10);
s[0] = val10;
s[0] = std::move(val10);
BOOST_CHECK(T(10) == s[0]);
BOOST_CHECK(T(10) == s.at(0));
T val20(20);
s.at(1) = val20;
s.at(1) = std::move(val20);
BOOST_CHECK(T(20) == s[1]);
BOOST_CHECK(T(20) == s.at(1));
}

View File

@ -4,6 +4,10 @@
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2013 Andrew Hundt.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, 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,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -23,9 +27,11 @@ public:
~value_ndc() {}
bool operator==(value_ndc const& v) const { return aa == v.aa; }
bool operator<(value_ndc const& v) const { return aa < v.aa; }
value_ndc(value_ndc const&) = delete;
value_ndc & operator=(value_ndc const&) = delete;
value_ndc(value_ndc&&) = default;
value_ndc & operator=(value_ndc&&) = default;
private:
value_ndc(value_ndc const&) {}
value_ndc & operator=(value_ndc const&) { return *this; }
size_t aa;
};
@ -47,9 +53,11 @@ public:
~value_nc() {}
bool operator==(value_nc const& v) const { return aa == v.aa; }
bool operator<(value_nc const& v) const { return aa < v.aa; }
value_nc(value_nc const&) = delete;
value_nc & operator=(value_nc const&) = delete;
value_nc(value_nc&&) = default;
value_nc & operator=(value_nc&&) = default;
private:
value_nc(value_nc const&) {}
value_nc & operator=(value_ndc const&) { return *this; }
size_t aa;
};

View File

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

View File

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

View File

@ -3,9 +3,10 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2021.
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -30,9 +31,10 @@
#include <boost/geometry/strategies/area/services.hpp>
#include <boost/geometry/strategies/spherical/side_by_cross_track.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategy/cartesian/side_non_robust.hpp>
#include <boost/geometry/strategy/cartesian/precise_area.hpp>
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/side_non_robust.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
@ -43,7 +45,11 @@ struct robust_cartesian : boost::geometry::strategies::detail::cartesian_base
{
static auto side()
{
return boost::geometry::strategy::side::side_robust<>();
return boost::geometry::strategy::side::side_robust
<
double,
boost::geometry::strategy::side::fp_equals_policy
>();
}
};
@ -159,15 +165,12 @@ struct test_convex_hull
std::size_t size_hull_closed,
double expected_area,
double expected_perimeter,
bool reverse)
bool /*reverse*/)
{
bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open;
static bool const is_hull_closed = bg::closure<Hull>::value != bg::open;
// convex_hull_insert() uses the original Geometry as a source of the info
// about the order and closure
std::size_t const size_hull_from_orig = is_original_closed ?
size_hull_closed : size_hull_closed - 1;
std::size_t const size_hull = is_hull_closed ? size_hull_closed :
size_hull_closed - 1;
@ -179,14 +182,19 @@ struct test_convex_hull
check_convex_hull(geometry, hull, size_original, size_hull,
expected_area, expected_perimeter, false, AreaStrategy());
// Test version with output iterator and strategy
// Do not test with output iterator since it does not support
// non-default strategy
/*
bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open;
std::size_t const size_hull_from_orig = is_original_closed ?
size_hull_closed : size_hull_closed - 1;
bg::clear(hull);
bg::detail::convex_hull::convex_hull_insert(
geometry,
std::back_inserter(hull.outer()), Strategy());
check_convex_hull(geometry, hull, size_original, size_hull_from_orig,
expected_area, expected_perimeter, reverse, AreaStrategy());
*/
}
};
@ -254,6 +262,49 @@ struct test_convex_hull<Hull, robust_cartesian, AreaStrategy>
};
template
<
typename Hull
>
struct test_convex_hull<Hull, robust_cartesian, precise_cartesian>
{
template <typename Geometry>
static void apply(Geometry const& geometry,
std::size_t size_original,
std::size_t size_hull_closed,
double expected_area,
double expected_perimeter,
bool reverse)
{
bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open;
static bool const is_hull_closed = bg::closure<Hull>::value != bg::open;
// convex_hull_insert() uses the original Geometry as a source of the info
// about the order and closure
std::size_t const size_hull_from_orig = is_original_closed ?
size_hull_closed : size_hull_closed - 1;
std::size_t const size_hull = is_hull_closed ? size_hull_closed :
size_hull_closed - 1;
Hull hull;
// Test version with strategy
bg::clear(hull);
bg::convex_hull(geometry, hull.outer(), robust_cartesian());
check_convex_hull(geometry, hull, size_original, size_hull, expected_area,
expected_perimeter, false, precise_cartesian());
// Test version with output iterator and strategy
bg::clear(hull);
bg::detail::convex_hull::convex_hull_insert(geometry,
std::back_inserter(hull.outer()), robust_cartesian());
check_convex_hull(geometry, hull, size_original, size_hull_from_orig,
expected_area, expected_perimeter, reverse, precise_cartesian());
}
};
template
<
typename Geometry,
@ -342,6 +393,4 @@ void test_empty_input()
BOOST_CHECK_MESSAGE(bg::is_empty(hull), "Output convex hull should be empty" );
}
#endif

View File

@ -284,21 +284,12 @@ void test_all()
"LINESTRING(2 8,4 0.4,8 1,0 5)",
expected("iuu++")("mui=+")("tiu+="));
#if ! ( defined(BOOST_CLANG) && defined(BOOST_GEOMETRY_COMPILER_MODE_RELEASE) )
// In clang/release mode this testcase gives other results
// assertion failure in 1.57
// FAILING - no assertion failure but the result is not very good
test_geometry<ls, ls>("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)",
"LINESTRING(31 -97, -46 57, -20 -4)",
expected("")(""));
expected("iuu++"));
test_geometry<ls, ls>("LINESTRING(31 -97, -46 57, -20 -4)",
"LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)",
expected("")(""));
#endif
expected("iuu++"));
}
// In 1.57 the results of those combinations was different for MinGW

View File

@ -27,9 +27,11 @@
# include <boost/geometry/io/svg/svg_mapper.hpp>
#endif
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/side.hpp>
template <typename P, typename T>
void test_with_point(std::string const& /*caseid*/,

View File

@ -46,8 +46,6 @@ void test_all()
{
typedef bg::model::polygon<P> polygon;
typedef typename bg::coordinate_type<P>::type ct;
test_one<polygon, polygon, polygon>("simplex_normal",
simplex_normal[0], simplex_normal[1],
3, 12, 2.52636706856656,
@ -68,10 +66,15 @@ void test_all()
1, 5, 8.0,
1, 5, 8.0);
test_one<polygon, polygon, polygon>("star_comb_15",
star_comb_15[0], star_comb_15[1],
30, -1, 227.658275102812,
30, -1, 480.485775259312);
{
ut_settings settings;
settings.validity_false_negative_sym = true;
test_one<polygon, polygon, polygon>("star_comb_15",
star_comb_15[0], star_comb_15[1],
30, -1, 227.658275102812,
30, -1, 480.485775259312,
settings);
}
test_one<polygon, polygon, polygon>("new_hole",
new_hole[0], new_hole[1],
@ -106,7 +109,7 @@ void test_all()
{
ut_settings settings;
settings.sym_difference_validity = BG_IF_RESCALED(true, false);
settings.validity_false_negative_sym = true;
test_one<polygon, polygon, polygon>("only_hole_intersections1",
only_hole_intersections[0], only_hole_intersections[1],
@ -114,7 +117,7 @@ void test_all()
4, 16, 10.9090909,
settings);
test_one<polygon, polygon, polygon>("only_hole_intersection2",
test_one<polygon, polygon, polygon>("only_hole_intersections2",
only_hole_intersections[0], only_hole_intersections[2],
3, 20, 30.9090909,
4, 16, 10.9090909,
@ -144,7 +147,7 @@ void test_all()
{
ut_settings settings;
settings.sym_difference_validity = BG_IF_RESCALED(false, true);
settings.validity_of_sym = BG_IF_RESCALED(false, true);
test_one<polygon, polygon, polygon>("intersect_holes_intersect_and_disjoint",
intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
2, 16, 15.75,
@ -180,7 +183,6 @@ void test_all()
{
ut_settings settings;
settings.sym_difference_validity = BG_IF_RESCALED(false, true);
test_one<polygon, polygon, polygon>("intersect_holes_intersect",
intersect_holes_intersect[0], intersect_holes_intersect[1],
2, 16, 15.75,
@ -295,10 +297,9 @@ void test_all()
1, 61, 10.2717,
1, 61, 10.2717);
if ( BOOST_GEOMETRY_CONDITION((std::is_same<ct, double>::value)) )
{
ut_settings settings;
settings.sym_difference_validity = BG_IF_RESCALED(true, false);
settings.validity_false_negative_sym = true;
TEST_DIFFERENCE_WITH(buffer_mp2, 1, 12.09857, 1, 24.19714,
count_set(1, 2), settings);
}
@ -319,7 +320,7 @@ void test_all()
ut_settings settings;
settings.percentage = BG_IF_RESCALED(0.001, 0.1);
settings.set_test_validity(BG_IF_RESCALED(true, false));
settings.sym_difference = BG_IF_RESCALED(true, false);
settings.sym_difference = false;
// Isovist - the # output polygons differ per compiler/pointtype, (very) small
// rings might be discarded. We check area only
@ -330,18 +331,24 @@ void test_all()
test_one<polygon, polygon, polygon>("isovist",
isovist1[0], isovist1[1],
ignore_count(), -1, 0.279132,
ignore_count(), -1, expectation_limits(0.279128, 0.279132),
ignore_count(), -1, 224.8892,
settings);
}
#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
// SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings
// PostGIS gives: 0.30859375 and 0.033203125 with 35/35 rings
TEST_DIFFERENCE_WITH(geos_1,
ignore_count(), expectation_limits(0.20705, 0.29172),
ignore_count(), expectation_limits(0.00060440758, 0.00076856),
ignore_count(), ut_settings(0.1, false));
{
ut_settings settings(0.1);
settings.set_test_validity(BG_IF_RESCALED(false, true));
settings.validity_false_negative_sym = BG_IF_RESCALED(true, false);
// SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings
// PostGIS gives: 0.30859375 and 0.033203125 with 35/35 rings
TEST_DIFFERENCE_WITH(geos_1,
ignore_count(), expectation_limits(0.20705, 0.29172),
ignore_count(), expectation_limits(0.00060440758, 0.00076856),
ignore_count(), settings);
}
#endif
{
@ -425,7 +432,7 @@ void test_all()
// With rescaling, difference of output a-b and a sym b is invalid
ut_settings settings;
settings.set_test_validity(BG_IF_RESCALED(false, true));
settings.sym_difference_validity = BG_IF_RESCALED(false, true);
settings.validity_of_sym = BG_IF_RESCALED(false, true);
TEST_DIFFERENCE_WITH(ggl_list_20190307_matthieu_1,
count_set(1, 2), 0.18461532,
count_set(1, 2), 0.617978,
@ -563,6 +570,7 @@ void test_all()
{
ut_settings settings;
settings.set_test_validity(BG_IF_RESCALED(true, false));
settings.validity_false_negative_a = true;
TEST_DIFFERENCE_WITH(issue_838,
count_set(1, 2), expectation_limits(0.000026, 0.0002823),
count_set(1, 2), expectation_limits(0.67257, 0.67499),
@ -583,12 +591,16 @@ void test_all()
TEST_DIFFERENCE(mysql_23023665_3, 1, 225.0, 1, 66.0, 2);
TEST_DIFFERENCE(mysql_23023665_5, 2, 165.23735, 2, 105.73735, 4);
{
// Without recaling it is invalid
// Without rescaling it is invalid
ut_settings settings;
settings.set_test_validity(BG_IF_RESCALED(true, false));
settings.set_test_validity(true);
TEST_DIFFERENCE_WITH(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5, settings);
}
TEST_DIFFERENCE(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6);
{
ut_settings settings;
settings.validity_false_negative_sym = true;
TEST_DIFFERENCE_WITH(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6, settings);
}
}
@ -633,7 +645,7 @@ int test_main(int, char* [])
// Not yet fully tested for float and long double.
// The difference algorithm can generate (additional) slivers
// Many of the failures are self-intersection points.
BoostGeometryWriteExpectedFailures(19, 10, 17, 12);
BoostGeometryWriteExpectedFailures(15, 5, 17, 10);
#endif
return 0;

View File

@ -240,8 +240,8 @@ int test_main(int, char* [])
test_all<bg::model::d2::point_xy<double> >();
test_ticket_10835<int>
("MULTILINESTRING((5239 2113,5233 2114),(4794 2205,1020 2986))",
"MULTILINESTRING((5239 2113,5233 2114),(4794 2205,1460 2895))");
("MULTILINESTRING((5239 2113,5232 2115),(4794 2205,1020 2986))",
"MULTILINESTRING((5239 2113,5232 2115),(4794 2205,1460 2895))");
test_ticket_10835<double>
("MULTILINESTRING((5239 2113,5232.52 2114.34),(4794.39 2205,1020 2986))",

View File

@ -155,10 +155,12 @@ void test_areal()
#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
{
// 1: Very small sliver for B (discarded when rescaling)
// 2: sym difference is not considered as valid
// 2: sym difference is not considered as valid (without rescaling
// this is a false negative)
// 3: with rescaling A is considered as invalid (robustness problem)
ut_settings settings;
settings.sym_difference_validity = false;
settings.validity_of_sym = BG_IF_RESCALED(false, true);
settings.validity_false_negative_sym = true;
TEST_DIFFERENCE_WITH(0, 1, bug_21155501,
(count_set(1, 4)), expectation_limits(3.75893, 3.75894),
(count_set(1, 4)), (expectation_limits(1.776357e-15, 7.661281e-15)),
@ -172,7 +174,7 @@ void test_areal()
// Without rescaling, one ring is missing (for a and s)
ut_settings settings;
settings.set_test_validity(BG_IF_RESCALED(false, true));
settings.sym_difference_validity = BG_IF_RESCALED(false, true);
settings.validity_of_sym = BG_IF_RESCALED(false, true);
TEST_DIFFERENCE_WITH(0, 1, ticket_9081,
2, 0.0907392476356186,
4, 0.126018011439877,
@ -211,9 +213,12 @@ void test_areal()
TEST_DIFFERENCE(issue_888_34, 22, 0.2506824, 6, 0.0253798, 28); // a went wrong
TEST_DIFFERENCE(issue_888_37, 15, 0.0451408, 65, 0.3014843, 80); // b went wrong
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
TEST_DIFFERENCE(issue_888_53, 117, 0.2973268, 17, 0.0525798, 134); // a goes wrong
#endif
{
ut_settings settings;
settings.validity_false_negative_a = true;
settings.validity_false_negative_sym = true;
TEST_DIFFERENCE_WITH(0, 1, issue_888_53, 117, 0.2973268, 17, 0.0525798, 134);
}
// Areas and #clips correspond with POSTGIS (except sym case)
test_one<Polygon, MultiPolygon, MultiPolygon>("case_101_multi",
@ -472,24 +477,29 @@ void test_specific_areal()
{
const std::string a_min_b =
TEST_DIFFERENCE(ticket_10661, 2, 1441632.5, 2, 13167454, 4);
test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_10661",
ticket_10661[0], ticket_10661[1],
2, -1, expectation_limits(1441632, 1441855),
2, -1, expectation_limits(13167454, 13182415),
count_set(3, 4));
test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_10661_2",
a_min_b, ticket_10661[2],
1, 8, 825192.0,
1, 10, expectation_limits(27226370, 27842812),
1, -1, 825192.0 + 27226370.5);
1, 10, expectation_limits(27226148, 27842812),
count_set(1, 2));
}
{
ut_settings settings;
settings.sym_difference = false;
TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4, expectation_limits(7427727.5), 4,
expectation_limits(130083, 131507), 4);
TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4,
expectation_limits(7427727, 7428108), 4,
expectation_limits(130083, 131823), 4);
TEST_DIFFERENCE_WITH(0, 1, ticket_9942a, 2,
expectation_limits(412676, 413184), 2,
expectation_limits(76779, 76925), 4);
expectation_limits(412676, 413469), 2,
expectation_limits(76779, 77038), 4);
}
}
@ -516,7 +526,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(28, 15, 19, 10);
BoostGeometryWriteExpectedFailures(24, 11, 21, 7);
#endif
return 0;

View File

@ -20,6 +20,7 @@ void test_spikes_in_ticket_8364()
{
ut_settings ignore_validity;
ignore_validity.set_test_validity(false);
ignore_validity.validity_of_sym = false;
// See: https://svn.boost.org/trac/boost/ticket/8364
//_TPolygon<T> polygon( "MULTIPOLYGON(((1031 1056,3232 1056,3232 2856,1031 2856)))" );
@ -30,44 +31,27 @@ void test_spikes_in_ticket_8364()
//polygon -= _TPolygon<T>( "MULTIPOLYGON(((1032 2556,1032 2130,1778 2556)),((3234 2580,2136 2760,1778 2556,3234 2556)))" ); USED IN STEP 4
// NOTE: polygons below are closed and clockwise
typedef typename bg::coordinate_type<P>::type ct;
typedef bg::model::polygon<P, ClockWise, Closed> polygon;
typedef bg::model::multi_polygon<polygon> multi_polygon;
// The difference of polygons below result in a spike. The spike should be there, it was also generated in ttmath,
// and (e.g.) in SQL Server. However, using int-coordinates, the spike makes the polygon invalid. Therefore it is now (since August 2013) checked and removed.
#ifdef BOOST_GEOMETRY_TEST_FAILURES
// TODO: commented working at ii/validity, this changes the area slightly, to be checked
// So using int's, the spike is removed automatically. Therefore there is one polygon less, and less points. Also area differs
test_one<polygon, multi_polygon, multi_polygon>("ticket_8364_step3",
"MULTIPOLYGON(((3232 2532,2136 2790,1032 1764,1032 1458,1032 1212,2136 2328,3232 2220,3232 1056,1031 1056,1031 2856,3232 2856,3232 2532)))",
"MULTIPOLYGON(((1032 2130,2052 2712,1032 1764,1032 2130)),((3234 2580,3234 2532,2558 2690,3234 2580)),((2558 2690,2136 2760,2052 2712,2136 2790,2558 2690)))",
2,
if_typed<ct, int>(19, 22),
if_typed<ct, int>(2775595.5, 2775256.487954), // SQL Server: 2775256.47588724
3,
-1, // don't check point-count
if_typed<ct, int>(7893.0, 7810.487954), // SQL Server: 7810.48711165739
if_typed<ct, int>(1, 5),
-1,
if_typed<ct, int>(2783349.5, 2775256.487954 + 7810.487954),
ignore_validity);
#endif
count_set(2, 3), -1, expectation_limits(2775256, 2775610), // SQL Server: 2775256.47588724
3, -1, expectation_limits(7810, 7893), // SQL Server: 7810.48711165739
count_set(2, 6), ignore_validity);
// TODO: behaviour is not good yet. It is changed at introduction of self-turns.
test_one<polygon, multi_polygon, multi_polygon>("ticket_8364_step4",
"MULTIPOLYGON(((2567 2688,2136 2790,2052 2712,1032 2130,1032 1764,1032 1458,1032 1212,2136 2328,3232 2220,3232 1056,1031 1056,1031 2856,3232 2856,3232 2580,2567 2688)))",
"MULTIPOLYGON(((1032 2556,1778 2556,1032 2130,1032 2556)),((3234 2580,3234 2556,1778 2556,2136 2760,3234 2580)))",
if_typed<ct, int>(1, 2),
if_typed<ct, int>(17, 20),
if_typed<ct, int>(2615783.5, 2616029.559567), // SQL Server: 2616029.55616044
1,
if_typed<ct, int>(9, 11),
if_typed<ct, int>(161133.5, 161054.559567), // SQL Server: 161054.560110092
if_typed<ct, int>(1, 3),
if_typed<ct, int>(25, 31),
if_typed<ct, int>(2776875.5, 2616029.559567 + 161054.559567));
count_set(1, 2), -1, expectation_limits(2615783, 2616030), // SQL Server: 2616029.55616044
1, -1, expectation_limits(161054, 161134), // SQL Server: 161054.560110092
count_set(1, 3));
}
template <typename P, bool ClockWise, bool Closed>
@ -76,7 +60,6 @@ void test_spikes_in_ticket_8365()
// See: https://svn.boost.org/trac/boost/ticket/8365
// NOTE: polygons below are closed and clockwise
typedef typename bg::coordinate_type<P>::type ct;
typedef bg::model::polygon<P, ClockWise, Closed> polygon;
typedef bg::model::multi_polygon<polygon> multi_polygon;
@ -85,13 +68,11 @@ void test_spikes_in_ticket_8365()
"MULTIPOLYGON(((5388 1560,4650 1722,3912 1884,4650 1398)),((2442 3186,1704 3348,966 2700,1704 3024)))",
2,
18,
if_typed<ct, int>(7975092.5, 7975207.6047877), // SQL Server:
expectation_limits(7975092.5, 7975207.6047877),
2,
-1,
if_typed<ct, int>(196.5, 197.1047877), // SQL Server:
if_typed<ct, int>(3, 4),
-1,
if_typed<ct, int>(7975092.5 + 196.5, 7975207.6047877 + 197.1047877));
expectation_limits(196.5, 198.5),
count_set(2, 4));
}
@ -109,6 +90,7 @@ int test_main(int, char* [])
test_spikes_in_ticket_8364<bg::model::d2::point_xy<int>, false, false>();
test_spikes_in_ticket_8365<bg::model::d2::point_xy<int>, true, true >();
test_spikes_in_ticket_8365<bg::model::d2::point_xy<int>, false, false >();
return 0;
}

View File

@ -59,20 +59,45 @@
# 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 sym_difference_validity = true;
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)
{}
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)
@ -137,7 +162,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g
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;
@ -145,8 +170,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g
bg::model::multi_polygon<OutputType> result;
if (sym)
if (dtype == difference_sym)
{
bg::sym_difference(g1, g2, result);
}
@ -167,7 +191,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g
<
G1, G2
>::type strategy_type;
if (sym)
if (dtype == difference_sym)
{
bg::sym_difference(g1, g2, result_s, strategy_type());
}
@ -191,12 +215,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g
typename bg::default_area_result<G1>::type const area = bg::area(result);
#if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST)
bool const test_validity
= sym
? (settings.sym_difference_validity || BG_IF_TEST_FAILURES)
: settings.test_validity();
if (test_validity)
if (settings.test_validity_of_diff(dtype))
{
// std::cout << bg::dsv(result) << std::endl;
typedef bg::model::multi_polygon<OutputType> result_type;
@ -218,7 +237,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g
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>
@ -287,12 +306,12 @@ template <typename OutputType, typename G1, typename G2>
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
@ -331,7 +350,7 @@ std::string test_one(std::string const& caseid,
#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, false, settings);
expected_area1, difference_a, settings);
#endif
#if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_A)
return result;
@ -339,7 +358,7 @@ std::string test_one(std::string const& caseid,
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;
@ -354,7 +373,7 @@ std::string test_one(std::string const& caseid,
expected_rings_count_s,
expected_point_count_s,
expected_area_s,
true, settings);
difference_sym, settings);
}
return result;
}
@ -383,6 +402,7 @@ std::string test_one(std::string const& caseid,
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,
@ -404,6 +424,30 @@ std::string test_one(std::string const& caseid,
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,

View File

@ -75,7 +75,7 @@ struct test_sym_difference_of_areal_geometries
PolygonOut
>(case_id, areal1, areal2,
expected_polygon_count, expected_point_count, expected_area,
true, settings);
difference_sym, settings);
}
};

View File

@ -348,7 +348,7 @@ inline void test_aa()
"MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((2 6, 2 8, 8 8, 8 5, 7 5, 7 6, 2 6)))",
"MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0)),"
"((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))",
"((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0, 5 0)))",
"MULTIPOINT()",
"MULTILINESTRING()",
"MULTIPOLYGON(((0 0,0 5,4 5,3 6,7 6,7 7,2 7,2 8,8 8,8 5,7 5,7 0,0 0),"

View File

@ -1,7 +1,7 @@
// Boost.Geometry
// Robustness Test
// Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2019-2021 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
@ -11,6 +11,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#include <iostream>
#include <iomanip>
#include <fstream>
@ -42,11 +44,22 @@ static std::string case_c[2] =
"MULTIPOLYGON(((1 1,0 1,0 3,1 3,1 1)))"
};
struct test_settings
{
bool verbose{false};
bool do_output{false};
// Settings currently not modifiable, and still giving quite some errors
double start_bound{1.0e-2};
double step_factor{50.0}; // on each side -> 100 steps per factor
int max_factor{10000};
};
template <bg::overlay_type OverlayType, typename Geometry>
bool test_overlay(std::string const& caseid,
Geometry const& g1, Geometry const& g2,
double expected_area,
bool do_output)
test_settings const& settings)
{
typedef typename boost::range_value<Geometry>::type geometry_out;
@ -62,9 +75,9 @@ bool test_overlay(std::string const& caseid,
OverlayType
> overlay;
typedef typename bg::strategy::intersection::services::default_strategy
typedef typename bg::strategies::relate::services::default_strategy
<
typename bg::cs_tag<Geometry>::type
Geometry, Geometry
>::type strategy_type;
strategy_type strategy;
@ -86,7 +99,7 @@ bool test_overlay(std::string const& caseid,
const double detected_area = bg::area(result);
if (std::fabs(detected_area - expected_area) > 0.01)
{
if (do_output)
if (settings.do_output)
{
std::cout << "ERROR: " << caseid << std::setprecision(18)
<< " detected=" << detected_area
@ -118,9 +131,9 @@ template <bg::overlay_type OverlayType, typename MultiPolygon>
std::size_t test_case(std::size_t& error_count,
std::size_t case_index, std::size_t i, std::size_t j,
std::size_t min_vertex_index, std::size_t max_vertex_index,
double x, double y, double expectation,
double offset_x, double offset_y, double expectation,
MultiPolygon const& poly1, MultiPolygon const& poly2,
bool do_output)
test_settings const settings)
{
std::size_t n = 0;
for (std::size_t k = min_vertex_index; k <= max_vertex_index; k++, ++n)
@ -130,21 +143,23 @@ std::size_t test_case(std::size_t& error_count,
switch (case_index)
{
case 2 :
update(bg::interior_rings(poly2_adapted.front()).front(), x, y, k);
update(bg::interior_rings(poly2_adapted.front()).front(), offset_x, offset_y, k);
break;
default :
update(bg::exterior_ring(poly2_adapted.front()), x, y, k);
update(bg::exterior_ring(poly2_adapted.front()), offset_x, offset_y, k);
break;
}
std::ostringstream out;
out << "case_" << i << "_" << j << "_" << k;
if (! test_overlay<OverlayType>(out.str(), poly1, poly2_adapted, expectation, do_output))
if (! test_overlay<OverlayType>(out.str(), poly1, poly2_adapted, expectation, settings))
{
if (error_count == 0)
if (error_count == 0 && ! settings.do_output)
{
// First failure is always reported
test_overlay<OverlayType>(out.str(), poly1, poly2_adapted, expectation, true);
test_settings adapted = settings;
adapted.do_output = true;
test_overlay<OverlayType>(out.str(), poly1, poly2_adapted, expectation, adapted);
}
error_count++;
}
@ -155,7 +170,7 @@ std::size_t test_case(std::size_t& error_count,
template <typename T, bool Clockwise, bg::overlay_type OverlayType>
std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index,
std::size_t max_vertex_index,
double expectation, bool do_output)
double expectation, test_settings const& settings)
{
typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
typedef bg::model::polygon<point_type, Clockwise> polygon;
@ -177,21 +192,25 @@ std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index,
std::size_t error_count = 0;
std::size_t n = 0;
for (double factor = 1.0; factor > 1.0e-10; factor /= 10.0)
for (int factor = 1; factor < settings.max_factor; factor *= 2)
{
std::size_t i = 0;
double const bound = 1.0e-5 * factor;
double const step = 1.0e-6 * factor;
for (double x = -bound; x <= bound; x += step, ++i)
double const bound = settings.start_bound / factor;
double const step = bound / settings.step_factor;
if (settings.verbose)
{
std::cout << "--> use " << bound << " " << step << std::endl;
}
for (double offset_x = -bound; offset_x <= bound; offset_x += step, ++i)
{
std::size_t j = 0;
for (double y = -bound; y <= bound; y += step, ++j, ++n)
for (double offset_y = -bound; offset_y <= bound; offset_y += step, ++j, ++n)
{
n += test_case<OverlayType>(error_count,
case_index, i, j,
min_vertex_index, max_vertex_index,
x, y, expectation,
poly1, poly2, do_output);
min_vertex_index, max_vertex_index,
offset_x, offset_y, expectation,
poly1, poly2, settings);
}
}
}
@ -205,22 +224,17 @@ std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index,
int test_main(int argc, char** argv)
{
typedef double coordinate_type;
BoostGeometryWriteTestConfiguration();
using coor_t = default_test_type;
const double factor = argc > 1 ? atof(argv[1]) : 2.0;
const bool do_output = argc > 2 && atol(argv[2]) == 1;
test_settings settings;
settings.do_output = argc > 2 && atol(argv[2]) == 1;
std::cout << std::endl << " -> TESTING "
<< string_from_type<coordinate_type>::name()
<< " " << factor
<< std::endl;
test_all<coordinate_type, true, bg::overlay_union>(1, 0, 3, 22.0, do_output);
test_all<coordinate_type, true, bg::overlay_union>(2, 0, 3, 73.0, do_output);
test_all<coordinate_type, true, bg::overlay_intersection>(3, 1, 2, 2.0, do_output);
test_all<coordinate_type, true, bg::overlay_union>(3, 1, 2, 14.0, do_output);
// Test three polygons, for the last test two types of intersections
test_all<coor_t, true, bg::overlay_union>(1, 0, 3, 22.0, settings);
test_all<coor_t, true, bg::overlay_union>(2, 0, 3, 73.0, settings);
test_all<coor_t, true, bg::overlay_intersection>(3, 1, 2, 2.0, settings);
test_all<coor_t, true, bg::overlay_union>(3, 1, 2, 14.0, settings);
return 0;
}
}

View File

@ -1,13 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
// NOTE: there is no randomness here. Count is to measure performance
#include <test_overlay_p_q.hpp>
@ -113,8 +117,10 @@ int main(int argc, char** argv)
("count_y", po::value<int>(&count_y)->default_value(10), "Triangle count in y-direction")
("offset", po::value<int>(&offset)->default_value(0), "Offset of second triangle in x-direction")
("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -129,6 +135,7 @@ int main(int argc, char** argv)
return 1;
}
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<default_test_type, false, false>(count, count_x, count_y, offset, settings);
@ -142,6 +149,7 @@ int main(int argc, char** argv)
test_all<default_test_type, true, false>(count, count_x, count_y, offset, settings);
}
else
#endif
{
test_all<default_test_type, true, true>(count, count_x, count_y, offset, settings);
}

View File

@ -1,13 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
#include <test_overlay_p_q.hpp>
@ -256,8 +258,10 @@ int main(int argc, char** argv)
("help", "Help message")
("multi", po::value<bool>(&multi)->default_value(false), "Multiple tangencies at one point")
("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -273,6 +277,7 @@ int main(int argc, char** argv)
}
// template par's are: CoordinateType, Clockwise, Closed
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<default_test_type, false, false>(multi, single_selftangent, settings);
@ -286,6 +291,7 @@ int main(int argc, char** argv)
test_all<default_test_type, true, false>(multi, single_selftangent, settings);
}
else
#endif
{
test_all<default_test_type, true, true>(multi, single_selftangent, settings);
}

View File

@ -1,13 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
// NOTE: there is no randomness here. Count is to measure performance
#include <test_overlay_p_q.hpp>
@ -109,12 +113,14 @@ void test_type(int count, int min_points, int max_points, T rotation, p_q_settin
template <typename T>
void test_all(std::string const& type, int count, int min_points, int max_points, T rotation, p_q_settings settings)
{
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (type == "float")
{
settings.tolerance = 1.0e-3;
test_type<float, float>(count, min_points, max_points, rotation, settings);
}
else if (type == "double")
#endif
{
test_type<double, double>(count, min_points, max_points, rotation, settings);
}
@ -130,7 +136,7 @@ int main(int argc, char** argv)
int count = 1;
//int seed = static_cast<unsigned int>(std::time(0));
std::string type = "float";
std::string type = "double";
int min_points = 9;
int max_points = 9;
bool ccw = false;
@ -140,15 +146,17 @@ int main(int argc, char** argv)
description.add_options()
("help", "Help message")
//("seed", po::value<int>(&seed), "Initialization seed for random generator")
// ("seed", po::value<int>(&seed), "Initialization seed for random generator")
("count", po::value<int>(&count)->default_value(1), "Number of tests")
("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
("min_points", po::value<int>(&min_points)->default_value(9), "Minimum number of points")
("max_points", po::value<int>(&max_points)->default_value(9), "Maximum number of points")
("rotation", po::value<double>(&rotation)->default_value(1.0e-13), "Rotation angle")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
("type", po::value<std::string>(&type)->default_value("float"), "Type (float,double)")
("type", po::value<std::string>(&type)->default_value("double"), "Type (float,double)")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;

View File

@ -1,13 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2011-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2011-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
// NOTE: there is no randomness here. Count is to measure performance
#include <test_overlay_p_q.hpp>
@ -43,9 +47,8 @@ inline void make_polygon(MultiPolygon& mp, int count_x, int count_y, int index,
}
template <typename MultiPolygon>
void test_intersects(int count_x, int count_y, int width_x, p_q_settings const& settings)
void test_intersects(int index, int count_x, int count_y, int width_x, p_q_settings const& settings)
{
MultiPolygon mp;
@ -64,6 +67,10 @@ void test_intersects(int count_x, int count_y, int width_x, p_q_settings const&
std::ostringstream filename;
filename << "intersects_"
<< string_from_type<coordinate_type>::name()
<< "_" << index
<< "_" << count_x
<< "_" << count_y
<< "_" << width_x
<< ".svg";
std::ofstream svg(filename.str().c_str());
@ -92,7 +99,7 @@ void test_all(int count, int count_x, int count_y, int width_x, p_q_settings con
for(int i = 0; i < count; i++)
{
test_intersects<multi_polygon>(count_x, count_y, width_x, settings);
test_intersects<multi_polygon>(i, count_x, count_y, width_x, settings);
}
auto const t = std::chrono::high_resolution_clock::now();
auto const elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t - t0).count();
@ -123,8 +130,10 @@ int main(int argc, char** argv)
("count_x", po::value<int>(&count_x)->default_value(10), "Triangle count in x-direction")
("count_y", po::value<int>(&count_y)->default_value(10), "Triangle count in y-direction")
("width_x", po::value<int>(&width_x)->default_value(7), "Width of triangle in x-direction")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -139,6 +148,7 @@ int main(int argc, char** argv)
return 1;
}
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<default_test_type, false, false>(count, count_x, count_y, width_x, settings);
@ -152,6 +162,7 @@ int main(int argc, char** argv)
test_all<default_test_type, true, false>(count, count_x, count_y, width_x, settings);
}
else
#endif
{
test_all<default_test_type, true, true>(count, count_x, count_y, width_x, settings);
}

View File

@ -1,13 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
#include <test_overlay_p_q.hpp>
@ -166,11 +168,13 @@ void test_type(int seed, int count, p_q_settings const& settings)
template <bool Clockwise, bool Closed>
void test_all(std::string const& type, int seed, int count, p_q_settings settings)
{
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (type == "float")
{
test_type<float, Clockwise, Closed>(seed, count, settings);
}
else if (type == "double")
#endif
{
test_type<double, Clockwise, Closed>(seed, count, settings);
}
@ -187,7 +191,7 @@ int main(int argc, char** argv)
int count = 1;
int seed = static_cast<unsigned int>(std::time(0));
std::string type = "float";
std::string type = "double";
bool ccw = false;
bool open = false;
p_q_settings settings;
@ -197,9 +201,11 @@ int main(int argc, char** argv)
("seed", po::value<int>(&seed), "Initialization seed for random generator")
("count", po::value<int>(&count)->default_value(1), "Number of tests")
("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
("type", po::value<std::string>(&type)->default_value("float"), "Type (float,double)")
("type", po::value<std::string>(&type)->default_value("double"), "Type (float,double)")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -214,6 +220,7 @@ int main(int argc, char** argv)
return 1;
}
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<false, false>(type, seed, count, settings);
@ -227,6 +234,7 @@ int main(int argc, char** argv)
test_all<true, false>(type, seed, count, settings);
}
else
#endif
{
test_all<true, true>(type, seed, count, settings);
}

View File

@ -1,13 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
#include <test_overlay_p_q.hpp>
@ -174,8 +176,10 @@ int main(int argc, char** argv)
("level", po::value<int>(&level)->default_value(3), "Level to reach (higher->slower)")
("size", po::value<int>(&field_size)->default_value(10), "Size of the field")
("form", po::value<std::string>(&form)->default_value("box"), "Form of the polygons (box, triangle)")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -193,7 +197,7 @@ int main(int argc, char** argv)
bool triangular = form != "box";
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<default_test_type, false, false>(seed, count, field_size, level, triangular, settings);
@ -207,6 +211,7 @@ int main(int argc, char** argv)
test_all<default_test_type, true, false>(seed, count, field_size, level, triangular, settings);
}
else
#endif
{
test_all<default_test_type, true, true>(seed, count, field_size, level, triangular, settings);
}

View File

@ -1,13 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 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)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
#include <test_overlay_p_q.hpp>
@ -98,8 +100,10 @@ int main(int argc, char** argv)
("count", po::value<int>(&count)->default_value(1), "Number of tests")
("point_count", po::value<int>(&point_count)->default_value(1), "Number of points in the star")
("diff", po::value<bool>(&settings.also_difference)->default_value(false), "Include testing on difference")
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
("ccw", po::value<bool>(&ccw)->default_value(false), "Counter clockwise polygons")
("open", po::value<bool>(&open)->default_value(false), "Open polygons")
#endif
("wkt", po::value<bool>(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests")
("svg", po::value<bool>(&settings.svg)->default_value(false), "Create a SVG for all tests")
;
@ -117,7 +121,7 @@ int main(int argc, char** argv)
int star_point_count = point_count * 2 + 1;
int comb_comb_count = point_count;
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
if (ccw && open)
{
test_all<default_test_type, false, false>(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings);
@ -131,6 +135,7 @@ int main(int argc, char** argv)
test_all<default_test_type, true, false>(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings);
}
else
#endif
{
test_all<default_test_type, true, true>(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings);
}

View File

@ -1,7 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
@ -40,21 +40,16 @@
struct p_q_settings
{
bool svg;
bool also_difference;
bool validity;
bool wkt;
bool verify_area;
double tolerance;
bool svg{false};
bool also_difference{false};
bool validity{false};
bool wkt{false};
bool verify_area{false};
double tolerance{1.0e-3};
bool verbose{false};
p_q_settings()
: svg(false)
, also_difference(false)
, validity(false)
, wkt(false)
, verify_area(false)
, tolerance(1.0e-3) // since rescaling to integer the tolerance should be less. Was originally 1.0e-6
{}
// NOTE: since rescaling to integer the tolerance is less.
// Was originally 1.0e-6 TODO: restore
};
template <typename Geometry>
@ -209,6 +204,7 @@ static bool test_overlay_p_q(std::string const& caseid,
}
bool svg = settings.svg;
bool wkt = settings.wkt;
if (wrong || settings.wkt)
{
@ -216,53 +212,66 @@ static bool test_overlay_p_q(std::string const& caseid,
{
result = false;
svg = true;
wkt = true;
}
bg::unique(out_i);
bg::unique(out_u);
std::cout
<< "type: " << string_from_type<CalculationType>::name()
<< " id: " << caseid
<< " area i: " << area_i
<< " area u: " << area_u
<< " area p: " << area_p
<< " area q: " << area_q
<< " sum: " << sum;
if (settings.also_difference)
if (settings.verbose)
{
std::cout
<< " area d1: " << area_d1
<< " area d2: " << area_d2;
}
std::cout
<< std::endl
<< std::setprecision(9)
<< " p: " << bg::wkt(p) << std::endl
<< " q: " << bg::wkt(q) << std::endl
<< " i: " << bg::wkt(out_i) << std::endl
<< " u: " << bg::wkt(out_u) << std::endl
;
<< "type: " << string_from_type<CalculationType>::name()
<< " id: " << caseid
<< " area i: " << area_i
<< " area u: " << area_u
<< " area p: " << area_p
<< " area q: " << area_q
<< " sum: " << sum;
if (settings.also_difference)
{
std::cout
<< " area d1: " << area_d1
<< " area d2: " << area_d2;
}
std::cout
<< std::endl
<< std::setprecision(9)
<< " p: " << bg::wkt(p) << std::endl
<< " q: " << bg::wkt(q) << std::endl
<< " i: " << bg::wkt(out_i) << std::endl
<< " u: " << bg::wkt(out_u) << std::endl;
}
}
if(svg)
std::string filename;
{
std::ostringstream filename;
filename << "overlay_" << caseid << "_"
std::ostringstream out;
out << "overlay_" << caseid << "_"
<< string_from_type<coordinate_type>::name();
if (!std::is_same<coordinate_type, CalculationType>::value)
{
filename << string_from_type<CalculationType>::name();
out << string_from_type<CalculationType>::name();
}
filename
out
#if defined(BOOST_GEOMETRY_USE_RESCALING)
<< "_rescaled"
<< "_rescaled"
#endif
<< ".svg";
<< ".";
filename = out.str();
}
std::ofstream svg(filename.str().c_str());
if (wkt)
{
std::ofstream stream(filename + "wkt");
// Stream input WKT's
stream << bg::wkt(p) << std::endl;
stream << bg::wkt(q) << std::endl;
// If you need the output WKT, then stream out_i and out_u
}
if (svg)
{
std::ofstream svg(filename + "svg");
bg::svg_mapper<point_type> mapper(svg, 500, 500);

View File

@ -1,7 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Robustness Test
// Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2012-2021 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015-2021.
// Modifications copyright (c) 2015-2021 Oracle and/or its affiliates.
@ -13,6 +13,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_GEOMETRY_NO_BOOST_TEST
#define BOOST_GEOMETRY_NO_ROBUSTNESS
#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
#if defined(_MSC_VER)
# pragma warning( disable : 4244 )

View File

@ -27,7 +27,7 @@
#include <boost/geometry/strategies/spherical/side_by_cross_track.hpp>
//#include <boost/geometry/strategies/spherical/side_via_plane.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/geographic/mapping_ssf.hpp>
#include <boost/geometry/strategies/geographic/side_andoyer.hpp>

View File

@ -21,6 +21,8 @@
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
@ -28,7 +30,6 @@
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
// TEMP