diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:18:43 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:18:43 +0900 |
commit | 5ce2ccf2f23c6d3de4c79f216f57ca6f2a18ed16 (patch) | |
tree | bbee48efb9867d19ac3fdd84ba714c7af326cd53 /boost/geometry | |
parent | b8cf34c691623e4ec329053cbbf68522a855882d (diff) | |
download | boost-5ce2ccf2f23c6d3de4c79f216f57ca6f2a18ed16.tar.gz boost-5ce2ccf2f23c6d3de4c79f216f57ca6f2a18ed16.tar.bz2 boost-5ce2ccf2f23c6d3de4c79f216f57ca6f2a18ed16.zip |
Imported Upstream version 1.68.0upstream/1.68.0
Diffstat (limited to 'boost/geometry')
180 files changed, 11750 insertions, 7809 deletions
diff --git a/boost/geometry/algorithms/detail/assign_values.hpp b/boost/geometry/algorithms/detail/assign_values.hpp index ef5691e97c..64ab9fa837 100644 --- a/boost/geometry/algorithms/detail/assign_values.hpp +++ b/boost/geometry/algorithms/detail/assign_values.hpp @@ -7,6 +7,11 @@ // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -34,6 +39,7 @@ #include <boost/geometry/geometries/concepts/check.hpp> +#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp> #include <boost/geometry/util/for_each_coordinate.hpp> @@ -86,12 +92,13 @@ struct assign_inverse_box_or_segment typedef typename coordinate_type<point_type>::type bound_type; initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply( - geometry, boost::numeric::bounds<bound_type>::highest() + geometry, geometry::bounds<bound_type>::highest() ); initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply( - geometry, boost::numeric::bounds<bound_type>::lowest() + geometry, geometry::bounds<bound_type>::lowest() ); } + }; diff --git a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index fe849e1091..baa4cf83dd 100644 --- a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -33,6 +33,7 @@ #include <boost/geometry/algorithms/detail/envelope/segment.hpp> #include <boost/geometry/algorithms/detail/normalize.hpp> #include <boost/geometry/algorithms/dispatch/disjoint.hpp> +#include <boost/geometry/algorithms/envelope.hpp> #include <boost/geometry/formulas/vertex_longitude.hpp> @@ -64,11 +65,39 @@ private: public: + struct disjoint_info + { + enum type + { + intersect, + disjoint_no_vertex, + disjoint_vertex + }; + disjoint_info(type t) : m_(t){} + operator type () const {return m_;} + type m_; + private : + //prevent automatic conversion for any other built-in types + template <typename T> + operator T () const; + }; + template <typename Segment, typename Box, typename Strategy> static inline bool apply(Segment const& segment, Box const& box, Strategy const& azimuth_strategy) { + typedef typename point_type<Segment>::type segment_point; + segment_point vertex; + return (apply(segment, box, azimuth_strategy, vertex) != disjoint_info::intersect); + } + + template <typename Segment, typename Box, typename Strategy, typename P> + static inline disjoint_info apply(Segment const& segment, + Box const& box, + Strategy const& azimuth_strategy, + P& vertex) + { assert_dimension_equal<Segment, Box>(); typedef typename point_type<Segment>::type segment_point_type; @@ -78,12 +107,15 @@ public: geometry::detail::assign_point_from_index<0>(segment, p0); geometry::detail::assign_point_from_index<1>(segment, p1); + //vertex not computed here + disjoint_info disjoint_return_value = disjoint_info::disjoint_no_vertex; + // Simplest cases first // Case 1: if box contains one of segment's endpoints then they are not disjoint if (! disjoint_point_box(p0, box) || ! disjoint_point_box(p1, box)) { - return false; + return disjoint_info::intersect; } // Case 2: disjoint if bounding boxes are disjoint @@ -119,9 +151,10 @@ public: box_seg, azimuth_strategy, alp1); + if (disjoint_box_box(box, box_seg)) { - return true; + return disjoint_return_value; } // Case 3: test intersection by comparing angles @@ -138,16 +171,14 @@ public: azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_max, a_b2); azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_max, a_b3); - bool b0 = alp1 > a_b0; - bool b1 = alp1 > a_b1; - bool b2 = alp1 > a_b2; - bool b3 = alp1 > a_b3; + bool b0 = formula::azimuth_side_value(alp1, a_b0) > 0; + bool b1 = formula::azimuth_side_value(alp1, a_b1) > 0; + bool b2 = formula::azimuth_side_value(alp1, a_b2) > 0; + bool b3 = formula::azimuth_side_value(alp1, a_b3) > 0; - // if not all box points on the same side of the segment then - // there is an intersection if (!(b0 && b1 && b2 && b3) && (b0 || b1 || b2 || b3)) { - return false; + return disjoint_info::intersect; } // Case 4: The only intersection case not covered above is when all four @@ -157,8 +188,8 @@ public: CT vertex_lat; CT lat_sum = lat1 + lat2; - if ((b0 && b1 && b2 && b3 && lat_sum > CT(0)) - || (!(b0 && b1 && b2 && b3) && lat_sum < CT(0))) + if ((lat1 < b_lat_min && lat_sum > CT(0)) + || (lat1 > b_lat_max && lat_sum < CT(0))) { CT b_lat_below; //latitude of box closest to equator @@ -180,6 +211,10 @@ public: alp1, azimuth_strategy); + geometry::set_from_radian<0>(vertex, vertex_lon); + geometry::set_from_radian<1>(vertex, vertex_lat); + disjoint_return_value = disjoint_info::disjoint_vertex; //vertex_computed + // Check if the vertex point is within the band defined by the // minimum and maximum longitude of the box; if yes, then return // false if the point is above the min latitude of the box; return @@ -187,11 +222,11 @@ public: if (vertex_lon >= b_lon_min && vertex_lon <= b_lon_max && std::abs(vertex_lat) > std::abs(b_lat_below)) { - return false; + return disjoint_info::intersect; } } - return true; + return disjoint_return_value; } }; diff --git a/boost/geometry/algorithms/detail/distance/default_strategies.hpp b/boost/geometry/algorithms/detail/distance/default_strategies.hpp index a01ace2b58..a4c607698d 100644 --- a/boost/geometry/algorithms/detail/distance/default_strategies.hpp +++ b/boost/geometry/algorithms/detail/distance/default_strategies.hpp @@ -110,6 +110,26 @@ struct default_strategy<Box1, Box2, box_tag, box_tag, false> > {}; +template <typename Linear, typename Box> +struct default_strategy<Linear, Box, segment_tag, box_tag, false> + : strategy::distance::services::default_strategy + < + segment_tag, box_tag, + typename point_type<Linear>::type, + typename point_type<Box>::type + > +{}; + +template <typename Linear, typename Box> +struct default_strategy<Linear, Box, linear_tag, box_tag, false> + : strategy::distance::services::default_strategy + < + segment_tag, box_tag, + typename point_type<Linear>::type, + typename point_type<Box>::type + > +{}; + // Helper metafunction for default point-segment strategy retrieval diff --git a/boost/geometry/algorithms/detail/distance/implementation.hpp b/boost/geometry/algorithms/detail/distance/implementation.hpp index 7c009f4d79..2e88f936d7 100644 --- a/boost/geometry/algorithms/detail/distance/implementation.hpp +++ b/boost/geometry/algorithms/detail/distance/implementation.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -25,6 +26,7 @@ #include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp> #include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp> #include <boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp> +#include <boost/geometry/algorithms/detail/distance/linear_to_box.hpp> #include <boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp> #include <boost/geometry/algorithms/detail/distance/segment_to_segment.hpp> #include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp> diff --git a/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp b/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp index b63104da7d..7b81d68bb4 100644 --- a/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp +++ b/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp @@ -18,7 +18,6 @@ #include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp> - namespace boost { namespace geometry { @@ -61,7 +60,6 @@ struct linear_to_areal } }; - template <typename Areal1, typename Areal2, typename Strategy> struct areal_to_areal { @@ -110,7 +108,6 @@ struct distance > {}; - template <typename Areal, typename Linear, typename Strategy> struct distance < diff --git a/boost/geometry/algorithms/detail/distance/linear_to_box.hpp b/boost/geometry/algorithms/detail/distance/linear_to_box.hpp new file mode 100644 index 0000000000..833dbf5f6a --- /dev/null +++ b/boost/geometry/algorithms/detail/distance/linear_to_box.hpp @@ -0,0 +1,123 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_BOX_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_BOX_HPP + +#include <boost/geometry/core/point_type.hpp> + +#include <boost/geometry/algorithms/intersects.hpp> + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + +template <typename Linear, typename Box, typename Strategy> +struct linear_to_box +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type<Linear>::type, + typename point_type<Box>::type + >::type return_type; + + template <typename Iterator> + static inline return_type apply(Box const& box, + Iterator begin, + Iterator end, + Strategy const& strategy) + { + bool first = true; + return_type d_min(0); + for (Iterator it = begin; it != end; ++it, first = false) + { + typedef typename std::iterator_traits<Iterator>::value_type + Segment; + + return_type d = dispatch::distance<Segment, Box, Strategy> + ::apply(*it, box, strategy); + + if ( first || d < d_min ) + { + d_min = d; + } + } + return d_min; + } + + static inline return_type apply(Linear const& linear, + Box const& box, + Strategy const& strategy) + { + if ( geometry::intersects(linear, box) ) + { + return 0; + } + + return apply(box, + geometry::segments_begin(linear), + geometry::segments_end(linear), + strategy); + } + + + static inline return_type apply(Box const& box, + Linear const& linear, + Strategy const& strategy) + { + return apply(linear, box, strategy); + } +}; + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template <typename Linear, typename Box, typename Strategy> +struct distance + < + Linear, Box, Strategy, + linear_tag, box_tag, + strategy_tag_distance_segment_box, false + > + : detail::distance::linear_to_box + < + Linear, Box, Strategy + > +{}; + + +template <typename Areal, typename Box, typename Strategy> +struct distance + < + Areal, Box, Strategy, + areal_tag, box_tag, + strategy_tag_distance_segment_box, false + > + : detail::distance::linear_to_box + < + Areal, Box, Strategy + > +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_BOX_HPP diff --git a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp index fa95152476..bfe52c7b1b 100644 --- a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014, Oracle and/or its affiliates. +// Copyright (c) 2014-2018 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Licensed under the Boost Software License version 1.0. @@ -9,7 +10,6 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP - #include <cstddef> #include <functional> @@ -48,7 +48,6 @@ #include <boost/geometry/algorithms/dispatch/distance.hpp> - namespace boost { namespace geometry { @@ -73,7 +72,7 @@ private: typedef typename strategy::distance::services::comparable_type < - Strategy + typename Strategy::distance_ps_strategy::type >::type comparable_strategy; typedef detail::closest_feature::point_to_point_range @@ -108,8 +107,8 @@ public: comparable_strategy cstrategy = strategy::distance::services::get_comparable < - Strategy - >::apply(strategy); + typename Strategy::distance_ps_strategy::type + >::apply(strategy.get_distance_ps_strategy()); // get segment points segment_point p[2]; @@ -159,12 +158,12 @@ public: if (imin < 4) { - return strategy.apply(box_points[imin], p[0], p[1]); + return strategy.get_distance_ps_strategy().apply(box_points[imin], p[0], p[1]); } else { unsigned int bimin = imin - 4; - return strategy.apply(p[bimin], + return strategy.get_distance_ps_strategy().apply(p[bimin], *bit_min[bimin].first, *bit_min[bimin].second); } @@ -280,8 +279,7 @@ template typename ReturnType, typename SegmentPoint, typename BoxPoint, - typename PPStrategy, - typename PSStrategy + typename SBStrategy > class segment_to_box_2D { @@ -340,10 +338,9 @@ private: SegmentPoint const& p1, BoxPoint const& bottom_right, BoxPoint const& top_right, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { - boost::ignore_unused(pp_strategy, ps_strategy); + boost::ignore_unused(sb_strategy); // the implementation below is written for non-negative slope // segments @@ -355,22 +352,29 @@ private: LessEqual less_equal; - if (less_equal(geometry::get<1>(top_right), geometry::get<1>(p0))) - { - // closest box point is the top-right corner - return cast::apply(pp_strategy.apply(p0, top_right)); - } - else if (less_equal(geometry::get<1>(bottom_right), - geometry::get<1>(p0))) + typename SBStrategy::distance_ps_strategy::type ps_strategy = + sb_strategy.get_distance_ps_strategy(); + + if (less_equal(geometry::get<1>(bottom_right), geometry::get<1>(p0))) { - // distance is realized between p0 and right-most - // segment of box - ReturnType diff = cast::apply(geometry::get<0>(p0)) - - cast::apply(geometry::get<0>(bottom_right)); - return strategy::distance::services::result_from_distance - < - PSStrategy, BoxPoint, SegmentPoint - >::apply(ps_strategy, math::abs(diff)); + //if p0 is in box's band + if (less_equal(geometry::get<1>(p0), geometry::get<1>(top_right))) + { + // segment & crosses band (TODO:merge with box-box dist) + if (math::equals(geometry::get<0>(p0), geometry::get<0>(p1))) + { + SegmentPoint high = geometry::get<1>(p1) > geometry::get<1>(p0) ? p1 : p0; + if (less_equal(geometry::get<1>(high), geometry::get<1>(top_right))) + { + return cast::apply(ps_strategy.apply(high, bottom_right, top_right)); + } + return cast::apply(ps_strategy.apply(top_right, p0, p1)); + } + return cast::apply(ps_strategy.apply(p0, bottom_right, top_right)); + } + // distance is realized between the top-right + // corner of the box and the segment + return cast::apply(ps_strategy.apply(top_right, p0, p1)); } else { @@ -381,45 +385,55 @@ private: } }; - // it is assumed here that p0 lies above the box (so the // entire segment lies above the box) + template <typename LessEqual> struct above_of_box { + static inline ReturnType apply(SegmentPoint const& p0, SegmentPoint const& p1, BoxPoint const& top_left, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { - boost::ignore_unused(ps_strategy); - - // the segment lies above the box + boost::ignore_unused(sb_strategy); + return apply(p0, p1, p0, top_left, sb_strategy); + } + static inline ReturnType apply(SegmentPoint const& p0, + SegmentPoint const& p1, + SegmentPoint const& p_max, + BoxPoint const& top_left, + SBStrategy const& sb_strategy) + { + boost::ignore_unused(sb_strategy); typedef cast_to_result<ReturnType> cast; - LessEqual less_equal; - // p0 is above the upper segment of the box - // (and inside its band) - if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p0))) + // p0 is above the upper segment of the box (and inside its band) + // then compute the vertical (i.e. meridian for spherical) distance + if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p_max))) { - ReturnType diff = cast::apply(geometry::get<1>(p0)) - - cast::apply(geometry::get<1>(top_left)); + ReturnType diff = + sb_strategy.get_distance_ps_strategy().vertical_or_meridian( + geometry::get_as_radian<1>(p_max), + geometry::get_as_radian<1>(top_left)); + return strategy::distance::services::result_from_distance < - PSStrategy, SegmentPoint, BoxPoint - >::apply(ps_strategy, math::abs(diff)); + SBStrategy, SegmentPoint, BoxPoint + >::apply(sb_strategy, math::abs(diff)); } // p0 is to the left of the box, but p1 is above the box // in this case the distance is realized between the // top-left corner of the box and the segment - return cast::apply(ps_strategy.apply(top_left, p0, p1)); + return cast::apply(sb_strategy.get_distance_ps_strategy(). + apply(top_left, p0, p1)); } }; - template <typename LessEqual> struct check_right_left_of_box { @@ -429,8 +443,7 @@ private: BoxPoint const& top_right, BoxPoint const& bottom_left, BoxPoint const& bottom_right, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy, + SBStrategy const& sb_strategy, ReturnType& result) { // p0 lies to the right of the box @@ -440,7 +453,7 @@ private: < LessEqual >::apply(p0, p1, bottom_right, top_right, - pp_strategy, ps_strategy); + sb_strategy); return true; } @@ -451,7 +464,7 @@ private: < typename other_compare<LessEqual>::type >::apply(p1, p0, top_left, bottom_left, - pp_strategy, ps_strategy); + sb_strategy); return true; } @@ -459,7 +472,6 @@ private: } }; - template <typename LessEqual> struct check_above_below_of_box { @@ -469,26 +481,35 @@ private: BoxPoint const& top_right, BoxPoint const& bottom_left, BoxPoint const& bottom_right, - PSStrategy const& ps_strategy, + SBStrategy const& sb_strategy, ReturnType& result) { + typedef compare_less_equal<ReturnType, false> GreaterEqual; + // the segment lies below the box if (geometry::get<1>(p1) < geometry::get<1>(bottom_left)) { - result = above_of_box - < - typename other_compare<LessEqual>::type - >::apply(p1, p0, bottom_right, ps_strategy); + result = sb_strategy.template segment_below_of_box + < + LessEqual, + ReturnType + >(p0, p1, + top_left, top_right, + bottom_left, bottom_right); return true; } // the segment lies above the box if (geometry::get<1>(p0) > geometry::get<1>(top_right)) { - result = above_of_box - < - LessEqual - >::apply(p0, p1, top_left, ps_strategy); + result = (std::min)(above_of_box + < + LessEqual + >::apply(p0, p1, top_left, sb_strategy), + above_of_box + < + GreaterEqual + >::apply(p1, p0, top_right, sb_strategy)); return true; } return false; @@ -499,47 +520,30 @@ private: { static inline bool apply(SegmentPoint const& p0, SegmentPoint const& p1, - BoxPoint const& bottom_left0, - BoxPoint const& top_right0, - BoxPoint const& bottom_left1, - BoxPoint const& top_right1, BoxPoint const& corner1, BoxPoint const& corner2, - PSStrategy const& ps_strategy, + SBStrategy const& sb_strategy, ReturnType& result) { - typedef cast_to_result<ReturnType> cast; - - ReturnType diff0 = cast::apply(geometry::get<0>(p1)) - - cast::apply(geometry::get<0>(p0)); - ReturnType t_min0 = cast::apply(geometry::get<0>(bottom_left0)) - - cast::apply(geometry::get<0>(p0)); - ReturnType t_max0 = cast::apply(geometry::get<0>(top_right0)) - - cast::apply(geometry::get<0>(p0)); + typedef typename geometry::strategy::side::services::default_strategy + < + typename geometry::cs_tag<SegmentPoint>::type + >::type side; + typedef cast_to_result<ReturnType> cast; ReturnType diff1 = cast::apply(geometry::get<1>(p1)) - - cast::apply(geometry::get<1>(p0)); - ReturnType t_min1 = cast::apply(geometry::get<1>(bottom_left1)) - - cast::apply(geometry::get<1>(p0)); - ReturnType t_max1 = cast::apply(geometry::get<1>(top_right1)) - - cast::apply(geometry::get<1>(p0)); + - cast::apply(geometry::get<1>(p0)); - if (diff1 < 0) - { - diff1 = -diff1; - t_min1 = -t_min1; - t_max1 = -t_max1; - } + typename SBStrategy::distance_ps_strategy::type ps_strategy = + sb_strategy.get_distance_ps_strategy(); - // t_min0 > t_max1 - if (t_min0 * diff1 > t_max1 * diff0) + int sign = diff1 < 0 ? -1 : 1; + if (side::apply(p0, p1, corner1) * sign < 0) { result = cast::apply(ps_strategy.apply(corner1, p0, p1)); return true; } - - // t_max0 < t_min1 - if (t_max0 * diff1 < t_min1 * diff0) + if (side::apply(p0, p1, corner2) * sign > 0) { result = cast::apply(ps_strategy.apply(corner2, p0, p1)); return true; @@ -555,8 +559,7 @@ private: BoxPoint const& top_right, BoxPoint const& bottom_left, BoxPoint const& bottom_right, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { typedef compare_less_equal<ReturnType, true> less_equal; @@ -576,7 +579,7 @@ private: less_equal >::apply(p0, p1, top_left, top_right, bottom_left, bottom_right, - pp_strategy, ps_strategy, result)) + sb_strategy, result)) { return result; } @@ -586,16 +589,14 @@ private: less_equal >::apply(p0, p1, top_left, top_right, bottom_left, bottom_right, - ps_strategy, result)) + sb_strategy, result)) { return result; } if (check_generic_position::apply(p0, p1, - bottom_left, top_right, - bottom_left, top_right, top_left, bottom_right, - ps_strategy, result)) + sb_strategy, result)) { return result; } @@ -612,8 +613,7 @@ private: BoxPoint const& top_right, BoxPoint const& bottom_left, BoxPoint const& bottom_right, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { typedef compare_less_equal<ReturnType, false> greater_equal; @@ -630,7 +630,7 @@ private: greater_equal >::apply(p0, p1, bottom_left, bottom_right, top_left, top_right, - pp_strategy, ps_strategy, result)) + sb_strategy, result)) { return result; } @@ -640,16 +640,14 @@ private: greater_equal >::apply(p1, p0, top_right, top_left, bottom_right, bottom_left, - ps_strategy, result)) + sb_strategy, result)) { return result; } if (check_generic_position::apply(p0, p1, bottom_left, top_right, - top_right, bottom_left, - bottom_left, top_right, - ps_strategy, result)) + sb_strategy, result)) { return result; } @@ -665,8 +663,7 @@ public: BoxPoint const& top_right, BoxPoint const& bottom_left, BoxPoint const& bottom_right, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1) || geometry::has_nan_coordinate(p0) @@ -678,27 +675,43 @@ public: return negative_slope_segment(p0, p1, top_left, top_right, bottom_left, bottom_right, - pp_strategy, ps_strategy); + sb_strategy); } return non_negative_slope_segment(p0, p1, top_left, top_right, bottom_left, bottom_right, - pp_strategy, ps_strategy); + sb_strategy); } -}; + template <typename LessEqual> + static inline ReturnType call_above_of_box(SegmentPoint const& p0, + SegmentPoint const& p1, + SegmentPoint const& p_max, + BoxPoint const& top_left, + SBStrategy const& sb_strategy) + { + return above_of_box<LessEqual>::apply(p0, p1, p_max, top_left, sb_strategy); + } -//========================================================================= + template <typename LessEqual> + static inline ReturnType call_above_of_box(SegmentPoint const& p0, + SegmentPoint const& p1, + BoxPoint const& top_left, + SBStrategy const& sb_strategy) + { + return above_of_box<LessEqual>::apply(p0, p1, top_left, sb_strategy); + } +}; +//========================================================================= template < typename Segment, typename Box, typename std::size_t Dimension, - typename PPStrategy, - typename PSStrategy + typename SBStrategy > class segment_to_box : not_implemented<Segment, Box> @@ -709,10 +722,9 @@ template < typename Segment, typename Box, - typename PPStrategy, - typename PSStrategy + typename SBStrategy > -class segment_to_box<Segment, Box, 2, PPStrategy, PSStrategy> +class segment_to_box<Segment, Box, 2, SBStrategy> { private: typedef typename point_type<Segment>::type segment_point; @@ -720,12 +732,7 @@ private: typedef typename strategy::distance::services::comparable_type < - PPStrategy - >::type pp_comparable_strategy; - - typedef typename strategy::distance::services::comparable_type - < - PSStrategy + SBStrategy >::type ps_comparable_strategy; typedef typename strategy::distance::services::return_type @@ -735,13 +742,12 @@ private: public: typedef typename strategy::distance::services::return_type < - PSStrategy, segment_point, box_point + SBStrategy, segment_point, box_point >::type return_type; static inline return_type apply(Segment const& segment, Box const& box, - PPStrategy const& pp_strategy, - PSStrategy const& ps_strategy) + SBStrategy const& sb_strategy) { segment_point p[2]; detail::assign_point_from_index<0>(segment, p[0]); @@ -754,7 +760,7 @@ public: boost::is_same < ps_comparable_strategy, - PSStrategy + SBStrategy >, typename strategy::distance::services::comparable_type < @@ -781,6 +787,10 @@ public: detail::assign_box_corners(box, bottom_left, bottom_right, top_left, top_right); + SBStrategy::mirror(p[0], p[1], + bottom_left, bottom_right, + top_left, top_right); + if (geometry::less<segment_point>()(p[0], p[1])) { return segment_to_box_2D @@ -788,12 +798,10 @@ public: return_type, segment_point, box_point, - PPStrategy, - PSStrategy + SBStrategy >::apply(p[0], p[1], top_left, top_right, bottom_left, bottom_right, - pp_strategy, - ps_strategy); + sb_strategy); } else { @@ -802,12 +810,10 @@ public: return_type, segment_point, box_point, - PPStrategy, - PSStrategy + SBStrategy >::apply(p[1], p[0], top_left, top_right, bottom_left, bottom_right, - pp_strategy, - ps_strategy); + sb_strategy); } } }; @@ -826,7 +832,7 @@ template <typename Segment, typename Box, typename Strategy> struct distance < Segment, Box, Strategy, segment_tag, box_tag, - strategy_tag_distance_point_segment, false + strategy_tag_distance_segment_box, false > { typedef typename strategy::distance::services::return_type @@ -843,40 +849,13 @@ struct distance { assert_dimension_equal<Segment, Box>(); - typedef typename boost::mpl::if_ - < - boost::is_same - < - typename strategy::distance::services::comparable_type - < - Strategy - >::type, - Strategy - >, - typename strategy::distance::services::comparable_type - < - typename detail::distance::default_strategy - < - typename point_type<Segment>::type, - typename point_type<Box>::type - >::type - >::type, - typename detail::distance::default_strategy - < - typename point_type<Segment>::type, - typename point_type<Box>::type - >::type - >::type pp_strategy_type; - - return detail::distance::segment_to_box < Segment, Box, dimension<Segment>::value, - pp_strategy_type, Strategy - >::apply(segment, box, pp_strategy_type(), strategy); + >::apply(segment, box, strategy); } }; diff --git a/boost/geometry/algorithms/detail/envelope/areal.hpp b/boost/geometry/algorithms/detail/envelope/areal.hpp new file mode 100644 index 0000000000..034a98c0ae --- /dev/null +++ b/boost/geometry/algorithms/detail/envelope/areal.hpp @@ -0,0 +1,146 @@ +// Boost.Geometry + +// Copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP + +#include <boost/geometry/core/cs.hpp> +#include <boost/geometry/core/tags.hpp> + +#include <boost/geometry/iterators/segment_iterator.hpp> + +#include <boost/geometry/algorithms/detail/envelope/range.hpp> +#include <boost/geometry/algorithms/detail/envelope/linear.hpp> + +#include <boost/geometry/algorithms/dispatch/envelope.hpp> + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace envelope +{ + +template <typename EnvelopePolicy> +struct envelope_polygon +{ + template <typename Polygon, typename Box, typename Strategy> + static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy) + { + typename ring_return_type<Polygon const>::type ext_ring + = exterior_ring(polygon); + + if (geometry::is_empty(ext_ring)) + { + // if the exterior ring is empty, consider the interior rings + envelope_multi_range + < + EnvelopePolicy + >::apply(interior_rings(polygon), mbr, strategy); + } + else + { + // otherwise, consider only the exterior ring + EnvelopePolicy::apply(ext_ring, mbr, strategy); + } + } +}; + + +}} // namespace detail::envelope +#endif // DOXYGEN_NO_DETAIL + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template <typename Ring, typename CS_Tag> +struct envelope<Ring, ring_tag, CS_Tag> + : detail::envelope::envelope_range +{}; + +template <typename Ring> +struct envelope<Ring, ring_tag, spherical_equatorial_tag> + : detail::envelope::envelope_linestring_or_ring_on_spheroid +{}; + +template <typename Ring> +struct envelope<Ring, ring_tag, geographic_tag> + : detail::envelope::envelope_linestring_or_ring_on_spheroid +{}; + + +template <typename Polygon, typename CS_Tag> +struct envelope<Polygon, polygon_tag, CS_Tag> + : detail::envelope::envelope_polygon + < + detail::envelope::envelope_range + > +{}; + +template <typename Polygon> +struct envelope<Polygon, polygon_tag, spherical_equatorial_tag> + : detail::envelope::envelope_polygon + < + detail::envelope::envelope_linestring_or_ring_on_spheroid + > +{}; + +template <typename Polygon> +struct envelope<Polygon, polygon_tag, geographic_tag> + : detail::envelope::envelope_polygon + < + detail::envelope::envelope_linestring_or_ring_on_spheroid + > +{}; + + +template <typename MultiPolygon, typename CS_Tag> +struct envelope<MultiPolygon, multi_polygon_tag, CS_Tag> + : detail::envelope::envelope_multi_range + < + detail::envelope::envelope_polygon + < + detail::envelope::envelope_range + > + > +{}; + +template <typename MultiPolygon> +struct envelope<MultiPolygon, multi_polygon_tag, spherical_equatorial_tag> + : detail::envelope::envelope_multi_range + < + detail::envelope::envelope_polygon + < + detail::envelope::envelope_linestring_or_ring_on_spheroid + > + > +{}; + +template <typename MultiPolygon> +struct envelope<MultiPolygon, multi_polygon_tag, geographic_tag> + : detail::envelope::envelope_multi_range + < + detail::envelope::envelope_polygon + < + detail::envelope::envelope_linestring_or_ring_on_spheroid + > + > +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp index 33b43da255..cf039a292a 100644 --- a/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/boost/geometry/algorithms/detail/envelope/box.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -124,7 +124,12 @@ struct envelope_box_on_spheroid BoxOut& mbr, Strategy const&) { - BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in); + BoxIn box_in_normalized = box_in; + + if (!is_inverse_spheroidal_coordinates(box_in)) + { + box_in_normalized = detail::return_normalized<BoxIn>(box_in); + } envelope_indexed_box_on_spheroid < diff --git a/boost/geometry/algorithms/detail/envelope/implementation.hpp b/boost/geometry/algorithms/detail/envelope/implementation.hpp index d549700791..66ba80dbe1 100644 --- a/boost/geometry/algorithms/detail/envelope/implementation.hpp +++ b/boost/geometry/algorithms/detail/envelope/implementation.hpp @@ -26,6 +26,7 @@ #include <boost/geometry/algorithms/is_empty.hpp> +#include <boost/geometry/algorithms/detail/envelope/areal.hpp> #include <boost/geometry/algorithms/detail/envelope/box.hpp> #include <boost/geometry/algorithms/detail/envelope/linear.hpp> #include <boost/geometry/algorithms/detail/envelope/multipoint.hpp> @@ -35,73 +36,4 @@ #include <boost/geometry/algorithms/dispatch/envelope.hpp> - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace envelope -{ - - -struct envelope_polygon -{ - template <typename Polygon, typename Box, typename Strategy> - static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy) - { - typename ring_return_type<Polygon const>::type ext_ring - = exterior_ring(polygon); - - if (geometry::is_empty(ext_ring)) - { - // if the exterior ring is empty, consider the interior rings - envelope_multi_range - < - envelope_range - >::apply(interior_rings(polygon), mbr, strategy); - } - else - { - // otherwise, consider only the exterior ring - envelope_range::apply(ext_ring, mbr, strategy); - } - } -}; - - -}} // namespace detail::envelope -#endif // DOXYGEN_NO_DETAIL - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -template <typename Ring> -struct envelope<Ring, ring_tag> - : detail::envelope::envelope_range -{}; - - -template <typename Polygon> -struct envelope<Polygon, polygon_tag> - : detail::envelope::envelope_polygon -{}; - - -template <typename MultiPolygon> -struct envelope<MultiPolygon, multi_polygon_tag> - : detail::envelope::envelope_multi_range - < - detail::envelope::envelope_polygon - > -{}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - -}} // namespace boost::geometry - #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp index 09d8a76da5..7fa788b738 100644 --- a/boost/geometry/algorithms/detail/envelope/linear.hpp +++ b/boost/geometry/algorithms/detail/envelope/linear.hpp @@ -34,16 +34,15 @@ namespace boost { namespace geometry namespace detail { namespace envelope { - -struct envelope_linestring_on_spheroid +struct envelope_linestring_or_ring_on_spheroid { - template <typename Linestring, typename Box, typename Strategy> - static inline void apply(Linestring const& linestring, + template <typename LinestringRing, typename Box, typename Strategy> + static inline void apply(LinestringRing const& linestring_or_ring, Box& mbr, Strategy const& strategy) { - envelope_range::apply(geometry::segments_begin(linestring), - geometry::segments_end(linestring), + envelope_range::apply(geometry::segments_begin(linestring_or_ring), + geometry::segments_end(linestring_or_ring), mbr, strategy); } @@ -66,12 +65,12 @@ struct envelope<Linestring, linestring_tag, CS_Tag> template <typename Linestring> struct envelope<Linestring, linestring_tag, spherical_equatorial_tag> - : detail::envelope::envelope_linestring_on_spheroid + : detail::envelope::envelope_linestring_or_ring_on_spheroid {}; template <typename Linestring> struct envelope<Linestring, linestring_tag, geographic_tag> - : detail::envelope::envelope_linestring_on_spheroid + : detail::envelope::envelope_linestring_or_ring_on_spheroid {}; @@ -91,7 +90,7 @@ struct envelope MultiLinestring, multi_linestring_tag, spherical_equatorial_tag > : detail::envelope::envelope_multi_range_on_spheroid < - detail::envelope::envelope_linestring_on_spheroid + detail::envelope::envelope_linestring_or_ring_on_spheroid > {}; @@ -101,7 +100,7 @@ struct envelope MultiLinestring, multi_linestring_tag, geographic_tag > : detail::envelope::envelope_multi_range_on_spheroid < - detail::envelope::envelope_linestring_on_spheroid + detail::envelope::envelope_linestring_or_ring_on_spheroid > {}; diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 9b9e2f85d3..92d1fe3959 100644 --- a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015-2017, Oracle and/or its affiliates. +// Copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -272,6 +272,11 @@ struct envelope_range_of_boxes it != boost::end(range_of_boxes); ++it) { + if (is_inverse_spheroidal_coordinates(*it)) + { + continue; + } + coordinate_type lat_min = geometry::get<min_corner, 1>(*it); coordinate_type lat_max = geometry::get<max_corner, 1>(*it); if (math::equals(lat_min, constants::max_latitude()) diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp index 06c64bafc8..cfa139a087 100644 --- a/boost/geometry/algorithms/detail/envelope/segment.hpp +++ b/boost/geometry/algorithms/detail/envelope/segment.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015-2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -21,6 +21,7 @@ #include <cstddef> #include <utility> +#include <boost/core/ignore_unused.hpp> #include <boost/numeric/conversion/cast.hpp> #include <boost/geometry/core/assert.hpp> @@ -35,13 +36,12 @@ #include <boost/geometry/geometries/helper_geometry.hpp> +#include <boost/geometry/formulas/meridian_segment.hpp> #include <boost/geometry/formulas/vertex_latitude.hpp> #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp> - #include <boost/geometry/algorithms/detail/envelope/point.hpp> #include <boost/geometry/algorithms/detail/envelope/transform_units.hpp> - #include <boost/geometry/algorithms/detail/expand/point.hpp> #include <boost/geometry/algorithms/dispatch/envelope.hpp> @@ -164,10 +164,17 @@ private: { // coordinates are assumed to be in radians BOOST_GEOMETRY_ASSERT(lon1 <= lon2); + boost::ignore_unused(lon1, lon2); CalculationType lat1_rad = math::as_radian<Units>(lat1); CalculationType lat2_rad = math::as_radian<Units>(lat2); + if (math::equals(a1, a2)) + { + // the segment must lie on the equator or is very short or is meridian + return; + } + if (lat1 > lat2) { std::swap(lat1, lat2); @@ -175,12 +182,6 @@ private: std::swap(a1, a2); } - if (math::equals(a1, a2)) - { - // the segment must lie on the equator or is very short - return; - } - if (contains_pi_half(a1, a2)) { CalculationType p_max = envelope_segment_call_vertex_latitude @@ -354,8 +355,7 @@ private: CalculationType lon2_rad = math::as_radian<Units>(lon2); CalculationType lat2_rad = math::as_radian<Units>(lat2); CalculationType alp2; - strategy.apply(lon2_rad, lat2_rad, lon1_rad, lat1_rad, alp2); - alp2 += math::pi<CalculationType>(); + strategy.apply_reverse(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp2); compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy); } diff --git a/boost/geometry/algorithms/detail/expand/point.hpp b/boost/geometry/algorithms/detail/expand/point.hpp index 2d8b0feff6..88ebe75db7 100644 --- a/boost/geometry/algorithms/detail/expand/point.hpp +++ b/boost/geometry/algorithms/detail/expand/point.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -35,6 +35,7 @@ #include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/tags.hpp> +#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp> #include <boost/geometry/util/math.hpp> #include <boost/geometry/util/select_coordinate_type.hpp> @@ -43,7 +44,6 @@ #include <boost/geometry/algorithms/dispatch/expand.hpp> - namespace boost { namespace geometry { @@ -112,95 +112,106 @@ struct point_loop_on_spheroid // normalize input point and input box Point p_normalized = detail::return_normalized<Point>(point); - detail::normalize(box, box); // transform input point to be of the same type as the box point box_point_type box_point; detail::envelope::transform_units(p_normalized, box_point); - box_coordinate_type p_lon = geometry::get<0>(box_point); - box_coordinate_type p_lat = geometry::get<1>(box_point); + if (is_inverse_spheroidal_coordinates(box)) + { + geometry::set_from_radian<min_corner, 0>(box, geometry::get_as_radian<0>(p_normalized)); + geometry::set_from_radian<min_corner, 1>(box, geometry::get_as_radian<1>(p_normalized)); + geometry::set_from_radian<max_corner, 0>(box, geometry::get_as_radian<0>(p_normalized)); + geometry::set_from_radian<max_corner, 1>(box, geometry::get_as_radian<1>(p_normalized)); - typename coordinate_type<Box>::type - b_lon_min = geometry::get<min_corner, 0>(box), - b_lat_min = geometry::get<min_corner, 1>(box), - b_lon_max = geometry::get<max_corner, 0>(box), - b_lat_max = geometry::get<max_corner, 1>(box); + } else { - if (math::is_latitude_pole<units_type, IsEquatorial>(p_lat)) - { - // the point of expansion is the either the north or the - // south pole; the only important coordinate here is the - // pole's latitude, as the longitude can be anything; - // we, thus, take into account the point's latitude only and return - geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min)); - geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max)); - return; - } + detail::normalize(box, box); - if (math::equals(b_lat_min, b_lat_max) - && math::is_latitude_pole<units_type, IsEquatorial>(b_lat_min)) - { - // the box degenerates to either the north or the south pole; - // the only important coordinate here is the pole's latitude, - // as the longitude can be anything; - // we thus take into account the box's latitude only and return - geometry::set<min_corner, 0>(box, p_lon); - geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min)); - geometry::set<max_corner, 0>(box, p_lon); - geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max)); - return; - } + box_coordinate_type p_lon = geometry::get<0>(box_point); + box_coordinate_type p_lat = geometry::get<1>(box_point); - // update latitudes - b_lat_min = (std::min)(b_lat_min, p_lat); - b_lat_max = (std::max)(b_lat_max, p_lat); + typename coordinate_type<Box>::type + b_lon_min = geometry::get<min_corner, 0>(box), + b_lat_min = geometry::get<min_corner, 1>(box), + b_lon_max = geometry::get<max_corner, 0>(box), + b_lat_max = geometry::get<max_corner, 1>(box); - // update longitudes - if (math::smaller(p_lon, b_lon_min)) - { - box_coordinate_type p_lon_shifted = p_lon + constants::period(); + if (math::is_latitude_pole<units_type, IsEquatorial>(p_lat)) + { + // the point of expansion is the either the north or the + // south pole; the only important coordinate here is the + // pole's latitude, as the longitude can be anything; + // we, thus, take into account the point's latitude only and return + geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min)); + geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max)); + return; + } + + if (math::equals(b_lat_min, b_lat_max) + && math::is_latitude_pole<units_type, IsEquatorial>(b_lat_min)) + { + // the box degenerates to either the north or the south pole; + // the only important coordinate here is the pole's latitude, + // as the longitude can be anything; + // we thus take into account the box's latitude only and return + geometry::set<min_corner, 0>(box, p_lon); + geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min)); + geometry::set<max_corner, 0>(box, p_lon); + geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max)); + return; + } + + // update latitudes + b_lat_min = (std::min)(b_lat_min, p_lat); + b_lat_max = (std::max)(b_lat_max, p_lat); + + // update longitudes + if (math::smaller(p_lon, b_lon_min)) + { + box_coordinate_type p_lon_shifted = p_lon + constants::period(); - if (math::larger(p_lon_shifted, b_lon_max)) + if (math::larger(p_lon_shifted, b_lon_max)) + { + // here we could check using: ! math::larger(.., ..) + if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max)) + { + b_lon_min = p_lon; + } + else + { + b_lon_max = p_lon_shifted; + } + } + } + else if (math::larger(p_lon, b_lon_max)) { - // here we could check using: ! math::larger(.., ..) - if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max)) + // in this case, and since p_lon is normalized in the range + // (-180, 180], we must have that b_lon_max <= 180 + if (b_lon_min < 0 + && math::larger(p_lon - b_lon_max, + constants::period() - p_lon + b_lon_min)) { b_lon_min = p_lon; + b_lon_max += constants::period(); } else { - b_lon_max = p_lon_shifted; + b_lon_max = p_lon; } } - } - else if (math::larger(p_lon, b_lon_max)) - { - // in this case, and since p_lon is normalized in the range - // (-180, 180], we must have that b_lon_max <= 180 - if (b_lon_min < 0 - && math::larger(p_lon - b_lon_max, - constants::period() - p_lon + b_lon_min)) - { - b_lon_min = p_lon; - b_lon_max += constants::period(); - } - else - { - b_lon_max = p_lon; - } - } - geometry::set<min_corner, 0>(box, b_lon_min); - geometry::set<min_corner, 1>(box, b_lat_min); - geometry::set<max_corner, 0>(box, b_lon_max); - geometry::set<max_corner, 1>(box, b_lat_max); + geometry::set<min_corner, 0>(box, b_lon_min); + geometry::set<min_corner, 1>(box, b_lat_min); + geometry::set<max_corner, 0>(box, b_lon_max); + geometry::set<max_corner, 1>(box, b_lat_max); + } point_loop < 2, DimensionCount >::apply(box, point, strategy); - } + } }; diff --git a/boost/geometry/algorithms/detail/relate/result.hpp b/boost/geometry/algorithms/detail/relate/result.hpp index 07287dc625..92bc160a6c 100644 --- a/boost/geometry/algorithms/detail/relate/result.hpp +++ b/boost/geometry/algorithms/detail/relate/result.hpp @@ -16,6 +16,7 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP #include <cstddef> +#include <cstring> #include <boost/mpl/assert.hpp> #include <boost/mpl/at.hpp> diff --git a/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/boost/geometry/algorithms/detail/sections/sectionalize.hpp index f1d8e7d231..d854c67148 100644 --- a/boost/geometry/algorithms/detail/sections/sectionalize.hpp +++ b/boost/geometry/algorithms/detail/sections/sectionalize.hpp @@ -162,12 +162,10 @@ struct get_direction_loop { typedef typename coordinate_type<Segment>::type coordinate_type; - coordinate_type const diff = - geometry::get<1, dimension::value>(seg) - - geometry::get<0, dimension::value>(seg); + coordinate_type const c0 = geometry::get<0, dimension::value>(seg); + coordinate_type const c1 = geometry::get<1, dimension::value>(seg); - coordinate_type zero = coordinate_type(); - directions[Index] = diff > zero ? 1 : diff < zero ? -1 : 0; + directions[Index] = c1 > c0 ? 1 : c1 < c0 ? -1 : 0; get_direction_loop < diff --git a/boost/geometry/formulas/area_formulas.hpp b/boost/geometry/formulas/area_formulas.hpp index 9243c7f749..66d90a7256 100644 --- a/boost/geometry/formulas/area_formulas.hpp +++ b/boost/geometry/formulas/area_formulas.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2015-2017 Oracle and/or its affiliates. +// Copyright (c) 2015-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -13,6 +13,7 @@ #define BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP #include <boost/geometry/formulas/flattening.hpp> +#include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> namespace boost { namespace geometry { namespace formula @@ -45,7 +46,7 @@ public: Evaluate the polynomial in x using Horner's method. */ template <typename NT, typename IteratorType> - static inline NT horner_evaluate(NT x, + static inline NT horner_evaluate(NT const& x, IteratorType begin, IteratorType end) { @@ -64,7 +65,7 @@ public: https://en.wikipedia.org/wiki/Clenshaw_algorithm */ template <typename NT, typename IteratorType> - static inline NT clenshaw_sum(NT cosx, + static inline NT clenshaw_sum(NT const& cosx, IteratorType begin, IteratorType end) { @@ -166,7 +167,7 @@ public: s/case\sCT(/case /g; s/):/:/g' */ - static inline void evaluate_coeffs_n(CT n, CT coeffs_n[]) + static inline void evaluate_coeffs_n(CT const& n, CT coeffs_n[]) { switch (SeriesOrder) { @@ -245,7 +246,7 @@ public: /* Expand in k2 and ep2. */ - static inline void evaluate_coeffs_ep(CT ep, CT coeffs_n[]) + static inline void evaluate_coeffs_ep(CT const& ep, CT coeffs_n[]) { switch (SeriesOrder) { case 0: @@ -323,18 +324,22 @@ public: Given the set of coefficients coeffs1[] evaluate on var2 and return the set of coefficients coeffs2[] */ - static inline void evaluate_coeffs_var2(CT var2, - CT coeffs1[], - CT coeffs2[]){ + + static inline void evaluate_coeffs_var2(CT const& var2, + CT const coeffs1[], + CT coeffs2[]) + { std::size_t begin(0), end(0); - for(std::size_t i = 0; i <= SeriesOrder; i++){ + for(std::size_t i = 0; i <= SeriesOrder; i++) + { end = begin + SeriesOrder + 1 - i; - coeffs2[i] = ((i==0) ? CT(1) : pow(var2,int(i))) + coeffs2[i] = ((i==0) ? CT(1) : math::pow(var2, int(i))) * horner_evaluate(var2, coeffs1 + begin, coeffs1 + end); begin = end; } } + /* Compute the spherical excess of a geodesic (or shperical) segment */ @@ -403,13 +408,12 @@ public: */ template < template <typename, bool, bool, bool, bool, bool> class Inverse, - //typename AzimuthStrategy, typename PointOfSegment, typename SpheroidConst > static inline return_type_ellipsoidal ellipsoidal(PointOfSegment const& p1, PointOfSegment const& p2, - SpheroidConst spheroid_const) + SpheroidConst const& spheroid_const) { return_type_ellipsoidal result; diff --git a/boost/geometry/formulas/meridian_direct.hpp b/boost/geometry/formulas/meridian_direct.hpp new file mode 100644 index 0000000000..e55b35e88f --- /dev/null +++ b/boost/geometry/formulas/meridian_direct.hpp @@ -0,0 +1,168 @@ +// Boost.Geometry + +// Copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_FORMULAS_MERIDIAN_DIRECT_HPP +#define BOOST_GEOMETRY_FORMULAS_MERIDIAN_DIRECT_HPP + +#include <boost/math/constants/constants.hpp> + +#include <boost/geometry/core/radius.hpp> + +#include <boost/geometry/util/condition.hpp> +#include <boost/geometry/util/math.hpp> + +#include <boost/geometry/formulas/meridian_inverse.hpp> +#include <boost/geometry/formulas/flattening.hpp> +#include <boost/geometry/formulas/quarter_meridian.hpp> +#include <boost/geometry/formulas/result_direct.hpp> + +namespace boost { namespace geometry { namespace formula +{ + +/*! +\brief Compute the direct geodesic problem on a meridian +*/ + +template < + typename CT, + bool EnableCoordinates = true, + bool EnableReverseAzimuth = false, + bool EnableReducedLength = false, + bool EnableGeodesicScale = false, + unsigned int Order = 4 +> +class meridian_direct +{ + static const bool CalcQuantities = EnableReducedLength || EnableGeodesicScale; + static const bool CalcRevAzimuth = EnableReverseAzimuth || CalcQuantities; + static const bool CalcCoordinates = EnableCoordinates || CalcRevAzimuth; + +public: + typedef result_direct<CT> result_type; + + template <typename T, typename Dist, typename Spheroid> + static inline result_type apply(T const& lo1, + T const& la1, + Dist const& distance, + bool north, + Spheroid const& spheroid) + { + result_type result; + + CT const half_pi = math::half_pi<CT>(); + CT const pi = math::pi<CT>(); + CT const one_and_a_half_pi = pi + half_pi; + CT const c0 = 0; + + CT azimuth = north ? c0 : pi; + + if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + { + CT s0 = meridian_inverse<CT, Order>::apply(la1, spheroid); + int signed_distance = north ? distance : -distance; + result.lon2 = lo1; + result.lat2 = apply(s0 + signed_distance, spheroid); + } + + if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + { + result.reverse_azimuth = azimuth; + + + if (result.lat2 > half_pi && + result.lat2 < one_and_a_half_pi) + { + result.reverse_azimuth = pi; + } + else if (result.lat2 < -half_pi && + result.lat2 > -one_and_a_half_pi) + { + result.reverse_azimuth = c0; + } + + } + + if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + { + CT const b = CT(get_radius<2>(spheroid)); + CT const f = formula::flattening<CT>(spheroid); + + boost::geometry::math::normalize_spheroidal_coordinates + < + boost::geometry::radian, + double + >(result.lon2, result.lat2); + + typedef differential_quantities + < + CT, + EnableReducedLength, + EnableGeodesicScale, + Order + > quantities; + quantities::apply(lo1, la1, result.lon2, result.lat2, + azimuth, result.reverse_azimuth, + b, f, + result.reduced_length, result.geodesic_scale); + } + return result; + } + + // https://en.wikipedia.org/wiki/Meridian_arc#The_inverse_meridian_problem_for_the_ellipsoid + // latitudes are assumed to be in radians and in [-pi/2,pi/2] + template <typename T, typename Spheroid> + static CT apply(T m, Spheroid const& spheroid) + { + CT const f = formula::flattening<CT>(spheroid); + CT n = f / (CT(2) - f); + CT mp = formula::quarter_meridian<CT>(spheroid); + CT mu = geometry::math::pi<CT>()/CT(2) * m / mp; + + if (Order == 0) + { + return mu; + } + + CT H2 = 1.5 * n; + + if (Order == 1) + { + return mu + H2 * sin(2*mu); + } + + CT n2 = n * n; + CT H4 = 1.3125 * n2; + + if (Order == 2) + { + return mu + H2 * sin(2*mu) + H4 * sin(4*mu); + } + + CT n3 = n2 * n; + H2 -= 0.84375 * n3; + CT H6 = 1.572916667 * n3; + + if (Order == 3) + { + return mu + H2 * sin(2*mu) + H4 * sin(4*mu) + H6 * sin(6*mu); + } + + CT n4 = n2 * n2; + H4 -= 1.71875 * n4; + CT H8 = 2.142578125 * n4; + + // Order 4 or higher + return mu + H2 * sin(2*mu) + H4 * sin(4*mu) + H6 * sin(6*mu) + H8 * sin(8*mu); + } +}; + +}}} // namespace boost::geometry::formula + +#endif // BOOST_GEOMETRY_FORMULAS_MERIDIAN_DIRECT_HPP diff --git a/boost/geometry/formulas/elliptic_arc_length.hpp b/boost/geometry/formulas/meridian_inverse.hpp index 65c8f60226..43bec19970 100644 --- a/boost/geometry/formulas/elliptic_arc_length.hpp +++ b/boost/geometry/formulas/meridian_inverse.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -8,8 +8,8 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_GEOMETRY_FORMULAS_ELLIPTIC_ARC_LENGTH_HPP -#define BOOST_GEOMETRY_FORMULAS_ELLIPTIC_ARC_LENGTH_HPP +#ifndef BOOST_GEOMETRY_FORMULAS_MERIDIAN_INVERSE_HPP +#define BOOST_GEOMETRY_FORMULAS_MERIDIAN_INVERSE_HPP #include <boost/math/constants/constants.hpp> @@ -20,6 +20,7 @@ #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/formulas/flattening.hpp> +#include <boost/geometry/formulas/meridian_segment.hpp> namespace boost { namespace geometry { namespace formula { @@ -29,7 +30,7 @@ namespace boost { namespace geometry { namespace formula */ template <typename CT, unsigned int Order = 1> -class elliptic_arc_length +class meridian_inverse { public : @@ -167,68 +168,9 @@ public : + C6 * sin(6*lat) + C8 * sin(8*lat) + C10 * sin(10*lat)); } - - // Iterative method to elliptic arc length based on - // http://www.codeguru.com/cpp/cpp/algorithms/article.php/c5115/ - // Geographic-Distance-and-Azimuth-Calculations.htm - // latitudes are assumed to be in radians and in [-pi/2,pi/2] - template <typename T1, typename T2, typename Spheroid> - CT interative_method(T1 lat1, - T2 lat2, - Spheroid const& spheroid) - { - CT result = 0; - CT const zero = 0; - CT const one = 1; - CT const c1 = 2; - CT const c2 = 0.5; - CT const c3 = 4000; - - CT const a = get_radius<0>(spheroid); - CT const f = formula::flattening<CT>(spheroid); - - // how many steps to use - - CT lat1_deg = lat1 * geometry::math::r2d<CT>(); - CT lat2_deg = lat2 * geometry::math::r2d<CT>(); - - int steps = c1 + (c2 + (lat2_deg > lat1_deg) ? CT(lat2_deg - lat1_deg) - : CT(lat1_deg - lat2_deg)); - steps = (steps > c3) ? c3 : steps; - - //std::cout << "Steps=" << steps << std::endl; - - CT snLat1 = sin(lat1); - CT snLat2 = sin(lat2); - CT twoF = 2 * f - f * f; - - // limits of integration - CT x1 = a * cos(lat1) / - sqrt(1 - twoF * snLat1 * snLat1); - CT x2 = a * cos(lat2) / - sqrt(1 - twoF * snLat2 * snLat2); - - CT dx = (x2 - x1) / (steps - one); - CT x, y1, y2, dy, dydx; - CT adx = (dx < zero) ? -dx : dx; // absolute value of dx - - CT a2 = a * a; - CT oneF = 1 - f; - - // now loop through each step adding up all the little - // hypotenuses - for (int i = 0; i < (steps - 1); i++){ - x = x1 + dx * i; - dydx = ((a * oneF * sqrt((one - ((x+dx)*(x+dx))/a2))) - - (a * oneF * sqrt((one - (x*x)/a2)))) / dx; - result += adx * sqrt(one + dydx*dydx); - } - - return result; - } }; }}} // namespace boost::geometry::formula -#endif // BOOST_GEOMETRY_FORMULAS_ELLIPTIC_ARC_LENGTH_HPP +#endif // BOOST_GEOMETRY_FORMULAS_MERIDIAN_INVERSE_HPP diff --git a/boost/geometry/formulas/meridian_segment.hpp b/boost/geometry/formulas/meridian_segment.hpp new file mode 100644 index 0000000000..535e31e3db --- /dev/null +++ b/boost/geometry/formulas/meridian_segment.hpp @@ -0,0 +1,72 @@ +// Boost.Geometry + +// Copyright (c) 2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP +#define BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP + +#include <boost/math/constants/constants.hpp> + +#include <boost/geometry/core/radius.hpp> +#include <boost/geometry/srs/srs.hpp> + +#include <boost/geometry/util/condition.hpp> +#include <boost/geometry/util/math.hpp> +#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> + +namespace boost { namespace geometry { namespace formula +{ + +/*! +\brief Test if a segment is meridian or not. +*/ + +class meridian_segment +{ + +public : + + enum SegmentType {NonMeridian, MeridianCrossingPole, MeridianNotCrossingPole}; + + template <typename T> + static inline SegmentType is_meridian(T lon1, T lat1, T lon2, T lat2) + { + SegmentType res = NonMeridian; + T diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2); + + if ( meridian_not_crossing_pole(lat1, lat2, diff) ) + { + res = MeridianNotCrossingPole; + } + else if ( meridian_crossing_pole(diff) ) + { + res = MeridianCrossingPole; + } + return res; + } + + template <typename T> + static bool meridian_not_crossing_pole(T lat1, T lat2, T diff) + { + T half_pi = math::half_pi<T>(); + return math::equals(diff, T(0)) || + (math::equals(lat2, half_pi) && math::equals(lat1, -half_pi)); + } + + template <typename T> + static bool meridian_crossing_pole(T diff) + { + return math::equals(math::abs(diff), math::pi<T>()); + } + +}; + +}}} // namespace boost::geometry::formula + +#endif //BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP diff --git a/boost/geometry/formulas/quarter_meridian.hpp b/boost/geometry/formulas/quarter_meridian.hpp new file mode 100644 index 0000000000..2f93f53cf6 --- /dev/null +++ b/boost/geometry/formulas/quarter_meridian.hpp @@ -0,0 +1,107 @@ +// Boost.Geometry + +// Copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_FORMULAS_QUARTER_MERIDIAN_HPP +#define BOOST_GEOMETRY_FORMULAS_QUARTER_MERIDIAN_HPP + +#include <boost/geometry/core/radius.hpp> +#include <boost/geometry/core/tag.hpp> +#include <boost/geometry/core/tags.hpp> + +#include <boost/geometry/algorithms/not_implemented.hpp> + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DISPATCH +namespace formula_dispatch +{ + +template <typename ResultType, typename Geometry, typename Tag = typename tag<Geometry>::type> +struct quarter_meridian + : not_implemented<Tag> +{}; + +template <typename ResultType, typename Geometry> +struct quarter_meridian<ResultType, Geometry, srs_spheroid_tag> +{ + //https://en.wikipedia.org/wiki/Meridian_arc#Generalized_series + //http://www.wolframalpha.com/input/?i=(sum(((2*j-3)!!%2F(2*j)!!)%5E2*n%5E(2*j),j,0,8)) + static inline ResultType apply(Geometry const& geometry) + { + //order 8 expansion + ResultType const C[] = + { + 1073741824, + 268435456, + 16777216, + 4194304, + 1638400, + 802816, + 451584, + 278784, + 184041 + }; + + ResultType const c2 = 2; + ResultType const c4 = 4; + ResultType const f = formula::flattening<ResultType>(geometry); + ResultType const n = f / (c2 - f); + ResultType const ab4 = (get_radius<0>(geometry) + + get_radius<2>(geometry)) / c4; + return geometry::math::pi<ResultType>() * ab4 * + horner_evaluate(n*n, C, C+8) / C[0]; + } + +private : + //TODO: move the following to a more general space to be used by other + // classes as well + /* + Evaluate the polynomial in x using Horner's method. + */ + template <typename NT, typename IteratorType> + static inline NT horner_evaluate(NT x, + IteratorType begin, + IteratorType end) + { + NT result(0); + if (begin == end) + { + return result; + } + IteratorType it = end; + do + { + result = result * x + *--it; + } + while (it != begin); + return result; + } +}; + +} // namespace formula_dispatch +#endif // DOXYGEN_NO_DISPATCH + +#ifndef DOXYGEN_NO_DETAIL +namespace formula +{ + +template <typename ResultType, typename Geometry> +ResultType quarter_meridian(Geometry const& geometry) +{ + return formula_dispatch::quarter_meridian<ResultType, Geometry>::apply(geometry); +} + +} // namespace formula +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_FORMULAS_QUARTER_MERIDIAN_HPP diff --git a/boost/geometry/formulas/spherical.hpp b/boost/geometry/formulas/spherical.hpp index ff24c51a88..5599cd6e81 100644 --- a/boost/geometry/formulas/spherical.hpp +++ b/boost/geometry/formulas/spherical.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -15,6 +15,7 @@ #include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/access.hpp> #include <boost/geometry/core/radian_access.hpp> +#include <boost/geometry/core/radius.hpp> //#include <boost/geometry/arithmetic/arithmetic.hpp> #include <boost/geometry/arithmetic/cross_product.hpp> @@ -24,6 +25,8 @@ #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/select_coordinate_type.hpp> +#include <boost/geometry/formulas/result_direct.hpp> + namespace boost { namespace geometry { namespace formula { @@ -217,6 +220,62 @@ inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2) : 1; // left } +template +< + bool Coordinates, + bool ReverseAzimuth, + typename CT, + typename Sphere +> +inline result_direct<CT> spherical_direct(CT const& lon1, + CT const& lat1, + CT const& sig12, + CT const& alp1, + Sphere const& sphere) +{ + result_direct<CT> result; + + CT const sin_alp1 = sin(alp1); + CT const sin_lat1 = sin(lat1); + CT const cos_alp1 = cos(alp1); + CT const cos_lat1 = cos(lat1); + + CT const norm = math::sqrt(cos_alp1 * cos_alp1 + sin_alp1 * sin_alp1 + * sin_lat1 * sin_lat1); + CT const alp0 = atan2(sin_alp1 * cos_lat1, norm); + CT const sig1 = atan2(sin_lat1, cos_alp1 * cos_lat1); + CT const sig2 = sig1 + sig12 / get_radius<0>(sphere); + + CT const cos_sig2 = cos(sig2); + CT const sin_alp0 = sin(alp0); + CT const cos_alp0 = cos(alp0); + + if (Coordinates) + { + CT const sin_sig2 = sin(sig2); + CT const sin_sig1 = sin(sig1); + CT const cos_sig1 = cos(sig1); + + CT const norm2 = math::sqrt(cos_alp0 * cos_alp0 * cos_sig2 * cos_sig2 + + sin_alp0 * sin_alp0); + CT const lat2 = atan2(cos_alp0 * sin_sig2, norm2); + + CT const omg1 = atan2(sin_alp0 * sin_sig1, cos_sig1); + CT const lon2 = atan2(sin_alp0 * sin_sig2, cos_sig2); + + result.lon2 = lon1 + lon2 - omg1; + result.lat2 = lat2; + } + + if (ReverseAzimuth) + { + CT const alp2 = atan2(sin_alp0, cos_alp0 * cos_sig2); + result.reverse_azimuth = alp2; + } + + return result; +} + } // namespace formula }} // namespace boost::geometry diff --git a/boost/geometry/formulas/thomas_direct.hpp b/boost/geometry/formulas/thomas_direct.hpp index 6a7ac3e414..830f256a6e 100644 --- a/boost/geometry/formulas/thomas_direct.hpp +++ b/boost/geometry/formulas/thomas_direct.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2016-2017 Oracle and/or its affiliates. +// Copyright (c) 2016-2018 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -30,16 +31,16 @@ namespace boost { namespace geometry { namespace formula /*! \brief The solution of the direct problem of geodesics on latlong coordinates, - Forsyth-Andoyer-Lambert type approximation with second order terms. + Forsyth-Andoyer-Lambert type approximation with first/second order terms. \author See - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965 http://www.dtic.mil/docs/citations/AD0627893 - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970 http://www.dtic.mil/docs/citations/AD0703541 - */ template < typename CT, + bool SecondOrder = true, bool EnableCoordinates = true, bool EnableReverseAzimuth = false, bool EnableReducedLength = false, @@ -91,7 +92,7 @@ public: CT azi12_alt = azimuth12; CT lat1_alt = lat1; bool alter_result = vflip_if_south(lat1, azimuth12, lat1_alt, azi12_alt); - + CT const theta1 = math::equals(lat1_alt, pi_half) ? lat1_alt : math::equals(lat1_alt, -pi_half) ? lat1_alt : atan(one_minus_f * tan(lat1_alt)); @@ -108,9 +109,18 @@ public: CT const N = cos_theta1 * cos_a12; CT const C1 = f * M; // lower-case c1 in the technical report CT const C2 = f * (c1 - math::sqr(M)) / c4; // lower-case c2 in the technical report - CT const D = (c1 - C2) * (c1 - C2 - C1 * M); - CT const P = C2 * (c1 + C1 * M / c2) / D; - + CT D = 0; + CT P = 0; + if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + { + D = (c1 - C2) * (c1 - C2 - C1 * M); + P = C2 * (c1 + C1 * M / c2) / D; + } + else + { + D = c1 - c2 * C2 - C1 * M; + P = C2 / D; + } // special case for equator: // sin_theta0 = 0 <=> lat1 = 0 ^ |azimuth12| = pi/2 // NOTE: in this case it doesn't matter what's the value of cos_sigma1 because @@ -132,9 +142,14 @@ public: CT const W = c1 - c2 * P * cos_u; CT const V = cos_u * cos_d - sin_u * sin_d; - CT const X = math::sqr(C2) * sin_d * cos_d * (2 * math::sqr(V) - c1); CT const Y = c2 * P * V * W * sin_d; - CT const d_sigma = d + X - Y; + CT X = 0; + CT d_sigma = d - Y; + if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + { + X = math::sqr(C2) * sin_d * cos_d * (2 * math::sqr(V) - c1); + d_sigma += X; + } CT const sin_d_sigma = sin(d_sigma); CT const cos_d_sigma = cos(d_sigma); @@ -151,11 +166,16 @@ public: if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) { CT const S_sigma = c2 * sigma1 - d_sigma; - CT const cos_S_sigma = cos(S_sigma); + CT cos_S_sigma = 0; + CT H = C1 * d_sigma; + if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + { + cos_S_sigma = cos(S_sigma); + H = H * (c1 - C2) - C1 * C2 * sin_d_sigma * cos_S_sigma; + } CT const d_eta = atan2(sin_d_sigma * sin_a12, cos_theta1 * cos_d_sigma - sin_theta1 * sin_d_sigma * cos_a12); - CT const H = C1 * (c1 - C2) * d_sigma - C1 * C2 * sin_d_sigma * cos_S_sigma; CT const d_lambda = d_eta - H; - + result.lon2 = lon1 + d_lambda; if (! math::equals(M, c0)) diff --git a/boost/geometry/formulas/vertex_longitude.hpp b/boost/geometry/formulas/vertex_longitude.hpp index cf63c10a0a..4be273126b 100644 --- a/boost/geometry/formulas/vertex_longitude.hpp +++ b/boost/geometry/formulas/vertex_longitude.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016-2017 Oracle and/or its affiliates. +// Copyright (c) 2016-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -332,6 +332,23 @@ public : } }; +template <typename CT> +class vertex_longitude<CT, cartesian_tag> +{ +public : + template <typename Strategy> + static inline CT apply(CT& /*lon1*/, + CT& /*lat1*/, + CT& lon2, + CT& /*lat2*/, + CT const& /*vertex_lat*/, + CT& /*alp1*/, + Strategy const& /*azimuth_strategy*/) + { + return lon2; + } +}; + }}} // namespace boost::geometry::formula #endif // BOOST_GEOMETRY_FORMULAS_MAXIMUM_LONGITUDE_HPP diff --git a/boost/geometry/iterators/closing_iterator.hpp b/boost/geometry/iterators/closing_iterator.hpp index a0ec6a5c90..1477ea6e23 100644 --- a/boost/geometry/iterators/closing_iterator.hpp +++ b/boost/geometry/iterators/closing_iterator.hpp @@ -38,10 +38,24 @@ struct closing_iterator < closing_iterator<Range>, typename boost::range_value<Range>::type const, - boost::random_access_traversal_tag + boost::random_access_traversal_tag, + typename boost::range_reference<Range const>::type, + typename boost::range_difference<Range>::type > { - typedef typename boost::range_difference<Range>::type difference_type; +private: + typedef boost::iterator_facade + < + closing_iterator<Range>, + typename boost::range_value<Range>::type const, + boost::random_access_traversal_tag, + typename boost::range_reference<Range const>::type, + typename boost::range_difference<Range>::type + > base_type; + +public: + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; /// Constructor including the range it is based on explicit inline closing_iterator(Range& range) @@ -71,7 +85,7 @@ struct closing_iterator private: friend class boost::iterator_core_access; - inline typename boost::range_value<Range>::type const& dereference() const + inline reference dereference() const { return *m_iterator; } diff --git a/boost/geometry/iterators/ever_circling_iterator.hpp b/boost/geometry/iterators/ever_circling_iterator.hpp index 569688aac2..4d72bed2c8 100644 --- a/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/boost/geometry/iterators/ever_circling_iterator.hpp @@ -100,9 +100,22 @@ struct ever_circling_range_iterator < ever_circling_range_iterator<Range>, typename boost::range_value<Range>::type const, - boost::random_access_traversal_tag + boost::random_access_traversal_tag, + typename boost::range_reference<Range const>::type, + typename boost::range_difference<Range>::type > { +private: + typedef boost::iterator_facade + < + ever_circling_range_iterator<Range>, + typename boost::range_value<Range>::type const, + boost::random_access_traversal_tag, + typename boost::range_reference<Range const>::type, + typename boost::range_difference<Range>::type + > base_type; + +public: /// Constructor including the range it is based on explicit inline ever_circling_range_iterator(Range& range) : m_range(&range) @@ -118,12 +131,13 @@ struct ever_circling_range_iterator , m_index(0) {} - typedef std::ptrdiff_t difference_type; + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; private: friend class boost::iterator_core_access; - inline typename boost::range_value<Range>::type const& dereference() const + inline reference dereference() const { return *m_iterator; } diff --git a/boost/geometry/srs/projections/constants.hpp b/boost/geometry/srs/projections/constants.hpp new file mode 100644 index 0000000000..a8ebf2bca0 --- /dev/null +++ b/boost/geometry/srs/projections/constants.hpp @@ -0,0 +1,62 @@ +// Boost.Geometry + +// Copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_GEOMETRY_PROJECTIONS_CONSTANTS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CONSTANTS_HPP + + +#include <boost/geometry/util/math.hpp> +#include <boost/math/constants/constants.hpp> + + +namespace boost { namespace geometry { namespace projections +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + + +template <typename T> +inline T fourth_pi() { return T(0.78539816339744830961566084581988); } +template <typename T> +inline T third_pi() { return boost::math::constants::third_pi<T>(); } +template <typename T> +inline T half_pi() { return boost::math::constants::half_pi<T>(); } +template <typename T> +inline T pi() { return boost::math::constants::pi<T>(); } +template <typename T> +inline T one_and_half_pi() { return T(4.7123889803846898576939650749193); } +template <typename T> +inline T two_pi() { return boost::math::constants::two_pi<T>(); } +template <typename T> +inline T two_and_half_pi() { return T(7.8539816339744830961566084581988); } + +template <typename T> +inline T two_div_pi() { return boost::math::constants::two_div_pi<T>(); } +template <typename T> +inline T half_pi_sqr() { return T(2.4674011002723396547086227499689); } +template <typename T> +inline T pi_sqr() { return boost::math::constants::pi_sqr<T>(); } + +template <typename T> +inline T sixth() { return boost::math::constants::sixth<T>(); } +template <typename T> +inline T third() { return boost::math::constants::third<T>(); } +template <typename T> +inline T two_thirds() { return boost::math::constants::two_thirds<T>(); } + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +}}} // namespace boost::geometry::projections +#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP diff --git a/boost/geometry/srs/projections/exception.hpp b/boost/geometry/srs/projections/exception.hpp index 222207024e..a361b98937 100644 --- a/boost/geometry/srs/projections/exception.hpp +++ b/boost/geometry/srs/projections/exception.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -15,6 +15,7 @@ #include <boost/geometry/core/exception.hpp> +#include <boost/geometry/srs/projections/impl/projects.hpp> #include <boost/geometry/srs/projections/impl/pj_strerrno.hpp> #include <boost/throw_exception.hpp> @@ -60,7 +61,7 @@ struct projection_not_named_exception : projection_exception { projection_not_named_exception() - : projection_exception(-4) + : projection_exception(projections::detail::error_proj_not_named) {} }; @@ -68,21 +69,27 @@ struct projection_unknown_id_exception : projection_exception { projection_unknown_id_exception(std::string const& proj_name) - : projection_exception(-5, msg(proj_name)) + : projection_exception(projections::detail::error_unknown_projection_id, + msg(proj_name)) {} private: static std::string msg(std::string const& proj_name) { - return projections::detail::pj_strerrno(-5) + " (" + proj_name + ")"; + using namespace projections::detail; + return pj_strerrno(error_unknown_projection_id) + " (" + proj_name + ")"; } }; struct projection_not_invertible_exception : projection_exception { + // NOTE: There is no error code in proj4 which could be used here + // Proj4 sets points as invalid (HUGE_VAL) and last errno to EINVAL + // in pj_inv() if inverse projection is not available. projection_not_invertible_exception(std::string const& proj_name) - : projection_exception(-17, msg(proj_name)) + : projection_exception(projections::detail::error_non_conv_inv_meri_dist, + msg(proj_name)) {} private: diff --git a/boost/geometry/srs/projections/grids.hpp b/boost/geometry/srs/projections/grids.hpp new file mode 100644 index 0000000000..611344ccd1 --- /dev/null +++ b/boost/geometry/srs/projections/grids.hpp @@ -0,0 +1,188 @@ +// Boost.Geometry + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_GRIDS_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_GRIDS_HPP + + +#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp> + +#include <fstream> + + +namespace boost { namespace geometry +{ + +namespace srs +{ + +// Forward declarations for functions declarations below +class grids; + +template <typename GridsStorage> +class projection_grids; + +} // namespace srs +namespace projections { namespace detail +{ + +// Forward declaratios of grids friends +template <typename StreamPolicy> +inline bool pj_gridlist_merge_gridfile(std::string const& gridname, + StreamPolicy const& stream_policy, + srs::grids & grids, + std::vector<std::size_t> & gridindexes); +template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> +inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, + Range & range, + srs::grids & grids, + std::vector<std::size_t> const& gridindexes); + +// Forward declaratios of projection_grids friends +template <typename Par, typename GridsStorage> +inline void pj_gridlist_from_nadgrids(Par const& defn, + srs::projection_grids<GridsStorage> & grids); +template <bool Inverse, typename Par, typename Range, typename Grids> +inline bool pj_apply_gridshift_2(Par const& defn, Range & range, Grids const& grids); + +}} // namespace projections::detail + +namespace srs +{ + +class grids +{ +public: + std::size_t size() const + { + return gridinfo.size(); + } + + bool empty() const + { + return gridinfo.empty(); + } + +private: + template <typename StreamPolicy> + friend inline bool projections::detail::pj_gridlist_merge_gridfile( + std::string const& gridname, + StreamPolicy const& stream_policy, + srs::grids & grids, + std::vector<std::size_t> & gridindexes); + template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> + friend inline bool projections::detail::pj_apply_gridshift_3( + StreamPolicy const& stream_policy, + Range & range, + srs::grids & grids, + std::vector<std::size_t> const& gridindexes); + + projections::detail::pj_gridinfo gridinfo; + +}; + +struct ifstream_policy +{ + typedef std::ifstream stream_type; + + static inline void open(stream_type & is, std::string const& gridname) + { + is.open(gridname.c_str(), std::ios::binary); + } +}; + +template +< + typename StreamPolicy = srs::ifstream_policy, + typename Grids = grids +> +struct grids_storage +{ + typedef StreamPolicy stream_policy_type; + typedef Grids grids_type; + + grids_storage() + {} + + explicit grids_storage(stream_policy_type const& policy) + : stream_policy(policy) + {} + + stream_policy_type stream_policy; + grids_type hgrids; +}; + + +template <typename GridsStorage = grids_storage<> > +class projection_grids +{ +public: + projection_grids(GridsStorage & storage) + : storage_ptr(boost::addressof(storage)) + {} + + std::size_t size() const + { + return hindexes.size(); + } + + bool empty() const + { + return hindexes.empty(); + } + +private: + template <typename Par, typename GridsStor> + friend inline void projections::detail::pj_gridlist_from_nadgrids( + Par const& defn, + srs::projection_grids<GridsStor> & grids); + template <bool Inverse, typename Par, typename Range, typename Grids> + friend inline bool projections::detail::pj_apply_gridshift_2( + Par const& defn, Range & range, Grids const& grids); + + GridsStorage * const storage_ptr; + std::vector<std::size_t> hindexes; +}; + + +template <typename GridsStorage = grids_storage<> > +struct transformation_grids +{ + explicit transformation_grids(GridsStorage & storage) + : src_grids(storage) + , dst_grids(storage) + {} + + projection_grids<GridsStorage> src_grids; + projection_grids<GridsStorage> dst_grids; +}; + + +namespace detail +{ + +struct empty_grids_storage {}; +struct empty_projection_grids {}; + +} // namespace detail + + +template <> +struct transformation_grids<detail::empty_grids_storage> +{ + detail::empty_projection_grids src_grids; + detail::empty_projection_grids dst_grids; +}; + + +}}} // namespace boost::geometry::srs + + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_GRIDS_HPP diff --git a/boost/geometry/srs/projections/impl/aasincos.hpp b/boost/geometry/srs/projections/impl/aasincos.hpp index 4678029bc0..de064f6a01 100644 --- a/boost/geometry/srs/projections/impl/aasincos.hpp +++ b/boost/geometry/srs/projections/impl/aasincos.hpp @@ -3,6 +3,10 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -66,7 +70,7 @@ inline T aasin(T const& v) { if (av > aasincos::ONE_TOL<T>()) { - BOOST_THROW_EXCEPTION( projection_exception(-19) ); + BOOST_THROW_EXCEPTION( projection_exception(error_acos_asin_arg_too_large) ); } return (v < 0.0 ? -geometry::math::half_pi<T>() : geometry::math::half_pi<T>()); } @@ -83,7 +87,7 @@ inline T aacos(T const& v) { if (av > aasincos::ONE_TOL<T>()) { - BOOST_THROW_EXCEPTION( projection_exception(-19) ); + BOOST_THROW_EXCEPTION( projection_exception(error_acos_asin_arg_too_large) ); } return (v < 0.0 ? geometry::math::pi<T>() : 0.0); } diff --git a/boost/geometry/srs/projections/impl/base_dynamic.hpp b/boost/geometry/srs/projections/impl/base_dynamic.hpp index 3979c34300..5eafbe5bea 100644 --- a/boost/geometry/srs/projections/impl/base_dynamic.hpp +++ b/boost/geometry/srs/projections/impl/base_dynamic.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -15,6 +15,7 @@ #include <string> +#include <boost/geometry/srs/projections/exception.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> namespace boost { namespace geometry { namespace projections diff --git a/boost/geometry/srs/projections/impl/dms_parser.hpp b/boost/geometry/srs/projections/impl/dms_parser.hpp index bbecc9b1a2..21e87d1f67 100644 --- a/boost/geometry/srs/projections/impl/dms_parser.hpp +++ b/boost/geometry/srs/projections/impl/dms_parser.hpp @@ -41,18 +41,12 @@ #include <string> -#include <boost/static_assert.hpp> - -#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST) -#include <boost/lexical_cast.hpp> -#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST) - #include <boost/algorithm/string.hpp> - #include <boost/config.hpp> +#include <boost/static_assert.hpp> #include <boost/geometry/core/cs.hpp> - +#include <boost/geometry/srs/projections/str_cast.hpp> #include <boost/geometry/util/math.hpp> namespace boost { namespace geometry { namespace projections @@ -129,27 +123,23 @@ struct dms_parser bool has_dms[3]; dms_value() -#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && (!defined(_MSC_VER) || (_MSC_VER >= 1900)) // workaround for VC++ 12 (aka 2013) : dms{0, 0, 0} , has_dms{false, false, false} -#endif + {} +#else { -#ifdef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX std::fill(dms, dms + 3, T(0)); std::fill(has_dms, has_dms + 3, false); -#endif } +#endif }; template <size_t I> static inline void assign_dms(dms_value& dms, std::string& value, bool& has_value) { -#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST) - dms.dms[I] = boost::lexical_cast<T>(value.c_str()); -#else // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST) - dms.dms[I] = std::atof(value.c_str()); -#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST) + dms.dms[I] = geometry::str_cast<T>(value); dms.has_dms[I] = true; has_value = false; value.clear(); diff --git a/boost/geometry/srs/projections/impl/function_overloads.hpp b/boost/geometry/srs/projections/impl/function_overloads.hpp index 43d33c6bea..5056ecb4db 100644 --- a/boost/geometry/srs/projections/impl/function_overloads.hpp +++ b/boost/geometry/srs/projections/impl/function_overloads.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -26,12 +26,6 @@ inline T atan2(T const& a, T const& b) using std::atan2; return atan2(a, b); } -template <typename T> -inline T pow(T const& a, T const& b) -{ - using std::pow; - return pow(a, b); -} */ template <typename T> diff --git a/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp b/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp new file mode 100644 index 0000000000..ee3aa6ed23 --- /dev/null +++ b/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp @@ -0,0 +1,429 @@ +// Boost.Geometry +// This file is manually converted from PROJ4 + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file is converted from PROJ4, http://trac.osgeo.org/proj +// PROJ4 is originally written by Gerald Evenden (then of the USGS) +// PROJ4 is maintained by Frank Warmerdam +// This file was converted to Geometry Library by Adam Wulkiewicz + +// Original copyright notice: +// Author: Frank Warmerdam, warmerdam@pobox.com + +// Copyright (c) 2000, Frank Warmerdam + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP + + +#include <boost/geometry/core/assert.hpp> +#include <boost/geometry/core/radian_access.hpp> + +#include <boost/geometry/srs/projections/impl/pj_gridlist.hpp> + + +namespace boost { namespace geometry { namespace projections +{ + +namespace detail +{ + +// Originally implemented in nad_intr.c +template <typename CalcT> +inline void nad_intr(CalcT in_lon, CalcT in_lat, + CalcT & out_lon, CalcT & out_lat, + pj_ctable const& ct) +{ + pj_ctable::lp_t frct; + pj_ctable::ilp_t indx; + boost::int32_t in; + + indx.lam = int_floor(in_lon /= ct.del.lam); + indx.phi = int_floor(in_lat /= ct.del.phi); + frct.lam = in_lon - indx.lam; + frct.phi = in_lat - indx.phi; + // TODO: implement differently + out_lon = out_lat = HUGE_VAL; + if (indx.lam < 0) { + if (indx.lam == -1 && frct.lam > 0.99999999999) { + ++indx.lam; + frct.lam = 0.; + } else + return; + } else if ((in = indx.lam + 1) >= ct.lim.lam) { + if (in == ct.lim.lam && frct.lam < 1e-11) { + --indx.lam; + frct.lam = 1.; + } else + return; + } + if (indx.phi < 0) { + if (indx.phi == -1 && frct.phi > 0.99999999999) { + ++indx.phi; + frct.phi = 0.; + } else + return; + } else if ((in = indx.phi + 1) >= ct.lim.phi) { + if (in == ct.lim.phi && frct.phi < 1e-11) { + --indx.phi; + frct.phi = 1.; + } else + return; + } + boost::int32_t index = indx.phi * ct.lim.lam + indx.lam; + pj_ctable::flp_t const& f00 = ct.cvs[index++]; + pj_ctable::flp_t const& f10 = ct.cvs[index]; + index += ct.lim.lam; + pj_ctable::flp_t const& f11 = ct.cvs[index--]; + pj_ctable::flp_t const& f01 = ct.cvs[index]; + CalcT m00, m10, m01, m11; + m11 = m10 = frct.lam; + m00 = m01 = 1. - frct.lam; + m11 *= frct.phi; + m01 *= frct.phi; + frct.phi = 1. - frct.phi; + m00 *= frct.phi; + m10 *= frct.phi; + out_lon = m00 * f00.lam + m10 * f10.lam + + m01 * f01.lam + m11 * f11.lam; + out_lat = m00 * f00.phi + m10 * f10.phi + + m01 * f01.phi + m11 * f11.phi; +} + +// Originally implemented in nad_cvt.c +template <bool Inverse, typename CalcT> +inline void nad_cvt(CalcT const& in_lon, CalcT const& in_lat, + CalcT & out_lon, CalcT & out_lat, + pj_gi const& gi) +{ + static const int max_iterations = 10; + static const CalcT tol = 1e-12; + static const CalcT toltol = tol * tol; + static const CalcT pi = math::pi<CalcT>(); + + // horizontal grid expected + BOOST_GEOMETRY_ASSERT_MSG(gi.format != pj_gi::gtx, + "Vertical grid cannot be used in horizontal shift."); + + pj_ctable const& ct = gi.ct; + + // TODO: implement differently + if (in_lon == HUGE_VAL) + { + out_lon = HUGE_VAL; + out_lat = HUGE_VAL; + return; + } + + // normalize input to ll origin + pj_ctable::lp_t tb; + tb.lam = in_lon - ct.ll.lam; + tb.phi = in_lat - ct.ll.phi; + tb.lam = adjlon (tb.lam - pi) + pi; + + pj_ctable::lp_t t; + nad_intr(tb.lam, tb.phi, t.lam, t.phi, ct); + if (t.lam == HUGE_VAL) + { + out_lon = HUGE_VAL; + out_lat = HUGE_VAL; + return; + } + + if (! Inverse) + { + out_lon = in_lon - t.lam; + out_lat = in_lat - t.phi; + return; + } + + t.lam = tb.lam + t.lam; + t.phi = tb.phi - t.phi; + + int i = max_iterations; + pj_ctable::lp_t del, dif; + do + { + nad_intr(t.lam, t.phi, del.lam, del.phi, ct); + + // This case used to return failure, but I have + // changed it to return the first order approximation + // of the inverse shift. This avoids cases where the + // grid shift *into* this grid came from another grid. + // While we aren't returning optimally correct results + // I feel a close result in this case is better than + // no result. NFW + // To demonstrate use -112.5839956 49.4914451 against + // the NTv2 grid shift file from Canada. + if (del.lam == HUGE_VAL) + { + // Inverse grid shift iteration failed, presumably at grid edge. Using first approximation. + break; + } + + dif.lam = t.lam - del.lam - tb.lam; + dif.phi = t.phi + del.phi - tb.phi; + t.lam -= dif.lam; + t.phi -= dif.phi; + + } + while (--i && (dif.lam*dif.lam + dif.phi*dif.phi > toltol)); // prob. slightly faster than hypot() + + if (i==0) + { + // Inverse grid shift iterator failed to converge. + out_lon = HUGE_VAL; + out_lat = HUGE_VAL; + return; + } + + out_lon = adjlon (t.lam + ct.ll.lam); + out_lat = t.phi + ct.ll.phi; +} + + +/************************************************************************/ +/* find_grid() */ +/* */ +/* Determine which grid is the correct given an input coordinate. */ +/************************************************************************/ + +// Originally find_ctable() +// here divided into grid_disjoint(), find_grid() and load_grid() + +template <typename T> +inline bool grid_disjoint(T const& lam, T const& phi, + pj_ctable const& ct) +{ + double epsilon = (fabs(ct.del.phi)+fabs(ct.del.lam))/10000.0; + return ct.ll.phi - epsilon > phi + || ct.ll.lam - epsilon > lam + || (ct.ll.phi + (ct.lim.phi-1) * ct.del.phi + epsilon < phi) + || (ct.ll.lam + (ct.lim.lam-1) * ct.del.lam + epsilon < lam); +} + +template <typename T> +inline pj_gi * find_grid(T const& lam, + T const& phi, + std::vector<pj_gi>::iterator first, + std::vector<pj_gi>::iterator last) +{ + pj_gi * gip = NULL; + + for( ; first != last ; ++first ) + { + // skip tables that don't match our point at all. + if (! grid_disjoint(lam, phi, first->ct)) + { + // skip vertical grids + if (first->format != pj_gi::gtx) + { + gip = boost::addressof(*first); + break; + } + } + } + + // If we didn't find a child then nothing more to do + if( gip == NULL ) + return gip; + + // Otherwise use the child, first checking it's children + pj_gi * child = find_grid(lam, phi, first->children.begin(), first->children.end()); + if (child != NULL) + gip = child; + + return gip; +} + +template <typename T> +inline pj_gi * find_grid(T const& lam, + T const& phi, + pj_gridinfo & grids, + std::vector<std::size_t> const& gridindexes) +{ + pj_gi * gip = NULL; + + // keep trying till we find a table that works + for (std::size_t i = 0 ; i < gridindexes.size() ; ++i) + { + pj_gi & gi = grids[gridindexes[i]]; + + // skip tables that don't match our point at all. + if (! grid_disjoint(lam, phi, gi.ct)) + { + // skip vertical grids + if (gi.format != pj_gi::gtx) + { + gip = boost::addressof(gi); + break; + } + } + } + + if (gip == NULL) + return gip; + + // If we have child nodes, check to see if any of them apply. + pj_gi * child = find_grid(lam, phi, gip->children.begin(), gip->children.end()); + if (child != NULL) + gip = child; + + // if we get this far we have found a suitable grid + return gip; +} + + +template <typename StreamPolicy> +inline bool load_grid(StreamPolicy const& stream_policy, pj_gi_load & gi) +{ + // load the grid shift info if we don't have it. + if (gi.ct.cvs.empty()) + { + typename StreamPolicy::stream_type is; + stream_policy.open(is, gi.gridname); + + if (! pj_gridinfo_load(is, gi)) + { + //pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return false; + } + } + + return true; +} + + +/************************************************************************/ +/* pj_apply_gridshift_3() */ +/* */ +/* This is the real workhorse, given a gridlist. */ +/************************************************************************/ + +template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> +inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, + Range & range, + srs::grids & grids, + std::vector<std::size_t> const& gridindexes) +{ + typedef typename boost::range_size<Range>::type size_type; + + // If the grids are empty the indexes are as well + if (gridindexes.empty()) + { + //pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + //return PJD_ERR_FAILED_TO_LOAD_GRID; + return false; + } + + size_type point_count = boost::size(range); + + for (size_type i = 0 ; i < point_count ; ++i) + { + typename boost::range_reference<Range>::type + point = range::at(range, i); + + CalcT in_lon = geometry::get_as_radian<0>(point); + CalcT in_lat = geometry::get_as_radian<1>(point); + + pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes); + + if ( gip != NULL ) + { + // load the grid shift info if we don't have it. + if (! gip->ct.cvs.empty() || load_grid(stream_policy, *gip)) + { + // TODO: use set_invalid_point() or similar mechanism + CalcT out_lon = HUGE_VAL; + CalcT out_lat = HUGE_VAL; + + nad_cvt<Inverse>(in_lon, in_lat, out_lon, out_lat, *gip); + + // TODO: check differently + if ( out_lon != HUGE_VAL ) + { + geometry::set_from_radian<0>(point, out_lon); + geometry::set_from_radian<1>(point, out_lat); + } + } + } + } + + return true; +} + + +/************************************************************************/ +/* pj_apply_gridshift_2() */ +/* */ +/* This implementation uses the gridlist from a coordinate */ +/* system definition. If the gridlist has not yet been */ +/* populated in the coordinate system definition we set it up */ +/* now. */ +/************************************************************************/ + +template <bool Inverse, typename Par, typename Range, typename ProjGrids> +inline bool pj_apply_gridshift_2(Par const& defn, Range & range, ProjGrids const& grids) +{ + /*if( defn->catalog_name != NULL ) + return pj_gc_apply_gridshift( defn, inverse, point_count, point_offset, + x, y, z );*/ + + /*std::vector<std::size_t> gridindexes; + pj_gridlist_from_nadgrids(pj_get_param_s(defn.params, "nadgrids"), + grids.storage_ptr->stream_policy, + grids.storage_ptr->grids, + gridindexes);*/ + + BOOST_GEOMETRY_ASSERT(grids.storage_ptr != NULL); + + // At this point the grids should be initialized + if (grids.hindexes.empty()) + return false; + + return pj_apply_gridshift_3 + < + Inverse, typename Par::type + >(grids.storage_ptr->stream_policy, + range, + grids.storage_ptr->hgrids, + grids.hindexes); +} + +template <bool Inverse, typename Par, typename Range> +inline bool pj_apply_gridshift_2(Par const& , Range & , srs::detail::empty_projection_grids const& ) +{ + return false; +} + + +} // namespace detail + +}}} // namespace boost::geometry::projections + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP diff --git a/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp b/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp new file mode 100644 index 0000000000..2f0d63169e --- /dev/null +++ b/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp @@ -0,0 +1,157 @@ +// Boost.Geometry +// This file is manually converted from PROJ4 + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file is converted from PROJ4, http://trac.osgeo.org/proj +// PROJ4 is originally written by Gerald Evenden (then of the USGS) +// PROJ4 is maintained by Frank Warmerdam +// This file was converted to Geometry Library by Adam Wulkiewicz + +// Original copyright notice: +// Author: Frank Warmerdam, warmerdam@pobox.com + +// Copyright (c) 2000, Frank Warmerdam + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP + + +#include <boost/geometry/core/assert.hpp> +#include <boost/geometry/core/radian_access.hpp> + +#include <boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp> +#include <boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp> + + +namespace boost { namespace geometry { namespace projections +{ + +namespace detail +{ + +template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> +inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, + Range & range, + srs::shared_grids & grids, + std::vector<std::size_t> const& gridindexes) +{ + typedef typename boost::range_size<Range>::type size_type; + + // If the grids are empty the indexes are as well + if (gridindexes.empty()) + { + //pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + //return PJD_ERR_FAILED_TO_LOAD_GRID; + return false; + } + + size_type point_count = boost::size(range); + + // local storage + pj_gi_load local_gi; + + for (size_type i = 0 ; i < point_count ; ) + { + bool load_needed = false; + + CalcT in_lon = 0; + CalcT in_lat = 0; + + { + boost::shared_lock<boost::shared_mutex> lock(grids.mutex); + + for ( ; i < point_count ; ++i ) + { + typename boost::range_reference<Range>::type + point = range::at(range, i); + + in_lon = geometry::get_as_radian<0>(point); + in_lat = geometry::get_as_radian<1>(point); + + pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes); + + if (gip == NULL) + { + // do nothing + } + else if (! gip->ct.cvs.empty()) + { + // TODO: use set_invalid_point() or similar mechanism + CalcT out_lon = HUGE_VAL; + CalcT out_lat = HUGE_VAL; + + nad_cvt<Inverse>(in_lon, in_lat, out_lon, out_lat, *gip); + + // TODO: check differently + if (out_lon != HUGE_VAL) + { + geometry::set_from_radian<0>(point, out_lon); + geometry::set_from_radian<1>(point, out_lat); + } + } + else + { + // loading is needed + local_gi = *gip; + load_needed = true; + break; + } + } + } + + if (load_needed) + { + if (load_grid(stream_policy, local_gi)) + { + boost::unique_lock<boost::shared_mutex> lock(grids.mutex); + + // check again in case other thread already loaded the grid. + pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes); + + if (gip != NULL && gip->ct.cvs.empty()) + { + // swap loaded local storage with empty grid + local_gi.swap(*gip); + } + } + else + { + ++i; + } + } + } + + return true; +} + + +} // namespace detail + +}}} // namespace boost::geometry::projections + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP diff --git a/boost/geometry/srs/projections/impl/pj_auth.hpp b/boost/geometry/srs/projections/impl/pj_auth.hpp index 899d0b25b1..8a9e34a09c 100644 --- a/boost/geometry/srs/projections/impl/pj_auth.hpp +++ b/boost/geometry/srs/projections/impl/pj_auth.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -48,14 +48,22 @@ namespace boost { namespace geometry { namespace projections { namespace detail { -static const int APA_SIZE = 3; +template <typename T> +struct apa +{ + static const std::size_t size = 3; + + T const& operator[](size_t i) const { return data[i]; } + T & operator[](size_t i) { return data[i]; } + +private: + T data[3]; +}; /* determine latitude from authalic latitude */ template <typename T> -inline bool pj_authset(T const& es, T* APA) +inline detail::apa<T> pj_authset(T const& es) { - BOOST_GEOMETRY_ASSERT(0 != APA); - static const T P00 = .33333333333333333333; static const T P01 = .17222222222222222222; static const T P02 = .10257936507936507936; @@ -64,29 +72,28 @@ inline bool pj_authset(T const& es, T* APA) static const T P20 = .01641501294219154443; T t = 0; + detail::apa<T> apa; - // if (APA = (double *)pj_malloc(APA_SIZE * sizeof(double))) { - APA[0] = es * P00; + apa[0] = es * P00; t = es * es; - APA[0] += t * P01; - APA[1] = t * P10; + apa[0] += t * P01; + apa[1] = t * P10; t *= es; - APA[0] += t * P02; - APA[1] += t * P11; - APA[2] = t * P20; + apa[0] += t * P02; + apa[1] += t * P11; + apa[2] = t * P20; } - return true; + + return apa; } template <typename T> -inline T pj_authlat(T const& beta, const T* APA) +inline T pj_authlat(T const& beta, detail::apa<T> const& apa) { - BOOST_GEOMETRY_ASSERT(0 != APA); - T const t = beta + beta; - return(beta + APA[0] * sin(t) + APA[1] * sin(t + t) + APA[2] * sin(t + t + t)); + return(beta + apa[0] * sin(t) + apa[1] * sin(t + t) + apa[2] * sin(t + t + t)); } } // namespace detail diff --git a/boost/geometry/srs/projections/impl/pj_datum_set.hpp b/boost/geometry/srs/projections/impl/pj_datum_set.hpp index 5301dc7cfe..622efe3403 100644 --- a/boost/geometry/srs/projections/impl/pj_datum_set.hpp +++ b/boost/geometry/srs/projections/impl/pj_datum_set.hpp @@ -75,7 +75,7 @@ inline void pj_datum_add_defn(BGParams const& , std::vector<pvalue<T> >& pvalues /* definition will last into the pj_ell_set() function called */ /* after this one. */ /* -------------------------------------------------------------------- */ - std::string name = pj_param(pvalues, "sdatum").s; + std::string name = pj_get_param_s(pvalues, "datum"); if(! name.empty()) { /* find the datum definition */ @@ -91,19 +91,19 @@ inline void pj_datum_add_defn(BGParams const& , std::vector<pvalue<T> >& pvalues if (index == -1) { - BOOST_THROW_EXCEPTION( projection_exception(-9) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) ); } - if(! pj_datums[index].ellipse_id.empty()) + pj_datums_type const& datum = pj_datums[index]; + + if(! datum.ellipse_id.empty()) { - std::string entry("ellps="); - entry +=pj_datums[index].ellipse_id; - pvalues.push_back(pj_mkparam<T>(entry)); + pvalues.push_back(pj_mkparam<T>("ellps", datum.ellipse_id)); } - if(! pj_datums[index].defn.empty()) + if(! datum.defn_n.empty() && ! datum.defn_v.empty()) { - pvalues.push_back(pj_mkparam<T>(pj_datums[index].defn)); + pvalues.push_back(pj_mkparam<T>(datum.defn_n, datum.defn_v)); } } } @@ -129,11 +129,12 @@ inline void pj_datum_add_defn(srs::static_proj4<BOOST_GEOMETRY_PROJECTIONS_DETAI || ! boost::is_same<typename datum_traits::ellps_type, void>::value; BOOST_MPL_ASSERT_MSG((not_set_or_known), UNKNOWN_DATUM, (bg_parameters_type)); - std::string defn = datum_traits::definition(); + std::string def_n = datum_traits::def_n(); + std::string def_v = datum_traits::def_v(); - if (! defn.empty()) + if (! def_n.empty() && ! def_v.empty()) { - pvalues.push_back(pj_mkparam<T>(defn)); + pvalues.push_back(pj_mkparam<T>(def_n, def_v)); } } @@ -146,21 +147,21 @@ inline void pj_datum_set(BGParams const& bg_params, std::vector<pvalue<T> >& pva { static const T SEC_TO_RAD = detail::SEC_TO_RAD<T>(); - projdef.datum_type = PJD_UNKNOWN; + projdef.datum_type = datum_unknown; pj_datum_add_defn(bg_params, pvalues); /* -------------------------------------------------------------------- */ /* Check for nadgrids parameter. */ /* -------------------------------------------------------------------- */ - std::string nadgrids = pj_param(pvalues, "snadgrids").s; - std::string towgs84 = pj_param(pvalues, "stowgs84").s; + std::string nadgrids = pj_get_param_s(pvalues, "nadgrids"); + std::string towgs84 = pj_get_param_s(pvalues, "towgs84"); if(! nadgrids.empty()) { /* We don't actually save the value separately. It will continue to exist int he param list for use in pj_apply_gridshift.c */ - projdef.datum_type = PJD_GRIDSHIFT; + projdef.datum_type = datum_gridshift; } /* -------------------------------------------------------------------- */ @@ -187,7 +188,7 @@ inline void pj_datum_set(BGParams const& bg_params, std::vector<pvalue<T> >& pva || projdef.datum_params[5] != 0.0 || projdef.datum_params[6] != 0.0 ) { - projdef.datum_type = PJD_7PARAM; + projdef.datum_type = datum_7param; /* transform from arc seconds to radians */ projdef.datum_params[3] *= SEC_TO_RAD; @@ -199,7 +200,7 @@ inline void pj_datum_set(BGParams const& bg_params, std::vector<pvalue<T> >& pva } else { - projdef.datum_type = PJD_3PARAM; + projdef.datum_type = datum_3param; } /* Note that pj_init() will later switch datum_type to diff --git a/boost/geometry/srs/projections/impl/pj_datums.hpp b/boost/geometry/srs/projections/impl/pj_datums.hpp index 55da24a2ca..ab2fcb2357 100644 --- a/boost/geometry/srs/projections/impl/pj_datums.hpp +++ b/boost/geometry/srs/projections/impl/pj_datums.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -41,53 +41,70 @@ #include <boost/geometry/srs/projections/impl/projects.hpp> +#include <string> + namespace boost { namespace geometry { namespace projections { namespace detail { +// Originally defined in projects.h +struct pj_datums_type +{ + std::string id; /* datum keyword */ + std::string defn_n; /* e.g. "to_wgs84" */ + std::string defn_v; /* e.g. "0,0,0" */ + std::string ellipse_id; /* ie from ellipse table */ + std::string comments; /* EPSG code, etc */ +}; + +// Originally defined in projects.h +struct pj_prime_meridians_type +{ + std::string id; /* prime meridian keyword */ + std::string defn; /* offset from greenwich in DMS format. */ +}; + /* * The ellipse code must match one from pj_ellps.c. The datum id should * be kept to 12 characters or less if possible. Use the official OGC * datum name for the comments if available. */ -static const PJ_DATUMS pj_datums[] = +static const pj_datums_type pj_datums[] = { - /* id definition ellipse comments */ - /* -- ---------- ------- -------- */ - {"WGS84", "towgs84=0,0,0", + {"WGS84", "towgs84", "0,0,0", "WGS84", ""}, - {"GGRS87", "towgs84=-199.87,74.79,246.62", + {"GGRS87", "towgs84", "-199.87,74.79,246.62", "GRS80", "Greek_Geodetic_Reference_System_1987"}, - {"NAD83", "towgs84=0,0,0", + {"NAD83", "towgs84", "0,0,0", "GRS80", "North_American_Datum_1983"}, - {"NAD27", "nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", + {"NAD27", "nadgrids", "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", "clrk66", "North_American_Datum_1927"}, - {"potsdam", "towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7", + {"potsdam", "towgs84", "598.1,73.7,418.2,0.202,0.045,-2.455,6.7", "bessel", "Potsdam Rauenberg 1950 DHDN"}, - {"carthage", "towgs84=-263.0,6.0,431.0", + {"carthage", "towgs84", "-263.0,6.0,431.0", "clrk80ign", "Carthage 1934 Tunisia"}, - {"hermannskogel", "towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232", + {"hermannskogel", "towgs84", "577.326,90.129,463.919,5.137,1.474,5.297,2.4232", "bessel", "Hermannskogel"}, - {"ire65", "towgs84=482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", + {"ire65", "towgs84", "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", "mod_airy", "Ireland 1965"}, - {"nzgd49", "towgs84=59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", + {"nzgd49", "towgs84", "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", "intl", "New Zealand Geodetic Datum 1949"}, - {"OSGB36", "towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", + {"OSGB36", "towgs84", "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", "airy", "Airy 1830"} }; -static const PJ_PRIME_MERIDIANS pj_prime_meridians[] = +static const pj_prime_meridians_type pj_prime_meridians[] = { /* id definition */ /* -- ---------- */ diff --git a/boost/geometry/srs/projections/impl/pj_ell_set.hpp b/boost/geometry/srs/projections/impl/pj_ell_set.hpp index 6f5f14b780..6e0b817adb 100644 --- a/boost/geometry/srs/projections/impl/pj_ell_set.hpp +++ b/boost/geometry/srs/projections/impl/pj_ell_set.hpp @@ -14,7 +14,9 @@ // This file is converted from PROJ4, http://trac.osgeo.org/proj // PROJ4 is originally written by Gerald Evenden (then of the USGS) // PROJ4 is maintained by Frank Warmerdam -// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam) +// PROJ4 is converted to Geometry Library by +// Barend Gehrels (Geodan, Amsterdam) +// Adam Wulkiewicz // Original copyright notice: @@ -78,12 +80,12 @@ inline void pj_ell_set(BGParams const& /*bg_params*/, std::vector<pvalue<T> >& p a = es = 0.; /* R takes precedence */ - if (pj_param(parameters, "tR").i) - a = pj_param(parameters, "dR").f; - else { /* probable elliptical figure */ + if (pj_param_f(parameters, "R", a)) { + /* empty */ + } else { /* probable elliptical figure */ /* check if ellps present and temporarily append its values to pl */ - name = pj_param(parameters, "sellps").s; + name = pj_get_param_s(parameters, "ellps"); if (! name.empty()) { const int n = sizeof(pj_ellps) / sizeof(pj_ellps[0]); @@ -97,59 +99,56 @@ inline void pj_ell_set(BGParams const& /*bg_params*/, std::vector<pvalue<T> >& p } if (index == -1) { - BOOST_THROW_EXCEPTION( projection_exception(-9) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) ); } - parameters.push_back(pj_mkparam<T>(pj_ellps[index].major)); - parameters.push_back(pj_mkparam<T>(pj_ellps[index].ell)); + pj_ellps_type const& pj_ellp = pj_ellps[index]; + parameters.push_back(pj_mkparam<T>("a", pj_ellp.major_v)); + parameters.push_back(pj_mkparam<T>(pj_ellp.ell_n, pj_ellp.ell_v)); } - a = pj_param(parameters, "da").f; - if (pj_param(parameters, "tes").i) /* eccentricity squared */ - es = pj_param(parameters, "des").f; - else if (pj_param(parameters, "te").i) { /* eccentricity */ - e = pj_param(parameters, "de").f; + a = pj_get_param_f(parameters, "a"); + if (pj_param_f(parameters, "es", es)) {/* eccentricity squared */ + /* empty */ + } else if (pj_param_f(parameters, "e", e)) { /* eccentricity */ es = e * e; - } else if (pj_param(parameters, "trf").i) { /* recip flattening */ - es = pj_param(parameters, "drf").f; + } else if (pj_param_f(parameters, "rf", es)) { /* recip flattening */ if (!es) { - BOOST_THROW_EXCEPTION( projection_exception(-10) ); + BOOST_THROW_EXCEPTION( projection_exception(error_rev_flattening_is_zero) ); } es = 1./ es; es = es * (2. - es); - } else if (pj_param(parameters, "tf").i) { /* flattening */ - es = pj_param(parameters, "df").f; + } else if (pj_param_f(parameters, "f", es)) { /* flattening */ es = es * (2. - es); - } else if (pj_param(parameters, "tb").i) { /* minor axis */ - b = pj_param(parameters, "db").f; + } else if (pj_param_f(parameters, "b", b)) { /* minor axis */ es = 1. - (b * b) / (a * a); } /* else es == 0. and sphere of radius a */ if (!b) b = a * sqrt(1. - es); /* following options turn ellipsoid into equivalent sphere */ - if (pj_param(parameters, "bR_A").i) { /* sphere--area of ellipsoid */ + if (pj_get_param_b(parameters, "R_A")) { /* sphere--area of ellipsoid */ a *= 1. - es * (SIXTH<T>() + es * (RA4<T>() + es * RA6<T>())); es = 0.; - } else if (pj_param(parameters, "bR_V").i) { /* sphere--vol. of ellipsoid */ + } else if (pj_get_param_b(parameters, "R_V")) { /* sphere--vol. of ellipsoid */ a *= 1. - es * (SIXTH<T>() + es * (RV4<T>() + es * RV6<T>())); es = 0.; - } else if (pj_param(parameters, "bR_a").i) { /* sphere--arithmetic mean */ + } else if (pj_get_param_b(parameters, "R_a")) { /* sphere--arithmetic mean */ a = .5 * (a + b); es = 0.; - } else if (pj_param(parameters, "bR_g").i) { /* sphere--geometric mean */ + } else if (pj_get_param_b(parameters, "R_g")) { /* sphere--geometric mean */ a = sqrt(a * b); es = 0.; - } else if (pj_param(parameters, "bR_h").i) { /* sphere--harmonic mean */ + } else if (pj_get_param_b(parameters, "R_h")) { /* sphere--harmonic mean */ a = 2. * a * b / (a + b); es = 0.; } else { - int i = pj_param(parameters, "tR_lat_a").i; + T tmp; + int i = pj_param_r(parameters, "R_lat_a", tmp); if (i || /* sphere--arith. */ - pj_param(parameters, "tR_lat_g").i) { /* or geom. mean at latitude */ - T tmp; + pj_param_r(parameters, "R_lat_g", tmp)) { /* or geom. mean at latitude */ - tmp = sin(pj_param(parameters, i ? "rR_lat_a" : "rR_lat_g").f); + tmp = sin(tmp); if (geometry::math::abs(tmp) > geometry::math::half_pi<T>()) { - BOOST_THROW_EXCEPTION( projection_exception(-11) ); + BOOST_THROW_EXCEPTION( projection_exception(error_ref_rad_larger_than_90) ); } tmp = 1. - es * tmp * tmp; a *= i ? .5 * (1. - es + tmp) / ( tmp * sqrt(tmp)) : @@ -161,10 +160,10 @@ inline void pj_ell_set(BGParams const& /*bg_params*/, std::vector<pvalue<T> >& p /* some remaining checks */ if (es < 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-12) ); + BOOST_THROW_EXCEPTION( projection_exception(error_es_less_than_zero) ); } if (a <= 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-13) ); + BOOST_THROW_EXCEPTION( projection_exception(error_major_axis_not_given) ); } } @@ -192,13 +191,85 @@ inline void pj_ell_set(srs::static_proj4<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> c /* some remaining checks */ if (es < 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-12) ); + BOOST_THROW_EXCEPTION( projection_exception(error_es_less_than_zero) ); } if (a <= 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-13) ); + BOOST_THROW_EXCEPTION( projection_exception(error_major_axis_not_given) ); } } +template <typename T> +inline void pj_calc_ellipsoid_params(parameters<T> & p, T const& a, T const& es) { +/**************************************************************************************** + Calculate a large number of ancillary ellipsoidal parameters, in addition to + the two traditional PROJ defining parameters: Semimajor axis, a, and the + eccentricity squared, es. + + Most of these parameters are fairly cheap to compute in comparison to the overall + effort involved in initializing a PJ object. They may, however, take a substantial + part of the time taken in computing an individual point transformation. + + So by providing them up front, we can amortize the (already modest) cost over all + transformations carried out over the entire lifetime of a PJ object, rather than + incur that cost for every single transformation. + + Most of the parameter calculations here are based on the "angular eccentricity", + i.e. the angle, measured from the semiminor axis, of a line going from the north + pole to one of the foci of the ellipsoid - or in other words: The arc sine of the + eccentricity. + + The formulae used are mostly taken from: + + Richard H. Rapp: Geometric Geodesy, Part I, (178 pp, 1991). + Columbus, Ohio: Dept. of Geodetic Science + and Surveying, Ohio State University. + +****************************************************************************************/ + + p.a = a; + p.es = es; + + /* Compute some ancillary ellipsoidal parameters */ + if (p.e==0) + p.e = sqrt(p.es); /* eccentricity */ + //p.alpha = asin (p.e); /* angular eccentricity */ + + /* second eccentricity */ + //p.e2 = tan (p.alpha); + //p.e2s = p.e2 * p.e2; + + /* third eccentricity */ + //p.e3 = (0!=p.alpha)? sin (p.alpha) / sqrt(2 - sin (p.alpha)*sin (p.alpha)): 0; + //p.e3s = p.e3 * p.e3; + + /* flattening */ + //if (0==p.f) + // p.f = 1 - cos (p.alpha); /* = 1 - sqrt (1 - PIN->es); */ + //p.rf = p.f != 0.0 ? 1.0/p.f: HUGE_VAL; + + /* second flattening */ + //p.f2 = (cos(p.alpha)!=0)? 1/cos (p.alpha) - 1: 0; + //p.rf2 = p.f2 != 0.0 ? 1/p.f2: HUGE_VAL; + + /* third flattening */ + //p.n = pow (tan (p.alpha/2), 2); + //p.rn = p.n != 0.0 ? 1/p.n: HUGE_VAL; + + /* ...and a few more */ + //if (0==p.b) + // p.b = (1 - p.f)*p.a; + //p.rb = 1. / p.b; + p.ra = 1. / p.a; + + p.one_es = 1. - p.es; + if (p.one_es == 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_eccentricity_is_one) ); + } + + p.rone_es = 1./p.one_es; +} + + } // namespace detail }}} // namespace boost::geometry::projections diff --git a/boost/geometry/srs/projections/impl/pj_ellps.hpp b/boost/geometry/srs/projections/impl/pj_ellps.hpp index 586802778c..7a10b7de67 100644 --- a/boost/geometry/srs/projections/impl/pj_ellps.hpp +++ b/boost/geometry/srs/projections/impl/pj_ellps.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -41,55 +41,67 @@ #include <boost/geometry/srs/projections/impl/projects.hpp> +#include <string> + namespace boost { namespace geometry { namespace projections { namespace detail { -static const PJ_ELLPS pj_ellps[] = +// Originally defined in projects.h +struct pj_ellps_type +{ + std::string id; /* ellipse keyword name */ + std::string major_v; /* a's value */ + std::string ell_n; /* elliptical parameter name */ + std::string ell_v; /* elliptical parameter value */ + std::string name; /* comments */ +}; + +static const pj_ellps_type pj_ellps[] = { - {"MERIT", "a=6378137.0", "rf=298.257", "MERIT 1983"}, - {"SGS85", "a=6378136.0", "rf=298.257", "Soviet Geodetic System 85"}, - {"GRS80", "a=6378137.0", "rf=298.257222101", "GRS 1980(IUGG, 1980)"}, - {"IAU76", "a=6378140.0", "rf=298.257", "IAU 1976"}, - {"airy", "a=6377563.396", "b=6356256.910", "Airy 1830"}, - {"APL4.9", "a=6378137.0.", "rf=298.25", "Appl. Physics. 1965"}, - {"NWL9D", "a=6378145.0.", "rf=298.25", "Naval Weapons Lab., 1965"}, - {"mod_airy", "a=6377340.189", "b=6356034.446", "Modified Airy"}, - {"andrae", "a=6377104.43", "rf=300.0", "Andrae 1876 (Den., Iclnd.)"}, - {"aust_SA", "a=6378160.0", "rf=298.25", "Australian Natl & S. Amer. 1969"}, - {"GRS67", "a=6378160.0", "rf=298.2471674270", "GRS 67(IUGG 1967)"}, - {"bessel", "a=6377397.155", "rf=299.1528128", "Bessel 1841"}, - {"bess_nam", "a=6377483.865", "rf=299.1528128", "Bessel 1841 (Namibia)"}, - {"clrk66", "a=6378206.4", "b=6356583.8", "Clarke 1866"}, - {"clrk80", "a=6378249.145", "rf=293.4663", "Clarke 1880 mod."}, - {"clrk80ign", "a=6378249.2", "rf=293.4660212936269", "Clarke 1880 (IGN)."}, - {"CPM", "a=6375738.7", "rf=334.29", "Comm. des Poids et Mesures 1799"}, - {"delmbr", "a=6376428.", "rf=311.5", "Delambre 1810 (Belgium)"}, - {"engelis", "a=6378136.05", "rf=298.2566", "Engelis 1985"}, - {"evrst30", "a=6377276.345", "rf=300.8017", "Everest 1830"}, - {"evrst48", "a=6377304.063", "rf=300.8017", "Everest 1948"}, - {"evrst56", "a=6377301.243", "rf=300.8017", "Everest 1956"}, - {"evrst69", "a=6377295.664", "rf=300.8017", "Everest 1969"}, - {"evrstSS", "a=6377298.556", "rf=300.8017", "Everest (Sabah & Sarawak)"}, - {"fschr60", "a=6378166.", "rf=298.3", "Fischer (Mercury Datum) 1960"}, - {"fschr60m", "a=6378155.", "rf=298.3", "Modified Fischer 1960"}, - {"fschr68", "a=6378150.", "rf=298.3", "Fischer 1968"}, - {"helmert", "a=6378200.", "rf=298.3", "Helmert 1906"}, - {"hough", "a=6378270.0", "rf=297.", "Hough"}, - {"intl", "a=6378388.0", "rf=297.", "International 1909 (Hayford)"}, - {"krass", "a=6378245.0", "rf=298.3", "Krassovsky, 1942"}, - {"kaula", "a=6378163.", "rf=298.24", "Kaula 1961"}, - {"lerch", "a=6378139.", "rf=298.257", "Lerch 1979"}, - {"mprts", "a=6397300.", "rf=191.", "Maupertius 1738"}, - {"new_intl", "a=6378157.5", "b=6356772.2", "New International 1967"}, - {"plessis", "a=6376523.", "b=6355863.", "Plessis 1817 (France)"}, - {"SEasia", "a=6378155.0", "b=6356773.3205", "Southeast Asia"}, - {"walbeck", "a=6376896.0", "b=6355834.8467", "Walbeck"}, - {"WGS60", "a=6378165.0", "rf=298.3", "WGS 60"}, - {"WGS66", "a=6378145.0", "rf=298.25", "WGS 66"}, - {"WGS72", "a=6378135.0", "rf=298.26", "WGS 72"}, - {"WGS84", "a=6378137.0", "rf=298.257223563", "WGS 84"}, - {"sphere", "a=6370997.0", "b=6370997.0", "Normal Sphere (r=6370997)"} + {"MERIT", "6378137.0", "rf", "298.257", "MERIT 1983"}, + {"SGS85", "6378136.0", "rf", "298.257", "Soviet Geodetic System 85"}, + {"GRS80", "6378137.0", "rf", "298.257222101", "GRS 1980(IUGG, 1980)"}, + {"IAU76", "6378140.0", "rf", "298.257", "IAU 1976"}, + {"airy", "6377563.396", "b", "6356256.910", "Airy 1830"}, + {"APL4.9", "6378137.0.", "rf", "298.25", "Appl. Physics. 1965"}, + {"NWL9D", "6378145.0.", "rf", "298.25", "Naval Weapons Lab., 1965"}, + {"mod_airy", "6377340.189", "b", "6356034.446", "Modified Airy"}, + {"andrae", "6377104.43", "rf", "300.0", "Andrae 1876 (Den., Iclnd.)"}, + {"aust_SA", "6378160.0", "rf", "298.25", "Australian Natl & S. Amer. 1969"}, + {"GRS67", "6378160.0", "rf", "298.2471674270", "GRS 67(IUGG 1967)"}, + {"bessel", "6377397.155", "rf", "299.1528128", "Bessel 1841"}, + {"bess_nam", "6377483.865", "rf", "299.1528128", "Bessel 1841 (Namibia)"}, + {"clrk66", "6378206.4", "b", "6356583.8", "Clarke 1866"}, + {"clrk80", "6378249.145", "rf", "293.4663", "Clarke 1880 mod."}, + {"clrk80ign", "6378249.2", "rf", "293.4660212936269", "Clarke 1880 (IGN)."}, + {"CPM", "6375738.7", "rf", "334.29", "Comm. des Poids et Mesures 1799"}, + {"delmbr", "6376428.", "rf", "311.5", "Delambre 1810 (Belgium)"}, + {"engelis", "6378136.05", "rf", "298.2566", "Engelis 1985"}, + {"evrst30", "6377276.345", "rf", "300.8017", "Everest 1830"}, + {"evrst48", "6377304.063", "rf", "300.8017", "Everest 1948"}, + {"evrst56", "6377301.243", "rf", "300.8017", "Everest 1956"}, + {"evrst69", "6377295.664", "rf", "300.8017", "Everest 1969"}, + {"evrstSS", "6377298.556", "rf", "300.8017", "Everest (Sabah & Sarawak)"}, + {"fschr60", "6378166.", "rf", "298.3", "Fischer (Mercury Datum) 1960"}, + {"fschr60m", "6378155.", "rf", "298.3", "Modified Fischer 1960"}, + {"fschr68", "6378150.", "rf", "298.3", "Fischer 1968"}, + {"helmert", "6378200.", "rf", "298.3", "Helmert 1906"}, + {"hough", "6378270.0", "rf", "297.", "Hough"}, + {"intl", "6378388.0", "rf", "297.", "International 1909 (Hayford)"}, + {"krass", "6378245.0", "rf", "298.3", "Krassovsky, 1942"}, + {"kaula", "6378163.", "rf", "298.24", "Kaula 1961"}, + {"lerch", "6378139.", "rf", "298.257", "Lerch 1979"}, + {"mprts", "6397300.", "rf", "191.", "Maupertius 1738"}, + {"new_intl", "6378157.5", "b", "6356772.2", "New International 1967"}, + {"plessis", "6376523.", "b", "6355863.", "Plessis 1817 (France)"}, + {"SEasia", "6378155.0", "b", "6356773.3205", "Southeast Asia"}, + {"walbeck", "6376896.0", "b", "6355834.8467", "Walbeck"}, + {"WGS60", "6378165.0", "rf", "298.3", "WGS 60"}, + {"WGS66", "6378145.0", "rf", "298.25", "WGS 66"}, + {"WGS72", "6378135.0", "rf", "298.26", "WGS 72"}, + {"WGS84", "6378137.0", "rf", "298.257223563", "WGS 84"}, + {"sphere", "6370997.0", "b", "6370997.0", "Normal Sphere (r=6370997)"} }; } // namespace detail diff --git a/boost/geometry/srs/projections/impl/pj_fwd.hpp b/boost/geometry/srs/projections/impl/pj_fwd.hpp index 73101b7f40..c1725b0a81 100644 --- a/boost/geometry/srs/projections/impl/pj_fwd.hpp +++ b/boost/geometry/srs/projections/impl/pj_fwd.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -69,7 +69,7 @@ inline void pj_fwd(Prj const& prj, P const& par, LL const& ll, XY& xy) /* check for forward and latitude or longitude overange */ if (t > EPS || geometry::math::abs(lp_lon) > 10.) { - BOOST_THROW_EXCEPTION( projection_exception(-14) ); + BOOST_THROW_EXCEPTION( projection_exception(error_lat_or_lon_exceed_limit) ); } if (geometry::math::abs(t) <= EPS) diff --git a/boost/geometry/srs/projections/impl/pj_gauss.hpp b/boost/geometry/srs/projections/impl/pj_gauss.hpp index 2c90870434..94b8f89862 100644 --- a/boost/geometry/srs/projections/impl/pj_gauss.hpp +++ b/boost/geometry/srs/projections/impl/pj_gauss.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -45,13 +45,11 @@ namespace boost { namespace geometry { namespace projections { -namespace detail { namespace gauss { +namespace detail { -static const int MAX_ITER = 20; - template <typename T> -struct GAUSS +struct gauss { T C; T K; @@ -62,13 +60,13 @@ struct GAUSS template <typename T> inline T srat(T const& esinp, T const& exp) { - return (pow((1.0 - esinp) / (1.0 + esinp), exp)); + return (math::pow((T(1) - esinp) / (T(1) + esinp), exp)); } template <typename T> -inline GAUSS<T> gauss_ini(T const& e, T const& phi0, T& chi, T& rc) +inline gauss<T> gauss_ini(T const& e, T const& phi0, T& chi, T& rc) { - static const T FORTPI = detail::FORTPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); using std::asin; using std::cos; @@ -80,7 +78,7 @@ inline GAUSS<T> gauss_ini(T const& e, T const& phi0, T& chi, T& rc) T cphi = 0; T es = 0; - GAUSS<T> en; + gauss<T> en; es = e * e; en.e = e; sphi = sin(phi0); @@ -91,38 +89,41 @@ inline GAUSS<T> gauss_ini(T const& e, T const& phi0, T& chi, T& rc) en.C = sqrt(1.0 + es * cphi * cphi / (1.0 - es)); chi = asin(sphi / en.C); en.ratexp = 0.5 * en.C * e; - en.K = tan(0.5 * chi + FORTPI) - / (pow(tan(0.5 * phi0 + FORTPI), en.C) * srat(en.e * sphi, en.ratexp)); + en.K = tan(0.5 * chi + fourth_pi) + / (math::pow(tan(T(0.5) * phi0 + fourth_pi), en.C) * srat(en.e * sphi, en.ratexp)); return en; } template <typename T> -inline void gauss(GAUSS<T> const& en, T& lam, T& phi) +inline void gauss_fwd(gauss<T> const& en, T& lam, T& phi) { - static const T FORTPI = detail::FORTPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); - phi = 2.0 * atan(en.K * pow(tan(0.5 * phi + FORTPI), en.C) - * srat(en.e * sin(phi), en.ratexp) ) - geometry::math::half_pi<T>(); + phi = T(2) * atan(en.K * math::pow(tan(T(0.5) * phi + fourth_pi), en.C) + * srat(en.e * sin(phi), en.ratexp) ) - half_pi; lam *= en.C; } template <typename T> -inline void inv_gauss(GAUSS<T> const& en, T& lam, T& phi) +inline void gauss_inv(gauss<T> const& en, T& lam, T& phi) { - static const T FORTPI = detail::FORTPI<T>(); - static const T DEL_TOL = 1e-14; + static const int max_iter = 20; + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T del_tol = 1e-14; lam /= en.C; - const T num = pow(tan(0.5 * phi + FORTPI) / en.K, 1.0 / en.C); + const T num = math::pow(tan(T(0.5) * phi + fourth_pi) / en.K, T(1) / en.C); int i = 0; - for (i = MAX_ITER; i; --i) + for (i = max_iter; i; --i) { - const T elp_phi = 2.0 * atan(num * srat(en.e * sin(phi), - 0.5 * en.e)) - geometry::math::half_pi<T>(); + const T elp_phi = 2.0 * atan(num * srat(en.e * sin(phi), - 0.5 * en.e)) - half_pi; - if (geometry::math::abs(elp_phi - phi) < DEL_TOL) + if (geometry::math::abs(elp_phi - phi) < del_tol) { break; } @@ -132,11 +133,12 @@ inline void inv_gauss(GAUSS<T> const& en, T& lam, T& phi) /* convergence failed */ if (!i) { - BOOST_THROW_EXCEPTION( projection_exception(-17) ); + BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) ); } } -}} // namespace detail::gauss +} // namespace detail + }}} // namespace boost::geometry::projections #endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP diff --git a/boost/geometry/srs/projections/impl/pj_gridinfo.hpp b/boost/geometry/srs/projections/impl/pj_gridinfo.hpp new file mode 100644 index 0000000000..af1fe471d8 --- /dev/null +++ b/boost/geometry/srs/projections/impl/pj_gridinfo.hpp @@ -0,0 +1,960 @@ +// Boost.Geometry +// This file is manually converted from PROJ4 + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file is converted from PROJ4, http://trac.osgeo.org/proj +// PROJ4 is originally written by Gerald Evenden (then of the USGS) +// PROJ4 is maintained by Frank Warmerdam +// This file was converted to Geometry Library by Adam Wulkiewicz + +// Original copyright notice: +// Author: Frank Warmerdam, warmerdam@pobox.com + +// Copyright (c) 2000, Frank Warmerdam + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP + + +#include <boost/algorithm/string.hpp> + +#include <boost/geometry/core/assert.hpp> + +#include <boost/cstdint.hpp> + +#include <algorithm> +#include <string> +#include <vector> + + +namespace boost { namespace geometry { namespace projections +{ + +namespace detail +{ + +/************************************************************************/ +/* swap_words() */ +/* */ +/* Convert the byte order of the given word(s) in place. */ +/************************************************************************/ + +inline bool is_lsb() +{ + static const int byte_order_test = 1; + static bool result = (1 == ((const unsigned char *) (&byte_order_test))[0]); + return result; +} + +inline void swap_words( char *data, int word_size, int word_count ) +{ + for (int word = 0; word < word_count; word++) + { + for (int i = 0; i < word_size/2; i++) + { + std::swap(data[i], data[word_size-i-1]); + } + + data += word_size; + } +} + +inline bool cstr_equal(const char * s1, const char * s2, std::size_t n) +{ + return std::equal(s1, s1 + n, s2); +} + +struct is_trimmable_char +{ + inline bool operator()(char ch) + { + return ch == '\n' || ch == ' '; + } +}; + +// structs originally defined in projects.h + +struct pj_ctable +{ + struct lp_t { double lam, phi; }; + struct flp_t { float lam, phi; }; + struct ilp_t { boost::int32_t lam, phi; }; + + std::string id; // ascii info + lp_t ll; // lower left corner coordinates + lp_t del; // size of cells + ilp_t lim; // limits of conversion matrix + std::vector<flp_t> cvs; // conversion matrix + + inline void swap(pj_ctable & r) + { + id.swap(r.id); + std::swap(ll, r.ll); + std::swap(del, r.del); + std::swap(lim, r.lim); + cvs.swap(r.cvs); + } +}; + +struct pj_gi_load +{ + enum format_t { missing = 0, ntv1, ntv2, gtx, ctable, ctable2 }; + typedef boost::long_long_type offset_t; + + explicit pj_gi_load(std::string const& gname = "", + format_t f = missing, + offset_t off = 0, + bool swap = false) + : gridname(gname) + , format(f) + , grid_offset(off) + , must_swap(swap) + {} + + std::string gridname; // identifying name of grid, eg "conus" or ntv2_0.gsb + + format_t format; // format of this grid, ie "ctable", "ntv1", "ntv2" or "missing". + + offset_t grid_offset; // offset in file, for delayed loading + bool must_swap; // only for NTv2 + + pj_ctable ct; + + inline void swap(pj_gi_load & r) + { + gridname.swap(r.gridname); + std::swap(format, r.format); + std::swap(grid_offset, r.grid_offset); + std::swap(must_swap, r.must_swap); + ct.swap(r.ct); + } + +}; + +struct pj_gi + : pj_gi_load +{ + explicit pj_gi(std::string const& gname = "", + pj_gi_load::format_t f = missing, + pj_gi_load::offset_t off = 0, + bool swap = false) + : pj_gi_load(gname, f, off, swap) + {} + + std::vector<pj_gi> children; + + inline void swap(pj_gi & r) + { + pj_gi_load::swap(r); + children.swap(r.children); + } +}; + +typedef std::vector<pj_gi> pj_gridinfo; + + +/************************************************************************/ +/* pj_gridinfo_load_ctable() */ +/* */ +/* Load the data portion of a ctable formatted grid. */ +/************************************************************************/ + +// Originally nad_ctable_load() defined in nad_init.c +template <typename IStream> +bool pj_gridinfo_load_ctable(IStream & is, pj_gi_load & gi) +{ + pj_ctable & ct = gi.ct; + + // Move the input stream by the size of the proj4 original CTABLE + std::size_t header_size = 80 + + 2 * sizeof(pj_ctable::lp_t) + + sizeof(pj_ctable::ilp_t) + + sizeof(pj_ctable::flp_t*); + is.seekg(header_size); + + // read all the actual shift values + std::size_t a_size = ct.lim.lam * ct.lim.phi; + ct.cvs.resize(a_size); + + std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size; + is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size); + + if (is.fail() || is.gcount() != ch_size) + { + ct.cvs.clear(); + //ctable loading failed on fread() - binary incompatible? + return false; + } + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_load_ctable2() */ +/* */ +/* Load the data portion of a ctable2 formatted grid. */ +/************************************************************************/ + +// Originally nad_ctable2_load() defined in nad_init.c +template <typename IStream> +bool pj_gridinfo_load_ctable2(IStream & is, pj_gi_load & gi) +{ + pj_ctable & ct = gi.ct; + + is.seekg(160); + + // read all the actual shift values + std::size_t a_size = ct.lim.lam * ct.lim.phi; + ct.cvs.resize(a_size); + + std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size; + is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size); + + if (is.fail() || is.gcount() != ch_size) + { + //ctable2 loading failed on fread() - binary incompatible? + ct.cvs.clear(); + return false; + } + + if (! is_lsb()) + { + swap_words(reinterpret_cast<char*>(&ct.cvs[0]), 4, (int)a_size * 2); + } + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_load_ntv1() */ +/* */ +/* NTv1 format. */ +/* We process one line at a time. Note that the array storage */ +/* direction (e-w) is different in the NTv1 file and what */ +/* the CTABLE is supposed to have. The phi/lam are also */ +/* reversed, and we have to be aware of byte swapping. */ +/************************************************************************/ + +// originally in pj_gridinfo_load() function +template <typename IStream> +inline bool pj_gridinfo_load_ntv1(IStream & is, pj_gi_load & gi) +{ + static const double s2r = math::d2r<double>() / 3600.0; + + std::size_t const r_size = gi.ct.lim.lam * 2; + std::size_t const ch_size = sizeof(double) * r_size; + + is.seekg(gi.grid_offset); + + std::vector<double> row_buf(r_size); + gi.ct.cvs.resize(gi.ct.lim.lam * gi.ct.lim.phi); + + for (boost::int32_t row = 0; row < gi.ct.lim.phi; row++ ) + { + is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size); + + if (is.fail() || is.gcount() != ch_size) + { + gi.ct.cvs.clear(); + return false; + } + + if (is_lsb()) + swap_words(reinterpret_cast<char*>(&row_buf[0]), 8, (int)r_size); + + // convert seconds to radians + for (boost::int32_t i = 0; i < gi.ct.lim.lam; i++ ) + { + pj_ctable::flp_t & cvs = gi.ct.cvs[row * gi.ct.lim.lam + (gi.ct.lim.lam - i - 1)]; + + cvs.phi = (float) (row_buf[i*2] * s2r); + cvs.lam = (float) (row_buf[i*2+1] * s2r); + } + } + + return true; +} + +/* -------------------------------------------------------------------- */ +/* pj_gridinfo_load_ntv2() */ +/* */ +/* NTv2 format. */ +/* We process one line at a time. Note that the array storage */ +/* direction (e-w) is different in the NTv2 file and what */ +/* the CTABLE is supposed to have. The phi/lam are also */ +/* reversed, and we have to be aware of byte swapping. */ +/* -------------------------------------------------------------------- */ + +// originally in pj_gridinfo_load() function +template <typename IStream> +inline bool pj_gridinfo_load_ntv2(IStream & is, pj_gi_load & gi) +{ + static const double s2r = math::d2r<double>() / 3600.0; + + std::size_t const r_size = gi.ct.lim.lam * 4; + std::size_t const ch_size = sizeof(float) * r_size; + + is.seekg(gi.grid_offset); + + std::vector<float> row_buf(r_size); + gi.ct.cvs.resize(gi.ct.lim.lam * gi.ct.lim.phi); + + for (boost::int32_t row = 0; row < gi.ct.lim.phi; row++ ) + { + is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size); + + if (is.fail() || is.gcount() != ch_size) + { + gi.ct.cvs.clear(); + return false; + } + + if (gi.must_swap) + { + swap_words(reinterpret_cast<char*>(&row_buf[0]), 4, (int)r_size); + } + + // convert seconds to radians + for (boost::int32_t i = 0; i < gi.ct.lim.lam; i++ ) + { + pj_ctable::flp_t & cvs = gi.ct.cvs[row * gi.ct.lim.lam + (gi.ct.lim.lam - i - 1)]; + + // skip accuracy values + cvs.phi = (float) (row_buf[i*4] * s2r); + cvs.lam = (float) (row_buf[i*4+1] * s2r); + } + } + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_load_gtx() */ +/* */ +/* GTX format. */ +/************************************************************************/ + +// originally in pj_gridinfo_load() function +template <typename IStream> +inline bool pj_gridinfo_load_gtx(IStream & is, pj_gi_load & gi) +{ + boost::int32_t words = gi.ct.lim.lam * gi.ct.lim.phi; + std::size_t const ch_size = sizeof(float) * words; + + is.seekg(gi.grid_offset); + + // TODO: Consider changing this unintuitive code + // NOTE: Vertical shift data (one float per point) is stored in a container + // holding horizontal shift data (two floats per point). + gi.ct.cvs.resize((words + 1) / 2); + + is.read(reinterpret_cast<char*>(&gi.ct.cvs[0]), ch_size); + + if (is.fail() || is.gcount() != ch_size) + { + gi.ct.cvs.clear(); + return false; + } + + if (is_lsb()) + { + swap_words(reinterpret_cast<char*>(&gi.ct.cvs[0]), 4, words); + } + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_load() */ +/* */ +/* This function is intended to implement delayed loading of */ +/* the data contents of a grid file. The header and related */ +/* stuff are loaded by pj_gridinfo_init(). */ +/************************************************************************/ + +template <typename IStream> +inline bool pj_gridinfo_load(IStream & is, pj_gi_load & gi) +{ + if (! gi.ct.cvs.empty()) + { + return true; + } + + if (! is.is_open()) + { + return false; + } + + // Original platform specific CTable format. + if (gi.format == pj_gi::ctable) + { + return pj_gridinfo_load_ctable(is, gi); + } + // CTable2 format. + else if (gi.format == pj_gi::ctable2) + { + return pj_gridinfo_load_ctable2(is, gi); + } + // NTv1 format. + else if (gi.format == pj_gi::ntv1) + { + return pj_gridinfo_load_ntv1(is, gi); + } + // NTv2 format. + else if (gi.format == pj_gi::ntv2) + { + return pj_gridinfo_load_ntv2(is, gi); + } + // GTX format. + else if (gi.format == pj_gi::gtx) + { + return pj_gridinfo_load_gtx(is, gi); + } + else + { + return false; + } +} + +/************************************************************************/ +/* pj_gridinfo_parent() */ +/* */ +/* Seek a parent grid file by name from a grid list */ +/************************************************************************/ + +template <typename It> +inline It pj_gridinfo_parent(It first, It last, std::string const& name) +{ + for ( ; first != last ; ++first) + { + if (first->ct.id == name) + return first; + + It parent = pj_gridinfo_parent(first->children.begin(), first->children.end(), name); + if( parent != first->children.end() ) + return parent; + } + + return last; +} + +/************************************************************************/ +/* pj_gridinfo_init_ntv2() */ +/* */ +/* Load a ntv2 (.gsb) file. */ +/************************************************************************/ + +template <typename IStream> +inline bool pj_gridinfo_init_ntv2(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 ); + BOOST_STATIC_ASSERT( sizeof(double) == 8 ); + + static const double s2r = math::d2r<double>() / 3600.0; + + std::size_t gridinfo_orig_size = gridinfo.size(); + + // Read the overview header. + char header[11*16]; + + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + bool must_swap = (header[8] == 11) + ? !is_lsb() + : is_lsb(); + + // NOTE: This check is not implemented in proj4 + if (! cstr_equal(header + 56, "SECONDS", 7)) + { + return false; + } + + // Byte swap interesting fields if needed. + if( must_swap ) + { + swap_words( header+8, 4, 1 ); + swap_words( header+8+16, 4, 1 ); + swap_words( header+8+32, 4, 1 ); + swap_words( header+8+7*16, 8, 1 ); + swap_words( header+8+8*16, 8, 1 ); + swap_words( header+8+9*16, 8, 1 ); + swap_words( header+8+10*16, 8, 1 ); + } + + // Get the subfile count out ... all we really use for now. + boost::int32_t num_subfiles; + memcpy( &num_subfiles, header+8+32, 4 ); + + // Step through the subfiles, creating a PJ_GRIDINFO for each. + for( boost::int32_t subfile = 0; subfile < num_subfiles; subfile++ ) + { + // Read header. + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + if(! cstr_equal(header, "SUB_NAME", 8)) + { + return false; + } + + // Byte swap interesting fields if needed. + if( must_swap ) + { + swap_words( header+8+16*4, 8, 1 ); + swap_words( header+8+16*5, 8, 1 ); + swap_words( header+8+16*6, 8, 1 ); + swap_words( header+8+16*7, 8, 1 ); + swap_words( header+8+16*8, 8, 1 ); + swap_words( header+8+16*9, 8, 1 ); + swap_words( header+8+16*10, 4, 1 ); + } + + // Initialize a corresponding "ct" structure. + pj_ctable ct; + pj_ctable::lp_t ur; + + ct.id = std::string(header + 8, 8); + + ct.ll.lam = - *((double *) (header+7*16+8)); /* W_LONG */ + ct.ll.phi = *((double *) (header+4*16+8)); /* S_LAT */ + + ur.lam = - *((double *) (header+6*16+8)); /* E_LONG */ + ur.phi = *((double *) (header+5*16+8)); /* N_LAT */ + + ct.del.lam = *((double *) (header+9*16+8)); + ct.del.phi = *((double *) (header+8*16+8)); + + ct.lim.lam = (boost::int32_t) (fabs(ur.lam-ct.ll.lam)/ct.del.lam + 0.5) + 1; + ct.lim.phi = (boost::int32_t) (fabs(ur.phi-ct.ll.phi)/ct.del.phi + 0.5) + 1; + + ct.ll.lam *= s2r; + ct.ll.phi *= s2r; + ct.del.lam *= s2r; + ct.del.phi *= s2r; + + boost::int32_t gs_count; + memcpy( &gs_count, header + 8 + 16*10, 4 ); + if( gs_count != ct.lim.lam * ct.lim.phi ) + { + return false; + } + + //ct.cvs.clear(); + + // Create a new gridinfo for this if we aren't processing the + // 1st subfile, and initialize our grid info. + + // Attach to the correct list or sublist. + + // TODO is offset needed? + pj_gi gi(gridname, pj_gi::ntv2, is.tellg(), must_swap); + gi.ct = ct; + + if( subfile == 0 ) + { + gridinfo.push_back(gi); + } + else if( cstr_equal(header+24, "NONE", 4) ) + { + gridinfo.push_back(gi); + } + else + { + pj_gridinfo::iterator git = pj_gridinfo_parent(gridinfo.begin() + gridinfo_orig_size, + gridinfo.end(), + std::string((const char*)header+24, 8)); + + if( git == gridinfo.end() ) + { + gridinfo.push_back(gi); + } + else + { + git->children.push_back(gi); + } + } + + // Seek past the data. + is.seekg(gs_count * 16, std::ios::cur); + } + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_init_ntv1() */ +/* */ +/* Load an NTv1 style Canadian grid shift file. */ +/************************************************************************/ + +template <typename IStream> +inline bool pj_gridinfo_init_ntv1(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 ); + BOOST_STATIC_ASSERT( sizeof(double) == 8 ); + + static const double d2r = math::d2r<double>(); + + // Read the header. + char header[176]; + + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + // Regularize fields of interest. + if( is_lsb() ) + { + swap_words( header+8, 4, 1 ); + swap_words( header+24, 8, 1 ); + swap_words( header+40, 8, 1 ); + swap_words( header+56, 8, 1 ); + swap_words( header+72, 8, 1 ); + swap_words( header+88, 8, 1 ); + swap_words( header+104, 8, 1 ); + } + + // NTv1 grid shift file has wrong record count, corrupt? + if( *((boost::int32_t *) (header+8)) != 12 ) + { + return false; + } + + // NOTE: This check is not implemented in proj4 + if (! cstr_equal(header + 120, "SECONDS", 7)) + { + return false; + } + + // Fill in CTABLE structure. + pj_ctable ct; + pj_ctable::lp_t ur; + + ct.id = "NTv1 Grid Shift File"; + + ct.ll.lam = - *((double *) (header+72)); + ct.ll.phi = *((double *) (header+24)); + ur.lam = - *((double *) (header+56)); + ur.phi = *((double *) (header+40)); + ct.del.lam = *((double *) (header+104)); + ct.del.phi = *((double *) (header+88)); + ct.lim.lam = (boost::int32_t) (fabs(ur.lam-ct.ll.lam)/ct.del.lam + 0.5) + 1; + ct.lim.phi = (boost::int32_t) (fabs(ur.phi-ct.ll.phi)/ct.del.phi + 0.5) + 1; + + ct.ll.lam *= d2r; + ct.ll.phi *= d2r; + ct.del.lam *= d2r; + ct.del.phi *= d2r; + //ct.cvs.clear(); + + // is offset needed? + gridinfo.push_back(pj_gi(gridname, pj_gi::ntv1, is.tellg())); + gridinfo.back().ct = ct; + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_init_gtx() */ +/* */ +/* Load a NOAA .gtx vertical datum shift file. */ +/************************************************************************/ + +template <typename IStream> +inline bool pj_gridinfo_init_gtx(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 ); + BOOST_STATIC_ASSERT( sizeof(double) == 8 ); + + static const double d2r = math::d2r<double>(); + + // Read the header. + char header[40]; + + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + // Regularize fields of interest and extract. + double xorigin, yorigin, xstep, ystep; + boost::int32_t rows, columns; + + if( is_lsb() ) + { + swap_words( header+0, 8, 4 ); + swap_words( header+32, 4, 2 ); + } + + memcpy( &yorigin, header+0, 8 ); + memcpy( &xorigin, header+8, 8 ); + memcpy( &ystep, header+16, 8 ); + memcpy( &xstep, header+24, 8 ); + + memcpy( &rows, header+32, 4 ); + memcpy( &columns, header+36, 4 ); + + // gtx file header has invalid extents, corrupt? + if( xorigin < -360 || xorigin > 360 + || yorigin < -90 || yorigin > 90 ) + { + return false; + } + + // Fill in CTABLE structure. + pj_ctable ct; + + ct.id = "GTX Vertical Grid Shift File"; + + ct.ll.lam = xorigin; + ct.ll.phi = yorigin; + ct.del.lam = xstep; + ct.del.phi = ystep; + ct.lim.lam = columns; + ct.lim.phi = rows; + + // some GTX files come in 0-360 and we shift them back into the + // expected -180 to 180 range if possible. This does not solve + // problems with grids spanning the dateline. + if( ct.ll.lam >= 180.0 ) + ct.ll.lam -= 360.0; + + if( ct.ll.lam >= 0.0 && ct.ll.lam + ct.del.lam * ct.lim.lam > 180.0 ) + { + //"This GTX spans the dateline! This will cause problems." ); + } + + ct.ll.lam *= d2r; + ct.ll.phi *= d2r; + ct.del.lam *= d2r; + ct.del.phi *= d2r; + //ct.cvs.clear(); + + // is offset needed? + gridinfo.push_back(pj_gi(gridname, pj_gi::gtx, 40)); + gridinfo.back().ct = ct; + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_init_ctable2() */ +/* */ +/* Read the header portion of a "ctable2" format grid. */ +/************************************************************************/ + +// Originally nad_ctable2_init() defined in nad_init.c +template <typename IStream> +inline bool pj_gridinfo_init_ctable2(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 ); + BOOST_STATIC_ASSERT( sizeof(double) == 8 ); + + char header[160]; + + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + if( !is_lsb() ) + { + swap_words( header + 96, 8, 4 ); + swap_words( header + 128, 4, 2 ); + } + + // ctable2 - wrong header! + if (! cstr_equal(header, "CTABLE V2", 9)) + { + return false; + } + + // read the table header + pj_ctable ct; + + ct.id = std::string(header + 16, std::find(header + 16, header + 16 + 80, '\0')); + //memcpy( &ct.ll.lam, header + 96, 8 ); + //memcpy( &ct.ll.phi, header + 104, 8 ); + //memcpy( &ct.del.lam, header + 112, 8 ); + //memcpy( &ct.del.phi, header + 120, 8 ); + //memcpy( &ct.lim.lam, header + 128, 4 ); + //memcpy( &ct.lim.phi, header + 132, 4 ); + memcpy( &ct.ll, header + 96, 40 ); + + // do some minimal validation to ensure the structure isn't corrupt + if ( ct.lim.lam < 1 || ct.lim.lam > 100000 + || ct.lim.phi < 1 || ct.lim.phi > 100000 ) + { + return false; + } + + // trim white space and newlines off id + boost::trim_right_if(ct.id, is_trimmable_char()); + + //ct.cvs.clear(); + + gridinfo.push_back(pj_gi(gridname, pj_gi::ctable2)); + gridinfo.back().ct = ct; + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_init_ctable() */ +/* */ +/* Read the header portion of a "ctable" format grid. */ +/************************************************************************/ + +// Originally nad_ctable_init() defined in nad_init.c +template <typename IStream> +inline bool pj_gridinfo_init_ctable(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 ); + BOOST_STATIC_ASSERT( sizeof(double) == 8 ); + + // 80 + 2*8 + 2*8 + 2*4 + char header[120]; + + // NOTE: in proj4 data is loaded directly into CTABLE + + is.read(header, sizeof(header)); + if( is.fail() ) + { + return false; + } + + // NOTE: in proj4 LSB is not checked here + + // read the table header + pj_ctable ct; + + ct.id = std::string(header, std::find(header, header + 80, '\0')); + memcpy( &ct.ll, header + 80, 40 ); + + // do some minimal validation to ensure the structure isn't corrupt + if ( ct.lim.lam < 1 || ct.lim.lam > 100000 + || ct.lim.phi < 1 || ct.lim.phi > 100000 ) + { + return false; + } + + // trim white space and newlines off id + boost::trim_right_if(ct.id, is_trimmable_char()); + + //ct.cvs.clear(); + + gridinfo.push_back(pj_gi(gridname, pj_gi::ctable)); + gridinfo.back().ct = ct; + + return true; +} + +/************************************************************************/ +/* pj_gridinfo_init() */ +/* */ +/* Open and parse header details from a datum gridshift file */ +/* returning a list of PJ_GRIDINFOs for the grids in that */ +/* file. This superceeds use of nad_init() for modern */ +/* applications. */ +/************************************************************************/ + +template <typename IStream> +inline bool pj_gridinfo_init(std::string const& gridname, + IStream & is, + pj_gridinfo & gridinfo) +{ + char header[160]; + + // Check if the stream is opened. + if (! is.is_open()) { + return false; + } + + // Load a header, to determine the file type. + is.read(header, sizeof(header)); + + if ( is.fail() ) { + return false; + } + + is.seekg(0); + + // Determine file type. + if ( cstr_equal(header + 0, "HEADER", 6) + && cstr_equal(header + 96, "W GRID", 6) + && cstr_equal(header + 144, "TO NAD83 ", 16) ) + { + return pj_gridinfo_init_ntv1(gridname, is, gridinfo); + } + else if( cstr_equal(header + 0, "NUM_OREC", 8) + && cstr_equal(header + 48, "GS_TYPE", 7) ) + { + return pj_gridinfo_init_ntv2(gridname, is, gridinfo); + } + else if( boost::algorithm::ends_with(gridname, "gtx") + || boost::algorithm::ends_with(gridname, "GTX") ) + { + return pj_gridinfo_init_gtx(gridname, is, gridinfo); + } + else if( cstr_equal(header + 0, "CTABLE V2", 9) ) + { + return pj_gridinfo_init_ctable2(gridname, is, gridinfo); + } + else + { + return pj_gridinfo_init_ctable(gridname, is, gridinfo); + } +} + + +} // namespace detail + +}}} // namespace boost::geometry::projections + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP diff --git a/boost/geometry/srs/projections/impl/pj_gridlist.hpp b/boost/geometry/srs/projections/impl/pj_gridlist.hpp new file mode 100644 index 0000000000..43fc3b70ab --- /dev/null +++ b/boost/geometry/srs/projections/impl/pj_gridlist.hpp @@ -0,0 +1,181 @@ +// Boost.Geometry +// This file is manually converted from PROJ4 + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file is converted from PROJ4, http://trac.osgeo.org/proj +// PROJ4 is originally written by Gerald Evenden (then of the USGS) +// PROJ4 is maintained by Frank Warmerdam +// This file was converted to Geometry Library by Adam Wulkiewicz + +// Original copyright notice: +// Author: Frank Warmerdam, warmerdam@pobox.com + +// Copyright (c) 2000, Frank Warmerdam + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP + + +#include <boost/geometry/srs/projections/grids.hpp> +#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp> + + +namespace boost { namespace geometry { namespace projections +{ + +namespace detail +{ + +/************************************************************************/ +/* pj_gridlist_merge_grid() */ +/* */ +/* Find/load the named gridfile and merge it into the */ +/* last_nadgrids_list. */ +/************************************************************************/ + +// Originally one function, here divided into several functions +// with overloads for various types of grids and stream policies + +inline bool pj_gridlist_find_all(std::string const& gridname, + pj_gridinfo const& grids, + std::vector<std::size_t> & gridindexes) +{ + bool result = false; + for (std::size_t i = 0 ; i < grids.size() ; ++i) + { + if (grids[i].gridname == gridname) + { + result = true; + gridindexes.push_back(i); + } + } + return result; +} + +// Fill container with sequentially increasing numbers +inline void pj_gridlist_add_seq_inc(std::vector<std::size_t> & gridindexes, + std::size_t first, std::size_t last) +{ + gridindexes.reserve(gridindexes.size() + (last - first)); + for ( ; first < last ; ++first) + { + gridindexes.push_back(first); + } +} + +// Generic stream policy and standard grids +template <typename StreamPolicy> +inline bool pj_gridlist_merge_gridfile(std::string const& gridname, + StreamPolicy const& stream_policy, + srs::grids & grids, + std::vector<std::size_t> & gridindexes) +{ + // Try to find in the existing list of loaded grids. Add all + // matching grids as with NTv2 we can get many grids from one + // file (one shared gridname). + if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes)) + return true; + + std::size_t orig_size = grids.gridinfo.size(); + + // Try to load the named grid. + typename StreamPolicy::stream_type is; + stream_policy.open(is, gridname); + + if (! pj_gridinfo_init(gridname, is, grids.gridinfo)) + { + return false; + } + + // Add the grid now that it is loaded. + pj_gridlist_add_seq_inc(gridindexes, orig_size, grids.gridinfo.size()); + + return true; +} + + +/************************************************************************/ +/* pj_gridlist_from_nadgrids() */ +/* */ +/* This functions loads the list of grids corresponding to a */ +/* particular nadgrids string into a list, and returns it. The */ +/* list is kept around till a request is made with a different */ +/* string in order to cut down on the string parsing cost, and */ +/* the cost of building the list of tables each time. */ +/************************************************************************/ + +template <typename StreamPolicy, typename Grids> +inline void pj_gridlist_from_nadgrids(std::string const& nadgrids, + StreamPolicy const& stream_policy, + Grids & grids, + std::vector<std::size_t> & gridindexes) + +{ + // Loop processing names out of nadgrids one at a time. + for (std::string::size_type i = 0 ; i < nadgrids.size() ; ) + { + bool required = true; + + if( nadgrids[i] == '@' ) + { + required = false; + ++i; + } + + std::string::size_type end = nadgrids.find(',', i); + std::string name = nadgrids.substr(i, end - i); + + i = end; + if (end != std::string::npos) + ++i; + + if ( ! pj_gridlist_merge_gridfile(name, stream_policy, grids, gridindexes) + && required ) + { + BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_load_grid) ); + } + } +} + +template <typename Par, typename GridsStorage> +inline void pj_gridlist_from_nadgrids(Par const& defn, srs::projection_grids<GridsStorage> & grids) +{ + BOOST_GEOMETRY_ASSERT(grids.storage_ptr != NULL); + + pj_gridlist_from_nadgrids(pj_get_param_s(defn.params, "nadgrids"), + grids.storage_ptr->stream_policy, + grids.storage_ptr->hgrids, + grids.hindexes); +} + + +} // namespace detail + +}}} // namespace boost::geometry::projections + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP diff --git a/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp b/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp new file mode 100644 index 0000000000..88753d034d --- /dev/null +++ b/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp @@ -0,0 +1,121 @@ +// Boost.Geometry +// This file is manually converted from PROJ4 + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This file is converted from PROJ4, http://trac.osgeo.org/proj +// PROJ4 is originally written by Gerald Evenden (then of the USGS) +// PROJ4 is maintained by Frank Warmerdam +// This file was converted to Geometry Library by Adam Wulkiewicz + +// Original copyright notice: +// Author: Frank Warmerdam, warmerdam@pobox.com + +// Copyright (c) 2000, Frank Warmerdam + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP + + +#include <boost/geometry/srs/projections/shared_grids.hpp> +#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp> + + +namespace boost { namespace geometry { namespace projections +{ + +namespace detail +{ + + +/************************************************************************/ +/* pj_gridlist_merge_grid() */ +/* */ +/* Find/load the named gridfile and merge it into the */ +/* last_nadgrids_list. */ +/************************************************************************/ + +// Generic stream policy and shared grids +template <typename StreamPolicy> +inline bool pj_gridlist_merge_gridfile(std::string const& gridname, + StreamPolicy const& stream_policy, + srs::shared_grids & grids, + std::vector<std::size_t> & gridindexes) +{ + // Try to find in the existing list of loaded grids. Add all + // matching grids as with NTv2 we can get many grids from one + // file (one shared gridname). + { + boost::shared_lock<boost::shared_mutex> lock(grids.mutex); + + if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes)) + return true; + } + + // Try to load the named grid. + typename StreamPolicy::stream_type is; + stream_policy.open(is, gridname); + + pj_gridinfo new_grids; + + if (! pj_gridinfo_init(gridname, is, new_grids)) + { + return false; + } + + // Add the grid now that it is loaded. + + std::size_t orig_size = 0; + std::size_t new_size = 0; + + { + boost::unique_lock<boost::shared_mutex> lock(grids.mutex); + + // Try to find in the existing list of loaded grids again + // in case other thread already added it. + if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes)) + return true; + + orig_size = grids.gridinfo.size(); + new_size = orig_size + new_grids.size(); + + grids.gridinfo.resize(new_size); + for (std::size_t i = 0 ; i < new_grids.size() ; ++ i) + new_grids[i].swap(grids.gridinfo[i + orig_size]); + } + + pj_gridlist_add_seq_inc(gridindexes, orig_size, new_size); + + return true; +} + + +} // namespace detail + +}}} // namespace boost::geometry::projections + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP diff --git a/boost/geometry/srs/projections/impl/pj_init.hpp b/boost/geometry/srs/projections/impl/pj_init.hpp index 8b93343bcd..1d2db1af24 100644 --- a/boost/geometry/srs/projections/impl/pj_init.hpp +++ b/boost/geometry/srs/projections/impl/pj_init.hpp @@ -44,7 +44,6 @@ #include <vector> #include <boost/algorithm/string.hpp> -#include <boost/lexical_cast.hpp> #include <boost/range.hpp> #include <boost/type_traits/is_same.hpp> @@ -71,21 +70,21 @@ namespace detail template <typename BGParams, typename T> inline void pj_push_defaults(BGParams const& /*bg_params*/, parameters<T>& pin) { - pin.params.push_back(pj_mkparam<T>("ellps=WGS84")); + pin.params.push_back(pj_mkparam<T>("ellps", "WGS84")); if (pin.name == "aea") { - pin.params.push_back(pj_mkparam<T>("lat_1=29.5")); - pin.params.push_back(pj_mkparam<T>("lat_2=45.5 ")); + pin.params.push_back(pj_mkparam<T>("lat_1", "29.5")); + pin.params.push_back(pj_mkparam<T>("lat_2", "45.5 ")); } else if (pin.name == "lcc") { - pin.params.push_back(pj_mkparam<T>("lat_1=33")); - pin.params.push_back(pj_mkparam<T>("lat_2=45")); + pin.params.push_back(pj_mkparam<T>("lat_1", "33")); + pin.params.push_back(pj_mkparam<T>("lat_2", "45")); } else if (pin.name == "lagrng") { - pin.params.push_back(pj_mkparam<T>("W=2")); + pin.params.push_back(pj_mkparam<T>("W", "2")); } } @@ -100,21 +99,21 @@ inline void pj_push_defaults(srs::static_proj4<BOOST_GEOMETRY_PROJECTIONS_DETAIL >::type proj_tag; // statically defaulting to WGS84 - //pin.params.push_back(pj_mkparam("ellps=WGS84")); + //pin.params.push_back(pj_mkparam("ellps", "WGS84")); if (BOOST_GEOMETRY_CONDITION((boost::is_same<proj_tag, srs::par4::aea>::value))) { - pin.params.push_back(pj_mkparam<T>("lat_1=29.5")); - pin.params.push_back(pj_mkparam<T>("lat_2=45.5 ")); + pin.params.push_back(pj_mkparam<T>("lat_1", "29.5")); + pin.params.push_back(pj_mkparam<T>("lat_2", "45.5 ")); } else if (BOOST_GEOMETRY_CONDITION((boost::is_same<proj_tag, srs::par4::lcc>::value))) { - pin.params.push_back(pj_mkparam<T>("lat_1=33")); - pin.params.push_back(pj_mkparam<T>("lat_2=45")); + pin.params.push_back(pj_mkparam<T>("lat_1", "33")); + pin.params.push_back(pj_mkparam<T>("lat_2", "45")); } else if (BOOST_GEOMETRY_CONDITION((boost::is_same<proj_tag, srs::par4::lagrng>::value))) { - pin.params.push_back(pj_mkparam<T>("W=2")); + pin.params.push_back(pj_mkparam<T>("W", "2")); } } @@ -128,7 +127,7 @@ inline void pj_init_units(std::vector<pvalue<T> > const& params, T const& default_fr_meter) { std::string s; - std::string units = pj_param(params, sunits).s; + std::string units = pj_get_param_s(params, sunits); if (! units.empty()) { const int n = sizeof(pj_units) / sizeof(pj_units[0]); @@ -142,14 +141,14 @@ inline void pj_init_units(std::vector<pvalue<T> > const& params, } if (index == -1) { - BOOST_THROW_EXCEPTION( projection_exception(-7) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unknow_unit_id) ); } s = pj_units[index].to_meter; } if (s.empty()) { - s = pj_param(params, sto_meter).s; + s = pj_get_param_s(params, sto_meter); } if (! s.empty()) @@ -157,21 +156,21 @@ inline void pj_init_units(std::vector<pvalue<T> > const& params, std::size_t const pos = s.find('/'); if (pos == std::string::npos) { - to_meter = lexical_cast<T>(s); + to_meter = geometry::str_cast<T>(s); } else { - T const numerator = lexical_cast<T>(s.substr(0, pos)); - T const denominator = lexical_cast<T>(s.substr(pos + 1)); + T const numerator = geometry::str_cast<T>(s.substr(0, pos)); + T const denominator = geometry::str_cast<T>(s.substr(pos + 1)); if (numerator == 0.0 || denominator == 0.0) { - BOOST_THROW_EXCEPTION( projection_exception(-99) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); } to_meter = numerator / denominator; } if (to_meter == 0.0) { - BOOST_THROW_EXCEPTION( projection_exception(-99) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); } fr_meter = 1. / to_meter; } @@ -200,15 +199,16 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool pin.params.push_back(pj_mkparam<T>(*it)); } + // maybe TODO: handle "init" parameter /* check if +init present */ - if (pj_param(pin.params, "tinit").i) - { - // maybe TODO: handle "init" parameter - //if (!(curr = get_init(&arguments, curr, pj_param(pin.params, "sinit").s))) - } + //std::string sinit; + //if (pj_param_s(pin.params, "init", sinit)) + //{ + // //if (!(curr = get_init(&arguments, curr, sinit))) + //} // find projection -> implemented in projection factory - pin.name = pj_param(pin.params, "sproj").s; + pin.name = pj_get_param_s(pin.params, "proj"); // exception thrown in projection<> // TODO: consider throwing here both projection_unknown_id_exception and // projection_not_named_exception in order to throw before other exceptions @@ -217,7 +217,7 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool // set defaults, unless inhibited // GL-Addition, if use_defaults is false then defaults are ignored - if (use_defaults && ! pj_param(pin.params, "bno_defs").i) + if (use_defaults && ! pj_get_param_b(pin.params, "no_defs")) { // proj4 gets defaults from "proj_def.dat", file of 94/02/23 with a few defaults. // Here manually @@ -246,61 +246,59 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool pin.ra = 1. / pin.a; pin.one_es = 1. - pin.es; if (pin.one_es == 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-6) ); + BOOST_THROW_EXCEPTION( projection_exception(error_eccentricity_is_one) ); } pin.rone_es = 1./pin.one_es; /* Now that we have ellipse information check for WGS84 datum */ - if( pin.datum_type == PJD_3PARAM + if( pin.datum_type == datum_3param && pin.datum_params[0] == 0.0 && pin.datum_params[1] == 0.0 && pin.datum_params[2] == 0.0 && pin.a == 6378137.0 && geometry::math::abs(pin.es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/ { - pin.datum_type = PJD_WGS84; + pin.datum_type = datum_wgs84; } /* set pin.geoc coordinate system */ - pin.geoc = (pin.es && pj_param(pin.params, "bgeoc").i); + pin.geoc = (pin.es && pj_get_param_b(pin.params, "geoc")); /* over-ranging flag */ - pin.over = pj_param(pin.params, "bover").i; + pin.over = pj_get_param_b(pin.params, "over"); /* longitude center for wrapping */ - pin.is_long_wrap_set = pj_param(pin.params, "tlon_wrap").i != 0; - if (pin.is_long_wrap_set) - pin.long_wrap_center = pj_param(pin.params, "rlon_wrap").f; + pin.is_long_wrap_set = pj_param_r(pin.params, "lon_wrap", pin.long_wrap_center); /* central meridian */ - pin.lam0 = pj_param(pin.params, "rlon_0").f; + pin.lam0 = pj_get_param_r(pin.params, "lon_0"); /* central latitude */ - pin.phi0 = pj_param(pin.params, "rlat_0").f; + pin.phi0 = pj_get_param_r(pin.params, "lat_0"); /* false easting and northing */ - pin.x0 = pj_param(pin.params, "dx_0").f; - pin.y0 = pj_param(pin.params, "dy_0").f; + pin.x0 = pj_get_param_f(pin.params, "x_0"); + pin.y0 = pj_get_param_f(pin.params, "y_0"); /* general scaling factor */ - if (pj_param(pin.params, "tk_0").i) - pin.k0 = pj_param(pin.params, "dk_0").f; - else if (pj_param(pin.params, "tk").i) - pin.k0 = pj_param(pin.params, "dk").f; - else + if (pj_param_f(pin.params, "k_0", pin.k0)) { + /* empty */ + } else if (pj_param_f(pin.params, "k", pin.k0)) { + /* empty */ + } else pin.k0 = 1.; if (pin.k0 <= 0.) { - BOOST_THROW_EXCEPTION( projection_exception(-31) ); + BOOST_THROW_EXCEPTION( projection_exception(error_k_less_than_zero) ); } /* set units */ - pj_init_units(pin.params, "sunits", "sto_meter", + pj_init_units(pin.params, "units", "to_meter", pin.to_meter, pin.fr_meter, 1., 1.); - pj_init_units(pin.params, "svunits", "svto_meter", + pj_init_units(pin.params, "vunits", "vto_meter", pin.vto_meter, pin.vfr_meter, pin.to_meter, pin.fr_meter); /* prime meridian */ - std::string pm = pj_param(pin.params, "spm").s; + std::string pm = pj_get_param_s(pin.params, "pm"); if (! pm.empty()) { std::string value; @@ -317,8 +315,8 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool dms_parser<T, true> parser; - // TODO: Handle case when lexical_cast is not used consistently. - // This should probably be done in dms_parser. + // TODO: Is this try-catch needed? + // In other cases the bad_str_cast exception is simply thrown BOOST_TRY { if (value.empty()) { @@ -327,9 +325,9 @@ inline parameters<T> pj_init(BGParams const& bg_params, R const& arguments, bool pin.from_greenwich = parser.apply(value).angle(); } } - BOOST_CATCH(boost::bad_lexical_cast const&) + BOOST_CATCH(geometry::bad_str_cast const&) { - BOOST_THROW_EXCEPTION( projection_exception(-46) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) ); } BOOST_CATCH_END } diff --git a/boost/geometry/srs/projections/impl/pj_mlfn.hpp b/boost/geometry/srs/projections/impl/pj_mlfn.hpp index 1317dd2e2f..04f0d19442 100644 --- a/boost/geometry/srs/projections/impl/pj_mlfn.hpp +++ b/boost/geometry/srs/projections/impl/pj_mlfn.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -36,10 +36,17 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +/* meridional distance for ellipsoid and inverse +** 8th degree - accurate to < 1e-5 meters when used in conjunction +** with typical major axis values. +** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds. +*/ + #ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP #define BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP +#include <cstdlib> #include <boost/geometry/util/math.hpp> @@ -48,10 +55,20 @@ namespace boost { namespace geometry { namespace projections { namespace detail { -static const int EN_SIZE = 5; +template <typename T> +struct en +{ + static const std::size_t size = 5; + + T const& operator[](size_t i) const { return data[i]; } + T & operator[](size_t i) { return data[i]; } + +private: + T data[5]; +}; template <typename T> -inline bool pj_enfn(T const& es, T* en) +inline en<T> pj_enfn(T const& es) { static const T C00 = 1.; static const T C02 = .25; @@ -66,9 +83,9 @@ inline bool pj_enfn(T const& es, T* en) static const T C68 = .00569661458333333333; static const T C88 = .3076171875; - T t; //, *en; + T t; + detail::en<T> en; - //if (en = (double *)pj_malloc(EN_SIZE * sizeof(double))) { en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08))); en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08))); @@ -76,12 +93,12 @@ inline bool pj_enfn(T const& es, T* en) en[3] = (t *= es) * (C66 - es * C68); en[4] = t * es * C88; } - // return en; - return true; + + return en; } template <typename T> -inline T pj_mlfn(T const& phi, T sphi, T cphi, const T *en) +inline T pj_mlfn(T const& phi, T sphi, T cphi, detail::en<T> const& en) { cphi *= sphi; sphi *= sphi; @@ -90,13 +107,8 @@ inline T pj_mlfn(T const& phi, T sphi, T cphi, const T *en) } template <typename T> -inline T pj_inv_mlfn(T const& arg, T const& es, const T *en) +inline T pj_inv_mlfn(T const& arg, T const& es, detail::en<T> const& en) { - /* meridinal distance for ellipsoid and inverse - ** 8th degree - accurate to < 1e-5 meters when used in conjuction - ** with typical major axis values. - ** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds. - */ static const T EPS = 1e-11; static const int MAX_ITER = 10; @@ -111,7 +123,7 @@ inline T pj_inv_mlfn(T const& arg, T const& es, const T *en) if (geometry::math::abs(t) < EPS) return phi; } - BOOST_THROW_EXCEPTION( projection_exception(-17) ); + BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) ); return phi; } diff --git a/boost/geometry/srs/projections/impl/pj_param.hpp b/boost/geometry/srs/projections/impl/pj_param.hpp index 4f33ad837f..7648055414 100644 --- a/boost/geometry/srs/projections/impl/pj_param.hpp +++ b/boost/geometry/srs/projections/impl/pj_param.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -43,15 +43,30 @@ #include <string> #include <vector> +#include <boost/geometry/srs/projections/exception.hpp> + #include <boost/geometry/srs/projections/impl/dms_parser.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/is_integral.hpp> + namespace boost { namespace geometry { namespace projections { namespace detail { +/* create pvalue list entry */ +template <typename T> +inline pvalue<T> pj_mkparam(std::string const& name, std::string const& value) +{ + pvalue<T> newitem; + newitem.param = name; + newitem.s = value; + //newitem.used = false; + return newitem; +} /* create pvalue list entry */ template <typename T> @@ -67,92 +82,146 @@ inline pvalue<T> pj_mkparam(std::string const& str) name.erase(loc); } + return pj_mkparam<T>(name, value); +} - pvalue<T> newitem; - newitem.param = name; - newitem.s = value; - newitem.used = 0; - newitem.i = atoi(value.c_str()); - newitem.f = atof(value.c_str()); - return newitem; +/* input exists */ +template <typename T> +inline typename std::vector<pvalue<T> >::const_iterator + pj_param_find(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + typedef typename std::vector<pvalue<T> >::const_iterator iterator; + for (iterator it = pl.begin(); it != pl.end(); it++) + { + if (it->param == name) + { + //it->used = true; + return it; + } + // TODO: needed for pipeline + /*else if (it->param == "step") + { + return pl.end(); + }*/ + } + + return pl.end(); } -/************************************************************************/ -/* pj_param() */ -/* */ -/* Test for presence or get pvalue value. The first */ -/* character in `opt' is a pvalue type which can take the */ -/* values: */ -/* */ -/* `t' - test for presence, return TRUE/FALSE in pvalue.i */ -/* `i' - integer value returned in pvalue.i */ -/* `d' - simple valued real input returned in pvalue.f */ -/* `r' - degrees (DMS translation applied), returned as */ -/* radians in pvalue.f */ -/* `s' - string returned in pvalue.s */ -/* `b' - test for t/T/f/F, return in pvalue.i */ -/* */ -/************************************************************************/ +/* input exists */ +template <typename T> +inline bool pj_param_exists(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + return pj_param_find(pl, name) != pl.end(); +} +/* integer input */ template <typename T> -inline pvalue<T> pj_param(std::vector<pvalue<T> > const& pl, std::string opt) +inline bool pj_param_i(std::vector<pvalue<T> > const& pl, std::string const& name, int & par) { - char type = opt[0]; - opt.erase(opt.begin()); + typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name); + if (it != pl.end()) + { + par = geometry::str_cast<int>(it->s); + return true; + } + return false; +} - pvalue<T> value; +/* floating point input */ +template <typename T> +inline bool pj_param_f(std::vector<pvalue<T> > const& pl, std::string const& name, T & par) +{ + typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name); + if (it != pl.end()) + { + par = geometry::str_cast<T>(it->s); + return true; + } + return false; +} - /* simple linear lookup */ - typedef typename std::vector<pvalue<T> >::const_iterator iterator; - for (iterator it = pl.begin(); it != pl.end(); it++) +/* radians input */ +template <typename T> +inline bool pj_param_r(std::vector<pvalue<T> > const& pl, std::string const& name, T & par) +{ + typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name); + if (it != pl.end()) + { + dms_parser<T, true> parser; + par = parser.apply(it->s.c_str()).angle(); + return true; + } + return false; +} + +/* string input */ +template <typename T> +inline bool pj_param_s(std::vector<pvalue<T> > const& pl, std::string const& name, std::string & par) +{ + typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name); + if (it != pl.end()) + { + par = it->s; + return true; + } + return false; +} + +/* bool input */ +template <typename T> +inline bool pj_get_param_b(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + typename std::vector<pvalue<T> >::const_iterator it = pj_param_find(pl, name); + if (it != pl.end()) { - if (it->param == opt) + switch (it->s[0]) { - //it->used = 1; - switch (type) - { - case 't': - value.i = 1; - break; - case 'i': /* integer input */ - value.i = atoi(it->s.c_str()); - break; - case 'd': /* simple real input */ - value.f = atof(it->s.c_str()); - break; - case 'r': /* degrees input */ - { - dms_parser<T, true> parser; - value.f = parser.apply(it->s.c_str()).angle(); - } - break; - case 's': /* char string */ - value.s = it->s; - break; - case 'b': /* boolean */ - switch (it->s[0]) - { - case 'F': case 'f': - value.i = 0; - break; - case '\0': case 'T': case 't': - value.i = 1; - break; - default: - value.i = 0; - break; - } - break; - } - return value; + case '\0': case 'T': case 't': + return true; + case 'F': case 'f': + return false; + default: + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_boolean_param) ); + return false; } + } + return false; +} - } +// NOTE: In the original code, in pl_ell_set.c there is a function pj_get_param +// which behavior is similar to pj_param but it doesn't set `user` member to TRUE +// while pj_param does in the original code. In Boost.Geometry this member is not used. +template <typename T> +inline int pj_get_param_i(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + int res = 0; + pj_param_i(pl, name, res); + return res; +} - value.i = 0; - value.f = 0.0; - value.s = ""; - return value; +template <typename T> +inline T pj_get_param_f(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + T res = 0; + pj_param_f(pl, name, res); + return res; +} + +template <typename T> +inline T pj_get_param_r(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + T res = 0; + pj_param_r(pl, name, res); + return res; +} + +template <typename T> +inline std::string pj_get_param_s(std::vector<pvalue<T> > const& pl, std::string const& name) +{ + std::string res; + pj_param_s(pl, name, res); + return res; } } // namespace detail diff --git a/boost/geometry/srs/projections/impl/pj_phi2.hpp b/boost/geometry/srs/projections/impl/pj_phi2.hpp index 71f0cf1249..868a8c659b 100644 --- a/boost/geometry/srs/projections/impl/pj_phi2.hpp +++ b/boost/geometry/srs/projections/impl/pj_phi2.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -58,12 +58,12 @@ inline T pj_phi2(T const& ts, T const& e) i = N_ITER; do { con = e * sin (Phi); - dphi = geometry::math::half_pi<T>() - 2. * atan (ts * pow((1. - con) / - (1. + con), eccnth)) - Phi; + dphi = geometry::math::half_pi<T>() - 2. * atan (ts * math::pow((T(1) - con) / + (T(1) + con), eccnth)) - Phi; Phi += dphi; } while ( geometry::math::abs(dphi) > TOL && --i); if (i <= 0) - BOOST_THROW_EXCEPTION( projection_exception(-18) ); + BOOST_THROW_EXCEPTION( projection_exception(error_non_con_inv_phi2) ); return Phi; } diff --git a/boost/geometry/srs/projections/impl/pj_strerrno.hpp b/boost/geometry/srs/projections/impl/pj_strerrno.hpp index 22e0c48af4..418bea9266 100644 --- a/boost/geometry/srs/projections/impl/pj_strerrno.hpp +++ b/boost/geometry/srs/projections/impl/pj_strerrno.hpp @@ -86,6 +86,17 @@ pj_err_list[] = { "point not within available datum shift grids", /* -48 */ "invalid sweep axis, choose x or y", /* -49 */ "malformed pipeline", /* -50 */ + "unit conversion factor must be > 0", /* -51 */ + "invalid scale", /* -52 */ + "non-convergent computation", /* -53 */ + "missing required arguments", /* -54 */ + "lat_0 = 0", /* -55 */ + "ellipsoidal usage unsupported", /* -56 */ + "only one +init allowed for non-pipeline operations", /* -57 */ + "argument not numerical or out of range", /* -58 */ + + /* When adding error messages, remember to update ID defines in + projects.h, and transient_error array in pj_transform */ }; inline std::string pj_generic_strerrno(std::string const& msg, int err) diff --git a/boost/geometry/srs/projections/impl/pj_transform.hpp b/boost/geometry/srs/projections/impl/pj_transform.hpp index 8c2095642f..bccf150db0 100644 --- a/boost/geometry/srs/projections/impl/pj_transform.hpp +++ b/boost/geometry/srs/projections/impl/pj_transform.hpp @@ -44,6 +44,7 @@ #include <boost/geometry/core/radian_access.hpp> #include <boost/geometry/srs/projections/impl/geocent.hpp> +#include <boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> #include <boost/geometry/srs/projections/invalid_point.hpp> @@ -157,14 +158,6 @@ private: // Boost.Geometry helpers end // ----------------------------------------------------------- -/*#ifndef SRS_WGS84_SEMIMAJOR -#define SRS_WGS84_SEMIMAJOR 6378137.0 -#endif - -#ifndef SRS_WGS84_ESQUARED -#define SRS_WGS84_ESQUARED 0.0066943799901413165 -#endif*/ - template <typename Par> inline typename Par::type Dx_BF(Par const& defn) { return defn.datum_params[0]; } template <typename Par> @@ -182,22 +175,32 @@ inline typename Par::type M_BF(Par const& defn) { return defn.datum_params[6]; } /* ** This table is intended to indicate for any given error code in -** the range 0 to -44, whether that error will occur for all locations (ie. +** the range 0 to -56, whether that error will occur for all locations (ie. ** it is a problem with the coordinate system as a whole) in which case the ** value would be 0, or if the problem is with the point being transformed ** in which case the value is 1. ** ** At some point we might want to move this array in with the error message ** list or something, but while experimenting with it this should be fine. +** +** +** NOTE (2017-10-01): Non-transient errors really should have resulted in a +** PJ==0 during initialization, and hence should be handled at the level +** before calling pj_transform. The only obvious example of the contrary +** appears to be the PJD_ERR_GRID_AREA case, which may also be taken to +** mean "no grids available" +** +** */ -static const int transient_error[50] = { +static const int transient_error[60] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 to 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 to 19 */ 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, /* 20 to 29 */ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 30 to 39 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }; + /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + /* 50 to 59 */ 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 }; template <typename T, typename Range> @@ -216,10 +219,18 @@ inline int pj_geodetic_to_geocentric( T const& a, T const& es, /* projection specific components). */ /************************************************************************/ -template <typename SrcPrj, typename DstPrj2, typename Par, typename Range> +template < + typename SrcPrj, + typename DstPrj2, + typename Par, + typename Range, + typename Grids +> inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, DstPrj2 const& dstprj, Par const& dstdefn, - Range & range) + Range & range, + Grids const& srcgrids, + Grids const& dstgrids) { typedef typename boost::range_value<Range>::type point_type; @@ -253,7 +264,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, { // Point should be cartesian 3D (ECEF) if (dimension < 3) - BOOST_THROW_EXCEPTION( projection_exception(PJD_ERR_GEOCENTRIC) ); + BOOST_THROW_EXCEPTION( projection_exception(error_geocentric) ); //return PJD_ERR_GEOCENTRIC; if( srcdefn.to_meter != 1.0 ) @@ -406,7 +417,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, /* -------------------------------------------------------------------- */ /* Convert datums if needed, and possible. */ /* -------------------------------------------------------------------- */ - if ( ! pj_datum_transform( srcdefn, dstdefn, range ) ) + if ( ! pj_datum_transform( srcdefn, dstdefn, range, srcgrids, dstgrids ) ) { result = false; } @@ -446,7 +457,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, { // Point should be cartesian 3D (ECEF) if (dimension < 3) - BOOST_THROW_EXCEPTION( projection_exception(PJD_ERR_GEOCENTRIC) ); + BOOST_THROW_EXCEPTION( projection_exception(error_geocentric) ); //return PJD_ERR_GEOCENTRIC; // NOTE: In the original code the return value of the following @@ -615,7 +626,7 @@ inline int pj_geodetic_to_geocentric( T const& a, T const& es, GeocentricInfo<T> gi; if( pj_Set_Geocentric_Parameters( gi, a, b ) != 0 ) { - return PJD_ERR_GEOCENTRIC; + return error_geocentric; } for( std::size_t i = 0 ; i < point_count ; ++i ) @@ -632,7 +643,7 @@ inline int pj_geodetic_to_geocentric( T const& a, T const& es, range_wrapper.get_z(i), // Height X, Y, Z ) != 0 ) { - ret_errno = -14; + ret_errno = error_lat_or_lon_exceed_limit; set_invalid_point(point); /* but keep processing points! */ } @@ -668,7 +679,7 @@ inline int pj_geocentric_to_geodetic( T const& a, T const& es, GeocentricInfo<T> gi; if( pj_Set_Geocentric_Parameters( gi, a, b ) != 0 ) { - return PJD_ERR_GEOCENTRIC; + return error_geocentric; } for( std::size_t i = 0 ; i < point_count ; ++i ) @@ -714,13 +725,13 @@ inline bool pj_compare_datums( Par & srcdefn, Par & dstdefn ) considered identical */ return false; } - else if( srcdefn.datum_type == PJD_3PARAM ) + else if( srcdefn.datum_type == datum_3param ) { return (srcdefn.datum_params[0] == dstdefn.datum_params[0] && srcdefn.datum_params[1] == dstdefn.datum_params[1] && srcdefn.datum_params[2] == dstdefn.datum_params[2]); } - else if( srcdefn.datum_type == PJD_7PARAM ) + else if( srcdefn.datum_type == datum_7param ) { return (srcdefn.datum_params[0] == dstdefn.datum_params[0] && srcdefn.datum_params[1] == dstdefn.datum_params[1] @@ -730,10 +741,10 @@ inline bool pj_compare_datums( Par & srcdefn, Par & dstdefn ) && srcdefn.datum_params[5] == dstdefn.datum_params[5] && srcdefn.datum_params[6] == dstdefn.datum_params[6]); } - else if( srcdefn.datum_type == PJD_GRIDSHIFT ) + else if( srcdefn.datum_type == datum_gridshift ) { - return pj_param(srcdefn.params,"snadgrids").s - == pj_param(dstdefn.params,"snadgrids").s; + return pj_get_param_s(srcdefn.params,"nadgrids") + == pj_get_param_s(dstdefn.params,"nadgrids"); } else return true; @@ -754,7 +765,7 @@ inline int pj_geocentric_to_wgs84( Par const& defn, Range & rng = range_wrapper.get_range(); std::size_t point_count = boost::size(rng); - if( defn.datum_type == PJD_3PARAM ) + if( defn.datum_type == datum_3param ) { for(std::size_t i = 0; i < point_count; i++ ) { @@ -768,7 +779,7 @@ inline int pj_geocentric_to_wgs84( Par const& defn, range_wrapper.set_z(i, range_wrapper.get_z(i) + Dz_BF(defn)); } } - else if( defn.datum_type == PJD_7PARAM ) + else if( defn.datum_type == datum_7param ) { for(std::size_t i = 0; i < point_count; i++ ) { @@ -811,7 +822,7 @@ inline int pj_geocentric_from_wgs84( Par const& defn, Range & rng = range_wrapper.get_range(); std::size_t point_count = boost::size(rng); - if( defn.datum_type == PJD_3PARAM ) + if( defn.datum_type == datum_3param ) { for(std::size_t i = 0; i < point_count; i++ ) { @@ -825,7 +836,7 @@ inline int pj_geocentric_from_wgs84( Par const& defn, range_wrapper.set_z(i, range_wrapper.get_z(i) - Dz_BF(defn)); } } - else if( defn.datum_type == PJD_7PARAM ) + else if( defn.datum_type == datum_7param ) { for(std::size_t i = 0; i < point_count; i++ ) { @@ -869,11 +880,17 @@ inline bool pj_datum_check_error(int err) /* coordinates in radians in the destination datum. */ /************************************************************************/ -template <typename Par, typename Range> -inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, - Range & range ) +template <typename Par, typename Range, typename Grids> +inline bool pj_datum_transform(Par const& srcdefn, + Par const& dstdefn, + Range & range, + Grids const& srcgrids, + Grids const& dstgrids) { + static const double wgs84_a = 6378137.0; + static const double wgs84_es = 0.0066943799901413165; + typedef typename Par::type calc_t; bool result = true; @@ -885,8 +902,8 @@ inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, /* (ie. only a +ellps declaration, no +datum). This is new */ /* behavior for PROJ 4.6.0. */ /* -------------------------------------------------------------------- */ - if( srcdefn.datum_type == PJD_UNKNOWN - || dstdefn.datum_type == PJD_UNKNOWN ) + if( srcdefn.datum_type == datum_unknown + || dstdefn.datum_type == datum_unknown ) return result; /* -------------------------------------------------------------------- */ @@ -911,34 +928,34 @@ inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, /* If this datum requires grid shifts, then apply it to geodetic */ /* coordinates. */ /* -------------------------------------------------------------------- */ - /*if( srcdefn.datum_type == PJD_GRIDSHIFT ) + if( srcdefn.datum_type == datum_gridshift ) { try { - pj_apply_gridshift_2( srcdefn, 0, point_count, point_offset, x, y, z ); + pj_apply_gridshift_2<false>( srcdefn, range, srcgrids ); } catch (projection_exception const& e) { if (pj_datum_check_error(e.code())) { BOOST_RETHROW } } - src_a = SRS_WGS84_SEMIMAJOR; - src_es = SRS_WGS84_ESQUARED; + src_a = wgs84_a; + src_es = wgs84_es; } - if( dstdefn.datum_type == PJD_GRIDSHIFT ) + if( dstdefn.datum_type == datum_gridshift ) { - dst_a = SRS_WGS84_SEMIMAJOR; - dst_es = SRS_WGS84_ESQUARED; - }*/ + dst_a = wgs84_a; + dst_es = wgs84_es; + } /* ==================================================================== */ /* Do we need to go through geocentric coordinates? */ /* ==================================================================== */ if( src_es != dst_es || src_a != dst_a - || srcdefn.datum_type == PJD_3PARAM - || srcdefn.datum_type == PJD_7PARAM - || dstdefn.datum_type == PJD_3PARAM - || dstdefn.datum_type == PJD_7PARAM) + || srcdefn.datum_type == datum_3param + || srcdefn.datum_type == datum_7param + || dstdefn.datum_type == datum_3param + || dstdefn.datum_type == datum_7param) { /* -------------------------------------------------------------------- */ /* Convert to geocentric coordinates. */ @@ -952,8 +969,8 @@ inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, /* -------------------------------------------------------------------- */ /* Convert between datums. */ /* -------------------------------------------------------------------- */ - if( srcdefn.datum_type == PJD_3PARAM - || srcdefn.datum_type == PJD_7PARAM ) + if( srcdefn.datum_type == datum_3param + || srcdefn.datum_type == datum_7param ) { try { pj_geocentric_to_wgs84( srcdefn, z_range ); @@ -964,8 +981,8 @@ inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, } } - if( dstdefn.datum_type == PJD_3PARAM - || dstdefn.datum_type == PJD_7PARAM ) + if( dstdefn.datum_type == datum_3param + || dstdefn.datum_type == datum_7param ) { try { pj_geocentric_from_wgs84( dstdefn, z_range ); @@ -989,15 +1006,15 @@ inline bool pj_datum_transform( Par const& srcdefn, Par const& dstdefn, /* -------------------------------------------------------------------- */ /* Apply grid shift to destination if required. */ /* -------------------------------------------------------------------- */ - /*if( dstdefn.datum_type == PJD_GRIDSHIFT ) + if( dstdefn.datum_type == datum_gridshift ) { try { - pj_apply_gridshift_2( dstdefn, 1, point_count, point_offset, x, y, z ); + pj_apply_gridshift_2<true>( dstdefn, range, dstgrids ); } catch (projection_exception const& e) { if (pj_datum_check_error(e.code())) BOOST_RETHROW } - }*/ + } return result; } diff --git a/boost/geometry/srs/projections/impl/pj_tsfn.hpp b/boost/geometry/srs/projections/impl/pj_tsfn.hpp index d39a0fb2fc..46d3edcce0 100644 --- a/boost/geometry/srs/projections/impl/pj_tsfn.hpp +++ b/boost/geometry/srs/projections/impl/pj_tsfn.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -50,7 +50,7 @@ namespace detail { { sinphi *= e; return (tan (.5 * (geometry::math::half_pi<T>() - phi)) / - pow((1. - sinphi) / (1. + sinphi), .5 * e)); + math::pow((T(1) - sinphi) / (T(1) + sinphi), T(0.5) * e)); } } // namespace detail diff --git a/boost/geometry/srs/projections/impl/pj_units.hpp b/boost/geometry/srs/projections/impl/pj_units.hpp index 269b8ff92e..98e1fa4c9f 100644 --- a/boost/geometry/srs/projections/impl/pj_units.hpp +++ b/boost/geometry/srs/projections/impl/pj_units.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -44,11 +44,19 @@ namespace boost { namespace geometry { namespace projections { namespace detail { +// Originally defined in projects.h +struct pj_units_type +{ + std::string id; /* units keyword */ + std::string to_meter; /* multiply by value to get meters */ + std::string name; /* comments */ +}; + /* Field 2 that contains the multiplier to convert named units to meters ** may be expressed by either a simple floating point constant or a ** numerator/denomenator values (e.g. 1/1000) */ -static const PJ_UNITS pj_units[] = +static const pj_units_type pj_units[] = { { "km", "1000.", "Kilometer" }, { "m", "1.", "Meter" }, diff --git a/boost/geometry/srs/projections/impl/pj_zpoly1.hpp b/boost/geometry/srs/projections/impl/pj_zpoly1.hpp index 613b6d2b35..4cb1cb1f6c 100644 --- a/boost/geometry/srs/projections/impl/pj_zpoly1.hpp +++ b/boost/geometry/srs/projections/impl/pj_zpoly1.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -52,10 +52,10 @@ namespace boost { namespace geometry { namespace projections { namespace detail ** n should always be >= 1 though no checks are made */ template <typename T> - inline COMPLEX<T> - pj_zpoly1(COMPLEX<T> z, const COMPLEX<T> *C, int n) + inline pj_complex<T> + pj_zpoly1(pj_complex<T> z, const pj_complex<T> *C, int n) { - COMPLEX<T> a; + pj_complex<T> a; T t; a = *(C += n); @@ -71,14 +71,14 @@ namespace boost { namespace geometry { namespace projections { namespace detail /* evaluate complex polynomial and derivative */ template <typename T> - inline COMPLEX<T> - pj_zpolyd1(COMPLEX<T> z, const COMPLEX<T> *C, int n, COMPLEX<T> *der) + inline pj_complex<T> + pj_zpolyd1(pj_complex<T> z, const pj_complex<T> *C, int n, pj_complex<T> *der) { T t; bool first = true; - COMPLEX<T> a = *(C += n); - COMPLEX<T> b = a; + pj_complex<T> a = *(C += n); + pj_complex<T> b = a; while (n-- > 0) { if (first) diff --git a/boost/geometry/srs/projections/impl/proj_mdist.hpp b/boost/geometry/srs/projections/impl/proj_mdist.hpp index 1c325df1c6..5f67546f54 100644 --- a/boost/geometry/srs/projections/impl/proj_mdist.hpp +++ b/boost/geometry/srs/projections/impl/proj_mdist.hpp @@ -3,6 +3,10 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -43,23 +47,23 @@ namespace boost { namespace geometry { namespace projections { namespace detail { - static const int MDIST_MAX_ITER = 20; - template <typename T> - struct MDIST + struct mdist { + static const int static_size = 20; + int nb; T es; T E; - T b[MDIST_MAX_ITER]; + T b[static_size]; }; - template <typename CT> - inline bool proj_mdist_ini(CT const& es, MDIST<CT>& b) + template <typename T> + inline bool proj_mdist_ini(T const& es, mdist<T>& b) { - CT numf, numfi, twon1, denf, denfi, ens, T, twon; - CT den, El, Es; - CT E[MDIST_MAX_ITER]; + T numf, numfi, twon1, denf, denfi, ens, t, twon; + T den, El, Es; + T E[mdist<T>::static_size]; int i, j; /* generate E(e^2) and its terms E[] */ @@ -68,12 +72,13 @@ namespace detail denf = 1.; twon = 4.; Es = El = E[0] = 1.; - for (i = 1; i < MDIST_MAX_ITER ; ++i) + for (i = 1; i < mdist<T>::static_size ; ++i) { numf *= (twon1 * twon1); den = twon * denf * denf * twon1; - T = numf/den; - Es -= (E[i] = T * ens); + t = numf/den; + E[i] = t * ens; + Es -= E[i]; ens *= es; twon *= 4.; denf *= ++denfi; @@ -103,7 +108,7 @@ namespace detail } template <typename T> - inline T proj_mdist(T const& phi, T const& sphi, T const& cphi, MDIST<T> const& b) + inline T proj_mdist(T const& phi, T const& sphi, T const& cphi, mdist<T> const& b) { T sc, sum, sphi2, D; int i; @@ -117,14 +122,14 @@ namespace detail } template <typename T> - inline T proj_inv_mdist(T const& dist, MDIST<T> const& b) + inline T proj_inv_mdist(T const& dist, mdist<T> const& b) { static const T TOL = 1e-14; T s, t, phi, k; int i; k = 1./(1.- b.es); - i = MDIST_MAX_ITER; + i = mdist<T>::static_size; phi = dist; while ( i-- ) { s = sin(phi); @@ -135,7 +140,7 @@ namespace detail return phi; } /* convergence failed */ - BOOST_THROW_EXCEPTION( projection_exception(-17) ); + BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) ); } } // namespace detail diff --git a/boost/geometry/srs/projections/impl/projects.hpp b/boost/geometry/srs/projections/impl/projects.hpp index 232ae67ae9..2f94ffd021 100644 --- a/boost/geometry/srs/projections/impl/projects.hpp +++ b/boost/geometry/srs/projections/impl/projects.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -44,8 +44,8 @@ #include <string> #include <vector> -#include <boost/geometry/srs/projections/exception.hpp> -#include <boost/math/constants/constants.hpp> +#include <boost/config.hpp> +#include <boost/geometry/srs/projections/constants.hpp> #include <boost/mpl/if.hpp> #include <boost/type_traits/is_pod.hpp> @@ -57,199 +57,172 @@ namespace boost { namespace geometry { namespace projections namespace detail { -/* some useful constants */ -template <typename T> -inline T ONEPI() { return boost::math::constants::pi<T>(); } -template <typename T> -inline T HALFPI() { return boost::math::constants::half_pi<T>(); } -template <typename T> -inline T FORTPI() { return boost::math::constants::pi<T>() / T(4); } -template <typename T> -inline T TWOPI() { return boost::math::constants::two_pi<T>(); } -template <typename T> -inline T TWO_D_PI() { return boost::math::constants::two_div_pi<T>(); } -template <typename T> -inline T HALFPI_SQR() { return 2.4674011002723396547086227499689; } -template <typename T> -inline T PI_SQR() { return boost::math::constants::pi_sqr<T>(); } -template <typename T> -inline T THIRD() { return 0.3333333333333333333333333333333; } -template <typename T> -inline T TWOTHIRD() { return 0.6666666666666666666666666666666; } -template <typename T> -inline T PI_HALFPI() { return 4.7123889803846898576939650749193; } -template <typename T> -inline T TWOPI_HALFPI() { return 7.8539816339744830961566084581988; } -template <typename T> -inline T PI_DIV_3() { return 1.0471975511965977461542144610932; } - /* datum_type values */ -static const int PJD_UNKNOWN = 0; -static const int PJD_3PARAM = 1; -static const int PJD_7PARAM = 2; -static const int PJD_GRIDSHIFT = 3; -static const int PJD_WGS84 = 4; /* WGS84 (or anything considered equivelent) */ +enum datum_type +{ + datum_unknown = 0, + datum_3param = 1, + datum_7param = 2, + datum_gridshift = 3, + datum_wgs84 = 4 /* WGS84 (or anything considered equivelent) */ +}; /* library errors */ -static const int PJD_ERR_GEOCENTRIC = -45; -static const int PJD_ERR_AXIS = -47; -static const int PJD_ERR_GRID_AREA = -48; -static const int PJD_ERR_CATALOG = -49; +enum error_type +{ + error_no_args = -1, + error_no_option_in_init_file = -2, + error_no_colon_in_init_string = -3, + error_proj_not_named = -4, + error_unknown_projection_id = -5, + error_eccentricity_is_one = -6, + error_unknow_unit_id = -7, + error_invalid_boolean_param = -8, + error_unknown_ellp_param = -9, + error_rev_flattening_is_zero = -10, + error_ref_rad_larger_than_90 = -11, + error_es_less_than_zero = -12, + error_major_axis_not_given = -13, + error_lat_or_lon_exceed_limit = -14, + error_invalid_x_or_y = -15, + error_wrong_format_dms_value = -16, + error_non_conv_inv_meri_dist = -17, + error_non_con_inv_phi2 = -18, + error_acos_asin_arg_too_large = -19, + error_tolerance_condition = -20, + error_conic_lat_equal = -21, + error_lat_larger_than_90 = -22, + error_lat1_is_zero = -23, + error_lat_ts_larger_than_90 = -24, + error_control_point_no_dist = -25, + error_no_rotation_proj = -26, + error_w_or_m_zero_or_less = -27, + error_lsat_not_in_range = -28, + error_path_not_in_range = -29, + error_h_less_than_zero = -30, + error_k_less_than_zero = -31, + error_lat_1_or_2_zero_or_90 = -32, + error_lat_0_or_alpha_eq_90 = -33, + error_ellipsoid_use_required = -34, + error_invalid_utm_zone = -35, + error_tcheby_val_out_of_range = -36, + error_failed_to_find_proj = -37, + error_failed_to_load_grid = -38, + error_invalid_m_or_n = -39, + error_n_out_of_range = -40, + error_lat_1_2_unspecified = -41, + error_abs_lat1_eq_abs_lat2 = -42, + error_lat_0_half_pi_from_mean = -43, + error_unparseable_cs_def = -44, + error_geocentric = -45, + error_unknown_prime_meridian = -46, + error_axis = -47, + error_grid_area = -48, + error_invalid_sweep_axis = -49, + error_malformed_pipeline = -50, + error_unit_factor_less_than_0 = -51, + error_invalid_scale = -52, + error_non_convergent = -53, + error_missing_args = -54, + error_lat_0_is_zero = -55, + error_ellipsoidal_unsupported = -56, + error_too_many_inits = -57, + error_invalid_arg = -58 +}; template <typename T> struct pvalue { std::string param; - int used; - - int i; - T f; std::string s; + //int used; }; -template <typename T> -struct pj_const_pod -{ - int over; /* over-range flag */ - int geoc; /* geocentric latitude flag */ - int is_latlong; /* proj=latlong ... not really a projection at all */ - int is_geocent; /* proj=geocent ... not really a projection at all */ - T - a, /* major axis or radius if es==0 */ - a_orig, /* major axis before any +proj related adjustment */ - es, /* e ^ 2 */ - es_orig, /* es before any +proj related adjustment */ - e, /* eccentricity */ - ra, /* 1/A */ - one_es, /* 1 - e^2 */ - rone_es, /* 1/one_es */ - lam0, phi0, /* central longitude, latitude */ - x0, y0, /* easting and northing */ - k0, /* general scaling factor */ - to_meter, fr_meter, /* cartesian scaling */ - vto_meter, vfr_meter; /* Vertical scaling. Internal unit [m] */ - - int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ - T datum_params[7]; - T from_greenwich; /* prime meridian offset (in radians) */ - T long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/ - bool is_long_wrap_set; - - // Initialize all variables to zero - pj_const_pod() - { - std::memset(this, 0, sizeof(pj_const_pod)); - } -}; +// Originally defined in proj_internal.h +//enum pj_io_units { +// pj_io_units_whatever = 0, /* Doesn't matter (or depends on pipeline neighbours) */ +// pj_io_units_classic = 1, /* Scaled meters (right), projected system */ +// pj_io_units_projected = 2, /* Meters, projected system */ +// pj_io_units_cartesian = 3, /* Meters, 3D cartesian system */ +// pj_io_units_angular = 4 /* Radians */ +//}; + +// Originally defined in proj_internal.h +/* Maximum latitudinal overshoot accepted */ +//static const double pj_epsilon_lat = 1e-12; template <typename T> -struct pj_const_non_pod +struct pj_consts { - int over; /* over-range flag */ - int geoc; /* geocentric latitude flag */ - int is_latlong; /* proj=latlong ... not really a projection at all */ - int is_geocent; /* proj=geocent ... not really a projection at all */ - T - a, /* major axis or radius if es==0 */ - a_orig, /* major axis before any +proj related adjustment */ - es, /* e ^ 2 */ - es_orig, /* es before any +proj related adjustment */ - e, /* eccentricity */ - ra, /* 1/A */ - one_es, /* 1 - e^2 */ - rone_es, /* 1/one_es */ - lam0, phi0, /* central longitude, latitude */ - x0, y0, /* easting and northing */ - k0, /* general scaling factor */ - to_meter, fr_meter, /* cartesian scaling */ - vto_meter, vfr_meter; /* Vertical scaling. Internal unit [m] */ - - int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ - T datum_params[7]; - T from_greenwich; /* prime meridian offset (in radians) */ - T long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/ - bool is_long_wrap_set; - - // Initialize all variables to zero - pj_const_non_pod() - : over(0), geoc(0), is_latlong(0), is_geocent(0) - , a(0), a_orig(0), es(0), es_orig(0), e(0), ra(0) - , one_es(0), rone_es(0), lam0(0), phi0(0), x0(0), y0(0), k0(0) - , to_meter(0), fr_meter(0), vto_meter(0), vfr_meter(0) - , datum_type(PJD_UNKNOWN) - , from_greenwich(0), long_wrap_center(0), is_long_wrap_set(false) - { - datum_params[0] = 0; - datum_params[1] = 0; - datum_params[2] = 0; - datum_params[3] = 0; - datum_params[4] = 0; - datum_params[5] = 0; - datum_params[6] = 0; - } -}; + // E L L I P S O I D P A R A M E T E R S -template <typename T> -struct pj_const - : boost::mpl::if_c - < - boost::is_pod<T>::value, - pj_const_pod<T>, - pj_const_non_pod<T> - >::type -{}; + T a; /* semimajor axis (radius if eccentricity==0) */ + T ra; /* 1/a */ -// PROJ4 complex. Might be replaced with std::complex -template <typename T> -struct COMPLEX { T r, i; }; + T e; /* first eccentricity */ + T es; /* first eccentricity squared */ + T one_es; /* 1 - e^2 */ + T rone_es; /* 1/one_es */ -struct PJ_ELLPS -{ - std::string id; /* ellipse keyword name */ - std::string major; /* a= value */ - std::string ell; /* elliptical parameter */ - std::string name; /* comments */ -}; + T es_orig, a_orig; /* es and a before any +proj related adjustment */ -struct PJ_DATUMS -{ - std::string id; /* datum keyword */ - std::string defn; /* ie. "to_wgs84=..." */ - std::string ellipse_id; /* ie from ellipse table */ - std::string comments; /* EPSG code, etc */ -}; + // C O O R D I N A T E H A N D L I N G -struct PJ_PRIME_MERIDIANS -{ - std::string id; /* prime meridian keyword */ - std::string defn; /* offset from greenwich in DMS format. */ -}; + int over; /* over-range flag */ + int geoc; /* geocentric latitude flag */ + int is_latlong; /* proj=latlong ... not really a projection at all */ + int is_geocent; /* proj=geocent ... not really a projection at all */ + //int need_ellps; /* 0 for operations that are purely cartesian */ -struct PJ_UNITS -{ - std::string id; /* units keyword */ - std::string to_meter; /* multiply by value to get meters */ - std::string name; /* comments */ -}; + //enum pj_io_units left; /* Flags for input/output coordinate types */ + //enum pj_io_units right; -template <typename T> -struct DERIVS -{ - T x_l, x_p; /* derivatives of x for lambda-phi */ - T y_l, y_p; /* derivatives of y for lambda-phi */ + // C A R T O G R A P H I C O F F S E T S + + T lam0, phi0; /* central longitude, latitude */ + T x0, y0/*, z0, t0*/; /* false easting and northing (and height and time) */ + + // S C A L I N G + + T k0; /* general scaling factor */ + T to_meter, fr_meter; /* cartesian scaling */ + T vto_meter, vfr_meter; /* Vertical scaling. Internal unit [m] */ + + // D A T U M S A N D H E I G H T S Y S T E M S + + detail::datum_type datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ + T datum_params[7]; /* Parameters for 3PARAM and 7PARAM */ + + T from_greenwich; /* prime meridian offset (in radians) */ + T long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/ + bool is_long_wrap_set; + + // Initialize all variables + pj_consts() + : a(0), ra(0) + , e(0), es(0), one_es(0), rone_es(0) + , es_orig(0), a_orig(0) + , over(0), geoc(0), is_latlong(0), is_geocent(0) + //, need_ellps(1) + //, left(PJ_IO_UNITS_ANGULAR), right(PJ_IO_UNITS_CLASSIC) + , lam0(0), phi0(0) + , x0(0), y0(0)/*, z0(0), t0(0)*/ + , k0(0) , to_meter(0), fr_meter(0), vto_meter(0), vfr_meter(0) + , datum_type(datum_unknown) +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && (!defined(_MSC_VER) || (_MSC_VER >= 1900)) // workaround for VC++ 12 (aka 2013) + , datum_params{0, 0, 0, 0, 0, 0, 0} +#endif + , from_greenwich(0), long_wrap_center(0), is_long_wrap_set(false) + { +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) || (defined(_MSC_VER) && (_MSC_VER < 1900)) // workaround for VC++ 12 (aka 2013) + std::fill(datum_params, datum_params + 7, T(0)); +#endif + } }; +// PROJ4 complex. Might be replaced with std::complex template <typename T> -struct FACTORS -{ - DERIVS<T> der; - T h, k; /* meridinal, parallel scales */ - T omega, thetap; /* angular distortion, theta prime */ - T conv; /* convergence */ - T s; /* areal scale factor */ - T a, b; /* max-min scale error */ - int code; /* info as to analytics, see following */ -}; +struct pj_complex { T r, i; }; } // namespace detail #endif // DOXYGEN_NO_DETAIL @@ -260,7 +233,7 @@ struct FACTORS \ingroup projection */ template <typename T> -struct parameters : public detail::pj_const<T> +struct parameters : public detail::pj_consts<T> { typedef T type; diff --git a/boost/geometry/srs/projections/par4.hpp b/boost/geometry/srs/projections/par4.hpp index 2b8656ae3e..616939afc1 100644 --- a/boost/geometry/srs/projections/par4.hpp +++ b/boost/geometry/srs/projections/par4.hpp @@ -241,28 +241,30 @@ struct datum_traits { typedef void ellps_type; static std::string id() { return ""; } - static std::string definition() { return ""; } + static std::string def_n() { return ""; } + static std::string def_v() { return ""; } }; -#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAME, ID, ELLPS, DEF) \ +#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAME, ID, ELLPS, DEF_N, DEF_V) \ template <> \ struct datum_traits< datum<par4::NAME> > \ { \ typedef par4::ellps<par4::ELLPS> ellps_type; \ static std::string id() { return ID; } \ - static std::string definition() { return DEF; } \ + static std::string def_n() { return DEF_N; } \ + static std::string def_v() { return DEF_V; } \ }; -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(WGS84, "WGS84", WGS84, "towgs84=0,0,0") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(GGRS87, "GGRS87", GRS80, "towgs84=-199.87,74.79,246.62") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAD83, "NAD83", GRS80, "towgs84=0,0,0") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAD27, "NAD27", clrk66, "nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(potsdam, "potsdam", bessel, "towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(carthage, "carthage", clrk80ign, "towgs84=-263.0,6.0,431.0") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(hermannskogel, "hermannskogel", bessel, "towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(ire65, "ire65", mod_airy, "towgs84=482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(nzgd49, "nzgd49", intl, "towgs84=59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993") -BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(OSGB36, "OSGB36", airy, "towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(WGS84, "WGS84", WGS84, "towgs84", "0,0,0") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(GGRS87, "GGRS87", GRS80, "towgs84", "-199.87,74.79,246.62") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAD83, "NAD83", GRS80, "towgs84", "0,0,0") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAD27, "NAD27", clrk66, "nadgrids", "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(potsdam, "potsdam", bessel, "towgs84", "598.1,73.7,418.2,0.202,0.045,-2.455,6.7") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(carthage, "carthage", clrk80ign, "towgs84", "-263.0,6.0,431.0") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(hermannskogel, "hermannskogel", bessel, "towgs84", "577.326,90.129,463.919,5.137,1.474,5.297,2.4232") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(ire65, "ire65", mod_airy, "towgs84", "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(nzgd49, "nzgd49", intl, "towgs84", "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993") +BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(OSGB36, "OSGB36", airy, "towgs84", "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894") template @@ -485,7 +487,7 @@ struct pick_o_proj_tag static const bool is_non_void = ! boost::is_void<proj_type>::value; - BOOST_MPL_ASSERT_MSG((is_non_void), PROJECTION_NOT_NAMED, (Tuple)); + BOOST_MPL_ASSERT_MSG((is_non_void), NO_O_PROJ_PARAMETER, (Tuple)); typedef typename proj_type::type type; }; diff --git a/boost/geometry/srs/projections/proj/aea.hpp b/boost/geometry/srs/projections/proj/aea.hpp index 1df5896c34..6deb9a8163 100644 --- a/boost/geometry/srs/projections/proj/aea.hpp +++ b/boost/geometry/srs/projections/proj/aea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_AEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_AEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,10 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 + // Author: Gerald Evenden (1995) + // Thomas Knudsen (2016) - revise/add regression tests + +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -45,6 +44,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_AEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_AEA_HPP + #include <boost/core/ignore_unused.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -74,11 +76,11 @@ namespace projections namespace detail { namespace aea { - static const double EPS10 = 1.e-10; - static const double TOL7 = 1.e-7; - static const double EPSILON = 1.0e-7; - static const double TOL = 1.0e-10; - static const int N_ITER = 15; + static const double epsilon10 = 1.e-10; + static const double tolerance7 = 1.e-7; + static const double epsilon = 1.0e-7; + static const double tolerance = 1.0e-10; + static const int n_iter = 15; template <typename T> struct par_aea @@ -91,7 +93,7 @@ namespace projections T rho0; T phi1; T phi2; - T en[EN_SIZE]; + detail::en<T> en; int ellips; }; @@ -103,9 +105,9 @@ namespace projections T Phi, sinpi, cospi, con, com, dphi; Phi = asin (.5 * qs); - if (Te < EPSILON) + if (Te < epsilon) return( Phi ); - i = N_ITER; + i = n_iter; do { sinpi = sin (Phi); cospi = cos (Phi); @@ -115,33 +117,30 @@ namespace projections sinpi / com + .5 / Te * log ((1. - con) / (1. + con))); Phi += dphi; - } while (fabs(dphi) > TOL && --i); + } while (fabs(dphi) > tolerance && --i); return( i ? Phi : HUGE_VAL ); } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_aea_ellipsoid : public base_t_fi<base_aea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_aea_ellipsoid + : public base_t_fi<base_aea_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aea<CalculationType> m_proj_parm; + par_aea<T> m_proj_parm; inline base_aea_ellipsoid(const Parameters& par) - : base_t_fi<base_aea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_aea_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid & spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType rho = 0.0; - if ((rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat), - this->m_par.e, this->m_par.one_es) : this->m_proj_parm.n2 * sin(lp_lat))) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + T rho = this->m_proj_parm.c - (this->m_proj_parm.ellips + ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) + : this->m_proj_parm.n2 * sin(lp_lat)); + if (rho < 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); rho = this->m_proj_parm.dd * sqrt(rho); xy_x = rho * sin( lp_lon *= this->m_proj_parm.n ); xy_y = this->m_proj_parm.rho0 - rho * cos(lp_lon); @@ -149,11 +148,11 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType rho = 0.0; + T rho = 0.0; if( (rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) { if (this->m_proj_parm.n < 0.) { rho = -rho; @@ -163,19 +162,19 @@ namespace projections lp_lat = rho / this->m_proj_parm.dd; if (this->m_proj_parm.ellips) { lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n; - if (fabs(this->m_proj_parm.ec - fabs(lp_lat)) > TOL7) { + if (fabs(this->m_proj_parm.ec - fabs(lp_lat)) > tolerance7) { if ((lp_lat = phi1_(lp_lat, this->m_par.e, this->m_par.one_es)) == HUGE_VAL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } else - lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + lp_lat = lp_lat < 0. ? -half_pi : half_pi; } else if (fabs(lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n2) <= 1.) lp_lat = asin(lp_lat); else - lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + lp_lat = lp_lat < 0. ? -half_pi : half_pi; lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; } else { lp_lon = 0.; - lp_lat = this->m_proj_parm.n > 0. ? HALFPI : - HALFPI; + lp_lat = this->m_proj_parm.n > 0. ? half_pi : - half_pi; } } @@ -192,16 +191,15 @@ namespace projections T cosphi, sinphi; int secant; - if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-21) ); + if (fabs(proj_parm.phi1 + proj_parm.phi2) < epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_conic_lat_equal) ); proj_parm.n = sinphi = sin(proj_parm.phi1); cosphi = cos(proj_parm.phi1); - secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10; + secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= epsilon10; if( (proj_parm.ellips = (par.es > 0.))) { T ml1, m1; - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.en = pj_enfn<T>(par.es); m1 = pj_msfn(sinphi, cosphi, par.es); ml1 = pj_qsfn(sinphi, par.e, par.one_es); if (secant) { /* secant cone */ @@ -211,6 +209,9 @@ namespace projections cosphi = cos(proj_parm.phi2); m2 = pj_msfn(sinphi, cosphi, par.es); ml2 = pj_qsfn(sinphi, par.e, par.one_es); + if (ml2 == ml1) + BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.n = (m1 * m1 - m2 * m2) / (ml2 - ml1); } proj_parm.ec = 1. - .5 * par.one_es * log((1. - par.e) / @@ -233,8 +234,8 @@ namespace projections template <typename Parameters, typename T> inline void setup_aea(Parameters& par, par_aea<T>& proj_parm) { - proj_parm.phi1 = pj_param(par.params, "rlat_1").f; - proj_parm.phi2 = pj_param(par.params, "rlat_2").f; + proj_parm.phi1 = pj_get_param_r(par.params, "lat_1"); + proj_parm.phi2 = pj_get_param_r(par.params, "lat_2"); setup(par, proj_parm); } @@ -242,10 +243,10 @@ namespace projections template <typename Parameters, typename T> inline void setup_leac(Parameters& par, par_aea<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); - proj_parm.phi2 = pj_param(par.params, "rlat_1").f; - proj_parm.phi1 = pj_param(par.params, "bsouth").i ? -HALFPI : HALFPI; + proj_parm.phi2 = pj_get_param_r(par.params, "lat_1"); + proj_parm.phi1 = pj_get_param_b(par.params, "south") ? -half_pi : half_pi; setup(par, proj_parm); } @@ -268,10 +269,10 @@ namespace projections \par Example \image html ex_aea.gif */ - template <typename CalculationType, typename Parameters> - struct aea_ellipsoid : public detail::aea::base_aea_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct aea_ellipsoid : public detail::aea::base_aea_ellipsoid<T, Parameters> { - inline aea_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<CalculationType, Parameters>(par) + inline aea_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<T, Parameters>(par) { detail::aea::setup_aea(this->m_par, this->m_proj_parm); } @@ -293,10 +294,10 @@ namespace projections \par Example \image html ex_leac.gif */ - template <typename CalculationType, typename Parameters> - struct leac_ellipsoid : public detail::aea::base_aea_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct leac_ellipsoid : public detail::aea::base_aea_ellipsoid<T, Parameters> { - inline leac_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<CalculationType, Parameters>(par) + inline leac_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<T, Parameters>(par) { detail::aea::setup_leac(this->m_par, this->m_proj_parm); } @@ -311,31 +312,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::leac, leac_ellipsoid, leac_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class aea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class aea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<aea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<aea_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class leac_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class leac_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<leac_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<leac_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void aea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void aea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("aea", new aea_entry<CalculationType, Parameters>); - factory.add_to_factory("leac", new leac_entry<CalculationType, Parameters>); + factory.add_to_factory("aea", new aea_entry<T, Parameters>); + factory.add_to_factory("leac", new leac_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/aeqd.hpp b/boost/geometry/srs/projections/proj/aeqd.hpp index de499213db..cfc6860797 100644 --- a/boost/geometry/srs/projections/proj/aeqd.hpp +++ b/boost/geometry/srs/projections/proj/aeqd.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP -#define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -45,7 +41,12 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP +#define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP + #include <boost/config.hpp> +#include <boost/geometry/formulas/vincenty_direct.hpp> +#include <boost/geometry/formulas/vincenty_inverse.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -76,66 +77,67 @@ namespace projections namespace detail { namespace aeqd { - static const double EPS10 = 1.e-10; - static const double TOL = 1.e-14; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + static const double epsilon10 = 1.e-10; + static const double tolerance = 1.e-14; + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_aeqd { T sinph0; T cosph0; - T en[EN_SIZE]; + detail::en<T> en; T M1; T N1; T Mp; T He; T G; - int mode; + mode_type mode; + srs::spheroid<T> spheroid; }; template <typename T, typename Par, typename ProjParm> inline void e_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& par, ProjParm const& proj_parm) { - T coslam, cosphi, sinphi, rho, s, H, H2, c, Az, t, ct, st, cA, sA; + T coslam, cosphi, sinphi, rho; + //T azi1, s12; + //T lam1, phi1, lam2, phi2; coslam = cos(lp_lon); cosphi = cos(lp_lat); sinphi = sin(lp_lat); switch (proj_parm.mode) { - case N_POLE: + case n_pole: coslam = - coslam; BOOST_FALLTHROUGH; - case S_POLE: + case s_pole: xy_x = (rho = fabs(proj_parm.Mp - pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en))) * sin(lp_lon); xy_y = rho * coslam; break; - case EQUIT: - case OBLIQ: - if (fabs(lp_lon) < EPS10 && fabs(lp_lat - par.phi0) < EPS10) { + case equit: + case obliq: + if (fabs(lp_lon) < epsilon10 && fabs(lp_lat - par.phi0) < epsilon10) { xy_x = xy_y = 0.; break; } - t = atan2(par.one_es * sinphi + par.es * proj_parm.N1 * proj_parm.sinph0 * - sqrt(1. - par.es * sinphi * sinphi), cosphi); - ct = cos(t); st = sin(t); - Az = atan2(sin(lp_lon) * ct, proj_parm.cosph0 * st - proj_parm.sinph0 * coslam * ct); - cA = cos(Az); sA = sin(Az); - s = aasin(fabs(sA) < TOL ? - (proj_parm.cosph0 * st - proj_parm.sinph0 * coslam * ct) / cA : - sin(lp_lon) * ct / sA ); - H = proj_parm.He * cA; - H2 = H * H; - c = proj_parm.N1 * s * (1. + s * s * (- H2 * (1. - H2)/6. + - s * ( proj_parm.G * H * (1. - 2. * H2 * H2) / 8. + - s * ((H2 * (4. - 7. * H2) - 3. * proj_parm.G * proj_parm.G * (1. - 7. * H2)) / - 120. - s * proj_parm.G * H / 48.)))); - xy_x = c * sA; - xy_y = c * cA; + + //phi1 = par.phi0; lam1 = par.lam0; + //phi2 = lp_lat; lam2 = lp_lon + par.lam0; + + formula::result_inverse<T> const inv = + formula::vincenty_inverse + < + T, true, true + >::apply(par.lam0, par.phi0, lp_lon + par.lam0, lp_lat, proj_parm.spheroid); + //azi1 = inv.azimuth; s12 = inv.distance; + xy_x = inv.distance * sin(inv.azimuth) / par.a; + xy_y = inv.distance * cos(inv.azimuth) / par.a; break; } } @@ -143,37 +145,32 @@ namespace projections template <typename T, typename Par, typename ProjParm> inline void e_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + T c; - T c, Az, cosAz, A, B, D, E, F, psi, t; - - if ((c = boost::math::hypot(xy_x, xy_y)) < EPS10) { + if ((c = boost::math::hypot(xy_x, xy_y)) < epsilon10) { lp_lat = par.phi0; lp_lon = 0.; return; } - if (proj_parm.mode == OBLIQ || proj_parm.mode == EQUIT) { - cosAz = cos(Az = atan2(xy_x, xy_y)); - t = proj_parm.cosph0 * cosAz; - B = par.es * t / par.one_es; - A = - B * t; - B *= 3. * (1. - A) * proj_parm.sinph0; - D = c / proj_parm.N1; - E = D * (1. - D * D * (A * (1. + A) / 6. + B * (1. + 3.*A) * D / 24.)); - F = 1. - E * E * (A / 2. + B * E / 6.); - psi = aasin(proj_parm.sinph0 * cos(E) + t * sin(E)); - lp_lon = aasin(sin(Az) * sin(E) / cos(psi)); - if ((t = fabs(psi)) < EPS10) - lp_lat = 0.; - else if (fabs(t - HALFPI) < 0.) - lp_lat = HALFPI; - else - lp_lat = atan((1. - par.es * F * proj_parm.sinph0 / sin(psi)) * tan(psi) / - par.one_es); + if (proj_parm.mode == obliq || proj_parm.mode == equit) { + T const x2 = xy_x * par.a; + T const y2 = xy_y * par.a; + //T const lat1 = par.phi0; + //T const lon1 = par.lam0; + T const azi1 = atan2(x2, y2); + T const s12 = sqrt(x2 * x2 + y2 * y2); + formula::result_direct<T> const dir = + formula::vincenty_direct + < + T, true + >::apply(par.lam0, par.phi0, s12, azi1, proj_parm.spheroid); + lp_lat = dir.lat2; + lp_lon = dir.lon2; + lp_lon -= par.lam0; } else { /* Polar */ - lp_lat = pj_inv_mlfn(proj_parm.mode == N_POLE ? proj_parm.Mp - c : proj_parm.Mp + c, + lp_lat = pj_inv_mlfn(proj_parm.mode == n_pole ? proj_parm.Mp - c : proj_parm.Mp + c, par.es, proj_parm.en); - lp_lon = atan2(xy_x, proj_parm.mode == N_POLE ? -xy_y : xy_y); + lp_lon = atan2(xy_x, proj_parm.mode == n_pole ? -xy_y : xy_y); } } @@ -193,7 +190,7 @@ namespace projections template <typename T, typename Par, typename ProjParm> inline void e_guam_inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) { - T x2, t; + T x2, t = 0.0; int i; x2 = 0.5 * xy_x * xy_x; @@ -209,7 +206,7 @@ namespace projections template <typename T, typename Par, typename ProjParm> inline void s_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& /*par*/, ProjParm const& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T coslam, cosphi, sinphi; @@ -217,33 +214,33 @@ namespace projections cosphi = cos(lp_lat); coslam = cos(lp_lon); switch (proj_parm.mode) { - case EQUIT: + case equit: xy_y = cosphi * coslam; goto oblcon; - case OBLIQ: + case obliq: xy_y = proj_parm.sinph0 * sinphi + proj_parm.cosph0 * cosphi * coslam; oblcon: - if (fabs(fabs(xy_y) - 1.) < TOL) + if (fabs(fabs(xy_y) - 1.) < tolerance) if (xy_y < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else xy_x = xy_y = 0.; else { xy_y = acos(xy_y); xy_y /= sin(xy_y); xy_x = xy_y * cosphi * sin(lp_lon); - xy_y *= (proj_parm.mode == EQUIT) ? sinphi : + xy_y *= (proj_parm.mode == equit) ? sinphi : proj_parm.cosph0 * sinphi - proj_parm.sinph0 * cosphi * coslam; } break; - case N_POLE: + case n_pole: lp_lat = -lp_lat; coslam = -coslam; BOOST_FALLTHROUGH; - case S_POLE: - if (fabs(lp_lat - HALFPI) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - xy_x = (xy_y = (HALFPI + lp_lat)) * sin(lp_lon); + case s_pole: + if (fabs(lp_lat - half_pi) < epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + xy_x = (xy_y = (half_pi + lp_lat)) * sin(lp_lon); xy_y *= coslam; break; } @@ -252,24 +249,24 @@ namespace projections template <typename T, typename Par, typename ProjParm> inline void s_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) { - static const T ONEPI = detail::ONEPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); T cosc, c_rh, sinc; - if ((c_rh = boost::math::hypot(xy_x, xy_y)) > ONEPI) { - if (c_rh - EPS10 > ONEPI) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - c_rh = ONEPI; - } else if (c_rh < EPS10) { + if ((c_rh = boost::math::hypot(xy_x, xy_y)) > pi) { + if (c_rh - epsilon10 > pi) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + c_rh = pi; + } else if (c_rh < epsilon10) { lp_lat = par.phi0; lp_lon = 0.; return; } - if (proj_parm.mode == OBLIQ || proj_parm.mode == EQUIT) { + if (proj_parm.mode == obliq || proj_parm.mode == equit) { sinc = sin(c_rh); cosc = cos(c_rh); - if (proj_parm.mode == EQUIT) { + if (proj_parm.mode == equit) { lp_lat = aasin(xy_y * sinc / c_rh); xy_x *= sinc; xy_y = cosc * c_rh; @@ -279,12 +276,12 @@ namespace projections xy_y = (cosc - proj_parm.sinph0 * sin(lp_lat)) * c_rh; xy_x *= sinc * proj_parm.cosph0; } - lp_lon = atan2(xy_x, xy_y); - } else if (proj_parm.mode == N_POLE) { - lp_lat = HALFPI - c_rh; + lp_lon = xy_y == 0. ? 0. : atan2(xy_x, xy_y); + } else if (proj_parm.mode == n_pole) { + lp_lat = half_pi - c_rh; lp_lon = atan2(xy_x, -xy_y); } else { - lp_lat = c_rh - HALFPI; + lp_lat = c_rh - half_pi; lp_lon = atan2(xy_x, xy_y); } } @@ -293,72 +290,71 @@ namespace projections template <typename Parameters, typename T> inline void setup_aeqd(Parameters& par, par_aeqd<T>& proj_parm, bool is_sphere, bool is_guam) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); - par.phi0 = pj_param(par.params, "rlat_0").f; - if (fabs(fabs(par.phi0) - HALFPI) < EPS10) { - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; + par.phi0 = pj_get_param_r(par.params, "lat_0"); + if (fabs(fabs(par.phi0) - half_pi) < epsilon10) { + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; proj_parm.sinph0 = par.phi0 < 0. ? -1. : 1.; proj_parm.cosph0 = 0.; - } else if (fabs(par.phi0) < EPS10) { - proj_parm.mode = EQUIT; + } else if (fabs(par.phi0) < epsilon10) { + proj_parm.mode = equit; proj_parm.sinph0 = 0.; proj_parm.cosph0 = 1.; } else { - proj_parm.mode = OBLIQ; + proj_parm.mode = obliq; proj_parm.sinph0 = sin(par.phi0); proj_parm.cosph0 = cos(par.phi0); } if (is_sphere) { + /* empty */ } else { - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.en = pj_enfn<T>(par.es); if (is_guam) { proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en); } else { switch (proj_parm.mode) { - case N_POLE: - proj_parm.Mp = pj_mlfn<T>(HALFPI, 1., 0., proj_parm.en); + case n_pole: + proj_parm.Mp = pj_mlfn<T>(half_pi, 1., 0., proj_parm.en); break; - case S_POLE: - proj_parm.Mp = pj_mlfn<T>(-HALFPI, -1., 0., proj_parm.en); + case s_pole: + proj_parm.Mp = pj_mlfn<T>(-half_pi, -1., 0., proj_parm.en); break; - case EQUIT: - case OBLIQ: + case equit: + case obliq: proj_parm.N1 = 1. / sqrt(1. - par.es * proj_parm.sinph0 * proj_parm.sinph0); proj_parm.G = proj_parm.sinph0 * (proj_parm.He = par.e / sqrt(par.one_es)); proj_parm.He *= proj_parm.cosph0; break; } + // Boost.Geometry specific, in proj4 geodesic is initialized at the beginning + T const b = math::sqrt(math::sqr(par.a) * (1. - par.es)); + proj_parm.spheroid = srs::spheroid<T>(par.a, b); } } } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_aeqd_e : public base_t_fi<base_aeqd_e<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_aeqd_e + : public base_t_fi<base_aeqd_e<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aeqd<CalculationType> m_proj_parm; + par_aeqd<T> m_proj_parm; inline base_aeqd_e(const Parameters& par) - : base_t_fi<base_aeqd_e<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_aeqd_e<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) elliptical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { e_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); } // INVERSE(e_inverse) elliptical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { e_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); } @@ -371,30 +367,26 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_aeqd_e_guam : public base_t_fi<base_aeqd_e_guam<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_aeqd_e_guam + : public base_t_fi<base_aeqd_e_guam<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aeqd<CalculationType> m_proj_parm; + par_aeqd<T> m_proj_parm; inline base_aeqd_e_guam(const Parameters& par) - : base_t_fi<base_aeqd_e_guam<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_aeqd_e_guam<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_guam_fwd) Guam elliptical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); } // INVERSE(e_guam_inv) Guam elliptical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); } @@ -407,15 +399,11 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename BGParameters, typename CalculationType, typename Parameters> - struct base_aeqd_e_static : public base_t_fi<base_aeqd_e_static<BGParameters, CalculationType, Parameters>, - CalculationType, Parameters> + template <typename BGParameters, typename T, typename Parameters> + struct base_aeqd_e_static + : public base_t_fi<base_aeqd_e_static<BGParameters, T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aeqd<CalculationType> m_proj_parm; + par_aeqd<T> m_proj_parm; static const bool is_guam = ! boost::is_same < @@ -429,13 +417,12 @@ namespace projections >::value; inline base_aeqd_e_static(const Parameters& par) - : base_t_fi<base_aeqd_e_static<BGParameters, CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) + : base_t_fi<base_aeqd_e_static<BGParameters, T, Parameters>, T, Parameters>(*this, par) {} // FORWARD(e_forward or e_guam_fwd) elliptical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { if (is_guam) e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); @@ -445,7 +432,7 @@ namespace projections // INVERSE(e_inverse or e_guam_inv) elliptical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { if (is_guam) e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); @@ -461,30 +448,26 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_aeqd_s : public base_t_fi<base_aeqd_s<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_aeqd_s + : public base_t_fi<base_aeqd_s<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aeqd<CalculationType> m_proj_parm; + par_aeqd<T> m_proj_parm; inline base_aeqd_s(const Parameters& par) - : base_t_fi<base_aeqd_s<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_aeqd_s<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spherical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { s_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); } // INVERSE(s_inverse) spherical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { s_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); } @@ -515,10 +498,10 @@ namespace projections \par Example \image html ex_aeqd.gif */ - template <typename CalculationType, typename Parameters> - struct aeqd_e : public detail::aeqd::base_aeqd_e<CalculationType, Parameters> + template <typename T, typename Parameters> + struct aeqd_e : public detail::aeqd::base_aeqd_e<T, Parameters> { - inline aeqd_e(const Parameters& par) : detail::aeqd::base_aeqd_e<CalculationType, Parameters>(par) + inline aeqd_e(const Parameters& par) : detail::aeqd::base_aeqd_e<T, Parameters>(par) { detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, false, false); } @@ -540,10 +523,10 @@ namespace projections \par Example \image html ex_aeqd.gif */ - template <typename CalculationType, typename Parameters> - struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam<CalculationType, Parameters> + template <typename T, typename Parameters> + struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam<T, Parameters> { - inline aeqd_e_guam(const Parameters& par) : detail::aeqd::base_aeqd_e_guam<CalculationType, Parameters>(par) + inline aeqd_e_guam(const Parameters& par) : detail::aeqd::base_aeqd_e_guam<T, Parameters>(par) { detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, false, true); } @@ -565,14 +548,14 @@ namespace projections \par Example \image html ex_aeqd.gif */ - template <typename BGParameters, typename CalculationType, typename Parameters> - struct aeqd_e_static : public detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters> + template <typename BGParameters, typename T, typename Parameters> + struct aeqd_e_static : public detail::aeqd::base_aeqd_e_static<BGParameters, T, Parameters> { - inline aeqd_e_static(const Parameters& par) : detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters>(par) + inline aeqd_e_static(const Parameters& par) : detail::aeqd::base_aeqd_e_static<BGParameters, T, Parameters>(par) { detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, false, - detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters>::is_guam); + detail::aeqd::base_aeqd_e_static<BGParameters, T, Parameters>::is_guam); } }; @@ -592,10 +575,10 @@ namespace projections \par Example \image html ex_aeqd.gif */ - template <typename CalculationType, typename Parameters> - struct aeqd_s : public detail::aeqd::base_aeqd_s<CalculationType, Parameters> + template <typename T, typename Parameters> + struct aeqd_s : public detail::aeqd::base_aeqd_s<T, Parameters> { - inline aeqd_s(const Parameters& par) : detail::aeqd::base_aeqd_s<CalculationType, Parameters>(par) + inline aeqd_s(const Parameters& par) : detail::aeqd::base_aeqd_s<T, Parameters>(par) { detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, true, false); } @@ -620,27 +603,27 @@ namespace projections //BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::aeqd_guam, aeqd_guam, aeqd_guam) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class aeqd_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class aeqd_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - bool const guam = pj_param(par.params, "bguam").i != 0; + bool const guam = pj_get_param_b(par.params, "guam"); if (par.es && ! guam) - return new base_v_fi<aeqd_e<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<aeqd_e<T, Parameters>, T, Parameters>(par); else if (par.es && guam) - return new base_v_fi<aeqd_e_guam<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<aeqd_e_guam<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<aeqd_s<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<aeqd_s<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void aeqd_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void aeqd_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("aeqd", new aeqd_entry<CalculationType, Parameters>); + factory.add_to_factory("aeqd", new aeqd_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/airy.hpp b/boost/geometry/srs/projections/proj/airy.hpp index 557d95f3e4..1762dec800 100644 --- a/boost/geometry/srs/projections/proj/airy.hpp +++ b/boost/geometry/srs/projections/proj/airy.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,12 +15,13 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Implementation of the airy (Airy) projection. -// Author: Gerald Evenden +// Author: Gerald Evenden (1995) +// Thomas Knudsen (2016) - revise/add regression tests // Copyright (c) 1995, Gerald Evenden // Permission is hereby granted, free of charge, to any person obtaining a @@ -45,6 +42,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -70,11 +70,13 @@ namespace projections namespace detail { namespace airy { - static const double EPS = 1.e-10; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + static const double epsilon = 1.e-10; + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_airy @@ -83,68 +85,65 @@ namespace projections T sinph0; T cosph0; T Cb; - int mode; + mode_type mode; int no_cut; /* do not cut at hemisphere limit */ }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_airy_spheroid : public base_t_f<base_airy_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_airy_spheroid + : public base_t_f<base_airy_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_airy<CalculationType> m_proj_parm; + par_airy<T> m_proj_parm; inline base_airy_spheroid(const Parameters& par) - : base_t_f<base_airy_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_airy_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz; + T sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz; sinlam = sin(lp_lon); coslam = cos(lp_lon); switch (this->m_proj_parm.mode) { - case EQUIT: - case OBLIQ: + case equit: + case obliq: sinphi = sin(lp_lat); cosphi = cos(lp_lat); cosz = cosphi * coslam; - if (this->m_proj_parm.mode == OBLIQ) + if (this->m_proj_parm.mode == obliq) cosz = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosz; - if (!this->m_proj_parm.no_cut && cosz < -EPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - if (fabs(s = 1. - cosz) > EPS) { + if (!this->m_proj_parm.no_cut && cosz < -epsilon) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + if (fabs(s = 1. - cosz) > epsilon) { t = 0.5 * (1. + cosz); Krho = -log(t)/s - this->m_proj_parm.Cb / t; } else Krho = 0.5 - this->m_proj_parm.Cb; xy_x = Krho * cosphi * sinlam; - if (this->m_proj_parm.mode == OBLIQ) + if (this->m_proj_parm.mode == obliq) xy_y = Krho * (this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam); else xy_y = Krho * sinphi; break; - case S_POLE: - case N_POLE: + case s_pole: + case n_pole: lp_lat = fabs(this->m_proj_parm.p_halfpi - lp_lat); - if (!this->m_proj_parm.no_cut && (lp_lat - EPS) > HALFPI) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - if ((lp_lat *= 0.5) > EPS) { + if (!this->m_proj_parm.no_cut && (lp_lat - epsilon) > half_pi) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + if ((lp_lat *= 0.5) > epsilon) { t = tan(lp_lat); Krho = -2.*(log(cos(lp_lat)) / t + t * this->m_proj_parm.Cb); xy_x = Krho * sinlam; xy_y = Krho * coslam; - if (this->m_proj_parm.mode == N_POLE) + if (this->m_proj_parm.mode == n_pole) xy_y = -xy_y; } else xy_x = xy_y = 0.; @@ -162,31 +161,32 @@ namespace projections template <typename Parameters, typename T> inline void setup_airy(Parameters& par, par_airy<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T beta; - proj_parm.no_cut = pj_param(par.params, "bno_cut").i; - beta = 0.5 * (HALFPI - pj_param(par.params, "rlat_b").f); - if (fabs(beta) < EPS) + proj_parm.no_cut = pj_get_param_b(par.params, "no_cut"); + beta = 0.5 * (half_pi - pj_get_param_r(par.params, "lat_b")); + if (fabs(beta) < epsilon) proj_parm.Cb = -0.5; else { proj_parm.Cb = 1./tan(beta); proj_parm.Cb *= proj_parm.Cb * log(cos(beta)); } - if (fabs(fabs(par.phi0) - HALFPI) < EPS) + + if (fabs(fabs(par.phi0) - half_pi) < epsilon) if (par.phi0 < 0.) { - proj_parm.p_halfpi = -HALFPI; - proj_parm.mode = S_POLE; + proj_parm.p_halfpi = -half_pi; + proj_parm.mode = s_pole; } else { - proj_parm.p_halfpi = HALFPI; - proj_parm.mode = N_POLE; + proj_parm.p_halfpi = half_pi; + proj_parm.mode = n_pole; } else { - if (fabs(par.phi0) < EPS) - proj_parm.mode = EQUIT; + if (fabs(par.phi0) < epsilon) + proj_parm.mode = equit; else { - proj_parm.mode = OBLIQ; + proj_parm.mode = obliq; proj_parm.sinph0 = sin(par.phi0); proj_parm.cosph0 = cos(par.phi0); } @@ -213,10 +213,10 @@ namespace projections \par Example \image html ex_airy.gif */ - template <typename CalculationType, typename Parameters> - struct airy_spheroid : public detail::airy::base_airy_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct airy_spheroid : public detail::airy::base_airy_spheroid<T, Parameters> { - inline airy_spheroid(const Parameters& par) : detail::airy::base_airy_spheroid<CalculationType, Parameters>(par) + inline airy_spheroid(const Parameters& par) : detail::airy::base_airy_spheroid<T, Parameters>(par) { detail::airy::setup_airy(this->m_par, this->m_proj_parm); } @@ -230,20 +230,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::airy, airy_spheroid, airy_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class airy_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class airy_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<airy_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<airy_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void airy_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void airy_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("airy", new airy_entry<CalculationType, Parameters>); + factory.add_to_factory("airy", new airy_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/aitoff.hpp b/boost/geometry/srs/projections/proj/aitoff.hpp index 7d34a23287..c09618d45e 100644 --- a/boost/geometry/srs/projections/proj/aitoff.hpp +++ b/boost/geometry/srs/projections/proj/aitoff.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP -#define BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,13 +15,15 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Implementation of the aitoff (Aitoff) and wintri (Winkel Tripel) -// projections. -// Author: Gerald Evenden +// projections. +// Author: Gerald Evenden (1995) +// Drazen Tutic, Lovro Gradiser (2015) - add inverse +// Thomas Knudsen (2016) - revise/add regression tests // Copyright (c) 1995, Gerald Evenden // Permission is hereby granted, free of charge, to any person obtaining a @@ -46,6 +44,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP +#define BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP + + #include <boost/core/ignore_unused.hpp> #include <boost/geometry/util/math.hpp> @@ -69,40 +71,41 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace aitoff { + enum mode_type { + mode_aitoff = 0, + mode_winkel_tripel = 1 + }; + template <typename T> struct par_aitoff { T cosphi1; - int mode; + mode_type mode; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_aitoff_spheroid : public base_t_fi<base_aitoff_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_aitoff_spheroid + : public base_t_fi<base_aitoff_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_aitoff<CalculationType> m_proj_parm; + par_aitoff<T> m_proj_parm; inline base_aitoff_spheroid(const Parameters& par) - : base_t_fi<base_aitoff_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_aitoff_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType c, d; + T c, d; if((d = acos(cos(lp_lat) * cos(c = 0.5 * lp_lon)))) {/* basic Aitoff */ xy_x = 2. * d * cos(lp_lat) * sin(c) * (xy_y = 1. / sin(d)); xy_y *= d * sin(lp_lat); } else xy_x = xy_y = 0.; - if (this->m_proj_parm.mode) { /* Winkel Tripel */ + if (this->m_proj_parm.mode == mode_winkel_tripel) { /* Winkel Tripel */ xy_x = (xy_x + lp_lon * this->m_proj_parm.cosphi1) * 0.5; xy_y = (xy_y + lp_lat) * 0.5; } @@ -116,7 +119,7 @@ namespace projections * Third International Symposium Mathematical & Computational Applications, * pages 175{182, Turkey, September 2002. * - * Expected accuracy is defined by EPSILON = 1e-12. Should be appropriate for + * Expected accuracy is defined by epsilon = 1e-12. Should be appropriate for * most applications of Aitoff and Winkel Tripel projections. * * Longitudes of 180W and 180E can be mixed in solution obtained. @@ -130,16 +133,19 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - static const CalculationType TWOPI = detail::TWOPI<CalculationType>(); - static const CalculationType EPSILON = 1e-12; + static const T pi = detail::pi<T>(); + static const T two_pi = detail::two_pi<T>(); + static const T epsilon = 1e-12; - int iter, MAXITER = 10, round = 0, MAXROUND = 20; - CalculationType D, C, f1, f2, f1p, f1l, f2p, f2l, dp, dl, sl, sp, cp, cl, x, y; + int iter, max_iter = 10, round = 0, max_round = 20; + T D, C, f1, f2, f1p, f1l, f2p, f2l, dp, dl, sl, sp, cp, cl, x, y; - if ((fabs(xy_x) < EPSILON) && (fabs(xy_y) < EPSILON )) { lp_lat = 0.; lp_lon = 0.; return; } + if ((fabs(xy_x) < epsilon) && (fabs(xy_y) < epsilon )) { + lp_lat = 0.; lp_lon = 0.; + return; + } /* intial values for Newton-Raphson method */ lp_lat = xy_y; lp_lon = xy_x; @@ -149,15 +155,15 @@ namespace projections sl = sin(lp_lon * 0.5); cl = cos(lp_lon * 0.5); sp = sin(lp_lat); cp = cos(lp_lat); D = cp * cl; - C = 1. - D * D; - D = acos(D) / pow(C, 1.5); - f1 = 2. * D * C * cp * sl; - f2 = D * C * sp; - f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl); - f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp; - f2p = sp * sp * cl / C + D * sl * sl * cp; - f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl); - if (this->m_proj_parm.mode) { /* Winkel Tripel */ + C = 1. - D * D; + D = acos(D) / math::pow(C, T(1.5)); + f1 = 2. * D * C * cp * sl; + f2 = D * C * sp; + f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl); + f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp; + f2p = sp * sp * cl / C + D * sl * sl * cp; + f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl); + if (this->m_proj_parm.mode == mode_winkel_tripel) { /* Winkel Tripel */ f1 = 0.5 * (f1 + lp_lon * this->m_proj_parm.cosphi1); f2 = 0.5 * (f2 + lp_lat); f1p *= 0.5; @@ -168,28 +174,31 @@ namespace projections f1 -= xy_x; f2 -= xy_y; dl = (f2 * f1p - f1 * f2p) / (dp = f1p * f2l - f2p * f1l); dp = (f1 * f2l - f2 * f1l) / dp; - while (dl > ONEPI) dl -= ONEPI; /* set to interval [-ONEPI, ONEPI] */ - while (dl < -ONEPI) dl += ONEPI; /* set to interval [-ONEPI, ONEPI] */ + dl = fmod(dl, pi); /* set to interval [-M_PI, M_PI] */ lp_lat -= dp; lp_lon -= dl; - } while ((fabs(dp) > EPSILON || fabs(dl) > EPSILON) && (iter++ < MAXITER)); - if (lp_lat > TWOPI) lp_lat -= 2.*(lp_lat-TWOPI); /* correct if symmetrical solution for Aitoff */ - if (lp_lat < -TWOPI) lp_lat -= 2.*(lp_lat+TWOPI); /* correct if symmetrical solution for Aitoff */ - if ((fabs(fabs(lp_lat) - TWOPI) < EPSILON) && (!this->m_proj_parm.mode)) lp_lon = 0.; /* if pole in Aitoff, return longitude of 0 */ + } while ((fabs(dp) > epsilon || fabs(dl) > epsilon) && (iter++ < max_iter)); + if (lp_lat > two_pi) lp_lat -= 2.*(lp_lat-two_pi); /* correct if symmetrical solution for Aitoff */ + if (lp_lat < -two_pi) lp_lat -= 2.*(lp_lat+two_pi); /* correct if symmetrical solution for Aitoff */ + if ((fabs(fabs(lp_lat) - two_pi) < epsilon) && (!this->m_proj_parm.mode)) lp_lon = 0.; /* if pole in Aitoff, return longitude of 0 */ /* calculate x,y coordinates with solution obtained */ - if((D = acos(cos(lp_lat) * cos(C = 0.5 * lp_lon)))) {/* Aitoff */ + if((D = acos(cos(lp_lat) * cos(C = 0.5 * lp_lon))) != 0.0) {/* Aitoff */ x = 2. * D * cos(lp_lat) * sin(C) * (y = 1. / sin(D)); y *= D * sin(lp_lat); } else x = y = 0.; - if (this->m_proj_parm.mode) { /* Winkel Tripel */ + if (this->m_proj_parm.mode == mode_winkel_tripel) { /* Winkel Tripel */ x = (x + lp_lon * this->m_proj_parm.cosphi1) * 0.5; y = (y + lp_lat) * 0.5; } /* if too far from given values of x,y, repeat with better approximation of phi,lam */ - } while (((fabs(xy_x-x) > EPSILON) || (fabs(xy_y-y) > EPSILON)) && (round++ < MAXROUND)); + } while (((fabs(xy_x-x) > epsilon) || (fabs(xy_y-y) > epsilon)) && (round++ < max_round)); - //if (iter == MAXITER && round == MAXROUND) fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); + if (iter == max_iter && round == max_round) + { + BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) ); + //fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); + } } static inline std::string get_name() @@ -199,10 +208,9 @@ namespace projections }; - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_aitoff<T>& proj_parm) + template <typename Parameters> + inline void setup(Parameters& par) { - boost::ignore_unused(proj_parm); par.es = 0.; } @@ -211,23 +219,25 @@ namespace projections template <typename Parameters, typename T> inline void setup_aitoff(Parameters& par, par_aitoff<T>& proj_parm) { - proj_parm.mode = 0; - setup(par, proj_parm); + proj_parm.mode = mode_aitoff; + setup(par); } // Winkel Tripel template <typename Parameters, typename T> inline void setup_wintri(Parameters& par, par_aitoff<T>& proj_parm) { - static const T TWO_D_PI = detail::TWO_D_PI<T>(); + static const T two_div_pi = detail::two_div_pi<T>(); + + T phi1; - proj_parm.mode = 1; - if (pj_param(par.params, "tlat_1").i) { - if ((proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f)) == 0.) - BOOST_THROW_EXCEPTION( projection_exception(-22) ); + proj_parm.mode = mode_winkel_tripel; + if (pj_param_r(par.params, "lat_1", phi1)) { + if ((proj_parm.cosphi1 = cos(phi1)) == 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_larger_than_90) ); } else /* 50d28' or phi1=acos(2/pi) */ - proj_parm.cosphi1 = TWO_D_PI; - setup(par, proj_parm); + proj_parm.cosphi1 = two_div_pi; + setup(par); } }} // namespace detail::aitoff @@ -245,10 +255,10 @@ namespace projections \par Example \image html ex_aitoff.gif */ - template <typename CalculationType, typename Parameters> - struct aitoff_spheroid : public detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct aitoff_spheroid : public detail::aitoff::base_aitoff_spheroid<T, Parameters> { - inline aitoff_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>(par) + inline aitoff_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<T, Parameters>(par) { detail::aitoff::setup_aitoff(this->m_par, this->m_proj_parm); } @@ -268,10 +278,10 @@ namespace projections \par Example \image html ex_wintri.gif */ - template <typename CalculationType, typename Parameters> - struct wintri_spheroid : public detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wintri_spheroid : public detail::aitoff::base_aitoff_spheroid<T, Parameters> { - inline wintri_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>(par) + inline wintri_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<T, Parameters>(par) { detail::aitoff::setup_wintri(this->m_par, this->m_proj_parm); } @@ -286,31 +296,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wintri, wintri_spheroid, wintri_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class aitoff_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class aitoff_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<aitoff_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<aitoff_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class wintri_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wintri_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wintri_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wintri_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void aitoff_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void aitoff_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("aitoff", new aitoff_entry<CalculationType, Parameters>); - factory.add_to_factory("wintri", new wintri_entry<CalculationType, Parameters>); + factory.add_to_factory("aitoff", new aitoff_entry<T, Parameters>); + factory.add_to_factory("wintri", new wintri_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/august.hpp b/boost/geometry/srs/projections/proj/august.hpp index 7358cfb12f..a52edc7806 100644 --- a/boost/geometry/srs/projections/proj/august.hpp +++ b/boost/geometry/srs/projections/proj/august.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP -#define BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP +#define BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -64,26 +63,21 @@ namespace projections //static const double M = 1.333333333333333; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_august_spheroid : public base_t_f<base_august_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_august_spheroid + : public base_t_f<base_august_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_august_spheroid(const Parameters& par) - : base_t_f<base_august_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_august_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType M = 1.333333333333333333333333333333333333; + static const T M = 1.333333333333333333333333333333333333; - CalculationType t, c1, c, x1, x12, y1, y12; + T t, c1, c, x1, x12, y1, y12; t = tan(.5 * lp_lat); c1 = sqrt(1. - t * t); @@ -124,10 +118,10 @@ namespace projections \par Example \image html ex_august.gif */ - template <typename CalculationType, typename Parameters> - struct august_spheroid : public detail::august::base_august_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct august_spheroid : public detail::august::base_august_spheroid<T, Parameters> { - inline august_spheroid(const Parameters& par) : detail::august::base_august_spheroid<CalculationType, Parameters>(par) + inline august_spheroid(const Parameters& par) : detail::august::base_august_spheroid<T, Parameters>(par) { detail::august::setup_august(this->m_par); } @@ -141,20 +135,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::august, august_spheroid, august_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class august_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class august_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<august_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<august_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void august_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void august_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("august", new august_entry<CalculationType, Parameters>); + factory.add_to_factory("august", new august_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/bacon.hpp b/boost/geometry/srs/projections/proj/bacon.hpp index 5e8d37980f..d82e30aa1f 100644 --- a/boost/geometry/srs/projections/proj/bacon.hpp +++ b/boost/geometry/srs/projections/proj/bacon.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_BACON_HPP -#define BOOST_GEOMETRY_PROJECTIONS_BACON_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_BACON_HPP +#define BOOST_GEOMETRY_PROJECTIONS_BACON_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -65,8 +64,8 @@ namespace projections namespace detail { namespace bacon { - //static const double HLFPI2 = 2.46740110027233965467; - static const double EPS = 1e-10; + //static const double half_pi_sqr = 2.46740110027233965467; + static const double epsilon = 1e-10; struct par_bacon { @@ -75,35 +74,31 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_bacon_spheroid : public base_t_f<base_bacon_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_bacon_spheroid + : public base_t_f<base_bacon_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - par_bacon m_proj_parm; inline base_bacon_spheroid(const Parameters& par) - : base_t_f<base_bacon_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_bacon_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType HLFPI2 = detail::HALFPI_SQR<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T half_pi_sqr = detail::half_pi_sqr<T>(); - CalculationType ax, f; + T ax, f; - xy_y = this->m_proj_parm.bacn ? HALFPI * sin(lp_lat) : lp_lat; - if ((ax = fabs(lp_lon)) >= EPS) { - if (this->m_proj_parm.ortl && ax >= HALFPI) - xy_x = sqrt(HLFPI2 - lp_lat * lp_lat + EPS) + ax - HALFPI; + xy_y = this->m_proj_parm.bacn ? half_pi * sin(lp_lat) : lp_lat; + if ((ax = fabs(lp_lon)) >= epsilon) { + if (this->m_proj_parm.ortl && ax >= half_pi) + xy_x = sqrt(half_pi_sqr - lp_lat * lp_lat + epsilon) + ax - half_pi; else { - f = 0.5 * (HLFPI2 / ax + ax); + f = 0.5 * (half_pi_sqr / ax + ax); xy_x = ax - f + sqrt(f * f - xy_y * xy_y); } if (lp_lon < 0.) xy_x = - xy_x; @@ -160,10 +155,10 @@ namespace projections \par Example \image html ex_apian.gif */ - template <typename CalculationType, typename Parameters> - struct apian_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct apian_spheroid : public detail::bacon::base_bacon_spheroid<T, Parameters> { - inline apian_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par) + inline apian_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<T, Parameters>(par) { detail::bacon::setup_apian(this->m_par, this->m_proj_parm); } @@ -182,10 +177,10 @@ namespace projections \par Example \image html ex_ortel.gif */ - template <typename CalculationType, typename Parameters> - struct ortel_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ortel_spheroid : public detail::bacon::base_bacon_spheroid<T, Parameters> { - inline ortel_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par) + inline ortel_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<T, Parameters>(par) { detail::bacon::setup_ortel(this->m_par, this->m_proj_parm); } @@ -204,10 +199,10 @@ namespace projections \par Example \image html ex_bacon.gif */ - template <typename CalculationType, typename Parameters> - struct bacon_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct bacon_spheroid : public detail::bacon::base_bacon_spheroid<T, Parameters> { - inline bacon_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par) + inline bacon_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<T, Parameters>(par) { detail::bacon::setup_bacon(this->m_par, this->m_proj_parm); } @@ -223,42 +218,42 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ortel, ortel_spheroid, ortel_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class apian_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class apian_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<apian_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<apian_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class ortel_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class ortel_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<ortel_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<ortel_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class bacon_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class bacon_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<bacon_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<bacon_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void bacon_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void bacon_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("apian", new apian_entry<CalculationType, Parameters>); - factory.add_to_factory("ortel", new ortel_entry<CalculationType, Parameters>); - factory.add_to_factory("bacon", new bacon_entry<CalculationType, Parameters>); + factory.add_to_factory("apian", new apian_entry<T, Parameters>); + factory.add_to_factory("ortel", new ortel_entry<T, Parameters>); + factory.add_to_factory("bacon", new bacon_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/bipc.hpp b/boost/geometry/srs/projections/proj/bipc.hpp index 6f014d0e66..02af27ff62 100644 --- a/boost/geometry/srs/projections/proj/bipc.hpp +++ b/boost/geometry/srs/projections/proj/bipc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -64,16 +63,16 @@ namespace projections namespace detail { namespace bipc { - static const double EPS = 1e-10; - static const double EPS10 = 1e-10; - static const double ONEEPS = 1.000000001; - static const int NITER = 10; + static const double epsilon = 1e-10; + static const double epsilon10 = 1e-10; + static const double one_plus_eps = 1.000000001; + static const int n_iter = 10; static const double lamB = -.34894976726250681539; static const double n = .63055844881274687180; static const double F = 1.89724742567461030582; static const double Azab = .81650043674686363166; static const double Azba = 1.82261843856185925133; - static const double T = 1.27246578267089012270; + static const double const_T = 1.27246578267089012270; static const double rhoc = 1.20709121521568721927; static const double cAzc = .69691523038678375519; static const double sAzc = .71715351331143607555; @@ -90,36 +89,32 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_bipc_spheroid : public base_t_fi<base_bipc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_bipc_spheroid + : public base_t_fi<base_bipc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - par_bipc m_proj_parm; inline base_bipc_spheroid(const Parameters& par) - : base_t_fi<base_bipc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_bipc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); - CalculationType cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r; + T cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r; int tag; cphi = cos(lp_lat); sphi = sin(lp_lat); cdlam = cos(sdlam = lamB - lp_lon); sdlam = sin(sdlam); - if (fabs(fabs(lp_lat) - HALFPI) < EPS10) { - Az = lp_lat < 0. ? ONEPI : 0.; + if (fabs(fabs(lp_lat) - half_pi) < epsilon10) { + Az = lp_lat < 0. ? pi : 0.; tphi = HUGE_VAL; } else { tphi = sphi / cphi; @@ -130,8 +125,8 @@ namespace projections sdlam = sin(sdlam); z = S20 * sphi + C20 * cphi * cdlam; if (fabs(z) > 1.) { - if (fabs(z) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(z) > one_plus_eps) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else z = z < 0. ? -1. : 1.; } else @@ -143,8 +138,8 @@ namespace projections } else { z = S45 * (sphi + cphi * cdlam); if (fabs(z) > 1.) { - if (fabs(z) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(z) > one_plus_eps) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else z = z < 0. ? -1. : 1.; } else @@ -152,14 +147,17 @@ namespace projections Av = Azba; xy_y = -rhoc; } - if (z < 0.) BOOST_THROW_EXCEPTION( projection_exception(-20) ); - r = F * (t = pow(tan(.5 * z), n)); - if ((al = .5 * (R104 - z)) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - al = (t + pow(al, n)) / T; + if (z < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + r = F * (t = math::pow(tan(T(0.5) * z), n)); + if ((al = .5 * (R104 - z)) < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + al = (t + math::pow(al, n)) / const_T; if (fabs(al) > 1.) { - if (fabs(al) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(al) > one_plus_eps) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else al = al < 0. ? -1. : 1.; } else @@ -177,9 +175,9 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType t, r, rp, rl, al, z, fAz, Az, s, c, Av; + T t, r, rp, rl, al, z, fAz, Az, s, c, Av; int neg, i; if (this->m_proj_parm.noskew) { @@ -200,18 +198,18 @@ namespace projections } rl = rp = r = boost::math::hypot(xy_x, xy_y); fAz = fabs(Az = atan2(xy_x, xy_y)); - for (i = NITER; i ; --i) { - z = 2. * atan(pow(r / F,1 / n)); - al = acos((pow(tan(.5 * z), n) + - pow(tan(.5 * (R104 - z)), n)) / T); + for (i = n_iter; i ; --i) { + z = 2. * atan(math::pow(r / F,T(1) / n)); + al = acos((math::pow(tan(T(0.5) * z), n) + + math::pow(tan(T(0.5) * (R104 - z)), n)) / const_T); if (fAz < al) r = rp * cos(al + (neg ? Az : -Az)); - if (fabs(rl - r) < EPS) + if (fabs(rl - r) < epsilon) break; rl = r; } if (! i) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); Az = Av - Az / n; lp_lat = asin(s * cos(z) + c * sin(z) * cos(Az)); lp_lon = atan2(sin(Az), c / tan(z) - s * cos(Az)); @@ -232,7 +230,7 @@ namespace projections template <typename Parameters> inline void setup_bipc(Parameters& par, par_bipc& proj_parm) { - proj_parm.noskew = pj_param(par.params, "bns").i; + proj_parm.noskew = pj_get_param_b(par.params, "ns"); par.es = 0.; } @@ -253,10 +251,10 @@ namespace projections \par Example \image html ex_bipc.gif */ - template <typename CalculationType, typename Parameters> - struct bipc_spheroid : public detail::bipc::base_bipc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct bipc_spheroid : public detail::bipc::base_bipc_spheroid<T, Parameters> { - inline bipc_spheroid(const Parameters& par) : detail::bipc::base_bipc_spheroid<CalculationType, Parameters>(par) + inline bipc_spheroid(const Parameters& par) : detail::bipc::base_bipc_spheroid<T, Parameters>(par) { detail::bipc::setup_bipc(this->m_par, this->m_proj_parm); } @@ -270,20 +268,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::bipc, bipc_spheroid, bipc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class bipc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class bipc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<bipc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<bipc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void bipc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void bipc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("bipc", new bipc_entry<CalculationType, Parameters>); + factory.add_to_factory("bipc", new bipc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/boggs.hpp b/boost/geometry/srs/projections/proj/boggs.hpp index 6c371e430f..c3c043faab 100644 --- a/boost/geometry/srs/projections/proj/boggs.hpp +++ b/boost/geometry/srs/projections/proj/boggs.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -63,52 +62,46 @@ namespace projections namespace detail { namespace boggs { - static const int NITER = 20; - static const double EPS = 1e-7; - static const double ONETOL = 1.000001; + static const int n_iter = 20; + static const double epsilon = 1e-7; static const double FXC = 2.00276; static const double FXC2 = 1.11072; static const double FYC = 0.49931; - static const double FYC2 = 1.41421356237309504880; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_boggs_spheroid : public base_t_f<base_boggs_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_boggs_spheroid + : public base_t_f<base_boggs_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_boggs_spheroid(const Parameters& par) - : base_t_f<base_boggs_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_boggs_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); + static const T root_two = boost::math::constants::root_two<T>(); - CalculationType theta, th1, c; + T theta, th1, c; int i; theta = lp_lat; - if (fabs(fabs(lp_lat) - HALFPI) < EPS) + if (fabs(fabs(lp_lat) - half_pi) < epsilon) xy_x = 0.; else { - c = sin(theta) * ONEPI; - for (i = NITER; i; --i) { + c = sin(theta) * pi; + for (i = n_iter; i; --i) { theta -= th1 = (theta + sin(theta) - c) / (1. + cos(theta)); - if (fabs(th1) < EPS) break; + if (fabs(th1) < epsilon) break; } theta *= 0.5; xy_x = FXC * lp_lon / (1. / cos(lp_lat) + FXC2 / cos(theta)); } - xy_y = FYC * (lp_lat + FYC2 * sin(theta)); + xy_y = FYC * (lp_lat + root_two * sin(theta)); } static inline std::string get_name() @@ -141,10 +134,10 @@ namespace projections \par Example \image html ex_boggs.gif */ - template <typename CalculationType, typename Parameters> - struct boggs_spheroid : public detail::boggs::base_boggs_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct boggs_spheroid : public detail::boggs::base_boggs_spheroid<T, Parameters> { - inline boggs_spheroid(const Parameters& par) : detail::boggs::base_boggs_spheroid<CalculationType, Parameters>(par) + inline boggs_spheroid(const Parameters& par) : detail::boggs::base_boggs_spheroid<T, Parameters>(par) { detail::boggs::setup_boggs(this->m_par); } @@ -158,20 +151,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::boggs, boggs_spheroid, boggs_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class boggs_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class boggs_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<boggs_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<boggs_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void boggs_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void boggs_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("boggs", new boggs_entry<CalculationType, Parameters>); + factory.add_to_factory("boggs", new boggs_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/bonne.hpp b/boost/geometry/srs/projections/proj/bonne.hpp index 52120a905f..3699537721 100644 --- a/boost/geometry/srs/projections/proj/bonne.hpp +++ b/boost/geometry/srs/projections/proj/bonne.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP -#define BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP +#define BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -65,7 +64,7 @@ namespace projections namespace detail { namespace bonne { - static const double EPS10 = 1e-10; + static const double epsilon10 = 1e-10; template <typename T> struct par_bonne @@ -74,29 +73,25 @@ namespace projections T cphi1; T am1; T m1; - T en[EN_SIZE]; + detail::en<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_bonne_ellipsoid : public base_t_fi<base_bonne_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_bonne_ellipsoid + : public base_t_fi<base_bonne_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_bonne<CalculationType> m_proj_parm; + par_bonne<T> m_proj_parm; inline base_bonne_ellipsoid(const Parameters& par) - : base_t_fi<base_bonne_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_bonne_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType rh, E, c; + T rh, E, c; rh = this->m_proj_parm.am1 + this->m_proj_parm.m1 - pj_mlfn(lp_lat, E = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en); E = c * lp_lon / (rh * sqrt(1. - this->m_par.es * E * E)); @@ -106,22 +101,22 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType s, rh; + T s, rh; rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.am1 - xy_y); lp_lat = pj_inv_mlfn(this->m_proj_parm.am1 + this->m_proj_parm.m1 - rh, this->m_par.es, this->m_proj_parm.en); - if ((s = fabs(lp_lat)) < HALFPI) { + if ((s = fabs(lp_lat)) < half_pi) { s = sin(lp_lat); lp_lon = rh * atan2(xy_x, xy_y) * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat); - } else if (fabs(s - HALFPI) <= EPS10) + } else if (fabs(s - half_pi) <= epsilon10) lp_lon = 0.; else - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } static inline std::string get_name() @@ -132,28 +127,24 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_bonne_spheroid : public base_t_fi<base_bonne_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_bonne_spheroid + : public base_t_fi<base_bonne_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_bonne<CalculationType> m_proj_parm; + par_bonne<T> m_proj_parm; inline base_bonne_spheroid(const Parameters& par) - : base_t_fi<base_bonne_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_bonne_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType E, rh; + T E, rh; rh = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - lp_lat; - if (fabs(rh) > EPS10) { + if (fabs(rh) > epsilon10) { xy_x = rh * sin(E = lp_lon * cos(lp_lat) / rh); xy_y = this->m_proj_parm.cphi1 - rh * cos(E); } else @@ -162,17 +153,18 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType rh; + T rh; rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.cphi1 - xy_y); lp_lat = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - rh; - if (fabs(lp_lat) > HALFPI) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) + if (fabs(lp_lat) > half_pi) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) lp_lon = 0.; else lp_lon = rh * atan2(xy_x, xy_y) / cos(lp_lat); @@ -189,20 +181,21 @@ namespace projections template <typename Parameters, typename T> inline void setup_bonne(Parameters& par, par_bonne<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T c; - proj_parm.phi1 = pj_param(par.params, "rlat_1").f; - if (fabs(proj_parm.phi1) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-23) ); - if (par.es) { - pj_enfn(par.es, proj_parm.en); + proj_parm.phi1 = pj_get_param_r(par.params, "lat_1"); + if (fabs(proj_parm.phi1) < epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_lat1_is_zero) ); + + if (par.es != 0.0) { + proj_parm.en = pj_enfn<T>(par.es); proj_parm.m1 = pj_mlfn(proj_parm.phi1, proj_parm.am1 = sin(proj_parm.phi1), c = cos(proj_parm.phi1), proj_parm.en); proj_parm.am1 = c / (sqrt(1. - par.es * proj_parm.am1 * proj_parm.am1) * proj_parm.am1); } else { - if (fabs(proj_parm.phi1) + EPS10 >= HALFPI) + if (fabs(proj_parm.phi1) + epsilon10 >= half_pi) proj_parm.cphi1 = 0.; else proj_parm.cphi1 = 1. / tan(proj_parm.phi1); @@ -227,10 +220,10 @@ namespace projections \par Example \image html ex_bonne.gif */ - template <typename CalculationType, typename Parameters> - struct bonne_ellipsoid : public detail::bonne::base_bonne_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct bonne_ellipsoid : public detail::bonne::base_bonne_ellipsoid<T, Parameters> { - inline bonne_ellipsoid(const Parameters& par) : detail::bonne::base_bonne_ellipsoid<CalculationType, Parameters>(par) + inline bonne_ellipsoid(const Parameters& par) : detail::bonne::base_bonne_ellipsoid<T, Parameters>(par) { detail::bonne::setup_bonne(this->m_par, this->m_proj_parm); } @@ -251,10 +244,10 @@ namespace projections \par Example \image html ex_bonne.gif */ - template <typename CalculationType, typename Parameters> - struct bonne_spheroid : public detail::bonne::base_bonne_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct bonne_spheroid : public detail::bonne::base_bonne_spheroid<T, Parameters> { - inline bonne_spheroid(const Parameters& par) : detail::bonne::base_bonne_spheroid<CalculationType, Parameters>(par) + inline bonne_spheroid(const Parameters& par) : detail::bonne::base_bonne_spheroid<T, Parameters>(par) { detail::bonne::setup_bonne(this->m_par, this->m_proj_parm); } @@ -268,23 +261,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::bonne, bonne_spheroid, bonne_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class bonne_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class bonne_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<bonne_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<bonne_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<bonne_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<bonne_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void bonne_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void bonne_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("bonne", new bonne_entry<CalculationType, Parameters>); + factory.add_to_factory("bonne", new bonne_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/cass.hpp b/boost/geometry/srs/projections/proj/cass.hpp index b5f32b5aab..e46750cb6f 100644 --- a/boost/geometry/srs/projections/proj/cass.hpp +++ b/boost/geometry/srs/projections/proj/cass.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_CASS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_CASS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_CASS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CASS_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -63,7 +62,7 @@ namespace projections namespace detail { namespace cass { - //static const double EPS10 = 1e-10; + //static const double epsilon10 = 1e-10; //static const double C1 = .16666666666666666666; //static const double C2 = .00833333333333333333; //static const double C3 = .04166666666666666666; @@ -85,40 +84,37 @@ namespace projections struct par_cass { T m0; - T en[EN_SIZE]; + detail::en<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_cass_ellipsoid : public base_t_fi<base_cass_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_cass_ellipsoid + : public base_t_fi<base_cass_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_cass<CalculationType> m_proj_parm; + par_cass<T> m_proj_parm; inline base_cass_ellipsoid(const Parameters& par) - : base_t_fi<base_cass_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_cass_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType C1 = cass::C1<CalculationType>(); - static const CalculationType C2 = cass::C2<CalculationType>(); - static const CalculationType C3 = cass::C3<CalculationType>(); + static const T C1 = cass::C1<T>(); + static const T C2 = cass::C2<T>(); + static const T C3 = cass::C3<T>(); - CalculationType n = sin(lp_lat); - CalculationType c = cos(lp_lat); + T n = sin(lp_lat); + T c = cos(lp_lat); xy_y = pj_mlfn(lp_lat, n, c, this->m_proj_parm.en); n = 1./sqrt(1. - this->m_par.es * n * n); - CalculationType tn = tan(lp_lat); CalculationType t = tn * tn; - CalculationType a1 = lp_lon * c; + T tn = tan(lp_lat); + T t = tn * tn; + T a1 = lp_lon * c; c *= this->m_par.es * c / (1 - this->m_par.es); - CalculationType a2 = a1 * a1; + T a2 = a1 * a1; xy_x = n * a1 * (1. - a2 * t * (C1 - (8. - t + 8. * c) * a2 * C2)); xy_y -= this->m_proj_parm.m0 - n * tn * a2 * @@ -127,22 +123,22 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType C3 = cass::C3<CalculationType>(); - static const CalculationType C4 = cass::C4<CalculationType>(); - static const CalculationType C5 = cass::C5<CalculationType>(); + static const T C3 = cass::C3<T>(); + static const T C4 = cass::C4<T>(); + static const T C5 = cass::C5<T>(); - CalculationType ph1; + T ph1; ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, this->m_par.es, this->m_proj_parm.en); - CalculationType tn = tan(ph1); CalculationType t = tn * tn; - CalculationType n = sin(ph1); - CalculationType r = 1. / (1. - this->m_par.es * n * n); + T tn = tan(ph1); T t = tn * tn; + T n = sin(ph1); + T r = 1. / (1. - this->m_par.es * n * n); n = sqrt(r); r *= (1. - this->m_par.es) * n; - CalculationType dd = xy_x / n; - CalculationType d2 = dd * dd; + T dd = xy_x / n; + T d2 = dd * dd; lp_lat = ph1 - (n * tn / r) * d2 * (.5 - (1. + 3. * t) * d2 * C3); lp_lon = dd * (1. + t * d2 * @@ -157,23 +153,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_cass_spheroid : public base_t_fi<base_cass_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_cass_spheroid + : public base_t_fi<base_cass_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_cass<CalculationType> m_proj_parm; + par_cass<T> m_proj_parm; inline base_cass_spheroid(const Parameters& par) - : base_t_fi<base_cass_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_cass_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = asin(cos(lp_lat) * sin(lp_lon)); xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - this->m_par.phi0; @@ -181,9 +173,9 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType dd = xy_y + this->m_par.phi0; + T dd = xy_y + this->m_par.phi0; lp_lat = asin(sin(dd) * cos(xy_x)); lp_lon = atan2(tan(xy_x), cos(dd)); } @@ -200,8 +192,7 @@ namespace projections inline void setup_cass(Parameters& par, par_cass<T>& proj_parm) { if (par.es) { - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.en = pj_enfn<T>(par.es); proj_parm.m0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en); } else { } @@ -223,10 +214,10 @@ namespace projections \par Example \image html ex_cass.gif */ - template <typename CalculationType, typename Parameters> - struct cass_ellipsoid : public detail::cass::base_cass_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct cass_ellipsoid : public detail::cass::base_cass_ellipsoid<T, Parameters> { - inline cass_ellipsoid(const Parameters& par) : detail::cass::base_cass_ellipsoid<CalculationType, Parameters>(par) + inline cass_ellipsoid(const Parameters& par) : detail::cass::base_cass_ellipsoid<T, Parameters>(par) { detail::cass::setup_cass(this->m_par, this->m_proj_parm); } @@ -245,10 +236,10 @@ namespace projections \par Example \image html ex_cass.gif */ - template <typename CalculationType, typename Parameters> - struct cass_spheroid : public detail::cass::base_cass_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct cass_spheroid : public detail::cass::base_cass_spheroid<T, Parameters> { - inline cass_spheroid(const Parameters& par) : detail::cass::base_cass_spheroid<CalculationType, Parameters>(par) + inline cass_spheroid(const Parameters& par) : detail::cass::base_cass_spheroid<T, Parameters>(par) { detail::cass::setup_cass(this->m_par, this->m_proj_parm); } @@ -262,23 +253,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cass, cass_spheroid, cass_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class cass_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class cass_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<cass_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<cass_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<cass_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<cass_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void cass_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void cass_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("cass", new cass_entry<CalculationType, Parameters>); + factory.add_to_factory("cass", new cass_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/cc.hpp b/boost/geometry/srs/projections/proj/cc.hpp index c7fc1f20ab..78c3ede008 100644 --- a/boost/geometry/srs/projections/proj/cc.hpp +++ b/boost/geometry/srs/projections/proj/cc.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_CC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_CC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_CC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -63,36 +62,33 @@ namespace projections namespace detail { namespace cc { - static const double EPS10 = 1.e-10; + static const double epsilon10 = 1.e-10; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_cc_spheroid : public base_t_fi<base_cc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_cc_spheroid + : public base_t_fi<base_cc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - inline base_cc_spheroid(const Parameters& par) - : base_t_fi<base_cc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_cc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = lp_lon; xy_y = tan(lp_lat); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = atan(xy_y); lp_lon = xy_x; @@ -127,10 +123,10 @@ namespace projections \par Example \image html ex_cc.gif */ - template <typename CalculationType, typename Parameters> - struct cc_spheroid : public detail::cc::base_cc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct cc_spheroid : public detail::cc::base_cc_spheroid<T, Parameters> { - inline cc_spheroid(const Parameters& par) : detail::cc::base_cc_spheroid<CalculationType, Parameters>(par) + inline cc_spheroid(const Parameters& par) : detail::cc::base_cc_spheroid<T, Parameters>(par) { detail::cc::setup_cc(this->m_par); } @@ -144,20 +140,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cc, cc_spheroid, cc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class cc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class cc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<cc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<cc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void cc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void cc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("cc", new cc_entry<CalculationType, Parameters>); + factory.add_to_factory("cc", new cc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/cea.hpp b/boost/geometry/srs/projections/proj/cea.hpp index b6d8707e08..2d7ba20d3d 100644 --- a/boost/geometry/srs/projections/proj/cea.hpp +++ b/boost/geometry/srs/projections/proj/cea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -65,33 +64,29 @@ namespace projections namespace detail { namespace cea { - static const double EPS = 1e-10; + static const double epsilon = 1e-10; template <typename T> struct par_cea { T qp; - T apa[APA_SIZE]; + detail::apa<T> apa; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_cea_ellipsoid : public base_t_fi<base_cea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_cea_ellipsoid + : public base_t_fi<base_cea_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_cea<CalculationType> m_proj_parm; + par_cea<T> m_proj_parm; inline base_cea_ellipsoid(const Parameters& par) - : base_t_fi<base_cea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_cea_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = this->m_par.k0 * lp_lon; xy_y = .5 * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) / this->m_par.k0; @@ -99,7 +94,7 @@ namespace projections // INVERSE(e_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = pj_authlat(asin( 2. * xy_y * this->m_par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa); lp_lon = xy_x / this->m_par.k0; @@ -113,23 +108,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_cea_spheroid : public base_t_fi<base_cea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_cea_spheroid + : public base_t_fi<base_cea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_cea<CalculationType> m_proj_parm; + par_cea<T> m_proj_parm; inline base_cea_spheroid(const Parameters& par) - : base_t_fi<base_cea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_cea_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = this->m_par.k0 * lp_lon; xy_y = sin(lp_lat) / this->m_par.k0; @@ -137,20 +128,20 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType t; + T t; - if ((t = fabs(xy_y *= this->m_par.k0)) - EPS <= 1.) { + if ((t = fabs(xy_y *= this->m_par.k0)) - epsilon <= 1.) { if (t >= 1.) - lp_lat = xy_y < 0. ? -HALFPI : HALFPI; + lp_lat = xy_y < 0. ? -half_pi : half_pi; else lp_lat = asin(xy_y); lp_lon = xy_x / this->m_par.k0; } else - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } static inline std::string get_name() @@ -166,17 +157,19 @@ namespace projections { T t = 0; - if (pj_param(par.params, "tlat_ts").i && - (par.k0 = cos(t = pj_param(par.params, "rlat_ts").f)) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-24) ); - if (par.es) { + if (pj_param_r(par.params, "lat_ts", t)) { + par.k0 = cos(t); + if (par.k0 < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_lat_ts_larger_than_90) ); + } + } + if (par.es != 0.0) { t = sin(t); par.k0 /= sqrt(1. - par.es * t * t); par.e = sqrt(par.es); - if (!pj_authset(par.es, proj_parm.apa)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.apa = pj_authset<T>(par.es); + proj_parm.qp = pj_qsfn(1., par.e, par.one_es); - } else { } } @@ -198,10 +191,10 @@ namespace projections \par Example \image html ex_cea.gif */ - template <typename CalculationType, typename Parameters> - struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<T, Parameters> { - inline cea_ellipsoid(const Parameters& par) : detail::cea::base_cea_ellipsoid<CalculationType, Parameters>(par) + inline cea_ellipsoid(const Parameters& par) : detail::cea::base_cea_ellipsoid<T, Parameters>(par) { detail::cea::setup_cea(this->m_par, this->m_proj_parm); } @@ -222,10 +215,10 @@ namespace projections \par Example \image html ex_cea.gif */ - template <typename CalculationType, typename Parameters> - struct cea_spheroid : public detail::cea::base_cea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct cea_spheroid : public detail::cea::base_cea_spheroid<T, Parameters> { - inline cea_spheroid(const Parameters& par) : detail::cea::base_cea_spheroid<CalculationType, Parameters>(par) + inline cea_spheroid(const Parameters& par) : detail::cea::base_cea_spheroid<T, Parameters>(par) { detail::cea::setup_cea(this->m_par, this->m_proj_parm); } @@ -239,23 +232,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cea, cea_spheroid, cea_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class cea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class cea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<cea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<cea_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<cea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<cea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void cea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void cea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("cea", new cea_entry<CalculationType, Parameters>); + factory.add_to_factory("cea", new cea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/chamb.hpp b/boost/geometry/srs/projections/proj/chamb.hpp index 9fd123bb2e..a2bed492c1 100644 --- a/boost/geometry/srs/projections/proj/chamb.hpp +++ b/boost/geometry/srs/projections/proj/chamb.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP -#define BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP + #include <boost/geometry/util/math.hpp> #include <cstdio> @@ -65,14 +64,14 @@ namespace projections namespace detail { namespace chamb { - //static const double THIRD = 0.333333333333333333; - static const double TOL = 1e-9; + //static const double third = 0.333333333333333333; + static const double tolerance = 1e-9; // specific for 'chamb' template <typename T> - struct VECT { T r, Az; }; + struct vect_ra { T r, Az; }; template <typename T> - struct XY { T x, y; }; + struct point_xy { T x, y; }; template <typename T> struct par_chamb @@ -80,19 +79,19 @@ namespace projections struct { /* control point data */ T phi, lam; T cosphi, sinphi; - VECT<T> v; - XY<T> p; + vect_ra<T> v; + point_xy<T> p; T Az; } c[3]; - XY<T> p; + point_xy<T> p; T beta_0, beta_1, beta_2; }; + /* distance and azimuth from point 1 to point 2 */ template <typename T> - inline VECT<T> /* distance and azimuth from point 1 to point 2 */ - vect(T const& dphi, T const& c1, T const& s1, T const& c2, T const& s2, T const& dlam) + inline vect_ra<T> vect(T const& dphi, T const& c1, T const& s1, T const& c2, T const& s2, T const& dlam) { - VECT<T> v; + vect_ra<T> v; T cdl, dp, dl; cdl = cos(dlam); @@ -103,43 +102,39 @@ namespace projections dl = sin(.5 * dlam); v.r = 2. * aasin(sqrt(dp * dp + c1 * c2 * dl * dl)); } - if (fabs(v.r) > TOL) + if (fabs(v.r) > tolerance) v.Az = atan2(c2 * sin(dlam), c1 * s2 - s1 * c2 * cdl); else v.r = v.Az = 0.; return v; } + /* law of cosines */ template <typename T> - inline T /* law of cosines */ - lc(T const& b, T const& c, T const& a) + inline T lc(T const& b, T const& c, T const& a) { return aacos(.5 * (b * b + c * c - a * a) / (b * c)); } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_chamb_spheroid : public base_t_f<base_chamb_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_chamb_spheroid + : public base_t_f<base_chamb_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_chamb<CalculationType> m_proj_parm; + par_chamb<T> m_proj_parm; inline base_chamb_spheroid(const Parameters& par) - : base_t_f<base_chamb_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_chamb_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType THIRD = detail::THIRD<CalculationType>(); + static const T third = detail::third<T>(); - CalculationType sinphi, cosphi, a; - VECT<CalculationType> v[3]; + T sinphi, cosphi, a; + vect_ra<T> v[3]; int i, j; sinphi = sin(lp_lat); @@ -147,7 +142,7 @@ namespace projections for (i = 0; i < 3; ++i) { /* dist/azimiths from control */ v[i] = vect(lp_lat - this->m_proj_parm.c[i].phi, this->m_proj_parm.c[i].cosphi, this->m_proj_parm.c[i].sinphi, cosphi, sinphi, lp_lon - this->m_proj_parm.c[i].lam); - if ( ! v[i].r) + if (v[i].r == 0.0) break; v[i].Az = adjlon(v[i].Az - this->m_proj_parm.c[i].v.Az); } @@ -173,8 +168,8 @@ namespace projections xy_y += v[i].r * sin(a); } } - xy_x *= THIRD; /* mean of arc intercepts */ - xy_y *= THIRD; + xy_x *= third; /* mean of arc intercepts */ + xy_y *= third; } } @@ -189,16 +184,16 @@ namespace projections template <typename Parameters, typename T> inline void setup_chamb(Parameters& par, par_chamb<T>& proj_parm) { - static const T ONEPI = detail::ONEPI<T>(); + static const T pi = detail::pi<T>(); + + static const std::string lat[3] = {"lat_1", "lat_2", "lat_3"}; + static const std::string lon[3] = {"lon_1", "lon_2", "lon_3"}; int i, j; - char line[10]; for (i = 0; i < 3; ++i) { /* get control point locations */ - (void)sprintf(line, "rlat_%d", i+1); - proj_parm.c[i].phi = pj_param(par.params, line).f; - (void)sprintf(line, "rlon_%d", i+1); - proj_parm.c[i].lam = pj_param(par.params, line).f; + proj_parm.c[i].phi = pj_get_param_r(par.params, lat[i]); + proj_parm.c[i].lam = pj_get_param_r(par.params, lon[i]); proj_parm.c[i].lam = adjlon(proj_parm.c[i].lam - par.lam0); proj_parm.c[i].cosphi = cos(proj_parm.c[i].phi); proj_parm.c[i].sinphi = sin(proj_parm.c[i].phi); @@ -207,17 +202,18 @@ namespace projections j = i == 2 ? 0 : i + 1; proj_parm.c[i].v = vect(proj_parm.c[j].phi - proj_parm.c[i].phi, proj_parm.c[i].cosphi, proj_parm.c[i].sinphi, proj_parm.c[j].cosphi, proj_parm.c[j].sinphi, proj_parm.c[j].lam - proj_parm.c[i].lam); - if (! proj_parm.c[i].v.r) - BOOST_THROW_EXCEPTION( projection_exception(-25) ); + if (proj_parm.c[i].v.r == 0.0) + BOOST_THROW_EXCEPTION( projection_exception(error_control_point_no_dist) ); /* co-linearity problem ignored for now */ } proj_parm.beta_0 = lc(proj_parm.c[0].v.r, proj_parm.c[2].v.r, proj_parm.c[1].v.r); proj_parm.beta_1 = lc(proj_parm.c[0].v.r, proj_parm.c[1].v.r, proj_parm.c[2].v.r); - proj_parm.beta_2 = ONEPI - proj_parm.beta_0; + proj_parm.beta_2 = pi - proj_parm.beta_0; proj_parm.p.y = 2. * (proj_parm.c[0].p.y = proj_parm.c[1].p.y = proj_parm.c[2].v.r * sin(proj_parm.beta_0)); proj_parm.c[2].p.y = 0.; proj_parm.c[0].p.x = - (proj_parm.c[1].p.x = 0.5 * proj_parm.c[0].v.r); proj_parm.p.x = proj_parm.c[2].p.x = proj_parm.c[0].p.x + proj_parm.c[2].v.r * cos(proj_parm.beta_0); + par.es = 0.; } @@ -244,10 +240,10 @@ namespace projections \par Example \image html ex_chamb.gif */ - template <typename CalculationType, typename Parameters> - struct chamb_spheroid : public detail::chamb::base_chamb_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct chamb_spheroid : public detail::chamb::base_chamb_spheroid<T, Parameters> { - inline chamb_spheroid(const Parameters& par) : detail::chamb::base_chamb_spheroid<CalculationType, Parameters>(par) + inline chamb_spheroid(const Parameters& par) : detail::chamb::base_chamb_spheroid<T, Parameters>(par) { detail::chamb::setup_chamb(this->m_par, this->m_proj_parm); } @@ -261,20 +257,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::chamb, chamb_spheroid, chamb_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class chamb_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class chamb_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<chamb_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<chamb_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void chamb_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void chamb_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("chamb", new chamb_entry<CalculationType, Parameters>); + factory.add_to_factory("chamb", new chamb_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/collg.hpp b/boost/geometry/srs/projections/proj/collg.hpp index 0bc347a305..1dc5b3ce48 100644 --- a/boost/geometry/srs/projections/proj/collg.hpp +++ b/boost/geometry/srs/projections/proj/collg.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP -#define BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -65,25 +64,20 @@ namespace projections static const double FXC = 1.12837916709551257390; static const double FYC = 1.77245385090551602729; - static const double ONEEPS = 1.0000001; + static const double one_plus_eps = 1.0000001; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_collg_spheroid : public base_t_fi<base_collg_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_collg_spheroid + : public base_t_fi<base_collg_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_collg_spheroid(const Parameters& par) - : base_t_fi<base_collg_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_collg_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { if ((xy_y = 1. - sin(lp_lat)) <= 0.) xy_y = 0.; @@ -95,15 +89,19 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { + static T const half_pi = detail::half_pi<T>(); + lp_lat = xy_y / FYC - 1.; if (fabs(lp_lat = 1. - lp_lat * lp_lat) < 1.) lp_lat = asin(lp_lat); - else if (fabs(lp_lat) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else - lp_lat = lp_lat < 0. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>(); + else if (fabs(lp_lat) > one_plus_eps) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else { + lp_lat = lp_lat < 0. ? -half_pi : half_pi; + } + if ((lp_lon = 1. - sin(lp_lat)) <= 0.) lp_lon = 0.; else @@ -139,10 +137,10 @@ namespace projections \par Example \image html ex_collg.gif */ - template <typename CalculationType, typename Parameters> - struct collg_spheroid : public detail::collg::base_collg_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct collg_spheroid : public detail::collg::base_collg_spheroid<T, Parameters> { - inline collg_spheroid(const Parameters& par) : detail::collg::base_collg_spheroid<CalculationType, Parameters>(par) + inline collg_spheroid(const Parameters& par) : detail::collg::base_collg_spheroid<T, Parameters>(par) { detail::collg::setup_collg(this->m_par); } @@ -156,20 +154,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::collg, collg_spheroid, collg_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class collg_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class collg_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<collg_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<collg_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void collg_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void collg_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("collg", new collg_entry<CalculationType, Parameters>); + factory.add_to_factory("collg", new collg_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/crast.hpp b/boost/geometry/srs/projections/proj/crast.hpp index 4aea886071..5f781f8776 100644 --- a/boost/geometry/srs/projections/proj/crast.hpp +++ b/boost/geometry/srs/projections/proj/crast.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP -#define BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP +#define BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -65,41 +64,36 @@ namespace projections static const double RXM = 1.02332670794648848847; static const double YM = 3.06998012383946546542; static const double RYM = 0.32573500793527994772; - //static const double THIRD = 0.333333333333333333; + //static const double third = 0.333333333333333333; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_crast_spheroid : public base_t_fi<base_crast_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_crast_spheroid + : public base_t_fi<base_crast_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_crast_spheroid(const Parameters& par) - : base_t_fi<base_crast_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_crast_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType THIRD = detail::THIRD<CalculationType>(); + static const T third = detail::third<T>(); - lp_lat *= THIRD; + lp_lat *= third; xy_x = XM * lp_lon * (2. * cos(lp_lat + lp_lat) - 1.); xy_y = YM * sin(lp_lat); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType THIRD = detail::THIRD<CalculationType>(); + static const T third = detail::third<T>(); lp_lat = 3. * asin(xy_y * RYM); - lp_lon = xy_x * RXM / (2. * cos((lp_lat + lp_lat) * THIRD) - 1); + lp_lon = xy_x * RXM / (2. * cos((lp_lat + lp_lat) * third) - 1); } static inline std::string get_name() @@ -131,10 +125,10 @@ namespace projections \par Example \image html ex_crast.gif */ - template <typename CalculationType, typename Parameters> - struct crast_spheroid : public detail::crast::base_crast_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct crast_spheroid : public detail::crast::base_crast_spheroid<T, Parameters> { - inline crast_spheroid(const Parameters& par) : detail::crast::base_crast_spheroid<CalculationType, Parameters>(par) + inline crast_spheroid(const Parameters& par) : detail::crast::base_crast_spheroid<T, Parameters>(par) { detail::crast::setup_crast(this->m_par); } @@ -148,20 +142,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::crast, crast_spheroid, crast_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class crast_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class crast_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<crast_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<crast_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void crast_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void crast_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("crast", new crast_entry<CalculationType, Parameters>); + factory.add_to_factory("crast", new crast_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/denoy.hpp b/boost/geometry/srs/projections/proj/denoy.hpp index afedae8734..9d54487f6f 100644 --- a/boost/geometry/srs/projections/proj/denoy.hpp +++ b/boost/geometry/srs/projections/proj/denoy.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -62,36 +61,31 @@ namespace projections { static const double C0 = 0.95; - //static const double C1 = -.08333333333333333333; - //static const double C3 = .00166666666666666666; + //static const double C1 = -0.08333333333333333333; + //static const double C3 = 0.00166666666666666666; static const double D1 = 0.9; static const double D5 = 0.03; template <typename T> - inline T C1() { return -.0833333333333333333333333333333; } + inline T C1() { return -0.0833333333333333333333333333333; } template <typename T> - inline T C3() { return .0016666666666666666666666666666; } + inline T C3() { return 0.0016666666666666666666666666666; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_denoy_spheroid : public base_t_f<base_denoy_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_denoy_spheroid + : public base_t_f<base_denoy_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_denoy_spheroid(const Parameters& par) - : base_t_f<base_denoy_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_denoy_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType C1 = denoy::C1<CalculationType>(); - static const CalculationType C3 = denoy::C3<CalculationType>(); + static const T C1 = denoy::C1<T>(); + static const T C3 = denoy::C3<T>(); xy_y = lp_lat; xy_x = lp_lon; @@ -111,7 +105,7 @@ namespace projections template <typename Parameters> inline void setup_denoy(Parameters& par) { - par.es = 0.; + par.es = 0.0; } }} // namespace detail::denoy @@ -130,10 +124,10 @@ namespace projections \par Example \image html ex_denoy.gif */ - template <typename CalculationType, typename Parameters> - struct denoy_spheroid : public detail::denoy::base_denoy_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct denoy_spheroid : public detail::denoy::base_denoy_spheroid<T, Parameters> { - inline denoy_spheroid(const Parameters& par) : detail::denoy::base_denoy_spheroid<CalculationType, Parameters>(par) + inline denoy_spheroid(const Parameters& par) : detail::denoy::base_denoy_spheroid<T, Parameters>(par) { detail::denoy::setup_denoy(this->m_par); } @@ -147,20 +141,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::denoy, denoy_spheroid, denoy_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class denoy_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class denoy_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<denoy_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<denoy_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void denoy_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void denoy_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("denoy", new denoy_entry<CalculationType, Parameters>); + factory.add_to_factory("denoy", new denoy_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eck1.hpp b/boost/geometry/srs/projections/proj/eck1.hpp index 41f0f6424f..e5ab6e2449 100644 --- a/boost/geometry/srs/projections/proj/eck1.hpp +++ b/boost/geometry/srs/projections/proj/eck1.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -65,22 +64,17 @@ namespace projections static const double RP = .31830988618379067154; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eck1_spheroid : public base_t_fi<base_eck1_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eck1_spheroid + : public base_t_fi<base_eck1_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_eck1_spheroid(const Parameters& par) - : base_t_fi<base_eck1_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eck1_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = FC * lp_lon * (1. - RP * fabs(lp_lat)); xy_y = FC * lp_lat; @@ -88,7 +82,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / FC; lp_lon = xy_x / (FC * (1. - RP * fabs(lp_lat))); @@ -123,10 +117,10 @@ namespace projections \par Example \image html ex_eck1.gif */ - template <typename CalculationType, typename Parameters> - struct eck1_spheroid : public detail::eck1::base_eck1_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck1_spheroid : public detail::eck1::base_eck1_spheroid<T, Parameters> { - inline eck1_spheroid(const Parameters& par) : detail::eck1::base_eck1_spheroid<CalculationType, Parameters>(par) + inline eck1_spheroid(const Parameters& par) : detail::eck1::base_eck1_spheroid<T, Parameters>(par) { detail::eck1::setup_eck1(this->m_par); } @@ -140,20 +134,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck1, eck1_spheroid, eck1_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eck1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eck1_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eck1_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eck1", new eck1_entry<CalculationType, Parameters>); + factory.add_to_factory("eck1", new eck1_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eck2.hpp b/boost/geometry/srs/projections/proj/eck2.hpp index 737057bfcd..fd39735d95 100644 --- a/boost/geometry/srs/projections/proj/eck2.hpp +++ b/boost/geometry/srs/projections/proj/eck2.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -66,25 +65,20 @@ namespace projections static const double FXC = 0.46065886596178063902; static const double FYC = 1.44720250911653531871; //static const double C13 = 0.33333333333333333333; - static const double ONEEPS = 1.0000001; + static const double one_plus_eps = 1.0000001; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eck2_spheroid : public base_t_fi<base_eck2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eck2_spheroid + : public base_t_fi<base_eck2_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_eck2_spheroid(const Parameters& par) - : base_t_fi<base_eck2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eck2_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = FXC * lp_lon * (xy_y = sqrt(4. - 3. * sin(fabs(lp_lat)))); xy_y = FYC * (2. - xy_y); @@ -93,18 +87,18 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType C13 = detail::THIRD<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T C13 = detail::third<T>(); lp_lon = xy_x / (FXC * ( lp_lat = 2. - fabs(xy_y) / FYC) ); lp_lat = (4. - lp_lat * lp_lat) * C13; if (fabs(lp_lat) >= 1.) { - if (fabs(lp_lat) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(lp_lat) > one_plus_eps) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else - lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + lp_lat = lp_lat < 0. ? -half_pi : half_pi; } else lp_lat = asin(lp_lat); if (xy_y < 0) @@ -140,10 +134,10 @@ namespace projections \par Example \image html ex_eck2.gif */ - template <typename CalculationType, typename Parameters> - struct eck2_spheroid : public detail::eck2::base_eck2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck2_spheroid : public detail::eck2::base_eck2_spheroid<T, Parameters> { - inline eck2_spheroid(const Parameters& par) : detail::eck2::base_eck2_spheroid<CalculationType, Parameters>(par) + inline eck2_spheroid(const Parameters& par) : detail::eck2::base_eck2_spheroid<T, Parameters>(par) { detail::eck2::setup_eck2(this->m_par); } @@ -157,20 +151,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck2, eck2_spheroid, eck2_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eck2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eck2_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eck2_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eck2", new eck2_entry<CalculationType, Parameters>); + factory.add_to_factory("eck2", new eck2_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eck3.hpp b/boost/geometry/srs/projections/proj/eck3.hpp index dbc1beb625..35933af3fe 100644 --- a/boost/geometry/srs/projections/proj/eck3.hpp +++ b/boost/geometry/srs/projections/proj/eck3.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP + #include <boost/core/ignore_unused.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,10 +53,10 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct eck3 {}; - struct putp1 {}; - struct wag6 {}; - struct kav7 {}; + struct eck3 {}; // Eckert III + struct putp1 {}; // Putnins P1 + struct wag6 {}; // Wagner VI + struct kav7 {}; // Kavraisky VII }} //namespace srs::par4 @@ -74,23 +73,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eck3_spheroid : public base_t_fi<base_eck3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eck3_spheroid + : public base_t_fi<base_eck3_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_eck3<CalculationType> m_proj_parm; + par_eck3<T> m_proj_parm; inline base_eck3_spheroid(const Parameters& par) - : base_t_fi<base_eck3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eck3_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_y = this->m_proj_parm.C_y * lp_lat; xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat)); @@ -98,10 +93,16 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { + T denominator; lp_lat = xy_y / this->m_proj_parm.C_y; - lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat))); + denominator = (this->m_proj_parm.C_x * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat))); + if ( denominator == 0.0) { + lp_lon = HUGE_VAL; + lp_lat = HUGE_VAL; + } else + lp_lon = xy_x / denominator; } static inline std::string get_name() @@ -111,10 +112,9 @@ namespace projections }; - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_eck3<T>& proj_parm) + template <typename Parameters> + inline void setup(Parameters& par) { - boost::ignore_unused(proj_parm); par.es = 0.; } @@ -123,11 +123,12 @@ namespace projections template <typename Parameters, typename T> inline void setup_eck3(Parameters& par, par_eck3<T>& proj_parm) { - proj_parm.C_x = .42223820031577120149; - proj_parm.C_y = .84447640063154240298; - proj_parm.A = 1.; + proj_parm.C_x = 0.42223820031577120149; + proj_parm.C_y = 0.84447640063154240298; + proj_parm.A = 1.0; proj_parm.B = 0.4052847345693510857755; - setup(par, proj_parm); + + setup(par); } // Putnins P1 @@ -138,7 +139,8 @@ namespace projections proj_parm.C_y = 0.94745; proj_parm.A = -0.5; proj_parm.B = 0.30396355092701331433; - setup(par, proj_parm); + + setup(par); } // Wagner VI @@ -146,21 +148,25 @@ namespace projections inline void setup_wag6(Parameters& par, par_eck3<T>& proj_parm) { proj_parm.C_x = proj_parm.C_y = 0.94745; - proj_parm.A = 0.; + proj_parm.A = 0.0; proj_parm.B = 0.30396355092701331433; - setup(par, proj_parm); + + setup(par); } // Kavraisky VII template <typename Parameters, typename T> inline void setup_kav7(Parameters& par, par_eck3<T>& proj_parm) { - proj_parm.C_x = 0.2632401569273184856851; + /* Defined twice in original code - Using 0.866..., + * but leaving the other one here as a safety measure. + * proj_parm.C_x = 0.2632401569273184856851; */ proj_parm.C_x = 0.8660254037844; - proj_parm.C_y = 1.; - proj_parm.A = 0.; + proj_parm.C_y = 1.0; + proj_parm.A = 0.0; proj_parm.B = 0.30396355092701331433; - setup(par, proj_parm); + + setup(par); } }} // namespace detail::eck3 @@ -178,10 +184,10 @@ namespace projections \par Example \image html ex_eck3.gif */ - template <typename CalculationType, typename Parameters> - struct eck3_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck3_spheroid : public detail::eck3::base_eck3_spheroid<T, Parameters> { - inline eck3_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par) + inline eck3_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<T, Parameters>(par) { detail::eck3::setup_eck3(this->m_par, this->m_proj_parm); } @@ -199,10 +205,10 @@ namespace projections \par Example \image html ex_putp1.gif */ - template <typename CalculationType, typename Parameters> - struct putp1_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp1_spheroid : public detail::eck3::base_eck3_spheroid<T, Parameters> { - inline putp1_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par) + inline putp1_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<T, Parameters>(par) { detail::eck3::setup_putp1(this->m_par, this->m_proj_parm); } @@ -220,10 +226,10 @@ namespace projections \par Example \image html ex_wag6.gif */ - template <typename CalculationType, typename Parameters> - struct wag6_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag6_spheroid : public detail::eck3::base_eck3_spheroid<T, Parameters> { - inline wag6_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par) + inline wag6_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<T, Parameters>(par) { detail::eck3::setup_wag6(this->m_par, this->m_proj_parm); } @@ -241,10 +247,10 @@ namespace projections \par Example \image html ex_kav7.gif */ - template <typename CalculationType, typename Parameters> - struct kav7_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct kav7_spheroid : public detail::eck3::base_eck3_spheroid<T, Parameters> { - inline kav7_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par) + inline kav7_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<T, Parameters>(par) { detail::eck3::setup_kav7(this->m_par, this->m_proj_parm); } @@ -261,53 +267,53 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::kav7, kav7_spheroid, kav7_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eck3_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck3_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck3_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class putp1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class wag6_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag6_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag6_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class kav7_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class kav7_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<kav7_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<kav7_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eck3_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eck3_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eck3", new eck3_entry<CalculationType, Parameters>); - factory.add_to_factory("putp1", new putp1_entry<CalculationType, Parameters>); - factory.add_to_factory("wag6", new wag6_entry<CalculationType, Parameters>); - factory.add_to_factory("kav7", new kav7_entry<CalculationType, Parameters>); + factory.add_to_factory("eck3", new eck3_entry<T, Parameters>); + factory.add_to_factory("putp1", new putp1_entry<T, Parameters>); + factory.add_to_factory("wag6", new wag6_entry<T, Parameters>); + factory.add_to_factory("kav7", new kav7_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eck4.hpp b/boost/geometry/srs/projections/proj/eck4.hpp index 4307b59439..7c1fc6178d 100644 --- a/boost/geometry/srs/projections/proj/eck4.hpp +++ b/boost/geometry/srs/projections/proj/eck4.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct eck4 {}; + struct eck4 {}; // Eckert IV }} //namespace srs::par4 @@ -67,39 +66,34 @@ namespace projections static const double RC_y = .75386330736002178205; static const double C_p = 3.57079632679489661922; static const double RC_p = .28004957675577868795; - static const double EPS = 1e-7; - static const int NITER = 6; + static const double epsilon = 1e-7; + static const int n_iter = 6; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eck4_spheroid : public base_t_fi<base_eck4_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eck4_spheroid + : public base_t_fi<base_eck4_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_eck4_spheroid(const Parameters& par) - : base_t_fi<base_eck4_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eck4_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType p, V, s, c; + T p, V, s, c; int i; p = C_p * sin(lp_lat); V = lp_lat * lp_lat; lp_lat *= 0.895168 + V * ( 0.0218849 + V * 0.00826809 ); - for (i = NITER; i ; --i) { + for (i = n_iter; i ; --i) { c = cos(lp_lat); s = sin(lp_lat); lp_lat -= V = (lp_lat + s * (c + 2.) - p) / (1. + c * (c + 2.) - s * s); - if (fabs(V) < EPS) + if (fabs(V) < epsilon) break; } if (!i) { @@ -113,13 +107,13 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType c; + T c; - lp_lat = aasin(xy_y / C_y); + lp_lat = aasin(xy_y * RC_y); lp_lon = xy_x / (C_x * (1. + (c = cos(lp_lat)))); - lp_lat = aasin((lp_lat + sin(lp_lat) * (c + 2.)) / C_p); + lp_lat = aasin((lp_lat + sin(lp_lat) * (c + 2.)) * RC_p); } static inline std::string get_name() @@ -151,10 +145,10 @@ namespace projections \par Example \image html ex_eck4.gif */ - template <typename CalculationType, typename Parameters> - struct eck4_spheroid : public detail::eck4::base_eck4_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck4_spheroid : public detail::eck4::base_eck4_spheroid<T, Parameters> { - inline eck4_spheroid(const Parameters& par) : detail::eck4::base_eck4_spheroid<CalculationType, Parameters>(par) + inline eck4_spheroid(const Parameters& par) : detail::eck4::base_eck4_spheroid<T, Parameters>(par) { detail::eck4::setup_eck4(this->m_par); } @@ -168,20 +162,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck4, eck4_spheroid, eck4_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eck4_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck4_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck4_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eck4_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eck4_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eck4", new eck4_entry<CalculationType, Parameters>); + factory.add_to_factory("eck4", new eck4_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eck5.hpp b/boost/geometry/srs/projections/proj/eck5.hpp index bc075702e8..823de91040 100644 --- a/boost/geometry/srs/projections/proj/eck5.hpp +++ b/boost/geometry/srs/projections/proj/eck5.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct eck5 {}; + struct eck5 {}; // Eckert V }} //namespace srs::par4 @@ -61,28 +60,23 @@ namespace projections namespace detail { namespace eck5 { - static const double XF = 0.44101277172455148219; + static const double XF = 0.44101277172455148219; static const double RXF = 2.26750802723822639137; - static const double YF = 0.88202554344910296438; + static const double YF = 0.88202554344910296438; static const double RYF = 1.13375401361911319568; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eck5_spheroid : public base_t_fi<base_eck5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eck5_spheroid + : public base_t_fi<base_eck5_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_eck5_spheroid(const Parameters& par) - : base_t_fi<base_eck5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eck5_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = XF * (1. + cos(lp_lat)) * lp_lon; xy_y = YF * lp_lat; @@ -90,7 +84,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = RXF * xy_x / (1. + cos( lp_lat = RYF * xy_y)); } @@ -106,7 +100,7 @@ namespace projections template <typename Parameters> inline void setup_eck5(Parameters& par) { - par.es = 0.; + par.es = 0.0; } }} // namespace detail::eck5 @@ -124,10 +118,10 @@ namespace projections \par Example \image html ex_eck5.gif */ - template <typename CalculationType, typename Parameters> - struct eck5_spheroid : public detail::eck5::base_eck5_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck5_spheroid : public detail::eck5::base_eck5_spheroid<T, Parameters> { - inline eck5_spheroid(const Parameters& par) : detail::eck5::base_eck5_spheroid<CalculationType, Parameters>(par) + inline eck5_spheroid(const Parameters& par) : detail::eck5::base_eck5_spheroid<T, Parameters>(par) { detail::eck5::setup_eck5(this->m_par); } @@ -141,20 +135,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck5, eck5_spheroid, eck5_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eck5_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck5_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck5_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eck5_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eck5_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eck5", new eck5_entry<CalculationType, Parameters>); + factory.add_to_factory("eck5", new eck5_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eqc.hpp b/boost/geometry/srs/projections/proj/eqc.hpp index 5234ce9b8d..355ab90567 100644 --- a/boost/geometry/srs/projections/proj/eqc.hpp +++ b/boost/geometry/srs/projections/proj/eqc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_EQC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_EQC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_EQC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_EQC_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct eqc {}; + struct eqc {}; // Equidistant Cylindrical (Plate Caree) }} //namespace srs::par4 @@ -67,23 +66,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eqc_spheroid : public base_t_fi<base_eqc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eqc_spheroid + : public base_t_fi<base_eqc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_eqc<CalculationType> m_proj_parm; + par_eqc<T> m_proj_parm; inline base_eqc_spheroid(const Parameters& par) - : base_t_fi<base_eqc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eqc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = this->m_proj_parm.rc * lp_lon; xy_y = lp_lat - this->m_par.phi0; @@ -91,7 +86,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = xy_x / this->m_proj_parm.rc; lp_lat = xy_y + this->m_par.phi0; @@ -108,8 +103,8 @@ namespace projections template <typename Parameters, typename T> inline void setup_eqc(Parameters& par, par_eqc<T>& proj_parm) { - if ((proj_parm.rc = cos(pj_param(par.params, "rlat_ts").f)) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-24) ); + if ((proj_parm.rc = cos(pj_get_param_r(par.params, "lat_ts"))) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_ts_larger_than_90) ); par.es = 0.; } @@ -131,10 +126,10 @@ namespace projections \par Example \image html ex_eqc.gif */ - template <typename CalculationType, typename Parameters> - struct eqc_spheroid : public detail::eqc::base_eqc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eqc_spheroid : public detail::eqc::base_eqc_spheroid<T, Parameters> { - inline eqc_spheroid(const Parameters& par) : detail::eqc::base_eqc_spheroid<CalculationType, Parameters>(par) + inline eqc_spheroid(const Parameters& par) : detail::eqc::base_eqc_spheroid<T, Parameters>(par) { detail::eqc::setup_eqc(this->m_par, this->m_proj_parm); } @@ -148,20 +143,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eqc, eqc_spheroid, eqc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eqc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eqc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eqc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eqc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eqc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eqc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eqc", new eqc_entry<CalculationType, Parameters>); + factory.add_to_factory("eqc", new eqc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/eqdc.hpp b/boost/geometry/srs/projections/proj/eqdc.hpp index 1af11338a4..f0c7597cbd 100644 --- a/boost/geometry/srs/projections/proj/eqdc.hpp +++ b/boost/geometry/srs/projections/proj/eqdc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -56,7 +55,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct eqdc {}; + struct eqdc {}; // Equidistant Conic }} //namespace srs::par4 @@ -66,40 +65,37 @@ namespace projections namespace detail { namespace eqdc { - static const double EPS10 = 1.e-10; + static const double epsilon10 = 1.e-10; template <typename T> struct par_eqdc { - T phi1; - T phi2; - T n; - T rho0; - T c; - T en[EN_SIZE]; - int ellips; + T phi1; + T phi2; + T n; + T rho0; + T c; + detail::en<T> en; + bool ellips; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_eqdc_ellipsoid : public base_t_fi<base_eqdc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_eqdc_ellipsoid + : public base_t_fi<base_eqdc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_eqdc<CalculationType> m_proj_parm; + par_eqdc<T> m_proj_parm; inline base_eqdc_ellipsoid(const Parameters& par) - : base_t_fi<base_eqdc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_eqdc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) sphere & ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType rho = 0.0; + T rho = 0.0; + rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sin(lp_lat), cos(lp_lat), this->m_proj_parm.en) : lp_lat); xy_x = rho * sin( lp_lon *= this->m_proj_parm.n ); @@ -108,9 +104,12 @@ namespace projections // INVERSE(e_inverse) sphere & ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType rho = 0.0; + static T const half_pi = detail::half_pi<T>(); + + T rho = 0.0; + if ((rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) { if (this->m_proj_parm.n < 0.) { rho = -rho; @@ -123,25 +122,10 @@ namespace projections lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; } else { lp_lon = 0.; - lp_lat = this->m_proj_parm.n > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>(); + lp_lat = this->m_proj_parm.n > 0. ? half_pi : -half_pi; } } - // SPECIAL(fac) - #ifdef SPECIAL_FACTORS_NOT_CONVERTED - inline void fac(Geographic lp, Factors &fac) const - { - CalculationType sinphi, cosphi; - - sinphi = sin(lp_lat); - cosphi = cos(lp_lat); - this->m_fac.code |= IS_ANAL_HK; - this->m_fac.h = 1.; - this->m_fac.k = this->m_proj_parm.n * (this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sinphi, - cosphi, this->m_proj_parm.en) : lp_lat)) / pj_msfn(sinphi, cosphi, this->m_par.es); - } - #endif - static inline std::string get_name() { return "eqdc_ellipsoid"; @@ -156,15 +140,17 @@ namespace projections T cosphi, sinphi; int secant; - proj_parm.phi1 = pj_param(par.params, "rlat_1").f; - proj_parm.phi2 = pj_param(par.params, "rlat_2").f; - if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-21) ); - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.phi1 = pj_get_param_r(par.params, "lat_1"); + proj_parm.phi2 = pj_get_param_r(par.params, "lat_2"); + + if (fabs(proj_parm.phi1 + proj_parm.phi2) < epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_conic_lat_equal) ); + + proj_parm.en = pj_enfn<T>(par.es); + proj_parm.n = sinphi = sin(proj_parm.phi1); cosphi = cos(proj_parm.phi1); - secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10; + secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= epsilon10; if( (proj_parm.ellips = (par.es > 0.)) ) { double ml1, m1; @@ -206,10 +192,10 @@ namespace projections \par Example \image html ex_eqdc.gif */ - template <typename CalculationType, typename Parameters> - struct eqdc_ellipsoid : public detail::eqdc::base_eqdc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eqdc_ellipsoid : public detail::eqdc::base_eqdc_ellipsoid<T, Parameters> { - inline eqdc_ellipsoid(const Parameters& par) : detail::eqdc::base_eqdc_ellipsoid<CalculationType, Parameters>(par) + inline eqdc_ellipsoid(const Parameters& par) : detail::eqdc::base_eqdc_ellipsoid<T, Parameters>(par) { detail::eqdc::setup_eqdc(this->m_par, this->m_proj_parm); } @@ -223,20 +209,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eqdc, eqdc_ellipsoid, eqdc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class eqdc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eqdc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eqdc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eqdc_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void eqdc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void eqdc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("eqdc", new eqdc_entry<CalculationType, Parameters>); + factory.add_to_factory("eqdc", new eqdc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/etmerc.hpp b/boost/geometry/srs/projections/proj/etmerc.hpp index 479c128f11..050aafacca 100644 --- a/boost/geometry/srs/projections/proj/etmerc.hpp +++ b/boost/geometry/srs/projections/proj/etmerc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -43,12 +39,28 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +/* The code in this file is largly based upon procedures: + * + * Written by: Knud Poder and Karsten Engsager + * + * Based on math from: R.Koenig and K.H. Weise, "Mathematische + * Grundlagen der hoeheren Geodaesie und Kartographie, + * Springer-Verlag, Berlin/Goettingen" Heidelberg, 1951. + * + * Modified and used here by permission of Reference Networks + * Division, Kort og Matrikelstyrelsen (KMS), Copenhagen, Denmark +*/ + +#ifndef BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP + #include <boost/math/special_functions/hypot.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> #include <boost/geometry/srs/projections/impl/factory_entry.hpp> +#include <boost/geometry/srs/projections/impl/function_overloads.hpp> namespace boost { namespace geometry { @@ -56,6 +68,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { struct etmerc {}; + struct utm {}; }} //namespace srs::par4 @@ -78,25 +91,8 @@ namespace projections T gtu[6]; /* Constants for geo -> transv. merc. */ }; - /* The code in this file is largly based upon procedures: - * - * Written by: Knud Poder and Karsten Engsager - * - * Based on math from: R.Koenig and K.H. Weise, "Mathematische - * Grundlagen der hoeheren Geodaesie und Kartographie, - * Springer-Verlag, Berlin/Goettingen" Heidelberg, 1951. - * - * Modified and used here by permission of Reference Networks - * Division, Kort og Matrikelstyrelsen (KMS), Copenhagen, Denmark - */ - - - - - template <typename T> - inline T - log1py(T const& x) { /* Compute log(1+x) accurately */ + inline T log1py(T const& x) { /* Compute log(1+x) accurately */ volatile T y = 1 + x, z = y - 1; @@ -108,16 +104,14 @@ namespace projections } template <typename T> - inline T - asinhy(T const& x) { /* Compute asinh(x) accurately */ + inline T asinhy(T const& x) { /* Compute asinh(x) accurately */ T y = fabs(x); /* Enforce odd parity */ y = log1py(y * (1 + y/(boost::math::hypot(1.0, y) + 1))); return x < 0 ? -y : y; } template <typename T> - inline T - gatg(const T *p1, int len_p1, T const& B) { + inline T gatg(const T *p1, int len_p1, T const& B) { const T *p; T h = 0, h1, h2 = 0, cos_2B; @@ -127,9 +121,9 @@ namespace projections return (B + h*sin(2*B)); } + /* Complex Clenshaw summation */ template <typename T> - inline T - clenS(const T *a, int size, T const& arg_r, T const& arg_i, T *R, T *I) { + inline T clenS(const T *a, int size, T const& arg_r, T const& arg_i, T *R, T *I) { T r, i, hr, hr1, hr2, hi, hi1, hi2; T sin_arg_r, cos_arg_r, sinh_arg_i, cosh_arg_i; @@ -157,14 +151,15 @@ namespace projections return(*R); } + /* Real Clenshaw summation */ template <typename T> - inline T - clens(const T *a, int size, T const& arg_r) { + inline T clens(const T *a, int size, T const& arg_r) { T r, hr, hr1, hr2, cos_arg_r; const T* p = a + size; cos_arg_r = cos(arg_r); r = 2*cos_arg_r; + /* summation loop */ for (hr1 = 0, hr = *--p; a - p;) { hr2 = hr1; @@ -175,26 +170,22 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_etmerc_ellipsoid : public base_t_fi<base_etmerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_etmerc_ellipsoid + : public base_t_fi<base_etmerc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_etmerc<CalculationType> m_proj_parm; + par_etmerc<T> m_proj_parm; inline base_etmerc_ellipsoid(const Parameters& par) - : base_t_fi<base_etmerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_etmerc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; - CalculationType Cn = lp_lat, Ce = lp_lon; + T sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; + T Cn = lp_lat, Ce = lp_lon; /* ell. LAT, LNG -> Gaussian LAT, LNG */ Cn = gatg(this->m_proj_parm.cbg, PROJ_ETMERC_ORDER, Cn); @@ -206,8 +197,9 @@ namespace projections Cn = atan2(sin_Cn, cos_Ce*cos_Cn); Ce = atan2(sin_Ce*cos_Cn, boost::math::hypot(sin_Cn, cos_Cn*cos_Ce)); + /* compl. sph. N, E -> ell. norm. N, E */ - Ce = asinhy(tan(Ce)); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */ + Ce = asinhy(tan(Ce)); /* Replaces: Ce = log(tan(fourth_pi + Ce*0.5)); */ Cn += clenS(this->m_proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe); Ce += dCe; if (fabs(Ce) <= 2.623395162778) { @@ -219,19 +211,20 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; - CalculationType Cn = xy_y, Ce = xy_x; + T sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; + T Cn = xy_y, Ce = xy_x; /* normalize N, E */ Cn = (Cn - this->m_proj_parm.Zb)/this->m_proj_parm.Qn; Ce = Ce/this->m_proj_parm.Qn; + if (fabs(Ce) <= 2.623395162778) { /* 150 degrees */ - /* norm. N, E -> compl. sph. LAT, LNG */ + /* norm. N, E -> compl. sph. LAT, LNG */ Cn += clenS(this->m_proj_parm.utg, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe); Ce += dCe; - Ce = atan(sinh(Ce)); /* Replaces: Ce = 2*(atan(exp(Ce)) - FORTPI); */ + Ce = atan(sinh(Ce)); /* Replaces: Ce = 2*(atan(exp(Ce)) - fourth_pi); */ /* compl. sph. LAT -> Gaussian LAT, LNG */ sin_Cn = sin(Cn); cos_Cn = cos(Cn); @@ -254,15 +247,17 @@ namespace projections }; - // Extended Transverse Mercator template <typename Parameters, typename T> - inline void setup_etmerc(Parameters& par, par_etmerc<T>& proj_parm) + inline void setup(Parameters& par, par_etmerc<T>& proj_parm) { T f, n, np, Z; - if (par.es <= 0) - BOOST_THROW_EXCEPTION( projection_exception(-34) ); + if (par.es <= 0) { + BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) ); + } + f = par.es / (1 + sqrt(1 - par.es)); /* Replaces: f = 1 - sqrt(1-par.es); */ + /* third flattening */ np = n = f/(2 - f); @@ -270,6 +265,7 @@ namespace projections /* cgb := Gaussian -> Geodetic, KW p190 - 191 (61) - (62) */ /* cbg := Geodetic -> Gaussian, KW p186 - 187 (51) - (52) */ /* PROJ_ETMERC_ORDER = 6th degree : Engsager and Poder: ICC2007 */ + proj_parm.cgb[0] = n*( 2 + n*(-2/3.0 + n*(-2 + n*(116/45.0 + n*(26/45.0 + n*(-2854/675.0 )))))); proj_parm.cbg[0] = n*(-2 + n*( 2/3.0 + n*( 4/3.0 + n*(-82/45.0 + n*(32/45.0 + @@ -326,13 +322,59 @@ namespace projections np *= n; proj_parm.utg[5] = np*(-20648693/638668800.0); proj_parm.gtu[5] = np*(212378941/319334400.0); + /* Gaussian latitude value of the origin latitude */ Z = gatg(proj_parm.cbg, PROJ_ETMERC_ORDER, par.phi0); + /* Origin northing minus true northing at the origin latitude */ /* i.e. true northing = N - proj_parm.Zb */ proj_parm.Zb = - proj_parm.Qn*(Z + clens(proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Z)); } + // Extended Transverse Mercator + template <typename Parameters, typename T> + inline void setup_etmerc(Parameters& par, par_etmerc<T>& proj_parm) + { + setup(par, proj_parm); + } + + // Universal Transverse Mercator (UTM) + template <typename Parameters, typename T> + inline void setup_utm(Parameters& par, par_etmerc<T>& proj_parm) + { + static const T pi = detail::pi<T>(); + + int zone; + + if (par.es == 0.0) { + BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) ); + } + + par.y0 = pj_get_param_b(par.params, "south") ? 10000000. : 0.; + par.x0 = 500000.; + if (pj_param_i(par.params, "zone", zone)) /* zone input ? */ + { + if (zone > 0 && zone <= 60) + --zone; + else { + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_utm_zone) ); + } + } + else /* nearest central meridian input */ + { + zone = int_floor((adjlon(par.lam0) + pi) * 30. / pi); + if (zone < 0) + zone = 0; + else if (zone >= 60) + zone = 59; + } + par.lam0 = (zone + .5) * pi / 30. - pi; + par.k0 = 0.9996; + par.phi0 = 0.; + + setup(par, proj_parm); + } + }} // namespace detail::etmerc #endif // doxygen @@ -351,37 +393,73 @@ namespace projections \par Example \image html ex_etmerc.gif */ - template <typename CalculationType, typename Parameters> - struct etmerc_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct etmerc_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid<T, Parameters> { - inline etmerc_ellipsoid(const Parameters& par) : detail::etmerc::base_etmerc_ellipsoid<CalculationType, Parameters>(par) + inline etmerc_ellipsoid(const Parameters& par) : detail::etmerc::base_etmerc_ellipsoid<T, Parameters>(par) { detail::etmerc::setup_etmerc(this->m_par, this->m_proj_parm); } }; + /*! + \brief Universal Transverse Mercator (UTM) projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Cylindrical + - Spheroid + \par Projection parameters + - zone: UTM Zone (integer) + - south: Denotes southern hemisphere UTM zone (boolean) + \par Example + \image html ex_utm.gif + */ + template <typename T, typename Parameters> + struct utm_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid<T, Parameters> + { + inline utm_ellipsoid(const Parameters& par) : detail::etmerc::base_etmerc_ellipsoid<T, Parameters>(par) + { + detail::etmerc::setup_utm(this->m_par, this->m_proj_parm); + } + }; + #ifndef DOXYGEN_NO_DETAIL namespace detail { // Static projection BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::etmerc, etmerc_ellipsoid, etmerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::utm, utm_ellipsoid, utm_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class etmerc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class etmerc_entry : public detail::factory_entry<T, Parameters> + { + public : + virtual base_v<T, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<etmerc_ellipsoid<T, Parameters>, T, Parameters>(par); + } + }; + + template <typename T, typename Parameters> + class utm_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<etmerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<utm_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void etmerc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void etmerc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("etmerc", new etmerc_entry<CalculationType, Parameters>); + factory.add_to_factory("etmerc", new etmerc_entry<T, Parameters>); + factory.add_to_factory("utm", new utm_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/fahey.hpp b/boost/geometry/srs/projections/proj/fahey.hpp index 8ea43ee94b..8438b5dad3 100644 --- a/boost/geometry/srs/projections/proj/fahey.hpp +++ b/boost/geometry/srs/projections/proj/fahey.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct fahey {}; + struct fahey {}; // Fahey }} //namespace srs::par4 @@ -62,37 +61,34 @@ namespace projections namespace detail { namespace fahey { - static const double TOL = 1e-6; + static const double tolerance = 1e-6; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_fahey_spheroid : public base_t_fi<base_fahey_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_fahey_spheroid + : public base_t_fi<base_fahey_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_fahey_spheroid(const Parameters& par) - : base_t_fi<base_fahey_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_fahey_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - xy_y = 1.819152 * ( xy_x = tan(0.5 * lp_lat) ); + xy_x = tan(0.5 * lp_lat); + xy_y = 1.819152 * xy_x; xy_x = 0.819152 * lp_lon * asqrt(1 - xy_x * xy_x); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - lp_lat = 2. * atan(xy_y /= 1.819152); - lp_lon = fabs(xy_y = 1. - xy_y * xy_y) < TOL ? 0. : - xy_x / (0.819152 * sqrt(xy_y)); + xy_y /= 1.819152; + lp_lat = 2. * atan(xy_y); + xy_y = 1. - xy_y * xy_y; + lp_lon = fabs(xy_y) < tolerance ? 0. : xy_x / (0.819152 * sqrt(xy_y)); } static inline std::string get_name() @@ -124,10 +120,10 @@ namespace projections \par Example \image html ex_fahey.gif */ - template <typename CalculationType, typename Parameters> - struct fahey_spheroid : public detail::fahey::base_fahey_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct fahey_spheroid : public detail::fahey::base_fahey_spheroid<T, Parameters> { - inline fahey_spheroid(const Parameters& par) : detail::fahey::base_fahey_spheroid<CalculationType, Parameters>(par) + inline fahey_spheroid(const Parameters& par) : detail::fahey::base_fahey_spheroid<T, Parameters>(par) { detail::fahey::setup_fahey(this->m_par); } @@ -141,20 +137,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fahey, fahey_spheroid, fahey_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class fahey_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class fahey_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<fahey_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<fahey_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void fahey_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void fahey_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("fahey", new fahey_entry<CalculationType, Parameters>); + factory.add_to_factory("fahey", new fahey_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/fouc_s.hpp b/boost/geometry/srs/projections/proj/fouc_s.hpp index 0f34593161..580bc1804b 100644 --- a/boost/geometry/srs/projections/proj/fouc_s.hpp +++ b/boost/geometry/srs/projections/proj/fouc_s.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP -#define BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP +#define BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct fouc_s {}; + struct fouc_s {}; // Foucaut Sinusoidal }} //namespace srs::par4 @@ -64,8 +63,8 @@ namespace projections namespace detail { namespace fouc_s { - static const int MAX_ITER = 10; - static const double LOOP_TOL = 1e-7; + static const int max_iter = 10; + static const double loop_tol = 1e-7; template <typename T> struct par_fouc_s @@ -74,25 +73,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_fouc_s_spheroid : public base_t_fi<base_fouc_s_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_fouc_s_spheroid + : public base_t_fi<base_fouc_s_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_fouc_s<CalculationType> m_proj_parm; + par_fouc_s<T> m_proj_parm; inline base_fouc_s_spheroid(const Parameters& par) - : base_t_fi<base_fouc_s_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_fouc_s_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType t; + T t; t = cos(lp_lat); xy_x = lp_lon * t / (this->m_proj_parm.n + this->m_proj_parm.n1 * t); @@ -101,21 +96,23 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType V; + static T const half_pi = detail::half_pi<T>(); + + T V; int i; - if (this->m_proj_parm.n) { + if (this->m_proj_parm.n != 0.0) { lp_lat = xy_y; - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { lp_lat -= V = (this->m_proj_parm.n * lp_lat + this->m_proj_parm.n1 * sin(lp_lat) - xy_y ) / (this->m_proj_parm.n + this->m_proj_parm.n1 * cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } if (!i) - lp_lat = xy_y < 0. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>(); + lp_lat = xy_y < 0. ? -half_pi : half_pi; } else lp_lat = aasin(xy_y); V = cos(lp_lat); @@ -133,9 +130,10 @@ namespace projections template <typename Parameters, typename T> inline void setup_fouc_s(Parameters& par, par_fouc_s<T>& proj_parm) { - proj_parm.n = pj_param(par.params, "dn").f; + proj_parm.n = pj_get_param_f(par.params, "n"); if (proj_parm.n < 0. || proj_parm.n > 1.) - BOOST_THROW_EXCEPTION( projection_exception(-99) ); + BOOST_THROW_EXCEPTION( projection_exception(error_n_out_of_range) ); + proj_parm.n1 = 1. - proj_parm.n; par.es = 0; } @@ -157,10 +155,10 @@ namespace projections \par Example \image html ex_fouc_s.gif */ - template <typename CalculationType, typename Parameters> - struct fouc_s_spheroid : public detail::fouc_s::base_fouc_s_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct fouc_s_spheroid : public detail::fouc_s::base_fouc_s_spheroid<T, Parameters> { - inline fouc_s_spheroid(const Parameters& par) : detail::fouc_s::base_fouc_s_spheroid<CalculationType, Parameters>(par) + inline fouc_s_spheroid(const Parameters& par) : detail::fouc_s::base_fouc_s_spheroid<T, Parameters>(par) { detail::fouc_s::setup_fouc_s(this->m_par, this->m_proj_parm); } @@ -174,20 +172,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fouc_s, fouc_s_spheroid, fouc_s_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class fouc_s_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class fouc_s_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<fouc_s_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<fouc_s_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void fouc_s_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void fouc_s_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("fouc_s", new fouc_s_entry<CalculationType, Parameters>); + factory.add_to_factory("fouc_s", new fouc_s_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/gall.hpp b/boost/geometry/srs/projections/proj/gall.hpp index fc1ad144d7..2c35c60985 100644 --- a/boost/geometry/srs/projections/proj/gall.hpp +++ b/boost/geometry/srs/projections/proj/gall.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GALL_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GALL_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GALL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GALL_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct gall {}; + struct gall {}; // Gall (Gall Stereographic) }} //namespace srs::par4 @@ -67,22 +66,17 @@ namespace projections static const double RXF = 1.41421356237309504880; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gall_spheroid : public base_t_fi<base_gall_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gall_spheroid + : public base_t_fi<base_gall_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_gall_spheroid(const Parameters& par) - : base_t_fi<base_gall_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_gall_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = XF * lp_lon; xy_y = YF * tan(.5 * lp_lat); @@ -90,7 +84,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = RXF * xy_x; lp_lat = 2. * atan(xy_y * RYF); @@ -107,7 +101,7 @@ namespace projections template <typename Parameters> inline void setup_gall(Parameters& par) { - par.es = 0.; + par.es = 0.0; } }} // namespace detail::gall @@ -125,10 +119,10 @@ namespace projections \par Example \image html ex_gall.gif */ - template <typename CalculationType, typename Parameters> - struct gall_spheroid : public detail::gall::base_gall_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gall_spheroid : public detail::gall::base_gall_spheroid<T, Parameters> { - inline gall_spheroid(const Parameters& par) : detail::gall::base_gall_spheroid<CalculationType, Parameters>(par) + inline gall_spheroid(const Parameters& par) : detail::gall::base_gall_spheroid<T, Parameters>(par) { detail::gall::setup_gall(this->m_par); } @@ -142,20 +136,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gall, gall_spheroid, gall_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class gall_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gall_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gall_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gall_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void gall_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void gall_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("gall", new gall_entry<CalculationType, Parameters>); + factory.add_to_factory("gall", new gall_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/geocent.hpp b/boost/geometry/srs/projections/proj/geocent.hpp index bfcbb145fa..92fd8e1070 100644 --- a/boost/geometry/srs/projections/proj/geocent.hpp +++ b/boost/geometry/srs/projections/proj/geocent.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,13 +15,13 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Stub projection for geocentric. The transformation isn't -// really done here since this code is 2D. The real transformation -// is handled by pj_transform.c. +// really done here since this code is 2D. The real transformation +// is handled by pj_transform.c. // Author: Frank Warmerdam, warmerdam@pobox.com // Copyright (c) 2002, Frank Warmerdam @@ -47,6 +43,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -57,7 +56,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct geocent {}; + struct geocent {}; // Geocentric }} //namespace srs::par4 @@ -68,22 +67,17 @@ namespace projections { // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_geocent_other : public base_t_fi<base_geocent_other<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_geocent_other + : public base_t_fi<base_geocent_other<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_geocent_other(const Parameters& par) - : base_t_fi<base_geocent_other<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_geocent_other<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = lp_lon; xy_y = lp_lat; @@ -91,7 +85,7 @@ namespace projections // INVERSE(inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y; lp_lon = xy_x; @@ -125,10 +119,10 @@ namespace projections \par Example \image html ex_geocent.gif */ - template <typename CalculationType, typename Parameters> - struct geocent_other : public detail::geocent::base_geocent_other<CalculationType, Parameters> + template <typename T, typename Parameters> + struct geocent_other : public detail::geocent::base_geocent_other<T, Parameters> { - inline geocent_other(const Parameters& par) : detail::geocent::base_geocent_other<CalculationType, Parameters>(par) + inline geocent_other(const Parameters& par) : detail::geocent::base_geocent_other<T, Parameters>(par) { detail::geocent::setup_geocent(this->m_par); } @@ -142,20 +136,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::geocent, geocent_other, geocent_other) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class geocent_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class geocent_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<geocent_other<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<geocent_other<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void geocent_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void geocent_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("geocent", new geocent_entry<CalculationType, Parameters>); + factory.add_to_factory("geocent", new geocent_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/geos.hpp b/boost/geometry/srs/projections/proj/geos.hpp index 798f7f6247..905411f766 100644 --- a/boost/geometry/srs/projections/proj/geos.hpp +++ b/boost/geometry/srs/projections/proj/geos.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,14 +15,15 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Copyright (c) 2004 Gerald I. Evenden // Copyright (c) 2012 Martin Raspaud + // See also (section 4.4.3.2): -// http://www.eumetsat.int/en/area4/msg/news/us_doc/cgms_03_26.pdf +// http://www.eumetsat.int/en/area4/msg/news/us_doc/cgms_03_26.pdf // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -46,6 +43,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP + #include <boost/math/special_functions/hypot.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -58,7 +58,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct geos {}; + struct geos {}; // Geostationary Satellite View }} //namespace srs::par4 @@ -77,87 +77,86 @@ namespace projections T radius_g; T radius_g_1; T C; - std::string sweep_axis; int flip_axis; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_geos_ellipsoid : public base_t_fi<base_geos_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_geos_ellipsoid + : public base_t_fi<base_geos_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_geos<CalculationType> m_proj_parm; + par_geos<T> m_proj_parm; inline base_geos_ellipsoid(const Parameters& par) - : base_t_fi<base_geos_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_geos_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType r, Vx, Vy, Vz, tmp; + T r, Vx, Vy, Vz, tmp; - /* Calculation of geocentric latitude. */ + /* Calculation of geocentric latitude. */ lp_lat = atan (this->m_proj_parm.radius_p2 * tan (lp_lat)); - /* Calculation of the three components of the vector from satellite to - ** position on earth surface (lon,lat).*/ + + /* Calculation of the three components of the vector from satellite to + ** position on earth surface (lon,lat).*/ r = (this->m_proj_parm.radius_p) / boost::math::hypot(this->m_proj_parm.radius_p * cos (lp_lat), sin (lp_lat)); Vx = r * cos (lp_lon) * cos (lp_lat); Vy = r * sin (lp_lon) * cos (lp_lat); Vz = r * sin (lp_lat); - /* Check visibility. */ - if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz * this->m_proj_parm.radius_p_inv2) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - /* Calculation based on view angles from satellite. */ + + /* Check visibility. */ + if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz * this->m_proj_parm.radius_p_inv2) < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + + /* Calculation based on view angles from satellite. */ tmp = this->m_proj_parm.radius_g - Vx; - if(this->m_proj_parm.flip_axis) - { - xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / boost::math::hypot (Vz, tmp)); - xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / tmp); - } - else - { - xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / tmp); - xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / boost::math::hypot (Vy, tmp)); - } + + if(this->m_proj_parm.flip_axis) { + xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / boost::math::hypot (Vz, tmp)); + xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / tmp); + } else { + xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / tmp); + xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / boost::math::hypot (Vy, tmp)); + } } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType Vx, Vy, Vz, a, b, det, k; + T Vx, Vy, Vz, a, b, det, k; - /* Setting three components of vector from satellite to position.*/ + /* Setting three components of vector from satellite to position.*/ Vx = -1.0; - if(this->m_proj_parm.flip_axis) - { - Vz = tan (xy_y / this->m_proj_parm.radius_g_1); - Vy = tan (xy_x / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vz); - } - else - { - Vy = tan (xy_x / this->m_proj_parm.radius_g_1); - Vz = tan (xy_y / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vy); - } - /* Calculation of terms in cubic equation and determinant.*/ + + if(this->m_proj_parm.flip_axis) { + Vz = tan (xy_y / this->m_proj_parm.radius_g_1); + Vy = tan (xy_x / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vz); + } else { + Vy = tan (xy_x / this->m_proj_parm.radius_g_1); + Vz = tan (xy_y / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vy); + } + + /* Calculation of terms in cubic equation and determinant.*/ a = Vz / this->m_proj_parm.radius_p; a = Vy * Vy + a * a + Vx * Vx; b = 2 * this->m_proj_parm.radius_g * Vx; - if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - /* Calculation of three components of vector from satellite to position.*/ + if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + + /* Calculation of three components of vector from satellite to position.*/ k = (-b - sqrt(det)) / (2. * a); Vx = this->m_proj_parm.radius_g + k * Vx; Vy *= k; Vz *= k; - /* Calculation of longitude and latitude.*/ - lp_lon = atan2 (Vy, Vx); + + /* Calculation of longitude and latitude.*/ + lp_lon = atan2 (Vy, Vx); lp_lat = atan (Vz * cos (lp_lon) / Vx); lp_lat = atan (this->m_proj_parm.radius_p_inv2 * tan (lp_lat)); } @@ -170,78 +169,76 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_geos_spheroid : public base_t_fi<base_geos_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_geos_spheroid + : public base_t_fi<base_geos_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_geos<CalculationType> m_proj_parm; + par_geos<T> m_proj_parm; inline base_geos_spheroid(const Parameters& par) - : base_t_fi<base_geos_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_geos_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType Vx, Vy, Vz, tmp; + T Vx, Vy, Vz, tmp; - /* Calculation of the three components of the vector from satellite to - ** position on earth surface (lon,lat).*/ + /* Calculation of the three components of the vector from satellite to + ** position on earth surface (lon,lat).*/ tmp = cos(lp_lat); Vx = cos (lp_lon) * tmp; Vy = sin (lp_lon) * tmp; Vz = sin (lp_lat); - /* Check visibility.*/ + + /* Check visibility.*/ + // TODO: in proj4 5.0.0 this check is not present if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - /* Calculation based on view angles from satellite.*/ + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + + /* Calculation based on view angles from satellite.*/ tmp = this->m_proj_parm.radius_g - Vx; - if(this->m_proj_parm.flip_axis) - { - xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / boost::math::hypot(Vz, tmp)); - xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / tmp); - } - else - { - xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / tmp); - xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / boost::math::hypot(Vy, tmp)); - } + + if(this->m_proj_parm.flip_axis) { + xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / boost::math::hypot(Vz, tmp)); + xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / tmp); + } else { + xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / tmp); + xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / boost::math::hypot(Vy, tmp)); + } } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType Vx, Vy, Vz, a, b, det, k; + T Vx, Vy, Vz, a, b, det, k; - /* Setting three components of vector from satellite to position.*/ + /* Setting three components of vector from satellite to position.*/ Vx = -1.0; - if(this->m_proj_parm.flip_axis) - { - Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)); - Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vz * Vz); - } - else - { - Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)); - Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vy * Vy); - } - /* Calculation of terms in cubic equation and determinant.*/ + if(this->m_proj_parm.flip_axis) { + Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)); + Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vz * Vz); + } else { + Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)); + Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vy * Vy); + } + + /* Calculation of terms in cubic equation and determinant.*/ a = Vy * Vy + Vz * Vz + Vx * Vx; b = 2 * this->m_proj_parm.radius_g * Vx; - if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - /* Calculation of three components of vector from satellite to position.*/ + if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + + /* Calculation of three components of vector from satellite to position.*/ k = (-b - sqrt(det)) / (2 * a); Vx = this->m_proj_parm.radius_g + k * Vx; Vy *= k; Vz *= k; - /* Calculation of longitude and latitude.*/ + + /* Calculation of longitude and latitude.*/ lp_lon = atan2 (Vy, Vx); lp_lat = atan (Vz * cos (lp_lon) / Vx); } @@ -257,27 +254,31 @@ namespace projections template <typename Parameters, typename T> inline void setup_geos(Parameters& par, par_geos<T>& proj_parm) { - if ((proj_parm.h = pj_param(par.params, "dh").f) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-30) ); - if (par.phi0) - BOOST_THROW_EXCEPTION( projection_exception(-46) ); - proj_parm.sweep_axis = pj_param(par.params, "ssweep").s; - if (proj_parm.sweep_axis.empty()) + std::string sweep_axis; + + if ((proj_parm.h = pj_get_param_f(par.params, "h")) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_h_less_than_zero) ); + + if (par.phi0 != 0.0) + BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) ); + + sweep_axis = pj_get_param_s(par.params, "sweep"); + if (sweep_axis.empty()) proj_parm.flip_axis = 0; else { - if (proj_parm.sweep_axis[1] != '\0' || - (proj_parm.sweep_axis[0] != 'x' && - proj_parm.sweep_axis[0] != 'y')) - BOOST_THROW_EXCEPTION( projection_exception(-49) ); - if (proj_parm.sweep_axis[0] == 'x') + if (sweep_axis[1] != '\0' || (sweep_axis[0] != 'x' && sweep_axis[0] != 'y')) + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_sweep_axis) ); + + if (sweep_axis[0] == 'x') proj_parm.flip_axis = 1; else proj_parm.flip_axis = 0; } + proj_parm.radius_g_1 = proj_parm.h / par.a; proj_parm.radius_g = 1. + proj_parm.radius_g_1; proj_parm.C = proj_parm.radius_g * proj_parm.radius_g - 1.0; - if (par.es) { + if (par.es != 0.0) { proj_parm.radius_p = sqrt (par.one_es); proj_parm.radius_p2 = par.one_es; proj_parm.radius_p_inv2 = par.rone_es; @@ -305,10 +306,10 @@ namespace projections \par Example \image html ex_geos.gif */ - template <typename CalculationType, typename Parameters> - struct geos_ellipsoid : public detail::geos::base_geos_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct geos_ellipsoid : public detail::geos::base_geos_ellipsoid<T, Parameters> { - inline geos_ellipsoid(const Parameters& par) : detail::geos::base_geos_ellipsoid<CalculationType, Parameters>(par) + inline geos_ellipsoid(const Parameters& par) : detail::geos::base_geos_ellipsoid<T, Parameters>(par) { detail::geos::setup_geos(this->m_par, this->m_proj_parm); } @@ -330,10 +331,10 @@ namespace projections \par Example \image html ex_geos.gif */ - template <typename CalculationType, typename Parameters> - struct geos_spheroid : public detail::geos::base_geos_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct geos_spheroid : public detail::geos::base_geos_spheroid<T, Parameters> { - inline geos_spheroid(const Parameters& par) : detail::geos::base_geos_spheroid<CalculationType, Parameters>(par) + inline geos_spheroid(const Parameters& par) : detail::geos::base_geos_spheroid<T, Parameters>(par) { detail::geos::setup_geos(this->m_par, this->m_proj_parm); } @@ -347,23 +348,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::geos, geos_spheroid, geos_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class geos_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class geos_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<geos_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<geos_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<geos_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<geos_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void geos_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void geos_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("geos", new geos_entry<CalculationType, Parameters>); + factory.add_to_factory("geos", new geos_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/gins8.hpp b/boost/geometry/srs/projections/proj/gins8.hpp index f6c0059b07..5cdc933943 100644 --- a/boost/geometry/srs/projections/proj/gins8.hpp +++ b/boost/geometry/srs/projections/proj/gins8.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct gins8 {}; + struct gins8 {}; // Ginsburg VIII (TsNIIGAiK) }} //namespace srs::par4 @@ -69,26 +68,21 @@ namespace projections inline T C12() { return 0.083333333333333333333333333333333333; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gins8_spheroid : public base_t_f<base_gins8_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gins8_spheroid + : public base_t_f<base_gins8_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_gins8_spheroid(const Parameters& par) - : base_t_f<base_gins8_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_gins8_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType C12 = gins8::C12<CalculationType>(); + static const T C12 = gins8::C12<T>(); - CalculationType t = lp_lat * lp_lat; + T t = lp_lat * lp_lat; xy_y = lp_lat * (1. + t * C12); xy_x = lp_lon * (1. - Cp * t); @@ -126,10 +120,10 @@ namespace projections \par Example \image html ex_gins8.gif */ - template <typename CalculationType, typename Parameters> - struct gins8_spheroid : public detail::gins8::base_gins8_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gins8_spheroid : public detail::gins8::base_gins8_spheroid<T, Parameters> { - inline gins8_spheroid(const Parameters& par) : detail::gins8::base_gins8_spheroid<CalculationType, Parameters>(par) + inline gins8_spheroid(const Parameters& par) : detail::gins8::base_gins8_spheroid<T, Parameters>(par) { detail::gins8::setup_gins8(this->m_par); } @@ -143,20 +137,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gins8, gins8_spheroid, gins8_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class gins8_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gins8_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<gins8_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<gins8_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void gins8_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void gins8_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("gins8", new gins8_entry<CalculationType, Parameters>); + factory.add_to_factory("gins8", new gins8_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/gn_sinu.hpp b/boost/geometry/srs/projections/proj/gn_sinu.hpp index c41b278255..2a8e82bdc5 100644 --- a/boost/geometry/srs/projections/proj/gn_sinu.hpp +++ b/boost/geometry/srs/projections/proj/gn_sinu.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -55,10 +54,10 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct gn_sinu {}; - struct sinu {}; - struct eck6 {}; - struct mbtfps {}; + struct gn_sinu {}; // General Sinusoidal Series + struct sinu {}; // Sinusoidal (Sanson-Flamsteed) + struct eck6 {}; // Eckert VI + struct mbtfps {}; // McBryde-Thomas Flat-Polar Sinusoidal }} //namespace srs::par4 @@ -68,39 +67,35 @@ namespace projections namespace detail { namespace gn_sinu { - static const double EPS10 = 1e-10; - static const int MAX_ITER = 8; - static const double LOOP_TOL = 1e-7; + static const double epsilon10 = 1e-10; + static const int max_iter = 8; + static const double loop_tol = 1e-7; template <typename T> struct par_gn_sinu { - T en[EN_SIZE]; + detail::en<T> en; T m, n, C_x, C_y; }; /* Ellipsoidal Sinusoidal only */ // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gn_sinu_ellipsoid : public base_t_fi<base_gn_sinu_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gn_sinu_ellipsoid + : public base_t_fi<base_gn_sinu_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_gn_sinu<CalculationType> m_proj_parm; + par_gn_sinu<T> m_proj_parm; inline base_gn_sinu_ellipsoid(const Parameters& par) - : base_t_fi<base_gn_sinu_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_gn_sinu_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType s, c; + T s, c; xy_y = pj_mlfn(lp_lat, s = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en); xy_x = lp_lon * c / sqrt(1. - this->m_par.es * s * s); @@ -108,19 +103,19 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType s; + T s; - if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < HALFPI) { + if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < half_pi) { s = sin(lp_lat); lp_lon = xy_x * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat); - } else if ((s - EPS10) < HALFPI) + } else if ((s - epsilon10) < half_pi) lp_lon = 0.; else - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } /* General spherical sinusoidals */ @@ -132,39 +127,36 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gn_sinu_spheroid : public base_t_fi<base_gn_sinu_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gn_sinu_spheroid + : public base_t_fi<base_gn_sinu_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_gn_sinu<CalculationType> m_proj_parm; + par_gn_sinu<T> m_proj_parm; inline base_gn_sinu_spheroid(const Parameters& par) - : base_t_fi<base_gn_sinu_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_gn_sinu_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - if (!this->m_proj_parm.m) + if (this->m_proj_parm.m == 0.0) lp_lat = this->m_proj_parm.n != 1. ? aasin(this->m_proj_parm.n * sin(lp_lat)): lp_lat; else { - CalculationType k, V; + T k, V; int i; k = this->m_proj_parm.n * sin(lp_lat); - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { lp_lat -= V = (this->m_proj_parm.m * lp_lat + sin(lp_lat) - k) / (this->m_proj_parm.m + cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } - if (!i) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (!i) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } } xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.m + cos(lp_lat)); xy_y = this->m_proj_parm.C_y * lp_lat; @@ -172,10 +164,10 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { xy_y /= this->m_proj_parm.C_y; - lp_lat = this->m_proj_parm.m ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) : + lp_lat = (this->m_proj_parm.m != 0.0) ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) : ( this->m_proj_parm.n != 1. ? aasin(sin(xy_y) / this->m_proj_parm.n) : xy_y ); lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.m + cos(xy_y))); } @@ -191,6 +183,7 @@ namespace projections inline void setup(Parameters& par, par_gn_sinu<T>& proj_parm) { par.es = 0; + proj_parm.C_x = (proj_parm.C_y = sqrt((proj_parm.m + 1.) / proj_parm.n))/(proj_parm.m + 1.); } @@ -199,11 +192,13 @@ namespace projections template <typename Parameters, typename T> inline void setup_gn_sinu(Parameters& par, par_gn_sinu<T>& proj_parm) { - if (pj_param(par.params, "tn").i && pj_param(par.params, "tm").i) { - proj_parm.n = pj_param(par.params, "dn").f; - proj_parm.m = pj_param(par.params, "dm").f; + if (pj_param_f(par.params, "n", proj_parm.n) + && pj_param_f(par.params, "m", proj_parm.m)) { + if (proj_parm.n <= 0 || proj_parm.m < 0) + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) ); } else - BOOST_THROW_EXCEPTION( projection_exception(-99) ); + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) ); + setup(par, proj_parm); } @@ -211,9 +206,10 @@ namespace projections template <typename Parameters, typename T> inline void setup_sinu(Parameters& par, par_gn_sinu<T>& proj_parm) { - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); - if (par.es) { + proj_parm.en = pj_enfn<T>(par.es); + + if (par.es != 0.0) { + /* empty */ } else { proj_parm.n = 1.; proj_parm.m = 0.; @@ -257,10 +253,10 @@ namespace projections \par Example \image html ex_gn_sinu.gif */ - template <typename CalculationType, typename Parameters> - struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters> { - inline gn_sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par) + inline gn_sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>(par) { detail::gn_sinu::setup_gn_sinu(this->m_par, this->m_proj_parm); } @@ -279,10 +275,10 @@ namespace projections \par Example \image html ex_sinu.gif */ - template <typename CalculationType, typename Parameters> - struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid<T, Parameters> { - inline sinu_ellipsoid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_ellipsoid<CalculationType, Parameters>(par) + inline sinu_ellipsoid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_ellipsoid<T, Parameters>(par) { detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm); } @@ -301,10 +297,10 @@ namespace projections \par Example \image html ex_sinu.gif */ - template <typename CalculationType, typename Parameters> - struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters> { - inline sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par) + inline sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>(par) { detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm); } @@ -322,10 +318,10 @@ namespace projections \par Example \image html ex_eck6.gif */ - template <typename CalculationType, typename Parameters> - struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters> { - inline eck6_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par) + inline eck6_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>(par) { detail::gn_sinu::setup_eck6(this->m_par, this->m_proj_parm); } @@ -343,10 +339,10 @@ namespace projections \par Example \image html ex_mbtfps.gif */ - template <typename CalculationType, typename Parameters> - struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters> { - inline mbtfps_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par) + inline mbtfps_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>(par) { detail::gn_sinu::setup_mbtfps(this->m_par, this->m_proj_parm); } @@ -363,56 +359,56 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfps, mbtfps_spheroid, mbtfps_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class gn_sinu_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gn_sinu_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gn_sinu_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gn_sinu_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class sinu_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class sinu_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<sinu_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<sinu_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<sinu_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<sinu_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class eck6_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class eck6_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<eck6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<eck6_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class mbtfps_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mbtfps_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mbtfps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mbtfps_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void gn_sinu_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void gn_sinu_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("gn_sinu", new gn_sinu_entry<CalculationType, Parameters>); - factory.add_to_factory("sinu", new sinu_entry<CalculationType, Parameters>); - factory.add_to_factory("eck6", new eck6_entry<CalculationType, Parameters>); - factory.add_to_factory("mbtfps", new mbtfps_entry<CalculationType, Parameters>); + factory.add_to_factory("gn_sinu", new gn_sinu_entry<T, Parameters>); + factory.add_to_factory("sinu", new sinu_entry<T, Parameters>); + factory.add_to_factory("eck6", new eck6_entry<T, Parameters>); + factory.add_to_factory("mbtfps", new mbtfps_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/gnom.hpp b/boost/geometry/srs/projections/proj/gnom.hpp index d691c136b6..9276391a76 100644 --- a/boost/geometry/srs/projections/proj/gnom.hpp +++ b/boost/geometry/srs/projections/proj/gnom.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP + #include <boost/config.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -65,72 +64,74 @@ namespace projections namespace detail { namespace gnom { - static const double EPS10 = 1.e-10; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + static const double epsilon10 = 1.e-10; + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_gnom { T sinph0; T cosph0; - int mode; + mode_type mode; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gnom_spheroid : public base_t_fi<base_gnom_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gnom_spheroid + : public base_t_fi<base_gnom_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_gnom<CalculationType> m_proj_parm; + par_gnom<T> m_proj_parm; inline base_gnom_spheroid(const Parameters& par) - : base_t_fi<base_gnom_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_gnom_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType coslam, cosphi, sinphi; + T coslam, cosphi, sinphi; sinphi = sin(lp_lat); cosphi = cos(lp_lat); coslam = cos(lp_lon); + switch (this->m_proj_parm.mode) { - case EQUIT: + case equit: xy_y = cosphi * coslam; break; - case OBLIQ: + case obliq: xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam; break; - case S_POLE: + case s_pole: xy_y = - sinphi; break; - case N_POLE: + case n_pole: xy_y = sinphi; break; } - if (xy_y <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + + if (xy_y <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + xy_x = (xy_y = 1. / xy_y) * cosphi * sin(lp_lon); switch (this->m_proj_parm.mode) { - case EQUIT: + case equit: xy_y *= sinphi; break; - case OBLIQ: + case obliq: xy_y *= this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam; break; - case N_POLE: + case n_pole: coslam = - coslam; BOOST_FALLTHROUGH; - case S_POLE: + case s_pole: xy_y *= cosphi * coslam; break; } @@ -138,43 +139,44 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType rh, cosz, sinz; + T rh, cosz, sinz; rh = boost::math::hypot(xy_x, xy_y); sinz = sin(lp_lat = atan(rh)); cosz = sqrt(1. - sinz * sinz); - if (fabs(rh) <= EPS10) { + + if (fabs(rh) <= epsilon10) { lp_lat = this->m_par.phi0; lp_lon = 0.; } else { switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: lp_lat = cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh; if (fabs(lp_lat) >= 1.) - lp_lat = lp_lat > 0. ? HALFPI : -HALFPI; + lp_lat = lp_lat > 0. ? half_pi : -half_pi; else lp_lat = asin(lp_lat); xy_y = (cosz - this->m_proj_parm.sinph0 * sin(lp_lat)) * rh; xy_x *= sinz * this->m_proj_parm.cosph0; break; - case EQUIT: + case equit: lp_lat = xy_y * sinz / rh; if (fabs(lp_lat) >= 1.) - lp_lat = lp_lat > 0. ? HALFPI : -HALFPI; + lp_lat = lp_lat > 0. ? half_pi : -half_pi; else lp_lat = asin(lp_lat); xy_y = cosz * rh; xy_x *= sinz; break; - case S_POLE: - lp_lat -= HALFPI; + case s_pole: + lp_lat -= half_pi; break; - case N_POLE: - lp_lat = HALFPI - lp_lat; + case n_pole: + lp_lat = half_pi - lp_lat; xy_y = -xy_y; break; } @@ -193,17 +195,18 @@ namespace projections template <typename Parameters, typename T> inline void setup_gnom(Parameters& par, par_gnom<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); - - if (fabs(fabs(par.phi0) - HALFPI) < EPS10) - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; - else if (fabs(par.phi0) < EPS10) - proj_parm.mode = EQUIT; - else { - proj_parm.mode = OBLIQ; + static const T half_pi = detail::half_pi<T>(); + + if (fabs(fabs(par.phi0) - half_pi) < epsilon10) { + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; + } else if (fabs(par.phi0) < epsilon10) { + proj_parm.mode = equit; + } else { + proj_parm.mode = obliq; proj_parm.sinph0 = sin(par.phi0); proj_parm.cosph0 = cos(par.phi0); } + par.es = 0.; } @@ -222,10 +225,10 @@ namespace projections \par Example \image html ex_gnom.gif */ - template <typename CalculationType, typename Parameters> - struct gnom_spheroid : public detail::gnom::base_gnom_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gnom_spheroid : public detail::gnom::base_gnom_spheroid<T, Parameters> { - inline gnom_spheroid(const Parameters& par) : detail::gnom::base_gnom_spheroid<CalculationType, Parameters>(par) + inline gnom_spheroid(const Parameters& par) : detail::gnom::base_gnom_spheroid<T, Parameters>(par) { detail::gnom::setup_gnom(this->m_par, this->m_proj_parm); } @@ -239,20 +242,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gnom, gnom_spheroid, gnom_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class gnom_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gnom_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gnom_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gnom_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void gnom_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void gnom_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("gnom", new gnom_entry<CalculationType, Parameters>); + factory.add_to_factory("gnom", new gnom_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/goode.hpp b/boost/geometry/srs/projections/proj/goode.hpp index ef4e5ebeee..014c9328cf 100644 --- a/boost/geometry/srs/projections/proj/goode.hpp +++ b/boost/geometry/srs/projections/proj/goode.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct goode {}; + struct goode {}; // Goode Homolosine }} //namespace srs::par4 @@ -66,66 +65,52 @@ namespace projections static const double Y_COR = 0.05280; static const double PHI_LIM = .71093078197902358062; - template <typename CalculationType, typename Parameters> + // TODO: consider storing references to Parameters instead of copies + template <typename T, typename Par> struct par_goode { - sinu_ellipsoid<CalculationType, Parameters> sinu; - moll_spheroid<CalculationType, Parameters> moll; + sinu_spheroid<T, Par> sinu; + moll_spheroid<T, Par> moll; - par_goode(const Parameters& par) : sinu(par), moll(par) {} + par_goode(Par const& par) : sinu(par), moll(par) {} }; - // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_goode_spheroid : public base_t_fi<base_goode_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Par> + inline void s_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, + Par const& par, par_goode<T, Par> const& proj_par) { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_goode<CalculationType, Parameters> m_proj_parm; - - inline base_goode_spheroid(const Parameters& par) - : base_t_fi<base_goode_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par), m_proj_parm(par) {} - - // FORWARD(s_forward) spheroid - // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const - { - if (fabs(lp_lat) <= PHI_LIM) - this->m_proj_parm.sinu.fwd(lp_lon, lp_lat, xy_x, xy_y); - else { - this->m_proj_parm.moll.fwd(lp_lon, lp_lat, xy_x, xy_y); - xy_y -= lp_lat >= 0.0 ? Y_COR : -Y_COR; - } - } - - // INVERSE(s_inverse) spheroid - // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const - { - if (fabs(xy_y) <= PHI_LIM) - this->m_proj_parm.sinu.inv(xy_x, xy_y, lp_lon, lp_lat); - else { - xy_y += xy_y >= 0.0 ? Y_COR : -Y_COR; - this->m_proj_parm.moll.inv(xy_x, xy_y, lp_lon, lp_lat); - } + if (fabs(lp_lat) <= PHI_LIM) + proj_par.sinu.fwd(lp_lon, lp_lat, xy_x, xy_y); + else { + proj_par.moll.fwd(lp_lon, lp_lat, xy_x, xy_y); + xy_y -= lp_lat >= 0.0 ? Y_COR : -Y_COR; } + } - static inline std::string get_name() - { - return "goode_spheroid"; + template <typename T, typename Par> + inline void s_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, + Par const& par, par_goode<T, Par> const& proj_par) + { + if (fabs(xy_y) <= PHI_LIM) + proj_par.sinu.inv(xy_x, xy_y, lp_lon, lp_lat); + else { + xy_y += xy_y >= 0.0 ? Y_COR : -Y_COR; + proj_par.moll.inv(xy_x, xy_y, lp_lon, lp_lat); } - - }; + } // Goode Homolosine - template <typename CalculationType, typename Parameters> - inline void setup_goode(Parameters& par, par_goode<CalculationType, Parameters>& /*proj_parm*/) + template <typename Par> + inline void setup_goode(Par& par) { par.es = 0.; + + // NOTE: The following explicit initialization of sinu projection + // is not needed because setup_goode() is called before proj_par.sinu + // is constructed and m_par of parent projection is used. + + //proj_par.sinu.m_par.es = 0.; + //detail::gn_sinu::setup_sinu(proj_par.sinu.m_par, proj_par.sinu.m_proj_parm); } }} // namespace detail::goode @@ -143,13 +128,42 @@ namespace projections \par Example \image html ex_goode.gif */ - template <typename CalculationType, typename Parameters> - struct goode_spheroid : public detail::goode::base_goode_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct goode_spheroid : public detail::base_t_fi<goode_spheroid<T, Parameters>, T, Parameters> { - inline goode_spheroid(const Parameters& par) : detail::goode::base_goode_spheroid<CalculationType, Parameters>(par) + detail::goode::par_goode<T, Parameters> m_proj_parm; + + inline goode_spheroid(const Parameters& par) + : detail::base_t_fi<goode_spheroid<T, Parameters>, T, Parameters>(*this, par) + , m_proj_parm(setup(this->m_par)) + {} + + // FORWARD(s_forward) spheroid + // Project coordinates from geographic (lon, lat) to cartesian (x, y) + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - detail::goode::setup_goode(this->m_par, this->m_proj_parm); + detail::goode::s_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); } + + // INVERSE(s_inverse) spheroid + // Project coordinates from cartesian (x, y) to geographic (lon, lat) + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const + { + detail::goode::s_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); + } + + static inline std::string get_name() + { + return "goode_spheroid"; + } + + private: + static Parameters& setup(Parameters& par) + { + detail::goode::setup_goode(par); + return par; + } + }; #ifndef DOXYGEN_NO_DETAIL @@ -160,20 +174,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::goode, goode_spheroid, goode_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class goode_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class goode_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<goode_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<goode_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void goode_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void goode_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("goode", new goode_entry<CalculationType, Parameters>); + factory.add_to_factory("goode", new goode_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/gstmerc.hpp b/boost/geometry/srs/projections/proj/gstmerc.hpp index 5e3581328e..69751c503c 100644 --- a/boost/geometry/srs/projections/proj/gstmerc.hpp +++ b/boost/geometry/srs/projections/proj/gstmerc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct gstmerc {}; + struct gstmerc {}; // Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion) }} //namespace srs::par4 @@ -75,45 +74,41 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_gstmerc_spheroid : public base_t_fi<base_gstmerc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_gstmerc_spheroid + : public base_t_fi<base_gstmerc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_gstmerc<CalculationType> m_proj_parm; + par_gstmerc<T> m_proj_parm; inline base_gstmerc_spheroid(const Parameters& par) - : base_t_fi<base_gstmerc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_gstmerc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType L, Ls, sinLs1, Ls1; + T L, Ls, sinLs1, Ls1; + L= this->m_proj_parm.n1*lp_lon; Ls= this->m_proj_parm.c+this->m_proj_parm.n1*log(pj_tsfn(-1.0*lp_lat,-1.0*sin(lp_lat),this->m_par.e)); sinLs1= sin(L)/cosh(Ls); Ls1= log(pj_tsfn(-1.0*asin(sinLs1),0.0,0.0)); xy_x= (this->m_proj_parm.XS + this->m_proj_parm.n2*Ls1)*this->m_par.ra; xy_y= (this->m_proj_parm.YS + this->m_proj_parm.n2*atan(sinh(Ls)/cos(L)))*this->m_par.ra; - /*fprintf(stderr,"fwd:\nL =%16.13f\nLs =%16.13f\nLs1 =%16.13f\nLP(%16.13f,%16.13f)=XY(%16.4f,%16.4f)\n",L,Ls,Ls1,lp_lon+this->m_par.lam0,lp_lat,(xy_x*this->m_par.a + this->m_par.x0)*this->m_par.to_meter,(xy_y*this->m_par.a + this->m_par.y0)*this->m_par.to_meter);*/ } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType L, LC, sinC; + T L, LC, sinC; + L= atan(sinh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2)/cos((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)); sinC= sin((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)/cosh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2); LC= log(pj_tsfn(-1.0*asin(sinC),0.0,0.0)); lp_lon= L/this->m_proj_parm.n1; lp_lat= -1.0*pj_phi2(exp((LC-this->m_proj_parm.c)/this->m_proj_parm.n1),this->m_par.e); - /*fprintf(stderr,"inv:\nL =%16.13f\nsinC =%16.13f\nLC =%16.13f\nXY(%16.4f,%16.4f)=LP(%16.13f,%16.13f)\n",L,sinC,LC,((xy_x/this->m_par.ra)+this->m_par.x0)/this->m_par.to_meter,((xy_y/this->m_par.ra)+this->m_par.y0)/this->m_par.to_meter,lp_lon+this->m_par.lam0,lp_lat);*/ } static inline std::string get_name() @@ -128,14 +123,13 @@ namespace projections inline void setup_gstmerc(Parameters& par, par_gstmerc<T>& proj_parm) { proj_parm.lamc= par.lam0; - proj_parm.n1= sqrt(1.0+par.es*pow(cos(par.phi0),4.0)/(1.0-par.es)); + proj_parm.n1= sqrt(T(1)+par.es*math::pow(cos(par.phi0),4)/(T(1)-par.es)); proj_parm.phic= asin(sin(par.phi0)/proj_parm.n1); - proj_parm.c= log(pj_tsfn(-1.0*proj_parm.phic,0.0,0.0)) - -proj_parm.n1*log(pj_tsfn(-1.0*par.phi0,-1.0*sin(par.phi0),par.e)); + proj_parm.c= log(pj_tsfn(-1.0*proj_parm.phic,0.0,0.0)) + - proj_parm.n1*log(pj_tsfn(-1.0*par.phi0,-1.0*sin(par.phi0),par.e)); proj_parm.n2= par.k0*par.a*sqrt(1.0-par.es)/(1.0-par.es*sin(par.phi0)*sin(par.phi0)); proj_parm.XS= 0;/* -par.x0 */ proj_parm.YS= -1.0*proj_parm.n2*proj_parm.phic;/* -par.y0 */ - /*fprintf(stderr,"a (m) =%16.4f\ne =%16.13f\nl0(rad)=%16.13f\np0(rad)=%16.13f\nk0 =%16.4f\nX0 (m)=%16.4f\nY0 (m)=%16.4f\n\nlC(rad)=%16.13f\npC(rad)=%16.13f\nc =%16.13f\nn1 =%16.13f\nn2 (m) =%16.4f\nXS (m) =%16.4f\nYS (m) =%16.4f\n", par.a, par.e, par.lam0, par.phi0, par.k0, par.x0, par.y0, proj_parm.lamc, proj_parm.phic, proj_parm.c, proj_parm.n1, proj_parm.n2, proj_parm.XS +par.x0, proj_parm.YS + par.y0);*/ } }} // namespace detail::gstmerc @@ -158,10 +152,10 @@ namespace projections \par Example \image html ex_gstmerc.gif */ - template <typename CalculationType, typename Parameters> - struct gstmerc_spheroid : public detail::gstmerc::base_gstmerc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gstmerc_spheroid : public detail::gstmerc::base_gstmerc_spheroid<T, Parameters> { - inline gstmerc_spheroid(const Parameters& par) : detail::gstmerc::base_gstmerc_spheroid<CalculationType, Parameters>(par) + inline gstmerc_spheroid(const Parameters& par) : detail::gstmerc::base_gstmerc_spheroid<T, Parameters>(par) { detail::gstmerc::setup_gstmerc(this->m_par, this->m_proj_parm); } @@ -175,20 +169,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gstmerc, gstmerc_spheroid, gstmerc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class gstmerc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gstmerc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gstmerc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gstmerc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void gstmerc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void gstmerc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("gstmerc", new gstmerc_entry<CalculationType, Parameters>); + factory.add_to_factory("gstmerc", new gstmerc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/hammer.hpp b/boost/geometry/srs/projections/proj/hammer.hpp index 58707a1499..9fd5bd34b1 100644 --- a/boost/geometry/srs/projections/proj/hammer.hpp +++ b/boost/geometry/srs/projections/proj/hammer.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP -#define BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP +#define BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct hammer {}; + struct hammer {}; // Hammer & Eckert-Greifendorff }} //namespace srs::par4 @@ -60,7 +59,7 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace hammer { - static const double EPS = 1.0e-10; + static const double epsilon = 1.0e-10; template <typename T> struct par_hammer @@ -70,25 +69,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_hammer_spheroid : public base_t_fi<base_hammer_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_hammer_spheroid + : public base_t_fi<base_hammer_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_hammer<CalculationType> m_proj_parm; + par_hammer<T> m_proj_parm; inline base_hammer_spheroid(const Parameters& par) - : base_t_fi<base_hammer_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_hammer_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType cosphi, d; + T cosphi, d; d = sqrt(2./(1. + (cosphi = cos(lp_lat)) * cos(lp_lon *= this->m_proj_parm.w))); xy_x = this->m_proj_parm.m * d * cosphi * sin(lp_lon); @@ -97,15 +92,15 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType z; + T z; z = sqrt(1. - 0.25*this->m_proj_parm.w*this->m_proj_parm.w*xy_x*xy_x - 0.25*xy_y*xy_y); - if (geometry::math::abs(2.*z*z-1.) < EPS) { + if (geometry::math::abs(2.*z*z-1.) < epsilon) { lp_lon = HUGE_VAL; lp_lat = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-14) ); + BOOST_THROW_EXCEPTION( projection_exception(error_lat_or_lon_exceed_limit) ); } else { lp_lon = aatan2(this->m_proj_parm.w * xy_x * z,2. * z * z - 1)/this->m_proj_parm.w; lp_lat = aasin(z * xy_y); @@ -123,18 +118,22 @@ namespace projections template <typename Parameters, typename T> inline void setup_hammer(Parameters& par, par_hammer<T>& proj_parm) { - if (pj_param(par.params, "tW").i) { - if ((proj_parm.w = fabs(pj_param(par.params, "dW").f)) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-27) ); + T tmp; + + if (pj_param_f(par.params, "W", tmp)) { + if ((proj_parm.w = fabs(tmp)) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_w_or_m_zero_or_less) ); } else proj_parm.w = .5; - if (pj_param(par.params, "tM").i) { - if ((proj_parm.m = fabs(pj_param(par.params, "dM").f)) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-27) ); + if (pj_param_f(par.params, "M", tmp)) { + if ((proj_parm.m = fabs(tmp)) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_w_or_m_zero_or_less) ); } else proj_parm.m = 1.; + proj_parm.rm = 1. / proj_parm.m; proj_parm.m /= proj_parm.w; + par.es = 0.; } @@ -157,10 +156,10 @@ namespace projections \par Example \image html ex_hammer.gif */ - template <typename CalculationType, typename Parameters> - struct hammer_spheroid : public detail::hammer::base_hammer_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct hammer_spheroid : public detail::hammer::base_hammer_spheroid<T, Parameters> { - inline hammer_spheroid(const Parameters& par) : detail::hammer::base_hammer_spheroid<CalculationType, Parameters>(par) + inline hammer_spheroid(const Parameters& par) : detail::hammer::base_hammer_spheroid<T, Parameters>(par) { detail::hammer::setup_hammer(this->m_par, this->m_proj_parm); } @@ -174,20 +173,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::hammer, hammer_spheroid, hammer_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class hammer_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class hammer_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<hammer_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<hammer_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void hammer_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void hammer_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("hammer", new hammer_entry<CalculationType, Parameters>); + factory.add_to_factory("hammer", new hammer_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/hatano.hpp b/boost/geometry/srs/projections/proj/hatano.hpp index e37a78196b..8392a2a3ca 100644 --- a/boost/geometry/srs/projections/proj/hatano.hpp +++ b/boost/geometry/srs/projections/proj/hatano.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP -#define BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP +#define BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct hatano {}; + struct hatano {}; // Hatano Asymmetrical Equal Area }} //namespace srs::par4 @@ -63,9 +62,9 @@ namespace projections namespace detail { namespace hatano { - static const int NITER = 20; - static const double EPS = 1e-7; - static const double ONETOL = 1.000001; + static const int n_iter = 20; + static const double epsilon = 1e-7; + static const double one_plus_tol = 1.000001; static const double CN_ = 2.67595; static const double CS_ = 2.43763; static const double RCN = 0.37369906014686373063; @@ -78,30 +77,25 @@ namespace projections static const double RXC = 1.17647058823529411764; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_hatano_spheroid : public base_t_fi<base_hatano_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_hatano_spheroid + : public base_t_fi<base_hatano_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_hatano_spheroid(const Parameters& par) - : base_t_fi<base_hatano_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_hatano_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType th1, c; + T th1, c; int i; c = sin(lp_lat) * (lp_lat < 0. ? CS_ : CN_); - for (i = NITER; i; --i) { + for (i = n_iter; i; --i) { lp_lat -= th1 = (lp_lat + sin(lp_lat) - c) / (1. + cos(lp_lat)); - if (fabs(th1) < EPS) break; + if (fabs(th1) < epsilon) break; } xy_x = FXC * lp_lon * cos(lp_lat *= .5); xy_y = sin(lp_lat) * (lp_lat < 0. ? FYCS : FYCN); @@ -109,16 +103,18 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType th; + static T const half_pi = detail::half_pi<T>(); + + T th; th = xy_y * ( xy_y < 0. ? RYCS : RYCN); if (fabs(th) > 1.) { - if (fabs(th) > ONETOL) { - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(th) > one_plus_tol) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } else { - th = th > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>(); + th = th > 0. ? half_pi : - half_pi; } } else { th = asin(th); @@ -128,10 +124,10 @@ namespace projections th += th; lp_lat = (th + sin(th)) * (xy_y < 0. ? RCS : RCN); if (fabs(lp_lat) > 1.) { - if (fabs(lp_lat) > ONETOL) { - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(lp_lat) > one_plus_tol) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } else { - lp_lat = lp_lat > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>(); + lp_lat = lp_lat > 0. ? half_pi : - half_pi; } } else { lp_lat = asin(lp_lat); @@ -167,10 +163,10 @@ namespace projections \par Example \image html ex_hatano.gif */ - template <typename CalculationType, typename Parameters> - struct hatano_spheroid : public detail::hatano::base_hatano_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct hatano_spheroid : public detail::hatano::base_hatano_spheroid<T, Parameters> { - inline hatano_spheroid(const Parameters& par) : detail::hatano::base_hatano_spheroid<CalculationType, Parameters>(par) + inline hatano_spheroid(const Parameters& par) : detail::hatano::base_hatano_spheroid<T, Parameters>(par) { detail::hatano::setup_hatano(this->m_par); } @@ -184,20 +180,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::hatano, hatano_spheroid, hatano_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class hatano_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class hatano_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<hatano_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<hatano_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void hatano_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void hatano_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("hatano", new hatano_entry<CalculationType, Parameters>); + factory.add_to_factory("hatano", new hatano_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/healpix.hpp b/boost/geometry/srs/projections/proj/healpix.hpp index d2f5a8c081..4615448192 100644 --- a/boost/geometry/srs/projections/proj/healpix.hpp +++ b/boost/geometry/srs/projections/proj/healpix.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP -#define BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,16 +15,17 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Implementation of the HEALPix and rHEALPix projections. -// For background see <http://code.scenzgrid.org/index.php/p/scenzgrid-py/source/tree/master/docs/rhealpix_dggs.pdf>. +// For background see <http://code.scenzgrid.org/index.php/p/scenzgrid-py/source/tree/master/docs/rhealpix_dggs.pdf>. // Authors: Alex Raichev (raichev@cs.auckland.ac.nz) -// Michael Speth (spethm@landcareresearch.co.nz) +// Michael Speth (spethm@landcareresearch.co.nz) // Notes: Raichev implemented these projections in Python and -// Speth translated them into C here. +// Speth translated them into C here. + // Copyright (c) 2001, Thomas Flemming, tf@ttqv.com // Permission is hereby granted, free of charge, to any person obtaining a @@ -49,6 +46,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP +#define BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -63,8 +63,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct healpix {}; - struct rhealpix {}; + struct healpix {}; // HEALPix + struct rhealpix {}; // rHEALPix }} //namespace srs::par4 @@ -74,7 +74,8 @@ namespace projections namespace detail { namespace healpix { - static const double EPS = 1e-15; + /* Fuzz to handle rounding errors: */ + static const double epsilon = 1e-15; template <typename T> struct par_healpix @@ -82,28 +83,36 @@ namespace projections int north_square; int south_square; T qp; - T apa[APA_SIZE]; + detail::apa<T> apa; }; - /* Matrix for counterclockwise rotation by pi/2: */ - /* Matrix for counterclockwise rotation by pi: */ - /* Matrix for counterclockwise rotation by 3*pi/2: */ - /* Identity matrix */ - /* IDENT, R1, R2, R3, R1 inverse, R2 inverse, R3 inverse:*/ - /* Fuzz to handle rounding errors: */ template <typename T> - struct CapMap + struct cap_map { int cn; /* An integer 0--3 indicating the position of the polar cap. */ T x, y; /* Coordinates of the pole point (point of most extreme latitude on the polar caps). */ - enum Region {north, south, equatorial} region; + enum region_type {north, south, equatorial} region; }; template <typename T> - struct Point + struct point_xy { T x, y; }; - static double rot[7][2][2] = {{{1, 0},{0, 1}}, {{ 0,-1},{ 1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0,-1},{ 1, 0}}}; + + /* IDENT, R1, R2, R3, R1 inverse, R2 inverse, R3 inverse:*/ + static double rot[7][2][2] = { + /* Identity matrix */ + {{1, 0},{0, 1}}, + /* Matrix for counterclockwise rotation by pi/2: */ + {{ 0,-1},{ 1, 0}}, + /* Matrix for counterclockwise rotation by pi: */ + {{-1, 0},{ 0,-1}}, + /* Matrix for counterclockwise rotation by 3*pi/2: */ + {{ 0, 1},{-1, 0}}, + {{ 0, 1},{-1, 0}}, // 3*pi/2 + {{-1, 0},{ 0,-1}}, // pi + {{ 0,-1},{ 1, 0}} // pi/2 + }; /** * Returns the sign of the double. @@ -149,41 +158,41 @@ namespace projections template <typename T> inline int pnpoly(int nvert, T vert[][2], T const& testx, T const& testy) { - int i, c = 0; + int i; int counter = 0; T xinters; - Point<T> p1, p2; + point_xy<T> p1, p2; + /* Check for boundrary cases */ for (i = 0; i < nvert; i++) { if (testx == vert[i][0] && testy == vert[i][1]) { return 1; } } + p1.x = vert[0][0]; p1.y = vert[0][1]; + for (i = 1; i < nvert; i++) { p2.x = vert[i % nvert][0]; p2.y = vert[i % nvert][1]; - if (testy > (std::min)(p1.y, p2.y)) { - if (testy <= (std::max)(p1.y, p2.y)) { - if (testx <= (std::max)(p1.x, p2.x)) { - if (p1.y != p2.y) { - xinters = (testy-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x; - if (p1.x == p2.x || testx <= xinters) { - counter++; - } - } - } - } + if (testy > (std::min)(p1.y, p2.y) && + testy <= (std::max)(p1.y, p2.y) && + testx <= (std::max)(p1.x, p2.x) && + p1.y != p2.y) + { + xinters = (testy-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x; + if (p1.x == p2.x || testx <= xinters) + counter++; } p1 = p2; } + if (counter % 2 == 0) { return 0; } else { return 1; } - return c; } /** * Return 1 if (x, y) lies in (the interior or boundary of) the image of the @@ -195,45 +204,49 @@ namespace projections template <typename T> inline int in_image(T const& x, T const& y, int proj, int north_square, int south_square) { - static const T ONEPI = detail::ONEPI<T>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); if (proj == 0) { T healpixVertsJit[][2] = { - {-1.0*ONEPI- EPS, ONEPI/4.0}, - {-3.0*ONEPI/4.0, ONEPI/2.0 + EPS}, - {-1.0*ONEPI/2.0, ONEPI/4.0 + EPS}, - {-1.0*ONEPI/4.0, ONEPI/2.0 + EPS}, - {0.0, ONEPI/4.0 + EPS}, - {ONEPI/4.0, ONEPI/2.0 + EPS}, - {ONEPI/2.0, ONEPI/4.0 + EPS}, - {3.0*ONEPI/4.0, ONEPI/2.0 + EPS}, - {ONEPI+ EPS, ONEPI/4.0}, - {ONEPI+ EPS, -1.0*ONEPI/4.0}, - {3.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS}, - {ONEPI/2.0, -1.0*ONEPI/4.0 - EPS}, - {ONEPI/4.0, -1.0*ONEPI/2.0 - EPS}, - {0.0, -1.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS}, - {-1.0*ONEPI/2.0, -1.0*ONEPI/4.0 - EPS}, - {-3.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS}, - {-1.0*ONEPI - EPS, -1.0*ONEPI/4.0} + {-pi - epsilon, fourth_pi}, + {-3.0*fourth_pi, half_pi + epsilon}, + {-half_pi, fourth_pi + epsilon}, + {-fourth_pi, half_pi + epsilon}, + {0.0, fourth_pi + epsilon}, + {fourth_pi, half_pi + epsilon}, + {half_pi, fourth_pi + epsilon}, + {3.0*fourth_pi, half_pi + epsilon}, + {pi + epsilon, fourth_pi}, + {pi + epsilon, -fourth_pi}, + {3.0*fourth_pi, -half_pi - epsilon}, + {half_pi, -fourth_pi - epsilon}, + {fourth_pi, -half_pi - epsilon}, + {0.0, -fourth_pi - epsilon}, + {-fourth_pi, -half_pi - epsilon}, + {-half_pi, -fourth_pi - epsilon}, + {-3.0*fourth_pi, -half_pi - epsilon}, + {-pi - epsilon, -fourth_pi} }; return pnpoly((int)sizeof(healpixVertsJit)/ sizeof(healpixVertsJit[0]), healpixVertsJit, x, y); } else { T rhealpixVertsJit[][2] = { - {-1.0*ONEPI - EPS, ONEPI/4.0 + EPS}, - {-1.0*ONEPI + north_square*ONEPI/2.0- EPS, ONEPI/4.0 + EPS}, - {-1.0*ONEPI + north_square*ONEPI/2.0- EPS, 3*ONEPI/4.0 + EPS}, - {-1.0*ONEPI + (north_square + 1.0)*ONEPI/2.0 + EPS, 3*ONEPI/4.0 + EPS}, - {-1.0*ONEPI + (north_square + 1.0)*ONEPI/2.0 + EPS, ONEPI/4.0 + EPS}, - {ONEPI + EPS, ONEPI/4.0 + EPS}, - {ONEPI + EPS, -1.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI + (south_square + 1.0)*ONEPI/2.0 + EPS, -1.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI + (south_square + 1.0)*ONEPI/2.0 + EPS, -3.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI + south_square*ONEPI/2.0 - EPS, -3.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI + south_square*ONEPI/2.0 - EPS, -1.0*ONEPI/4.0 - EPS}, - {-1.0*ONEPI - EPS, -1.0*ONEPI/4.0 - EPS}}; + {-pi - epsilon, fourth_pi + epsilon}, + {-pi + north_square*half_pi - epsilon, fourth_pi + epsilon}, + {-pi + north_square*half_pi - epsilon, 3.0*fourth_pi + epsilon}, + {-pi + (north_square + 1.0)*half_pi + epsilon, 3.0*fourth_pi + epsilon}, + {-pi + (north_square + 1.0)*half_pi + epsilon, fourth_pi + epsilon}, + {pi + epsilon, fourth_pi + epsilon}, + {pi + epsilon, -fourth_pi - epsilon}, + {-pi + (south_square + 1.0)*half_pi + epsilon, -fourth_pi - epsilon}, + {-pi + (south_square + 1.0)*half_pi + epsilon, -3.0*fourth_pi - epsilon}, + {-pi + south_square*half_pi - epsilon, -3.0*fourth_pi - epsilon}, + {-pi + south_square*half_pi - epsilon, -fourth_pi - epsilon}, + {-pi - epsilon, -fourth_pi - epsilon} + }; + return pnpoly((int)sizeof(rhealpixVertsJit)/ sizeof(rhealpixVertsJit[0]), rhealpixVertsJit, x, y); } @@ -251,10 +264,12 @@ namespace projections T q = pj_qsfn(sin(alpha), par.e, 1.0 - par.es); T qp = proj_parm.qp; T ratio = q/qp; - if (fabsl(ratio) > 1) { + + if (math::abs(ratio) > 1) { /* Rounding error. */ ratio = pj_sign(ratio); } + return asin(ratio); } else { /* Approximation to inverse authalic latitude. */ @@ -268,7 +283,9 @@ namespace projections template <typename T> inline void healpix_sphere(T const& lp_lam, T const& lp_phi, T& xy_x, T& xy_y) { - static const T ONEPI = detail::ONEPI<T>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); T lam = lp_lam; T phi = lp_phi; @@ -277,17 +294,17 @@ namespace projections /* equatorial region */ if ( fabsl(phi) <= phi0) { xy_x = lam; - xy_y = 3.0*ONEPI/8.0*sin(phi); + xy_y = 3.0*pi/8.0*sin(phi); } else { T lamc; - T sigma = sqrt(3.0*(1 - fabsl(sin(phi)))); - T cn = floor(2*lam / ONEPI + 2); + T sigma = sqrt(3.0*(1 - math::abs(sin(phi)))); + T cn = floor(2*lam / pi + 2); if (cn >= 4) { cn = 3; } - lamc = -3*ONEPI/4 + (ONEPI/2)*cn; + lamc = -3*fourth_pi + half_pi*cn; xy_x = lamc + (lam - lamc)*sigma; - xy_y = pj_sign(phi)*ONEPI/4*(2 - sigma); + xy_y = pj_sign(phi)*fourth_pi*(2 - sigma); } return; } @@ -297,28 +314,31 @@ namespace projections template <typename T> inline void healpix_sphere_inverse(T const& xy_x, T const& xy_y, T& lp_lam, T& lp_phi) { - static const T ONEPI = detail::ONEPI<T>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); T x = xy_x; T y = xy_y; - T y0 = ONEPI/4.0; + T y0 = fourth_pi; + /* Equatorial region. */ - if (fabsl(y) <= y0) { + if (math::abs(y) <= y0) { lp_lam = x; - lp_phi = asin(8.0*y/(3.0*ONEPI)); - } else if (fabsl(y) < ONEPI/2.0) { - T cn = floor(2.0*x/ONEPI + 2.0); + lp_phi = asin(8.0*y/(3.0*pi)); + } else if (fabsl(y) < half_pi) { + T cn = floor(2.0*x/pi + 2.0); T xc, tau; if (cn >= 4) { cn = 3; } - xc = -3.0*ONEPI/4.0 + (ONEPI/2.0)*cn; - tau = 2.0 - 4.0*fabsl(y)/ONEPI; + xc = -3.0*fourth_pi + (half_pi)*cn; + tau = 2.0 - 4.0*fabsl(y)/pi; lp_lam = xc + (x - xc)/tau; - lp_phi = pj_sign(y)*asin(1.0 - pow(tau , 2.0)/3.0); + lp_phi = pj_sign(y)*asin(1.0 - math::pow(tau, 2)/3.0); } else { - lp_lam = -1.0*ONEPI; - lp_phi = pj_sign(y)*ONEPI/2.0; + lp_lam = -1.0*pi; + lp_phi = pj_sign(y)*half_pi; } return; } @@ -351,8 +371,8 @@ namespace projections * b is a 2 x 1 matrix. * @param ret holds a*b. **/ - template <typename T> - inline void dot_product(T a[2][2], T b[2], T *ret) + template <typename T1, typename T2> + inline void dot_product(T1 a[2][2], T2 b[2], T2 *ret) { int i, j; int length = 2; @@ -372,89 +392,88 @@ namespace projections * (north_square, south_square)-rHEALPix projection of the unit sphere. **/ template <typename T> - inline CapMap<T> get_cap(T x, T const& y, int north_square, int south_square, + inline cap_map<T> get_cap(T x, T const& y, int north_square, int south_square, int inverse) { - static const T ONEPI = detail::ONEPI<T>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); - CapMap<T> capmap; + cap_map<T> capmap; T c; capmap.x = x; capmap.y = y; if (inverse == 0) { - if (y > ONEPI/4.0) { - capmap.region = CapMap<T>::north; - c = ONEPI/2.0; - } else if (y < -1*ONEPI/4.0) { - capmap.region = CapMap<T>::south; - c = -1*ONEPI/2.0; + if (y > fourth_pi) { + capmap.region = cap_map<T>::north; + c = half_pi; + } else if (y < -fourth_pi) { + capmap.region = cap_map<T>::south; + c = -half_pi; } else { - capmap.region = CapMap<T>::equatorial; + capmap.region = cap_map<T>::equatorial; capmap.cn = 0; return capmap; } /* polar region */ - if (x < -1*ONEPI/2.0) { + if (x < -half_pi) { capmap.cn = 0; - capmap.x = (-1*3.0*ONEPI/4.0); + capmap.x = (-3.0*fourth_pi); capmap.y = c; - } else if (x >= -1*ONEPI/2.0 && x < 0) { + } else if (x >= -half_pi && x < 0) { capmap.cn = 1; - capmap.x = -1*ONEPI/4.0; + capmap.x = -fourth_pi; capmap.y = c; - } else if (x >= 0 && x < ONEPI/2.0) { + } else if (x >= 0 && x < half_pi) { capmap.cn = 2; - capmap.x = ONEPI/4.0; + capmap.x = fourth_pi; capmap.y = c; } else { capmap.cn = 3; - capmap.x = 3.0*ONEPI/4.0; + capmap.x = 3.0*fourth_pi; capmap.y = c; } - return capmap; } else { - T eps; - if (y > ONEPI/4.0) { - capmap.region = CapMap<T>::north; - capmap.x = (-3.0*ONEPI/4.0 + north_square*ONEPI/2.0); - capmap.y = ONEPI/2.0; - x = x - north_square*ONEPI/2.0; - } else if (y < -1*ONEPI/4.0) { - capmap.region = CapMap<T>::south; - capmap.x = (-3.0*ONEPI/4.0 + south_square*ONEPI/2); - capmap.y = -1*ONEPI/2.0; - x = x - south_square*ONEPI/2.0; + if (y > fourth_pi) { + capmap.region = cap_map<T>::north; + capmap.x = (-3.0*fourth_pi + north_square*half_pi); + capmap.y = half_pi; + x = x - north_square*half_pi; + } else if (y < -fourth_pi) { + capmap.region = cap_map<T>::south; + capmap.x = (-3.0*fourth_pi + south_square*pi/2); + capmap.y = -half_pi; + x = x - south_square*half_pi; } else { - capmap.region = CapMap<T>::equatorial; + capmap.region = cap_map<T>::equatorial; capmap.cn = 0; return capmap; } /* Polar Region, find the HEALPix polar cap number that x, y moves to when rHEALPix polar square is disassembled. */ - eps = 1e-15; /* Kludge. Fuzz to avoid some rounding errors. */ - if (capmap.region == CapMap<T>::north) { - if (y >= -1*x - ONEPI/4.0 - eps && y < x + 5.0*ONEPI/4.0 - eps) { + if (capmap.region == cap_map<T>::north) { + if (y >= -x - fourth_pi - epsilon && y < x + 5.0*fourth_pi - epsilon) { capmap.cn = (north_square + 1) % 4; - } else if (y > -1*x -1*ONEPI/4.0 + eps && y >= x + 5.0*ONEPI/4.0 - eps) { + } else if (y > -x -fourth_pi + epsilon && y >= x + 5.0*fourth_pi - epsilon) { capmap.cn = (north_square + 2) % 4; - } else if (y <= -1*x -1*ONEPI/4.0 + eps && y > x + 5.0*ONEPI/4.0 + eps) { + } else if (y <= -x -fourth_pi + epsilon && y > x + 5.0*fourth_pi + epsilon) { capmap.cn = (north_square + 3) % 4; } else { capmap.cn = north_square; } - } else if (capmap.region == CapMap<T>::south) { - if (y <= x + ONEPI/4.0 + eps && y > -1*x - 5.0*ONEPI/4 + eps) { + } else if (capmap.region == cap_map<T>::south) { + if (y <= x + fourth_pi + epsilon && y > -x - 5.0*fourth_pi + epsilon) { capmap.cn = (south_square + 1) % 4; - } else if (y < x + ONEPI/4.0 - eps && y <= -1*x - 5.0*ONEPI/4.0 + eps) { + } else if (y < x + fourth_pi - epsilon && y <= -x - 5.0*fourth_pi + epsilon) { capmap.cn = (south_square + 2) % 4; - } else if (y >= x + ONEPI/4.0 - eps && y < -1*x - 5.0*ONEPI/4.0 - eps) { + } else if (y >= x + fourth_pi - epsilon && y < -x - 5.0*fourth_pi - epsilon) { capmap.cn = (south_square + 3) % 4; } else { capmap.cn = south_square; } } - return capmap; } + return capmap; } /** * Rearrange point (x, y) in the HEALPix projection by @@ -469,95 +488,84 @@ namespace projections inline void combine_caps(T& xy_x, T& xy_y, int north_square, int south_square, int inverse) { - static const T ONEPI = detail::ONEPI<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); T v[2]; - T a[2]; + T c[2]; T vector[2]; T v_min_c[2]; T ret_dot[2]; - CapMap<T> capmap = get_cap(xy_x, xy_y, north_square, south_square, inverse); - if (capmap.region == CapMap<T>::equatorial) { + const double (*tmpRot)[2]; + int pole = 0; + + cap_map<T> capmap = get_cap(xy_x, xy_y, north_square, south_square, inverse); + if (capmap.region == cap_map<T>::equatorial) { xy_x = capmap.x; xy_y = capmap.y; return; } - v[0] = xy_x; - v[1] = xy_y; + + v[0] = xy_x; v[1] = xy_y; + c[0] = capmap.x; c[1] = capmap.y; + if (inverse == 0) { /* Rotate (xy_x, xy_y) about its polar cap tip and then translate it to north_square or south_square. */ - int pole = 0; - T (*tmpRot)[2]; - T c[2] = {capmap.x, capmap.y}; - if (capmap.region == CapMap<T>::north) { + + if (capmap.region == cap_map<T>::north) { pole = north_square; - a[0] = (-3.0*ONEPI/4.0 + pole*ONEPI/2); - a[1] = (ONEPI/2.0 + pole*0); tmpRot = rot[get_rotate_index(capmap.cn - pole)]; - vector_sub(v, c, v_min_c); - dot_product(tmpRot, v_min_c, ret_dot); - vector_add(ret_dot, a, vector); } else { pole = south_square; - a[0] = (-3.0*ONEPI/4.0 + pole*ONEPI/2); - a[1] = (ONEPI/-2.0 + pole*0); tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))]; - vector_sub(v, c, v_min_c); - dot_product(tmpRot, v_min_c, ret_dot); - vector_add(ret_dot, a, vector); } - xy_x = vector[0]; - xy_y = vector[1]; - return; } else { /* Inverse function. Unrotate (xy_x, xy_y) and then translate it back. */ - int pole = 0; - T (*tmpRot)[2]; - T c[2] = {capmap.x, capmap.y}; + /* disassemble */ - if (capmap.region == CapMap<T>::north) { + if (capmap.region == cap_map<T>::north) { pole = north_square; - a[0] = (-3.0*ONEPI/4.0 + capmap.cn*ONEPI/2); - a[1] = (ONEPI/2.0 + capmap.cn*0); tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))]; - vector_sub(v, c, v_min_c); - dot_product(tmpRot, v_min_c, ret_dot); - vector_add(ret_dot, a, vector); } else { pole = south_square; - a[0] = (-3.0*ONEPI/4.0 + capmap.cn*ONEPI/2); - a[1] = (ONEPI/-2.0 + capmap.cn*0); tmpRot = rot[get_rotate_index(capmap.cn - pole)]; - vector_sub(v, c, v_min_c); - dot_product(tmpRot, v_min_c, ret_dot); - vector_add(ret_dot, a, vector); } - xy_x = vector[0]; - xy_y = vector[1]; - return; } + + vector_sub(v, c, v_min_c); + dot_product(tmpRot, v_min_c, ret_dot); + + { + T a[2]; + /* Workaround cppcheck git issue */ + T* pa = a; + // TODO: in proj4 5.0.0 this line is used instead + //pa[0] = -3.0*fourth_pi + ((inverse == 0) ? 0 : capmap.cn) *half_pi; + pa[0] = -3.0*fourth_pi + ((inverse == 0) ? pole : capmap.cn) *half_pi; + pa[1] = half_pi; + vector_add(ret_dot, a, vector); + } + + xy_x = vector[0]; + xy_y = vector[1]; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_healpix_ellipsoid : public base_t_fi<base_healpix_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_healpix_ellipsoid + : public base_t_fi<base_healpix_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_healpix<CalculationType> m_proj_parm; + par_healpix<T> m_proj_parm; inline base_healpix_ellipsoid(const Parameters& par) - : base_t_fi<base_healpix_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_healpix_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_healpix_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0); return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); @@ -565,13 +573,13 @@ namespace projections // INVERSE(e_healpix_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the HEALPix image. */ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) { lp_lon = HUGE_VAL; lp_lat = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-15) ); + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_x_or_y) ); } healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1); @@ -585,36 +593,32 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_healpix_spheroid : public base_t_fi<base_healpix_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_healpix_spheroid + : public base_t_fi<base_healpix_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_healpix<CalculationType> m_proj_parm; + par_healpix<T> m_proj_parm; inline base_healpix_spheroid(const Parameters& par) - : base_t_fi<base_healpix_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_healpix_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_healpix_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); } // INVERSE(s_healpix_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the HEALPix image */ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) { lp_lon = HUGE_VAL; lp_lat = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-15) ); + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_x_or_y) ); } return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); } @@ -627,23 +631,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_rhealpix_ellipsoid : public base_t_fi<base_rhealpix_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_rhealpix_ellipsoid + : public base_t_fi<base_rhealpix_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_healpix<CalculationType> m_proj_parm; + par_healpix<T> m_proj_parm; inline base_rhealpix_ellipsoid(const Parameters& par) - : base_t_fi<base_rhealpix_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_rhealpix_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_rhealpix_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0); healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); @@ -652,13 +652,13 @@ namespace projections // INVERSE(e_rhealpix_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the rHEALPix image. */ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) { lp_lon = HUGE_VAL; lp_lat = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-15) ); + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_x_or_y) ); } combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1); healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); @@ -673,23 +673,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_rhealpix_spheroid : public base_t_fi<base_rhealpix_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_rhealpix_spheroid + : public base_t_fi<base_rhealpix_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_healpix<CalculationType> m_proj_parm; + par_healpix<T> m_proj_parm; inline base_rhealpix_spheroid(const Parameters& par) - : base_t_fi<base_rhealpix_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_rhealpix_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_rhealpix_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0); @@ -697,13 +693,13 @@ namespace projections // INVERSE(s_rhealpix_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the rHEALPix image. */ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) { lp_lon = HUGE_VAL; lp_lat = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-15) ); + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_x_or_y) ); } combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1); return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); @@ -720,11 +716,11 @@ namespace projections template <typename Parameters, typename T> inline void setup_healpix(Parameters& par, par_healpix<T>& proj_parm) { - if (par.es) { - pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */ + if (par.es != 0.0) { + proj_parm.apa = pj_authset<T>(par.es); /* For auth_lat(). */ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */ - par.ra = 1.0/par.a; + pj_calc_ellipsoid_params(par, par.a, par.es); /* Ensure we have a consistent parameter set */ } else { } } @@ -733,19 +729,21 @@ namespace projections template <typename Parameters, typename T> inline void setup_rhealpix(Parameters& par, par_healpix<T>& proj_parm) { - proj_parm.north_square = pj_param(par.params,"inorth_square").i; - proj_parm.south_square = pj_param(par.params,"isouth_square").i; + proj_parm.north_square = pj_get_param_i(par.params, "north_square"); + proj_parm.south_square = pj_get_param_i(par.params, "south_square"); /* Check for valid north_square and south_square inputs. */ if (proj_parm.north_square < 0 || proj_parm.north_square > 3) { - BOOST_THROW_EXCEPTION( projection_exception(-47) ); + BOOST_THROW_EXCEPTION( projection_exception(error_axis) ); } if (proj_parm.south_square < 0 || proj_parm.south_square > 3) { - BOOST_THROW_EXCEPTION( projection_exception(-47) ); + BOOST_THROW_EXCEPTION( projection_exception(error_axis) ); } - if (par.es) { - pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */ + if (par.es != 0.0) { + proj_parm.apa = pj_authset<T>(par.es); /* For auth_lat(). */ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */ + // TODO: why not the same as in healpix? + //pj_calc_ellipsoid_params(par, par.a, par.es); par.ra = 1.0/par.a; } else { } @@ -766,10 +764,10 @@ namespace projections \par Example \image html ex_healpix.gif */ - template <typename CalculationType, typename Parameters> - struct healpix_ellipsoid : public detail::healpix::base_healpix_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct healpix_ellipsoid : public detail::healpix::base_healpix_ellipsoid<T, Parameters> { - inline healpix_ellipsoid(const Parameters& par) : detail::healpix::base_healpix_ellipsoid<CalculationType, Parameters>(par) + inline healpix_ellipsoid(const Parameters& par) : detail::healpix::base_healpix_ellipsoid<T, Parameters>(par) { detail::healpix::setup_healpix(this->m_par, this->m_proj_parm); } @@ -787,10 +785,10 @@ namespace projections \par Example \image html ex_healpix.gif */ - template <typename CalculationType, typename Parameters> - struct healpix_spheroid : public detail::healpix::base_healpix_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct healpix_spheroid : public detail::healpix::base_healpix_spheroid<T, Parameters> { - inline healpix_spheroid(const Parameters& par) : detail::healpix::base_healpix_spheroid<CalculationType, Parameters>(par) + inline healpix_spheroid(const Parameters& par) : detail::healpix::base_healpix_spheroid<T, Parameters>(par) { detail::healpix::setup_healpix(this->m_par, this->m_proj_parm); } @@ -811,10 +809,10 @@ namespace projections \par Example \image html ex_rhealpix.gif */ - template <typename CalculationType, typename Parameters> - struct rhealpix_ellipsoid : public detail::healpix::base_rhealpix_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct rhealpix_ellipsoid : public detail::healpix::base_rhealpix_ellipsoid<T, Parameters> { - inline rhealpix_ellipsoid(const Parameters& par) : detail::healpix::base_rhealpix_ellipsoid<CalculationType, Parameters>(par) + inline rhealpix_ellipsoid(const Parameters& par) : detail::healpix::base_rhealpix_ellipsoid<T, Parameters>(par) { detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm); } @@ -835,10 +833,10 @@ namespace projections \par Example \image html ex_rhealpix.gif */ - template <typename CalculationType, typename Parameters> - struct rhealpix_spheroid : public detail::healpix::base_rhealpix_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct rhealpix_spheroid : public detail::healpix::base_rhealpix_spheroid<T, Parameters> { - inline rhealpix_spheroid(const Parameters& par) : detail::healpix::base_rhealpix_spheroid<CalculationType, Parameters>(par) + inline rhealpix_spheroid(const Parameters& par) : detail::healpix::base_rhealpix_spheroid<T, Parameters>(par) { detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm); } @@ -853,37 +851,37 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rhealpix, rhealpix_spheroid, rhealpix_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class healpix_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class healpix_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<healpix_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<healpix_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<healpix_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<healpix_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class rhealpix_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class rhealpix_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<rhealpix_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<rhealpix_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<rhealpix_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<rhealpix_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void healpix_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void healpix_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("healpix", new healpix_entry<CalculationType, Parameters>); - factory.add_to_factory("rhealpix", new rhealpix_entry<CalculationType, Parameters>); + factory.add_to_factory("healpix", new healpix_entry<T, Parameters>); + factory.add_to_factory("rhealpix", new rhealpix_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/igh.hpp b/boost/geometry/srs/projections/proj/igh.hpp index 219f74239e..6661863c91 100644 --- a/boost/geometry/srs/projections/proj/igh.hpp +++ b/boost/geometry/srs/projections/proj/igh.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP -#define BOOST_GEOMETRY_PROJECTIONS_IGH_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP +#define BOOST_GEOMETRY_PROJECTIONS_IGH_HPP + #include <boost/geometry/util/math.hpp> #include <boost/shared_ptr.hpp> @@ -56,7 +55,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct igh {}; + struct igh {}; // Interrupted Goode Homolosine }} //namespace srs::par4 @@ -65,16 +64,18 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace igh { - - template <typename CalculationType, typename Parameters> + // TODO: consider replacing dynamically created projections + // with member objects + template <typename T, typename Parameters> struct par_igh { - boost::shared_ptr<base_v<CalculationType, Parameters> > pj[12]; - CalculationType dy0; + boost::shared_ptr<base_v<T, Parameters> > pj[12]; + T dy0; }; + /* 40d 44' 11.8" [degrees] */ template <typename T> - inline T d4044118() { return (T(40) + T(44)/T(60.) + T(11.8)/T(3600.)) * geometry::math::d2r<T>(); } // 40d 44' 11.8" [degrees] + inline T d4044118() { return (T(40) + T(44)/T(60.) + T(11.8)/T(3600.)) * geometry::math::d2r<T>(); } template <typename T> inline T d10() { return T(10) * geometry::math::d2r<T>(); } @@ -101,15 +102,18 @@ namespace projections template <typename T> inline T d180() { return T(180) * geometry::math::d2r<T>(); } - static const double EPSLN = 1.e-10; // allow a little 'slack' on zone edge positions + static const double epsilon = 1.e-10; // allow a little 'slack' on zone edge positions // Converted from #define SETUP(n, proj, x_0, y_0, lon_0) - template <template <typename, typename> class Entry, typename Parameters, typename CalculationType> - inline void do_setup(int n, Parameters const& par, par_igh<CalculationType, Parameters>& proj_parm, - CalculationType const& x_0, CalculationType const& y_0, - CalculationType const& lon_0) + template <template <typename, typename> class Entry, typename Parameters, typename T> + inline void do_setup(int n, Parameters const& par, par_igh<T, Parameters>& proj_parm, + T const& x_0, T const& y_0, + T const& lon_0) { - Entry<CalculationType, Parameters> entry; + // NOTE: in the original proj4 these projections are initialized + // with zeroed parameters which could be done here as well instead + // of initializing with parent projection's parameters. + Entry<T, Parameters> entry; proj_parm.pj[n-1].reset(entry.create_new(par)); proj_parm.pj[n-1]->mutable_params().x0 = x_0; proj_parm.pj[n-1]->mutable_params().y0 = y_0; @@ -117,29 +121,25 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_igh_spheroid : public base_t_fi<base_igh_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_igh_spheroid + : public base_t_fi<base_igh_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_igh<CalculationType, Parameters> m_proj_parm; + par_igh<T, Parameters> m_proj_parm; inline base_igh_spheroid(const Parameters& par) - : base_t_fi<base_igh_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_igh_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType d4044118 = igh::d4044118<CalculationType>(); - static const CalculationType d20 = igh::d20<CalculationType>(); - static const CalculationType d40 = igh::d40<CalculationType>(); - static const CalculationType d80 = igh::d80<CalculationType>(); - static const CalculationType d100 = igh::d100<CalculationType>(); + static const T d4044118 = igh::d4044118<T>(); + static const T d20 = igh::d20<T>(); + static const T d40 = igh::d40<T>(); + static const T d80 = igh::d80<T>(); + static const T d100 = igh::d100<T>(); int z; if (lp_lat >= d4044118) { // 1|2 @@ -169,26 +169,26 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType d4044118 = igh::d4044118<CalculationType>(); - static const CalculationType d10 = igh::d10<CalculationType>(); - static const CalculationType d20 = igh::d20<CalculationType>(); - static const CalculationType d40 = igh::d40<CalculationType>(); - static const CalculationType d50 = igh::d50<CalculationType>(); - static const CalculationType d60 = igh::d60<CalculationType>(); - static const CalculationType d80 = igh::d80<CalculationType>(); - static const CalculationType d90 = igh::d90<CalculationType>(); - static const CalculationType d100 = igh::d100<CalculationType>(); - static const CalculationType d160 = igh::d160<CalculationType>(); - static const CalculationType d180 = igh::d180<CalculationType>(); - - static const CalculationType c2 = 2.0; + static const T d4044118 = igh::d4044118<T>(); + static const T d10 = igh::d10<T>(); + static const T d20 = igh::d20<T>(); + static const T d40 = igh::d40<T>(); + static const T d50 = igh::d50<T>(); + static const T d60 = igh::d60<T>(); + static const T d80 = igh::d80<T>(); + static const T d90 = igh::d90<T>(); + static const T d100 = igh::d100<T>(); + static const T d160 = igh::d160<T>(); + static const T d180 = igh::d180<T>(); + + static const T c2 = 2.0; - const CalculationType y90 = this->m_proj_parm.dy0 + sqrt(c2); // lt=90 corresponds to y=y0+sqrt(2.0) + const T y90 = this->m_proj_parm.dy0 + sqrt(c2); // lt=90 corresponds to y=y0+sqrt(2.0) int z = 0; - if (xy_y > y90+EPSLN || xy_y < -y90+EPSLN) // 0 + if (xy_y > y90+epsilon || xy_y < -y90+epsilon) // 0 z = 0; else if (xy_y >= d4044118) // 1|2 z = (xy_x <= -d40? 1: 2); @@ -217,24 +217,24 @@ namespace projections lp_lon += this->m_proj_parm.pj[z-1]->params().lam0; switch (z) { - case 1: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN) || - ((lp_lon >= -d40-EPSLN && lp_lon <= -d10+EPSLN) && - (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break; - case 2: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN) || - ((lp_lon >= -d180-EPSLN && lp_lon <= -d160+EPSLN) && - (lp_lat >= d50-EPSLN && lp_lat <= d90+EPSLN)) || - ((lp_lon >= -d50-EPSLN && lp_lon <= -d40+EPSLN) && - (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break; - case 3: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN); break; - case 4: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN); break; - case 5: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break; - case 6: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break; - case 7: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break; - case 8: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break; - case 9: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break; - case 10: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break; - case 11: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break; - case 12: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break; + case 1: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d40+epsilon) || + ((lp_lon >= -d40-epsilon && lp_lon <= -d10+epsilon) && + (lp_lat >= d60-epsilon && lp_lat <= d90+epsilon)); break; + case 2: ok = (lp_lon >= -d40-epsilon && lp_lon <= d180+epsilon) || + ((lp_lon >= -d180-epsilon && lp_lon <= -d160+epsilon) && + (lp_lat >= d50-epsilon && lp_lat <= d90+epsilon)) || + ((lp_lon >= -d50-epsilon && lp_lon <= -d40+epsilon) && + (lp_lat >= d60-epsilon && lp_lat <= d90+epsilon)); break; + case 3: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d40+epsilon); break; + case 4: ok = (lp_lon >= -d40-epsilon && lp_lon <= d180+epsilon); break; + case 5: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d100+epsilon); break; + case 6: ok = (lp_lon >= -d100-epsilon && lp_lon <= -d20+epsilon); break; + case 7: ok = (lp_lon >= -d20-epsilon && lp_lon <= d80+epsilon); break; + case 8: ok = (lp_lon >= d80-epsilon && lp_lon <= d180+epsilon); break; + case 9: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d100+epsilon); break; + case 10: ok = (lp_lon >= -d100-epsilon && lp_lon <= -d20+epsilon); break; + case 11: ok = (lp_lon >= -d20-epsilon && lp_lon <= d80+epsilon); break; + case 12: ok = (lp_lon >= d80-epsilon && lp_lon <= d180+epsilon); break; } z = (!ok? 0: z); // projectable? @@ -252,17 +252,17 @@ namespace projections }; // Interrupted Goode Homolosine - template <typename CalculationType, typename Parameters> - inline void setup_igh(Parameters& par, par_igh<CalculationType, Parameters>& proj_parm) + template <typename T, typename Parameters> + inline void setup_igh(Parameters& par, par_igh<T, Parameters>& proj_parm) { - static const CalculationType d0 = 0; - static const CalculationType d4044118 = igh::d4044118<CalculationType>(); - static const CalculationType d20 = igh::d20<CalculationType>(); - static const CalculationType d30 = igh::d30<CalculationType>(); - static const CalculationType d60 = igh::d60<CalculationType>(); - static const CalculationType d100 = igh::d100<CalculationType>(); - static const CalculationType d140 = igh::d140<CalculationType>(); - static const CalculationType d160 = igh::d160<CalculationType>(); + static const T d0 = 0; + static const T d4044118 = igh::d4044118<T>(); + static const T d20 = igh::d20<T>(); + static const T d30 = igh::d30<T>(); + static const T d60 = igh::d60<T>(); + static const T d100 = igh::d100<T>(); + static const T d140 = igh::d140<T>(); + static const T d160 = igh::d160<T>(); /* Zones: @@ -283,11 +283,17 @@ namespace projections +-------+--------+-----------+-----------+ -180 -100 -20 80 180 */ - - - CalculationType lp_lam = 0, lp_phi = d4044118; - CalculationType xy1_x, xy1_y; - CalculationType xy3_x, xy3_y; + + T lp_lam = 0, lp_phi = d4044118; + T xy1_x, xy1_y; + T xy3_x, xy3_y; + + // IMPORTANT: Force spherical sinu projection + // This is required because unlike in the original proj4 here + // parameters are used to initialize underlying projections. + // In the original code zeroed parameters are passed which + // could be done here as well though. + par.es = 0.; // sinusoidal zones do_setup<sinu_entry>(3, par, proj_parm, -d100, d0, -d100); @@ -315,7 +321,8 @@ namespace projections do_setup<moll_entry>(11, par, proj_parm, d20, -proj_parm.dy0, d20); do_setup<moll_entry>(12, par, proj_parm, d140, -proj_parm.dy0, d140); - par.es = 0.; + // Already done before + //par.es = 0.; } }} // namespace detail::igh @@ -333,10 +340,10 @@ namespace projections \par Example \image html ex_igh.gif */ - template <typename CalculationType, typename Parameters> - struct igh_spheroid : public detail::igh::base_igh_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct igh_spheroid : public detail::igh::base_igh_spheroid<T, Parameters> { - inline igh_spheroid(const Parameters& par) : detail::igh::base_igh_spheroid<CalculationType, Parameters>(par) + inline igh_spheroid(const Parameters& par) : detail::igh::base_igh_spheroid<T, Parameters>(par) { detail::igh::setup_igh(this->m_par, this->m_proj_parm); } @@ -350,20 +357,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::igh, igh_spheroid, igh_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class igh_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class igh_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<igh_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<igh_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void igh_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void igh_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("igh", new igh_entry<CalculationType, Parameters>); + factory.add_to_factory("igh", new igh_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/imw_p.hpp b/boost/geometry/srs/projections/proj/imw_p.hpp index 1a7fe9e915..78bd10d63b 100644 --- a/boost/geometry/srs/projections/proj/imw_p.hpp +++ b/boost/geometry/srs/projections/proj/imw_p.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP -#define BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP +#define BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct imw_p {}; + struct imw_p {}; // International Map of the World Polyconic }} //namespace srs::par4 @@ -64,19 +63,25 @@ namespace projections namespace detail { namespace imw_p { - static const double TOL = 1e-10; - static const double EPS = 1e-10; + static const double tolerance = 1e-10; + static const double epsilon = 1e-10; template <typename T> - struct XY { T x, y; }; // specific for IMW_P + struct point_xy { T x, y; }; // specific for IMW_P + + enum mode_type { + none_is_zero = 0, /* phi_1 and phi_2 != 0 */ + phi_1_is_zero = 1, /* phi_1 = 0 */ + phi_2_is_zero = -1 /* phi_2 = 0 */ + }; template <typename T> struct par_imw_p { T P, Pp, Q, Qp, R_1, R_2, sphi_1, sphi_2, C2; T phi_1, phi_2, lam_1; - T en[EN_SIZE]; - int mode; /* = 0, phi_1 and phi_2 != 0, = 1, phi_1 = 0, = -1 phi_2 = 0 */ + detail::en<T> en; + mode_type mode; }; template <typename Parameters, typename T> @@ -85,25 +90,25 @@ namespace projections { int err = 0; - if (!pj_param(par.params, "tlat_1").i || - !pj_param(par.params, "tlat_2").i) { + if (!pj_param_r(par.params, "lat_1", proj_parm.phi_1) || + !pj_param_r(par.params, "lat_2", proj_parm.phi_2)) { err = -41; } else { - proj_parm.phi_1 = pj_param(par.params, "rlat_1").f; - proj_parm.phi_2 = pj_param(par.params, "rlat_2").f; + //proj_parm.phi_1 = pj_get_param_r(par.params, "lat_1"); // set above + //proj_parm.phi_2 = pj_get_param_r(par.params, "lat_2"); // set above *del = 0.5 * (proj_parm.phi_2 - proj_parm.phi_1); *sig = 0.5 * (proj_parm.phi_2 + proj_parm.phi_1); - err = (fabs(*del) < EPS || fabs(*sig) < EPS) ? -42 : 0; + err = (fabs(*del) < epsilon || fabs(*sig) < epsilon) ? -42 : 0; } return err; } template <typename Parameters, typename T> - inline XY<T> + inline point_xy<T> loc_for(T const& lp_lam, T const& lp_phi, Parameters const& par, par_imw_p<T> const& proj_parm, T *yc) { - XY<T> xy; + point_xy<T> xy; - if (! lp_phi) { + if (lp_phi == 0.0) { xy.x = lp_lam; xy.y = 0.; } else { @@ -117,7 +122,7 @@ namespace projections C = sqrt(R * R - xa * xa); if (lp_phi < 0.) C = - C; C += ya - R; - if (proj_parm.mode < 0) { + if (proj_parm.mode == phi_2_is_zero) { xb = lp_lam; yb = proj_parm.C2; } else { @@ -125,7 +130,7 @@ namespace projections xb = proj_parm.R_2 * sin(t); yb = proj_parm.C2 + proj_parm.R_2 * (1. - cos(t)); } - if (proj_parm.mode > 0) { + if (proj_parm.mode == phi_1_is_zero) { xc = lp_lam; *yc = 0.; } else { @@ -160,35 +165,33 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_imw_p_ellipsoid : public base_t_fi<base_imw_p_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_imw_p_ellipsoid + : public base_t_fi<base_imw_p_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_imw_p<CalculationType> m_proj_parm; + par_imw_p<T> m_proj_parm; inline base_imw_p_ellipsoid(const Parameters& par) - : base_t_fi<base_imw_p_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_imw_p_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType yc = 0; - XY<CalculationType> xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc); + T yc = 0; + point_xy<T> xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc); xy_x = xy.x; xy_y = xy.y; } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - XY<CalculationType> t; - CalculationType yc = 0; + point_xy<T> t; + T yc = 0.0; + int i = 0; + const int n_max_iter = 1000; /* Arbitrarily choosen number... */ lp_lat = this->m_proj_parm.phi_2; lp_lon = xy_x / cos(lp_lat); @@ -196,7 +199,14 @@ namespace projections t = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc); lp_lat = ((lp_lat - this->m_proj_parm.phi_1) * (xy_y - yc) / (t.y - yc)) + this->m_proj_parm.phi_1; lp_lon = lp_lon * xy_x / t.x; - } while (fabs(t.x - xy_x) > TOL || fabs(t.y - xy_y) > TOL); + i++; + } while (i < n_max_iter && + (fabs(t.x - xy_x) > tolerance || fabs(t.y - xy_y) > tolerance)); + + if( i == n_max_iter ) + { + lp_lon = lp_lat = HUGE_VAL; + } } static inline std::string get_name() @@ -211,36 +221,37 @@ namespace projections inline void setup_imw_p(Parameters& par, par_imw_p<T>& proj_parm) { T del, sig, s, t, x1, x2, T2, y1, m1, m2, y2; - int i; + int err; - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); - if( (i = phi12(par, proj_parm, &del, &sig)) != 0) - BOOST_THROW_EXCEPTION( projection_exception(i) ); + proj_parm.en = pj_enfn<T>(par.es); + if( (err = phi12(par, proj_parm, &del, &sig)) != 0) + BOOST_THROW_EXCEPTION( projection_exception(err) ); if (proj_parm.phi_2 < proj_parm.phi_1) { /* make sure proj_parm.phi_1 most southerly */ del = proj_parm.phi_1; proj_parm.phi_1 = proj_parm.phi_2; proj_parm.phi_2 = del; } - if (pj_param(par.params, "tlon_1").i) - proj_parm.lam_1 = pj_param(par.params, "rlon_1").f; - else { /* use predefined based upon latitude */ + if (pj_param_r(par.params, "lon_1", proj_parm.lam_1)) { + /* empty */ + } else { /* use predefined based upon latitude */ sig = fabs(sig * geometry::math::r2d<T>()); - if (sig <= 60) sig = 2.; + if (sig <= 60) sig = 2.; else if (sig <= 76) sig = 4.; else sig = 8.; proj_parm.lam_1 = sig * geometry::math::d2r<T>(); } - proj_parm.mode = 0; - if (proj_parm.phi_1) xy(par, proj_parm, proj_parm.phi_1, &x1, &y1, &proj_parm.sphi_1, &proj_parm.R_1); + proj_parm.mode = none_is_zero; + if (proj_parm.phi_1 != 0.0) + xy(par, proj_parm, proj_parm.phi_1, &x1, &y1, &proj_parm.sphi_1, &proj_parm.R_1); else { - proj_parm.mode = 1; + proj_parm.mode = phi_1_is_zero; y1 = 0.; x1 = proj_parm.lam_1; } - if (proj_parm.phi_2) xy(par, proj_parm, proj_parm.phi_2, &x2, &T2, &proj_parm.sphi_2, &proj_parm.R_2); + if (proj_parm.phi_2 != 0.0) + xy(par, proj_parm, proj_parm.phi_2, &x2, &T2, &proj_parm.sphi_2, &proj_parm.R_2); else { - proj_parm.mode = -1; + proj_parm.mode = phi_2_is_zero; T2 = 0.; x2 = proj_parm.lam_1; } @@ -276,10 +287,10 @@ namespace projections \par Example \image html ex_imw_p.gif */ - template <typename CalculationType, typename Parameters> - struct imw_p_ellipsoid : public detail::imw_p::base_imw_p_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct imw_p_ellipsoid : public detail::imw_p::base_imw_p_ellipsoid<T, Parameters> { - inline imw_p_ellipsoid(const Parameters& par) : detail::imw_p::base_imw_p_ellipsoid<CalculationType, Parameters>(par) + inline imw_p_ellipsoid(const Parameters& par) : detail::imw_p::base_imw_p_ellipsoid<T, Parameters>(par) { detail::imw_p::setup_imw_p(this->m_par, this->m_proj_parm); } @@ -293,20 +304,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::imw_p, imw_p_ellipsoid, imw_p_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class imw_p_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class imw_p_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<imw_p_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<imw_p_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void imw_p_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void imw_p_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("imw_p", new imw_p_entry<CalculationType, Parameters>); + factory.add_to_factory("imw_p", new imw_p_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/isea.hpp b/boost/geometry/srs/projections/proj/isea.hpp index 4cffbc430f..6ae803b65e 100644 --- a/boost/geometry/srs/projections/proj/isea.hpp +++ b/boost/geometry/srs/projections/proj/isea.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -44,6 +40,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP + #include <sstream> #include <boost/core/ignore_unused.hpp> @@ -68,48 +67,42 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace isea { + static const double epsilon = std::numeric_limits<double>::epsilon(); - static const double E = 52.62263186; - static const double F = 10.81231696; - //static const double DEG60 = 1.04719755119659774614; - //static const double DEG120 = 2.09439510239319549229; - //static const double DEG72 = 1.25663706143591729537; - //static const double DEG90 = 1.57079632679489661922; - //static const double DEG144 = 2.51327412287183459075; - //static const double DEG36 = 0.62831853071795864768; - //static const double DEG108 = 1.88495559215387594306; - //static const double DEG180 = geometry::math::pi<double>(); - static const double ISEA_SCALE = 0.8301572857837594396028083; - static const double V_LAT = 0.46364760899944494524; - static const double E_RAD = 0.91843818702186776133; - static const double F_RAD = 0.18871053072122403508; - static const double TABLE_G = 0.6615845383; - static const double TABLE_H = 0.1909830056; - static const double RPRIME = 0.91038328153090290025; - static const double PRECISION = 0.0000000000005; - static const double ISEA_STD_LAT = 1.01722196792335072101; - static const double ISEA_STD_LON = .19634954084936207740; + /* sqrt(5)/M_PI */ + static const double isea_scale = 0.8301572857837594396028083; + /* 26.565051177 degrees */ + static const double v_lat = 0.46364760899944494524; + /* 52.62263186 */ + static const double e_rad = 0.91843818702186776133; + /* 10.81231696 */ + static const double f_rad = 0.18871053072122403508; + /* R tan(g) sin(60) */ + static const double table_g = 0.6615845383; + /* H = 0.25 R tan g = */ + static const double table_h = 0.1909830056; + //static const double RPRIME = 0.91038328153090290025; + static const double isea_std_lat = 1.01722196792335072101; + static const double isea_std_lon = .19634954084936207740; template <typename T> - inline T DEG30() { return T(30) * geometry::math::d2r<T>(); } - template <typename T> - inline T DEG60() { return T(60) * geometry::math::d2r<T>(); } + inline T deg30_rad() { return T(30) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG120() { return T(120) * geometry::math::d2r<T>(); } + inline T deg120_rad() { return T(120) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG72() { return T(72) * geometry::math::d2r<T>(); } + inline T deg72_rad() { return T(72) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG90() { return geometry::math::half_pi<T>(); } + inline T deg90_rad() { return geometry::math::half_pi<T>(); } template <typename T> - inline T DEG144() { return T(144) * geometry::math::d2r<T>(); } + inline T deg144_rad() { return T(144) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG36() { return T(36) * geometry::math::d2r<T>(); } + inline T deg36_rad() { return T(36) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG108() { return T(108) * geometry::math::d2r<T>(); } + inline T deg108_rad() { return T(108) * geometry::math::d2r<T>(); } template <typename T> - inline T DEG180() { return geometry::math::pi<T>(); } + inline T deg180_rad() { return geometry::math::pi<T>(); } - inline bool DOWNTRI(int tri) { return (((tri - 1) / 5) % 2 == 1); } + inline bool downtri(int tri) { return (((tri - 1) / 5) % 2 == 1); } /* * Proj 4 provides its own entry points into @@ -155,14 +148,16 @@ namespace projections template <typename T> inline - int hexbin2(T const& width, T x, T y, - int *i, int *j) { + int hexbin2(T const& width, T x, T y, int *i, int *j) + { T z, rx, ry, rz; T abs_dx, abs_dy, abs_dz; int ix, iy, iz, s; struct hex h; - x = x / cos(DEG30<T>()); /* rotated X coord */ + static const T cos_deg30 = cos(deg30_rad<T>()); + + x = x / cos_deg30; /* rotated X coord */ y = y - x / 2.0; /* adjustment for rotated X */ /* adjust for actual hexwidth */ @@ -201,28 +196,30 @@ namespace projections hex_xy(&h); *i = h.x; *j = h.y; - return ix * 100 + iy; + return ix * 100 + iy; } - enum isea_poly { ISEA_NONE, ISEA_ICOSAHEDRON = 20 }; - enum isea_topology { ISEA_HEXAGON=6, ISEA_TRIANGLE=3, ISEA_DIAMOND=4 }; - enum isea_address_form { ISEA_GEO, ISEA_Q2DI, ISEA_SEQNUM, ISEA_INTERLEAVE, - ISEA_PLANE, ISEA_Q2DD, ISEA_PROJTRI, ISEA_VERTEX2DD, ISEA_HEX + //enum isea_poly { isea_none = 0, isea_icosahedron = 20 }; + //enum isea_topology { isea_hexagon=6, isea_triangle=3, isea_diamond=4 }; + enum isea_address_form { + isea_addr_geo, isea_addr_q2di, isea_addr_seqnum, + isea_addr_interleave, isea_addr_plane, isea_addr_q2dd, + isea_addr_projtri, isea_addr_vertex2dd, isea_addr_hex }; template <typename T> struct isea_dgg { - int polyhedron; /* ignored, icosahedron */ - T o_lat, o_lon, o_az; /* orientation, radians */ - int pole; /* true if standard snyder */ - int topology; /* ignored, hexagon */ - int aperture; /* valid values depend on partitioning method */ - int resolution; - T radius; /* radius of the earth in meters, ignored 1.0 */ - int output; /* an isea_address_form */ - int triangle; /* triangle of last transformed point */ - int quad; /* quad of last transformed point */ - unsigned long serial; + //isea_poly polyhedron; /* ignored, icosahedron */ + T o_lat, o_lon, o_az; /* orientation, radians */ + int pole; /* true if standard snyder */ + //isea_topology topology; /* ignored, hexagon */ + int aperture; /* valid values depend on partitioning method */ + int resolution; + T radius; /* radius of the earth in meters, ignored 1.0 */ + isea_address_form output; /* an isea_address_form */ + int triangle; /* triangle of last transformed point */ + int quad; /* quad of last transformed point */ + unsigned long serial; }; template <typename T> @@ -245,10 +242,10 @@ namespace projections /* ENDINC */ enum snyder_polyhedron { - SNYDER_POLY_HEXAGON, SNYDER_POLY_PENTAGON, - SNYDER_POLY_TETRAHEDRON, SNYDER_POLY_CUBE, - SNYDER_POLY_OCTAHEDRON, SNYDER_POLY_DODECAHEDRON, - SNYDER_POLY_ICOSAHEDRON + snyder_poly_hexagon = 0, snyder_poly_pentagon = 1, + snyder_poly_tetrahedron = 2, snyder_poly_cube = 3, + snyder_poly_octahedron = 4, snyder_poly_dodecahedron = 5, + snyder_poly_icosahedron = 6 }; template <typename T> @@ -271,29 +268,23 @@ namespace projections }; return result; } - - - /* sqrt(5)/M_PI */ - - /* 26.565051177 degrees */ - - + template <typename T> inline const isea_geo<T> * vertex() { static isea_geo<T> result[] = { - {0.0, DEG90<T>()}, - {DEG180<T>(), V_LAT}, - {-DEG108<T>(), V_LAT}, - {-DEG36<T>(), V_LAT}, - {DEG36<T>(), V_LAT}, - {DEG108<T>(), V_LAT}, - {-DEG144<T>(), -V_LAT}, - {-DEG72<T>(), -V_LAT}, - {0.0, -V_LAT}, - {DEG72<T>(), -V_LAT}, - {DEG144<T>(), -V_LAT}, - {0.0, -DEG90<T>()} + { 0.0, deg90_rad<T>()}, + { deg180_rad<T>(), v_lat}, + {-deg108_rad<T>(), v_lat}, + {-deg36_rad<T>(), v_lat}, + { deg36_rad<T>(), v_lat}, + { deg108_rad<T>(), v_lat}, + {-deg144_rad<T>(), -v_lat}, + {-deg72_rad<T>(), -v_lat}, + { 0.0, -v_lat}, + { deg72_rad<T>(), -v_lat}, + { deg144_rad<T>(), -v_lat}, + { 0.0, -deg90_rad<T>()} }; return result; } @@ -302,36 +293,32 @@ namespace projections static int tri_v1[] = {0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 2, 3, 4, 5, 1, 11, 11, 11, 11, 11}; - /* 52.62263186 */ - - /* 10.81231696 */ - /* triangle Centers */ template <typename T> inline const isea_geo<T> * icostriangles() { static isea_geo<T> result[] = { - {0.0, 0.0}, - {-DEG144<T>(), E_RAD}, - {-DEG72<T>(), E_RAD}, - {0.0, E_RAD}, - {DEG72<T>(), E_RAD}, - {DEG144<T>(), E_RAD}, - {-DEG144<T>(), F_RAD}, - {-DEG72<T>(), F_RAD}, - {0.0, F_RAD}, - {DEG72<T>(), F_RAD}, - {DEG144<T>(), F_RAD}, - {-DEG108<T>(), -F_RAD}, - {-DEG36<T>(), -F_RAD}, - {DEG36<T>(), -F_RAD}, - {DEG108<T>(), -F_RAD}, - {DEG180<T>(), -F_RAD}, - {-DEG108<T>(), -E_RAD}, - {-DEG36<T>(), -E_RAD}, - {DEG36<T>(), -E_RAD}, - {DEG108<T>(), -E_RAD}, - {DEG180<T>(), -E_RAD}, + { 0.0, 0.0}, + {-deg144_rad<T>(), e_rad}, + {-deg72_rad<T>(), e_rad}, + { 0.0, e_rad}, + { deg72_rad<T>(), e_rad}, + { deg144_rad<T>(), e_rad}, + {-deg144_rad<T>(), f_rad}, + {-deg72_rad<T>(), f_rad}, + { 0.0, f_rad}, + { deg72_rad<T>(), f_rad}, + { deg144_rad<T>(), f_rad}, + {-deg108_rad<T>(), -f_rad}, + {-deg36_rad<T>(), -f_rad}, + { deg36_rad<T>(), -f_rad}, + { deg108_rad<T>(), -f_rad}, + { deg180_rad<T>(), -f_rad}, + {-deg108_rad<T>(), -e_rad}, + {-deg36_rad<T>(), -e_rad}, + { deg36_rad<T>(), -e_rad}, + { deg108_rad<T>(), -e_rad}, + { deg180_rad<T>(), -e_rad}, }; return result; } @@ -355,11 +342,6 @@ namespace projections return adj; } - /* R tan(g) sin(60) */ - - /* H = 0.25 R tan g = */ - - template <typename T> inline isea_pt<T> isea_triangle_xy(int triangle) { @@ -368,22 +350,22 @@ namespace projections triangle = (triangle - 1) % 20; - c.x = TABLE_G * ((triangle % 5) - 2) * 2.0; + c.x = table_g * ((triangle % 5) - 2) * 2.0; if (triangle > 9) { - c.x += TABLE_G; + c.x += table_g; } switch (triangle / 5) { case 0: - c.y = 5.0 * TABLE_H; + c.y = 5.0 * table_h; break; case 1: - c.y = TABLE_H; + c.y = table_h; break; case 2: - c.y = -TABLE_H; + c.y = -table_h; break; case 3: - c.y = -5.0 * TABLE_H; + c.y = -5.0 * table_h; break; default: /* should be impossible */ @@ -412,6 +394,9 @@ namespace projections template <typename T> inline int isea_snyder_forward(isea_geo<T> * ll, isea_pt<T> * out) { + static T const two_pi = detail::two_pi<T>(); + static T const d2r = geometry::math::d2r<T>(); + int i; /* @@ -450,10 +435,10 @@ namespace projections */ /* TODO put these constants in as radians to begin with */ - c = constants<T>()[SNYDER_POLY_ICOSAHEDRON]; - theta = c.theta * geometry::math::d2r<T>(); - g = c.g * geometry::math::d2r<T>(); - G = c.G * geometry::math::d2r<T>(); + c = constants<T>()[snyder_poly_icosahedron]; + theta = c.theta * d2r; + g = c.g * d2r; + G = c.G * d2r; for (i = 1; i <= 20; i++) { T z; @@ -462,23 +447,15 @@ namespace projections center = icostriangles<T>()[i]; /* step 1 */ - #if 0 - z = sph_distance(center.lon, center.lat, ll->lon, ll->lat); - #else z = acos(sin(center.lat) * sin(ll->lat) + cos(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon)); - #endif /* not on this triangle */ if (z > g + 0.000005) { /* TODO DBL_EPSILON */ continue; } - Az = sph_azimuth(ll->lon, ll->lat, center.lon, center.lat); - Az = atan2(cos(ll->lat) * sin(ll->lon - center.lon), - cos(center.lat) * sin(ll->lat) - - sin(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon) - ); + Az = sph_azimuth(center.lon, center.lat, ll->lon, ll->lat); /* step 2 */ @@ -490,7 +467,7 @@ namespace projections /* TODO I don't know why we do this. It's not in snyder */ /* maybe because we should have picked a better vertex */ if (Az < 0.0) { - Az += geometry::math::two_pi<T>(); + Az += two_pi; } /* * adjust Az for the point to fall within the range of 0 to @@ -503,11 +480,11 @@ namespace projections Az_adjust_multiples = 0; while (Az < 0.0) { - Az += DEG120<T>(); + Az += deg120_rad<T>(); Az_adjust_multiples--; } - while (Az > DEG120<T>() + DBL_EPSILON) { - Az -= DEG120<T>(); + while (Az > deg120_rad<T>() + epsilon) { + Az -= deg120_rad<T>(); Az_adjust_multiples++; } @@ -536,8 +513,8 @@ namespace projections H = acos(sin(Az) * sin(G) * cos(g) - cos(Az) * cos(G)); /* eq 7 */ - /* Ag = (Az + G + H - DEG180) * M_PI * R * R / DEG180; */ - Ag = Az + G + H - DEG180<T>(); + /* Ag = (Az + G + H - deg180_rad) * M_PI * R * R / deg180_rad; */ + Ag = Az + G + H - deg180_rad<T>(); /* eq 8 */ Azprime = atan2(2.0 * Ag, Rprime * Rprime * tan_g * tan_g - 2.0 * Ag * cot_theta); @@ -557,7 +534,7 @@ namespace projections * 2 to Azprime */ - Azprime += DEG120<T>() * Az_adjust_multiples; + Azprime += deg120_rad<T>() * Az_adjust_multiples; /* calculate rectangular coordinates */ @@ -612,6 +589,9 @@ namespace projections template <typename T> inline isea_geo<T> snyder_ctran(isea_geo<T> * np, isea_geo<T> * pt) { + static T const pi = detail::pi<T>(); + static T const two_pi = detail::two_pi<T>(); + isea_geo<T> npt; T alpha, phi, lambda, lambda0, beta, lambdap, phip; T sin_phip; @@ -640,11 +620,11 @@ namespace projections /* normalize longitude */ /* TODO can we just do a modulus ? */ - lambdap = fmod(lambdap, geometry::math::two_pi<T>()); - while (lambdap > geometry::math::pi<T>()) - lambdap -= geometry::math::two_pi<T>(); - while (lambdap < -geometry::math::pi<T>()) - lambdap += geometry::math::two_pi<T>(); + lambdap = fmod(lambdap, two_pi); + while (lambdap > pi) + lambdap -= two_pi; + while (lambdap < -pi) + lambdap += two_pi; phip = asin(sin_phip); @@ -657,25 +637,28 @@ namespace projections template <typename T> inline isea_geo<T> isea_ctran(isea_geo<T> * np, isea_geo<T> * pt, T const& lon0) { + static T const pi = detail::pi<T>(); + static T const two_pi = detail::two_pi<T>(); + isea_geo<T> npt; - np->lon += geometry::math::pi<T>(); + np->lon += pi; npt = snyder_ctran(np, pt); - np->lon -= geometry::math::pi<T>(); + np->lon -= pi; - npt.lon -= (geometry::math::pi<T>() - lon0 + np->lon); + npt.lon -= (pi - lon0 + np->lon); /* * snyder is down tri 3, isea is along side of tri1 from vertex 0 to * vertex 1 these are 180 degrees apart */ - npt.lon += geometry::math::pi<T>(); + npt.lon += pi; /* normalize longitude */ - npt.lon = fmod(npt.lon, geometry::math::two_pi<T>()); - while (npt.lon > geometry::math::pi<T>()) - npt.lon -= geometry::math::two_pi<T>(); - while (npt.lon < -geometry::math::pi<T>()) - npt.lon += geometry::math::two_pi<T>(); + npt.lon = fmod(npt.lon, two_pi); + while (npt.lon > pi) + npt.lon -= two_pi; + while (npt.lon < -pi) + npt.lon += two_pi; return npt; } @@ -690,14 +673,14 @@ namespace projections if (!g) return 0; - g->polyhedron = 20; - g->o_lat = ISEA_STD_LAT; - g->o_lon = ISEA_STD_LON; + //g->polyhedron = isea_icosahedron; + g->o_lat = isea_std_lat; + g->o_lon = isea_std_lon; g->o_az = 0.0; g->aperture = 4; g->resolution = 6; g->radius = 1.0; - g->topology = 6; + //g->topology = isea_hexagon; return 1; } @@ -707,8 +690,8 @@ namespace projections { if (!g) return 0; - g->o_lat = ISEA_STD_LAT; - g->o_lon = ISEA_STD_LON; + g->o_lat = isea_std_lat; + g->o_lon = isea_std_lon; g->o_az = 0.0; return 1; } @@ -716,9 +699,11 @@ namespace projections template <typename T> inline int isea_orient_pole(isea_dgg<T> * g) { + static T const half_pi = detail::half_pi<T>(); + if (!g) return 0; - g->o_lat = geometry::math::half_pi<T>(); + g->o_lat = half_pi; g->o_lon = 0.0; g->o_az = 0; return 1; @@ -748,13 +733,16 @@ namespace projections template <typename T> inline void isea_rotate(isea_pt<T> * pt, T const& degrees) { + static T const d2r = geometry::math::d2r<T>(); + static T const two_pi = detail::two_pi<T>(); + T rad; T x, y; - rad = -degrees * geometry::math::d2r<T>(); - while (rad >= geometry::math::two_pi<T>()) rad -= geometry::math::two_pi<T>(); - while (rad <= -geometry::math::two_pi<T>()) rad += geometry::math::two_pi<T>(); + rad = -degrees * d2r; + while (rad >= two_pi) rad -= two_pi; + while (rad <= -two_pi) rad += two_pi; x = pt->x * cos(rad) + pt->y * sin(rad); y = -pt->x * sin(rad) + pt->y * cos(rad); @@ -768,7 +756,7 @@ namespace projections { isea_pt<T> tc; /* center of triangle */ - if (DOWNTRI(tri)) { + if (downtri(tri)) { isea_rotate(pt, 180.0); } tc = isea_triangle_xy<T>(tri); @@ -787,7 +775,6 @@ namespace projections int downtri, quad; downtri = (((tri - 1) / 5) % 2 == 1); - boost::ignore_unused(downtri); quad = ((tri - 1) % 5) + ((tri - 1) / 10) * 5 + 1; isea_rotate(pt, downtri ? 240.0 : 60.0); @@ -802,6 +789,8 @@ namespace projections template <typename T> inline int isea_dddi_ap3odd(isea_dgg<T> *g, int quad, isea_pt<T> *pt, isea_pt<T> *di) { + static T const pi = detail::pi<T>(); + isea_pt<T> v; T hexwidth; T sidelength; /* in hexes */ @@ -810,10 +799,10 @@ namespace projections hex h; /* This is the number of hexes from apex to base of a triangle */ - sidelength = (pow(2.0, g->resolution) + 1.0) / 2.0; + sidelength = (math::pow(T(2), g->resolution) + T(1)) / T(2); /* apex to base is cos(30deg) */ - hexwidth = cos(geometry::math::pi<T>() / 6.0) / sidelength; + hexwidth = cos(pi / 6.0) / sidelength; /* TODO I think sidelength is always x.5, so * (int)sidelength * 2 + 1 might be just as good @@ -890,7 +879,7 @@ namespace projections } /* todo might want to do this as an iterated loop */ if (g->aperture >0) { - sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5); + sidelength = (int) (math::pow(T(g->aperture), T(g->resolution / T(2))) + T(0.5)); } else { sidelength = g->resolution; } @@ -976,19 +965,19 @@ namespace projections return g->serial; } /* hexes in a quad */ - hexes = (int) (pow(T(g->aperture), T(g->resolution)) + 0.5); + hexes = (int) (math::pow(T(g->aperture), T(g->resolution)) + T(0.5)); if (quad == 11) { g->serial = 1 + 10 * hexes + 1; return g->serial; } if (g->aperture == 3 && g->resolution % 2 == 1) { - height = (int) (pow(T(g->aperture), T((g->resolution - 1) / 2.0))); + height = (int) (math::pow(T(g->aperture), T((g->resolution - 1) / T(2)))); sn = ((int) di->x) * height; sn += ((int) di->y) / height; sn += (quad - 1) * hexes; sn += 2; } else { - sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5); + sidelength = (int) (math::pow(T(g->aperture), T(g->resolution / T(2))) + T(0.5)); sn = (int) ((quad - 1) * hexes + sidelength * di->x + di->y + 2); } @@ -1068,47 +1057,44 @@ namespace projections template <typename T> inline isea_pt<T> isea_forward(isea_dgg<T> *g, isea_geo<T> *in) { - int tri, downtri; + int tri; isea_pt<T> out, coord; tri = isea_transform(g, in, &out); - downtri = (((tri - 1) / 5) % 2 == 1); - boost::ignore_unused(downtri); - - if (g->output == ISEA_PLANE) { + if (g->output == isea_addr_plane) { isea_tri_plane(tri, &out, g->radius); return out; } /* convert to isea standard triangle size */ - out.x = out.x / g->radius * ISEA_SCALE; - out.y = out.y / g->radius * ISEA_SCALE; + out.x = out.x / g->radius * isea_scale; + out.y = out.y / g->radius * isea_scale; out.x += 0.5; out.y += 2.0 * .14433756729740644112; switch (g->output) { - case ISEA_PROJTRI: + case isea_addr_projtri: /* nothing to do, already in projected triangle */ break; - case ISEA_VERTEX2DD: + case isea_addr_vertex2dd: g->quad = isea_ptdd(tri, &out); break; - case ISEA_Q2DD: + case isea_addr_q2dd: /* Same as above, we just don't print as much */ g->quad = isea_ptdd(tri, &out); break; - case ISEA_Q2DI: + case isea_addr_q2di: g->quad = isea_ptdi(g, tri, &out, &coord); return coord; break; - case ISEA_SEQNUM: + case isea_addr_seqnum: isea_ptdi(g, tri, &out, &coord); /* disn will set g->serial */ isea_disn(g, g->quad, &coord); return coord; break; - case ISEA_HEX: + case isea_addr_hex: isea_hex(g, tri, &out, &coord); return coord; break; @@ -1127,31 +1113,27 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_isea_spheroid : public base_t_f<base_isea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_isea_spheroid + : public base_t_f<base_isea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_isea<CalculationType> m_proj_parm; + par_isea<T> m_proj_parm; inline base_isea_spheroid(const Parameters& par) - : base_t_f<base_isea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_isea_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - isea_pt<CalculationType> out; - isea_geo<CalculationType> in; + isea_pt<T> out; + isea_geo<T> in; in.lon = lp_lon; in.lat = lp_lat; - isea_dgg<CalculationType> copy = this->m_proj_parm.dgg; + isea_dgg<T> copy = this->m_proj_parm.dgg; out = isea_forward(©, &in); xy_x = out.x; @@ -1171,74 +1153,63 @@ namespace projections { std::string opt; - isea_grid_init(&proj_parm.dgg); + isea_grid_init(&proj_parm.dgg); - proj_parm.dgg.output = ISEA_PLANE; + proj_parm.dgg.output = isea_addr_plane; /* proj_parm.dgg.radius = par.a; / * otherwise defaults to 1 */ /* calling library will scale, I think */ - opt = pj_param(par.params, "sorient").s; + opt = pj_get_param_s(par.params, "orient"); if (! opt.empty()) { if (opt == std::string("isea")) { isea_orient_isea(&proj_parm.dgg); } else if (opt == std::string("pole")) { isea_orient_pole(&proj_parm.dgg); } else { - BOOST_THROW_EXCEPTION( projection_exception(-34) ); + BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) ); } } - if (pj_param(par.params, "tazi").i) { - proj_parm.dgg.o_az = pj_param(par.params, "razi").f; - } - - if (pj_param(par.params, "tlon_0").i) { - proj_parm.dgg.o_lon = pj_param(par.params, "rlon_0").f; - } - - if (pj_param(par.params, "tlat_0").i) { - proj_parm.dgg.o_lat = pj_param(par.params, "rlat_0").f; - } - - if (pj_param(par.params, "taperture").i) { - proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i; - } - - if (pj_param(par.params, "tresolution").i) { - proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i; - } - - opt = pj_param(par.params, "smode").s; + pj_param_r(par.params, "azi", proj_parm.dgg.o_az); + pj_param_r(par.params, "lon_0", proj_parm.dgg.o_lon); + pj_param_r(par.params, "lat_0", proj_parm.dgg.o_lat); + // TODO: this parameter is set below second time + pj_param_i(par.params, "aperture", proj_parm.dgg.aperture); + // TODO: this parameter is set below second time + pj_param_i(par.params, "resolution", proj_parm.dgg.resolution); + + opt = pj_get_param_s(par.params, "mode"); if (! opt.empty()) { if (opt == std::string("plane")) { - proj_parm.dgg.output = ISEA_PLANE; + proj_parm.dgg.output = isea_addr_plane; } else if (opt == std::string("di")) { - proj_parm.dgg.output = ISEA_Q2DI; + proj_parm.dgg.output = isea_addr_q2di; } else if (opt == std::string("dd")) { - proj_parm.dgg.output = ISEA_Q2DD; + proj_parm.dgg.output = isea_addr_q2dd; } else if (opt == std::string("hex")) { - proj_parm.dgg.output = ISEA_HEX; + proj_parm.dgg.output = isea_addr_hex; } else { /* TODO verify error code. Possibly eliminate magic */ - BOOST_THROW_EXCEPTION( projection_exception(-34) ); + BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) ); } } - if (pj_param(par.params, "trescale").i) { - proj_parm.dgg.radius = ISEA_SCALE; + // TODO: pj_param_exists -> pj_get_param_b ? + if (pj_param_exists(par.params, "rescale")) { + proj_parm.dgg.radius = isea_scale; } - if (pj_param(par.params, "tresolution").i) { - proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i; + if (pj_param_i(par.params, "resolution", proj_parm.dgg.resolution)) { + /* empty */ } else { proj_parm.dgg.resolution = 4; } - if (pj_param(par.params, "taperture").i) { - proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i; + if (pj_param_i(par.params, "aperture", proj_parm.dgg.aperture)) { + /* empty */ } else { proj_parm.dgg.aperture = 3; } @@ -1267,10 +1238,10 @@ namespace projections \par Example \image html ex_isea.gif */ - template <typename CalculationType, typename Parameters> - struct isea_spheroid : public detail::isea::base_isea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct isea_spheroid : public detail::isea::base_isea_spheroid<T, Parameters> { - inline isea_spheroid(const Parameters& par) : detail::isea::base_isea_spheroid<CalculationType, Parameters>(par) + inline isea_spheroid(const Parameters& par) : detail::isea::base_isea_spheroid<T, Parameters>(par) { detail::isea::setup_isea(this->m_par, this->m_proj_parm); } @@ -1284,20 +1255,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::isea, isea_spheroid, isea_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class isea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class isea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<isea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<isea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void isea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void isea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("isea", new isea_entry<CalculationType, Parameters>); + factory.add_to_factory("isea", new isea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/krovak.hpp b/boost/geometry/srs/projections/proj/krovak.hpp index 09c24772ed..a008f181db 100644 --- a/boost/geometry/srs/projections/proj/krovak.hpp +++ b/boost/geometry/srs/projections/proj/krovak.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP -#define BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,12 +15,12 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Implementation of the krovak (Krovak) projection. -// Definition: http://www.ihsenergy.com/epsg/guid7.html#1.4.3 +// Definition: http://www.ihsenergy.com/epsg/guid7.html#1.4.3 // Author: Thomas Flemming, tf@ttqv.com // Copyright (c) 2001, Thomas Flemming, tf@ttqv.com @@ -46,6 +42,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP +#define BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -56,7 +55,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct krovak {}; + struct krovak {}; // Krovak }} //namespace srs::par4 @@ -65,10 +64,23 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace krovak { + static double epsilon = 1e-15; + static double S45 = 0.785398163397448; /* 45 deg */ + static double S90 = 1.570796326794896; /* 90 deg */ + static double UQ = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */ + static double S0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78deg 30'00" N */ + /* Not sure at all of the appropriate number for max_iter... */ + static int max_iter = 100; + template <typename T> struct par_krovak { - T C_x; + T alpha; + T k; + T n; + T rho0; + T ad; + int czech; }; /** @@ -95,164 +107,81 @@ namespace projections **/ // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_krovak_ellipsoid : public base_t_fi<base_krovak_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_krovak_ellipsoid + : public base_t_fi<base_krovak_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_krovak<CalculationType> m_proj_parm; + par_krovak<T> m_proj_parm; inline base_krovak_ellipsoid(const Parameters& par) - : base_t_fi<base_krovak_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_krovak_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - /* calculate xy from lat/lon */ - - /* Constants, identical to inverse transform function */ - CalculationType s45, s90, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n; - CalculationType gfi, u, fi0, deltav, s, d, eps, ro; - - - s45 = 0.785398163397448; /* 45 DEG */ - s90 = 2 * s45; - fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */ - - /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must - be set to 1 here. - Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128, - e2=0.006674372230614; - */ - a = 1; /* 6377397.155; */ - /* e2 = this->m_par.es;*/ /* 0.006674372230614; */ - e2 = 0.006674372230614; - e = sqrt(e2); - - alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2)); + T gfi, u, deltav, s, d, eps, rho; - uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */ - u0 = asin(sin(fi0) / alfa); - g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. ); + gfi = math::pow( (T(1) + this->m_par.e * sin(lp_lat)) / (T(1) - this->m_par.e * sin(lp_lat)), this->m_proj_parm.alpha * this->m_par.e / T(2)); - k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g; + u = 2. * (atan(this->m_proj_parm.k * math::pow( tan(lp_lat / T(2) + S45), this->m_proj_parm.alpha) / gfi)-S45); + deltav = -lp_lon * this->m_proj_parm.alpha; - k1 = this->m_par.k0; - n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2)); - s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */ - n = sin(s0); - ro0 = k1 * n0 / tan(s0); - ad = s90 - uq; - - /* Transformation */ - - gfi =pow ( ((1. + e * sin(lp_lat)) / - (1. - e * sin(lp_lat))) , (alfa * e / 2.)); + s = asin(cos(this->m_proj_parm.ad) * sin(u) + sin(this->m_proj_parm.ad) * cos(u) * cos(deltav)); + d = asin(cos(u) * sin(deltav) / cos(s)); - u= 2. * (atan(k * pow( tan(lp_lat / 2. + s45), alfa) / gfi)-s45); + eps = this->m_proj_parm.n * d; + rho = this->m_proj_parm.rho0 * math::pow(tan(S0 / T(2) + S45) , this->m_proj_parm.n) / math::pow(tan(s / T(2) + S45) , this->m_proj_parm.n); - deltav = - lp_lon * alfa; + xy_y = rho * cos(eps); + xy_x = rho * sin(eps); - s = asin(cos(ad) * sin(u) + sin(ad) * cos(u) * cos(deltav)); - d = asin(cos(u) * sin(deltav) / cos(s)); - eps = n * d; - ro = ro0 * pow(tan(s0 / 2. + s45) , n) / pow(tan(s / 2. + s45) , n) ; - - /* x and y are reverted! */ - xy_y = ro * cos(eps) / a; - xy_x = ro * sin(eps) / a; - - if( !pj_param(this->m_par.params, "tczech").i ) - { - xy_y *= -1.0; - xy_x *= -1.0; - } + xy_y *= this->m_proj_parm.czech; + xy_x *= this->m_proj_parm.czech; } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - /* calculate lat/lon from xy */ - - /* Constants, identisch wie in der Umkehrfunktion */ - CalculationType s45, s90, fi0, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n; - CalculationType u, deltav, s, d, eps, ro, fi1, xy0; - int ok; - - s45 = 0.785398163397448; /* 45 DEG */ - s90 = 2 * s45; - fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */ - - - /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must - be set to 1 here. - Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128, - e2=0.006674372230614; - */ - a = 1; /* 6377397.155; */ - /* e2 = this->m_par.es; */ /* 0.006674372230614; */ - e2 = 0.006674372230614; - e = sqrt(e2); - - alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2)); - uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */ - u0 = asin(sin(fi0) / alfa); - g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. ); - - k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g; - - k1 = this->m_par.k0; - n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2)); - s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */ - n = sin(s0); - ro0 = k1 * n0 / tan(s0); - ad = s90 - uq; - - - /* Transformation */ - /* revert y, x*/ - xy0=xy_x; - xy_x=xy_y; - xy_y=xy0; - - if( !pj_param(this->m_par.params, "tczech").i ) - { - xy_x *= -1.0; - xy_y *= -1.0; - } - - ro = sqrt(xy_x * xy_x + xy_y * xy_y); + T u, deltav, s, d, eps, rho, fi1, xy0; + int i; + + // TODO: replace with std::swap() + xy0 = xy_x; + xy_x = xy_y; + xy_y = xy0; + + xy_x *= this->m_proj_parm.czech; + xy_y *= this->m_proj_parm.czech; + + rho = sqrt(xy_x * xy_x + xy_y * xy_y); eps = atan2(xy_y, xy_x); - d = eps / sin(s0); - s = 2. * (atan( pow(ro0 / ro, 1. / n) * tan(s0 / 2. + s45)) - s45); - u = asin(cos(ad) * sin(s) - sin(ad) * cos(s) * cos(d)); - deltav = asin(cos(s) * sin(d) / cos(u)); + d = eps / sin(S0); + s = T(2) * (atan(math::pow(this->m_proj_parm.rho0 / rho, T(1) / this->m_proj_parm.n) * tan(S0 / T(2) + S45)) - S45); - lp_lon = this->m_par.lam0 - deltav / alfa; + u = asin(cos(this->m_proj_parm.ad) * sin(s) - sin(this->m_proj_parm.ad) * cos(s) * cos(d)); + deltav = asin(cos(s) * sin(d) / cos(u)); - /* ITERATION FOR lp_lat */ - fi1 = u; + lp_lon = this->m_par.lam0 - deltav / this->m_proj_parm.alpha; - ok = 0; - do - { - lp_lat = 2. * ( atan( pow( k, -1. / alfa) * - pow( tan(u / 2. + s45) , 1. / alfa) * - pow( (1. + e * sin(fi1)) / (1. - e * sin(fi1)) , e / 2.) - ) - s45); + /* ITERATION FOR lp_lat */ + fi1 = u; - if (fabs(fi1 - lp_lat) < 0.000000000000001) ok=1; - fi1 = lp_lat; + for (i = max_iter; i ; --i) { + lp_lat = T(2) * ( atan( math::pow( this->m_proj_parm.k, T(-1) / this->m_proj_parm.alpha) * + math::pow( tan(u / T(2) + S45) , T(1) / this->m_proj_parm.alpha) * + math::pow( (T(1) + this->m_par.e * sin(fi1)) / (T(1) - this->m_par.e * sin(fi1)) , this->m_par.e / T(2)) + ) - S45); - } - while (ok==0); + if (fabs(fi1 - lp_lat) < epsilon) + break; + fi1 = lp_lat; + } + if( i == 0 ) + BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) ); lp_lon -= this->m_par.lam0; } @@ -268,32 +197,39 @@ namespace projections template <typename Parameters, typename T> inline void setup_krovak(Parameters& par, par_krovak<T>& proj_parm) { - T ts; - /* read some Parameters, - * here Latitude Truescale */ - - ts = pj_param(par.params, "rlat_ts").f; - proj_parm.C_x = ts; + T u0, n0, g; /* we want Bessel as fixed ellipsoid */ par.a = 6377397.155; par.e = sqrt(par.es = 0.006674372230614); - /* if latitude of projection center is not set, use 49d30'N */ - if (!pj_param(par.params, "tlat_0").i) - par.phi0 = 0.863937979737193; - - /* if center long is not set use 42d30'E of Ferro - 17d40' for Ferro */ - /* that will correspond to using longitudes relative to greenwich */ - /* as input and output, instead of lat/long relative to Ferro */ - if (!pj_param(par.params, "tlon_0").i) - par.lam0 = 0.7417649320975901 - 0.308341501185665; - - /* if scale not set default to 0.9999 */ - if (!pj_param(par.params, "tk").i) - par.k0 = 0.9999; - - /* always the same */ + /* if latitude of projection center is not set, use 49d30'N */ + if (!pj_param_exists(par.params, "lat_0")) + par.phi0 = 0.863937979737193; + + /* if center long is not set use 42d30'E of Ferro - 17d40' for Ferro */ + /* that will correspond to using longitudes relative to greenwich */ + /* as input and output, instead of lat/long relative to Ferro */ + if (!pj_param_exists(par.params, "lon_0")) + par.lam0 = 0.7417649320975901 - 0.308341501185665; + + /* if scale not set default to 0.9999 */ + if (!pj_param_exists(par.params, "k")) + par.k0 = 0.9999; + + proj_parm.czech = 1; + if( !pj_param_exists(par.params, "czech") ) + proj_parm.czech = -1; + + /* Set up shared parameters between forward and inverse */ + proj_parm.alpha = sqrt(T(1) + (par.es * math::pow(cos(par.phi0), 4)) / (T(1) - par.es)); + u0 = asin(sin(par.phi0) / proj_parm.alpha); + g = math::pow( (T(1) + par.e * sin(par.phi0)) / (T(1) - par.e * sin(par.phi0)) , proj_parm.alpha * par.e / T(2) ); + proj_parm.k = tan( u0 / 2. + S45) / math::pow(tan(par.phi0 / T(2) + S45) , proj_parm.alpha) * g; + n0 = sqrt(T(1) - par.es) / (T(1) - par.es * math::pow(sin(par.phi0), 2)); + proj_parm.n = sin(S0); + proj_parm.rho0 = par.k0 * n0 / tan(S0); + proj_parm.ad = S90 - UQ; } }} // namespace detail::krovak @@ -316,10 +252,10 @@ namespace projections \par Example \image html ex_krovak.gif */ - template <typename CalculationType, typename Parameters> - struct krovak_ellipsoid : public detail::krovak::base_krovak_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct krovak_ellipsoid : public detail::krovak::base_krovak_ellipsoid<T, Parameters> { - inline krovak_ellipsoid(const Parameters& par) : detail::krovak::base_krovak_ellipsoid<CalculationType, Parameters>(par) + inline krovak_ellipsoid(const Parameters& par) : detail::krovak::base_krovak_ellipsoid<T, Parameters>(par) { detail::krovak::setup_krovak(this->m_par, this->m_proj_parm); } @@ -333,20 +269,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::krovak, krovak_ellipsoid, krovak_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class krovak_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class krovak_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<krovak_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<krovak_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void krovak_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void krovak_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("krovak", new krovak_entry<CalculationType, Parameters>); + factory.add_to_factory("krovak", new krovak_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/labrd.hpp b/boost/geometry/srs/projections/proj/labrd.hpp index 0a51689308..32a15e2781 100644 --- a/boost/geometry/srs/projections/proj/labrd.hpp +++ b/boost/geometry/srs/projections/proj/labrd.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct labrd {}; + struct labrd {}; // Laborde }} //namespace srs::par4 @@ -60,7 +59,7 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace labrd { - static const double EPS = 1.e-10; + static const double epsilon = 1.e-10; template <typename T> struct par_labrd @@ -70,33 +69,29 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_labrd_ellipsoid : public base_t_fi<base_labrd_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_labrd_ellipsoid + : public base_t_fi<base_labrd_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_labrd<CalculationType> m_proj_parm; + par_labrd<T> m_proj_parm; inline base_labrd_ellipsoid(const Parameters& par) - : base_t_fi<base_labrd_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_labrd_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); - CalculationType V1, V2, ps, sinps, cosps, sinps2, cosps2, I1, I2, I3, I4, I5, I6, - x2, y2, t; + T V1, V2, ps, sinps, cosps, sinps2, cosps2; + T I1, I2, I3, I4, I5, I6, x2, y2, t; - V1 = this->m_proj_parm.A * log( tan(FORTPI + .5 * lp_lat) ); + V1 = this->m_proj_parm.A * log( tan(fourth_pi + .5 * lp_lat) ); t = this->m_par.e * sin(lp_lat); V2 = .5 * this->m_par.e * this->m_proj_parm.A * log ((1. + t)/(1. - t)); - ps = 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI); + ps = 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - fourth_pi); I1 = ps - this->m_proj_parm.p0s; cosps = cos(ps); cosps2 = cosps * cosps; sinps = sin(ps); sinps2 = sinps * sinps; @@ -120,12 +115,15 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); - CalculationType x2, y2, V1, V2, V3, V4, t, t2, ps, pe, tpe, s, - I7, I8, I9, I10, I11, d, Re; + /* t = 0.0 optimization is to avoid a false positive cppcheck warning */ + /* (cppcheck git beaf29c15867984aa3c2a15cf15bd7576ccde2b3). Might no */ + /* longer be necessary with later versions. */ + T x2, y2, V1, V2, V3, V4, t = 0.0, t2, ps, pe, tpe, s; + T I7, I8, I9, I10, I11, d, Re; int i; x2 = xy_x * xy_x; @@ -138,20 +136,17 @@ namespace projections xy_y += this->m_proj_parm.Cb * V1 - this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cd * V3 + this->m_proj_parm.Cc * V4; ps = this->m_proj_parm.p0s + xy_y / this->m_proj_parm.kRg; pe = ps + this->m_par.phi0 - this->m_proj_parm.p0s; + for ( i = 20; i; --i) { - V1 = this->m_proj_parm.A * log(tan(FORTPI + .5 * pe)); + V1 = this->m_proj_parm.A * log(tan(fourth_pi + .5 * pe)); tpe = this->m_par.e * sin(pe); V2 = .5 * this->m_par.e * this->m_proj_parm.A * log((1. + tpe)/(1. - tpe)); - t = ps - 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI); + t = ps - 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - fourth_pi); pe += t; - if (fabs(t) < EPS) + if (fabs(t) < epsilon) break; } - /* - if (!i) { - } else { - } - */ + t = this->m_par.e * sin(pe); t = 1. - t * t; Re = this->m_par.one_es / ( t * sqrt(t) ); @@ -182,12 +177,12 @@ namespace projections template <typename Parameters, typename T> inline void setup_labrd(Parameters& par, par_labrd<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); T Az, sinp, R, N, t; - proj_parm.rot = pj_param(par.params, "bno_rot").i == 0; - Az = pj_param(par.params, "razi").f; + proj_parm.rot = pj_get_param_b(par.params, "no_rot"); + Az = pj_get_param_r(par.params, "azi"); sinp = sin(par.phi0); t = 1. - par.es * sinp * sinp; N = 1. / sqrt(t); @@ -197,8 +192,8 @@ namespace projections proj_parm.A = sinp / sin(proj_parm.p0s); t = par.e * sinp; proj_parm.C = .5 * par.e * proj_parm.A * log((1. + t)/(1. - t)) + - - proj_parm.A * log( tan(FORTPI + .5 * par.phi0)) - + log( tan(FORTPI + .5 * proj_parm.p0s)); + - proj_parm.A * log( tan(fourth_pi + .5 * par.phi0)) + + log( tan(fourth_pi + .5 * proj_parm.p0s)); t = Az + Az; proj_parm.Ca = (1. - cos(t)) * ( proj_parm.Cb = 1. / (12. * proj_parm.kRg * proj_parm.kRg) ); proj_parm.Cb *= sin(t); @@ -225,10 +220,10 @@ namespace projections \par Example \image html ex_labrd.gif */ - template <typename CalculationType, typename Parameters> - struct labrd_ellipsoid : public detail::labrd::base_labrd_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct labrd_ellipsoid : public detail::labrd::base_labrd_ellipsoid<T, Parameters> { - inline labrd_ellipsoid(const Parameters& par) : detail::labrd::base_labrd_ellipsoid<CalculationType, Parameters>(par) + inline labrd_ellipsoid(const Parameters& par) : detail::labrd::base_labrd_ellipsoid<T, Parameters>(par) { detail::labrd::setup_labrd(this->m_par, this->m_proj_parm); } @@ -242,20 +237,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::labrd, labrd_ellipsoid, labrd_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class labrd_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class labrd_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<labrd_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<labrd_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void labrd_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void labrd_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("labrd", new labrd_entry<CalculationType, Parameters>); + factory.add_to_factory("labrd", new labrd_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/laea.hpp b/boost/geometry/srs/projections/proj/laea.hpp index 757d2b7ff0..6d5a948672 100644 --- a/boost/geometry/srs/projections/proj/laea.hpp +++ b/boost/geometry/srs/projections/proj/laea.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP + #include <boost/config.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -66,13 +65,14 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace laea { - static const double EPS10 = 1.e-10; - static const int NITER = 20; - static const double CONV = 1.e-10; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + static const double epsilon10 = 1.e-10; + + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_laea @@ -85,75 +85,77 @@ namespace projections T qp; T dd; T rq; - T apa[APA_SIZE]; - int mode; + detail::apa<T> apa; + mode_type mode; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_laea_ellipsoid : public base_t_fi<base_laea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_laea_ellipsoid + : public base_t_fi<base_laea_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_laea<CalculationType> m_proj_parm; + par_laea<T> m_proj_parm; inline base_laea_ellipsoid(const Parameters& par) - : base_t_fi<base_laea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_laea_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0; + T coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0; coslam = cos(lp_lon); sinlam = sin(lp_lon); sinphi = sin(lp_lat); q = pj_qsfn(sinphi, this->m_par.e, this->m_par.one_es); - if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) { + + if (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit) { sinb = q / this->m_proj_parm.qp; cosb = sqrt(1. - sinb * sinb); } + switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: b = 1. + this->m_proj_parm.sinb1 * sinb + this->m_proj_parm.cosb1 * cosb * coslam; break; - case EQUIT: + case equit: b = 1. + cosb * coslam; break; - case N_POLE: - b = HALFPI + lp_lat; + case n_pole: + b = half_pi + lp_lat; q = this->m_proj_parm.qp - q; break; - case S_POLE: - b = lp_lat - HALFPI; + case s_pole: + b = lp_lat - half_pi; q = this->m_proj_parm.qp + q; break; } - if (fabs(b) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(b) < epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + switch (this->m_proj_parm.mode) { - case OBLIQ: - xy_y = this->m_proj_parm.ymf * ( b = sqrt(2. / b) ) - * (this->m_proj_parm.cosb1 * sinb - this->m_proj_parm.sinb1 * cosb * coslam); + case obliq: + b = sqrt(2. / b); + xy_y = this->m_proj_parm.ymf * b * (this->m_proj_parm.cosb1 * sinb - this->m_proj_parm.sinb1 * cosb * coslam); goto eqcon; break; - case EQUIT: - xy_y = (b = sqrt(2. / (1. + cosb * coslam))) * sinb * this->m_proj_parm.ymf; + case equit: + b = sqrt(2. / (1. + cosb * coslam)); + xy_y = b * sinb * this->m_proj_parm.ymf; eqcon: xy_x = this->m_proj_parm.xmf * b * cosb * sinlam; break; - case N_POLE: - case S_POLE: + case n_pole: + case s_pole: if (q >= 0.) { - xy_x = (b = sqrt(q)) * sinlam; - xy_y = coslam * (this->m_proj_parm.mode == S_POLE ? b : -b); + b = sqrt(q); + xy_x = b * sinlam; + xy_y = coslam * (this->m_proj_parm.mode == s_pole ? b : -b); } else xy_x = xy_y = 0.; break; @@ -162,42 +164,45 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType cCe, sCe, q, rho, ab=0.0; + T cCe, sCe, q, rho, ab=0.0; switch (this->m_proj_parm.mode) { - case EQUIT: - case OBLIQ: - if ((rho = boost::math::hypot(xy_x /= this->m_proj_parm.dd, xy_y *= this->m_proj_parm.dd)) < EPS10) { + case equit: + case obliq: + xy_x /= this->m_proj_parm.dd; + xy_y *= this->m_proj_parm.dd; + rho = boost::math::hypot(xy_x, xy_y); + if (rho < epsilon10) { lp_lon = 0.; lp_lat = this->m_par.phi0; return; } - cCe = cos(sCe = 2. * asin(.5 * rho / this->m_proj_parm.rq)); - xy_x *= (sCe = sin(sCe)); - if (this->m_proj_parm.mode == OBLIQ) { - q = this->m_proj_parm.qp * (ab = cCe * this->m_proj_parm.sinb1 + xy_y * sCe * this->m_proj_parm.cosb1 / rho); + sCe = 2. * asin(.5 * rho / this->m_proj_parm.rq); + cCe = cos(sCe); + sCe = sin(sCe); + xy_x *= sCe; + if (this->m_proj_parm.mode == obliq) { + ab = cCe * this->m_proj_parm.sinb1 + xy_y * sCe * this->m_proj_parm.cosb1 / rho; xy_y = rho * this->m_proj_parm.cosb1 * cCe - xy_y * this->m_proj_parm.sinb1 * sCe; } else { - q = this->m_proj_parm.qp * (ab = xy_y * sCe / rho); + ab = xy_y * sCe / rho; xy_y = rho * cCe; } break; - case N_POLE: + case n_pole: xy_y = -xy_y; BOOST_FALLTHROUGH; - case S_POLE: - if (!(q = (xy_x * xy_x + xy_y * xy_y)) ) { + case s_pole: + q = (xy_x * xy_x + xy_y * xy_y); + if (q == 0.0) { lp_lon = 0.; lp_lat = this->m_par.phi0; return; } - /* - q = this->m_proj_parm.qp - q; - */ ab = 1. - q / this->m_proj_parm.qp; - if (this->m_proj_parm.mode == S_POLE) + if (this->m_proj_parm.mode == s_pole) ab = - ab; break; } @@ -213,52 +218,51 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_laea_spheroid : public base_t_fi<base_laea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_laea_spheroid + : public base_t_fi<base_laea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_laea<CalculationType> m_proj_parm; + par_laea<T> m_proj_parm; inline base_laea_spheroid(const Parameters& par) - : base_t_fi<base_laea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_laea_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); - CalculationType coslam, cosphi, sinphi; + T coslam, cosphi, sinphi; sinphi = sin(lp_lat); cosphi = cos(lp_lat); coslam = cos(lp_lon); switch (this->m_proj_parm.mode) { - case EQUIT: + case equit: xy_y = 1. + cosphi * coslam; goto oblcon; - case OBLIQ: + case obliq: xy_y = 1. + this->m_proj_parm.sinb1 * sinphi + this->m_proj_parm.cosb1 * cosphi * coslam; oblcon: - if (xy_y <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - xy_x = (xy_y = sqrt(2. / xy_y)) * cosphi * sin(lp_lon); - xy_y *= this->m_proj_parm.mode == EQUIT ? sinphi : + if (xy_y <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + xy_y = sqrt(2. / xy_y); + xy_x = xy_y * cosphi * sin(lp_lon); + xy_y *= this->m_proj_parm.mode == equit ? sinphi : this->m_proj_parm.cosb1 * sinphi - this->m_proj_parm.sinb1 * cosphi * coslam; break; - case N_POLE: + case n_pole: coslam = -coslam; BOOST_FALLTHROUGH; - case S_POLE: - if (fabs(lp_lat + this->m_par.phi0) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - xy_y = FORTPI - lp_lat * .5; - xy_y = 2. * (this->m_proj_parm.mode == S_POLE ? cos(xy_y) : sin(xy_y)); + case s_pole: + if (fabs(lp_lat + this->m_par.phi0) < epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + xy_y = fourth_pi - lp_lat * .5; + xy_y = 2. * (this->m_proj_parm.mode == s_pole ? cos(xy_y) : sin(xy_y)); xy_x = xy_y * sin(lp_lon); xy_y *= coslam; break; @@ -267,41 +271,42 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType cosz=0.0, rh, sinz=0.0; + T cosz=0.0, rh, sinz=0.0; rh = boost::math::hypot(xy_x, xy_y); - if ((lp_lat = rh * .5 ) > 1.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((lp_lat = rh * .5 ) > 1.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } lp_lat = 2. * asin(lp_lat); - if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) { + if (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit) { sinz = sin(lp_lat); cosz = cos(lp_lat); } switch (this->m_proj_parm.mode) { - case EQUIT: - lp_lat = fabs(rh) <= EPS10 ? 0. : asin(xy_y * sinz / rh); + case equit: + lp_lat = fabs(rh) <= epsilon10 ? 0. : asin(xy_y * sinz / rh); xy_x *= sinz; xy_y = cosz * rh; break; - case OBLIQ: - lp_lat = fabs(rh) <= EPS10 ? this->m_par.phi0 : + case obliq: + lp_lat = fabs(rh) <= epsilon10 ? this->m_par.phi0 : asin(cosz * this->m_proj_parm.sinb1 + xy_y * sinz * this->m_proj_parm.cosb1 / rh); xy_x *= sinz * this->m_proj_parm.cosb1; xy_y = (cosz - sin(lp_lat) * this->m_proj_parm.sinb1) * rh; break; - case N_POLE: + case n_pole: xy_y = -xy_y; - lp_lat = HALFPI - lp_lat; + lp_lat = half_pi - lp_lat; break; - case S_POLE: - lp_lat -= HALFPI; + case s_pole: + lp_lat -= half_pi; break; } - lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == EQUIT || this->m_proj_parm.mode == OBLIQ)) ? + lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == equit || this->m_proj_parm.mode == obliq)) ? 0. : atan2(xy_x, xy_y); } @@ -316,34 +321,35 @@ namespace projections template <typename Parameters, typename T> inline void setup_laea(Parameters& par, par_laea<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T t; - if (fabs((t = fabs(par.phi0)) - HALFPI) < EPS10) - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; - else if (fabs(t) < EPS10) - proj_parm.mode = EQUIT; + t = fabs(par.phi0); + if (fabs(t - half_pi) < epsilon10) + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; + else if (fabs(t) < epsilon10) + proj_parm.mode = equit; else - proj_parm.mode = OBLIQ; - if (par.es) { + proj_parm.mode = obliq; + if (par.es != 0.0) { double sinphi; par.e = sqrt(par.es); proj_parm.qp = pj_qsfn(1., par.e, par.one_es); proj_parm.mmf = .5 / (1. - par.es); - pj_authset(par.es, proj_parm.apa); + proj_parm.apa = pj_authset<T>(par.es); switch (proj_parm.mode) { - case N_POLE: - case S_POLE: + case n_pole: + case s_pole: proj_parm.dd = 1.; break; - case EQUIT: + case equit: proj_parm.dd = 1. / (proj_parm.rq = sqrt(.5 * proj_parm.qp)); proj_parm.xmf = 1.; proj_parm.ymf = .5 * proj_parm.qp; break; - case OBLIQ: + case obliq: proj_parm.rq = sqrt(.5 * proj_parm.qp); sinphi = sin(par.phi0); proj_parm.sinb1 = pj_qsfn(sinphi, par.e, par.one_es) / proj_parm.qp; @@ -355,7 +361,7 @@ namespace projections break; } } else { - if (proj_parm.mode == OBLIQ) { + if (proj_parm.mode == obliq) { proj_parm.sinb1 = sin(par.phi0); proj_parm.cosb1 = cos(par.phi0); } @@ -378,10 +384,10 @@ namespace projections \par Example \image html ex_laea.gif */ - template <typename CalculationType, typename Parameters> - struct laea_ellipsoid : public detail::laea::base_laea_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct laea_ellipsoid : public detail::laea::base_laea_ellipsoid<T, Parameters> { - inline laea_ellipsoid(const Parameters& par) : detail::laea::base_laea_ellipsoid<CalculationType, Parameters>(par) + inline laea_ellipsoid(const Parameters& par) : detail::laea::base_laea_ellipsoid<T, Parameters>(par) { detail::laea::setup_laea(this->m_par, this->m_proj_parm); } @@ -400,10 +406,10 @@ namespace projections \par Example \image html ex_laea.gif */ - template <typename CalculationType, typename Parameters> - struct laea_spheroid : public detail::laea::base_laea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct laea_spheroid : public detail::laea::base_laea_spheroid<T, Parameters> { - inline laea_spheroid(const Parameters& par) : detail::laea::base_laea_spheroid<CalculationType, Parameters>(par) + inline laea_spheroid(const Parameters& par) : detail::laea::base_laea_spheroid<T, Parameters>(par) { detail::laea::setup_laea(this->m_par, this->m_proj_parm); } @@ -417,23 +423,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::laea, laea_spheroid, laea_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class laea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class laea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<laea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<laea_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<laea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<laea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void laea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void laea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("laea", new laea_entry<CalculationType, Parameters>); + factory.add_to_factory("laea", new laea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/lagrng.hpp b/boost/geometry/srs/projections/proj/lagrng.hpp index 8ed5c1389e..6cedef717f 100644 --- a/boost/geometry/srs/projections/proj/lagrng.hpp +++ b/boost/geometry/srs/projections/proj/lagrng.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct lagrng {}; + struct lagrng {}; // Lagrange }} //namespace srs::par4 @@ -63,47 +62,44 @@ namespace projections namespace detail { namespace lagrng { - static const double TOL = 1e-10; + static const double tolerance = 1e-10; template <typename T> struct par_lagrng { - T hrw; - T rw; T a1; + T rw; + T hrw; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_lagrng_spheroid : public base_t_f<base_lagrng_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_lagrng_spheroid + : public base_t_f<base_lagrng_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_lagrng<CalculationType> m_proj_parm; + par_lagrng<T> m_proj_parm; inline base_lagrng_spheroid(const Parameters& par) - : base_t_f<base_lagrng_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_lagrng_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType v, c; + T v, c; - if (fabs(fabs(lp_lat) - HALFPI) < TOL) { + if (fabs(fabs(lp_lat) - half_pi) < tolerance) { xy_x = 0; xy_y = lp_lat < 0 ? -2. : 2.; } else { lp_lat = sin(lp_lat); - v = this->m_proj_parm.a1 * pow((1. + lp_lat)/(1. - lp_lat), this->m_proj_parm.hrw); - if ((c = 0.5 * (v + 1./v) + cos(lp_lon *= this->m_proj_parm.rw)) < TOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + v = this->m_proj_parm.a1 * math::pow((T(1) + lp_lat)/(T(1) - lp_lat), this->m_proj_parm.hrw); + if ((c = 0.5 * (v + 1./v) + cos(lp_lon *= this->m_proj_parm.rw)) < tolerance) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = 2. * sin(lp_lon) / c; xy_y = (v - 1./v) / c; } @@ -122,13 +118,18 @@ namespace projections { T phi1; - if ((proj_parm.rw = pj_param(par.params, "dW").f) <= 0) - BOOST_THROW_EXCEPTION( projection_exception(-27) ); - proj_parm.hrw = 0.5 * (proj_parm.rw = 1. / proj_parm.rw); - phi1 = pj_param(par.params, "rlat_1").f; - if (fabs(fabs(phi1 = sin(phi1)) - 1.) < TOL) - BOOST_THROW_EXCEPTION( projection_exception(-22) ); - proj_parm.a1 = pow((1. - phi1)/(1. + phi1), proj_parm.hrw); + proj_parm.rw = pj_get_param_f(par.params, "W"); + if (proj_parm.rw <= 0) + BOOST_THROW_EXCEPTION( projection_exception(error_w_or_m_zero_or_less) ); + + proj_parm.rw = 1. / proj_parm.rw; + proj_parm.hrw = 0.5 * proj_parm.rw; + phi1 = pj_get_param_r(par.params, "lat_1"); + if (fabs(fabs(phi1 = sin(phi1)) - 1.) < tolerance) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_larger_than_90) ); + + proj_parm.a1 = math::pow((T(1) - phi1)/(T(1) + phi1), proj_parm.hrw); + par.es = 0.; } @@ -151,10 +152,10 @@ namespace projections \par Example \image html ex_lagrng.gif */ - template <typename CalculationType, typename Parameters> - struct lagrng_spheroid : public detail::lagrng::base_lagrng_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lagrng_spheroid : public detail::lagrng::base_lagrng_spheroid<T, Parameters> { - inline lagrng_spheroid(const Parameters& par) : detail::lagrng::base_lagrng_spheroid<CalculationType, Parameters>(par) + inline lagrng_spheroid(const Parameters& par) : detail::lagrng::base_lagrng_spheroid<T, Parameters>(par) { detail::lagrng::setup_lagrng(this->m_par, this->m_proj_parm); } @@ -168,20 +169,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lagrng, lagrng_spheroid, lagrng_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lagrng_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lagrng_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<lagrng_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<lagrng_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void lagrng_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void lagrng_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lagrng", new lagrng_entry<CalculationType, Parameters>); + factory.add_to_factory("lagrng", new lagrng_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/larr.hpp b/boost/geometry/srs/projections/proj/larr.hpp index 2b2735c0dd..84fbafac62 100644 --- a/boost/geometry/srs/projections/proj/larr.hpp +++ b/boost/geometry/srs/projections/proj/larr.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LARR_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LARR_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LARR_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LARR_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct larr {}; + struct larr {}; // Larrivee }} //namespace srs::par4 @@ -61,33 +60,23 @@ namespace projections namespace detail { namespace larr { - //static const double SIXTH = .16666666666666666; - - template <typename T> - inline T SIXTH() { return .16666666666666666666666666666666; } - // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_larr_spheroid : public base_t_f<base_larr_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_larr_spheroid + : public base_t_f<base_larr_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_larr_spheroid(const Parameters& par) - : base_t_f<base_larr_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_larr_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType SIXTH = larr::SIXTH<CalculationType>(); + static const T sixth = detail::sixth<T>(); xy_x = 0.5 * lp_lon * (1. + sqrt(cos(lp_lat))); - xy_y = lp_lat / (cos(0.5 * lp_lat) * cos(SIXTH * lp_lon)); + xy_y = lp_lat / (cos(0.5 * lp_lat) * cos(sixth * lp_lon)); } static inline std::string get_name() @@ -120,10 +109,10 @@ namespace projections \par Example \image html ex_larr.gif */ - template <typename CalculationType, typename Parameters> - struct larr_spheroid : public detail::larr::base_larr_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct larr_spheroid : public detail::larr::base_larr_spheroid<T, Parameters> { - inline larr_spheroid(const Parameters& par) : detail::larr::base_larr_spheroid<CalculationType, Parameters>(par) + inline larr_spheroid(const Parameters& par) : detail::larr::base_larr_spheroid<T, Parameters>(par) { detail::larr::setup_larr(this->m_par); } @@ -137,20 +126,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::larr, larr_spheroid, larr_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class larr_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class larr_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<larr_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<larr_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void larr_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void larr_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("larr", new larr_entry<CalculationType, Parameters>); + factory.add_to_factory("larr", new larr_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/lask.hpp b/boost/geometry/srs/projections/proj/lask.hpp index 9ee1a95efe..3f06533bf2 100644 --- a/boost/geometry/srs/projections/proj/lask.hpp +++ b/boost/geometry/srs/projections/proj/lask.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LASK_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LASK_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LASK_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LASK_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct lask {}; + struct lask {}; // Laskowski }} //namespace srs::par4 @@ -73,30 +72,25 @@ namespace projections static const double b05 = -0.0491032; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_lask_spheroid : public base_t_f<base_lask_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_lask_spheroid + : public base_t_f<base_lask_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - - inline base_lask_spheroid(const Parameters& par) - : base_t_f<base_lask_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + inline base_lask_spheroid(const Parameters& par) + : base_t_f<base_lask_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType l2, p2; + T l2, p2; l2 = lp_lon * lp_lon; p2 = lp_lat * lp_lat; xy_x = lp_lon * (a10 + p2 * (a12 + l2 * a32 + p2 * a14)); xy_y = lp_lat * (b01 + l2 * (b21 + p2 * b23 + l2 * b41) + - p2 * (b03 + p2 * b05)); + p2 * (b03 + p2 * b05)); } static inline std::string get_name() @@ -129,10 +123,10 @@ namespace projections \par Example \image html ex_lask.gif */ - template <typename CalculationType, typename Parameters> - struct lask_spheroid : public detail::lask::base_lask_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lask_spheroid : public detail::lask::base_lask_spheroid<T, Parameters> { - inline lask_spheroid(const Parameters& par) : detail::lask::base_lask_spheroid<CalculationType, Parameters>(par) + inline lask_spheroid(const Parameters& par) : detail::lask::base_lask_spheroid<T, Parameters>(par) { detail::lask::setup_lask(this->m_par); } @@ -146,20 +140,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lask, lask_spheroid, lask_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lask_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lask_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<lask_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<lask_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void lask_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void lask_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lask", new lask_entry<CalculationType, Parameters>); + factory.add_to_factory("lask", new lask_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/latlong.hpp b/boost/geometry/srs/projections/proj/latlong.hpp index e806381f2d..4c2d00a805 100644 --- a/boost/geometry/srs/projections/proj/latlong.hpp +++ b/boost/geometry/srs/projections/proj/latlong.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,13 +15,13 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Stub projection implementation for lat/long coordinates. We -// don't actually change the coordinates, but we want proj=latlong -// to act sort of like a projection. +// don't actually change the coordinates, but we want proj=latlong +// to act sort of like a projection. // Author: Frank Warmerdam, warmerdam@pobox.com // Copyright (c) 2000, Frank Warmerdam @@ -47,6 +43,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -58,10 +57,10 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct lonlat {}; - struct latlon {}; - struct latlong {}; - struct longlat {}; + struct lonlat {}; // Lat/long (Geodetic) + struct latlon {}; // Lat/long (Geodetic alias) + struct latlong {}; // Lat/long (Geodetic alias) + struct longlat {}; // Lat/long (Geodetic alias) }} //namespace srs::par4 @@ -74,33 +73,32 @@ namespace projections /* very loosely based upon DMA code by Bradford W. Drew */ // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_latlong_other : public base_t_fi<base_latlong_other<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_latlong_other + : public base_t_fi<base_latlong_other<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_latlong_other(const Parameters& par) - : base_t_fi<base_latlong_other<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_latlong_other<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - xy_x = lp_lon / this->m_par.a; - xy_y = lp_lat / this->m_par.a; + // TODO: in the original code a is not used + // different mechanism is probably used instead + xy_x = lp_lon / this->m_par.a; + xy_y = lp_lat / this->m_par.a; } // INVERSE(inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - lp_lat = xy_y * this->m_par.a; - lp_lon = xy_x * this->m_par.a; + // TODO: in the original code a is not used + // different mechanism is probably used instead + lp_lat = xy_y * this->m_par.a; + lp_lon = xy_x * this->m_par.a; } static inline std::string get_name() @@ -158,10 +156,10 @@ namespace projections \par Example \image html ex_lonlat.gif */ - template <typename CalculationType, typename Parameters> - struct lonlat_other : public detail::latlong::base_latlong_other<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lonlat_other : public detail::latlong::base_latlong_other<T, Parameters> { - inline lonlat_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par) + inline lonlat_other(const Parameters& par) : detail::latlong::base_latlong_other<T, Parameters>(par) { detail::latlong::setup_lonlat(this->m_par); } @@ -176,10 +174,10 @@ namespace projections \par Example \image html ex_latlon.gif */ - template <typename CalculationType, typename Parameters> - struct latlon_other : public detail::latlong::base_latlong_other<CalculationType, Parameters> + template <typename T, typename Parameters> + struct latlon_other : public detail::latlong::base_latlong_other<T, Parameters> { - inline latlon_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par) + inline latlon_other(const Parameters& par) : detail::latlong::base_latlong_other<T, Parameters>(par) { detail::latlong::setup_latlon(this->m_par); } @@ -194,10 +192,10 @@ namespace projections \par Example \image html ex_latlong.gif */ - template <typename CalculationType, typename Parameters> - struct latlong_other : public detail::latlong::base_latlong_other<CalculationType, Parameters> + template <typename T, typename Parameters> + struct latlong_other : public detail::latlong::base_latlong_other<T, Parameters> { - inline latlong_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par) + inline latlong_other(const Parameters& par) : detail::latlong::base_latlong_other<T, Parameters>(par) { detail::latlong::setup_latlong(this->m_par); } @@ -212,10 +210,10 @@ namespace projections \par Example \image html ex_longlat.gif */ - template <typename CalculationType, typename Parameters> - struct longlat_other : public detail::latlong::base_latlong_other<CalculationType, Parameters> + template <typename T, typename Parameters> + struct longlat_other : public detail::latlong::base_latlong_other<T, Parameters> { - inline longlat_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par) + inline longlat_other(const Parameters& par) : detail::latlong::base_latlong_other<T, Parameters>(par) { detail::latlong::setup_longlat(this->m_par); } @@ -232,53 +230,53 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::longlat, longlat_other, longlat_other) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lonlat_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lonlat_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<lonlat_other<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<lonlat_other<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class latlon_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class latlon_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<latlon_other<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<latlon_other<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class latlong_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class latlong_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<latlong_other<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<latlong_other<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class longlat_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class longlat_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<longlat_other<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<longlat_other<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void latlong_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void latlong_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lonlat", new lonlat_entry<CalculationType, Parameters>); - factory.add_to_factory("latlon", new latlon_entry<CalculationType, Parameters>); - factory.add_to_factory("latlong", new latlong_entry<CalculationType, Parameters>); - factory.add_to_factory("longlat", new longlat_entry<CalculationType, Parameters>); + factory.add_to_factory("lonlat", new lonlat_entry<T, Parameters>); + factory.add_to_factory("latlon", new latlon_entry<T, Parameters>); + factory.add_to_factory("latlong", new latlong_entry<T, Parameters>); + factory.add_to_factory("longlat", new longlat_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/lcc.hpp b/boost/geometry/srs/projections/proj/lcc.hpp index 609c08491c..f8fdd015ea 100644 --- a/boost/geometry/srs/projections/proj/lcc.hpp +++ b/boost/geometry/srs/projections/proj/lcc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LCC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LCC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LCC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LCC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -58,7 +57,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct lcc {}; + struct lcc {}; // Lambert Conformal Conic }} //namespace srs::par4 @@ -67,7 +66,7 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace lcc { - static const double EPS10 = 1.e-10; + static const double epsilon10 = 1.e-10; template <typename T> struct par_lcc @@ -81,88 +80,73 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_lcc_ellipsoid : public base_t_fi<base_lcc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_lcc_ellipsoid + : public base_t_fi<base_lcc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_lcc<CalculationType> m_proj_parm; + par_lcc<T> m_proj_parm; inline base_lcc_ellipsoid(const Parameters& par) - : base_t_fi<base_lcc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_lcc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid & spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + + T rho; - CalculationType rho; - if (fabs(fabs(lp_lat) - HALFPI) < EPS10) { - if ((lp_lat * this->m_proj_parm.n) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(fabs(lp_lat) - half_pi) < epsilon10) { + if ((lp_lat * this->m_proj_parm.n) <= 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } rho = 0.; - } else - rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat), - this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n)); - xy_x = this->m_par.k0 * (rho * sin( lp_lon *= this->m_proj_parm.n ) ); + } else { + rho = this->m_proj_parm.c * (this->m_proj_parm.ellips + ? math::pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.n) + : math::pow(tan(fourth_pi + T(0.5) * lp_lat), -this->m_proj_parm.n)); + } + lp_lon *= this->m_proj_parm.n; + xy_x = this->m_par.k0 * (rho * sin( lp_lon) ); xy_y = this->m_par.k0 * (this->m_proj_parm.rho0 - rho * cos(lp_lon) ); } // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + + T rho; - CalculationType rho; xy_x /= this->m_par.k0; xy_y /= this->m_par.k0; - if( (rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0) { + + xy_y = this->m_proj_parm.rho0 - xy_y; + rho = boost::math::hypot(xy_x, xy_y); + if(rho != 0.0) { if (this->m_proj_parm.n < 0.) { rho = -rho; xy_x = -xy_x; xy_y = -xy_y; } if (this->m_proj_parm.ellips) { - if ((lp_lat = pj_phi2(pow(rho / this->m_proj_parm.c, 1./this->m_proj_parm.n), this->m_par.e)) - == HUGE_VAL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + lp_lat = pj_phi2(math::pow(rho / this->m_proj_parm.c, T(1)/this->m_proj_parm.n), this->m_par.e); + if (lp_lat == HUGE_VAL) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } } else - lp_lat = 2. * atan(pow(this->m_proj_parm.c / rho, 1./this->m_proj_parm.n)) - HALFPI; + lp_lat = 2. * atan(math::pow(this->m_proj_parm.c / rho, T(1)/this->m_proj_parm.n)) - half_pi; lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; } else { lp_lon = 0.; - lp_lat = this->m_proj_parm.n > 0. ? HALFPI : -HALFPI; + lp_lat = this->m_proj_parm.n > 0. ? half_pi : -half_pi; } } - // SPECIAL(fac) - #ifdef SPECIAL_FACTORS_NOT_CONVERTED - inline void fac(Geographic lp, Factors &fac) const - { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - - CalculationType rho; - if (fabs(fabs(lp_lat) - HALFPI) < EPS10) { - if ((lp_lat * this->m_proj_parm.n) <= 0.) return; - rho = 0.; - } else - rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat), - this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n)); - this->m_fac.code |= IS_ANAL_HK + IS_ANAL_CONV; - this->m_fac.k = this->m_fac.h = this->m_par.k0 * this->m_proj_parm.n * rho / - pj_msfn(sin(lp_lat), cos(lp_lat), this->m_par.es); - this->m_fac.conv = - this->m_proj_parm.n * lp_lon; - } - #endif - static inline std::string get_name() { return "lcc_ellipsoid"; @@ -174,25 +158,26 @@ namespace projections template <typename Parameters, typename T> inline void setup_lcc(Parameters& par, par_lcc<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); T cosphi, sinphi; int secant; - proj_parm.phi1 = pj_param(par.params, "rlat_1").f; - if (pj_param(par.params, "tlat_2").i) - proj_parm.phi2 = pj_param(par.params, "rlat_2").f; - else { + proj_parm.phi1 = pj_get_param_r(par.params, "lat_1"); + if (pj_param_r(par.params, "lat_2", proj_parm.phi2)) { + /* empty */ + } else { proj_parm.phi2 = proj_parm.phi1; - if (!pj_param(par.params, "tlat_0").i) + if (!pj_param_exists(par.params, "lat_0")) par.phi0 = proj_parm.phi1; } - if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-21) ); + if (fabs(proj_parm.phi1 + proj_parm.phi2) < epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_conic_lat_equal) ); + proj_parm.n = sinphi = sin(proj_parm.phi1); cosphi = cos(proj_parm.phi1); - secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10; + secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= epsilon10; if( (proj_parm.ellips = (par.es != 0.)) ) { double ml1, m1; @@ -200,21 +185,21 @@ namespace projections m1 = pj_msfn(sinphi, cosphi, par.es); ml1 = pj_tsfn(proj_parm.phi1, sinphi, par.e); if (secant) { /* secant cone */ - proj_parm.n = log(m1 / - pj_msfn(sinphi = sin(proj_parm.phi2), cos(proj_parm.phi2), par.es)); + sinphi = sin(proj_parm.phi2); + proj_parm.n = log(m1 / pj_msfn(sinphi, cos(proj_parm.phi2), par.es)); proj_parm.n /= log(ml1 / pj_tsfn(proj_parm.phi2, sinphi, par.e)); } - proj_parm.c = (proj_parm.rho0 = m1 * pow(ml1, -proj_parm.n) / proj_parm.n); - proj_parm.rho0 *= (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. : - pow(pj_tsfn(par.phi0, sin(par.phi0), par.e), proj_parm.n); + proj_parm.c = (proj_parm.rho0 = m1 * math::pow(ml1, -proj_parm.n) / proj_parm.n); + proj_parm.rho0 *= (fabs(fabs(par.phi0) - half_pi) < epsilon10) ? T(0) : + math::pow(pj_tsfn(par.phi0, sin(par.phi0), par.e), proj_parm.n); } else { if (secant) proj_parm.n = log(cosphi / cos(proj_parm.phi2)) / - log(tan(FORTPI + .5 * proj_parm.phi2) / - tan(FORTPI + .5 * proj_parm.phi1)); - proj_parm.c = cosphi * pow(tan(FORTPI + .5 * proj_parm.phi1), proj_parm.n) / proj_parm.n; - proj_parm.rho0 = (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. : - proj_parm.c * pow(tan(FORTPI + .5 * par.phi0), -proj_parm.n); + log(tan(fourth_pi + .5 * proj_parm.phi2) / + tan(fourth_pi + .5 * proj_parm.phi1)); + proj_parm.c = cosphi * math::pow(tan(fourth_pi + T(0.5) * proj_parm.phi1), proj_parm.n) / proj_parm.n; + proj_parm.rho0 = (fabs(fabs(par.phi0) - half_pi) < epsilon10) ? 0. : + proj_parm.c * math::pow(tan(fourth_pi + T(0.5) * par.phi0), -proj_parm.n); } } @@ -238,10 +223,10 @@ namespace projections \par Example \image html ex_lcc.gif */ - template <typename CalculationType, typename Parameters> - struct lcc_ellipsoid : public detail::lcc::base_lcc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lcc_ellipsoid : public detail::lcc::base_lcc_ellipsoid<T, Parameters> { - inline lcc_ellipsoid(const Parameters& par) : detail::lcc::base_lcc_ellipsoid<CalculationType, Parameters>(par) + inline lcc_ellipsoid(const Parameters& par) : detail::lcc::base_lcc_ellipsoid<T, Parameters>(par) { detail::lcc::setup_lcc(this->m_par, this->m_proj_parm); } @@ -255,20 +240,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lcc, lcc_ellipsoid, lcc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lcc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lcc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<lcc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<lcc_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void lcc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void lcc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lcc", new lcc_entry<CalculationType, Parameters>); + factory.add_to_factory("lcc", new lcc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/lcca.hpp b/boost/geometry/srs/projections/proj/lcca.hpp index a1a2069d8f..ddbdfdb0d1 100644 --- a/boost/geometry/srs/projections/proj/lcca.hpp +++ b/boost/geometry/srs/projections/proj/lcca.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,7 +37,55 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include <boost/core/ignore_unused.hpp> +/***************************************************************************** + + Lambert Conformal Conic Alternative + ----------------------------------- + + This is Gerald Evenden's 2003 implementation of an alternative + "almost" LCC, which has been in use historically, but which + should NOT be used for new projects - i.e: use this implementation + if you need interoperability with old data represented in this + projection, but not in any other case. + + The code was originally discussed on the PROJ.4 mailing list in + a thread archived over at + + http://lists.maptools.org/pipermail/proj/2003-March/000644.html + + It was discussed again in the thread starting at + + http://lists.maptools.org/pipermail/proj/2017-October/007828.html + and continuing at + http://lists.maptools.org/pipermail/proj/2017-November/007831.html + + which prompted Clifford J. Mugnier to add these clarifying notes: + + The French Army Truncated Cubic Lambert (partially conformal) Conic + projection is the Legal system for the projection in France between + the late 1800s and 1948 when the French Legislature changed the law + to recognize the fully conformal version. + + It was (might still be in one or two North African prior French + Colonies) used in North Africa in Algeria, Tunisia, & Morocco, as + well as in Syria during the Levant. + + Last time I have seen it used was about 30+ years ago in + Algeria when it was used to define Lease Block boundaries for + Petroleum Exploration & Production. + + (signed) + + Clifford J. Mugnier, c.p., c.m.s. + Chief of Geodesy + LSU Center for GeoInformatics + Dept. of Civil Engineering + LOUISIANA STATE UNIVERSITY + +*****************************************************************************/ + +#ifndef BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> @@ -64,13 +108,13 @@ namespace projections namespace detail { namespace lcca { - static const int MAX_ITER = 10; - static const double DEL_TOL = 1e-12; + static const int max_iter = 10; + static const double del_tol = 1e-12; template <typename T> struct par_lcca { - T en[EN_SIZE]; + detail::en<T> en; T r0, l, M0; T C; }; @@ -88,25 +132,21 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_lcca_ellipsoid : public base_t_fi<base_lcca_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_lcca_ellipsoid + : public base_t_fi<base_lcca_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_lcca<CalculationType> m_proj_parm; + par_lcca<T> m_proj_parm; inline base_lcca_ellipsoid(const Parameters& par) - : base_t_fi<base_lcca_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_lcca_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType S, r, dr; + T S, r, dr; S = pj_mlfn(lp_lat, sin(lp_lat), cos(lp_lat), this->m_proj_parm.en) - this->m_proj_parm.M0; dr = fS(S, this->m_proj_parm.C); @@ -117,9 +157,9 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType theta, dr, S, dif; + T theta, dr, S, dif; int i; xy_x /= this->m_par.k0; @@ -128,12 +168,13 @@ namespace projections dr = xy_y - xy_x * tan(0.5 * theta); lp_lon = theta / this->m_proj_parm.l; S = dr; - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { S -= (dif = (fS(S, this->m_proj_parm.C) - dr) / fSp(S, this->m_proj_parm.C)); - if (fabs(dif) < DEL_TOL) break; + if (fabs(dif) < del_tol) break; + } + if (!i) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - if (!i) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); lp_lat = pj_inv_mlfn(S + this->m_proj_parm.M0, this->m_par.es, this->m_proj_parm.en); } @@ -148,14 +189,13 @@ namespace projections template <typename Parameters, typename T> inline void setup_lcca(Parameters& par, par_lcca<T>& proj_parm) { - T s2p0, N0, R0, tan0, tan20; - - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); - if (!pj_param(par.params, "tlat_0").i) - BOOST_THROW_EXCEPTION( projection_exception(50) ); - if (par.phi0 == 0.) - BOOST_THROW_EXCEPTION( projection_exception(51) ); + T s2p0, N0, R0, tan0; + + proj_parm.en = pj_enfn<T>(par.es); + + if (par.phi0 == 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_is_zero) ); + } proj_parm.l = sin(par.phi0); proj_parm.M0 = pj_mlfn(par.phi0, proj_parm.l, cos(par.phi0), proj_parm.en); s2p0 = proj_parm.l * proj_parm.l; @@ -163,10 +203,8 @@ namespace projections N0 = sqrt(R0); R0 *= par.one_es * N0; tan0 = tan(par.phi0); - tan20 = tan0 * tan0; proj_parm.r0 = N0 / tan0; proj_parm.C = 1. / (6. * R0 * N0); - boost::ignore_unused(tan20); } }} // namespace detail::lcca @@ -187,10 +225,10 @@ namespace projections \par Example \image html ex_lcca.gif */ - template <typename CalculationType, typename Parameters> - struct lcca_ellipsoid : public detail::lcca::base_lcca_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lcca_ellipsoid : public detail::lcca::base_lcca_ellipsoid<T, Parameters> { - inline lcca_ellipsoid(const Parameters& par) : detail::lcca::base_lcca_ellipsoid<CalculationType, Parameters>(par) + inline lcca_ellipsoid(const Parameters& par) : detail::lcca::base_lcca_ellipsoid<T, Parameters>(par) { detail::lcca::setup_lcca(this->m_par, this->m_proj_parm); } @@ -204,20 +242,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lcca, lcca_ellipsoid, lcca_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lcca_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lcca_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<lcca_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<lcca_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void lcca_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void lcca_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lcca", new lcca_entry<CalculationType, Parameters>); + factory.add_to_factory("lcca", new lcca_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/loxim.hpp b/boost/geometry/srs/projections/proj/loxim.hpp index f88eb4ca6e..badac3c765 100644 --- a/boost/geometry/srs/projections/proj/loxim.hpp +++ b/boost/geometry/srs/projections/proj/loxim.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct loxim {}; + struct loxim {}; // Loximuthal }} //namespace srs::par4 @@ -62,7 +61,7 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace loxim { - static const double EPS = 1e-8; + static const double epsilon = 1e-8; template <typename T> struct par_loxim @@ -73,33 +72,29 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_loxim_spheroid : public base_t_fi<base_loxim_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_loxim_spheroid + : public base_t_fi<base_loxim_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_loxim<CalculationType> m_proj_parm; + par_loxim<T> m_proj_parm; inline base_loxim_spheroid(const Parameters& par) - : base_t_fi<base_loxim_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_loxim_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); xy_y = lp_lat - this->m_proj_parm.phi1; - if (fabs(xy_y) < EPS) + if (fabs(xy_y) < epsilon) xy_x = lp_lon * this->m_proj_parm.cosphi1; else { - xy_x = FORTPI + 0.5 * lp_lat; - if (fabs(xy_x) < EPS || fabs(fabs(xy_x) - HALFPI) < EPS) + xy_x = fourth_pi + 0.5 * lp_lat; + if (fabs(xy_x) < epsilon || fabs(fabs(xy_x) - half_pi) < epsilon) xy_x = 0.; else xy_x = lp_lon * xy_y / log( tan(xy_x) / this->m_proj_parm.tanphi1 ); @@ -108,20 +103,21 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); lp_lat = xy_y + this->m_proj_parm.phi1; - if (fabs(xy_y) < EPS) + if (fabs(xy_y) < epsilon) { lp_lon = xy_x / this->m_proj_parm.cosphi1; - else - if (fabs( lp_lon = FORTPI + 0.5 * lp_lat ) < EPS || - fabs(fabs(lp_lon) - HALFPI) < EPS) + } else { + lp_lon = fourth_pi + 0.5 * lp_lat; + if (fabs(lp_lon) < epsilon || fabs(fabs(lp_lon) - half_pi) < epsilon) lp_lon = 0.; else lp_lon = xy_x * log( tan(lp_lon) / this->m_proj_parm.tanphi1 ) / xy_y ; + } } static inline std::string get_name() @@ -135,12 +131,15 @@ namespace projections template <typename Parameters, typename T> inline void setup_loxim(Parameters& par, par_loxim<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + + proj_parm.phi1 = pj_get_param_r(par.params, "lat_1"); + proj_parm.cosphi1 = cos(proj_parm.phi1); + if (proj_parm.cosphi1 < epsilon) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_larger_than_90) ); + + proj_parm.tanphi1 = tan(fourth_pi + 0.5 * proj_parm.phi1); - proj_parm.phi1 = pj_param(par.params, "rlat_1").f; - if ((proj_parm.cosphi1 = cos(proj_parm.phi1)) < EPS) - BOOST_THROW_EXCEPTION( projection_exception(-22) ); - proj_parm.tanphi1 = tan(FORTPI + 0.5 * proj_parm.phi1); par.es = 0.; } @@ -161,10 +160,10 @@ namespace projections \par Example \image html ex_loxim.gif */ - template <typename CalculationType, typename Parameters> - struct loxim_spheroid : public detail::loxim::base_loxim_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct loxim_spheroid : public detail::loxim::base_loxim_spheroid<T, Parameters> { - inline loxim_spheroid(const Parameters& par) : detail::loxim::base_loxim_spheroid<CalculationType, Parameters>(par) + inline loxim_spheroid(const Parameters& par) : detail::loxim::base_loxim_spheroid<T, Parameters>(par) { detail::loxim::setup_loxim(this->m_par, this->m_proj_parm); } @@ -178,20 +177,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::loxim, loxim_spheroid, loxim_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class loxim_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class loxim_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<loxim_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<loxim_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void loxim_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void loxim_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("loxim", new loxim_entry<CalculationType, Parameters>); + factory.add_to_factory("loxim", new loxim_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/lsat.hpp b/boost/geometry/srs/projections/proj/lsat.hpp index d305339d5b..6ed729f75c 100644 --- a/boost/geometry/srs/projections/proj/lsat.hpp +++ b/boost/geometry/srs/projections/proj/lsat.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP -#define BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP +#define BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct lsat {}; + struct lsat {}; // Space oblique for LANDSAT }} //namespace srs::par4 @@ -63,9 +62,7 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace lsat { - static const double TOL = 1e-7; - //static const double PI_HALFPI = 4.71238898038468985766; - //static const double TWOPI_HALFPI = 7.85398163397448309610; + static const double tolerance = 1e-7; template <typename T> struct par_lsat @@ -79,18 +76,21 @@ namespace projections inline void seraz0(T lam, T const& mult, par_lsat<T>& proj_parm) { - T sdsq, h, s, fc, sd, sq, d__1; + T sdsq, h, s, fc, sd, sq, d__1 = 0; lam *= geometry::math::d2r<T>(); sd = sin(lam); sdsq = sd * sd; - s = proj_parm.p22 * proj_parm.sa * cos(lam) * sqrt((1. + proj_parm.t * sdsq) / (( - 1. + proj_parm.w * sdsq) * (1. + proj_parm.q * sdsq))); + s = proj_parm.p22 * proj_parm.sa * cos(lam) * sqrt((1. + proj_parm.t * sdsq) + / ((1. + proj_parm.w * sdsq) * (1. + proj_parm.q * sdsq))); + d__1 = 1. + proj_parm.q * sdsq; - h = sqrt((1. + proj_parm.q * sdsq) / (1. + proj_parm.w * sdsq)) * ((1. + - proj_parm.w * sdsq) / (d__1 * d__1) - proj_parm.p22 * proj_parm.ca); + h = sqrt((1. + proj_parm.q * sdsq) / (1. + proj_parm.w * sdsq)) * ((1. + proj_parm.w * sdsq) + / (d__1 * d__1) - proj_parm.p22 * proj_parm.ca); + sq = sqrt(proj_parm.xj * proj_parm.xj + s * s); - proj_parm.b += fc = mult * (h * proj_parm.xj - s * s) / sq; + fc = mult * (h * proj_parm.xj - s * s) / sq; + proj_parm.b += fc; proj_parm.a2 += fc * cos(lam + lam); proj_parm.a4 += fc * cos(lam * 4.); fc = mult * s * (h + proj_parm.xj) / sq; @@ -99,68 +99,73 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_lsat_ellipsoid : public base_t_fi<base_lsat_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_lsat_ellipsoid + : public base_t_fi<base_lsat_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_lsat<CalculationType> m_proj_parm; + par_lsat<T> m_proj_parm; inline base_lsat_ellipsoid(const Parameters& par) - : base_t_fi<base_lsat_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_lsat_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType PI_HALFPI = detail::PI_HALFPI<CalculationType>(); - static const CalculationType TWOPI_HALFPI = detail::TWOPI_HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T one_and_half_pi = detail::one_and_half_pi<T>(); + static const T two_and_half_pi = detail::two_and_half_pi<T>(); int l, nn; - CalculationType lamt, xlam, sdsq, c, d, s, lamdp, phidp, lampp, tanph, - lamtp, cl, sd, sp, fac, sav, tanphi; - - if (lp_lat > HALFPI) - lp_lat = HALFPI; - else if (lp_lat < -HALFPI) - lp_lat = -HALFPI; - lampp = lp_lat >= 0. ? HALFPI : PI_HALFPI; + T lamt = 0.0, xlam, sdsq, c, d, s, lamdp = 0.0, phidp, lampp, tanph; + T lamtp, cl, sd, sp, sav, tanphi; + + if (lp_lat > half_pi) + lp_lat = half_pi; + else if (lp_lat < -half_pi) + lp_lat = -half_pi; + + if (lp_lat >= 0. ) + lampp = half_pi; + else + lampp = one_and_half_pi; tanphi = tan(lp_lat); for (nn = 0;;) { + T fac; sav = lampp; lamtp = lp_lon + this->m_proj_parm.p22 * lampp; cl = cos(lamtp); - if (fabs(cl) < TOL) - lamtp -= TOL; - fac = lampp - sin(lampp) * (cl < 0. ? -HALFPI : HALFPI); + if (fabs(cl) < tolerance) + lamtp -= tolerance; + if( cl < 0 ) + fac = lampp + sin(lampp) * half_pi; + else + fac = lampp - sin(lampp) * half_pi; for (l = 50; l; --l) { lamt = lp_lon + this->m_proj_parm.p22 * sav; - if (fabs(c = cos(lamt)) < TOL) - lamt -= TOL; + c = cos(lamt); + if (fabs(c) < tolerance) + lamt -= tolerance; xlam = (this->m_par.one_es * tanphi * this->m_proj_parm.sa + sin(lamt) * this->m_proj_parm.ca) / c; lamdp = atan(xlam) + fac; - if (fabs(fabs(sav) - fabs(lamdp)) < TOL) + if (fabs(fabs(sav) - fabs(lamdp)) < tolerance) break; sav = lamdp; } if (!l || ++nn >= 3 || (lamdp > this->m_proj_parm.rlm && lamdp < this->m_proj_parm.rlm2)) break; if (lamdp <= this->m_proj_parm.rlm) - lampp = TWOPI_HALFPI; + lampp = two_and_half_pi; else if (lamdp >= this->m_proj_parm.rlm2) - lampp = HALFPI; + lampp = half_pi; } if (l) { sp = sin(lp_lat); phidp = aasin((this->m_par.one_es * this->m_proj_parm.ca * sp - this->m_proj_parm.sa * cos(lp_lat) * sin(lamt)) / sqrt(1. - this->m_par.es * sp * sp)); - tanph = log(tan(FORTPI + .5 * phidp)); + tanph = log(tan(fourth_pi + .5 * phidp)); sd = sin(lamdp); sdsq = sd * sd; s = this->m_proj_parm.p22 * this->m_proj_parm.sa * cos(lamdp) * sqrt((1. + this->m_proj_parm.t * sdsq) @@ -175,13 +180,13 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); int nn; - CalculationType lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp; + T lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp; lamdp = xy_x / this->m_proj_parm.b; nn = 50; @@ -195,14 +200,14 @@ namespace projections 2. * lamdp) - this->m_proj_parm.a4 * sin(lamdp * 4.) - s / this->m_proj_parm.xj * ( this->m_proj_parm.c1 * sin(lamdp) + this->m_proj_parm.c3 * sin(lamdp * 3.)); lamdp /= this->m_proj_parm.b; - } while (fabs(lamdp - sav) >= TOL && --nn); + } while (fabs(lamdp - sav) >= tolerance && --nn); sl = sin(lamdp); fac = exp(sqrt(1. + s * s / this->m_proj_parm.xj / this->m_proj_parm.xj) * (xy_y - this->m_proj_parm.c1 * sl - this->m_proj_parm.c3 * sin(lamdp * 3.))); - phidp = 2. * (atan(fac) - FORTPI); + phidp = 2. * (atan(fac) - fourth_pi); dd = sl * sl; - if (fabs(cos(lamdp)) < TOL) - lamdp -= TOL; + if (fabs(cos(lamdp)) < tolerance) + lamdp -= tolerance; spp = sin(phidp); sppsq = spp * spp; lamt = atan(((1. - sppsq * this->m_par.rone_es) * tan(lamdp) * @@ -211,9 +216,9 @@ namespace projections * (1. + this->m_proj_parm.u))); sl = lamt >= 0. ? 1. : -1.; scl = cos(lamdp) >= 0. ? 1. : -1; - lamt -= HALFPI * (1. - scl) * sl; + lamt -= half_pi * (1. - scl) * sl; lp_lon = lamt - this->m_proj_parm.p22 * lamdp; - if (fabs(this->m_proj_parm.sa) < TOL) + if (fabs(this->m_proj_parm.sa) < tolerance) lp_lat = aasin(spp / sqrt(this->m_par.one_es * this->m_par.one_es + this->m_par.es * sppsq)); else lp_lat = atan((tan(lamdp) * cos(lamt) - this->m_proj_parm.ca * sin(lamt)) / @@ -231,23 +236,29 @@ namespace projections template <typename Parameters, typename T> inline void setup_lsat(Parameters& par, par_lsat<T>& proj_parm) { + static T const d2r = geometry::math::d2r<T>(); + static T const pi = detail::pi<T>(); + static T const two_pi = detail::two_pi<T>(); + int land, path; T lam, alf, esc, ess; - land = pj_param(par.params, "ilsat").i; + land = pj_get_param_i(par.params, "lsat"); if (land <= 0 || land > 5) - BOOST_THROW_EXCEPTION( projection_exception(-28) ); - path = pj_param(par.params, "ipath").i; + BOOST_THROW_EXCEPTION( projection_exception(error_lsat_not_in_range) ); + + path = pj_get_param_i(par.params, "path"); if (path <= 0 || path > (land <= 3 ? 251 : 233)) - BOOST_THROW_EXCEPTION( projection_exception(-29) ); + BOOST_THROW_EXCEPTION( projection_exception(error_path_not_in_range) ); + if (land <= 3) { - par.lam0 = geometry::math::d2r<T>() * 128.87 - geometry::math::two_pi<T>() / 251. * path; + par.lam0 = d2r * 128.87 - two_pi / 251. * path; proj_parm.p22 = 103.2669323; - alf = geometry::math::d2r<T>() * 99.092; + alf = d2r * 99.092; } else { - par.lam0 = geometry::math::d2r<T>() * 129.3 - geometry::math::two_pi<T>() / 233. * path; + par.lam0 = d2r * 129.3 - two_pi / 233. * path; proj_parm.p22 = 98.8841202; - alf = geometry::math::d2r<T>() * 98.2; + alf = d2r * 98.2; } proj_parm.p22 /= 1440.; proj_parm.sa = sin(alf); @@ -262,8 +273,8 @@ namespace projections proj_parm.t = ess * (2. - par.es) * par.rone_es * par.rone_es; proj_parm.u = esc * par.rone_es; proj_parm.xj = par.one_es * par.one_es * par.one_es; - proj_parm.rlm = geometry::math::pi<T>() * (1. / 248. + .5161290322580645); - proj_parm.rlm2 = proj_parm.rlm + geometry::math::two_pi<T>(); + proj_parm.rlm = pi * (1. / 248. + .5161290322580645); + proj_parm.rlm2 = proj_parm.rlm + two_pi; proj_parm.a2 = proj_parm.a4 = proj_parm.b = proj_parm.c1 = proj_parm.c3 = 0.; seraz0(0., 1., proj_parm); for (lam = 9.; lam <= 81.0001; lam += 18.) @@ -297,10 +308,10 @@ namespace projections \par Example \image html ex_lsat.gif */ - template <typename CalculationType, typename Parameters> - struct lsat_ellipsoid : public detail::lsat::base_lsat_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lsat_ellipsoid : public detail::lsat::base_lsat_ellipsoid<T, Parameters> { - inline lsat_ellipsoid(const Parameters& par) : detail::lsat::base_lsat_ellipsoid<CalculationType, Parameters>(par) + inline lsat_ellipsoid(const Parameters& par) : detail::lsat::base_lsat_ellipsoid<T, Parameters>(par) { detail::lsat::setup_lsat(this->m_par, this->m_proj_parm); } @@ -314,20 +325,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lsat, lsat_ellipsoid, lsat_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class lsat_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lsat_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<lsat_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<lsat_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void lsat_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void lsat_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("lsat", new lsat_entry<CalculationType, Parameters>); + factory.add_to_factory("lsat", new lsat_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/mbt_fps.hpp b/boost/geometry/srs/projections/proj/mbt_fps.hpp index 3823725f1c..130590f8e5 100644 --- a/boost/geometry/srs/projections/proj/mbt_fps.hpp +++ b/boost/geometry/srs/projections/proj/mbt_fps.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct mbt_fps {}; + struct mbt_fps {}; // McBryde-Thomas Flat-Pole Sine (No. 2) }} //namespace srs::par4 @@ -62,8 +61,8 @@ namespace projections namespace detail { namespace mbt_fps { - static const int MAX_ITER = 10; - static const double LOOP_TOL = 1e-7; + static const int max_iter = 10; + static const double loop_tol = 1e-7; static const double C1 = 0.45503; static const double C2 = 1.36509; static const double C3 = 1.41546; @@ -72,37 +71,32 @@ namespace projections //static const double C1_2 = 0.33333333333333333333333333; template <typename T> - inline T C1_2() { return detail::THIRD<T>(); } + inline T C1_2() { return detail::third<T>(); } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_mbt_fps_spheroid : public base_t_fi<base_mbt_fps_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_mbt_fps_spheroid + : public base_t_fi<base_mbt_fps_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_mbt_fps_spheroid(const Parameters& par) - : base_t_fi<base_mbt_fps_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_mbt_fps_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType C1_2 = mbt_fps::C1_2<CalculationType>(); + static const T C1_2 = mbt_fps::C1_2<T>(); - CalculationType k, V, t; + T k, V, t; int i; k = C3 * sin(lp_lat); - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { t = lp_lat / C2; lp_lat -= V = (C1 * sin(t) + sin(lp_lat) - k) / (C1_2 * cos(t) + cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } t = lp_lat / C2; @@ -112,9 +106,9 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType t; + T t; lp_lat = C2 * (t = aasin(xy_y / C_y)); lp_lon = xy_x / (C_x * (1. + 3. * cos(lp_lat)/cos(t))); @@ -150,10 +144,10 @@ namespace projections \par Example \image html ex_mbt_fps.gif */ - template <typename CalculationType, typename Parameters> - struct mbt_fps_spheroid : public detail::mbt_fps::base_mbt_fps_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mbt_fps_spheroid : public detail::mbt_fps::base_mbt_fps_spheroid<T, Parameters> { - inline mbt_fps_spheroid(const Parameters& par) : detail::mbt_fps::base_mbt_fps_spheroid<CalculationType, Parameters>(par) + inline mbt_fps_spheroid(const Parameters& par) : detail::mbt_fps::base_mbt_fps_spheroid<T, Parameters>(par) { detail::mbt_fps::setup_mbt_fps(this->m_par); } @@ -167,20 +161,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbt_fps, mbt_fps_spheroid, mbt_fps_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class mbt_fps_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mbt_fps_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mbt_fps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mbt_fps_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void mbt_fps_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void mbt_fps_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("mbt_fps", new mbt_fps_entry<CalculationType, Parameters>); + factory.add_to_factory("mbt_fps", new mbt_fps_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/mbtfpp.hpp b/boost/geometry/srs/projections/proj/mbtfpp.hpp index 123d1e4b02..cd09fdf181 100644 --- a/boost/geometry/srs/projections/proj/mbtfpp.hpp +++ b/boost/geometry/srs/projections/proj/mbtfpp.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct mbtfpp {}; + struct mbtfpp {}; // McBride-Thomas Flat-Polar Parabolic }} //namespace srs::par4 @@ -68,33 +67,23 @@ namespace projections static const double FYC = 3.40168025708304504493; //static const double C23 = .66666666666666666666; //static const double C13 = .33333333333333333333; - static const double ONEEPS = 1.0000001; - - template <typename T> - inline T C23() { return detail::TWOTHIRD<T>(); } - template <typename T> - inline T C13() { return detail::THIRD<T>(); } + static const double one_plus_eps = 1.0000001; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_mbtfpp_spheroid : public base_t_fi<base_mbtfpp_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_mbtfpp_spheroid + : public base_t_fi<base_mbtfpp_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_mbtfpp_spheroid(const Parameters& par) - : base_t_fi<base_mbtfpp_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_mbtfpp_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType C23 = mbtfpp::C23<CalculationType>(); - static const CalculationType C13 = mbtfpp::C13<CalculationType>(); + static const T C23 = detail::two_thirds<T>(); + static const T C13 = detail::third<T>(); lp_lat = asin(CS_ * sin(lp_lat)); xy_x = FXC * lp_lon * (2. * cos(C23 * lp_lat) - 1.); @@ -103,25 +92,28 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType C23 = mbtfpp::C23<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T C23 = detail::two_thirds<T>(); lp_lat = xy_y / FYC; if (fabs(lp_lat) >= 1.) { - if (fabs(lp_lat) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else - lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + if (fabs(lp_lat) > one_plus_eps) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else { + lp_lat = (lp_lat < 0.) ? -half_pi : half_pi; + } } else lp_lat = asin(lp_lat); + lp_lon = xy_x / ( FXC * (2. * cos(C23 * (lp_lat *= 3.)) - 1.) ); if (fabs(lp_lat = sin(lp_lat) / CS_) >= 1.) { - if (fabs(lp_lat) > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else - lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + if (fabs(lp_lat) > one_plus_eps) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else { + lp_lat = (lp_lat < 0.) ? -half_pi : half_pi; + } } else lp_lat = asin(lp_lat); } @@ -155,10 +147,10 @@ namespace projections \par Example \image html ex_mbtfpp.gif */ - template <typename CalculationType, typename Parameters> - struct mbtfpp_spheroid : public detail::mbtfpp::base_mbtfpp_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mbtfpp_spheroid : public detail::mbtfpp::base_mbtfpp_spheroid<T, Parameters> { - inline mbtfpp_spheroid(const Parameters& par) : detail::mbtfpp::base_mbtfpp_spheroid<CalculationType, Parameters>(par) + inline mbtfpp_spheroid(const Parameters& par) : detail::mbtfpp::base_mbtfpp_spheroid<T, Parameters>(par) { detail::mbtfpp::setup_mbtfpp(this->m_par); } @@ -172,20 +164,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfpp, mbtfpp_spheroid, mbtfpp_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class mbtfpp_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mbtfpp_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mbtfpp_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mbtfpp_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void mbtfpp_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void mbtfpp_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("mbtfpp", new mbtfpp_entry<CalculationType, Parameters>); + factory.add_to_factory("mbtfpp", new mbtfpp_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/mbtfpq.hpp b/boost/geometry/srs/projections/proj/mbtfpq.hpp index b4eeb34d5a..4d7858c020 100644 --- a/boost/geometry/srs/projections/proj/mbtfpq.hpp +++ b/boost/geometry/srs/projections/proj/mbtfpq.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct mbtfpq {}; + struct mbtfpq {}; // McBryde-Thomas Flat-Polar Quartic }} //namespace srs::par4 @@ -63,9 +62,9 @@ namespace projections namespace detail { namespace mbtfpq { - static const int NITER = 20; - static const double EPS = 1e-7; - static const double ONETOL = 1.000001; + static const int n_iter = 20; + static const double epsilon = 1e-7; + static const double one_plus_tol = 1.000001; static const double C = 1.70710678118654752440; static const double RC = 0.58578643762690495119; static const double FYC = 1.87475828462269495505; @@ -74,31 +73,26 @@ namespace projections static const double RXC = 3.20041258076506210122; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_mbtfpq_spheroid : public base_t_fi<base_mbtfpq_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_mbtfpq_spheroid + : public base_t_fi<base_mbtfpq_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_mbtfpq_spheroid(const Parameters& par) - : base_t_fi<base_mbtfpq_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_mbtfpq_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType th1, c; + T th1, c; int i; c = C * sin(lp_lat); - for (i = NITER; i; --i) { + for (i = n_iter; i; --i) { lp_lat -= th1 = (sin(.5*lp_lat) + sin(lp_lat) - c) / (.5*cos(.5*lp_lat) + cos(lp_lat)); - if (fabs(th1) < EPS) break; + if (fabs(th1) < epsilon) break; } xy_x = FXC * lp_lon * (1.0 + 2. * cos(lp_lat)/cos(0.5 * lp_lat)); xy_y = FYC * sin(0.5 * lp_lat); @@ -106,31 +100,31 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType t; + T t; lp_lat = RYC * xy_y; if (fabs(lp_lat) > 1.) { - if (fabs(lp_lat) > ONETOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else if (lp_lat < 0.) { - t = -1.; lp_lat = -ONEPI; + if (fabs(lp_lat) > one_plus_tol) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else if (lp_lat < 0.) { + t = -1.; lp_lat = -pi; } else { - t = 1.; lp_lat = ONEPI; + t = 1.; lp_lat = pi; } } else lp_lat = 2. * asin(t = lp_lat); lp_lon = RXC * xy_x / (1. + 2. * cos(lp_lat)/cos(0.5 * lp_lat)); lp_lat = RC * (t + sin(lp_lat)); if (fabs(lp_lat) > 1.) - if (fabs(lp_lat) > ONETOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else - lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + if (fabs(lp_lat) > one_plus_tol) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else + lp_lat = lp_lat < 0. ? -half_pi : half_pi; else lp_lat = asin(lp_lat); } @@ -164,10 +158,10 @@ namespace projections \par Example \image html ex_mbtfpq.gif */ - template <typename CalculationType, typename Parameters> - struct mbtfpq_spheroid : public detail::mbtfpq::base_mbtfpq_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mbtfpq_spheroid : public detail::mbtfpq::base_mbtfpq_spheroid<T, Parameters> { - inline mbtfpq_spheroid(const Parameters& par) : detail::mbtfpq::base_mbtfpq_spheroid<CalculationType, Parameters>(par) + inline mbtfpq_spheroid(const Parameters& par) : detail::mbtfpq::base_mbtfpq_spheroid<T, Parameters>(par) { detail::mbtfpq::setup_mbtfpq(this->m_par); } @@ -181,20 +175,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfpq, mbtfpq_spheroid, mbtfpq_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class mbtfpq_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mbtfpq_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mbtfpq_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mbtfpq_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void mbtfpq_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void mbtfpq_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("mbtfpq", new mbtfpq_entry<CalculationType, Parameters>); + factory.add_to_factory("mbtfpq", new mbtfpq_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/merc.hpp b/boost/geometry/srs/projections/proj/merc.hpp index ac34aee33e..74449f64c8 100644 --- a/boost/geometry/srs/projections/proj/merc.hpp +++ b/boost/geometry/srs/projections/proj/merc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MERC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -56,7 +55,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct merc {}; + struct merc {}; // Mercator }} //namespace srs::par4 @@ -66,40 +65,37 @@ namespace projections namespace detail { namespace merc { - static const double EPS10 = 1.e-10; + static const double epsilon10 = 1.e-10; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_merc_ellipsoid : public base_t_fi<base_merc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_merc_ellipsoid + : public base_t_fi<base_merc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_merc_ellipsoid(const Parameters& par) - : base_t_fi<base_merc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_merc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = this->m_par.k0 * lp_lon; xy_y = - this->m_par.k0 * log(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e)); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - if ((lp_lat = pj_phi2(exp(- xy_y / this->m_par.k0), this->m_par.e)) == HUGE_VAL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((lp_lat = pj_phi2(exp(- xy_y / this->m_par.k0), this->m_par.e)) == HUGE_VAL) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } lp_lon = xy_x / this->m_par.k0; } @@ -111,39 +107,35 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_merc_spheroid : public base_t_fi<base_merc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_merc_spheroid + : public base_t_fi<base_merc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_merc_spheroid(const Parameters& par) - : base_t_fi<base_merc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_merc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); - if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = this->m_par.k0 * lp_lon; - xy_y = this->m_par.k0 * log(tan(FORTPI + .5 * lp_lat)); + xy_y = this->m_par.k0 * log(tan(fourth_pi + .5 * lp_lat)); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - lp_lat = HALFPI - 2. * atan(exp(-xy_y / this->m_par.k0)); + lp_lat = half_pi - 2. * atan(exp(-xy_y / this->m_par.k0)); lp_lon = xy_x / this->m_par.k0; } @@ -159,17 +151,17 @@ namespace projections inline void setup_merc(Parameters& par) { typedef typename Parameters::type calc_t; - static const calc_t HALFPI = detail::HALFPI<calc_t>(); + static const calc_t half_pi = detail::half_pi<calc_t>(); calc_t phits=0.0; int is_phits; - if( (is_phits = pj_param(par.params, "tlat_ts").i) ) { - phits = fabs(pj_param(par.params, "rlat_ts").f); - if (phits >= HALFPI) - BOOST_THROW_EXCEPTION( projection_exception(-24) ); + if( (is_phits = pj_param_r(par.params, "lat_ts", phits)) ) { + phits = fabs(phits); + if (phits >= half_pi) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_ts_larger_than_90) ); } - if (par.es) { /* ellipsoid */ + if (par.es != 0.0) { /* ellipsoid */ if (is_phits) par.k0 = pj_msfn(sin(phits), cos(phits), par.es); } else { /* sphere */ @@ -196,10 +188,10 @@ namespace projections \par Example \image html ex_merc.gif */ - template <typename CalculationType, typename Parameters> - struct merc_ellipsoid : public detail::merc::base_merc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct merc_ellipsoid : public detail::merc::base_merc_ellipsoid<T, Parameters> { - inline merc_ellipsoid(const Parameters& par) : detail::merc::base_merc_ellipsoid<CalculationType, Parameters>(par) + inline merc_ellipsoid(const Parameters& par) : detail::merc::base_merc_ellipsoid<T, Parameters>(par) { detail::merc::setup_merc(this->m_par); } @@ -220,10 +212,10 @@ namespace projections \par Example \image html ex_merc.gif */ - template <typename CalculationType, typename Parameters> - struct merc_spheroid : public detail::merc::base_merc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct merc_spheroid : public detail::merc::base_merc_spheroid<T, Parameters> { - inline merc_spheroid(const Parameters& par) : detail::merc::base_merc_spheroid<CalculationType, Parameters>(par) + inline merc_spheroid(const Parameters& par) : detail::merc::base_merc_spheroid<T, Parameters>(par) { detail::merc::setup_merc(this->m_par); } @@ -237,23 +229,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::merc, merc_spheroid, merc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class merc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class merc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<merc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<merc_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<merc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<merc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void merc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void merc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("merc", new merc_entry<CalculationType, Parameters>); + factory.add_to_factory("merc", new merc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/mill.hpp b/boost/geometry/srs/projections/proj/mill.hpp index 1d3d4a01d2..9c73f1b21c 100644 --- a/boost/geometry/srs/projections/proj/mill.hpp +++ b/boost/geometry/srs/projections/proj/mill.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MILL_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MILL_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MILL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MILL_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct mill {}; + struct mill {}; // Miller Cylindrical }} //namespace srs::par4 @@ -61,37 +60,32 @@ namespace projections namespace detail { namespace mill { // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_mill_spheroid : public base_t_fi<base_mill_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_mill_spheroid + : public base_t_fi<base_mill_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_mill_spheroid(const Parameters& par) - : base_t_fi<base_mill_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_mill_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); xy_x = lp_lon; - xy_y = log(tan(FORTPI + lp_lat * .4)) * 1.25; + xy_y = log(tan(fourth_pi + lp_lat * .4)) * 1.25; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); lp_lon = xy_x; - lp_lat = 2.5 * (atan(exp(.8 * xy_y)) - FORTPI); + lp_lat = 2.5 * (atan(exp(.8 * xy_y)) - fourth_pi); } static inline std::string get_name() @@ -123,10 +117,10 @@ namespace projections \par Example \image html ex_mill.gif */ - template <typename CalculationType, typename Parameters> - struct mill_spheroid : public detail::mill::base_mill_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mill_spheroid : public detail::mill::base_mill_spheroid<T, Parameters> { - inline mill_spheroid(const Parameters& par) : detail::mill::base_mill_spheroid<CalculationType, Parameters>(par) + inline mill_spheroid(const Parameters& par) : detail::mill::base_mill_spheroid<T, Parameters>(par) { detail::mill::setup_mill(this->m_par); } @@ -140,20 +134,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mill, mill_spheroid, mill_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class mill_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mill_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mill_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mill_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void mill_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void mill_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("mill", new mill_entry<CalculationType, Parameters>); + factory.add_to_factory("mill", new mill_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/mod_ster.hpp b/boost/geometry/srs/projections/proj/mod_ster.hpp index 8a50a275f9..ca33adcdbd 100644 --- a/boost/geometry/srs/projections/proj/mod_ster.hpp +++ b/boost/geometry/srs/projections/proj/mod_ster.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -56,11 +55,11 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct mil_os {}; - struct lee_os {}; - struct gs48 {}; - struct alsk {}; - struct gs50 {}; + struct mil_os {}; // Miller Oblated Stereographic + struct lee_os {}; // Lee Oblated Stereographic + struct gs48 {}; // Mod. Stereographic of 48 U.S. + struct alsk {}; // Mod. Stereographic of Alaska + struct gs50 {}; // Mod. Stereographic of 50 U.S. }} //namespace srs::par4 @@ -70,12 +69,12 @@ namespace projections namespace detail { namespace mod_ster { - static const double EPSLN = 1e-10; + static const double epsilon = 1e-12; template <typename T> struct par_mod_ster { - COMPLEX<T> *zcoeff; + pj_complex<T> *zcoeff; T cchio, schio; int n; }; @@ -83,34 +82,30 @@ namespace projections /* based upon Snyder and Linck, USGS-NMD */ // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_mod_ster_ellipsoid : public base_t_fi<base_mod_ster_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_mod_ster_ellipsoid + : public base_t_fi<base_mod_ster_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_mod_ster<CalculationType> m_proj_parm; + par_mod_ster<T> m_proj_parm; inline base_mod_ster_ellipsoid(const Parameters& par) - : base_t_fi<base_mod_ster_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_mod_ster_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType sinlon, coslon, esphi, chi, schi, cchi, s; - COMPLEX<CalculationType> p; + T sinlon, coslon, esphi, chi, schi, cchi, s; + pj_complex<T> p; sinlon = sin(lp_lon); coslon = cos(lp_lon); esphi = this->m_par.e * sin(lp_lat); - chi = 2. * atan(tan((HALFPI + lp_lat) * .5) * - pow((1. - esphi) / (1. + esphi), this->m_par.e * .5)) - HALFPI; + chi = 2. * atan(tan((half_pi + lp_lat) * .5) * + math::pow((T(1) - esphi) / (T(1) + esphi), this->m_par.e * T(0.5))) - half_pi; schi = sin(chi); cchi = cos(chi); s = 2. / (1. + this->m_proj_parm.schio * schi + this->m_proj_parm.cchio * cchi * coslon); @@ -123,13 +118,13 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); int nn; - COMPLEX<CalculationType> p, fxy, fpxy, dp; - CalculationType den, rh = 0, z, sinz = 0, cosz = 0, chi, phi = 0, dphi, esphi; + pj_complex<T> p, fxy, fpxy, dp; + T den, rh = 0, z, sinz = 0, cosz = 0, chi, phi = 0, dphi, esphi; p.r = xy_x; p.i = xy_y; @@ -142,7 +137,7 @@ namespace projections dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den; p.r += dp.r; p.i += dp.i; - if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN) + if ((fabs(dp.r) + fabs(dp.i)) <= epsilon) break; } if (nn) { @@ -151,7 +146,11 @@ namespace projections sinz = sin(z); cosz = cos(z); lp_lon = this->m_par.lam0; - if (fabs(rh) <= EPSLN) { + if (fabs(rh) <= epsilon) { + /* if we end up here input coordinates were (0,0). + * pj_inv() adds P->lam0 to lp.lam, this way we are + * sure to get the correct offset */ + lp_lon = 0.0; lp_lat = this->m_par.phi0; return; } @@ -159,10 +158,10 @@ namespace projections phi = chi; for (nn = 20; nn ;--nn) { esphi = this->m_par.e * sin(phi); - dphi = 2. * atan(tan((HALFPI + chi) * .5) * - pow((1. + esphi) / (1. - esphi), this->m_par.e * .5)) - HALFPI - phi; + dphi = 2. * atan(tan((half_pi + chi) * .5) * + math::pow((T(1) + esphi) / (T(1) - esphi), this->m_par.e * T(0.5))) - half_pi - phi; phi += dphi; - if (fabs(dphi) <= EPSLN) + if (fabs(dphi) <= epsilon) break; } } @@ -184,12 +183,14 @@ namespace projections template <typename Parameters, typename T> inline void setup(Parameters& par, par_mod_ster<T>& proj_parm) /* general initialization */ { + static T const half_pi = detail::half_pi<T>(); + T esphi, chio; - if (par.es) { + if (par.es != 0.0) { esphi = par.e * sin(par.phi0); - chio = 2. * atan(tan((geometry::math::half_pi<T>() + par.phi0) * .5) * - pow((1. - esphi) / (1. + esphi), par.e * .5)) - geometry::math::half_pi<T>(); + chio = 2. * atan(tan((half_pi + par.phi0) * .5) * + math::pow((T(1) - esphi) / (T(1) + esphi), par.e * T(0.5))) - half_pi; } else chio = par.phi0; proj_parm.schio = sin(chio); @@ -197,41 +198,45 @@ namespace projections } - // Miller Oblated Stereographic + /* Miller Oblated Stereographic */ template <typename Parameters, typename T> inline void setup_mil_os(Parameters& par, par_mod_ster<T>& proj_parm) { - static COMPLEX<T> /* Miller Oblated Stereographic */ - AB[] = { - {0.924500, 0.}, - {0., 0.}, - {0.019430, 0.} - }; + static const T d2r = geometry::math::d2r<T>(); + + static pj_complex<T> AB[] = { + {0.924500, 0.}, + {0., 0.}, + {0.019430, 0.} + }; proj_parm.n = 2; - par.lam0 = geometry::math::d2r<T>() * 20.; - par.phi0 = geometry::math::d2r<T>() * 18.; + par.lam0 = d2r * 20.; + par.phi0 = d2r * 18.; proj_parm.zcoeff = AB; par.es = 0.; + setup(par, proj_parm); } - // Lee Oblated Stereographic + /* Lee Oblated Stereographic */ template <typename Parameters, typename T> inline void setup_lee_os(Parameters& par, par_mod_ster<T>& proj_parm) { - static COMPLEX<T> /* Lee Oblated Stereographic */ - AB[] = { - {0.721316, 0.}, - {0., 0.}, - {-0.0088162, -0.00617325} - }; + static const T d2r = geometry::math::d2r<T>(); + + static pj_complex<T> AB[] = { + { 0.721316, 0.}, + { 0., 0.}, + {-0.0088162, -0.00617325} + }; proj_parm.n = 2; - par.lam0 = geometry::math::d2r<T>() * -165.; - par.phi0 = geometry::math::d2r<T>() * -10.; + par.lam0 = d2r * -165.; + par.phi0 = d2r * -10.; proj_parm.zcoeff = AB; par.es = 0.; + setup(par, proj_parm); } @@ -239,21 +244,23 @@ namespace projections template <typename Parameters, typename T> inline void setup_gs48(Parameters& par, par_mod_ster<T>& proj_parm) { - static COMPLEX<T> /* 48 United States */ - AB[] = { - {0.98879, 0.}, - {0., 0.}, - {-0.050909, 0.}, - {0., 0.}, - {0.075528, 0.} - }; + static const T d2r = geometry::math::d2r<T>(); + + static pj_complex<T> AB[] = { /* 48 United States */ + { 0.98879, 0.}, + { 0., 0.}, + {-0.050909, 0.}, + { 0., 0.}, + { 0.075528, 0.} + }; proj_parm.n = 4; - par.lam0 = geometry::math::d2r<T>() * -96.; - par.phi0 = geometry::math::d2r<T>() * -39.; + par.lam0 = d2r * -96.; + par.phi0 = d2r * -39.; proj_parm.zcoeff = AB; par.es = 0.; par.a = 6370997.; + setup(par, proj_parm); } @@ -261,27 +268,30 @@ namespace projections template <typename Parameters, typename T> inline void setup_alsk(Parameters& par, par_mod_ster<T>& proj_parm) { - static COMPLEX<T> - ABe[] = { /* Alaska ellipsoid */ - {.9945303, 0.}, - {.0052083, -.0027404}, - {.0072721, .0048181}, - {-.0151089, -.1932526}, - {.0642675, -.1381226}, - {.3582802, -.2884586}}, - ABs[] = { /* Alaska sphere */ - {.9972523, 0.}, - {.0052513, -.0041175}, - {.0074606, .0048125}, - {-.0153783, -.1968253}, - {.0636871, -.1408027}, - {.3660976, -.2937382} - }; + static const T d2r = geometry::math::d2r<T>(); + + static pj_complex<T> ABe[] = { /* Alaska ellipsoid */ + { .9945303, 0.}, + { .0052083, -.0027404}, + { .0072721, .0048181}, + {-.0151089, -.1932526}, + { .0642675, -.1381226}, + { .3582802, -.2884586} + }; + + static pj_complex<T> ABs[] = { /* Alaska sphere */ + { .9972523, 0.}, + { .0052513, -.0041175}, + { .0074606, .0048125}, + {-.0153783, -.1968253}, + { .0636871, -.1408027}, + { .3660976, -.2937382} + }; proj_parm.n = 5; - par.lam0 = geometry::math::d2r<T>() * -152.; - par.phi0 = geometry::math::d2r<T>() * 64.; - if (par.es) { /* fixed ellipsoid/sphere */ + par.lam0 = d2r * -152.; + par.phi0 = d2r * 64.; + if (par.es != 0.0) { /* fixed ellipsoid/sphere */ proj_parm.zcoeff = ABe; par.a = 6378206.4; par.e = sqrt(par.es = 0.00676866); @@ -289,6 +299,7 @@ namespace projections proj_parm.zcoeff = ABs; par.a = 6370997.; } + setup(par, proj_parm); } @@ -296,36 +307,37 @@ namespace projections template <typename Parameters, typename T> inline void setup_gs50(Parameters& par, par_mod_ster<T>& proj_parm) { - static COMPLEX<T> - ABe[] = { /* GS50 ellipsoid */ - {.9827497, 0.}, - {.0210669, .0053804}, - {-.1031415, -.0571664}, - {-.0323337, -.0322847}, - {.0502303, .1211983}, - {.0251805, .0895678}, - {-.0012315, -.1416121}, - {.0072202, -.1317091}, - {-.0194029, .0759677}, - {-.0210072, .0834037} - }, - ABs[] = { /* GS50 sphere */ - {.9842990, 0.}, - {.0211642, .0037608}, - {-.1036018, -.0575102}, - {-.0329095, -.0320119}, - {.0499471, .1223335}, - {.0260460, .0899805}, - {.0007388, -.1435792}, - {.0075848, -.1334108}, - {-.0216473, .0776645}, - {-.0225161, .0853673} - }; + static const T d2r = geometry::math::d2r<T>(); + + static pj_complex<T> ABe[] = { /* GS50 ellipsoid */ + { .9827497, 0.}, + { .0210669, .0053804}, + {-.1031415, -.0571664}, + {-.0323337, -.0322847}, + { .0502303, .1211983}, + { .0251805, .0895678}, + {-.0012315, -.1416121}, + { .0072202, -.1317091}, + {-.0194029, .0759677}, + {-.0210072, .0834037} + }; + static pj_complex<T> ABs[] = { /* GS50 sphere */ + { .9842990, 0.}, + { .0211642, .0037608}, + {-.1036018, -.0575102}, + {-.0329095, -.0320119}, + { .0499471, .1223335}, + { .0260460, .0899805}, + { .0007388, -.1435792}, + { .0075848, -.1334108}, + {-.0216473, .0776645}, + {-.0225161, .0853673} + }; proj_parm.n = 9; - par.lam0 = geometry::math::d2r<T>() * -120.; - par.phi0 = geometry::math::d2r<T>() * 45.; - if (par.es) { /* fixed ellipsoid/sphere */ + par.lam0 = d2r * -120.; + par.phi0 = d2r * 45.; + if (par.es != 0.0) { /* fixed ellipsoid/sphere */ proj_parm.zcoeff = ABe; par.a = 6378206.4; par.e = sqrt(par.es = 0.00676866); @@ -333,6 +345,7 @@ namespace projections proj_parm.zcoeff = ABs; par.a = 6370997.; } + setup(par, proj_parm); } @@ -350,10 +363,10 @@ namespace projections \par Example \image html ex_mil_os.gif */ - template <typename CalculationType, typename Parameters> - struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters> { - inline mil_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + inline mil_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters>(par) { detail::mod_ster::setup_mil_os(this->m_par, this->m_proj_parm); } @@ -370,10 +383,10 @@ namespace projections \par Example \image html ex_lee_os.gif */ - template <typename CalculationType, typename Parameters> - struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters> { - inline lee_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + inline lee_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters>(par) { detail::mod_ster::setup_lee_os(this->m_par, this->m_proj_parm); } @@ -390,10 +403,10 @@ namespace projections \par Example \image html ex_gs48.gif */ - template <typename CalculationType, typename Parameters> - struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters> { - inline gs48_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + inline gs48_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters>(par) { detail::mod_ster::setup_gs48(this->m_par, this->m_proj_parm); } @@ -410,10 +423,10 @@ namespace projections \par Example \image html ex_alsk.gif */ - template <typename CalculationType, typename Parameters> - struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters> { - inline alsk_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + inline alsk_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters>(par) { detail::mod_ster::setup_alsk(this->m_par, this->m_proj_parm); } @@ -430,10 +443,10 @@ namespace projections \par Example \image html ex_gs50.gif */ - template <typename CalculationType, typename Parameters> - struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters> { - inline gs50_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + inline gs50_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<T, Parameters>(par) { detail::mod_ster::setup_gs50(this->m_par, this->m_proj_parm); } @@ -451,64 +464,64 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gs50, gs50_ellipsoid, gs50_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class mil_os_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mil_os_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mil_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mil_os_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class lee_os_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class lee_os_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<lee_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<lee_os_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class gs48_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gs48_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gs48_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gs48_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class alsk_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class alsk_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<alsk_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<alsk_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class gs50_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class gs50_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<gs50_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<gs50_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void mod_ster_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void mod_ster_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("mil_os", new mil_os_entry<CalculationType, Parameters>); - factory.add_to_factory("lee_os", new lee_os_entry<CalculationType, Parameters>); - factory.add_to_factory("gs48", new gs48_entry<CalculationType, Parameters>); - factory.add_to_factory("alsk", new alsk_entry<CalculationType, Parameters>); - factory.add_to_factory("gs50", new gs50_entry<CalculationType, Parameters>); + factory.add_to_factory("mil_os", new mil_os_entry<T, Parameters>); + factory.add_to_factory("lee_os", new lee_os_entry<T, Parameters>); + factory.add_to_factory("gs48", new gs48_entry<T, Parameters>); + factory.add_to_factory("alsk", new alsk_entry<T, Parameters>); + factory.add_to_factory("gs50", new gs50_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/moll.hpp b/boost/geometry/srs/projections/proj/moll.hpp index 6f02c7dea0..deceb3401e 100644 --- a/boost/geometry/srs/projections/proj/moll.hpp +++ b/boost/geometry/srs/projections/proj/moll.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP -#define BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,9 +53,9 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct moll {}; - struct wag4 {}; - struct wag5 {}; + struct moll {}; // Mollweide + struct wag4 {}; // Wagner IV + struct wag5 {}; // Wagner V }} //namespace srs::par4 @@ -66,8 +65,8 @@ namespace projections namespace detail { namespace moll { - static const int MAX_ITER = 10; - static const double LOOP_TOL = 1e-7; + static const int max_iter = 10; + static const double loop_tol = 1e-7; template <typename T> struct par_moll @@ -76,38 +75,34 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_moll_spheroid : public base_t_fi<base_moll_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_moll_spheroid + : public base_t_fi<base_moll_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_moll<CalculationType> m_proj_parm; + par_moll<T> m_proj_parm; inline base_moll_spheroid(const Parameters& par) - : base_t_fi<base_moll_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_moll_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType k, V; + T k, V; int i; k = this->m_proj_parm.C_p * sin(lp_lat); - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { lp_lat -= V = (lp_lat + sin(lp_lat) - k) / (1. + cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } if (!i) - lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + lp_lat = (lp_lat < 0.) ? -half_pi : half_pi; else lp_lat *= 0.5; xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); @@ -116,12 +111,18 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { + static const T pi = detail::pi<T>(); + lp_lat = aasin(xy_y / this->m_proj_parm.C_y); lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat)); - lp_lat += lp_lat; - lp_lat = aasin((lp_lat + sin(lp_lat)) / this->m_proj_parm.C_p); + if (fabs(lp_lon) < pi) { + lp_lat += lp_lat; + lp_lat = aasin((lp_lat + sin(lp_lat)) / this->m_proj_parm.C_p); + } else { + lp_lon = lp_lat = HUGE_VAL; + } } static inline std::string get_name() @@ -139,6 +140,7 @@ namespace projections par.es = 0; sp = sin(p); r = sqrt(geometry::math::two_pi<T>() * sp / (p2 + sin(p2))); + proj_parm.C_x = 2. * r / geometry::math::pi<T>(); proj_parm.C_y = r / sp; proj_parm.C_p = p2 + sin(p2); @@ -184,10 +186,10 @@ namespace projections \par Example \image html ex_moll.gif */ - template <typename CalculationType, typename Parameters> - struct moll_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct moll_spheroid : public detail::moll::base_moll_spheroid<T, Parameters> { - inline moll_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + inline moll_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<T, Parameters>(par) { detail::moll::setup_moll(this->m_par, this->m_proj_parm); } @@ -205,10 +207,10 @@ namespace projections \par Example \image html ex_wag4.gif */ - template <typename CalculationType, typename Parameters> - struct wag4_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag4_spheroid : public detail::moll::base_moll_spheroid<T, Parameters> { - inline wag4_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + inline wag4_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<T, Parameters>(par) { detail::moll::setup_wag4(this->m_par, this->m_proj_parm); } @@ -226,10 +228,10 @@ namespace projections \par Example \image html ex_wag5.gif */ - template <typename CalculationType, typename Parameters> - struct wag5_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag5_spheroid : public detail::moll::base_moll_spheroid<T, Parameters> { - inline wag5_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + inline wag5_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<T, Parameters>(par) { detail::moll::setup_wag5(this->m_par, this->m_proj_parm); } @@ -245,42 +247,42 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag5, wag5_spheroid, wag5_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class moll_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class moll_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<moll_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<moll_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class wag4_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag4_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag4_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class wag5_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag5_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag5_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void moll_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void moll_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("moll", new moll_entry<CalculationType, Parameters>); - factory.add_to_factory("wag4", new wag4_entry<CalculationType, Parameters>); - factory.add_to_factory("wag5", new wag5_entry<CalculationType, Parameters>); + factory.add_to_factory("moll", new moll_entry<T, Parameters>); + factory.add_to_factory("wag4", new wag4_entry<T, Parameters>); + factory.add_to_factory("wag5", new wag5_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/natearth.hpp b/boost/geometry/srs/projections/proj/natearth.hpp index dcd259d9d1..47da25b9e2 100644 --- a/boost/geometry/srs/projections/proj/natearth.hpp +++ b/boost/geometry/srs/projections/proj/natearth.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,23 +15,10 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: -// The Natural Earth projection was designed by Tom Patterson, US National Park -// Service, in 2007, using Flex Projector. The shape of the original projection -// was defined at every 5 degrees and piece-wise cubic spline interpolation was -// used to compute the complete graticule. -// The code here uses polynomial functions instead of cubic splines and -// is therefore much simpler to program. The polynomial approximation was -// developed by Bojan Savric, in collaboration with Tom Patterson and Bernhard -// Jenny, Institute of Cartography, ETH Zurich. It slightly deviates from -// Patterson's original projection by adding additional curvature to meridians -// where they meet the horizontal pole line. This improvement is by intention -// and designed in collaboration with Tom Patterson. -// Port to PROJ.4 by Bernhard Jenny, 6 June 2011 - // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation @@ -54,6 +37,22 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +// The Natural Earth projection was designed by Tom Patterson, US National Park +// Service, in 2007, using Flex Projector. The shape of the original projection +// was defined at every 5 degrees and piece-wise cubic spline interpolation was +// used to compute the complete graticule. +// The code here uses polynomial functions instead of cubic splines and +// is therefore much simpler to program. The polynomial approximation was +// developed by Bojan Savric, in collaboration with Tom Patterson and Bernhard +// Jenny, Institute of Cartography, ETH Zurich. It slightly deviates from +// Patterson's original projection by adding additional curvature to meridians +// where they meet the horizontal pole line. This improvement is by intention +// and designed in collaboration with Tom Patterson. +// Port to PROJ.4 by Bernhard Jenny, 6 June 2011 + +#ifndef BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -64,7 +63,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct natearth {}; + struct natearth {}; // Natural Earth }} //namespace srs::par4 @@ -89,31 +88,28 @@ namespace projections static const double C2 = (7 * B2); static const double C3 = (9 * B3); static const double C4 = (11 * B4); - static const double EPS = 1e-11; - //static const double MAX_Y = (0.8707 * 0.52 * geometry::math::pi<double>()); + static const double epsilon = 1e-11; template <typename T> - inline T MAX_Y() { return (0.8707 * 0.52 * detail::ONEPI<T>()); } + inline T max_y() { return (0.8707 * 0.52 * detail::pi<T>()); } + + /* Not sure at all of the appropriate number for max_iter... */ + static const int max_iter = 100; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_natearth_spheroid : public base_t_fi<base_natearth_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_natearth_spheroid + : public base_t_fi<base_natearth_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_natearth_spheroid(const Parameters& par) - : base_t_fi<base_natearth_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_natearth_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType phi2, phi4; + T phi2, phi4; phi2 = lp_lat * lp_lat; phi4 = phi2 * phi2; @@ -123,31 +119,34 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType MAX_Y = natearth::MAX_Y<CalculationType>(); + static const T max_y = natearth::max_y<T>(); - CalculationType yc, tol, y2, y4, f, fder; + T yc, tol, y2, y4, f, fder; + int i; /* make sure y is inside valid range */ - if (xy_y > MAX_Y) { - xy_y = MAX_Y; - } else if (xy_y < -MAX_Y) { - xy_y = -MAX_Y; + if (xy_y > max_y) { + xy_y = max_y; + } else if (xy_y < -max_y) { + xy_y = -max_y; } /* latitude */ yc = xy_y; - for (;;) { /* Newton-Raphson */ + for (i = max_iter; i ; --i) { /* Newton-Raphson */ y2 = yc * yc; y4 = y2 * y2; f = (yc * (B0 + y2 * (B1 + y4 * (B2 + B3 * y2 + B4 * y4)))) - xy_y; fder = C0 + y2 * (C1 + y4 * (C2 + C3 * y2 + C4 * y4)); yc -= tol = f / fder; - if (fabs(tol) < EPS) { + if (fabs(tol) < epsilon) { break; } } + if( i == 0 ) + BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) ); lp_lat = yc; /* longitude */ @@ -184,10 +183,10 @@ namespace projections \par Example \image html ex_natearth.gif */ - template <typename CalculationType, typename Parameters> - struct natearth_spheroid : public detail::natearth::base_natearth_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct natearth_spheroid : public detail::natearth::base_natearth_spheroid<T, Parameters> { - inline natearth_spheroid(const Parameters& par) : detail::natearth::base_natearth_spheroid<CalculationType, Parameters>(par) + inline natearth_spheroid(const Parameters& par) : detail::natearth::base_natearth_spheroid<T, Parameters>(par) { detail::natearth::setup_natearth(this->m_par); } @@ -201,20 +200,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::natearth, natearth_spheroid, natearth_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class natearth_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class natearth_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<natearth_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<natearth_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void natearth_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void natearth_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("natearth", new natearth_entry<CalculationType, Parameters>); + factory.add_to_factory("natearth", new natearth_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/nell.hpp b/boost/geometry/srs/projections/proj/nell.hpp index 351a4101f7..fcb0e18b17 100644 --- a/boost/geometry/srs/projections/proj/nell.hpp +++ b/boost/geometry/srs/projections/proj/nell.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NELL_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NELL_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct nell {}; + struct nell {}; // Nell }} //namespace srs::par4 @@ -62,37 +61,32 @@ namespace projections namespace detail { namespace nell { - static const int MAX_ITER = 10; - static const double LOOP_TOL = 1e-7; + static const int max_iter = 10; + static const double loop_tol = 1e-7; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_nell_spheroid : public base_t_fi<base_nell_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_nell_spheroid + : public base_t_fi<base_nell_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_nell_spheroid(const Parameters& par) - : base_t_fi<base_nell_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_nell_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType k, V; + T k, V; int i; k = 2. * sin(lp_lat); V = lp_lat * lp_lat; lp_lat *= 1.00371 + V * (-0.0935382 + V * -0.011412); - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { lp_lat -= V = (lp_lat + sin(lp_lat) - k) / (1. + cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } xy_x = 0.5 * lp_lon * (1. + cos(lp_lat)); @@ -101,7 +95,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = 2. * xy_x / (1. + cos(xy_y)); lp_lat = aasin(0.5 * (xy_y + sin(xy_y))); @@ -136,10 +130,10 @@ namespace projections \par Example \image html ex_nell.gif */ - template <typename CalculationType, typename Parameters> - struct nell_spheroid : public detail::nell::base_nell_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct nell_spheroid : public detail::nell::base_nell_spheroid<T, Parameters> { - inline nell_spheroid(const Parameters& par) : detail::nell::base_nell_spheroid<CalculationType, Parameters>(par) + inline nell_spheroid(const Parameters& par) : detail::nell::base_nell_spheroid<T, Parameters>(par) { detail::nell::setup_nell(this->m_par); } @@ -153,20 +147,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nell, nell_spheroid, nell_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class nell_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class nell_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<nell_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<nell_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void nell_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void nell_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("nell", new nell_entry<CalculationType, Parameters>); + factory.add_to_factory("nell", new nell_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/nell_h.hpp b/boost/geometry/srs/projections/proj/nell_h.hpp index 05de9e263e..73f0018ac6 100644 --- a/boost/geometry/srs/projections/proj/nell_h.hpp +++ b/boost/geometry/srs/projections/proj/nell_h.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct nell_h {}; + struct nell_h {}; // Nell-Hammer }} //namespace srs::par4 @@ -63,26 +62,21 @@ namespace projections namespace detail { namespace nell_h { - static const int NITER = 9; - static const double EPS = 1e-7; + static const int n_iter = 9; + static const double epsilon = 1e-7; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_nell_h_spheroid : public base_t_fi<base_nell_h_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_nell_h_spheroid + : public base_t_fi<base_nell_h_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_nell_h_spheroid(const Parameters& par) - : base_t_fi<base_nell_h_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_nell_h_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = 0.5 * lp_lon * (1. + cos(lp_lat)); xy_y = 2.0 * (lp_lat - tan(0.5 *lp_lat)); @@ -90,22 +84,22 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType V, c, p; + T V, c, p; int i; p = 0.5 * xy_y; - for (i = NITER; i ; --i) { + for (i = n_iter; i ; --i) { c = cos(0.5 * lp_lat); lp_lat -= V = (lp_lat - tan(lp_lat/2) - p)/(1. - 0.5/(c*c)); - if (fabs(V) < EPS) + if (fabs(V) < epsilon) break; } if (!i) { - lp_lat = p < 0. ? -HALFPI : HALFPI; + lp_lat = p < 0. ? -half_pi : half_pi; lp_lon = 2. * xy_x; } else lp_lon = 2. * xy_x / (1. + cos(lp_lat)); @@ -140,10 +134,10 @@ namespace projections \par Example \image html ex_nell_h.gif */ - template <typename CalculationType, typename Parameters> - struct nell_h_spheroid : public detail::nell_h::base_nell_h_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct nell_h_spheroid : public detail::nell_h::base_nell_h_spheroid<T, Parameters> { - inline nell_h_spheroid(const Parameters& par) : detail::nell_h::base_nell_h_spheroid<CalculationType, Parameters>(par) + inline nell_h_spheroid(const Parameters& par) : detail::nell_h::base_nell_h_spheroid<T, Parameters>(par) { detail::nell_h::setup_nell_h(this->m_par); } @@ -157,20 +151,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nell_h, nell_h_spheroid, nell_h_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class nell_h_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class nell_h_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<nell_h_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<nell_h_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void nell_h_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void nell_h_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("nell_h", new nell_h_entry<CalculationType, Parameters>); + factory.add_to_factory("nell_h", new nell_h_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/nocol.hpp b/boost/geometry/srs/projections/proj/nocol.hpp index ef2e95a843..01e428c6d4 100644 --- a/boost/geometry/srs/projections/proj/nocol.hpp +++ b/boost/geometry/srs/projections/proj/nocol.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct nicol {}; + struct nicol {}; // Nicolosi Globular }} //namespace srs::par4 @@ -63,45 +62,40 @@ namespace projections namespace detail { namespace nocol { - static const double EPS = 1e-10; + static const double epsilon = 1e-10; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_nocol_spheroid : public base_t_f<base_nocol_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_nocol_spheroid + : public base_t_f<base_nocol_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_nocol_spheroid(const Parameters& par) - : base_t_f<base_nocol_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_nocol_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - if (fabs(lp_lon) < EPS) { + if (fabs(lp_lon) < epsilon) { xy_x = 0; xy_y = lp_lat; - } else if (fabs(lp_lat) < EPS) { + } else if (fabs(lp_lat) < epsilon) { xy_x = lp_lon; xy_y = 0.; - } else if (fabs(fabs(lp_lon) - HALFPI) < EPS) { + } else if (fabs(fabs(lp_lon) - half_pi) < epsilon) { xy_x = lp_lon * cos(lp_lat); - xy_y = HALFPI * sin(lp_lat); - } else if (fabs(fabs(lp_lat) - HALFPI) < EPS) { + xy_y = half_pi * sin(lp_lat); + } else if (fabs(fabs(lp_lat) - half_pi) < epsilon) { xy_x = 0; xy_y = lp_lat; } else { - CalculationType tb, c, d, m, n, r2, sp; + T tb, c, d, m, n, r2, sp; - tb = HALFPI / lp_lon - lp_lon / HALFPI; - c = lp_lat / HALFPI; + tb = half_pi / lp_lon - lp_lon / half_pi; + c = lp_lat / half_pi; d = (1 - c * c)/((sp = sin(lp_lat)) - c); r2 = tb / d; r2 *= r2; @@ -109,10 +103,10 @@ namespace projections n = (sp / r2 + 0.5 * d)/(1. + 1./r2); xy_x = cos(lp_lat); xy_x = sqrt(m * m + xy_x * xy_x / (1. + r2)); - xy_x = HALFPI * ( m + (lp_lon < 0. ? -xy_x : xy_x)); + xy_x = half_pi * ( m + (lp_lon < 0. ? -xy_x : xy_x)); xy_y = sqrt(n * n - (sp * sp / r2 + d * sp - 1.) / (1. + 1./r2)); - xy_y = HALFPI * ( n + (lp_lat < 0. ? xy_y : -xy_y )); + xy_y = half_pi * ( n + (lp_lat < 0. ? xy_y : -xy_y )); } } @@ -146,10 +140,10 @@ namespace projections \par Example \image html ex_nicol.gif */ - template <typename CalculationType, typename Parameters> - struct nicol_spheroid : public detail::nocol::base_nocol_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct nicol_spheroid : public detail::nocol::base_nocol_spheroid<T, Parameters> { - inline nicol_spheroid(const Parameters& par) : detail::nocol::base_nocol_spheroid<CalculationType, Parameters>(par) + inline nicol_spheroid(const Parameters& par) : detail::nocol::base_nocol_spheroid<T, Parameters>(par) { detail::nocol::setup_nicol(this->m_par); } @@ -163,20 +157,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nicol, nicol_spheroid, nicol_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class nicol_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class nicol_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<nicol_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<nicol_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void nocol_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void nocol_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("nicol", new nicol_entry<CalculationType, Parameters>); + factory.add_to_factory("nicol", new nicol_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/nsper.hpp b/boost/geometry/srs/projections/proj/nsper.hpp index 85576bf963..2910ee6203 100644 --- a/boost/geometry/srs/projections/proj/nsper.hpp +++ b/boost/geometry/srs/projections/proj/nsper.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP + #include <boost/config.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -55,8 +54,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct nsper {}; - struct tpers {}; + struct nsper {}; // Near-sided perspective + struct tpers {}; // Tilted perspective }} //namespace srs::par4 @@ -66,11 +65,13 @@ namespace projections namespace detail { namespace nsper { - static const double EPS10 = 1.e-10; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + static const double epsilon10 = 1.e-10; + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_nsper @@ -87,69 +88,66 @@ namespace projections T sg; T sw; T cw; - int mode; + mode_type mode; int tilt; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_nsper_spheroid : public base_t_fi<base_nsper_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_nsper_spheroid + : public base_t_fi<base_nsper_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_nsper<CalculationType> m_proj_parm; + par_nsper<T> m_proj_parm; inline base_nsper_spheroid(const Parameters& par) - : base_t_fi<base_nsper_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_nsper_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType coslam, cosphi, sinphi; + T coslam, cosphi, sinphi; sinphi = sin(lp_lat); cosphi = cos(lp_lat); coslam = cos(lp_lon); switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam; break; - case EQUIT: + case equit: xy_y = cosphi * coslam; break; - case S_POLE: + case s_pole: xy_y = - sinphi; break; - case N_POLE: + case n_pole: xy_y = sinphi; break; } - if (xy_y < this->m_proj_parm.rp) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (xy_y < this->m_proj_parm.rp) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_y = this->m_proj_parm.pn1 / (this->m_proj_parm.p - xy_y); xy_x = xy_y * cosphi * sin(lp_lon); switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: xy_y *= (this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam); break; - case EQUIT: + case equit: xy_y *= sinphi; break; - case N_POLE: + case n_pole: coslam = - coslam; BOOST_FALLTHROUGH; - case S_POLE: + case s_pole: xy_y *= cosphi * coslam; break; } if (this->m_proj_parm.tilt) { - CalculationType yt, ba; + T yt, ba; yt = xy_y * this->m_proj_parm.cg + xy_x * this->m_proj_parm.sg; ba = 1. / (yt * this->m_proj_parm.sw * this->m_proj_parm.h + this->m_proj_parm.cw); @@ -160,12 +158,12 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType rh, cosz, sinz; + T rh, cosz, sinz; if (this->m_proj_parm.tilt) { - CalculationType bm, bq, yt; + T bm, bq, yt; yt = 1./(this->m_proj_parm.pn1 - xy_y * this->m_proj_parm.sw); bm = this->m_proj_parm.pn1 * xy_x * yt; @@ -174,30 +172,31 @@ namespace projections xy_y = bq * this->m_proj_parm.cg - bm * this->m_proj_parm.sg; } rh = boost::math::hypot(xy_x, xy_y); - if ((sinz = 1. - rh * rh * this->m_proj_parm.pfact) < 0.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((sinz = 1. - rh * rh * this->m_proj_parm.pfact) < 0.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } sinz = (this->m_proj_parm.p - sqrt(sinz)) / (this->m_proj_parm.pn1 / rh + rh / this->m_proj_parm.pn1); cosz = sqrt(1. - sinz * sinz); - if (fabs(rh) <= EPS10) { + if (fabs(rh) <= epsilon10) { lp_lon = 0.; lp_lat = this->m_par.phi0; } else { switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: lp_lat = asin(cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh); xy_y = (cosz - this->m_proj_parm.sinph0 * sin(lp_lat)) * rh; xy_x *= sinz * this->m_proj_parm.cosph0; break; - case EQUIT: + case equit: lp_lat = asin(xy_y * sinz / rh); xy_y = cosz * rh; xy_x *= sinz; break; - case N_POLE: + case n_pole: lp_lat = asin(cosz); xy_y = -xy_y; break; - case S_POLE: + case s_pole: lp_lat = - asin(cosz); break; } @@ -215,14 +214,15 @@ namespace projections template <typename Parameters, typename T> inline void setup(Parameters& par, par_nsper<T>& proj_parm) { - if ((proj_parm.height = pj_param(par.params, "dh").f) <= 0.) - BOOST_THROW_EXCEPTION( projection_exception(-30) ); - if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) < EPS10) - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; - else if (fabs(par.phi0) < EPS10) - proj_parm.mode = EQUIT; + if ((proj_parm.height = pj_get_param_f(par.params, "h")) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(error_h_less_than_zero) ); + + if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) < epsilon10) + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; + else if (fabs(par.phi0) < epsilon10) + proj_parm.mode = equit; else { - proj_parm.mode = OBLIQ; + proj_parm.mode = obliq; proj_parm.sinph0 = sin(par.phi0); proj_parm.cosph0 = cos(par.phi0); } @@ -240,6 +240,7 @@ namespace projections inline void setup_nsper(Parameters& par, par_nsper<T>& proj_parm) { proj_parm.tilt = 0; + setup(par, proj_parm); } @@ -249,11 +250,12 @@ namespace projections { T omega, gamma; - omega = pj_param(par.params, "dtilt").f * geometry::math::d2r<T>(); - gamma = pj_param(par.params, "dazi").f * geometry::math::d2r<T>(); + omega = pj_get_param_r(par.params, "tilt"); + gamma = pj_get_param_r(par.params, "azi"); proj_parm.tilt = 1; proj_parm.cg = cos(gamma); proj_parm.sg = sin(gamma); proj_parm.cw = cos(omega); proj_parm.sw = sin(omega); + setup(par, proj_parm); } @@ -274,10 +276,10 @@ namespace projections \par Example \image html ex_nsper.gif */ - template <typename CalculationType, typename Parameters> - struct nsper_spheroid : public detail::nsper::base_nsper_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct nsper_spheroid : public detail::nsper::base_nsper_spheroid<T, Parameters> { - inline nsper_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<CalculationType, Parameters>(par) + inline nsper_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<T, Parameters>(par) { detail::nsper::setup_nsper(this->m_par, this->m_proj_parm); } @@ -299,10 +301,10 @@ namespace projections \par Example \image html ex_tpers.gif */ - template <typename CalculationType, typename Parameters> - struct tpers_spheroid : public detail::nsper::base_nsper_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tpers_spheroid : public detail::nsper::base_nsper_spheroid<T, Parameters> { - inline tpers_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<CalculationType, Parameters>(par) + inline tpers_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<T, Parameters>(par) { detail::nsper::setup_tpers(this->m_par, this->m_proj_parm); } @@ -317,31 +319,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tpers, tpers_spheroid, tpers_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class nsper_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class nsper_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<nsper_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<nsper_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class tpers_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tpers_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<tpers_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tpers_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void nsper_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void nsper_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("nsper", new nsper_entry<CalculationType, Parameters>); - factory.add_to_factory("tpers", new tpers_entry<CalculationType, Parameters>); + factory.add_to_factory("nsper", new nsper_entry<T, Parameters>); + factory.add_to_factory("tpers", new tpers_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/nzmg.hpp b/boost/geometry/srs/projections/proj/nzmg.hpp index 067eece27a..2806e1a2d2 100644 --- a/boost/geometry/srs/projections/proj/nzmg.hpp +++ b/boost/geometry/srs/projections/proj/nzmg.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP -#define BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,12 +15,12 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // Purpose: Implementation of the nzmg (New Zealand Map Grid) projection. -// Very loosely based upon DMA code by Bradford W. Drew +// Very loosely based upon DMA code by Bradford W. Drew // Author: Gerald Evenden // Copyright (c) 1995, Gerald Evenden @@ -46,6 +42,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -59,7 +58,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct nzmg {}; + struct nzmg {}; // New Zealand Map Grid }} //namespace srs::par4 @@ -69,22 +68,20 @@ namespace projections namespace detail { namespace nzmg { - static const double EPSLN = 1e-10; - //static const double SEC5_TO_RAD = 0.4848136811095359935899141023; - //static const double RAD_TO_SEC5 = 2.062648062470963551564733573; + static const double epsilon = 1e-10; static const int Nbf = 5; static const int Ntpsi = 9; static const int Ntphi = 8; template <typename T> - inline T SEC5_TO_RAD() { return 0.4848136811095359935899141023; } + inline T sec5_to_rad() { return 0.4848136811095359935899141023; } template <typename T> - inline T RAD_TO_SEC5() { return 2.062648062470963551564733573; } + inline T rad_to_sec5() { return 2.062648062470963551564733573; } template <typename T> - inline const COMPLEX<T> * bf() + inline const pj_complex<T> * bf() { - static const COMPLEX<T> result[] = { + static const pj_complex<T> result[] = { {.7557853228, 0.0}, {.249204646, .003371507}, {-.001541739, .041058560}, @@ -98,80 +95,76 @@ namespace projections template <typename T> inline const T * tphi() { - static const T result[] = { 1.5627014243, .5185406398, -.03333098, -.1052906, -.0368594, - .007317, .01220, .00394, -.0013 }; + static const T result[] = { 1.5627014243, .5185406398, -.03333098, + -.1052906, -.0368594, .007317, + .01220, .00394, -.0013 }; return result; } template <typename T> inline const T * tpsi() { static const T result[] = { .6399175073, -.1358797613, .063294409, -.02526853, .0117879, - -.0055161, .0026906, -.001333, .00067, -.00034 }; + -.0055161, .0026906, -.001333, .00067, -.00034 }; return result; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_nzmg_ellipsoid : public base_t_fi<base_nzmg_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_nzmg_ellipsoid + : public base_t_fi<base_nzmg_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_nzmg_ellipsoid(const Parameters& par) - : base_t_fi<base_nzmg_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_nzmg_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType RAD_TO_SEC5 = nzmg::RAD_TO_SEC5<CalculationType>(); + static const T rad_to_sec5 = nzmg::rad_to_sec5<T>(); - COMPLEX<CalculationType> p; - const CalculationType * C; + pj_complex<T> p; + const T * C; int i; - lp_lat = (lp_lat - this->m_par.phi0) * RAD_TO_SEC5; - for (p.r = *(C = tpsi<CalculationType>() + (i = Ntpsi)); i ; --i) + lp_lat = (lp_lat - this->m_par.phi0) * rad_to_sec5; + for (p.r = *(C = tpsi<T>() + (i = Ntpsi)); i ; --i) p.r = *--C + lp_lat * p.r; p.r *= lp_lat; p.i = lp_lon; - p = pj_zpoly1(p, bf<CalculationType>(), Nbf); + p = pj_zpoly1(p, bf<T>(), Nbf); xy_x = p.i; xy_y = p.r; } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType SEC5_TO_RAD = nzmg::SEC5_TO_RAD<CalculationType>(); + static const T sec5_to_rad = nzmg::sec5_to_rad<T>(); int nn, i; - COMPLEX<CalculationType> p, f, fp, dp; - CalculationType den; - const CalculationType* C; + pj_complex<T> p, f, fp, dp; + T den; + const T* C; p.r = xy_y; p.i = xy_x; for (nn = 20; nn ;--nn) { - f = pj_zpolyd1(p, bf<CalculationType>(), Nbf, &fp); + f = pj_zpolyd1(p, bf<T>(), Nbf, &fp); f.r -= xy_y; f.i -= xy_x; den = fp.r * fp.r + fp.i * fp.i; p.r += dp.r = -(f.r * fp.r + f.i * fp.i) / den; p.i += dp.i = -(f.i * fp.r - f.r * fp.i) / den; - if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN) + if ((fabs(dp.r) + fabs(dp.i)) <= epsilon) break; } if (nn) { lp_lon = p.i; - for (lp_lat = *(C = tphi<CalculationType>() + (i = Ntphi)); i ; --i) + for (lp_lat = *(C = tphi<T>() + (i = Ntphi)); i ; --i) lp_lat = *--C + p.r * lp_lat; - lp_lat = this->m_par.phi0 + p.r * lp_lat * SEC5_TO_RAD; + lp_lat = this->m_par.phi0 + p.r * lp_lat * sec5_to_rad; } else lp_lon = lp_lat = HUGE_VAL; } @@ -188,11 +181,12 @@ namespace projections inline void setup_nzmg(Parameters& par) { typedef typename Parameters::type calc_t; + static const calc_t d2r = geometry::math::d2r<calc_t>(); /* force to International major axis */ par.ra = 1. / (par.a = 6378388.0); - par.lam0 = geometry::math::d2r<calc_t>() * 173.; - par.phi0 = geometry::math::d2r<calc_t>() * -41.; + par.lam0 = 173. * d2r; + par.phi0 = -41. * d2r; par.x0 = 2510000.; par.y0 = 6023150.; } @@ -211,10 +205,10 @@ namespace projections \par Example \image html ex_nzmg.gif */ - template <typename CalculationType, typename Parameters> - struct nzmg_ellipsoid : public detail::nzmg::base_nzmg_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct nzmg_ellipsoid : public detail::nzmg::base_nzmg_ellipsoid<T, Parameters> { - inline nzmg_ellipsoid(const Parameters& par) : detail::nzmg::base_nzmg_ellipsoid<CalculationType, Parameters>(par) + inline nzmg_ellipsoid(const Parameters& par) : detail::nzmg::base_nzmg_ellipsoid<T, Parameters>(par) { detail::nzmg::setup_nzmg(this->m_par); } @@ -228,20 +222,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nzmg, nzmg_ellipsoid, nzmg_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class nzmg_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class nzmg_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<nzmg_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<nzmg_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void nzmg_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void nzmg_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("nzmg", new nzmg_entry<CalculationType, Parameters>); + factory.add_to_factory("nzmg", new nzmg_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/ob_tran.hpp b/boost/geometry/srs/projections/proj/ob_tran.hpp index ae74cc27d2..dd6df24def 100644 --- a/boost/geometry/srs/projections/proj/ob_tran.hpp +++ b/boost/geometry/srs/projections/proj/ob_tran.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP -#define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP + #include <boost/geometry/util/math.hpp> #include <boost/shared_ptr.hpp> @@ -57,7 +56,7 @@ namespace srs { namespace par4 { //struct ob_tran_oblique {}; //struct ob_tran_transverse {}; - struct ob_tran {}; + struct ob_tran {}; // General Oblique Transformation }} //namespace srs::par4 @@ -67,36 +66,32 @@ namespace projections namespace detail { // fwd declaration needed below - template <typename CalculationType> - inline detail::base_v<CalculationType, parameters<CalculationType> >* - create_new(parameters<CalculationType> const& parameters); + template <typename T> + inline detail::base_v<T, parameters<T> >* + create_new(parameters<T> const& parameters); } // namespace detail namespace detail { namespace ob_tran { - static const double TOL = 1e-10; + static const double tolerance = 1e-10; template <typename Parameters> inline Parameters o_proj_parameters(Parameters const& par) { - Parameters pj; + /* copy existing header into new */ + Parameters pj = par; /* get name of projection to be translated */ - pj.name = pj_param(par.params, "so_proj").s; - /* copy existing header into new */ - pj.params = par.params; - pj.over = par.over; - pj.geoc = par.geoc; - pj.a = par.a; - pj.es = par.es; - pj.ra = par.ra; - pj.lam0 = par.lam0; - pj.phi0 = par.phi0; - pj.x0 = par.x0; - pj.y0 = par.y0; - pj.k0 = par.k0; + pj.name = pj_get_param_s(par.params, "o_proj"); + if (pj.name.empty()) + BOOST_THROW_EXCEPTION( projection_exception(error_no_rotation_proj) ); + + /* avoid endless recursion */ + if( pj.name == "ob_tran") + BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_find_proj) ); + /* force spherical earth */ pj.one_es = pj.rone_es = 1.; pj.es = pj.e = 0.; @@ -104,47 +99,50 @@ namespace projections return pj; } - template <typename CalculationType, typename Parameters> + template <typename T, typename Parameters> struct par_ob_tran { par_ob_tran(Parameters const& par) : link(projections::detail::create_new(o_proj_parameters(par))) { if (! link.get()) - BOOST_THROW_EXCEPTION( projection_exception(-26) ); + BOOST_THROW_EXCEPTION( projection_exception(error_unknown_projection_id) ); } - template <typename T> inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { link->fwd(lp_lon, lp_lat, xy_x, xy_y); } - template <typename T> inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { link->inv(xy_x, xy_y, lp_lon, lp_lat); } - boost::shared_ptr<base_v<CalculationType, Parameters> > link; - CalculationType lamp; - CalculationType cphip, sphip; + boost::shared_ptr<base_v<T, Parameters> > link; + T lamp; + T cphip, sphip; }; - template <typename StaticParameters, typename CalculationType, typename Parameters> + template <typename StaticParameters, typename T, typename Parameters> struct par_ob_tran_static { + // this metafunction handles static error handling typedef typename srs::par4::detail::pick_o_proj_tag < StaticParameters >::type o_proj_tag; + /* avoid endless recursion */ + static const bool is_o_proj_not_ob_tran = ! boost::is_same<o_proj_tag, srs::par4::ob_tran>::value; + BOOST_MPL_ASSERT_MSG((is_o_proj_not_ob_tran), INVALID_O_PROJ_PARAMETER, (StaticParameters)); + typedef typename projections::detail::static_projection_type < o_proj_tag, srs_sphere_tag, // force spherical StaticParameters, - CalculationType, + T, Parameters >::type projection_type; @@ -152,21 +150,19 @@ namespace projections : link(o_proj_parameters(par)) {} - template <typename T> inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { link.fwd(lp_lon, lp_lat, xy_x, xy_y); } - template <typename T> inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { link.inv(xy_x, xy_y, lp_lon, lp_lat); } projection_type link; - CalculationType lamp; - CalculationType cphip, sphip; + T lamp; + T cphip, sphip; }; template <typename T, typename Par> @@ -209,6 +205,7 @@ namespace projections coslam = cos(lp_lon); lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + proj_parm.lamp); lp_lat = aasin(- cosphi * coslam); + proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y); } @@ -227,92 +224,92 @@ namespace projections } // General Oblique Transformation - template <typename CalculationType, typename Parameters, typename ProjParameters> - inline CalculationType setup_ob_tran(Parameters & par, ProjParameters& proj_parm) + template <typename T, typename Parameters, typename ProjParameters> + inline T setup_ob_tran(Parameters & par, ProjParameters& proj_parm) { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType phip; + T phip, alpha; par.es = 0.; /* force to spherical */ // proj_parm.link should be created at this point - if (pj_param(par.params, "to_alpha").i) { - CalculationType lamc, phic, alpha; - - lamc = pj_param(par.params, "ro_lon_c").f; - phic = pj_param(par.params, "ro_lat_c").f; - alpha = pj_param(par.params, "ro_alpha").f; - /* - if (fabs(phic) <= TOL || - fabs(fabs(phic) - HALFPI) <= TOL || - fabs(fabs(alpha) - HALFPI) <= TOL) - */ - if (fabs(fabs(phic) - HALFPI) <= TOL) - BOOST_THROW_EXCEPTION( projection_exception(-32) ); + if (pj_param_r(par.params, "o_alpha", alpha)) { + T lamc, phic; + + lamc = pj_get_param_r(par.params, "o_lon_c"); + phic = pj_get_param_r(par.params, "o_lat_c"); + //alpha = pj_get_param_r(par.params, "o_alpha"); + + if (fabs(fabs(phic) - half_pi) <= tolerance) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_or_alpha_eq_90) ); + proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic)); phip = aasin(cos(phic) * sin(alpha)); - } else if (pj_param(par.params, "to_lat_p").i) { /* specified new pole */ - proj_parm.lamp = pj_param(par.params, "ro_lon_p").f; - phip = pj_param(par.params, "ro_lat_p").f; + } else if (pj_param_r(par.params, "o_lat_p", phip)) { /* specified new pole */ + proj_parm.lamp = pj_get_param_r(par.params, "o_lon_p"); + //phip = pj_param_r(par.params, "o_lat_p"); } else { /* specified new "equator" points */ - CalculationType lam1, lam2, phi1, phi2, con; - - lam1 = pj_param(par.params, "ro_lon_1").f; - phi1 = pj_param(par.params, "ro_lat_1").f; - lam2 = pj_param(par.params, "ro_lon_2").f; - phi2 = pj_param(par.params, "ro_lat_2").f; - if (fabs(phi1 - phi2) <= TOL || - (con = fabs(phi1)) <= TOL || - fabs(con - HALFPI) <= TOL || - fabs(fabs(phi2) - HALFPI) <= TOL) - BOOST_THROW_EXCEPTION( projection_exception(-33) ); + T lam1, lam2, phi1, phi2, con; + + lam1 = pj_get_param_r(par.params, "o_lon_1"); + phi1 = pj_get_param_r(par.params, "o_lat_1"); + lam2 = pj_get_param_r(par.params, "o_lon_2"); + phi2 = pj_get_param_r(par.params, "o_lat_2"); + if (fabs(phi1 - phi2) <= tolerance || (con = fabs(phi1)) <= tolerance || + fabs(con - half_pi) <= tolerance || fabs(fabs(phi2) - half_pi) <= tolerance) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_1_or_2_zero_or_90) ); + proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) - sin(phi1) * cos(phi2) * cos(lam2), sin(phi1) * cos(phi2) * sin(lam2) - cos(phi1) * sin(phi2) * sin(lam1)); phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1)); } - if (fabs(phip) > TOL) { /* oblique */ + + if (fabs(phip) > tolerance) { /* oblique */ proj_parm.cphip = cos(phip); proj_parm.sphip = sin(phip); } else { /* transverse */ } + + // TODO: + /* Support some rather speculative test cases, where the rotated projection */ + /* is actually latlong. We do not want scaling in that case... */ + //if (proj_parm.link...mutable_parameters().right==PJ_IO_UNITS_ANGULAR) + // par.right = PJ_IO_UNITS_PROJECTED; + // return phip to choose model return phip; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_ob_tran_oblique : public base_t_fi<base_ob_tran_oblique<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_ob_tran_oblique + : public base_t_fi<base_ob_tran_oblique<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_ob_tran<CalculationType, Parameters> m_proj_parm; + par_ob_tran<T, Parameters> m_proj_parm; inline base_ob_tran_oblique(Parameters const& par, - par_ob_tran<CalculationType, Parameters> const& proj_parm) + par_ob_tran<T, Parameters> const& proj_parm) : base_t_fi < - base_ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters + base_ob_tran_oblique<T, Parameters>, T, Parameters >(*this, par) , m_proj_parm(proj_parm) {} // FORWARD(o_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); } // INVERSE(o_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); } @@ -325,35 +322,31 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_ob_tran_transverse : public base_t_fi<base_ob_tran_transverse<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_ob_tran_transverse + : public base_t_fi<base_ob_tran_transverse<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_ob_tran<CalculationType, Parameters> m_proj_parm; + par_ob_tran<T, Parameters> m_proj_parm; inline base_ob_tran_transverse(Parameters const& par, - par_ob_tran<CalculationType, Parameters> const& proj_parm) + par_ob_tran<T, Parameters> const& proj_parm) : base_t_fi < - base_ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters + base_ob_tran_transverse<T, Parameters>, T, Parameters >(*this, par) , m_proj_parm(proj_parm) {} // FORWARD(t_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); } // INVERSE(t_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); } @@ -366,25 +359,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename StaticParameters, typename CalculationType, typename Parameters> - struct base_ob_tran_static : public base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, - CalculationType, Parameters> + template <typename StaticParameters, typename T, typename Parameters> + struct base_ob_tran_static + : public base_t_fi<base_ob_tran_static<StaticParameters, T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_ob_tran_static<StaticParameters, CalculationType, Parameters> m_proj_parm; + par_ob_tran_static<StaticParameters, T, Parameters> m_proj_parm; bool m_is_oblique; inline base_ob_tran_static(Parameters const& par) - : base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, CalculationType, Parameters>(*this, par) + : base_t_fi<base_ob_tran_static<StaticParameters, T, Parameters>, T, Parameters>(*this, par) , m_proj_parm(par) {} // FORWARD(o_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { if (m_is_oblique) { o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); @@ -395,7 +384,7 @@ namespace projections // INVERSE(o_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { if (m_is_oblique) { o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); @@ -439,12 +428,12 @@ namespace projections \par Example \image html ex_ob_tran.gif */ - template <typename CalculationType, typename Parameters> - struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<T, Parameters> { inline ob_tran_oblique(Parameters const& par, - detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm) - : detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters>(par, proj_parm) + detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm) + : detail::ob_tran::base_ob_tran_oblique<T, Parameters>(par, proj_parm) { // already done //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); @@ -476,12 +465,12 @@ namespace projections \par Example \image html ex_ob_tran.gif */ - template <typename CalculationType, typename Parameters> - struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<T, Parameters> { inline ob_tran_transverse(Parameters const& par, - detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm) - : detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters>(par, proj_parm) + detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm) + : detail::ob_tran::base_ob_tran_transverse<T, Parameters>(par, proj_parm) { // already done //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); @@ -513,14 +502,14 @@ namespace projections \par Example \image html ex_ob_tran.gif */ - template <typename StaticParameters, typename CalculationType, typename Parameters> - struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters> + template <typename StaticParameters, typename T, typename Parameters> + struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters> { inline ob_tran_static(const Parameters& par) - : detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>(par) + : detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters>(par) { - CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(this->m_par, this->m_proj_parm); - this->m_is_oblique = fabs(phip) > detail::ob_tran::TOL; + T phip = detail::ob_tran::setup_ob_tran<T>(this->m_par, this->m_proj_parm); + this->m_is_oblique = fabs(phip) > detail::ob_tran::tolerance; } }; @@ -541,27 +530,27 @@ namespace projections }; // Factory entry(s) - template <typename CalculationType, typename Parameters> - class ob_tran_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class ob_tran_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { Parameters params = par; - detail::ob_tran::par_ob_tran<CalculationType, Parameters> proj_parm(params); - CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(params, proj_parm); + detail::ob_tran::par_ob_tran<T, Parameters> proj_parm(params); + T phip = detail::ob_tran::setup_ob_tran<T>(params, proj_parm); - if (fabs(phip) > detail::ob_tran::TOL) - return new base_v_fi<ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm); + if (fabs(phip) > detail::ob_tran::tolerance) + return new base_v_fi<ob_tran_oblique<T, Parameters>, T, Parameters>(params, proj_parm); else - return new base_v_fi<ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm); + return new base_v_fi<ob_tran_transverse<T, Parameters>, T, Parameters>(params, proj_parm); } }; - template <typename CalculationType, typename Parameters> - inline void ob_tran_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void ob_tran_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("ob_tran", new ob_tran_entry<CalculationType, Parameters>); + factory.add_to_factory("ob_tran", new ob_tran_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/ocea.hpp b/boost/geometry/srs/projections/proj/ocea.hpp index 4b8da5be6e..f8dd4c4ed1 100644 --- a/boost/geometry/srs/projections/proj/ocea.hpp +++ b/boost/geometry/srs/projections/proj/ocea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct ocea {}; + struct ocea {}; // Oblique Cylindrical Equal Area }} //namespace srs::par4 @@ -74,45 +73,38 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_ocea_spheroid : public base_t_fi<base_ocea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_ocea_spheroid + : public base_t_fi<base_ocea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_ocea<CalculationType> m_proj_parm; + par_ocea<T> m_proj_parm; inline base_ocea_spheroid(const Parameters& par) - : base_t_fi<base_ocea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_ocea_spheroid<T, Parameters>, + T, Parameters>(*this, par) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const T pi = detail::pi<T>(); - CalculationType t; + T t; xy_y = sin(lp_lon); - /* - xy_x = atan2((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) , cos(lp_lon)); - */ t = cos(lp_lon); xy_x = atan((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) / t); if (t < 0.) - xy_x += ONEPI; + xy_x += pi; xy_x *= this->m_proj_parm.rtk; xy_y = this->m_proj_parm.rok * (this->m_proj_parm.sinphi * sin(lp_lat) - this->m_proj_parm.cosphi * cos(lp_lat) * xy_y); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType t, s; + T t, s; xy_y /= this->m_proj_parm.rok; xy_x /= this->m_proj_parm.rtk; @@ -133,31 +125,42 @@ namespace projections template <typename Parameters, typename T> inline void setup_ocea(Parameters& par, par_ocea<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; proj_parm.rok = 1. / par.k0; proj_parm.rtk = par.k0; - if ( pj_param(par.params, "talpha").i) { - alpha = pj_param(par.params, "ralpha").f; - lonz = pj_param(par.params, "rlonc").f; + /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/ + if ( pj_param_r(par.params, "alpha", alpha)) { + /*Define Pole of oblique transformation from 1 point & 1 azimuth*/ + //alpha = pj_get_param_r(par.params, "alpha"); // set above + lonz = pj_get_param_r(par.params, "lonc"); + /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ proj_parm.singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; + /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ proj_parm.sinphi = asin(cos(phi_0) * sin(alpha)); + /*If the keyword "alpha" is NOT found in the sentence then use 2points*/ } else { - phi_1 = pj_param(par.params, "rlat_1").f; - phi_2 = pj_param(par.params, "rlat_2").f; - lam_1 = pj_param(par.params, "rlon_1").f; - lam_2 = pj_param(par.params, "rlon_2").f; + /*Define Pole of oblique transformation from 2 points*/ + phi_1 = pj_get_param_r(par.params, "lat_1"); + phi_2 = pj_get_param_r(par.params, "lat_2"); + lam_1 = pj_get_param_r(par.params, "lon_1"); + lam_2 = pj_get_param_r(par.params, "lon_2"); + /*Equation 9-1 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ proj_parm.singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - sin(phi_1) * cos(phi_2) * cos(lam_2), sin(phi_1) * cos(phi_2) * sin(lam_2) - cos(phi_1) * sin(phi_2) * sin(lam_1) ); - if (lam_1 == -HALFPI) + + /* take care of P->lam0 wrap-around when +lam_1=-90*/ + if (lam_1 == -half_pi) proj_parm.singam = -proj_parm.singam; + + /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ proj_parm.sinphi = atan(-cos(proj_parm.singam - lam_1) / tan(phi_1)); } - par.lam0 = proj_parm.singam + HALFPI; + par.lam0 = proj_parm.singam + half_pi; proj_parm.cosphi = cos(proj_parm.sinphi); proj_parm.sinphi = sin(proj_parm.sinphi); proj_parm.cosgam = cos(proj_parm.singam); @@ -187,10 +190,10 @@ namespace projections \par Example \image html ex_ocea.gif */ - template <typename CalculationType, typename Parameters> - struct ocea_spheroid : public detail::ocea::base_ocea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ocea_spheroid : public detail::ocea::base_ocea_spheroid<T, Parameters> { - inline ocea_spheroid(const Parameters& par) : detail::ocea::base_ocea_spheroid<CalculationType, Parameters>(par) + inline ocea_spheroid(const Parameters& par) : detail::ocea::base_ocea_spheroid<T, Parameters>(par) { detail::ocea::setup_ocea(this->m_par, this->m_proj_parm); } @@ -204,20 +207,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ocea, ocea_spheroid, ocea_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class ocea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class ocea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<ocea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<ocea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void ocea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void ocea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("ocea", new ocea_entry<CalculationType, Parameters>); + factory.add_to_factory("ocea", new ocea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/oea.hpp b/boost/geometry/srs/projections/proj/oea.hpp index 469a41a2d5..24840ea1d6 100644 --- a/boost/geometry/srs/projections/proj/oea.hpp +++ b/boost/geometry/srs/projections/proj/oea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_OEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_OEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_OEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OEA_HPP + #include <boost/math/special_functions/hypot.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct oea {}; + struct oea {}; // Oblated Equal Area }} //namespace srs::par4 @@ -73,25 +72,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_oea_spheroid : public base_t_fi<base_oea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_oea_spheroid + : public base_t_fi<base_oea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_oea<CalculationType> m_proj_parm; + par_oea<T> m_proj_parm; inline base_oea_spheroid(const Parameters& par) - : base_t_fi<base_oea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_oea_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType Az, M, N, cp, sp, cl, shz; + T Az, M, N, cp, sp, cl, shz; cp = cos(lp_lat); sp = sin(lp_lat); @@ -106,9 +101,9 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType N, M, xp, yp, z, Az, cz, sz, cAz; + T N, M, xp, yp, z, Az, cz, sz, cAz; N = this->m_proj_parm.hn * aasin(xy_y * this->m_proj_parm.rn); M = this->m_proj_parm.hm * aasin(xy_x * this->m_proj_parm.rm * cos(N * this->m_proj_parm.two_r_n) / cos(N)); @@ -134,11 +129,11 @@ namespace projections template <typename Parameters, typename T> inline void setup_oea(Parameters& par, par_oea<T>& proj_parm) { - if (((proj_parm.n = pj_param(par.params, "dn").f) <= 0.) || - ((proj_parm.m = pj_param(par.params, "dm").f) <= 0.)) - BOOST_THROW_EXCEPTION( projection_exception(-39) ); - else { - proj_parm.theta = pj_param(par.params, "rtheta").f; + if (((proj_parm.n = pj_get_param_f(par.params, "n")) <= 0.) || + ((proj_parm.m = pj_get_param_f(par.params, "m")) <= 0.)) { + BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) ); + } else { + proj_parm.theta = pj_get_param_r(par.params, "theta"); proj_parm.sp0 = sin(par.phi0); proj_parm.cp0 = cos(par.phi0); proj_parm.rn = 1./ proj_parm.n; @@ -170,10 +165,10 @@ namespace projections \par Example \image html ex_oea.gif */ - template <typename CalculationType, typename Parameters> - struct oea_spheroid : public detail::oea::base_oea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct oea_spheroid : public detail::oea::base_oea_spheroid<T, Parameters> { - inline oea_spheroid(const Parameters& par) : detail::oea::base_oea_spheroid<CalculationType, Parameters>(par) + inline oea_spheroid(const Parameters& par) : detail::oea::base_oea_spheroid<T, Parameters>(par) { detail::oea::setup_oea(this->m_par, this->m_proj_parm); } @@ -187,20 +182,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::oea, oea_spheroid, oea_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class oea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class oea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<oea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<oea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void oea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void oea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("oea", new oea_entry<CalculationType, Parameters>); + factory.add_to_factory("oea", new oea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/omerc.hpp b/boost/geometry/srs/projections/proj/omerc.hpp index 4da6871d13..a4448d182d 100644 --- a/boost/geometry/srs/projections/proj/omerc.hpp +++ b/boost/geometry/srs/projections/proj/omerc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -43,6 +39,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -57,7 +56,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct omerc {}; + struct omerc {}; // Oblique Mercator }} //namespace srs::par4 @@ -66,9 +65,6 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace omerc { - static const double TOL = 1.e-7; - static const double EPS = 1.e-10; - template <typename T> struct par_omerc { @@ -77,45 +73,45 @@ namespace projections int no_rot; }; + static const double tolerance = 1.e-7; + static const double epsilon = 1.e-10; + // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_omerc_ellipsoid : public base_t_fi<base_omerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_omerc_ellipsoid + : public base_t_fi<base_omerc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_omerc<CalculationType> m_proj_parm; + par_omerc<T> m_proj_parm; inline base_omerc_ellipsoid(const Parameters& par) - : base_t_fi<base_omerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_omerc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType Q, S, T, U, V, temp, u, v; + T s, t, U, V, W, temp, u, v; - if (fabs(fabs(lp_lat) - HALFPI) > EPS) { - Q = this->m_proj_parm.E / pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.B); - temp = 1. / Q; - S = .5 * (Q - temp); - T = .5 * (Q + temp); + if (fabs(fabs(lp_lat) - half_pi) > epsilon) { + W = this->m_proj_parm.E / math::pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.B); + temp = 1. / W; + s = .5 * (W - temp); + t = .5 * (W + temp); V = sin(this->m_proj_parm.B * lp_lon); - U = (S * this->m_proj_parm.singam - V * this->m_proj_parm.cosgam) / T; - if (fabs(fabs(U) - 1.0) < EPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + U = (s * this->m_proj_parm.singam - V * this->m_proj_parm.cosgam) / t; + if (fabs(fabs(U) - 1.0) < epsilon) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } v = 0.5 * this->m_proj_parm.ArB * log((1. - U)/(1. + U)); temp = cos(this->m_proj_parm.B * lp_lon); - if(fabs(temp) < TOL) { - u = this->m_proj_parm.A * lp_lon; - } else { - u = this->m_proj_parm.ArB * atan2((S * this->m_proj_parm.cosgam + V * this->m_proj_parm.singam), temp); - } + if(fabs(temp) < tolerance) { + u = this->m_proj_parm.A * lp_lon; + } else { + u = this->m_proj_parm.ArB * atan2((s * this->m_proj_parm.cosgam + V * this->m_proj_parm.singam), temp); + } } else { v = lp_lat > 0 ? this->m_proj_parm.v_pole_n : this->m_proj_parm.v_pole_s; u = this->m_proj_parm.ArB * lp_lat; @@ -132,11 +128,11 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType u, v, Qp, Sp, Tp, Vp, Up; + T u, v, Qp, Sp, Tp, Vp, Up; if (this->m_proj_parm.no_rot) { v = xy_y; @@ -150,13 +146,14 @@ namespace projections Tp = .5 * (Qp + 1. / Qp); Vp = sin(this->m_proj_parm.BrA * u); Up = (Vp * this->m_proj_parm.cosgam + Sp * this->m_proj_parm.singam) / Tp; - if (fabs(fabs(Up) - 1.) < EPS) { + if (fabs(fabs(Up) - 1.) < epsilon) { lp_lon = 0.; - lp_lat = Up < 0. ? -HALFPI : HALFPI; + lp_lat = Up < 0. ? -half_pi : half_pi; } else { lp_lat = this->m_proj_parm.E / sqrt((1. + Up) / (1. - Up)); - if ((lp_lat = pj_phi2(pow(lp_lat, 1. / this->m_proj_parm.B), this->m_par.e)) == HUGE_VAL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((lp_lat = pj_phi2(math::pow(lp_lat, T(1) / this->m_proj_parm.B), this->m_par.e)) == HUGE_VAL) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } lp_lon = - this->m_proj_parm.rB * atan2((Sp * this->m_proj_parm.cosgam - Vp * this->m_proj_parm.singam), cos(this->m_proj_parm.BrA * u)); } @@ -173,47 +170,46 @@ namespace projections template <typename Parameters, typename T> inline void setup_omerc(Parameters& par, par_omerc<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); - static const T ONEPI = detail::ONEPI<T>(); - static const T TWOPI = detail::TWOPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); + static const T two_pi = detail::two_pi<T>(); T con, com, cosph0, D, F, H, L, sinph0, p, J, gamma=0, - gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0.0; + gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0; int alp, gam, no_off = 0; - proj_parm.no_rot = pj_param(par.params, "tno_rot").i; - if ((alp = pj_param(par.params, "talpha").i) != 0) - alpha_c = pj_param(par.params, "ralpha").f; - if ((gam = pj_param(par.params, "tgamma").i) != 0) - gamma = pj_param(par.params, "rgamma").f; + proj_parm.no_rot = pj_get_param_b(par.params, "no_rot"); + alp = pj_param_r(par.params, "alpha", alpha_c); + gam = pj_param_r(par.params, "gamma", gamma); if (alp || gam) { - lamc = pj_param(par.params, "rlonc").f; - no_off = - /* For libproj4 compatability */ - pj_param(par.params, "tno_off").i - /* for backward compatibility */ - || pj_param(par.params, "tno_uoff").i; - if( no_off ) - { - /* Mark the parameter as used, so that the pj_get_def() return them */ - pj_param(par.params, "sno_uoff"); - pj_param(par.params, "sno_off"); - } + lamc = pj_get_param_r(par.params, "lonc"); + // NOTE: This is not needed in Boost.Geometry + //no_off = + // /* For libproj4 compatability */ + // pj_param_exists(par.params, "no_off") + // /* for backward compatibility */ + // || pj_param_exists(par.params, "no_uoff"); + //if( no_off ) + //{ + // /* Mark the parameter as used, so that the pj_get_def() return them */ + // pj_get_param_s(par.params, "no_uoff"); + // pj_get_param_s(par.params, "no_off"); + //} } else { - lam1 = pj_param(par.params, "rlon_1").f; - phi1 = pj_param(par.params, "rlat_1").f; - lam2 = pj_param(par.params, "rlon_2").f; - phi2 = pj_param(par.params, "rlat_2").f; - if (fabs(phi1 - phi2) <= TOL || - (con = fabs(phi1)) <= TOL || - fabs(con - HALFPI) <= TOL || - fabs(fabs(par.phi0) - HALFPI) <= TOL || - fabs(fabs(phi2) - HALFPI) <= TOL) - BOOST_THROW_EXCEPTION( projection_exception(-33) ); + lam1 = pj_get_param_r(par.params, "lon_1"); + phi1 = pj_get_param_r(par.params, "lat_1"); + lam2 = pj_get_param_r(par.params, "lon_2"); + phi2 = pj_get_param_r(par.params, "lat_2"); + if (fabs(phi1 - phi2) <= tolerance || + (con = fabs(phi1)) <= tolerance || + fabs(con - half_pi) <= tolerance || + fabs(fabs(par.phi0) - half_pi) <= tolerance || + fabs(fabs(phi2) - half_pi) <= tolerance) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_or_alpha_eq_90) ); } com = sqrt(par.one_es); - if (fabs(par.phi0) > EPS) { + if (fabs(par.phi0) > epsilon) { sinph0 = sin(par.phi0); cosph0 = cos(par.phi0); con = 1. - par.es * sinph0 * sinph0; @@ -229,7 +225,7 @@ namespace projections F = -F; } proj_parm.E = F += D; - proj_parm.E *= pow(pj_tsfn(par.phi0, sinph0, par.e), proj_parm.B); + proj_parm.E *= math::pow(pj_tsfn(par.phi0, sinph0, par.e), proj_parm.B); } else { proj_parm.B = 1. / com; proj_parm.A = par.k0; @@ -237,33 +233,29 @@ namespace projections } if (alp || gam) { if (alp) { - gamma0 = asin(sin(alpha_c) / D); + gamma0 = aasin(sin(alpha_c) / D); if (!gam) gamma = alpha_c; } else - alpha_c = asin(D*sin(gamma0 = gamma)); - if ((con = fabs(alpha_c)) <= TOL || - fabs(con - ONEPI) <= TOL || - fabs(fabs(par.phi0) - HALFPI) <= TOL) - BOOST_THROW_EXCEPTION( projection_exception(-32) ); - par.lam0 = lamc - asin(.5 * (F - 1. / F) * + alpha_c = aasin(D*sin(gamma0 = gamma)); + par.lam0 = lamc - aasin(.5 * (F - 1. / F) * tan(gamma0)) / proj_parm.B; } else { - H = pow(pj_tsfn(phi1, sin(phi1), par.e), proj_parm.B); - L = pow(pj_tsfn(phi2, sin(phi2), par.e), proj_parm.B); + H = math::pow(pj_tsfn(phi1, sin(phi1), par.e), proj_parm.B); + L = math::pow(pj_tsfn(phi2, sin(phi2), par.e), proj_parm.B); F = proj_parm.E / H; p = (L - H) / (L + H); J = proj_parm.E * proj_parm.E; J = (J - L * H) / (J + L * H); - if ((con = lam1 - lam2) < -ONEPI) - lam2 -= TWOPI; - else if (con > ONEPI) - lam2 += TWOPI; + if ((con = lam1 - lam2) < -pi) + lam2 -= two_pi; + else if (con > pi) + lam2 += two_pi; par.lam0 = adjlon(.5 * (lam1 + lam2) - atan( J * tan(.5 * proj_parm.B * (lam1 - lam2)) / p) / proj_parm.B); gamma0 = atan(2. * sin(proj_parm.B * adjlon(lam1 - par.lam0)) / (F - 1. / F)); - gamma = alpha_c = asin(D * sin(gamma0)); + gamma = alpha_c = aasin(D * sin(gamma0)); } proj_parm.singam = sin(gamma0); proj_parm.cosgam = cos(gamma0); @@ -274,13 +266,13 @@ namespace projections if (no_off) proj_parm.u_0 = 0; else { - proj_parm.u_0 = fabs(proj_parm.ArB * atan2(sqrt(D * D - 1.), cos(alpha_c))); + proj_parm.u_0 = fabs(proj_parm.ArB * atan(sqrt(D * D - 1.) / cos(alpha_c))); if (par.phi0 < 0.) proj_parm.u_0 = - proj_parm.u_0; } F = 0.5 * gamma0; - proj_parm.v_pole_n = proj_parm.ArB * log(tan(FORTPI - F)); - proj_parm.v_pole_s = proj_parm.ArB * log(tan(FORTPI + F)); + proj_parm.v_pole_n = proj_parm.ArB * log(tan(fourth_pi - F)); + proj_parm.v_pole_s = proj_parm.ArB * log(tan(fourth_pi + F)); } }} // namespace detail::omerc @@ -310,10 +302,10 @@ namespace projections \par Example \image html ex_omerc.gif */ - template <typename CalculationType, typename Parameters> - struct omerc_ellipsoid : public detail::omerc::base_omerc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct omerc_ellipsoid : public detail::omerc::base_omerc_ellipsoid<T, Parameters> { - inline omerc_ellipsoid(const Parameters& par) : detail::omerc::base_omerc_ellipsoid<CalculationType, Parameters>(par) + inline omerc_ellipsoid(const Parameters& par) : detail::omerc::base_omerc_ellipsoid<T, Parameters>(par) { detail::omerc::setup_omerc(this->m_par, this->m_proj_parm); } @@ -327,20 +319,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::omerc, omerc_ellipsoid, omerc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class omerc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class omerc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<omerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<omerc_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void omerc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void omerc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("omerc", new omerc_entry<CalculationType, Parameters>); + factory.add_to_factory("omerc", new omerc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/ortho.hpp b/boost/geometry/srs/projections/proj/ortho.hpp index 4510f9dab9..370af50f70 100644 --- a/boost/geometry/srs/projections/proj/ortho.hpp +++ b/boost/geometry/srs/projections/proj/ortho.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP + #include <boost/config.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -55,7 +54,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct ortho {}; + struct ortho {}; // Orthographic }} //namespace srs::par4 @@ -65,63 +64,65 @@ namespace projections namespace detail { namespace ortho { - static const double EPS10 = 1.e-10; - static const int N_POLE = 0; - static const int S_POLE = 1; - static const int EQUIT = 2; - static const int OBLIQ = 3; + enum mode_type { + n_pole = 0, + s_pole = 1, + equit = 2, + obliq = 3 + }; template <typename T> struct par_ortho { T sinph0; T cosph0; - int mode; + mode_type mode; }; + static const double epsilon10 = 1.e-10; + // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_ortho_spheroid : public base_t_fi<base_ortho_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_ortho_spheroid + : public base_t_fi<base_ortho_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_ortho<CalculationType> m_proj_parm; + par_ortho<T> m_proj_parm; inline base_ortho_spheroid(const Parameters& par) - : base_t_fi<base_ortho_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_ortho_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType coslam, cosphi, sinphi; + T coslam, cosphi, sinphi; cosphi = cos(lp_lat); coslam = cos(lp_lon); switch (this->m_proj_parm.mode) { - case EQUIT: - if (cosphi * coslam < - EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + case equit: + if (cosphi * coslam < - epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_y = sin(lp_lat); break; - case OBLIQ: + case obliq: if (this->m_proj_parm.sinph0 * (sinphi = sin(lp_lat)) + - this->m_proj_parm.cosph0 * cosphi * coslam < - EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + this->m_proj_parm.cosph0 * cosphi * coslam < - epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_y = this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam; break; - case N_POLE: + case n_pole: coslam = - coslam; BOOST_FALLTHROUGH; - case S_POLE: - if (fabs(lp_lat - this->m_par.phi0) - EPS10 > HALFPI) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + case s_pole: + if (fabs(lp_lat - this->m_par.phi0) - epsilon10 > half_pi) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_y = cosphi * coslam; break; } @@ -130,48 +131,49 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType rh, cosc, sinc; + T rh, cosc, sinc; if ((sinc = (rh = boost::math::hypot(xy_x, xy_y))) > 1.) { - if ((sinc - 1.) > EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((sinc - 1.) > epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } sinc = 1.; } cosc = sqrt(1. - sinc * sinc); /* in this range OK */ - if (fabs(rh) <= EPS10) { + if (fabs(rh) <= epsilon10) { lp_lat = this->m_par.phi0; lp_lon = 0.0; } else { switch (this->m_proj_parm.mode) { - case N_POLE: + case n_pole: xy_y = -xy_y; lp_lat = acos(sinc); break; - case S_POLE: + case s_pole: lp_lat = - acos(sinc); break; - case EQUIT: + case equit: lp_lat = xy_y * sinc / rh; xy_x *= sinc; xy_y = cosc * rh; goto sinchk; - case OBLIQ: + case obliq: lp_lat = cosc * this->m_proj_parm.sinph0 + xy_y * sinc * this->m_proj_parm.cosph0 /rh; xy_y = (cosc - this->m_proj_parm.sinph0 * lp_lat) * rh; xy_x *= sinc * this->m_proj_parm.cosph0; sinchk: if (fabs(lp_lat) >= 1.) - lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + lp_lat = lp_lat < 0. ? -half_pi : half_pi; else lp_lat = asin(lp_lat); break; } - lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT)) - ? (xy_x == 0. ? 0. : xy_x < 0. ? -HALFPI : HALFPI) + lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit)) + ? (xy_x == 0. ? 0. : xy_x < 0. ? -half_pi : half_pi) : atan2(xy_x, xy_y); } } @@ -187,14 +189,14 @@ namespace projections template <typename Parameters, typename T> inline void setup_ortho(Parameters& par, par_ortho<T>& proj_parm) { - if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) <= EPS10) - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; - else if (fabs(par.phi0) > EPS10) { - proj_parm.mode = OBLIQ; + if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) <= epsilon10) + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; + else if (fabs(par.phi0) > epsilon10) { + proj_parm.mode = obliq; proj_parm.sinph0 = sin(par.phi0); proj_parm.cosph0 = cos(par.phi0); } else - proj_parm.mode = EQUIT; + proj_parm.mode = equit; par.es = 0.; } @@ -213,10 +215,10 @@ namespace projections \par Example \image html ex_ortho.gif */ - template <typename CalculationType, typename Parameters> - struct ortho_spheroid : public detail::ortho::base_ortho_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ortho_spheroid : public detail::ortho::base_ortho_spheroid<T, Parameters> { - inline ortho_spheroid(const Parameters& par) : detail::ortho::base_ortho_spheroid<CalculationType, Parameters>(par) + inline ortho_spheroid(const Parameters& par) : detail::ortho::base_ortho_spheroid<T, Parameters>(par) { detail::ortho::setup_ortho(this->m_par, this->m_proj_parm); } @@ -230,20 +232,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ortho, ortho_spheroid, ortho_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class ortho_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class ortho_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<ortho_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<ortho_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void ortho_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void ortho_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("ortho", new ortho_entry<CalculationType, Parameters>); + factory.add_to_factory("ortho", new ortho_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/poly.hpp b/boost/geometry/srs/projections/proj/poly.hpp index ff97ecadec..95da13f0d7 100644 --- a/boost/geometry/srs/projections/proj/poly.hpp +++ b/boost/geometry/srs/projections/proj/poly.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_POLY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_POLY_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_POLY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_POLY_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct poly {}; + struct poly {}; // Polyconic (American) }} //namespace srs::par4 @@ -63,44 +62,42 @@ namespace projections namespace detail { namespace poly { - static const double TOL = 1e-10; - static const double CONV = 1e-10; - static const int N_ITER = 10; - static const int I_ITER = 20; - static const double ITOL = 1.e-12; + static const double tolerance = 1e-10; + static const double conv_tolerance = 1e-10; + static const int n_iter = 10; + static const int i_iter = 20; + static const double i_tolerance = 1.e-12; template <typename T> struct par_poly { T ml0; - T en[EN_SIZE]; + detail::en<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_poly_ellipsoid : public base_t_fi<base_poly_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_poly_ellipsoid + : public base_t_fi<base_poly_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_poly<CalculationType> m_proj_parm; + par_poly<T> m_proj_parm; inline base_poly_ellipsoid(const Parameters& par) - : base_t_fi<base_poly_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_poly_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType ms, sp, cp; + T ms, sp, cp; - if (fabs(lp_lat) <= TOL) { xy_x = lp_lon; xy_y = -this->m_proj_parm.ml0; } - else { + if (fabs(lp_lat) <= tolerance) { + xy_x = lp_lon; + xy_y = -this->m_proj_parm.ml0; + } else { sp = sin(lp_lat); - ms = fabs(cp = cos(lp_lat)) > TOL ? pj_msfn(sp, cp, this->m_par.es) / sp : 0.; + ms = fabs(cp = cos(lp_lat)) > tolerance ? pj_msfn(sp, cp, this->m_par.es) / sp : 0.; xy_x = ms * sin(lp_lon *= sp); xy_y = (pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.ml0) + ms * (1. - cos(lp_lon)); } @@ -108,22 +105,23 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { xy_y += this->m_proj_parm.ml0; - if (fabs(xy_y) <= TOL) { + if (fabs(xy_y) <= tolerance) { lp_lon = xy_x; lp_lat = 0.; } else { - CalculationType r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi; + T r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi; int i; r = xy_y * xy_y + xy_x * xy_x; - for (lp_lat = xy_y, i = I_ITER; i ; --i) { + for (lp_lat = xy_y, i = i_iter; i ; --i) { sp = sin(lp_lat); s2ph = sp * ( cp = cos(lp_lat)); - if (fabs(cp) < ITOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(cp) < i_tolerance) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } c = sp * (mlp = sqrt(1. - this->m_par.es * sp * sp)) / cp; ml = pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en); mlb = ml * ml + r; @@ -132,11 +130,12 @@ namespace projections ( ml + ml + c * mlb - 2. * xy_y * (c * ml + 1.) ) / ( this->m_par.es * s2ph * (mlb - 2. * xy_y * ml) / c + 2.* (xy_y - ml) * (c * mlp - 1. / s2ph) - mlp - mlp )); - if (fabs(dPhi) <= ITOL) + if (fabs(dPhi) <= i_tolerance) break; } - if (!i) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (!i) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } c = sin(lp_lat); lp_lon = asin(xy_x * tan(lp_lat) * sqrt(1. - this->m_par.es * c * c)) / sin(lp_lat); } @@ -150,27 +149,23 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_poly_spheroid : public base_t_fi<base_poly_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_poly_spheroid + : public base_t_fi<base_poly_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_poly<CalculationType> m_proj_parm; + par_poly<T> m_proj_parm; inline base_poly_spheroid(const Parameters& par) - : base_t_fi<base_poly_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_poly_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType cot, E; + T cot, E; - if (fabs(lp_lat) <= TOL) { + if (fabs(lp_lat) <= tolerance) { xy_x = lp_lon; xy_y = this->m_proj_parm.ml0; } else { @@ -182,26 +177,27 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType B, dphi, tp; + T B, dphi, tp; int i; - if (fabs(xy_y = this->m_par.phi0 + xy_y) <= TOL) { + if (fabs(xy_y = this->m_par.phi0 + xy_y) <= tolerance) { lp_lon = xy_x; lp_lat = 0.; } else { lp_lat = xy_y; B = xy_x * xy_x + xy_y * xy_y; - i = N_ITER; + i = n_iter; do { tp = tan(lp_lat); lp_lat -= (dphi = (xy_y * (lp_lat * tp + 1.) - lp_lat - .5 * ( lp_lat * lp_lat + B) * tp) / ((lp_lat - xy_y) / tp - 1.)); - } while (fabs(dphi) > CONV && --i); - if (! i) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + } while (fabs(dphi) > conv_tolerance && --i); + if (! i) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } lp_lon = asin(xy_x * tan(lp_lat)) / sin(lp_lat); } } @@ -217,9 +213,8 @@ namespace projections template <typename Parameters, typename T> inline void setup_poly(Parameters& par, par_poly<T>& proj_parm) { - if (par.es) { - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + if (par.es != 0.0) { + proj_parm.en = pj_enfn<T>(par.es); proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en); } else { proj_parm.ml0 = -par.phi0; @@ -242,10 +237,10 @@ namespace projections \par Example \image html ex_poly.gif */ - template <typename CalculationType, typename Parameters> - struct poly_ellipsoid : public detail::poly::base_poly_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct poly_ellipsoid : public detail::poly::base_poly_ellipsoid<T, Parameters> { - inline poly_ellipsoid(const Parameters& par) : detail::poly::base_poly_ellipsoid<CalculationType, Parameters>(par) + inline poly_ellipsoid(const Parameters& par) : detail::poly::base_poly_ellipsoid<T, Parameters>(par) { detail::poly::setup_poly(this->m_par, this->m_proj_parm); } @@ -264,10 +259,10 @@ namespace projections \par Example \image html ex_poly.gif */ - template <typename CalculationType, typename Parameters> - struct poly_spheroid : public detail::poly::base_poly_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct poly_spheroid : public detail::poly::base_poly_spheroid<T, Parameters> { - inline poly_spheroid(const Parameters& par) : detail::poly::base_poly_spheroid<CalculationType, Parameters>(par) + inline poly_spheroid(const Parameters& par) : detail::poly::base_poly_spheroid<T, Parameters>(par) { detail::poly::setup_poly(this->m_par, this->m_proj_parm); } @@ -281,23 +276,23 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::poly, poly_spheroid, poly_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class poly_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class poly_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<poly_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<poly_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<poly_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<poly_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void poly_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void poly_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("poly", new poly_entry<CalculationType, Parameters>); + factory.add_to_factory("poly", new poly_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/putp2.hpp b/boost/geometry/srs/projections/proj/putp2.hpp index 458ee81aa3..181afe5086 100644 --- a/boost/geometry/srs/projections/proj/putp2.hpp +++ b/boost/geometry/srs/projections/proj/putp2.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP -#define BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct putp2 {}; + struct putp2 {}; // Putnins P2 }} //namespace srs::par4 @@ -65,55 +64,51 @@ namespace projections static const double C_x = 1.89490; static const double C_y = 1.71848; static const double C_p = 0.6141848493043784; - static const double EPS = 1e-10; - static const int NITER = 10; - //static const double PI_DIV_3 = 1.0471975511965977; + static const double epsilon = 1e-10; + static const int n_iter = 10; + //static const double third_pi = 1.0471975511965977; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_putp2_spheroid : public base_t_fi<base_putp2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_putp2_spheroid + : public base_t_fi<base_putp2_spheroid<T, Parameters>, T, Parameters> { - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_putp2_spheroid(const Parameters& par) - : base_t_fi<base_putp2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_putp2_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType PI_DIV_3 = detail::PI_DIV_3<CalculationType>(); + static const T third_pi = detail::third_pi<T>(); - CalculationType p, c, s, V; + T p, c, s, V; int i; p = C_p * sin(lp_lat); s = lp_lat * lp_lat; lp_lat *= 0.615709 + s * ( 0.00909953 + s * 0.0046292 ); - for (i = NITER; i ; --i) { + for (i = n_iter; i ; --i) { c = cos(lp_lat); s = sin(lp_lat); lp_lat -= V = (lp_lat + s * (c - 1.) - p) / (1. + c * (c - 1.) - s * s); - if (fabs(V) < EPS) + if (fabs(V) < epsilon) break; } if (!i) - lp_lat = lp_lat < 0 ? - PI_DIV_3 : PI_DIV_3; + lp_lat = lp_lat < 0 ? - third_pi : third_pi; xy_x = C_x * lp_lon * (cos(lp_lat) - 0.5); xy_y = C_y * sin(lp_lat); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType c; + T c; lp_lat = aasin(xy_y / C_y); lp_lon = xy_x / (C_x * ((c = cos(lp_lat)) - 0.5)); @@ -149,10 +144,10 @@ namespace projections \par Example \image html ex_putp2.gif */ - template <typename CalculationType, typename Parameters> - struct putp2_spheroid : public detail::putp2::base_putp2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp2_spheroid : public detail::putp2::base_putp2_spheroid<T, Parameters> { - inline putp2_spheroid(const Parameters& par) : detail::putp2::base_putp2_spheroid<CalculationType, Parameters>(par) + inline putp2_spheroid(const Parameters& par) : detail::putp2::base_putp2_spheroid<T, Parameters>(par) { detail::putp2::setup_putp2(this->m_par); } @@ -166,20 +161,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp2, putp2_spheroid, putp2_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class putp2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void putp2_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void putp2_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("putp2", new putp2_entry<CalculationType, Parameters>); + factory.add_to_factory("putp2", new putp2_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/putp3.hpp b/boost/geometry/srs/projections/proj/putp3.hpp index 91150082b8..aac6d04f2d 100644 --- a/boost/geometry/srs/projections/proj/putp3.hpp +++ b/boost/geometry/srs/projections/proj/putp3.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP -#define BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,7 +37,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include <boost/core/ignore_unused.hpp> +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> @@ -53,8 +50,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct putp3 {}; - struct putp3p {}; + struct putp3 {}; // Putnins P3 + struct putp3p {}; // Putnins P3' }} //namespace srs::par4 @@ -74,23 +71,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_putp3_spheroid : public base_t_fi<base_putp3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_putp3_spheroid + : public base_t_fi<base_putp3_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_putp3<CalculationType> m_proj_parm; + par_putp3<T> m_proj_parm; inline base_putp3_spheroid(const Parameters& par) - : base_t_fi<base_putp3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_putp3_spheroid<T, Parameters>, + T, Parameters>(*this, par) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = C * lp_lon * (1. - this->m_proj_parm.A * lp_lat * lp_lat); xy_y = C * lp_lat; @@ -98,7 +91,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C; lp_lon = xy_x / (C * (1. - this->m_proj_parm.A * lp_lat * lp_lat)); @@ -111,20 +104,14 @@ namespace projections }; - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_putp3<T>& proj_parm) - { - boost::ignore_unused(proj_parm); - par.es = 0.; - } - // Putnins P3 template <typename Parameters, typename T> inline void setup_putp3(Parameters& par, par_putp3<T>& proj_parm) { proj_parm.A = 4. * RPISQ; - setup(par, proj_parm); + + par.es = 0.; } // Putnins P3' @@ -132,7 +119,8 @@ namespace projections inline void setup_putp3p(Parameters& par, par_putp3<T>& proj_parm) { proj_parm.A = 2. * RPISQ; - setup(par, proj_parm); + + par.es = 0.; } }} // namespace detail::putp3 @@ -150,10 +138,10 @@ namespace projections \par Example \image html ex_putp3.gif */ - template <typename CalculationType, typename Parameters> - struct putp3_spheroid : public detail::putp3::base_putp3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp3_spheroid : public detail::putp3::base_putp3_spheroid<T, Parameters> { - inline putp3_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<CalculationType, Parameters>(par) + inline putp3_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<T, Parameters>(par) { detail::putp3::setup_putp3(this->m_par, this->m_proj_parm); } @@ -171,10 +159,10 @@ namespace projections \par Example \image html ex_putp3p.gif */ - template <typename CalculationType, typename Parameters> - struct putp3p_spheroid : public detail::putp3::base_putp3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp3p_spheroid : public detail::putp3::base_putp3_spheroid<T, Parameters> { - inline putp3p_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<CalculationType, Parameters>(par) + inline putp3p_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<T, Parameters>(par) { detail::putp3::setup_putp3p(this->m_par, this->m_proj_parm); } @@ -189,31 +177,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp3p, putp3p_spheroid, putp3p_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class putp3_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp3_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp3_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class putp3p_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp3p_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp3p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp3p_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void putp3_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void putp3_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("putp3", new putp3_entry<CalculationType, Parameters>); - factory.add_to_factory("putp3p", new putp3p_entry<CalculationType, Parameters>); + factory.add_to_factory("putp3", new putp3_entry<T, Parameters>); + factory.add_to_factory("putp3p", new putp3p_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/putp4p.hpp b/boost/geometry/srs/projections/proj/putp4p.hpp index 4252b37141..899278eba8 100644 --- a/boost/geometry/srs/projections/proj/putp4p.hpp +++ b/boost/geometry/srs/projections/proj/putp4p.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP -#define BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,7 +37,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include <boost/core/ignore_unused.hpp> +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> @@ -54,8 +51,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct putp4p {}; - struct weren {}; + struct putp4p {}; // Putnins P4' + struct weren {}; // Werenskiold I }} //namespace srs::par4 @@ -71,33 +68,31 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_putp4p_spheroid : public base_t_fi<base_putp4p_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_putp4p_spheroid + : public base_t_fi<base_putp4p_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_putp4p<CalculationType> m_proj_parm; + par_putp4p<T> m_proj_parm; inline base_putp4p_spheroid(const Parameters& par) - : base_t_fi<base_putp4p_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_putp4p_spheroid<T, Parameters>, + T, Parameters>(*this, par) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { + static T const third = detail::third<T>(); + lp_lat = aasin(0.883883476 * sin(lp_lat)); xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); - xy_x /= cos(lp_lat *= 0.333333333333333); + xy_x /= cos(lp_lat *= third); xy_y = this->m_proj_parm.C_y * sin(lp_lat); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = aasin(xy_y / this->m_proj_parm.C_y); lp_lon = xy_x * cos(lp_lat) / this->m_proj_parm.C_x; @@ -113,13 +108,6 @@ namespace projections }; - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_putp4p<T>& proj_parm) - { - boost::ignore_unused(proj_parm); - par.es = 0.; - } - // Putnins P4' template <typename Parameters, typename T> @@ -127,7 +115,8 @@ namespace projections { proj_parm.C_x = 0.874038744; proj_parm.C_y = 3.883251825; - setup(par, proj_parm); + + par.es = 0.; } // Werenskiold I @@ -136,7 +125,8 @@ namespace projections { proj_parm.C_x = 1.; proj_parm.C_y = 4.442882938; - setup(par, proj_parm); + + par.es = 0.; } }} // namespace detail::putp4p @@ -154,10 +144,10 @@ namespace projections \par Example \image html ex_putp4p.gif */ - template <typename CalculationType, typename Parameters> - struct putp4p_spheroid : public detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp4p_spheroid : public detail::putp4p::base_putp4p_spheroid<T, Parameters> { - inline putp4p_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters>(par) + inline putp4p_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<T, Parameters>(par) { detail::putp4p::setup_putp4p(this->m_par, this->m_proj_parm); } @@ -175,10 +165,10 @@ namespace projections \par Example \image html ex_weren.gif */ - template <typename CalculationType, typename Parameters> - struct weren_spheroid : public detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct weren_spheroid : public detail::putp4p::base_putp4p_spheroid<T, Parameters> { - inline weren_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters>(par) + inline weren_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<T, Parameters>(par) { detail::putp4p::setup_weren(this->m_par, this->m_proj_parm); } @@ -193,31 +183,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::weren, weren_spheroid, weren_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class putp4p_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp4p_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp4p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp4p_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class weren_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class weren_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<weren_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<weren_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void putp4p_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void putp4p_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("putp4p", new putp4p_entry<CalculationType, Parameters>); - factory.add_to_factory("weren", new weren_entry<CalculationType, Parameters>); + factory.add_to_factory("putp4p", new putp4p_entry<T, Parameters>); + factory.add_to_factory("weren", new weren_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/putp5.hpp b/boost/geometry/srs/projections/proj/putp5.hpp index 652dca5231..de308a8948 100644 --- a/boost/geometry/srs/projections/proj/putp5.hpp +++ b/boost/geometry/srs/projections/proj/putp5.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP -#define BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,7 +37,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include <boost/core/ignore_unused.hpp> +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> @@ -53,8 +50,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct putp5 {}; - struct putp5p {}; + struct putp5 {}; // Putnins P5 + struct putp5p {}; // Putnins P5' }} //namespace srs::par4 @@ -74,23 +71,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_putp5_spheroid : public base_t_fi<base_putp5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_putp5_spheroid + : public base_t_fi<base_putp5_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_putp5<CalculationType> m_proj_parm; + par_putp5<T> m_proj_parm; inline base_putp5_spheroid(const Parameters& par) - : base_t_fi<base_putp5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_putp5_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = C * lp_lon * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat)); xy_y = C * lp_lat; @@ -98,7 +91,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C; lp_lon = xy_x / (C * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat))); @@ -110,14 +103,7 @@ namespace projections } }; - - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_putp5<T>& proj_parm) - { - boost::ignore_unused(proj_parm); - par.es = 0.; - } - + // Putnins P5 template <typename Parameters, typename T> @@ -125,7 +111,8 @@ namespace projections { proj_parm.A = 2.; proj_parm.B = 1.; - setup(par, proj_parm); + + par.es = 0.; } // Putnins P5' @@ -134,7 +121,8 @@ namespace projections { proj_parm.A = 1.5; proj_parm.B = 0.5; - setup(par, proj_parm); + + par.es = 0.; } }} // namespace detail::putp5 @@ -152,10 +140,10 @@ namespace projections \par Example \image html ex_putp5.gif */ - template <typename CalculationType, typename Parameters> - struct putp5_spheroid : public detail::putp5::base_putp5_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp5_spheroid : public detail::putp5::base_putp5_spheroid<T, Parameters> { - inline putp5_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<CalculationType, Parameters>(par) + inline putp5_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<T, Parameters>(par) { detail::putp5::setup_putp5(this->m_par, this->m_proj_parm); } @@ -173,10 +161,10 @@ namespace projections \par Example \image html ex_putp5p.gif */ - template <typename CalculationType, typename Parameters> - struct putp5p_spheroid : public detail::putp5::base_putp5_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp5p_spheroid : public detail::putp5::base_putp5_spheroid<T, Parameters> { - inline putp5p_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<CalculationType, Parameters>(par) + inline putp5p_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<T, Parameters>(par) { detail::putp5::setup_putp5p(this->m_par, this->m_proj_parm); } @@ -191,31 +179,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp5p, putp5p_spheroid, putp5p_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class putp5_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp5_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp5_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class putp5p_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp5p_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp5p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp5p_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void putp5_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void putp5_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("putp5", new putp5_entry<CalculationType, Parameters>); - factory.add_to_factory("putp5p", new putp5p_entry<CalculationType, Parameters>); + factory.add_to_factory("putp5", new putp5_entry<T, Parameters>); + factory.add_to_factory("putp5p", new putp5p_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/putp6.hpp b/boost/geometry/srs/projections/proj/putp6.hpp index 2dff641717..19ca6cc76d 100644 --- a/boost/geometry/srs/projections/proj/putp6.hpp +++ b/boost/geometry/srs/projections/proj/putp6.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP -#define BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,7 +37,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include <boost/core/ignore_unused.hpp> +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> @@ -54,8 +51,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct putp6 {}; - struct putp6p {}; + struct putp6 {}; // Putnins P6 + struct putp6p {}; // Putnins P6' }} //namespace srs::par4 @@ -65,8 +62,8 @@ namespace projections namespace detail { namespace putp6 { - static const double EPS = 1e-10; - static const int NITER = 10; + static const double epsilon = 1e-10; + static const int n_iter = 10; static const double CON_POLE = 1.732050807568877; template <typename T> @@ -76,34 +73,30 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_putp6_spheroid : public base_t_fi<base_putp6_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_putp6_spheroid + : public base_t_fi<base_putp6_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_putp6<CalculationType> m_proj_parm; + par_putp6<T> m_proj_parm; inline base_putp6_spheroid(const Parameters& par) - : base_t_fi<base_putp6_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_putp6_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType p, r, V; + T p, r, V; int i; p = this->m_proj_parm.B * sin(lp_lat); lp_lat *= 1.10265779; - for (i = NITER; i ; --i) { + for (i = n_iter; i ; --i) { r = sqrt(1. + lp_lat * lp_lat); lp_lat -= V = ( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) - p ) / (this->m_proj_parm.A - 2. * r); - if (fabs(V) < EPS) + if (fabs(V) < epsilon) break; } if (!i) @@ -114,9 +107,9 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType r; + T r; lp_lat = xy_y / this->m_proj_parm.C_y; r = sqrt(1. + lp_lat * lp_lat); @@ -130,14 +123,7 @@ namespace projections } }; - - template <typename Parameters, typename T> - inline void setup(Parameters& par, par_putp6<T>& proj_parm) - { - boost::ignore_unused(proj_parm); - par.es = 0.; - } - + // Putnins P6 template <typename Parameters, typename T> @@ -148,7 +134,8 @@ namespace projections proj_parm.A = 4.; proj_parm.B = 2.1471437182129378784; proj_parm.D = 2.; - setup(par, proj_parm); + + par.es = 0.; } // Putnins P6' @@ -160,7 +147,8 @@ namespace projections proj_parm.A = 6.; proj_parm.B = 5.61125; proj_parm.D = 3.; - setup(par, proj_parm); + + par.es = 0.; } }} // namespace detail::putp6 @@ -178,10 +166,10 @@ namespace projections \par Example \image html ex_putp6.gif */ - template <typename CalculationType, typename Parameters> - struct putp6_spheroid : public detail::putp6::base_putp6_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp6_spheroid : public detail::putp6::base_putp6_spheroid<T, Parameters> { - inline putp6_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<CalculationType, Parameters>(par) + inline putp6_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<T, Parameters>(par) { detail::putp6::setup_putp6(this->m_par, this->m_proj_parm); } @@ -199,10 +187,10 @@ namespace projections \par Example \image html ex_putp6p.gif */ - template <typename CalculationType, typename Parameters> - struct putp6p_spheroid : public detail::putp6::base_putp6_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct putp6p_spheroid : public detail::putp6::base_putp6_spheroid<T, Parameters> { - inline putp6p_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<CalculationType, Parameters>(par) + inline putp6p_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<T, Parameters>(par) { detail::putp6::setup_putp6p(this->m_par, this->m_proj_parm); } @@ -217,31 +205,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp6p, putp6p_spheroid, putp6p_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class putp6_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp6_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp6_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class putp6p_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class putp6p_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<putp6p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<putp6p_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void putp6_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void putp6_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("putp6", new putp6_entry<CalculationType, Parameters>); - factory.add_to_factory("putp6p", new putp6p_entry<CalculationType, Parameters>); + factory.add_to_factory("putp6", new putp6_entry<T, Parameters>); + factory.add_to_factory("putp6p", new putp6p_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/qsc.hpp b/boost/geometry/srs/projections/proj/qsc.hpp index 4cccc29f8b..bb31849049 100644 --- a/boost/geometry/srs/projections/proj/qsc.hpp +++ b/boost/geometry/srs/projections/proj/qsc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_QSC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_QSC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,17 +15,37 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: // This implements the Quadrilateralized Spherical Cube (QSC) projection. // Copyright (c) 2011, 2012 Martin Lambers <marlam@marlam.de> + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + // The QSC projection was introduced in: // [OL76] // E.M. O'Neill and R.E. Laubscher, "Extended Studies of a Quadrilateralized // Spherical Cube Earth Data Base", Naval Environmental Prediction Research // Facility Tech. Report NEPRF 3-76 (CSC), May 1976. + // The preceding shift from an ellipsoid to a sphere, which allows to apply // this projection to ellipsoids as used in the Ellipsoidal Cube Map model, // is described in @@ -37,6 +53,7 @@ // M. Lambers and A. Kolb, "Ellipsoidal Cube Maps for Accurate Rendering of // Planetary-Scale Terrain Data", Proc. Pacfic Graphics (Short Papers), Sep. // 2012 + // You have to choose one of the following projection centers, // corresponding to the centers of the six cube faces: // phi0 = 0.0, lam0 = 0.0 ("front" face) @@ -46,32 +63,19 @@ // phi0 = 90.0 ("top" face) // phi0 = -90.0 ("bottom" face) // Other projection centers will not work! + // In the projection code below, each cube face is handled differently. // See the computation of the face parameter in the ENTRY0(qsc) function // and the handling of different face values (FACE_*) in the forward and // inverse projections. + // Furthermore, the projection is originally only defined for theta angles // between (-1/4 * PI) and (+1/4 * PI) on the current cube face. This area // of definition is named AREA_0 in the projection code below. The other // three areas of a cube face are handled by rotation of AREA_0. -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_QSC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_QSC_HPP #include <boost/core/ignore_unused.hpp> #include <boost/geometry/util/math.hpp> @@ -86,7 +90,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct qsc {}; + struct qsc {}; // Quadrilateralized Spherical Cube }} //namespace srs::par4 @@ -95,76 +99,81 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace qsc { - static const double EPS10 = 1.e-10; - static const int FACE_FRONT = 0; - static const int FACE_RIGHT = 1; - static const int FACE_BACK = 2; - static const int FACE_LEFT = 3; - static const int FACE_TOP = 4; - static const int FACE_BOTTOM = 5; - static const int AREA_0 = 0; - static const int AREA_1 = 1; - static const int AREA_2 = 2; - static const int AREA_3 = 3; + + /* The six cube faces. */ + enum face_type { + face_front = 0, + face_right = 1, + face_back = 2, + face_left = 3, + face_top = 4, + face_bottom = 5 + }; template <typename T> struct par_qsc { - int face; - T a_squared; - T b; - T one_minus_f; - T one_minus_f_squared; + face_type face; + T a_squared; + T b; + T one_minus_f; + T one_minus_f_squared; }; - /* The six cube faces. */ + static const double epsilon10 = 1.e-10; /* The four areas on a cube face. AREA_0 is the area of definition, * the other three areas are counted counterclockwise. */ + enum area_type { + area_0 = 0, + area_1 = 1, + area_2 = 2, + area_3 = 3 + }; /* Helper function for forward projection: compute the theta angle * and determine the area number. */ template <typename T> - inline T qsc_fwd_equat_face_theta(T const& phi, T const& y, T const& x, int *area) + inline T qsc_fwd_equat_face_theta(T const& phi, T const& y, T const& x, area_type *area) { - static const T FORTPI = detail::FORTPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); - static const T ONEPI = detail::ONEPI<T>(); - - T theta; - if (phi < EPS10) { - *area = AREA_0; - theta = 0.0; + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); + + T theta; + if (phi < epsilon10) { + *area = area_0; + theta = 0.0; + } else { + theta = atan2(y, x); + if (fabs(theta) <= fourth_pi) { + *area = area_0; + } else if (theta > fourth_pi && theta <= half_pi + fourth_pi) { + *area = area_1; + theta -= half_pi; + } else if (theta > half_pi + fourth_pi || theta <= -(half_pi + fourth_pi)) { + *area = area_2; + theta = (theta >= 0.0 ? theta - pi : theta + pi); } else { - theta = atan2(y, x); - if (fabs(theta) <= FORTPI) { - *area = AREA_0; - } else if (theta > FORTPI && theta <= HALFPI + FORTPI) { - *area = AREA_1; - theta -= HALFPI; - } else if (theta > HALFPI + FORTPI || theta <= -(HALFPI + FORTPI)) { - *area = AREA_2; - theta = (theta >= 0.0 ? theta - ONEPI : theta + ONEPI); - } else { - *area = AREA_3; - theta += HALFPI; - } + *area = area_3; + theta += half_pi; } - return (theta); + } + return theta; } /* Helper function: shift the longitude. */ template <typename T> inline T qsc_shift_lon_origin(T const& lon, T const& offset) { - static const T ONEPI = detail::ONEPI<T>(); - static const T TWOPI = detail::TWOPI<T>(); + static const T pi = detail::pi<T>(); + static const T two_pi = detail::two_pi<T>(); T slon = lon + offset; - if (slon < -ONEPI) { - slon += TWOPI; - } else if (slon > +ONEPI) { - slon -= TWOPI; + if (slon < -pi) { + slon += two_pi; + } else if (slon > +pi) { + slon -= two_pi; } return slon; } @@ -172,40 +181,33 @@ namespace projections /* Forward projection, ellipsoid */ // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_qsc_ellipsoid : public base_t_fi<base_qsc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_qsc_ellipsoid + : public base_t_fi<base_qsc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_qsc<CalculationType> m_proj_parm; + par_qsc<T> m_proj_parm; inline base_qsc_ellipsoid(const Parameters& par) - : base_t_fi<base_qsc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_qsc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - - CalculationType lat, lon; - CalculationType sinlat, coslat; - CalculationType sinlon, coslon; - CalculationType q = 0.0, r = 0.0, s = 0.0; - CalculationType theta, phi; - CalculationType t, mu, nu; - int area; + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); + + T lat, lon; + T theta, phi; + T t, mu; /* nu; */ + area_type area; /* Convert the geodetic latitude to a geocentric latitude. * This corresponds to the shift from the ellipsoid to the sphere * described in [LK12]. */ - if (this->m_par.es) { + if (this->m_par.es != 0.0) { lat = atan(this->m_proj_parm.one_minus_f_squared * tan(lp_lat)); } else { lat = lp_lat; @@ -217,13 +219,47 @@ namespace projections * directly from phi, lam. For the other faces, we must use * unit sphere cartesian coordinates as an intermediate step. */ lon = lp_lon; - if (this->m_proj_parm.face != FACE_TOP && this->m_proj_parm.face != FACE_BOTTOM) { - if (this->m_proj_parm.face == FACE_RIGHT) { - lon = qsc_shift_lon_origin(lon, +HALFPI); - } else if (this->m_proj_parm.face == FACE_BACK) { - lon = qsc_shift_lon_origin(lon, +ONEPI); - } else if (this->m_proj_parm.face == FACE_LEFT) { - lon = qsc_shift_lon_origin(lon, -HALFPI); + if (this->m_proj_parm.face == face_top) { + phi = half_pi - lat; + if (lon >= fourth_pi && lon <= half_pi + fourth_pi) { + area = area_0; + theta = lon - half_pi; + } else if (lon > half_pi + fourth_pi || lon <= -(half_pi + fourth_pi)) { + area = area_1; + theta = (lon > 0.0 ? lon - pi : lon + pi); + } else if (lon > -(half_pi + fourth_pi) && lon <= -fourth_pi) { + area = area_2; + theta = lon + half_pi; + } else { + area = area_3; + theta = lon; + } + } else if (this->m_proj_parm.face == face_bottom) { + phi = half_pi + lat; + if (lon >= fourth_pi && lon <= half_pi + fourth_pi) { + area = area_0; + theta = -lon + half_pi; + } else if (lon < fourth_pi && lon >= -fourth_pi) { + area = area_1; + theta = -lon; + } else if (lon < -fourth_pi && lon >= -(half_pi + fourth_pi)) { + area = area_2; + theta = -lon - half_pi; + } else { + area = area_3; + theta = (lon > 0.0 ? -lon + pi : -lon - pi); + } + } else { + T q, r, s; + T sinlat, coslat; + T sinlon, coslon; + + if (this->m_proj_parm.face == face_right) { + lon = qsc_shift_lon_origin(lon, +half_pi); + } else if (this->m_proj_parm.face == face_back) { + lon = qsc_shift_lon_origin(lon, +pi); + } else if (this->m_proj_parm.face == face_left) { + lon = qsc_shift_lon_origin(lon, -half_pi); } sinlat = sin(lat); coslat = cos(lat); @@ -232,85 +268,60 @@ namespace projections q = coslat * coslon; r = coslat * sinlon; s = sinlat; - } - if (this->m_proj_parm.face == FACE_FRONT) { - phi = acos(q); - theta = qsc_fwd_equat_face_theta(phi, s, r, &area); - } else if (this->m_proj_parm.face == FACE_RIGHT) { - phi = acos(r); - theta = qsc_fwd_equat_face_theta(phi, s, -q, &area); - } else if (this->m_proj_parm.face == FACE_BACK) { - phi = acos(-q); - theta = qsc_fwd_equat_face_theta(phi, s, -r, &area); - } else if (this->m_proj_parm.face == FACE_LEFT) { - phi = acos(-r); - theta = qsc_fwd_equat_face_theta(phi, s, q, &area); - } else if (this->m_proj_parm.face == FACE_TOP) { - phi = HALFPI - lat; - if (lon >= FORTPI && lon <= HALFPI + FORTPI) { - area = AREA_0; - theta = lon - HALFPI; - } else if (lon > HALFPI + FORTPI || lon <= -(HALFPI + FORTPI)) { - area = AREA_1; - theta = (lon > 0.0 ? lon - ONEPI : lon + ONEPI); - } else if (lon > -(HALFPI + FORTPI) && lon <= -FORTPI) { - area = AREA_2; - theta = lon + HALFPI; - } else { - area = AREA_3; - theta = lon; - } - } else /* this->m_proj_parm.face == FACE_BOTTOM */ { - phi = HALFPI + lat; - if (lon >= FORTPI && lon <= HALFPI + FORTPI) { - area = AREA_0; - theta = -lon + HALFPI; - } else if (lon < FORTPI && lon >= -FORTPI) { - area = AREA_1; - theta = -lon; - } else if (lon < -FORTPI && lon >= -(HALFPI + FORTPI)) { - area = AREA_2; - theta = -lon - HALFPI; + + if (this->m_proj_parm.face == face_front) { + phi = acos(q); + theta = qsc_fwd_equat_face_theta(phi, s, r, &area); + } else if (this->m_proj_parm.face == face_right) { + phi = acos(r); + theta = qsc_fwd_equat_face_theta(phi, s, -q, &area); + } else if (this->m_proj_parm.face == face_back) { + phi = acos(-q); + theta = qsc_fwd_equat_face_theta(phi, s, -r, &area); + } else if (this->m_proj_parm.face == face_left) { + phi = acos(-r); + theta = qsc_fwd_equat_face_theta(phi, s, q, &area); } else { - area = AREA_3; - theta = (lon > 0.0 ? -lon + ONEPI : -lon - ONEPI); + /* Impossible */ + phi = theta = 0.0; + area = area_0; } } /* Compute mu and nu for the area of definition. * For mu, see Eq. (3-21) in [OL76], but note the typos: * compare with Eq. (3-14). For nu, see Eq. (3-38). */ - mu = atan((12.0 / ONEPI) * (theta + acos(sin(theta) * cos(FORTPI)) - HALFPI)); + mu = atan((12.0 / pi) * (theta + acos(sin(theta) * cos(fourth_pi)) - half_pi)); + // TODO: (cos(mu) * cos(mu)) could be replaced with sqr(cos(mu)) t = sqrt((1.0 - cos(phi)) / (cos(mu) * cos(mu)) / (1.0 - cos(atan(1.0 / cos(theta))))); /* nu = atan(t); We don't really need nu, just t, see below. */ /* Apply the result to the real area. */ - if (area == AREA_1) { - mu += HALFPI; - } else if (area == AREA_2) { - mu += ONEPI; - } else if (area == AREA_3) { - mu += HALFPI + ONEPI; + if (area == area_1) { + mu += half_pi; + } else if (area == area_2) { + mu += pi; + } else if (area == area_3) { + mu += half_pi + pi; } /* Now compute x, y from mu and nu */ /* t = tan(nu); */ xy_x = t * cos(mu); xy_y = t * sin(mu); - boost::ignore_unused(nu); } /* Inverse projection, ellipsoid */ // INVERSE(e_inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); - CalculationType mu, nu, cosmu, tannu; - CalculationType tantheta, theta, cosphi, phi; - CalculationType t; + T mu, nu, cosmu, tannu; + T tantheta, theta, cosphi, phi; + T t; int area; /* Convert the input x, y to the mu and nu angles as used by QSC. @@ -318,16 +329,16 @@ namespace projections nu = atan(sqrt(xy_x * xy_x + xy_y * xy_y)); mu = atan2(xy_y, xy_x); if (xy_x >= 0.0 && xy_x >= fabs(xy_y)) { - area = AREA_0; + area = area_0; } else if (xy_y >= 0.0 && xy_y >= fabs(xy_x)) { - area = AREA_1; - mu -= HALFPI; + area = area_1; + mu -= half_pi; } else if (xy_x < 0.0 && -xy_x >= fabs(xy_y)) { - area = AREA_2; - mu = (mu < 0.0 ? mu + ONEPI : mu - ONEPI); + area = area_2; + mu = (mu < 0.0 ? mu + pi : mu - pi); } else { - area = AREA_3; - mu += HALFPI; + area = area_3; + mu += half_pi; } /* Compute phi and theta for the area of definition. @@ -335,7 +346,7 @@ namespace projections * good hints can be found here (as of 2011-12-14): * http://fits.gsfc.nasa.gov/fitsbits/saf.93/saf.9302 * (search for "Message-Id: <9302181759.AA25477 at fits.cv.nrao.edu>") */ - t = (ONEPI / 12.0) * tan(mu); + t = (pi / 12.0) * tan(mu); tantheta = sin(t) / (cos(t) - (1.0 / sqrt(2.0))); theta = atan(tantheta); cosmu = cos(mu); @@ -351,33 +362,33 @@ namespace projections * For the top and bottom face, we can compute phi and lam directly. * For the other faces, we must use unit sphere cartesian coordinates * as an intermediate step. */ - if (this->m_proj_parm.face == FACE_TOP) { + if (this->m_proj_parm.face == face_top) { phi = acos(cosphi); - lp_lat = HALFPI - phi; - if (area == AREA_0) { - lp_lon = theta + HALFPI; - } else if (area == AREA_1) { - lp_lon = (theta < 0.0 ? theta + ONEPI : theta - ONEPI); - } else if (area == AREA_2) { - lp_lon = theta - HALFPI; + lp_lat = half_pi - phi; + if (area == area_0) { + lp_lon = theta + half_pi; + } else if (area == area_1) { + lp_lon = (theta < 0.0 ? theta + pi : theta - pi); + } else if (area == area_2) { + lp_lon = theta - half_pi; } else /* area == AREA_3 */ { lp_lon = theta; } - } else if (this->m_proj_parm.face == FACE_BOTTOM) { + } else if (this->m_proj_parm.face == face_bottom) { phi = acos(cosphi); - lp_lat = phi - HALFPI; - if (area == AREA_0) { - lp_lon = -theta + HALFPI; - } else if (area == AREA_1) { + lp_lat = phi - half_pi; + if (area == area_0) { + lp_lon = -theta + half_pi; + } else if (area == area_1) { lp_lon = -theta; - } else if (area == AREA_2) { - lp_lon = -theta - HALFPI; - } else /* area == AREA_3 */ { - lp_lon = (theta < 0.0 ? -theta - ONEPI : -theta + ONEPI); + } else if (area == area_2) { + lp_lon = -theta - half_pi; + } else /* area == area_3 */ { + lp_lon = (theta < 0.0 ? -theta - pi : -theta + pi); } } else { /* Compute phi and lam via cartesian unit sphere coordinates. */ - CalculationType q, r, s, t; + T q, r, s; q = cosphi; t = q * q; if (t >= 1.0) { @@ -392,48 +403,48 @@ namespace projections r = sqrt(1.0 - t); } /* Rotate q,r,s into the correct area. */ - if (area == AREA_1) { + if (area == area_1) { t = r; r = -s; s = t; - } else if (area == AREA_2) { + } else if (area == area_2) { r = -r; s = -s; - } else if (area == AREA_3) { + } else if (area == area_3) { t = r; r = s; s = -t; } /* Rotate q,r,s into the correct cube face. */ - if (this->m_proj_parm.face == FACE_RIGHT) { + if (this->m_proj_parm.face == face_right) { t = q; q = -r; r = t; - } else if (this->m_proj_parm.face == FACE_BACK) { + } else if (this->m_proj_parm.face == face_back) { q = -q; r = -r; - } else if (this->m_proj_parm.face == FACE_LEFT) { + } else if (this->m_proj_parm.face == face_left) { t = q; q = r; r = -t; } /* Now compute phi and lam from the unit sphere coordinates. */ - lp_lat = acos(-s) - HALFPI; + lp_lat = acos(-s) - half_pi; lp_lon = atan2(r, q); - if (this->m_proj_parm.face == FACE_RIGHT) { - lp_lon = qsc_shift_lon_origin(lp_lon, -HALFPI); - } else if (this->m_proj_parm.face == FACE_BACK) { - lp_lon = qsc_shift_lon_origin(lp_lon, -ONEPI); - } else if (this->m_proj_parm.face == FACE_LEFT) { - lp_lon = qsc_shift_lon_origin(lp_lon, +HALFPI); + if (this->m_proj_parm.face == face_right) { + lp_lon = qsc_shift_lon_origin(lp_lon, -half_pi); + } else if (this->m_proj_parm.face == face_back) { + lp_lon = qsc_shift_lon_origin(lp_lon, -pi); + } else if (this->m_proj_parm.face == face_left) { + lp_lon = qsc_shift_lon_origin(lp_lon, +half_pi); } } /* Apply the shift from the sphere to the ellipsoid as described * in [LK12]. */ - if (this->m_par.es) { + if (this->m_par.es != 0.0) { int invert_sign; - CalculationType tanphi, xa; + T tanphi, xa; invert_sign = (lp_lat < 0.0 ? 1 : 0); tanphi = tan(lp_lat); xa = this->m_proj_parm.b / sqrt(tanphi * tanphi + this->m_proj_parm.one_minus_f_squared); @@ -455,29 +466,29 @@ namespace projections template <typename Parameters, typename T> inline void setup_qsc(Parameters& par, par_qsc<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); - - /* Determine the cube face from the center of projection. */ - if (par.phi0 >= HALFPI - FORTPI / 2.0) { - proj_parm.face = FACE_TOP; - } else if (par.phi0 <= -(HALFPI - FORTPI / 2.0)) { - proj_parm.face = FACE_BOTTOM; - } else if (fabs(par.lam0) <= FORTPI) { - proj_parm.face = FACE_FRONT; - } else if (fabs(par.lam0) <= HALFPI + FORTPI) { - proj_parm.face = (par.lam0 > 0.0 ? FACE_RIGHT : FACE_LEFT); - } else { - proj_parm.face = FACE_BACK; - } - /* Fill in useful values for the ellipsoid <-> sphere shift - * described in [LK12]. */ - if (par.es) { - proj_parm.a_squared = par.a * par.a; - proj_parm.b = par.a * sqrt(1.0 - par.es); - proj_parm.one_minus_f = 1.0 - (par.a - proj_parm.b) / par.a; - proj_parm.one_minus_f_squared = proj_parm.one_minus_f * proj_parm.one_minus_f; - } + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); + + /* Determine the cube face from the center of projection. */ + if (par.phi0 >= half_pi - fourth_pi / 2.0) { + proj_parm.face = face_top; + } else if (par.phi0 <= -(half_pi - fourth_pi / 2.0)) { + proj_parm.face = face_bottom; + } else if (fabs(par.lam0) <= fourth_pi) { + proj_parm.face = face_front; + } else if (fabs(par.lam0) <= half_pi + fourth_pi) { + proj_parm.face = (par.lam0 > 0.0 ? face_right : face_left); + } else { + proj_parm.face = face_back; + } + /* Fill in useful values for the ellipsoid <-> sphere shift + * described in [LK12]. */ + if (par.es != 0.0) { + proj_parm.a_squared = par.a * par.a; + proj_parm.b = par.a * sqrt(1.0 - par.es); + proj_parm.one_minus_f = 1.0 - (par.a - proj_parm.b) / par.a; + proj_parm.one_minus_f_squared = proj_parm.one_minus_f * proj_parm.one_minus_f; + } } }} // namespace detail::qsc @@ -495,10 +506,10 @@ namespace projections \par Example \image html ex_qsc.gif */ - template <typename CalculationType, typename Parameters> - struct qsc_ellipsoid : public detail::qsc::base_qsc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct qsc_ellipsoid : public detail::qsc::base_qsc_ellipsoid<T, Parameters> { - inline qsc_ellipsoid(const Parameters& par) : detail::qsc::base_qsc_ellipsoid<CalculationType, Parameters>(par) + inline qsc_ellipsoid(const Parameters& par) : detail::qsc::base_qsc_ellipsoid<T, Parameters>(par) { detail::qsc::setup_qsc(this->m_par, this->m_proj_parm); } @@ -512,20 +523,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::qsc, qsc_ellipsoid, qsc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class qsc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class qsc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<qsc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<qsc_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void qsc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void qsc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("qsc", new qsc_entry<CalculationType, Parameters>); + factory.add_to_factory("qsc", new qsc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/robin.hpp b/boost/geometry/srs/projections/proj/robin.hpp index 52acb58e41..f5ec97be51 100644 --- a/boost/geometry/srs/projections/proj/robin.hpp +++ b/boost/geometry/srs/projections/proj/robin.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct robin {}; + struct robin {}; // Robinson }} //namespace srs::par4 @@ -68,9 +67,11 @@ namespace projections static const double FYC = 1.3523; static const double C1 = 11.45915590261646417544; static const double RC1 = 0.08726646259971647884; - static const int NODES = 18; - static const double ONEEPS = 1.000001; - static const double EPS = 1e-8; + static const int n_nodes = 18; + static const double one_plus_eps = 1.000001; + static const double epsilon = 1e-8; + /* Not sure at all of the appropriate number for max_iter... */ + static const int max_iter = 100; /* note: following terms based upon 5 deg. intervals in degrees. @@ -82,14 +83,14 @@ namespace projections */ template <typename T> - struct COEFS { + struct coefs { T c0, c1, c2, c3; }; template <typename T> - inline const COEFS<T> * X() + inline const coefs<T> * coefs_x() { - static const COEFS<T> result[] = { + static const coefs<T> result[] = { {1.0, 2.2199e-17, -7.15515e-05, 3.1103e-06}, {0.9986, -0.000482243, -2.4897e-05, -1.3309e-06}, {0.9954, -0.00083103, -4.48605e-05, -9.86701e-07}, @@ -114,9 +115,9 @@ namespace projections } template <typename T> - inline const COEFS<T> * Y() + inline const coefs<T> * coefs_y() { - static const COEFS<T> result[] = { + static const coefs<T> result[] = { {-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11}, {0.062, 0.0124, -1.26793e-09, 4.22642e-10}, {0.124, 0.0124, 5.07171e-09, -1.60604e-09}, @@ -141,87 +142,85 @@ namespace projections } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_robin_spheroid : public base_t_fi<base_robin_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_robin_spheroid + : public base_t_fi<base_robin_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_robin_spheroid(const Parameters& par) - : base_t_fi<base_robin_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_robin_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} - template <typename T> - inline T V(COEFS<T> const& C, T const& z) const - { return (C.c0 + z * (C.c1 + z * (C.c2 + z * C.c3))); } - template <typename T> - inline T DV(COEFS<T> const& C, T const& z) const - { return (C.c1 + z * (C.c2 + C.c2 + z * 3. * C.c3)); } + inline T v(coefs<T> const& c, T const& z) const + { return (c.c0 + z * (c.c1 + z * (c.c2 + z * c.c3))); } + inline T dv(coefs<T> const& c, T const& z) const + { return (c.c1 + z * (c.c2 + c.c2 + z * 3. * c.c3)); } // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { int i; - CalculationType dphi; + T dphi; i = int_floor((dphi = fabs(lp_lat)) * C1); - if (i < 0) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - if (i >= NODES) i = NODES - 1; - dphi = geometry::math::r2d<CalculationType>() * (dphi - RC1 * i); - xy_x = V(X<CalculationType>()[i], dphi) * FXC * lp_lon; - xy_y = V(Y<CalculationType>()[i], dphi) * FYC; + if (i < 0) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + if (i >= n_nodes) i = n_nodes - 1; + dphi = geometry::math::r2d<T>() * (dphi - RC1 * i); + xy_x = v(coefs_x<T>()[i], dphi) * FXC * lp_lon; + xy_y = v(coefs_y<T>()[i], dphi) * FYC; if (lp_lat < 0.) xy_y = -xy_y; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - const COEFS<CalculationType> * X = robin::X<CalculationType>(); - const COEFS<CalculationType> * Y = robin::Y<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + const coefs<T> * coefs_x = robin::coefs_x<T>(); + const coefs<T> * coefs_y = robin::coefs_y<T>(); int i; - CalculationType t, t1; - COEFS<CalculationType> T; + T t, t1; + coefs<T> coefs_t; + int iters; lp_lon = xy_x / FXC; lp_lat = fabs(xy_y / FYC); if (lp_lat >= 1.) { /* simple pathologic cases */ - if (lp_lat > ONEEPS) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - else { - lp_lat = xy_y < 0. ? -HALFPI : HALFPI; - lp_lon /= X[NODES].c0; + if (lp_lat > one_plus_eps) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } else { + lp_lat = xy_y < 0. ? -half_pi : half_pi; + lp_lon /= coefs_x[n_nodes].c0; } } else { /* general problem */ /* in Y space, reduce to table interval */ - i = int_floor(lp_lat * NODES); - if( i < 0 || i >= NODES ) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + i = int_floor(lp_lat * n_nodes); + if( i < 0 || i >= n_nodes ) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } for (;;) { - if (Y[i].c0 > lp_lat) --i; - else if (Y[i+1].c0 <= lp_lat) ++i; + if (coefs_y[i].c0 > lp_lat) --i; + else if (coefs_y[i+1].c0 <= lp_lat) ++i; else break; } - T = Y[i]; + coefs_t = coefs_y[i]; /* first guess, linear interp */ - t = 5. * (lp_lat - T.c0)/(Y[i+1].c0 - T.c0); + t = 5. * (lp_lat - coefs_t.c0)/(coefs_y[i+1].c0 - coefs_t.c0); /* make into root */ - T.c0 -= lp_lat; - for (;;) { /* Newton-Raphson reduction */ - t -= t1 = V(T,t) / DV(T,t); - if (fabs(t1) < EPS) + coefs_t.c0 = (T)(coefs_t.c0 - lp_lat); + for (iters = max_iter; iters ; --iters) { /* Newton-Raphson */ + t -= t1 = v(coefs_t,t) / dv(coefs_t,t); + if (fabs(t1) < epsilon) break; } - lp_lat = (5 * i + t) * geometry::math::d2r<CalculationType>(); + if( iters == 0 ) + BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) ); + lp_lat = (5 * i + t) * geometry::math::d2r<T>(); if (xy_y < 0.) lp_lat = -lp_lat; - lp_lon /= V(X[i], t); + lp_lon /= v(coefs_x[i], t); } } @@ -254,10 +253,10 @@ namespace projections \par Example \image html ex_robin.gif */ - template <typename CalculationType, typename Parameters> - struct robin_spheroid : public detail::robin::base_robin_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct robin_spheroid : public detail::robin::base_robin_spheroid<T, Parameters> { - inline robin_spheroid(const Parameters& par) : detail::robin::base_robin_spheroid<CalculationType, Parameters>(par) + inline robin_spheroid(const Parameters& par) : detail::robin::base_robin_spheroid<T, Parameters>(par) { detail::robin::setup_robin(this->m_par); } @@ -271,20 +270,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::robin, robin_spheroid, robin_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class robin_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class robin_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<robin_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<robin_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void robin_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void robin_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("robin", new robin_entry<CalculationType, Parameters>); + factory.add_to_factory("robin", new robin_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/rouss.hpp b/boost/geometry/srs/projections/proj/rouss.hpp index edad904799..1cbc795e9d 100644 --- a/boost/geometry/srs/projections/proj/rouss.hpp +++ b/boost/geometry/srs/projections/proj/rouss.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -43,6 +39,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct rouss {}; + struct rouss {}; // Roussilhe Stereographic }} //namespace srs::par4 @@ -71,29 +70,25 @@ namespace projections T B1, B2, B3, B4, B5, B6, B7, B8; T C1, C2, C3, C4, C5, C6, C7, C8; T D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11; - MDIST<T> en; + mdist<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_rouss_ellipsoid : public base_t_fi<base_rouss_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_rouss_ellipsoid + : public base_t_fi<base_rouss_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_rouss<CalculationType> m_proj_parm; + par_rouss<T> m_proj_parm; inline base_rouss_ellipsoid(const Parameters& par) - : base_t_fi<base_rouss_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_rouss_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType s, al, cp, sp, al2, s2; + T s, al, cp, sp, al2, s2; cp = cos(lp_lat); sp = sin(lp_lat); @@ -110,9 +105,9 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType s, al, x = xy_x / this->m_par.k0, y = xy_y / this->m_par.k0, x2, y2;; + T s, al, x = xy_x / this->m_par.k0, y = xy_y / this->m_par.k0, x2, y2; x2 = x * x; y2 = y * y; @@ -141,6 +136,7 @@ namespace projections if (!proj_mdist_ini(par.es, proj_parm.en)) BOOST_THROW_EXCEPTION( projection_exception(0) ); + es2 = sin(par.phi0); proj_parm.s0 = proj_mdist(par.phi0, es2, cos(par.phi0), proj_parm.en); t = 1. - (es2 = par.es * es2 * es2); @@ -197,10 +193,10 @@ namespace projections \par Example \image html ex_rouss.gif */ - template <typename CalculationType, typename Parameters> - struct rouss_ellipsoid : public detail::rouss::base_rouss_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct rouss_ellipsoid : public detail::rouss::base_rouss_ellipsoid<T, Parameters> { - inline rouss_ellipsoid(const Parameters& par) : detail::rouss::base_rouss_ellipsoid<CalculationType, Parameters>(par) + inline rouss_ellipsoid(const Parameters& par) : detail::rouss::base_rouss_ellipsoid<T, Parameters>(par) { detail::rouss::setup_rouss(this->m_par, this->m_proj_parm); } @@ -214,20 +210,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rouss, rouss_ellipsoid, rouss_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class rouss_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class rouss_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<rouss_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<rouss_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void rouss_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void rouss_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("rouss", new rouss_entry<CalculationType, Parameters>); + factory.add_to_factory("rouss", new rouss_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/rpoly.hpp b/boost/geometry/srs/projections/proj/rpoly.hpp index fcb9f1043b..b2146426bd 100644 --- a/boost/geometry/srs/projections/proj/rpoly.hpp +++ b/boost/geometry/srs/projections/proj/rpoly.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct rpoly {}; + struct rpoly {}; // Rectangular Polyconic }} //namespace srs::par4 @@ -61,7 +60,7 @@ namespace projections namespace detail { namespace rpoly { - static const double EPS = 1e-9; + static const double epsilon = 1e-9; template <typename T> struct par_rpoly @@ -73,31 +72,27 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_rpoly_spheroid : public base_t_f<base_rpoly_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_rpoly_spheroid + : public base_t_f<base_rpoly_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_rpoly<CalculationType> m_proj_parm; + par_rpoly<T> m_proj_parm; inline base_rpoly_spheroid(const Parameters& par) - : base_t_f<base_rpoly_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_rpoly_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType fa; + T fa; if (this->m_proj_parm.mode) fa = tan(lp_lon * this->m_proj_parm.fxb) * this->m_proj_parm.fxa; else fa = 0.5 * lp_lon; - if (fabs(lp_lat) < EPS) { + if (fabs(lp_lat) < epsilon) { xy_x = fa + fa; xy_y = - this->m_par.phi0; } else { @@ -118,7 +113,7 @@ namespace projections template <typename Parameters, typename T> inline void setup_rpoly(Parameters& par, par_rpoly<T>& proj_parm) { - if ((proj_parm.mode = (proj_parm.phi1 = fabs(pj_param(par.params, "rlat_ts").f)) > EPS)) { + if ((proj_parm.mode = (proj_parm.phi1 = fabs(pj_get_param_r(par.params, "lat_ts"))) > epsilon)) { proj_parm.fxb = 0.5 * sin(proj_parm.phi1); proj_parm.fxa = 0.5 / proj_parm.fxb; } @@ -143,10 +138,10 @@ namespace projections \par Example \image html ex_rpoly.gif */ - template <typename CalculationType, typename Parameters> - struct rpoly_spheroid : public detail::rpoly::base_rpoly_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct rpoly_spheroid : public detail::rpoly::base_rpoly_spheroid<T, Parameters> { - inline rpoly_spheroid(const Parameters& par) : detail::rpoly::base_rpoly_spheroid<CalculationType, Parameters>(par) + inline rpoly_spheroid(const Parameters& par) : detail::rpoly::base_rpoly_spheroid<T, Parameters>(par) { detail::rpoly::setup_rpoly(this->m_par, this->m_proj_parm); } @@ -160,20 +155,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rpoly, rpoly_spheroid, rpoly_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class rpoly_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class rpoly_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<rpoly_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<rpoly_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void rpoly_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void rpoly_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("rpoly", new rpoly_entry<CalculationType, Parameters>); + factory.add_to_factory("rpoly", new rpoly_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/sconics.hpp b/boost/geometry/srs/projections/proj/sconics.hpp index b5f97fa542..b1119d622a 100644 --- a/boost/geometry/srs/projections/proj/sconics.hpp +++ b/boost/geometry/srs/projections/proj/sconics.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP + + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -54,13 +54,13 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct euler {}; - struct murd1 {}; - struct murd2 {}; - struct murd3 {}; - struct pconic {}; - struct tissot {}; - struct vitk1 {}; + struct euler {}; // Euler + struct murd1 {}; // Murdoch I + struct murd2 {}; // Murdoch II + struct murd3 {}; // Murdoch III + struct pconic {}; // Perspective Conic + struct tissot {}; // Tissot + struct vitk1 {}; // Vitkovsky I }} //namespace srs::par4 @@ -70,15 +70,17 @@ namespace projections namespace detail { namespace sconics { - static const int EULER = 0; - static const int MURD1 = 1; - static const int MURD2 = 2; - static const int MURD3 = 3; - static const int PCONIC = 4; - static const int TISSOT = 5; - static const int VITK1 = 6; - static const double EPS10 = 1.e-10; - static const double EPS = 1e-10; + enum proj_type { + proj_euler = 0, + proj_murd1 = 1, + proj_murd2 = 2, + proj_murd3 = 3, + proj_pconic = 4, + proj_tissot = 5, + proj_vitk1 = 6 + }; + static const double epsilon10 = 1.e-10; + static const double epsilon = 1e-10; template <typename T> struct par_sconics @@ -88,7 +90,7 @@ namespace projections T rho_0; T sig; T c1, c2; - int type; + proj_type type; }; /* get common factors for simple conics */ @@ -98,46 +100,41 @@ namespace projections T p1, p2; int err = 0; - if (!pj_param(par.params, "tlat_1").i || - !pj_param(par.params, "tlat_2").i) { + if (!pj_param_r(par.params, "lat_1", p1) || + !pj_param_r(par.params, "lat_2", p2)) { err = -41; } else { - p1 = pj_param(par.params, "rlat_1").f; - p2 = pj_param(par.params, "rlat_2").f; + //p1 = pj_get_param_r(par.params, "lat_1"); // set above + //p2 = pj_get_param_r(par.params, "lat_2"); // set above *del = 0.5 * (p2 - p1); proj_parm.sig = 0.5 * (p2 + p1); - err = (fabs(*del) < EPS || fabs(proj_parm.sig) < EPS) ? -42 : 0; - *del = *del; + err = (fabs(*del) < epsilon || fabs(proj_parm.sig) < epsilon) ? -42 : 0; } return err; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_sconics_spheroid : public base_t_fi<base_sconics_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_sconics_spheroid + : public base_t_fi<base_sconics_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_sconics<CalculationType> m_proj_parm; + par_sconics<T> m_proj_parm; inline base_sconics_spheroid(const Parameters& par) - : base_t_fi<base_sconics_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_sconics_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType rho; + T rho; switch (this->m_proj_parm.type) { - case MURD2: + case proj_murd2: rho = this->m_proj_parm.rho_c + tan(this->m_proj_parm.sig - lp_lat); break; - case PCONIC: + case proj_pconic: rho = this->m_proj_parm.c2 * (this->m_proj_parm.c1 - tan(lp_lat - this->m_proj_parm.sig)); break; default: @@ -150,9 +147,9 @@ namespace projections // INVERSE(s_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType rho; + T rho; rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho_0 - xy_y); if (this->m_proj_parm.n < 0.) { @@ -160,12 +157,14 @@ namespace projections xy_x = - xy_x; xy_y = - xy_y; } + lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; + switch (this->m_proj_parm.type) { - case PCONIC: + case proj_pconic: lp_lat = atan(this->m_proj_parm.c1 - rho / this->m_proj_parm.c2) + this->m_proj_parm.sig; break; - case MURD2: + case proj_murd2: lp_lat = this->m_proj_parm.sig - atan(rho - this->m_proj_parm.rho_c); break; default: @@ -181,115 +180,113 @@ namespace projections }; template <typename Parameters, typename T> - inline void setup(Parameters& par, par_sconics<T>& proj_parm) + inline void setup(Parameters& par, par_sconics<T>& proj_parm, proj_type type) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); T del, cs; - int i; + int err; + + proj_parm.type = type; + + err = phi12(par, proj_parm, &del); + if(err) + BOOST_THROW_EXCEPTION( projection_exception(err) ); - if( (i = phi12(par, proj_parm, &del)) ) - BOOST_THROW_EXCEPTION( projection_exception(i) ); switch (proj_parm.type) { - case TISSOT: + case proj_tissot: proj_parm.n = sin(proj_parm.sig); cs = cos(del); proj_parm.rho_c = proj_parm.n / cs + cs / proj_parm.n; proj_parm.rho_0 = sqrt((proj_parm.rho_c - 2 * sin(par.phi0))/proj_parm.n); break; - case MURD1: + case proj_murd1: proj_parm.rho_c = sin(del)/(del * tan(proj_parm.sig)) + proj_parm.sig; proj_parm.rho_0 = proj_parm.rho_c - par.phi0; proj_parm.n = sin(proj_parm.sig); break; - case MURD2: + case proj_murd2: proj_parm.rho_c = (cs = sqrt(cos(del))) / tan(proj_parm.sig); proj_parm.rho_0 = proj_parm.rho_c + tan(proj_parm.sig - par.phi0); proj_parm.n = sin(proj_parm.sig) * cs; break; - case MURD3: + case proj_murd3: proj_parm.rho_c = del / (tan(proj_parm.sig) * tan(del)) + proj_parm.sig; proj_parm.rho_0 = proj_parm.rho_c - par.phi0; proj_parm.n = sin(proj_parm.sig) * sin(del) * tan(del) / (del * del); break; - case EULER: + case proj_euler: proj_parm.n = sin(proj_parm.sig) * sin(del) / del; del *= 0.5; proj_parm.rho_c = del / (tan(del) * tan(proj_parm.sig)) + proj_parm.sig; proj_parm.rho_0 = proj_parm.rho_c - par.phi0; break; - case PCONIC: + case proj_pconic: proj_parm.n = sin(proj_parm.sig); proj_parm.c2 = cos(del); proj_parm.c1 = 1./tan(proj_parm.sig); - if (fabs(del = par.phi0 - proj_parm.sig) - EPS10 >= HALFPI) - BOOST_THROW_EXCEPTION( projection_exception(-43) ); + if (fabs(del = par.phi0 - proj_parm.sig) - epsilon10 >= half_pi) + BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_half_pi_from_mean) ); proj_parm.rho_0 = proj_parm.c2 * (proj_parm.c1 - tan(del)); break; - case VITK1: + case proj_vitk1: proj_parm.n = (cs = tan(del)) * sin(proj_parm.sig) / del; proj_parm.rho_c = del / (cs * tan(proj_parm.sig)) + proj_parm.sig; proj_parm.rho_0 = proj_parm.rho_c - par.phi0; break; } + par.es = 0; } + // Euler + template <typename Parameters, typename T> + inline void setup_euler(Parameters& par, par_sconics<T>& proj_parm) + { + setup(par, proj_parm, proj_euler); + } + // Tissot template <typename Parameters, typename T> inline void setup_tissot(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = TISSOT; - setup(par, proj_parm); + setup(par, proj_parm, proj_tissot); } // Murdoch I template <typename Parameters, typename T> inline void setup_murd1(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = MURD1; - setup(par, proj_parm); + setup(par, proj_parm, proj_murd1); } // Murdoch II template <typename Parameters, typename T> inline void setup_murd2(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = MURD2; - setup(par, proj_parm); + setup(par, proj_parm, proj_murd2); } // Murdoch III template <typename Parameters, typename T> inline void setup_murd3(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = MURD3; - setup(par, proj_parm); - } - - // Euler - template <typename Parameters, typename T> - inline void setup_euler(Parameters& par, par_sconics<T>& proj_parm) - { - proj_parm.type = EULER; - setup(par, proj_parm); - } + setup(par, proj_parm, proj_murd3); + } // Perspective Conic template <typename Parameters, typename T> inline void setup_pconic(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = PCONIC; - setup(par, proj_parm); + setup(par, proj_parm, proj_pconic); } // Vitkovsky I template <typename Parameters, typename T> inline void setup_vitk1(Parameters& par, par_sconics<T>& proj_parm) { - proj_parm.type = VITK1; - setup(par, proj_parm); + setup(par, proj_parm, proj_vitk1); } }} // namespace detail::sconics @@ -310,10 +307,10 @@ namespace projections \par Example \image html ex_tissot.gif */ - template <typename CalculationType, typename Parameters> - struct tissot_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tissot_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline tissot_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline tissot_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_tissot(this->m_par, this->m_proj_parm); } @@ -334,10 +331,10 @@ namespace projections \par Example \image html ex_murd1.gif */ - template <typename CalculationType, typename Parameters> - struct murd1_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct murd1_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline murd1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline murd1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_murd1(this->m_par, this->m_proj_parm); } @@ -358,10 +355,10 @@ namespace projections \par Example \image html ex_murd2.gif */ - template <typename CalculationType, typename Parameters> - struct murd2_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct murd2_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline murd2_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline murd2_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_murd2(this->m_par, this->m_proj_parm); } @@ -382,10 +379,10 @@ namespace projections \par Example \image html ex_murd3.gif */ - template <typename CalculationType, typename Parameters> - struct murd3_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct murd3_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline murd3_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline murd3_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_murd3(this->m_par, this->m_proj_parm); } @@ -406,10 +403,10 @@ namespace projections \par Example \image html ex_euler.gif */ - template <typename CalculationType, typename Parameters> - struct euler_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct euler_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline euler_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline euler_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_euler(this->m_par, this->m_proj_parm); } @@ -430,10 +427,10 @@ namespace projections \par Example \image html ex_pconic.gif */ - template <typename CalculationType, typename Parameters> - struct pconic_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct pconic_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline pconic_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline pconic_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_pconic(this->m_par, this->m_proj_parm); } @@ -454,10 +451,10 @@ namespace projections \par Example \image html ex_vitk1.gif */ - template <typename CalculationType, typename Parameters> - struct vitk1_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct vitk1_spheroid : public detail::sconics::base_sconics_spheroid<T, Parameters> { - inline vitk1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + inline vitk1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<T, Parameters>(par) { detail::sconics::setup_vitk1(this->m_par, this->m_proj_parm); } @@ -477,86 +474,86 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vitk1, vitk1_spheroid, vitk1_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class tissot_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tissot_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<tissot_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tissot_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class murd1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class murd1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<murd1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<murd1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class murd2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class murd2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<murd2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<murd2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class murd3_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class murd3_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<murd3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<murd3_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class euler_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class euler_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<euler_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<euler_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class pconic_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class pconic_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<pconic_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<pconic_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class vitk1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class vitk1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<vitk1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<vitk1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void sconics_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void sconics_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("tissot", new tissot_entry<CalculationType, Parameters>); - factory.add_to_factory("murd1", new murd1_entry<CalculationType, Parameters>); - factory.add_to_factory("murd2", new murd2_entry<CalculationType, Parameters>); - factory.add_to_factory("murd3", new murd3_entry<CalculationType, Parameters>); - factory.add_to_factory("euler", new euler_entry<CalculationType, Parameters>); - factory.add_to_factory("pconic", new pconic_entry<CalculationType, Parameters>); - factory.add_to_factory("vitk1", new vitk1_entry<CalculationType, Parameters>); + factory.add_to_factory("tissot", new tissot_entry<T, Parameters>); + factory.add_to_factory("murd1", new murd1_entry<T, Parameters>); + factory.add_to_factory("murd2", new murd2_entry<T, Parameters>); + factory.add_to_factory("murd3", new murd3_entry<T, Parameters>); + factory.add_to_factory("euler", new euler_entry<T, Parameters>); + factory.add_to_factory("pconic", new pconic_entry<T, Parameters>); + factory.add_to_factory("vitk1", new vitk1_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/somerc.hpp b/boost/geometry/srs/projections/proj/somerc.hpp index e67d09719e..548ebe5275 100644 --- a/boost/geometry/srs/projections/proj/somerc.hpp +++ b/boost/geometry/srs/projections/proj/somerc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -54,7 +53,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct somerc {}; + struct somerc {}; // Swiss. Obl. Mercator }} //namespace srs::par4 @@ -63,8 +62,8 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace somerc { - static const double EPS = 1.e-10; - static const int NITER = 6; + static const double epsilon = 1.e-10; + static const int n_iter = 6; template <typename T> struct par_somerc @@ -73,70 +72,67 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_somerc_ellipsoid : public base_t_fi<base_somerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_somerc_ellipsoid + : public base_t_fi<base_somerc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_somerc<CalculationType> m_proj_parm; + par_somerc<T> m_proj_parm; inline base_somerc_ellipsoid(const Parameters& par) - : base_t_fi<base_somerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_somerc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType phip, lamp, phipp, lampp, sp, cp; + T phip, lamp, phipp, lampp, sp, cp; sp = this->m_par.e * sin(lp_lat); phip = 2.* atan( exp( this->m_proj_parm.c * ( - log(tan(FORTPI + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp))) - + this->m_proj_parm.K)) - HALFPI; + log(tan(fourth_pi + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp))) + + this->m_proj_parm.K)) - half_pi; lamp = this->m_proj_parm.c * lp_lon; cp = cos(phip); phipp = aasin(this->m_proj_parm.cosp0 * sin(phip) - this->m_proj_parm.sinp0 * cp * cos(lamp)); lampp = aasin(cp * sin(lamp) / cos(phipp)); xy_x = this->m_proj_parm.kR * lampp; - xy_y = this->m_proj_parm.kR * log(tan(FORTPI + 0.5 * phipp)); + xy_y = this->m_proj_parm.kR * log(tan(fourth_pi + 0.5 * phipp)); } // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); - CalculationType phip, lamp, phipp, lampp, cp, esp, con, delp; + T phip, lamp, phipp, lampp, cp, esp, con, delp; int i; - phipp = 2. * (atan(exp(xy_y / this->m_proj_parm.kR)) - FORTPI); + phipp = 2. * (atan(exp(xy_y / this->m_proj_parm.kR)) - fourth_pi); lampp = xy_x / this->m_proj_parm.kR; cp = cos(phipp); phip = aasin(this->m_proj_parm.cosp0 * sin(phipp) + this->m_proj_parm.sinp0 * cp * cos(lampp)); lamp = aasin(cp * sin(lampp) / cos(phip)); - con = (this->m_proj_parm.K - log(tan(FORTPI + 0.5 * phip)))/this->m_proj_parm.c; - for (i = NITER; i ; --i) { + con = (this->m_proj_parm.K - log(tan(fourth_pi + 0.5 * phip)))/this->m_proj_parm.c; + for (i = n_iter; i ; --i) { esp = this->m_par.e * sin(phip); - delp = (con + log(tan(FORTPI + 0.5 * phip)) - this->m_proj_parm.hlf_e * + delp = (con + log(tan(fourth_pi + 0.5 * phip)) - this->m_proj_parm.hlf_e * log((1. + esp)/(1. - esp)) ) * (1. - esp * esp) * cos(phip) * this->m_par.rone_es; phip -= delp; - if (fabs(delp) < EPS) + if (fabs(delp) < epsilon) break; } if (i) { lp_lat = phip; lp_lon = lamp / this->m_proj_parm.c; - } else - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + } else { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } } static inline std::string get_name() @@ -150,7 +146,7 @@ namespace projections template <typename Parameters, typename T> inline void setup_somerc(Parameters& par, par_somerc<T>& proj_parm) { - static const T FORTPI = detail::FORTPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); T cp, phip0, sp; @@ -161,8 +157,8 @@ namespace projections sp = sin(par.phi0); proj_parm.cosp0 = cos( phip0 = aasin(proj_parm.sinp0 = sp / proj_parm.c) ); sp *= par.e; - proj_parm.K = log(tan(FORTPI + 0.5 * phip0)) - proj_parm.c * ( - log(tan(FORTPI + 0.5 * par.phi0)) - proj_parm.hlf_e * + proj_parm.K = log(tan(fourth_pi + 0.5 * phip0)) - proj_parm.c * ( + log(tan(fourth_pi + 0.5 * par.phi0)) - proj_parm.hlf_e * log((1. + sp) / (1. - sp))); proj_parm.kR = par.k0 * sqrt(par.one_es) / (1. - sp * sp); } @@ -183,10 +179,10 @@ namespace projections \par Example \image html ex_somerc.gif */ - template <typename CalculationType, typename Parameters> - struct somerc_ellipsoid : public detail::somerc::base_somerc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct somerc_ellipsoid : public detail::somerc::base_somerc_ellipsoid<T, Parameters> { - inline somerc_ellipsoid(const Parameters& par) : detail::somerc::base_somerc_ellipsoid<CalculationType, Parameters>(par) + inline somerc_ellipsoid(const Parameters& par) : detail::somerc::base_somerc_ellipsoid<T, Parameters>(par) { detail::somerc::setup_somerc(this->m_par, this->m_proj_parm); } @@ -200,20 +196,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::somerc, somerc_ellipsoid, somerc_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class somerc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class somerc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<somerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<somerc_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void somerc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void somerc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("somerc", new somerc_entry<CalculationType, Parameters>); + factory.add_to_factory("somerc", new somerc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/stere.hpp b/boost/geometry/srs/projections/proj/stere.hpp index 9278902e34..ea8af31149 100644 --- a/boost/geometry/srs/projections/proj/stere.hpp +++ b/boost/geometry/srs/projections/proj/stere.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_STERE_HPP -#define BOOST_GEOMETRY_PROJECTIONS_STERE_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_STERE_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STERE_HPP + #include <boost/config.hpp> #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -56,8 +55,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct stere {}; - struct ups {}; + struct stere {}; // Stereographic + struct ups {}; // Universal Polar Stereographic }} //namespace srs::par4 @@ -66,14 +65,17 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace stere { - static const double EPS10 = 1.e-10; - static const double TOL = 1.e-8; - static const int NITER = 8; - static const double CONV = 1.e-10; - static const int S_POLE = 0; - static const int N_POLE = 1; - static const int OBLIQ = 2; - static const int EQUIT = 3; + static const double epsilon10 = 1.e-10; + static const double tolerance = 1.e-8; + static const int n_iter = 8; + static const double conv_tolerance = 1.e-10; + + enum mode_type { + s_pole = 0, + n_pole = 1, + obliq = 2, + equit = 3 + }; template <typename T> struct par_stere @@ -82,118 +84,125 @@ namespace projections T sinX1; T cosX1; T akm1; - int mode; + mode_type mode; }; template <typename T> inline T ssfn_(T const& phit, T sinphi, T const& eccen) { + static const T half_pi = detail::half_pi<T>(); + sinphi *= eccen; - return (tan (.5 * (geometry::math::half_pi<T>() + phit)) * - pow((1. - sinphi) / (1. + sinphi), .5 * eccen)); + return (tan (.5 * (half_pi + phit)) * + math::pow((T(1) - sinphi) / (T(1) + sinphi), T(0.5) * eccen)); } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_stere_ellipsoid : public base_t_fi<base_stere_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_stere_ellipsoid + : public base_t_fi<base_stere_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_stere<CalculationType> m_proj_parm; + par_stere<T> m_proj_parm; inline base_stere_ellipsoid(const Parameters& par) - : base_t_fi<base_stere_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_stere_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType coslam, sinlam, sinX=0.0, cosX=0.0, X, A, sinphi; + T coslam, sinlam, sinX=0.0, cosX=0.0, X, A = 0.0, sinphi; coslam = cos(lp_lon); sinlam = sin(lp_lon); sinphi = sin(lp_lat); - if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) { - sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, this->m_par.e)) - HALFPI); + if (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit) { + sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, this->m_par.e)) - half_pi); cosX = cos(X); } switch (this->m_proj_parm.mode) { - case OBLIQ: + case obliq: A = this->m_proj_parm.akm1 / (this->m_proj_parm.cosX1 * (1. + this->m_proj_parm.sinX1 * sinX + this->m_proj_parm.cosX1 * cosX * coslam)); xy_y = A * (this->m_proj_parm.cosX1 * sinX - this->m_proj_parm.sinX1 * cosX * coslam); - goto xmul; - case EQUIT: - A = this->m_proj_parm.akm1 / (1. + cosX * coslam); - xy_y = A * sinX; + goto xmul; /* but why not just xy.x = A * cosX; break; ? */ + + case equit: + // TODO: calculate denominator once + /* avoid zero division */ + if (1. + cosX * coslam == 0.0) { + xy_y = HUGE_VAL; + } else { + A = this->m_proj_parm.akm1 / (1. + cosX * coslam); + xy_y = A * sinX; + } xmul: xy_x = A * cosX; break; - case S_POLE: + + case s_pole: lp_lat = -lp_lat; coslam = - coslam; sinphi = -sinphi; BOOST_FALLTHROUGH; - case N_POLE: + case n_pole: xy_x = this->m_proj_parm.akm1 * pj_tsfn(lp_lat, sinphi, this->m_par.e); xy_y = - xy_x * coslam; break; } + xy_x = xy_x * sinlam; } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0; + T cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0; int i; rho = boost::math::hypot(xy_x, xy_y); switch (this->m_proj_parm.mode) { - case OBLIQ: - case EQUIT: + case obliq: + case equit: cosphi = cos( tp = 2. * atan2(rho * this->m_proj_parm.cosX1 , this->m_proj_parm.akm1) ); sinphi = sin(tp); - if( rho == 0.0 ) + if( rho == 0.0 ) phi_l = asin(cosphi * this->m_proj_parm.sinX1); - else + else phi_l = asin(cosphi * this->m_proj_parm.sinX1 + (xy_y * sinphi * this->m_proj_parm.cosX1 / rho)); - tp = tan(.5 * (HALFPI + phi_l)); + tp = tan(.5 * (half_pi + phi_l)); xy_x *= sinphi; xy_y = rho * this->m_proj_parm.cosX1 * cosphi - xy_y * this->m_proj_parm.sinX1* sinphi; - halfpi = HALFPI; + halfpi = half_pi; halfe = .5 * this->m_par.e; break; - case N_POLE: + case n_pole: xy_y = -xy_y; BOOST_FALLTHROUGH; - case S_POLE: - phi_l = HALFPI - 2. * atan(tp = - rho / this->m_proj_parm.akm1); - halfpi = -HALFPI; + case s_pole: + phi_l = half_pi - 2. * atan(tp = - rho / this->m_proj_parm.akm1); + halfpi = -half_pi; halfe = -.5 * this->m_par.e; break; } - for (i = NITER; i--; phi_l = lp_lat) { + for (i = n_iter; i--; phi_l = lp_lat) { sinphi = this->m_par.e * sin(phi_l); - lp_lat = 2. * atan(tp * pow((1.+sinphi)/(1.-sinphi), halfe)) - halfpi; - if (fabs(phi_l - lp_lat) < CONV) { - if (this->m_proj_parm.mode == S_POLE) + lp_lat = T(2) * atan(tp * math::pow((T(1)+sinphi)/(T(1)-sinphi), halfe)) - halfpi; + if (fabs(phi_l - lp_lat) < conv_tolerance) { + if (this->m_proj_parm.mode == s_pole) lp_lat = -lp_lat; lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y); return; } } - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } static inline std::string get_name() @@ -204,54 +213,52 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_stere_spheroid : public base_t_fi<base_stere_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_stere_spheroid + : public base_t_fi<base_stere_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_stere<CalculationType> m_proj_parm; + par_stere<T> m_proj_parm; inline base_stere_spheroid(const Parameters& par) - : base_t_fi<base_stere_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_stere_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType sinphi, cosphi, coslam, sinlam; + T sinphi, cosphi, coslam, sinlam; sinphi = sin(lp_lat); cosphi = cos(lp_lat); coslam = cos(lp_lon); sinlam = sin(lp_lon); switch (this->m_proj_parm.mode) { - case EQUIT: + case equit: xy_y = 1. + cosphi * coslam; goto oblcon; - case OBLIQ: + case obliq: xy_y = 1. + this->m_proj_parm.sinX1 * sinphi + this->m_proj_parm.cosX1 * cosphi * coslam; oblcon: - if (xy_y <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (xy_y <= epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = (xy_y = this->m_proj_parm.akm1 / xy_y) * cosphi * sinlam; - xy_y *= (this->m_proj_parm.mode == EQUIT) ? sinphi : + xy_y *= (this->m_proj_parm.mode == equit) ? sinphi : this->m_proj_parm.cosX1 * sinphi - this->m_proj_parm.sinX1 * cosphi * coslam; break; - case N_POLE: + case n_pole: coslam = - coslam; lp_lat = - lp_lat; BOOST_FALLTHROUGH; - case S_POLE: - if (fabs(lp_lat - HALFPI) < TOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); - xy_x = sinlam * ( xy_y = this->m_proj_parm.akm1 * tan(FORTPI + .5 * lp_lat) ); + case s_pole: + if (fabs(lp_lat - half_pi) < tolerance) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } + xy_x = sinlam * ( xy_y = this->m_proj_parm.akm1 * tan(fourth_pi + .5 * lp_lat) ); xy_y *= coslam; break; } @@ -259,38 +266,39 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType c, rh, sinc, cosc; + T c, rh, sinc, cosc; sinc = sin(c = 2. * atan((rh = boost::math::hypot(xy_x, xy_y)) / this->m_proj_parm.akm1)); cosc = cos(c); lp_lon = 0.; + switch (this->m_proj_parm.mode) { - case EQUIT: - if (fabs(rh) <= EPS10) + case equit: + if (fabs(rh) <= epsilon10) lp_lat = 0.; else lp_lat = asin(xy_y * sinc / rh); if (cosc != 0. || xy_x != 0.) lp_lon = atan2(xy_x * sinc, cosc * rh); break; - case OBLIQ: - if (fabs(rh) <= EPS10) + case obliq: + if (fabs(rh) <= epsilon10) lp_lat = this->m_par.phi0; else lp_lat = asin(cosc * this->m_proj_parm.sinX1 + xy_y * sinc * this->m_proj_parm.cosX1 / rh); if ((c = cosc - this->m_proj_parm.sinX1 * sin(lp_lat)) != 0. || xy_x != 0.) lp_lon = atan2(xy_x * sinc * this->m_proj_parm.cosX1, c * rh); break; - case N_POLE: + case n_pole: xy_y = -xy_y; BOOST_FALLTHROUGH; - case S_POLE: - if (fabs(rh) <= EPS10) + case s_pole: + if (fabs(rh) <= epsilon10) lp_lat = this->m_par.phi0; else - lp_lat = asin(this->m_proj_parm.mode == S_POLE ? - cosc : cosc); + lp_lat = asin(this->m_proj_parm.mode == s_pole ? - cosc : cosc); lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y); break; } @@ -306,25 +314,26 @@ namespace projections template <typename Parameters, typename T> inline void setup(Parameters& par, par_stere<T>& proj_parm) /* general initialization */ { - static const T FORTPI = detail::FORTPI<T>(); - static const T HALFPI = detail::HALFPI<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T half_pi = detail::half_pi<T>(); T t; - if (fabs((t = fabs(par.phi0)) - HALFPI) < EPS10) - proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; + if (fabs((t = fabs(par.phi0)) - half_pi) < epsilon10) + proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; else - proj_parm.mode = t > EPS10 ? OBLIQ : EQUIT; + proj_parm.mode = t > epsilon10 ? obliq : equit; proj_parm.phits = fabs(proj_parm.phits); + if (par.es != 0.0) { T X; switch (proj_parm.mode) { - case N_POLE: - case S_POLE: - if (fabs(proj_parm.phits - HALFPI) < EPS10) + case n_pole: + case s_pole: + if (fabs(proj_parm.phits - half_pi) < epsilon10) proj_parm.akm1 = 2. * par.k0 / - sqrt(pow(1+par.e,1+par.e)*pow(1-par.e,1-par.e)); + sqrt(math::pow(T(1)+par.e,T(1)+par.e)*math::pow(T(1)-par.e,T(1)-par.e)); else { proj_parm.akm1 = cos(proj_parm.phits) / pj_tsfn(proj_parm.phits, t = sin(proj_parm.phits), par.e); @@ -332,12 +341,10 @@ namespace projections proj_parm.akm1 /= sqrt(1. - t * t); } break; - case EQUIT: - //proj_parm.akm1 = 2. * par.k0; - //break; - case OBLIQ: + case equit: + case obliq: t = sin(par.phi0); - X = 2. * atan(ssfn_(par.phi0, t, par.e)) - HALFPI; + X = 2. * atan(ssfn_(par.phi0, t, par.e)) - half_pi; t *= par.e; proj_parm.akm1 = 2. * par.k0 * cos(par.phi0) / sqrt(1. - t * t); proj_parm.sinX1 = sin(X); @@ -346,17 +353,17 @@ namespace projections } } else { switch (proj_parm.mode) { - case OBLIQ: + case obliq: proj_parm.sinX1 = sin(par.phi0); proj_parm.cosX1 = cos(par.phi0); BOOST_FALLTHROUGH; - case EQUIT: + case equit: proj_parm.akm1 = 2. * par.k0; break; - case S_POLE: - case N_POLE: - proj_parm.akm1 = fabs(proj_parm.phits - HALFPI) >= EPS10 ? - cos(proj_parm.phits) / tan(FORTPI - .5 * proj_parm.phits) : + case s_pole: + case n_pole: + proj_parm.akm1 = fabs(proj_parm.phits - half_pi) >= epsilon10 ? + cos(proj_parm.phits) / tan(fourth_pi - .5 * proj_parm.phits) : 2. * par.k0 ; break; } @@ -368,10 +375,11 @@ namespace projections template <typename Parameters, typename T> inline void setup_stere(Parameters& par, par_stere<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); + + if (! pj_param_r(par.params, "lat_ts", proj_parm.phits)) + proj_parm.phits = half_pi; - proj_parm.phits = pj_param(par.params, "tlat_ts").i ? - pj_param(par.params, "rlat_ts").f : HALFPI; setup(par, proj_parm); } @@ -379,17 +387,19 @@ namespace projections template <typename Parameters, typename T> inline void setup_ups(Parameters& par, par_stere<T>& proj_parm) { - static const T HALFPI = detail::HALFPI<T>(); + static const T half_pi = detail::half_pi<T>(); /* International Ellipsoid */ - par.phi0 = pj_param(par.params, "bsouth").i ? -HALFPI: HALFPI; - if (!par.es) - BOOST_THROW_EXCEPTION( projection_exception(-34) ); + par.phi0 = pj_get_param_b(par.params, "south") ? -half_pi: half_pi; + if (par.es == 0.0) { + BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) ); + } par.k0 = .994; par.x0 = 2000000.; par.y0 = 2000000.; - proj_parm.phits = HALFPI; + proj_parm.phits = half_pi; par.lam0 = 0.; + setup(par, proj_parm); } @@ -411,10 +421,10 @@ namespace projections \par Example \image html ex_stere.gif */ - template <typename CalculationType, typename Parameters> - struct stere_ellipsoid : public detail::stere::base_stere_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct stere_ellipsoid : public detail::stere::base_stere_ellipsoid<T, Parameters> { - inline stere_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<CalculationType, Parameters>(par) + inline stere_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<T, Parameters>(par) { detail::stere::setup_stere(this->m_par, this->m_proj_parm); } @@ -435,10 +445,10 @@ namespace projections \par Example \image html ex_stere.gif */ - template <typename CalculationType, typename Parameters> - struct stere_spheroid : public detail::stere::base_stere_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct stere_spheroid : public detail::stere::base_stere_spheroid<T, Parameters> { - inline stere_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<CalculationType, Parameters>(par) + inline stere_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<T, Parameters>(par) { detail::stere::setup_stere(this->m_par, this->m_proj_parm); } @@ -459,10 +469,10 @@ namespace projections \par Example \image html ex_ups.gif */ - template <typename CalculationType, typename Parameters> - struct ups_ellipsoid : public detail::stere::base_stere_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ups_ellipsoid : public detail::stere::base_stere_ellipsoid<T, Parameters> { - inline ups_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<CalculationType, Parameters>(par) + inline ups_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<T, Parameters>(par) { detail::stere::setup_ups(this->m_par, this->m_proj_parm); } @@ -483,10 +493,10 @@ namespace projections \par Example \image html ex_ups.gif */ - template <typename CalculationType, typename Parameters> - struct ups_spheroid : public detail::stere::base_stere_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct ups_spheroid : public detail::stere::base_stere_spheroid<T, Parameters> { - inline ups_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<CalculationType, Parameters>(par) + inline ups_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<T, Parameters>(par) { detail::stere::setup_ups(this->m_par, this->m_proj_parm); } @@ -501,37 +511,37 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ups, ups_spheroid, ups_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class stere_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class stere_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<stere_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<stere_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<stere_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<stere_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class ups_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class ups_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<ups_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<ups_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<ups_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<ups_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void stere_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void stere_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("stere", new stere_entry<CalculationType, Parameters>); - factory.add_to_factory("ups", new ups_entry<CalculationType, Parameters>); + factory.add_to_factory("stere", new stere_entry<T, Parameters>); + factory.add_to_factory("ups", new ups_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/sterea.hpp b/boost/geometry/srs/projections/proj/sterea.hpp index f9de2c6896..055be84e98 100644 --- a/boost/geometry/srs/projections/proj/sterea.hpp +++ b/boost/geometry/srs/projections/proj/sterea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -43,6 +39,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP + #include <boost/math/special_functions/hypot.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -57,7 +56,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct sterea {}; + struct sterea {}; // Oblique Stereographic Alternative }} //namespace srs::par4 @@ -67,40 +66,33 @@ namespace projections namespace detail { namespace sterea { - static const double DEL_TOL = 1.e-14; - static const int MAX_ITER = 10; - template <typename T> struct par_sterea { T phic0; T cosc0, sinc0; T R2; - gauss::GAUSS<T> en; + gauss<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_sterea_ellipsoid : public base_t_fi<base_sterea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_sterea_ellipsoid + : public base_t_fi<base_sterea_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_sterea<CalculationType> m_proj_parm; + par_sterea<T> m_proj_parm; inline base_sterea_ellipsoid(const Parameters& par) - : base_t_fi<base_sterea_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_sterea_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType cosc, sinc, cosl_, k; + T cosc, sinc, cosl_, k; - detail::gauss::gauss(m_proj_parm.en, lp_lon, lp_lat); + detail::gauss_fwd(m_proj_parm.en, lp_lon, lp_lat); sinc = sin(lp_lat); cosc = cos(lp_lat); cosl_ = cos(lp_lon); @@ -111,24 +103,24 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType rho, c, sinc, cosc; + T rho, c, sinc, cosc; xy_x /= this->m_par.k0; xy_y /= this->m_par.k0; - if((rho = boost::math::hypot(xy_x, xy_y))) { + if((rho = boost::math::hypot(xy_x, xy_y)) != 0.0) { c = 2. * atan2(rho, this->m_proj_parm.R2); sinc = sin(c); cosc = cos(c); lp_lat = asin(cosc * this->m_proj_parm.sinc0 + xy_y * sinc * this->m_proj_parm.cosc0 / rho); lp_lon = atan2(xy_x * sinc, rho * this->m_proj_parm.cosc0 * cosc - - xy_y * this->m_proj_parm.sinc0 * sinc); + xy_y * this->m_proj_parm.sinc0 * sinc); } else { lp_lat = this->m_proj_parm.phic0; lp_lon = 0.; } - detail::gauss::inv_gauss(m_proj_parm.en, lp_lon, lp_lat); + detail::gauss_inv(m_proj_parm.en, lp_lon, lp_lat); } static inline std::string get_name() @@ -144,7 +136,7 @@ namespace projections { T R; - proj_parm.en = detail::gauss::gauss_ini(par.e, par.phi0, proj_parm.phic0, R); + proj_parm.en = detail::gauss_ini(par.e, par.phi0, proj_parm.phic0, R); proj_parm.sinc0 = sin(proj_parm.phic0); proj_parm.cosc0 = cos(proj_parm.phic0); proj_parm.R2 = 2. * R; @@ -166,10 +158,10 @@ namespace projections \par Example \image html ex_sterea.gif */ - template <typename CalculationType, typename Parameters> - struct sterea_ellipsoid : public detail::sterea::base_sterea_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct sterea_ellipsoid : public detail::sterea::base_sterea_ellipsoid<T, Parameters> { - inline sterea_ellipsoid(const Parameters& par) : detail::sterea::base_sterea_ellipsoid<CalculationType, Parameters>(par) + inline sterea_ellipsoid(const Parameters& par) : detail::sterea::base_sterea_ellipsoid<T, Parameters>(par) { detail::sterea::setup_sterea(this->m_par, this->m_proj_parm); } @@ -183,20 +175,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::sterea, sterea_ellipsoid, sterea_ellipsoid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class sterea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class sterea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<sterea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<sterea_ellipsoid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void sterea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void sterea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("sterea", new sterea_entry<CalculationType, Parameters>); + factory.add_to_factory("sterea", new sterea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/sts.hpp b/boost/geometry/srs/projections/proj/sts.hpp index ca0d3f0cd1..73bef01626 100644 --- a/boost/geometry/srs/projections/proj/sts.hpp +++ b/boost/geometry/srs/projections/proj/sts.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_STS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_STS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_STS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STS_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,10 +51,10 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct kav5 {}; - struct qua_aut {}; - struct mbt_s {}; - struct fouc {}; + struct kav5 {}; // Kavraisky V + struct qua_aut {}; // Quartic Authalic + struct fouc {}; // Foucaut + struct mbt_s {}; // McBryde-Thomas Flat-Polar Sine (No. 1) }} //namespace srs::par4 @@ -68,29 +67,25 @@ namespace projections struct par_sts { T C_x, C_y, C_p; - int tan_mode; + bool tan_mode; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_sts_spheroid : public base_t_fi<base_sts_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_sts_spheroid + : public base_t_fi<base_sts_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_sts<CalculationType> m_proj_parm; + par_sts<T> m_proj_parm; inline base_sts_spheroid(const Parameters& par) - : base_t_fi<base_sts_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_sts_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType c; + T c; xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); xy_y = this->m_proj_parm.C_y; @@ -107,9 +102,9 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType c; + T c; xy_y /= this->m_proj_parm.C_y; c = cos(lp_lat = this->m_proj_parm.tan_mode ? atan(xy_y) : aasin(xy_y)); @@ -129,7 +124,7 @@ namespace projections }; template <typename Parameters, typename T> - inline void setup(Parameters& par, par_sts<T>& proj_parm, T const& p, T const& q, int mode) + inline void setup(Parameters& par, par_sts<T>& proj_parm, T const& p, T const& q, bool mode) { par.es = 0.; proj_parm.C_x = q / p; @@ -139,32 +134,32 @@ namespace projections } + // Foucaut + template <typename Parameters, typename T> + inline void setup_fouc(Parameters& par, par_sts<T>& proj_parm) + { + setup(par, proj_parm, 2., 2., true); + } + // Kavraisky V template <typename Parameters, typename T> inline void setup_kav5(Parameters& par, par_sts<T>& proj_parm) { - setup(par, proj_parm, 1.50488, 1.35439, 0); + setup(par, proj_parm, 1.50488, 1.35439, false); } // Quartic Authalic template <typename Parameters, typename T> inline void setup_qua_aut(Parameters& par, par_sts<T>& proj_parm) { - setup(par, proj_parm, 2., 2., 0); + setup(par, proj_parm, 2., 2., false); } // McBryde-Thomas Flat-Polar Sine (No. 1) template <typename Parameters, typename T> inline void setup_mbt_s(Parameters& par, par_sts<T>& proj_parm) { - setup(par, proj_parm, 1.48875, 1.36509, 0); - } - - // Foucaut - template <typename Parameters, typename T> - inline void setup_fouc(Parameters& par, par_sts<T>& proj_parm) - { - setup(par, proj_parm, 2., 2., 1); + setup(par, proj_parm, 1.48875, 1.36509, false); } }} // namespace detail::sts @@ -182,10 +177,10 @@ namespace projections \par Example \image html ex_kav5.gif */ - template <typename CalculationType, typename Parameters> - struct kav5_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct kav5_spheroid : public detail::sts::base_sts_spheroid<T, Parameters> { - inline kav5_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + inline kav5_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<T, Parameters>(par) { detail::sts::setup_kav5(this->m_par, this->m_proj_parm); } @@ -203,10 +198,10 @@ namespace projections \par Example \image html ex_qua_aut.gif */ - template <typename CalculationType, typename Parameters> - struct qua_aut_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct qua_aut_spheroid : public detail::sts::base_sts_spheroid<T, Parameters> { - inline qua_aut_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + inline qua_aut_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<T, Parameters>(par) { detail::sts::setup_qua_aut(this->m_par, this->m_proj_parm); } @@ -224,10 +219,10 @@ namespace projections \par Example \image html ex_mbt_s.gif */ - template <typename CalculationType, typename Parameters> - struct mbt_s_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct mbt_s_spheroid : public detail::sts::base_sts_spheroid<T, Parameters> { - inline mbt_s_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + inline mbt_s_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<T, Parameters>(par) { detail::sts::setup_mbt_s(this->m_par, this->m_proj_parm); } @@ -245,10 +240,10 @@ namespace projections \par Example \image html ex_fouc.gif */ - template <typename CalculationType, typename Parameters> - struct fouc_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct fouc_spheroid : public detail::sts::base_sts_spheroid<T, Parameters> { - inline fouc_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + inline fouc_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<T, Parameters>(par) { detail::sts::setup_fouc(this->m_par, this->m_proj_parm); } @@ -265,53 +260,53 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fouc, fouc_spheroid, fouc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class kav5_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class kav5_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<kav5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<kav5_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class qua_aut_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class qua_aut_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<qua_aut_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<qua_aut_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class mbt_s_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class mbt_s_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<mbt_s_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<mbt_s_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class fouc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class fouc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<fouc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<fouc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void sts_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void sts_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("kav5", new kav5_entry<CalculationType, Parameters>); - factory.add_to_factory("qua_aut", new qua_aut_entry<CalculationType, Parameters>); - factory.add_to_factory("mbt_s", new mbt_s_entry<CalculationType, Parameters>); - factory.add_to_factory("fouc", new fouc_entry<CalculationType, Parameters>); + factory.add_to_factory("kav5", new kav5_entry<T, Parameters>); + factory.add_to_factory("qua_aut", new qua_aut_entry<T, Parameters>); + factory.add_to_factory("mbt_s", new mbt_s_entry<T, Parameters>); + factory.add_to_factory("fouc", new fouc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/tcc.hpp b/boost/geometry/srs/projections/proj/tcc.hpp index 26cb62b3e8..34e386f91c 100644 --- a/boost/geometry/srs/projections/proj/tcc.hpp +++ b/boost/geometry/srs/projections/proj/tcc.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_TCC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_TCC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_TCC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TCC_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct tcc {}; + struct tcc {}; // Transverse Central Cylindrical }} //namespace srs::par4 @@ -61,30 +60,27 @@ namespace projections namespace detail { namespace tcc { - static const double EPS10 = 1.e-10; + static const double epsilon10 = 1.e-10; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_tcc_spheroid : public base_t_f<base_tcc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_tcc_spheroid + : public base_t_f<base_tcc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - inline base_tcc_spheroid(const Parameters& par) - : base_t_f<base_tcc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_tcc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType b, bt; + T b, bt; b = cos(lp_lat) * sin(lp_lon); - if ((bt = 1. - b * b) < EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((bt = 1. - b * b) < epsilon10) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } xy_x = b / sqrt(bt); xy_y = atan2(tan(lp_lat) , cos(lp_lon)); } @@ -119,10 +115,10 @@ namespace projections \par Example \image html ex_tcc.gif */ - template <typename CalculationType, typename Parameters> - struct tcc_spheroid : public detail::tcc::base_tcc_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tcc_spheroid : public detail::tcc::base_tcc_spheroid<T, Parameters> { - inline tcc_spheroid(const Parameters& par) : detail::tcc::base_tcc_spheroid<CalculationType, Parameters>(par) + inline tcc_spheroid(const Parameters& par) : detail::tcc::base_tcc_spheroid<T, Parameters>(par) { detail::tcc::setup_tcc(this->m_par); } @@ -136,20 +132,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tcc, tcc_spheroid, tcc_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class tcc_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tcc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<tcc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<tcc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void tcc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void tcc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("tcc", new tcc_entry<CalculationType, Parameters>); + factory.add_to_factory("tcc", new tcc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/tcea.hpp b/boost/geometry/srs/projections/proj/tcea.hpp index b87574e947..3eafcc262a 100644 --- a/boost/geometry/srs/projections/proj/tcea.hpp +++ b/boost/geometry/srs/projections/proj/tcea.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP -#define BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct tcea {}; + struct tcea {}; // Transverse Cylindrical Equal Area }} //namespace srs::par4 @@ -60,42 +59,30 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace tcea { - template <typename T> - struct par_tcea - { - T rk0; - }; - // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_tcea_spheroid : public base_t_fi<base_tcea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_tcea_spheroid + : public base_t_fi<base_tcea_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_tcea<CalculationType> m_proj_parm; - inline base_tcea_spheroid(const Parameters& par) - : base_t_fi<base_tcea_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_tcea_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - xy_x = this->m_proj_parm.rk0 * cos(lp_lat) * sin(lp_lon); + xy_x = cos(lp_lat) * sin(lp_lon) / this->m_par.k0; xy_y = this->m_par.k0 * (atan2(tan(lp_lat), cos(lp_lon)) - this->m_par.phi0); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType t; + T t; - xy_y = xy_y * this->m_proj_parm.rk0 + this->m_par.phi0; + xy_y = xy_y / this->m_par.k0 + this->m_par.phi0; xy_x *= this->m_par.k0; t = sqrt(1. - xy_x * xy_x); lp_lat = asin(t * sin(xy_y)); @@ -110,10 +97,9 @@ namespace projections }; // Transverse Cylindrical Equal Area - template <typename Parameters, typename T> - inline void setup_tcea(Parameters& par, par_tcea<T>& proj_parm) + template <typename Parameters> + inline void setup_tcea(Parameters& par) { - proj_parm.rk0 = 1 / par.k0; par.es = 0.; } @@ -132,12 +118,12 @@ namespace projections \par Example \image html ex_tcea.gif */ - template <typename CalculationType, typename Parameters> - struct tcea_spheroid : public detail::tcea::base_tcea_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tcea_spheroid : public detail::tcea::base_tcea_spheroid<T, Parameters> { - inline tcea_spheroid(const Parameters& par) : detail::tcea::base_tcea_spheroid<CalculationType, Parameters>(par) + inline tcea_spheroid(const Parameters& par) : detail::tcea::base_tcea_spheroid<T, Parameters>(par) { - detail::tcea::setup_tcea(this->m_par, this->m_proj_parm); + detail::tcea::setup_tcea(this->m_par); } }; @@ -149,20 +135,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tcea, tcea_spheroid, tcea_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class tcea_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tcea_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<tcea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tcea_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void tcea_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void tcea_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("tcea", new tcea_entry<CalculationType, Parameters>); + factory.add_to_factory("tcea", new tcea_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/tmerc.hpp b/boost/geometry/srs/projections/proj/tmerc.hpp index 6ed2902142..7c976f82d5 100644 --- a/boost/geometry/srs/projections/proj/tmerc.hpp +++ b/boost/geometry/srs/projections/proj/tmerc.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP -#define BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -56,8 +55,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct tmerc {}; - struct utm {}; + struct tmerc {}; // Transverse Mercator }} //namespace srs::par4 @@ -67,15 +65,7 @@ namespace projections namespace detail { namespace tmerc { - static const double EPS10 = 1.e-10; - //static const double FC1 = 1.; - //static const double FC2 = .5; - //static const double FC3 = .16666666666666666666; - //static const double FC4 = .08333333333333333333; - //static const double FC5 = .05; - //static const double FC6 = .03333333333333333333; - //static const double FC7 = .02380952380952380952; - //static const double FC8 = .01785714285714285714; + static const double epsilon10 = 1.e-10; template <typename T> inline T FC1() { return 1.; } @@ -99,39 +89,35 @@ namespace projections { T esp; T ml0; - T en[EN_SIZE]; + detail::en<T> en; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_tmerc_ellipsoid : public base_t_fi<base_tmerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_tmerc_ellipsoid + : public base_t_fi<base_tmerc_ellipsoid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_tmerc<CalculationType> m_proj_parm; + par_tmerc<T> m_proj_parm; inline base_tmerc_ellipsoid(const Parameters& par) - : base_t_fi<base_tmerc_ellipsoid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_tmerc_ellipsoid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(e_forward) ellipse // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType FC1 = tmerc::FC1<CalculationType>(); - static const CalculationType FC2 = tmerc::FC2<CalculationType>(); - static const CalculationType FC3 = tmerc::FC3<CalculationType>(); - static const CalculationType FC4 = tmerc::FC4<CalculationType>(); - static const CalculationType FC5 = tmerc::FC5<CalculationType>(); - static const CalculationType FC6 = tmerc::FC6<CalculationType>(); - static const CalculationType FC7 = tmerc::FC7<CalculationType>(); - static const CalculationType FC8 = tmerc::FC8<CalculationType>(); - - CalculationType al, als, n, cosphi, sinphi, t; + static const T half_pi = detail::half_pi<T>(); + static const T FC1 = tmerc::FC1<T>(); + static const T FC2 = tmerc::FC2<T>(); + static const T FC3 = tmerc::FC3<T>(); + static const T FC4 = tmerc::FC4<T>(); + static const T FC5 = tmerc::FC5<T>(); + static const T FC6 = tmerc::FC6<T>(); + static const T FC7 = tmerc::FC7<T>(); + static const T FC8 = tmerc::FC8<T>(); + + T al, als, n, cosphi, sinphi, t; /* * Fail if our longitude is more than 90 degrees from the @@ -140,11 +126,11 @@ namespace projections * * http://trac.osgeo.org/proj/ticket/5 */ - if( lp_lon < -HALFPI || lp_lon > HALFPI ) + if( lp_lon < -half_pi || lp_lon > half_pi ) { xy_x = HUGE_VAL; xy_y = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-14) ); + BOOST_THROW_EXCEPTION( projection_exception(error_lat_or_lon_exceed_limit) ); return; } @@ -171,23 +157,23 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType FC1 = tmerc::FC1<CalculationType>(); - static const CalculationType FC2 = tmerc::FC2<CalculationType>(); - static const CalculationType FC3 = tmerc::FC3<CalculationType>(); - static const CalculationType FC4 = tmerc::FC4<CalculationType>(); - static const CalculationType FC5 = tmerc::FC5<CalculationType>(); - static const CalculationType FC6 = tmerc::FC6<CalculationType>(); - static const CalculationType FC7 = tmerc::FC7<CalculationType>(); - static const CalculationType FC8 = tmerc::FC8<CalculationType>(); - - CalculationType n, con, cosphi, d, ds, sinphi, t; + static const T half_pi = detail::half_pi<T>(); + static const T FC1 = tmerc::FC1<T>(); + static const T FC2 = tmerc::FC2<T>(); + static const T FC3 = tmerc::FC3<T>(); + static const T FC4 = tmerc::FC4<T>(); + static const T FC5 = tmerc::FC5<T>(); + static const T FC6 = tmerc::FC6<T>(); + static const T FC7 = tmerc::FC7<T>(); + static const T FC8 = tmerc::FC8<T>(); + + T n, con, cosphi, d, ds, sinphi, t; lp_lat = pj_inv_mlfn(this->m_proj_parm.ml0 + xy_y / this->m_par.k0, this->m_par.es, this->m_proj_parm.en); - if (fabs(lp_lat) >= HALFPI) { - lp_lat = xy_y < 0. ? -HALFPI : HALFPI; + if (fabs(lp_lat) >= half_pi) { + lp_lat = xy_y < 0. ? -half_pi : half_pi; lp_lon = 0.; } else { sinphi = sin(lp_lat); @@ -220,27 +206,23 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_tmerc_spheroid : public base_t_fi<base_tmerc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_tmerc_spheroid + : public base_t_fi<base_tmerc_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_tmerc<CalculationType> m_proj_parm; + par_tmerc<T> m_proj_parm; inline base_tmerc_spheroid(const Parameters& par) - : base_t_fi<base_tmerc_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_tmerc_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); - CalculationType b, cosphi; + T b, cosphi; /* * Fail if our longitude is more than 90 degrees from the @@ -249,26 +231,26 @@ namespace projections * * http://trac.osgeo.org/proj/ticket/5 */ - if( lp_lon < -HALFPI || lp_lon > HALFPI ) + if( lp_lon < -half_pi || lp_lon > half_pi ) { xy_x = HUGE_VAL; xy_y = HUGE_VAL; - BOOST_THROW_EXCEPTION( projection_exception(-14) ); + BOOST_THROW_EXCEPTION( projection_exception(error_lat_or_lon_exceed_limit) ); return; } cosphi = cos(lp_lat); b = cosphi * sin(lp_lon); - if (fabs(fabs(b) - 1.) <= EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (fabs(fabs(b) - 1.) <= epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); xy_x = this->m_proj_parm.ml0 * log((1. + b) / (1. - b)); xy_y = cosphi * cos(lp_lon) / sqrt(1. - b * b); b = fabs( xy_y ); if (b >= 1.) { - if ((b - 1.) > EPS10) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if ((b - 1.) > epsilon10) + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); else xy_y = 0.; } else xy_y = acos(xy_y); @@ -280,16 +262,19 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType h, g; + T h, g; h = exp(xy_x / this->m_proj_parm.esp); g = .5 * (h - 1. / h); h = cos(this->m_par.phi0 + xy_y / this->m_proj_parm.esp); lp_lat = asin(sqrt((1. - h * h) / (1. + g * g))); - if (xy_y < 0.) lp_lat = -lp_lat; - lp_lon = (g || h) ? atan2(g, h) : 0.; + + /* Make sure that phi is on the correct hemisphere when false northing is used */ + if (xy_y < 0. && -lp_lat+this->m_par.phi0 < 0.0) lp_lat = -lp_lat; + + lp_lon = (g != 0.0 || h != 0.0) ? atan2(g, h) : 0.; } static inline std::string get_name() @@ -300,11 +285,10 @@ namespace projections }; template <typename Parameters, typename T> - inline void setup(Parameters& par, par_tmerc<T>& proj_parm) /* general initialization */ + inline void setup(Parameters& par, par_tmerc<T>& proj_parm) { - if (par.es) { - if (!pj_enfn(par.es, proj_parm.en)) - BOOST_THROW_EXCEPTION( projection_exception(0) ); + if (par.es != 0.0) { + proj_parm.en = pj_enfn<T>(par.es); proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en); proj_parm.esp = par.es / (1. - par.es); } else { @@ -313,40 +297,6 @@ namespace projections } } - - // Transverse Mercator - template <typename Parameters, typename T> - inline void setup_tmerc(Parameters& par, par_tmerc<T>& proj_parm) - { - setup(par, proj_parm); - } - - // Universal Transverse Mercator (UTM) - template <typename Parameters, typename T> - inline void setup_utm(Parameters& par, par_tmerc<T>& proj_parm) - { - static const T ONEPI = detail::ONEPI<T>(); - - int zone; - - par.y0 = pj_param(par.params, "bsouth").i ? 10000000. : 0.; - par.x0 = 500000.; - if (pj_param(par.params, "tzone").i) /* zone input ? */ - if ((zone = pj_param(par.params, "izone").i) > 0 && zone <= 60) - --zone; - else - BOOST_THROW_EXCEPTION( projection_exception(-35) ); - else /* nearest central meridian input */ - if ((zone = int_floor((adjlon(par.lam0) + ONEPI) * 30. / ONEPI)) < 0) - zone = 0; - else if (zone >= 60) - zone = 59; - par.lam0 = (zone + .5) * ONEPI / 30. - ONEPI; - par.k0 = 0.9996; - par.phi0 = 0.; - setup(par, proj_parm); - } - }} // namespace detail::tmerc #endif // doxygen @@ -363,12 +313,12 @@ namespace projections \par Example \image html ex_tmerc.gif */ - template <typename CalculationType, typename Parameters> - struct tmerc_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tmerc_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<T, Parameters> { - inline tmerc_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters>(par) + inline tmerc_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<T, Parameters>(par) { - detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm); + detail::tmerc::setup(this->m_par, this->m_proj_parm); } }; @@ -385,60 +335,12 @@ namespace projections \par Example \image html ex_tmerc.gif */ - template <typename CalculationType, typename Parameters> - struct tmerc_spheroid : public detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters> - { - inline tmerc_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters>(par) - { - detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm); - } - }; - - /*! - \brief Universal Transverse Mercator (UTM) projection - \ingroup projections - \tparam Geographic latlong point type - \tparam Cartesian xy point type - \tparam Parameters parameter type - \par Projection characteristics - - Cylindrical - - Spheroid - \par Projection parameters - - zone: UTM Zone (integer) - - south: Denotes southern hemisphere UTM zone (boolean) - \par Example - \image html ex_utm.gif - */ - template <typename CalculationType, typename Parameters> - struct utm_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tmerc_spheroid : public detail::tmerc::base_tmerc_spheroid<T, Parameters> { - inline utm_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters>(par) + inline tmerc_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<T, Parameters>(par) { - detail::tmerc::setup_utm(this->m_par, this->m_proj_parm); - } - }; - - /*! - \brief Universal Transverse Mercator (UTM) projection - \ingroup projections - \tparam Geographic latlong point type - \tparam Cartesian xy point type - \tparam Parameters parameter type - \par Projection characteristics - - Cylindrical - - Spheroid - \par Projection parameters - - zone: UTM Zone (integer) - - south: Denotes southern hemisphere UTM zone (boolean) - \par Example - \image html ex_utm.gif - */ - template <typename CalculationType, typename Parameters> - struct utm_spheroid : public detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters> - { - inline utm_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters>(par) - { - detail::tmerc::setup_utm(this->m_par, this->m_proj_parm); + detail::tmerc::setup(this->m_par, this->m_proj_parm); } }; @@ -448,40 +350,25 @@ namespace projections // Static projection BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tmerc, tmerc_spheroid, tmerc_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::utm, utm_spheroid, utm_ellipsoid) // Factory entry(s) - dynamic projection - template <typename CalculationType, typename Parameters> - class tmerc_entry : public detail::factory_entry<CalculationType, Parameters> - { - public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const - { - if (par.es) - return new base_v_fi<tmerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); - else - return new base_v_fi<tmerc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); - } - }; - - template <typename CalculationType, typename Parameters> - class utm_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tmerc_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { if (par.es) - return new base_v_fi<utm_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tmerc_ellipsoid<T, Parameters>, T, Parameters>(par); else - return new base_v_fi<utm_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tmerc_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void tmerc_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void tmerc_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("tmerc", new tmerc_entry<CalculationType, Parameters>); - factory.add_to_factory("utm", new utm_entry<CalculationType, Parameters>); + factory.add_to_factory("tmerc", new tmerc_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/tpeqd.hpp b/boost/geometry/srs/projections/proj/tpeqd.hpp index 2d08d49bde..1e8447076a 100644 --- a/boost/geometry/srs/projections/proj/tpeqd.hpp +++ b/boost/geometry/srs/projections/proj/tpeqd.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP -#define BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP + #include <boost/geometry/util/math.hpp> #include <boost/math/special_functions/hypot.hpp> @@ -55,7 +54,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct tpeqd {}; + struct tpeqd {}; // Two Point Equidistant }} //namespace srs::par4 @@ -72,25 +71,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_tpeqd_spheroid : public base_t_fi<base_tpeqd_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_tpeqd_spheroid + : public base_t_fi<base_tpeqd_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_tpeqd<CalculationType> m_proj_parm; + par_tpeqd<T> m_proj_parm; inline base_tpeqd_spheroid(const Parameters& par) - : base_t_fi<base_tpeqd_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_tpeqd_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType t, z1, z2, dl1, dl2, sp, cp; + T t, z1, z2, dl1, dl2, sp, cp; sp = sin(lp_lat); cp = cos(lp_lat); @@ -98,6 +93,7 @@ namespace projections z2 = aacos(this->m_proj_parm.sp2 * sp + this->m_proj_parm.cp2 * cp * cos(dl2 = lp_lon - this->m_proj_parm.dlam2)); z1 *= z1; z2 *= z2; + xy_x = this->m_proj_parm.r2z0 * (t = z1 - z2); t = this->m_proj_parm.z02 - t; xy_y = this->m_proj_parm.r2z0 * asqrt(4. * this->m_proj_parm.z02 * z2 - t * t); @@ -107,9 +103,9 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - CalculationType cz1, cz2, s, d, cp, sp; + T cz1, cz2, s, d, cp, sp; cz1 = cos(boost::math::hypot(xy_y, xy_x + this->m_proj_parm.hz0)); cz2 = cos(boost::math::hypot(xy_y, xy_x - this->m_proj_parm.hz0)); @@ -140,14 +136,17 @@ namespace projections T lam_1, lam_2, phi_1, phi_2, A12, pp; /* get control point locations */ - phi_1 = pj_param(par.params, "rlat_1").f; - lam_1 = pj_param(par.params, "rlon_1").f; - phi_2 = pj_param(par.params, "rlat_2").f; - lam_2 = pj_param(par.params, "rlon_2").f; + phi_1 = pj_get_param_r(par.params, "lat_1"); + lam_1 = pj_get_param_r(par.params, "lon_1"); + phi_2 = pj_get_param_r(par.params, "lat_2"); + lam_2 = pj_get_param_r(par.params, "lon_2"); + if (phi_1 == phi_2 && lam_1 == lam_2) - BOOST_THROW_EXCEPTION( projection_exception(-25) ); + BOOST_THROW_EXCEPTION( projection_exception(error_control_point_no_dist) ); + par.lam0 = adjlon(0.5 * (lam_1 + lam_2)); proj_parm.dlam2 = adjlon(lam_2 - lam_1); + proj_parm.cp1 = cos(phi_1); proj_parm.cp2 = cos(phi_2); proj_parm.sp1 = sin(phi_1); @@ -168,6 +167,7 @@ namespace projections proj_parm.rhshz0 = .5 / sin(proj_parm.hz0); proj_parm.r2z0 = 0.5 / proj_parm.z02; proj_parm.z02 *= proj_parm.z02; + par.es = 0.; } @@ -191,10 +191,10 @@ namespace projections \par Example \image html ex_tpeqd.gif */ - template <typename CalculationType, typename Parameters> - struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid<T, Parameters> { - inline tpeqd_spheroid(const Parameters& par) : detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters>(par) + inline tpeqd_spheroid(const Parameters& par) : detail::tpeqd::base_tpeqd_spheroid<T, Parameters>(par) { detail::tpeqd::setup_tpeqd(this->m_par, this->m_proj_parm); } @@ -208,20 +208,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tpeqd, tpeqd_spheroid, tpeqd_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class tpeqd_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class tpeqd_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<tpeqd_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<tpeqd_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void tpeqd_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void tpeqd_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("tpeqd", new tpeqd_entry<CalculationType, Parameters>); + factory.add_to_factory("tpeqd", new tpeqd_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/urm5.hpp b/boost/geometry/srs/projections/proj/urm5.hpp index 96b541f4ea..bdda5fc400 100644 --- a/boost/geometry/srs/projections/proj/urm5.hpp +++ b/boost/geometry/srs/projections/proj/urm5.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_URM5_HPP -#define BOOST_GEOMETRY_PROJECTIONS_URM5_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_URM5_HPP +#define BOOST_GEOMETRY_PROJECTIONS_URM5_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct urm5 {}; + struct urm5 {}; // Urmaev V }} //namespace srs::par4 @@ -68,25 +67,21 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_urm5_spheroid : public base_t_f<base_urm5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_urm5_spheroid + : public base_t_f<base_urm5_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_urm5<CalculationType> m_proj_parm; + par_urm5<T> m_proj_parm; inline base_urm5_spheroid(const Parameters& par) - : base_t_f<base_urm5_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_urm5_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType t; + T t; t = lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat)); xy_x = this->m_proj_parm.m * lp_lon * cos(lp_lat); @@ -107,17 +102,18 @@ namespace projections { T alpha, t; - if (pj_param(par.params, "tn").i) { - proj_parm.n = pj_param(par.params, "dn").f; + if (pj_param_f(par.params, "n", proj_parm.n)) { if (proj_parm.n <= 0. || proj_parm.n > 1.) - BOOST_THROW_EXCEPTION( projection_exception(-40) ); - } else - BOOST_THROW_EXCEPTION( projection_exception(-40) ); - proj_parm.q3 = pj_param(par.params, "dq").f / 3.; - alpha = pj_param(par.params, "ralpha").f; + BOOST_THROW_EXCEPTION( projection_exception(error_n_out_of_range) ); + } else { + BOOST_THROW_EXCEPTION( projection_exception(error_n_out_of_range) ); + } + proj_parm.q3 = pj_get_param_f(par.params, "q") / 3.; + alpha = pj_get_param_r(par.params, "alpha"); t = proj_parm.n * sin(alpha); proj_parm.m = cos(alpha) / sqrt(1. - t * t); proj_parm.rmn = 1. / (proj_parm.m * proj_parm.n); + par.es = 0.; } @@ -141,10 +137,10 @@ namespace projections \par Example \image html ex_urm5.gif */ - template <typename CalculationType, typename Parameters> - struct urm5_spheroid : public detail::urm5::base_urm5_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct urm5_spheroid : public detail::urm5::base_urm5_spheroid<T, Parameters> { - inline urm5_spheroid(const Parameters& par) : detail::urm5::base_urm5_spheroid<CalculationType, Parameters>(par) + inline urm5_spheroid(const Parameters& par) : detail::urm5::base_urm5_spheroid<T, Parameters>(par) { detail::urm5::setup_urm5(this->m_par, this->m_proj_parm); } @@ -158,20 +154,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::urm5, urm5_spheroid, urm5_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class urm5_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class urm5_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<urm5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<urm5_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void urm5_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void urm5_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("urm5", new urm5_entry<CalculationType, Parameters>); + factory.add_to_factory("urm5", new urm5_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/urmfps.hpp b/boost/geometry/srs/projections/proj/urmfps.hpp index 14840057dc..d4b303ba37 100644 --- a/boost/geometry/srs/projections/proj/urmfps.hpp +++ b/boost/geometry/srs/projections/proj/urmfps.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP -#define BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,8 +51,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct urmfps {}; - struct wag1 {}; + struct urmfps {}; // Urmaev Flat-Polar Sinusoidal + struct wag1 {}; // Wagner I (Kavraisky VI) }} //namespace srs::par4 @@ -73,23 +72,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_urmfps_spheroid : public base_t_fi<base_urmfps_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_urmfps_spheroid + : public base_t_fi<base_urmfps_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_urmfps<CalculationType> m_proj_parm; + par_urmfps<T> m_proj_parm; inline base_urmfps_spheroid(const Parameters& par) - : base_t_fi<base_urmfps_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_urmfps_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat)); xy_x = C_x * lp_lon * cos(lp_lat); @@ -98,7 +93,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { xy_y /= this->m_proj_parm.C_y; lp_lat = aasin(sin(xy_y) / this->m_proj_parm.n); @@ -124,12 +119,12 @@ namespace projections template <typename Parameters, typename T> inline void setup_urmfps(Parameters& par, par_urmfps<T>& proj_parm) { - if (pj_param(par.params, "tn").i) { - proj_parm.n = pj_param(par.params, "dn").f; + if (pj_param_f(par.params, "n", proj_parm.n)) { if (proj_parm.n <= 0. || proj_parm.n > 1.) - BOOST_THROW_EXCEPTION( projection_exception(-40) ); + BOOST_THROW_EXCEPTION( projection_exception(error_n_out_of_range) ); } else - BOOST_THROW_EXCEPTION( projection_exception(-40) ); + BOOST_THROW_EXCEPTION( projection_exception(error_n_out_of_range) ); + setup(par, proj_parm); } @@ -158,10 +153,10 @@ namespace projections \par Example \image html ex_urmfps.gif */ - template <typename CalculationType, typename Parameters> - struct urmfps_spheroid : public detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct urmfps_spheroid : public detail::urmfps::base_urmfps_spheroid<T, Parameters> { - inline urmfps_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters>(par) + inline urmfps_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<T, Parameters>(par) { detail::urmfps::setup_urmfps(this->m_par, this->m_proj_parm); } @@ -179,10 +174,10 @@ namespace projections \par Example \image html ex_wag1.gif */ - template <typename CalculationType, typename Parameters> - struct wag1_spheroid : public detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag1_spheroid : public detail::urmfps::base_urmfps_spheroid<T, Parameters> { - inline wag1_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters>(par) + inline wag1_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<T, Parameters>(par) { detail::urmfps::setup_wag1(this->m_par, this->m_proj_parm); } @@ -197,31 +192,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag1, wag1_spheroid, wag1_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class urmfps_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class urmfps_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<urmfps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<urmfps_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class wag1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void urmfps_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void urmfps_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("urmfps", new urmfps_entry<CalculationType, Parameters>); - factory.add_to_factory("wag1", new wag1_entry<CalculationType, Parameters>); + factory.add_to_factory("urmfps", new urmfps_entry<T, Parameters>); + factory.add_to_factory("wag1", new wag1_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/vandg.hpp b/boost/geometry/srs/projections/proj/vandg.hpp index 1fd95285ea..4124ca2354 100644 --- a/boost/geometry/srs/projections/proj/vandg.hpp +++ b/boost/geometry/srs/projections/proj/vandg.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP -#define BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017, 2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -63,14 +62,7 @@ namespace projections namespace detail { namespace vandg { - static const double TOL = 1.e-10; - //static const double THIRD = .33333333333333333333; - //static const double TWO_THRD = .66666666666666666666; - //static const double C2_27 = .07407407407407407407; - //static const double PI4_3 = 4.18879020478639098458; - //static const double PISQ = 9.86960440108935861869; - //static const double TPISQ = 19.73920880217871723738; - //static const double HPISQ = 4.93480220054467930934; + static const double tolerance = 1.e-10; template <typename T> inline T C2_27() { return .07407407407407407407407407407407; } @@ -82,42 +74,38 @@ namespace projections inline T HPISQ() { return 4.9348022005446793094172454999381; } // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_vandg_spheroid : public base_t_fi<base_vandg_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_vandg_spheroid + : public base_t_fi<base_vandg_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_vandg_spheroid(const Parameters& par) - : base_t_fi<base_vandg_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_vandg_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); - CalculationType al, al2, g, g2, p2; + T al, al2, g, g2, p2; - p2 = fabs(lp_lat / HALFPI); - if ((p2 - TOL) > 1.) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + p2 = fabs(lp_lat / half_pi); + if ((p2 - tolerance) > 1.) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } if (p2 > 1.) p2 = 1.; - if (fabs(lp_lat) <= TOL) { + if (fabs(lp_lat) <= tolerance) { xy_x = lp_lon; xy_y = 0.; - } else if (fabs(lp_lon) <= TOL || fabs(p2 - 1.) < TOL) { + } else if (fabs(lp_lon) <= tolerance || fabs(p2 - 1.) < tolerance) { xy_x = 0.; - xy_y = ONEPI * tan(.5 * asin(p2)); + xy_y = pi * tan(.5 * asin(p2)); if (lp_lat < 0.) xy_y = -xy_y; } else { - al = .5 * fabs(ONEPI / lp_lon - lp_lon / ONEPI); + al = .5 * fabs(pi / lp_lon - lp_lon / pi); al2 = al * al; g = sqrt(1. - p2 * p2); g = g / (p2 + g - 1.); @@ -125,63 +113,65 @@ namespace projections p2 = g * (2. / p2 - 1.); p2 = p2 * p2; xy_x = g - p2; g = p2 + al2; - xy_x = ONEPI * (al * xy_x + sqrt(al2 * xy_x * xy_x - g * (g2 - p2))) / g; + xy_x = pi * (al * xy_x + sqrt(al2 * xy_x * xy_x - g * (g2 - p2))) / g; if (lp_lon < 0.) xy_x = -xy_x; - xy_y = fabs(xy_x / ONEPI); + xy_y = fabs(xy_x / pi); xy_y = 1. - xy_y * (xy_y + 2. * al); - if (xy_y < -TOL) - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (xy_y < -tolerance) { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } if (xy_y < 0.) xy_y = 0.; else - xy_y = sqrt(xy_y) * (lp_lat < 0. ? -ONEPI : ONEPI); + xy_y = sqrt(xy_y) * (lp_lat < 0. ? -pi : pi); } } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - static const CalculationType PISQ = detail::PI_SQR<CalculationType>(); - static const CalculationType THIRD = detail::THIRD<CalculationType>(); - static const CalculationType TWOPI = detail::TWOPI<CalculationType>(); - - static const CalculationType C2_27 = vandg::C2_27<CalculationType>(); - static const CalculationType PI4_3 = vandg::PI4_3<CalculationType>(); - static const CalculationType TPISQ = vandg::TPISQ<CalculationType>(); - static const CalculationType HPISQ = vandg::HPISQ<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T pi = detail::pi<T>(); + static const T pi_sqr = detail::pi_sqr<T>(); + static const T third = detail::third<T>(); + static const T two_pi = detail::two_pi<T>(); + + static const T C2_27 = vandg::C2_27<T>(); + static const T PI4_3 = vandg::PI4_3<T>(); + static const T TPISQ = vandg::TPISQ<T>(); + static const T HPISQ = vandg::HPISQ<T>(); - CalculationType t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2; + T t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2; x2 = xy_x * xy_x; - if ((ay = fabs(xy_y)) < TOL) { + if ((ay = fabs(xy_y)) < tolerance) { lp_lat = 0.; t = x2 * x2 + TPISQ * (x2 + HPISQ); - lp_lon = fabs(xy_x) <= TOL ? 0. : - .5 * (x2 - PISQ + sqrt(t)) / xy_x; + lp_lon = fabs(xy_x) <= tolerance ? 0. : + .5 * (x2 - pi_sqr + sqrt(t)) / xy_x; return; } y2 = xy_y * xy_y; r = x2 + y2; r2 = r * r; - c1 = - ONEPI * ay * (r + PISQ); - c3 = r2 + TWOPI * (ay * r + ONEPI * (y2 + ONEPI * (ay + HALFPI))); - c2 = c1 + PISQ * (r - 3. * y2); - c0 = ONEPI * ay; + c1 = - pi * ay * (r + pi_sqr); + c3 = r2 + two_pi * (ay * r + pi * (y2 + pi * (ay + half_pi))); + c2 = c1 + pi_sqr * (r - 3. * y2); + c0 = pi * ay; c2 /= c3; - al = c1 / c3 - THIRD * c2 * c2; - m = 2. * sqrt(-THIRD * al); - d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3; - if (((t = fabs(d = 3. * d / (al * m))) - TOL) <= 1.) { - d = t > 1. ? (d > 0. ? 0. : ONEPI) : acos(d); - lp_lat = ONEPI * (m * cos(d * THIRD + PI4_3) - THIRD * c2); + al = c1 / c3 - third * c2 * c2; + m = 2. * sqrt(-third * al); + d = C2_27 * c2 * c2 * c2 + (c0 * c0 - third * c2 * c1) / c3; + if (((t = fabs(d = 3. * d / (al * m))) - tolerance) <= 1.) { + d = t > 1. ? (d > 0. ? 0. : pi) : acos(d); + lp_lat = pi * (m * cos(d * third + PI4_3) - third * c2); if (xy_y < 0.) lp_lat = -lp_lat; t = r2 + TPISQ * (x2 - y2 + HPISQ); - lp_lon = fabs(xy_x) <= TOL ? 0. : - .5 * (r - PISQ + (t <= 0. ? 0. : sqrt(t))) / xy_x; - } else - BOOST_THROW_EXCEPTION( projection_exception(-20) ); + lp_lon = fabs(xy_x) <= tolerance ? 0. : + .5 * (r - pi_sqr + (t <= 0. ? 0. : sqrt(t))) / xy_x; + } else { + BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); + } } static inline std::string get_name() @@ -213,10 +203,10 @@ namespace projections \par Example \image html ex_vandg.gif */ - template <typename CalculationType, typename Parameters> - struct vandg_spheroid : public detail::vandg::base_vandg_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct vandg_spheroid : public detail::vandg::base_vandg_spheroid<T, Parameters> { - inline vandg_spheroid(const Parameters& par) : detail::vandg::base_vandg_spheroid<CalculationType, Parameters>(par) + inline vandg_spheroid(const Parameters& par) : detail::vandg::base_vandg_spheroid<T, Parameters>(par) { detail::vandg::setup_vandg(this->m_par); } @@ -230,20 +220,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg, vandg_spheroid, vandg_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class vandg_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class vandg_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<vandg_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<vandg_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void vandg_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void vandg_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("vandg", new vandg_entry<CalculationType, Parameters>); + factory.add_to_factory("vandg", new vandg_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/vandg2.hpp b/boost/geometry/srs/projections/proj/vandg2.hpp index 650a64f432..a1af0302a7 100644 --- a/boost/geometry/srs/projections/proj/vandg2.hpp +++ b/boost/geometry/srs/projections/proj/vandg2.hpp @@ -1,8 +1,4 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP -#define BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,8 +52,8 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct vandg2 {}; - struct vandg3 {}; + struct vandg2 {}; // van der Grinten II + struct vandg3 {}; // van der Grinten III }} //namespace srs::par4 @@ -64,57 +63,52 @@ namespace projections namespace detail { namespace vandg2 { - static const double TOL = 1e-10; - //static const double TWORPI = 0.63661977236758134308; + static const double tolerance = 1e-10; struct par_vandg2 { - int vdg3; + bool vdg3; }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_vandg2_spheroid : public base_t_f<base_vandg2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_vandg2_spheroid + : public base_t_f<base_vandg2_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - par_vandg2 m_proj_parm; inline base_vandg2_spheroid(const Parameters& par) - : base_t_f<base_vandg2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_vandg2_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - static const CalculationType TWORPI = detail::TWO_D_PI<CalculationType>(); + static const T pi = detail::pi<T>(); + static const T two_div_pi = detail::two_div_pi<T>(); - CalculationType x1, at, bt, ct; + T x1, at, bt, ct; - bt = fabs(TWORPI * lp_lat); + bt = fabs(two_div_pi * lp_lat); if ((ct = 1. - bt * bt) < 0.) ct = 0.; else ct = sqrt(ct); - if (fabs(lp_lon) < TOL) { + if (fabs(lp_lon) < tolerance) { xy_x = 0.; - xy_y = ONEPI * (lp_lat < 0. ? -bt : bt) / (1. + ct); + xy_y = pi * (lp_lat < 0. ? -bt : bt) / (1. + ct); } else { - at = 0.5 * fabs(ONEPI / lp_lon - lp_lon / ONEPI); + at = 0.5 * fabs(pi / lp_lon - lp_lon / pi); if (this->m_proj_parm.vdg3) { x1 = bt / (1. + ct); - xy_x = ONEPI * (sqrt(at * at + 1. - x1 * x1) - at); - xy_y = ONEPI * x1; + xy_x = pi * (sqrt(at * at + 1. - x1 * x1) - at); + xy_y = pi * x1; } else { x1 = (ct * sqrt(1. + at * at) - at * ct * ct) / (1. + at * at * bt * bt); - xy_x = ONEPI * x1; - xy_y = ONEPI * sqrt(1. - x1 * (x1 + 2. * at) + TOL); + xy_x = pi * x1; + xy_y = pi * sqrt(1. - x1 * (x1 + 2. * at) + tolerance); } if ( lp_lon < 0.) xy_x = -xy_x; if ( lp_lat < 0.) xy_y = -xy_y; @@ -132,14 +126,14 @@ namespace projections template <typename Parameters> inline void setup_vandg2(Parameters& /*par*/, par_vandg2& proj_parm) { - proj_parm.vdg3 = 0; + proj_parm.vdg3 = false; } // van der Grinten III template <typename Parameters> inline void setup_vandg3(Parameters& par, par_vandg2& proj_parm) { - proj_parm.vdg3 = 1; + proj_parm.vdg3 = true; par.es = 0.; } @@ -159,10 +153,10 @@ namespace projections \par Example \image html ex_vandg2.gif */ - template <typename CalculationType, typename Parameters> - struct vandg2_spheroid : public detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct vandg2_spheroid : public detail::vandg2::base_vandg2_spheroid<T, Parameters> { - inline vandg2_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters>(par) + inline vandg2_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<T, Parameters>(par) { detail::vandg2::setup_vandg2(this->m_par, this->m_proj_parm); } @@ -181,10 +175,10 @@ namespace projections \par Example \image html ex_vandg3.gif */ - template <typename CalculationType, typename Parameters> - struct vandg3_spheroid : public detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct vandg3_spheroid : public detail::vandg2::base_vandg2_spheroid<T, Parameters> { - inline vandg3_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters>(par) + inline vandg3_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<T, Parameters>(par) { detail::vandg2::setup_vandg3(this->m_par, this->m_proj_parm); } @@ -199,31 +193,31 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg3, vandg3_spheroid, vandg3_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class vandg2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class vandg2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<vandg2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<vandg2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - class vandg3_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class vandg3_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<vandg3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<vandg3_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void vandg2_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void vandg2_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("vandg2", new vandg2_entry<CalculationType, Parameters>); - factory.add_to_factory("vandg3", new vandg3_entry<CalculationType, Parameters>); + factory.add_to_factory("vandg2", new vandg2_entry<T, Parameters>); + factory.add_to_factory("vandg3", new vandg3_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/vandg4.hpp b/boost/geometry/srs/projections/proj/vandg4.hpp index 0b85fedef4..35f1dafdb0 100644 --- a/boost/geometry/srs/projections/proj/vandg4.hpp +++ b/boost/geometry/srs/projections/proj/vandg4.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP -#define BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct vandg4 {}; + struct vandg4 {}; // van der Grinten IV }} //namespace srs::par4 @@ -63,48 +62,42 @@ namespace projections namespace detail { namespace vandg4 { - static const double TOL = 1e-10; - //static const double TWORPI = 0.63661977236758134308; + static const double tolerance = 1e-10; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_vandg4_spheroid : public base_t_f<base_vandg4_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_vandg4_spheroid + : public base_t_f<base_vandg4_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_vandg4_spheroid(const Parameters& par) - : base_t_f<base_vandg4_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_vandg4_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType TWORPI = detail::TWO_D_PI<CalculationType>(); + static const T half_pi = detail::half_pi<T>(); + static const T two_div_pi = detail::two_div_pi<T>(); - CalculationType x1, t, bt, ct, ft, bt2, ct2, dt, dt2; + T x1, t, bt, ct, ft, bt2, ct2, dt, dt2; - if (fabs(lp_lat) < TOL) { + if (fabs(lp_lat) < tolerance) { xy_x = lp_lon; xy_y = 0.; - } else if (fabs(lp_lon) < TOL || fabs(fabs(lp_lat) - HALFPI) < TOL) { + } else if (fabs(lp_lon) < tolerance || fabs(fabs(lp_lat) - half_pi) < tolerance) { xy_x = 0.; xy_y = lp_lat; } else { - bt = fabs(TWORPI * lp_lat); + bt = fabs(two_div_pi * lp_lat); bt2 = bt * bt; ct = 0.5 * (bt * (8. - bt * (2. + bt2)) - 5.) / (bt2 * (bt - 1.)); ct2 = ct * ct; - dt = TWORPI * lp_lon; + dt = two_div_pi * lp_lon; dt = dt + 1. / dt; dt = sqrt(dt * dt - 4.); - if ((fabs(lp_lon) - HALFPI) < 0.) dt = -dt; + if ((fabs(lp_lon) - half_pi) < 0.) dt = -dt; dt2 = dt * dt; x1 = bt + ct; x1 *= x1; t = bt + 3.*ct; @@ -113,8 +106,8 @@ namespace projections ct2 * (12. * bt * ct + 4. * ct2) ); x1 = (dt*(x1 + ct2 - 1.) + 2.*sqrt(ft)) / (4.* x1 + dt2); - xy_x = HALFPI * x1; - xy_y = HALFPI * sqrt(1. + dt * fabs(x1) - x1 * x1); + xy_x = half_pi * x1; + xy_y = half_pi * sqrt(1. + dt * fabs(x1) - x1 * x1); if (lp_lon < 0.) xy_x = -xy_x; if (lp_lat < 0.) xy_y = -xy_y; } @@ -150,10 +143,10 @@ namespace projections \par Example \image html ex_vandg4.gif */ - template <typename CalculationType, typename Parameters> - struct vandg4_spheroid : public detail::vandg4::base_vandg4_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct vandg4_spheroid : public detail::vandg4::base_vandg4_spheroid<T, Parameters> { - inline vandg4_spheroid(const Parameters& par) : detail::vandg4::base_vandg4_spheroid<CalculationType, Parameters>(par) + inline vandg4_spheroid(const Parameters& par) : detail::vandg4::base_vandg4_spheroid<T, Parameters>(par) { detail::vandg4::setup_vandg4(this->m_par); } @@ -167,20 +160,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg4, vandg4_spheroid, vandg4_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class vandg4_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class vandg4_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<vandg4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<vandg4_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void vandg4_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void vandg4_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("vandg4", new vandg4_entry<CalculationType, Parameters>); + factory.add_to_factory("vandg4", new vandg4_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/wag2.hpp b/boost/geometry/srs/projections/proj/wag2.hpp index 2d16892a9d..c598936e08 100644 --- a/boost/geometry/srs/projections/proj/wag2.hpp +++ b/boost/geometry/srs/projections/proj/wag2.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP -#define BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -52,7 +51,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct wag2 {}; + struct wag2 {}; // Wagner II }} //namespace srs::par4 @@ -68,22 +67,17 @@ namespace projections static const double C_p2 = 0.88550; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_wag2_spheroid : public base_t_fi<base_wag2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_wag2_spheroid + : public base_t_fi<base_wag2_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_wag2_spheroid(const Parameters& par) - : base_t_fi<base_wag2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_wag2_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { lp_lat = aasin(C_p1 * sin(C_p2 * lp_lat)); xy_x = C_x * lp_lon * cos(lp_lat); @@ -92,7 +86,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C_y; lp_lon = xy_x / (C_x * cos(lp_lat)); @@ -128,10 +122,10 @@ namespace projections \par Example \image html ex_wag2.gif */ - template <typename CalculationType, typename Parameters> - struct wag2_spheroid : public detail::wag2::base_wag2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag2_spheroid : public detail::wag2::base_wag2_spheroid<T, Parameters> { - inline wag2_spheroid(const Parameters& par) : detail::wag2::base_wag2_spheroid<CalculationType, Parameters>(par) + inline wag2_spheroid(const Parameters& par) : detail::wag2::base_wag2_spheroid<T, Parameters>(par) { detail::wag2::setup_wag2(this->m_par); } @@ -145,20 +139,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag2, wag2_spheroid, wag2_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class wag2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void wag2_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void wag2_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("wag2", new wag2_entry<CalculationType, Parameters>); + factory.add_to_factory("wag2", new wag2_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/wag3.hpp b/boost/geometry/srs/projections/proj/wag3.hpp index 3ddbfe8258..05edf18ec8 100644 --- a/boost/geometry/srs/projections/proj/wag3.hpp +++ b/boost/geometry/srs/projections/proj/wag3.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP -#define BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct wag3 {}; + struct wag3 {}; // Wagner III }} //namespace srs::par4 @@ -67,38 +66,34 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_wag3_spheroid : public base_t_fi<base_wag3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_wag3_spheroid + : public base_t_fi<base_wag3_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_wag3<CalculationType> m_proj_parm; + par_wag3<T> m_proj_parm; inline base_wag3_spheroid(const Parameters& par) - : base_t_fi<base_wag3_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_wag3_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType TWOTHIRD = detail::TWOTHIRD<CalculationType>(); + static const T two_thirds = detail::two_thirds<T>(); - xy_x = this->m_proj_parm.C_x * lp_lon * cos(TWOTHIRD * lp_lat); + xy_x = this->m_proj_parm.C_x * lp_lon * cos(two_thirds * lp_lat); xy_y = lp_lat; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { - static const CalculationType TWOTHIRD = detail::TWOTHIRD<CalculationType>(); + static const T two_thirds = detail::two_thirds<T>(); lp_lat = xy_y; - lp_lon = xy_x / (this->m_proj_parm.C_x * cos(TWOTHIRD * lp_lat)); + lp_lon = xy_x / (this->m_proj_parm.C_x * cos(two_thirds * lp_lat)); } static inline std::string get_name() @@ -114,7 +109,7 @@ namespace projections { T ts; - ts = pj_param(par.params, "rlat_ts").f; + ts = pj_get_param_r(par.params, "lat_ts"); proj_parm.C_x = cos(ts) / cos(2.*ts/3.); par.es = 0.; } @@ -136,10 +131,10 @@ namespace projections \par Example \image html ex_wag3.gif */ - template <typename CalculationType, typename Parameters> - struct wag3_spheroid : public detail::wag3::base_wag3_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag3_spheroid : public detail::wag3::base_wag3_spheroid<T, Parameters> { - inline wag3_spheroid(const Parameters& par) : detail::wag3::base_wag3_spheroid<CalculationType, Parameters>(par) + inline wag3_spheroid(const Parameters& par) : detail::wag3::base_wag3_spheroid<T, Parameters>(par) { detail::wag3::setup_wag3(this->m_par, this->m_proj_parm); } @@ -153,20 +148,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag3, wag3_spheroid, wag3_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class wag3_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag3_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wag3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wag3_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void wag3_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void wag3_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("wag3", new wag3_entry<CalculationType, Parameters>); + factory.add_to_factory("wag3", new wag3_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/wag7.hpp b/boost/geometry/srs/projections/proj/wag7.hpp index c752ff33ee..4604dc6eab 100644 --- a/boost/geometry/srs/projections/proj/wag7.hpp +++ b/boost/geometry/srs/projections/proj/wag7.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP -#define BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct wag7 {}; + struct wag7 {}; // Wagner VII }} //namespace srs::par4 @@ -62,24 +61,19 @@ namespace projections { // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_wag7_spheroid : public base_t_f<base_wag7_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_wag7_spheroid + : public base_t_f<base_wag7_spheroid<T, Parameters>, T, Parameters> { - - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - inline base_wag7_spheroid(const Parameters& par) - : base_t_f<base_wag7_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_wag7_spheroid<T, Parameters>, T, Parameters>(*this, par) + {} // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - CalculationType theta, ct, D; + T theta, ct, D; theta = asin(xy_y = 0.90630778703664996 * sin(lp_lat)); xy_x = 2.66723 * (ct = cos(theta)) * sin(lp_lon /= 3.); @@ -117,10 +111,10 @@ namespace projections \par Example \image html ex_wag7.gif */ - template <typename CalculationType, typename Parameters> - struct wag7_spheroid : public detail::wag7::base_wag7_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wag7_spheroid : public detail::wag7::base_wag7_spheroid<T, Parameters> { - inline wag7_spheroid(const Parameters& par) : detail::wag7::base_wag7_spheroid<CalculationType, Parameters>(par) + inline wag7_spheroid(const Parameters& par) : detail::wag7::base_wag7_spheroid<T, Parameters>(par) { detail::wag7::setup_wag7(this->m_par); } @@ -134,20 +128,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag7, wag7_spheroid, wag7_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class wag7_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wag7_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<wag7_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<wag7_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void wag7_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void wag7_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("wag7", new wag7_entry<CalculationType, Parameters>); + factory.add_to_factory("wag7", new wag7_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/wink1.hpp b/boost/geometry/srs/projections/proj/wink1.hpp index 36ecc95500..5fdd739629 100644 --- a/boost/geometry/srs/projections/proj/wink1.hpp +++ b/boost/geometry/srs/projections/proj/wink1.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP -#define BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP + #include <boost/geometry/srs/projections/impl/base_static.hpp> #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> #include <boost/geometry/srs/projections/impl/projects.hpp> @@ -51,7 +50,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct wink1 {}; + struct wink1 {}; // Winkel I }} //namespace srs::par4 @@ -68,23 +67,19 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_wink1_spheroid : public base_t_fi<base_wink1_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_wink1_spheroid + : public base_t_fi<base_wink1_spheroid<T, Parameters>, T, Parameters> { - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_wink1<CalculationType> m_proj_parm; + par_wink1<T> m_proj_parm; inline base_wink1_spheroid(const Parameters& par) - : base_t_fi<base_wink1_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_fi<base_wink1_spheroid<T, Parameters>, T, Parameters>(*this, par) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { xy_x = .5 * lp_lon * (this->m_proj_parm.cosphi1 + cos(lp_lat)); xy_y = lp_lat; @@ -92,7 +87,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y; lp_lon = 2. * xy_x / (this->m_proj_parm.cosphi1 + cos(lp_lat)); @@ -109,7 +104,7 @@ namespace projections template <typename Parameters, typename T> inline void setup_wink1(Parameters& par, par_wink1<T>& proj_parm) { - proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_ts").f); + proj_parm.cosphi1 = cos(pj_get_param_r(par.params, "lat_ts")); par.es = 0.; } @@ -130,10 +125,10 @@ namespace projections \par Example \image html ex_wink1.gif */ - template <typename CalculationType, typename Parameters> - struct wink1_spheroid : public detail::wink1::base_wink1_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wink1_spheroid : public detail::wink1::base_wink1_spheroid<T, Parameters> { - inline wink1_spheroid(const Parameters& par) : detail::wink1::base_wink1_spheroid<CalculationType, Parameters>(par) + inline wink1_spheroid(const Parameters& par) : detail::wink1::base_wink1_spheroid<T, Parameters>(par) { detail::wink1::setup_wink1(this->m_par, this->m_proj_parm); } @@ -147,20 +142,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wink1, wink1_spheroid, wink1_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class wink1_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wink1_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_fi<wink1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_fi<wink1_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void wink1_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void wink1_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("wink1", new wink1_entry<CalculationType, Parameters>); + factory.add_to_factory("wink1", new wink1_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/proj/wink2.hpp b/boost/geometry/srs/projections/proj/wink2.hpp index 9c90d42481..ba6fb70bf1 100644 --- a/boost/geometry/srs/projections/proj/wink2.hpp +++ b/boost/geometry/srs/projections/proj/wink2.hpp @@ -1,13 +1,9 @@ -#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP -#define BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP - -// Boost.Geometry - extensions-gis-projections (based on PROJ4) -// This file is automatically generated. DO NOT EDIT. +// Boost.Geometry - gis-projections (based on PROJ4) // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +15,7 @@ // PROJ4 is maintained by Frank Warmerdam // PROJ4 is converted to Boost.Geometry by Barend Gehrels -// Last updated version of proj: 4.9.1 +// Last updated version of proj: 5.0.0 // Original copyright notice: @@ -41,6 +37,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP + #include <boost/geometry/util/math.hpp> #include <boost/geometry/srs/projections/impl/base_static.hpp> @@ -53,7 +52,7 @@ namespace boost { namespace geometry namespace srs { namespace par4 { - struct wink2 {}; + struct wink2 {}; // Winkel II }} //namespace srs::par4 @@ -63,10 +62,8 @@ namespace projections namespace detail { namespace wink2 { - static const int MAX_ITER = 10; - - static const double LOOP_TOL = 1e-7; - //static const double TWO_D_PI = 0.636619772367581343; + static const int max_iter = 10; + static const double loop_tol = 1e-7; template <typename T> struct par_wink2 @@ -75,47 +72,43 @@ namespace projections }; // template class, using CRTP to implement forward/inverse - template <typename CalculationType, typename Parameters> - struct base_wink2_spheroid : public base_t_f<base_wink2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters> + template <typename T, typename Parameters> + struct base_wink2_spheroid + : public base_t_f<base_wink2_spheroid<T, Parameters>, T, Parameters> { - typedef CalculationType geographic_type; - typedef CalculationType cartesian_type; - - par_wink2<CalculationType> m_proj_parm; + par_wink2<T> m_proj_parm; inline base_wink2_spheroid(const Parameters& par) - : base_t_f<base_wink2_spheroid<CalculationType, Parameters>, - CalculationType, Parameters>(*this, par) {} + : base_t_f<base_wink2_spheroid<T, Parameters>, T, Parameters>(*this, par) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const { - static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); - static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); - static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); - static const CalculationType TWO_D_PI = detail::TWO_D_PI<CalculationType>(); + static const T pi = detail::pi<T>(); + static const T half_pi = detail::half_pi<T>(); + static const T fourth_pi = detail::fourth_pi<T>(); + static const T two_div_pi = detail::two_div_pi<T>(); - CalculationType k, V; + T k, V; int i; - xy_y = lp_lat * TWO_D_PI; - k = ONEPI * sin(lp_lat); + xy_y = lp_lat * two_div_pi; + k = pi * sin(lp_lat); lp_lat *= 1.8; - for (i = MAX_ITER; i ; --i) { + for (i = max_iter; i ; --i) { lp_lat -= V = (lp_lat + sin(lp_lat) - k) / (1. + cos(lp_lat)); - if (fabs(V) < LOOP_TOL) + if (fabs(V) < loop_tol) break; } if (!i) - lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + lp_lat = (lp_lat < 0.) ? -half_pi : half_pi; else lp_lat *= 0.5; xy_x = 0.5 * lp_lon * (cos(lp_lat) + this->m_proj_parm.cosphi1); - xy_y = FORTPI * (sin(lp_lat) + xy_y); + xy_y = fourth_pi * (sin(lp_lat) + xy_y); } static inline std::string get_name() @@ -129,7 +122,7 @@ namespace projections template <typename Parameters, typename T> inline void setup_wink2(Parameters& par, par_wink2<T>& proj_parm) { - proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f); + proj_parm.cosphi1 = cos(pj_get_param_r(par.params, "lat_1")); par.es = 0.; } @@ -151,10 +144,10 @@ namespace projections \par Example \image html ex_wink2.gif */ - template <typename CalculationType, typename Parameters> - struct wink2_spheroid : public detail::wink2::base_wink2_spheroid<CalculationType, Parameters> + template <typename T, typename Parameters> + struct wink2_spheroid : public detail::wink2::base_wink2_spheroid<T, Parameters> { - inline wink2_spheroid(const Parameters& par) : detail::wink2::base_wink2_spheroid<CalculationType, Parameters>(par) + inline wink2_spheroid(const Parameters& par) : detail::wink2::base_wink2_spheroid<T, Parameters>(par) { detail::wink2::setup_wink2(this->m_par, this->m_proj_parm); } @@ -168,20 +161,20 @@ namespace projections BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wink2, wink2_spheroid, wink2_spheroid) // Factory entry(s) - template <typename CalculationType, typename Parameters> - class wink2_entry : public detail::factory_entry<CalculationType, Parameters> + template <typename T, typename Parameters> + class wink2_entry : public detail::factory_entry<T, Parameters> { public : - virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + virtual base_v<T, Parameters>* create_new(const Parameters& par) const { - return new base_v_f<wink2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + return new base_v_f<wink2_spheroid<T, Parameters>, T, Parameters>(par); } }; - template <typename CalculationType, typename Parameters> - inline void wink2_init(detail::base_factory<CalculationType, Parameters>& factory) + template <typename T, typename Parameters> + inline void wink2_init(detail::base_factory<T, Parameters>& factory) { - factory.add_to_factory("wink2", new wink2_entry<CalculationType, Parameters>); + factory.add_to_factory("wink2", new wink2_entry<T, Parameters>); } } // namespace detail diff --git a/boost/geometry/srs/projections/shared_grids.hpp b/boost/geometry/srs/projections/shared_grids.hpp new file mode 100644 index 0000000000..54191808cb --- /dev/null +++ b/boost/geometry/srs/projections/shared_grids.hpp @@ -0,0 +1,95 @@ +// Boost.Geometry + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP + + +#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp> + +#include <boost/thread.hpp> + +#include <vector> + + +namespace boost { namespace geometry +{ + + +// Forward declarations +namespace srs +{ + +// Forward declaration for functions declarations below +class shared_grids; + +} // namespace srs +namespace projections { namespace detail +{ + +// Forward declaratios of shared_grids friends +template <typename StreamPolicy> +inline bool pj_gridlist_merge_gridfile(std::string const& gridname, + StreamPolicy const& stream_policy, + srs::shared_grids & grids, + std::vector<std::size_t> & gridindexes); +template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> +inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, + Range & range, + srs::shared_grids & grids, + std::vector<std::size_t> const& gridindexes); + +}} // namespace projections::detail + + +namespace srs +{ + + +class shared_grids +{ +public: + std::size_t size() const + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + return gridinfo.size(); + } + + bool empty() const + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + return gridinfo.empty(); + } + +private: + template <typename StreamPolicy> + friend inline bool projections::detail::pj_gridlist_merge_gridfile( + std::string const& gridname, + StreamPolicy const& stream_policy, + srs::shared_grids & grids, + std::vector<std::size_t> & gridindexes); + template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range> + friend inline bool projections::detail::pj_apply_gridshift_3( + StreamPolicy const& stream_policy, + Range & range, + srs::shared_grids & grids, + std::vector<std::size_t> const& gridindexes); + + projections::detail::pj_gridinfo gridinfo; + mutable boost::shared_mutex mutex; +}; + + +} // namespace srs + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP diff --git a/boost/geometry/srs/projections/str_cast.hpp b/boost/geometry/srs/projections/str_cast.hpp new file mode 100644 index 0000000000..c6c1e2447b --- /dev/null +++ b/boost/geometry/srs/projections/str_cast.hpp @@ -0,0 +1,160 @@ +// Boost.Geometry + +// Copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP +#define BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP + +#include <boost/config.hpp> +#include <boost/geometry/core/exception.hpp> +#include <boost/throw_exception.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_signed.hpp> + +#include <cstdlib> +#include <string> + +namespace boost { namespace geometry +{ + +class bad_str_cast : public geometry::exception +{ + virtual char const* what() const throw() + { + return "Unable to convert from string."; + } +}; + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +< + typename T, + bool IsIntegral = boost::is_integral<T>::value, + bool IsSigned = boost::is_signed<T>::value +> +struct str_cast_traits_strtox +{ + static inline T apply(const char *str, char **str_end) + { + return strtod(str, str_end); + } +}; + +template <typename T> +struct str_cast_traits_strtox<T, true, true> +{ + static inline T apply(const char *str, char **str_end) + { + return strtol(str, str_end, 0); + } +}; + +template <typename T> +struct str_cast_traits_strtox<T, true, false> +{ + static inline T apply(const char *str, char **str_end) + { + return strtoul(str, str_end, 0); + } +}; + +template <typename T> +struct str_cast_traits_strtox<T, false, false> +{ + static inline T apply(const char *str, char **str_end) + { + return strtod(str, str_end); + } +}; + +// Assuming a compiler supporting r-value references +// supports long long and strtoll, strtoull, strtof, strtold +// If it's MSVC enable in MSVC++ 12.0 aka Visual Studio 2013 +// TODO: in MSVC-11.0 _strtoi64() intrinsic could be used +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined(_MSC_VER) || (_MSC_VER >= 1800)) +template <> +struct str_cast_traits_strtox<long long, true, true> +{ + static inline long long apply(const char *str, char **str_end) + { + return strtoll(str, str_end, 0); + } +}; + +template <> +struct str_cast_traits_strtox<unsigned long long, true, false> +{ + static inline unsigned long long apply(const char *str, char **str_end) + { + return strtoull(str, str_end, 0); + } +}; + +template <> +struct str_cast_traits_strtox<float, false, false> +{ + static inline float apply(const char *str, char **str_end) + { + return strtof(str, str_end); + } +}; + +template <> +struct str_cast_traits_strtox<long double, false, false> +{ + static inline long double apply(const char *str, char **str_end) + { + return strtold(str, str_end); + } +}; +#endif // C++11 strtox supported + +template <typename T> +struct str_cast_traits_generic +{ + static inline T apply(const char *str) + { + char * str_end = (char*)(void*)str; + T res = str_cast_traits_strtox + < + typename boost::remove_cv<T>::type + >::apply(str, &str_end); + if (str_end == str) + { + BOOST_THROW_EXCEPTION( bad_str_cast() ); + } + return res; + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +template <typename T> +struct str_cast_traits +{ + template <typename String> + static inline T apply(String const& str) + { + return detail::str_cast_traits_generic<T>::apply(str.c_str()); + } +}; + +template <typename T, typename String> +inline T str_cast(String const& str) +{ + return str_cast_traits<T>::apply(str); +} + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_STR_CAST_HPP diff --git a/boost/geometry/srs/shared_grids.hpp b/boost/geometry/srs/shared_grids.hpp new file mode 100644 index 0000000000..9eb61717ba --- /dev/null +++ b/boost/geometry/srs/shared_grids.hpp @@ -0,0 +1,20 @@ +// Boost.Geometry + +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP +#define BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP + + +#include <boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp> +#include <boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp> +#include <boost/geometry/srs/projections/shared_grids.hpp> + + +#endif // BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP diff --git a/boost/geometry/srs/transformation.hpp b/boost/geometry/srs/transformation.hpp index c726d09ac4..2b1351b656 100644 --- a/boost/geometry/srs/transformation.hpp +++ b/boost/geometry/srs/transformation.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -24,6 +24,7 @@ #include <boost/geometry/geometries/segment.hpp> #include <boost/geometry/srs/projection.hpp> +#include <boost/geometry/srs/projections/grids.hpp> #include <boost/geometry/srs/projections/impl/pj_transform.hpp> #include <boost/geometry/views/detail/indexed_point_view.hpp> @@ -298,11 +299,13 @@ struct transform_range < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename RangeIn, typename RangeOut + typename RangeIn, typename RangeOut, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - RangeIn const& in, RangeOut & out) + RangeIn const& in, RangeOut & out, + Grids const& grids1, Grids const& grids2) { // NOTE: this has to be consistent with pj_transform() bool const input_angles = !par1.is_geocent && par1.is_latlong; @@ -312,9 +315,9 @@ struct transform_range bool res = true; try { - res = pj_transform(proj1, par1, proj2, par2, wrapper.get()); + res = pj_transform(proj1, par1, proj2, par2, wrapper.get(), grids1, grids2); } - catch (projection_exception) + catch (projection_exception const&) { res = false; } @@ -336,18 +339,21 @@ struct transform_multi < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename MultiIn, typename MultiOut + typename MultiIn, typename MultiOut, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - MultiIn const& in, MultiOut & out) + MultiIn const& in, MultiOut & out, + Grids const& grids1, Grids const& grids2) { if (! same_object(in, out)) range::resize(out, boost::size(in)); return apply(proj1, par1, proj2, par2, boost::begin(in), boost::end(in), - boost::begin(out)); + boost::begin(out), + grids1, grids2); } private: @@ -355,16 +361,18 @@ private: < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename InIt, typename OutIt + typename InIt, typename OutIt, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - InIt in_first, InIt in_last, OutIt out_first) + InIt in_first, InIt in_last, OutIt out_first, + Grids const& grids1, Grids const& grids2) { bool res = true; for ( ; in_first != in_last ; ++in_first, ++out_first ) { - if ( ! Policy::apply(proj1, par1, proj2, par2, *in_first, *out_first) ) + if ( ! Policy::apply(proj1, par1, proj2, par2, *in_first, *out_first, grids1, grids2) ) { res = false; } @@ -390,11 +398,13 @@ struct transform<Point, CT, point_tag> < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename PointIn, typename PointOut + typename PointIn, typename PointOut, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - PointIn const& in, PointOut & out) + PointIn const& in, PointOut & out, + Grids const& grids1, Grids const& grids2) { // NOTE: this has to be consistent with pj_transform() bool const input_angles = !par1.is_geocent && par1.is_latlong; @@ -409,9 +419,9 @@ struct transform<Point, CT, point_tag> bool res = true; try { - res = pj_transform(proj1, par1, proj2, par2, range); + res = pj_transform(proj1, par1, proj2, par2, range, grids1, grids2); } - catch (projection_exception) + catch (projection_exception const&) { res = false; } @@ -438,11 +448,13 @@ struct transform<Segment, CT, segment_tag> < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename SegmentIn, typename SegmentOut + typename SegmentIn, typename SegmentOut, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - SegmentIn const& in, SegmentOut & out) + SegmentIn const& in, SegmentOut & out, + Grids const& grids1, Grids const& grids2) { // NOTE: this has to be consistent with pj_transform() bool const input_angles = !par1.is_geocent && par1.is_latlong; @@ -464,9 +476,9 @@ struct transform<Segment, CT, segment_tag> bool res = true; try { - res = pj_transform(proj1, par1, proj2, par2, range); + res = pj_transform(proj1, par1, proj2, par2, range, grids1, grids2); } - catch (projection_exception) + catch (projection_exception const&) { res = false; } @@ -506,24 +518,28 @@ struct transform<Polygon, CT, polygon_tag> < typename Proj1, typename Par1, typename Proj2, typename Par2, - typename PolygonIn, typename PolygonOut + typename PolygonIn, typename PolygonOut, + typename Grids > static inline bool apply(Proj1 const& proj1, Par1 const& par1, Proj2 const& proj2, Par2 const& par2, - PolygonIn const& in, PolygonOut & out) + PolygonIn const& in, PolygonOut & out, + Grids const& grids1, Grids const& grids2) { bool r1 = transform_range < CT >::apply(proj1, par1, proj2, par2, geometry::exterior_ring(in), - geometry::exterior_ring(out)); + geometry::exterior_ring(out), + grids1, grids2); bool r2 = transform_multi < transform_range<CT> >::apply(proj1, par1, proj2, par2, geometry::interior_rings(in), - geometry::interior_rings(out)); + geometry::interior_rings(out), + grids1, grids2); return r1 && r2; } }; @@ -584,6 +600,19 @@ public: template <typename GeometryIn, typename GeometryOut> bool forward(GeometryIn const& in, GeometryOut & out) const { + return forward(in, out, transformation_grids<detail::empty_grids_storage>()); + } + + template <typename GeometryIn, typename GeometryOut> + bool inverse(GeometryIn const& in, GeometryOut & out) const + { + return inverse(in, out, transformation_grids<detail::empty_grids_storage>()); + } + + template <typename GeometryIn, typename GeometryOut, typename GridsStorage> + bool forward(GeometryIn const& in, GeometryOut & out, + transformation_grids<GridsStorage> const& grids) const + { BOOST_MPL_ASSERT_MSG((projections::detail::same_tags<GeometryIn, GeometryOut>::value), NOT_SUPPORTED_COMBINATION_OF_GEOMETRIES, (GeometryIn, GeometryOut)); @@ -594,11 +623,14 @@ public: calc_t >::apply(m_proj1.proj(), m_proj1.proj().params(), m_proj2.proj(), m_proj2.proj().params(), - in, out); + in, out, + grids.src_grids, + grids.dst_grids); } - template <typename GeometryIn, typename GeometryOut> - bool inverse(GeometryIn const& in, GeometryOut & out) const + template <typename GeometryIn, typename GeometryOut, typename GridsStorage> + bool inverse(GeometryIn const& in, GeometryOut & out, + transformation_grids<GridsStorage> const& grids) const { BOOST_MPL_ASSERT_MSG((projections::detail::same_tags<GeometryIn, GeometryOut>::value), NOT_SUPPORTED_COMBINATION_OF_GEOMETRIES, @@ -610,7 +642,23 @@ public: calc_t >::apply(m_proj2.proj(), m_proj2.proj().params(), m_proj1.proj(), m_proj1.proj().params(), - in, out); + in, out, + grids.dst_grids, + grids.src_grids); + } + + template <typename GridsStorage> + inline transformation_grids<GridsStorage> initialize_grids(GridsStorage & grids_storage) const + { + transformation_grids<GridsStorage> result(grids_storage); + + using namespace projections::detail; + pj_gridlist_from_nadgrids(m_proj1.proj().params(), + result.src_grids); + pj_gridlist_from_nadgrids(m_proj2.proj().params(), + result.dst_grids); + + return result; } private: @@ -618,6 +666,7 @@ private: projections::proj_wrapper<Proj2, CT> m_proj2; }; + } // namespace srs diff --git a/boost/geometry/strategies/cartesian/distance_projected_point.hpp b/boost/geometry/strategies/cartesian/distance_projected_point.hpp index b7127c834d..5aaa9db434 100644 --- a/boost/geometry/strategies/cartesian/distance_projected_point.hpp +++ b/boost/geometry/strategies/cartesian/distance_projected_point.hpp @@ -94,8 +94,6 @@ public : > {}; -public : - template <typename Point, typename PointOfSegment> inline typename calculation_type<Point, PointOfSegment>::type apply(Point const& p, PointOfSegment const& p1, PointOfSegment const& p2) const @@ -159,6 +157,13 @@ public : return strategy.apply(p, projected); } + + template <typename CT> + inline CT vertical_or_meridian(CT const& lat1, CT const& lat2) const + { + return lat1 - lat2; + } + }; #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS diff --git a/boost/geometry/strategies/cartesian/distance_segment_box.hpp b/boost/geometry/strategies/cartesian/distance_segment_box.hpp new file mode 100644 index 0000000000..80f5094a59 --- /dev/null +++ b/boost/geometry/strategies/cartesian/distance_segment_box.hpp @@ -0,0 +1,192 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2018 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_SEGMENT_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_SEGMENT_BOX_HPP + +#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp> + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace distance +{ + +template +< + typename CalculationType = void, + typename Strategy = pythagoras<CalculationType> +> +struct cartesian_segment_box +{ + template <typename PointOfSegment, typename PointOfBox> + struct calculation_type + : promote_floating_point + < + typename strategy::distance::services::return_type + < + Strategy, + PointOfSegment, + PointOfBox + >::type + > + {}; + + // point-point strategy getters + struct distance_pp_strategy + { + typedef Strategy type; + }; + + inline typename distance_pp_strategy::type get_distance_pp_strategy() const + { + return typename distance_pp_strategy::type(); + } + // point-segment strategy getters + struct distance_ps_strategy + { + typedef projected_point<CalculationType, Strategy> type; + }; + + inline typename distance_ps_strategy::type get_distance_ps_strategy() const + { + return typename distance_ps_strategy::type(); + } + + template <typename LessEqual, typename ReturnType, + typename SegmentPoint, typename BoxPoint> + inline ReturnType segment_below_of_box(SegmentPoint const& p0, + SegmentPoint const& p1, + BoxPoint const&, + BoxPoint const&, + BoxPoint const&, + BoxPoint const& bottom_right) const + { + + + return geometry::detail::distance::segment_to_box_2D + < + ReturnType, + SegmentPoint, + BoxPoint, + cartesian_segment_box<CalculationType, Strategy> + >::template call_above_of_box + < + typename LessEqual::other + >(p1, p0, bottom_right, *this); + } + + template <typename SPoint, typename BPoint> + static void mirror(SPoint&, + SPoint&, + BPoint&, + BPoint&, + BPoint&, + BPoint&) + {} +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template <typename CalculationType, typename Strategy> +struct tag<cartesian_segment_box<CalculationType, Strategy> > +{ + typedef strategy_tag_distance_segment_box type; +}; + +template <typename CalculationType, typename Strategy, typename PS, typename PB> +struct return_type<cartesian_segment_box<CalculationType, Strategy>, PS, PB> + : cartesian_segment_box<CalculationType, Strategy>::template calculation_type<PS, PB> +{}; + +template <typename CalculationType, typename Strategy> +struct comparable_type<cartesian_segment_box<CalculationType, Strategy> > +{ + // Define a cartesian_segment_box strategy with its underlying point-point + // strategy being comparable + typedef cartesian_segment_box + < + CalculationType, + typename comparable_type<Strategy>::type + > type; +}; + + +template <typename CalculationType, typename Strategy> +struct get_comparable<cartesian_segment_box<CalculationType, Strategy> > +{ + typedef typename comparable_type + < + cartesian_segment_box<CalculationType, Strategy> + >::type comparable_type; +public : + static inline comparable_type apply(cartesian_segment_box<CalculationType, Strategy> const& ) + { + return comparable_type(); + } +}; + +template <typename CalculationType, typename Strategy, typename PS, typename PB> +struct result_from_distance<cartesian_segment_box<CalculationType, Strategy>, PS, PB> +{ +private : + typedef typename return_type< + cartesian_segment_box + < + CalculationType, + Strategy + >, + PS, + PB + >::type return_type; +public : + template <typename T> + static inline return_type apply(cartesian_segment_box<CalculationType, + Strategy> const& , + T const& value) + { + Strategy s; + return result_from_distance<Strategy, PS, PB>::apply(s, value); + } +}; + +template <typename Segment, typename Box> +struct default_strategy + < + segment_tag, box_tag, Segment, Box, + cartesian_tag, cartesian_tag + > +{ + typedef cartesian_segment_box<> type; +}; + +template <typename Box, typename Segment> +struct default_strategy + < + box_tag, segment_tag, Box, Segment, + cartesian_tag, cartesian_tag + > +{ + typedef typename default_strategy + < + segment_tag, box_tag, Segment, Box, + cartesian_tag, cartesian_tag + >::type type; +}; + +} +#endif + +}} // namespace strategy::distance + +}} // namespace boost::geometry +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_SEGMENT_BOX_HPP diff --git a/boost/geometry/strategies/geographic/azimuth.hpp b/boost/geometry/strategies/geographic/azimuth.hpp index b918caccea..1179050208 100644 --- a/boost/geometry/strategies/geographic/azimuth.hpp +++ b/boost/geometry/strategies/geographic/azimuth.hpp @@ -57,39 +57,68 @@ public : T const& lon2_rad, T const& lat2_rad, T& a1, T& a2) const { - typedef typename boost::mpl::if_ - < - boost::is_void<CalculationType>, T, CalculationType - >::type calc_t; - - typedef typename FormulaPolicy::template inverse<calc_t, false, true, true, false, false> inverse_type; - typedef typename inverse_type::result_type inverse_result; - inverse_result i_res = inverse_type::apply(calc_t(lon1_rad), calc_t(lat1_rad), - calc_t(lon2_rad), calc_t(lat2_rad), - m_spheroid); - a1 = i_res.azimuth; - a2 = i_res.reverse_azimuth; + compute<true, true>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a1, a2); } - template <typename T> inline void apply(T const& lon1_rad, T const& lat1_rad, T const& lon2_rad, T const& lat2_rad, T& a1) const { + compute<true, false>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a1, a1); + } + template <typename T> + inline void apply_reverse(T const& lon1_rad, T const& lat1_rad, + T const& lon2_rad, T const& lat2_rad, + T& a2) const + { + compute<false, true>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a2, a2); + } + +private : + + template < + bool EnableAzimuth, + bool EnableReverseAzimuth, + typename T + > + inline void compute(T const& lon1_rad, T const& lat1_rad, + T const& lon2_rad, T const& lat2_rad, + T& a1, T& a2) const + { typedef typename boost::mpl::if_ - < - boost::is_void<CalculationType>, T, CalculationType - >::type calc_t; + < + boost::is_void<CalculationType>, T, CalculationType + >::type calc_t; - typedef typename FormulaPolicy::template inverse<calc_t, false, true, false, false, false> inverse_type; + typedef typename FormulaPolicy::template inverse + < + calc_t, + false, + EnableAzimuth, + EnableReverseAzimuth, + false, + false + > inverse_type; typedef typename inverse_type::result_type inverse_result; inverse_result i_res = inverse_type::apply(calc_t(lon1_rad), calc_t(lat1_rad), calc_t(lon2_rad), calc_t(lat2_rad), m_spheroid); - a1 = i_res.azimuth; + if (EnableAzimuth) + { + a1 = i_res.azimuth; + } + if (EnableReverseAzimuth) + { + a2 = i_res.reverse_azimuth; + } } -private : Spheroid m_spheroid; }; diff --git a/boost/geometry/strategies/geographic/distance.hpp b/boost/geometry/strategies/geographic/distance.hpp index 01f766c10e..41e3cd7aaa 100644 --- a/boost/geometry/strategies/geographic/distance.hpp +++ b/boost/geometry/strategies/geographic/distance.hpp @@ -22,7 +22,7 @@ #include <boost/geometry/core/radius.hpp> #include <boost/geometry/formulas/andoyer_inverse.hpp> -#include <boost/geometry/formulas/elliptic_arc_length.hpp> +#include <boost/geometry/formulas/meridian_inverse.hpp> #include <boost/geometry/formulas/flattening.hpp> #include <boost/geometry/srs/spheroid.hpp> @@ -92,13 +92,13 @@ public : static inline CT apply(CT lon1, CT lat1, CT lon2, CT lat2, Spheroid const& spheroid) { - typedef typename formula::elliptic_arc_length + typedef typename formula::meridian_inverse < CT, strategy::default_order<FormulaPolicy>::value - > elliptic_arc_length; + > meridian_inverse; - typename elliptic_arc_length::result res = - elliptic_arc_length::apply(lon1, lat1, lon2, lat2, spheroid); + typename meridian_inverse::result res = + meridian_inverse::apply(lon1, lat1, lon2, lat2, spheroid); if (res.meridian) { @@ -125,19 +125,6 @@ public : return apply(lon1, lat1, lon2, lat2, m_spheroid); } - // points on a meridian not crossing poles - template <typename CT> - inline CT meridian(CT lat1, CT lat2) const - { - typedef typename formula::elliptic_arc_length - < - CT, strategy::default_order<FormulaPolicy>::value - > elliptic_arc_length; - - return elliptic_arc_length::meridian_not_crossing_pole_dist(lat1, lat2, - m_spheroid); - } - inline Spheroid const& model() const { return m_spheroid; diff --git a/boost/geometry/strategies/geographic/distance_cross_track.hpp b/boost/geometry/strategies/geographic/distance_cross_track.hpp index be930a3fd4..f84bb4134f 100644 --- a/boost/geometry/strategies/geographic/distance_cross_track.hpp +++ b/boost/geometry/strategies/geographic/distance_cross_track.hpp @@ -13,6 +13,8 @@ #include <algorithm> +#include <boost/tuple/tuple.hpp> +#include <boost/algorithm/minmax.hpp> #include <boost/config.hpp> #include <boost/concept_check.hpp> #include <boost/mpl/if.hpp> @@ -27,6 +29,7 @@ #include <boost/geometry/strategies/concepts/distance_concept.hpp> #include <boost/geometry/strategies/spherical/distance_haversine.hpp> #include <boost/geometry/strategies/geographic/azimuth.hpp> +#include <boost/geometry/strategies/geographic/distance.hpp> #include <boost/geometry/strategies/geographic/parameters.hpp> #include <boost/geometry/formulas/vincenty_direct.hpp> @@ -94,17 +97,6 @@ public : > {}; - struct distance_strategy - { - typedef geographic<FormulaPolicy, Spheroid, CalculationType> type; - }; - - inline typename distance_strategy::type get_distance_strategy() const - { - typedef typename distance_strategy::type distance_type; - return distance_type(m_spheroid); - } - explicit geographic_cross_track(Spheroid const& spheroid = Spheroid()) : m_spheroid(spheroid) {} @@ -121,6 +113,20 @@ public : m_spheroid)).distance; } + // points on a meridian not crossing poles + template <typename CT> + inline CT vertical_or_meridian(CT lat1, CT lat2) const + { + typedef typename formula::meridian_inverse + < + CT, + strategy::default_order<FormulaPolicy>::value + > meridian_inverse; + + return meridian_inverse::meridian_not_crossing_pole_dist(lat1, lat2, + m_spheroid); + } + private : template <typename CT> @@ -171,21 +177,22 @@ private : if (g4 < -1.25*pi)//close to -270 { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "g4=" << g4 << ", close to -270" << std::endl; + std::cout << "g4=" << g4 * math::r2d<CT>() << ", close to -270" << std::endl; #endif return g4 + 1.5 * pi; } else if (g4 > 1.25*pi)//close to 270 { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "g4=" << g4 << ", close to 270" << std::endl; + std::cout << "g4=" << g4 * math::r2d<CT>() << ", close to 270" << std::endl; #endif + der = -der; return - g4 + 1.5 * pi; } else if (g4 < 0 && g4 > -0.75*pi)//close to -90 { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "g4=" << g4 << ", close to -90" << std::endl; + std::cout << "g4=" << g4 * math::r2d<CT>() << ", close to -90" << std::endl; #endif der = -der; return -g4 - pi/2; @@ -233,21 +240,30 @@ private : std::swap(lat1, lat2); } +#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK + std::cout << ">>\nSegment=(" << lon1 * math::r2d<CT>(); + std::cout << "," << lat1 * math::r2d<CT>(); + std::cout << "),(" << lon2 * math::r2d<CT>(); + std::cout << "," << lat2 * math::r2d<CT>(); + std::cout << ")\np=(" << lon3 * math::r2d<CT>(); + std::cout << "," << lat3 * math::r2d<CT>(); + std::cout << ")" << std::endl; +#endif + //segment on equator //Note: antipodal points on equator does not define segment on equator //but pass by the pole CT diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2); - typedef typename formula::elliptic_arc_length<CT> elliptic_arc_length; + typedef typename formula::meridian_inverse<CT> + meridian_inverse; bool meridian_not_crossing_pole = - elliptic_arc_length::meridian_not_crossing_pole(lat1, lat2, diff); + meridian_inverse::meridian_not_crossing_pole + (lat1, lat2, diff); bool meridian_crossing_pole = - elliptic_arc_length::meridian_crossing_pole(diff); - - //bool meridian_crossing_pole = math::equals(math::abs(diff), pi); - //bool meridian_not_crossing_pole = math::equals(math::abs(diff), c0); + meridian_inverse::meridian_crossing_pole(diff); if (math::equals(lat1, c0) && math::equals(lat2, c0) && !meridian_crossing_pole) { @@ -271,18 +287,28 @@ private : return non_iterative_case(lon3, lat1, lon3, lat3, spheroid); } - if ( (meridian_not_crossing_pole || meridian_crossing_pole ) && lat1 > lat2) + if ( (meridian_not_crossing_pole || meridian_crossing_pole ) && std::abs(lat1) > std::abs(lat2)) { +#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK + std::cout << "Meridian segment not crossing pole" << std::endl; +#endif std::swap(lat1,lat2); } if (meridian_crossing_pole) { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "Meridian segment" << std::endl; + std::cout << "Meridian segment crossing pole" << std::endl; #endif - result_distance_point_segment<CT> d1 = apply<geometry::radian>(lon1, lat1, lon1, half_pi, lon3, lat3, spheroid); - result_distance_point_segment<CT> d2 = apply<geometry::radian>(lon2, lat2, lon2, half_pi, lon3, lat3, spheroid); + CT sign_non_zero = lat3 >= c0 ? 1 : -1; + result_distance_point_segment<CT> d1 = + apply<geometry::radian>(lon1, lat1, + lon1, half_pi * sign_non_zero, + lon3, lat3, spheroid); + result_distance_point_segment<CT> d2 = + apply<geometry::radian>(lon2, lat2, + lon2, half_pi * sign_non_zero, + lon3, lat3, spheroid); if (d1.distance < d2.distance) { return d1; @@ -319,29 +345,31 @@ private : CT a312 = a13 - a12; - if (geometry::math::equals(a312, c0)) + // TODO: meridian case optimization + if (geometry::math::equals(a312, c0) && meridian_not_crossing_pole) { + boost::tuple<CT,CT> minmax_elem = boost::minmax(lat1, lat2); + if (lat3 >= minmax_elem.template get<0>() && + lat3 <= minmax_elem.template get<1>()) + { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "point on segment" << std::endl; + std::cout << "Point on meridian segment" << std::endl; #endif - return non_iterative_case(lon3, lat3, c0); + return non_iterative_case(lon3, lat3, c0); + } } CT projection1 = cos( a312 ) * d1 / d3; #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK - std::cout << "segment=(" << lon1 * math::r2d<CT>(); - std::cout << "," << lat1 * math::r2d<CT>(); - std::cout << "),(" << lon2 * math::r2d<CT>(); - std::cout << "," << lat2 * math::r2d<CT>(); - std::cout << ")\np=(" << lon3 * math::r2d<CT>(); - std::cout << "," << lat3 * math::r2d<CT>(); - std::cout << ")\na1=" << a12 * math::r2d<CT>() << std::endl; + std::cout << "a1=" << a12 * math::r2d<CT>() << std::endl; std::cout << "a13=" << a13 * math::r2d<CT>() << std::endl; std::cout << "a312=" << a312 * math::r2d<CT>() << std::endl; std::cout << "cos(a312)=" << cos(a312) << std::endl; + std::cout << "projection 1=" << projection1 << std::endl; #endif - if (projection1 < 0.0) + + if (projection1 < c0) { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "projection closer to p1" << std::endl; @@ -356,15 +384,17 @@ private : CT a321 = a23 - a21; + CT projection2 = cos( a321 ) * d2 / d3; + #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "a21=" << a21 * math::r2d<CT>() << std::endl; std::cout << "a23=" << a23 * math::r2d<CT>() << std::endl; std::cout << "a321=" << a321 * math::r2d<CT>() << std::endl; std::cout << "cos(a321)=" << cos(a321) << std::endl; + std::cout << "projection 2=" << projection2 << std::endl; #endif - CT projection2 = cos( a321 ) * d2 / d3; - if (projection2 < 0.0) + if (projection2 < c0) { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "projection closer to p2" << std::endl; @@ -400,13 +430,15 @@ private : #endif // Update s14 (using Newton method) - CT prev_distance = 0; + CT prev_distance; geometry::formula::result_direct<CT> res14; geometry::formula::result_inverse<CT> res34; + res34.distance = -1; int counter = 0; // robustness CT g4; CT delta_g4; + bool dist_improve = true; do{ prev_distance = res34.distance; @@ -423,23 +455,27 @@ private : lon3, lat3, spheroid); g4 = res34.azimuth - a4; - - CT M43 = res34.geodesic_scale; // cos(s14/earth_radius) is the spherical limit CT m34 = res34.reduced_length; CT der = (M43 / m34) * sin(g4); - // normalize (g4 - pi/2) + //normalize delta_g4 = normalize(g4, der); - s14 = s14 - delta_g4 / der; + result.distance = res34.distance; + + dist_improve = prev_distance > res34.distance || prev_distance == -1; + if (!dist_improve) + { + result.distance = prev_distance; + } #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "p4=" << res14.lon2 * math::r2d<CT>() << "," << res14.lat2 * math::r2d<CT>() << std::endl; std::cout << "a34=" << res34.azimuth * math::r2d<CT>() << std::endl; std::cout << "a4=" << a4 * math::r2d<CT>() << std::endl; - std::cout << "g4=" << g4 * math::r2d<CT>() << std::endl; + std::cout << "g4(normalized)=" << g4 * math::r2d<CT>() << std::endl; std::cout << "delta_g4=" << delta_g4 * math::r2d<CT>() << std::endl; std::cout << "der=" << der << std::endl; std::cout << "M43=" << M43 << std::endl; @@ -448,15 +484,11 @@ private : std::cout << "new_s14=" << s14 << std::endl; std::cout << std::setprecision(16) << "dist =" << res34.distance << std::endl; std::cout << "---------end of step " << counter << std::endl<< std::endl; -#endif - result.distance = prev_distance; - -#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK if (g4 == half_pi) { std::cout << "Stop msg: g4 == half_pi" << std::endl; } - if (res34.distance >= prev_distance && prev_distance != 0) + if (!dist_improve) { std::cout << "Stop msg: res34.distance >= prev_distance" << std::endl; } @@ -464,16 +496,16 @@ private : { std::cout << "Stop msg: delta_g4 == 0" << std::endl; } - if (counter == 19) + if (counter == BOOST_GEOMETRY_DETAIL_POINT_SEGMENT_DISTANCE_MAX_STEPS) { std::cout << "Stop msg: counter" << std::endl; } #endif } while (g4 != half_pi - && (prev_distance > res34.distance || prev_distance == 0) + && dist_improve && delta_g4 != 0 - && ++counter < BOOST_GEOMETRY_DETAIL_POINT_SEGMENT_DISTANCE_MAX_STEPS ) ; + && counter++ < BOOST_GEOMETRY_DETAIL_POINT_SEGMENT_DISTANCE_MAX_STEPS); #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "distance=" << res34.distance << std::endl; diff --git a/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp index 4f6b3b45b7..8e48fbf19a 100644 --- a/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp +++ b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp @@ -61,14 +61,37 @@ template class geographic_cross_track_box_box { public: - typedef geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> Strategy; + + // point-point strategy getters + struct distance_pp_strategy + { + typedef geographic<FormulaPolicy, Spheroid, CalculationType> type; + }; + + // point-segment strategy getters + struct distance_ps_strategy + { + typedef geographic_cross_track + < + FormulaPolicy, + Spheroid, + CalculationType + > type; + }; template <typename Box1, typename Box2> - struct return_type - : services::return_type<Strategy, typename point_type<Box1>::type, typename point_type<Box2>::type> + struct return_type : services::return_type + < + typename distance_ps_strategy::type, + typename point_type<Box1>::type, + typename point_type<Box2>::type + > {}; - inline geographic_cross_track_box_box() + //constructor + + explicit geographic_cross_track_box_box(Spheroid const& spheroid = Spheroid()) + : m_spheroid(spheroid) {} template <typename Box1, typename Box2> @@ -90,8 +113,12 @@ public: */ typedef typename return_type<Box1, Box2>::type return_type; return details::cross_track_box_box_generic - <return_type>::apply(box1, box2, Strategy()); + <return_type>::apply(box1, box2, + typename distance_pp_strategy::type(m_spheroid), + typename distance_ps_strategy::type(m_spheroid)); } +private : + Spheroid m_spheroid; }; diff --git a/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp index 016427428c..4508d5acb5 100644 --- a/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp +++ b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp @@ -62,14 +62,22 @@ template class geographic_cross_track_point_box { public: - typedef geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> Strategy; + // point-point strategy getters + struct distance_ps_strategy + { + typedef geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> type; + }; template <typename Point, typename Box> struct return_type - : services::return_type<Strategy, Point, typename point_type<Box>::type> + : services::return_type<typename distance_ps_strategy::type, + Point, typename point_type<Box>::type> {}; - inline geographic_cross_track_point_box() + //constructor + + explicit geographic_cross_track_point_box(Spheroid const& spheroid = Spheroid()) + : m_spheroid(spheroid) {} template <typename Point, typename Box> @@ -91,8 +99,12 @@ public: typedef typename return_type<Point, Box>::type return_type; return details::cross_track_point_box_generic - <return_type>::apply(point, box, Strategy()); + <return_type>::apply(point, box, + typename distance_ps_strategy::type(m_spheroid)); } + +private : + Spheroid m_spheroid; }; diff --git a/boost/geometry/strategies/geographic/distance_segment_box.hpp b/boost/geometry/strategies/geographic/distance_segment_box.hpp new file mode 100644 index 0000000000..6bde78ca27 --- /dev/null +++ b/boost/geometry/strategies/geographic/distance_segment_box.hpp @@ -0,0 +1,311 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2018 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP + +#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp> + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace distance +{ + +template +< + typename FormulaPolicy = strategy::andoyer, + typename Spheroid = srs::spheroid<double>, + typename CalculationType = void +> +struct geographic_segment_box +{ + template <typename PointOfSegment, typename PointOfBox> + struct return_type + : promote_floating_point + < + typename select_calculation_type + < + PointOfSegment, + PointOfBox, + CalculationType + >::type + > + {}; + + // point-point strategy getters + struct distance_pp_strategy + { + typedef geographic<FormulaPolicy, Spheroid, CalculationType> type; + }; + + inline typename distance_pp_strategy::type get_distance_pp_strategy() const + { + typedef typename distance_pp_strategy::type distance_type; + return distance_type(m_spheroid); + } + // point-segment strategy getters + struct distance_ps_strategy + { + typedef geographic_cross_track + < + FormulaPolicy, + Spheroid, + CalculationType + > type; + }; + + inline typename distance_ps_strategy::type get_distance_ps_strategy() const + { + typedef typename distance_ps_strategy::type distance_type; + return distance_type(m_spheroid); + } + + //constructor + + explicit geographic_segment_box(Spheroid const& spheroid = Spheroid()) + : m_spheroid(spheroid) + {} + + // methods + + template <typename LessEqual, typename ReturnType, + typename SegmentPoint, typename BoxPoint> + inline ReturnType segment_below_of_box(SegmentPoint const& p0, + SegmentPoint const& p1, + BoxPoint const& top_left, + BoxPoint const& top_right, + BoxPoint const& bottom_left, + BoxPoint const& bottom_right) const + { + typedef typename azimuth::geographic + < + FormulaPolicy, + Spheroid, + CalculationType + > azimuth_strategy_type; + azimuth_strategy_type az_strategy(m_spheroid); + + typedef typename envelope::geographic_segment + < + FormulaPolicy, + Spheroid, + CalculationType + > envelope_segment_strategy_type; + envelope_segment_strategy_type es_strategy(m_spheroid); + + return generic_segment_box::segment_below_of_box + < + LessEqual, + ReturnType + >(p0,p1,top_left,top_right,bottom_left,bottom_right, + geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>(), + az_strategy, es_strategy); + } + + template <typename SPoint, typename BPoint> + static void mirror(SPoint& p0, + SPoint& p1, + BPoint& bottom_left, + BPoint& bottom_right, + BPoint& top_left, + BPoint& top_right) + { + + generic_segment_box::mirror(p0, p1, + bottom_left, bottom_right, + top_left, top_right); + } + +private : + Spheroid m_spheroid; +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +//tags + +template <typename FormulaPolicy> +struct tag<geographic_segment_box<FormulaPolicy> > +{ + typedef strategy_tag_distance_segment_box type; +}; + +template +< + typename FormulaPolicy, + typename Spheroid +> +struct tag<geographic_segment_box<FormulaPolicy, Spheroid> > +{ + typedef strategy_tag_distance_segment_box type; +}; + +template +< + typename FormulaPolicy, + typename Spheroid, + typename CalculationType +> +struct tag<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> > +{ + typedef strategy_tag_distance_segment_box type; +}; + +// return types + +template <typename FormulaPolicy, typename PS, typename PB> +struct return_type<geographic_segment_box<FormulaPolicy>, PS, PB> + : geographic_segment_box<FormulaPolicy>::template return_type<PS, PB> +{}; + +template +< + typename FormulaPolicy, + typename Spheroid, + typename PS, + typename PB +> +struct return_type<geographic_segment_box<FormulaPolicy, Spheroid>, PS, PB> + : geographic_segment_box<FormulaPolicy, Spheroid>::template return_type<PS, PB> +{}; + +template +< + typename FormulaPolicy, + typename Spheroid, + typename CalculationType, + typename PS, + typename PB +> +struct return_type<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>, PS, PB> + : geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>::template return_type<PS, PB> +{}; + +//comparable types + +template +< + typename FormulaPolicy, + typename Spheroid, + typename CalculationType +> +struct comparable_type<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> > +{ + typedef geographic_segment_box + < + FormulaPolicy, Spheroid, CalculationType + > type; +}; + +template +< + typename FormulaPolicy, + typename Spheroid, + typename CalculationType +> +struct get_comparable<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> > +{ + typedef typename comparable_type + < + geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> + >::type comparable_type; +public : + static inline comparable_type + apply(geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> const& ) + { + return comparable_type(); + } +}; + +// result from distance + +template +< + typename FormulaPolicy, + typename PS, + typename PB +> +struct result_from_distance<geographic_segment_box<FormulaPolicy>, PS, PB> +{ +private : + typedef typename geographic_segment_box + < + FormulaPolicy + >::template return_type<PS, PB>::type return_type; +public : + template <typename T> + static inline return_type + apply(geographic_segment_box<FormulaPolicy> const& , T const& distance) + { + return distance; + } +}; + +template +< + typename FormulaPolicy, + typename Spheroid, + typename CalculationType, + typename PS, + typename PB +> +struct result_from_distance<geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>, PS, PB> +{ +private : + typedef typename geographic_segment_box + < + FormulaPolicy, Spheroid, CalculationType + >::template return_type<PS, PB>::type return_type; +public : + template <typename T> + static inline return_type + apply(geographic_segment_box<FormulaPolicy, Spheroid, CalculationType> const& , T const& distance) + { + return distance; + } +}; + + +// default strategies + +template <typename Segment, typename Box> +struct default_strategy + < + segment_tag, box_tag, Segment, Box, + geographic_tag, geographic_tag + > +{ + typedef geographic_segment_box<> type; +}; + +template <typename Box, typename Segment> +struct default_strategy + < + box_tag, segment_tag, Box, Segment, + geographic_tag, geographic_tag + > +{ + typedef typename default_strategy + < + segment_tag, box_tag, Segment, Box, + geographic_tag, geographic_tag + >::type type; +}; + +} +#endif + +}} // namespace strategy::distance + +}} // namespace boost::geometry +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP diff --git a/boost/geometry/strategies/geographic/intersection.hpp b/boost/geometry/strategies/geographic/intersection.hpp index b017097f3e..76c83bb534 100644 --- a/boost/geometry/strategies/geographic/intersection.hpp +++ b/boost/geometry/strategies/geographic/intersection.hpp @@ -2,7 +2,7 @@ // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2016-2017, Oracle and/or its affiliates. +// Copyright (c) 2016-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -425,7 +425,7 @@ private: if (res_a1_a2.distance <= res_b1_b2.distance) { calculate_collinear_data(a1, a2, b1, b2, res_a1_a2, res_a1_b1, res_a1_b2, dist_a1_a2, dist_a1_b1); - calculate_collinear_data(a1, a2, b1, b2, res_a1_a2, res_a1_b2, res_a1_b1, dist_a1_a2, dist_a1_b2); + calculate_collinear_data(a1, a2, b2, b1, res_a1_a2, res_a1_b2, res_a1_b1, dist_a1_a2, dist_a1_b2); dist_b1_b2 = dist_a1_b2 - dist_a1_b1; dist_b1_a1 = -dist_a1_b1; dist_b1_a2 = dist_a1_a2 - dist_a1_b1; @@ -433,7 +433,7 @@ private: else { calculate_collinear_data(b1, b2, a1, a2, res_b1_b2, res_b1_a1, res_b1_a2, dist_b1_b2, dist_b1_a1); - calculate_collinear_data(b1, b2, a1, a2, res_b1_b2, res_b1_a2, res_b1_a1, dist_b1_b2, dist_b1_a2); + calculate_collinear_data(b1, b2, a2, a1, res_b1_b2, res_b1_a2, res_b1_a1, dist_b1_b2, dist_b1_a2); dist_a1_a2 = dist_b1_a2 - dist_b1_a1; dist_a1_b1 = -dist_b1_a1; dist_a1_b2 = dist_b1_b2 - dist_b1_a1; @@ -611,48 +611,48 @@ private: ResultInverse const& res_a1_b1, // in ResultInverse const& res_a1_b2, // in CalcT& dist_a1_a2, // out - CalcT& dist_a1_bi, // out + CalcT& dist_a1_b1, // out bool degen_neq_coords = false) // in { dist_a1_a2 = res_a1_a2.distance; - dist_a1_bi = res_a1_b1.distance; + dist_a1_b1 = res_a1_b1.distance; if (! same_direction(res_a1_b1.azimuth, res_a1_a2.azimuth)) { - dist_a1_bi = -dist_a1_bi; + dist_a1_b1 = -dist_a1_b1; } - // if i1 is close to a1 and b1 or b2 is equal to a1 - if (is_endpoint_equal(dist_a1_bi, a1, b1, b2)) + // if b1 is close a1 + if (is_endpoint_equal(dist_a1_b1, a1, b1)) { - dist_a1_bi = 0; + dist_a1_b1 = 0; return true; } - // or i1 is close to a2 and b1 or b2 is equal to a2 - else if (is_endpoint_equal(dist_a1_a2 - dist_a1_bi, a2, b1, b2)) + // if b1 is close a2 + else if (is_endpoint_equal(dist_a1_a2 - dist_a1_b1, a2, b1)) { - dist_a1_bi = dist_a1_a2; + dist_a1_b1 = dist_a1_a2; return true; } - // check the other endpoint of a very short segment near the pole + // check the other endpoint of degenerated segment near a pole if (degen_neq_coords) { static CalcT const c0 = 0; if (math::equals(res_a1_b2.distance, c0)) { - dist_a1_bi = 0; + dist_a1_b1 = 0; return true; } else if (math::equals(dist_a1_a2 - res_a1_b2.distance, c0)) { - dist_a1_bi = dist_a1_a2; + dist_a1_b1 = dist_a1_a2; return true; } } // or i1 is on b - return segment_ratio<CalcT>(dist_a1_bi, dist_a1_a2).on_segment(); + return segment_ratio<CalcT>(dist_a1_b1, dist_a1_a2).on_segment(); } template <typename Point1, typename Point2, typename CalcT, typename ResultInverse, typename Spheroid_> @@ -876,11 +876,11 @@ private: template <typename CalcT, typename P1, typename P2> static inline bool is_endpoint_equal(CalcT const& dist, - P1 const& ai, P2 const& b1, P2 const& b2) + P1 const& ai, P2 const& b1) { static CalcT const c0 = 0; using geometry::detail::equals::equals_point_point; - return is_near(dist) && (equals_point_point(ai, b1) || equals_point_point(ai, b2) || math::equals(dist, c0)); + return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1)); } template <typename CalcT> diff --git a/boost/geometry/strategies/geographic/parameters.hpp b/boost/geometry/strategies/geographic/parameters.hpp index 4896e42e8d..92ebe08f2a 100644 --- a/boost/geometry/strategies/geographic/parameters.hpp +++ b/boost/geometry/strategies/geographic/parameters.hpp @@ -10,7 +10,6 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_PARAMETERS_HPP #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_PARAMETERS_HPP - #include <boost/geometry/formulas/andoyer_inverse.hpp> #include <boost/geometry/formulas/thomas_direct.hpp> #include <boost/geometry/formulas/thomas_inverse.hpp> @@ -26,7 +25,6 @@ namespace boost { namespace geometry { namespace strategy struct andoyer { - //TODO: this should be replaced by an andoyer direct formula template < typename CT, @@ -38,7 +36,8 @@ struct andoyer struct direct : formula::thomas_direct < - CT, EnableCoordinates, EnableReverseAzimuth, + CT, false, + EnableCoordinates, EnableReverseAzimuth, EnableReducedLength, EnableGeodesicScale > {}; @@ -75,7 +74,8 @@ struct thomas struct direct : formula::thomas_direct < - CT, EnableCoordinates, EnableReverseAzimuth, + CT, true, + EnableCoordinates, EnableReverseAzimuth, EnableReducedLength, EnableGeodesicScale > {}; diff --git a/boost/geometry/strategies/spherical/azimuth.hpp b/boost/geometry/strategies/spherical/azimuth.hpp index 7a711c9814..bdfc401575 100644 --- a/boost/geometry/strategies/spherical/azimuth.hpp +++ b/boost/geometry/strategies/spherical/azimuth.hpp @@ -37,42 +37,67 @@ public : {} template <typename T> - static inline void apply(T const& lon1_rad, T const& lat1_rad, - T const& lon2_rad, T const& lat2_rad, - T& a1, T& a2) + inline void apply(T const& lon1_rad, T const& lat1_rad, + T const& lon2_rad, T const& lat2_rad, + T& a1, T& a2) const { - typedef typename boost::mpl::if_ - < - boost::is_void<CalculationType>, T, CalculationType - >::type calc_t; - - geometry::formula::result_spherical<calc_t> - result = geometry::formula::spherical_azimuth<calc_t, true>( - calc_t(lon1_rad), calc_t(lat1_rad), - calc_t(lon2_rad), calc_t(lat2_rad)); - - a1 = result.azimuth; - a2 = result.reverse_azimuth; + compute<true, true>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a1, a2); } - template <typename T> inline void apply(T const& lon1_rad, T const& lat1_rad, T const& lon2_rad, T const& lat2_rad, T& a1) const { - typedef typename boost::mpl::if_ + compute<true, false>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a1, a1); + } + template <typename T> + inline void apply_reverse(T const& lon1_rad, T const& lat1_rad, + T const& lon2_rad, T const& lat2_rad, + T& a2) const + { + compute<false, true>(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + a2, a2); + } + +private : + + template + < + bool EnableAzimuth, + bool EnableReverseAzimuth, + typename T + > + inline void compute(T const& lon1_rad, T const& lat1_rad, + T const& lon2_rad, T const& lat2_rad, + T& a1, T& a2) const + { + typedef typename boost::mpl::if_ < boost::is_void<CalculationType>, T, CalculationType >::type calc_t; geometry::formula::result_spherical<calc_t> - result = geometry::formula::spherical_azimuth<calc_t, false>( - calc_t(lon1_rad), calc_t(lat1_rad), - calc_t(lon2_rad), calc_t(lat2_rad)); - - a1 = result.azimuth; + result = geometry::formula::spherical_azimuth + < + calc_t, + EnableReverseAzimuth + >(calc_t(lon1_rad), calc_t(lat1_rad), + calc_t(lon2_rad), calc_t(lat2_rad)); + + if (EnableAzimuth) + { + a1 = result.azimuth; + } + if (EnableReverseAzimuth) + { + a2 = result.reverse_azimuth; + } } - }; #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS diff --git a/boost/geometry/strategies/spherical/distance_cross_track.hpp b/boost/geometry/strategies/spherical/distance_cross_track.hpp index db029dff90..97a36b8b27 100644 --- a/boost/geometry/strategies/spherical/distance_cross_track.hpp +++ b/boost/geometry/strategies/spherical/distance_cross_track.hpp @@ -352,12 +352,6 @@ public : : m_strategy(s) {} - //TODO: apply a more general strategy getter - inline Strategy get_distance_strategy() const - { - return m_strategy; - } - // It might be useful in the future // to overload constructor with strategy info. // crosstrack(...) {} @@ -473,6 +467,12 @@ public : } } + template <typename T1, typename T2> + inline radius_type vertical_or_meridian(T1 lat1, T2 lat2) const + { + return m_strategy.radius() * (lat1 - lat2); + } + inline typename Strategy::radius_type radius() const { return m_strategy.radius(); } @@ -531,12 +531,6 @@ public : : m_strategy(s) {} - //TODO: apply a more general strategy getter - inline Strategy get_distance_strategy() const - { - return m_strategy; - } - // It might be useful in the future // to overload constructor with strategy info. // crosstrack(...) {} @@ -569,6 +563,12 @@ public : return c * radius(); } + template <typename T1, typename T2> + inline radius_type vertical_or_meridian(T1 lat1, T2 lat2) const + { + return m_strategy.radius() * (lat1 - lat2); + } + inline typename Strategy::radius_type radius() const { return m_strategy.radius(); } diff --git a/boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp b/boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp index efa7a728a6..55500af0ed 100644 --- a/boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp +++ b/boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp @@ -44,18 +44,19 @@ class cross_track_box_box_generic { public : - template <typename Point, typename Strategy> + template <typename Point, typename PPStrategy, typename PSStrategy> ReturnType static inline diagonal_case(Point topA, Point topB, Point bottomA, Point bottomB, bool north_shortest, bool non_overlap, - Strategy ps_strategy) + PPStrategy pp_strategy, + PSStrategy ps_strategy) { if (north_shortest && non_overlap) { - return ps_strategy.get_distance_strategy().apply(topA, bottomB); + return pp_strategy.apply(topA, bottomB); } if (north_shortest && !non_overlap) { @@ -63,7 +64,7 @@ public : } if (!north_shortest && non_overlap) { - return ps_strategy.get_distance_strategy().apply(bottomA, topB); + return pp_strategy.apply(bottomA, topB); } return ps_strategy.apply(bottomA, topB, bottomB); } @@ -73,11 +74,13 @@ public : < typename Box1, typename Box2, - typename Strategy + typename PPStrategy, + typename PSStrategy > ReturnType static inline apply (Box1 const& box1, Box2 const& box2, - Strategy ps_strategy) + PPStrategy pp_strategy, + PSStrategy ps_strategy) { // this method assumes that the coordinates of the point and @@ -129,7 +132,7 @@ public : #ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK_BOX_BOX std::cout << "(box1 crosses antimeridian)"; #endif - return apply(box2, box1, ps_strategy); + return apply(box2, box1, pp_strategy, ps_strategy); } else { @@ -160,17 +163,17 @@ public : { return geometry::strategy::distance::services::result_from_distance < - Strategy, box_point_type1, box_point_type2 - >::apply(ps_strategy, ps_strategy.get_distance_strategy() - .meridian(lat_min1, lat_max2)); + PSStrategy, box_point_type1, box_point_type2 + >::apply(ps_strategy, ps_strategy + .vertical_or_meridian(lat_min1, lat_max2)); } else if (lat_max1 < lat_min2) { return geometry::strategy::distance::services::result_from_distance < - Strategy, box_point_type1, box_point_type2 - >::apply(ps_strategy, ps_strategy.get_distance_strategy(). - meridian(lat_min2, lat_max1)); + PSStrategy, box_point_type1, box_point_type2 + >::apply(ps_strategy, ps_strategy + .vertical_or_meridian(lat_min2, lat_max1)); } else { @@ -211,7 +214,7 @@ public : return diagonal_case(top_right2, top_left1, bottom_right2, bottom_left1, north_shortest, non_overlap, - ps_strategy); + pp_strategy, ps_strategy); } if (bottom_max && right_wrap) { @@ -221,7 +224,7 @@ public : return diagonal_case(top_left2, top_right1, bottom_left2, bottom_right1, north_shortest, non_overlap, - ps_strategy); + pp_strategy, ps_strategy); } if (!bottom_max && !right_wrap) { @@ -231,7 +234,7 @@ public : return diagonal_case(top_left1, top_right2, bottom_left1, bottom_right2, north_shortest, non_overlap, - ps_strategy); + pp_strategy, ps_strategy); } if (!bottom_max && right_wrap) { @@ -241,7 +244,7 @@ public : return diagonal_case(top_right1, top_left2, bottom_right1, bottom_left2, north_shortest, non_overlap, - ps_strategy); + pp_strategy, ps_strategy); } return ReturnType(0); } @@ -265,7 +268,7 @@ to cross track template < typename CalculationType = void, - typename Strategy = cross_track<CalculationType> + typename Strategy = haversine<double, CalculationType> > class cross_track_box_box { @@ -279,15 +282,44 @@ public: typedef typename Strategy::radius_type radius_type; + // strategy getters + + // point-segment strategy getters + struct distance_ps_strategy + { + typedef cross_track<CalculationType, Strategy> type; + }; + + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type pp_comparable_strategy; + + typedef typename boost::mpl::if_ + < + boost::is_same + < + pp_comparable_strategy, + Strategy + >, + typename strategy::distance::services::comparable_type + < + typename distance_ps_strategy::type + >::type, + typename distance_ps_strategy::type + >::type ps_strategy_type; + + // constructors + inline cross_track_box_box() {} explicit inline cross_track_box_box(typename Strategy::radius_type const& r) - : m_ps_strategy(r) + : m_strategy(r) {} inline cross_track_box_box(Strategy const& s) - : m_ps_strategy(s) + : m_strategy(s) {} @@ -302,7 +334,7 @@ public: #if !defined(BOOST_MSVC) BOOST_CONCEPT_ASSERT ( - (concepts::PointSegmentDistanceStrategy + (concepts::PointDistanceStrategy < Strategy, typename point_type<Box1>::type, @@ -312,16 +344,18 @@ public: #endif typedef typename return_type<Box1, Box2>::type return_type; return details::cross_track_box_box_generic - <return_type>::apply(box1, box2, m_ps_strategy); + <return_type>::apply(box1, box2, + m_strategy, + ps_strategy_type(m_strategy)); } inline typename Strategy::radius_type radius() const { - return m_ps_strategy.radius(); + return m_strategy.radius(); } private: - Strategy m_ps_strategy; + Strategy m_strategy; }; @@ -419,7 +453,7 @@ struct default_strategy boost::is_void<Strategy>, typename default_strategy < - point_tag, segment_tag, + point_tag, point_tag, typename point_type<Box1>::type, typename point_type<Box2>::type, spherical_equatorial_tag, spherical_equatorial_tag >::type, diff --git a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp index 9c8e7f1a3e..917eabb8d6 100644 --- a/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp +++ b/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp @@ -100,14 +100,16 @@ public : return geometry::strategy::distance::services::result_from_distance < Strategy, Point, box_point_type - >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(plat, lat_max)); + >::apply(ps_strategy, ps_strategy + .vertical_or_meridian(plat, lat_max)); } else if (plat < lat_min) { return geometry::strategy::distance::services::result_from_distance < Strategy, Point, box_point_type - >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(lat_min, plat)); + >::apply(ps_strategy, ps_strategy + .vertical_or_meridian(lat_min, plat)); } else { @@ -186,8 +188,7 @@ public : \details Class which calculates the distance of a point to a box, for points and boxes on a sphere or globe \tparam CalculationType \tparam_calculation -\tparam Strategy underlying point-segment distance strategy, defaults -to cross track +\tparam Strategy underlying point-point distance strategy \qbk{ [heading See also] [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)] @@ -196,7 +197,7 @@ to cross track template < typename CalculationType = void, - typename Strategy = cross_track<CalculationType> + typename Strategy = haversine<double, CalculationType> > class cross_track_point_box { @@ -208,18 +209,49 @@ public: typedef typename Strategy::radius_type radius_type; + // strategy getters + + // point-segment strategy getters + struct distance_ps_strategy + { + typedef cross_track<CalculationType, Strategy> type; + }; + + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type pp_comparable_strategy; + + typedef typename boost::mpl::if_ + < + boost::is_same + < + pp_comparable_strategy, + Strategy + >, + typename strategy::distance::services::comparable_type + < + typename distance_ps_strategy::type + >::type, + typename distance_ps_strategy::type + >::type ps_strategy_type; + + // constructors + inline cross_track_point_box() {} explicit inline cross_track_point_box(typename Strategy::radius_type const& r) - : m_ps_strategy(r) + : m_strategy(r) {} inline cross_track_point_box(Strategy const& s) - : m_ps_strategy(s) + : m_strategy(s) {} + // methods + // It might be useful in the future // to overload constructor with strategy info. // crosstrack(...) {} @@ -231,7 +263,7 @@ public: #if !defined(BOOST_MSVC) BOOST_CONCEPT_ASSERT ( - (concepts::PointSegmentDistanceStrategy + (concepts::PointDistanceStrategy < Strategy, Point, typename point_type<Box>::type >) @@ -239,16 +271,17 @@ public: #endif typedef typename return_type<Point, Box>::type return_type; return details::cross_track_point_box_generic - <return_type>::apply(point, box, m_ps_strategy); + <return_type>::apply(point, box, + ps_strategy_type(m_strategy)); } inline typename Strategy::radius_type radius() const { - return m_ps_strategy.radius(); + return m_strategy.radius(); } private: - Strategy m_ps_strategy; + Strategy m_strategy; }; @@ -344,7 +377,7 @@ struct default_strategy boost::is_void<Strategy>, typename default_strategy < - point_tag, segment_tag, + point_tag, point_tag, Point, typename point_type<Box>::type, spherical_equatorial_tag, spherical_equatorial_tag >::type, diff --git a/boost/geometry/strategies/spherical/distance_haversine.hpp b/boost/geometry/strategies/spherical/distance_haversine.hpp index 1a4cbdf36b..bd46a93c6a 100644 --- a/boost/geometry/strategies/spherical/distance_haversine.hpp +++ b/boost/geometry/strategies/spherical/distance_haversine.hpp @@ -94,12 +94,6 @@ public : ); } - template <typename T1, typename T2> - inline radius_type meridian(T1 lat1, T2 lat2) const - { - return m_radius * (lat1 - lat2); - } - inline radius_type radius() const { return m_radius; @@ -198,19 +192,6 @@ public : } /*! - \brief meridian distance calculation - \return the calculated distance (including multiplying with radius) - \param p1 first point - \param p2 second point - */ - - template <typename T1, typename T2> - inline radius_type meridian(T1 lat1, T2 lat2) const - { - return m_radius * (lat1 - lat2); - } - - /*! \brief access to radius value \return the radius */ diff --git a/boost/geometry/strategies/spherical/distance_segment_box.hpp b/boost/geometry/strategies/spherical/distance_segment_box.hpp new file mode 100644 index 0000000000..d5647182a8 --- /dev/null +++ b/boost/geometry/strategies/spherical/distance_segment_box.hpp @@ -0,0 +1,340 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2018 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_SEGMENT_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_SEGMENT_BOX_HPP + +#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp> + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace distance +{ + +struct generic_segment_box +{ + template + < + typename LessEqual, + typename ReturnType, + typename SegmentPoint, + typename BoxPoint, + typename SegmentBoxStrategy, + typename AzimuthStrategy, + typename EnvelopeSegmentStrategy + > + static inline ReturnType segment_below_of_box( + SegmentPoint const& p0, + SegmentPoint const& p1, + BoxPoint const&, + BoxPoint const& top_right, + BoxPoint const& bottom_left, + BoxPoint const& bottom_right, + SegmentBoxStrategy const& sb_strategy, + AzimuthStrategy & az_strategy, + EnvelopeSegmentStrategy & es_strategy) + { + ReturnType result; + typename LessEqual::other less_equal; + typedef geometry::model::segment<SegmentPoint> Segment; + typedef typename cs_tag<Segment>::type segment_cs_type; + typedef geometry::detail::disjoint:: + disjoint_segment_box_sphere_or_spheroid<segment_cs_type> + disjoint_sb; + typedef typename disjoint_sb::disjoint_info disjoint_info_type; + + Segment seg(p0, p1); + + geometry::model::box<BoxPoint> input_box; + geometry::set_from_radian<geometry::min_corner, 0> + (input_box, geometry::get_as_radian<0>(bottom_left)); + geometry::set_from_radian<geometry::min_corner, 1> + (input_box, geometry::get_as_radian<1>(bottom_left)); + geometry::set_from_radian<geometry::max_corner, 0> + (input_box, geometry::get_as_radian<0>(top_right)); + geometry::set_from_radian<geometry::max_corner, 1> + (input_box, geometry::get_as_radian<1>(top_right)); + + SegmentPoint p_max; + + disjoint_info_type disjoint_result = disjoint_sb:: + apply(seg, input_box, az_strategy, p_max); + + if (disjoint_result == disjoint_info_type::intersect) //intersect + { + return 0; + } + // disjoint but vertex not computed + if (disjoint_result == disjoint_info_type::disjoint_no_vertex) + { + typedef typename coordinate_type<SegmentPoint>::type CT; + + geometry::model::box<SegmentPoint> mbr; + geometry::envelope(seg, mbr, es_strategy); + + CT lon1 = geometry::get_as_radian<0>(p0); + CT lat1 = geometry::get_as_radian<1>(p0); + CT lon2 = geometry::get_as_radian<0>(p1); + CT lat2 = geometry::get_as_radian<1>(p1); + + CT vertex_lat; + CT lat_sum = lat1 + lat2; + if (lat_sum > CT(0)) + { + vertex_lat = geometry::get_as_radian<geometry::max_corner, 1>(mbr); + } else { + vertex_lat = geometry::get_as_radian<geometry::min_corner, 1>(mbr); + } + + CT alp1; + az_strategy.apply(lon1, lat1, lon2, lat2, alp1); + CT vertex_lon = geometry::formula::vertex_longitude + < + CT, + segment_cs_type + >::apply(lon1, lat1, lon2, lat2, + vertex_lat, alp1, az_strategy); + + geometry::set_from_radian<0>(p_max, vertex_lon); + geometry::set_from_radian<1>(p_max, vertex_lat); + } + //otherwise disjoint and vertex computed inside disjoint + + if (less_equal(geometry::get_as_radian<0>(bottom_left), + geometry::get_as_radian<0>(p_max))) + { + result = boost::numeric_cast<ReturnType>(typename + SegmentBoxStrategy::distance_ps_strategy::type().apply(bottom_left, p0, p1)); + } + else + { + result = geometry::detail::distance::segment_to_box_2D + < + ReturnType, + SegmentPoint, + BoxPoint, + SegmentBoxStrategy + >::template call_above_of_box + < + typename LessEqual::other + >(p1, p0, p_max, bottom_right, sb_strategy); + } + return result; + } + + template <typename SPoint, typename BPoint> + static void mirror(SPoint& p0, + SPoint& p1, + BPoint& bottom_left, + BPoint& bottom_right, + BPoint& top_left, + BPoint& top_right) + { + //if segment's vertex is the southest point then mirror geometries + if (geometry::get<1>(p0) + geometry::get<1>(p1) < 0) + { + BPoint bl = bottom_left; + BPoint br = bottom_right; + geometry::set<1>(p0, geometry::get<1>(p0) * -1); + geometry::set<1>(p1, geometry::get<1>(p1) * -1); + geometry::set<1>(bottom_left, geometry::get<1>(top_left) * -1); + geometry::set<1>(top_left, geometry::get<1>(bl) * -1); + geometry::set<1>(bottom_right, geometry::get<1>(top_right) * -1); + geometry::set<1>(top_right, geometry::get<1>(br) * -1); + } + } +}; + +//=========================================================================== + +template +< + typename CalculationType = void, + typename Strategy = haversine<double, CalculationType> +> +struct spherical_segment_box +{ + template <typename PointOfSegment, typename PointOfBox> + struct calculation_type + : promote_floating_point + < + typename strategy::distance::services::return_type + < + Strategy, + PointOfSegment, + PointOfBox + >::type + > + {}; + + // strategy getters + + // point-point strategy getters + struct distance_pp_strategy + { + typedef Strategy type; + }; + + inline typename distance_pp_strategy::type get_distance_pp_strategy() const + { + return typename distance_pp_strategy::type(); + } + // point-segment strategy getters + struct distance_ps_strategy + { + typedef cross_track<CalculationType, Strategy> type; + }; + + inline typename distance_ps_strategy::type get_distance_ps_strategy() const + { + return typename distance_ps_strategy::type(); + } + + // methods + + template <typename LessEqual, typename ReturnType, + typename SegmentPoint, typename BoxPoint> + inline ReturnType segment_below_of_box(SegmentPoint const& p0, + SegmentPoint const& p1, + BoxPoint const& top_left, + BoxPoint const& top_right, + BoxPoint const& bottom_left, + BoxPoint const& bottom_right) const + { + typedef typename azimuth::spherical<CalculationType> azimuth_strategy_type; + azimuth_strategy_type az_strategy; + + typedef typename envelope::spherical_segment<CalculationType> + envelope_segment_strategy_type; + envelope_segment_strategy_type es_strategy; + + return generic_segment_box::segment_below_of_box + < + LessEqual, + ReturnType + >(p0,p1,top_left,top_right,bottom_left,bottom_right, + spherical_segment_box<CalculationType>(), + az_strategy, es_strategy); + } + + template <typename SPoint, typename BPoint> + static void mirror(SPoint& p0, + SPoint& p1, + BPoint& bottom_left, + BPoint& bottom_right, + BPoint& top_left, + BPoint& top_right) + { + + generic_segment_box::mirror(p0, p1, + bottom_left, bottom_right, + top_left, top_right); + } + +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template <typename CalculationType, typename Strategy> +struct tag<spherical_segment_box<CalculationType, Strategy> > +{ + typedef strategy_tag_distance_segment_box type; +}; + +template <typename CalculationType, typename Strategy, typename PS, typename PB> +struct return_type<spherical_segment_box<CalculationType, Strategy>, PS, PB> + : spherical_segment_box<CalculationType, Strategy>::template calculation_type<PS, PB> +{}; + +template <typename CalculationType, typename Strategy> +struct comparable_type<spherical_segment_box<CalculationType, Strategy> > +{ + // Define a cartesian_segment_box strategy with its underlying point-segment + // strategy being comparable + typedef spherical_segment_box + < + CalculationType, + typename comparable_type<Strategy>::type + > type; +}; + + +template <typename CalculationType, typename Strategy> +struct get_comparable<spherical_segment_box<CalculationType, Strategy> > +{ + typedef typename comparable_type + < + spherical_segment_box<CalculationType, Strategy> + >::type comparable_type; +public : + static inline comparable_type apply(spherical_segment_box<CalculationType, Strategy> const& ) + { + return comparable_type(); + } +}; + +template <typename CalculationType, typename Strategy, typename PS, typename PB> +struct result_from_distance<spherical_segment_box<CalculationType, Strategy>, PS, PB> +{ +private : + typedef typename return_type< + spherical_segment_box + < + CalculationType, + Strategy + >, + PS, + PB + >::type return_type; +public : + template <typename T> + static inline return_type apply(spherical_segment_box<CalculationType, + Strategy> const& , + T const& value) + { + Strategy s; + return result_from_distance<Strategy, PS, PB>::apply(s, value); + } +}; + +template <typename Segment, typename Box> +struct default_strategy + < + segment_tag, box_tag, Segment, Box, + spherical_equatorial_tag, spherical_equatorial_tag + > +{ + typedef spherical_segment_box<> type; +}; + +template <typename Box, typename Segment> +struct default_strategy + < + box_tag, segment_tag, Box, Segment, + spherical_equatorial_tag, spherical_equatorial_tag + > +{ + typedef typename default_strategy + < + segment_tag, box_tag, Segment, Box, + spherical_equatorial_tag, spherical_equatorial_tag + >::type type; +}; + +} +#endif + +}} // namespace strategy::distance + +}} // namespace boost::geometry +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_SEGMENT_BOX_HPP diff --git a/boost/geometry/strategies/spherical/intersection.hpp b/boost/geometry/strategies/spherical/intersection.hpp index 1cc7b20764..2bdc8b51ab 100644 --- a/boost/geometry/strategies/spherical/intersection.hpp +++ b/boost/geometry/strategies/spherical/intersection.hpp @@ -2,7 +2,7 @@ // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2016-2017, Oracle and/or its affiliates. +// Copyright (c) 2016-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -425,7 +425,7 @@ struct ecef_segments if (len1 <= len2) { calculate_collinear_data(a1, a2, b1, b2, a1v, a2v, plane1, b1v, b2v, dist_a1_a2, dist_a1_b1); - calculate_collinear_data(a1, a2, b1, b2, a1v, a2v, plane1, b2v, b1v, dist_a1_a2, dist_a1_b2); + calculate_collinear_data(a1, a2, b2, b1, a1v, a2v, plane1, b2v, b1v, dist_a1_a2, dist_a1_b2); dist_b1_b2 = dist_a1_b2 - dist_a1_b1; dist_b1_a1 = -dist_a1_b1; dist_b1_a2 = dist_a1_a2 - dist_a1_b1; @@ -433,7 +433,7 @@ struct ecef_segments else { calculate_collinear_data(b1, b2, a1, a2, b1v, b2v, plane2, a1v, a2v, dist_b1_b2, dist_b1_a1); - calculate_collinear_data(b1, b2, a1, a2, b1v, b2v, plane2, a2v, a1v, dist_b1_b2, dist_b1_a2); + calculate_collinear_data(b1, b2, a2, a1, b1v, b2v, plane2, a2v, a1v, dist_b1_b2, dist_b1_a2); dist_a1_a2 = dist_b1_a2 - dist_b1_a1; dist_a1_b1 = -dist_b1_a1; dist_a1_b2 = dist_b1_b2 - dist_b1_a1; @@ -541,54 +541,54 @@ private: template <typename Point1, typename Point2, typename Vec3d, typename Plane, typename CalcT> static inline bool calculate_collinear_data(Point1 const& a1, Point1 const& a2, // in - Point2 const& b1, Point2 const& b2, // in + Point2 const& b1, Point2 const& /*b2*/, // in Vec3d const& a1v, // in Vec3d const& a2v, // in Plane const& plane1, // in Vec3d const& b1v, // in Vec3d const& b2v, // in CalcT const& dist_a1_a2, // in - CalcT& dist_a1_i1, // out + CalcT& dist_a1_b1, // out bool degen_neq_coords = false) // in { - // calculate dist_a1_a2 and dist_a1_i1 - calculate_dist(a1v, a2v, plane1, b1v, dist_a1_i1); + // calculate dist_a1_b1 + calculate_dist(a1v, a2v, plane1, b1v, dist_a1_b1); - // if i1 is close to a1 and b1 or b2 is equal to a1 - if (is_endpoint_equal(dist_a1_i1, a1, b1, b2)) + // if b1 is equal to a1 + if (is_endpoint_equal(dist_a1_b1, a1, b1)) { - dist_a1_i1 = 0; + dist_a1_b1 = 0; return true; } - // or i1 is close to a2 and b1 or b2 is equal to a2 - else if (is_endpoint_equal(dist_a1_a2 - dist_a1_i1, a2, b1, b2)) + // or b1 is equal to a2 + else if (is_endpoint_equal(dist_a1_a2 - dist_a1_b1, a2, b1)) { - dist_a1_i1 = dist_a1_a2; + dist_a1_b1 = dist_a1_a2; return true; } - // check the other endpoint of a very short segment near the pole + // check the other endpoint of degenerated segment near a pole if (degen_neq_coords) { static CalcT const c0 = 0; - CalcT dist_a1_i2 = 0; - calculate_dist(a1v, a2v, plane1, b2v, dist_a1_i2); + CalcT dist_a1_b2 = 0; + calculate_dist(a1v, a2v, plane1, b2v, dist_a1_b2); - if (math::equals(dist_a1_i2, c0)) + if (math::equals(dist_a1_b2, c0)) { - dist_a1_i1 = 0; + dist_a1_b1 = 0; return true; } - else if (math::equals(dist_a1_a2 - dist_a1_i2, c0)) + else if (math::equals(dist_a1_a2 - dist_a1_b2, c0)) { - dist_a1_i1 = dist_a1_a2; + dist_a1_b1 = dist_a1_a2; return true; } } // or i1 is on b - return segment_ratio<CalcT>(dist_a1_i1, dist_a1_a2).on_segment(); + return segment_ratio<CalcT>(dist_a1_b1, dist_a1_a2).on_segment(); } template <typename Point1, typename Point2, typename Vec3d, typename Plane, typename CalcT> @@ -819,11 +819,11 @@ private: template <typename CalcT, typename P1, typename P2> static inline bool is_endpoint_equal(CalcT const& dist, - P1 const& ai, P2 const& b1, P2 const& b2) + P1 const& ai, P2 const& b1) { static CalcT const c0 = 0; using geometry::detail::equals::equals_point_point; - return is_near(dist) && (equals_point_point(ai, b1) || equals_point_point(ai, b2) || math::equals(dist, c0)); + return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1)); } template <typename CalcT> diff --git a/boost/geometry/strategies/strategies.hpp b/boost/geometry/strategies/strategies.hpp index 7d6cb618c6..b6430692f4 100644 --- a/boost/geometry/strategies/strategies.hpp +++ b/boost/geometry/strategies/strategies.hpp @@ -63,6 +63,7 @@ #include <boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp> #include <boost/geometry/strategies/cartesian/distance_projected_point.hpp> #include <boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp> +#include <boost/geometry/strategies/cartesian/distance_segment_box.hpp> #include <boost/geometry/strategies/cartesian/envelope_segment.hpp> #include <boost/geometry/strategies/cartesian/intersection.hpp> #include <boost/geometry/strategies/cartesian/point_in_box.hpp> @@ -79,6 +80,7 @@ #include <boost/geometry/strategies/spherical/distance_cross_track.hpp> #include <boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp> #include <boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp> +#include <boost/geometry/strategies/spherical/distance_segment_box.hpp> #include <boost/geometry/strategies/spherical/compare.hpp> #include <boost/geometry/strategies/spherical/envelope_segment.hpp> #include <boost/geometry/strategies/spherical/intersection.hpp> @@ -94,6 +96,7 @@ #include <boost/geometry/strategies/geographic/distance_cross_track.hpp> #include <boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp> #include <boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp> +#include <boost/geometry/strategies/geographic/distance_segment_box.hpp> #include <boost/geometry/strategies/geographic/distance_thomas.hpp> #include <boost/geometry/strategies/geographic/distance_vincenty.hpp> #include <boost/geometry/strategies/geographic/envelope_segment.hpp> diff --git a/boost/geometry/strategies/tags.hpp b/boost/geometry/strategies/tags.hpp index 7589c21071..748541f59b 100644 --- a/boost/geometry/strategies/tags.hpp +++ b/boost/geometry/strategies/tags.hpp @@ -7,6 +7,11 @@ // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -36,6 +41,7 @@ struct strategy_tag_distance_point_point {}; struct strategy_tag_distance_point_segment {}; struct strategy_tag_distance_point_box {}; struct strategy_tag_distance_box_box {}; +struct strategy_tag_distance_segment_box {}; }} // namespace boost::geometry diff --git a/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp b/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp new file mode 100644 index 0000000000..d67251254d --- /dev/null +++ b/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp @@ -0,0 +1,43 @@ +// Boost.Geometry + +// Copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP +#define BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP + +#include <boost/geometry/util/math.hpp> + +namespace boost { namespace geometry +{ + +template<class CT> +struct bounds +{ + static CT lowest () { return boost::numeric::bounds<CT>::lowest(); } + static CT highest () { return boost::numeric::bounds<CT>::highest(); } +}; + +template <typename Box> +bool is_inverse_spheroidal_coordinates(Box const& box) +{ + typedef typename point_type<Box>::type point_type; + typedef typename coordinate_type<point_type>::type bound_type; + + bound_type high = bounds<bound_type>::highest(); + bound_type low = bounds<bound_type>::lowest(); + + return (geometry::get<0, 0>(box) == high) && + (geometry::get<0, 1>(box) == high) && + (geometry::get<1, 0>(box) == low) && + (geometry::get<1, 1>(box) == low); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP diff --git a/boost/geometry/util/math.hpp b/boost/geometry/util/math.hpp index b1c3648c98..aed930dd97 100644 --- a/boost/geometry/util/math.hpp +++ b/boost/geometry/util/math.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -771,6 +771,17 @@ inline Result rounding_cast(T const& v) return detail::rounding_cast<Result, T>::apply(v); } +/*! +\brief Short utility to calculate the power +\ingroup utility +*/ +template <typename T1, typename T2> +inline T1 pow(T1 const& a, T2 const& b) +{ + using std::pow; + return pow(a, b); +} + } // namespace math |