From 88241b32eeaccdc9eda7b92b7e7b6d4deac88e12 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 15 Jan 2021 15:21:09 +0000 Subject: [PATCH] Initial implementation of new proj7 APIs support --- SConstruct | 75 +++++----- benchmark/data/gdal-wgs.xml | 4 +- benchmark/data/raster-wgs.xml | 4 +- benchmark/src/test_noop_rendering.cpp | 4 +- benchmark/src/test_polygon_clipping.cpp | 2 +- benchmark/src/test_proj_transform1.cpp | 6 +- include/mapnik/layer.hpp | 2 +- include/mapnik/proj_transform.hpp | 6 +- include/mapnik/projection.hpp | 13 +- src/build.py | 2 +- src/proj_transform.cpp | 115 ++++++--------- src/projection.cpp | 135 ++++++++---------- src/well_known_srs.cpp | 8 +- test/data | 2 +- test/data-visual | 2 +- test/unit/core/exceptions_test.cpp | 5 +- test/unit/geometry/geometry_reprojection.cpp | 72 +++++----- test/unit/geometry/geometry_strategy_test.cpp | 4 +- test/unit/projection/proj_transform.cpp | 26 ++-- .../vertex_adapter/transform_path_adapter.cpp | 8 +- 20 files changed, 224 insertions(+), 271 deletions(-) diff --git a/SConstruct b/SConstruct index a2c8439c86..e357bd4aaf 100644 --- a/SConstruct +++ b/SConstruct @@ -1,6 +1,6 @@ # This file is part of Mapnik (c++ mapping toolkit) # -# Copyright (C) 2017 Artem Pavlenko +# Copyright (C) 2021 Artem Pavlenko # # Mapnik is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -79,7 +79,7 @@ SCONF_TEMP_DIR = '.sconf_temp' BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',] BOOST_MIN_VERSION = '1.61' #CAIRO_MIN_VERSION = '1.8.0' - +PROJ_MIN_VERSION = (7, 2, 0) HARFBUZZ_MIN_VERSION = (0, 9, 34) HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION @@ -92,7 +92,7 @@ pretty_dep_names = { 'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/GDAL', 'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/OGR', 'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', - 'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/', + 'proj':'Proj C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/', 'pg':'Postgres C Library required for PostGIS plugin | configure with pg_config program or configure with PG_LIBS & PG_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/PostGIS', 'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite', 'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES', @@ -116,7 +116,7 @@ pretty_dep_names = { 'boost_regex_icu':'libboost_regex built with optional ICU unicode support is needed for unicode regex support in mapnik.', 'sqlite_rtree':'The SQLite plugin requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)', 'pgsql2sqlite_rtree':'The pgsql2sqlite program requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)', - 'PROJ_LIB':'The directory where proj4 stores its data files. Must exist for proj4 to work correctly', + 'PROJ_LIB':'The directory where proj stores its data files. Must exist for proj to work correctly', 'GDAL_DATA':'The directory where GDAL stores its data files. Must exist for GDAL to work correctly', 'ICU_DATA':'The directory where icu stores its data files. If ICU reports a path, it must exist. ICU can also be built without .dat files and in that case this path is empty' } @@ -422,7 +422,7 @@ opts.AddVariables( BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'), PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept), PathVariable('WEBP_LIBS','Search path for libwebp library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), - BoolVariable('PROJ', 'Build Mapnik with proj4 support to enable transformations between many different projections', 'True'), + BoolVariable('PROJ', 'Build Mapnik with proj support to enable transformations between many different projections', 'True'), PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/include', PathVariable.PathAccept), PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), ('PG_INCLUDES', 'Search path for libpq (postgres client) include files', ''), @@ -940,51 +940,40 @@ def CheckProjData(context, silent=False): context.Message('Checking for PROJ_LIB directory...') ret, out = context.TryRun(""" -// This is narly, could eventually be replaced using https://github.com/OSGeo/proj.4/pull/551] -#include +#include #include -#include +#include +#include +#include +#include -static void my_proj4_logger(void * user_data, int /*level*/, const char * msg) +std::vector split_searchpath(std::string const& paths) { - std::string* posMsg = static_cast(user_data); - *posMsg += msg; -} + std::vector output; + std::stringstream ss(paths); + std::string path; -// https://github.com/OSGeo/gdal/blob/ddbf6d39aa4b005a77ca4f27c2d61a3214f336f8/gdal/alg/gdalapplyverticalshiftgrid.cpp#L616-L633 - -std::string find_proj_path(const char * pszFilename) { - std::string osMsg; - std::string osFilename; - projCtx ctx = pj_ctx_alloc(); - pj_ctx_set_app_data(ctx, &osMsg); - pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR); - pj_ctx_set_logger(ctx, my_proj4_logger); - PAFile f = pj_open_lib(ctx, pszFilename, "rb"); - if( f ) - { - pj_ctx_fclose(ctx, f); - } - size_t nPos = osMsg.find("fopen("); - if( nPos != std::string::npos ) + for( std::string path;std::getline(ss, path, ':');) { - osFilename = osMsg.substr(nPos + strlen("fopen(")); - nPos = osFilename.find(")"); - if( nPos != std::string::npos ) - osFilename = osFilename.substr(0, nPos); + output.push_back(path); } - pj_ctx_free(ctx); - return osFilename; + return output; } - -int main() { - std::string result = find_proj_path(" "); - std::cout << result; - if (result.empty()) { - return -1; +int main() +{ + PJ_INFO info = proj_info(); + std::string result = info.searchpath; + for (auto path : split_searchpath(result)) + { + std::ifstream file(path + "/proj.db"); + if (file) + { + std::cout << path; + return 0; + } } - return 0; + return -1; } """, '.cpp') @@ -992,7 +981,7 @@ int main() { if silent: context.did_show_result=1 if ret: - context.Result('pj_open_lib returned %s' % value) + context.Result('proj_info.searchpath returned %s' % value) else: context.Result('Failed to detect (mapnik-config will have null value)') return value @@ -1565,7 +1554,7 @@ if not preconfigured: env['SKIPPED_DEPS'].append('jpeg') if env['PROJ']: - OPTIONAL_LIBSHEADERS.append(['proj', 'proj_api.h', False,'C','-DMAPNIK_USE_PROJ4']) + OPTIONAL_LIBSHEADERS.append(['proj', 'proj.h', False,'C','-DMAPNIK_USE_PROJ']) inc_path = env['%s_INCLUDES' % 'PROJ'] lib_path = env['%s_LIBS' % 'PROJ'] env.AppendUnique(CPPPATH = fix_path(inc_path)) diff --git a/benchmark/data/gdal-wgs.xml b/benchmark/data/gdal-wgs.xml index aa58665321..7a0ca60121 100644 --- a/benchmark/data/gdal-wgs.xml +++ b/benchmark/data/gdal-wgs.xml @@ -1,7 +1,7 @@ + srs="epsg:4326"> style ./valid.geotiff.tif diff --git a/benchmark/data/raster-wgs.xml b/benchmark/data/raster-wgs.xml index 3ee054d2dd..d879f4fc84 100644 --- a/benchmark/data/raster-wgs.xml +++ b/benchmark/data/raster-wgs.xml @@ -1,7 +1,7 @@ + srs="epsg:4326"> style ./valid.geotiff.tif diff --git a/benchmark/src/test_noop_rendering.cpp b/benchmark/src/test_noop_rendering.cpp index 03d2e675c6..55c09e34c2 100644 --- a/benchmark/src/test_noop_rendering.cpp +++ b/benchmark/src/test_noop_rendering.cpp @@ -11,7 +11,7 @@ #include #include - + class test : public benchmark::test_case { public: @@ -24,7 +24,7 @@ class test : public benchmark::test_case } bool operator()() const { - mapnik::Map m(256,256,"+init=epsg:3857"); + mapnik::Map m(256,256,"epsg:3857"); mapnik::parameters params; params["type"]="memory"; diff --git a/benchmark/src/test_polygon_clipping.cpp b/benchmark/src/test_polygon_clipping.cpp index aed74fe33f..e27300423b 100644 --- a/benchmark/src/test_polygon_clipping.cpp +++ b/benchmark/src/test_polygon_clipping.cpp @@ -51,7 +51,7 @@ void render(mapnik::geometry::multi_polygon const& geom, agg::pixfmt_rgba32_plain pixf(buf); ren_base renb(pixf); renderer ren(renb); - mapnik::proj_transform prj_trans(mapnik::projection("+init=epsg:4326"),mapnik::projection("+init=epsg:4326")); + mapnik::proj_transform prj_trans(mapnik::projection("epsg:4326"),mapnik::projection("epsg:4326")); ren.color(agg::rgba8(127,127,127,255)); agg::rasterizer_scanline_aa<> ras; for (auto const& poly : geom) diff --git a/benchmark/src/test_proj_transform1.cpp b/benchmark/src/test_proj_transform1.cpp index fa050da128..fd8cf6a7bd 100644 --- a/benchmark/src/test_proj_transform1.cpp +++ b/benchmark/src/test_proj_transform1.cpp @@ -56,13 +56,13 @@ class test : public benchmark::test_case } }; -// echo -180 -60 | cs2cs -f "%.10f" +init=epsg:4326 +to +init=epsg:3857 +// echo -180 -60 | cs2cs -f "%.10f" epsg:4326 +to epsg:3857 int main(int argc, char** argv) { mapnik::box2d from(-180,-80,180,80); mapnik::box2d to(-20037508.3427892476,-15538711.0963092316,20037508.3427892476,15538711.0963092316); - std::string from_str("+init=epsg:4326"); - std::string to_str("+init=epsg:3857"); + std::string from_str("epsg:4326"); + std::string to_str("epsg:3857"); std::string from_str2("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"); std::string to_str2("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"); return benchmark::sequencer(argc, argv) diff --git a/include/mapnik/layer.hpp b/include/mapnik/layer.hpp index 81f8bf5345..96a161816b 100644 --- a/include/mapnik/layer.hpp +++ b/include/mapnik/layer.hpp @@ -42,7 +42,7 @@ using datasource_ptr = std::shared_ptr; * @brief A Mapnik map layer. * * Create a layer with a named string and, optionally, an srs string either - * with a Proj.4 epsg code ('+init=epsg:') or with a Proj.4 literal + * with a Proj.4 epsg code ('epsg:') or with a Proj.4 literal * ('+proj='). If no srs is specified it will default to * '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' */ diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index 588a048ebc..475faeefc9 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.hpp @@ -27,12 +27,12 @@ #include #include #include +#include // stl #include namespace mapnik { -class projection; template class box2d; class MAPNIK_DECL proj_transform : private util::noncopyable @@ -40,7 +40,7 @@ class MAPNIK_DECL proj_transform : private util::noncopyable public: proj_transform(projection const& source, projection const& dest); - + ~proj_transform(); bool equal() const; bool is_known() const; bool forward (double& x, double& y , double& z) const; @@ -59,6 +59,8 @@ class MAPNIK_DECL proj_transform : private util::noncopyable mapnik::projection const& dest() const; private: + PJ_CONTEXT* ctx_ = nullptr; + PJ* transform_ = nullptr; projection const& source_; projection const& dest_; bool is_source_longlat_; diff --git a/include/mapnik/projection.hpp b/include/mapnik/projection.hpp index cba5f71107..ac78a4469c 100644 --- a/include/mapnik/projection.hpp +++ b/include/mapnik/projection.hpp @@ -37,6 +37,13 @@ MAPNIK_DISABLE_WARNING_POP #include #include + +// fwd decl +struct projCtx_t; +struct PJconsts; +using PJ_CONTEXT = struct projCtx_t; +using PJ = struct PJconsts; + namespace mapnik { class proj_init_error : public std::runtime_error @@ -66,7 +73,7 @@ class MAPNIK_DECL projection void forward(double & x, double & y) const; void inverse(double & x,double & y) const; std::string expanded() const; - void init_proj4() const; + void init_proj() const; private: void swap (projection& rhs); @@ -75,8 +82,8 @@ class MAPNIK_DECL projection std::string params_; bool defer_proj_init_; mutable bool is_geographic_; - mutable void * proj_; - mutable void * proj_ctx_; + mutable PJ * proj_; + mutable PJ_CONTEXT * proj_ctx_; }; template diff --git a/src/build.py b/src/build.py index 3231a0085d..1904b02f8f 100644 --- a/src/build.py +++ b/src/build.py @@ -76,7 +76,7 @@ def ldconfig(*args,**kwargs): lib_env['LIBS'].append('png') enabled_imaging_libraries.append('png_reader.cpp') -if '-DMAPNIK_USE_PROJ4' in env['CPPDEFINES']: +if '-DMAPNIK_USE_PROJ' in env['CPPDEFINES']: lib_env['LIBS'].append('proj') if '-DHAVE_TIFF' in env['CPPDEFINES']: diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index ed0563837d..a3ff8180d4 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -32,9 +32,9 @@ // boost #include -#ifdef MAPNIK_USE_PROJ4 -// proj4 -#include +#ifdef MAPNIK_USE_PROJ +// proj +#include #endif // stl @@ -126,16 +126,44 @@ proj_transform::proj_transform(projection const& source, } if (!known_trans) { -#ifdef MAPNIK_USE_PROJ4 - source_.init_proj4(); - dest_.init_proj4(); +#ifdef MAPNIK_USE_PROJ + transform_ = proj_create_crs_to_crs(ctx_, + source_.params().c_str(), + dest_.params().c_str(), nullptr); + if (transform_ == nullptr) + { + throw std::runtime_error(std::string("Cannot initialize proj_transform for given projections without proj4 support (-DMAPNIK_USE_PROJ): '") + source_.params() + "'->'" + dest_.params() + "'"); + } + PJ* transform_gis = proj_normalize_for_visualization(ctx_, transform_); + if (transform_gis == nullptr) + { + throw std::runtime_error(std::string("Cannot initialize proj_transform for given projections without proj4 support (-DMAPNIK_USE_PROJ): '") + source_.params() + "'->'" + dest_.params() + "'"); + } + proj_destroy(transform_); + transform_ = transform_gis; #else - throw std::runtime_error(std::string("Cannot initialize proj_transform for given projections without proj4 support (-DMAPNIK_USE_PROJ4): '") + source_.params() + "'->'" + dest_.params() + "'"); + throw std::runtime_error(std::string("Cannot initialize proj_transform for given projections without proj4 support (-DMAPNIK_USE_PROJ): '") + source_.params() + "'->'" + dest_.params() + "'"); #endif } } } +proj_transform::~proj_transform() +{ +#ifdef MAPNIK_USE_PROJ + if (transform_) + { + proj_destroy(transform_); + transform_ = nullptr; + } + if (ctx_) + { + proj_context_destroy(ctx_); + ctx_ = nullptr; + } +#endif +} + bool proj_transform::equal() const { return is_source_equal_dest_; @@ -189,7 +217,6 @@ unsigned int proj_transform::forward (std::vector> & ls) bool proj_transform::forward (double * x, double * y , double * z, int point_count, int offset) const { - if (is_source_equal_dest_) return true; @@ -202,37 +229,14 @@ bool proj_transform::forward (double * x, double * y , double * z, int point_cou return merc2lonlat(x, y, point_count, offset); } -#ifdef MAPNIK_USE_PROJ4 - if (is_source_longlat_) - { - int i; - for(i=0; i -#ifdef MAPNIK_USE_PROJ4 -// proj4 -#include - #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480 - #include - static std::mutex mutex_; - #ifdef _MSC_VER - #pragma NOTE(mapnik is building against < proj 4.8, reprojection will be faster if you use >= 4.8) - #else - #warning mapnik is building against < proj 4.8, reprojection will be faster if you use >= 4.8 - #endif - #endif +#ifdef MAPNIK_USE_PROJ +// proj +#include #endif namespace mapnik { - projection::projection(std::string const& params, bool defer_proj_init) : params_(params), defer_proj_init_(defer_proj_init), @@ -58,13 +48,13 @@ projection::projection(std::string const& params, bool defer_proj_init) } else { -#ifdef MAPNIK_USE_PROJ4 - init_proj4(); +#ifdef MAPNIK_USE_PROJ + init_proj(); #else - throw std::runtime_error(std::string("Cannot initialize projection '") + params_ + " ' without proj4 support (-DMAPNIK_USE_PROJ4)"); + throw std::runtime_error(std::string("Cannot initialize projection '") + params_ + " ' without proj support (-DMAPNIK_USE_PROJ)"); #endif } - if (!defer_proj_init_) init_proj4(); + if (!defer_proj_init_) init_proj(); } projection::projection(projection const& rhs) @@ -74,7 +64,7 @@ projection::projection(projection const& rhs) proj_(nullptr), proj_ctx_(nullptr) { - if (!defer_proj_init_) init_proj4(); + if (!defer_proj_init_) init_proj(); } projection& projection::operator=(projection const& rhs) @@ -83,7 +73,7 @@ projection& projection::operator=(projection const& rhs) swap(tmp); proj_ctx_ = nullptr; proj_ = nullptr; - if (!defer_proj_init_) init_proj4(); + if (!defer_proj_init_) init_proj(); return *this; } @@ -97,34 +87,35 @@ bool projection::operator!=(const projection& other) const return !(*this == other); } -void projection::init_proj4() const +void projection::init_proj() const { -#ifdef MAPNIK_USE_PROJ4 +#ifdef MAPNIK_USE_PROJ if (!proj_) { -#if PJ_VERSION >= 480 - proj_ctx_ = pj_ctx_alloc(); - proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str()); + proj_ctx_ = proj_context_create(); + proj_ = proj_create_crs_to_crs(proj_ctx_, "epsg:4326", params_.c_str(), nullptr); if (!proj_ || !proj_ctx_) { if (proj_ctx_) { - pj_ctx_free(proj_ctx_); + proj_context_destroy(proj_ctx_); proj_ctx_ = nullptr; } if (proj_) { - pj_free(proj_); + proj_destroy(proj_); proj_ = nullptr; } throw proj_init_error(params_); } -#else - #if defined(MAPNIK_THREADSAFE) - std::lock_guard lock(mutex_); - #endif - proj_ = pj_init_plus(params_.c_str()); - if (!proj_) throw proj_init_error(params_); -#endif - is_geographic_ = pj_is_latlong(proj_) ? true : false; + // determine the type of CRS + PJ* crs = proj_create(proj_ctx_, params_.c_str()); + if (crs) + { + PJ_TYPE type = proj_get_type(crs); + is_geographic_ = (type == PJ_TYPE_GEOGRAPHIC_2D_CRS + || + type == PJ_TYPE_GEOGRAPHIC_3D_CRS) ? true : false; + } + proj_destroy(crs); } #endif } @@ -151,82 +142,68 @@ std::string const& projection::params() const void projection::forward(double & x, double &y ) const { -#ifdef MAPNIK_USE_PROJ4 +#ifdef MAPNIK_USE_PROJ if (!proj_) { - throw std::runtime_error("projection::forward not supported unless proj4 is initialized"); - } - #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480 - std::lock_guard lock(mutex_); - #endif - projUV p; - p.u = x * DEG_TO_RAD; - p.v = y * DEG_TO_RAD; - p = pj_fwd(p,proj_); - x = p.u; - y = p.v; - if (is_geographic_) - { - x *=RAD_TO_DEG; - y *=RAD_TO_DEG; + throw std::runtime_error("projection::forward not supported unless proj is initialized"); } + PJ_COORD coord; + coord.lpzt.z = 0.0; + coord.lpzt.t = HUGE_VAL; + coord.lpzt.lam = x; + coord.lpzt.phi = y; + PJ_COORD coord_out = proj_trans(proj_, PJ_FWD, coord); + x = coord_out.xy.x; + y = coord_out.xy.y; #else - throw std::runtime_error("projection::forward not supported without proj4 support (-DMAPNIK_USE_PROJ4)"); + throw std::runtime_error("projection::forward not supported without proj support (-DMAPNIK_USE_PROJ)"); #endif } void projection::inverse(double & x,double & y) const { -#ifdef MAPNIK_USE_PROJ4 +#ifdef MAPNIK_USE_PROJ if (!proj_) { - throw std::runtime_error("projection::inverse not supported unless proj4 is initialized"); + throw std::runtime_error("projection::forward not supported unless proj is initialized"); } - - #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480 - std::lock_guard lock(mutex_); - #endif - if (is_geographic_) - { - x *=DEG_TO_RAD; - y *=DEG_TO_RAD; - } - projUV p; - p.u = x; - p.v = y; - p = pj_inv(p,proj_); - x = RAD_TO_DEG * p.u; - y = RAD_TO_DEG * p.v; + PJ_COORD coord; + coord.xyzt.z = 0.0; + coord.xyzt.t = HUGE_VAL; + coord.xyzt.x = x; + coord.xyzt.y = y; + PJ_COORD coord_out = proj_trans(proj_, PJ_INV, coord); + x = coord_out.xy.x; + y = coord_out.xy.y; #else - throw std::runtime_error("projection::inverse not supported without proj4 support (-DMAPNIK_USE_PROJ4)"); + throw std::runtime_error("projection::inverse not supported without proj support (-DMAPNIK_USE_PROJ)"); #endif } projection::~projection() { -#ifdef MAPNIK_USE_PROJ4 - #if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480 - std::lock_guard lock(mutex_); - #endif +#ifdef MAPNIK_USE_PROJ if (proj_) { - pj_free(proj_); + proj_destroy(proj_); proj_ = nullptr; } - #if PJ_VERSION >= 480 if (proj_ctx_) { - pj_ctx_free(proj_ctx_); + proj_context_destroy(proj_ctx_); proj_ctx_ = nullptr; } - #endif #endif } std::string projection::expanded() const { -#ifdef MAPNIK_USE_PROJ4 - if (proj_) return mapnik::util::trim_copy(pj_get_def( proj_, 0 )); +#ifdef MAPNIK_USE_PROJ + if (proj_) + { + PJ_PROJ_INFO info = proj_pj_info(proj_); + return mapnik::util::trim_copy(info.definition); + } #endif return params_; } diff --git a/src/well_known_srs.cpp b/src/well_known_srs.cpp index 93fd6815e1..8a09bbd78e 100644 --- a/src/well_known_srs.cpp +++ b/src/well_known_srs.cpp @@ -51,11 +51,11 @@ static const char * well_known_srs_strings[] = { boost::optional is_well_known_srs(std::string const& srs) { - if (srs == "+init=epsg:4326" || srs == MAPNIK_LONGLAT_PROJ) + if (srs == "epsg:4326" || srs == MAPNIK_LONGLAT_PROJ) { return boost::optional(mapnik::WGS_84); } - else if (srs == "+init=epsg:3857" || srs == MAPNIK_GMERC_PROJ) + else if (srs == "epsg:3857" || srs == MAPNIK_GMERC_PROJ) { return boost::optional(mapnik::G_MERC); } @@ -65,11 +65,11 @@ boost::optional is_well_known_srs(std::string const& srs) boost::optional is_known_geographic(std::string const& srs) { std::string trimmed = util::trim_copy(srs); - if (trimmed == "+init=epsg:3857") + if (trimmed == "epsg:3857") { return boost::optional(false); } - else if (trimmed == "+init=epsg:4326") + else if (trimmed == "epsg:4326") { return boost::optional(true); } diff --git a/test/data b/test/data index c67cf11850..004b170698 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit c67cf11850d65e963e6103b6141f1eca67667aa2 +Subproject commit 004b170698a826de599e42678a27868e861e595e diff --git a/test/data-visual b/test/data-visual index bacfd251da..d0072a3839 160000 --- a/test/data-visual +++ b/test/data-visual @@ -1 +1 @@ -Subproject commit bacfd251da550fa82ea56f6710dc6f85431480c2 +Subproject commit d0072a38390375794be2804b65e36982b4e50711 diff --git a/test/unit/core/exceptions_test.cpp b/test/unit/core/exceptions_test.cpp index 16ed519742..62d414ba68 100644 --- a/test/unit/core/exceptions_test.cpp +++ b/test/unit/core/exceptions_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -25,7 +24,7 @@ TEST_CASE("exceptions") { SECTION("handling") { try { - mapnik::projection srs("foo"); + mapnik::projection srs("FAIL"); // to avoid unused variable warning srs.params(); REQUIRE(false); @@ -38,7 +37,7 @@ SECTION("handling") { mapnik::projection srs("+proj=longlat foo",true); REQUIRE(srs.is_geographic()); REQUIRE(true); - srs.init_proj4(); + srs.init_proj(); // oddly init_proj4 does not throw with old proj/ubuntu precise //REQUIRE(false); } catch (...) { diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp index cf64a41e8d..011525de72 100644 --- a/test/unit/geometry/geometry_reprojection.cpp +++ b/test/unit/geometry/geometry_reprojection.cpp @@ -11,8 +11,8 @@ TEST_CASE("geometry reprojection") { SECTION("test_projection_4326_3857 - Empty Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { geometry_empty geom; @@ -37,8 +37,8 @@ SECTION("test_projection_4326_3857 - Empty Geometry Object") { SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { geometry geom = geometry_empty(); @@ -66,8 +66,8 @@ SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { SECTION("test_projection_4326_3857 - Point Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); point geom1(-97.552175, 35.522895); @@ -119,8 +119,8 @@ SECTION("test_projection_4326_3857 - Point Geometry Object") { SECTION("test_projection_4326_3857 - Point Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); double x1 = -97.552175; @@ -176,8 +176,8 @@ SECTION("test_projection_4326_3857 - Point Geometry Variant Object") { SECTION("test_projection_4326_3857 - Line_String Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); line_string geom1; @@ -241,8 +241,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Object") { SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); line_string geom1_; @@ -316,8 +316,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { SECTION("test_projection_4326_3857 - Polygon Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1; @@ -411,8 +411,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") { SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1_; @@ -503,8 +503,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); multi_point geom1; @@ -568,8 +568,8 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); multi_point geom1_; @@ -643,8 +643,8 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); line_string geom1a; @@ -720,8 +720,8 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); line_string geom1a_; @@ -799,8 +799,8 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a; @@ -898,8 +898,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") { SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a_; @@ -993,8 +993,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { SECTION("test_projection_4326_3857 - Geometry Collection Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a; @@ -1092,8 +1092,8 @@ SECTION("test_projection_4326_3857 - Geometry Collection Object") { SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a_; @@ -1187,8 +1187,8 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { SECTION("test_projection_4269_3857 - Line_String Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4269"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4269"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); line_string geom1; @@ -1252,8 +1252,8 @@ SECTION("test_projection_4269_3857 - Line_String Geometry Object") { SECTION("test_projection_4269_3857 - Point Geometry Object") { using namespace mapnik::geometry; - mapnik::projection source("+init=epsg:4269"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4269"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); point geom1(-97.552175, 35.522895); diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index d052f9edfd..b8add9a817 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -18,8 +18,8 @@ SECTION("proj and view strategy") { mapnik::view_transform vt(256, 256, e); mapnik::view_strategy vs(vt); mapnik::unview_strategy uvs(vt); - mapnik::projection source("+init=epsg:4326"); - mapnik::projection dest("+init=epsg:3857"); + mapnik::projection source("epsg:4326"); + mapnik::projection dest("epsg:3857"); mapnik::proj_transform proj_trans(source, dest); mapnik::proj_transform proj_trans_rev(dest, source); mapnik::proj_strategy ps(proj_trans); diff --git a/test/unit/projection/proj_transform.cpp b/test/unit/projection/proj_transform.cpp index f8cd718d26..a900c4184c 100644 --- a/test/unit/projection/proj_transform.cpp +++ b/test/unit/projection/proj_transform.cpp @@ -15,8 +15,8 @@ TEST_CASE("projection transform") SECTION("Test bounding box transforms - 4326 to 3857") { - mapnik::projection proj_4326("+init=epsg:4326"); - mapnik::projection proj_3857("+init=epsg:3857"); + mapnik::projection proj_4326("epsg:4326"); + mapnik::projection proj_3857("epsg:3857"); mapnik::proj_transform prj_trans(proj_4326, proj_3857); double minx = -45.0; @@ -48,8 +48,8 @@ SECTION("Test bounding box transforms - 4326 to 3857") #if defined(MAPNIK_USE_PROJ4) && PJ_VERSION >= 480 SECTION("test pj_transform failure behavior") { - mapnik::projection proj_4269("+init=epsg:4269"); - mapnik::projection proj_3857("+init=epsg:3857"); + mapnik::projection proj_4269("epsg:4269"); + mapnik::projection proj_3857("epsg:3857"); mapnik::proj_transform prj_trans(proj_4269, proj_3857); mapnik::proj_transform prj_trans2(proj_3857, proj_4269); @@ -125,8 +125,8 @@ SECTION("test pj_transform failure behavior") // Github Issue https://github.com/mapnik/mapnik/issues/2648 SECTION("Test proj antimeridian bbox") { - mapnik::projection prj_geog("+init=epsg:4326"); - mapnik::projection prj_proj("+init=epsg:2193"); + mapnik::projection prj_geog("epsg:4326"); + mapnik::projection prj_proj("epsg:2193"); mapnik::proj_transform prj_trans_fwd(prj_proj, prj_geog); mapnik::proj_transform prj_trans_rev(prj_geog, prj_proj); @@ -134,7 +134,7 @@ SECTION("Test proj antimeridian bbox") // reference values taken from proj4 command line tool: // (non-corner points assume PROJ_ENVELOPE_POINTS == 20) // - // cs2cs -Ef %.10f +init=epsg:2193 +to +init=epsg:4326 < 1") { - mapnik::projection const proj_4326("+init=epsg:4326"); - mapnik::projection const proj_3857("+init=epsg:3857"); - mapnik::projection const proj_2193("+init=epsg:2193"); + mapnik::projection const proj_4326("epsg:4326"); + mapnik::projection const proj_3857("epsg:3857"); + mapnik::projection const proj_2193("epsg:2193"); SECTION("lonlat <-> Web Mercator") { - // cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:3857 < 1") #ifdef MAPNIK_USE_PROJ4 SECTION("lonlat <-> New Zealand Transverse Mercator 2000") { - // cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:2193 < extent(16310607, 7704513, 16310621, 7704527); mapnik::view_transform tr(512, 512, extent); - mapnik::projection proj1("+init=epsg:2330"); - mapnik::projection proj2("+init=epsg:4326"); + mapnik::projection proj1("epsg:2330"); + mapnik::projection proj2("epsg:4326"); mapnik::proj_transform prj_trans(proj1, proj2); path_type path(tr, va, prj_trans); @@ -78,8 +78,8 @@ SECTION("polygon closing - epsg 32633") { va_type va(g); mapnik::box2d extent(166022, 0, 833978, 9329005); mapnik::view_transform tr(512, 512, extent); - mapnik::projection proj1("+init=epsg:32633"); - mapnik::projection proj2("+init=epsg:4326"); + mapnik::projection proj1("epsg:32633"); + mapnik::projection proj2("epsg:4326"); mapnik::proj_transform prj_trans(proj1, proj2); path_type path(tr, va, prj_trans);