Imported Upstream version 1.71.0
[platform/upstream/boost.git] / boost / geometry / srs / projections / impl / pj_apply_gridshift_shared.hpp
1 // Boost.Geometry
2 // This file is manually converted from PROJ4
3
4 // This file was modified by Oracle on 2018, 2019.
5 // Modifications copyright (c) 2018-2019, Oracle and/or its affiliates.
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11
12 // This file is converted from PROJ4, http://trac.osgeo.org/proj
13 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
14 // PROJ4 is maintained by Frank Warmerdam
15 // This file was converted to Geometry Library by Adam Wulkiewicz
16
17 // Original copyright notice:
18 // Author:   Frank Warmerdam, warmerdam@pobox.com
19
20 // Copyright (c) 2000, Frank Warmerdam
21
22 // Permission is hereby granted, free of charge, to any person obtaining a
23 // copy of this software and associated documentation files (the "Software"),
24 // to deal in the Software without restriction, including without limitation
25 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
26 // and/or sell copies of the Software, and to permit persons to whom the
27 // Software is furnished to do so, subject to the following conditions:
28
29 // The above copyright notice and this permission notice shall be included
30 // in all copies or substantial portions of the Software.
31
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
33 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
35 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
37 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
38 // DEALINGS IN THE SOFTWARE.
39
40 #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP
41 #define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP
42
43
44 #include <boost/geometry/core/assert.hpp>
45 #include <boost/geometry/core/radian_access.hpp>
46
47 #include <boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp>
48 #include <boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp>
49
50
51 namespace boost { namespace geometry { namespace projections
52 {
53
54 namespace detail
55 {
56
57 template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
58 inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
59                                  Range & range,
60                                  shared_grids & grids,
61                                  std::vector<std::size_t> const& gridindexes)
62 {
63     typedef typename boost::range_size<Range>::type size_type;
64     
65     // If the grids are empty the indexes are as well
66     if (gridindexes.empty())
67     {
68         //pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
69         //return PJD_ERR_FAILED_TO_LOAD_GRID;
70         return false;
71     }
72
73     size_type point_count = boost::size(range);
74
75     // local storage
76     pj_gi_load local_gi;
77
78     for (size_type i = 0 ; i < point_count ; )
79     {
80         bool load_needed = false;
81
82         CalcT in_lon = 0;
83         CalcT in_lat = 0;
84
85         {
86             boost::shared_lock<boost::shared_mutex> lock(grids.mutex);
87
88             for ( ; i < point_count ; ++i )
89             {
90                 typename boost::range_reference<Range>::type
91                     point = range::at(range, i);
92
93                 in_lon = geometry::get_as_radian<0>(point);
94                 in_lat = geometry::get_as_radian<1>(point);
95
96                 pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes);
97
98                 if (gip == NULL)
99                 {
100                     // do nothing
101                 }
102                 else if (! gip->ct.cvs.empty())
103                 {
104                     // TODO: use set_invalid_point() or similar mechanism
105                     CalcT out_lon = HUGE_VAL;
106                     CalcT out_lat = HUGE_VAL;
107
108                     nad_cvt<Inverse>(in_lon, in_lat, out_lon, out_lat, *gip);
109
110                     // TODO: check differently
111                     if (out_lon != HUGE_VAL)
112                     {
113                         geometry::set_from_radian<0>(point, out_lon);
114                         geometry::set_from_radian<1>(point, out_lat);
115                     }
116                 }
117                 else
118                 {
119                     // loading is needed
120                     local_gi = *gip;
121                     load_needed = true;
122                     break;
123                 }
124             }
125         }
126
127         if (load_needed)
128         {
129             if (load_grid(stream_policy, local_gi))
130             {
131                 boost::unique_lock<boost::shared_mutex> lock(grids.mutex);
132
133                 // check again in case other thread already loaded the grid.
134                 pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes);
135
136                 if (gip != NULL && gip->ct.cvs.empty())
137                 {
138                     // swap loaded local storage with empty grid
139                     local_gi.swap(*gip);
140                 }
141             }
142             else
143             {
144                 ++i;
145             }
146         }
147     }
148
149     return true;
150 }
151
152
153 } // namespace detail
154
155 }}} // namespace boost::geometry::projections
156
157 #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP