Libosmium  2.11.1
Fast and flexible C++ library for working with OpenStreetMap data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
projection.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_GEOM_PROJECTION_HPP
2 #define OSMIUM_GEOM_PROJECTION_HPP
3 
4 /*
5 
6 This file is part of Osmium (http://osmcode.org/libosmium).
7 
8 Copyright 2013-2017 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
45 #include <memory>
46 #include <string>
47 
48 #include <proj_api.h>
49 
51 #include <osmium/geom/util.hpp>
52 #include <osmium/osm/location.hpp>
53 
54 namespace osmium {
55 
56  namespace geom {
57 
61  class CRS {
62 
63  struct ProjCRSDeleter {
64  void operator()(void* crs) {
65  pj_free(crs);
66  }
67  }; // struct ProjCRSDeleter
68 
69  std::unique_ptr<void, ProjCRSDeleter> m_crs;
70 
71  public:
72 
73  explicit CRS(const std::string& crs) :
74  m_crs(pj_init_plus(crs.c_str()), ProjCRSDeleter()) {
75  if (!m_crs) {
76  throw osmium::projection_error(std::string{"creation of CRS failed: "} + pj_strerrno(*pj_get_errno_ref()));
77  }
78  }
79 
80  explicit CRS(const char* crs) :
81  CRS(std::string{crs}) {
82  }
83 
84  explicit CRS(int epsg) :
85  CRS(std::string{"+init=epsg:"} + std::to_string(epsg)) {
86  }
87 
91  projPJ get() const {
92  return m_crs.get();
93  }
94 
95  bool is_latlong() const {
96  return pj_is_latlong(m_crs.get()) != 0;
97  }
98 
99  bool is_geocent() const {
100  return pj_is_geocent(m_crs.get()) != 0;
101  }
102 
103  }; // class CRS
104 
113  inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
114  int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr);
115  if (result != 0) {
116  throw osmium::projection_error(std::string("projection failed: ") + pj_strerrno(result));
117  }
118  return c;
119  }
120 
125  class Projection {
126 
127  int m_epsg;
128  std::string m_proj_string;
129  CRS m_crs_wgs84 {4326};
131 
132  public:
133 
134  explicit Projection(const std::string& proj_string) :
135  m_epsg(-1),
136  m_proj_string(proj_string),
137  m_crs_user(proj_string) {
138  }
139 
140  explicit Projection(const char* proj_string) :
141  m_epsg(-1),
142  m_proj_string(proj_string),
143  m_crs_user(proj_string) {
144  }
145 
146  explicit Projection(int epsg) :
147  m_epsg(epsg),
148  m_proj_string(std::string("+init=epsg:") + std::to_string(epsg)),
149  m_crs_user(epsg) {
150  }
151 
153  Coordinates c {location.lon(), location.lat()};
154 
155  if (m_epsg != 4326) {
156  c = transform(m_crs_wgs84, m_crs_user, Coordinates(deg_to_rad(location.lon()), deg_to_rad(location.lat())));
157  if (m_crs_user.is_latlong()) {
158  c.x = rad_to_deg(c.x);
159  c.y = rad_to_deg(c.y);
160  }
161  }
162 
163  return c;
164  }
165 
166  int epsg() const noexcept {
167  return m_epsg;
168  }
169 
170  std::string proj_string() const {
171  return m_proj_string;
172  }
173 
174  }; // class Projection
175 
176  } // namespace geom
177 
178 } // namespace osmium
179 
180 #endif // OSMIUM_GEOM_PROJECTION_HPP
double y
Definition: coordinates.hpp:51
Definition: projection.hpp:63
CRS m_crs_wgs84
Definition: projection.hpp:129
Definition: reader_iterator.hpp:39
CRS(int epsg)
Definition: projection.hpp:84
bool is_latlong() const
Definition: projection.hpp:95
Projection(int epsg)
Definition: projection.hpp:146
CRS(const std::string &crs)
Definition: projection.hpp:73
std::string proj_string() const
Definition: projection.hpp:170
Coordinates transform(const CRS &src, const CRS &dest, Coordinates c)
Definition: projection.hpp:113
double lat() const
Definition: location.hpp:390
Namespace for everything in the Osmium library.
Definition: assembler.hpp:73
constexpr double deg_to_rad(double degree) noexcept
Convert angle from degrees to radians.
Definition: util.hpp:62
std::string m_proj_string
Definition: projection.hpp:128
Definition: coordinates.hpp:48
CRS m_crs_user
Definition: projection.hpp:130
std::unique_ptr< void, ProjCRSDeleter > m_crs
Definition: projection.hpp:69
CRS(const char *crs)
Definition: projection.hpp:80
projPJ get() const
Definition: projection.hpp:91
Definition: projection.hpp:125
Definition: location.hpp:266
int m_epsg
Definition: projection.hpp:127
void operator()(void *crs)
Definition: projection.hpp:64
Coordinates operator()(osmium::Location location) const
Definition: projection.hpp:152
double lon() const
Definition: location.hpp:371
Definition: projection.hpp:61
Projection(const std::string &proj_string)
Definition: projection.hpp:134
Projection(const char *proj_string)
Definition: projection.hpp:140
int epsg() const noexcept
Definition: projection.hpp:166
double x
Definition: coordinates.hpp:50
bool is_geocent() const
Definition: projection.hpp:99
Definition: util.hpp:45
constexpr double rad_to_deg(double radians) noexcept
Convert angle from radians to degrees.
Definition: util.hpp:67