[buffer][fix] to get a proper rescale policy, the buffer distance must be added

This commit is contained in:
Barend Gehrels 2014-07-23 15:13:16 +02:00
parent dd418dbc69
commit 1fa87bcbba
9 changed files with 73 additions and 6 deletions

View File

@ -22,10 +22,11 @@
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
@ -259,8 +260,12 @@ inline void buffer(GeometryIn const& geometry_in,
geometry_out.clear();
model::box<point_type> box;
envelope(geometry_in, box);
buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(geometry_in);
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
detail::buffer::buffer_inserter<polygon_type>(geometry_in, std::back_inserter(geometry_out),
distance_strategy,

View File

@ -74,13 +74,26 @@ public :
return m_left < 0 && m_right < 0;
}
//! Returns the max distance distance up to the buffer will reach
template <typename JoinStrategy, typename EndStrategy>
inline NumericType max_distance(JoinStrategy const& join_strategy,
EndStrategy const& end_strategy) const
{
NumericType const left = geometry::math::abs(m_left);
NumericType const right = geometry::math::abs(m_right);
NumericType const dist = (std::max)(left, right);
return (std::max)(join_strategy.max_distance(dist),
end_strategy.max_distance(dist));
}
//! Returns the distance at which the input is simplified before the buffer process
inline NumericType simplify_distance() const
{
NumericType const left = geometry::math::abs(m_left);
NumericType const right = geometry::math::abs(m_right);
return (left < right ? left : right) / 1000.0;
return (std::min)(left, right) / 1000.0;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :

View File

@ -71,6 +71,17 @@ public :
return m_distance < 0;
}
//! Returns the max distance distance up to the buffer will reach
template <typename JoinStrategy, typename EndStrategy>
inline NumericType max_distance(JoinStrategy const& join_strategy,
EndStrategy const& end_strategy) const
{
NumericType const dist = geometry::math::abs(m_distance);
return (std::max)(join_strategy.max_distance(dist),
end_strategy.max_distance(dist));
}
//! Returns the distance at which the input is simplified before the buffer process
inline NumericType simplify_distance() const
{

View File

@ -90,6 +90,12 @@ public :
// In other cases it does no harm but is further useless
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
//! Returns the piece_type (flat end)
static inline piece_type get_piece_type()
{

View File

@ -144,6 +144,12 @@ public :
}
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
//! Returns the piece_type (flat end)
static inline piece_type get_piece_type()
{

View File

@ -105,6 +105,13 @@ public:
range_out.push_back(perp2);
return true;
}
template <typename NumericType>
inline NumericType max_distance(NumericType const& distance) const
{
return distance * m_miter_limit;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :

View File

@ -108,6 +108,7 @@ private :
public :
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//! Fills output_range with a rounded shape around a vertex
template <typename Point, typename DistanceType, typename RangeOut>
@ -155,6 +156,13 @@ public :
range_out.push_back(perp2);
return true;
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
private :

View File

@ -136,6 +136,12 @@ public :
return true;
}
template <typename NumericType>
static inline NumericType max_distance(NumericType const& distance)
{
return distance;
}
private :
std::size_t m_max_level;
};

View File

@ -347,6 +347,9 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
distance_right = distance_left;
}
bg::model::box<point_type> envelope;
bg::envelope(geometry, envelope);
std::string join_name = JoinTestProperties<JoinStrategy>::name();
std::string end_name = EndTestProperties<EndStrategy>::name();
@ -378,10 +381,9 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
mapper_type mapper(svg, 1000, 1000);
{
bg::model::box<point_type> box;
bg::envelope(geometry, box);
double d = std::abs(distance_left) + std::abs(distance_right);
bg::model::box<point_type> box = envelope;
bg::buffer(box, box, d * (join_name == "miter" ? 2.0 : 1.1));
mapper.add(box);
}
@ -408,8 +410,11 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
typedef typename bg::rescale_policy_type<point_type>::type
rescale_policy_type;
// Enlarge the box to get a proper rescale policy
bg::buffer(envelope, envelope, distance_strategy.max_distance(join_strategy, end_strategy));
rescale_policy_type rescale_policy
= bg::get_rescale_policy<rescale_policy_type>(geometry);
= bg::get_rescale_policy<rescale_policy_type>(envelope);
std::vector<GeometryOut> buffered;