Skip to content
This repository
Newer
Older
100644 325 lines (272 sloc) 8.344 kb
110016fe »
2006-10-17 1. refactored proj stuff into separate files
1 /*****************************************************************************
17d13cff »
2012-02-01 whitespace fixes - closes #911
2 *
110016fe »
2006-10-17 1. refactored proj stuff into separate files
3 * This file is part of Mapnik (c++ mapping toolkit)
4 *
f1fb0c19 »
2011-10-23 - fix copyright to 2011 (script to do this will follow)
5 * Copyright (C) 2011 Artem Pavlenko
110016fe »
2006-10-17 1. refactored proj stuff into separate files
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 *****************************************************************************/
22
f4949ffc »
2008-02-04 patch from TomH adds a global mutex to protect all access to the
23 // mapnik
911981ae »
2011-10-19 + various win32 fixes, mainly adding extra namespace qualifiers
24 #include <mapnik/global.hpp>
110016fe »
2006-10-17 1. refactored proj stuff into separate files
25 #include <mapnik/proj_transform.hpp>
17d13cff »
2012-02-01 whitespace fixes - closes #911
26 #include <mapnik/coord.hpp>
f4949ffc »
2008-02-04 patch from TomH adds a global mutex to protect all access to the
27 #include <mapnik/utils.hpp>
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
28
f4949ffc »
2008-02-04 patch from TomH adds a global mutex to protect all access to the
29 // proj4
bc54b150 »
2007-10-08 - reversed header include order
30 #include <proj_api.h>
31
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
32 // stl
33 #include <vector>
34
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
35 static const float MAXEXTENT = 20037508.34;
36 static const float M_PI_by2 = M_PI / 2;
37 static const float D2R = M_PI / 180;
38 static const float R2D = 180 / M_PI;
39 static const float M_PIby360 = M_PI / 360;
40 static const float MAXEXTENTby180 = MAXEXTENT/180;
41
110016fe »
2006-10-17 1. refactored proj stuff into separate files
42 namespace mapnik {
17d13cff »
2012-02-01 whitespace fixes - closes #911
43
44 proj_transform::proj_transform(projection const& source,
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
45 projection const& dest)
46 : source_(source),
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
47 dest_(dest)
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
48 {
6cce96dd »
2010-08-10 upgrade default projection of epsg:4326 to match exactly what proj4 s…
49 is_source_longlat_ = source_.is_geographic();
50 is_dest_longlat_ = dest_.is_geographic();
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
51 is_source_equal_dest_ = (source_ == dest_);
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
52 if (source.params() == "+init=epsg:3857" && dest.params() == "+init=epsg:4326")
53 {
54 wgs84_to_merc_ = true;
55 }
56 else
57 {
58 wgs84_to_merc_ = false;
59 }
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
60 }
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
61
62 bool proj_transform::equal() const
63 {
64 return is_source_equal_dest_;
65 }
66
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
67
6ffbd071 »
2011-09-13 use AGG for interpolation when warping rasters
68 bool proj_transform::forward (double & x, double & y , double & z) const
69 {
70 return forward(&x, &y, &z, 1);
71 }
72
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
73 bool proj_transform::forward (double * x, double * y , double * z, int point_count) const
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
74 {
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
75
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
76 if (is_source_equal_dest_)
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
77 return true;
65ea5bca »
2008-12-07 + applied mapnik-skip-projection-if-equal.patch (jonb)
78
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
79 if (wgs84_to_merc_) {
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
80 int i;
81 for(i=0; i<point_count; i++) {
82 x[i] = (x[i] / MAXEXTENT) * 180;
83 y[i] = (y[i] / MAXEXTENT) * 180;
84 y[i] = R2D * (2 * atan(exp(y[i] * D2R)) - M_PI_by2);
85 if (x[i] > 180) x[i] = 180;
86 if (x[i] < -180) x[i] = -180;
87 if (y[i] > 85.0511) y[i] = 85.0511;
88 if (y[i] < -85.0511) y[i] = -85.0511;
89 }
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
90 return true;
91 }
17d13cff »
2012-02-01 whitespace fixes - closes #911
92
93 if (is_source_longlat_)
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
94 {
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
95 int i;
96 for(i=0; i<point_count; i++) {
97 x[i] *= DEG_TO_RAD;
98 y[i] *= DEG_TO_RAD;
99 }
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
100 }
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
101
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
102 do {
7c529600 »
2012-03-24 Revert "avoid mutex locks on pj_transform for proj 4.7 and above - cl…
103 #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
104 mutex::scoped_lock lock(projection::mutex_);
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
105 #endif
17d13cff »
2012-02-01 whitespace fixes - closes #911
106 if (pj_transform( source_.proj_, dest_.proj_, point_count,
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
107 0, x,y,z) != 0)
108 {
109 return false;
110 }
111 } while(false);
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
112
6cce96dd »
2010-08-10 upgrade default projection of epsg:4326 to match exactly what proj4 s…
113 if (is_dest_longlat_)
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
114 {
6ffbd071 »
2011-09-13 use AGG for interpolation when warping rasters
115 int i;
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
116 for(i=0; i<point_count; i++) {
117 x[i] *= RAD_TO_DEG;
118 y[i] *= RAD_TO_DEG;
119 }
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
120 }
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
121
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
122 return true;
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
123 }
124
125 bool proj_transform::backward (double * x, double * y , double * z, int point_count) const
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
126 {
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
127 if (is_source_equal_dest_)
110016fe »
2006-10-17 1. refactored proj stuff into separate files
128 return true;
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
129
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
130 if (wgs84_to_merc_) {
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
131 int i;
132 for(i=0; i<point_count; i++) {
133 x[i] = x[i] * MAXEXTENTby180;
1f351e0e »
2012-04-08 implement new debug system
134 y[i] = std::log(tan((90 + y[i]) * M_PIby360)) / D2R;
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
135 y[i] = y[i] * MAXEXTENTby180;
136 if (x[i] > MAXEXTENT) x[i] = MAXEXTENT;
137 if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT;
138 if (y[i] > MAXEXTENT) y[i] = MAXEXTENT;
139 if (y[i] < -MAXEXTENT) y[i] = -MAXEXTENT;
140 }
ac3e43e5 »
2011-09-12 support faster wgs84->merc transforms, a very common reprojection sce…
141 return true;
142 }
143
6cce96dd »
2010-08-10 upgrade default projection of epsg:4326 to match exactly what proj4 s…
144 if (is_dest_longlat_)
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
145 {
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
146 int i;
147 for(i=0; i<point_count; i++) {
148 x[i] *= DEG_TO_RAD;
149 y[i] *= DEG_TO_RAD;
150 }
dadd6451 »
2009-05-24 +add pickle support for proj_transform and view/coord_transform - see #…
151 }
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
152
2834b2ad »
2012-09-19 + not sure why we have do { } while(false); - removing
153 {
7c529600 »
2012-03-24 Revert "avoid mutex locks on pj_transform for proj 4.7 and above - cl…
154 #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
155 mutex::scoped_lock lock(projection::mutex_);
f802d218 »
2010-07-21 speed optimizations by more careful use (or avoidance) of locking aro…
156 #endif
157
17d13cff »
2012-02-01 whitespace fixes - closes #911
158 if (pj_transform( dest_.proj_, source_.proj_, point_count,
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
159 0, x,y,z) != 0)
160 {
161 return false;
162 }
2834b2ad »
2012-09-19 + not sure why we have do { } while(false); - removing
163 }
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
164
6cce96dd »
2010-08-10 upgrade default projection of epsg:4326 to match exactly what proj4 s…
165 if (is_source_longlat_)
dadd6451 »
2009-05-24 +add pickle support for proj_transform and view/coord_transform - see #…
166 {
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
167 int i;
168 for(i=0; i<point_count; i++) {
169 x[i] *= RAD_TO_DEG;
170 y[i] *= RAD_TO_DEG;
171 }
dadd6451 »
2009-05-24 +add pickle support for proj_transform and view/coord_transform - see #…
172 }
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
173
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
174 return true;
175 }
176
67df6983 »
2011-09-12 allow reprojection of batches of points - patch cherry picked from al…
177 bool proj_transform::backward (double & x, double & y , double & z) const
178 {
179 return backward(&x, &y, &z, 1);
180 }
181
182
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
183 bool proj_transform::forward (box2d<double> & box) const
184 {
185 if (is_source_equal_dest_)
186 return true;
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
187
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
188 double minx = box.minx();
189 double miny = box.miny();
190 double maxx = box.maxx();
191 double maxy = box.maxy();
192 double z = 0.0;
ac3488ef »
2011-04-13 fix return from proj_transform when coordinates cannot be reprojected
193 if (!forward(minx,miny,z))
194 return false;
195 if (!forward(maxx,maxy,z))
196 return false;
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
197 box.init(minx,miny,maxx,maxy);
ac3488ef »
2011-04-13 fix return from proj_transform when coordinates cannot be reprojected
198 return true;
17d13cff »
2012-02-01 whitespace fixes - closes #911
199 }
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
200
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
201 bool proj_transform::backward (box2d<double> & box) const
202 {
203 if (is_source_equal_dest_)
204 return true;
205
206 double minx = box.minx();
207 double miny = box.miny();
208 double maxx = box.maxx();
209 double maxy = box.maxy();
210 double z = 0.0;
ac3488ef »
2011-04-13 fix return from proj_transform when coordinates cannot be reprojected
211 if (!backward(minx,miny,z))
212 return false;
213 if (!backward(maxx,maxy,z))
214 return false;
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
215 box.init(minx,miny,maxx,maxy);
ac3488ef »
2011-04-13 fix return from proj_transform when coordinates cannot be reprojected
216 return true;
383d8a3f »
2011-04-13 add proj_transform forward/backward box2d implementation
217 }
218
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
219 void envelope_points(std::vector< coord<double,2> > & coords, box2d<double>& env, int points)
220 {
221 double width = env.width();
222 double height = env.height();
17d13cff »
2012-02-01 whitespace fixes - closes #911
223
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
224 int steps;
17d13cff »
2012-02-01 whitespace fixes - closes #911
225
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
226 if (points <= 4) {
227 steps = 0;
228 } else {
229 steps = static_cast<int>(ceil((points - 4) / 4.0));
230 }
17d13cff »
2012-02-01 whitespace fixes - closes #911
231
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
232 steps += 1;
233 double xstep = width / steps;
234 double ystep = height / steps;
17d13cff »
2012-02-01 whitespace fixes - closes #911
235
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
236 for (int i=0; i<=steps; i++) {
237 coords.push_back(coord<double,2>(env.minx() + i * xstep, env.miny()));
238 coords.push_back(coord<double,2>(env.minx() + i * xstep, env.maxy()));
239
240 }
241 for (int i=1; i<steps; i++) {
242 coords.push_back(coord<double,2>(env.minx(), env.miny() + i * ystep));
243 coords.push_back(coord<double,2>(env.maxx(), env.miny() + i * ystep));
244 }
245 }
246
247 box2d<double> calculate_bbox(std::vector<coord<double,2> > & points) {
248 std::vector<coord<double,2> >::iterator it = points.begin();
249 std::vector<coord<double,2> >::iterator it_end = points.end();
17d13cff »
2012-02-01 whitespace fixes - closes #911
250
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
251 box2d<double> env(*it, *(++it));
252 for (; it!=it_end; ++it) {
253 env.expand_to_include(*it);
254 }
255 return env;
256 }
257
258
259 /* More robust, but expensive, bbox transform
260 * in the face of proj4 out of bounds conditions.
261 * Can result in 20 -> 10 r/s performance hit.
262 * Alternative is to provide proper clipping box
17d13cff »
2012-02-01 whitespace fixes - closes #911
263 * in the target srs by setting map 'maximum-extent'
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
264 */
265 bool proj_transform::backward(box2d<double>& env, int points) const
266 {
267 if (is_source_equal_dest_)
268 return true;
17d13cff »
2012-02-01 whitespace fixes - closes #911
269
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
270 std::vector<coord<double,2> > coords;
271 envelope_points(coords, env, points);
17d13cff »
2012-02-01 whitespace fixes - closes #911
272
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
273 double z;
274 for (std::vector<coord<double,2> >::iterator it = coords.begin(); it!=coords.end(); ++it) {
275 z = 0;
276 if (!backward(it->x, it->y, z)) {
277 return false;
278 }
279 }
280
281 box2d<double> result = calculate_bbox(coords);
17d13cff »
2012-02-01 whitespace fixes - closes #911
282
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
283 env.re_center(result.center().x, result.center().y);
284 env.height(result.height());
285 env.width(result.width());
286
287 return true;
288 }
289
290 bool proj_transform::forward(box2d<double>& env, int points) const
291 {
292 if (is_source_equal_dest_)
293 return true;
17d13cff »
2012-02-01 whitespace fixes - closes #911
294
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
295 std::vector<coord<double,2> > coords;
296 envelope_points(coords, env, points);
17d13cff »
2012-02-01 whitespace fixes - closes #911
297
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
298 double z;
299 for (std::vector<coord<double,2> >::iterator it = coords.begin(); it!=coords.end(); ++it) {
300 z = 0;
301 if (!forward(it->x, it->y, z)) {
302 return false;
303 }
304 }
305
306 box2d<double> result = calculate_bbox(coords);
17d13cff »
2012-02-01 whitespace fixes - closes #911
307
c230ed67 »
2011-05-31 add alternative bbox forward/inverse functions
308 env.re_center(result.center().x, result.center().y);
309 env.height(result.height());
310 env.width(result.width());
311
312 return true;
313 }
314
24673187 »
2010-06-02 + apply 'mapnik-format' to *.cpp *.hpp
315 mapnik::projection const& proj_transform::source() const
316 {
317 return source_;
318 }
319 mapnik::projection const& proj_transform::dest() const
320 {
321 return dest_;
322 }
17d13cff »
2012-02-01 whitespace fixes - closes #911
323
110016fe »
2006-10-17 1. refactored proj stuff into separate files
324 }
Something went wrong with that request. Please try again.