-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dadfe0f
Showing
3 changed files
with
140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Boost Software License - Version 1.0 - August 17th, 2003 | ||
|
||
Permission is hereby granted, free of charge, to any person or organization | ||
obtaining a copy of the software and accompanying documentation covered by | ||
this license (the "Software") to use, reproduce, display, distribute, | ||
execute, and transmit the Software, and to prepare derivative works of the | ||
Software, and to permit third-parties to whom the Software is furnished to | ||
do so, all subject to the following: | ||
|
||
The copyright notices in the Software and this entire statement, including | ||
the above license grant, this restriction and the following disclaimer, | ||
must be included in all copies of the Software, in whole or in part, and | ||
all derivative works of the Software, unless such copies or derivative | ||
works are solely in the form of machine-executable object code generated by | ||
a source language processor. | ||
|
||
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT | ||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | ||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | ||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Projection class for Libosmium | ||
|
||
This repository contains code for projecting OSM locations to arbitrary | ||
coordinate reference systems. It is based on the PROJ library. Unlike | ||
the code which is included in libosmium which only supports older | ||
PROJ versions, this one is for PROJ version 6 and above. | ||
|
||
**This is untested code just provided as a starting point, because libosmium | ||
doesn't support PROJ 6 and above.** | ||
|
||
To use this include `projection.hpp` in your program and instantiate the | ||
`osmium::geom::GeometryFactory` class with the class `PROJ_Projection` as | ||
template parameter. See the libosmium documentation for details of how to | ||
use the `GeometryFactory` class. | ||
|
||
You need to compile with `libproj`. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#once | ||
|
||
#include <osmium/geom/coordinates.hpp> | ||
#include <osmium/geom/mercator_projection.hpp> | ||
#include <osmium/geom/util.hpp> | ||
#include <osmium/osm/location.hpp> | ||
|
||
#include <proj.h> | ||
|
||
#include <cassert> | ||
#include <memory> | ||
#include <string> | ||
|
||
|
||
/** | ||
* Functor that does projection from WGS84 (EPSG:4326) to the given | ||
* CRS. | ||
* | ||
* If this Projection is initialized with the constructor taking | ||
* an integer with the epsg code 4326, no projection is done. If it | ||
* is initialized with epsg code 3857 the Osmium-internal | ||
* implementation of the Mercator projection is used, otherwise this | ||
* falls back to using the PROJ library. Note that this "magic" does | ||
* not work if you use any of the constructors taking a string. | ||
*/ | ||
class PROJ_Projection { | ||
|
||
struct ProjDestroyer { | ||
void operator()(PJ* crs) { | ||
proj_destroy(crs); | ||
} | ||
}; // struct ProjDestroyer | ||
|
||
std::string m_proj_string; | ||
std::unique_ptr<PJ, ProjDestroyer> m_proj; | ||
int m_epsg = -1; | ||
|
||
PJ* make_proj(const char* to_crs) { | ||
PJ* p = proj_create_crs_to_crs(PJ_DEFAULT_CTX, | ||
"EPSG:4326", to_crs, | ||
nullptr); | ||
if (p) { | ||
return p; | ||
} | ||
|
||
throw osmium::projection_error{std::string{"Creating PROJ projection failed: "} + | ||
proj_errno_string(proj_errno(p))}; | ||
} | ||
|
||
public: | ||
|
||
explicit Projection(const char* proj_string) : | ||
m_proj_string(proj_string), | ||
m_proj(make_proj(proj_string)) { | ||
} | ||
|
||
explicit Projection(const std::string& proj_string) : | ||
Projection(proj_string.c_str()) { | ||
} | ||
|
||
explicit Projection(int epsg) : | ||
m_proj_string(std::string{"EPSG:"} + std::to_string(epsg)), | ||
m_proj((epsg == 4326 || epsg == 3857) ? nullptr | ||
: make_proj(m_proj_string.c_str())), | ||
m_epsg(epsg) { | ||
} | ||
|
||
/** | ||
* Do coordinate transformation. | ||
* | ||
* @pre Location must be in valid range (depends on projection used). | ||
*/ | ||
Coordinates operator()(osmium::Location location) const { | ||
if (m_epsg == 4326) { | ||
return Coordinates{location.lon(), location.lat()}; | ||
} | ||
|
||
if (m_epsg == 3857) { | ||
return Coordinates{detail::lon_to_x(location.lon()), | ||
detail::lat_to_y(location.lat())}; | ||
} | ||
|
||
PJ_COORD from; | ||
from.lpzt.z = 0.0; | ||
from.lpzt.t = HUGE_VAL; | ||
from.lpzt.lam = location.lon(); | ||
from.lpzt.phi = location.lat(); | ||
|
||
assert(m_proj); | ||
PJ_COORD to = proj_trans(m_proj.get(), PJ_FWD, from); | ||
|
||
return Coordinates{to.xy.x, to.xy.y}; | ||
} | ||
|
||
int epsg() const noexcept { | ||
return m_epsg; | ||
} | ||
|
||
}; // class PROJ_Projection | ||
|