Merge branch 'feature/relate' of https://github.com/boostorg/geometry into feature/setops

This commit is contained in:
Menelaos Karavelas
2014-02-12 18:06:37 +02:00
3 changed files with 107 additions and 25 deletions

View File

@@ -490,7 +490,9 @@ struct get_turn_info_linear_linear
bool append0_first = enable_first && (p0_first || q0_first);
bool append0_last = enable_last && (p0_last || q0_last);
result_ignore_ip0 = append0_last;
result_ignore_ip0 = !opposite ? // <=> ip_count == 1 || ip_count == 2 && !opposite
append0_last :
(append0_last && p0j);
if ( append0_first || append0_last )
{
@@ -529,7 +531,9 @@ struct get_turn_info_linear_linear
bool append1_first = enable_first && (p1_first || q1_first);
bool append1_last = enable_last && (p1_last || q1_last);
result_ignore_ip1 = append1_last;
result_ignore_ip1 = !opposite ? // <=> ip_count == 2 && !opposite
append1_last :
(append1_last && q1j);
if ( append1_first || append1_last )
{
@@ -554,8 +558,7 @@ struct get_turn_info_linear_linear
}
}
return ip_count == 1 ? result_ignore_ip0 :
!opposite ? result_ignore_ip1 : result_ignore_ip0;
return result_ignore_ip0 || result_ignore_ip1;
}
template<typename Point, typename Point1, typename Point2>

View File

@@ -53,6 +53,8 @@ inline void update_result(result & res)
// boundary_checker
enum boundary_query { boundary_front, boundary_back, boundary_front_explicit, boundary_back_explicit, boundary_any };
template <typename Geometry,
typename Tag = typename geometry::tag<Geometry>::type>
class boundary_checker {};
@@ -68,7 +70,7 @@ public:
, geometry(g)
{}
// TODO: optimization expect ENTRY or EXIT
template <boundary_query BoundaryQuery>
bool is_boundary(point_type const& pt, segment_identifier const& sid)
{
// TODO: replace with assert?
@@ -77,11 +79,28 @@ public:
// TODO: handle also linestrings with points_num == 2 and equals(front, back) - treat like point?
return has_boundary
&& ( ( sid.segment_index == 0
&& detail::equals::equals_point_point(pt, range::front(geometry)) )
|| ( sid.segment_index + 2 == geometry::num_points(geometry)
&& detail::equals::equals_point_point(pt, range::back(geometry)) ) );
if ( !has_boundary )
return false;
if ( BoundaryQuery == boundary_front_explicit || BoundaryQuery == boundary_back_explicit )
return true;
if ( BoundaryQuery == boundary_front )
return sid.segment_index == 0
&& detail::equals::equals_point_point(pt, range::front(geometry));
if ( BoundaryQuery == boundary_back )
return sid.segment_index + 2 == geometry::num_points(geometry)
&& detail::equals::equals_point_point(pt, range::back(geometry));
if ( BoundaryQuery == boundary_any )
return sid.segment_index == 0
&& detail::equals::equals_point_point(pt, range::front(geometry))
|| sid.segment_index + 2 == geometry::num_points(geometry)
&& detail::equals::equals_point_point(pt, range::back(geometry));
BOOST_ASSERT(false);
return false;
}
private:
@@ -99,7 +118,7 @@ public:
: is_filled(false), geometry(g)
{}
// TODO: optimization expect ENTRY or EXIT
template <boundary_query BoundaryQuery>
bool is_boundary(point_type const& pt, segment_identifier const& sid)
{
typedef typename boost::range_size<Geometry>::type size_type;
@@ -109,8 +128,23 @@ public:
if ( multi_count < 1 )
return false;
if ( sid.segment_index != 0 && sid.segment_index + 2 != geometry::num_points(geometry) )
return false;
if ( BoundaryQuery == boundary_front || BoundaryQuery == boundary_front_explicit )
{
if ( sid.segment_index != 0 )
return false;
}
if ( BoundaryQuery == boundary_back || BoundaryQuery == boundary_back_explicit )
{
if ( sid.segment_index + 2 != geometry::num_points(geometry) )
return false;
}
if ( BoundaryQuery == boundary_any )
{
if ( sid.segment_index != 0 && sid.segment_index + 2 != geometry::num_points(geometry) )
return false;
}
if ( ! is_filled )
{
@@ -444,10 +478,14 @@ struct linear_linear
update_result<interior, interior, '1', reverse_result>(res);
// going inside on boundary point
if ( boundary_checker.is_boundary(it->point, seg_id) )
if ( boundary_checker.template is_boundary<boundary_front>(it->point, seg_id) )
{
// TODO: check operation_blocked here - only for Ls, for MLs it's not enough
if ( other_boundary_checker.is_boundary(it->point, other_id) )
bool other_b =
it->operations[OtherOpId].operation == overlay::operation_blocked ?
other_boundary_checker.template is_boundary<boundary_back_explicit>(it->point, other_id) :
other_boundary_checker.template is_boundary<boundary_any>(it->point, other_id);
if ( other_b )
{
update_result<boundary, boundary, '0', reverse_result>(res);
}
@@ -481,12 +519,13 @@ struct linear_linear
if ( is_last_point )
{
// check if this is indeed the boundary point
// TODO: For Linestring it's enough to check has_boundary
// because we know that this is the last point of the range
if ( boundary_checker.is_boundary(it->point, seg_id) )
if ( boundary_checker.template is_boundary<boundary_back_explicit>(it->point, seg_id) )
{
// TODO: check operation_blocked here - only for Ls, for MLs it's not enough
if ( other_boundary_checker.is_boundary(it->point, other_id) )
bool other_b =
it->operations[OtherOpId].operation == overlay::operation_blocked ?
other_boundary_checker.template is_boundary<boundary_back_explicit>(it->point, other_id) :
other_boundary_checker.template is_boundary<boundary_any>(it->point, other_id);
if ( other_b )
{
update_result<boundary, boundary, '0', reverse_result>(res);
}
@@ -512,11 +551,17 @@ struct linear_linear
}
else
{
// TODO: check operation_blocked here - only for Ls, for MLs it's not enough
if ( boundary_checker.is_boundary(it->point, seg_id) )
bool this_b =
is_last_point ?
boundary_checker.template is_boundary<boundary_back_explicit>(it->point, seg_id) :
boundary_checker.template is_boundary<boundary_front>(it->point, seg_id);
if ( this_b )
{
// TODO: check operation_blocked here - only for Ls, for MLs it's not enough
if ( other_boundary_checker.is_boundary(it->point, other_id) )
bool other_b =
it->operations[OtherOpId].operation == overlay::operation_blocked ?
other_boundary_checker.template is_boundary<boundary_back_explicit>(it->point, other_id) :
other_boundary_checker.template is_boundary<boundary_any>(it->point, other_id);
if ( other_b )
update_result<boundary, boundary, '0', reverse_result>(res);
else
update_result<boundary, interior, '0', reverse_result>(res);

View File

@@ -138,6 +138,22 @@ void test_geometry(std::string const& wkt1, std::string const& wkt2,
test_geometry<G1, G2>(wkt1, wkt2, expected);
}
struct expected_pusher
{
expected_pusher & operator()(std::string const& ex)
{
vec.push_back(ex);
return *this;
}
std::vector<std::string> vec;
};
expected_pusher expected(std::string const& ex)
{
expected_pusher res;
return res(ex);
}
//TEST
//#include <to_svg.hpp>
//#include <boost/geometry.hpp>
@@ -192,12 +208,30 @@ void test_all()
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(-1 -1,1 0,10 0,20 -1)", "mii", "txu");
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(20 -1,10 0,1 0,-1 -1)", "miu", "txi");
test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)",
"LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)",
expected("tii")("ecc")("muu")("mii")("muu")("mii")("mux").vec);
test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)",
"LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)",
expected("tiu")("ecc")("mui")("miu")("mui")("miu")("mui").vec);
test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)",
"LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)",
expected("tui")("ecc")("miu")("mui")("miu")("mui")("mix").vec);
test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)",
"LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)",
expected("tuu")("ecc")("mii")("muu")("mii")("muu")("mii").vec);
//if ( boost::is_same<T, double>::value )
//{
// to_svg<ls, ls>("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(0 0,2 0,2.5 0,3 1)", "test11.svg");
// to_svg<ls, ls>("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(3 1,2.5 0,2 0,0 0)", "test12.svg");
// to_svg<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,20 0,30 0,31 1)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test21.svg");
// to_svg<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,20 0,30 0,31 1)", "LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)", "test22.svg");
// to_svg<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)", "LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)", "test31.svg");
// to_svg<ls, ls>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test32.svg");
// to_svg<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)", "test33.svg");
// to_svg<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test34.svg");
//}
}