Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Box-segment distance for spherical and geographic coordinate systems #478

Merged
merged 39 commits into from Jul 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1451bea
[strategies] [algorithms] Add support for geographic box-sgmt distance
vissarion Dec 11, 2017
2acdbf7
[strategies] Fix meridian case bug for pt-sgmt geo distance
vissarion Dec 11, 2017
5a0cfff
[algorithms] [envelope] Add meridian segment case
vissarion Dec 11, 2017
ea181b4
[algorithms] [strategies] [tests] Fix meridian distance point to meri…
vissarion Dec 13, 2017
27d8955
[algorithms] Some solution for correcting distance seg-box for spheri…
vissarion Dec 21, 2017
0fb5cab
[algorithms] Fix box/segment distance for segment bottom of box
vissarion Jan 11, 2018
a51b2dd
[algorithm] [test] Meridian case for segment box distance; segments l…
vissarion Jan 18, 2018
57b9cd0
[algorithms] [tests] Fix distance segment-box for spehrical and geogr…
vissarion Jan 19, 2018
b485646
[algorithms] [tests] Generic box-segment distance for both cartesian …
vissarion Jan 24, 2018
c416382
[formulas] [tests] Handle cases of geometries in both hemispheres
vissarion Mar 20, 2018
e6e1b1d
[tests] Crossing prime meridian tests
vissarion Mar 23, 2018
821bb37
[algorithms] [strategies] Fix issue with envelope segment algorithm; …
vissarion Mar 24, 2018
2b5fc9a
Merge remote-tracking branch 'origin/develop' into feature_box_seg
vissarion Mar 24, 2018
d6569be
Update include files for srs.hpp
vissarion Mar 24, 2018
3887cee
[tests] South hemispahre box-box tests
vissarion Mar 27, 2018
37c78ac
[strategies] [tests] Diagonal case fix for box-box distance
vissarion Mar 28, 2018
51a3a6b
Merge branch 'feature_box_box_fix' into feature_box_seg
vissarion Mar 28, 2018
350836f
Merge with develop branch
vissarion Mar 29, 2018
1e41a4d
[strategies] [tests] Fix pt-seg distance cases for south hemisphere
vissarion Apr 2, 2018
93bd850
[strategies] [algorithms] Azimuth strategy and box mirror function in…
vissarion Apr 2, 2018
aee17ee
[strategies] [tests] Activating some tests for pt-seg distance with t…
vissarion Apr 4, 2018
1484a0e
[strategies] [tests] Fix special case for geo pt-seg distance
vissarion Apr 5, 2018
26fb76c
[algorithms] [distance] Optimize segment check below of box
vissarion Apr 13, 2018
7f5236b
[algorithms] [distance] Use the whole segment instead of starting poi…
vissarion Apr 17, 2018
18f1394
[alsorithms] [distance] Optimization: avoid to compute vertex twice i…
vissarion Apr 17, 2018
8c09769
[algorithms] [strategies] In check segment below box function move CS…
vissarion Apr 19, 2018
e4dcc5b
[strategies] Use general units for box in segment_below_of_box strategy
vissarion Apr 20, 2018
077653f
[algorithms] [strategies] Move mirror box functionality to strategies
vissarion Apr 20, 2018
e4f55ea
[algorithms] [distance] Clean and optimize seg on the right of box di…
vissarion Apr 23, 2018
3f2660d
[tests] Remove unused strategy pt-box definitions
vissarion Apr 24, 2018
72019d5
[algorithms] [strategies] Rename meridian method to vertical_or_meridian
vissarion Apr 24, 2018
2583dec
[algorithms] [tests] Use azimuth side formula in disjoint
vissarion Apr 26, 2018
4c63f40
[strategies] Remove default values from functional templates
vissarion May 2, 2018
2c72e1d
[algorithms] [strategies] Change int return values with enums in disj…
vissarion May 11, 2018
fb7da10
[algorithms] [strategies] Change azimuth strategy interface
vissarion May 11, 2018
4f755af
[algorithms] [strategies] [tests] Create unique segment-box distance …
vissarion May 15, 2018
a54ac78
[strategies] [distance] Move vertical_or_meridian method from pt-pt t…
vissarion May 16, 2018
4a237e6
[strategies] [distance] Remove pt-pt distance strategy getters from p…
vissarion May 16, 2018
c1dd927
Fix conflicts by merging to develop
vissarion Jul 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions include/boost/geometry/algorithms/detail/assign_values.hpp
Expand Up @@ -92,6 +92,7 @@ struct assign_inverse_box_or_segment
geometry, boost::numeric::bounds<bound_type>::lowest()
);
}

};


Expand Down
61 changes: 48 additions & 13 deletions include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
Expand Up @@ -33,6 +33,7 @@
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/algorithms/envelope.hpp>

#include <boost/geometry/formulas/vertex_longitude.hpp>

Expand Down Expand Up @@ -64,10 +65,38 @@ struct disjoint_segment_box_sphere_or_spheroid

public:

struct disjoint_info
{
enum type
{
intersect,
disjoint_no_vertex,
disjoint_vertex
};
disjoint_info(type t) : m_(t){}
operator type () const {return m_;}
type m_;
private :
//prevent automatic conversion for any other built-in types
template <typename T>
operator T () const;
};

template <typename Segment, typename Box, typename Strategy>
static inline bool apply(Segment const& segment,
Box const& box,
Strategy const& azimuth_strategy)
{
typedef typename point_type<Segment>::type segment_point;
segment_point vertex;
return (apply(segment, box, azimuth_strategy, vertex) != disjoint_info::intersect);
}

template <typename Segment, typename Box, typename Strategy, typename P>
static inline disjoint_info apply(Segment const& segment,
Box const& box,
Strategy const& azimuth_strategy,
P& vertex)
{
assert_dimension_equal<Segment, Box>();

Expand All @@ -78,12 +107,15 @@ struct disjoint_segment_box_sphere_or_spheroid
geometry::detail::assign_point_from_index<0>(segment, p0);
geometry::detail::assign_point_from_index<1>(segment, p1);

//vertex not computed here
disjoint_info disjoint_return_value = disjoint_info::disjoint_no_vertex;

// Simplest cases first

// Case 1: if box contains one of segment's endpoints then they are not disjoint
if (! disjoint_point_box(p0, box) || ! disjoint_point_box(p1, box))
{
return false;
return disjoint_info::intersect;
}

// Case 2: disjoint if bounding boxes are disjoint
Expand Down Expand Up @@ -119,9 +151,10 @@ struct disjoint_segment_box_sphere_or_spheroid
box_seg,
azimuth_strategy,
alp1);

if (disjoint_box_box(box, box_seg))
{
return true;
return disjoint_return_value;
}

// Case 3: test intersection by comparing angles
Expand All @@ -138,16 +171,14 @@ struct disjoint_segment_box_sphere_or_spheroid
azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_max, a_b2);
azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_max, a_b3);

bool b0 = alp1 > a_b0;
bool b1 = alp1 > a_b1;
bool b2 = alp1 > a_b2;
bool b3 = alp1 > a_b3;
bool b0 = formula::azimuth_side_value(alp1, a_b0) > 0;
bool b1 = formula::azimuth_side_value(alp1, a_b1) > 0;
bool b2 = formula::azimuth_side_value(alp1, a_b2) > 0;
bool b3 = formula::azimuth_side_value(alp1, a_b3) > 0;

// if not all box points on the same side of the segment then
// there is an intersection
if (!(b0 && b1 && b2 && b3) && (b0 || b1 || b2 || b3))
{
return false;
return disjoint_info::intersect;
}

// Case 4: The only intersection case not covered above is when all four
Expand All @@ -157,8 +188,8 @@ struct disjoint_segment_box_sphere_or_spheroid
CT vertex_lat;
CT lat_sum = lat1 + lat2;

if ((b0 && b1 && b2 && b3 && lat_sum > CT(0))
|| (!(b0 && b1 && b2 && b3) && lat_sum < CT(0)))
if ((lat1 < b_lat_min && lat_sum > CT(0))
|| (lat1 > b_lat_max && lat_sum < CT(0)))
{
CT b_lat_below; //latitude of box closest to equator

Expand All @@ -180,18 +211,22 @@ struct disjoint_segment_box_sphere_or_spheroid
alp1,
azimuth_strategy);

geometry::set_from_radian<0>(vertex, vertex_lon);
geometry::set_from_radian<1>(vertex, vertex_lat);
disjoint_return_value = disjoint_info::disjoint_vertex; //vertex_computed

// Check if the vertex point is within the band defined by the
// minimum and maximum longitude of the box; if yes, then return
// false if the point is above the min latitude of the box; return
// true in all other cases
if (vertex_lon >= b_lon_min && vertex_lon <= b_lon_max
&& std::abs(vertex_lat) > std::abs(b_lat_below))
{
return false;
return disjoint_info::intersect;
}
}

return true;
return disjoint_return_value;
}
};

Expand Down
Expand Up @@ -110,6 +110,26 @@ struct default_strategy<Box1, Box2, box_tag, box_tag, false>
>
{};

template <typename Linear, typename Box>
struct default_strategy<Linear, Box, segment_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
segment_tag, box_tag,
typename point_type<Linear>::type,
typename point_type<Box>::type
>
{};

template <typename Linear, typename Box>
struct default_strategy<Linear, Box, linear_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
segment_tag, box_tag,
typename point_type<Linear>::type,
typename point_type<Box>::type
>
{};



// Helper metafunction for default point-segment strategy retrieval
Expand Down
Expand Up @@ -110,6 +110,19 @@ struct distance
>
{};

template <typename Linear, typename Box, typename Strategy>
struct distance
<
Linear, Box, Strategy,
linear_tag, box_tag,
strategy_tag_distance_segment_box, false
>
: detail::distance::linear_to_areal
<
Linear, Box, Strategy
>
{};


template <typename Areal, typename Linear, typename Strategy>
struct distance
Expand Down