Merge branch 'proj6' of https://github.com/mapnik/mapnik into cmake-support
This commit is contained in:
commit
4eed15f87a
36 changed files with 644 additions and 518 deletions
114
SConstruct
114
SConstruct
|
@ -1,6 +1,6 @@
|
||||||
# This file is part of Mapnik (c++ mapping toolkit)
|
# 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
|
# Mapnik is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -66,7 +66,8 @@ SCONF_TEMP_DIR = '.sconf_temp'
|
||||||
BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',]
|
BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',]
|
||||||
BOOST_MIN_VERSION = '1.61'
|
BOOST_MIN_VERSION = '1.61'
|
||||||
#CAIRO_MIN_VERSION = '1.8.0'
|
#CAIRO_MIN_VERSION = '1.8.0'
|
||||||
|
PROJ_MIN_VERSION = (7, 2, 0)
|
||||||
|
PROJ_MIN_VERSION_STRING = "%s.%s.%s" % PROJ_MIN_VERSION
|
||||||
HARFBUZZ_MIN_VERSION = (0, 9, 34)
|
HARFBUZZ_MIN_VERSION = (0, 9, 34)
|
||||||
HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION
|
HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ pretty_dep_names = {
|
||||||
'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',
|
'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',
|
'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
|
||||||
'proj':'Proj 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/',
|
||||||
|
'proj-min-version':'libproj >=%s required' % PROJ_MIN_VERSION_STRING,
|
||||||
'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',
|
'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',
|
'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',
|
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
|
||||||
|
@ -103,7 +105,7 @@ pretty_dep_names = {
|
||||||
'boost_regex_icu':'libboost_regex built with optional ICU unicode support is needed for unicode regex support in mapnik.',
|
'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)',
|
'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)',
|
'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',
|
'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'
|
'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'
|
||||||
}
|
}
|
||||||
|
@ -407,7 +409,7 @@ opts.AddVariables(
|
||||||
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'),
|
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'),
|
||||||
PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept),
|
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),
|
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_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),
|
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', ''),
|
('PG_INCLUDES', 'Search path for libpq (postgres client) include files', ''),
|
||||||
|
@ -918,6 +920,31 @@ def CheckGdalData(context, silent=False):
|
||||||
context.Result('Failed to detect (mapnik-config will have null value)')
|
context.Result('Failed to detect (mapnik-config will have null value)')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def proj_version(context):
|
||||||
|
context.Message('Checking for Proj version >=%s...' % PROJ_MIN_VERSION_STRING)
|
||||||
|
ret, out = context.TryRun("""
|
||||||
|
#include "proj.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#define PROJ_VERSION_ATLEAST(major,minor,micro) \
|
||||||
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
|
PROJ_VERSION_MAJOR*10000+PROJ_VERSION_MINOR*100+PROJ_VERSION_PATCH)
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("%d;%d.%d.%d", PROJ_VERSION_ATLEAST{min-version}, PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR, PROJ_VERSION_PATCH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
""".replace("{min-version}", str(PROJ_MIN_VERSION)),'.c')
|
||||||
|
if not ret:
|
||||||
|
context.Result('error (could not get version from proj.h)')
|
||||||
|
else:
|
||||||
|
ok_str, found_version_str = out.strip().split(';', 1)
|
||||||
|
major,minor,patch = found_version_str.split('.')
|
||||||
|
ret = int(ok_str), int(major)*10000+int(minor)*100+int(patch)
|
||||||
|
if ret:
|
||||||
|
context.Result('yes (found Proj %s)' % found_version_str)
|
||||||
|
else:
|
||||||
|
context.Result('no (found Proj %s)' % found_version_str)
|
||||||
|
return ret
|
||||||
|
|
||||||
def CheckProjData(context, silent=False):
|
def CheckProjData(context, silent=False):
|
||||||
|
|
||||||
|
@ -925,51 +952,40 @@ def CheckProjData(context, silent=False):
|
||||||
context.Message('Checking for PROJ_LIB directory...')
|
context.Message('Checking for PROJ_LIB directory...')
|
||||||
ret, out = context.TryRun("""
|
ret, out = context.TryRun("""
|
||||||
|
|
||||||
// This is narly, could eventually be replaced using https://github.com/OSGeo/proj.4/pull/551]
|
#include <proj.h>
|
||||||
#include <proj_api.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
static void my_proj4_logger(void * user_data, int /*level*/, const char * msg)
|
std::vector<std::string> split_searchpath(std::string const& paths)
|
||||||
{
|
{
|
||||||
std::string* posMsg = static_cast<std::string*>(user_data);
|
std::vector<std::string> output;
|
||||||
*posMsg += msg;
|
std::stringstream ss(paths);
|
||||||
|
std::string path;
|
||||||
|
|
||||||
|
for( std::string path;std::getline(ss, path, ':');)
|
||||||
|
{
|
||||||
|
output.push_back(path);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/OSGeo/gdal/blob/ddbf6d39aa4b005a77ca4f27c2d61a3214f336f8/gdal/alg/gdalapplyverticalshiftgrid.cpp#L616-L633
|
int main()
|
||||||
|
{
|
||||||
std::string find_proj_path(const char * pszFilename) {
|
PJ_INFO info = proj_info();
|
||||||
std::string osMsg;
|
std::string result = info.searchpath;
|
||||||
std::string osFilename;
|
for (auto path : split_searchpath(result))
|
||||||
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);
|
std::ifstream file(path + "/proj.db");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
std::cout << path;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
size_t nPos = osMsg.find("fopen(");
|
return -1;
|
||||||
if( nPos != std::string::npos )
|
|
||||||
{
|
|
||||||
osFilename = osMsg.substr(nPos + strlen("fopen("));
|
|
||||||
nPos = osFilename.find(")");
|
|
||||||
if( nPos != std::string::npos )
|
|
||||||
osFilename = osFilename.substr(0, nPos);
|
|
||||||
}
|
|
||||||
pj_ctx_free(ctx);
|
|
||||||
return osFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
std::string result = find_proj_path(" ");
|
|
||||||
std::cout << result;
|
|
||||||
if (result.empty()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
""", '.cpp')
|
""", '.cpp')
|
||||||
|
@ -977,7 +993,7 @@ int main() {
|
||||||
if silent:
|
if silent:
|
||||||
context.did_show_result=1
|
context.did_show_result=1
|
||||||
if ret:
|
if ret:
|
||||||
context.Result('pj_open_lib returned %s' % value)
|
context.Result('proj_info.searchpath returned %s' % value)
|
||||||
else:
|
else:
|
||||||
context.Result('Failed to detect (mapnik-config will have null value)')
|
context.Result('Failed to detect (mapnik-config will have null value)')
|
||||||
return value
|
return value
|
||||||
|
@ -1215,7 +1231,7 @@ int main()
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
__cplusplus = {'14':'201402L', '17':'201703L'}
|
__cplusplus = {'14':'201402L', '17':'201703L', '20':'202002L'}
|
||||||
|
|
||||||
def supports_cxx_std (context, silent=False):
|
def supports_cxx_std (context, silent=False):
|
||||||
cplusplus_string = __cplusplus[env['CXX_STD']]
|
cplusplus_string = __cplusplus[env['CXX_STD']]
|
||||||
|
@ -1245,6 +1261,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths,
|
||||||
'FindBoost' : FindBoost,
|
'FindBoost' : FindBoost,
|
||||||
'CheckBoost' : CheckBoost,
|
'CheckBoost' : CheckBoost,
|
||||||
'CheckIcuData' : CheckIcuData,
|
'CheckIcuData' : CheckIcuData,
|
||||||
|
'proj_version' : proj_version,
|
||||||
'CheckProjData' : CheckProjData,
|
'CheckProjData' : CheckProjData,
|
||||||
'CheckGdalData' : CheckGdalData,
|
'CheckGdalData' : CheckGdalData,
|
||||||
'CheckCairoHasFreetype' : CheckCairoHasFreetype,
|
'CheckCairoHasFreetype' : CheckCairoHasFreetype,
|
||||||
|
@ -1545,7 +1562,7 @@ if not preconfigured:
|
||||||
env['SKIPPED_DEPS'].append('jpeg')
|
env['SKIPPED_DEPS'].append('jpeg')
|
||||||
|
|
||||||
if env['PROJ']:
|
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']
|
inc_path = env['%s_INCLUDES' % 'PROJ']
|
||||||
lib_path = env['%s_LIBS' % 'PROJ']
|
lib_path = env['%s_LIBS' % 'PROJ']
|
||||||
env.AppendUnique(CPPPATH = fix_path(inc_path))
|
env.AppendUnique(CPPPATH = fix_path(inc_path))
|
||||||
|
@ -1697,6 +1714,13 @@ if not preconfigured:
|
||||||
else:
|
else:
|
||||||
color_print(4, 'Could not find optional header or shared library for %s' % libname)
|
color_print(4, 'Could not find optional header or shared library for %s' % libname)
|
||||||
env['SKIPPED_DEPS'].append(libname)
|
env['SKIPPED_DEPS'].append(libname)
|
||||||
|
elif libname == 'proj':
|
||||||
|
result, version = conf.proj_version()
|
||||||
|
if not result:
|
||||||
|
env['SKIPPED_DEPS'].append('proj-min-version')
|
||||||
|
else:
|
||||||
|
env.Append(CPPDEFINES = define)
|
||||||
|
env.Append(CPPDEFINES = "-DPROJ_VERSION=%d" % version)
|
||||||
else:
|
else:
|
||||||
env.Append(CPPDEFINES = define)
|
env.Append(CPPDEFINES = define)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -9,6 +9,7 @@ test_env = env.Clone()
|
||||||
test_env['LIBS'] = [env['MAPNIK_NAME']]
|
test_env['LIBS'] = [env['MAPNIK_NAME']]
|
||||||
test_env.AppendUnique(LIBS=copy(env['LIBMAPNIK_LIBS']))
|
test_env.AppendUnique(LIBS=copy(env['LIBMAPNIK_LIBS']))
|
||||||
test_env.AppendUnique(LIBS='mapnik-wkt')
|
test_env.AppendUnique(LIBS='mapnik-wkt')
|
||||||
|
test_env.AppendUnique(LIBS='sqlite3')
|
||||||
if env['PLATFORM'] == 'Linux':
|
if env['PLATFORM'] == 'Linux':
|
||||||
test_env.AppendUnique(LIBS='dl')
|
test_env.AppendUnique(LIBS='dl')
|
||||||
test_env.AppendUnique(LIBS='rt')
|
test_env.AppendUnique(LIBS='rt')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[]>
|
<!DOCTYPE Map[]>
|
||||||
<Map
|
<Map
|
||||||
srs="+init=epsg:4326"
|
srs="epsg:4326"
|
||||||
background-color="#dfd8c9">
|
background-color="#dfd8c9">
|
||||||
|
|
||||||
<Style name="style">
|
<Style name="style">
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Layer name="layer"
|
<Layer name="layer"
|
||||||
srs="+init=epsg:4326">
|
srs="epsg:4326">
|
||||||
<StyleName>style</StyleName>
|
<StyleName>style</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[]>
|
<!DOCTYPE Map[]>
|
||||||
<Map
|
<Map
|
||||||
srs="+init=epsg:4326"
|
srs="epsg:4326"
|
||||||
background-color="#dfd8c9">
|
background-color="#dfd8c9">
|
||||||
|
|
||||||
<Style name="style">
|
<Style name="style">
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Layer name="layer"
|
<Layer name="layer"
|
||||||
srs="+init=epsg:4326">
|
srs="epsg:4326">
|
||||||
<StyleName>style</StyleName>
|
<StyleName>style</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
}
|
}
|
||||||
bool operator()() const
|
bool operator()() const
|
||||||
{
|
{
|
||||||
mapnik::Map m(256,256,"+init=epsg:3857");
|
mapnik::Map m(256,256,"epsg:3857");
|
||||||
|
|
||||||
mapnik::parameters params;
|
mapnik::parameters params;
|
||||||
params["type"]="memory";
|
params["type"]="memory";
|
||||||
|
|
|
@ -51,7 +51,7 @@ void render(mapnik::geometry::multi_polygon<double> const& geom,
|
||||||
agg::pixfmt_rgba32_plain pixf(buf);
|
agg::pixfmt_rgba32_plain pixf(buf);
|
||||||
ren_base renb(pixf);
|
ren_base renb(pixf);
|
||||||
renderer ren(renb);
|
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));
|
ren.color(agg::rgba8(127,127,127,255));
|
||||||
agg::rasterizer_scanline_aa<> ras;
|
agg::rasterizer_scanline_aa<> ras;
|
||||||
for (auto const& poly : geom)
|
for (auto const& poly : geom)
|
||||||
|
|
|
@ -9,7 +9,7 @@ class test : public benchmark::test_case
|
||||||
std::string dest_;
|
std::string dest_;
|
||||||
mapnik::box2d<double> from_;
|
mapnik::box2d<double> from_;
|
||||||
mapnik::box2d<double> to_;
|
mapnik::box2d<double> to_;
|
||||||
bool defer_proj4_init_;
|
bool defer_proj_init_;
|
||||||
public:
|
public:
|
||||||
test(mapnik::parameters const& params,
|
test(mapnik::parameters const& params,
|
||||||
std::string const& src,
|
std::string const& src,
|
||||||
|
@ -22,11 +22,11 @@ public:
|
||||||
dest_(dest),
|
dest_(dest),
|
||||||
from_(from),
|
from_(from),
|
||||||
to_(to),
|
to_(to),
|
||||||
defer_proj4_init_(defer_proj) {}
|
defer_proj_init_(defer_proj) {}
|
||||||
bool validate() const
|
bool validate() const
|
||||||
{
|
{
|
||||||
mapnik::projection src(src_,defer_proj4_init_);
|
mapnik::projection src(src_,defer_proj_init_);
|
||||||
mapnik::projection dest(dest_,defer_proj4_init_);
|
mapnik::projection dest(dest_,defer_proj_init_);
|
||||||
mapnik::proj_transform tr(src,dest);
|
mapnik::proj_transform tr(src,dest);
|
||||||
mapnik::box2d<double> bbox = from_;
|
mapnik::box2d<double> bbox = from_;
|
||||||
if (!tr.forward(bbox)) return false;
|
if (!tr.forward(bbox)) return false;
|
||||||
|
@ -38,15 +38,15 @@ public:
|
||||||
}
|
}
|
||||||
bool operator()() const
|
bool operator()() const
|
||||||
{
|
{
|
||||||
|
mapnik::projection src(src_,defer_proj_init_);
|
||||||
|
mapnik::projection dest(dest_,defer_proj_init_);
|
||||||
|
mapnik::proj_transform tr(src,dest);
|
||||||
for (std::size_t i=0;i<iterations_;++i)
|
for (std::size_t i=0;i<iterations_;++i)
|
||||||
{
|
{
|
||||||
for (int j=-180;j<180;j=j+5)
|
for (int j=-180;j<180;j=j+5)
|
||||||
{
|
{
|
||||||
for (int k=-85;k<85;k=k+5)
|
for (int k=-85;k<85;k=k+5)
|
||||||
{
|
{
|
||||||
mapnik::projection src(src_,defer_proj4_init_);
|
|
||||||
mapnik::projection dest(dest_,defer_proj4_init_);
|
|
||||||
mapnik::proj_transform tr(src,dest);
|
|
||||||
mapnik::box2d<double> box(j,k,j,k);
|
mapnik::box2d<double> box(j,k,j,k);
|
||||||
if (!tr.forward(box)) throw std::runtime_error("could not transform coords");
|
if (!tr.forward(box)) throw std::runtime_error("could not transform coords");
|
||||||
}
|
}
|
||||||
|
@ -56,19 +56,19 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
mapnik::box2d<double> from(-180,-80,180,80);
|
mapnik::box2d<double> from(-180,-80,180,80);
|
||||||
mapnik::box2d<double> to(-20037508.3427892476,-15538711.0963092316,20037508.3427892476,15538711.0963092316);
|
mapnik::box2d<double> to(-20037508.3427892476,-15538711.0963092316,20037508.3427892476,15538711.0963092316);
|
||||||
std::string from_str("+init=epsg:4326");
|
std::string from_str("epsg:4326");
|
||||||
std::string to_str("+init=epsg:3857");
|
std::string to_str("epsg:3857");
|
||||||
std::string from_str2("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
|
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");
|
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)
|
return benchmark::sequencer(argc, argv)
|
||||||
.run<test>("lonlat->merc epsg", from_str, to_str, from, to, true)
|
.run<test>("lonlat->merc epsg (internal)", from_str, to_str, from, to, true)
|
||||||
.run<test>("lonlat->merc literal", from_str2, to_str2, from, to, true)
|
.run<test>("lonlat->merc literal (libproj)", from_str2, to_str2, from, to, true)
|
||||||
.run<test>("merc->lonlat epsg", to_str, from_str, to, from, true)
|
.run<test>("merc->lonlat epsg (internal)", to_str, from_str, to, from, true)
|
||||||
.run<test>("merc->lonlat literal", to_str2, from_str2, to, from, true)
|
.run<test>("merc->lonlat literal (libproj)", to_str2, from_str2, to, from, true)
|
||||||
.done();
|
.done();
|
||||||
}
|
}
|
||||||
|
|
16
bootstrap.sh
16
bootstrap.sh
|
@ -8,7 +8,7 @@ todo
|
||||||
- shrink icu data
|
- shrink icu data
|
||||||
'
|
'
|
||||||
|
|
||||||
MASON_VERSION="edb620c7"
|
MASON_VERSION="485514d8"
|
||||||
|
|
||||||
function setup_mason() {
|
function setup_mason() {
|
||||||
if [[ ! -d ./.mason ]]; then
|
if [[ ! -d ./.mason ]]; then
|
||||||
|
@ -49,17 +49,17 @@ BOOST_VERSION="1.75.0"
|
||||||
function install_mason_deps() {
|
function install_mason_deps() {
|
||||||
install ccache 3.3.1
|
install ccache 3.3.1
|
||||||
install zlib 1.2.8
|
install zlib 1.2.8
|
||||||
install jpeg_turbo 1.5.1 libjpeg
|
install jpeg_turbo 1.5.2 libjpeg
|
||||||
install libpng 1.6.28 libpng
|
install libpng 1.6.32 libpng
|
||||||
install libtiff 4.0.7 libtiff
|
install libtiff 4.0.8 libtiff
|
||||||
install libpq 9.6.2
|
install libpq 9.6.5
|
||||||
install sqlite 3.17.0 libsqlite3
|
install sqlite 3.34.0 libsqlite3
|
||||||
install icu ${ICU_VERSION}
|
install icu ${ICU_VERSION}
|
||||||
install proj 4.9.3 libproj
|
install proj 7.2.1 libproj
|
||||||
install pixman 0.34.0 libpixman-1
|
install pixman 0.34.0 libpixman-1
|
||||||
install cairo 1.14.8 libcairo
|
install cairo 1.14.8 libcairo
|
||||||
install webp 0.6.0 libwebp
|
install webp 0.6.0 libwebp
|
||||||
install libgdal 2.1.3 libgdal
|
install libgdal 2.2.3 libgdal
|
||||||
install boost ${BOOST_VERSION}
|
install boost ${BOOST_VERSION}
|
||||||
install boost_libsystem ${BOOST_VERSION}
|
install boost_libsystem ${BOOST_VERSION}
|
||||||
install boost_libfilesystem ${BOOST_VERSION}
|
install boost_libfilesystem ${BOOST_VERSION}
|
||||||
|
|
|
@ -41,7 +41,7 @@ if env['HAS_CAIRO']:
|
||||||
demo_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
demo_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
||||||
|
|
||||||
libraries = [env['MAPNIK_NAME']]
|
libraries = [env['MAPNIK_NAME']]
|
||||||
libraries.extend(copy(env['LIBMAPNIK_LIBS']))
|
libraries.extend([copy(env['LIBMAPNIK_LIBS']), 'sqlite3', 'pthread'])
|
||||||
rundemo = demo_env.Program('rundemo', source, LIBS=libraries)
|
rundemo = demo_env.Program('rundemo', source, LIBS=libraries)
|
||||||
|
|
||||||
Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
|
@ -421,11 +421,11 @@ void MainWindow::set_default_extent(double x0,double y0, double x1, double y1)
|
||||||
if (map_ptr)
|
if (map_ptr)
|
||||||
{
|
{
|
||||||
mapnik::projection prj(map_ptr->srs());
|
mapnik::projection prj(map_ptr->srs());
|
||||||
prj.forward(x0,y0);
|
prj.forward(x0, y0);
|
||||||
prj.forward(x1,y1);
|
prj.forward(x1, y1);
|
||||||
default_extent_=mapnik::box2d<double>(x0,y0,x1,y1);
|
default_extent_=mapnik::box2d<double>(x0, y0, x1, y1);
|
||||||
mapWidget_->zoomToBox(default_extent_);
|
mapWidget_->zoomToBox(default_extent_);
|
||||||
std::cout << "SET DEFAULT EXT\n";
|
std::cout << "SET DEFAULT EXT:" << default_extent_ << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...) {}
|
catch (...) {}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <mapnik/agg_renderer.hpp>
|
#include <mapnik/agg_renderer.hpp>
|
||||||
#include <mapnik/layer.hpp>
|
#include <mapnik/layer.hpp>
|
||||||
#include <mapnik/projection.hpp>
|
#include <mapnik/proj_transform.hpp>
|
||||||
#include <mapnik/scale_denominator.hpp>
|
#include <mapnik/scale_denominator.hpp>
|
||||||
#include <mapnik/view_transform.hpp>
|
#include <mapnik/view_transform.hpp>
|
||||||
#include <mapnik/transform_path_adapter.hpp>
|
#include <mapnik/transform_path_adapter.hpp>
|
||||||
|
@ -156,7 +156,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
||||||
{
|
{
|
||||||
QVector<QPair<QString,QString> > info;
|
QVector<QPair<QString,QString> > info;
|
||||||
|
|
||||||
projection map_proj(map_->srs()); // map projection
|
projection map_proj(map_->srs(), true); // map projection
|
||||||
double scale_denom = scale_denominator(map_->scale(),map_proj.is_geographic());
|
double scale_denom = scale_denominator(map_->scale(),map_proj.is_geographic());
|
||||||
view_transform t(map_->width(),map_->height(),map_->get_current_extent());
|
view_transform t(map_->width(),map_->height(),map_->get_current_extent());
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
||||||
double x = e->x();
|
double x = e->x();
|
||||||
double y = e->y();
|
double y = e->y();
|
||||||
std::cout << "query at " << x << "," << y << "\n";
|
std::cout << "query at " << x << "," << y << "\n";
|
||||||
projection layer_proj(layer.srs());
|
projection layer_proj(layer.srs(), true);
|
||||||
mapnik::proj_transform prj_trans(map_proj,layer_proj);
|
mapnik::proj_transform prj_trans(map_proj,layer_proj);
|
||||||
//std::auto_ptr<mapnik::memory_datasource> data(new mapnik::memory_datasource);
|
//std::auto_ptr<mapnik::memory_datasource> data(new mapnik::memory_datasource);
|
||||||
mapnik::featureset_ptr fs = map_->query_map_point(index,x,y);
|
mapnik::featureset_ptr fs = map_->query_map_point(index,x,y);
|
||||||
|
@ -586,38 +586,43 @@ void MapWidget::updateMap()
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
projection prj(map_->srs()); // map projection
|
projection prj(map_->srs(), true); // map projection
|
||||||
box2d<double> ext = map_->get_current_extent();
|
box2d<double> ext = map_->get_current_extent();
|
||||||
double x0 = ext.minx();
|
double x0 = ext.minx();
|
||||||
double y0 = ext.miny();
|
double y0 = ext.miny();
|
||||||
double x1 = ext.maxx();
|
double x1 = ext.maxx();
|
||||||
double y1 = ext.maxy();
|
double y1 = ext.maxy();
|
||||||
prj.inverse(x0,y0);
|
double z = 0;
|
||||||
prj.inverse(x1,y1);
|
std::string dest_srs = {"epsg:4326"};
|
||||||
std::cout << "BBOX (WGS84): " << x0 << "," << y0 << "," << x1 << "," << y1 << "\n";
|
mapnik::proj_transform proj_tr(map_->srs(), dest_srs);
|
||||||
update();
|
|
||||||
// emit signal to interested widgets
|
proj_tr.forward(x0, y0, z);
|
||||||
emit mapViewChanged();
|
proj_tr.forward(x1, y1, z);
|
||||||
}
|
std::cout << "MAP SIZE:" << map_->width() << "," << map_->height() << std::endl;
|
||||||
catch (...)
|
std::cout << "BBOX (WGS84): " << x0 << "," << y0 << "," << x1 << "," << y1 << "\n";
|
||||||
{
|
update();
|
||||||
std::cerr << "Unknown exception caught!\n";
|
// emit signal to interested widgets
|
||||||
}
|
emit mapViewChanged();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Unknown exception caught!\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Map> MapWidget::getMap()
|
std::shared_ptr<Map> MapWidget::getMap()
|
||||||
{
|
{
|
||||||
return map_;
|
return map_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::setMap(std::shared_ptr<Map> map)
|
void MapWidget::setMap(std::shared_ptr<Map> map)
|
||||||
{
|
{
|
||||||
map_ = map;
|
map_ = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapWidget::layerSelected(int index)
|
void MapWidget::layerSelected(int index)
|
||||||
{
|
{
|
||||||
selectedLayer_ = index;
|
selectedLayer_ = index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,10 +66,9 @@ struct layer_rendering_material
|
||||||
std::vector<layer_rendering_material> materials_;
|
std::vector<layer_rendering_material> materials_;
|
||||||
|
|
||||||
layer_rendering_material(layer const& lay, projection const& dest)
|
layer_rendering_material(layer const& lay, projection const& dest)
|
||||||
:
|
: lay_(lay),
|
||||||
lay_(lay),
|
proj0_(dest),
|
||||||
proj0_(dest),
|
proj1_(lay.srs(), true) {}
|
||||||
proj1_(lay.srs(),true) {}
|
|
||||||
|
|
||||||
layer_rendering_material(layer_rendering_material && rhs) = default;
|
layer_rendering_material(layer_rendering_material && rhs) = default;
|
||||||
};
|
};
|
||||||
|
@ -255,8 +254,7 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
||||||
}
|
}
|
||||||
|
|
||||||
processor_context_ptr current_ctx = ds->get_context(ctx_map);
|
processor_context_ptr current_ctx = ds->get_context(ctx_map);
|
||||||
proj_transform prj_trans(mat.proj0_,mat.proj1_);
|
proj_transform * proj_trans_ptr = m_.get_proj_transform(mat.proj0_.params(), mat.proj1_.params());
|
||||||
|
|
||||||
box2d<double> query_ext = extent; // unbuffered
|
box2d<double> query_ext = extent; // unbuffered
|
||||||
box2d<double> buffered_query_ext(query_ext); // buffered
|
box2d<double> buffered_query_ext(query_ext); // buffered
|
||||||
|
|
||||||
|
@ -286,22 +284,22 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
||||||
bool early_return = false;
|
bool early_return = false;
|
||||||
|
|
||||||
// first, try intersection of map extent forward projected into layer srs
|
// first, try intersection of map extent forward projected into layer srs
|
||||||
if (prj_trans.forward(buffered_query_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
|
if (proj_trans_ptr->forward(buffered_query_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
|
||||||
{
|
{
|
||||||
fw_success = true;
|
fw_success = true;
|
||||||
layer_ext.clip(buffered_query_ext);
|
layer_ext.clip(buffered_query_ext);
|
||||||
}
|
}
|
||||||
// if no intersection and projections are also equal, early return
|
// if no intersection and projections are also equal, early return
|
||||||
else if (prj_trans.equal())
|
else if (proj_trans_ptr->equal())
|
||||||
{
|
{
|
||||||
early_return = true;
|
early_return = true;
|
||||||
}
|
}
|
||||||
// next try intersection of layer extent back projected into map srs
|
// next try intersection of layer extent back projected into map srs
|
||||||
else if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext_map_srs.intersects(layer_ext))
|
else if (proj_trans_ptr->backward(layer_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext_map_srs.intersects(layer_ext))
|
||||||
{
|
{
|
||||||
layer_ext.clip(buffered_query_ext_map_srs);
|
layer_ext.clip(buffered_query_ext_map_srs);
|
||||||
// forward project layer extent back into native projection
|
// forward project layer extent back into native projection
|
||||||
if (! prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS))
|
if (! proj_trans_ptr->forward(layer_ext, PROJ_ENVELOPE_POINTS))
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_ERROR(feature_style_processor)
|
MAPNIK_LOG_ERROR(feature_style_processor)
|
||||||
<< "feature_style_processor: Layer=" << lay.name()
|
<< "feature_style_processor: Layer=" << lay.name()
|
||||||
|
@ -353,17 +351,17 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
||||||
layer_ext2 = lay.envelope();
|
layer_ext2 = lay.envelope();
|
||||||
if (fw_success)
|
if (fw_success)
|
||||||
{
|
{
|
||||||
if (prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS))
|
if (proj_trans_ptr->forward(query_ext, PROJ_ENVELOPE_POINTS))
|
||||||
{
|
{
|
||||||
layer_ext2.clip(query_ext);
|
layer_ext2.clip(query_ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (prj_trans.backward(layer_ext2, PROJ_ENVELOPE_POINTS))
|
if (proj_trans_ptr->backward(layer_ext2, PROJ_ENVELOPE_POINTS))
|
||||||
{
|
{
|
||||||
layer_ext2.clip(query_ext);
|
layer_ext2.clip(query_ext);
|
||||||
prj_trans.forward(layer_ext2, PROJ_ENVELOPE_POINTS);
|
proj_trans_ptr->forward(layer_ext2, PROJ_ENVELOPE_POINTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,9 +493,7 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||||
layer const& lay = mat.lay_;
|
layer const& lay = mat.lay_;
|
||||||
|
|
||||||
std::vector<rule_cache> const & rule_caches = mat.rule_caches_;
|
std::vector<rule_cache> const & rule_caches = mat.rule_caches_;
|
||||||
|
proj_transform * proj_trans_ptr = m_.get_proj_transform(mat.proj0_.params(), mat.proj1_.params());
|
||||||
proj_transform prj_trans(mat.proj0_,mat.proj1_);
|
|
||||||
|
|
||||||
bool cache_features = lay.cache_features() && active_styles.size() > 1;
|
bool cache_features = lay.cache_features() && active_styles.size() > 1;
|
||||||
|
|
||||||
datasource_ptr ds = lay.datasource();
|
datasource_ptr ds = lay.datasource();
|
||||||
|
@ -525,10 +521,9 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||||
|
|
||||||
cache->prepare();
|
cache->prepare();
|
||||||
render_style(p, style,
|
render_style(p, style,
|
||||||
rule_caches[i],
|
rule_caches[i++],
|
||||||
cache,
|
cache,
|
||||||
prj_trans);
|
*proj_trans_ptr);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
cache->clear();
|
cache->clear();
|
||||||
}
|
}
|
||||||
|
@ -540,8 +535,7 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||||
for (feature_type_style const* style : active_styles)
|
for (feature_type_style const* style : active_styles)
|
||||||
{
|
{
|
||||||
cache->prepare();
|
cache->prepare();
|
||||||
render_style(p, style, rule_caches[i], cache, prj_trans);
|
render_style(p, style, rule_caches[i++], cache, *proj_trans_ptr);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
cache->clear();
|
cache->clear();
|
||||||
}
|
}
|
||||||
|
@ -565,9 +559,8 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||||
{
|
{
|
||||||
cache->prepare();
|
cache->prepare();
|
||||||
render_style(p, style,
|
render_style(p, style,
|
||||||
rule_caches[i],
|
rule_caches[i++],
|
||||||
cache, prj_trans);
|
cache, *proj_trans_ptr);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We only have a single style and no grouping.
|
// We only have a single style and no grouping.
|
||||||
|
@ -579,10 +572,9 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||||
{
|
{
|
||||||
featureset_ptr features = *featuresets++;
|
featureset_ptr features = *featuresets++;
|
||||||
render_style(p, style,
|
render_style(p, style,
|
||||||
rule_caches[i],
|
rule_caches[i++],
|
||||||
features,
|
features,
|
||||||
prj_trans);
|
*proj_trans_ptr);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ using datasource_ptr = std::shared_ptr<datasource>;
|
||||||
* @brief A Mapnik map layer.
|
* @brief A Mapnik map layer.
|
||||||
*
|
*
|
||||||
* Create a layer with a named string and, optionally, an srs string either
|
* Create a layer with a named string and, optionally, an srs string either
|
||||||
* with a Proj.4 epsg code ('+init=epsg:<code>') or with a Proj.4 literal
|
* with a Proj.4 epsg code ('epsg:<code>') or with a Proj.4 literal
|
||||||
* ('+proj=<literal>'). If no srs is specified it will default to
|
* ('+proj=<literal>'). If no srs is specified it will default to
|
||||||
* '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
|
* '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +50,7 @@ class MAPNIK_DECL layer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
layer(std::string const& name,
|
layer(std::string const& name,
|
||||||
std::string const& srs=MAPNIK_LONGLAT_PROJ);
|
std::string const& srs = MAPNIK_GEOGRAPHIC_PROJ);
|
||||||
// copy
|
// copy
|
||||||
layer(layer const& l);
|
layer(layer const& l);
|
||||||
// move
|
// move
|
||||||
|
|
|
@ -33,15 +33,17 @@
|
||||||
#include <mapnik/well_known_srs.hpp>
|
#include <mapnik/well_known_srs.hpp>
|
||||||
#include <mapnik/image_compositing.hpp>
|
#include <mapnik/image_compositing.hpp>
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <mapnik/proj_transform.hpp>
|
||||||
#include <mapnik/warning.hpp>
|
#include <mapnik/warning.hpp>
|
||||||
MAPNIK_DISABLE_WARNING_PUSH
|
MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -58,6 +60,31 @@ class layer;
|
||||||
class MAPNIK_DECL Map : boost::equality_comparable<Map>
|
class MAPNIK_DECL Map : boost::equality_comparable<Map>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using key_type = std::pair<std::string, std::string>;
|
||||||
|
using compatible_key_type = std::pair<boost::string_view, boost::string_view>;
|
||||||
|
|
||||||
|
struct compatible_hash
|
||||||
|
{
|
||||||
|
template <typename KeyType>
|
||||||
|
std::size_t operator() (KeyType const& key) const
|
||||||
|
{
|
||||||
|
using hash_type = boost::hash<typename KeyType::first_type>;
|
||||||
|
std::size_t seed = hash_type{}(key.first);
|
||||||
|
seed ^= hash_type{}(key.second) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct compatible_predicate
|
||||||
|
{
|
||||||
|
bool operator()(compatible_key_type const& k1,
|
||||||
|
compatible_key_type const& k2) const
|
||||||
|
{
|
||||||
|
return k1 == k2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using proj_cache_type = boost::unordered_map<key_type, std::unique_ptr<proj_transform>, compatible_hash>;
|
||||||
|
|
||||||
enum aspect_fix_mode
|
enum aspect_fix_mode
|
||||||
{
|
{
|
||||||
|
@ -83,8 +110,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const unsigned MIN_MAPSIZE=16;
|
static const unsigned MIN_MAPSIZE = 16;
|
||||||
static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
|
static const unsigned MAX_MAPSIZE = MIN_MAPSIZE << 10;
|
||||||
unsigned width_;
|
unsigned width_;
|
||||||
unsigned height_;
|
unsigned height_;
|
||||||
std::string srs_;
|
std::string srs_;
|
||||||
|
@ -104,7 +131,7 @@ private:
|
||||||
boost::optional<std::string> font_directory_;
|
boost::optional<std::string> font_directory_;
|
||||||
freetype_engine::font_file_mapping_type font_file_mapping_;
|
freetype_engine::font_file_mapping_type font_file_mapping_;
|
||||||
freetype_engine::font_memory_cache_type font_memory_cache_;
|
freetype_engine::font_memory_cache_type font_memory_cache_;
|
||||||
|
thread_local static proj_cache_type proj_cache_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using const_style_iterator = std::map<std::string,feature_type_style>::const_iterator;
|
using const_style_iterator = std::map<std::string,feature_type_style>::const_iterator;
|
||||||
|
@ -126,7 +153,7 @@ public:
|
||||||
* @param height Initial map height.
|
* @param height Initial map height.
|
||||||
* @param srs Initial map projection.
|
* @param srs Initial map projection.
|
||||||
*/
|
*/
|
||||||
Map(int width, int height, std::string const& srs = MAPNIK_LONGLAT_PROJ);
|
Map(int width, int height, std::string const& srs = MAPNIK_GEOGRAPHIC_PROJ);
|
||||||
|
|
||||||
/*! \brief Copy Constructor.
|
/*! \brief Copy Constructor.
|
||||||
*
|
*
|
||||||
|
@ -503,9 +530,12 @@ public:
|
||||||
return font_memory_cache_;
|
return font_memory_cache_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proj_transform * get_proj_transform(std::string const& source, std::string const& dest) const;
|
||||||
private:
|
private:
|
||||||
friend void swap(Map & rhs, Map & lhs);
|
friend void swap(Map & rhs, Map & lhs);
|
||||||
void fixAspectRatio();
|
void fixAspectRatio();
|
||||||
|
void init_proj_transform(std::string const& source, std::string const& dest);
|
||||||
|
void init_proj_transforms();
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_ENUM(aspect_fix_mode_e,Map::aspect_fix_mode);
|
DEFINE_ENUM(aspect_fix_mode_e,Map::aspect_fix_mode);
|
||||||
|
|
|
@ -27,40 +27,37 @@
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/util/noncopyable.hpp>
|
#include <mapnik/util/noncopyable.hpp>
|
||||||
#include <mapnik/geometry/point.hpp>
|
#include <mapnik/geometry/point.hpp>
|
||||||
|
#include <mapnik/projection.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
class projection;
|
|
||||||
template <typename T> class box2d;
|
template <typename T> class box2d;
|
||||||
|
|
||||||
class MAPNIK_DECL proj_transform : private util::noncopyable
|
class MAPNIK_DECL proj_transform : private util::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
proj_transform(projection const& source,
|
proj_transform(projection const& source, projection const& dest);
|
||||||
projection const& dest);
|
~proj_transform();
|
||||||
|
|
||||||
bool equal() const;
|
bool equal() const;
|
||||||
bool is_known() const;
|
bool is_known() const;
|
||||||
bool forward (double& x, double& y , double& z) const;
|
bool forward (double& x, double& y , double& z) const;
|
||||||
bool backward (double& x, double& y , double& z) const;
|
bool backward (double& x, double& y , double& z) const;
|
||||||
bool forward (double *x, double *y , double *z, int point_count, int offset = 1) const;
|
bool forward (double *x, double *y , double *z, std::size_t point_count, std::size_t offset = 1) const;
|
||||||
bool backward (double *x, double *y , double *z, int point_count, int offset = 1) const;
|
bool backward (double *x, double *y , double *z, std::size_t point_count, std::size_t offset = 1) const;
|
||||||
bool forward (geometry::point<double> & p) const;
|
bool forward (geometry::point<double> & p) const;
|
||||||
bool backward (geometry::point<double> & p) const;
|
bool backward (geometry::point<double> & p) const;
|
||||||
unsigned int forward (std::vector<geometry::point<double>> & ls) const;
|
unsigned int forward (std::vector<geometry::point<double>> & ls) const;
|
||||||
unsigned int backward (std::vector<geometry::point<double>> & ls) const;
|
unsigned int backward (std::vector<geometry::point<double>> & ls) const;
|
||||||
bool forward (box2d<double> & box) const;
|
bool forward (box2d<double> & box) const;
|
||||||
bool backward (box2d<double> & box) const;
|
bool backward (box2d<double> & box) const;
|
||||||
bool forward (box2d<double> & box, int points) const;
|
bool forward (box2d<double> & box, std::size_t points) const;
|
||||||
bool backward (box2d<double> & box, int points) const;
|
bool backward (box2d<double> & box, std::size_t points) const;
|
||||||
mapnik::projection const& source() const;
|
std::string definition() const;
|
||||||
mapnik::projection const& dest() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
projection const& source_;
|
PJ_CONTEXT* ctx_ = nullptr;
|
||||||
projection const& dest_;
|
PJ* transform_ = nullptr;
|
||||||
bool is_source_longlat_;
|
bool is_source_longlat_;
|
||||||
bool is_dest_longlat_;
|
bool is_dest_longlat_;
|
||||||
bool is_source_equal_dest_;
|
bool is_source_equal_dest_;
|
||||||
|
|
|
@ -37,6 +37,18 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
|
// fwd decl
|
||||||
|
#if PROJ_VERSION >= 80000
|
||||||
|
struct pj_ctx;
|
||||||
|
using PJ_CONTEXT = struct pj_ctx;
|
||||||
|
#else
|
||||||
|
struct projCtx_t;
|
||||||
|
using PJ_CONTEXT = struct projCtx_t;
|
||||||
|
#endif
|
||||||
|
struct PJconsts;
|
||||||
|
using PJ = struct PJconsts;
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
class proj_init_error : public std::runtime_error
|
class proj_init_error : public std::runtime_error
|
||||||
|
@ -52,7 +64,7 @@ class MAPNIK_DECL projection
|
||||||
public:
|
public:
|
||||||
|
|
||||||
projection(std::string const& params,
|
projection(std::string const& params,
|
||||||
bool defer_proj_init = false);
|
bool defer_proj_init = false);
|
||||||
projection(projection const& rhs);
|
projection(projection const& rhs);
|
||||||
~projection();
|
~projection();
|
||||||
|
|
||||||
|
@ -66,7 +78,7 @@ public:
|
||||||
void forward(double & x, double & y) const;
|
void forward(double & x, double & y) const;
|
||||||
void inverse(double & x,double & y) const;
|
void inverse(double & x,double & y) const;
|
||||||
std::string expanded() const;
|
std::string expanded() const;
|
||||||
void init_proj4() const;
|
void init_proj() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void swap (projection& rhs);
|
void swap (projection& rhs);
|
||||||
|
@ -75,8 +87,8 @@ private:
|
||||||
std::string params_;
|
std::string params_;
|
||||||
bool defer_proj_init_;
|
bool defer_proj_init_;
|
||||||
mutable bool is_geographic_;
|
mutable bool is_geographic_;
|
||||||
mutable void * proj_;
|
mutable PJ * proj_;
|
||||||
mutable void * proj_ctx_;
|
mutable PJ_CONTEXT * proj_ctx_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename charT, typename traits>
|
template <typename charT, typename traits>
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
namespace mapnik { namespace util {
|
namespace mapnik { namespace util {
|
||||||
|
|
||||||
constexpr double pi = 3.1415926535897932384626433832795;
|
constexpr double pi = 3.14159265358979323846;
|
||||||
constexpr double tau = 6.283185307179586476925286766559;
|
constexpr double tau = 2.0 * pi;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr T const& clamp(T const& v, T const& lo, T const& hi)
|
constexpr T const& clamp(T const& v, T const& lo, T const& hi)
|
||||||
|
@ -38,12 +38,12 @@ constexpr T const& clamp(T const& v, T const& lo, T const& hi)
|
||||||
|
|
||||||
constexpr double degrees(double rad)
|
constexpr double degrees(double rad)
|
||||||
{
|
{
|
||||||
return rad * (360 / tau);
|
return rad * (180.0 / pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr double radians(double deg)
|
constexpr double radians(double deg)
|
||||||
{
|
{
|
||||||
return deg * (tau / 360);
|
return deg * (pi / 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
MAPNIK_DECL double normalize_angle(double angle);
|
MAPNIK_DECL double normalize_angle(double angle);
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace mapnik {
|
||||||
|
|
||||||
enum well_known_srs_enum : std::uint8_t {
|
enum well_known_srs_enum : std::uint8_t {
|
||||||
WGS_84,
|
WGS_84,
|
||||||
G_MERC,
|
WEB_MERC,
|
||||||
well_known_srs_enum_MAX
|
well_known_srs_enum_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ constexpr double MERC_MAX_EXTENT = EARTH_RADIUS * util::pi;
|
||||||
constexpr double MERC_MAX_LATITUDE = 85.0511287798065923778;
|
constexpr double MERC_MAX_LATITUDE = 85.0511287798065923778;
|
||||||
// MERC_MAX_LATITUDE = degrees(2 * atan(exp(pi)) - pi / 2)
|
// MERC_MAX_LATITUDE = degrees(2 * atan(exp(pi)) - pi / 2)
|
||||||
|
|
||||||
extern MAPNIK_DECL std::string const MAPNIK_LONGLAT_PROJ;
|
extern MAPNIK_DECL std::string const MAPNIK_GEOGRAPHIC_PROJ;
|
||||||
extern MAPNIK_DECL std::string const MAPNIK_GMERC_PROJ;
|
extern MAPNIK_DECL std::string const MAPNIK_WEBMERCATOR_PROJ;
|
||||||
|
|
||||||
MAPNIK_DECL boost::optional<bool> is_known_geographic(std::string const& srs);
|
MAPNIK_DECL boost::optional<bool> is_known_geographic(std::string const& srs);
|
||||||
MAPNIK_DECL boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs);
|
MAPNIK_DECL boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs);
|
||||||
|
|
|
@ -76,8 +76,9 @@ if '-DHAVE_PNG' in env['CPPDEFINES']:
|
||||||
lib_env['LIBS'].append('png')
|
lib_env['LIBS'].append('png')
|
||||||
enabled_imaging_libraries.append('png_reader.cpp')
|
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')
|
lib_env['LIBS'].append('proj')
|
||||||
|
lib_env['LIBS'].append('sqlite3')
|
||||||
|
|
||||||
if '-DHAVE_TIFF' in env['CPPDEFINES']:
|
if '-DHAVE_TIFF' in env['CPPDEFINES']:
|
||||||
lib_env['LIBS'].append('tiff')
|
lib_env['LIBS'].append('tiff')
|
||||||
|
|
72
src/map.cpp
72
src/map.cpp
|
@ -66,7 +66,7 @@ IMPLEMENT_ENUM( aspect_fix_mode_e, aspect_fix_mode_strings )
|
||||||
Map::Map()
|
Map::Map()
|
||||||
: width_(400),
|
: width_(400),
|
||||||
height_(400),
|
height_(400),
|
||||||
srs_(MAPNIK_LONGLAT_PROJ),
|
srs_(MAPNIK_GEOGRAPHIC_PROJ),
|
||||||
buffer_size_(0),
|
buffer_size_(0),
|
||||||
background_image_comp_op_(src_over),
|
background_image_comp_op_(src_over),
|
||||||
background_image_opacity_(1.0),
|
background_image_opacity_(1.0),
|
||||||
|
@ -110,8 +110,11 @@ Map::Map(Map const& rhs)
|
||||||
extra_params_(rhs.extra_params_),
|
extra_params_(rhs.extra_params_),
|
||||||
font_directory_(rhs.font_directory_),
|
font_directory_(rhs.font_directory_),
|
||||||
font_file_mapping_(rhs.font_file_mapping_),
|
font_file_mapping_(rhs.font_file_mapping_),
|
||||||
// on copy discard memory cache
|
// on copy discard memory caches
|
||||||
font_memory_cache_() {}
|
font_memory_cache_()
|
||||||
|
{
|
||||||
|
init_proj_transforms();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Map::Map(Map && rhs)
|
Map::Map(Map && rhs)
|
||||||
|
@ -137,9 +140,12 @@ Map::Map(Map && rhs)
|
||||||
|
|
||||||
Map::~Map() {}
|
Map::~Map() {}
|
||||||
|
|
||||||
|
thread_local Map::proj_cache_type Map::proj_cache_ = proj_cache_type();
|
||||||
|
|
||||||
Map& Map::operator=(Map rhs)
|
Map& Map::operator=(Map rhs)
|
||||||
{
|
{
|
||||||
swap(*this, rhs);
|
swap(*this, rhs);
|
||||||
|
init_proj_transforms();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +170,7 @@ void swap (Map & lhs, Map & rhs)
|
||||||
std::swap(lhs.extra_params_, rhs.extra_params_);
|
std::swap(lhs.extra_params_, rhs.extra_params_);
|
||||||
std::swap(lhs.font_directory_,rhs.font_directory_);
|
std::swap(lhs.font_directory_,rhs.font_directory_);
|
||||||
std::swap(lhs.font_file_mapping_,rhs.font_file_mapping_);
|
std::swap(lhs.font_file_mapping_,rhs.font_file_mapping_);
|
||||||
// on assignment discard memory cache
|
// on assignment discard memory caches
|
||||||
//std::swap(lhs.font_memory_cache_,rhs.font_memory_cache_);
|
//std::swap(lhs.font_memory_cache_,rhs.font_memory_cache_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,13 +327,30 @@ size_t Map::layer_count() const
|
||||||
return layers_.size();
|
return layers_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proj_transform * Map::get_proj_transform(std::string const& source, std::string const& dest) const
|
||||||
|
{
|
||||||
|
|
||||||
|
compatible_key_type key = std::make_pair<boost::string_view, boost::string_view>(source, dest);
|
||||||
|
auto itr = proj_cache_.find(key, compatible_hash{}, compatible_predicate{});
|
||||||
|
if (itr == proj_cache_.end())
|
||||||
|
{
|
||||||
|
mapnik::projection srs1(source, true);
|
||||||
|
mapnik::projection srs2(dest, true);
|
||||||
|
return proj_cache_.emplace(std::make_pair(source, dest),
|
||||||
|
std::make_unique<proj_transform>(srs1, srs2)).first->second.get();
|
||||||
|
}
|
||||||
|
return itr->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
void Map::add_layer(layer const& l)
|
void Map::add_layer(layer const& l)
|
||||||
{
|
{
|
||||||
|
init_proj_transform(srs_, l.srs());
|
||||||
layers_.emplace_back(l);
|
layers_.emplace_back(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::add_layer(layer && l)
|
void Map::add_layer(layer && l)
|
||||||
{
|
{
|
||||||
|
init_proj_transform(srs_, l.srs());
|
||||||
layers_.push_back(std::move(l));
|
layers_.push_back(std::move(l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +366,7 @@ void Map::remove_all()
|
||||||
fontsets_.clear();
|
fontsets_.clear();
|
||||||
font_file_mapping_.clear();
|
font_file_mapping_.clear();
|
||||||
font_memory_cache_.clear();
|
font_memory_cache_.clear();
|
||||||
|
proj_cache_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
layer const& Map::get_layer(size_t index) const
|
layer const& Map::get_layer(size_t index) const
|
||||||
|
@ -419,7 +443,9 @@ std::string const& Map::srs() const
|
||||||
|
|
||||||
void Map::set_srs(std::string const& _srs)
|
void Map::set_srs(std::string const& _srs)
|
||||||
{
|
{
|
||||||
|
if (srs_ != _srs) init_proj_transforms();
|
||||||
srs_ = _srs;
|
srs_ = _srs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::set_buffer_size(int _buffer_size)
|
void Map::set_buffer_size(int _buffer_size)
|
||||||
|
@ -517,7 +543,6 @@ void Map::zoom_all()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
projection proj0(srs_);
|
|
||||||
box2d<double> ext;
|
box2d<double> ext;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
@ -526,10 +551,9 @@ void Map::zoom_all()
|
||||||
if (layer.active())
|
if (layer.active())
|
||||||
{
|
{
|
||||||
std::string const& layer_srs = layer.srs();
|
std::string const& layer_srs = layer.srs();
|
||||||
projection proj1(layer_srs);
|
proj_transform * proj_trans_ptr = get_proj_transform(srs_, layer_srs);;
|
||||||
proj_transform prj_trans(proj0,proj1);
|
|
||||||
box2d<double> layer_ext = layer.envelope();
|
box2d<double> layer_ext = layer.envelope();
|
||||||
if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS))
|
if (proj_trans_ptr->backward(layer_ext, PROJ_ENVELOPE_POINTS))
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
MAPNIK_LOG_DEBUG(map) << "map: Layer " << layer.name() << " original ext=" << layer.envelope();
|
MAPNIK_LOG_DEBUG(map) << "map: Layer " << layer.name() << " original ext=" << layer.envelope();
|
||||||
|
@ -707,11 +731,9 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const
|
||||||
mapnik::datasource_ptr ds = layer.datasource();
|
mapnik::datasource_ptr ds = layer.datasource();
|
||||||
if (ds)
|
if (ds)
|
||||||
{
|
{
|
||||||
mapnik::projection dest(srs_);
|
proj_transform * proj_trans_ptr = get_proj_transform(layer.srs(), srs_);
|
||||||
mapnik::projection source(layer.srs());
|
|
||||||
proj_transform prj_trans(source,dest);
|
|
||||||
double z = 0;
|
double z = 0;
|
||||||
if (!prj_trans.equal() && !prj_trans.backward(x,y,z))
|
if (!proj_trans_ptr->equal() && !proj_trans_ptr->backward(x,y,z))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("query_point: could not project x,y into layer srs");
|
throw std::runtime_error("query_point: could not project x,y into layer srs");
|
||||||
}
|
}
|
||||||
|
@ -721,7 +743,7 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const
|
||||||
{
|
{
|
||||||
map_ex.clip(*maximum_extent_);
|
map_ex.clip(*maximum_extent_);
|
||||||
}
|
}
|
||||||
if (!prj_trans.backward(map_ex,PROJ_ENVELOPE_POINTS))
|
if (!proj_trans_ptr->backward(map_ex,PROJ_ENVELOPE_POINTS))
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "query_point: could not project map extent '" << map_ex
|
s << "query_point: could not project map extent '" << map_ex
|
||||||
|
@ -772,4 +794,28 @@ void Map::set_extra_parameters(parameters& params)
|
||||||
extra_params_ = params;
|
extra_params_ = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Map::init_proj_transform(std::string const& source, std::string const& dest)
|
||||||
|
{
|
||||||
|
compatible_key_type key = std::make_pair<boost::string_view, boost::string_view>(source, dest);
|
||||||
|
auto itr = proj_cache_.find(key, compatible_hash{}, compatible_predicate{});
|
||||||
|
if (itr == proj_cache_.end())
|
||||||
|
{
|
||||||
|
mapnik::projection p0(source, true);
|
||||||
|
mapnik::projection p1(dest, true);
|
||||||
|
proj_cache_.emplace(std::make_pair(source, dest),
|
||||||
|
std::make_unique<proj_transform>(p0, p1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::init_proj_transforms()
|
||||||
|
{
|
||||||
|
std::for_each(layers_.begin(),
|
||||||
|
layers_.end(),
|
||||||
|
[this] (auto const& l)
|
||||||
|
{
|
||||||
|
init_proj_transform(srs_, l.srs());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
#include <mapnik/proj_transform.hpp>
|
#include <mapnik/proj_transform.hpp>
|
||||||
#include <mapnik/coord.hpp>
|
#include <mapnik/coord.hpp>
|
||||||
#include <mapnik/util/is_clockwise.hpp>
|
#include <mapnik/util/is_clockwise.hpp>
|
||||||
|
#include <mapnik/util/trim.hpp>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/geometry/algorithms/envelope.hpp>
|
#include <boost/geometry/algorithms/envelope.hpp>
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
// proj4
|
// proj
|
||||||
#include <proj_api.h>
|
#include <proj.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
|
@ -95,30 +95,28 @@ auto envelope_points(box2d<T> const& env, std::size_t num_points)
|
||||||
|
|
||||||
proj_transform::proj_transform(projection const& source,
|
proj_transform::proj_transform(projection const& source,
|
||||||
projection const& dest)
|
projection const& dest)
|
||||||
: source_(source),
|
: is_source_longlat_(false),
|
||||||
dest_(dest),
|
|
||||||
is_source_longlat_(false),
|
|
||||||
is_dest_longlat_(false),
|
is_dest_longlat_(false),
|
||||||
is_source_equal_dest_(false),
|
is_source_equal_dest_(false),
|
||||||
wgs84_to_merc_(false),
|
wgs84_to_merc_(false),
|
||||||
merc_to_wgs84_(false)
|
merc_to_wgs84_(false)
|
||||||
{
|
{
|
||||||
is_source_equal_dest_ = (source_ == dest_);
|
is_source_equal_dest_ = (source == dest);
|
||||||
if (!is_source_equal_dest_)
|
if (!is_source_equal_dest_)
|
||||||
{
|
{
|
||||||
is_source_longlat_ = source_.is_geographic();
|
is_source_longlat_ = source.is_geographic();
|
||||||
is_dest_longlat_ = dest_.is_geographic();
|
is_dest_longlat_ = dest.is_geographic();
|
||||||
boost::optional<well_known_srs_e> src_k = source.well_known();
|
boost::optional<well_known_srs_e> src_k = source.well_known();
|
||||||
boost::optional<well_known_srs_e> dest_k = dest.well_known();
|
boost::optional<well_known_srs_e> dest_k = dest.well_known();
|
||||||
bool known_trans = false;
|
bool known_trans = false;
|
||||||
if (src_k && dest_k)
|
if (src_k && dest_k)
|
||||||
{
|
{
|
||||||
if (*src_k == WGS_84 && *dest_k == G_MERC)
|
if (*src_k == WGS_84 && *dest_k == WEB_MERC)
|
||||||
{
|
{
|
||||||
wgs84_to_merc_ = true;
|
wgs84_to_merc_ = true;
|
||||||
known_trans = true;
|
known_trans = true;
|
||||||
}
|
}
|
||||||
else if (*src_k == G_MERC && *dest_k == WGS_84)
|
else if (*src_k == WEB_MERC && *dest_k == WGS_84)
|
||||||
{
|
{
|
||||||
merc_to_wgs84_ = true;
|
merc_to_wgs84_ = true;
|
||||||
known_trans = true;
|
known_trans = true;
|
||||||
|
@ -126,16 +124,45 @@ proj_transform::proj_transform(projection const& source,
|
||||||
}
|
}
|
||||||
if (!known_trans)
|
if (!known_trans)
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
source_.init_proj4();
|
ctx_ = proj_context_create();
|
||||||
dest_.init_proj4();
|
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: '") + 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: '") + source.params() + "'->'" + dest.params() + "'");
|
||||||
|
}
|
||||||
|
proj_destroy(transform_);
|
||||||
|
transform_ = transform_gis;
|
||||||
#else
|
#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 proj support (-DMAPNIK_USE_PROJ): '") + source.params() + "'->'" + dest.params() + "'");
|
||||||
#endif
|
#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
|
bool proj_transform::equal() const
|
||||||
{
|
{
|
||||||
return is_source_equal_dest_;
|
return is_source_equal_dest_;
|
||||||
|
@ -187,9 +214,8 @@ unsigned int proj_transform::forward (std::vector<geometry::point<double>> & ls)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool proj_transform::forward (double * x, double * y , double * z, int point_count, int offset) const
|
bool proj_transform::forward (double * x, double * y , double * z, std::size_t point_count, std::size_t offset) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if (is_source_equal_dest_)
|
if (is_source_equal_dest_)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -202,42 +228,19 @@ bool proj_transform::forward (double * x, double * y , double * z, int point_cou
|
||||||
return merc2lonlat(x, y, point_count, offset);
|
return merc2lonlat(x, y, point_count, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (is_source_longlat_)
|
if (proj_trans_generic(transform_, PJ_FWD,
|
||||||
{
|
x, offset * sizeof(double), point_count,
|
||||||
int i;
|
y, offset * sizeof(double), point_count,
|
||||||
for(i=0; i<point_count; i++) {
|
z, offset * sizeof(double), point_count,
|
||||||
x[i*offset] *= DEG_TO_RAD;
|
0, 0, 0) != point_count)
|
||||||
y[i*offset] *= DEG_TO_RAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pj_transform( source_.proj_, dest_.proj_, point_count,
|
|
||||||
offset, x,y,z) != 0)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
for(int j=0; j<point_count; j++) {
|
|
||||||
if (x[j] == HUGE_VAL || y[j] == HUGE_VAL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dest_longlat_)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=0; i<point_count; i++) {
|
|
||||||
x[i*offset] *= RAD_TO_DEG;
|
|
||||||
y[i*offset] *= RAD_TO_DEG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool proj_transform::backward (double * x, double * y , double * z, int point_count, int offset) const
|
bool proj_transform::backward (double * x, double * y , double * z, std::size_t point_count, std::size_t offset) const
|
||||||
{
|
{
|
||||||
if (is_source_equal_dest_)
|
if (is_source_equal_dest_)
|
||||||
return true;
|
return true;
|
||||||
|
@ -251,38 +254,13 @@ bool proj_transform::backward (double * x, double * y , double * z, int point_co
|
||||||
return lonlat2merc(x, y, point_count, offset);
|
return lonlat2merc(x, y, point_count, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (is_dest_longlat_)
|
if (proj_trans_generic(transform_, PJ_INV,
|
||||||
{
|
x, offset * sizeof(double), point_count,
|
||||||
for (int i = 0; i < point_count; ++i)
|
y, offset * sizeof(double), point_count,
|
||||||
{
|
z, offset * sizeof(double), point_count,
|
||||||
x[i * offset] *= DEG_TO_RAD;
|
0, 0, 0) != point_count)
|
||||||
y[i * offset] *= DEG_TO_RAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pj_transform(dest_.proj_, source_.proj_, point_count,
|
|
||||||
offset, x, y, z) != 0)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < point_count; ++j)
|
|
||||||
{
|
|
||||||
if (x[j] == HUGE_VAL || y[j] == HUGE_VAL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_source_longlat_)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < point_count; ++i)
|
|
||||||
{
|
|
||||||
x[i * offset] *= RAD_TO_DEG;
|
|
||||||
y[i * offset] *= RAD_TO_DEG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +372,7 @@ bool proj_transform::backward (box2d<double> & box) const
|
||||||
// Alternative is to provide proper clipping box
|
// Alternative is to provide proper clipping box
|
||||||
// in the target srs by setting map 'maximum-extent'
|
// in the target srs by setting map 'maximum-extent'
|
||||||
|
|
||||||
bool proj_transform::backward(box2d<double>& env, int points) const
|
bool proj_transform::backward(box2d<double>& env, std::size_t points) const
|
||||||
{
|
{
|
||||||
if (is_source_equal_dest_)
|
if (is_source_equal_dest_)
|
||||||
return true;
|
return true;
|
||||||
|
@ -433,7 +411,7 @@ bool proj_transform::backward(box2d<double>& env, int points) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool proj_transform::forward(box2d<double>& env, int points) const
|
bool proj_transform::forward(box2d<double>& env, std::size_t points) const
|
||||||
{
|
{
|
||||||
if (is_source_equal_dest_)
|
if (is_source_equal_dest_)
|
||||||
return true;
|
return true;
|
||||||
|
@ -473,13 +451,25 @@ bool proj_transform::forward(box2d<double>& env, int points) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::projection const& proj_transform::source() const
|
std::string proj_transform::definition() const
|
||||||
{
|
{
|
||||||
return source_;
|
#ifdef MAPNIK_USE_PROJ
|
||||||
}
|
if (transform_)
|
||||||
mapnik::projection const& proj_transform::dest() const
|
{
|
||||||
{
|
PJ_PROJ_INFO info = proj_pj_info(transform_);
|
||||||
return dest_;
|
return mapnik::util::trim_copy(info.definition);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (wgs84_to_merc_)
|
||||||
|
{
|
||||||
|
return "wgs84 => merc";
|
||||||
|
}
|
||||||
|
else if (merc_to_wgs84_)
|
||||||
|
{
|
||||||
|
return "merc => wgs84";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,23 +28,14 @@
|
||||||
// stl
|
// stl
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
// proj4
|
// proj
|
||||||
#include <proj_api.h>
|
#include <proj.h>
|
||||||
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
|
#include <cmath> // HUGE_VAL
|
||||||
#include <mutex>
|
|
||||||
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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
|
||||||
projection::projection(std::string const& params, bool defer_proj_init)
|
projection::projection(std::string const& params, bool defer_proj_init)
|
||||||
: params_(params),
|
: params_(params),
|
||||||
defer_proj_init_(defer_proj_init),
|
defer_proj_init_(defer_proj_init),
|
||||||
|
@ -58,13 +49,13 @@ projection::projection(std::string const& params, bool defer_proj_init)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
init_proj4();
|
init_proj();
|
||||||
#else
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
if (!defer_proj_init_) init_proj4();
|
if (!defer_proj_init_) init_proj();
|
||||||
}
|
}
|
||||||
|
|
||||||
projection::projection(projection const& rhs)
|
projection::projection(projection const& rhs)
|
||||||
|
@ -74,7 +65,7 @@ projection::projection(projection const& rhs)
|
||||||
proj_(nullptr),
|
proj_(nullptr),
|
||||||
proj_ctx_(nullptr)
|
proj_ctx_(nullptr)
|
||||||
{
|
{
|
||||||
if (!defer_proj_init_) init_proj4();
|
if (!defer_proj_init_) init_proj();
|
||||||
}
|
}
|
||||||
|
|
||||||
projection& projection::operator=(projection const& rhs)
|
projection& projection::operator=(projection const& rhs)
|
||||||
|
@ -83,7 +74,7 @@ projection& projection::operator=(projection const& rhs)
|
||||||
swap(tmp);
|
swap(tmp);
|
||||||
proj_ctx_ = nullptr;
|
proj_ctx_ = nullptr;
|
||||||
proj_ = nullptr;
|
proj_ = nullptr;
|
||||||
if (!defer_proj_init_) init_proj4();
|
if (!defer_proj_init_) init_proj();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,34 +88,29 @@ bool projection::operator!=(const projection& other) const
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void projection::init_proj4() const
|
void projection::init_proj() const
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (!proj_)
|
if (!proj_)
|
||||||
{
|
{
|
||||||
#if PJ_VERSION >= 480
|
proj_ctx_ = proj_context_create();
|
||||||
proj_ctx_ = pj_ctx_alloc();
|
proj_ = proj_create(proj_ctx_, params_.c_str());
|
||||||
proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str());
|
|
||||||
if (!proj_ || !proj_ctx_)
|
if (!proj_ || !proj_ctx_)
|
||||||
{
|
{
|
||||||
if (proj_ctx_) {
|
if (proj_ctx_) {
|
||||||
pj_ctx_free(proj_ctx_);
|
proj_context_destroy(proj_ctx_);
|
||||||
proj_ctx_ = nullptr;
|
proj_ctx_ = nullptr;
|
||||||
}
|
}
|
||||||
if (proj_) {
|
if (proj_) {
|
||||||
pj_free(proj_);
|
proj_destroy(proj_);
|
||||||
proj_ = nullptr;
|
proj_ = nullptr;
|
||||||
}
|
}
|
||||||
throw proj_init_error(params_);
|
throw proj_init_error(params_);
|
||||||
}
|
}
|
||||||
#else
|
PJ_TYPE type = proj_get_type(proj_);
|
||||||
#if defined(MAPNIK_THREADSAFE)
|
is_geographic_ = (type == PJ_TYPE_GEOGRAPHIC_2D_CRS
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
||
|
||||||
#endif
|
type == PJ_TYPE_GEOGRAPHIC_3D_CRS) ? true : false;
|
||||||
proj_ = pj_init_plus(params_.c_str());
|
|
||||||
if (!proj_) throw proj_init_error(params_);
|
|
||||||
#endif
|
|
||||||
is_geographic_ = pj_is_latlong(proj_) ? true : false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -151,82 +137,68 @@ std::string const& projection::params() const
|
||||||
|
|
||||||
void projection::forward(double & x, double &y ) const
|
void projection::forward(double & x, double &y ) const
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (!proj_)
|
if (!proj_)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("projection::forward 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<std::mutex> 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;
|
|
||||||
}
|
}
|
||||||
|
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
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void projection::inverse(double & x,double & y) const
|
void projection::inverse(double & x,double & y) const
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (!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");
|
||||||
}
|
}
|
||||||
|
PJ_COORD coord;
|
||||||
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
|
coord.xyzt.z = 0.0;
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
coord.xyzt.t = HUGE_VAL;
|
||||||
#endif
|
coord.xyzt.x = x;
|
||||||
if (is_geographic_)
|
coord.xyzt.y = y;
|
||||||
{
|
PJ_COORD coord_out = proj_trans(proj_, PJ_INV, coord);
|
||||||
x *=DEG_TO_RAD;
|
x = coord_out.xy.x;
|
||||||
y *=DEG_TO_RAD;
|
y = coord_out.xy.y;
|
||||||
}
|
|
||||||
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;
|
|
||||||
#else
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
projection::~projection()
|
projection::~projection()
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
|
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
|
||||||
#endif
|
|
||||||
if (proj_)
|
if (proj_)
|
||||||
{
|
{
|
||||||
pj_free(proj_);
|
proj_destroy(proj_);
|
||||||
proj_ = nullptr;
|
proj_ = nullptr;
|
||||||
}
|
}
|
||||||
#if PJ_VERSION >= 480
|
|
||||||
if (proj_ctx_)
|
if (proj_ctx_)
|
||||||
{
|
{
|
||||||
pj_ctx_free(proj_ctx_);
|
proj_context_destroy(proj_ctx_);
|
||||||
proj_ctx_ = nullptr;
|
proj_ctx_ = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string projection::expanded() const
|
std::string projection::expanded() const
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
if (proj_) return mapnik::util::trim_copy(pj_get_def( proj_, 0 ));
|
if (proj_)
|
||||||
|
{
|
||||||
|
PJ_PROJ_INFO info = proj_pj_info(proj_);
|
||||||
|
return mapnik::util::trim_copy(info.definition);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return params_;
|
return params_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,10 +326,9 @@ void base_symbolizer_helper::initialize_points() const
|
||||||
else if (type == geometry::geometry_types::Polygon)
|
else if (type == geometry::geometry_types::Polygon)
|
||||||
{
|
{
|
||||||
auto const& poly = util::get<geometry::polygon<double>>(geom);
|
auto const& poly = util::get<geometry::polygon<double>>(geom);
|
||||||
proj_transform backwart_transform(prj_trans_.dest(), prj_trans_.source());
|
|
||||||
view_strategy vs(t_);
|
view_strategy vs(t_);
|
||||||
proj_strategy ps(backwart_transform);
|
proj_backward_strategy ps(prj_trans_);
|
||||||
using transform_group_type = geometry::strategy_group<proj_strategy, view_strategy>;
|
using transform_group_type = geometry::strategy_group<proj_backward_strategy, view_strategy>;
|
||||||
transform_group_type transform_group(ps, vs);
|
transform_group_type transform_group(ps, vs);
|
||||||
geometry::polygon<double> tranformed_poly(geometry::transform<double>(poly, transform_group));
|
geometry::polygon<double> tranformed_poly(geometry::transform<double>(poly, transform_group));
|
||||||
if (how_placed == INTERIOR_PLACEMENT)
|
if (how_placed == INTERIOR_PLACEMENT)
|
||||||
|
|
|
@ -36,28 +36,27 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
extern std::string const MAPNIK_LONGLAT_PROJ =
|
extern std::string const MAPNIK_GEOGRAPHIC_PROJ =
|
||||||
"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
|
"epsg:4326"; //wgs84
|
||||||
|
|
||||||
extern std::string const MAPNIK_GMERC_PROJ =
|
extern std::string const MAPNIK_WEBMERCATOR_PROJ =
|
||||||
"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0"
|
"epsg:3857"; // webmercator
|
||||||
" +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over";
|
|
||||||
|
|
||||||
static const char * well_known_srs_strings[] = {
|
static const char * well_known_srs_strings[] = {
|
||||||
"mapnik-longlat",
|
MAPNIK_GEOGRAPHIC_PROJ.c_str(),
|
||||||
"mapnik-gmerc",
|
MAPNIK_WEBMERCATOR_PROJ.c_str(),
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs)
|
boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs)
|
||||||
{
|
{
|
||||||
if (srs == "+init=epsg:4326" || srs == MAPNIK_LONGLAT_PROJ)
|
if (srs == MAPNIK_GEOGRAPHIC_PROJ)
|
||||||
{
|
{
|
||||||
return boost::optional<well_known_srs_e>(mapnik::WGS_84);
|
return boost::optional<well_known_srs_e>(mapnik::WGS_84);
|
||||||
}
|
}
|
||||||
else if (srs == "+init=epsg:3857" || srs == MAPNIK_GMERC_PROJ)
|
else if (srs == MAPNIK_WEBMERCATOR_PROJ)
|
||||||
{
|
{
|
||||||
return boost::optional<well_known_srs_e>(mapnik::G_MERC);
|
return boost::optional<well_known_srs_e>(mapnik::WEB_MERC);
|
||||||
}
|
}
|
||||||
return boost::optional<well_known_srs_e>();
|
return boost::optional<well_known_srs_e>();
|
||||||
}
|
}
|
||||||
|
@ -65,28 +64,13 @@ boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs)
|
||||||
boost::optional<bool> is_known_geographic(std::string const& srs)
|
boost::optional<bool> is_known_geographic(std::string const& srs)
|
||||||
{
|
{
|
||||||
std::string trimmed = util::trim_copy(srs);
|
std::string trimmed = util::trim_copy(srs);
|
||||||
if (trimmed == "+init=epsg:3857")
|
if (trimmed == MAPNIK_GEOGRAPHIC_PROJ)
|
||||||
{
|
|
||||||
return boost::optional<bool>(false);
|
|
||||||
}
|
|
||||||
else if (trimmed == "+init=epsg:4326")
|
|
||||||
{
|
{
|
||||||
return boost::optional<bool>(true);
|
return boost::optional<bool>(true);
|
||||||
}
|
}
|
||||||
else if (srs.find("+proj=") != std::string::npos)
|
else if (trimmed == MAPNIK_WEBMERCATOR_PROJ)
|
||||||
{
|
{
|
||||||
if ((srs.find("+proj=longlat") != std::string::npos) ||
|
return boost::optional<bool>(false);
|
||||||
(srs.find("+proj=latlong") != std::string::npos) ||
|
|
||||||
(srs.find("+proj=lonlat") != std::string::npos) ||
|
|
||||||
(srs.find("+proj=latlon") != std::string::npos)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return boost::optional<bool>(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return boost::optional<bool>(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return boost::optional<bool>();
|
return boost::optional<bool>();
|
||||||
}
|
}
|
||||||
|
@ -99,7 +83,7 @@ bool lonlat2merc(double & x, double & y)
|
||||||
auto dx = clamp(x, -180.0, 180.0);
|
auto dx = clamp(x, -180.0, 180.0);
|
||||||
auto dy = clamp(y, -MERC_MAX_LATITUDE, MERC_MAX_LATITUDE);
|
auto dy = clamp(y, -MERC_MAX_LATITUDE, MERC_MAX_LATITUDE);
|
||||||
x = EARTH_RADIUS * radians(dx);
|
x = EARTH_RADIUS * radians(dx);
|
||||||
y = EARTH_RADIUS * std::log(std::tan(radians(90 + dy) / 2));
|
y = EARTH_RADIUS * std::log(std::tan(radians(90.0 + dy) / 2.0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +111,7 @@ bool merc2lonlat(double & x, double & y)
|
||||||
auto rx = clamp(x / EARTH_RADIUS, -pi, pi);
|
auto rx = clamp(x / EARTH_RADIUS, -pi, pi);
|
||||||
auto ry = clamp(y / EARTH_RADIUS, -pi, pi);
|
auto ry = clamp(y / EARTH_RADIUS, -pi, pi);
|
||||||
x = degrees(rx);
|
x = degrees(rx);
|
||||||
y = degrees(2 * std::atan(std::exp(ry)) - pi / 2);
|
y = degrees(2.0 * std::atan(std::exp(ry)) - pi / 2.0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,6 @@ MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <unicode/uclean.h>
|
#include <unicode/uclean.h>
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
|
||||||
#include <proj_api.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
|
@ -47,15 +44,6 @@ inline void run_cleanup()
|
||||||
|
|
||||||
// http://icu-project.org/apiref/icu4c/uclean_8h.html#a93f27d0ddc7c196a1da864763f2d8920
|
// http://icu-project.org/apiref/icu4c/uclean_8h.html#a93f27d0ddc7c196a1da864763f2d8920
|
||||||
u_cleanup();
|
u_cleanup();
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
|
||||||
// http://trac.osgeo.org/proj/ticket/149
|
|
||||||
#if PJ_VERSION >= 480
|
|
||||||
pj_clear_initcache();
|
|
||||||
#endif
|
|
||||||
// https://trac.osgeo.org/proj/wiki/ProjAPI#EnvironmentFunctions
|
|
||||||
pj_deallocate_grids();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c67cf11850d65e963e6103b6141f1eca67667aa2
|
Subproject commit dd0c41c3f9f5dc98291a727af00bb42734d2a8c0
|
|
@ -1 +1 @@
|
||||||
Subproject commit bacfd251da550fa82ea56f6710dc6f85431480c2
|
Subproject commit 1f20cf257f35224d3c139a6015b1cf70814b0d24
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -25,7 +24,7 @@ TEST_CASE("exceptions") {
|
||||||
|
|
||||||
SECTION("handling") {
|
SECTION("handling") {
|
||||||
try {
|
try {
|
||||||
mapnik::projection srs("foo");
|
mapnik::projection srs("FAIL");
|
||||||
// to avoid unused variable warning
|
// to avoid unused variable warning
|
||||||
srs.params();
|
srs.params();
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
|
@ -35,11 +34,11 @@ SECTION("handling") {
|
||||||
|
|
||||||
// https://github.com/mapnik/mapnik/issues/2170
|
// https://github.com/mapnik/mapnik/issues/2170
|
||||||
try {
|
try {
|
||||||
mapnik::projection srs("+proj=longlat foo",true);
|
mapnik::projection srs("epsg:4326 foo",true);
|
||||||
REQUIRE(srs.is_geographic());
|
REQUIRE(srs.is_geographic());
|
||||||
REQUIRE(true);
|
REQUIRE(true);
|
||||||
srs.init_proj4();
|
srs.init_proj();
|
||||||
// oddly init_proj4 does not throw with old proj/ubuntu precise
|
// oddly init_proj does not throw with old proj/ubuntu precise
|
||||||
//REQUIRE(false);
|
//REQUIRE(false);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
REQUIRE(true);
|
REQUIRE(true);
|
||||||
|
|
|
@ -128,7 +128,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto const& p : zip_crange(ls1, ls2))
|
for (auto const p : zip_crange(ls1, ls2))
|
||||||
{
|
{
|
||||||
REQUIRE(p.template get<0>().x == Approx(p.template get<1>().x));
|
REQUIRE(p.template get<0>().x == Approx(p.template get<1>().x));
|
||||||
REQUIRE(p.template get<0>().y == Approx(p.template get<1>().y));
|
REQUIRE(p.template get<0>().y == Approx(p.template get<1>().y));
|
||||||
|
@ -143,7 +143,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& p : zip_crange(p1, p2))
|
for (auto const p : zip_crange(p1, p2))
|
||||||
{
|
{
|
||||||
(*this)(static_cast<std::vector<point<T>> const&>(p.template get<0>()),
|
(*this)(static_cast<std::vector<point<T>> const&>(p.template get<0>()),
|
||||||
static_cast<std::vector<point<T>> const&>(p.template get<1>()));
|
static_cast<std::vector<point<T>> const&>(p.template get<1>()));
|
||||||
|
@ -173,7 +173,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& ls : zip_crange(mls1, mls2))
|
for (auto const ls : zip_crange(mls1, mls2))
|
||||||
{
|
{
|
||||||
(*this)(ls.template get<0>(),ls.template get<1>());
|
(*this)(ls.template get<0>(),ls.template get<1>());
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& poly : zip_crange(mpoly1, mpoly2))
|
for (auto const poly : zip_crange(mpoly1, mpoly2))
|
||||||
{
|
{
|
||||||
(*this)(poly.template get<0>(),poly.template get<1>());
|
(*this)(poly.template get<0>(),poly.template get<1>());
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& g : zip_crange(c1, c2))
|
for (auto const g : zip_crange(c1, c2))
|
||||||
{
|
{
|
||||||
assert_g_equal(g.template get<0>(),g.template get<1>());
|
assert_g_equal(g.template get<0>(),g.template get<1>());
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ struct geometry_equal_visitor
|
||||||
REQUIRE(false);
|
REQUIRE(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& g : zip_crange(c1, c2))
|
for (auto const g : zip_crange(c1, c2))
|
||||||
{
|
{
|
||||||
assert_g_equal(g.template get<0>(),g.template get<1>());
|
assert_g_equal(g.template get<0>(),g.template get<1>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ TEST_CASE("geometry reprojection") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Empty Geometry Object") {
|
SECTION("test_projection_4326_3857 - Empty Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans(source, dest);
|
mapnik::proj_transform proj_trans(source, dest);
|
||||||
{
|
{
|
||||||
geometry_empty geom;
|
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") {
|
SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans(source, dest);
|
mapnik::proj_transform proj_trans(source, dest);
|
||||||
{
|
{
|
||||||
geometry<double> geom = geometry_empty();
|
geometry<double> 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") {
|
SECTION("test_projection_4326_3857 - Point Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
point<double> geom1(-97.552175, 35.522895);
|
point<double> 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") {
|
SECTION("test_projection_4326_3857 - Point Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
double x1 = -97.552175;
|
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") {
|
SECTION("test_projection_4326_3857 - Line_String Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
line_string<double> geom1;
|
line_string<double> geom1;
|
||||||
|
@ -241,8 +241,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") {
|
SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
line_string<double> geom1_;
|
line_string<double> geom1_;
|
||||||
|
@ -316,8 +316,8 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
|
SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1;
|
polygon<double> geom1;
|
||||||
|
@ -411,8 +411,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") {
|
SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1_;
|
polygon<double> geom1_;
|
||||||
|
@ -503,8 +503,8 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") {
|
SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
multi_point<double> geom1;
|
multi_point<double> geom1;
|
||||||
|
@ -568,8 +568,8 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") {
|
SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
multi_point<double> geom1_;
|
multi_point<double> 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") {
|
SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
line_string<double> geom1a;
|
line_string<double> 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") {
|
SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
line_string<double> geom1a_;
|
line_string<double> 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") {
|
SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1a;
|
polygon<double> geom1a;
|
||||||
|
@ -898,8 +898,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") {
|
SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1a_;
|
polygon<double> geom1a_;
|
||||||
|
@ -993,8 +993,8 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Geometry Collection Object") {
|
SECTION("test_projection_4326_3857 - Geometry Collection Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1a;
|
polygon<double> geom1a;
|
||||||
|
@ -1092,8 +1092,8 @@ SECTION("test_projection_4326_3857 - Geometry Collection Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") {
|
SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
polygon<double> geom1a_;
|
polygon<double> geom1a_;
|
||||||
|
@ -1185,11 +1185,11 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") {
|
||||||
}
|
}
|
||||||
} // END SECTION
|
} // END SECTION
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
SECTION("test_projection_4269_3857 - Line_String Geometry Object") {
|
SECTION("test_projection_4269_3857 - Line_String Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4269");
|
mapnik::projection source("epsg:4269");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
line_string<double> geom1;
|
line_string<double> geom1;
|
||||||
|
@ -1254,8 +1254,8 @@ SECTION("test_projection_4269_3857 - Line_String Geometry Object") {
|
||||||
|
|
||||||
SECTION("test_projection_4269_3857 - Point Geometry Object") {
|
SECTION("test_projection_4269_3857 - Point Geometry Object") {
|
||||||
using namespace mapnik::geometry;
|
using namespace mapnik::geometry;
|
||||||
mapnik::projection source("+init=epsg:4269");
|
mapnik::projection source("epsg:4269");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans1(source, dest);
|
mapnik::proj_transform proj_trans1(source, dest);
|
||||||
mapnik::proj_transform proj_trans2(dest, source);
|
mapnik::proj_transform proj_trans2(dest, source);
|
||||||
point<double> geom1(-97.552175, 35.522895);
|
point<double> geom1(-97.552175, 35.522895);
|
||||||
|
@ -1305,6 +1305,6 @@ SECTION("test_projection_4269_3857 - Point Geometry Object") {
|
||||||
}
|
}
|
||||||
} // End Section
|
} // End Section
|
||||||
|
|
||||||
#endif // MAPNIK_USE_PROJ4
|
#endif // MAPNIK_USE_PROJ
|
||||||
|
|
||||||
} // End Testcase
|
} // End Testcase
|
||||||
|
|
|
@ -18,8 +18,8 @@ SECTION("proj and view strategy") {
|
||||||
mapnik::view_transform vt(256, 256, e);
|
mapnik::view_transform vt(256, 256, e);
|
||||||
mapnik::view_strategy vs(vt);
|
mapnik::view_strategy vs(vt);
|
||||||
mapnik::unview_strategy uvs(vt);
|
mapnik::unview_strategy uvs(vt);
|
||||||
mapnik::projection source("+init=epsg:4326");
|
mapnik::projection source("epsg:4326");
|
||||||
mapnik::projection dest("+init=epsg:3857");
|
mapnik::projection dest("epsg:3857");
|
||||||
mapnik::proj_transform proj_trans(source, dest);
|
mapnik::proj_transform proj_trans(source, dest);
|
||||||
mapnik::proj_transform proj_trans_rev(dest, source);
|
mapnik::proj_transform proj_trans_rev(dest, source);
|
||||||
mapnik::proj_strategy ps(proj_trans);
|
mapnik::proj_strategy ps(proj_trans);
|
||||||
|
|
|
@ -1,3 +1,24 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
@ -63,4 +84,3 @@ SECTION("set background - cairo") {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
60
test/unit/map/query_map_point.cpp
Normal file
60
test/unit/map/query_map_point.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/featureset.hpp>
|
||||||
|
#include <mapnik/load_map.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool test_query_point(mapnik::Map const& map,
|
||||||
|
double x, double y,
|
||||||
|
std::string const& name, std::string const& expected_val)
|
||||||
|
{
|
||||||
|
auto featureset = map.query_map_point(0u, x, y);
|
||||||
|
while (auto feature = featureset->next())
|
||||||
|
{
|
||||||
|
auto val = feature->get(name);
|
||||||
|
return (val.to_string() == expected_val);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Query map point") {
|
||||||
|
|
||||||
|
SECTION("Polygons") {
|
||||||
|
|
||||||
|
mapnik::Map map(882,780);
|
||||||
|
mapnik::load_map(map, "./test/data/good_maps/wgs842merc_reprojection.xml");
|
||||||
|
map.zoom_all();
|
||||||
|
CHECK(test_query_point(map, 351, 94, "ADMIN", "Greenland"));
|
||||||
|
CHECK(test_query_point(map, 402, 182,"ADMIN", "Iceland"));
|
||||||
|
CHECK(test_query_point(map, 339, 687,"ADMIN", "Antarctica"));
|
||||||
|
CHECK(test_query_point(map, 35, 141, "ADMIN", "Russia"));
|
||||||
|
CHECK(test_query_point(map, 737, 297,"ADMIN", "Japan"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,20 +3,20 @@
|
||||||
#include <mapnik/projection.hpp>
|
#include <mapnik/projection.hpp>
|
||||||
#include <mapnik/proj_transform.hpp>
|
#include <mapnik/proj_transform.hpp>
|
||||||
#include <mapnik/geometry/box2d.hpp>
|
#include <mapnik/geometry/box2d.hpp>
|
||||||
|
#include <cmath>
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#include <tuple>
|
||||||
// proj4
|
|
||||||
#include <proj_api.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("projection transform")
|
TEST_CASE("projection transform")
|
||||||
{
|
{
|
||||||
|
|
||||||
SECTION("Test bounding box transforms - 4326 to 3857")
|
SECTION("Test bounding box transforms - 4326 to 3857")
|
||||||
{
|
{
|
||||||
mapnik::projection proj_4326("+init=epsg:4326");
|
mapnik::projection proj_4326("epsg:4326");
|
||||||
mapnik::projection proj_3857("+init=epsg:3857");
|
mapnik::projection proj_3857("epsg:3857");
|
||||||
|
|
||||||
|
CHECK(proj_4326.is_geographic());
|
||||||
|
CHECK(!proj_3857.is_geographic());
|
||||||
|
|
||||||
mapnik::proj_transform prj_trans(proj_4326, proj_3857);
|
mapnik::proj_transform prj_trans(proj_4326, proj_3857);
|
||||||
|
|
||||||
double minx = -45.0;
|
double minx = -45.0;
|
||||||
|
@ -45,36 +45,15 @@ SECTION("Test bounding box transforms - 4326 to 3857")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(MAPNIK_USE_PROJ4) && PJ_VERSION >= 480
|
#if defined(MAPNIK_USE_PROJ)
|
||||||
SECTION("test pj_transform failure behavior")
|
SECTION("test proj_transform failure behavior")
|
||||||
{
|
{
|
||||||
mapnik::projection proj_4269("+init=epsg:4269");
|
mapnik::projection proj_4269("epsg:4269");
|
||||||
mapnik::projection proj_3857("+init=epsg:3857");
|
mapnik::projection proj_3857("epsg:3857");
|
||||||
mapnik::proj_transform prj_trans(proj_4269, proj_3857);
|
mapnik::proj_transform prj_trans(proj_4269, proj_3857);
|
||||||
mapnik::proj_transform prj_trans2(proj_3857, proj_4269);
|
mapnik::proj_transform prj_trans2(proj_3857, proj_4269);
|
||||||
|
|
||||||
auto proj_ctx0 = pj_ctx_alloc();
|
// test valid coordinate
|
||||||
REQUIRE( proj_ctx0 != nullptr );
|
|
||||||
auto proj0 = pj_init_plus_ctx(proj_ctx0, proj_4269.params().c_str());
|
|
||||||
REQUIRE( proj0 != nullptr );
|
|
||||||
|
|
||||||
auto proj_ctx1 = pj_ctx_alloc();
|
|
||||||
REQUIRE( proj_ctx1 != nullptr );
|
|
||||||
auto proj1 = pj_init_plus_ctx(proj_ctx1, proj_3857.params().c_str());
|
|
||||||
REQUIRE( proj1 != nullptr );
|
|
||||||
|
|
||||||
// first test valid values directly against proj
|
|
||||||
double x = -180.0;
|
|
||||||
double y = -60.0;
|
|
||||||
x *= DEG_TO_RAD;
|
|
||||||
y *= DEG_TO_RAD;
|
|
||||||
CHECK( x == Approx(-3.1415926536) );
|
|
||||||
CHECK( y == Approx(-1.0471975512) );
|
|
||||||
CHECK( 0 == pj_transform(proj0, proj1, 1, 0, &x, &y, nullptr) );
|
|
||||||
CHECK( x == Approx(-20037508.3427892439) );
|
|
||||||
CHECK( y == Approx(-8399737.8896366451) );
|
|
||||||
|
|
||||||
// now test mapnik class
|
|
||||||
double x0 = -180.0;
|
double x0 = -180.0;
|
||||||
double y0 = -60.0;
|
double y0 = -60.0;
|
||||||
CHECK( prj_trans.forward(&x0,&y0,nullptr,1,1) );
|
CHECK( prj_trans.forward(&x0,&y0,nullptr,1,1) );
|
||||||
|
@ -86,45 +65,69 @@ SECTION("test pj_transform failure behavior")
|
||||||
CHECK( x1 == Approx(-20037508.3427892439) );
|
CHECK( x1 == Approx(-20037508.3427892439) );
|
||||||
CHECK( y1 == Approx(-8399737.8896366451) );
|
CHECK( y1 == Approx(-8399737.8896366451) );
|
||||||
|
|
||||||
// longitude value outside the value range for mercator
|
// now test invalid coordinate
|
||||||
x = -181.0;
|
|
||||||
y = -91.0;
|
|
||||||
x *= DEG_TO_RAD;
|
|
||||||
y *= DEG_TO_RAD;
|
|
||||||
CHECK( x == Approx(-3.1590459461) );
|
|
||||||
CHECK( y == Approx(-1.5882496193) );
|
|
||||||
CHECK( 0 == pj_transform(proj0, proj1, 1, 0, &x, &y, nullptr) );
|
|
||||||
CHECK( std::isinf(x) );
|
|
||||||
CHECK( std::isinf(y) );
|
|
||||||
|
|
||||||
// now test mapnik class
|
|
||||||
double x2 = -181.0;
|
double x2 = -181.0;
|
||||||
double y2 = -91.0;
|
double y2 = -91.0;
|
||||||
CHECK( false == prj_trans.forward(&x2,&y2,nullptr,1,1) );
|
prj_trans.forward(&x2,&y2,nullptr,1,1);
|
||||||
CHECK( std::isinf(x2) );
|
CHECK( std::isinf(x2) );
|
||||||
CHECK( std::isinf(y2) );
|
CHECK( std::isinf(y2) );
|
||||||
double x3 = -181.0;
|
double x3 = -181.0;
|
||||||
double y3 = -91.0;
|
double y3 = -91.0;
|
||||||
CHECK( false == prj_trans2.backward(&x3,&y3,nullptr,1,1) );
|
prj_trans2.backward(&x3,&y3,nullptr,1,1);
|
||||||
CHECK( std::isinf(x3) );
|
CHECK( std::isinf(x3) );
|
||||||
CHECK( std::isinf(y3) );
|
CHECK( std::isinf(y3) );
|
||||||
|
}
|
||||||
|
|
||||||
// cleanup
|
SECTION("test forward/backward transformations")
|
||||||
pj_ctx_free(proj_ctx0);
|
{
|
||||||
proj_ctx0 = nullptr;
|
//WGS 84 - World Geodetic System 1984, used in GPS
|
||||||
pj_free(proj0);
|
mapnik::projection proj_4236("epsg:4236");
|
||||||
proj0 = nullptr;
|
//OSGB 1936 / British National Grid -- United Kingdom Ordnance Survey
|
||||||
pj_ctx_free(proj_ctx1);
|
mapnik::projection proj_27700("epsg:27700");
|
||||||
proj_ctx1 = nullptr;
|
//WGS 84 / Equal Earth Greenwich
|
||||||
pj_free(proj1);
|
mapnik::projection proj_8857("epsg:8857");
|
||||||
proj1 = nullptr;
|
//European Terrestrial Reference System 1989 (ETRS89)
|
||||||
|
mapnik::projection proj_4937("epsg:4937");
|
||||||
|
//"Webmercator" WGS 84 / Pseudo-Mercator -- Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI
|
||||||
|
mapnik::projection proj_3857("epsg:3857");
|
||||||
|
|
||||||
|
mapnik::proj_transform tr1(proj_4236, proj_27700);
|
||||||
|
mapnik::proj_transform tr2(proj_4236, proj_8857);
|
||||||
|
mapnik::proj_transform tr3(proj_4236, proj_4236);
|
||||||
|
mapnik::proj_transform tr4(proj_4236, proj_4937);
|
||||||
|
mapnik::proj_transform tr5(proj_4236, proj_3857);
|
||||||
|
std::initializer_list<std::reference_wrapper<mapnik::proj_transform>> transforms = {
|
||||||
|
tr1, tr2, tr3, tr4, tr5
|
||||||
|
};
|
||||||
|
|
||||||
|
std::initializer_list<std::tuple<double, double>> coords = {
|
||||||
|
{-4.0278869, 57.8796955}, // Dórnach, Highland
|
||||||
|
{-4.2488787, 55.8609825}, // Glaschú, Alba
|
||||||
|
{-1.4823897, 51.8726941}, // Charlbury, England
|
||||||
|
{-3.9732612, 51.7077400} // Felindre, Cymru
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& c : coords)
|
||||||
|
{
|
||||||
|
double x0, y0;
|
||||||
|
std::tie(x0, y0) = c;
|
||||||
|
for (mapnik::proj_transform const& tr : transforms)
|
||||||
|
{
|
||||||
|
double x1 = x0;
|
||||||
|
double y1 = y0;
|
||||||
|
tr.forward (&x1, &y1, nullptr, 1, 1);
|
||||||
|
tr.backward(&x1, &y1, nullptr, 1, 1);
|
||||||
|
CHECK (x0 == Approx(x1));
|
||||||
|
CHECK (y0 == Approx(y1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Github Issue https://github.com/mapnik/mapnik/issues/2648
|
// Github Issue https://github.com/mapnik/mapnik/issues/2648
|
||||||
SECTION("Test proj antimeridian bbox")
|
SECTION("Test proj antimeridian bbox")
|
||||||
{
|
{
|
||||||
mapnik::projection prj_geog("+init=epsg:4326");
|
mapnik::projection prj_geog("epsg:4326");
|
||||||
mapnik::projection prj_proj("+init=epsg:2193");
|
mapnik::projection prj_proj("epsg:2193");
|
||||||
|
|
||||||
mapnik::proj_transform prj_trans_fwd(prj_proj, prj_geog);
|
mapnik::proj_transform prj_trans_fwd(prj_proj, prj_geog);
|
||||||
mapnik::proj_transform prj_trans_rev(prj_geog, prj_proj);
|
mapnik::proj_transform prj_trans_rev(prj_geog, prj_proj);
|
||||||
|
@ -132,7 +135,7 @@ SECTION("Test proj antimeridian bbox")
|
||||||
// reference values taken from proj4 command line tool:
|
// reference values taken from proj4 command line tool:
|
||||||
// (non-corner points assume PROJ_ENVELOPE_POINTS == 20)
|
// (non-corner points assume PROJ_ENVELOPE_POINTS == 20)
|
||||||
//
|
//
|
||||||
// cs2cs -Ef %.10f +init=epsg:2193 +to +init=epsg:4326 <<END
|
// cs2cs -Ef %.10f epsg:2193 +to epsg:4326 <<END
|
||||||
// 2105800 3087000 # left-most
|
// 2105800 3087000 # left-most
|
||||||
// 1495200 3087000 # bottom-most
|
// 1495200 3087000 # bottom-most
|
||||||
// 2105800 7173000 # right-most
|
// 2105800 7173000 # right-most
|
||||||
|
@ -169,14 +172,14 @@ SECTION("Test proj antimeridian bbox")
|
||||||
|
|
||||||
// reference values taken from proj4 command line tool:
|
// reference values taken from proj4 command line tool:
|
||||||
//
|
//
|
||||||
// cs2cs -Ef %.10f +init=epsg:2193 +to +init=epsg:4326 <<END
|
// cs2cs -Ef %.10f epsg:2193 +to epsg:4326 <<END
|
||||||
// 274000 3087000 # left-most
|
// 274000 3087000 # left-most
|
||||||
// 276000 3087000 # bottom-most
|
// 276000 3087000 # bottom-most
|
||||||
// 276000 7173000 # right-most
|
// 276000 7173000 # right-most
|
||||||
// 274000 7173000 # top-most
|
// 274000 7173000 # top-most
|
||||||
// END
|
// END
|
||||||
//
|
//
|
||||||
const mapnik::box2d<double> normal(148.7667597489, -60.1222810241,
|
const mapnik::box2d<double> normal(148.7639922894, -60.1222810241,
|
||||||
159.9548489296, -24.9771195155);
|
159.9548489296, -24.9771195155);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -207,12 +210,14 @@ SECTION("Test proj antimeridian bbox")
|
||||||
|
|
||||||
SECTION("proj_transform of coordinate arrays with stride > 1")
|
SECTION("proj_transform of coordinate arrays with stride > 1")
|
||||||
{
|
{
|
||||||
mapnik::projection const proj_4326("+init=epsg:4326");
|
|
||||||
mapnik::projection const proj_3857("+init=epsg:3857");
|
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")
|
SECTION("lonlat <-> Web Mercator")
|
||||||
{
|
{
|
||||||
// cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:3857 <<END
|
// cs2cs -Ef %.10f epsg:4326 +to epsg:3857 <<END
|
||||||
// 170.142139 -43.595056
|
// 170.142139 -43.595056
|
||||||
// 175.566667 -39.283333
|
// 175.566667 -39.283333
|
||||||
// END
|
// END
|
||||||
|
@ -240,11 +245,12 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
SECTION("lonlat <-> New Zealand Transverse Mercator 2000")
|
SECTION("lonlat <-> New Zealand Transverse Mercator 2000")
|
||||||
{
|
{
|
||||||
mapnik::projection const proj_2193("+init=epsg:2193");
|
|
||||||
// cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:2193 <<END
|
mapnik::projection const proj_2193("epsg:2193");
|
||||||
|
// cs2cs -Ef %.10f epsg:4326 +to epsg:2193 <<END
|
||||||
// 170.142139 -43.595056
|
// 170.142139 -43.595056
|
||||||
// 175.566667 -39.283333
|
// 175.566667 -39.283333
|
||||||
// END
|
// END
|
||||||
|
@ -271,7 +277,7 @@ SECTION("proj_transform of coordinate arrays with stride > 1")
|
||||||
CHECK(points[1].y == Approx(-39.283333));
|
CHECK(points[1].y == Approx(-39.283333));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // MAPNIK_USE_PROJ4
|
#endif // MAPNIK_USE_PROJ
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ SECTION("test_renderer - apply() with single layer") {
|
||||||
rendering_result result;
|
rendering_result result;
|
||||||
test_renderer renderer(map, result);
|
test_renderer renderer(map, result);
|
||||||
std::set<std::string> attributes;
|
std::set<std::string> attributes;
|
||||||
mapnik::layer & layer = map.get_layer(0);
|
mapnik::layer const& layer = map.get_layer(0);
|
||||||
renderer.apply(layer, attributes);
|
renderer.apply(layer, attributes);
|
||||||
|
|
||||||
REQUIRE(renderer.painted());
|
REQUIRE(renderer.painted());
|
||||||
|
@ -222,7 +222,7 @@ SECTION("test_renderer - apply_to_layer") {
|
||||||
test_renderer renderer(map, result);
|
test_renderer renderer(map, result);
|
||||||
std::set<std::string> attributes;
|
std::set<std::string> attributes;
|
||||||
mapnik::projection map_proj(map.srs(), true);
|
mapnik::projection map_proj(map.srs(), true);
|
||||||
mapnik::layer & layer = map.get_layer(0);
|
mapnik::layer const& layer = map.get_layer(0);
|
||||||
renderer.apply_to_layer(layer,
|
renderer.apply_to_layer(layer,
|
||||||
renderer,
|
renderer,
|
||||||
map_proj,
|
map_proj,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
TEST_CASE("transform_path_adapter") {
|
TEST_CASE("transform_path_adapter") {
|
||||||
|
|
||||||
#ifdef MAPNIK_USE_PROJ4
|
#ifdef MAPNIK_USE_PROJ
|
||||||
SECTION("polygon closing - epsg 2330") {
|
SECTION("polygon closing - epsg 2330") {
|
||||||
mapnik::geometry::polygon<double> g;
|
mapnik::geometry::polygon<double> g;
|
||||||
g.emplace_back();
|
g.emplace_back();
|
||||||
|
@ -28,8 +28,8 @@ SECTION("polygon closing - epsg 2330") {
|
||||||
va_type va(g);
|
va_type va(g);
|
||||||
mapnik::box2d<double> extent(16310607, 7704513, 16310621, 7704527);
|
mapnik::box2d<double> extent(16310607, 7704513, 16310621, 7704527);
|
||||||
mapnik::view_transform tr(512, 512, extent);
|
mapnik::view_transform tr(512, 512, extent);
|
||||||
mapnik::projection proj1("+init=epsg:2330");
|
mapnik::projection proj1("epsg:2330");
|
||||||
mapnik::projection proj2("+init=epsg:4326");
|
mapnik::projection proj2("epsg:4326");
|
||||||
mapnik::proj_transform prj_trans(proj1, proj2);
|
mapnik::proj_transform prj_trans(proj1, proj2);
|
||||||
path_type path(tr, va, prj_trans);
|
path_type path(tr, va, prj_trans);
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ SECTION("polygon closing - epsg 32633") {
|
||||||
va_type va(g);
|
va_type va(g);
|
||||||
mapnik::box2d<double> extent(166022, 0, 833978, 9329005);
|
mapnik::box2d<double> extent(166022, 0, 833978, 9329005);
|
||||||
mapnik::view_transform tr(512, 512, extent);
|
mapnik::view_transform tr(512, 512, extent);
|
||||||
mapnik::projection proj1("+init=epsg:32633");
|
mapnik::projection proj1("epsg:32633");
|
||||||
mapnik::projection proj2("+init=epsg:4326");
|
mapnik::projection proj2("epsg:4326");
|
||||||
mapnik::proj_transform prj_trans(proj1, proj2);
|
mapnik::proj_transform prj_trans(proj1, proj2);
|
||||||
path_type path(tr, va, prj_trans);
|
path_type path(tr, va, prj_trans);
|
||||||
|
|
||||||
|
@ -116,5 +116,5 @@ SECTION("polygon closing - epsg 32633") {
|
||||||
CHECK( y == 0 );
|
CHECK( y == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MAPNIK_USE_PROJ4
|
#endif //MAPNIK_USE_PROJ
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue