mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-13 00:22:10 +00:00
Merge branch 'feature/relate' of https://github.com/boostorg/geometry into feature/setops
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user