mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-02 08:52:10 +00:00
Merge branch 'develop' into bg-prepare
Conflicts: include/boost/geometry/extensions/algorithms/offset.hpp include/boost/geometry/extensions/gis/projections/impl/pj_init.hpp include/boost/geometry/extensions/iterators/section_iterators.hpp include/boost/geometry/extensions/nsphere/algorithms/disjoint.hpp include/boost/geometry/extensions/nsphere/algorithms/within.hpp include/boost/geometry/extensions/nsphere/nsphere.hpp include/boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp include/boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp
This commit is contained in:
@@ -18,6 +18,19 @@
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[/=================]
|
||||
[heading Boost 1.60]
|
||||
[/=================]
|
||||
|
||||
[*Solved tickets]
|
||||
|
||||
* [@https://svn.boost.org/trac/boost/ticket/11533 11533] Assert failure in rtree caused by a bug in remove() if min elements number is 1
|
||||
* [@https://svn.boost.org/trac/boost/ticket/11607 11607] Private geometry::exception::what()
|
||||
|
||||
[*Bugfixes]
|
||||
|
||||
* Fix removing values from an empty rtree - no effect and 0 returned instead of assertion failure.
|
||||
|
||||
[/=================]
|
||||
[heading Boost 1.59]
|
||||
[/=================]
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <boost/geometry/algorithms/detail/buffer/line_line_intersection.hpp>
|
||||
#include <boost/geometry/algorithms/detail/buffer/parallel_continue.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/simplify.hpp>
|
||||
|
||||
@@ -135,6 +136,7 @@ struct buffer_range
|
||||
RobustPolicy const& )
|
||||
{
|
||||
output_point_type intersection_point;
|
||||
geometry::assign_zero(intersection_point);
|
||||
|
||||
strategy::buffer::join_selector join
|
||||
= get_join_type(penultimate_input, previous_input, input);
|
||||
@@ -392,7 +394,7 @@ inline void buffer_point(Point const& point, Collection& collection,
|
||||
point_strategy.apply(point, distance_strategy, range_out);
|
||||
collection.add_piece(strategy::buffer::buffered_point, range_out, false);
|
||||
collection.set_piece_center(point);
|
||||
collection.finish_ring();
|
||||
collection.finish_ring(strategy::buffer::result_normal);
|
||||
}
|
||||
|
||||
|
||||
@@ -680,7 +682,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
|
||||
distance, side_strategy, join_strategy, end_strategy, robust_policy,
|
||||
first_p1);
|
||||
}
|
||||
collection.finish_ring();
|
||||
collection.finish_ring(code);
|
||||
}
|
||||
if (code == strategy::buffer::result_no_output && n >= 1)
|
||||
{
|
||||
@@ -740,12 +742,7 @@ private:
|
||||
join_strategy, end_strategy, point_strategy,
|
||||
robust_policy);
|
||||
|
||||
if (code == strategy::buffer::result_error_numerical)
|
||||
{
|
||||
collection.abort_ring();
|
||||
return;
|
||||
}
|
||||
collection.finish_ring(is_interior);
|
||||
collection.finish_ring(code, is_interior);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,14 +802,8 @@ public:
|
||||
join_strategy, end_strategy, point_strategy,
|
||||
robust_policy);
|
||||
|
||||
if (code == strategy::buffer::result_error_numerical)
|
||||
{
|
||||
collection.abort_ring();
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
|
||||
}
|
||||
collection.finish_ring(code, false,
|
||||
geometry::num_interior_rings(polygon) > 0u);
|
||||
}
|
||||
|
||||
apply_interior_rings(interior_rings(polygon),
|
||||
|
||||
@@ -860,8 +860,15 @@ struct buffered_piece_collection
|
||||
m_robust_policy);
|
||||
}
|
||||
|
||||
inline void finish_ring(bool is_interior = false, bool has_interiors = false)
|
||||
inline void finish_ring(strategy::buffer::result_code code,
|
||||
bool is_interior = false, bool has_interiors = false)
|
||||
{
|
||||
if (code == strategy::buffer::result_error_numerical)
|
||||
{
|
||||
abort_ring();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_first_piece_index == -1)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2015.
|
||||
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@@ -36,7 +36,6 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland
|
||||
|
||||
// This file was modified by Oracle on 2013-2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2015.
|
||||
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
@@ -562,11 +562,12 @@ private:
|
||||
|
||||
// assert that the segment has non-negative slope
|
||||
BOOST_GEOMETRY_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
|
||||
&& geometry::get<1>(p0) < geometry::get<1>(p1))
|
||||
||
|
||||
( geometry::get<0>(p0) < geometry::get<0>(p1)
|
||||
&& geometry::get<1>(p0) <= geometry::get<1>(p1) )
|
||||
);
|
||||
&& geometry::get<1>(p0) < geometry::get<1>(p1))
|
||||
||
|
||||
( geometry::get<0>(p0) < geometry::get<0>(p1)
|
||||
&& geometry::get<1>(p0) <= geometry::get<1>(p1) )
|
||||
|| geometry::has_nan_coordinate(p0)
|
||||
|| geometry::has_nan_coordinate(p1));
|
||||
|
||||
ReturnType result(0);
|
||||
|
||||
@@ -617,8 +618,10 @@ private:
|
||||
typedef compare_less_equal<ReturnType, false> greater_equal;
|
||||
|
||||
// assert that the segment has negative slope
|
||||
BOOST_GEOMETRY_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
|
||||
&& geometry::get<1>(p0) > geometry::get<1>(p1) );
|
||||
BOOST_GEOMETRY_ASSERT( ( geometry::get<0>(p0) < geometry::get<0>(p1)
|
||||
&& geometry::get<1>(p0) > geometry::get<1>(p1) )
|
||||
|| geometry::has_nan_coordinate(p0)
|
||||
|| geometry::has_nan_coordinate(p1) );
|
||||
|
||||
ReturnType result(0);
|
||||
|
||||
@@ -665,7 +668,9 @@ public:
|
||||
PPStrategy const& pp_strategy,
|
||||
PSStrategy const& ps_strategy)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
|
||||
BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1)
|
||||
|| geometry::has_nan_coordinate(p0)
|
||||
|| geometry::has_nan_coordinate(p1) );
|
||||
|
||||
if (geometry::get<0>(p0) < geometry::get<0>(p1)
|
||||
&& geometry::get<1>(p0) > geometry::get<1>(p1))
|
||||
|
||||
113
include/boost/geometry/algorithms/detail/expand_by_epsilon.hpp
Normal file
113
include/boost/geometry/algorithms/detail/expand_by_epsilon.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Distributed under 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_ALGORITHMS_DETAIL_EXPAND_EXPAND_BY_EPSILON_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_EXPAND_BY_EPSILON_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace expand
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
template <typename> class PlusOrMinus,
|
||||
std::size_t I = 0,
|
||||
std::size_t D = dimension<Point>::value,
|
||||
bool Enable = boost::is_floating_point
|
||||
<
|
||||
typename coordinate_type<Point>::type
|
||||
>::value
|
||||
>
|
||||
struct corner_by_epsilon
|
||||
{
|
||||
static inline void apply(Point & point)
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coord_type;
|
||||
coord_type const coord = get<I>(point);
|
||||
coord_type const eps = math::scaled_epsilon(coord);
|
||||
|
||||
set<I>(point, PlusOrMinus<coord_type>()(coord, eps));
|
||||
|
||||
corner_by_epsilon<Point, PlusOrMinus, I+1>::apply(point);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
template <typename> class PlusOrMinus,
|
||||
std::size_t I,
|
||||
std::size_t D
|
||||
>
|
||||
struct corner_by_epsilon<Point, PlusOrMinus, I, D, false>
|
||||
{
|
||||
static inline void apply(Point const&) {}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
template <typename> class PlusOrMinus,
|
||||
std::size_t D,
|
||||
bool Enable
|
||||
>
|
||||
struct corner_by_epsilon<Point, PlusOrMinus, D, D, Enable>
|
||||
{
|
||||
static inline void apply(Point const&) {}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
template <typename> class PlusOrMinus,
|
||||
std::size_t D
|
||||
>
|
||||
struct corner_by_epsilon<Point, PlusOrMinus, D, D, false>
|
||||
{
|
||||
static inline void apply(Point const&) {}
|
||||
};
|
||||
|
||||
} // namespace expand
|
||||
|
||||
template <typename Box>
|
||||
inline void expand_by_epsilon(Box & box)
|
||||
{
|
||||
typedef detail::indexed_point_view<Box, min_corner> min_type;
|
||||
min_type min_point(box);
|
||||
expand::corner_by_epsilon<min_type, std::minus>::apply(min_point);
|
||||
|
||||
typedef detail::indexed_point_view<Box, max_corner> max_type;
|
||||
max_type max_point(box);
|
||||
expand::corner_by_epsilon<max_type, std::plus>::apply(max_point);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_EXPAND_BY_EPSILON_HPP
|
||||
@@ -11,6 +11,9 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POLYGON_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
#include <iostream>
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
@@ -327,7 +330,9 @@ protected:
|
||||
g.add_edge(v2, vip);
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
debug_print_complement_graph(std::cout, g);
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
if (g.has_cycles())
|
||||
{
|
||||
|
||||
@@ -51,14 +51,14 @@ class liang_barsky
|
||||
private:
|
||||
typedef model::referring_segment<Point> segment_type;
|
||||
|
||||
template <typename T>
|
||||
inline bool check_edge(T const& p, T const& q, T& t1, T& t2) const
|
||||
template <typename CoordinateType, typename CalcType>
|
||||
inline bool check_edge(CoordinateType const& p, CoordinateType const& q, CalcType& t1, CalcType& t2) const
|
||||
{
|
||||
bool visible = true;
|
||||
|
||||
if(p < 0)
|
||||
{
|
||||
T const r = q / p;
|
||||
CalcType const r = static_cast<CalcType>(q) / p;
|
||||
if (r > t2)
|
||||
visible = false;
|
||||
else if (r > t1)
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
}
|
||||
else if(p > 0)
|
||||
{
|
||||
T const r = q / p;
|
||||
CalcType const r = static_cast<CalcType>(q) / p;
|
||||
if (r < t1)
|
||||
visible = false;
|
||||
else if (r < t2)
|
||||
@@ -86,9 +86,10 @@ public:
|
||||
inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
|
||||
{
|
||||
typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
|
||||
typedef typename select_most_precise<coordinate_type, double>::type calc_type;
|
||||
|
||||
coordinate_type t1 = 0;
|
||||
coordinate_type t2 = 1;
|
||||
calc_type t1 = 0;
|
||||
calc_type t2 = 1;
|
||||
|
||||
coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
|
||||
coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/follow.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/inconsistent_turns_exception.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
@@ -35,24 +36,6 @@
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
class inconsistent_turns_exception : public geometry::exception
|
||||
{
|
||||
public:
|
||||
|
||||
inline inconsistent_turns_exception() {}
|
||||
|
||||
virtual ~inconsistent_turns_exception() throw()
|
||||
{}
|
||||
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return "Boost.Geometry Inconsistent Turns exception";
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
@@ -585,8 +585,8 @@ struct collinear : public base_turn_handler
|
||||
typename SidePolicy
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& , Point1 const& , Point1 const& ,
|
||||
Point2 const& , Point2 const& , Point2 const& ,
|
||||
Point1 const& , Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& , Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& info,
|
||||
DirInfo const& dir_info,
|
||||
@@ -623,8 +623,30 @@ struct collinear : public base_turn_handler
|
||||
{
|
||||
ui_else_iu(product == 1, ti);
|
||||
}
|
||||
|
||||
// Calculate remaining distance. If it continues collinearly it is
|
||||
// measured until the end of the next segment
|
||||
ti.operations[0].remaining_distance
|
||||
= side_p == 0
|
||||
? distance_measure(ti.point, pk)
|
||||
: distance_measure(ti.point, pj);
|
||||
ti.operations[1].remaining_distance
|
||||
= side_q == 0
|
||||
? distance_measure(ti.point, qk)
|
||||
: distance_measure(ti.point, qj);
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
static inline typename geometry::coordinate_type<Point1>::type
|
||||
distance_measure(Point1 const& a, Point2 const& b)
|
||||
{
|
||||
// TODO: use comparable distance for point-point instead - but that
|
||||
// causes currently cycling include problems
|
||||
typedef typename geometry::coordinate_type<Point1>::type ctype;
|
||||
ctype const dx = get<0>(a) - get<0>(b);
|
||||
ctype const dy = get<1>(b) - get<1>(b);
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace detail { namespace overlay {
|
||||
|
||||
enum turn_position { position_middle, position_front, position_back };
|
||||
|
||||
template <typename SegmentRatio>
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct turn_operation_linear
|
||||
: public turn_operation<SegmentRatio>
|
||||
: public turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
turn_operation_linear()
|
||||
: position(position_middle)
|
||||
|
||||
@@ -802,19 +802,19 @@ template <typename Geometry1, typename Geometry2, typename SegmentRatio,
|
||||
typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
|
||||
struct turn_operation_type
|
||||
{
|
||||
typedef overlay::turn_operation<SegmentRatio> type;
|
||||
typedef overlay::turn_operation<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
|
||||
struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, linear_tag>
|
||||
{
|
||||
typedef overlay::turn_operation_linear<SegmentRatio> type;
|
||||
typedef overlay::turn_operation_linear<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
|
||||
struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, areal_tag>
|
||||
{
|
||||
typedef overlay::turn_operation_linear<SegmentRatio> type;
|
||||
typedef overlay::turn_operation_linear<typename point_type<Geometry1>::type, SegmentRatio> type;
|
||||
};
|
||||
|
||||
}} // namespace detail::get_turns
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INCONSISTENT_TURNS_EXCEPTION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INCONSISTENT_TURNS_EXCEPTION_HPP
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
#include <boost/geometry/core/exception.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
class inconsistent_turns_exception : public geometry::exception
|
||||
{
|
||||
public:
|
||||
|
||||
inline inconsistent_turns_exception() {}
|
||||
|
||||
virtual ~inconsistent_turns_exception() throw()
|
||||
{}
|
||||
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return "Boost.Geometry Inconsistent Turns exception";
|
||||
}
|
||||
};
|
||||
|
||||
}} // boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_OVERLAY_NO_THROW
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INCONSISTENT_TURNS_EXCEPTION_HPP
|
||||
@@ -1,6 +1,11 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, 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
|
||||
@@ -39,19 +44,26 @@ struct intersection_box_box
|
||||
{
|
||||
typedef typename coordinate_type<BoxOut>::type ct;
|
||||
|
||||
ct min1 = get<min_corner, Dimension>(box1);
|
||||
ct min2 = get<min_corner, Dimension>(box2);
|
||||
ct max1 = get<max_corner, Dimension>(box1);
|
||||
ct max2 = get<max_corner, Dimension>(box2);
|
||||
ct min2 = get<min_corner, Dimension>(box2);
|
||||
|
||||
if (max1 < min2 || max2 < min1)
|
||||
if (max1 < min2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ct max2 = get<max_corner, Dimension>(box2);
|
||||
ct min1 = get<min_corner, Dimension>(box1);
|
||||
|
||||
if (max2 < min1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set dimensions of output coordinate
|
||||
set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
|
||||
set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
|
||||
|
||||
|
||||
return intersection_box_box<Dimension + 1, DimensionCount>
|
||||
::apply(box1, box2, robust_policy, box_out, strategy);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <boost/geometry/views/segment_view.hpp>
|
||||
#include <boost/geometry/views/detail/boundary_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
|
||||
@@ -175,22 +176,116 @@ template
|
||||
struct intersection_of_linestring_with_areal
|
||||
{
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
||||
template <typename Turn, typename Operation>
|
||||
static inline void debug_follow(Turn const& turn, Operation op,
|
||||
int index)
|
||||
{
|
||||
std::cout << index
|
||||
<< " at " << op.seg_id
|
||||
<< " meth: " << method_char(turn.method)
|
||||
<< " op: " << operation_char(op.operation)
|
||||
<< " vis: " << visited_char(op.visited)
|
||||
<< " of: " << operation_char(turn.operations[0].operation)
|
||||
<< operation_char(turn.operations[1].operation)
|
||||
<< " " << geometry::wkt(turn.point)
|
||||
<< std::endl;
|
||||
}
|
||||
template <typename Turn, typename Operation>
|
||||
static inline void debug_follow(Turn const& turn, Operation op,
|
||||
int index)
|
||||
{
|
||||
std::cout << index
|
||||
<< " at " << op.seg_id
|
||||
<< " meth: " << method_char(turn.method)
|
||||
<< " op: " << operation_char(op.operation)
|
||||
<< " vis: " << visited_char(op.visited)
|
||||
<< " of: " << operation_char(turn.operations[0].operation)
|
||||
<< operation_char(turn.operations[1].operation)
|
||||
<< " " << geometry::wkt(turn.point)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
static inline void debug_turn(Turn const& t, bool non_crossing)
|
||||
{
|
||||
std::cout << "checking turn @"
|
||||
<< geometry::wkt(t.point)
|
||||
<< "; " << method_char(t.method)
|
||||
<< ":" << operation_char(t.operations[0].operation)
|
||||
<< "/" << operation_char(t.operations[1].operation)
|
||||
<< "; non-crossing? "
|
||||
<< std::boolalpha << non_crossing << std::noboolalpha
|
||||
<< std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
class is_crossing_turn
|
||||
{
|
||||
// return true is the operation is intersection or blocked
|
||||
template <std::size_t Index, typename Turn>
|
||||
static inline bool has_op_i_or_b(Turn const& t)
|
||||
{
|
||||
return
|
||||
t.operations[Index].operation == overlay::operation_intersection
|
||||
||
|
||||
t.operations[Index].operation == overlay::operation_blocked;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
static inline bool has_method_crosses(Turn const& t)
|
||||
{
|
||||
return t.method == overlay::method_crosses;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
static inline bool is_cc(Turn const& t)
|
||||
{
|
||||
return
|
||||
(t.method == overlay::method_touch_interior
|
||||
||
|
||||
t.method == overlay::method_equal
|
||||
||
|
||||
t.method == overlay::method_collinear)
|
||||
&&
|
||||
t.operations[0].operation == t.operations[1].operation
|
||||
&&
|
||||
t.operations[0].operation == overlay::operation_continue
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
static inline bool has_i_or_b_ops(Turn const& t)
|
||||
{
|
||||
return
|
||||
(t.method == overlay::method_touch
|
||||
||
|
||||
t.method == overlay::method_touch_interior
|
||||
||
|
||||
t.method == overlay::method_collinear)
|
||||
&&
|
||||
t.operations[1].operation != t.operations[0].operation
|
||||
&&
|
||||
(has_op_i_or_b<0>(t) || has_op_i_or_b<1>(t));
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename Turn>
|
||||
static inline bool apply(Turn const& t)
|
||||
{
|
||||
bool const is_crossing
|
||||
= has_method_crosses(t) || is_cc(t) || has_i_or_b_ops(t);
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
||||
debug_turn(t, ! is_crossing);
|
||||
#endif
|
||||
return is_crossing;
|
||||
}
|
||||
};
|
||||
|
||||
struct is_non_crossing_turn
|
||||
{
|
||||
template <typename Turn>
|
||||
static inline bool apply(Turn const& t)
|
||||
{
|
||||
return ! is_crossing_turn::apply(t);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Turns>
|
||||
static inline bool no_crossing_turns_or_empty(Turns const& turns)
|
||||
{
|
||||
return detail::check_iterator_range
|
||||
<
|
||||
is_non_crossing_turn,
|
||||
true // allow an empty turns range
|
||||
>::apply(boost::begin(turns), boost::end(turns));
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename LineString, typename Areal,
|
||||
@@ -212,7 +307,8 @@ struct intersection_of_linestring_with_areal
|
||||
LineStringOut,
|
||||
LineString,
|
||||
Areal,
|
||||
OverlayType
|
||||
OverlayType,
|
||||
false // do not remove spikes for linear geometries
|
||||
> follower;
|
||||
|
||||
typedef typename point_type<LineStringOut>::type point_type;
|
||||
@@ -231,7 +327,7 @@ struct intersection_of_linestring_with_areal
|
||||
detail::overlay::assign_null_policy
|
||||
>(linestring, areal, robust_policy, turns, policy);
|
||||
|
||||
if (turns.empty())
|
||||
if (no_crossing_turns_or_empty(turns))
|
||||
{
|
||||
// No intersection points, it is either completely
|
||||
// inside (interior + borders)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace detail { namespace overlay
|
||||
|
||||
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct traversal_turn_operation : public turn_operation<SegmentRatio>
|
||||
struct traversal_turn_operation : public turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
enrichment_info<Point> enriched;
|
||||
visit_info visited;
|
||||
|
||||
@@ -174,7 +174,17 @@ inline bool select_next_ip(operation_type operation,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has_tp = false;
|
||||
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
Iterator
|
||||
>::value_type operation_type;
|
||||
|
||||
typename operation_type::comparable_distance_type
|
||||
max_remaining_distance = 0;
|
||||
|
||||
selected = boost::end(turn.operations);
|
||||
for (Iterator it = boost::begin(turn.operations);
|
||||
it != boost::end(turn.operations);
|
||||
@@ -206,10 +216,24 @@ inline bool select_next_ip(operation_type operation,
|
||||
)
|
||||
)
|
||||
{
|
||||
if (it->operation == operation_continue)
|
||||
{
|
||||
max_remaining_distance = it->remaining_distance;
|
||||
}
|
||||
selected = it;
|
||||
debug_traverse(turn, *it, " Candidate");
|
||||
has_tp = true;
|
||||
}
|
||||
|
||||
if (it->operation == operation_continue && has_tp)
|
||||
{
|
||||
if (it->remaining_distance > max_remaining_distance)
|
||||
{
|
||||
max_remaining_distance = it->remaining_distance;
|
||||
selected = it;
|
||||
debug_traverse(turn, *it, " Candidate override");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_tp)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -54,15 +55,19 @@ enum method_type
|
||||
The class is to be included in the turn_info class, either direct
|
||||
or a derived or similar class with more (e.g. enrichment) information.
|
||||
*/
|
||||
template <typename SegmentRatio>
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct turn_operation
|
||||
{
|
||||
operation_type operation;
|
||||
segment_identifier seg_id;
|
||||
SegmentRatio fraction;
|
||||
|
||||
typedef typename coordinate_type<Point>::type comparable_distance_type;
|
||||
comparable_distance_type remaining_distance;
|
||||
|
||||
inline turn_operation()
|
||||
: operation(operation_none)
|
||||
, remaining_distance(0)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -80,7 +85,7 @@ template
|
||||
<
|
||||
typename Point,
|
||||
typename SegmentRatio,
|
||||
typename Operation = turn_operation<SegmentRatio>,
|
||||
typename Operation = turn_operation<Point, SegmentRatio>,
|
||||
typename Container = boost::array<Operation, 2>
|
||||
>
|
||||
struct turn_info
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, 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
|
||||
@@ -12,8 +17,6 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_IS_EQUAL_OR_SPIKE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_IS_EQUAL_OR_SPIKE_HPP
|
||||
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/recalculate.hpp>
|
||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
@@ -28,6 +31,17 @@ namespace boost { namespace geometry
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <std::size_t Index, typename Point1, typename Point2>
|
||||
inline int sign_of_difference(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
return
|
||||
math::equals(geometry::get<Index>(point1), geometry::get<Index>(point2))
|
||||
?
|
||||
0
|
||||
:
|
||||
(geometry::get<Index>(point1) > geometry::get<Index>(point2) ? 1 : -1);
|
||||
}
|
||||
|
||||
// Checks if a point ("last_point") causes a spike w.r.t.
|
||||
// the specified two other points (segment_a, segment_b)
|
||||
//
|
||||
@@ -35,7 +49,9 @@ namespace detail
|
||||
// a lp b
|
||||
//
|
||||
// Above, lp generates a spike w.r.t. segment(a,b)
|
||||
// So specify last point first, then (a,b) (this is unordered, so unintuitive)
|
||||
// So specify last point first, then (a,b)
|
||||
// The segment's orientation does matter: if lp is to the right of b
|
||||
// no spike is reported
|
||||
template <typename Point1, typename Point2, typename Point3>
|
||||
static inline bool point_is_spike_or_equal(Point1 const& last_point,
|
||||
Point2 const& segment_a,
|
||||
@@ -46,29 +62,21 @@ static inline bool point_is_spike_or_equal(Point1 const& last_point,
|
||||
typename cs_tag<Point1>::type
|
||||
>::type side_strategy;
|
||||
|
||||
typedef Point1 vector_type;
|
||||
|
||||
int const side = side_strategy::apply(last_point, segment_a, segment_b);
|
||||
if (side == 0)
|
||||
{
|
||||
// Last point is collinear w.r.t previous segment.
|
||||
// Check if it is equal
|
||||
vector_type diff1;
|
||||
conversion::convert_point_to_point(last_point, diff1);
|
||||
geometry::subtract_point(diff1, segment_b);
|
||||
int const sgn_x1 = math::sign(geometry::get<0>(diff1));
|
||||
int const sgn_y1 = math::sign(geometry::get<1>(diff1));
|
||||
int const sgn_x1 = sign_of_difference<0>(last_point, segment_b);
|
||||
int const sgn_y1 = sign_of_difference<1>(last_point, segment_b);
|
||||
if (sgn_x1 == 0 && sgn_y1 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it moves forward
|
||||
vector_type diff2;
|
||||
conversion::convert_point_to_point(segment_b, diff2);
|
||||
geometry::subtract_point(diff2, segment_a);
|
||||
int const sgn_x2 = math::sign(geometry::get<0>(diff2));
|
||||
int const sgn_y2 = math::sign(geometry::get<1>(diff2));
|
||||
int const sgn_x2 = sign_of_difference<0>(segment_b, segment_a);
|
||||
int const sgn_y2 = sign_of_difference<1>(segment_b, segment_a);
|
||||
|
||||
return sgn_x1 != sgn_x2 || sgn_y1 != sgn_y2;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ struct areal_areal
|
||||
template <std::size_t OpId, typename Turn>
|
||||
inline void per_turn(Turn const& turn)
|
||||
{
|
||||
static const std::size_t other_op_id = (OpId + 1) % 2;
|
||||
//static const std::size_t other_op_id = (OpId + 1) % 2;
|
||||
static const bool transpose_result = OpId != 0;
|
||||
|
||||
overlay::operation_type const op = turn.operations[OpId].operation;
|
||||
@@ -357,11 +357,14 @@ struct areal_areal
|
||||
else if ( op == overlay::operation_intersection )
|
||||
{
|
||||
// ignore i/i
|
||||
if ( turn.operations[other_op_id].operation != overlay::operation_intersection )
|
||||
/*if ( turn.operations[other_op_id].operation != overlay::operation_intersection )
|
||||
{
|
||||
update<interior, interior, '2', transpose_result>(m_result);
|
||||
// not correct e.g. for G1 touching G2 in a point where a hole is touching the exterior ring
|
||||
// in this case 2 turns i/... and u/u will be generated for this IP
|
||||
//update<interior, interior, '2', transpose_result>(m_result);
|
||||
|
||||
//update<boundary, interior, '1', transpose_result>(m_result);
|
||||
}
|
||||
}*/
|
||||
|
||||
update<boundary, boundary, '0', transpose_result>(m_result);
|
||||
}
|
||||
@@ -473,8 +476,11 @@ struct areal_areal
|
||||
// ignore i/i
|
||||
if ( it->operations[other_op_id].operation != overlay::operation_intersection )
|
||||
{
|
||||
// already set in interrupt policy
|
||||
// this was set in the interrupt policy but it was wrong
|
||||
// also here it's wrong since it may be a fake entry point
|
||||
//update<interior, interior, '2', transpose_result>(result);
|
||||
|
||||
// already set in interrupt policy
|
||||
//update<boundary, boundary, '0', transpose_result>(result);
|
||||
m_enter_detected = true;
|
||||
}
|
||||
@@ -523,6 +529,7 @@ struct areal_areal
|
||||
template <typename Result>
|
||||
static inline void update_enter(Result & result)
|
||||
{
|
||||
update<interior, interior, '2', transpose_result>(result);
|
||||
update<boundary, interior, '1', transpose_result>(result);
|
||||
update<exterior, interior, '2', transpose_result>(result);
|
||||
}
|
||||
@@ -574,6 +581,7 @@ struct areal_areal
|
||||
, m_flags(0)
|
||||
{
|
||||
// check which relations must be analysed
|
||||
// NOTE: 1 and 4 could probably be connected
|
||||
|
||||
if ( ! may_update<interior, interior, '2', transpose_result>(m_result) )
|
||||
{
|
||||
@@ -662,21 +670,12 @@ struct areal_areal
|
||||
if ( it->operations[0].operation == overlay::operation_intersection
|
||||
&& it->operations[1].operation == overlay::operation_intersection )
|
||||
{
|
||||
// ignore exterior ring
|
||||
if ( it->operations[OpId].seg_id.ring_index >= 0 )
|
||||
{
|
||||
found_ii = true;
|
||||
}
|
||||
found_ii = true;
|
||||
}
|
||||
else if ( it->operations[0].operation == overlay::operation_union
|
||||
&& it->operations[1].operation == overlay::operation_union )
|
||||
{
|
||||
// ignore if u/u is for holes
|
||||
//if ( it->operations[OpId].seg_id.ring_index >= 0
|
||||
// && it->operations[other_id].seg_id.ring_index >= 0 )
|
||||
{
|
||||
found_uu = true;
|
||||
}
|
||||
found_uu = true;
|
||||
}
|
||||
else // ignore
|
||||
{
|
||||
@@ -687,8 +686,11 @@ struct areal_areal
|
||||
// only i/i was generated for this ring
|
||||
if ( found_ii )
|
||||
{
|
||||
//update<interior, interior, '0', transpose_result>(m_result);
|
||||
//update<boundary, boundary, '0', transpose_result>(m_result);
|
||||
update<interior, interior, '2', transpose_result>(m_result);
|
||||
m_flags |= 1;
|
||||
|
||||
//update<boundary, boundary, '0', transpose_result>(m_result);
|
||||
|
||||
update<boundary, interior, '1', transpose_result>(m_result);
|
||||
update<exterior, interior, '2', transpose_result>(m_result);
|
||||
m_flags |= 4;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
|
||||
#include <boost/geometry/util/has_nan_coordinate.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -90,19 +92,43 @@ public:
|
||||
for ( multi_iterator it = boost::begin(geometry) ;
|
||||
it != boost::end(geometry) ; ++ it )
|
||||
{
|
||||
typename boost::range_reference<Geometry const>::type
|
||||
ls = *it;
|
||||
|
||||
// empty or point - no boundary
|
||||
if ( boost::size(*it) < 2 )
|
||||
if (boost::size(ls) < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
typedef typename boost::range_reference
|
||||
<
|
||||
typename boost::range_value<Geometry const>::type const
|
||||
>::type point_reference;
|
||||
|
||||
point_reference front_pt = range::front(ls);
|
||||
point_reference back_pt = range::back(ls);
|
||||
|
||||
// linear ring or point - no boundary
|
||||
if ( equals::equals_point_point(range::front(*it), range::back(*it)) )
|
||||
continue;
|
||||
|
||||
boundary_points.push_back(range::front(*it));
|
||||
boundary_points.push_back(range::back(*it));
|
||||
if (! equals::equals_point_point(front_pt, back_pt))
|
||||
{
|
||||
// do not add points containing NaN coordinates
|
||||
// because they cannot be reasonably compared, e.g. with MSVC
|
||||
// an assertion failure is reported in std::equal_range()
|
||||
if (! geometry::has_nan_coordinate(front_pt))
|
||||
{
|
||||
boundary_points.push_back(front_pt);
|
||||
}
|
||||
if (! geometry::has_nan_coordinate(back_pt))
|
||||
{
|
||||
boundary_points.push_back(back_pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(boundary_points.begin(), boundary_points.end(), geometry::less<point_type>());
|
||||
std::sort(boundary_points.begin(),
|
||||
boundary_points.end(),
|
||||
geometry::less<point_type>());
|
||||
|
||||
is_filled = true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/util/has_nan_coordinate.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
@@ -106,20 +108,42 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
typedef typename boost::range_iterator<MultiLinestring const>::type ls_iterator;
|
||||
for ( ls_iterator it = boost::begin(mls) ; it != boost::end(mls) ; ++it )
|
||||
{
|
||||
std::size_t count = boost::size(*it);
|
||||
typename boost::range_reference<MultiLinestring const>::type
|
||||
ls = *it;
|
||||
|
||||
if ( count > 0 )
|
||||
std::size_t count = boost::size(ls);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
has_interior = true;
|
||||
}
|
||||
|
||||
if ( count > 1 )
|
||||
if (count > 1)
|
||||
{
|
||||
typedef typename boost::range_reference
|
||||
<
|
||||
typename boost::range_value<MultiLinestring const>::type const
|
||||
>::type point_reference;
|
||||
|
||||
point_reference front_pt = range::front(ls);
|
||||
point_reference back_pt = range::back(ls);
|
||||
|
||||
// don't store boundaries of linear rings, this doesn't change anything
|
||||
if ( ! equals::equals_point_point(range::front(*it), range::back(*it)) )
|
||||
if (! equals::equals_point_point(front_pt, back_pt))
|
||||
{
|
||||
endpoints.push_back(range::front(*it));
|
||||
endpoints.push_back(range::back(*it));
|
||||
// do not add points containing NaN coordinates
|
||||
// because they cannot be reasonably compared, e.g. with MSVC
|
||||
// an assertion failure is reported in std::equal_range()
|
||||
// NOTE: currently ignoring_counter calling std::equal_range()
|
||||
// is not used anywhere in the code, still it's safer this way
|
||||
if (! geometry::has_nan_coordinate(front_pt))
|
||||
{
|
||||
endpoints.push_back(front_pt);
|
||||
}
|
||||
if (! geometry::has_nan_coordinate(back_pt))
|
||||
{
|
||||
endpoints.push_back(back_pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ struct get_turns
|
||||
template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
|
||||
struct op_to_int
|
||||
{
|
||||
template <typename SegmentRatio>
|
||||
inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
|
||||
template <typename Operation>
|
||||
inline int operator()(Operation const& op) const
|
||||
{
|
||||
switch(op.operation)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, 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)
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -599,19 +601,18 @@ inline void enlarge_sections(Sections& sections)
|
||||
// Reason: turns might, rarely, be missed otherwise (case: "buffer_mp1")
|
||||
// Drawback: not really, range is now completely inside the section. Section is a tiny bit too large,
|
||||
// which might cause (a small number) of more comparisons
|
||||
// TODO: make dimension-agnostic
|
||||
|
||||
// NOTE: above is old comment to the not used code expanding the Boxes by relaxed_epsilon(10)
|
||||
|
||||
// Enlarge sections by scaled epsilon, this should be consistent with math::equals().
|
||||
// Points and Segments are equal-compared WRT machine epsilon, but Boxes aren't
|
||||
// Enlarging Boxes ensures that they correspond to the bound objects,
|
||||
// Segments in this case, since Sections are collections of Segments.
|
||||
for (typename boost::range_iterator<Sections>::type it = boost::begin(sections);
|
||||
it != boost::end(sections);
|
||||
++it)
|
||||
{
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
typedef typename section_type::box_type box_type;
|
||||
typedef typename geometry::coordinate_type<box_type>::type coordinate_type;
|
||||
coordinate_type const reps = math::relaxed_epsilon(10.0);
|
||||
geometry::set<0, 0>(it->bounding_box, geometry::get<0, 0>(it->bounding_box) - reps);
|
||||
geometry::set<0, 1>(it->bounding_box, geometry::get<0, 1>(it->bounding_box) - reps);
|
||||
geometry::set<1, 0>(it->bounding_box, geometry::get<1, 0>(it->bounding_box) + reps);
|
||||
geometry::set<1, 1>(it->bounding_box, geometry::get<1, 1>(it->bounding_box) + reps);
|
||||
detail::expand_by_epsilon(it->bounding_box);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -802,6 +803,8 @@ inline void sectionalize(Geometry const& geometry,
|
||||
Reverse,
|
||||
DimensionVector
|
||||
>::apply(geometry, robust_policy, sections, ring_id, max_count);
|
||||
|
||||
detail::sectionalize::enlarge_sections(sections);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// 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) 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 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014, 2015.
|
||||
// Modifications copyright (c) 2014-2015 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.
|
||||
@@ -14,8 +16,6 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -83,6 +84,7 @@ struct box_box_loop
|
||||
{
|
||||
one_in_two = false;
|
||||
}
|
||||
|
||||
// Same other way round
|
||||
if (min2 < min1 || max2 > max1)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// 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.
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014, 2015.
|
||||
// Modifications copyright (c) 2013-2015, 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.
|
||||
@@ -15,8 +17,6 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -70,12 +71,12 @@ struct box_box_loop
|
||||
// TODO assert or exception?
|
||||
//BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
|
||||
|
||||
if ( max1 < min2 || max2 < min1 )
|
||||
if (max1 < min2 || max2 < min1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( max1 == min2 || max2 == min1 )
|
||||
if (max1 == min2 || max2 == min1)
|
||||
{
|
||||
touch = true;
|
||||
}
|
||||
@@ -385,6 +386,16 @@ struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, true>
|
||||
|
||||
template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
|
||||
struct touches<Areal1, Areal2, Tag1, Tag2, areal_tag, areal_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Areal1,
|
||||
Areal2
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Areal1, typename Areal2>
|
||||
struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false>
|
||||
: detail::touches::areal_areal<Areal1, Areal2>
|
||||
{};
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace boost { namespace geometry
|
||||
*/
|
||||
class exception : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return "Boost.Geometry exception";
|
||||
|
||||
35
include/boost/geometry/index/detail/is_bounding_geometry.hpp
Normal file
35
include/boost/geometry/index/detail/is_bounding_geometry.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Boost.Geometry Index
|
||||
//
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// 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_INDEX_DETAIL_IS_BOUNDING_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_IS_BOUNDING_GEOMETRY_HPP
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type
|
||||
>
|
||||
struct is_bounding_geometry
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct is_bounding_geometry<Box, box_tag>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}}}} // namespave boost::geometry::index::detail
|
||||
|
||||
#endif // BOOST_GEOMETRY_INDEX_DETAIL_IS_BOUNDING_GEOMETRY_HPP
|
||||
47
include/boost/geometry/index/detail/is_indexable.hpp
Normal file
47
include/boost/geometry/index/detail/is_indexable.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// Boost.Geometry Index
|
||||
//
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// 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_INDEX_DETAIL_IS_INDEXABLE_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_IS_INDEXABLE_HPP
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type
|
||||
>
|
||||
struct is_indexable
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct is_indexable<Point, geometry::point_tag>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct is_indexable<Box, geometry::box_tag>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename Segment>
|
||||
struct is_indexable<Segment, geometry::segment_tag>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}}}} // namespave boost::geometry::index::detail
|
||||
|
||||
#endif // BOOST_GEOMETRY_INDEX_DETAIL_IS_INDEXABLE_HPP
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
|
||||
#include <boost/geometry/index/detail/is_bounding_geometry.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
@@ -45,8 +46,16 @@ template <typename Box, typename FwdIter, typename Translator>
|
||||
inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
|
||||
{
|
||||
Box result;
|
||||
|
||||
// Only here to suppress 'uninitialized local variable used' warning
|
||||
// until the suggestion below is not implemented
|
||||
geometry::assign_inverse(result);
|
||||
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(first != last, "non-empty range required");
|
||||
//BOOST_GEOMETRY_INDEX_ASSERT(first != last, "non-empty range required");
|
||||
// NOTE: this is not elegant temporary solution,
|
||||
// reference to box could be passed as parameter and bool returned
|
||||
if ( first == last )
|
||||
return result;
|
||||
|
||||
detail::bounds(element_indexable(*first, tr), result);
|
||||
++first;
|
||||
@@ -57,6 +66,35 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Enlarge bounds of a leaf node WRT epsilon if needed.
|
||||
// It's because Points and Segments are compared WRT machine epsilon.
|
||||
// This ensures that leafs bounds correspond to the stored elements.
|
||||
// NOTE: this is done only if the Indexable is not a Box
|
||||
// in the future don't do it also for NSphere
|
||||
template <typename Box, typename FwdIter, typename Translator>
|
||||
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIter>::value_type element_type;
|
||||
BOOST_MPL_ASSERT_MSG((is_leaf_element<element_type>::value),
|
||||
SHOULD_BE_CALLED_ONLY_FOR_LEAF_ELEMENTS,
|
||||
(element_type));
|
||||
|
||||
Box result = elements_box<Box>(first, last, tr);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
|
||||
if (BOOST_GEOMETRY_CONDITION((
|
||||
! is_bounding_geometry
|
||||
<
|
||||
typename indexable_type<Translator>::type
|
||||
>::value)))
|
||||
{
|
||||
geometry::detail::expand_by_epsilon(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// destroys subtree if the element is internal node's element
|
||||
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct destroy_element
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree node elements access
|
||||
//
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -12,6 +12,7 @@
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP
|
||||
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
#include <boost/geometry/index/detail/varray.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
|
||||
|
||||
@@ -36,6 +37,20 @@ struct element_indexable_type<
|
||||
typedef First type;
|
||||
};
|
||||
|
||||
// is leaf element
|
||||
|
||||
template <typename Element>
|
||||
struct is_leaf_element
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename First, typename Pointer>
|
||||
struct is_leaf_element< rtree::ptr_pair<First, Pointer> >
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
// element's indexable getter
|
||||
|
||||
template <typename Element, typename Translator>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
|
||||
|
||||
namespace pack_utils {
|
||||
@@ -214,6 +216,11 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void expand_by_epsilon()
|
||||
{
|
||||
geometry::detail::expand_by_epsilon(m_box);
|
||||
}
|
||||
|
||||
BoxType const& get() const
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(m_initialized, "uninitialized envelope accessed");
|
||||
@@ -264,6 +271,23 @@ private:
|
||||
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
|
||||
// Enlarge bounds of a leaf node.
|
||||
// It's because Points and Segments are compared WRT machine epsilon
|
||||
// This ensures that leafs bounds correspond to the stored elements
|
||||
// NOTE: this is done only if the Indexable is a different kind of Geometry
|
||||
// than the bounds (only Box for now). Spatial predicates are checked
|
||||
// the same way for Geometry of the same kind.
|
||||
if ( BOOST_GEOMETRY_CONDITION((
|
||||
! index::detail::is_bounding_geometry
|
||||
<
|
||||
typename indexable_type<Translator>::type
|
||||
>::value )) )
|
||||
{
|
||||
elements_box.expand_by_epsilon();
|
||||
}
|
||||
#endif
|
||||
|
||||
auto_remover.release();
|
||||
return internal_element(elements_box.get(), n);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree R*-tree insert algorithm implementation
|
||||
//
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -231,16 +231,28 @@ struct level_insert_base
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
inline void recalculate_aabb_if_necessary(Node &n) const
|
||||
inline void recalculate_aabb_if_necessary(Node const& n) const
|
||||
{
|
||||
if ( !result_elements.empty() && !base::m_traverse_data.current_is_root() )
|
||||
{
|
||||
// calulate node's new box
|
||||
base::m_traverse_data.current_element().first =
|
||||
elements_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
|
||||
recalculate_aabb(n);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
inline void recalculate_aabb(Node const& n) const
|
||||
{
|
||||
base::m_traverse_data.current_element().first =
|
||||
elements_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
|
||||
}
|
||||
|
||||
inline void recalculate_aabb(leaf const& n) const
|
||||
{
|
||||
base::m_traverse_data.current_element().first =
|
||||
values_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
|
||||
}
|
||||
|
||||
size_type result_relative_level;
|
||||
result_elements_type result_elements;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree boxes validating visitor implementation
|
||||
//
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -60,13 +60,7 @@ public:
|
||||
m_box = box_bckup;
|
||||
m_is_root = is_root_bckup;
|
||||
|
||||
Box box_exp;
|
||||
geometry::convert(elements.front().first, box_exp);
|
||||
for( typename elements_type::const_iterator it = elements.begin() + 1;
|
||||
it != elements.end() ; ++it)
|
||||
{
|
||||
geometry::expand(box_exp, it->first);
|
||||
}
|
||||
Box box_exp = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr);
|
||||
|
||||
if ( m_exact_match )
|
||||
result = m_is_root || geometry::equals(box_exp, m_box);
|
||||
@@ -88,15 +82,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
Box box_exp;
|
||||
geometry::convert(
|
||||
index::detail::return_ref_or_bounds(m_tr(elements.front())),
|
||||
box_exp);
|
||||
for(typename elements_type::const_iterator it = elements.begin() + 1;
|
||||
it != elements.end() ; ++it)
|
||||
{
|
||||
geometry::expand(box_exp, m_tr(*it));
|
||||
}
|
||||
Box box_exp = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr);
|
||||
|
||||
if ( m_exact_match )
|
||||
result = geometry::equals(box_exp, m_box);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree node children box calculating visitor implementation
|
||||
//
|
||||
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
typedef typename rtree::elements_type<leaf>::type elements_type;
|
||||
elements_type const& elements = rtree::elements(n);
|
||||
|
||||
m_result = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr);
|
||||
m_result = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
@@ -262,6 +267,29 @@ protected:
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(0 != m_root_node, "there is no root node");
|
||||
// TODO
|
||||
// assert - check if Box is correct
|
||||
|
||||
// When a value is inserted, during the tree traversal bounds of nodes
|
||||
// on a path from the root to a leaf must be expanded. So prepare
|
||||
// a bounding object at the beginning to not do it later for each node.
|
||||
// NOTE: This is actually only needed because conditionally the bounding
|
||||
// object may be expanded below. Otherwise the indexable could be
|
||||
// directly used instead
|
||||
index::detail::bounds(rtree::element_indexable(m_element, m_translator), m_element_bounds);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
|
||||
// Enlarge it in case if it's not bounding geometry type.
|
||||
// It's because Points and Segments are compared WRT machine epsilon
|
||||
// This ensures that leafs bounds correspond to the stored elements
|
||||
if (BOOST_GEOMETRY_CONDITION((
|
||||
boost::is_same<Element, Value>::value
|
||||
&& ! index::detail::is_bounding_geometry
|
||||
<
|
||||
typename indexable_type<Translator>::type
|
||||
>::value )) )
|
||||
{
|
||||
geometry::detail::expand_by_epsilon(m_element_bounds);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
@@ -274,7 +302,8 @@ protected:
|
||||
// expand the node to contain value
|
||||
geometry::expand(
|
||||
rtree::elements(n)[choosen_node_index].first,
|
||||
rtree::element_indexable(m_element, m_translator));
|
||||
m_element_bounds
|
||||
/*rtree::element_indexable(m_element, m_translator)*/);
|
||||
|
||||
// next traversing step
|
||||
traverse_apply_visitor(visitor, n, choosen_node_index); // MAY THROW (V, E: alloc, copy, N:alloc)
|
||||
@@ -342,6 +371,22 @@ protected:
|
||||
// for exception safety
|
||||
subtree_destroyer additional_node_ptr(additional_nodes[0].second, m_allocators);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
|
||||
// Enlarge bounds of a leaf node.
|
||||
// It's because Points and Segments are compared WRT machine epsilon
|
||||
// This ensures that leafs' bounds correspond to the stored elements.
|
||||
if (BOOST_GEOMETRY_CONDITION((
|
||||
boost::is_same<Node, leaf>::value
|
||||
&& ! index::detail::is_bounding_geometry
|
||||
<
|
||||
typename indexable_type<Translator>::type
|
||||
>::value )))
|
||||
{
|
||||
geometry::detail::expand_by_epsilon(n_box);
|
||||
geometry::detail::expand_by_epsilon(additional_nodes[0].first);
|
||||
}
|
||||
#endif
|
||||
|
||||
// node is not the root - just add the new node
|
||||
if ( !m_traverse_data.current_is_root() )
|
||||
{
|
||||
@@ -383,6 +428,7 @@ protected:
|
||||
// TODO: awulkiew - implement dispatchable split::apply to enable additional nodes creation
|
||||
|
||||
Element const& m_element;
|
||||
Box m_element_bounds;
|
||||
parameters_type const& m_parameters;
|
||||
Translator const& m_translator;
|
||||
size_type const m_relative_level;
|
||||
|
||||
@@ -97,6 +97,9 @@ public:
|
||||
size_type relative_level = m_leafs_level - m_current_level;
|
||||
|
||||
// move node to the container - store node's relative level as well and return new underflow state
|
||||
// NOTE: if the min elements number is 1, then after an underflow
|
||||
// here the child elements count is 0, so it's not required to store this node,
|
||||
// it could just be destroyed
|
||||
m_is_underflow = store_underflowed_node(elements, underfl_el_it, relative_level); // MAY THROW (E: alloc, copy)
|
||||
}
|
||||
|
||||
@@ -120,10 +123,16 @@ public:
|
||||
reinsert_removed_nodes_elements(); // MAY THROW (V, E: alloc, copy, N: alloc)
|
||||
|
||||
// shorten the tree
|
||||
if ( rtree::elements(n).size() == 1 )
|
||||
// NOTE: if the min elements number is 1, then after underflow
|
||||
// here the number of elements may be equal to 0
|
||||
// this can occur only for the last removed element
|
||||
if ( rtree::elements(n).size() <= 1 )
|
||||
{
|
||||
node_pointer root_to_destroy = m_root_node;
|
||||
m_root_node = rtree::elements(n)[0].second;
|
||||
if ( rtree::elements(n).size() == 0 )
|
||||
m_root_node = 0;
|
||||
else
|
||||
m_root_node = rtree::elements(n)[0].second;
|
||||
--m_leafs_level;
|
||||
|
||||
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, root_to_destroy);
|
||||
@@ -161,7 +170,7 @@ public:
|
||||
if ( 0 != m_parent )
|
||||
{
|
||||
rtree::elements(*m_parent)[m_current_child_index].first
|
||||
= rtree::elements_box<Box>(elements.begin(), elements.end(), m_translator);
|
||||
= rtree::values_box<Box>(elements.begin(), elements.end(), m_translator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost.Geometry Index
|
||||
//
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -11,31 +11,10 @@
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/is_indexable.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
template <typename Geometry, typename GeometryTag>
|
||||
struct is_indexable_impl { static const bool value = false; };
|
||||
|
||||
template <typename Point>
|
||||
struct is_indexable_impl<Point, geometry::point_tag> { static const bool value = true; };
|
||||
|
||||
template <typename Box>
|
||||
struct is_indexable_impl<Box, geometry::box_tag> { static const bool value = true; };
|
||||
|
||||
template <typename Segment>
|
||||
struct is_indexable_impl<Segment, geometry::segment_tag> { static const bool value = true; };
|
||||
|
||||
template <typename Indexable>
|
||||
struct is_indexable
|
||||
{
|
||||
static const bool value =
|
||||
is_indexable_impl
|
||||
<
|
||||
Indexable,
|
||||
typename geometry::tag<Indexable>::type
|
||||
>::value;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief The function object extracting Indexable from Value.
|
||||
|
||||
|
||||
@@ -627,6 +627,9 @@ public:
|
||||
template <typename ConvertibleOrRange>
|
||||
inline void insert(ConvertibleOrRange const& conv_or_rng)
|
||||
{
|
||||
if ( !m_members.root )
|
||||
this->raw_create();
|
||||
|
||||
typedef boost::mpl::bool_
|
||||
<
|
||||
boost::is_convertible<ConvertibleOrRange, value_type>::value
|
||||
@@ -657,6 +660,9 @@ public:
|
||||
*/
|
||||
inline size_type remove(value_type const& value)
|
||||
{
|
||||
if ( !m_members.root )
|
||||
return 0;
|
||||
|
||||
return this->raw_remove(value);
|
||||
}
|
||||
|
||||
@@ -687,6 +693,10 @@ public:
|
||||
inline size_type remove(Iterator first, Iterator last)
|
||||
{
|
||||
size_type result = 0;
|
||||
|
||||
if ( !m_members.root )
|
||||
return result;
|
||||
|
||||
for ( ; first != last ; ++first )
|
||||
result += this->raw_remove(*first);
|
||||
return result;
|
||||
@@ -716,6 +726,9 @@ public:
|
||||
template <typename ConvertibleOrRange>
|
||||
inline size_type remove(ConvertibleOrRange const& conv_or_rng)
|
||||
{
|
||||
if ( !m_members.root )
|
||||
return 0;
|
||||
|
||||
typedef boost::mpl::bool_
|
||||
<
|
||||
boost::is_convertible<ConvertibleOrRange, value_type>::value
|
||||
@@ -1279,6 +1292,9 @@ public:
|
||||
template <typename ValueOrIndexable>
|
||||
size_type count(ValueOrIndexable const& vori) const
|
||||
{
|
||||
if ( !m_members.root )
|
||||
return 0;
|
||||
|
||||
// the input should be convertible to Value or Indexable type
|
||||
|
||||
enum { as_val = 0, as_ind, dont_know };
|
||||
@@ -1570,9 +1586,6 @@ private:
|
||||
inline void insert_dispatch(ValueConvertible const& val_conv,
|
||||
boost::mpl::bool_<true> const& /*is_convertible*/)
|
||||
{
|
||||
if ( !m_members.root )
|
||||
this->raw_create();
|
||||
|
||||
this->raw_insert(val_conv);
|
||||
}
|
||||
|
||||
@@ -1592,9 +1605,6 @@ private:
|
||||
PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
|
||||
(Range));
|
||||
|
||||
if ( !m_members.root )
|
||||
this->raw_create();
|
||||
|
||||
typedef typename boost::range_const_iterator<Range>::type It;
|
||||
for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
|
||||
this->raw_insert(*it);
|
||||
@@ -1664,6 +1674,8 @@ private:
|
||||
template <typename Predicates, typename OutIter>
|
||||
size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_distance_predicate*/) const
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
||||
|
||||
static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
|
||||
detail::rtree::visitors::distance_query<
|
||||
value_type,
|
||||
@@ -1690,8 +1702,7 @@ private:
|
||||
template <typename ValueOrIndexable>
|
||||
size_type raw_count(ValueOrIndexable const& vori) const
|
||||
{
|
||||
if ( !m_members.root )
|
||||
return 0;
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
||||
|
||||
detail::rtree::visitors::count
|
||||
<
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// 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.
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, 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.
|
||||
@@ -32,10 +37,10 @@ namespace within
|
||||
struct box_within_range
|
||||
{
|
||||
template <typename BoxContainedValue, typename BoxContainingValue>
|
||||
static inline bool apply(BoxContainedValue const& bed_min
|
||||
, BoxContainedValue const& bed_max
|
||||
, BoxContainingValue const& bing_min
|
||||
, BoxContainingValue const& bing_max)
|
||||
static inline bool apply(BoxContainedValue const& bed_min,
|
||||
BoxContainedValue const& bed_max,
|
||||
BoxContainingValue const& bing_min,
|
||||
BoxContainingValue const& bing_max)
|
||||
{
|
||||
return bing_min <= bed_min && bed_max <= bing_max // contained in containing
|
||||
&& bed_min < bed_max; // interiors overlap
|
||||
@@ -46,10 +51,10 @@ struct box_within_range
|
||||
struct box_covered_by_range
|
||||
{
|
||||
template <typename BoxContainedValue, typename BoxContainingValue>
|
||||
static inline bool apply(BoxContainedValue const& bed_min
|
||||
, BoxContainedValue const& bed_max
|
||||
, BoxContainingValue const& bing_min
|
||||
, BoxContainingValue const& bing_max)
|
||||
static inline bool apply(BoxContainedValue const& bed_min,
|
||||
BoxContainedValue const& bed_max,
|
||||
BoxContainingValue const& bing_min,
|
||||
BoxContainingValue const& bing_max)
|
||||
{
|
||||
return bed_min >= bing_min && bed_max <= bing_max;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// 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) 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.
|
||||
// Modifications copyright (c) 2015, 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.
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
// Remove the ublas checking, otherwise the inverse might fail
|
||||
// (while nothing seems to be wrong)
|
||||
#ifdef BOOST_UBLAS_TYPE_CHECK
|
||||
#undef BOOST_UBLAS_TYPE_CHECK
|
||||
#endif
|
||||
#define BOOST_UBLAS_TYPE_CHECK 0
|
||||
|
||||
#include <boost/numeric/ublas/lu.hpp>
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
// Remove the ublas checking, otherwise the inverse might fail
|
||||
// (while nothing seems to be wrong)
|
||||
#ifdef BOOST_UBLAS_TYPE_CHECK
|
||||
#undef BOOST_UBLAS_TYPE_CHECK
|
||||
#endif
|
||||
#define BOOST_UBLAS_TYPE_CHECK 0
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
59
include/boost/geometry/util/has_nan_coordinate.hpp
Normal file
59
include/boost/geometry/util/has_nan_coordinate.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 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)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail {
|
||||
|
||||
template <typename Point,
|
||||
std::size_t I = 0,
|
||||
std::size_t N = geometry::dimension<Point>::value>
|
||||
struct has_nan_coordinate
|
||||
{
|
||||
static bool apply(Point const& point)
|
||||
{
|
||||
return boost::math::isnan(geometry::get<I>(point))
|
||||
|| has_nan_coordinate<Point, I+1, N>::apply(point);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, std::size_t N>
|
||||
struct has_nan_coordinate<Point, N, N>
|
||||
{
|
||||
static bool apply(Point const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
template <typename Point>
|
||||
bool has_nan_coordinate(Point const& point)
|
||||
{
|
||||
return detail::has_nan_coordinate<Point>::apply(point);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_HAS_NAN_COORDINATE_HPP
|
||||
@@ -201,11 +201,36 @@ struct smaller<Type, true>
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
if (equals<Type, true>::apply(a, b, equals_default_policy()))
|
||||
if (!(a < b)) // a >= b
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return a < b;
|
||||
|
||||
return ! equals<Type, true>::apply(b, a, equals_default_policy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type,
|
||||
bool IsFloatingPoint = boost::is_floating_point<Type>::value>
|
||||
struct smaller_or_equals
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct smaller_or_equals<Type, true>
|
||||
{
|
||||
static inline bool apply(Type const& a, Type const& b)
|
||||
{
|
||||
if (a <= b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return equals<Type, true>::apply(a, b, equals_default_policy());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -407,6 +432,30 @@ struct relaxed_epsilon
|
||||
}
|
||||
};
|
||||
|
||||
// This must be consistent with math::equals.
|
||||
// By default math::equals() scales the error by epsilon using the greater of
|
||||
// compared values but here is only one value, though it should work the same way.
|
||||
// (a-a) <= max(a, a) * EPS -> 0 <= a*EPS
|
||||
// (a+da-a) <= max(a+da, a) * EPS -> da <= (a+da)*EPS
|
||||
template <typename T, bool IsFloat = boost::is_floating_point<T>::value>
|
||||
struct scaled_epsilon
|
||||
{
|
||||
static inline T apply(T const& val)
|
||||
{
|
||||
return (std::max)(abs<T>::apply(val), T(1))
|
||||
* std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct scaled_epsilon<T, false>
|
||||
{
|
||||
static inline T apply(T const&)
|
||||
{
|
||||
return T(0);
|
||||
}
|
||||
};
|
||||
|
||||
// ItoF ItoI FtoF
|
||||
template <typename Result, typename Source,
|
||||
bool ResultIsInteger = std::numeric_limits<Result>::is_integer,
|
||||
@@ -460,6 +509,12 @@ inline T relaxed_epsilon(T const& factor)
|
||||
return detail::relaxed_epsilon<T>::apply(factor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T scaled_epsilon(T const& value)
|
||||
{
|
||||
return detail::scaled_epsilon<T>::apply(value);
|
||||
}
|
||||
|
||||
|
||||
// Maybe replace this by boost equals or boost ublas numeric equals or so
|
||||
|
||||
@@ -512,6 +567,24 @@ inline bool larger(T1 const& a, T2 const& b)
|
||||
>::apply(b, a);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool smaller_or_equals(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller_or_equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(a, b);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline bool larger_or_equals(T1 const& a, T2 const& b)
|
||||
{
|
||||
return detail::smaller_or_equals
|
||||
<
|
||||
typename select_most_precise<T1, T2>::type
|
||||
>::apply(b, a);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T d2r()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost.Geometry Index
|
||||
// Additional tests
|
||||
|
||||
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,6 +21,9 @@
|
||||
#include <boost/geometry/geometries/linestring.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
|
||||
|
||||
namespace bg = boost::geometry;
|
||||
namespace bgi = bg::index;
|
||||
|
||||
@@ -139,7 +142,10 @@ int main()
|
||||
RT t(values.begin(), values.end());
|
||||
|
||||
dur_t time = clock_t::now() - start;
|
||||
std::cout << time << " - pack " << values_count << '\n';
|
||||
std::cout << time << " - pack " << values_count /*<< '\n'*/;
|
||||
|
||||
std::cout << (bgi::detail::rtree::utilities::are_levels_ok(t) ? " ok" : " NOK")
|
||||
<< (bgi::detail::rtree::utilities::are_boxes_ok(t) ? " ok\n" : "NOK\n");
|
||||
|
||||
{
|
||||
clock_t::time_point start = clock_t::now();
|
||||
@@ -164,7 +170,10 @@ int main()
|
||||
clock_t::time_point start = clock_t::now();
|
||||
t.insert(values);
|
||||
dur_t time = clock_t::now() - start;
|
||||
std::cout << time << " - insert " << values_count << '\n';
|
||||
std::cout << time << " - insert " << values_count /*<< '\n'*/;
|
||||
|
||||
std::cout << (bgi::detail::rtree::utilities::are_levels_ok(t) ? " ok" : " NOK")
|
||||
<< (bgi::detail::rtree::utilities::are_boxes_ok(t) ? " ok\n" : "NOK\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -462,6 +471,8 @@ int main()
|
||||
}
|
||||
dur_t time = clock_t::now() - start;
|
||||
std::cout << time << " - remove " << values_count / 10 << '\n';
|
||||
|
||||
std::cout << (bgi::detail::rtree::utilities::are_boxes_ok(t) ? " boxes ok\n" : "boxes NOT ok\n");
|
||||
}
|
||||
|
||||
std::cout << "------------------------------------------------\n";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Boost.Geometry Index
|
||||
#
|
||||
# Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
# Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software License,
|
||||
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -12,6 +12,8 @@ build-project generated ;
|
||||
|
||||
test-suite boost-geometry-index-rtree
|
||||
:
|
||||
[ run rtree_epsilon.cpp ]
|
||||
[ run rtree_insert_remove.cpp ]
|
||||
[ run rtree_move_pack.cpp ]
|
||||
[ run rtree_values.cpp ]
|
||||
[ compile-fail rtree_values_invalid.cpp ]
|
||||
|
||||
95
index/test/rtree/rtree_epsilon.cpp
Normal file
95
index/test/rtree/rtree_epsilon.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Boost.Geometry Index
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// 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)
|
||||
|
||||
// Enable enlargement of Values' bounds by epsilon in the rtree
|
||||
// for Points and Segments
|
||||
#define BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <rtree/test_rtree.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/register/point.hpp>
|
||||
#include <boost/geometry/geometries/polygon.hpp>
|
||||
|
||||
template <typename Params>
|
||||
void test_rtree(unsigned vcount)
|
||||
{
|
||||
typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
|
||||
|
||||
std::vector<point_t> values;
|
||||
|
||||
double eps = std::numeric_limits<double>::epsilon();
|
||||
values.push_back(point_t(eps/2, eps/2));
|
||||
|
||||
for ( unsigned i = 1 ; i < vcount ; ++i )
|
||||
{
|
||||
values.push_back(point_t(i, i));
|
||||
}
|
||||
|
||||
point_t qpt(0, 0);
|
||||
|
||||
BOOST_CHECK(bg::intersects(qpt, values[0]));
|
||||
|
||||
{
|
||||
bgi::rtree<point_t, Params> rt(values);
|
||||
|
||||
std::vector<point_t> result;
|
||||
rt.query(bgi::intersects(qpt), std::back_inserter(result));
|
||||
BOOST_CHECK(result.size() == 1);
|
||||
|
||||
rt.remove(values.begin() + vcount/2, values.end());
|
||||
|
||||
result.clear();
|
||||
rt.query(bgi::intersects(qpt), std::back_inserter(result));
|
||||
BOOST_CHECK(result.size() == 1);
|
||||
}
|
||||
|
||||
{
|
||||
bgi::rtree<point_t, Params> rt;
|
||||
rt.insert(values);
|
||||
|
||||
std::vector<point_t> result;
|
||||
rt.query(bgi::intersects(qpt), std::back_inserter(result));
|
||||
BOOST_CHECK(result.size() == 1);
|
||||
|
||||
rt.remove(values.begin() + vcount/2, values.end());
|
||||
|
||||
result.clear();
|
||||
rt.query(bgi::intersects(qpt), std::back_inserter(result));
|
||||
BOOST_CHECK(result.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <int Max, int Min>
|
||||
void test_rtree_all()
|
||||
{
|
||||
int pow = Max;
|
||||
for (int l = 0 ; l < 3 ; ++l)
|
||||
{
|
||||
pow *= Max;
|
||||
int vcount = (pow * 8) / 10;
|
||||
|
||||
//std::cout << Max << " " << Min << " " << vcount << std::endl;
|
||||
|
||||
test_rtree< bgi::linear<Max, Min> >(vcount);
|
||||
test_rtree< bgi::quadratic<Max, Min> >(vcount);
|
||||
test_rtree< bgi::rstar<Max, Min> >(vcount);
|
||||
}
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_rtree_all<2, 1>();
|
||||
test_rtree_all<4, 1>();
|
||||
test_rtree_all<4, 2>();
|
||||
test_rtree_all<5, 3>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
82
index/test/rtree/rtree_insert_remove.cpp
Normal file
82
index/test/rtree/rtree_insert_remove.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
// Boost.Geometry Index
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <rtree/test_rtree.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/register/point.hpp>
|
||||
#include <boost/geometry/geometries/polygon.hpp>
|
||||
|
||||
template <typename Params>
|
||||
void test_rtree(unsigned vcount)
|
||||
{
|
||||
typedef bg::model::point<int, 1, bg::cs::cartesian> point_t;
|
||||
|
||||
bgi::rtree<point_t, Params> rt;
|
||||
|
||||
BOOST_CHECK(rt.remove(point_t(0)) == 0);
|
||||
|
||||
for ( unsigned i = 0 ; i < vcount ; ++i )
|
||||
{
|
||||
rt.insert(point_t(static_cast<int>(i)));
|
||||
}
|
||||
|
||||
BOOST_CHECK(rt.size() == vcount);
|
||||
BOOST_CHECK(rt.count(point_t(vcount / 2)) == 1);
|
||||
|
||||
for ( unsigned i = 0 ; i < vcount + 3 ; ++i )
|
||||
{
|
||||
rt.remove(point_t((i + 3) % vcount));
|
||||
}
|
||||
|
||||
BOOST_CHECK(rt.size() == 0);
|
||||
BOOST_CHECK(rt.count(point_t(vcount / 2)) == 0);
|
||||
|
||||
for ( unsigned i = 0 ; i < vcount ; ++i )
|
||||
{
|
||||
rt.insert(point_t((i + 5) % vcount));
|
||||
}
|
||||
|
||||
BOOST_CHECK(rt.size() == vcount);
|
||||
BOOST_CHECK(rt.count(point_t(vcount / 2)) == 1);
|
||||
|
||||
for ( unsigned i = 0 ; i < vcount + 3 ; ++i )
|
||||
{
|
||||
rt.remove(point_t((i + 7) % vcount));
|
||||
}
|
||||
|
||||
BOOST_CHECK(rt.size() == 0);
|
||||
BOOST_CHECK(rt.count(point_t(vcount / 2)) == 0);
|
||||
}
|
||||
|
||||
template <int Max, int Min>
|
||||
void test_rtree_all()
|
||||
{
|
||||
int pow = Max;
|
||||
for (int l = 0 ; l < 3 ; ++l)
|
||||
{
|
||||
pow *= Max;
|
||||
int vcount = (pow * 8) / 10;
|
||||
|
||||
//std::cout << Max << " " << Min << " " << vcount << std::endl;
|
||||
|
||||
test_rtree< bgi::linear<Max, Min> >(vcount);
|
||||
test_rtree< bgi::quadratic<Max, Min> >(vcount);
|
||||
test_rtree< bgi::rstar<Max, Min> >(vcount);
|
||||
}
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_rtree_all<2, 1>();
|
||||
test_rtree_all<4, 1>();
|
||||
test_rtree_all<4, 2>();
|
||||
test_rtree_all<5, 3>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost.Geometry Index
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -1828,20 +1828,19 @@ void test_rtree_bounds(Parameters const& parameters, Allocator const& allocator)
|
||||
typedef typename Tree::bounds_type B;
|
||||
//typedef typename bg::traits::point_type<B>::type P;
|
||||
|
||||
B b;
|
||||
bg::assign_inverse(b);
|
||||
|
||||
Tree t(parameters, I(), E(), allocator);
|
||||
std::vector<Value> input;
|
||||
B qbox;
|
||||
|
||||
B b;
|
||||
bg::assign_inverse(b);
|
||||
|
||||
BOOST_CHECK(bg::equals(t.bounds(), b));
|
||||
|
||||
generate::rtree(t, input, qbox);
|
||||
|
||||
BOOST_FOREACH(Value const& v, input)
|
||||
bg::expand(b, t.indexable_get()(v));
|
||||
|
||||
b = bgi::detail::rtree::values_box<B>(input.begin(), input.end(), t.indexable_get());
|
||||
|
||||
BOOST_CHECK(bg::equals(t.bounds(), b));
|
||||
BOOST_CHECK(bg::equals(t.bounds(), bgi::bounds(t)));
|
||||
|
||||
@@ -1852,9 +1851,7 @@ void test_rtree_bounds(Parameters const& parameters, Allocator const& allocator)
|
||||
input.pop_back();
|
||||
}
|
||||
|
||||
bg::assign_inverse(b);
|
||||
BOOST_FOREACH(Value const& v, input)
|
||||
bg::expand(b, t.indexable_get()(v));
|
||||
b = bgi::detail::rtree::values_box<B>(input.begin(), input.end(), t.indexable_get());
|
||||
|
||||
BOOST_CHECK(bg::equals(t.bounds(), b));
|
||||
|
||||
|
||||
@@ -93,6 +93,10 @@ static std::string const mysql_report_2015_06_11 = "LINESTRING("
|
||||
"-162.7456296900030000 11.7183989853218000, 115.6208648232840000 "
|
||||
"51.0941612539320000, -48.7772321835054000 50.4339743128205000)";
|
||||
|
||||
static std::string const mysql_report_2015_09_08a = "LINESTRING(1 1, 2 1, 1.765258e+308 4, -1 1, 10 4)";
|
||||
static std::string const mysql_report_2015_09_08b = "LINESTRING(2199023255556 16777218, 32770 8194, 1.417733e+308 7.823620e+307, -8 -9, 2147483649 20)";
|
||||
static std::string const mysql_report_2015_09_08c = "LINESTRING(-5 -8, 2 8, 2.160023e+307 1.937208e+307, -4 -3, -5 -4, 8796093022208 281474976710653)";
|
||||
|
||||
template <bool Clockwise, typename P>
|
||||
void test_all()
|
||||
{
|
||||
@@ -270,6 +274,12 @@ void test_all()
|
||||
mysql_report_2015_06_11, join_round32, end_round32,
|
||||
27862.733459829971,
|
||||
5.9518403867035365);
|
||||
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
test_one<linestring, polygon>("mysql_report_2015_09_08a", mysql_report_2015_09_08a, join_round32, end_round32, 0.0, 1.0);
|
||||
test_one<linestring, polygon>("mysql_report_2015_09_08b", mysql_report_2015_09_08b, join_round32, end_round32, 0.0, 1099511627778.0);
|
||||
test_one<linestring, polygon>("mysql_report_2015_09_08c", mysql_report_2015_09_08c, join_round32, end_round32, 0.0, 0xbe);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <bool Clockwise, typename P>
|
||||
|
||||
@@ -32,6 +32,9 @@ static std::string const mikado4 = "MULTILINESTRING((-15 2,-15 -17,-6 11,-1.9358
|
||||
static std::string const mysql_2015_04_10a = "MULTILINESTRING((-58 19, 61 88),(1.922421e+307 1.520384e+308, 15 42, 89 -93,-89 -22),(-63 -5, -262141 -536870908, -3 87, 77 -69))";
|
||||
static std::string const mysql_2015_04_10b = "MULTILINESTRING((-58 19, 61 88), (-63 -5, -262141 -536870908, -3 87, 77 -69))";
|
||||
|
||||
static std::string const mysql_2015_09_08a = "MULTILINESTRING((7 -4, -3 -5), (72057594037927936 15, 72057594037927940 70368744177660, 32771 36028797018963964, 8589934589 2305843009213693953, 7 2, 9.300367e+307 9.649737e+307, -4092 -274877906946, 5 10, -3 4))";
|
||||
static std::string const mysql_2015_09_08b = "MULTILINESTRING((-9 -10, 0 -1, 5 -10, -6 7, -7 7, 5.041061e+307 9.926906e+307, 6.870356e+307 1.064454e+307, 35184372088830 288230376151711743, 183673728842483250000000000000000000000.000000 244323751784861950000000000000000000000.000000), (-23530 -7131, -6 1, 1 1, 2 -6, 32766 -4194302, -4 -6), (134217725 0, 50336782742294697000000000000000000000.000000 36696596077212901000000000000000000000.000000, 7434 16486, 3.025467e+307 8.926790e+307), (2147483646 67108868, 71328904281592545000000000000000000000.000000 225041650340452780000000000000000000000.000000, -7 4, 1.667154e+307 3.990414e+307))";
|
||||
|
||||
template <bool Clockwise, typename P>
|
||||
void test_all()
|
||||
{
|
||||
@@ -96,7 +99,7 @@ void test_all()
|
||||
test_one<multi_linestring_type, polygon>("mikado1_small", mikado1, join_round32, end_round32, 1057.37, 10.0);
|
||||
test_one<multi_linestring_type, polygon>("mikado1_small", mikado1, join_round32, end_flat, 874.590, 10.0);
|
||||
|
||||
test_one<multi_linestring_type, polygon>("mikado2_large", mikado2, join_round32, end_round32, 19878812253, 79610.0, same_distance, true, mikado_tolerance);
|
||||
test_one<multi_linestring_type, polygon>("mikado2_large", mikado2, join_round32, end_round32, 19878812253, 79610.0, same_distance, true, 10 * mikado_tolerance);
|
||||
test_one<multi_linestring_type, polygon>("mikado2_small", mikado2, join_round32, end_round32, 1082.470, 10.0);
|
||||
test_one<multi_linestring_type, polygon>("mikado2_small", mikado2, join_round32, end_flat, 711.678, 10.0);
|
||||
|
||||
@@ -104,7 +107,7 @@ void test_all()
|
||||
// msvc 29151950611
|
||||
// clang/linux 29151950612
|
||||
// mingw 29151950711
|
||||
test_one<multi_linestring_type, polygon>("mikado3_large", mikado3, join_round32, end_round32, 29151950650, 96375.0, same_distance, true, 3 * mikado_tolerance);
|
||||
test_one<multi_linestring_type, polygon>("mikado3_large", mikado3, join_round32, end_round32, 29151950650, 96375.0, same_distance, true, 10 * mikado_tolerance);
|
||||
test_one<multi_linestring_type, polygon>("mikado3_small", mikado3, join_round32, end_round32, 2533.285, 10.0);
|
||||
test_one<multi_linestring_type, polygon>("mikado3_small", mikado3, join_round32, end_flat, 2136.236, 10.0);
|
||||
|
||||
@@ -125,6 +128,17 @@ void test_all()
|
||||
test_one<multi_linestring_type, polygon>("mysql_2015_04_10a", mysql_2015_04_10a, join_round32, end_round32, 1063005187.214, 0.98);
|
||||
test_one<multi_linestring_type, polygon>("mysql_2015_04_10b", mysql_2015_04_10b, join_round32, end_round32, 1063005187.214, 0.98);
|
||||
#endif
|
||||
|
||||
// Two other cases with inf for length calculation (tolerance quite high
|
||||
// because the output area is quite high and varies between gcc/clang)
|
||||
test_one<multi_linestring_type, polygon>("mysql_2015_09_08a",
|
||||
mysql_2015_09_08a, join_round32, end_round32,
|
||||
5.12436196736438764e+19, 4051744443.0,
|
||||
same_distance, true, 1.0e12);
|
||||
test_one<multi_linestring_type, polygon>("mysql_2015_09_08b",
|
||||
mysql_2015_09_08b, join_round32, end_round32,
|
||||
1.32832149026508268e+19, 2061380362.0,
|
||||
same_distance, true, 1.0e12);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -570,7 +570,8 @@ void test_all()
|
||||
test_one<polygon_type, polygon_type>("mysql_report_2015_07_05_1", mysql_report_2015_07_05_1,
|
||||
join_round32, end_round32, 2.07548405999982264e+19, 6);
|
||||
test_one<polygon_type, polygon_type>("mysql_report_2015_07_05_2", mysql_report_2015_07_05_2,
|
||||
join_round32, end_round32, 9.48681585720922691e+23, 549755813889);
|
||||
join_round32, end_round32, 9.48681585720922691e+23, 549755813889,
|
||||
same_distance, true, high_tolerance);
|
||||
test_one<polygon_type, polygon_type>("mysql_report_2015_07_05_3", mysql_report_2015_07_05_3,
|
||||
join_round32, end_round32, 6.10005339242509925e+22, 49316,
|
||||
same_distance, false, high_tolerance);
|
||||
@@ -578,7 +579,8 @@ void test_all()
|
||||
join_round32, end_round32, 4.25405937213774089e+23, 1479986,
|
||||
same_distance, false, high_tolerance);
|
||||
test_one<polygon_type, polygon_type>("mysql_report_2015_07_05_5", mysql_report_2015_07_05_5,
|
||||
join_round32, end_round32, 644489321051.62439, 38141);
|
||||
join_round32, end_round32, 644489321051.62439, 38141,
|
||||
same_distance, false, 10000.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,8 @@ private :
|
||||
color = 'b';
|
||||
is_good = false;
|
||||
break;
|
||||
default:
|
||||
; // to avoid "enumeration value not handled" warning
|
||||
}
|
||||
if (!it->selectable_start)
|
||||
{
|
||||
|
||||
@@ -226,6 +226,19 @@ void test_distance_multipoint_multilinestring(Strategy const& strategy)
|
||||
tester::apply("multipoint(0 0,1 0,0 1,1 1)",
|
||||
"multilinestring((4 4,5 5),(),(3 3))",
|
||||
sqrt(8.0), 8, strategy);
|
||||
|
||||
// 21890717 - assertion failure in distance(Pt, Box)
|
||||
{
|
||||
multi_point_type mpt;
|
||||
bg::read_wkt("multipoint(1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1)", mpt);
|
||||
multi_linestring_type mls;
|
||||
linestring_type ls;
|
||||
point_type pt(std::numeric_limits<double>::quiet_NaN(), 1.0);
|
||||
ls.push_back(pt);
|
||||
ls.push_back(pt);
|
||||
mls.push_back(ls);
|
||||
bg::distance(mpt, mls);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
@@ -713,6 +713,67 @@ inline void test_open_polygons()
|
||||
0.7808688094430304 -0.6246950475544243,\
|
||||
0.7808688094430304 -0.6246950475544243))",
|
||||
AllowDuplicates);
|
||||
|
||||
|
||||
// MySQL report on Sep 30, 2015
|
||||
test::apply
|
||||
("pg077",
|
||||
"POLYGON((72.8714768817168 -167.0048853643874,9274.40641550926 3433.5957427942167,-58.09039811390054 187.50989457746405,-81.09039811390053 179.50989457746405,-207.99999999999997 135.36742435621204,-208 1,-208 0,-208 -276.9111154485375,49.8714768817168 -176.0048853643874))",
|
||||
true);
|
||||
|
||||
test::apply("pg077-simplified",
|
||||
"POLYGON((-200 0,-207.99999999999997 135.36742435621204,-208 1,-208 0,-208 -276.9111154485375))",
|
||||
true);
|
||||
|
||||
test::apply
|
||||
("pg078",
|
||||
"POLYGON((0 10,-10 0,0 0,10 0))",
|
||||
true);
|
||||
|
||||
test::apply
|
||||
("pg078spike1",
|
||||
"POLYGON((0 10,-10 0,0 0,-10 0,10 0))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg078spike2",
|
||||
"POLYGON((0 10,-10 0,0 0,-8 0,10 0))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg078spike3",
|
||||
"POLYGON((0 10,-10 0,0 0,-11 0,10 0))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg078reversed",
|
||||
"POLYGON((0 10,10 0,0 0,-10 0))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg079",
|
||||
"POLYGON((10 0,0 10,0 0,0 -10))",
|
||||
true);
|
||||
|
||||
test::apply
|
||||
("pg079spike1",
|
||||
"POLYGON((10 0,0 10,0 0,0 10,0 -10))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg079spike2",
|
||||
"POLYGON((10 0,0 10,0 0,0 8,0 -10))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg079spike3",
|
||||
"POLYGON((10 0,0 10,0 0,0 11,0 -10))",
|
||||
false);
|
||||
|
||||
test::apply
|
||||
("pg079reversed",
|
||||
"POLYGON((10 0,0 -10,0 0,0 10))",
|
||||
false);
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
template <typename Geometry>
|
||||
void test_geometry(std::string const& wkt, int expected)
|
||||
void test_geometry(std::string const& wkt, std::size_t expected)
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
int detected = bg::num_geometries(geometry);
|
||||
std::size_t detected = bg::num_geometries(geometry);
|
||||
BOOST_CHECK_MESSAGE(detected == expected,
|
||||
"num_geometries: " << wkt
|
||||
<< " -> Expected: " << expected
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
template <typename Geometry>
|
||||
void test_geometry(std::string const& wkt, int expected)
|
||||
void test_geometry(std::string const& wkt, std::size_t expected)
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
int detected = bg::num_interior_rings(geometry);
|
||||
std::size_t detected = bg::num_interior_rings(geometry);
|
||||
BOOST_CHECK_MESSAGE(detected == expected,
|
||||
"num_interior_rings: " << wkt
|
||||
<< " -> Expected: " << expected
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
void check_geometry(Geometry const& geometry, std::string const& wkt, int expected)
|
||||
void check_geometry(Geometry const& geometry, std::string const& wkt, std::size_t expected)
|
||||
{
|
||||
int detected = bg::num_points(geometry);
|
||||
std::size_t detected = bg::num_points(geometry);
|
||||
BOOST_CHECK_MESSAGE(detected == expected,
|
||||
"num_points: " << wkt
|
||||
<< " -> Expected: " << expected
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
// To test that "get_turns" can be called using additional information
|
||||
template <typename Point, typename SegmentRatio>
|
||||
struct my_turn_op : public bg::detail::overlay::turn_operation<SegmentRatio>
|
||||
struct my_turn_op : public bg::detail::overlay::turn_operation<Point, SegmentRatio>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -285,6 +285,10 @@ 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)",
|
||||
@@ -293,6 +297,9 @@ void test_all()
|
||||
test_geometry<ls, ls>("LINESTRING(31 -97, -46 57, -20 -4)",
|
||||
"LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)",
|
||||
expected("")(""));
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// In 1.57 the results of those combinations was different for MinGW
|
||||
@@ -511,6 +518,18 @@ void test_all()
|
||||
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0))",
|
||||
"MULTILINESTRING((2 0,0 0,-1 -1))",
|
||||
expected("tiu+=")("mui=+"));
|
||||
|
||||
// parts of boundaries taken from union A/A buffer_mp1
|
||||
if ( BOOST_GEOMETRY_CONDITION((boost::is_same<T, double>::value)) )
|
||||
{
|
||||
test_geometry<ls, ls>("LINESTRING(6.95629520146761 5.415823381635526,6.989043790736545 5.209056926535316,7 5,6.989043790736547 4.790943073464693,6.956295201467611 4.584176618364482)",
|
||||
"LINESTRING(7.415823381635519 5.043704798532389,7.209056926535308 5.010956209263453,7.000000000000001 5,6.790943073464693 5.010956209263453,6.584176618364483 5.043704798532389)",
|
||||
expected("tuu++"));
|
||||
// the above should give the same result as this:
|
||||
test_geometry<ls, ls>("LINESTRING(6.95629520146761 5.415823381635526,6.989043790736545 5.209056926535316,7 5,6.989043790736547 4.790943073464693,6.956295201467611 4.584176618364482)",
|
||||
"LINESTRING(7.415823381635519 5.043704798532389,7.209056926535308 5.010956209263453,7 5,6.790943073464693 5.010956209263453,6.584176618364483 5.043704798532389)",
|
||||
expected("tuu++"));
|
||||
}
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
|
||||
@@ -380,6 +380,13 @@ static std::string case_recursive_boxes_4[2] =
|
||||
"MULTIPOLYGON(((1 0,2 1,2 0,1 0)),((7 9,7 10,8 10,7 9)),((1 0,0 0,0 3,1 3,2 2,2 3,1 3,1 4,2 4,2 5,1 4,0 4,0 8,1 7,1 6,2 7,1 7,1 9,0 9,0 10,7 10,6 9,6.5 8.5,7 9,8 9,9 8,8 8,9 7,9 6,10 7,10 5,9 5,9 4,10 5,10 0,7 0,8 1,7 1,6 0,3 0,3 1,1 1,1 0),(5 1,5.5 0.5,6 1,6 2,6.5 1.5,7 2,8 2,8 4,7 3,6 3,6 2,5 2,6 1,5 1),(4 4,5 4,5 5,4 4),(4 6,4 7,3 7,2 6,3 6,3 7,4 6),(6 5,6.5 4.5,7 5,6 5,7 6,7 7,6 7,6 5),(3.5 7.5,4 8,4 9,3 8,3.5 7.5)),((9 8,9 9,8 9,9 10,10 10,10 8,9 8)))"
|
||||
};
|
||||
|
||||
static std::string case_recursive_boxes_5[2] =
|
||||
{
|
||||
// Occurs after refactoring uu / handle_touch (not yet integrated)
|
||||
"MULTIPOLYGON(((0 9,0 10,1 10,1 9,0 9)),((9 0,9 1,10 1,10 0,9 0)),((5 6,5 7,6 7,6 6,7 6,7 4,6 4,6 5,5 5,5 6)),((5 3,7 3,7 2,4 2,4 3,5 3)),((5 8,5 9,7 9,7 8,5 8)),((4 0,1 0,1 1,5 1,5 0,4 0)),((3 5,3 4,4 4,4 3,2 3,2 2,1 2,1 3,0 3,0 4,2 4,2 5,1 5,1 6,4 6,4 5,3 5)),((0 2,1 2,1 1,0 1,0 2)),((4 10,4 7,1 7,1 6,0 6,0 8,1 8,1 9,2 9,2 10,4 10)),((9 4,9 3,8 3,8 5,9 5,9 4)),((7 2,8 2,8 0,7 0,7 2)),((8 7,10 7,10 6,7 6,7 8,8 8,8 7)))",
|
||||
"MULTIPOLYGON(((2 3,2 4,3 4,3 3,2 3)),((1 5,1 6,2 6,2 5,1 5)),((2 1,2 2,3 2,3 1,2 1)),((8 1,9 1,9 0,8 0,8 1)),((9 7,10 7,10 6,9 6,9 7)),((1 4,1 3,0 3,0 5,1 5,1 4)),((7 6,7 7,8 7,8 6,7 6)),((7 1,7 2,8 2,8 1,7 1)),((6 2,6 3,7 3,7 2,6 2)),((6 8,6 9,7 9,7 8,6 8)),((5 0,3 0,3 1,4 1,4 2,6 2,6 1,7 1,7 0,5 0)),((5 5,5 6,6 6,6 5,8 5,8 6,9 6,9 4,8 4,8 3,7 3,7 4,6 4,6 3,5 3,5 4,3 4,3 6,2 6,2 8,3 8,3 7,5 7,5 6,4 6,4 5,5 5)),((1 1,2 1,2 0,1 0,1 1)),((1 3,2 3,2 2,1 2,1 3)),((3 10,4 10,4 9,2 9,2 8,0 8,0 10,3 10)),((10 3,10 1,9 1,9 2,8 2,8 3,9 3,9 4,10 4,10 3)),((9 9,10 9,10 8,9 8,9 7,8 7,8 10,9 10,9 9)))"
|
||||
};
|
||||
|
||||
static std::string pie_21_7_21_0_3[2] =
|
||||
{
|
||||
"MULTIPOLYGON(((2500 2500,2500 3875,2855 3828,3187 3690,3472 3472,3690 3187,3828 2855,3875 2500,3828 2144,3690 1812,3472 1527,3187 1309,2855 1171,2499 1125,2144 1171,1812 1309,1527 1527,1309 1812,1171 2144,1125 2499,1171 2855,1309 3187,2500 2500)))",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
template <typename Geometry>
|
||||
static void test_self_intersection_points(std::string const& case_id,
|
||||
int expected_count,
|
||||
std::size_t expected_count,
|
||||
Geometry const& geometry,
|
||||
bool check_has_intersections,
|
||||
double /*precision*/ = 0.001)
|
||||
@@ -84,7 +84,7 @@ static void test_self_intersection_points(std::string const& case_id,
|
||||
x += bg::get<0>(turn.point);
|
||||
y += bg::get<1>(turn.point);
|
||||
}
|
||||
int n = boost::size(turns);
|
||||
std::size_t n = boost::size(turns);
|
||||
if (n > 0)
|
||||
{
|
||||
x /= n;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015 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
|
||||
@@ -145,6 +150,7 @@ int test_main( int , char* [] )
|
||||
|
||||
#if defined(HAVE_TTMATH)
|
||||
test_all<bg::model::d2::point_xy<ttmath_big> >();
|
||||
test_eps<bg::model::d2::point_xy<ttmath_big> >();
|
||||
//test_spherical<bg::model::point<ttmath_big, 2, bg::cs::spherical_equatorial<bg::degree> > >();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -111,9 +111,11 @@ void test_3d()
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_all<bg::model::d2::point_xy<float> >();
|
||||
|
||||
test_all<bg::model::d2::point_xy<double> >();
|
||||
|
||||
#ifdef HAVE_TTMATH
|
||||
@@ -121,7 +123,6 @@ int test_main(int, char* [])
|
||||
#endif
|
||||
|
||||
test_3d<bg::model::point<double, 3, bg::cs::cartesian> >();
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,30 @@ void test_additional()
|
||||
"LINESTRING(1 2)",
|
||||
"BOX(0 0,3 5)",
|
||||
true);
|
||||
|
||||
// http://stackoverflow.com/questions/32457920/boost-rtree-of-box-gives-wrong-intersection-with-segment
|
||||
// http://lists.boost.org/geometry/2015/09/3476.php
|
||||
// For now disabled by default even though it works properly on MSVC14
|
||||
// it's probable that the result depends on the compiler
|
||||
#ifdef BOOST_GEOMETRY_ENABLE_FAILING_TESTS
|
||||
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
|
||||
"SEGMENT(12 0,20 10)",
|
||||
"BOX(0 0,10 10)",
|
||||
false);
|
||||
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
|
||||
"SEGMENT(2 0,8 6)",
|
||||
"BOX(0 0,10 10)",
|
||||
true);
|
||||
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
|
||||
"SEGMENT(2 0,18 8)",
|
||||
"BOX(0 0,10 10)",
|
||||
true);
|
||||
typedef bg::model::point<typename bg::coordinate_type<P>::type, 3, bg::cs::cartesian> point3d_t;
|
||||
test_geometry<bg::model::segment<point3d_t>, bg::model::box<point3d_t> >(
|
||||
"SEGMENT(2 1 0,2 1 10)",
|
||||
"BOX(0 0 0,10 0 10)",
|
||||
false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
130
test/algorithms/relational_operations/nan_cases.hpp
Normal file
130
test/algorithms/relational_operations/nan_cases.hpp
Normal file
@@ -0,0 +1,130 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2015 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)
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
template <typename Container>
|
||||
struct pusher
|
||||
: public Container
|
||||
{
|
||||
typedef typename Container::value_type value_type;
|
||||
pusher(value_type const& val)
|
||||
{
|
||||
this->push_back(val);
|
||||
}
|
||||
|
||||
pusher & operator()(value_type const& val)
|
||||
{
|
||||
this->push_back(val);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry,
|
||||
typename Tag = typename bg::tag<Geometry>::type,
|
||||
typename Coord = typename bg::coordinate_type<Geometry>::type>
|
||||
struct nan_case_generator
|
||||
{
|
||||
static void apply(Geometry & , std::string & )
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct nan_case_generator<Geometry, bg::multi_linestring_tag, double>
|
||||
{
|
||||
static void apply(Geometry & geometry, std::string & wkt)
|
||||
{
|
||||
typedef typename boost::range_value<Geometry>::type ls;
|
||||
typedef typename bg::point_type<Geometry>::type P;
|
||||
typedef typename bg::coordinate_type<Geometry>::type coord_t;
|
||||
coord_t nan = std::numeric_limits<coord_t>::quiet_NaN();
|
||||
|
||||
wkt = "MULTILINESTRING((3.1e+307 1,-nan -nan),(3.1e+307 1,-nan -nan),(3.1e+307 1,5.1e+307 6e+307,nan nan),(-nan -nan,nan nan),(-nan -nan,-1 -3.97843,-1 3.28571,-1 47.6364),(3 78.5455,3 2),(nan nan,3 12.9689),(3 -2,-nan -nan),(3 2,3 12.9689,3 78.5455),(-1 4.29497e+09,-1 7,-nan -nan),(9 5,-nan -nan),(-nan -nan,9 60.8755,9 124.909),(nan nan,1 6.87195e+10,-nan -nan),(nan nan,4 86.2727,4 20.9533),(4 -5,-nan -nan),(4 -5,-nan -nan),(4 -5,-nan -nan),(4 -5,1.1e+308 2.1e+307,nan nan),(-nan -nan,-1 -8),(-nan -nan,-9 -4))";
|
||||
|
||||
typedef pusher<Geometry> ml;
|
||||
typedef pusher<ls> l;
|
||||
geometry = ml(l(P(3.1e+307, 1))(P(-nan, -nan)))
|
||||
(l(P(3.1e+307, 1))(P(-nan, -nan)))
|
||||
(l(P(3.1e+307, 1))(P(5.1e+307, 6e+307))(P(nan, nan)))
|
||||
(l(P(-nan, -nan))(P(nan, nan)))
|
||||
(l(P(-nan, -nan))(P(-1, -3.97843))(P(-1, 3.28571))(P(-1, 47.6364)))
|
||||
(l(P(3, 78.5455))(P(3, 2)))
|
||||
(l(P(nan, nan))(P(3, 12.9689)))
|
||||
(l(P(3, -2))(P(-nan, -nan)))
|
||||
(l(P(3, 2))(P(3, 12.9689))(P(3, 78.5455)))
|
||||
(l(P(-1, 4.29497e+09))(P(-1, 7))(P(-nan, -nan)))
|
||||
(l(P(9, 5))(P(-nan, -nan)))
|
||||
(l(P(-nan, -nan))(P(9, 60.8755))(P(9, 124.909)))
|
||||
(l(P(nan, nan))(P(1, 6.87195e+10))(P(-nan, -nan)))
|
||||
(l(P(nan, nan))(P(4, 86.2727))(P(4, 20.9533)))
|
||||
(l(P(4, -5))(P(-nan, -nan)))
|
||||
(l(P(4, -5))(P(-nan, -nan)))
|
||||
(l(P(4, -5))(P(-nan, -nan)))
|
||||
(l(P(4, -5))(P(1.1e+308, 2.1e+307))(P(nan, nan)))
|
||||
(l(P(-nan, -nan))(P(-1, -8)))
|
||||
(l(P(-nan, -nan))(P(-9, -4)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct nan_case_generator<Geometry, bg::multi_point_tag, double>
|
||||
{
|
||||
static void apply(Geometry & geometry, std::string & wkt)
|
||||
{
|
||||
typedef typename bg::point_type<Geometry>::type P;
|
||||
typedef typename bg::coordinate_type<Geometry>::type coord_t;
|
||||
coord_t nan = std::numeric_limits<coord_t>::quiet_NaN();
|
||||
|
||||
wkt = "MULTIPOINT((3.1e+307 1),(-nan -nan),(3.1e+307 1),(-nan -nan),(3.1e+307 1),(5.1e+307 6e+307),(nan nan),(-nan -nan),(nan nan),(-nan -nan),(-1 -3.97843),(-1 3.28571),(-1 47.6364),(3 78.5455),(3 2),(nan nan),(3 12.9689),(3 -2),(-nan -nan),(3 2),(3 12.9689),(3 78.5455),(-1 4.29497e+09),(-1 7),(-nan -nan),(9 5),(-nan -nan),(-nan -nan),(9 60.8755),(9 124.909),(nan nan),(1 6.87195e+10),(-nan -nan),(nan nan),(4 86.2727),(4 20.9533),(4 -5),(-nan -nan),(4 -5),(-nan -nan),(4 -5),(-nan -nan),(4 -5),(1.1e+308 2.1e+307),(nan nan),(-nan -nan),(-1 -8),(-nan -nan),(-9 -4))";
|
||||
|
||||
typedef pusher<Geometry> mp;
|
||||
geometry = mp(P(3.1e+307, 1))(P(-nan, -nan))
|
||||
(P(3.1e+307, 1))(P(-nan, -nan))
|
||||
(P(3.1e+307, 1))(P(5.1e+307, 6e+307))(P(nan, nan))
|
||||
(P(-nan, -nan))(P(nan, nan))
|
||||
(P(-nan, -nan))(P(-1, -3.97843))(P(-1, 3.28571))(P(-1, 47.6364))
|
||||
(P(3, 78.5455))(P(3, 2))
|
||||
(P(nan, nan))(P(3, 12.9689))
|
||||
(P(3, -2))(P(-nan, -nan))
|
||||
(P(3, 2))(P(3, 12.9689))(P(3, 78.5455))
|
||||
(P(-1, 4.29497e+09))(P(-1, 7))(P(-nan, -nan))
|
||||
(P(9, 5))(P(-nan, -nan))
|
||||
(P(-nan, -nan))(P(9, 60.8755))(P(9, 124.909))
|
||||
(P(nan, nan))(P(1, 6.87195e+10))(P(-nan, -nan))
|
||||
(P(nan, nan))(P(4, 86.2727))(P(4, 20.9533))
|
||||
(P(4, -5))(P(-nan, -nan))
|
||||
(P(4, -5))(P(-nan, -nan))
|
||||
(P(4, -5))(P(-nan, -nan))
|
||||
(P(4, -5))(P(1.1e+308, 2.1e+307))(P(nan, nan))
|
||||
(P(-nan, -nan))(P(-1, -8))
|
||||
(P(-nan, -nan))(P(-9, -4));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
void nan_case(Geometry & geometry, std::string & wkt)
|
||||
{
|
||||
nan_case_generator<Geometry>::apply(geometry, wkt);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
struct is_nan_case_supported
|
||||
{
|
||||
typedef typename bg::coordinate_type<Geometry>::type coord_t;
|
||||
|
||||
static const bool value = boost::is_same<coord_t, double>::value
|
||||
&& std::numeric_limits<coord_t>::has_quiet_NaN;
|
||||
};
|
||||
@@ -44,6 +44,14 @@ void test_aa()
|
||||
test_geometry<mpoly, poly>("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 0,0 -10,-10 -10,-10 0,0 0)))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
false);
|
||||
|
||||
// mysql 21872795
|
||||
test_geometry<poly, poly>("POLYGON((2 2,2 8,8 8,8 2,2 2))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(8 8,4 6,4 4,8 8))",
|
||||
true);
|
||||
test_geometry<poly, poly>("POLYGON((2 2,2 8,8 8,8 2,2 2))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 4,4 6,2 2))",
|
||||
true);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -43,6 +43,7 @@ void test_3d()
|
||||
test_geometry<bg::model::box<P>, bg::model::box<P> >("BOX(1 1 1, 3 3 3)", "BOX(4 4 4,6 6 6)", false);
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
void test_2d()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015 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)
|
||||
@@ -22,15 +28,12 @@
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
void test_geometry(std::string const& wkt1,
|
||||
std::string const& wkt2, bool expected)
|
||||
void test_geometry(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
std::string const& wkt1,
|
||||
std::string const& wkt2,
|
||||
bool expected)
|
||||
{
|
||||
Geometry1 geometry1;
|
||||
Geometry2 geometry2;
|
||||
|
||||
bg::read_wkt(wkt1, geometry1);
|
||||
bg::read_wkt(wkt2, geometry2);
|
||||
|
||||
bool detected = bg::overlaps(geometry1, geometry2);
|
||||
|
||||
BOOST_CHECK_MESSAGE(detected == expected,
|
||||
@@ -48,5 +51,19 @@ void test_geometry(std::string const& wkt1,
|
||||
<< " detected: " << detected);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
void test_geometry(std::string const& wkt1,
|
||||
std::string const& wkt2,
|
||||
bool expected)
|
||||
{
|
||||
Geometry1 geometry1;
|
||||
Geometry2 geometry2;
|
||||
|
||||
bg::read_wkt(wkt1, geometry1);
|
||||
bg::read_wkt(wkt2, geometry2);
|
||||
|
||||
test_geometry(geometry1, geometry2, wkt1, wkt2, expected);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -343,6 +343,25 @@ void test_polygon_polygon()
|
||||
"POLYGON((1 1,1 2,2 2,2 1,1 1))",
|
||||
"****F****");*/
|
||||
}
|
||||
|
||||
// mysql 21872795 (overlaps)
|
||||
test_geometry<poly, poly>("POLYGON((2 2,2 8,8 8,8 2,2 2))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(8 8,4 6,4 4,8 8))",
|
||||
"21210F212");
|
||||
test_geometry<poly, poly>("POLYGON((2 2,2 8,8 8,8 2,2 2))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 4,4 6,2 2))",
|
||||
"21210F212");
|
||||
// mysql 21873343 (touches)
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0), (0 8, 8 5, 8 8, 0 8))",
|
||||
"POLYGON((0 8,-8 5,-8 8,0 8))",
|
||||
"FF2F01212");
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0), (0 6, 6 3, 6 6, 0 6))",
|
||||
"POLYGON((0 6,-6 3,-6 6,0 6))",
|
||||
"FF2F01212");
|
||||
// similar but touching from the inside of the hole
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0), (0 8, 8 5, 8 8, 0 8))",
|
||||
"POLYGON((0 8,7 7, 7 6,0 8))",
|
||||
"FF2F01212");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "test_relate.hpp"
|
||||
#include "../nan_cases.hpp"
|
||||
|
||||
//TEST
|
||||
//#include <to_svg.hpp>
|
||||
@@ -381,6 +382,7 @@ void test_multi_linestring_polygon()
|
||||
typedef bg::model::linestring<P> ls;
|
||||
typedef bg::model::multi_linestring<ls> mls;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef typename bg::coordinate_type<P>::type coord_t;
|
||||
|
||||
test_geometry<mls, poly>("MULTILINESTRING((11 11, 20 20),(5 7, 4 1))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 2,4 4,2 4,2 2))",
|
||||
@@ -390,7 +392,7 @@ void test_multi_linestring_polygon()
|
||||
"1F10F0212");
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION((
|
||||
boost::is_same<typename bg::coordinate_type<P>::type, double>::value )) )
|
||||
boost::is_same<coord_t, double>::value )) )
|
||||
{
|
||||
// assertion failure in 1.57
|
||||
test_geometry<mls, poly>("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))",
|
||||
@@ -422,6 +424,21 @@ void test_multi_linestring_polygon()
|
||||
test_geometry<mls, poly>("MULTILINESTRING((3 10, 1 5, 1 10, 3 4, 7 8, 6 10, 10 2))",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"10FF0F212");
|
||||
|
||||
// mysql bug
|
||||
// assertion failure in relate->boundary_checker->std::equal_range with msvc
|
||||
if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mls>::value))
|
||||
{
|
||||
mls g1;
|
||||
std::string wkt1;
|
||||
nan_case(g1, wkt1);
|
||||
|
||||
std::string wkt2 = "POLYGON((1.1e+308 1.2e+308,-1 -9,1 1e+12,1.1e+308 7.8e+307,1.1e+308 1.2e+308),(3 2,1 1,8e+307 1e+308,3 2),(258 2049,1 -3,1 1,-6 9,258 2049))";
|
||||
poly g2;
|
||||
bg::read_wkt(wkt2, g2);
|
||||
|
||||
check_geometry(g1, g2, wkt1, wkt2, "*********");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#include "test_relate.hpp"
|
||||
#include "../nan_cases.hpp"
|
||||
|
||||
//TEST
|
||||
//#include <to_svg.hpp>
|
||||
@@ -47,6 +48,16 @@ void test_multipoint_multipoint()
|
||||
//typedef bg::model::d2::point_xy<float> ptf;
|
||||
//typedef bg::model::multi_point<ptf> mptf;
|
||||
//test_geometry<mptf, mpt>("MULTIPOINT(0 0)", "MULTIPOINT(0 0)", "0FFFFFFF2");
|
||||
|
||||
// assertion failure in relate->boundary_checker->std::equal_range with msvc
|
||||
if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mpt>::value))
|
||||
{
|
||||
mpt g;
|
||||
std::string wkt;
|
||||
nan_case(g, wkt);
|
||||
|
||||
check_geometry(g, g, wkt, wkt, "*********");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@@ -78,6 +89,27 @@ void test_point_multilinestring()
|
||||
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");
|
||||
test_geometry<P, mls>("POINT(5 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");
|
||||
test_geometry<P, mls>("POINT(1 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");
|
||||
|
||||
// assertion failure in relate->boundary_checker->std::equal_range with msvc
|
||||
if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mls>::value))
|
||||
{
|
||||
// on the boundary
|
||||
std::string wkt0 = "POINT(3.1e+307 1)";
|
||||
P g0;
|
||||
bg::read_wkt(wkt0, g0);
|
||||
|
||||
// disjoint
|
||||
std::string wkt1 = "POINT(1.1e+308 1.2e+308)";
|
||||
P g1;
|
||||
bg::read_wkt(wkt1, g1);
|
||||
|
||||
mls g2;
|
||||
std::string wkt2;
|
||||
nan_case(g2, wkt2);
|
||||
|
||||
check_geometry(g0, g2, wkt0, wkt2, "*********");
|
||||
check_geometry(g1, g2, wkt1, wkt2, "*********");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013.
|
||||
// Modifications copyright (c) 2013, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2015.
|
||||
// Modifications copyright (c) 2013, 2015 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
|
||||
@@ -43,8 +45,8 @@ void check_touches(Geometry1 const& geometry1,
|
||||
detected = bg::touches(geometry2, geometry1);
|
||||
|
||||
BOOST_CHECK_MESSAGE(detected == expected,
|
||||
"touches: " << wkt2
|
||||
<< " with " << wkt1
|
||||
"touches: " << wkt1
|
||||
<< " with " << wkt2
|
||||
<< " -> Expected: " << expected
|
||||
<< " detected: " << detected);
|
||||
}
|
||||
|
||||
@@ -118,6 +118,20 @@ void test_all()
|
||||
true
|
||||
);
|
||||
|
||||
// mysql 21873343
|
||||
test_touches<polygon, polygon>
|
||||
(
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0), (0 8, 8 5, 8 8, 0 8))",
|
||||
"POLYGON((0 8,-8 5,-8 8,0 8))",
|
||||
true
|
||||
);
|
||||
test_touches<polygon, polygon>
|
||||
(
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0), (0 6, 6 3, 6 6, 0 6))",
|
||||
"POLYGON((0 6,-6 3,-6 6,0 6))",
|
||||
true
|
||||
);
|
||||
|
||||
// Point-Polygon
|
||||
test_touches<P, ring>("POINT(40 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true);
|
||||
test_touches<P, polygon>("POINT(40 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014. 2015.
|
||||
// This file was modified by Oracle on 2013, 2014, 2015.
|
||||
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@@ -42,6 +42,7 @@ void test_box_3d()
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
test_all<bg::model::d2::point_xy<double> >();
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
// This file was modified by Oracle on 2014, 2015.
|
||||
// Modifications copyright (c) 2014-2015 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)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#include "test_within.hpp"
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// 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
|
||||
@@ -86,6 +87,81 @@ void test_areal_linear()
|
||||
test_one_lp<LineString, LineString, Polygon>("case25", "LINESTRING(4 0,4 5,7 5)", poly_9, 2, 5, 5.0);
|
||||
test_one_lp<LineString, LineString, Polygon>("case26", "LINESTRING(4 0,4 3,4 5,7 5)", poly_9, 2, 5, 5.0);
|
||||
test_one_lp<LineString, LineString, Polygon>("case27", "LINESTRING(4 4,4 5,5 5)", poly_9, 1, 3, 2.0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case28",
|
||||
"LINESTRING(-1.3 0,-15 0,-1.3 0)",
|
||||
"POLYGON((2 3,-9 -7,12 -13,2 3))",
|
||||
1, 3, 27.4);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case29",
|
||||
"LINESTRING(5 5,-10 5,5 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
1, 3, 20);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case29a",
|
||||
"LINESTRING(1 1,5 5,-10 5,5 5,6 6)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
1, 3, 20);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case30",
|
||||
"LINESTRING(-10 5,5 5,-10 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
2, 4, 20);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case30a",
|
||||
"LINESTRING(-20 10,-10 5,5 5,-10 5,-20 -10)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
2, 6, 49.208096);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case31",
|
||||
"LINESTRING(0 5,5 5,0 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case31",
|
||||
"LINESTRING(0 5,5 5,1 1,9 1,5 5,0 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case32",
|
||||
"LINESTRING(5 5,0 5,5 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case32a",
|
||||
"LINESTRING(-10 10,5 5,0 5,5 5,20 10)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
2, 4, 21.081851);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case33",
|
||||
"LINESTRING(-5 5,0 5,-5 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case33a",
|
||||
"LINESTRING(-10 10,-5 5,0 5,-5 5,-10 -10)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
1, 5, 32.882456);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case33b",
|
||||
"LINESTRING(0 5,-5 5,0 5)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case34",
|
||||
"LINESTRING(5 5,0 5,5 5,5 4,0 4,5 4)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case35",
|
||||
"LINESTRING(5 5,0 5,5 5,5 4,0 4,5 3)",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, LineString, Polygon>("case36",
|
||||
"LINESTRING(-1 -1,10 10)",
|
||||
"POLYGON((5 5,15 15,15 5,5 5))",
|
||||
1, 2, 6 * std::sqrt(2.0));
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
@@ -599,6 +675,21 @@ void test_all()
|
||||
5, 22, 1.1901714,
|
||||
5, 27, 1.6701714);
|
||||
***/
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_ENABLE_FAILING
|
||||
test_one<polygon, polygon, polygon>("ticket_11725_2",
|
||||
"POLYGON((0 0,0 3,3 3,3 0,0 0))",
|
||||
"POLYGON((3 1,1 1,1 2,2 2,3 1))",
|
||||
2, -1, 7.5, 0, -1, 0.0);
|
||||
test_one<polygon, polygon, polygon>("mysql_21977775",
|
||||
"POLYGON((8 6,5 7,-1 4,-8 -7, 0 -17, 8 6), (3 6, 5 5, 0 -2, 3 6))",
|
||||
"POLYGON((3 3,-17 11,-8 -3, 3 3))",
|
||||
2, -1, 160.856568913, 2, -1, 92.3565689126);
|
||||
test_one<polygon, polygon, polygon>("mysql_21965285",
|
||||
"POLYGON((7 3,0 10,0 -6, 9 -5, 7 7, 7 3), (0 8, 2 3, 2 -2, 0 8))",
|
||||
"POLYGON((0 6,0 8,-14 13,0 6))",
|
||||
0, -1, 0.0, 0, -1, 0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******
|
||||
|
||||
@@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE( test_difference_linestring_linestring )
|
||||
from_wkt<L>("LINESTRING(0 -.2, 8 1)"),
|
||||
from_wkt<ML>("MULTILINESTRING((4 .4,2 8))"),
|
||||
"lldf31x",
|
||||
4.0 * std::numeric_limits<double>::epsilon()
|
||||
1e-10
|
||||
);
|
||||
|
||||
tester::apply
|
||||
@@ -561,7 +561,7 @@ BOOST_AUTO_TEST_CASE( test_difference_linestring_linestring )
|
||||
from_wkt<L>("LINESTRING(0 -.2, 8 1)"),
|
||||
from_wkt<ML>("MULTILINESTRING((2 8,4 .4))"),
|
||||
"lldf31x-r",
|
||||
4.0 * std::numeric_limits<double>::epsilon()
|
||||
1e-10
|
||||
);
|
||||
|
||||
tester::apply
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
<< ", difference L/L: " << bg::wkt(geometry1)
|
||||
<< " " << bg::wkt(geometry2)
|
||||
<< " -> Expected: " << bg::wkt(mls_diff)
|
||||
<< std::setprecision(20)
|
||||
<< " computed: " << bg::wkt(mls_output) );
|
||||
|
||||
set_operation_output("difference", case_id,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// 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.
|
||||
@@ -323,14 +324,20 @@ void test_areal()
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
|
||||
1, 29, 0.457126);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_ENABLE_FAILING
|
||||
test_one<Polygon, Polygon, Polygon>("mysql_21964465",
|
||||
"POLYGON((0 0,0 10,10 10,10 0, 0 0), (0 8, 4 4, 4 6, 0 8))",
|
||||
"POLYGON((0 8,-8 8,-2 2,0 8))",
|
||||
0, -1, 0.0);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>(
|
||||
"polygon_pseudo_line",
|
||||
"Polygon((0 0,0 4,4 4,4 0,0 0))",
|
||||
"Polygon((2 -2,2 -1,2 6,2 -2))",
|
||||
5, 22, 1.1901714);
|
||||
"polygon_pseudo_line",
|
||||
"Polygon((0 0,0 4,4 4,4 0,0 0))",
|
||||
"Polygon((2 -2,2 -1,2 6,2 -2))",
|
||||
5, 22, 1.1901714);
|
||||
}
|
||||
|
||||
template <typename Polygon, typename Box>
|
||||
@@ -446,6 +453,86 @@ void test_areal_linear()
|
||||
test_one_lp<LineString, Polygon, LineString>("case19", poly_9, "LINESTRING(1 2,1 3,0 3)", 1, 2, 1.0);
|
||||
test_one_lp<LineString, Polygon, LineString>("case20", poly_9, "LINESTRING(1 2,1 3,2 3)", 1, 3, 2.0);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case21",
|
||||
"POLYGON((2 3,-9 -7,12 -13,2 3))",
|
||||
"LINESTRING(-1.3 0,-15 0,-1.3 0)",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case22",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(5 5,-10 5,5 5)",
|
||||
2, 4, 10);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case22a",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(1 1,5 5,-10 5,5 5,6 6)",
|
||||
2, 6, 17.071068);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case23",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-10 5,5 5,-10 5)",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case23a",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-20 10,-10 5,5 5,-10 5,-20 -10)",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case24",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(0 5,5 5,0 5)",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case24",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(0 5,5 5,1 1,9 1,5 5,0 5)",
|
||||
1, 6, 29.313708);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case25",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(5 5,0 5,5 5)",
|
||||
1, 3, 10);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case25a",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-10 10,5 5,0 5,5 5,20 10)",
|
||||
1, 4, 20.540925);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case25b",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-10 10,5 5,1 5,5 5,20 10)",
|
||||
1, 4, 18.540925);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case25c",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-10 10,5 5,-1 5,5 5,20 10)",
|
||||
2, 6, 20.540925);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case26",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-5 5,0 5,-5 5)",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case26a",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(-10 10,-5 5,0 5,-5 5,-10 -10)",
|
||||
0, 0, 0);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case27",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(5 5,0 5,5 5,5 4,0 4,5 4)",
|
||||
1, 6, 21.0);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case28",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"LINESTRING(5 5,0 5,5 5,5 4,0 4,5 3)",
|
||||
1, 6, 21.099019);
|
||||
|
||||
test_one_lp<LineString, Polygon, LineString>("case29",
|
||||
"POLYGON((5 5,15 15,15 5,5 5))",
|
||||
"LINESTRING(0 0,10 10)",
|
||||
1, 2, 5 * std::sqrt(2.0));
|
||||
|
||||
// PROPERTIES CHANGED BY switch_to_integer
|
||||
// TODO test_one_lp<LineString, Polygon, LineString>("case21", poly_9, "LINESTRING(1 2,1 4,4 4,4 1,2 1,2 2)", 1, 6, 11.0);
|
||||
|
||||
@@ -681,6 +768,7 @@ void test_boxes_nd()
|
||||
test_boxes_per_d(p3(0,0,0), p3(5,5,5), p3(3,3,3), p3(6,6,6), true);
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateType>
|
||||
void test_ticket_10868(std::string const& wkt_out)
|
||||
{
|
||||
|
||||
@@ -257,6 +257,9 @@ void test_one_lp(std::string const& caseid,
|
||||
double percentage = 0.0001,
|
||||
bool debug1 = false, bool debug2 = false)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
std::cout << caseid << " -- start" << std::endl;
|
||||
#endif
|
||||
Areal areal;
|
||||
bg::read_wkt(wkt_areal, areal);
|
||||
bg::correct(areal);
|
||||
@@ -274,6 +277,9 @@ void test_one_lp(std::string const& caseid,
|
||||
test_intersection<OutputType, void>(caseid + "_rev", areal, linear,
|
||||
expected_count, expected_point_count,
|
||||
expected_length, percentage, debug2);
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
std::cout << caseid << " -- end" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// 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
|
||||
@@ -51,6 +52,7 @@ void test_union(std::string const& caseid, G1 const& g1, G2 const& g2,
|
||||
{
|
||||
typedef typename bg::coordinate_type<G1>::type coordinate_type;
|
||||
boost::ignore_unused<coordinate_type>();
|
||||
boost::ignore_unused(expected_point_count);
|
||||
|
||||
std::vector<OutputType> clip;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// 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) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -248,7 +248,7 @@ void test_areal()
|
||||
1,
|
||||
0,
|
||||
-1,
|
||||
313.36036462, 0.01);
|
||||
313.36036462, 0.1);
|
||||
|
||||
// SQL Server gives: 313.360374193241
|
||||
// PostGIS gives: 313.360364623393
|
||||
@@ -319,10 +319,8 @@ void test_areal()
|
||||
1, 0, if_typed<ct, double>(18, 23), 4.60853);
|
||||
#endif
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
|
||||
1, 0, if_typed<ct, float>(18, 17), 16.571);
|
||||
#endif
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_g_rev", buffer_rt_g[1], buffer_rt_g[0],
|
||||
1, 0, if_typed<ct, float>(18, 17), 16.571);
|
||||
|
||||
@@ -355,10 +353,8 @@ void test_areal()
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_m2_rev", buffer_rt_m2[1], buffer_rt_m2[0],
|
||||
1, 0, if_typed_tt<ct>(20, 19), 21.4853);
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_q", buffer_rt_q[0], buffer_rt_q[1],
|
||||
1, 0, 18, 18.5710);
|
||||
#endif
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_q_rev", buffer_rt_q[1], buffer_rt_q[0],
|
||||
1, 0, 18, 18.5710);
|
||||
|
||||
@@ -376,13 +372,30 @@ void test_areal()
|
||||
1, 0, if_typed_tt<ct>(16, if_typed<ct, float>(15, 14)), 15.6569);
|
||||
#endif
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_mp1", buffer_mp1[0], buffer_mp1[1],
|
||||
1, 0, if_typed_tt<ct>(93, 91), 22.815);
|
||||
#endif
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
|
||||
1, 0, 217, 36.752837);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_ENABLE_FAILING
|
||||
test_one<Polygon, Polygon, Polygon>("ticket_11725",
|
||||
"POLYGON((0 0, 0 1, 3 1, 3 0, 0 0))",
|
||||
"POLYGON((0 1, 0 3, 3 3, 3 1, 2 2, 1 2 , 1 1, 0 1))",
|
||||
1, 1, -1, 7.5);
|
||||
test_one<Polygon, Polygon, Polygon>("mysql_21964079_1",
|
||||
"POLYGON((7 3,0 10,0 -6,9 -5, 7 7, 7 3), (0 8, 2 3, 2 -2, 0 8))",
|
||||
"POLYGON((0 8,-8 14,-11 18,-19 11, -3 1, 0 8))",
|
||||
2, 1, -1, 234.5);
|
||||
test_one<Polygon, Polygon, Polygon>("mysql_21964079_2",
|
||||
"POLYGON((0 0,0 10,10 10,10 0,0 0), (0 8, 4 4, 4 6, 0 8))",
|
||||
"POLYGON((0 8,-8 8,-10 4,0 8))",
|
||||
2, 1, -1, 112.0);
|
||||
test_one<Polygon, Polygon, Polygon>("mysql_21964049",
|
||||
"POLYGON((7 0,10 -3,7 1,7 0))",
|
||||
"POLYGON((7 4,-14 10,7 -17,7 4),(7 1,0 3,-2 4,7 1))",
|
||||
1, 1, -1, 220.5);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -113,6 +113,13 @@ void test_areal()
|
||||
case_recursive_boxes_3[0], case_recursive_boxes_3[1],
|
||||
17, 0, 159, 56.5); // Area from SQL Server
|
||||
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_4",
|
||||
case_recursive_boxes_4[0], case_recursive_boxes_4[1],
|
||||
1, 1, 42, 96.75);
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_5",
|
||||
case_recursive_boxes_5[0], case_recursive_boxes_5[1],
|
||||
3, 2, 110, 70.0);
|
||||
|
||||
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
|
||||
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
|
||||
1, 0, 12, 23.0); // Area from SQL Server
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
test-suite boost-geometry-arithmetic
|
||||
:
|
||||
[ run arithmetic.cpp : : : : arithmetic ]
|
||||
[ run general.cpp : : : : arithmetic_general ]
|
||||
[ run dot_product.cpp : : : : arithmetic_dot_product ]
|
||||
;
|
||||
|
||||
@@ -25,6 +25,6 @@ test-suite boost-geometry-geometries
|
||||
# geometries_custom_linestring_test_fail_clear
|
||||
#]
|
||||
[ run custom_linestring.cpp : : : : geometries_custom_linestring ]
|
||||
[ run geometries.cpp : : : : geometries ]
|
||||
[ run initialization.cpp : : : : geometries_initialization ]
|
||||
[ run segment.cpp : : : : geometries_segment ]
|
||||
;
|
||||
|
||||
@@ -33,12 +33,12 @@ void test_geometry(std::string const& wkt)
|
||||
|
||||
|
||||
// Run 3 times through the geometry
|
||||
int n = boost::size(geo) * 3;
|
||||
std::size_t n = boost::size(geo) * 3;
|
||||
|
||||
{
|
||||
std::ostringstream out;
|
||||
bg::ever_circling_iterator<iterator_type> it(boost::begin(geo), boost::end(geo));
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
for (std::size_t i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
out << bg::get<0>(*it);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ void test_geometry(std::string const& wkt)
|
||||
// Start somewhere
|
||||
bg::ever_circling_iterator<iterator_type> it(
|
||||
boost::begin(geo), boost::end(geo), boost::begin(geo) + 1);
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
for (std::size_t i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
out << bg::get<0>(*it);
|
||||
}
|
||||
@@ -62,9 +62,9 @@ void test_geometry(std::string const& wkt)
|
||||
|
||||
// Navigate to somewhere
|
||||
bg::ever_circling_iterator<iterator_type> it(boost::begin(geo), boost::end(geo));
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
for (std::size_t i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
const int m = boost::size(geo);
|
||||
std::size_t const m = boost::size(geo);
|
||||
it.moveto(boost::begin(geo) + m - (i % m) - 1);
|
||||
out << bg::get<0>(*it);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ void test_geometry(std::string const& wkt)
|
||||
{
|
||||
std::ostringstream out;
|
||||
bg::ever_circling_range_iterator<G> it(geo);
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
for (std::size_t i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
out << bg::get<0>(*it);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# 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) 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) 2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software License,
|
||||
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -10,9 +11,9 @@
|
||||
|
||||
test-suite boost-geometry-views
|
||||
:
|
||||
[ run segment_view.cpp ]
|
||||
[ run box_view.cpp ]
|
||||
[ run reversible_view.cpp ]
|
||||
[ run closeable_view.cpp ]
|
||||
[ run reversible_closeable.cpp ]
|
||||
[ run segment_view.cpp : : : : views_segment_view ]
|
||||
[ run box_view.cpp : : : : views_box_view ]
|
||||
[ run reversible_view.cpp : : : : views_reversible_view ]
|
||||
[ run closeable_view.cpp : : : : views_closeable_view ]
|
||||
[ run reversible_closeable.cpp : : : : views_reversible_closeable ]
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user