@@ -46,16 +46,16 @@ struct direction_code_impl
4646template <>
4747struct direction_code_impl <cartesian_tag>
4848{
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,
5151 Point2 const & point)
5252 {
53- typedef typename geometry::select_coordinate_type
53+ using calc_t = typename geometry::select_coordinate_type
5454 <
55- Point1 , Point2
56- >::type calc_t ;
55+ PointSegmentA, PointSegmentB , Point2
56+ >::type;
5757
58- typedef model::infinite_line<calc_t > line_type ;
58+ using line_type = model::infinite_line<calc_t >;
5959
6060 // Situation and construction of perpendicular line
6161 //
@@ -87,42 +87,59 @@ struct direction_code_impl<cartesian_tag>
8787template <>
8888struct direction_code_impl <spherical_equatorial_tag>
8989{
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,
9292 Point2 const & p)
9393 {
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 ();
108125 static calc_t const c0 = 0 ;
109126
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+
117134 if ( (math::equals (b0, a0) && math::equals (b1, a1))
118135 || (math::equals (b0, p0) && math::equals (b1, p1)) )
119136 {
120137 return 0 ;
121138 }
122139
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));
126143
127144 if ( is_b_pole && ((is_a_pole && math::sign (b1) == math::sign (a1))
128145 || (is_p_pole && math::sign (b1) == math::sign (p1))) )
@@ -140,12 +157,12 @@ struct direction_code_impl<spherical_equatorial_tag>
140157 calc_t const dlat1 = latitude_distance_signed<units_t , calc_t >(b1, a1, dlon1, is_antilon1);
141158 calc_t const dlat2 = latitude_distance_signed<units_t , calc_t >(b1, p1, dlon2, is_antilon2);
142159
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));
149166
150167 int s1 = 0 , s2 = 0 ;
151168 if (mx >= my)
@@ -165,7 +182,7 @@ struct direction_code_impl<spherical_equatorial_tag>
165182 template <typename Units, typename T>
166183 static inline T latitude_distance_signed (T const & lat1, T const & lat2, T const & lon_ds, bool & is_antilon)
167184 {
168- typedef math::detail::constants_on_spheroid<T, Units> constants ;
185+ using constants = math::detail::constants_on_spheroid<T, Units>;
169186 static T const pi = constants::half_period ();
170187 static T const c0 = 0 ;
171188
@@ -188,27 +205,27 @@ struct direction_code_impl<spherical_equatorial_tag>
188205template <>
189206struct direction_code_impl <spherical_polar_tag>
190207{
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,
193210 Point2 p)
194211 {
195- typedef math::detail::constants_on_spheroid
212+ using constants_sa_t = math::detail::constants_on_spheroid
196213 <
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
201218 <
202219 typename coordinate_type<Point2>::type,
203220 typename cs_angular_units<Point2>::type
204- > constants2 ;
221+ >;
205222
206223 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));
208225 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));
210227 geometry::set<1 >(p,
211- constants2 ::max_latitude () - geometry::get<1 >(p));
228+ constants_p_t ::max_latitude () - geometry::get<1 >(p));
212229
213230 return direction_code_impl
214231 <
@@ -217,13 +234,13 @@ struct direction_code_impl<spherical_polar_tag>
217234 }
218235};
219236
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
221238// with spherical_equatorial_tag as the default
222239template <>
223240struct direction_code_impl <spherical_tag>
224241{
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,
227244 Point2 p)
228245 {
229246 return direction_code_impl
@@ -232,7 +249,7 @@ struct direction_code_impl<spherical_tag>
232249 <
233250 std::is_same
234251 <
235- typename geometry::cs_tag<Point1 >::type,
252+ typename geometry::cs_tag<PointSegmentA >::type,
236253 spherical_polar_tag
237254 >::value,
238255 spherical_polar_tag,
@@ -252,8 +269,10 @@ struct direction_code_impl<geographic_tag>
252269// Returns 1 if p goes forward, so extends (a,b)
253270// Returns 0 if p is equal with b, or if (a,b) is degenerate
254271// 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,
257276 Point2 const & p)
258277{
259278 return direction_code_impl<CSTag>::apply (segment_a, segment_b, p);
0 commit comments