diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a254f32..cc823f6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -401,7 +401,7 @@ if(BUILD_HEADERS) file(MAKE_DIRECTORY header_check) foreach(hpp ${ALL_HPPS}) - if((GDAL_FOUND AND PROJ_FOUND) OR NOT ((hpp STREQUAL "osmium/area/problem_reporter_ogr.hpp") OR (hpp STREQUAL "osmium/geom/ogr.hpp") OR (hpp STREQUAL "osmium/geom/projection.hpp"))) + if((GDAL_FOUND) OR NOT ((hpp STREQUAL "osmium/area/problem_reporter_ogr.hpp") OR (hpp STREQUAL "osmium/geom/ogr.hpp"))) string(REPLACE ".hpp" "" tmp ${hpp}) string(REPLACE "/" "__" libname ${tmp}) diff --git a/include/osmium/geom/projection.hpp b/include/osmium/geom/projection.hpp deleted file mode 100644 index 1049e057..00000000 --- a/include/osmium/geom/projection.hpp +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef OSMIUM_GEOM_PROJECTION_HPP -#define OSMIUM_GEOM_PROJECTION_HPP - -/* - -This file is part of Osmium (https://osmcode.org/libosmium). - -Copyright 2013-2024 Jochen Topf and others (see README). - -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. - -*/ - -/** - * @file - * - * This file contains code for projecting OSM locations to arbitrary - * coordinate reference systems. It is based on the Proj.4 library. - * - * @attention If you include this file, you'll need to link with `libproj`. - */ - -#include -#include -#include -#include -#include - -#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -# include -#else -# define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -# include -# undef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif - -#include -#include - -namespace osmium { - - namespace geom { - - /** - * C++ wrapper for a Coordinate Reference System of the proj library. - * - * @deprecated Only supports the old PROJ API. - */ - class OSMIUM_DEPRECATED CRS { - - struct ProjCRSDeleter { - void operator()(void* crs) { - pj_free(crs); - } - }; // struct ProjCRSDeleter - - std::unique_ptr m_crs; - - public: - - explicit CRS(const char* crs) : - m_crs(pj_init_plus(crs), ProjCRSDeleter()) { - if (!m_crs) { - throw osmium::projection_error{std::string{"creation of CRS failed: "} + pj_strerrno(*pj_get_errno_ref())}; - } - } - - explicit CRS(const std::string& crs) : - CRS(crs.c_str()) { - } - - explicit CRS(int epsg) : - CRS(std::string{"+init=epsg:"} + std::to_string(epsg)) { - } - - /** - * Get underlying projPJ handle from proj library. - */ - projPJ get() const noexcept { - return m_crs.get(); - } - - bool is_latlong() const noexcept { - return pj_is_latlong(m_crs.get()) != 0; - } - - bool is_geocent() const noexcept { - return pj_is_geocent(m_crs.get()) != 0; - } - - }; // class CRS - - /** - * Transform coordinates from one CRS into another. Wraps the same - * function of the proj library. - * - * Coordinates have to be in radians and are produced in radians. - * - * @throws osmium::projection_error if the projection fails - * - * @deprecated Only supports the old PROJ API. - */ - inline OSMIUM_DEPRECATED Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) { - const int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr); - if (result != 0) { - throw osmium::projection_error{std::string{"projection failed: "} + pj_strerrno(result)}; - } - return c; - } - - /** - * 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.4 library. Note that this "magic" does - * not work if you use any of the constructors taking a string. - * - * @deprecated Only supports the old PROJ API. - */ - class OSMIUM_DEPRECATED Projection { - - int m_epsg; - std::string m_proj_string; - CRS m_crs_wgs84{4326}; - CRS m_crs_user; - - public: - - explicit Projection(std::string proj_string) : - m_epsg(-1), - m_proj_string(std::move(proj_string)), - m_crs_user(proj_string) { - } - - explicit Projection(const char* proj_string) : - m_epsg(-1), - m_proj_string(proj_string), - m_crs_user(proj_string) { - } - - explicit Projection(int epsg) : - m_epsg(epsg), - m_proj_string(std::string{"+init=epsg:"} + std::to_string(epsg)), - m_crs_user(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())}; - } - - Coordinates c{transform(m_crs_wgs84, m_crs_user, Coordinates{deg_to_rad(location.lon()), - deg_to_rad(location.lat())})}; - if (m_crs_user.is_latlong()) { - c.x = rad_to_deg(c.x); - c.y = rad_to_deg(c.y); - } - - return c; - } - - int epsg() const noexcept { - return m_epsg; - } - - std::string proj_string() const { - return m_proj_string; - } - - }; // class Projection - - } // namespace geom - -} // namespace osmium - -#endif // OSMIUM_GEOM_PROJECTION_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6eb6b811..ab9cd43e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -105,10 +105,6 @@ if(NOT GEOS_FOUND) set(GEOS_FOUND FALSE) endif() -if(NOT PROJ_FOUND) - set(PROJ_FOUND FALSE) -endif() - if(NOT SPARSEHASH_FOUND) set(SPARSEHASH_FOUND FALSE) endif() @@ -157,15 +153,14 @@ add_unit_test(builder test_attr) add_unit_test(builder test_object_builder) add_unit_test(geom test_coordinates) -add_unit_test(geom test_crs ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY}) add_unit_test(geom test_exception) -add_unit_test(geom test_factory_with_projection ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY}) +add_unit_test(geom test_factory_with_projection) add_unit_test(geom test_geojson) add_unit_test(geom test_geos ENABLE_IF ${GEOS_FOUND} LIBS ${GEOS_LIBRARY}) add_unit_test(geom test_mercator) add_unit_test(geom test_ogr ENABLE_IF ${GDAL_FOUND} LIBS ${GDAL_LIBRARY}) add_unit_test(geom test_ogr_wkb ENABLE_IF ${GDAL_FOUND} LIBS ${GDAL_LIBRARY}) -add_unit_test(geom test_projection ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY}) +add_unit_test(geom test_projection) add_unit_test(geom test_tile) add_unit_test(geom test_wkb) add_unit_test(geom test_wkt) diff --git a/test/t/geom/test_crs.cpp b/test/t/geom/test_crs.cpp deleted file mode 100644 index c8a37654..00000000 --- a/test/t/geom/test_crs.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "catch.hpp" - -#include -#include -#include - -TEST_CASE("CRS") { - const osmium::geom::CRS wgs84{4326}; - const osmium::geom::CRS mercator{3857}; - - const osmium::geom::Coordinates c{osmium::geom::deg_to_rad(1.2), osmium::geom::deg_to_rad(3.4)}; - const auto ct = osmium::geom::transform(wgs84, mercator, c); - const auto c2 = osmium::geom::transform(mercator, wgs84, ct); - - REQUIRE(c.x == Approx(c2.x)); - REQUIRE(c.y == Approx(c2.y)); -} - diff --git a/test/t/geom/test_factory_with_projection.cpp b/test/t/geom/test_factory_with_projection.cpp index 3e98c9ab..3d9923db 100644 --- a/test/t/geom/test_factory_with_projection.cpp +++ b/test/t/geom/test_factory_with_projection.cpp @@ -1,7 +1,6 @@ #include "catch.hpp" #include -#include #include #include @@ -13,10 +12,3 @@ TEST_CASE("Projection using MercatorProjection class to WKT") { REQUIRE(wkt == "POINT(356222.37 467961.14)"); } -TEST_CASE("Projection using Projection class to WKT") { - osmium::geom::WKTFactory factory{osmium::geom::Projection{3857}, 2}; - - const std::string wkt{factory.create_point(osmium::Location{3.2, 4.2})}; - REQUIRE(wkt == "POINT(356222.37 467961.14)"); -} - diff --git a/test/t/geom/test_projection.cpp b/test/t/geom/test_projection.cpp index 56a16337..ea2ef6d4 100644 --- a/test/t/geom/test_projection.cpp +++ b/test/t/geom/test_projection.cpp @@ -2,7 +2,6 @@ #include #include -#include TEST_CASE("Indentity Projection") { const osmium::geom::IdentityProjection projection; @@ -10,70 +9,6 @@ TEST_CASE("Indentity Projection") { REQUIRE("+proj=longlat +datum=WGS84 +no_defs" == projection.proj_string()); } -TEST_CASE("Projection 4326") { - const osmium::geom::Projection projection{4326}; - REQUIRE(4326 == projection.epsg()); - REQUIRE("+init=epsg:4326" == projection.proj_string()); - - const osmium::Location loc{1.0, 2.0}; - const osmium::geom::Coordinates c{1.0, 2.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); -} - -TEST_CASE("Projection 4326 from init string") { - const osmium::geom::Projection projection{"+init=epsg:4326"}; - REQUIRE(-1 == projection.epsg()); - REQUIRE("+init=epsg:4326" == projection.proj_string()); - - const osmium::Location loc{1.0, 2.0}; - const osmium::geom::Coordinates c{1.0, 2.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); -} - -TEST_CASE("Creating projection from unknown init string") { - REQUIRE_THROWS_AS(osmium::geom::Projection{"abc"}, osmium::projection_error); -} - -TEST_CASE("Creating projection from unknown EPSG code") { - REQUIRE_THROWS_AS(osmium::geom::Projection{9999999}, osmium::projection_error); -} - -TEST_CASE("Projection 3857") { - const osmium::geom::Projection projection{3857}; - REQUIRE(3857 == projection.epsg()); - REQUIRE("+init=epsg:3857" == projection.proj_string()); - - SECTION("Zero coordinates") { - const osmium::Location loc{0.0, 0.0}; - const osmium::geom::Coordinates c{0.0, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Max longitude") { - const osmium::Location loc{180.0, 0.0}; - const osmium::geom::Coordinates c{20037508.34, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Min longitude") { - const osmium::Location loc{-180.0, 0.0}; - const osmium::geom::Coordinates c{-20037508.34, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Max latitude") { - const osmium::Location loc{0.0, 85.0511288}; - const osmium::geom::Coordinates c{0.0, 20037508.34}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } -} - TEST_CASE("MercatorProjection: Zero coordinates") { const osmium::geom::MercatorProjection projection; const osmium::Location loc{0.0, 0.0};