Skip to content

Commit

Permalink
[algorithms] Fix covered_by() Point/Box and Box/Box in geographic CS.
Browse files Browse the repository at this point in the history
  • Loading branch information
awulkiew committed Aug 27, 2016
1 parent 2f45b5a commit 0fb9e29
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 23 deletions.
35 changes: 26 additions & 9 deletions include/boost/geometry/strategies/cartesian/box_in_box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ namespace within
{


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_within_range
struct box_within_coord
{
template <typename BoxContainedValue, typename BoxContainingValue>
static inline bool apply(BoxContainedValue const& bed_min,
Expand All @@ -51,8 +50,7 @@ struct box_within_range
};


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_covered_by_range
struct box_covered_by_coord
{
template <typename BoxContainedValue, typename BoxContainingValue>
static inline bool apply(BoxContainedValue const& bed_min,
Expand All @@ -65,7 +63,19 @@ struct box_covered_by_range
};


struct box_within_longitude_check
template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_within_range
: box_within_coord
{};


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct box_covered_by_range
: box_covered_by_coord
{};


struct box_within_longitude_diff
{
template <typename CalcT>
static inline bool apply(CalcT const& diff_ed)
Expand All @@ -74,7 +84,7 @@ struct box_within_longitude_check
}
};

struct box_covered_by_longitude_check
struct box_covered_by_longitude_diff
{
template <typename CalcT>
static inline bool apply(CalcT const&)
Expand All @@ -84,6 +94,7 @@ struct box_covered_by_longitude_check
};

template <typename Geometry,
typename CoordCheck,
typename InteriorCheck>
struct box_longitude_range
{
Expand All @@ -101,6 +112,11 @@ struct box_longitude_range
typedef typename coordinate_system<Geometry>::type::units units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;

if (CoordCheck::apply(bed_min, bed_max, bing_min, bing_max))
{
return true;
}

// min <= max <=> diff >= 0
calc_t const diff_ed = bed_max - bed_min;
calc_t const diff_ing = bing_max - bing_min;
Expand All @@ -122,21 +138,22 @@ struct box_longitude_range
calc_t const diff_min = math::longitude_distance_unsigned<units_t>(bing_min, bed_min);

// max of contained translated into the containing origin must be lesser than max of containing
return bing_min + diff_min + diff_ed <= bing_max;
return bing_min + diff_min + diff_ed <= bing_max
/*|| bing_max - diff_min - diff_ed >= bing_min*/;
}
};


// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Geometry>
struct box_within_range<Geometry, 0, spherical_tag>
: box_longitude_range<Geometry, box_within_longitude_check>
: box_longitude_range<Geometry, box_within_coord, box_within_longitude_diff>
{};


template <typename Geometry>
struct box_covered_by_range<Geometry, 0, spherical_tag>
: box_longitude_range<Geometry, box_covered_by_longitude_check>
: box_longitude_range<Geometry, box_covered_by_coord, box_covered_by_longitude_diff>
{};


Expand Down
44 changes: 30 additions & 14 deletions include/boost/geometry/strategies/cartesian/point_in_box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ namespace boost { namespace geometry { namespace strategy
namespace within
{


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct within_range
struct within_coord
{
template <typename Value1, typename Value2>
static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
Expand All @@ -44,9 +42,7 @@ struct within_range
}
};


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct covered_by_range
struct covered_by_coord
{
template <typename Value1, typename Value2>
static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
Expand All @@ -55,32 +51,47 @@ struct covered_by_range
}
};

template <typename Geometry, std::size_t Dimension, typename CSTag>
struct within_range
: within_coord
{};


template <typename Geometry, std::size_t Dimension, typename CSTag>
struct covered_by_range
: covered_by_coord
{};


// NOTE: the result would be the same if instead of structs defined below
// the above xxx_range were used with the following arguments:
// (min_value + diff_min, min_value, max_value)
struct within_longitude_range
struct within_longitude_diff
{
template <typename CalcT>
static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
{
CalcT const c0 = 0;
return diff_min > c0 && min_value + diff_min < max_value;
return diff_min > c0
&& (min_value + diff_min < max_value
/*|| max_value - diff_min > min_value*/);
}
};

struct covered_by_longitude_range
struct covered_by_longitude_diff
{
template <typename CalcT>
static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
{
return min_value + diff_min <= max_value;
return min_value + diff_min <= max_value
/*|| max_value - diff_min >= min_value*/;
}
};


template <typename Geometry,
typename ResultCheck>
typename CoordCheck,
typename DiffCheck>
struct longitude_range
{
template <typename Value1, typename Value2>
Expand All @@ -93,6 +104,11 @@ struct longitude_range
typedef typename coordinate_system<Geometry>::type::units units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;

if (CoordCheck::apply(value, min_value, max_value))
{
return true;
}

// min <= max <=> diff >= 0
calc_t const diff_ing = max_value - min_value;

Expand All @@ -105,21 +121,21 @@ struct longitude_range
// calculate positive longitude translation with min_value as origin
calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value);

return ResultCheck::template apply<calc_t>(diff_min, min_value, max_value);
return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value);
}
};


// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Geometry>
struct within_range<Geometry, 0, spherical_tag>
: longitude_range<Geometry, within_longitude_range>
: longitude_range<Geometry, within_coord, within_longitude_diff>
{};


template <typename Geometry>
struct covered_by_range<Geometry, 0, spherical_tag>
: longitude_range<Geometry, covered_by_longitude_range>
: longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff>
{};


Expand Down

0 comments on commit 0fb9e29

Please sign in to comment.