[relate] cleanup, increase the readability of relate() dispatching, remove unneeded code

This commit is contained in:
Adam Wulkiewicz
2014-04-09 21:53:12 +02:00
parent 9b384bbcab
commit ccc40d3a0b
4 changed files with 112 additions and 292 deletions

View File

@@ -23,8 +23,6 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/relate/relate.hpp>
@@ -32,46 +30,6 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace crosses
{
struct use_relate
{
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
{
typedef typename detail::relate::
static_mask_crosses_type<Geometry1, Geometry2>::type static_mask;
return detail::relate::relate<static_mask>(g1, g2);
}
};
}} // namespace detail::crosses
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename Geometry1,
typename Geometry2,
typename Tag1 = typename tag<Geometry1>::type,
typename Tag2 = typename tag<Geometry2>::type
>
struct crosses
: detail::crosses::use_relate
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
/*!
\brief \brief_check2{crosses}
\ingroup crosses
@@ -89,11 +47,10 @@ inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
return dispatch::crosses
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2);
typedef typename detail::relate::
static_mask_crosses_type<Geometry1, Geometry2>::type static_mask;
return detail::relate::relate<static_mask>(geometry1, geometry2);
}
}} // namespace boost::geometry

View File

@@ -100,8 +100,9 @@ public:
// Check if any interior ring is outside
ring_identifier ring_id(0, -1, 0);
for ( ; ring_id.ring_index < boost::numeric_cast<int>(geometry::num_interior_rings(areal)) ;
++ring_id.ring_index )
int const irings_count = boost::numeric_cast<int>(
geometry::num_interior_rings(areal) );
for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -135,8 +136,9 @@ public:
// Check if any interior ring is inside
ring_identifier ring_id(0, -1, 0);
for ( ; ring_id.ring_index < boost::numeric_cast<int>(geometry::num_interior_rings(areal)) ;
++ring_id.ring_index )
int const irings_count = boost::numeric_cast<int>(
geometry::num_interior_rings(areal) );
for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -237,9 +239,7 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 0> analyser;
analyse_each_turn(result, analyser,
turns.begin(), turns.end(),
geometry1, geometry2);
analyse_each_turn(result, analyser, turns.begin(), turns.end());
if ( result.interrupt )
return;
@@ -278,9 +278,7 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 1> analyser;
analyse_each_turn(result, analyser,
turns.begin(), turns.end(),
geometry2, geometry1);
analyse_each_turn(result, analyser, turns.begin(), turns.end());
if ( result.interrupt )
return;
@@ -401,13 +399,8 @@ struct areal_areal
{}
template <typename Result,
typename TurnIt,
typename Geometry,
typename OtherGeometry>
void apply(Result & result,
TurnIt first, TurnIt it, TurnIt last,
Geometry const& geometry,
OtherGeometry const& other_geometry)
typename TurnIt>
void apply(Result & result, TurnIt it)
{
//BOOST_ASSERT( it != last );
@@ -499,14 +492,8 @@ struct areal_areal
}
// it == last
template <typename Result,
typename TurnIt,
typename Geometry,
typename OtherGeometry>
void apply(Result & result,
TurnIt first, TurnIt last,
Geometry const& geometry,
OtherGeometry const& other_geometry)
template <typename Result>
void apply(Result & result)
{
//BOOST_ASSERT( first != last );
@@ -548,30 +535,24 @@ struct areal_areal
// call analyser.apply() for each turn in range
// IMPORTANT! The analyser is also called for the end iterator - last
template <typename Result,
typename TurnIt,
typename Analyser,
typename Geometry,
typename OtherGeometry>
typename TurnIt>
static inline void analyse_each_turn(Result & res,
Analyser & analyser,
TurnIt first, TurnIt last,
Geometry const& geometry,
OtherGeometry const& other_geometry)
TurnIt first, TurnIt last)
{
if ( first == last )
return;
for ( TurnIt it = first ; it != last ; ++it )
{
analyser.apply(res, first, it, last,
geometry, other_geometry);
analyser.apply(res, it);
if ( res.interrupt )
return;
}
analyser.apply(res, first, last,
geometry, other_geometry);
analyser.apply(res);
}
template <std::size_t OpId, typename Result, typename Geometry, typename OtherGeometry>
@@ -810,16 +791,21 @@ struct areal_areal
template <typename Analyser, typename Turn>
static inline void for_preceding_rings(Analyser & analyser, Turn const& turn)
{
for_no_turns_rings(analyser, turn, -1, turn.operations[OpId].seg_id.ring_index);
segment_identifier const& seg_id = turn.operations[OpId].seg_id;
for_no_turns_rings(analyser, turn, -1, seg_id.ring_index);
}
template <typename Analyser, typename Turn>
static inline void for_following_rings(Analyser & analyser, Turn const& turn)
{
std::size_t count = geometry::num_interior_rings(
detail::single_geometry(analyser.geometry,
turn.operations[OpId].seg_id));
for_no_turns_rings(analyser, turn, turn.operations[OpId].seg_id.ring_index + 1, count);
segment_identifier const& seg_id = turn.operations[OpId].seg_id;
int count = boost::numeric_cast<int>(
geometry::num_interior_rings(
detail::single_geometry(analyser.geometry, seg_id)));
for_no_turns_rings(analyser, turn, seg_id.ring_index + 1, count);
}
template <typename Analyser, typename Turn>

View File

@@ -53,180 +53,137 @@ namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail_dispatch { namespace relate {
namespace detail { namespace relate {
// Those are used only to allow dispatch::relate to produce compile-time error
template <typename Geometry,
typename Tag = typename geometry::tag<Geometry>::type>
struct is_supported_by_generic
{
static const bool value
= boost::is_same<Tag, linestring_tag>::value
|| boost::is_same<Tag, multi_linestring_tag>::value
|| boost::is_same<Tag, ring_tag>::value
|| boost::is_same<Tag, polygon_tag>::value
|| boost::is_same<Tag, multi_polygon_tag>::value;
};
template <typename Geometry1,
typename Geometry2,
typename Tag1 = typename geometry::tag<Geometry1>::type,
typename Tag2 = typename geometry::tag<Geometry2>::type>
struct is_generic
{
static const bool value = is_supported_by_generic<Geometry1>::value
&& is_supported_by_generic<Geometry2>::value;
};
template <typename Point, typename Geometry, typename Tag>
struct is_generic<Point, Geometry, point_tag, Tag>
{
static const bool value = is_supported_by_generic<Geometry>::value;
};
template <typename Geometry, typename Point, typename Tag>
struct is_generic<Geometry, Point, Tag, point_tag>
{
static const bool value = is_supported_by_generic<Geometry>::value;
};
template <typename Point1, typename Point2>
struct is_generic<Point1, Point2, point_tag, point_tag>
{
static const bool value = false;
};
}} // namespace detail::relate
#ifndef DOXYGEN_NO_DISPATCH
namespace detail_dispatch { namespace relate {
template <typename Geometry1,
typename Geometry2,
typename Tag1 = typename geometry::tag<Geometry1>::type,
typename Tag2 = typename geometry::tag<Geometry2>::type,
int TopDim1 = geometry::topological_dimension<Geometry1>::value,
int TopDim2 = geometry::topological_dimension<Geometry2>::value,
bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
>
struct relate : not_implemented<Tag1, Tag2>
{};
template <typename Point1, typename Point2>
struct relate<Point1, Point2, point_tag, point_tag>
struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
: detail::relate::point_point<Point1, Point2>
{};
template <typename Point, typename MultiPoint>
struct relate<Point, MultiPoint, point_tag, multi_point_tag>
struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
: detail::relate::point_multipoint<Point, MultiPoint>
{};
template <typename MultiPoint, typename Point>
struct relate<MultiPoint, Point, multi_point_tag, point_tag>
struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
: detail::relate::multipoint_point<MultiPoint, Point>
{};
template <typename MultiPoint1, typename MultiPoint2>
struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag>
struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
: detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
{};
//template <typename Point, typename Box>
//struct relate<Point, Box, point_tag, box_tag>
//template <typename Point, typename Box, int TopDim2>
//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
// : detail::relate::point_box<Point, Box>
//{};
//
//template <typename Box, typename Point>
//struct relate<Box, Point, box_tag, point_tag>
//template <typename Box, typename Point, int TopDim1>
//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
// : detail::relate::box_point<Box, Point>
//{};
template <typename Point, typename Geometry, typename Tag2>
struct relate<Point, Geometry, point_tag, Tag2>
template <typename Point, typename Geometry, typename Tag2, int TopDim2>
struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
: detail::relate::point_geometry<Point, Geometry>
{};
template <typename Geometry, typename Point, typename Tag1>
struct relate<Geometry, Point, Tag1, point_tag>
template <typename Geometry, typename Point, typename Tag1, int TopDim1>
struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
: detail::relate::geometry_point<Geometry, Point>
{};
template <typename Linestring1, typename Linestring2>
struct relate<Linestring1, Linestring2, linestring_tag, linestring_tag>
: detail::relate::linear_linear<Linestring1, Linestring2>
{};
template <typename Linestring, typename MultiLinestring>
struct relate<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
: detail::relate::linear_linear<Linestring, MultiLinestring>
{};
template <typename MultiLinestring, typename Linestring>
struct relate<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
: detail::relate::linear_linear<MultiLinestring, Linestring>
{};
template <typename MultiLinestring1, typename MultiLinestring2>
struct relate<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
: detail::relate::linear_linear<MultiLinestring1, MultiLinestring2>
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
: detail::relate::linear_linear<Linear1, Linear2>
{};
template <typename Linestring, typename Polygon>
struct relate<Linestring, Polygon, linestring_tag, polygon_tag>
: detail::relate::linear_areal<Linestring, Polygon>
{};
template <typename Linestring, typename Ring>
struct relate<Linestring, Ring, linestring_tag, ring_tag>
: detail::relate::linear_areal<Linestring, Ring>
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
: detail::relate::linear_areal<Linear, Areal>
{};
template <typename Polygon, typename Linestring>
struct relate<Polygon, Linestring, polygon_tag, linestring_tag>
: detail::relate::areal_linear<Polygon, Linestring>
{};
template <typename Ring, typename Linestring>
struct relate<Ring, Linestring, ring_tag, linestring_tag>
: detail::relate::areal_linear<Ring, Linestring>
{};
template <typename Linestring, typename MultiPolygon>
struct relate<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
: detail::relate::linear_areal<Linestring, MultiPolygon>
{};
template <typename MultiPolygon, typename Linestring>
struct relate<MultiPolygon, Linestring, multi_polygon_tag, linestring_tag>
: detail::relate::areal_linear<MultiPolygon, Linestring>
{};
template <typename MultiLinestring, typename Polygon>
struct relate<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
: detail::relate::linear_areal<MultiLinestring, Polygon>
{};
template <typename MultiLinestring, typename Ring>
struct relate<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
: detail::relate::linear_areal<MultiLinestring, Ring>
{};
template <typename Polygon, typename MultiLinestring>
struct relate<Polygon, MultiLinestring, polygon_tag, multi_linestring_tag>
: detail::relate::areal_linear<Polygon, MultiLinestring>
{};
template <typename Ring, typename MultiLinestring>
struct relate<Ring, MultiLinestring, ring_tag, multi_linestring_tag>
: detail::relate::areal_linear<Ring, MultiLinestring>
{};
template <typename MultiLinestring, typename MultiPolygon>
struct relate<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
: detail::relate::linear_areal<MultiLinestring, MultiPolygon>
{};
template <typename MultiPolygon, typename MultiLinestring>
struct relate<MultiPolygon, MultiLinestring, multi_polygon_tag, multi_linestring_tag>
: detail::relate::areal_linear<MultiPolygon, MultiLinestring>
template <typename Areal, typename Linear, typename Tag1, typename Tag2>
struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
: detail::relate::areal_linear<Areal, Linear>
{};
template <typename Polygon1, typename Polygon2>
struct relate<Polygon1, Polygon2, polygon_tag, polygon_tag>
: detail::relate::areal_areal<Polygon1, Polygon2>
template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
: detail::relate::areal_areal<Areal1, Areal2>
{};
template <typename Ring, typename Polygon>
struct relate<Ring, Polygon, ring_tag, polygon_tag>
: detail::relate::areal_areal<Ring, Polygon>
{};
template <typename Polygon, typename Ring>
struct relate<Polygon, Ring, polygon_tag, ring_tag>
: detail::relate::areal_areal<Polygon, Ring>
{};
template <typename Ring1, typename Ring2>
struct relate<Ring1, Ring2, ring_tag, ring_tag>
: detail::relate::areal_areal<Ring1, Ring2>
{};
template <typename Polygon, typename MultiPolygon>
struct relate<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
: detail::relate::areal_areal<Polygon, MultiPolygon>
{};
template <typename MultiPolygon, typename Polygon>
struct relate<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
: detail::relate::areal_areal<MultiPolygon, Polygon>
{};
template <typename Ring, typename MultiPolygon>
struct relate<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
: detail::relate::areal_areal<Ring, MultiPolygon>
{};
template <typename MultiPolygon, typename Ring>
struct relate<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
: detail::relate::areal_areal<MultiPolygon, Ring>
{};
template <typename MultiPolygon1, typename MultiPolygon2>
struct relate<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
: detail::relate::areal_areal<MultiPolygon1, MultiPolygon2>
{};
}} // namespace detail_dispatch::relate
#endif // DOXYGEN_NO_DISPATCH
namespace detail { namespace relate {

View File

@@ -227,86 +227,6 @@ struct less
}
};
//template <typename Turn> inline
//bool is_valid_method(Turn const& turn)
//{
// return turn.method != detail::overlay::method_none
// && turn.method != detail::overlay::method_disjoint
// && turn.method != detail::overlay::method_error;
//}
//
//template <typename Turn> inline
//bool is_valid_operation(Turn const& turn)
//{
// BOOST_ASSERT(!turn.has(detail::overlay::operation_opposite));
// return !turn.both(detail::overlay::operation_none);
//}
//
//template <typename Turn> inline
//bool is_valid_turn(Turn const& turn)
//{
// return is_valid_method(turn) && is_valid_operation(turn);
//}
//
//template <bool IsCyclic, typename TurnIt, typename Cond> inline
//TurnIt find_next_if(TurnIt first, TurnIt current, TurnIt last, Cond cond)
//{
// if ( first == last )
// return last;
//
// if ( current != last )
// {
// TurnIt it = current;
// ++it;
//
// for ( ; it != last ; ++it )
// if ( cond(*it) )
// return it;
// }
//
// if ( IsCyclic )
// {
// for ( TurnIt it = first ; it != current ; ++it )
// if ( cond(*it) )
// return it;
// }
//
// return last;
//}
//
//template <bool IsCyclic, typename TurnIt, typename Cond> inline
//TurnIt find_previous_if(TurnIt first, TurnIt current, TurnIt last, Cond cond)
//{
// typedef std::reverse_iterator<TurnIt> Rit;
// Rit rlast = Rit(first);
// if ( current == last )
// return last;
// ++current;
// Rit res = find_next_if<IsCyclic>(Rit(last), Rit(current), rlast, cond);
// if ( res == rlast )
// return last;
// else
// return --res.base();
//}
//
//template <typename TurnIt, typename Cond> inline
//TurnIt find_first_if(TurnIt first, TurnIt last, Cond cond)
//{
// return std::find_if(first, last, cond);
//}
//
//template <typename TurnIt, typename Cond> inline
//TurnIt find_last_if(TurnIt first, TurnIt last, Cond cond)
//{
// typedef std::reverse_iterator<TurnIt> Rit;
// Rit rlast = Rit(first);
// Rit res = std::find_if(Rit(last), rlast, cond);
// if ( res == rlast )
// return last;
// else
// return --res.base();
//}
}}} // namespace detail::relate::turns
#endif // DOXYGEN_NO_DETAIL