Skip to content

Commit 47d398a

Browse files
authored
Merge pull request #1364 from awulkiew/fix/strategies
Fix several strategies (add getters, fix compilation error and warning)
2 parents fe817e6 + c661868 commit 47d398a

File tree

12 files changed

+163
-106
lines changed

12 files changed

+163
-106
lines changed

include/boost/geometry/strategies/cartesian.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Boost.Geometry
22

3+
// Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland.
4+
35
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
46

57
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -14,6 +16,8 @@
1416
#include <boost/geometry/strategies/area/cartesian.hpp>
1517
#include <boost/geometry/strategies/azimuth/cartesian.hpp>
1618
#include <boost/geometry/strategies/buffer/cartesian.hpp>
19+
#include <boost/geometry/strategies/centroid/cartesian.hpp>
20+
#include <boost/geometry/strategies/closest_points/cartesian.hpp>
1721
#include <boost/geometry/strategies/convex_hull/cartesian.hpp>
1822
#include <boost/geometry/strategies/distance/cartesian.hpp>
1923
#include <boost/geometry/strategies/envelope/cartesian.hpp>
@@ -36,7 +40,8 @@ namespace strategies
3640
template <typename CalculationType = void>
3741
class cartesian
3842
// derived from the umbrella strategy defining the most strategies
39-
: public strategies::index::cartesian<CalculationType>
43+
: public strategies::closest_points::cartesian<CalculationType>
44+
, public strategies::centroid::detail::cartesian<CalculationType>
4045
{
4146
public:
4247

include/boost/geometry/strategies/centroid/cartesian.hpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Boost.Geometry
22

3+
// Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland.
4+
35
// Copyright (c) 2021, Oracle and/or its affiliates.
46

57
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -27,9 +29,12 @@ namespace boost { namespace geometry
2729
namespace strategies { namespace centroid
2830
{
2931

32+
#ifndef DOXYGEN_NO_DETAIL
33+
namespace detail
34+
{
35+
3036
template <typename CalculationType = void>
3137
struct cartesian
32-
: public strategies::detail::cartesian_base
3338
{
3439
template <typename Geometry>
3540
static auto centroid(Geometry const&,
@@ -77,6 +82,17 @@ struct cartesian
7782
};
7883

7984

85+
} // namespace detail
86+
#endif // DOXYGEN_NO_DETAIL
87+
88+
89+
template <typename CalculationType = void>
90+
struct cartesian
91+
: public strategies::detail::cartesian_base
92+
, public strategies::centroid::detail::cartesian<CalculationType>
93+
{};
94+
95+
8096
namespace services
8197
{
8298

include/boost/geometry/strategies/centroid/geographic.hpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Boost.Geometry
22

3+
// Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland.
4+
35
// Copyright (c) 2021, Oracle and/or its affiliates.
46

57
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,6 +24,31 @@ namespace boost { namespace geometry
2224
namespace strategies { namespace centroid
2325
{
2426

27+
#ifndef DOXYGEN_NO_DETAIL
28+
namespace detail
29+
{
30+
31+
class geographic
32+
{
33+
public:
34+
// TODO: Box and Segment should have proper strategies.
35+
template <typename Geometry, typename Point>
36+
static auto centroid(Geometry const&, Point const&,
37+
std::enable_if_t
38+
<
39+
util::is_segment<Geometry>::value
40+
|| util::is_box<Geometry>::value
41+
> * = nullptr)
42+
{
43+
return strategy::centroid::not_applicable_strategy();
44+
}
45+
};
46+
47+
48+
} // namespace detail
49+
#endif // DOXYGEN_NO_DETAIL
50+
51+
2552
template
2653
<
2754
typename FormulaPolicy = strategy::andoyer,
@@ -30,6 +57,7 @@ template
3057
>
3158
class geographic
3259
: public strategies::detail::geographic_base<Spheroid>
60+
, public strategies::centroid::detail::geographic
3361
{
3462
using base_t = strategies::detail::geographic_base<Spheroid>;
3563

@@ -39,20 +67,9 @@ class geographic
3967
explicit geographic(Spheroid const& spheroid)
4068
: base_t(spheroid)
4169
{}
42-
43-
// TODO: Box and Segment should have proper strategies.
44-
template <typename Geometry, typename Point>
45-
static auto centroid(Geometry const&, Point const&,
46-
std::enable_if_t
47-
<
48-
util::is_segment<Geometry>::value
49-
|| util::is_box<Geometry>::value
50-
> * = nullptr)
51-
{
52-
return strategy::centroid::not_applicable_strategy();
53-
}
5470
};
5571

72+
5673
namespace services
5774
{
5875

include/boost/geometry/strategies/centroid/spherical.hpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Boost.Geometry
22

3+
// Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland.
4+
35
// Copyright (c) 2021, Oracle and/or its affiliates.
46

57
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,18 +24,13 @@ namespace boost { namespace geometry
2224
namespace strategies { namespace centroid
2325
{
2426

25-
template
26-
<
27-
typename CalculationType = void
28-
>
29-
class spherical
30-
: public strategies::detail::spherical_base<void>
27+
#ifndef DOXYGEN_NO_DETAIL
28+
namespace detail
3129
{
32-
using base_t = strategies::detail::spherical_base<void>;
3330

31+
class spherical
32+
{
3433
public:
35-
spherical() = default;
36-
3734
// TODO: Box and Segment should have proper strategies.
3835
template <typename Geometry, typename Point>
3936
static auto centroid(Geometry const&, Point const&,
@@ -48,6 +45,20 @@ class spherical
4845
};
4946

5047

48+
} // namespace detail
49+
#endif // DOXYGEN_NO_DETAIL
50+
51+
52+
template <typename CalculationType = void>
53+
class spherical
54+
: public strategies::detail::spherical_base<void>
55+
, public strategies::centroid::detail::spherical
56+
{
57+
public:
58+
spherical() = default;
59+
};
60+
61+
5162
namespace services
5263
{
5364

include/boost/geometry/strategies/geographic.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Boost.Geometry
22

3+
// Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland.
4+
35
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
46

57
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -14,6 +16,8 @@
1416
#include <boost/geometry/strategies/area/geographic.hpp>
1517
#include <boost/geometry/strategies/azimuth/geographic.hpp>
1618
#include <boost/geometry/strategies/buffer/geographic.hpp>
19+
#include <boost/geometry/strategies/centroid/geographic.hpp>
20+
#include <boost/geometry/strategies/closest_points/geographic.hpp>
1721
#include <boost/geometry/strategies/convex_hull/geographic.hpp>
1822
#include <boost/geometry/strategies/distance/geographic.hpp>
1923
#include <boost/geometry/strategies/envelope/geographic.hpp>
@@ -41,9 +45,10 @@ template
4145
>
4246
class geographic
4347
// derived from the umbrella strategy defining the most strategies
44-
: public index::geographic<FormulaPolicy, Spheroid, CalculationType>
48+
: public strategies::closest_points::geographic<FormulaPolicy, Spheroid, CalculationType>
49+
, public strategies::centroid::detail::geographic
4550
{
46-
using base_t = index::geographic<FormulaPolicy, Spheroid, CalculationType>;
51+
using base_t = strategies::closest_points::geographic<FormulaPolicy, Spheroid, CalculationType>;
4752

4853
public:
4954
geographic() = default;

include/boost/geometry/strategies/geographic/distance_cross_track.hpp

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Boost.Geometry (aka GGL, Generic Geometry Library)
22

3-
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
3+
// Copyright (c) 2023-2025 Adam Wulkiewicz, Lodz, Poland.
44

55
// Copyright (c) 2016-2022, Oracle and/or its affiliates.
66
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
@@ -273,7 +273,7 @@ class geographic_cross_track
273273
pl_lat = res14.lat2;
274274
}
275275

276-
CT new_distance = inverse_distance_type::apply(lon3, lat3, res14.lon2, res14.lat2,
276+
CT const new_distance = inverse_distance_type::apply(lon3, lat3, res14.lon2, res14.lat2,
277277
spheroid).distance;
278278

279279
dist_improve = new_distance != result.distance;
@@ -346,8 +346,8 @@ class geographic_cross_track
346346
// g4 is the angle between segment (p1,p2) and segment (p3,p4)
347347
// that meet on p4 (GEO)
348348

349-
CT a4 = inverse_dist_azimuth_type::apply(res14.lon2, res14.lat2,
350-
lon2, lat2, spheroid).azimuth;
349+
CT const a4 = inverse_dist_azimuth_type::apply(res14.lon2, res14.lat2,
350+
lon2, lat2, spheroid).azimuth;
351351
res34 = inverse_distance_azimuth_quantities_type::apply(res14.lon2, res14.lat2,
352352
lon3, lat3, spheroid);
353353
g4 = res34.azimuth - a4;
@@ -527,8 +527,8 @@ class geographic_cross_track
527527
CT lat1 = la1;
528528
CT lon2 = lo2;
529529
CT lat2 = la2;
530-
CT lon3 = lo3;
531-
CT lat3 = la3;
530+
CT const lon3 = lo3;
531+
CT const lat3 = la3;
532532

533533
if (lon1 > lon2)
534534
{
@@ -549,14 +549,14 @@ class geographic_cross_track
549549
//segment on equator
550550
//Note: antipodal points on equator does not define segment on equator
551551
//but pass by the pole
552-
CT diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2);
552+
CT const diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2);
553553

554554
using meridian_inverse = typename formula::meridian_inverse<CT>;
555555

556-
bool meridian_not_crossing_pole =
556+
bool const meridian_not_crossing_pole =
557557
meridian_inverse::meridian_not_crossing_pole(lat1, lat2, diff);
558558

559-
bool meridian_crossing_pole =
559+
bool const meridian_crossing_pole =
560560
meridian_inverse::meridian_crossing_pole(diff);
561561

562562
if (math::equals(lat1, c0) && math::equals(lat2, c0)
@@ -596,18 +596,18 @@ class geographic_cross_track
596596
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
597597
std::cout << "Meridian segment crossing pole" << std::endl;
598598
#endif
599-
CT sign_non_zero = lat3 >= c0 ? 1 : -1;
599+
CT const sign_non_zero = lat3 >= c0 ? 1 : -1;
600600

601-
auto res13 = apply(lon1, lat1, lon1, half_pi * sign_non_zero, lon3, lat3, spheroid);
601+
auto const res13 = apply(lon1, lat1, lon1, half_pi * sign_non_zero, lon3, lat3, spheroid);
602602

603-
auto res23 = apply(lon2, lat2, lon2, half_pi * sign_non_zero, lon3, lat3, spheroid);
603+
auto const res23 = apply(lon2, lat2, lon2, half_pi * sign_non_zero, lon3, lat3, spheroid);
604604

605605
return (res13.distance) < (res23.distance) ? res13 : res23;
606606
}
607607

608-
auto res12 = inverse_dist_azimuth_reverse_type::apply(lon1, lat1, lon2, lat2, spheroid);
608+
auto const res12 = inverse_dist_azimuth_reverse_type::apply(lon1, lat1, lon2, lat2, spheroid);
609609

610-
auto res13 = inverse_dist_azimuth_type::apply(lon1, lat1, lon3, lat3, spheroid);
610+
auto const res13 = inverse_dist_azimuth_type::apply(lon1, lat1, lon3, lat3, spheroid);
611611

612612
if (geometry::math::equals(res12.distance, c0))
613613
{
@@ -616,14 +616,14 @@ class geographic_cross_track
616616
std::cout << "distance between points="
617617
<< res13.distance << std::endl;
618618
#endif
619-
auto res = meridian_inverse::apply(lon1, lat1, lon3, lat3, spheroid);
619+
auto const res = meridian_inverse::apply(lon1, lat1, lon3, lat3, spheroid);
620620

621621
return non_iterative_case(lon3, lat3, lon1, lat2,
622622
res.meridian ? res.distance : res13.distance);
623623
}
624624

625625
// Compute a12 (GEO)
626-
CT a312 = res13.azimuth - res12.azimuth;
626+
CT const a312 = res13.azimuth - res12.azimuth;
627627

628628
// TODO: meridian case optimization
629629
if (geometry::math::equals(a312, c0) && meridian_not_crossing_pole)
@@ -640,7 +640,7 @@ class geographic_cross_track
640640
}
641641
}
642642

643-
CT projection1 = cos( a312 ) * res13.distance / res12.distance;
643+
CT const projection1 = cos( a312 ) * res13.distance / res12.distance;
644644

645645
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
646646
std::cout << "a1=" << res12.azimuth * math::r2d<CT>() << std::endl;
@@ -661,10 +661,10 @@ class geographic_cross_track
661661
return non_iterative_case(lon3, lat3, lon1, lat1, spheroid);
662662
}
663663

664-
auto res23 = inverse_dist_azimuth_type::apply(lon2, lat2, lon3, lat3, spheroid);
664+
auto const res23 = inverse_dist_azimuth_type::apply(lon2, lat2, lon3, lat3, spheroid);
665665

666-
CT a321 = res23.azimuth - res12.reverse_azimuth + pi;
667-
CT projection2 = cos( a321 ) * res23.distance / res12.distance;
666+
CT const a321 = res23.azimuth - res12.reverse_azimuth + pi;
667+
CT const projection2 = cos( a321 ) * res23.distance / res12.distance;
668668

669669
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
670670
std::cout << "a21=" << res12.reverse_azimuth * math::r2d<CT>()
@@ -693,25 +693,28 @@ class geographic_cross_track
693693
geometry::cs::spherical_equatorial<geometry::radian>
694694
>;
695695

696-
point p1 = point(lon1, lat1);
697-
point p2 = point(lon2, lat2);
698-
point p3 = point(lon3, lat3);
696+
point const p1(lon1, lat1);
697+
point const p2(lon2, lat2);
698+
point const p3(lon3, lat3);
699699

700-
geometry::strategy::distance::cross_track<CT> cross_track(earth_radius);
701-
CT s34_sph = cross_track.apply(p3, p1, p2);
700+
using haversine_t = geometry::strategy::distance::haversine<CT>;
701+
using cross_track_t = geometry::strategy::distance::cross_track<void, haversine_t>;
702702

703-
geometry::strategy::distance::haversine<CT> str(earth_radius);
704-
CT s13_sph = str.apply(p1, p3);
703+
cross_track_t const cross_track(earth_radius);
704+
CT const s34_sph = cross_track.apply(p3, p1, p2);
705+
706+
haversine_t const str(earth_radius);
707+
CT const s13_sph = str.apply(p1, p3);
705708

706709
//CT s14 = acos( cos(s13/earth_radius) / cos(s34/earth_radius) ) * earth_radius;
707-
CT cos_frac = cos(s13_sph / earth_radius) / cos(s34_sph / earth_radius);
708-
CT s14_sph = cos_frac >= 1 ? CT(0)
710+
CT const cos_frac = cos(s13_sph / earth_radius) / cos(s34_sph / earth_radius);
711+
CT const s14_sph = cos_frac >= 1 ? CT(0)
709712
: cos_frac <= -1 ? pi * earth_radius
710713
: acos(cos_frac) * earth_radius;
711714

712715
CT const a12_sph = geometry::formula::spherical_azimuth<>(lon1, lat1, lon2, lat2);
713716

714-
auto res = geometry::formula::spherical_direct<true, false>(lon1, lat1,
717+
auto const res = geometry::formula::spherical_direct<true, false>(lon1, lat1,
715718
s14_sph, a12_sph, srs::sphere<CT>(earth_radius));
716719

717720
// this is what postgis (version 2.5) returns
@@ -734,7 +737,7 @@ class geographic_cross_track
734737
}
735738
else
736739
{
737-
CT s14_start = geometry::strategy::distance::geographic
740+
CT const s14_start = geometry::strategy::distance::geographic
738741
<
739742
FormulaPolicy,
740743
Spheroid,

0 commit comments

Comments
 (0)