@@ -46,16 +46,16 @@ struct direction_code_impl
46
46
template <>
47
47
struct direction_code_impl <cartesian_tag>
48
48
{
49
- template <typename Point1 , typename Point2>
50
- static inline int apply (Point1 const & segment_a, Point1 const & segment_b,
49
+ template <typename PointSegmentA, typename PointSegmentB , typename Point2>
50
+ static inline int apply (PointSegmentA const & segment_a, PointSegmentB const & segment_b,
51
51
Point2 const & point)
52
52
{
53
- typedef typename geometry::select_coordinate_type
53
+ using calc_t = typename geometry::select_coordinate_type
54
54
<
55
- Point1 , Point2
56
- >::type calc_t ;
55
+ PointSegmentA, PointSegmentB , Point2
56
+ >::type;
57
57
58
- typedef model::infinite_line<calc_t > line_type ;
58
+ using line_type = model::infinite_line<calc_t >;
59
59
60
60
// Situation and construction of perpendicular line
61
61
//
@@ -87,42 +87,59 @@ struct direction_code_impl<cartesian_tag>
87
87
template <>
88
88
struct direction_code_impl <spherical_equatorial_tag>
89
89
{
90
- template <typename Point1 , typename Point2>
91
- static inline int apply (Point1 const & segment_a, Point1 const & segment_b,
90
+ template <typename PointSegmentA, typename PointSegmentB , typename Point2>
91
+ static inline int apply (PointSegmentA const & segment_a, PointSegmentB const & segment_b,
92
92
Point2 const & p)
93
93
{
94
- typedef typename coordinate_type<Point1>::type coord1_t ;
95
- typedef typename coordinate_type<Point2>::type coord2_t ;
96
- typedef typename cs_angular_units<Point1>::type units_t ;
97
- typedef typename cs_angular_units<Point2>::type units2_t ;
98
- BOOST_GEOMETRY_STATIC_ASSERT (
99
- (std::is_same<units_t , units2_t >::value),
100
- " Not implemented for different units." ,
101
- units_t , units2_t );
102
-
103
- typedef typename geometry::select_coordinate_type <Point1, Point2>::type calc_t ;
104
- typedef math::detail::constants_on_spheroid<coord1_t , units_t > constants1;
105
- typedef math::detail::constants_on_spheroid<coord2_t , units_t > constants2;
106
- static coord1_t const pi_half1 = constants1::max_latitude ();
107
- static coord2_t const pi_half2 = constants2::max_latitude ();
94
+ {
95
+ using units_sa_t = typename cs_angular_units<PointSegmentA>::type;
96
+ using units_sb_t = typename cs_angular_units<PointSegmentB>::type;
97
+ using units_p_t = typename cs_angular_units<Point2>::type;
98
+ BOOST_GEOMETRY_STATIC_ASSERT (
99
+ (std::is_same<units_sa_t , units_sb_t >::value),
100
+ " Not implemented for different units." ,
101
+ units_sa_t , units_sb_t );
102
+ BOOST_GEOMETRY_STATIC_ASSERT (
103
+ (std::is_same<units_sa_t , units_p_t >::value),
104
+ " Not implemented for different units." ,
105
+ units_sa_t , units_p_t );
106
+ }
107
+
108
+ using coor_sa_t = typename coordinate_type<PointSegmentA>::type;
109
+ using coor_sb_t = typename coordinate_type<PointSegmentB>::type;
110
+ using coor_p_t = typename coordinate_type<Point2>::type;
111
+
112
+ // Declare unit type (equal for all types) and calc type (coerced to most precise)
113
+ using units_t = typename cs_angular_units<Point2>::type;
114
+ using calc_t = typename geometry::select_coordinate_type
115
+ <
116
+ PointSegmentA, PointSegmentB, Point2
117
+ >::type;
118
+ using constants_sa_t = math::detail::constants_on_spheroid<coor_sa_t , units_t >;
119
+ using constants_sb_t = math::detail::constants_on_spheroid<coor_sb_t , units_t >;
120
+ using constants_p_t = math::detail::constants_on_spheroid<coor_p_t , units_t >;
121
+
122
+ static coor_sa_t const pi_half_sa = constants_sa_t::max_latitude ();
123
+ static coor_sb_t const pi_half_sb = constants_sb_t::max_latitude ();
124
+ static coor_p_t const pi_half_p = constants_p_t::max_latitude ();
108
125
static calc_t const c0 = 0 ;
109
126
110
- coord1_t const a0 = geometry::get<0 >(segment_a);
111
- coord1_t const a1 = geometry::get<1 >(segment_a);
112
- coord1_t const b0 = geometry::get<0 >(segment_b);
113
- coord1_t const b1 = geometry::get<1 >(segment_b);
114
- coord2_t const p0 = geometry::get<0 >(p);
115
- coord2_t const p1 = geometry::get<1 >(p);
116
-
127
+ coor_sa_t const a0 = geometry::get<0 >(segment_a);
128
+ coor_sa_t const a1 = geometry::get<1 >(segment_a);
129
+ coor_sb_t const b0 = geometry::get<0 >(segment_b);
130
+ coor_sb_t const b1 = geometry::get<1 >(segment_b);
131
+ coor_p_t const p0 = geometry::get<0 >(p);
132
+ coor_p_t const p1 = geometry::get<1 >(p);
133
+
117
134
if ( (math::equals (b0, a0) && math::equals (b1, a1))
118
135
|| (math::equals (b0, p0) && math::equals (b1, p1)) )
119
136
{
120
137
return 0 ;
121
138
}
122
139
123
- bool const is_a_pole = math::equals (pi_half1 , math::abs (a1));
124
- bool const is_b_pole = math::equals (pi_half1 , math::abs (b1));
125
- bool const is_p_pole = math::equals (pi_half2 , math::abs (p1));
140
+ bool const is_a_pole = math::equals (pi_half_sa , math::abs (a1));
141
+ bool const is_b_pole = math::equals (pi_half_sb , math::abs (b1));
142
+ bool const is_p_pole = math::equals (pi_half_p , math::abs (p1));
126
143
127
144
if ( is_b_pole && ((is_a_pole && math::sign (b1) == math::sign (a1))
128
145
|| (is_p_pole && math::sign (b1) == math::sign (p1))) )
@@ -140,12 +157,12 @@ struct direction_code_impl<spherical_equatorial_tag>
140
157
calc_t const dlat1 = latitude_distance_signed<units_t , calc_t >(b1, a1, dlon1, is_antilon1);
141
158
calc_t const dlat2 = latitude_distance_signed<units_t , calc_t >(b1, p1, dlon2, is_antilon2);
142
159
143
- calc_t mx = is_a_pole || is_b_pole || is_p_pole ?
144
- c0 :
145
- (std::min)(is_antilon1 ? c0 : math::abs (dlon1),
146
- is_antilon2 ? c0 : math::abs (dlon2));
147
- calc_t my = (std::min)(math::abs (dlat1),
148
- math::abs (dlat2));
160
+ calc_t const mx = is_a_pole || is_b_pole || is_p_pole
161
+ ? c0
162
+ : (std::min)(is_antilon1 ? c0 : math::abs (dlon1),
163
+ is_antilon2 ? c0 : math::abs (dlon2));
164
+ calc_t const my = (std::min)(math::abs (dlat1),
165
+ math::abs (dlat2));
149
166
150
167
int s1 = 0 , s2 = 0 ;
151
168
if (mx >= my)
@@ -165,7 +182,7 @@ struct direction_code_impl<spherical_equatorial_tag>
165
182
template <typename Units, typename T>
166
183
static inline T latitude_distance_signed (T const & lat1, T const & lat2, T const & lon_ds, bool & is_antilon)
167
184
{
168
- typedef math::detail::constants_on_spheroid<T, Units> constants ;
185
+ using constants = math::detail::constants_on_spheroid<T, Units>;
169
186
static T const pi = constants::half_period ();
170
187
static T const c0 = 0 ;
171
188
@@ -188,27 +205,27 @@ struct direction_code_impl<spherical_equatorial_tag>
188
205
template <>
189
206
struct direction_code_impl <spherical_polar_tag>
190
207
{
191
- template <typename Point1 , typename Point2>
192
- static inline int apply (Point1 segment_a, Point1 segment_b,
208
+ template <typename PointSegmentA, typename PointSegmentB , typename Point2>
209
+ static inline int apply (PointSegmentA segment_a, PointSegmentB segment_b,
193
210
Point2 p)
194
211
{
195
- typedef math::detail::constants_on_spheroid
212
+ using constants_sa_t = math::detail::constants_on_spheroid
196
213
<
197
- typename coordinate_type<Point1 >::type,
198
- typename cs_angular_units<Point1 >::type
199
- > constants1 ;
200
- typedef math::detail::constants_on_spheroid
214
+ typename coordinate_type<PointSegmentA >::type,
215
+ typename cs_angular_units<PointSegmentA >::type
216
+ >;
217
+ using constants_p_t = math::detail::constants_on_spheroid
201
218
<
202
219
typename coordinate_type<Point2>::type,
203
220
typename cs_angular_units<Point2>::type
204
- > constants2 ;
221
+ >;
205
222
206
223
geometry::set<1 >(segment_a,
207
- constants1 ::max_latitude () - geometry::get<1 >(segment_a));
224
+ constants_sa_t ::max_latitude () - geometry::get<1 >(segment_a));
208
225
geometry::set<1 >(segment_b,
209
- constants1 ::max_latitude () - geometry::get<1 >(segment_b));
226
+ constants_sa_t ::max_latitude () - geometry::get<1 >(segment_b));
210
227
geometry::set<1 >(p,
211
- constants2 ::max_latitude () - geometry::get<1 >(p));
228
+ constants_p_t ::max_latitude () - geometry::get<1 >(p));
212
229
213
230
return direction_code_impl
214
231
<
@@ -217,13 +234,13 @@ struct direction_code_impl<spherical_polar_tag>
217
234
}
218
235
};
219
236
220
- // if spherical_tag is passed then pick cs_tag based on Point1 type
237
+ // if spherical_tag is passed then pick cs_tag based on PointSegmentA type
221
238
// with spherical_equatorial_tag as the default
222
239
template <>
223
240
struct direction_code_impl <spherical_tag>
224
241
{
225
- template <typename Point1 , typename Point2>
226
- static inline int apply (Point1 segment_a, Point1 segment_b,
242
+ template <typename PointSegmentA, typename PointSegmentB , typename Point2>
243
+ static inline int apply (PointSegmentA segment_a, PointSegmentB segment_b,
227
244
Point2 p)
228
245
{
229
246
return direction_code_impl
@@ -232,7 +249,7 @@ struct direction_code_impl<spherical_tag>
232
249
<
233
250
std::is_same
234
251
<
235
- typename geometry::cs_tag<Point1 >::type,
252
+ typename geometry::cs_tag<PointSegmentA >::type,
236
253
spherical_polar_tag
237
254
>::value,
238
255
spherical_polar_tag,
@@ -252,8 +269,10 @@ struct direction_code_impl<geographic_tag>
252
269
// Returns 1 if p goes forward, so extends (a,b)
253
270
// Returns 0 if p is equal with b, or if (a,b) is degenerate
254
271
// Note that it does not do any collinearity test, that should be done before
255
- template <typename CSTag, typename Point1, typename Point2>
256
- inline int direction_code (Point1 const & segment_a, Point1 const & segment_b,
272
+ // In some cases the "segment" consists of different source points, and therefore
273
+ // their types might differ.
274
+ template <typename CSTag, typename PointSegmentA, typename PointSegmentB, typename Point2>
275
+ inline int direction_code (PointSegmentA const & segment_a, PointSegmentB const & segment_b,
257
276
Point2 const & p)
258
277
{
259
278
return direction_code_impl<CSTag>::apply (segment_a, segment_b, p);
0 commit comments