3#ifndef BOAT_GEOMETRY_ALGORITHM_HPP
4#define BOAT_GEOMETRY_ALGORITHM_HPP
6#include <boat/detail/numbers.hpp>
8#include <boost/geometry.hpp>
15 auto a = mbr.min_corner(), b = mbr.max_corner();
16 return std::views::iota(0uz, num_points) |
18 return {std::lerp(a.x(), b.x(), frac(n * numbers::inv_phi)),
19 std::lerp(a.y(), b.y(), (n + .5) / num_points)};
27 auto num_per_edge = num_points >= 4 ? (num_points / 4 - 1) : 0;
28 for (
auto tup : boost::geometry::box_view{mbr} | std::views::pairwise) {
29 auto a = std::get<0>(tup), b = std::get<1>(tup);
31 for (
auto n : std::views::iota(0uz, num_per_edge)) {
32 auto t = (n + 1.) / (num_per_edge + 1.);
33 ret.emplace_back(std::lerp(a.x(), b.x(), t),
34 std::lerp(a.y(), b.y(), t));
40inline auto buffer(
double distance,
size_t num_points)
43 namespace strategy = boost::geometry::strategy::buffer;
44 using strategy_point_circle = std::conditional_t<
45 std::same_as<typename boost::geometry::cs_tag<T>::type,
46 boost::geometry::geographic_tag>,
47 strategy::geographic_point_circle<>,
48 strategy::point_circle>;
50 boost::geometry::buffer(
53 strategy::distance_symmetric{distance},
54 strategy::side_straight{},
55 strategy::join_round{num_points},
56 strategy::end_round{num_points},
57 strategy_point_circle{num_points});
58 return std::move(out.at(0));
63constexpr auto meter = overloaded{
64 [] {
return numbers::radian / numbers::earth::mean_radius; },
65 [](
this auto&& self,
double lat) {
66 auto den = std::cos(lat * numbers::degree);
67 return den ? self() / den : 0.;
72 double xmin = INFINITY;
73 double ymin = INFINITY;
74 double xmax = -INFINITY;
75 double ymax = -INFINITY;
78 boost::geometry::for_each_point(g, [&](
point auto& p) {
79 xmin = std::min<>(xmin, p.x());
80 ymin = std::min<>(ymin, p.y());
81 xmax = std::max<>(xmax, p.x());
82 ymax = std::max<>(ymax, p.y());
85 [](
this auto&& self,
multi auto& g) ->
void {
86 std::ranges::for_each(g, self);
88 [](
this auto&& self,
dynamic auto& var) ->
void {
89 std::visit(self, var);
99 boost::geometry::convert(geom, ret);
106 auto [y, reflected] = reflect(p.y(), -90., 90.);
107 auto x = boat::wrap(p.x() + 180 * reflected, -180., 180.);
116 auto dx = eastward *
meter(p.y());
117 auto dy = northward *
meter();
Definition vocabulary.hpp:29
Definition vocabulary.hpp:32
Definition vocabulary.hpp:41
Definition vocabulary.hpp:38
Definition vocabulary.hpp:44
Definition vocabulary.hpp:47
Definition vocabulary.hpp:53
Definition vocabulary.hpp:26
Definition algorithm.hpp:10
polygon auto to_polygon(T const &geom)
Definition algorithm.hpp:96
geographic::point wrap(geographic::point const &p)
Wraps at the poles and antimeridian.
Definition algorithm.hpp:104
geographic::point add_meters(geographic::point const &p, double eastward, double northward)
Definition algorithm.hpp:111
auto buffer(double distance, size_t num_points)
Definition algorithm.hpp:40
constexpr auto meter
Approximate degrees per meter of latitude, or longitude at a given latitude.
Definition algorithm.hpp:63
multi_point auto box_border_interpolate(T const &mbr, size_t num_points)
Definition algorithm.hpp:24
auto box_area_interpolate(T const &mbr, size_t num_points)
Definition algorithm.hpp:13
constexpr auto minmax
Definition algorithm.hpp:71
model::multi_polygon< polygon > multi_polygon
Definition vocabulary.hpp:65
model::multi_point< point > multi_point
Definition vocabulary.hpp:63
model::d2::point_xy< double, CoordSys > point
Definition vocabulary.hpp:60
model::polygon< point, false, true > polygon
Definition vocabulary.hpp:62
model::box< point > box
Definition vocabulary.hpp:66