[mapnik] 01/07: Imported Upstream version 3.0.12~rc1+ds
Bas Couwenberg
sebastic at debian.org
Fri Aug 5 13:39:47 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository mapnik.
commit 4cbbc3006e9f565e6d8fb291e81db9b770928291
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Fri Aug 5 14:39:39 2016 +0200
Imported Upstream version 3.0.12~rc1+ds
---
.travis.yml | 35 +-
CHANGELOG.md | 68 ++-
INSTALL.md | 2 +-
README.md | 5 +-
SConstruct | 31 +-
appveyor.yml | 2 +-
bootstrap.sh | 12 +-
circle.yml | 14 +-
demo/c++/README.md | 4 +-
demo/c++/rundemo.cpp | 6 +-
demo/data/boundaries.dbf | Bin 750 -> 749 bytes
demo/data/boundaries.prj | 1 -
demo/data/boundaries.sbx | Bin 116 -> 0 bytes
demo/data/boundaries_l.dbf | Bin 972 -> 971 bytes
demo/data/boundaries_l.prj | 1 -
demo/data/boundaries_l.sbx | Bin 132 -> 0 bytes
demo/data/ontdrainage.dbf | Bin 264968 -> 264967 bytes
demo/data/ontdrainage.prj | 1 -
demo/data/ontdrainage.sbx | Bin 644 -> 0 bytes
demo/data/popplaces.dbf | Bin 93538 -> 93537 bytes
demo/data/popplaces.prj | 1 -
demo/data/popplaces.sbx | Bin 268 -> 0 bytes
demo/data/qcdrainage.dbf | Bin 219468 -> 219467 bytes
demo/data/qcdrainage.prj | 1 -
demo/data/qcdrainage.sbx | Bin 644 -> 0 bytes
demo/data/roads.dbf | Bin 1127356 -> 1127355 bytes
demo/data/roads.prj | 1 -
demo/data/roads.sbx | Bin 2060 -> 0 bytes
deps/agg/include/agg_rasterizer_scanline_aa.h | 161 ++++---
deps/mapnik/build.py | 2 +-
include/mapnik/box2d.hpp | 5 +-
src/box2d.cpp => include/mapnik/box2d_impl.hpp | 7 +-
include/mapnik/config.hpp | 13 +-
include/mapnik/debug.hpp | 6 +-
include/mapnik/expression_grammar_impl.hpp | 1 +
include/mapnik/feature.hpp | 2 +-
include/mapnik/featureset.hpp | 15 +
include/mapnik/function_call.hpp | 11 +
include/mapnik/geometry.hpp | 70 +--
include/mapnik/geometry_envelope.hpp | 4 +-
include/mapnik/geometry_envelope_impl.hpp | 23 +-
include/mapnik/json/attribute_value_visitor.hpp | 68 +++
.../json/extract_bounding_box_grammar_impl.hpp | 9 +-
include/mapnik/json/feature_grammar.hpp | 32 +-
include/mapnik/json/feature_grammar_impl.hpp | 26 +-
include/mapnik/json/generic_json.hpp | 67 ++-
include/mapnik/json/geometry_grammar_impl.hpp | 15 +-
include/mapnik/json/positions_grammar.hpp | 23 -
include/mapnik/json/positions_grammar_impl.hpp | 24 ++
include/mapnik/json/stringifier.hpp | 101 +++++
include/mapnik/json/topojson_grammar.hpp | 152 ++++++-
include/mapnik/json/topojson_grammar_impl.hpp | 184 +++-----
include/mapnik/json/topojson_utils.hpp | 195 +++++----
include/mapnik/json/topology.hpp | 9 +-
include/mapnik/palette.hpp | 21 +-
include/mapnik/params.hpp | 4 +
include/mapnik/plugin.hpp | 3 +-
include/mapnik/png_io.hpp | 75 ++--
.../renderer_common/process_point_symbolizer.hpp | 2 +-
include/mapnik/symbolizer_base.hpp | 4 +-
include/mapnik/text/placement_finder.hpp | 1 -
include/mapnik/text/scrptrun.hpp | 2 +-
include/mapnik/text/symbolizer_helpers.hpp | 6 +-
include/mapnik/util/char_array_buffer.hpp | 87 ++++
include/mapnik/util/is_clockwise.hpp | 11 +-
include/mapnik/util/variant.hpp | 10 +-
include/mapnik/value_hash.hpp | 16 +-
include/mapnik/version.hpp | 2 +-
include/mapnik/vertex_adapters.hpp | 16 +-
include/mapnik/warning_ignore.hpp | 1 +
include/mapnik/wkt/wkt_generator_grammar.hpp | 2 +-
include/mapnik/xml_attribute_cast.hpp | 15 +-
localize.sh | 10 +-
mason_latest.sh | 8 +-
plugins/input/csv/csv_datasource.cpp | 2 +-
plugins/input/gdal/gdal_datasource.cpp | 11 +-
plugins/input/gdal/gdal_featureset.cpp | 100 +++--
plugins/input/gdal/gdal_featureset.hpp | 5 -
plugins/input/geojson/geojson_datasource.cpp | 4 +-
plugins/input/ogr/ogr_datasource.cpp | 20 +-
plugins/input/pgraster/pgraster_datasource.cpp | 19 +-
plugins/input/pgraster/pgraster_wkb_reader.cpp | 2 +-
plugins/input/postgis/postgis_datasource.cpp | 8 +-
plugins/input/raster/raster_datasource.cpp | 2 +-
plugins/input/sqlite/sqlite_datasource.cpp | 4 +-
plugins/input/topojson/topojson_datasource.cpp | 25 +-
scripts/travis-common.sh | 5 +-
src/agg/process_line_pattern_symbolizer.cpp | 2 +-
src/agg/process_polygon_pattern_symbolizer.cpp | 2 +-
src/agg/process_text_symbolizer.cpp | 2 +-
src/box2d.cpp | 475 +-------------------
src/cairo/process_line_pattern_symbolizer.cpp | 2 +-
src/cairo/process_polygon_pattern_symbolizer.cpp | 2 +-
src/datasource_cache.cpp | 4 +-
src/font_engine_freetype.cpp | 4 +-
src/geometry_envelope.cpp | 21 +-
src/grid/process_text_symbolizer.cpp | 2 +-
src/image_compositing.cpp | 34 +-
src/jpeg_reader.cpp | 30 +-
src/load_map.cpp | 18 +-
src/map.cpp | 2 +-
src/marker_helpers.cpp | 9 +
src/palette.cpp | 10 -
src/plugin.cpp | 14 +-
src/png_reader.cpp | 32 +-
src/proj_transform.cpp | 91 ++--
src/renderer_common/render_markers_symbolizer.cpp | 4 +-
src/text/formatting/layout.cpp | 6 +-
src/text/placement_finder.cpp | 68 +--
src/text/symbolizer_helpers.cpp | 38 +-
src/text/text_line.cpp | 2 +-
src/text/text_properties.cpp | 12 +-
src/tiff_reader.cpp | 33 +-
src/value.cpp | 4 +-
src/vertex_adapters.cpp | 8 +-
src/webp_reader.cpp | 3 -
src/xml_tree.cpp | 6 +-
test/run | 14 +-
test/standalone/font_registration_test.cpp | 18 +-
test/unit/core/expressions_test.cpp | 3 +
test/unit/datasource/ds_test_util.hpp | 15 +-
test/unit/datasource/geojson.cpp | 68 +++
test/unit/datasource/postgis.cpp | 477 +++++++++++----------
test/unit/datasource/topojson.cpp | 41 +-
test/unit/geometry/geometry_envelope_test.cpp | 86 ++--
test/unit/geometry/geometry_equal.hpp | 11 +-
test/unit/geometry/geometry_test_helper.cpp | 15 +
test/unit/geometry/is_clockwise.cpp | 27 ++
test/unit/imaging/image_io_test.cpp | 51 ++-
test/unit/imaging/tiff_io.cpp | 19 +-
test/unit/serialization/wkb_test.cpp | 4 +
test/visual/renderer.hpp | 135 ++++--
test/visual/run.cpp | 39 +-
utils/mapnik-index/mapnik-index.cpp | 13 +-
utils/mapnik-index/process_csv_file.cpp | 9 +-
utils/mapnik-render/mapnik-render.cpp | 4 +-
utils/pgsql2sqlite/pgsql2sqlite.hpp | 10 +-
137 files changed, 2137 insertions(+), 1775 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 13cf1f2..5de9299 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,4 @@
-language: c
+language: cpp
git:
depth: 10
@@ -25,26 +25,34 @@ matrix:
- os: linux
sudo: false
compiler: ": clang"
- env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.5 -Qunused-arguments" CC="clang-3.5" TRIGGER=true
+ env: JOBS=8 MASON_PUBLISH=true _CXX="ccache clang++-3.8 -Qunused-arguments" _CC="clang-3.8" TRIGGER=true
addons:
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ]
- packages: [ 'clang-3.5' ]
+ sources: [ 'ubuntu-toolchain-r-test']
+ packages: [ 'libstdc++6', 'libstdc++-5-dev']
- os: linux
sudo: false
compiler: ": clang-coverage"
- env: JOBS=8 COVERAGE=true LLVM_VERSION="3.5" CXX="ccache clang++-3.5 -Qunused-arguments" CC="clang-3.5"
+ env: JOBS=8 COVERAGE=true _CXX="ccache clang++-3.8 -Qunused-arguments" _CC="clang-3.8"
addons:
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ]
- packages: [ 'clang-3.5', 'llvm-3.5-dev' ]
+ sources: [ 'ubuntu-toolchain-r-test']
+ packages: [ 'libstdc++6','libstdc++-5-dev' ]
- os: osx
- compiler: clang
+ compiler: ": clang-osx"
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
osx_image: xcode7.3 # upgrades clang from 6 -> 7
- env: JOBS=4 MASON_PUBLISH=true
+ env: JOBS=4 MASON_PUBLISH=true _CXX="ccache clang++ -Qunused-arguments"
before_install:
+ # workaround travis rvm bug
+ # http://superuser.com/questions/1044130/why-am-i-having-how-can-i-fix-this-error-shell-session-update-command-not-f
+ - |
+ if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
+ rvm get head || true
+ fi
+ - if [[ ${_CXX:-false} != false ]]; then export CXX=${_CXX}; fi
+ - if [[ ${_CC:-false} != false ]]; then export CC=${_CC}; fi
- source scripts/travis-common.sh
- export PYTHONUSERBASE=$(pwd)/mason_packages/.link
- export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PYTHONUSERBASE}/bin:${PATH}
@@ -56,7 +64,6 @@ before_install:
- git_submodule_update --init --depth=10
install:
- - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi
- on 'linux' export PYTHONPATH=${PYTHONUSERBASE}/lib/python2.7/site-packages
- on 'osx' export PYTHONPATH=${PYTHONUSERBASE}/lib/python/site-packages
- on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres
@@ -71,6 +78,13 @@ install:
before_script:
- source bootstrap.sh
+ - |
+ if [[ $(uname -s) == 'Linux' ]]; then
+ mason install clang 3.8.0
+ export PATH=$(mason prefix clang 3.8.0)/bin:${PATH}
+ which clang++
+ export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov"
+ fi
- ccache --version
- ccache -p || true
- ccache --show-stats || true
@@ -79,6 +93,7 @@ before_script:
script:
- export SCONSFLAGS='--debug=time'
- configure BENCHMARK=${BENCH}
+ - cat config.log
- make
- make test
- enabled ${COVERAGE} coverage
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 762cee9..8c3c00b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,40 @@ Developers: Please commit along with changes.
For a complete change history, see the git log.
+## 3.0.12
+
+Released: xx-xx-xx
+
+(Packaged from xxxxxx)
+
+#### Summary
+
+- Ensured gdal.input is registered once (refs #3093 #3339 #3340)
+- Fixed `mapnik::util::is_clockwise` implementation to use coordinates relative to the origin and avoid numeric precision issues
+- `mapnik-index` is updated to fail on first error in input (csv)
+- Added `guard` to `get_object_severity` method (ref #3322)
+- Improved `hash` calculation for `mapnik::value` (ref #3406)
+- AGG - made cover `unsigned` to avoid left shift of negative values (ref #3406)
+- Fixed using `scale_factor` in `evaluate_transform(..)`
+- Fixed line spacing logic by applying `scale factor`
+- ~~Fixed `stringify_object/stringify_array` implementations by disabling white space skipping (ref #3419)~~
+- Added geojson unit test for property types/values
+- JSON - added support for object and array type in `json_value` and update `stringifier`
+- GDAL.input - fallback to using `overviews` if present (8e8482803bb435726534c3b686a56037b7d3e8ad)
+- TopoJSON.input - improved and simplified grammer/parser implementation (https://github.com/mapnik/mapnik/pull/3429)
+- GDAL.input - Added support for non-alpha mask band
+- TopoJSON.input - fixed order of ellements limitation (ref #3434)
+- Fixed stroke-width size not included in markers ellipse bounding box (ref #3445)
+- Implemented `char_array_buffer` and removed `boost::iostreams` dependency (2e8c0d36c2237f2815d8004c1b96bad909056eb9)
+- JSON.input - `extract_bounding_box_grammar` - make features optional (ref #3463)
+- Ensure input plugins return `empty_featureset` rather than `nullptr` (feature_ptr())
+- Added support for quantising small (less than 3 pixel) images (ref #3466)
+- Added support for natural logarithm function in expressions (ref #3475)
+- Improved logic determining if certain compiler features are available e.g `inheriting constructors` (MSVC)
+
## 3.0.11
-Released:
+Released: April 1, 2016
(Packaged from 8d9dc27)
@@ -16,7 +47,10 @@ Released:
- Raster scaling: fixed crash and clipping negative pixel values of floating point rasters (https://github.com/mapnik/mapnik/pull/3349)
- Restored support for unquoted strings in expressions (https://github.com/mapnik/mapnik/pull/3390)
-
+ - [TWKB](https://github.com/TWKB/) support via https://github.com/mapnik/mapnik/pull/3356 (#3355)
+ - Visual test runner can render SVG, PDF and Postscript with Cairo renderer (https://github.com/mapnik/mapnik/pull/3418)
+ - Scale factor is now applied also to `text-line-spacing` and transforms (https://github.com/mapnik/mapnik/pull/3416)
+
## 3.0.10
Released: February 25, 2016
@@ -541,8 +575,8 @@ Summary: The 2.2.0 release is primarily a performance and stability release. The
- Enabled default input plugin directory and fonts path to be set inherited from environment settings in
python bindings to make it easier to run tests locally (#1594). New environment settings are:
- - MAPNIK_INPUT_PLUGINS_DIRECTORY
- - MAPNIK_FONT_DIRECTORY
+ - MAPNIK_INPUT_PLUGINS_DIRECTORY
+ - MAPNIK_FONT_DIRECTORY
- Added support for controlling rendering behavior of markers on multi-geometries `marker-multi-policy` (#1555,#1573)
@@ -934,7 +968,7 @@ Released January, 19 2010
- Gdal Plugin: Added support for Gdal overviews, enabling fast loading of > 1GB rasters (#54)
- * Use the gdaladdo utility to add overviews to existing GDAL datasets
+ * Use the gdaladdo utility to add overviews to existing GDAL datasets
- PostGIS: Added an optional `geometry_table` parameter. The `geometry_table` used by Mapnik to look up
metadata in the geometry_columns and calculate extents (when the `geometry_field` and `srid` parameters
@@ -959,23 +993,23 @@ Released January, 19 2010
complex queries that may aggregate geometries to be kept fast by allowing proper placement of the bbox
query to be used by indexes. (#415)
- * Pass the bbox token inside a subquery like: !bbox!
+ * Pass the bbox token inside a subquery like: !bbox!
- * Valid Usages include:
+ * Valid Usages include:
- <Parameter name="table">
- (Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map
- </Parameter>
+ <Parameter name="table">
+ (Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map
+ </Parameter>
- <Parameter name="table">
- (Select * from table where geom && !bbox!) as map
- </Parameter>
+ <Parameter name="table">
+ (Select * from table where geom && !bbox!) as map
+ </Parameter>
- PostGIS Plugin: Added `scale_denominator` substitution ability in sql query string (#415/#465)
- * Pass the scale_denominator token inside a subquery like: !scale_denominator!
+ * Pass the scale_denominator token inside a subquery like: !scale_denominator!
- * e.g. (Select * from table where field_value > !scale_denominator!) as map
+ * e.g. (Select * from table where field_value > !scale_denominator!) as map
- PostGIS Plugin: Added support for quoted table names (r1454) (#393)
@@ -1007,14 +1041,14 @@ Released January, 19 2010
- TextSymbolizer: Large set of new attributes: `text_transform`, `line_spacing`, `character_spacing`,
`wrap_character`, `wrap_before`, `horizontal_alignment`, `justify_alignment`, and `opacity`.
- * More details at changesets: r1254 and r1341
+ * More details at changesets: r1254 and r1341
- SheildSymbolizer: Added special new attributes: `unlock_image`, `VERTEX` placement, `no_text` and many
attributes previously only supported in the TextSymbolizer: `allow_overlap`, `vertical_alignment`,
`horizontal_alignment`, `justify_alignment`, `wrap_width`, `wrap_character`, `wrap_before`, `text_transform`,
`line_spacing`, `character_spacing`, and `opacity`.
- * More details at changeset r1341
+ * More details at changeset r1341
- XML: Added support for using CDATA with libxml2 parser (r1364)
diff --git a/INSTALL.md b/INSTALL.md
index d27004d..8992144 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -98,7 +98,7 @@ Additional optional dependencies:
* PostgreSQL (for PostGIS plugin support)
- libpq - PostreSQL libraries
- pg_config - PostgreSQL installation capabilities
- * libgdal - GDAL/OGR input (For gdal and ogr plugin support)
+ * libgdal - GDAL/OGR input (For gdal and ogr plugin support) (>= GDAL 2.0.2 for thread safety - https://github.com/mapnik/mapnik/issues/3339)
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
Instructions for installing many of these dependencies on
diff --git a/README.md b/README.md
index b5ebf6a..e99df98 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/
```
[](http://travis-ci.org/mapnik/mapnik)
+[](https://circleci.com/gh/mapnik/mapnik)
[](https://ci.appveyor.com/project/Mapbox/mapnik)
[](https://coveralls.io/github/mapnik/mapnik?branch=master)
@@ -20,7 +21,7 @@ For further information see [http://mapnik.org](http://mapnik.org) and also our
# Installation
-See [INSTALL.md](https://github.com/mapnik/mapnik/blob/master/INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
+See [INSTALL.md](INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
# Code of Conduct
@@ -28,4 +29,4 @@ Please note that this project is released with a [Contributor Code of Conduct](h
# License
-Mapnik software is free and is released under the LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html_)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
+Mapnik software is free and is released under the LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
diff --git a/SConstruct b/SConstruct
index dacc950..0523e18 100644
--- a/SConstruct
+++ b/SConstruct
@@ -704,11 +704,7 @@ def FindBoost(context, prefixes, thread_flag):
BOOST_INCLUDE_DIR = None
BOOST_APPEND = None
env['BOOST_APPEND'] = str()
-
- if env['THREADING'] == 'multi':
- search_lib = 'libboost_thread'
- else:
- search_lib = 'libboost_filesystem'
+ search_lib = 'libboost_filesystem'
# note: must call normpath to strip trailing slash otherwise dirname
# does not remove 'lib' and 'include'
@@ -1359,7 +1355,7 @@ if not preconfigured:
# test for C++11 support, which is required
if not env['HOST'] and not conf.supports_cxx11():
- color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler to at least g++ 4.7 (ideally 4.8)")
+ color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler")
Exit(1)
if not env['HOST']:
@@ -1411,15 +1407,6 @@ if not preconfigured:
['program_options', 'boost/program_options.hpp', False]
]
- if env['THREADING'] == 'multi':
- BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True])
- # on solaris the configure checks for boost_thread
- # require the -pthreads flag to be able to check for
- # threading support, so we add as a global library instead
- # of attaching to cxxflags after configure
- if env['PLATFORM'] == 'SunOS':
- env.Append(CXXFLAGS = '-pthreads')
-
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
if env['PRIORITIZE_LINKING']:
conf.prioritize_paths(silent=True)
@@ -1451,12 +1438,13 @@ if not preconfigured:
# just turn it off like this, but seems the only available work-
# around. See https://svn.boost.org/trac/boost/ticket/6779 for more
# details.
- boost_version = [int(x) for x in env.get('BOOST_LIB_VERSION_FROM_HEADER').split('_')]
- if not conf.CheckBoostScopedEnum():
- if boost_version < [1, 51]:
- env.Append(CXXFLAGS = '-DBOOST_NO_SCOPED_ENUMS')
- elif boost_version < [1, 57]:
- env.Append(CXXFLAGS = '-DBOOST_NO_CXX11_SCOPED_ENUMS')
+ if not env['HOST']:
+ boost_version = [int(x) for x in env.get('BOOST_LIB_VERSION_FROM_HEADER').split('_')]
+ if not conf.CheckBoostScopedEnum():
+ if boost_version < [1, 51]:
+ env.Append(CXXFLAGS = '-DBOOST_NO_SCOPED_ENUMS')
+ elif boost_version < [1, 57]:
+ env.Append(CXXFLAGS = '-DBOOST_NO_CXX11_SCOPED_ENUMS')
if not env['HOST'] and env['ICU_LIB_NAME'] not in env['MISSING_DEPS']:
# http://lists.boost.org/Archives/boost/2009/03/150076.php
@@ -1609,6 +1597,7 @@ if not preconfigured:
# prepend to make sure we link locally
env.Prepend(CPPPATH = '#deps/agg/include')
env.Prepend(LIBPATH = '#deps/agg')
+ env.Prepend(CPPPATH = '#deps/mapbox/variant/include')
# prepend deps dir for auxillary headers
env.Prepend(CPPPATH = '#deps')
diff --git a/appveyor.yml b/appveyor.yml
index f236021..34ddc3b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,6 +1,6 @@
environment:
msvs_toolset: 14
- BOOST_VERSION: 59
+ BOOST_VERSION: 60
FASTBUILD: 1
matrix:
- platform: x64
diff --git a/bootstrap.sh b/bootstrap.sh
index 3a64709..fd877a6 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -10,7 +10,7 @@ todo
- shrink icu data
'
-MASON_VERSION="694d08c"
+MASON_VERSION="b709931"
function setup_mason() {
if [[ ! -d ./.mason ]]; then
@@ -20,7 +20,6 @@ function setup_mason() {
echo "Updating to latest mason"
(cd ./.mason && git fetch && git checkout ${MASON_VERSION})
fi
- export MASON_DIR=$(pwd)/.mason
export PATH=$(pwd)/.mason:$PATH
export CXX=${CXX:-clang++}
export CC=${CC:-clang}
@@ -32,7 +31,7 @@ function install() {
mason install $1 $2
mason link $1 $2
if [[ ${3:-false} != false ]]; then
- LA_FILE=$(${MASON_DIR:-~/.mason}/mason prefix $1 $2)/lib/$3.la
+ LA_FILE=$(mason prefix $1 $2)/lib/$3.la
if [[ -f ${LA_FILE} ]]; then
perl -i -p -e 's:\Q$ENV{HOME}/build/mapbox/mason\E:$ENV{PWD}:g' ${LA_FILE}
else
@@ -63,8 +62,11 @@ function install_mason_deps() {
wait
install webp 0.4.2 libwebp &
install gdal 1.11.2 libgdal &
- install boost 1.59.0 &
- install boost_liball 1.59.0 &
+ install boost 1.61.0 &
+ install boost_libsystem 1.61.0 &
+ install boost_libfilesystem 1.61.0 &
+ install boost_libprogram_options 1.61.0 &
+ install boost_libregex 1.61.0 &
install freetype 2.6 libfreetype &
install harfbuzz 0.9.41 libharfbuzz &
wait
diff --git a/circle.yml b/circle.yml
index e7c12d7..cf3e31c 100644
--- a/circle.yml
+++ b/circle.yml
@@ -7,7 +7,7 @@ machine:
JOBS: 8
CCACHE_TEMPDIR: /tmp/.ccache-temp
CCACHE_COMPRESS: 1
- LLVM_VERSION: 3.7
+ LLVM_VERSION: 3.8
pre:
- echo "here"
post:
@@ -25,20 +25,16 @@ dependencies:
pre:
# https://discuss.circleci.com/t/add-ability-to-cache-apt-get-programs/598/3
- sudo rm -rf /var/cache/apt/archives && sudo ln -s ~/.apt-cache /var/cache/apt/archives && mkdir -p ~/.apt-cache/partial
- - sudo wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- - sudo add-apt-repository -y "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-${LLVM_VERSION} main"
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- - sudo apt-get update -y
override:
- - sudo apt-get install clang-${LLVM_VERSION} -y
- post:
- - which clang-${LLVM_VERSION}
- - which clang++-${LLVM_VERSION}
+ - sudo apt-get update -y
database:
pre:
- ./bootstrap.sh
- - ./configure CC="clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache clang++-${LLVM_VERSION} -Qunused-arguments"
+ - ./.mason/mason install clang ${LLVM_VERSION}.0
+ - ./.mason/mason link clang ${LLVM_VERSION}.0
+ - ./configure CC="$(pwd)/mason_packages/.link/bin/clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++-${LLVM_VERSION} -Qunused-arguments"
- make
override:
- psql -c 'create database template_postgis;'
diff --git a/demo/c++/README.md b/demo/c++/README.md
index daa4198..548508e 100644
--- a/demo/c++/README.md
+++ b/demo/c++/README.md
@@ -52,11 +52,11 @@ If you do not have svn installed you can grab gyp from:
Simply type:
- make
+ make
Then to run do:
- ./rundemo `mapnik-config --prefix`
+ ./rundemo `mapnik-config --prefix`
On OS X you can also create an xcode project:
diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp
index c07bd5c..c20c288 100644
--- a/demo/c++/rundemo.cpp
+++ b/demo/c++/rundemo.cpp
@@ -55,7 +55,7 @@ int main ( int, char** )
try {
std::cout << " running demo ... \n";
datasource_cache::instance().register_datasources("plugins/input/");
- freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.34/ttf/DejaVuSans.ttf");
+ freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.35/ttf/DejaVuSans.ttf");
Map m(800,600);
m.set_background(parse_color("white"));
@@ -230,7 +230,7 @@ int main ( int, char** )
parameters p;
p["type"]="shape";
p["file"]="demo/data/boundaries";
- p["encoding"]="latin1";
+ p["encoding"]="utf8";
layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance().create(p));
@@ -295,7 +295,7 @@ int main ( int, char** )
parameters p;
p["type"]="shape";
p["file"]="demo/data/popplaces";
- p["encoding"] = "latin1";
+ p["encoding"] = "utf8";
layer lyr("Populated Places");
lyr.set_srs(srs_lcc);
lyr.set_datasource(datasource_cache::instance().create(p));
diff --git a/demo/data/boundaries.dbf b/demo/data/boundaries.dbf
index aeed235..04d2ed6 100644
Binary files a/demo/data/boundaries.dbf and b/demo/data/boundaries.dbf differ
diff --git a/demo/data/boundaries.prj b/demo/data/boundaries.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/boundaries.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/boundaries.sbx b/demo/data/boundaries.sbx
deleted file mode 100644
index c66e6e3..0000000
Binary files a/demo/data/boundaries.sbx and /dev/null differ
diff --git a/demo/data/boundaries_l.dbf b/demo/data/boundaries_l.dbf
index e6bc20c..44d4ca8 100644
Binary files a/demo/data/boundaries_l.dbf and b/demo/data/boundaries_l.dbf differ
diff --git a/demo/data/boundaries_l.prj b/demo/data/boundaries_l.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/boundaries_l.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/boundaries_l.sbx b/demo/data/boundaries_l.sbx
deleted file mode 100644
index e609d80..0000000
Binary files a/demo/data/boundaries_l.sbx and /dev/null differ
diff --git a/demo/data/ontdrainage.dbf b/demo/data/ontdrainage.dbf
index 33d8004..8192650 100644
Binary files a/demo/data/ontdrainage.dbf and b/demo/data/ontdrainage.dbf differ
diff --git a/demo/data/ontdrainage.prj b/demo/data/ontdrainage.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/ontdrainage.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/ontdrainage.sbx b/demo/data/ontdrainage.sbx
deleted file mode 100644
index 3739c61..0000000
Binary files a/demo/data/ontdrainage.sbx and /dev/null differ
diff --git a/demo/data/popplaces.dbf b/demo/data/popplaces.dbf
index 408968e..d385b6f 100644
Binary files a/demo/data/popplaces.dbf and b/demo/data/popplaces.dbf differ
diff --git a/demo/data/popplaces.prj b/demo/data/popplaces.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/popplaces.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/popplaces.sbx b/demo/data/popplaces.sbx
deleted file mode 100644
index c028881..0000000
Binary files a/demo/data/popplaces.sbx and /dev/null differ
diff --git a/demo/data/qcdrainage.dbf b/demo/data/qcdrainage.dbf
index 95ce20f..04fcf85 100644
Binary files a/demo/data/qcdrainage.dbf and b/demo/data/qcdrainage.dbf differ
diff --git a/demo/data/qcdrainage.prj b/demo/data/qcdrainage.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/qcdrainage.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/qcdrainage.sbx b/demo/data/qcdrainage.sbx
deleted file mode 100644
index c73534e..0000000
Binary files a/demo/data/qcdrainage.sbx and /dev/null differ
diff --git a/demo/data/roads.dbf b/demo/data/roads.dbf
index 73c1db9..709f881 100644
Binary files a/demo/data/roads.dbf and b/demo/data/roads.dbf differ
diff --git a/demo/data/roads.prj b/demo/data/roads.prj
deleted file mode 100644
index 21aa9c3..0000000
--- a/demo/data/roads.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git a/demo/data/roads.sbx b/demo/data/roads.sbx
deleted file mode 100644
index b804cb3..0000000
Binary files a/demo/data/roads.sbx and /dev/null differ
diff --git a/deps/agg/include/agg_rasterizer_scanline_aa.h b/deps/agg/include/agg_rasterizer_scanline_aa.h
index 77bc41b..b2d4e3e 100644
--- a/deps/agg/include/agg_rasterizer_scanline_aa.h
+++ b/deps/agg/include/agg_rasterizer_scanline_aa.h
@@ -2,15 +2,15 @@
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
-// The author gratefully acknowleges the support of David Turner,
-// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
+// The author gratefully acknowleges the support of David Turner,
+// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
@@ -19,12 +19,12 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
-// Adaptation for 32-bit screen coordinates has been sponsored by
+// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
-//
+//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
@@ -39,8 +39,8 @@ namespace agg
//-----------------------------------------------------------------cell_aa
- // A pixel cell. There're no constructors defined and it was done
- // intentionally in order to avoid extra overhead when allocating an
+ // A pixel cell. There're no constructors defined and it was done
+ // intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_aa
{
@@ -67,10 +67,10 @@ namespace agg
//==================================================rasterizer_scanline_aa
- // Polygon rasterizer that is used to render filled polygons with
- // high-quality Anti-Aliasing. Internally, by default, the class uses
- // integer coordinates in format 24.8, i.e. 24 bits for integer part
- // and 8 bits for fractional - see poly_subpixel_shift. This class can be
+ // Polygon rasterizer that is used to render filled polygons with
+ // high-quality Anti-Aliasing. Internally, by default, the class uses
+ // integer coordinates in format 24.8, i.e. 24 bits for integer part
+ // and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
@@ -79,20 +79,20 @@ namespace agg
//
// 3. reset()
//
- // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
+ // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// more than one contour, but each contour must consist of at least 3
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
// is the absolute minimum of vertices that define a triangle.
// The algorithm does not check either the number of vertices nor
- // coincidence of their coordinates, but in the worst case it just
+ // coincidence of their coordinates, but in the worst case it just
// won't draw anything.
- // The orger of the vertices (clockwise or counterclockwise)
+ // The orger of the vertices (clockwise or counterclockwise)
// is important when using the non-zero filling rule (fill_non_zero).
// In this case the vertex order of all the contours must be the same
// if you want your intersecting polygons to be without "holes".
- // You actually can use different vertices order. If the contours do not
- // intersect each other the order is not important anyway. If they do,
- // contours with the same vertex order will be rendered without "holes"
+ // You actually can use different vertices order. If the contours do not
+ // intersect each other the order is not important anyway. If they do,
+ // contours with the same vertex order will be rendered without "holes"
// while the intersecting contours with different orders will have "holes".
//
// filling_rule() and gamma() can be called anytime before "sweeping".
@@ -122,7 +122,7 @@ namespace agg
};
//--------------------------------------------------------------------
- rasterizer_scanline_aa() :
+ rasterizer_scanline_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
@@ -136,8 +136,8 @@ namespace agg
}
//--------------------------------------------------------------------
- template<class GammaF>
- rasterizer_scanline_aa(const GammaF& gamma_function) :
+ template<class GammaF>
+ rasterizer_scanline_aa(const GammaF& gamma_function) :
m_outline(),
m_clipper(m_outline),
m_filling_rule(fill_non_zero),
@@ -150,7 +150,7 @@ namespace agg
}
//--------------------------------------------------------------------
- void reset();
+ void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
@@ -158,7 +158,7 @@ namespace agg
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
- {
+ {
int i;
for(i = 0; i < aa_scale; i++)
{
@@ -167,9 +167,9 @@ namespace agg
}
//--------------------------------------------------------------------
- unsigned apply_gamma(unsigned cover) const
- {
- return m_gamma[cover];
+ unsigned apply_gamma(unsigned cover) const
+ {
+ return m_gamma[cover];
}
//--------------------------------------------------------------------
@@ -198,7 +198,7 @@ namespace agg
add_vertex(x, y, cmd);
}
}
-
+
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
@@ -237,7 +237,7 @@ namespace agg
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
- int cover = 0;
+ unsigned cover = 0;
while(num_cells)
{
@@ -276,7 +276,7 @@ namespace agg
}
}
}
-
+
if(sl.num_spans()) break;
++m_scan_y;
}
@@ -294,7 +294,7 @@ namespace agg
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
- const rasterizer_scanline_aa<Clip>&
+ const rasterizer_scanline_aa<Clip>&
operator = (const rasterizer_scanline_aa<Clip>&);
private:
@@ -321,32 +321,32 @@ namespace agg
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::reset()
- {
- m_outline.reset();
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::reset()
+ {
+ m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
- {
- m_filling_rule = filling_rule;
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
+ {
+ m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
- m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
+ m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::reset_clipping()
{
reset();
@@ -354,7 +354,7 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::close_polygon()
{
if(m_status == status_line_to)
@@ -365,56 +365,56 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
- m_clipper.move_to(m_start_x = conv_type::downscale(x),
+ m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
{
- m_clipper.line_to(m_outline,
- conv_type::downscale(x),
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
- {
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
+ {
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
- m_clipper.move_to(m_start_x = conv_type::upscale(x),
- m_start_y = conv_type::upscale(y));
+ m_clipper.move_to(m_start_x = conv_type::upscale(x),
+ m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
- {
- m_clipper.line_to(m_outline,
- conv_type::upscale(x),
- conv_type::upscale(y));
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
+ {
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x),
+ conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
- if(is_move_to(cmd))
+ if(is_move_to(cmd))
{
move_to_d(x, y);
}
- else
+ else
if(is_vertex(cmd))
{
line_to_d(x, y);
@@ -427,32 +427,32 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
- m_clipper.line_to(m_outline,
- conv_type::downscale(x2),
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
-
+
//------------------------------------------------------------------------
- template<class Clip>
- void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
- m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
- m_clipper.line_to(m_outline,
- conv_type::upscale(x2),
- conv_type::upscale(y2));
+ m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x2),
+ conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
void rasterizer_scanline_aa<Clip>::sort()
{
if(m_auto_close) close_polygon();
@@ -460,12 +460,12 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
- if(m_outline.total_cells() == 0)
+ if(m_outline.total_cells() == 0)
{
return false;
}
@@ -475,14 +475,14 @@ namespace agg
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
- if(m_outline.total_cells() == 0 ||
- y < m_outline.min_y() ||
- y > m_outline.max_y())
+ if(m_outline.total_cells() == 0 ||
+ y < m_outline.min_y() ||
+ y > m_outline.max_y())
{
return false;
}
@@ -491,7 +491,7 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class Clip>
+ template<class Clip>
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
@@ -507,4 +507,3 @@ namespace agg
#endif
-
diff --git a/deps/mapnik/build.py b/deps/mapnik/build.py
index 0d6dc84..76529fb 100644
--- a/deps/mapnik/build.py
+++ b/deps/mapnik/build.py
@@ -7,7 +7,7 @@ subdirs = {
'./sparsehash':{'dir':'sparsehash','glob':'*'},
'./sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'},
'../agg/include':{'dir':'agg','glob':'agg*'},
- '../mapbox':{'dir':'mapbox/variant','glob':'*/*.hpp'}
+ '../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'}
}
if 'install' in COMMAND_LINE_TARGETS:
diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp
index a790c1d..2671201 100644
--- a/include/mapnik/box2d.hpp
+++ b/include/mapnik/box2d.hpp
@@ -40,9 +40,8 @@ struct trans_affine;
namespace mapnik {
-/*!
- * A spatial envelope (i.e. bounding box) which also defines some basic operators.
- */
+// A spatial envelope (i.e. bounding box) which also defines some basic operators.
+
template <typename T> class MAPNIK_DECL box2d
: boost::equality_comparable<box2d<T> ,
boost::addable<box2d<T>,
diff --git a/src/box2d.cpp b/include/mapnik/box2d_impl.hpp
similarity index 98%
copy from src/box2d.cpp
copy to include/mapnik/box2d_impl.hpp
index 7d54233..7f3e9d1 100644
--- a/src/box2d.cpp
+++ b/include/mapnik/box2d_impl.hpp
@@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
- * Copyright (C) 2015 Artem Pavlenko
+ * Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -493,9 +493,4 @@ box2d<T>& box2d<T>::operator*=(agg::trans_affine const& tr)
expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
return *this;
}
-
-template class box2d<int>;
-template class box2d<float>;
-template class box2d<double>;
-
}
diff --git a/include/mapnik/config.hpp b/include/mapnik/config.hpp
index 6461a6c..a05caf9 100644
--- a/include/mapnik/config.hpp
+++ b/include/mapnik/config.hpp
@@ -53,6 +53,17 @@
#define PROJ_ENVELOPE_POINTS 20
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
-#define BOOST_MPL_LIMIT_VECTOR_SIZE 30
+
+#ifndef BOOST_MPL_LIMIT_VECTOR_SIZE
+ #define BOOST_MPL_LIMIT_VECTOR_SIZE 30
+#else
+ #warning "WARNING: BOOST_MPL_LIMIT_VECTOR_SIZE is already defined. Ensure config.hpp is included before any Boost headers"
+#endif
+
+#ifndef BOOST_MPL_LIMIT_LIST_SIZE
+ #define BOOST_MPL_LIMIT_LIST_SIZE 30
+#else
+ #warning "WARNING: BOOST_MPL_LIMIT_LIST_SIZE is already defined. Ensure config.hpp is included before any Boost headers"
+#endif
#endif // MAPNIK_CONFIG_HPP
diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp
index cf5e5b9..8429095 100644
--- a/include/mapnik/debug.hpp
+++ b/include/mapnik/debug.hpp
@@ -69,15 +69,15 @@ public:
static void set_severity(severity_type severity_level)
{
-//#ifdef MAPNIK_THREADSAFE
-// std::lock_guard<std::mutex> lock(severity_mutex_);
-//#endif
severity_level_ = severity_level;
}
// per object security levels
static severity_type get_object_severity(std::string const& object_name)
{
+#ifdef MAPNIK_THREADSAFE
+ std::lock_guard<std::mutex> lock(severity_mutex_);
+#endif
severity_map::iterator it = object_severity_level_.find(object_name);
if (object_name.empty() || it == object_severity_level_.end())
{
diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp
index 40be6b9..ad28f01 100644
--- a/include/mapnik/expression_grammar_impl.hpp
+++ b/include/mapnik/expression_grammar_impl.hpp
@@ -102,6 +102,7 @@ unary_function_types::unary_function_types()
("tan", tan_impl())
("atan", atan_impl())
("exp", exp_impl())
+ ("log", log_impl())
("abs", abs_impl())
("length",length_impl())
;
diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp
index f340c83..1300d32 100644
--- a/include/mapnik/feature.hpp
+++ b/include/mapnik/feature.hpp
@@ -154,7 +154,7 @@ public:
inline bool has_key(context_type::key_type const& key) const
{
- return (ctx_->mapping_.find(key) != ctx_->mapping_.end());
+ return (ctx_->mapping_.count(key) == 1);
}
inline value_type const& get(context_type::key_type const& key) const
diff --git a/include/mapnik/featureset.hpp b/include/mapnik/featureset.hpp
index c6829d1..6886d87 100644
--- a/include/mapnik/featureset.hpp
+++ b/include/mapnik/featureset.hpp
@@ -41,8 +41,23 @@ struct MAPNIK_DECL Featureset : private util::noncopyable
virtual ~Featureset() {}
};
+
+struct MAPNIK_DECL empty_featureset final : Featureset
+{
+ feature_ptr next()
+ {
+ return feature_ptr();
+ }
+ ~empty_featureset() {}
+};
+
using featureset_ptr = std::shared_ptr<Featureset>;
+inline featureset_ptr make_empty_featureset()
+{
+ return std::make_shared<empty_featureset>();
+}
+
}
#endif // MAPNIK_FEATURESET_HPP
diff --git a/include/mapnik/function_call.hpp b/include/mapnik/function_call.hpp
index efbaa5f..f50829b 100644
--- a/include/mapnik/function_call.hpp
+++ b/include/mapnik/function_call.hpp
@@ -50,6 +50,17 @@ struct exp_impl
};
+// log
+struct log_impl
+{
+ //using type = T;
+ value_type operator() (value_type const& val) const
+ {
+ return std::log(val.to_double());
+ }
+
+};
+
// sin
struct sin_impl
{
diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp
index 7063685..aae2bf3 100644
--- a/include/mapnik/geometry.hpp
+++ b/include/mapnik/geometry.hpp
@@ -24,43 +24,41 @@
#define MAPNIK_GEOMETRY_HPP
#include <mapnik/util/variant.hpp>
-#include <mapnik/coord.hpp>
#include <vector>
#include <type_traits>
#include <cstddef>
-
-
namespace mapnik { namespace geometry {
template <typename T>
struct point
{
- using value_type = T;
+ using coord_type = T;
point() {}
point(T x_, T y_)
: x(x_), y(y_)
{}
- // temp - remove when geometry is templated on value_type
- point(mapnik::coord<double, 2> const& c)
- : x(c.x), y(c.y) {}
- friend inline bool operator== (point<T> const& a, point<T> const& b)
- {
- return a.x == b.x && a.y == b.y;
- }
- friend inline bool operator!= (point<T> const& a, point <T> const& b)
- {
- return a.x != b.x || a.y != b.y;
- }
- value_type x;
- value_type y;
+ coord_type x;
+ coord_type y;
};
+template <typename T>
+bool operator==(point<T> const& lhs, point<T> const& rhs)
+{
+ return lhs.x == rhs.x && lhs.y == rhs.y;
+}
+
+template <typename T>
+bool operator!=(point<T> const& lhs, point<T> const& rhs)
+{
+ return !(lhs == rhs);
+}
template <typename T>
struct line_string : std::vector<point<T> >
{
+ using coord_type = T;
line_string() = default;
explicit line_string(std::size_t size)
: std::vector<point<T> >(size) {}
@@ -71,6 +69,7 @@ struct line_string : std::vector<point<T> >
template <typename T>
struct linear_ring : line_string<T>
{
+ using coord_type = T;
linear_ring() = default;
explicit linear_ring(std::size_t size)
: line_string<T>(size) {}
@@ -86,8 +85,9 @@ using rings_container = std::vector<linear_ring<T>>;
template <typename T, template <typename> class InteriorRings = rings_container>
struct polygon
{
- linear_ring<T> exterior_ring;
+ using coord_type = T;
using rings_container = InteriorRings<T>;
+ linear_ring<T> exterior_ring;
rings_container interior_rings;
inline void set_exterior_ring(linear_ring<T> && ring)
@@ -109,13 +109,22 @@ struct polygon
};
template <typename T>
-struct multi_point : line_string<T> {};
+struct multi_point : line_string<T>
+{
+ using coord_type = T;
+};
template <typename T>
-struct multi_line_string : std::vector<line_string<T>> {};
+struct multi_line_string : std::vector<line_string<T>>
+{
+ using coord_type = T;
+};
template <typename T>
-struct multi_polygon : std::vector<polygon<T>> {};
+struct multi_polygon : std::vector<polygon<T>>
+{
+ using coord_type = T;
+};
template <typename T>
struct geometry_collection;
@@ -131,23 +140,32 @@ using geometry_base = mapnik::util::variant<geometry_empty,
multi_point<T>,
multi_line_string<T>,
multi_polygon<T>,
- mapnik::util::recursive_wrapper<geometry_collection<T> > >;
+ geometry_collection<T> >;
template <typename T>
struct geometry : geometry_base<T>
{
- using value_type = T;
+ using coord_type = T;
+
+#if __cpp_inheriting_constructors >= 200802
+
+ using geometry_base<T>::geometry_base;
- geometry()
- : geometry_base<T>() {} // empty
+#else
+
+ geometry() = default;
template <typename G>
geometry(G && geom)
: geometry_base<T>(std::forward<G>(geom)) {}
+#endif
};
template <typename T>
-struct geometry_collection : std::vector<geometry<T>> {};
+struct geometry_collection : std::vector<geometry<T>>
+{
+ using coord_type = T;
+};
}}
diff --git a/include/mapnik/geometry_envelope.hpp b/include/mapnik/geometry_envelope.hpp
index 17b8fcb..981b978 100644
--- a/include/mapnik/geometry_envelope.hpp
+++ b/include/mapnik/geometry_envelope.hpp
@@ -26,11 +26,11 @@
#include <mapnik/config.hpp>
#include <mapnik/box2d.hpp>
-namespace mapnik {
+namespace mapnik {
namespace geometry {
template <typename T>
-MAPNIK_DECL mapnik::box2d<double> envelope(T const& geom);
+MAPNIK_DECL auto envelope(T const& geom) -> box2d<typename T::coord_type>;
} // end ns geometry
} // end ns mapnik
diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry_envelope_impl.hpp
index 5c39bc3..2ebddb9 100644
--- a/include/mapnik/geometry_envelope_impl.hpp
+++ b/include/mapnik/geometry_envelope_impl.hpp
@@ -28,23 +28,24 @@ namespace mapnik { namespace geometry {
namespace detail {
+template <typename T>
struct geometry_envelope
{
- using bbox_type = box2d<double>;
+ using coord_type = T;
+ using bbox_type = box2d<coord_type>;
bbox_type & bbox;
geometry_envelope(bbox_type & bbox_)
: bbox(bbox_) {}
- template <typename T>
- void operator() (T const& geom) const
+ template <typename U>
+ void operator() (U const& geom) const
{
return mapnik::util::apply_visitor(*this, geom);
}
void operator() (mapnik::geometry::geometry_empty const&) const {}
- template <typename T>
void operator() (mapnik::geometry::point<T> const& pt) const
{
if (!bbox.valid())
@@ -54,7 +55,6 @@ struct geometry_envelope
bbox.expand_to_include(pt.x, pt.y);
}
- template <typename T>
void operator() (mapnik::geometry::line_string<T> const& line) const
{
bool first = true;
@@ -72,13 +72,11 @@ struct geometry_envelope
}
}
- template <typename T>
void operator() (mapnik::geometry::linear_ring<T> const& ring) const
{
(*this)(static_cast<mapnik::geometry::line_string<T> const&>(ring));
}
- template <typename T>
void operator() (mapnik::geometry::polygon<T> const& poly) const
{
bool first = true;
@@ -96,7 +94,6 @@ struct geometry_envelope
}
}
- template <typename T>
void operator() (mapnik::geometry::multi_point<T> const& multi_point) const
{
bool first = true;
@@ -114,7 +111,6 @@ struct geometry_envelope
}
}
- template <typename T>
void operator() (mapnik::geometry::multi_line_string<T> const& multi_line) const
{
for (auto const& line : multi_line)
@@ -123,7 +119,6 @@ struct geometry_envelope
}
}
- template <typename T>
void operator() (mapnik::geometry::multi_polygon<T> const& multi_poly) const
{
for (auto const& poly : multi_poly)
@@ -132,7 +127,6 @@ struct geometry_envelope
}
}
- template <typename T>
void operator() (mapnik::geometry::geometry_collection<T> const& collection) const
{
for (auto const& geom : collection)
@@ -145,10 +139,11 @@ struct geometry_envelope
} // end ns detail
template <typename T>
-mapnik::box2d<double> envelope(T const& geom)
+auto envelope(T const& geom) -> box2d<typename T::coord_type>
{
- box2d<double> bbox;
- detail::geometry_envelope op(bbox);
+ using coord_type = typename T::coord_type;
+ box2d<coord_type> bbox;
+ detail::geometry_envelope<coord_type> op(bbox);
op(geom);
return bbox;
}
diff --git a/include/mapnik/json/attribute_value_visitor.hpp b/include/mapnik/json/attribute_value_visitor.hpp
new file mode 100644
index 0000000..206530c
--- /dev/null
+++ b/include/mapnik/json/attribute_value_visitor.hpp
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2016 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
+ *
+ *****************************************************************************/
+
+#ifndef MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP
+#define MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP
+
+// mapnik
+#include <mapnik/value.hpp>
+#include <mapnik/unicode.hpp>
+#include <mapnik/json/stringifier.hpp>
+#include <mapnik/json/value_converters.hpp>
+
+namespace mapnik { namespace json {
+
+struct attribute_value_visitor
+{
+public:
+ attribute_value_visitor(mapnik::transcoder const& tr)
+ : tr_(tr) {}
+
+ mapnik::value operator()(std::string const& val) const
+ {
+ return mapnik::value(tr_.transcode(val.c_str()));
+ }
+
+ mapnik::value operator()(std::vector<mapnik::json::json_value> const& array) const
+ {
+ std::string str = stringifier()(array);
+ return mapnik::value(tr_.transcode(str.c_str()));
+ }
+
+ mapnik::value operator()(std::vector<std::pair<std::string, mapnik::json::json_value> > const& object) const
+ {
+ std::string str = stringifier()(object);
+ return mapnik::value(tr_.transcode(str.c_str()));
+ }
+
+ template <typename T>
+ mapnik::value operator()(T const& val) const
+ {
+ return mapnik::value(val);
+ }
+
+ mapnik::transcoder const& tr_;
+};
+
+}}
+
+#endif //MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP
diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
index 8a7fc33..25ddbcd 100644
--- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
+++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
@@ -110,7 +110,7 @@ extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_bo
>> *((json.key_value - lit("\"features\"")) >> lit(','))
>> lit("\"features\"")
>> lit(':'))
- >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
+ >> lit('[') >> -(feature(_r1,_a) % lit(',')) >> lit(']')
;
feature = raw[lit('{')[_a = 1]
@@ -148,13 +148,10 @@ extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_bo
json.value = json.object | json.array | json.string_ | json.number
;
- json.pairs = json.key_value % lit(',')
+ json.key_value = json.string_ >> lit(':') >> json.value
;
- json.key_value = (json.string_ >> lit(':') >> json.value)
- ;
-
- json.object = lit('{') >> *json.pairs >> lit('}')
+ json.object = lit('{') >> json.key_value % lit(',') >> lit('}')
;
json.array = lit('[')
diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp
index ae59e3b..c329eb7 100644
--- a/include/mapnik/json/feature_grammar.hpp
+++ b/include/mapnik/json/feature_grammar.hpp
@@ -24,14 +24,10 @@
#define MAPNIK_FEATURE_GRAMMAR_HPP
// mapnik
-#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/value.hpp>
#include <mapnik/feature.hpp>
-#include <mapnik/unicode.hpp>
-#include <mapnik/value.hpp>
-#include <mapnik/json/generic_json.hpp>
-#include <mapnik/json/value_converters.hpp>
-
+#include <mapnik/json/geometry_grammar.hpp>
+#include <mapnik/json/attribute_value_visitor.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
@@ -45,27 +41,6 @@ namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace fusion = boost::fusion;
-class attribute_value_visitor
-
-{
-public:
- attribute_value_visitor(mapnik::transcoder const& tr)
- : tr_(tr) {}
-
- mapnik::value operator()(std::string const& val) const
- {
- return mapnik::value(tr_.transcode(val.c_str()));
- }
-
- template <typename T>
- mapnik::value operator()(T const& val) const
- {
- return mapnik::value(val);
- }
-
- mapnik::transcoder const& tr_;
-};
-
struct put_property
{
using result_type = void;
@@ -101,9 +76,6 @@ struct feature_grammar : qi::grammar<Iterator, void(FeatureType&), space_type>
qi::rule<Iterator, space_type> feature_type;
qi::rule<Iterator,void(FeatureType &),space_type> properties;
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;
- qi::rule<Iterator, json_value(), space_type> attribute_value;
- qi::rule<Iterator, qi::locals<std::int32_t>, std::string(), space_type> stringify_object;
- qi::rule<Iterator, qi::locals<std::int32_t>, std::string(), space_type> stringify_array;
// functions
phoenix::function<put_property> put_property_;
phoenix::function<set_geometry_impl> set_geometry;
diff --git a/include/mapnik/json/feature_grammar_impl.hpp b/include/mapnik/json/feature_grammar_impl.hpp
index 61a23f9..0fc4205 100644
--- a/include/mapnik/json/feature_grammar_impl.hpp
+++ b/include/mapnik/json/feature_grammar_impl.hpp
@@ -50,23 +50,22 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
using phoenix::construct;
// generic json types
- json_.value = json_.object | json_.array | json_.string_ | json_.number
+ json_.value = json_.object | json_.array | json_.string_ | json_.number
;
- json_.pairs = json_.key_value % lit(',')
- ;
-
- json_.key_value = (json_.string_ > lit(':') > json_.value)
+ json_.key_value = json_.string_ > lit(':') > json_.value
;
json_.object = lit('{')
- > *json_.pairs
+ > -(json_.key_value % lit(','))
> lit('}')
;
+
json_.array = lit('[')
- > json_.value > *(lit(',') > json_.value)
+ > -(json_.value % lit(','))
> lit(']')
;
+
json_.number = json_.strict_double[_val = json_.double_converter(_1)]
| json_.int__[_val = json_.integer_converter(_1)]
| lit("true") [_val = true]
@@ -95,24 +94,13 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
> lit(':') > ((lit('{') > -attributes(_r1) > lit('}')) | lit("null"))
;
- attributes = (json_.string_ [_a = _1] > lit(':') > attribute_value [put_property_(_r1,_a,_1)]) % lit(',')
- ;
-
- attribute_value %= json_.number | json_.string_ | stringify_object | stringify_array
- ;
-
- stringify_object %= char_('{')[_a = 1 ] > *(eps(_a > 0) > (char_('{')[_a +=1] | char_('}')[_a -=1] | char_))
- ;
-
- stringify_array %= char_('[')[_a = 1 ] > *(eps(_a > 0) > (char_('[')[_a +=1] | char_(']')[_a -=1] | char_))
+ attributes = (json_.string_ [_a = _1] > lit(':') > json_.value [put_property_(_r1,_a,_1)]) % lit(',')
;
feature.name("Feature");
feature_type.name("type");
properties.name("properties");
attributes.name("Attributes");
- attribute_value.name("Attribute Value");
-
on_error<fail>(feature, error_handler(_1, _2, _3, _4));
}
diff --git a/include/mapnik/json/generic_json.hpp b/include/mapnik/json/generic_json.hpp
index 3313410..7ea1bc0 100644
--- a/include/mapnik/json/generic_json.hpp
+++ b/include/mapnik/json/generic_json.hpp
@@ -31,15 +31,47 @@
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
+#include <boost/fusion/include/std_pair.hpp>
#pragma GCC diagnostic pop
+#include <vector>
+
namespace mapnik { namespace json {
namespace qi = boost::spirit::qi;
namespace standard = boost::spirit::standard;
namespace phoenix = boost::phoenix;
using space_type = standard::space_type;
-using json_value = mapnik::util::variant<value_null,value_bool, value_integer, value_double, std::string>;
+
+struct json_value;
+
+using json_array = std::vector<json_value>;
+using json_object_element = std::pair<std::string, json_value>;
+using json_object = std::vector<json_object_element>;
+using json_value_base = mapnik::util::variant<value_null,
+ value_bool,
+ value_integer,
+ value_double,
+ std::string,
+ mapnik::util::recursive_wrapper<json_array>,
+ mapnik::util::recursive_wrapper<json_object> >;
+struct json_value : json_value_base
+{
+#if __cpp_inheriting_constructors >= 200802
+
+ using json_value_base::json_value_base;
+
+#else
+
+ json_value() = default;
+
+ template <typename T>
+ json_value(T && val)
+ : json_value_base(std::forward<T>(val)) {}
+
+#endif
+};
+
using uchar = std::uint32_t; // a unicode code point
// unicode string grammar via boost/libs/spirit/example/qi/json/json/parser/grammar.hpp
@@ -121,10 +153,14 @@ unicode_string<Iterator>::unicode_string()
escape =
('x' > hex) [push_utf8(_r1, _1)]
- | ('u' > hex4) [push_utf8(_r1, _1)]
- | ('U' > hex8) [push_utf8(_r1, _1)]
- | char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)]
- | eol // continue to next line
+ |
+ ('u' > hex4) [push_utf8(_r1, _1)]
+ |
+ ('U' > hex8) [push_utf8(_r1, _1)]
+ |
+ char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)]
+ |
+ eol // continue to next line
;
char_esc =
@@ -132,7 +168,7 @@ unicode_string<Iterator>::unicode_string()
;
double_quoted =
- '"'
+ '"'
> *(char_esc(_val) | (~char_('"')) [_val += _1])
> '"'
;
@@ -141,18 +177,17 @@ unicode_string<Iterator>::unicode_string()
template <typename Iterator>
struct generic_json
{
- qi::rule<Iterator,space_type> value;
- qi::int_parser<mapnik::value_integer,10,1,-1> int__;
+ qi::rule<Iterator, json_value(), space_type> value;
+ qi::int_parser<mapnik::value_integer, 10, 1, -1> int__;
unicode_string<Iterator> string_;
- qi::rule<Iterator,space_type> key_value;
- qi::rule<Iterator,json_value(),space_type> number;
- qi::rule<Iterator,space_type> object;
- qi::rule<Iterator,space_type> array;
- qi::rule<Iterator,space_type> pairs;
- qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
+ qi::rule<Iterator, json_object_element(), space_type> key_value;
+ qi::rule<Iterator, json_value(), space_type> number;
+ qi::rule<Iterator, json_object(), space_type> object;
+ qi::rule<Iterator, json_array(), space_type> array;
+ qi::real_parser<double, qi::strict_real_policies<double>> strict_double;
// conversions
- boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_integer> > integer_converter;
- boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_double> > double_converter;
+ boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_integer>> integer_converter;
+ boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_double>> double_converter;
};
}}
diff --git a/include/mapnik/json/geometry_grammar_impl.hpp b/include/mapnik/json/geometry_grammar_impl.hpp
index 3c5693f..285be27 100644
--- a/include/mapnik/json/geometry_grammar_impl.hpp
+++ b/include/mapnik/json/geometry_grammar_impl.hpp
@@ -47,7 +47,6 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
qi::_a_type _a;
qi::_b_type _b;
qi::eps_type eps;
- qi::omit_type omit;
using qi::fail;
using qi::on_error;
using phoenix::push_back;
@@ -58,26 +57,26 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
json_.value = json_.object | json_.array | json_.string_ | json_.number
;
- json_.pairs = json_.key_value % lit(',')
- ;
-
- json_.key_value = (json_.string_ > lit(':') > json_.value)
+ json_.key_value = json_.string_ > lit(':') > json_.value
;
json_.object = lit('{')
- > *json_.pairs
+ > -(json_.key_value % lit(','))
> lit('}')
;
+
json_.array = lit('[')
- > json_.value > *(lit(',') > json_.value)
+ > -(json_.value % lit(','))
> lit(']')
;
+
json_.number = json_.strict_double
| json_.int__
| lit("true")
| lit ("false")
| lit("null")
;
+
geometry = lit('{')[_a = 0]
> (((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1])
|
@@ -85,7 +84,7 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
|
(lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_val = _1] > lit(']'))
|
- omit[json_.key_value]) % lit(',')) [create_geometry(_val,_a,_b)]
+ json_.key_value) % lit(',')) [create_geometry(_val,_a,_b)]
> lit('}')
;
diff --git a/include/mapnik/json/positions_grammar.hpp b/include/mapnik/json/positions_grammar.hpp
index bc81046..75a6b21 100644
--- a/include/mapnik/json/positions_grammar.hpp
+++ b/include/mapnik/json/positions_grammar.hpp
@@ -32,7 +32,6 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
#pragma GCC diagnostic pop
@@ -40,26 +39,6 @@ namespace mapnik { namespace json {
namespace qi = boost::spirit::qi;
-struct set_position_impl
-{
- using result_type = void;
- template <typename T0,typename T1>
- result_type operator() (T0 & coords, T1 const& pos) const
- {
- if (pos) coords = *pos;
- }
-};
-
-struct push_position_impl
-{
- using result_type = void;
- template <typename T0, typename T1>
- result_type operator() (T0 & coords, T1 const& pos) const
- {
- if (pos) coords.emplace_back(*pos);
- }
-};
-
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
struct positions_grammar :
qi::grammar<Iterator,coordinates(),space_type>
@@ -70,8 +49,6 @@ struct positions_grammar :
qi::rule<Iterator, positions(), space_type> ring;
qi::rule<Iterator, std::vector<positions>(), space_type> rings;
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
- boost::phoenix::function<set_position_impl> set_position;
- boost::phoenix::function<push_position_impl> push_position;
};
}}
diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp
index 90df172..65f2a93 100644
--- a/include/mapnik/json/positions_grammar_impl.hpp
+++ b/include/mapnik/json/positions_grammar_impl.hpp
@@ -28,12 +28,33 @@
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
// stl
#include <iostream>
#include <string>
namespace mapnik { namespace json {
+struct set_position_impl
+{
+ using result_type = void;
+ template <typename T0,typename T1>
+ result_type operator() (T0 & coords, T1 const& pos) const
+ {
+ if (pos) coords = *pos;
+ }
+};
+
+struct push_position_impl
+{
+ using result_type = void;
+ template <typename T0, typename T1>
+ result_type operator() (T0 & coords, T1 const& pos) const
+ {
+ if (pos) coords.emplace_back(*pos);
+ }
+};
+
template <typename Iterator, typename ErrorHandler>
positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & error_handler)
: positions_grammar::base_type(coords,"coordinates")
@@ -49,6 +70,9 @@ positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & erro
using qi::fail;
using qi::on_error;
+ boost::phoenix::function<set_position_impl> set_position;
+ boost::phoenix::function<push_position_impl> push_position;
+
coords = rings_array[_val = _1] | rings [_val = _1] | ring[_val = _1] | pos[set_position(_val,_1)]
;
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
diff --git a/include/mapnik/json/stringifier.hpp b/include/mapnik/json/stringifier.hpp
new file mode 100644
index 0000000..93906f6
--- /dev/null
+++ b/include/mapnik/json/stringifier.hpp
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2016 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
+ *
+ *****************************************************************************/
+
+#ifndef MAPNIK_JSON_STRINGIFIER_HPP
+#define MAPNIK_JSON_STRINGIFIER_HPP
+
+// mapnik
+#include <mapnik/json/generic_json.hpp>
+#include <mapnik/util/conversions.hpp>
+#include <mapnik/util/variant.hpp>
+// stl
+#include <string>
+
+
+namespace mapnik { namespace json {
+
+struct stringifier
+{
+ std::string operator()(std::string const& val) const
+ {
+ return "\"" + val + "\"";
+ }
+
+ std::string operator()(value_null) const
+ {
+ return "null";
+ }
+
+ std::string operator()(value_bool val) const
+ {
+ return val ? "true" : "false";
+ }
+
+ std::string operator()(value_integer val) const
+ {
+ std::string str;
+ util::to_string(str, val);
+ return str;
+ }
+
+ std::string operator()(value_double val) const
+ {
+ std::string str;
+ util::to_string(str, val);
+ return str;
+ }
+
+ std::string operator()(std::vector<mapnik::json::json_value> const& array) const
+ {
+ std::string str = "[";
+ bool first = true;
+ for (auto const& val : array)
+ {
+ if (first) first = false;
+ else str += ",";
+ str += mapnik::util::apply_visitor(*this, val);
+ }
+ str += "]";
+ return str;
+ }
+
+ std::string operator()(std::vector<std::pair<std::string, mapnik::json::json_value>> const& object) const
+ {
+ std::string str = "{";
+ bool first = true;
+ for (auto const& kv : object)
+ {
+ if (first) first = false;
+ else str += ",";
+ str += kv.first;
+ str += ":";
+ str += mapnik::util::apply_visitor(*this, kv.second);
+ }
+ str += "}";
+ return str;
+ }
+};
+
+}}
+
+
+#endif // MAPNIK_JSON_STRINGIFIER_HPP
diff --git a/include/mapnik/json/topojson_grammar.hpp b/include/mapnik/json/topojson_grammar.hpp
index eec2bb4..c21be95 100644
--- a/include/mapnik/json/topojson_grammar.hpp
+++ b/include/mapnik/json/topojson_grammar.hpp
@@ -42,6 +42,138 @@ namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
using space_type = mapnik::json::space_type;
+struct create_point
+{
+ using result_type = mapnik::topojson::point;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & coord, T1 & props) const
+ {
+ mapnik::topojson::point pt;
+ if (coord.template is<mapnik::topojson::coordinate>())
+ {
+ auto const& coord_ = coord.template get<mapnik::topojson::coordinate>();
+ pt.coord = coord_;
+ pt.props = props;
+ }
+ return pt;
+ }
+};
+
+struct create_multi_point
+{
+ using result_type = mapnik::topojson::multi_point;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & coords, T1 & props) const
+ {
+ mapnik::topojson::multi_point mpt;
+ if (coords.template is<std::vector<mapnik::topojson::coordinate>>())
+ {
+ auto const& points = coords.template get<std::vector<mapnik::topojson::coordinate>>();
+ mpt. points = points;
+ mpt.props = props;
+ }
+ return mpt;
+ }
+};
+
+struct create_line_string
+{
+ using result_type = mapnik::topojson::linestring;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & arcs, T1 & props) const
+ {
+ mapnik::topojson::linestring line;
+ if (arcs.template is<std::vector<index_type>>())
+ {
+ auto const& arcs_ = arcs.template get<std::vector<index_type>>();
+ line.rings = arcs_;
+ line.props = props;
+ }
+ return line;
+ }
+};
+
+struct create_multi_line_string
+{
+ using result_type = mapnik::topojson::multi_linestring;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & arcs, T1 & props) const
+ {
+ mapnik::topojson::multi_linestring mline;
+ if (arcs.template is<std::vector<std::vector<index_type>>>())
+ {
+ auto const& arcs_ = arcs.template get<std::vector<std::vector<index_type>>>();
+ mline.lines = arcs_;
+ mline.props = props;
+ }
+ return mline;
+ }
+};
+
+struct create_polygon
+{
+ using result_type = mapnik::topojson::polygon;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & arcs, T1 & props) const
+ {
+ mapnik::topojson::polygon poly;
+ if (arcs.template is<std::vector<std::vector<index_type>>>())
+ {
+ auto const& arcs_ = arcs.template get<std::vector<std::vector<index_type>>>();
+ poly.rings = arcs_;
+ poly.props = props;
+ }
+ return poly;
+ }
+};
+
+struct create_multi_polygon
+{
+ using result_type = mapnik::topojson::multi_polygon;
+ template <typename T0, typename T1>
+ result_type operator()(T0 & arcs, T1 & props) const
+ {
+ mapnik::topojson::multi_polygon mpoly;
+ if (arcs.template is<std::vector<std::vector<std::vector<index_type>>>>())
+ {
+ auto const& arcs_ = arcs.template get<std::vector<std::vector<std::vector<index_type>>>>();
+ mpoly.polygons = arcs_;
+ mpoly.props = props;
+ }
+ return mpoly;
+ }
+};
+
+
+struct create_geometry_impl
+{
+ using result_type = mapnik::topojson::geometry;
+ template <typename T0, typename T1, typename T2, typename T3>
+ result_type operator()(T0 geom_type, T1 & coord, T2 & arcs, T3 & props) const
+ {
+ switch (geom_type)
+ {
+ case 1: //Point
+ return create_point()(coord, props);
+ case 2: //LineString
+ return create_line_string()(arcs, props);
+ case 3: //Polygon
+ return create_polygon()(arcs, props);
+ case 4: //MultiPoint
+ return create_multi_point()(coord, props);
+ case 5: //MultiLineString
+ return create_multi_line_string()(arcs, props);
+ case 6: //MultiPolygon
+ return create_multi_polygon()(arcs, props);
+ default:
+ break;
+ }
+ return mapnik::topojson::geometry(); //empty
+ }
+};
+
+using coordinates_type = util::variant<coordinate,std::vector<coordinate>>;
+using arcs_type = util::variant<std::vector<index_type>, std::vector<std::vector<index_type>>, std::vector<std::vector<std::vector<index_type>>>>;
template <typename Iterator, typename ErrorHandler = json::error_handler<Iterator> >
struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
@@ -55,24 +187,18 @@ private:
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::geometry>()> objects;
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::arc>()> arcs;
qi::rule<Iterator, space_type, mapnik::topojson::arc()> arc;
- qi::rule<Iterator, space_type, mapnik::topojson::coordinate()> coordinate;
+ qi::rule<Iterator, space_type, mapnik::topojson::coordinate()> coordinate_;
+ qi::rule<Iterator, space_type, coordinates_type()> coordinates;
qi::rule<Iterator, space_type, mapnik::topojson::transform()> transform;
qi::rule<Iterator, space_type, mapnik::topojson::bounding_box()> bbox;
- qi::rule<Iterator, space_type, mapnik::topojson::geometry() > geometry;
- qi::rule<Iterator, space_type, mapnik::topojson::point()> point;
- qi::rule<Iterator, space_type, mapnik::topojson::multi_point()> multi_point;
- qi::rule<Iterator, space_type, mapnik::topojson::linestring()> linestring;
- qi::rule<Iterator, space_type, mapnik::topojson::multi_linestring()> multi_linestring;
- qi::rule<Iterator, space_type, mapnik::topojson::polygon()> polygon;
- qi::rule<Iterator, space_type, mapnik::topojson::multi_polygon()> multi_polygon;
+ qi::rule<Iterator, qi::locals<int, coordinates_type, arcs_type, properties>, mapnik::topojson::geometry(), space_type> geometry;
qi::rule<Iterator, space_type, void(std::vector<mapnik::topojson::geometry>&)> geometry_collection;
qi::rule<Iterator, space_type, std::vector<index_type>()> ring;
+ qi::rule<Iterator, space_type, std::vector<std::vector<index_type>>()> rings;
+ qi::rule<Iterator, space_type, arcs_type()> rings_array;
// properties
- qi::rule<Iterator, space_type, mapnik::topojson::properties()> properties;
- qi::rule<Iterator, space_type, mapnik::topojson::properties()> attributes;
- qi::rule<Iterator, space_type, mapnik::json::json_value()> attribute_value;
- // id
- qi::rule<Iterator,space_type> id;
+ qi::rule<Iterator, space_type, mapnik::topojson::properties()> properties_;
+ qi::symbols<char, int> geometry_type_dispatch;
};
}}
diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp
index ca86079..f868cef 100644
--- a/include/mapnik/json/topojson_grammar_impl.hpp
+++ b/include/mapnik/json/topojson_grammar_impl.hpp
@@ -58,42 +58,6 @@ BOOST_FUSION_ADAPT_STRUCT(
)
BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::point,
- (mapnik::topojson::coordinate, coord)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::multi_point,
- (std::vector<mapnik::topojson::coordinate>, points)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::linestring,
- (mapnik::topojson::index_type, ring)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::multi_linestring,
- (std::vector<mapnik::topojson::index_type>, rings)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::polygon,
- (std::vector<std::vector<mapnik::topojson::index_type> >, rings)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::multi_polygon,
- (std::vector<std::vector<std::vector<mapnik::topojson::index_type> > >, polygons)
- (boost::optional<mapnik::topojson::properties>, props)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
mapnik::topojson::topology,
(std::vector<mapnik::topojson::geometry>, geometries)
(std::vector<mapnik::topojson::arc>, arcs)
@@ -101,6 +65,8 @@ BOOST_FUSION_ADAPT_STRUCT(
(boost::optional<mapnik::topojson::bounding_box>, bbox)
)
+
+
namespace mapnik { namespace topojson {
namespace qi = boost::spirit::qi;
@@ -121,30 +87,43 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
qi::_3_type _3;
qi::_4_type _4;
qi::_r1_type _r1;
+ qi::_a_type _a;
+ qi::_b_type _b;
+ qi::_c_type _c;
+ qi::_d_type _d;
using qi::fail;
using qi::on_error;
using phoenix::push_back;
using phoenix::construct;
+ geometry_type_dispatch.add
+ ("\"Point\"",1)
+ ("\"LineString\"",2)
+ ("\"Polygon\"",3)
+ ("\"MultiPoint\"",4)
+ ("\"MultiLineString\"",5)
+ ("\"MultiPolygon\"",6)
+ ("\"GeometryCollection\"",7)
+ ;
+
// error handler
boost::phoenix::function<ErrorHandler> const error_handler;
-
+ boost::phoenix::function<create_geometry_impl> const create_geometry;
// generic JSON types
json.value = json.object | json.array | json.string_ | json.number
;
- json.pairs = json.key_value % lit(',')
+ json.key_value = json.string_ > lit(':') > json.value
;
- json.key_value = (json.string_ >> lit(':') >> json.value)
- ;
-
- json.object = lit('{') >> *json.pairs >> lit('}')
+ json.object = lit('{')
+ > -(json.key_value % lit(','))
+ > lit('}')
;
json.array = lit('[')
- >> json.value >> *(lit(',') >> json.value)
- >> lit(']')
+ > -(json.value % lit(','))
+ > lit(']')
;
json.number = json.strict_double[_val = json.double_converter(_1)]
@@ -181,101 +160,58 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
>> lit('{')
>> -((omit[json.string_]
>> lit(':')
- >> (geometry_collection(_val) | geometry)) % lit(','))
+ >> (geometry_collection(_val) | geometry[push_back(_val, _1)]) % lit(',')))
>> lit('}')
;
- geometry =
- point |
- linestring |
- polygon |
- multi_point |
- multi_linestring |
- multi_polygon |
- omit[json.object]
+ geometry = lit('{')[_a = 0]
+ > ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1])
+ |
+ (lit("\"coordinates\"") > lit(':') > coordinates[_b = _1])
+ |
+ (lit("\"arcs\"") > lit(':') > rings_array[_c = _1])
+ |
+ properties_[_d = _1]
+ |
+ json.key_value) % lit(',')
+ > lit('}')[_val = create_geometry(_a, _b, _c, _d)]
;
- geometry_collection = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
- >> -(lit(',') >> omit[bbox])
- >> lit(',') >> lit("\"geometries\"") >> lit(':') >> lit('[') >> -(geometry[push_back(_r1, _1)] % lit(','))
- >> lit(']')
- >> lit('}')
- ;
- point = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"Point\"")
- >> -(lit(',') >> omit[bbox])
- >> ((lit(',') >> lit("\"coordinates\"") >> lit(':') >> coordinate)
- ^ (lit(',') >> properties) /*^ (lit(',') >> omit[id])*/)
- >> lit('}')
- ;
-
- multi_point = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"MultiPoint\"")
- >> -(lit(',') >> omit[bbox])
- >> ((lit(',') >> lit("\"coordinates\"") >> lit(':')
- >> lit('[') >> -(coordinate % lit(',')) >> lit(']'))
- ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
- >> lit('}')
- ;
-
- linestring = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"LineString\"")
- >> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[') >> int_ >> lit(']'))
- ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
- >> lit('}')
- ;
-
- multi_linestring = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"MultiLineString\"")
- >> -(lit(',') >> omit[bbox])
- >> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[')
- >> -((lit('[') >> int_ >> lit(']')) % lit(',')) >> lit(']'))
- ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
- >> lit('}')
- ;
- polygon = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"Polygon\"")
- >> -(lit(',') >> omit[bbox])
- >> ((lit(',') >> lit("\"arcs\"") >> lit(':')
- >> lit('[') >> -(ring % lit(',')) >> lit(']'))
- ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
+ geometry_collection = lit('{')
+ >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
+ >> lit(',') >> lit("\"geometries\"") >> lit(':')
+ >> lit('[')
+ >> -(geometry[push_back(_r1, _1)] % lit(','))
+ >> lit(']')
>> lit('}')
;
- multi_polygon = lit('{')
- >> lit("\"type\"") >> lit(':') >> lit("\"MultiPolygon\"")
- >> -(lit(',') >> omit[bbox])
- >> ((lit(',') >> lit("\"arcs\"") >> lit(':')
- >> lit('[')
- >> -((lit('[') >> -(ring % lit(',')) >> lit(']')) % lit(','))
- >> lit(']')) ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
- >> lit('}')
+ ring = lit('[') >> -(int_ % lit(',')) >> lit(']')
;
-
- id = lit("\"id\"") >> lit(':') >> omit[json.value]
+ rings = lit('[') >> -(ring % lit(',')) >> lit(']')
;
-
- ring = lit('[') >> -(int_ % lit(',')) >> lit(']')
+ rings_array = lit('[') >> -(rings % lit(',')) >> lit(']')
+ |
+ rings
+ |
+ ring
;
- properties = lit("\"properties\"")
+ properties_ = lit("\"properties\"")
>> lit(':')
- >> (( lit('{') >> attributes >> lit('}')) | json.object)
- ;
-
- attributes = (json.string_ >> lit(':') >> attribute_value) % lit(',')
+ >> lit('{') >> (json.string_ >> lit(':') >> json.value) % lit(',') >> lit('}')
;
- attribute_value %= json.number | json.string_ ;
-
arcs = lit("\"arcs\"") >> lit(':')
>> lit('[') >> -( arc % lit(',')) >> lit(']') ;
- arc = lit('[') >> -(coordinate % lit(',')) >> lit(']') ;
+ arc = lit('[') >> -(coordinate_ % lit(',')) >> lit(']') ;
+
+ coordinate_ = lit('[') > double_ > lit(',') > double_ > lit(']');
- coordinate = lit('[') >> double_ >> lit(',') >> double_ >> lit(']');
+ coordinates = (lit('[') >> coordinate_ % lit(',') > lit(']'))
+ | coordinate_;
topology.name("topology");
transform.name("transform");
@@ -283,13 +219,9 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
arc.name("arc");
arcs.name("arcs");
json.value.name("value");
- coordinate.name("coordinate");
-
- point.name("point");
- multi_point.name("multi_point");
- linestring.name("linestring");
- polygon.name("polygon");
- multi_polygon.name("multi_polygon");
+ coordinate_.name("coordinate");
+ geometry.name("geometry");
+ properties_.name("properties");
geometry_collection.name("geometry_collection");
// error handler
on_error<fail>(topology, error_handler(_1, _2, _3, _4));
diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp
index c4de306..40a2c91 100644
--- a/include/mapnik/json/topojson_utils.hpp
+++ b/include/mapnik/json/topojson_utils.hpp
@@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
- * Copyright (C) 2015 Artem Pavlenko
+ * Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
#include <mapnik/box2d.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/json/topology.hpp>
+#include <mapnik/json/attribute_value_visitor.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/geometry_adapters.hpp>
#include <mapnik/geometry_correct.hpp>
@@ -39,6 +40,11 @@ struct bounding_box_visitor
: topo_(topo),
num_arcs_(topo_.arcs.size()) {}
+ box2d<double> operator() (mapnik::topojson::empty const&) const
+ {
+ return box2d<double>();
+ }
+
box2d<double> operator() (mapnik::topojson::point const& pt) const
{
double x = pt.coord.x;
@@ -81,50 +87,15 @@ struct bounding_box_visitor
box2d<double> operator() (mapnik::topojson::linestring const& line) const
{
box2d<double> bbox;
+ bool first = true;
if (num_arcs_ > 0)
{
- index_type index = line.ring;
- index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
- {
- bool first = true;
- double px = 0, py = 0;
- auto const& arcs = topo_.arcs[arc_index];
- for (auto pt : arcs.coordinates)
- {
- double x = pt.x;
- double y = pt.y;
- if (topo_.tr)
- {
- x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
- }
- if (first)
- {
- first = false;
- bbox.init(x, y, x, y);
- }
- else
- {
- bbox.expand_to_include(x, y);
- }
- }
- }
- }
- return bbox;
- }
-
- box2d<double> operator() (mapnik::topojson::multi_linestring const& multi_line) const
- {
- box2d<double> bbox;
- if (num_arcs_ > 0)
- {
- bool first = true;
- for (auto index : multi_line.rings)
+ for (auto index : line.rings)
{
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
+
double px = 0, py = 0;
auto const& arcs = topo_.arcs[arc_index];
for (auto pt : arcs.coordinates)
@@ -152,6 +123,47 @@ struct bounding_box_visitor
return bbox;
}
+ box2d<double> operator() (mapnik::topojson::multi_linestring const& multi_line) const
+ {
+ box2d<double> bbox;
+ if (num_arcs_ > 0)
+ {
+ bool first = true;
+ for (auto const& line : multi_line.lines)
+ {
+ for (auto index : line)
+ {
+ index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
+ {
+ double px = 0, py = 0;
+ auto const& arcs = topo_.arcs[arc_index];
+ for (auto pt : arcs.coordinates)
+ {
+ double x = pt.x;
+ double y = pt.y;
+ if (topo_.tr)
+ {
+ x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
+ y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ }
+ if (first)
+ {
+ first = false;
+ bbox.init(x, y, x, y);
+ }
+ else
+ {
+ bbox.expand_to_include(x, y);
+ }
+ }
+ }
+ }
+ }
+ }
+ return bbox;
+ }
+
box2d<double> operator() (mapnik::topojson::polygon const& poly) const
{
box2d<double> bbox;
@@ -246,26 +258,6 @@ private:
};
namespace {
-struct attribute_value_visitor
-
-{
-public:
- attribute_value_visitor(mapnik::transcoder const& tr)
- : tr_(tr) {}
-
- mapnik::value operator()(std::string const& val) const
- {
- return mapnik::value(tr_.transcode(val.c_str()));
- }
-
- template <typename T>
- mapnik::value operator()(T const& val) const
- {
- return mapnik::value(val);
- }
-
- mapnik::transcoder const& tr_;
-};
template <typename T>
void assign_properties(mapnik::feature_impl & feature, T const& geom, mapnik::transcoder const& tr)
@@ -274,7 +266,7 @@ void assign_properties(mapnik::feature_impl & feature, T const& geom, mapnik::tr
{
for (auto const& p : *geom.props)
{
- feature.put_new(std::get<0>(p), mapnik::util::apply_visitor(attribute_value_visitor(tr),std::get<1>(p)));
+ feature.put_new(std::get<0>(p), mapnik::util::apply_visitor(mapnik::json::attribute_value_visitor(tr),std::get<1>(p)));
}
}
}
@@ -333,29 +325,31 @@ struct feature_generator
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
if (num_arcs_ > 0)
{
- index_type index = line.ring;
- index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
- {
- auto const& arcs = topo_.arcs[arc_index];
- double px = 0, py = 0;
- mapnik::geometry::line_string<double> line_string;
- line_string.reserve(arcs.coordinates.size());
+ mapnik::geometry::line_string<double> line_string;
- for (auto pt : arcs.coordinates)
+ for (auto index : line.rings)
+ {
+ index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
- double x = pt.x;
- double y = pt.y;
- if (topo_.tr)
+ auto const& arcs = topo_.arcs[arc_index];
+ double px = 0, py = 0;
+ line_string.reserve(line_string.size() + arcs.coordinates.size());
+ for (auto pt : arcs.coordinates)
{
- x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ double x = pt.x;
+ double y = pt.y;
+ if (topo_.tr)
+ {
+ x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
+ y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ }
+ line_string.add_coord(x,y);
}
- line_string.add_coord(x,y);
}
- feature->set_geometry(std::move(line_string));
- assign_properties(*feature, line, tr_);
}
+ feature->set_geometry(std::move(line_string));
+ assign_properties(*feature, line, tr_);
}
return feature;
}
@@ -367,30 +361,34 @@ struct feature_generator
{
mapnik::geometry::multi_line_string<double> multi_line_string;
bool hit = false;
- multi_line_string.reserve(multi_line.rings.size());
- for (auto const& index : multi_line.rings)
+ for (auto const& line : multi_line.lines)
{
- index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
+ multi_line_string.reserve(multi_line_string.size() + line.size());
+ mapnik::geometry::line_string<double> line_string;
+ for (auto index : line)
{
- hit = true;
- double px = 0, py = 0;
- mapnik::geometry::line_string<double> line_string;
- auto const& arcs = topo_.arcs[arc_index];
- line_string.reserve(arcs.coordinates.size());
- for (auto pt : arcs.coordinates)
+ index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
- double x = pt.x;
- double y = pt.y;
- if (topo_.tr)
+ hit = true;
+ double px = 0, py = 0;
+ auto const& arcs = topo_.arcs[arc_index];
+ line_string.reserve(line_string.size() + arcs.coordinates.size());
+ for (auto pt : arcs.coordinates)
{
- x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ double x = pt.x;
+ double y = pt.y;
+ if (topo_.tr)
+ {
+ x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
+ y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ }
+ line_string.add_coord(x, y);
}
- line_string.add_coord(x, y);
+
}
- multi_line_string.push_back(std::move(line_string));
}
+ multi_line_string.push_back(std::move(line_string));
}
if (hit)
{
@@ -439,7 +437,7 @@ struct feature_generator
}
processed_coords.emplace_back(coordinate{x,y});
}
-
+ linear_ring.reserve(linear_ring.size() + processed_coords.size());
if (reverse)
{
for (auto const& c : processed_coords | boost::adaptors::reversed)
@@ -513,14 +511,15 @@ struct feature_generator
if (topo_.tr)
{
- x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ transform const& tr = *topo_.tr;
+ x = (px += x) * tr.scale_x + tr.translate_x;
+ y = (py += y) * tr.scale_y + tr.translate_y;
}
processed_coords.emplace_back(coordinate{x,y});
}
using namespace boost::adaptors;
-
+ linear_ring.reserve(linear_ring.size() + processed_coords.size());
if (reverse)
{
for (auto const& c : (processed_coords | reversed))
diff --git a/include/mapnik/json/topology.hpp b/include/mapnik/json/topology.hpp
index 05f35b4..048c855 100644
--- a/include/mapnik/json/topology.hpp
+++ b/include/mapnik/json/topology.hpp
@@ -62,13 +62,13 @@ struct multi_point
struct linestring
{
- index_type ring ;
+ std::vector<index_type> rings ;
boost::optional<properties> props;
};
struct multi_linestring
{
- std::vector<index_type> rings;
+ std::vector<std::vector<index_type> > lines;
boost::optional<properties> props;
};
@@ -84,7 +84,10 @@ struct multi_polygon
boost::optional<properties> props;
};
-using geometry = util::variant<point,
+struct empty {};
+
+using geometry = util::variant<empty,
+ point,
linestring,
polygon,
multi_point,
diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp
index 5f96272..1276d13 100644
--- a/include/mapnik/palette.hpp
+++ b/include/mapnik/palette.hpp
@@ -43,6 +43,7 @@ using rgba_hash_table = std::unordered_map<unsigned int, unsigned char>;
// stl
#include <vector>
+#include <tuple>
#define U2RED(x) ((x)&0xff)
#define U2GREEN(x) (((x)>>8)&0xff)
@@ -53,7 +54,8 @@ namespace mapnik {
struct rgba;
-struct MAPNIK_DECL rgb {
+struct MAPNIK_DECL rgb
+{
std::uint8_t r;
std::uint8_t g;
std::uint8_t b;
@@ -92,7 +94,7 @@ struct MAPNIK_DECL rgba
b(U2BLUE(c)),
a(U2ALPHA(c)) {}
- inline bool operator==(const rgba& y) const
+ inline bool operator==(rgba const& y) const
{
return r == y.r && g == y.g && b == y.b && a == y.a;
}
@@ -103,18 +105,27 @@ struct MAPNIK_DECL rgba
bool operator() (const rgba& x, const rgba& y) const;
};
+ inline bool operator<(rgba const& y) const
+ {
+ return std::tie(r, g, b, a) < std::tie(y.r, y.g, y.b, y.a);
+ }
+
};
-class MAPNIK_DECL rgba_palette : private util::noncopyable {
+class MAPNIK_DECL rgba_palette : private util::noncopyable
+{
public:
enum palette_type { PALETTE_RGBA = 0, PALETTE_RGB = 1, PALETTE_ACT = 2 };
explicit rgba_palette(std::string const& pal, palette_type type = PALETTE_RGBA);
rgba_palette();
- const std::vector<rgb>& palette() const;
- const std::vector<unsigned>& alphaTable() const;
+ inline std::vector<rgb> const& palette() const { return rgb_pal_;}
+ inline std::vector<unsigned> const& alpha_table() const { return alpha_pal_;}
+
+ inline std::vector<rgb>& palette() { return rgb_pal_;}
+ inline std::vector<unsigned>& alpha_table() { return alpha_pal_;}
unsigned char quantize(unsigned c) const;
diff --git a/include/mapnik/params.hpp b/include/mapnik/params.hpp
index a38fa54..535cacb 100644
--- a/include/mapnik/params.hpp
+++ b/include/mapnik/params.hpp
@@ -51,6 +51,10 @@ struct value_holder : value_holder_base
value_holder()
: value_holder_base() {}
+ // C-string -> std::string
+ value_holder(char const* str)
+ : value_holder(std::string(str)) {}
+
// perfect forwarding
template <typename T>
value_holder(T && obj)
diff --git a/include/mapnik/plugin.hpp b/include/mapnik/plugin.hpp
index a3428de..68e7de6 100644
--- a/include/mapnik/plugin.hpp
+++ b/include/mapnik/plugin.hpp
@@ -38,7 +38,8 @@ using mapnik_lib_t = struct _mapnik_lib_t;
class PluginInfo : util::noncopyable
{
public:
- using name_func = const char* (*) ();
+ using callable_returning_string = const char* (*) ();
+ using callable_returning_void = void (*) ();
PluginInfo (std::string const& filename,
std::string const& library_name);
~PluginInfo();
diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp
index 051ea6b..9f8b38d 100644
--- a/include/mapnik/png_io.hpp
+++ b/include/mapnik/png_io.hpp
@@ -39,7 +39,7 @@ extern "C"
{
#include <png.h>
}
-
+#include <set>
#pragma GCC diagnostic pop
#define MAX_OCTREE_LEVELS 4
@@ -515,19 +515,19 @@ void save_as_png8_oct(T1 & file,
}
//transparency values per palette index
- std::vector<unsigned> alphaTable;
- //alphaTable.resize(palette.size());//allow semitransparency also in almost opaque range
+ std::vector<unsigned> alpha_table;
+ //alpha_table.resize(palette.size());//allow semitransparency also in almost opaque range
if (opts.trans_mode != 0)
{
- alphaTable.resize(palette.size() - cols[TRANSPARENCY_LEVELS-1]);
+ alpha_table.resize(palette.size() - cols[TRANSPARENCY_LEVELS-1]);
}
if (palette.size() > 16 )
{
// >16 && <=256 colors -> write 8-bit color depth
image_gray8 reduced_image(width,height);
- reduce_8(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
- save_as_png(file,palette,reduced_image,width,height,8,alphaTable,opts);
+ reduce_8(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alpha_table);
+ save_as_png(file,palette,reduced_image,width,height,8,alpha_table,opts);
}
else if (palette.size() == 1)
{
@@ -535,13 +535,13 @@ void save_as_png8_oct(T1 & file,
unsigned image_width = ((width + 15) >> 3) & ~1U; // 1-bit image, round up to 16-bit boundary
unsigned image_height = height;
image_gray8 reduced_image(image_width,image_height);
- reduce_1(image,reduced_image,trees, limits, alphaTable);
+ reduce_1(image,reduced_image,trees, limits, alpha_table);
if (meanAlpha<255 && cols[0]==0)
{
- alphaTable.resize(1);
- alphaTable[0] = meanAlpha;
+ alpha_table.resize(1);
+ alpha_table[0] = meanAlpha;
}
- save_as_png(file,palette,reduced_image,width,height,1,alphaTable,opts);
+ save_as_png(file,palette,reduced_image,width,height,1,alpha_table,opts);
}
else
{
@@ -549,8 +549,8 @@ void save_as_png8_oct(T1 & file,
unsigned image_width = ((width + 7) >> 1) & ~3U; // 4-bit image, round up to 32-bit boundary
unsigned image_height = height;
image_gray8 reduced_image(image_width,image_height);
- reduce_4(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
- save_as_png(file,palette,reduced_image,width,height,4,alphaTable,opts);
+ reduce_4(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alpha_table);
+ save_as_png(file,palette,reduced_image,width,height,4,alpha_table,opts);
}
}
@@ -560,7 +560,7 @@ void save_as_png8(T1 & file,
T2 const& image,
T3 const & tree,
std::vector<mapnik::rgb> const& palette,
- std::vector<unsigned> const& alphaTable,
+ std::vector<unsigned> const& alpha_table,
png_options const& opts)
{
unsigned width = image.width();
@@ -579,7 +579,7 @@ void save_as_png8(T1 & file,
row_out[x] = tree.quantize(row[x]);
}
}
- save_as_png(file, palette, reduced_image, width, height, 8, alphaTable, opts);
+ save_as_png(file, palette, reduced_image, width, height, 8, alpha_table, opts);
}
else if (palette.size() == 1)
{
@@ -588,7 +588,7 @@ void save_as_png8(T1 & file,
unsigned image_height = height;
image_gray8 reduced_image(image_width, image_height);
reduced_image.set(0);
- save_as_png(file, palette, reduced_image, width, height, 1, alphaTable, opts);
+ save_as_png(file, palette, reduced_image, width, height, 1, alpha_table, opts);
}
else
{
@@ -612,7 +612,7 @@ void save_as_png8(T1 & file,
row_out[x>>1] |= index;
}
}
- save_as_png(file, palette, reduced_image, width, height, 4, alphaTable, opts);
+ save_as_png(file, palette, reduced_image, width, height, 4, alpha_table, opts);
}
}
@@ -623,6 +623,7 @@ void save_as_png8_hex(T1 & file,
{
unsigned width = image.width();
unsigned height = image.height();
+
if (width + height > 3) // at least 3 pixels (hextree implementation requirement)
{
// structure for color quantization
@@ -647,20 +648,44 @@ void save_as_png8_hex(T1 & file,
}
//transparency values per palette index
- std::vector<mapnik::rgba> pal;
- tree.create_palette(pal);
+ std::vector<mapnik::rgba> rgba_palette;
+ tree.create_palette(rgba_palette);
+ auto size = rgba_palette.size();
std::vector<mapnik::rgb> palette;
- std::vector<unsigned> alphaTable;
- for (unsigned i=0; i<pal.size(); ++i)
+ std::vector<unsigned> alpha_table;
+ palette.reserve(size);
+ alpha_table.reserve(size);
+ for (auto const& c : rgba_palette)
{
- palette.push_back(rgb(pal[i].r, pal[i].g, pal[i].b));
- alphaTable.push_back(pal[i].a);
+ palette.emplace_back(c.r, c.g, c.b);
+ alpha_table.push_back(c.a);
}
- save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alphaTable, opts);
+ save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alpha_table, opts);
}
else
{
- throw std::runtime_error("Can't quantize images with less than 3 pixels");
+
+ std::set<mapnik::rgba> colors;
+ for (unsigned y = 0; y < height; ++y)
+ {
+ typename T2::pixel_type const * row = image.get_row(y);
+
+ for (unsigned x = 0; x < width; ++x)
+ {
+ unsigned val = row[x];
+ colors.emplace(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val));
+ }
+ }
+ std::string str;
+ for (auto c : colors)
+ {
+ str.push_back(c.r);
+ str.push_back(c.g);
+ str.push_back(c.b);
+ str.push_back(c.a);
+ }
+ rgba_palette pal(str, rgba_palette::PALETTE_RGBA);
+ save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette(), pal.alpha_table(), opts);
}
}
@@ -670,7 +695,7 @@ void save_as_png8_pal(T1 & file,
rgba_palette const& pal,
png_options const& opts)
{
- save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette(), pal.alphaTable(), opts);
+ save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette(), pal.alpha_table(), opts);
}
}
diff --git a/include/mapnik/renderer_common/process_point_symbolizer.hpp b/include/mapnik/renderer_common/process_point_symbolizer.hpp
index 12ffba5..ef0863f 100644
--- a/include/mapnik/renderer_common/process_point_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_point_symbolizer.hpp
@@ -61,7 +61,7 @@ void render_point_symbolizer(point_symbolizer const &sym,
agg::trans_affine tr;
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
- if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
+ if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform, common.scale_factor_);
agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine recenter_tr = recenter * tr;
diff --git a/include/mapnik/symbolizer_base.hpp b/include/mapnik/symbolizer_base.hpp
index 8ac4462..f07cf3d 100644
--- a/include/mapnik/symbolizer_base.hpp
+++ b/include/mapnik/symbolizer_base.hpp
@@ -58,7 +58,7 @@ MAPNIK_DECL void evaluate_transform(agg::trans_affine& tr,
feature_impl const& feature,
attributes const& vars,
transform_type const& trans_expr,
- double scale_factor=1.0);
+ double scale_factor);
struct enumeration_wrapper
{
@@ -101,7 +101,7 @@ struct strict_value : value_base_type
strict_value() = default;
strict_value(const char* val)
- : value_base_type(val) {}
+ : value_base_type(std::string(val)) {}
template <typename T>
strict_value(T const& obj)
diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp
index f35a5d5..3b02d89 100644
--- a/include/mapnik/text/placement_finder.hpp
+++ b/include/mapnik/text/placement_finder.hpp
@@ -78,7 +78,6 @@ private:
// Maps upright==auto, left-only and right-only to left,right to simplify processing.
// angle = angle of at start of line (to estimate best option for upright==auto)
text_upright_e simplify_upright(text_upright_e upright, double angle) const;
- box2d<double> get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot);
feature_impl const& feature_;
attributes const& attr_;
DetectorType & detector_;
diff --git a/include/mapnik/text/scrptrun.hpp b/include/mapnik/text/scrptrun.hpp
index 7c8063b..2161c51 100644
--- a/include/mapnik/text/scrptrun.hpp
+++ b/include/mapnik/text/scrptrun.hpp
@@ -105,7 +105,7 @@ private:
inline ScriptRun::ScriptRun()
{
- reset(NULL, 0, 0);
+ reset(nullptr, 0, 0);
}
inline ScriptRun::ScriptRun(const UChar chars[], int32_t length)
diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp
index 6d6fbdc..8fd3c15 100644
--- a/include/mapnik/text/symbolizer_helpers.hpp
+++ b/include/mapnik/text/symbolizer_helpers.hpp
@@ -158,6 +158,10 @@ protected:
void init_marker() const;
};
-} //namespace
+namespace geometry {
+MAPNIK_DECL mapnik::box2d<double> envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom);
+}
+
+} //namespace mapnik
#endif // SYMBOLIZER_HELPERS_HPP
diff --git a/include/mapnik/util/char_array_buffer.hpp b/include/mapnik/util/char_array_buffer.hpp
new file mode 100644
index 0000000..e5b834b
--- /dev/null
+++ b/include/mapnik/util/char_array_buffer.hpp
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2016 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
+ *
+ *****************************************************************************/
+
+#ifndef MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
+#define MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
+
+#include <streambuf>
+
+namespace mapnik { namespace util {
+
+// ref https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/
+
+class char_array_buffer : public std::streambuf
+{
+public:
+ char_array_buffer(char const* data, std::size_t size)
+ : begin_(data), end_(data + size), current_(data) {}
+
+private:
+ int_type underflow()
+ {
+ if (current_ == end_)
+ {
+ return traits_type::eof();
+ }
+ return traits_type::to_int_type(*current_);
+ }
+
+ int_type uflow()
+ {
+ if (current_ == end_)
+ {
+ return traits_type::eof();
+ }
+ return traits_type::to_int_type(*current_++);
+ }
+
+ int_type pbackfail(int_type ch)
+ {
+ if (current_ == begin_ || (ch != traits_type::eof() && ch != current_[-1]))
+ {
+ return traits_type::eof();
+ }
+ return traits_type::to_int_type(*--current_);
+ }
+
+ std::streamsize showmanyc()
+ {
+ return end_ - current_;
+ }
+
+ pos_type seekoff(off_type off, std::ios_base::seekdir dir,
+ std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
+ {
+ if (dir == std::ios_base::beg) current_ = std::min(begin_ + off, end_);
+ else if (dir == std::ios_base::cur) current_ = std::min(current_ + off, end_);
+ else current_ = std::max(end_ - off, begin_); // dir == std::ios_base::end
+ return pos_type(off_type(current_ - begin_));
+ }
+ char const * const begin_;
+ char const * const end_;
+ char const * current_;
+};
+
+}}
+
+
+#endif // MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
diff --git a/include/mapnik/util/is_clockwise.hpp b/include/mapnik/util/is_clockwise.hpp
index 2483727..93951df 100644
--- a/include/mapnik/util/is_clockwise.hpp
+++ b/include/mapnik/util/is_clockwise.hpp
@@ -23,6 +23,8 @@
#ifndef MAPNIK_UTIL_IS_CLOCKWISE_HPP
#define MAPNIK_UTIL_IS_CLOCKWISE_HPP
+#include <cassert>
+
namespace mapnik { namespace util {
template <typename T>
@@ -30,11 +32,18 @@ bool is_clockwise(T const& ring)
{
double area = 0.0;
std::size_t num_points = ring.size();
+ assert(num_points > 2);
+ double orig_x = ring[0].x;
+ double orig_y = ring[0].y;
for (std::size_t i = 0; i < num_points; ++i)
{
auto const& p0 = ring[i];
auto const& p1 = ring[(i + 1) % num_points];
- area += p0.x * p1.y - p0.y * p1.x;
+ double x0 = p0.x - orig_x;
+ double y0 = p0.y - orig_y;
+ double x1 = p1.x - orig_x;
+ double y1 = p1.y - orig_y;
+ area += x0 * y1 - x1 * y0;
}
return (area < 0.0) ? true : false;
}
diff --git a/include/mapnik/util/variant.hpp b/include/mapnik/util/variant.hpp
index 05dddec..87cfb70 100644
--- a/include/mapnik/util/variant.hpp
+++ b/include/mapnik/util/variant.hpp
@@ -24,7 +24,7 @@
#define MAPNIK_UTIL_VARIANT_HPP
#include <mapnik/config.hpp>
-#include <mapbox/variant/variant.hpp>
+#include <mapbox/variant.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
@@ -51,13 +51,13 @@ public:
// unary visitor interface
// const
template <typename F, typename V>
-auto VARIANT_INLINE static apply_visitor(F && f, V const& v) -> decltype(V::visit(v, f))
+auto VARIANT_INLINE static apply_visitor(F && f, V const& v) -> decltype(V::visit(v, std::forward<F>(f)))
{
return V::visit(v, std::forward<F>(f));
}
// non-const
template <typename F, typename V>
-auto VARIANT_INLINE static apply_visitor(F && f, V & v) -> decltype(V::visit(v, f))
+auto VARIANT_INLINE static apply_visitor(F && f, V & v) -> decltype(V::visit(v, std::forward<F>(f)))
{
return V::visit(v, std::forward<F>(f));
}
@@ -65,14 +65,14 @@ auto VARIANT_INLINE static apply_visitor(F && f, V & v) -> decltype(V::visit(v,
// binary visitor interface
// const
template <typename F, typename V>
-auto VARIANT_INLINE static apply_visitor(F && f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, f))
+auto VARIANT_INLINE static apply_visitor(F && f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
{
return V::binary_visit(v0, v1, std::forward<F>(f));
}
// non-const
template <typename F, typename V>
-auto VARIANT_INLINE static apply_visitor(F && f, V & v0, V & v1) -> decltype(V::binary_visit(v0, v1, f))
+auto VARIANT_INLINE static apply_visitor(F && f, V & v0, V & v1) -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
{
return V::binary_visit(v0, v1, std::forward<F>(f));
}
diff --git a/include/mapnik/value_hash.hpp b/include/mapnik/value_hash.hpp
index b050e37..80e10d8 100644
--- a/include/mapnik/value_hash.hpp
+++ b/include/mapnik/value_hash.hpp
@@ -26,22 +26,20 @@
// mapnik
#include <mapnik/util/variant.hpp>
#include <mapnik/value_types.hpp>
-
// stl
#include <functional>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <unicode/unistr.h>
+
#pragma GCC diagnostic pop
namespace mapnik { namespace detail {
-template <class T>
-inline void hash_combine(std::size_t & seed, T const& v)
+inline void hash_combine(std::size_t & seed, std::size_t val)
{
- std::hash<T> hasher;
- seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+ seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
struct value_hasher
@@ -56,6 +54,11 @@ struct value_hasher
return static_cast<std::size_t>(val.hashCode());
}
+ std::size_t operator()(value_integer val) const
+ {
+ return static_cast<std::size_t>(val);
+ }
+
template <class T>
std::size_t operator()(T const& val) const
{
@@ -69,7 +72,8 @@ struct value_hasher
template <typename T>
std::size_t mapnik_hash_value(T const& val)
{
- std::size_t seed = util::apply_visitor(detail::value_hasher(), val);
+ std::size_t seed = 0;
+ detail::hash_combine(seed, util::apply_visitor(detail::value_hasher(), val));
detail::hash_combine(seed, val.which());
return seed;
}
diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp
index e1a367b..deba428 100644
--- a/include/mapnik/version.hpp
+++ b/include/mapnik/version.hpp
@@ -27,7 +27,7 @@
#define MAPNIK_MAJOR_VERSION 3
#define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 11
+#define MAPNIK_PATCH_VERSION 12
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp
index 3a41bee..0c77d75 100644
--- a/include/mapnik/vertex_adapters.hpp
+++ b/include/mapnik/vertex_adapters.hpp
@@ -32,10 +32,10 @@ namespace mapnik { namespace geometry {
template <typename T>
struct point_vertex_adapter
{
- using value_type = typename point<T>::value_type;
+ using coord_type = typename point<T>::coord_type;
point_vertex_adapter(point<T> const& pt);
- unsigned vertex(value_type * x, value_type * y) const;
+ unsigned vertex(coord_type * x, coord_type * y) const;
void rewind(unsigned) const;
geometry_types type () const;
point<T> const& pt_;
@@ -45,9 +45,9 @@ struct point_vertex_adapter
template <typename T>
struct line_string_vertex_adapter
{
- using value_type = typename point<T>::value_type;
+ using coord_type = typename point<T>::coord_type;
line_string_vertex_adapter(line_string<T> const& line);
- unsigned vertex(value_type * x, value_type * y) const;
+ unsigned vertex(coord_type * x, coord_type * y) const;
void rewind(unsigned) const;
geometry_types type () const;
line_string<T> const& line_;
@@ -58,10 +58,10 @@ struct line_string_vertex_adapter
template <typename T>
struct polygon_vertex_adapter
{
- using value_type = typename point<T>::value_type;
+ using coord_type = typename point<T>::coord_type;
polygon_vertex_adapter(polygon<T> const& poly);
void rewind(unsigned) const;
- unsigned vertex(value_type * x, value_type * y) const;
+ unsigned vertex(coord_type * x, coord_type * y) const;
geometry_types type () const;
private:
polygon<T> const& poly_;
@@ -75,10 +75,10 @@ private:
template <typename T>
struct ring_vertex_adapter
{
- using value_type = typename point<T>::value_type;
+ using coord_type = typename point<T>::coord_type;
ring_vertex_adapter(linear_ring<T> const& ring);
void rewind(unsigned) const;
- unsigned vertex(value_type * x, value_type * y) const;
+ unsigned vertex(coord_type * x, coord_type * y) const;
geometry_types type () const;
private:
linear_ring<T> const& ring_;
diff --git a/include/mapnik/warning_ignore.hpp b/include/mapnik/warning_ignore.hpp
index 62b7899..95249b8 100644
--- a/include/mapnik/warning_ignore.hpp
+++ b/include/mapnik/warning_ignore.hpp
@@ -23,6 +23,7 @@
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
+#pragma GCC diagnostic ignored "-W#pragma-messages"
#pragma GCC diagnostic ignored "-Wunsequenced"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp
index 892e551..f31fcc0 100644
--- a/include/mapnik/wkt/wkt_generator_grammar.hpp
+++ b/include/mapnik/wkt/wkt_generator_grammar.hpp
@@ -104,7 +104,7 @@ template <typename OutputIterator, typename Geometry>
struct wkt_generator_grammar :
karma::grammar<OutputIterator, Geometry const& ()>
{
- using coord_type = typename Geometry::value_type;
+ using coord_type = typename Geometry::coord_type;
wkt_generator_grammar();
// rules
karma::rule<OutputIterator, Geometry const&()> geometry;
diff --git a/include/mapnik/xml_attribute_cast.hpp b/include/mapnik/xml_attribute_cast.hpp
index fb3b7eb..cafa7e7 100644
--- a/include/mapnik/xml_attribute_cast.hpp
+++ b/include/mapnik/xml_attribute_cast.hpp
@@ -55,7 +55,7 @@ struct do_xml_attribute_cast
{
static inline boost::optional<T> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& /*source*/)
{
- std::string err_msg("No conversion from std::string to");
+ std::string err_msg("No conversion from std::string to ");
err_msg += std::string(typeid(T).name());
throw std::runtime_error(err_msg);
}
@@ -74,6 +74,19 @@ struct do_xml_attribute_cast<mapnik::boolean_type>
}
};
+// specialization for mapnik::value_bool
+template <>
+struct do_xml_attribute_cast<mapnik::value_bool>
+{
+ static inline boost::optional<mapnik::value_bool> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
+ {
+ bool result;
+ if (mapnik::util::string2bool(source, result))
+ return boost::optional<mapnik::value_bool>(result);
+ return boost::optional<mapnik::value_bool>();
+ }
+};
+
// specialization for int
template <>
struct do_xml_attribute_cast<int>
diff --git a/localize.sh b/localize.sh
index 4b69c2f..3d034f5 100755
--- a/localize.sh
+++ b/localize.sh
@@ -1,10 +1,12 @@
#!/bin/bash
+
# TODO - use rpath to avoid needing this to run tests locally
+
export CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-if [ $(uname -s) = 'Darwin' ]; then
- export DYLD_LIBRARY_PATH="${CURRENT_DIR}/src/":${DYLD_LIBRARY_PATH}
-else
- export LD_LIBRARY_PATH="${CURRENT_DIR}/src/":${LD_LIBRARY_PATH}
+if [[ $(uname -s) == 'Darwin' ]]; then
+ export DYLD_LIBRARY_PATH="${CURRENT_DIR}/src/":${DYLD_LIBRARY_PATH:-""}
+elif [[ $(uname -s) == 'Linux' ]]; then
+ export LD_LIBRARY_PATH="${CURRENT_DIR}/src/":${LD_LIBRARY_PATH:-""}
fi
export PATH=$(pwd)/utils/mapnik-render/:${PATH}
diff --git a/mason_latest.sh b/mason_latest.sh
index 7b3e02a..d5db696 100755
--- a/mason_latest.sh
+++ b/mason_latest.sh
@@ -1,12 +1,14 @@
#!/usr/bin/env bash
-set -eu
-
MASON_NAME=mapnik
MASON_VERSION=latest
MASON_LIB_FILE=lib/libmapnik-wkt.a
-. ${MASON_DIR:-~/.mason}/mason.sh
+# warning: may break when https://github.com/mapbox/mason/issues/141 lands
+# hence we are pinned for now to older mason in bootstrap.sh
+. ./.mason/mason.sh
+
+set -eu
function mason_load_source {
export MASON_BUILD_PATH=$(pwd)
diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp
index 6c1ff10..4a246b4 100644
--- a/plugins/input/csv/csv_datasource.cpp
+++ b/plugins/input/csv/csv_datasource.cpp
@@ -431,7 +431,7 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const
return std::make_shared<csv_index_featureset>(filename_, filter, locator_, separator_, quote_, headers_, ctx_);
}
}
- return mapnik::featureset_ptr();
+ return mapnik::make_empty_featureset();
}
mapnik::featureset_ptr csv_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp
index 07cec47..2454ed6 100644
--- a/plugins/input/gdal/gdal_datasource.cpp
+++ b/plugins/input/gdal/gdal_datasource.cpp
@@ -44,11 +44,14 @@ using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::datasource_exception;
+static std::once_flag once_flag;
-static bool GDALAllRegister_once_()
+extern "C" MAPNIK_EXP void on_plugin_load()
{
- static bool const quiet_unused = (GDALAllRegister(), true);
- return quiet_unused;
+ // initialize gdal formats
+ std::call_once(once_flag,[](){
+ GDALAllRegister();
+ });
}
gdal_datasource::gdal_datasource(parameters const& params)
@@ -60,8 +63,6 @@ gdal_datasource::gdal_datasource(parameters const& params)
{
MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource: Initializing...";
- GDALAllRegister_once_();
-
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "gdal_datasource::init");
#endif
diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp
index fe1fe64..1377322 100644
--- a/plugins/input/gdal/gdal_featureset.cpp
+++ b/plugins/input/gdal/gdal_featureset.cpp
@@ -44,6 +44,41 @@ using mapnik::view_transform;
using mapnik::datasource_exception;
using mapnik::feature_factory;
+#ifdef MAPNIK_LOG
+namespace {
+
+void get_overview_meta(GDALRasterBand* band)
+{
+ int band_overviews = band->GetOverviewCount();
+ if (band_overviews > 0)
+ {
+ MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: " << band_overviews << " overviews found!";
+
+ for (int b = 0; b < band_overviews; b++)
+ {
+ GDALRasterBand * overview = band->GetOverview(b);
+ MAPNIK_LOG_DEBUG(gdal) << "Overview= " << b
+ << " Width=" << overview->GetXSize()
+ << " Height=" << overview->GetYSize();
+ }
+ }
+ else
+ {
+ MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: No overviews found!";
+ }
+
+ int bsx,bsy;
+ double scale;
+ band->GetBlockSize(&bsx, &bsy);
+ scale = band->GetScale();
+
+ MAPNIK_LOG_DEBUG(gdal) << "Block=" << bsx << "x" << bsy
+ << " Scale=" << scale
+ << " Type=" << GDALGetDataTypeName(band->GetRasterDataType())
+ << "Color=" << GDALGetColorInterpretationName(band->GetColorInterpretation());
+}
+} // anonymous ns
+#endif
gdal_featureset::gdal_featureset(GDALDataset& dataset,
int band,
gdal_query q,
@@ -403,15 +438,15 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 )
{
int nBandsToRead = 3;
- if( alpha != NULL && alpha->GetBand() == 4 && !raster_has_nodata )
+ if( alpha != nullptr && alpha->GetBand() == 4 && !raster_has_nodata )
{
nBandsToRead = 4;
- alpha = NULL; // to avoid reading it again afterwards
+ alpha = nullptr; // to avoid reading it again afterwards
}
raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height,
image.bytes(),
image.width(), image.height(), GDT_Byte,
- nBandsToRead, NULL,
+ nBandsToRead, nullptr,
4, 4 * image.width(), 1);
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
@@ -551,6 +586,32 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band";
}
}
+ else if( dataset_.GetRasterCount() > 0 && dataset_.GetRasterBand(1) )
+ {
+ // Check if we have a non-alpha mask band (for example a TIFF internal mask)
+ int flags = dataset_.GetRasterBand(1)->GetMaskFlags();
+ GDALRasterBand* mask = 0;
+ if (flags == GMF_PER_DATASET)
+ {
+ mask = dataset_.GetRasterBand(1)->GetMaskBand();
+ }
+ if (mask)
+ {
+ MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: found and processing mask band...";
+ if (!raster_has_nodata)
+ {
+ raster_io_error = mask->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
+ image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
+ if (raster_io_error == CE_Failure) {
+ throw datasource_exception(CPLGetLastErrorMsg());
+ }
+ }
+ else
+ {
+ MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of mask band";
+ }
+ }
+ }
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
// set nodata value to be used in raster colorizer
if (nodata_value_) raster->set_nodata(*nodata_value_);
@@ -620,36 +681,3 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
}
return feature_ptr();
}
-
-#ifdef MAPNIK_LOG
-void gdal_featureset::get_overview_meta(GDALRasterBand* band)
-{
- int band_overviews = band->GetOverviewCount();
- if (band_overviews > 0)
- {
- MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: " << band_overviews << " overviews found!";
-
- for (int b = 0; b < band_overviews; b++)
- {
- GDALRasterBand * overview = band->GetOverview(b);
- MAPNIK_LOG_DEBUG(gdal) << "Overview= " << b
- << " Width=" << overview->GetXSize()
- << " Height=" << overview->GetYSize();
- }
- }
- else
- {
- MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: No overviews found!";
- }
-
- int bsx,bsy;
- double scale;
- band->GetBlockSize(&bsx, &bsy);
- scale = band->GetScale();
-
- MAPNIK_LOG_DEBUG(gdal) << "Block=" << bsx << "x" << bsy
- << " Scale=" << scale
- << " Type=" << GDALGetDataTypeName(band->GetRasterDataType())
- << "Color=" << GDALGetColorInterpretationName(band->GetColorInterpretation());
-}
-#endif
diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp
index 639028b..f2f66f7 100644
--- a/plugins/input/gdal/gdal_featureset.hpp
+++ b/plugins/input/gdal/gdal_featureset.hpp
@@ -73,11 +73,6 @@ public:
private:
mapnik::feature_ptr get_feature(mapnik::query const& q);
mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
-
-#ifdef MAPNIK_LOG
- void get_overview_meta(GDALRasterBand * band);
-#endif
-
GDALDataset & dataset_;
mapnik::context_ptr ctx_;
int band_;
diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp
index e9456f8..d2ebc2d 100644
--- a/plugins/input/geojson/geojson_datasource.cpp
+++ b/plugins/input/geojson/geojson_datasource.cpp
@@ -587,8 +587,8 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons
}
}
- // otherwise return an empty featureset pointer
- return mapnik::featureset_ptr();
+ // otherwise return an empty featureset
+ return mapnik::make_empty_featureset();
}
mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp
index 41c0ebb..2943962 100644
--- a/plugins/input/ogr/ogr_datasource.cpp
+++ b/plugins/input/ogr/ogr_datasource.cpp
@@ -59,6 +59,16 @@ using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;
+static std::once_flag once_flag;
+
+extern "C" MAPNIK_EXP void on_plugin_load()
+{
+ // initialize ogr formats
+ // NOTE: in GDAL >= 2.0 this is the same as GDALAllRegister()
+ std::call_once(once_flag,[](){
+ OGRRegisterAll();
+ });
+}
ogr_datasource::ogr_datasource(parameters const& params)
: datasource(params),
@@ -87,10 +97,6 @@ void ogr_datasource::init(mapnik::parameters const& params)
mapnik::progress_timer __stats__(std::clog, "ogr_datasource::init");
#endif
- // initialize ogr formats
- // NOTE: in GDAL >= 2.0 this is the same as GDALAllRegister()
- OGRRegisterAll();
-
boost::optional<std::string> file = params.get<std::string>("file");
boost::optional<std::string> string = params.get<std::string>("string");
if (!string) string = params.get<std::string>("inline");
@@ -371,7 +377,7 @@ void ogr_datasource::init(mapnik::parameters const& params)
}
mapnik::parameters & extra_params = desc_.get_extra_parameters();
OGRSpatialReference * srs_ref = layer->GetSpatialRef();
- char * srs_output = NULL;
+ char * srs_output = nullptr;
if (srs_ref && srs_ref->exportToProj4( &srs_output ) == OGRERR_NONE ) {
extra_params["proj4"] = mapnik::util::trim_copy(srs_output);
}
@@ -554,7 +560,7 @@ featureset_ptr ogr_datasource::features(query const& q) const
}
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
featureset_ptr ogr_datasource::features_at_point(coord2d const& pt, double tol) const
@@ -597,5 +603,5 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt, double tol)
}
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp
index 451c74e..ced1810 100644
--- a/plugins/input/pgraster/pgraster_datasource.cpp
+++ b/plugins/input/pgraster/pgraster_datasource.cpp
@@ -257,7 +257,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
if (srid_ == 0)
{
const char* srid_c = rs->getValue("srid");
- if (srid_c != NULL)
+ if (srid_c != nullptr)
{
int result = 0;
const char * end = srid_c + std::strlen(srid_c);
@@ -274,7 +274,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
}
else
{
- MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str();
+ MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str();
}
rs->close();
}
@@ -297,7 +297,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params)
if (rs->next())
{
const char* srid_c = rs->getValue("srid");
- if (srid_c != NULL)
+ if (srid_c != nullptr)
{
int result = 0;
const char * end = srid_c + std::strlen(srid_c);
@@ -878,9 +878,10 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process
std::string table_with_bbox;
std::string col = geometryColumn_;
- if ( use_overviews_ ) {
- std::string sch = schema_;
- std::string tab = mapnik::sql_utils::unquote_double(raster_table_);
+ if ( use_overviews_ && !overviews_.empty()) {
+ std::string sch = overviews_[0].schema;
+ std::string tab = overviews_[0].table;
+ col = overviews_[0].column;
const double scale = std::min(px_gw, px_gh);
std::vector<pgraster_overview>::const_reverse_iterator i;
for (i=overviews_.rbegin(); i!=overviews_.rend(); ++i) {
@@ -997,7 +998,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
@@ -1010,7 +1011,7 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double
if (pool)
{
shared_ptr<Connection> conn = pool->borrowObject();
- if (!conn) return featureset_ptr();
+ if (!conn) return mapnik::make_empty_featureset();
if (conn->isOK())
{
@@ -1081,7 +1082,7 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double
}
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
box2d<double> pgraster_datasource::envelope() const
diff --git a/plugins/input/pgraster/pgraster_wkb_reader.cpp b/plugins/input/pgraster/pgraster_wkb_reader.cpp
index b97d0cd..4a9fd1c 100644
--- a/plugins/input/pgraster/pgraster_wkb_reader.cpp
+++ b/plugins/input/pgraster/pgraster_wkb_reader.cpp
@@ -66,7 +66,7 @@ read_uint16(const uint8_t** from, uint8_t littleEndian) {
/*
int16_t
read_int16(const uint8_t** from, uint8_t littleEndian) {
- assert(NULL != from);
+ assert(nullptr != from);
return read_uint16(from, littleEndian);
}
diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp
index 909cd58..2653e57 100644
--- a/plugins/input/postgis/postgis_datasource.cpp
+++ b/plugins/input/postgis/postgis_datasource.cpp
@@ -479,7 +479,7 @@ postgis_datasource::postgis_datasource(parameters const& params)
// Finally, add unique metadata to layer descriptor
mapnik::parameters & extra_params = desc_.get_extra_parameters();
// explicitly make copies of values due to https://github.com/mapnik/mapnik/issues/2651
- extra_params["srid"] = srid_;
+ extra_params["srid"] = mapnik::value_integer(srid_);
if (!key_field_.empty())
{
extra_params["key_field"] = key_field_;
@@ -942,7 +942,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
@@ -955,7 +955,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
if (pool)
{
shared_ptr<Connection> conn = pool->borrowObject();
- if (!conn) return featureset_ptr();
+ if (!conn) return mapnik::make_empty_featureset();
if (conn->isOK())
{
@@ -1030,7 +1030,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
}
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
box2d<double> postgis_datasource::envelope() const
diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp
index 4d8b5f9..38a6aa9 100644
--- a/plugins/input/raster/raster_datasource.cpp
+++ b/plugins/input/raster/raster_datasource.cpp
@@ -224,5 +224,5 @@ featureset_ptr raster_datasource::features_at_point(coord2d const&, double tol)
{
MAPNIK_LOG_WARN(raster) << "raster_datasource: feature_at_point not supported";
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp
index 939d9d3..37e4411 100644
--- a/plugins/input/sqlite/sqlite_datasource.cpp
+++ b/plugins/input/sqlite/sqlite_datasource.cpp
@@ -551,7 +551,7 @@ featureset_ptr sqlite_datasource::features(query const& q) const
using_subquery_);
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt, double tol) const
@@ -631,5 +631,5 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt, double to
using_subquery_);
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp
index 4c4e6b5..e6cab26 100644
--- a/plugins/input/topojson/topojson_datasource.cpp
+++ b/plugins/input/topojson/topojson_datasource.cpp
@@ -66,18 +66,9 @@ struct attr_value_converter
{
return mapnik::Boolean;
}
-
- mapnik::eAttributeType operator() (std::string const& /*val*/) const
- {
- return mapnik::String;
- }
-
- mapnik::eAttributeType operator() (mapnik::value_unicode_string const& /*val*/) const
- {
- return mapnik::String;
- }
-
- mapnik::eAttributeType operator() (mapnik::value_null const& /*val*/) const
+ // string, object, array
+ template <typename T>
+ mapnik::eAttributeType operator() (T const& /*val*/) const
{
return mapnik::String;
}
@@ -109,6 +100,11 @@ struct geometry_type_visitor
{
return static_cast<int>(mapnik::datasource_geometry_t::Polygon);
}
+ template <typename T>
+ int operator() (T const& ) const
+ {
+ return 0;
+ }
};
struct collect_attributes_visitor
@@ -117,6 +113,9 @@ struct collect_attributes_visitor
collect_attributes_visitor(mapnik::layer_descriptor & desc):
desc_(desc) {}
+ // no-op
+ void operator() (mapnik::topojson::empty) {}
+ //
template <typename GeomType>
void operator() (GeomType const& g)
{
@@ -285,7 +284,7 @@ mapnik::featureset_ptr topojson_datasource::features(mapnik::query const& q) con
}
}
// otherwise return an empty featureset pointer
- return mapnik::featureset_ptr();
+ return mapnik::make_empty_featureset();
}
mapnik::featureset_ptr topojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
diff --git a/scripts/travis-common.sh b/scripts/travis-common.sh
index 15b38dd..40d1837 100644
--- a/scripts/travis-common.sh
+++ b/scripts/travis-common.sh
@@ -62,7 +62,7 @@ commit_message_contains () {
}
commit_message_parse () {
- if commit_message_contains '[skip tests]' || [[ $(uname -s) == 'Darwin' ]]; then
+ if commit_message_contains '[skip tests]'; then
config_override "CPP_TESTS = False"
fi
if commit_message_contains '[skip utils]'; then
@@ -92,8 +92,7 @@ configure () {
coverage () {
./mason_packages/.link/bin/cpp-coveralls \
- --gcov /usr/bin/llvm-cov-${LLVM_VERSION} \
- --build-root . --gcov-options '\-lp' \
+ --gcov ${LLVM_COV} \
--exclude mason_packages \
--exclude .sconf_temp --exclude benchmark --exclude deps \
--exclude scons --exclude test --exclude demo --exclude docs \
diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp
index 3b947a4..dbbb7f2 100644
--- a/src/agg/process_line_pattern_symbolizer.cpp
+++ b/src/agg/process_line_pattern_symbolizer.cpp
@@ -92,7 +92,7 @@ struct agg_renderer_process_visitor_l
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
image_rgba8 image(bbox_image.width(), bbox_image.height());
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp
index e654886..f2a0159 100644
--- a/src/agg/process_polygon_pattern_symbolizer.cpp
+++ b/src/agg/process_polygon_pattern_symbolizer.cpp
@@ -84,7 +84,7 @@ struct agg_renderer_process_visitor_p
{
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height());
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp
index b3794bc..685b66c 100644
--- a/src/agg/process_text_symbolizer.cpp
+++ b/src/agg/process_text_symbolizer.cpp
@@ -63,7 +63,7 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
if (halo_transform)
{
agg::trans_affine halo_affine_transform;
- evaluate_transform(halo_affine_transform, feature, common_.vars_, *halo_transform);
+ evaluate_transform(halo_affine_transform, feature, common_.vars_, *halo_transform, common_.scale_factor_);
ren.set_halo_transform(halo_affine_transform);
}
diff --git a/src/box2d.cpp b/src/box2d.cpp
index 7d54233..407c054 100644
--- a/src/box2d.cpp
+++ b/src/box2d.cpp
@@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
- * Copyright (C) 2015 Artem Pavlenko
+ * Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,478 +21,9 @@
*****************************************************************************/
// mapnik
-#include <mapnik/box2d.hpp>
-#include <mapnik/safe_cast.hpp>
+#include <mapnik/box2d_impl.hpp>
-// stl
-#include <stdexcept>
-#include <sstream>
-#include <iomanip>
-
-#include <mapnik/config.hpp>
-
-#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include <boost/fusion/include/adapt_adt.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
-#pragma GCC diagnostic pop
-
-// agg
-#include "agg_trans_affine.h"
-
-BOOST_FUSION_ADAPT_TPL_ADT(
- (T),
- (mapnik::box2d)(T),
- (T, T, obj.minx(), obj.set_minx(mapnik::safe_cast<T>(val)))
- (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast<T>(val)))
- (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast<T>(val)))
- (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast<T>(val))))
-
-namespace mapnik
-{
-template <typename T>
-box2d<T>::box2d()
- :minx_( std::numeric_limits<T>::max()),
- miny_( std::numeric_limits<T>::max()),
- maxx_(-std::numeric_limits<T>::max()),
- maxy_(-std::numeric_limits<T>::max()) {}
-
-template <typename T>
-box2d<T>::box2d(T minx,T miny,T maxx,T maxy)
-{
- init(minx,miny,maxx,maxy);
-}
-
-template <typename T>
-box2d<T>::box2d(coord<T,2> const& c0, coord<T,2> const& c1)
-{
- init(c0.x,c0.y,c1.x,c1.y);
-}
-
-template <typename T>
-box2d<T>::box2d(box2d_type const& rhs)
- : minx_(rhs.minx_),
- miny_(rhs.miny_),
- maxx_(rhs.maxx_),
- maxy_(rhs.maxy_) {}
-
-template <typename T>
-box2d<T>::box2d(box2d_type && rhs)
- : minx_(std::move(rhs.minx_)),
- miny_(std::move(rhs.miny_)),
- maxx_(std::move(rhs.maxx_)),
- maxy_(std::move(rhs.maxy_)) {}
-
-template <typename T>
-box2d<T>& box2d<T>::operator=(box2d_type other)
-{
- swap(*this, other);
- return *this;
-}
-
-template <typename T>
-box2d<T>::box2d(box2d_type const& rhs, agg::trans_affine const& tr)
-{
- double x0 = rhs.minx_, y0 = rhs.miny_;
- double x1 = rhs.maxx_, y1 = rhs.miny_;
- double x2 = rhs.maxx_, y2 = rhs.maxy_;
- double x3 = rhs.minx_, y3 = rhs.maxy_;
- tr.transform(&x0, &y0);
- tr.transform(&x1, &y1);
- tr.transform(&x2, &y2);
- tr.transform(&x3, &y3);
- init(static_cast<T>(x0), static_cast<T>(y0),
- static_cast<T>(x2), static_cast<T>(y2));
- expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
- expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
-}
-
-template <typename T>
-bool box2d<T>::operator==(box2d<T> const& other) const
-{
- return minx_==other.minx_ &&
- miny_==other.miny_ &&
- maxx_==other.maxx_ &&
- maxy_==other.maxy_;
-}
-
-template <typename T>
-T box2d<T>::minx() const
-{
- return minx_;
-}
-
-template <typename T>
-T box2d<T>::maxx() const
-{
- return maxx_;
-}
-
-template <typename T>
-T box2d<T>::miny() const
-{
- return miny_;
-}
-
-template <typename T>
-T box2d<T>::maxy() const
-{
- return maxy_;
-}
-
-template<typename T>
-void box2d<T>::set_minx(T v)
-{
- minx_ = v;
-}
-
-template<typename T>
-void box2d<T>::set_miny(T v)
-{
- miny_ = v;
-}
-
-template<typename T>
-void box2d<T>::set_maxx(T v)
-{
- maxx_ = v;
-}
-
-template<typename T>
-void box2d<T>::set_maxy(T v)
-{
- maxy_ = v;
-}
-
-template <typename T>
-T box2d<T>::width() const
-{
- return maxx_-minx_;
-}
-
-template <typename T>
-T box2d<T>::height() const
-{
- return maxy_-miny_;
-}
-
-template <typename T>
-void box2d<T>::width(T w)
-{
- T cx=center().x;
- minx_=static_cast<T>(cx-w*0.5);
- maxx_=static_cast<T>(cx+w*0.5);
-}
-
-template <typename T>
-void box2d<T>::height(T h)
-{
- T cy=center().y;
- miny_=static_cast<T>(cy-h*0.5);
- maxy_=static_cast<T>(cy+h*0.5);
-}
-
-template <typename T>
-coord<T,2> box2d<T>::center() const
-{
- return coord<T,2>(static_cast<T>(0.5*(minx_+maxx_)),
- static_cast<T>(0.5*(miny_+maxy_)));
-}
-
-template <typename T>
-void box2d<T>::expand_to_include(coord<T,2> const& c)
-{
- expand_to_include(c.x,c.y);
-}
-
-template <typename T>
-void box2d<T>::expand_to_include(T x,T y)
-{
- if (x<minx_) minx_=x;
- if (x>maxx_) maxx_=x;
- if (y<miny_) miny_=y;
- if (y>maxy_) maxy_=y;
-}
-
-template <typename T>
-void box2d<T>::expand_to_include(box2d<T> const& other)
-{
- if (other.minx_<minx_) minx_=other.minx_;
- if (other.maxx_>maxx_) maxx_=other.maxx_;
- if (other.miny_<miny_) miny_=other.miny_;
- if (other.maxy_>maxy_) maxy_=other.maxy_;
-}
-
-template <typename T>
-bool box2d<T>::contains(coord<T,2> const& c) const
-{
- return contains(c.x,c.y);
-}
-
-template <typename T>
-bool box2d<T>::contains(T x,T y) const
-{
- return x>=minx_ && x<=maxx_ && y>=miny_ && y<=maxy_;
-}
-
-template <typename T>
-bool box2d<T>::contains(box2d<T> const& other) const
-{
- return other.minx_>=minx_ &&
- other.maxx_<=maxx_ &&
- other.miny_>=miny_ &&
- other.maxy_<=maxy_;
-}
-
-template <typename T>
-bool box2d<T>::intersects(coord<T,2> const& c) const
-{
- return intersects(c.x,c.y);
-}
-
-template <typename T>
-bool box2d<T>::intersects(T x,T y) const
-{
- return !(x>maxx_ || x<minx_ || y>maxy_ || y<miny_);
-}
-
-template <typename T>
-bool box2d<T>::intersects(box2d<T> const& other) const
-{
- return !(other.minx_>maxx_ || other.maxx_<minx_ ||
- other.miny_>maxy_ || other.maxy_<miny_);
-}
-
-template <typename T>
-box2d<T> box2d<T>::intersect(box2d_type const& other) const
-{
- if (intersects(other))
- {
- T x0=std::max(minx_,other.minx_);
- T y0=std::max(miny_,other.miny_);
- T x1=std::min(maxx_,other.maxx_);
- T y1=std::min(maxy_,other.maxy_);
- return box2d<T>(x0,y0,x1,y1);
- }
- else
- {
- return box2d<T>();
- }
-}
-
-template <typename T>
-void box2d<T>::re_center(T cx,T cy)
-{
- T dx=cx-center().x;
- T dy=cy-center().y;
- minx_+=dx;
- miny_+=dy;
- maxx_+=dx;
- maxy_+=dy;
-}
-
-template <typename T>
-void box2d<T>::re_center(coord<T,2> const& c)
-{
- re_center(c.x,c.y);
-}
-
-template <typename T>
-void box2d<T>::init(T x0, T y0, T x1, T y1)
-{
- if (x0 < x1)
- {
- minx_ = x0;
- maxx_ = x1;
- }
- else
- {
- minx_ = x1;
- maxx_ = x0;
- }
- if (y0 < y1)
- {
- miny_ = y0;
- maxy_ = y1;
- }
- else
- {
- miny_ = y1;
- maxy_ = y0;
- }
-}
-
-template <typename T>
-void box2d<T>::init(T x, T y)
-{
- init(x, y, x, y);
-}
-
-template <typename T>
-void box2d<T>::clip(box2d_type const& other)
-{
- minx_ = std::max(minx_, other.minx());
- miny_ = std::max(miny_, other.miny());
- maxx_ = std::min(maxx_, other.maxx());
- maxy_ = std::min(maxy_, other.maxy());
-}
-
-template <typename T>
-void box2d<T>::pad(T padding)
-{
- minx_ -= padding;
- miny_ -= padding;
- maxx_ += padding;
- maxy_ += padding;
-}
-
-template <typename T>
-bool box2d<T>::from_string(std::string const& str)
-{
- boost::spirit::qi::lit_type lit;
- boost::spirit::qi::double_type double_;
- boost::spirit::ascii::space_type space;
- bool r = boost::spirit::qi::phrase_parse(str.begin(),
- str.end(),
- double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_,
- space,
- *this);
- return r;
-}
-
-template <typename T>
-bool box2d<T>::valid() const
-{
- return (minx_ <= maxx_ && miny_ <= maxy_) ;
-}
-
-template <typename T>
-void box2d<T>::move(T x, T y)
-{
- minx_ += x;
- maxx_ += x;
- miny_ += y;
- maxy_ += y;
-}
-
-template <typename T>
-std::string box2d<T>::to_string() const
-{
- std::ostringstream s;
- if (valid())
- {
- s << "box2d(" << std::fixed << std::setprecision(16)
- << minx_ << ',' << miny_ << ','
- << maxx_ << ',' << maxy_ << ')';
- }
- else
- {
- s << "box2d(INVALID)";
- }
- return s.str();
-}
-
-
-template <typename T>
-box2d<T>& box2d<T>::operator+=(box2d<T> const& other)
-{
- expand_to_include(other);
- return *this;
-}
-
-template <typename T>
-box2d<T> box2d<T>::operator+ (T other) const
-{
- return box2d<T>(minx_ - other, miny_ - other, maxx_ + other, maxy_ + other);
-}
-
-template <typename T>
-box2d<T>& box2d<T>::operator+= (T other)
-{
- minx_ -= other;
- miny_ -= other;
- maxx_ += other;
- maxy_ += other;
- return *this;
-}
-
-
-template <typename T>
-box2d<T>& box2d<T>::operator*=(T t)
-{
- coord<T,2> c = center();
- T sx = static_cast<T>(0.5 * width() * t);
- T sy = static_cast<T>(0.5 * height() * t);
- minx_ = c.x - sx;
- maxx_ = c.x + sx;
- miny_ = c.y - sy;
- maxy_ = c.y + sy;
- return *this;
-}
-
-template <typename T>
-box2d<T>& box2d<T>::operator/=(T t)
-{
- coord<T,2> c = center();
- T sx = static_cast<T>(0.5 * width() / t);
- T sy = static_cast<T>(0.5 * height() / t);
- minx_ = c.x - sx;
- maxx_ = c.x + sx;
- miny_ = c.y - sy;
- maxy_ = c.y + sy;
- return *this;
-}
-
-template <typename T>
-T box2d<T>::operator[] (int index) const
-{
- switch(index)
- {
- case 0:
- return minx_;
- case 1:
- return miny_;
- case 2:
- return maxx_;
- case 3:
- return maxy_;
- case -4:
- return minx_;
- case -3:
- return miny_;
- case -2:
- return maxx_;
- case -1:
- return maxy_;
- default:
- throw std::out_of_range("index out of range, max value is 3, min value is -4 ");
- }
-}
-
-template <typename T>
-box2d<T> box2d<T>::operator*(agg::trans_affine const& tr) const
-{
- return box2d<T>(*this, tr);
-}
-
-template <typename T>
-box2d<T>& box2d<T>::operator*=(agg::trans_affine const& tr)
-{
- double x0 = minx_, y0 = miny_;
- double x1 = maxx_, y1 = miny_;
- double x2 = maxx_, y2 = maxy_;
- double x3 = minx_, y3 = maxy_;
- tr.transform(&x0, &y0);
- tr.transform(&x1, &y1);
- tr.transform(&x2, &y2);
- tr.transform(&x3, &y3);
- init(static_cast<T>(x0), static_cast<T>(y0),
- static_cast<T>(x2), static_cast<T>(y2));
- expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
- expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
- return *this;
-}
+namespace mapnik {
template class box2d<int>;
template class box2d<float>;
diff --git a/src/cairo/process_line_pattern_symbolizer.cpp b/src/cairo/process_line_pattern_symbolizer.cpp
index 7aa85ab..f53d850 100644
--- a/src/cairo/process_line_pattern_symbolizer.cpp
+++ b/src/cairo/process_line_pattern_symbolizer.cpp
@@ -62,7 +62,7 @@ struct cairo_renderer_process_visitor_l
mapnik::rasterizer ras;
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height());
render_pattern<image_rgba8>(ras, marker, image_tr, 1.0, image);
diff --git a/src/cairo/process_polygon_pattern_symbolizer.cpp b/src/cairo/process_polygon_pattern_symbolizer.cpp
index c2b211f..4e21234 100644
--- a/src/cairo/process_polygon_pattern_symbolizer.cpp
+++ b/src/cairo/process_polygon_pattern_symbolizer.cpp
@@ -96,7 +96,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
value_double opacity = get<value_double, keys::opacity>(sym, feature, common_.vars_);
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform);
+ if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform, common_.scale_factor_);
cairo_save_restore guard(context_);
context_.set_operator(comp_op);
diff --git a/src/datasource_cache.cpp b/src/datasource_cache.cpp
index c561a7f..3759a6c 100644
--- a/src/datasource_cache.cpp
+++ b/src/datasource_cache.cpp
@@ -65,7 +65,7 @@ datasource_cache::~datasource_cache()
datasource_ptr datasource_cache::create(parameters const& params)
{
boost::optional<std::string> type = params.get<std::string>("type");
- if ( ! type)
+ if (!type)
{
throw config_error(std::string("Could not create datasource. Required ") +
"parameter 'type' is missing");
@@ -117,7 +117,7 @@ datasource_ptr datasource_cache::create(parameters const& params)
#endif
create_ds create_datasource = reinterpret_cast<create_ds>(itr->second->get_symbol("create"));
- if (! create_datasource)
+ if (!create_datasource)
{
throw std::runtime_error(std::string("Cannot load symbols: ") +
itr->second->get_error());
diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp
index a14e6b6..9721d70 100644
--- a/src/font_engine_freetype.cpp
+++ b/src/font_engine_freetype.cpp
@@ -105,7 +105,7 @@ bool freetype_engine::register_font_impl(std::string const& file_name,
streamRec.size = file.size();
streamRec.descriptor.pointer = file.get();
streamRec.read = ft_read_cb;
- streamRec.close = NULL;
+ streamRec.close = nullptr;
args.flags = FT_OPEN_STREAM;
args.stream = &streamRec;
int num_faces = 0;
@@ -269,7 +269,7 @@ bool freetype_engine::can_open(std::string const& face_name,
streamRec.size = file.size();
streamRec.descriptor.pointer = file.get();
streamRec.read = ft_read_cb;
- streamRec.close = NULL;
+ streamRec.close = nullptr;
args.flags = FT_OPEN_STREAM;
args.stream = &streamRec;
// -1 is used to quickly check if the font file appears valid without iterating each face
diff --git a/src/geometry_envelope.cpp b/src/geometry_envelope.cpp
index 5b3ade6..bb79f59 100644
--- a/src/geometry_envelope.cpp
+++ b/src/geometry_envelope.cpp
@@ -23,30 +23,21 @@
#include <mapnik/geometry_envelope.hpp>
#include <mapnik/geometry_envelope_impl.hpp>
#include <mapnik/text/symbolizer_helpers.hpp>
-namespace mapnik {
-namespace geometry {
+
+namespace mapnik { namespace geometry {
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry<double> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_empty const& geom);
+// single
template MAPNIK_DECL mapnik::box2d<double> envelope(point<double> const& geom);
template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<double> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(linear_ring<double> const& geom);
template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<double> const& geom);
+template MAPNIK_DECL mapnik::box2d<double> envelope(linear_ring<double> const& geom);
+// multi
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<double> const& geom);
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<double> const& geom);
template MAPNIK_DECL mapnik::box2d<double> envelope(multi_polygon<double> const& geom);
+// collection
template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_collection<double> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(geometry<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(point<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(line_string<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(linear_ring<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(polygon<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(multi_point<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(multi_line_string<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(multi_polygon<std::int64_t> const& geom);
-template MAPNIK_DECL mapnik::box2d<double> envelope(geometry_collection<std::int64_t> const& geom);
-
} // end ns geometry
} // end ns mapnik
diff --git a/src/grid/process_text_symbolizer.cpp b/src/grid/process_text_symbolizer.cpp
index 7fe0ff3..d1b6a17 100644
--- a/src/grid/process_text_symbolizer.cpp
+++ b/src/grid/process_text_symbolizer.cpp
@@ -60,7 +60,7 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
if (halo_transform)
{
agg::trans_affine halo_affine_transform;
- evaluate_transform(halo_affine_transform, feature, common_.vars_, *halo_transform);
+ evaluate_transform(halo_affine_transform, feature, common_.vars_, *halo_transform, common_.scale_factor_);
ren.set_halo_transform(halo_affine_transform);
}
diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp
index a8f9bba..d6c8a33 100644
--- a/src/image_compositing.cpp
+++ b/src/image_compositing.cpp
@@ -191,7 +191,20 @@ struct composite_visitor
dy_(dy) {}
template <typename T>
- void operator() (T & dst) const;
+ void operator() (T & dst) const
+ {
+ throw std::runtime_error("Error: Composite with " + std::string(typeid(dst).name()) + " is not supported");
+ }
+
+ void operator()(image_rgba8 & dst) const
+ {
+ composite(dst, util::get<image_rgba8>(src_), mode_, opacity_, dx_, dy_);
+ }
+
+ void operator() (image_gray32f & dst) const
+ {
+ composite(dst, util::get<image_gray32f>(src_), mode_, opacity_, dx_, dy_);
+ }
private:
image_any const& src_;
@@ -199,25 +212,8 @@ struct composite_visitor
float opacity_;
int dx_;
int dy_;
-};
-
-template <typename T>
-void composite_visitor::operator() (T & dst) const
-{
- throw std::runtime_error("Error: Composite with " + std::string(typeid(dst).name()) + " is not supported");
-}
-
-template <>
-void composite_visitor::operator()<image_rgba8> (image_rgba8 & dst) const
-{
- composite(dst, util::get<image_rgba8>(src_), mode_, opacity_, dx_, dy_);
-}
-template <>
-void composite_visitor::operator()<image_gray32f> (image_gray32f & dst) const
-{
- composite(dst, util::get<image_gray32f>(src_), mode_, opacity_, dx_, dy_);
-}
+};
} // end ns
diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp
index 84c805e..6b6e1b1 100644
--- a/src/jpeg_reader.cpp
+++ b/src/jpeg_reader.cpp
@@ -22,6 +22,7 @@
// mapnik
#include <mapnik/image_reader.hpp>
+#include <mapnik/util/char_array_buffer.hpp>
#include <mapnik/color.hpp>
// jpeg
@@ -30,16 +31,10 @@ extern "C"
#include <jpeglib.h>
}
-#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include <boost/iostreams/device/file.hpp>
-#include <boost/iostreams/device/array.hpp>
-#include <boost/iostreams/stream.hpp>
-#pragma GCC diagnostic pop
-
// std
#include <cstdio>
#include <memory>
+#include <fstream>
namespace mapnik
{
@@ -49,7 +44,7 @@ class jpeg_reader : public image_reader
{
public:
using source_type = T;
- using input_stream = boost::iostreams::stream<source_type>;
+ using input_stream = std::iostream;
const static unsigned BUF_SIZE = 4096;
private:
struct jpeg_stream_wrapper
@@ -77,7 +72,7 @@ private:
unsigned width_;
unsigned height_;
public:
- explicit jpeg_reader(std::string const& file_name);
+ explicit jpeg_reader(std::string const& filename);
explicit jpeg_reader(char const* data, size_t size);
~jpeg_reader();
unsigned width() const final;
@@ -99,14 +94,14 @@ private:
namespace
{
-image_reader* create_jpeg_reader(std::string const& file)
+image_reader* create_jpeg_reader(std::string const& filename)
{
- return new jpeg_reader<boost::iostreams::file_source>(file);
+ return new jpeg_reader<std::filebuf>(filename);
}
image_reader* create_jpeg_reader2(char const* data, size_t size)
{
- return new jpeg_reader<boost::iostreams::array_source>(data, size);
+ return new jpeg_reader<mapnik::util::char_array_buffer>(data, size);
}
const bool registered = register_image_reader("jpeg",create_jpeg_reader);
@@ -115,20 +110,21 @@ const bool registered2 = register_image_reader("jpeg",create_jpeg_reader2);
// ctors
template <typename T>
-jpeg_reader<T>::jpeg_reader(std::string const& file_name)
- : source_(file_name,std::ios_base::in | std::ios_base::binary),
- stream_(source_),
+jpeg_reader<T>::jpeg_reader(std::string const& filename)
+ : source_(),
+ stream_(&source_),
width_(0),
height_(0)
{
- if (!stream_) throw image_reader_exception("cannot open image file "+ file_name);
+ source_.open(filename, std::ios_base::in | std::ios_base::binary);
+ if (!stream_) throw image_reader_exception("cannot open image file "+ filename);
init();
}
template <typename T>
jpeg_reader<T>::jpeg_reader(char const* data, size_t size)
: source_(data, size),
- stream_(source_),
+ stream_(&source_),
width_(0),
height_(0)
{
diff --git a/src/load_map.cpp b/src/load_map.cpp
index f217082..fcb04c0 100644
--- a/src/load_map.cpp
+++ b/src/load_map.cpp
@@ -200,7 +200,7 @@ void map_parser::parse_map(Map & map, xml_node const& node, std::string const& b
{
map.set_background(*bgcolor);
}
-
+
optional<std::string> image_filename = map_node.get_opt_attr<std::string>("background-image");
if (image_filename)
{
@@ -891,7 +891,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const& nod
{
set_symbolizer_property<symbolizer_base,double>(sym, keys::simplify_tolerance, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::smooth, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::clip, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::clip, node);
set_symbolizer_property<symbolizer_base,composite_mode_e>(sym, keys::comp_op, node);
set_symbolizer_property<symbolizer_base,transform_type>(sym, keys::geometry_transform, node);
set_symbolizer_property<symbolizer_base,simplify_algorithm_e>(sym, keys::simplify_algorithm, node);
@@ -907,8 +907,8 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & node)
point_symbolizer sym;
parse_symbolizer_base(sym, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::opacity, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::allow_overlap, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::ignore_placement, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::allow_overlap, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::ignore_placement, node);
set_symbolizer_property<symbolizer_base,point_placement_enum>(sym, keys::point_placement_type, node);
set_symbolizer_property<symbolizer_base,transform_type>(sym, keys::image_transform, node);
if (file && !file->empty())
@@ -1011,9 +1011,9 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
set_symbolizer_property<symbolizer_base,double>(sym, keys::offset, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::width, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::height, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::allow_overlap, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::avoid_edges, node);
- set_symbolizer_property<symbolizer_base,boolean_type>(sym, keys::ignore_placement, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::allow_overlap, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::avoid_edges, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::ignore_placement, node);
set_symbolizer_property<symbolizer_base,color>(sym, keys::fill, node);
set_symbolizer_property<symbolizer_base,transform_type>(sym, keys::image_transform, node);
set_symbolizer_property<symbolizer_base,marker_placement_enum>(sym, keys::markers_placement_type, node);
@@ -1172,7 +1172,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& node)
set_symbolizer_property<symbolizer_base,double>(sym, keys::shield_dx, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::shield_dy, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::opacity, node);
- set_symbolizer_property<symbolizer_base,mapnik::boolean_type>(sym, keys::unlock_image, node);
+ set_symbolizer_property<symbolizer_base,value_bool>(sym, keys::unlock_image, node);
std::string file = node.get_attr<std::string>("file");
if (file.empty())
@@ -1343,7 +1343,7 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & node)
// premultiplied status of image
optional<mapnik::boolean_type> premultiplied = node.get_opt_attr<mapnik::boolean_type>("premultiplied");
- if (premultiplied) put(raster_sym, keys::premultiplied, *premultiplied);
+ if (premultiplied) put(raster_sym, keys::premultiplied, bool(*premultiplied));
bool found_colorizer = false;
for ( auto const& css : node)
diff --git a/src/map.cpp b/src/map.cpp
index 3aff557..ca813e2 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -746,7 +746,7 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const
else s << " (map has no layers)";
throw std::out_of_range(s.str());
}
- return featureset_ptr();
+ return mapnik::make_empty_featureset();
}
featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
diff --git a/src/marker_helpers.cpp b/src/marker_helpers.cpp
index dc9f679..eb02021 100644
--- a/src/marker_helpers.cpp
+++ b/src/marker_helpers.cpp
@@ -37,6 +37,7 @@ void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, a
{
double width = 0.0;
double height = 0.0;
+ double half_stroke_width = 0.0;
if (has_key(sym,keys::width) && has_key(sym,keys::height))
{
width = get<double>(sym, keys::width, feature, vars, 0.0);
@@ -50,6 +51,10 @@ void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, a
{
width = height = get<double>(sym, keys::height, feature, vars, 0.0);
}
+ if (has_key(sym,keys::stroke_width))
+ {
+ half_stroke_width = get<double>(sym, keys::stroke_width, feature, vars, 0.0) / 2.0;
+ }
svg::svg_converter_type styled_svg(svg_path, marker_ellipse.attributes());
styled_svg.push_attr();
styled_svg.begin_path();
@@ -59,6 +64,10 @@ void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, a
styled_svg.pop_attr();
double lox,loy,hix,hiy;
styled_svg.bounding_rect(&lox, &loy, &hix, &hiy);
+ lox -= half_stroke_width;
+ loy -= half_stroke_width;
+ hix += half_stroke_width;
+ hiy += half_stroke_width;
styled_svg.set_dimensions(width,height);
marker_ellipse.set_dimensions(width,height);
marker_ellipse.set_bounding_box(lox,loy,hix,hiy);
diff --git a/src/palette.cpp b/src/palette.cpp
index 4c3807d..1fc5b8b 100644
--- a/src/palette.cpp
+++ b/src/palette.cpp
@@ -65,16 +65,6 @@ rgba_palette::rgba_palette()
#endif
}
-const std::vector<rgb>& rgba_palette::palette() const
-{
- return rgb_pal_;
-}
-
-const std::vector<unsigned>& rgba_palette::alphaTable() const
-{
- return alpha_pal_;
-}
-
bool rgba_palette::valid() const
{
return colors_ > 0;
diff --git a/src/plugin.cpp b/src/plugin.cpp
index af9bef3..b218630 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -58,16 +58,24 @@ PluginInfo::PluginInfo(std::string const& filename,
if (module_) module_->dl = LoadLibraryA(filename.c_str());
if (module_ && module_->dl)
{
- name_func name = reinterpret_cast<name_func>(dlsym(module_->dl, library_name.c_str()));
+ callable_returning_string name = reinterpret_cast<callable_returning_string>(dlsym(module_->dl, library_name.c_str()));
if (name) name_ = name();
+ callable_returning_void init_once = reinterpret_cast<callable_returning_void>(dlsym(module_->dl, "on_plugin_load"));
+ if (init_once) {
+ init_once();
+ }
}
#else
#ifdef MAPNIK_HAS_DLCFN
if (module_) module_->dl = dlopen(filename.c_str(),RTLD_LAZY);
if (module_ && module_->dl)
{
- name_func name = reinterpret_cast<name_func>(dlsym(module_->dl, library_name.c_str()));
+ callable_returning_string name = reinterpret_cast<callable_returning_string>(dlsym(module_->dl, library_name.c_str()));
if (name) name_ = name();
+ callable_returning_void init_once = reinterpret_cast<callable_returning_void>(dlsym(module_->dl, "on_plugin_load"));
+ if (init_once) {
+ init_once();
+ }
}
#else
throw std::runtime_error("no support for loading dynamic objects (Mapnik not compiled with -DMAPNIK_HAS_DLCFN)");
@@ -108,7 +116,7 @@ void * PluginInfo::get_symbol(std::string const& sym_name) const
#ifdef MAPNIK_SUPPORTS_DLOPEN
return static_cast<void *>(dlsym(module_->dl, sym_name.c_str()));
#else
- return NULL;
+ return nullptr;
#endif
}
diff --git a/src/png_reader.cpp b/src/png_reader.cpp
index 30b470f..8c58b22 100644
--- a/src/png_reader.cpp
+++ b/src/png_reader.cpp
@@ -23,22 +23,17 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/image_reader.hpp>
+#include <mapnik/util/char_array_buffer.hpp>
extern "C"
{
#include <png.h>
}
-#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include <boost/iostreams/device/file.hpp>
-#include <boost/iostreams/device/array.hpp>
-#include <boost/iostreams/stream.hpp>
-#pragma GCC diagnostic pop
-
// stl
#include <cstring>
#include <memory>
+#include <fstream>
namespace mapnik
{
@@ -47,7 +42,7 @@ template <typename T>
class png_reader : public image_reader
{
using source_type = T;
- using input_stream = boost::iostreams::stream<source_type>;
+ using input_stream = std::istream;
struct png_struct_guard
{
@@ -73,7 +68,7 @@ private:
int color_type_;
bool has_alpha_;
public:
- explicit png_reader(std::string const& file_name);
+ explicit png_reader(std::string const& filename);
png_reader(char const* data, std::size_t size);
~png_reader();
unsigned width() const final;
@@ -90,14 +85,14 @@ private:
namespace
{
-image_reader* create_png_reader(std::string const& file)
+image_reader* create_png_reader(std::string const& filename)
{
- return new png_reader<boost::iostreams::file_source>(file);
+ return new png_reader<std::filebuf>(filename);
}
image_reader* create_png_reader2(char const * data, std::size_t size)
{
- return new png_reader<boost::iostreams::array_source>(data, size);
+ return new png_reader<mapnik::util::char_array_buffer>(data, size);
}
const bool registered = register_image_reader("png",create_png_reader);
@@ -128,31 +123,30 @@ void png_reader<T>::png_read_data(png_structp png_ptr, png_bytep data, png_size_
}
template <typename T>
-png_reader<T>::png_reader(std::string const& file_name)
- : source_(file_name,std::ios_base::in | std::ios_base::binary),
- stream_(source_),
+png_reader<T>::png_reader(std::string const& filename)
+ : source_(),
+ stream_(&source_),
width_(0),
height_(0),
bit_depth_(0),
color_type_(0),
has_alpha_(false)
{
- if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'");
- if (!stream_) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'");
+ source_.open(filename, std::ios_base::in | std::ios_base::binary);
+ if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ filename + "'");
init();
}
template <typename T>
png_reader<T>::png_reader(char const* data, std::size_t size)
: source_(data,size),
- stream_(source_),
+ stream_(&source_),
width_(0),
height_(0),
bit_depth_(0),
color_type_(0),
has_alpha_(false)
{
-
if (!stream_) throw image_reader_exception("PNG reader: cannot open image stream");
init();
}
diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp
index a08b4d7..9c23d80 100644
--- a/src/proj_transform.cpp
+++ b/src/proj_transform.cpp
@@ -26,6 +26,7 @@
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/coord.hpp>
+#include <mapnik/util/is_clockwise.hpp>
#ifdef MAPNIK_USE_PROJ4
// proj4
@@ -124,7 +125,7 @@ unsigned int proj_transform::forward (geometry::line_string<double> & ls) const
geometry::point<double> * ptr = ls.data();
double * x = reinterpret_cast<double*>(ptr);
double * y = x + 1;
- double * z = NULL;
+ double * z = nullptr;
if(!forward(x, y, z, size, 2))
{
return size;
@@ -199,20 +200,21 @@ bool proj_transform::backward (double * x, double * y , double * z, int point_co
#ifdef MAPNIK_USE_PROJ4
if (is_dest_longlat_)
{
- int i;
- for(i=0; i<point_count; i++) {
- x[i*offset] *= DEG_TO_RAD;
- y[i*offset] *= DEG_TO_RAD;
+ for (int i = 0; i < point_count; ++i)
+ {
+ x[i * offset] *= DEG_TO_RAD;
+ y[i * offset] *= DEG_TO_RAD;
}
}
- if (pj_transform( dest_.proj_, source_.proj_, point_count,
- offset, x,y,z) != 0)
+ if (pj_transform(dest_.proj_, source_.proj_, point_count,
+ offset, x, y, z) != 0)
{
return false;
}
- for(int j=0; j<point_count; j++) {
+ for (int j = 0; j < point_count; ++j)
+ {
if (x[j] == HUGE_VAL || y[j] == HUGE_VAL)
{
return false;
@@ -221,10 +223,10 @@ bool proj_transform::backward (double * x, double * y , double * z, int point_co
if (is_source_longlat_)
{
- int i;
- for(i=0; i<point_count; i++) {
- x[i*offset] *= RAD_TO_DEG;
- y[i*offset] *= RAD_TO_DEG;
+ for (int i = 0; i < point_count; ++i)
+ {
+ x[i * offset] *= RAD_TO_DEG;
+ y[i * offset] *= RAD_TO_DEG;
}
}
#endif
@@ -264,8 +266,8 @@ unsigned int proj_transform::backward (geometry::line_string<double> & ls) const
geometry::point<double> * ptr = ls.data();
double * x = reinterpret_cast<double*>(ptr);
double * y = x + 1;
- double * z = NULL;
- if(!backward(x, y, z, size, 2))
+ double * z = nullptr;
+ if (!backward(x, y, z, size, 2))
{
return size;
}
@@ -311,31 +313,24 @@ bool proj_transform::backward (box2d<double> & box) const
if (is_source_equal_dest_)
return true;
- double llx = box.minx();
- double ulx = box.minx();
- double lly = box.miny();
- double lry = box.miny();
- double lrx = box.maxx();
- double urx = box.maxx();
- double uly = box.maxy();
- double ury = box.maxy();
- double z = 0.0;
- if (!backward(llx,lly,z))
- return false;
- if (!backward(lrx,lry,z))
- return false;
- if (!backward(ulx,uly,z))
- return false;
- if (!backward(urx,ury,z))
+ double x[4], y[4];
+ x[0] = box.minx(); // llx 0
+ y[0] = box.miny(); // lly 1
+ x[1] = box.maxx(); // lrx 2
+ y[1] = box.miny(); // lry 3
+ x[2] = box.minx(); // ulx 4
+ y[2] = box.maxy(); // uly 5
+ x[3] = box.maxx(); // urx 6
+ y[3] = box.maxy(); // ury 7
+
+ if (!backward(x, y, nullptr, 4, 1))
return false;
- double minx = std::min(ulx, llx);
- double miny = std::min(lly, lry);
- double maxx = std::max(urx, lrx);
- double maxy = std::max(ury, uly);
- box.init(minx,
- miny,
- maxx,
- maxy);
+
+ double minx = std::min(x[0], x[2]);
+ double miny = std::min(y[0], y[1]);
+ double maxx = std::max(x[1], x[3]);
+ double maxy = std::max(y[2], y[3]);
+ box.init(minx, miny, maxx, maxy);
return true;
}
@@ -370,21 +365,6 @@ void envelope_points(std::vector< coord<double,2> > & coords, box2d<double>& env
}
}
-// determine if an ordered sequence of coordinates is in clockwise order
-bool is_clockwise(const std::vector< coord<double,2> > & coords)
-{
- int n = coords.size();
- coord<double,2> c1, c2;
- double a = 0.0;
-
- for (int i=0; i<n; i++) {
- c1 = coords[i];
- c2 = coords[(i + 1) % n];
- a += (c1.x * c2.y - c2.x * c1.y);
- }
- return a <= 0.0;
-}
-
box2d<double> calculate_bbox(std::vector<coord<double,2> > & points) {
std::vector<coord<double,2> >::iterator it = points.begin();
std::vector<coord<double,2> >::iterator it_end = points.end();
@@ -425,7 +405,7 @@ bool proj_transform::backward(box2d<double>& env, int points) const
}
box2d<double> result = calculate_bbox(coords);
- if (is_source_longlat_ && !is_clockwise(coords))
+ if (is_source_longlat_ && !util::is_clockwise(coords))
{
// we've gone to a geographic CS, and our clockwise envelope has
// changed into an anticlockwise one. This means we've crossed the antimeridian, and
@@ -439,7 +419,6 @@ bool proj_transform::backward(box2d<double>& env, int points) const
env.re_center(result.center().x, result.center().y);
env.height(result.height());
env.width(result.width());
-
return true;
}
@@ -466,7 +445,7 @@ bool proj_transform::forward(box2d<double>& env, int points) const
box2d<double> result = calculate_bbox(coords);
- if (is_dest_longlat_ && !is_clockwise(coords))
+ if (is_dest_longlat_ && !util::is_clockwise(coords))
{
// we've gone to a geographic CS, and our clockwise envelope has
// changed into an anticlockwise one. This means we've crossed the antimeridian, and
diff --git a/src/renderer_common/render_markers_symbolizer.cpp b/src/renderer_common/render_markers_symbolizer.cpp
index 2ecc51b..6706cb1 100644
--- a/src/renderer_common/render_markers_symbolizer.cpp
+++ b/src/renderer_common/render_markers_symbolizer.cpp
@@ -159,7 +159,7 @@ struct render_marker_symbolizer_visitor
if (auto image_transform = get_optional<transform_type>(sym_, keys::image_transform))
{
- evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
}
vector_dispatch_type rasterizer_dispatch(marker_ptr,
@@ -183,7 +183,7 @@ struct render_marker_symbolizer_visitor
setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
box2d<double> const& bbox = mark.bounding_box();
mapnik::image_rgba8 const& marker = mark.get_data();
// - clamp sizes to > 4 pixels of interactivity
diff --git a/src/text/formatting/layout.cpp b/src/text/formatting/layout.cpp
index ef908c5..9a5ca10 100644
--- a/src/text/formatting/layout.cpp
+++ b/src/text/formatting/layout.cpp
@@ -75,9 +75,9 @@ node_ptr layout_node::from_xml(xml_node const& xml, fontset_map const& fontsets)
if (xml.has_attribute("text-ratio")) set_property_from_xml<double>(n->text_ratio, "text-ratio", xml);
if (xml.has_attribute("wrap-width")) set_property_from_xml<double>(n->wrap_width, "wrap-width", xml);
if (xml.has_attribute("wrap-character")) set_property_from_xml<std::string>(n->wrap_char, "wrap-character", xml);
- if (xml.has_attribute("wrap-before")) set_property_from_xml<mapnik::boolean_type>(n->wrap_before, "wrap-before", xml);
- if (xml.has_attribute("repeat-wrap-character")) set_property_from_xml<mapnik::boolean_type>(n->repeat_wrap_char, "repeat-wrap-character", xml);
- if (xml.has_attribute("rotate-displacement")) set_property_from_xml<mapnik::boolean_type>(n->rotate_displacement, "rotate-displacement", xml);
+ if (xml.has_attribute("wrap-before")) set_property_from_xml<mapnik::value_bool>(n->wrap_before, "wrap-before", xml);
+ if (xml.has_attribute("repeat-wrap-character")) set_property_from_xml<mapnik::value_bool>(n->repeat_wrap_char, "repeat-wrap-character", xml);
+ if (xml.has_attribute("rotate-displacement")) set_property_from_xml<mapnik::value_bool>(n->rotate_displacement, "rotate-displacement", xml);
if (xml.has_attribute("orientation")) set_property_from_xml<double>(n->orientation, "orientation", xml);
if (xml.has_attribute("horizontal-alignment")) set_property_from_xml<horizontal_alignment_e>(n->halign, "horizontal-alignment", xml);
if (xml.has_attribute("vertical-alignment")) set_property_from_xml<vertical_alignment_e>(n->valign, "vertical-alignment", xml);
diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp
index 04a2907..e4adddf 100644
--- a/src/text/placement_finder.cpp
+++ b/src/text/placement_finder.cpp
@@ -39,6 +39,41 @@
namespace mapnik
{
+namespace {
+box2d<double> get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
+{
+ /*
+
+ (0/ymax) (width/ymax)
+ ***************
+ * *
+ (0/0)* *
+ * *
+ ***************
+ (0/ymin) (width/ymin)
+ Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)!
+ */
+ double width = layout.cluster_width(glyph.char_index);
+ if (glyph.advance() <= 0) width = -width;
+ pixel_position tmp, tmp2;
+ tmp.set(0, glyph.ymax());
+ tmp = tmp.rotate(rot);
+ tmp2.set(width, glyph.ymax());
+ tmp2 = tmp2.rotate(rot);
+ box2d<double> bbox(tmp.x, -tmp.y,
+ tmp2.x, -tmp2.y);
+ tmp.set(width, glyph.ymin());
+ tmp = tmp.rotate(rot);
+ bbox.expand_to_include(tmp.x, -tmp.y);
+ tmp.set(0, glyph.ymin());
+ tmp = tmp.rotate(rot);
+ bbox.expand_to_include(tmp.x, -tmp.y);
+ pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot);
+ bbox.move(pos2.x , -pos2.y);
+ return bbox;
+}
+} // anonymous namespace
+
placement_finder::placement_finder(feature_impl const& feature,
attributes const& attr,
DetectorType &detector,
@@ -432,37 +467,4 @@ bool placement_finder::add_marker(glyph_positions_ptr & glyphs, pixel_position c
return true;
}
-box2d<double> placement_finder::get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
-{
- /*
-
- (0/ymax) (width/ymax)
- ***************
- * *
- (0/0)* *
- * *
- ***************
- (0/ymin) (width/ymin)
- Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)!
- */
- double width = layout.cluster_width(glyph.char_index);
- if (glyph.advance() <= 0) width = -width;
- pixel_position tmp, tmp2;
- tmp.set(0, glyph.ymax());
- tmp = tmp.rotate(rot);
- tmp2.set(width, glyph.ymax());
- tmp2 = tmp2.rotate(rot);
- box2d<double> bbox(tmp.x, -tmp.y,
- tmp2.x, -tmp2.y);
- tmp.set(width, glyph.ymin());
- tmp = tmp.rotate(rot);
- bbox.expand_to_include(tmp.x, -tmp.y);
- tmp.set(0, glyph.ymin());
- tmp = tmp.rotate(rot);
- bbox.expand_to_include(tmp.x, -tmp.y);
- pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot);
- bbox.move(pos2.x , -pos2.y);
- return bbox;
-}
-
}// ns mapnik
diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp
index 1d0fe48..fe5568a 100644
--- a/src/text/symbolizer_helpers.cpp
+++ b/src/text/symbolizer_helpers.cpp
@@ -41,8 +41,39 @@
#include <mapnik/text/placements/base.hpp>
#include <mapnik/text/placements/dummy.hpp>
+namespace mapnik {
+namespace geometry {
-namespace mapnik { namespace detail {
+struct envelope_impl
+{
+ template <typename T>
+ box2d<double> operator() (T const& ref) const
+ {
+ return envelope<T>(ref);
+ }
+};
+
+mapnik::box2d<double> envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom)
+{
+ return mapnik::util::apply_visitor(envelope_impl(), geom);
+}
+
+struct geometry_type_impl
+{
+ template <typename T>
+ auto operator() (T const& ref) const -> decltype(geometry_type<T>(ref))
+ {
+ return geometry_type<T>(ref);
+ }
+};
+
+mapnik::geometry::geometry_types geometry_type(mapnik::base_symbolizer_helper::geometry_cref const& geom)
+{
+ return mapnik::util::apply_visitor(geometry_type_impl(), geom);
+}
+
+} // geometry
+namespace detail {
template <typename Points>
struct apply_vertex_placement
@@ -389,7 +420,7 @@ bool text_symbolizer_helper::next_point_placement() const
return true;
}
//No placement for this point. Keep it in points_ for next try.
- point_itr_++;
+ ++point_itr_;
}
return false;
}
@@ -434,7 +465,7 @@ void text_symbolizer_helper::init_marker() const
if (marker->is<marker_null>()) return;
agg::trans_affine trans;
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(trans, feature_, vars_, *image_transform);
+ if (image_transform) evaluate_transform(trans, feature_, vars_, *image_transform, scale_factor_);
double width = marker->width();
double height = marker->height();
double px0 = - 0.5 * width;
@@ -460,7 +491,6 @@ void text_symbolizer_helper::init_marker() const
finder_.set_marker(std::make_shared<marker_info>(marker, trans), bbox, unlock_image, marker_displacement);
}
-
template text_symbolizer_helper::text_symbolizer_helper(
text_symbolizer const& sym,
feature_impl const& feature,
diff --git a/src/text/text_line.cpp b/src/text/text_line.cpp
index f228e5b..2d05167 100644
--- a/src/text/text_line.cpp
+++ b/src/text/text_line.cpp
@@ -51,7 +51,7 @@ text_line::text_line(text_line && rhs)
void text_line::add_glyph(glyph_info && glyph, double scale_factor_)
{
- line_height_ = std::max(line_height_, glyph.line_height() + glyph.format->line_spacing);
+ line_height_ = std::max(line_height_, glyph.line_height() + glyph.format->line_spacing * scale_factor_);
double advance = glyph.advance();
if (glyphs_.empty())
{
diff --git a/src/text/text_properties.cpp b/src/text/text_properties.cpp
index ef5b9af..73210d1 100644
--- a/src/text/text_properties.cpp
+++ b/src/text/text_properties.cpp
@@ -103,9 +103,9 @@ void text_symbolizer_properties::text_properties_from_xml(xml_node const& node)
set_property_from_xml<value_double>(expressions.label_position_tolerance, "label-position-tolerance", node);
set_property_from_xml<value_double>(expressions.minimum_padding, "minimum-padding", node);
set_property_from_xml<value_double>(expressions.minimum_path_length, "minimum-path-length", node);
- set_property_from_xml<boolean_type>(expressions.avoid_edges, "avoid-edges", node);
- set_property_from_xml<boolean_type>(expressions.allow_overlap, "allow-overlap", node);
- set_property_from_xml<boolean_type>(expressions.largest_bbox_only, "largest-bbox-only", node);
+ set_property_from_xml<value_bool>(expressions.avoid_edges, "avoid-edges", node);
+ set_property_from_xml<value_bool>(expressions.allow_overlap, "allow-overlap", node);
+ set_property_from_xml<value_bool>(expressions.largest_bbox_only, "largest-bbox-only", node);
set_property_from_xml<value_double>(expressions.max_char_angle_delta, "max-char-angle-delta", node);
set_property_from_xml<text_upright_e>(expressions.upright, "upright", node);
}
@@ -215,9 +215,9 @@ void text_layout_properties::from_xml(xml_node const &node, fontset_map const& f
set_property_from_xml<double>(text_ratio, "text-ratio", node);
set_property_from_xml<double>(wrap_width, "wrap-width", node);
set_property_from_xml<std::string>(wrap_char, "wrap-character", node);
- set_property_from_xml<boolean_type>(wrap_before, "wrap-before", node);
- set_property_from_xml<boolean_type>(repeat_wrap_char, "repeat-wrap-character", node);
- set_property_from_xml<boolean_type>(rotate_displacement, "rotate-displacement", node);
+ set_property_from_xml<value_bool>(wrap_before, "wrap-before", node);
+ set_property_from_xml<value_bool>(repeat_wrap_char, "repeat-wrap-character", node);
+ set_property_from_xml<value_bool>(rotate_displacement, "rotate-displacement", node);
set_property_from_xml<double>(orientation, "orientation", node);
set_property_from_xml<vertical_alignment_e>(valign, "vertical-alignment", node);
set_property_from_xml<horizontal_alignment_e>(halign, "horizontal-alignment", node);
diff --git a/src/tiff_reader.cpp b/src/tiff_reader.cpp
index 1f88540..157e4d0 100644
--- a/src/tiff_reader.cpp
+++ b/src/tiff_reader.cpp
@@ -23,21 +23,15 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/image_reader.hpp>
-
+#include <mapnik/util/char_array_buffer.hpp>
extern "C"
{
#include <tiffio.h>
}
-#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include <boost/iostreams/device/file.hpp>
-#include <boost/iostreams/device/array.hpp>
-#include <boost/iostreams/stream.hpp>
-#pragma GCC diagnostic pop
-
// stl
#include <memory>
+#include <fstream>
namespace mapnik { namespace impl {
@@ -106,7 +100,7 @@ class tiff_reader : public image_reader
{
using tiff_ptr = std::shared_ptr<TIFF>;
using source_type = T;
- using input_stream = boost::iostreams::stream<source_type>;
+ using input_stream = std::istream;
struct tiff_closer
{
@@ -145,7 +139,7 @@ public:
stripped,
tiled
};
- explicit tiff_reader(std::string const& file_name);
+ explicit tiff_reader(std::string const& filename);
tiff_reader(char const* data, std::size_t size);
virtual ~tiff_reader();
unsigned width() const final;
@@ -183,14 +177,14 @@ private:
namespace
{
-image_reader* create_tiff_reader(std::string const& file)
+image_reader* create_tiff_reader(std::string const& filename)
{
- return new tiff_reader<boost::iostreams::file_source>(file);
+ return new tiff_reader<std::filebuf>(filename);
}
image_reader* create_tiff_reader2(char const * data, std::size_t size)
{
- return new tiff_reader<boost::iostreams::array_source>(data, size);
+ return new tiff_reader<mapnik::util::char_array_buffer>(data, size);
}
const bool registered = register_image_reader("tiff",create_tiff_reader);
@@ -199,9 +193,9 @@ const bool registered2 = register_image_reader("tiff", create_tiff_reader2);
}
template <typename T>
-tiff_reader<T>::tiff_reader(std::string const& file_name)
- : source_(file_name, std::ios_base::in | std::ios_base::binary),
- stream_(source_),
+tiff_reader<T>::tiff_reader(std::string const& filename)
+ : source_(),
+ stream_(&source_),
tif_(nullptr),
read_method_(generic),
rows_per_strip_(0),
@@ -218,14 +212,15 @@ tiff_reader<T>::tiff_reader(std::string const& file_name)
has_alpha_(false),
is_tiled_(false)
{
- if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ file_name);
+ source_.open(filename, std::ios_base::in | std::ios_base::binary);
+ if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ filename);
init();
}
template <typename T>
tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
: source_(data, size),
- stream_(source_),
+ stream_(&source_),
tif_(nullptr),
read_method_(generic),
rows_per_strip_(0),
@@ -243,8 +238,6 @@ tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
is_tiled_(false)
{
if (!stream_) throw image_reader_exception("TIFF reader: cannot open image stream ");
- stream_.rdbuf()->pubsetbuf(0, 0);
- stream_.seekg(0, std::ios::beg);
init();
}
diff --git a/src/value.cpp b/src/value.cpp
index a3c8770..b5ad606 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -673,7 +673,7 @@ struct convert<std::string>
std::string operator()(value_null const&) const
{
- return std::string();
+ return std::string("");
}
};
@@ -708,7 +708,7 @@ struct to_unicode_impl
value_unicode_string operator()(value_null const&) const
{
- return value_unicode_string();
+ return value_unicode_string("");
}
};
diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp
index 06be6c2..e96a9e2 100644
--- a/src/vertex_adapters.cpp
+++ b/src/vertex_adapters.cpp
@@ -34,7 +34,7 @@ point_vertex_adapter<T>::point_vertex_adapter(point<T> const& pt)
first_(true) {}
template <typename T>
-unsigned point_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+unsigned point_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
{
if (first_)
{
@@ -67,7 +67,7 @@ line_string_vertex_adapter<T>::line_string_vertex_adapter(line_string<T> const&
{}
template <typename T>
-unsigned line_string_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+unsigned line_string_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
{
if (current_index_ != end_index_)
{
@@ -117,7 +117,7 @@ void polygon_vertex_adapter<T>::rewind(unsigned) const
start_loop_ = true;
}
template <typename T>
-unsigned polygon_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+unsigned polygon_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
{
if (rings_itr_ == rings_end_)
{
@@ -177,7 +177,7 @@ void ring_vertex_adapter<T>::rewind(unsigned) const
}
template <typename T>
-unsigned ring_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+unsigned ring_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
{
if (current_index_ < end_index_)
{
diff --git a/src/webp_reader.cpp b/src/webp_reader.cpp
index c806df9..ca611ae 100644
--- a/src/webp_reader.cpp
+++ b/src/webp_reader.cpp
@@ -33,9 +33,6 @@ extern "C"
#include <webp/decode.h>
}
-#include <boost/iostreams/device/file.hpp>
-#include <boost/iostreams/device/array.hpp>
-#include <boost/iostreams/stream.hpp>
#pragma GCC diagnostic pop
// stl
diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp
index e342e68..2e2a7df 100644
--- a/src/xml_tree.cpp
+++ b/src/xml_tree.cpp
@@ -69,11 +69,10 @@ DEFINE_NAME_TRAIT( double, "double")
DEFINE_NAME_TRAIT( float, "float")
DEFINE_NAME_TRAIT( unsigned, "unsigned")
DEFINE_NAME_TRAIT( int, "int")
+DEFINE_NAME_TRAIT( bool, "bool")
DEFINE_NAME_TRAIT( boolean_type, "boolean_type")
#ifdef BIGINT
DEFINE_NAME_TRAIT( mapnik::value_integer, "long long" )
-#else
-DEFINE_NAME_TRAIT( mapnik::value_integer, "int" )
#endif
DEFINE_NAME_TRAIT( std::string, "string" )
DEFINE_NAME_TRAIT( color, "color" )
@@ -413,10 +412,13 @@ std::string xml_node::line_to_string() const
#define compile_get_value(T) template T xml_node::get_value<T>() const
compile_get_opt_attr(boolean_type);
+compile_get_opt_attr(mapnik::value_bool);
compile_get_opt_attr(std::string);
compile_get_opt_attr(int);
compile_get_opt_attr(unsigned);
+#ifdef BIGINT
compile_get_opt_attr(mapnik::value_integer);
+#endif
compile_get_opt_attr(float);
compile_get_opt_attr(double);
compile_get_opt_attr(color);
diff --git a/test/run b/test/run
index f623609..014b798 100755
--- a/test/run
+++ b/test/run
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
+set -o pipefail
+set -eu
+
failures=0
cd "$( dirname "${BASH_SOURCE[0]}" )"
@@ -18,9 +21,8 @@ if [ -d "test/data" ]; then
run_substep "Running C++ Unit tests..."
if [[ -f ./test/unit/run ]]; then
- ./test/unit/run
- failures=$((failures+$?))
ran_a_test=true
+ ./test/unit/run || failures=$((failures+$?))
else
run_warn "Skipping unit tests since they were not built"
fi
@@ -31,8 +33,7 @@ if [ -d "test/data" ]; then
for FILE in test/standalone/*-bin; do
found_test=true
ran_a_test=true
- ${FILE};
- failures=$((failures+$?))
+ ${FILE} || failures=$((failures+$?))
done
fi
if [[ $found_test == false ]]; then
@@ -41,13 +42,12 @@ if [ -d "test/data" ]; then
if [ -d "test/data-visual/styles" ]; then
run_substep "Running visual tests..."
- if [ -z "$JOBS" ]; then
+ if [ -z "${JOBS:-}" ]; then
JOBS=1
fi
if [[ -f ./test/visual/run ]]; then
- ./test/visual/run -j $JOBS
ran_a_test=true
- failures=$((failures+$?))
+ ./test/visual/run -j $JOBS || failures=$((failures+$?))
else
run_warn "Skipping visual tests since they were not built"
fi
diff --git a/test/standalone/font_registration_test.cpp b/test/standalone/font_registration_test.cpp
index fda605f..db56a30 100644
--- a/test/standalone/font_registration_test.cpp
+++ b/test/standalone/font_registration_test.cpp
@@ -46,16 +46,16 @@ SECTION("registration") {
REQUIRE( m.load_fonts() );
REQUIRE( m.get_font_memory_cache().size() == 1 );
REQUIRE( m.register_fonts(fontdir , true ) );
- REQUIRE( m.get_font_file_mapping().size() == 22 );
+ REQUIRE( m.get_font_file_mapping().size() == 23 );
REQUIRE( m.load_fonts() );
- REQUIRE( m.get_font_memory_cache().size() == 22 );
+ REQUIRE( m.get_font_memory_cache().size() == 23 );
// copy discards memory cache but not file mapping
mapnik::Map m2(m);
REQUIRE( m2.get_font_memory_cache().size() == 0 );
- REQUIRE( m2.get_font_file_mapping().size() == 22 );
+ REQUIRE( m2.get_font_file_mapping().size() == 23 );
REQUIRE( m2.load_fonts() );
- REQUIRE( m2.get_font_memory_cache().size() == 22 );
+ REQUIRE( m2.get_font_memory_cache().size() == 23 );
// test font-directory from XML
mapnik::Map m3(1,1);
@@ -132,7 +132,7 @@ SECTION("registration") {
// recurse to find all dejavu fonts
REQUIRE( mapnik::freetype_engine::register_fonts(fontdir, true) );
face_names = mapnik::freetype_engine::face_names();
- REQUIRE( face_names.size() == 22 );
+ REQUIRE( face_names.size() == 23 );
// we should have re-registered 'DejaVu Sans Mono Bold Oblique' again,
// but now at a new path
@@ -154,7 +154,7 @@ SECTION("registration") {
mapnik::Map m4(1,1);
REQUIRE( m4.register_fonts(fontdir , true ) );
REQUIRE( m4.get_font_memory_cache().size() == 0 );
- REQUIRE( m4.get_font_file_mapping().size() == 22 );
+ REQUIRE( m4.get_font_file_mapping().size() == 23 );
REQUIRE( !m4.load_fonts() );
REQUIRE( m4.get_font_memory_cache().size() == 0 );
REQUIRE( m4.register_fonts(dejavu_bold_oblique, false) );
@@ -166,7 +166,7 @@ SECTION("registration") {
// https://github.com/mapnik/mapnik/issues/2274
REQUIRE( mapnik::freetype_engine::register_font("test/data/fonts/NotoSans-Regular.ttc") );
face_names = mapnik::freetype_engine::face_names();
- REQUIRE( face_names.size() == 24 );
+ REQUIRE( face_names.size() == 25 );
// now blindly register as many system fonts as possible
// the goal here to make sure we don't crash
@@ -179,7 +179,7 @@ SECTION("registration") {
// windows
mapnik::freetype_engine::register_fonts("C:\\Windows\\Fonts", true);
face_names = mapnik::freetype_engine::face_names();
- REQUIRE( face_names.size() > 22 );
+ REQUIRE( face_names.size() > 23 );
}
catch (std::exception const & ex)
{
@@ -188,4 +188,4 @@ SECTION("registration") {
}
}
-}
\ No newline at end of file
+}
diff --git a/test/unit/core/expressions_test.cpp b/test/unit/core/expressions_test.cpp
index 64cdd9e..e60d612 100644
--- a/test/unit/core/expressions_test.cpp
+++ b/test/unit/core/expressions_test.cpp
@@ -108,6 +108,9 @@ TEST_CASE("expressions")
TRY_CHECK(eval(" rad_to_deg * atan(1.0) ").to_double() == approx(45.0));
// exp
TRY_CHECK(eval(" exp(0.0) ") == 1.0);
+ // log
+ TRY_CHECK(eval(" log(1.0) ") == 0.0);
+ TRY_CHECK(eval(" log(exp(1.0)) ") == 1.0);
// abs
TRY_CHECK(eval(" abs(cos(-pi)) ") == 1.0);
// length (string)
diff --git a/test/unit/datasource/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp
index 6e1c222..46868d4 100644
--- a/test/unit/datasource/ds_test_util.hpp
+++ b/test/unit/datasource/ds_test_util.hpp
@@ -106,13 +106,18 @@ inline std::size_t count_features(mapnik::featureset_ptr features) {
}
using attr = std::tuple<std::string, mapnik::value>;
+
+#define REQUIRE_ATTRIBUTES(feature, attrs) \
+ REQUIRE(bool(feature)); \
+ for (auto const &kv : attrs) { \
+ REQUIRE(feature->has_key(std::get<0>(kv))); \
+ CHECK(feature->get(std::get<0>(kv)) == std::get<1>(kv)); \
+ } \
+
+
inline void require_attributes(mapnik::feature_ptr feature,
std::initializer_list<attr> const &attrs) {
- REQUIRE(bool(feature));
- for (auto const &kv : attrs) {
- REQUIRE(feature->has_key(std::get<0>(kv)));
- CHECK(feature->get(std::get<0>(kv)) == std::get<1>(kv));
- }
+ REQUIRE_ATTRIBUTES(feature, attrs);
}
namespace detail {
diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp
index 0b0f205..1edeb4b 100644
--- a/test/unit/datasource/geojson.cpp
+++ b/test/unit/datasource/geojson.cpp
@@ -23,6 +23,7 @@
#include "catch.hpp"
#include "ds_test_util.hpp"
+#include <mapnik/unicode.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/geometry.hpp>
@@ -654,5 +655,72 @@ TEST_CASE("geojson") {
}
}
}
+
+ SECTION("GeoJSON properties are properly expressed")
+ {
+ mapnik::transcoder tr("utf8");
+ mapnik::parameters params;
+ params["type"] = "geojson";
+
+ std::string filename("./test/data/json/escaped.geojson");
+ params["file"] = filename;
+
+ // cleanup in the case of a failed previous run
+ if (mapnik::util::exists(filename + ".index"))
+ {
+ mapnik::util::remove(filename + ".index");
+ }
+
+ for (auto create_index : { true, false })
+ {
+ if (create_index)
+ {
+ CHECK(!mapnik::util::exists(filename + ".index"));
+ int ret = create_disk_index(filename);
+ int ret_posix = (ret >> 8) & 0x000000ff;
+ INFO(ret);
+ INFO(ret_posix);
+ CHECK(mapnik::util::exists(filename + ".index"));
+ }
+
+ for (auto cache_features : {true, false})
+ {
+ params["cache_features"] = cache_features;
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(bool(ds));
+ auto fields = ds->get_descriptor().get_descriptors();
+ std::initializer_list<std::string> names = {"NOM_FR","array","boolean","description","double","empty_array", "empty_object","int","name","object","spaces"};
+ REQUIRE_FIELD_NAMES(fields, names);
+
+ auto fs = all_features(ds);
+ REQUIRE(bool(fs));
+ std::initializer_list<attr> attrs = {
+ attr{"name", tr.transcode("Test")},
+ attr{"NOM_FR", tr.transcode("Québec")},
+ attr{"boolean", mapnik::value_bool("true")},
+ attr{"description", tr.transcode("Test: \u005C")},
+ attr{"double", mapnik::value_double(1.1)},
+ attr{"int", mapnik::value_integer(1)},
+ attr{"object", tr.transcode("{name:\"waka\",spaces:\"value with spaces\",int:1,double:1.1,boolean:false"
+ ",NOM_FR:\"Québec\",array:[\"string\",\"value with spaces\",3,1.1,null,true"
+ ",\"Québec\"],another_object:{name:\"nested object\"}}")},
+ attr{"spaces", tr.transcode("this has spaces")},
+ attr{"array", tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true,"
+ "\"Québec\",{name:\"object within an array\"},"
+ "[\"array\",\"within\",\"an\",\"array\"]]")},
+ attr{"empty_array", tr.transcode("[]")},
+ attr{"empty_object", tr.transcode("{}")},
+ };
+ auto feature = fs->next();
+ REQUIRE(bool(feature));
+ REQUIRE_ATTRIBUTES(feature, attrs);
+ }
+ // cleanup
+ if (create_index && mapnik::util::exists(filename + ".index"))
+ {
+ mapnik::util::remove(filename + ".index");
+ }
+ }
+ }
}
}
diff --git a/test/unit/datasource/postgis.cpp b/test/unit/datasource/postgis.cpp
index 2689952..95ee658 100644
--- a/test/unit/datasource/postgis.cpp
+++ b/test/unit/datasource/postgis.cpp
@@ -29,13 +29,15 @@
#include <mapnik/util/fs.hpp>
/*
-Compile and run just this test:
-clang++ -o test-postgis -g -I./test/ test/unit/run.cpp test/unit/datasource/postgis.cpp `mapnik-config --all-flags` && ./test-postgis -d yes
+ Compile and run just this test:
+ clang++ -o test-postgis -g -I./test/ test/unit/run.cpp test/unit/datasource/postgis.cpp `mapnik-config --all-flags` && ./test-postgis -d yes
*/
#include <boost/optional/optional_io.hpp>
-int run(std::string const& command, bool okay_to_fail = false)
+namespace {
+
+bool run(std::string const& command, bool okay_to_fail = false)
{
std::string cmd;
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
@@ -61,251 +63,278 @@ int run(std::string const& command, bool okay_to_fail = false)
return worked;
}
-std::string dbname("mapnik-tmp-postgis-test-db");
-TEST_CASE("postgis") {
+std::string const dbname("mapnik-tmp-postgis-test-db");
+bool status = false;
- SECTION("Postgis data initialization")
- {
- //don't add 'true' here, to get error message, when drop fails. If it works nothing is output
- REQUIRE(run("dropdb --if-exists " + dbname));
- REQUIRE(run("createdb -T template_postgis " + dbname));
- //REQUIRE(run("createdb " + dbname));
- // Breaks when raster support is missing (unfortunately this is common)
- //REQUIRE(run("psql -c 'CREATE EXTENSION postgis;' " + dbname, true));
- REQUIRE(run("psql -q -f ./test/data/sql/postgis-create-db-and-tables.sql " + dbname));
- }
+bool ping_postmaster()
+{
+ return (run("psql --version")
+ && run("dropdb --if-exists " + dbname)
+ && run("createdb -T template_postgis " + dbname));
+}
- mapnik::parameters base_params;
- base_params["type"] = "postgis";
- base_params["dbname"] = dbname;
+}
- SECTION("Postgis should throw without 'table' parameter")
- {
- mapnik::parameters params(base_params);
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
- }
+TEST_CASE("postgis") {
- SECTION("Postgis should throw with 'max_async_connection' greater than 'max_size'")
+ SECTION("Ping Postmaster (check if server is runnging and accessible")
{
- mapnik::parameters params(base_params);
- params["table"] = "test";
- params["max_async_connection"] = "2";
- params["max_size"] = "1";
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ if (!ping_postmaster())
+ {
+ WARN("Can't run postgis.input tests - check postmaster is running and accessible");
+ return;
+ }
+ else
+ {
+ status = true;
+ }
}
-
- SECTION("Postgis should throw with invalid metadata query")
+ if (status)
{
- mapnik::parameters params(base_params);
- params["table"] = "does_not_exist";
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
- }
+ SECTION("Postgis data initialization")
+ {
+ //don't add 'true' here, to get error message, when drop fails. If it works nothing is output
+ REQUIRE(run("dropdb --if-exists " + dbname));
+ REQUIRE(run("createdb -T template_postgis " + dbname));
+ //REQUIRE(run("createdb " + dbname));
+ // Breaks when raster support is missing (unfortunately this is common)
+ //REQUIRE(run("psql -c 'CREATE EXTENSION postgis;' " + dbname, true));
+ REQUIRE(run("psql -q -f ./test/data/sql/postgis-create-db-and-tables.sql " + dbname));
+ }
- SECTION("Postgis should throw with invalid key field")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test_invalid_id";
- params["key_field"] = "id";
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
- }
+ mapnik::parameters base_params;
+ base_params["type"] = "postgis";
+ base_params["dbname"] = dbname;
- SECTION("Postgis should throw with multicolumn primary key")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test_invalid_multi_col_pk";
- params["autodetect_key_field"] = "true";
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
- }
+ SECTION("Postgis should throw without 'table' parameter")
+ {
+ mapnik::parameters params(base_params);
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ }
- SECTION("Postgis should throw without geom column")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test_no_geom_col";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- CHECK_THROWS(all_features(ds));
- }
+ SECTION("Postgis should throw with 'max_async_connection' greater than 'max_size'")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test";
+ params["max_async_connection"] = "2";
+ params["max_size"] = "1";
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ }
- SECTION("Postgis should throw with invalid credentials")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test";
- params["user"] = "not_a_valid_user";
- params["password"] = "not_a_valid_pwd";
- CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
- }
+ SECTION("Postgis should throw with invalid metadata query")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "does_not_exist";
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ }
- SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key field, simplify_geometries, row_limit")
- {
- mapnik::parameters params(base_params);
- params["persist_connection"] = "false";
- params["table"] = "public.test";
- params["geometry_field"] = "geom";
- params["autodetect_key_field"] = "true";
- params["extent"] = "-1 -1, -1 2, 4 3, 3 -1, -1 -1";
- params["simplify_geometries"] = "true";
- params["row_limit"] = "1";
- auto ds = mapnik::datasource_cache::instance().create(params);
- }
+ SECTION("Postgis should throw with invalid key field")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test_invalid_id";
+ params["key_field"] = "id";
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ }
- SECTION("Postgis dataset geometry type")
- {
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM test WHERE gid=1) as data";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
- }
+ SECTION("Postgis should throw with multicolumn primary key")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test_invalid_multi_col_pk";
+ params["autodetect_key_field"] = "true";
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
+ }
- SECTION("Postgis query field names")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector);
- auto fields = ds->get_descriptor().get_descriptors();
- require_field_names(fields, { "gid", "colbigint", "col_text", "col-char", "col+bool", "colnumeric", "colsmallint", "colfloat4", "colfloat8", "colcharacter" });
- require_field_types(fields, { mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Boolean, mapnik::Double, mapnik::Integer, mapnik::Double, mapnik::Double, mapnik::String });
- }
+ SECTION("Postgis should throw without geom column")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test_no_geom_col";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ CHECK_THROWS(all_features(ds));
+ }
- SECTION("Postgis iterate features")
- {
- mapnik::parameters params(base_params);
- params["table"] = "test";
- params["key_field"] = "gid";
- params["max_async_connection"] = "2";
- //params["cursor_size"] = "2";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
-
- auto featureset = ds->features_at_point(mapnik::coord2d(1, 1));
- mapnik::feature_ptr feature;
- while ((bool(feature = featureset->next()))) {
- REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string());
- REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool());
- REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double());
- REQUIRE(feature->get(5).to_string() == feature->get("colnumeric").to_string());
+ SECTION("Postgis should throw with invalid credentials")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test";
+ params["user"] = "not_a_valid_user";
+ params["password"] = "not_a_valid_pwd";
+ CHECK_THROWS(mapnik::datasource_cache::instance().create(params));
}
- featureset = all_features(ds);
- feature = featureset->next();
- //deactivate char tests for now: not yet implemented.
- //add at postgis_datasource.cpp:423
- //case 18: // char
- //REQUIRE("A" == feature->get("col-char").to_string());
- feature = featureset->next();
- //REQUIRE("B" == feature->get("col-char").to_string());
- feature = featureset->next();
- REQUIRE(false == feature->get("col+bool").to_bool());
- }
+ SECTION("Postgis initialize dataset with persist_connection, schema, extent, geometry field, autodectect key field, simplify_geometries, row_limit")
+ {
+ mapnik::parameters params(base_params);
+ params["persist_connection"] = "false";
+ params["table"] = "public.test";
+ params["geometry_field"] = "geom";
+ params["autodetect_key_field"] = "true";
+ params["extent"] = "-1 -1, -1 2, 4 3, 3 -1, -1 -1";
+ params["simplify_geometries"] = "true";
+ params["row_limit"] = "1";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ }
- SECTION("Postgis cursorresultest")
- {
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM test) as data";
- params["cursor_size"] = "2";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- auto featureset = all_features(ds);
- CHECK(count_features(featureset) == 8);
-
- featureset = all_features(ds);
- mapnik::feature_ptr feature;
- while (bool(feature = featureset->next())) {
- CHECK(feature->size() == 10);
+ SECTION("Postgis dataset geometry type")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM test WHERE gid=1) as data";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
}
- featureset = all_features(ds);
- require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
- require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
- require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPoint);
- require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::LineString);
- require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiLineString);
- require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Polygon);
- require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPolygon);
- require_geometry(featureset->next(), 3, mapnik::geometry::geometry_types::GeometryCollection);
- }
+ SECTION("Postgis query field names")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ REQUIRE(ds->type() == mapnik::datasource::datasource_t::Vector);
+ auto fields = ds->get_descriptor().get_descriptors();
+ require_field_names(fields, { "gid", "colbigint", "col_text", "col-char", "col+bool", "colnumeric", "colsmallint", "colfloat4", "colfloat8", "colcharacter" });
+ require_field_types(fields, { mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Boolean, mapnik::Double, mapnik::Integer, mapnik::Double, mapnik::Double, mapnik::String });
+ }
- SECTION("Postgis bbox query")
- {
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM public.test) as data WHERE geom && !bbox!";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- mapnik::box2d<double> ext = ds->envelope();
- CAPTURE(ext);
- INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
- REQUIRE(ext.minx() == -2);
- REQUIRE(ext.miny() == -2);
- REQUIRE(ext.maxx() == 5);
- REQUIRE(ext.maxy() == 4);
- }
+ SECTION("Postgis iterate features")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "test";
+ params["key_field"] = "gid";
+ params["max_async_connection"] = "2";
+ //params["cursor_size"] = "2";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
- SECTION("Postgis query extent: full dataset")
- {
- //include schema to increase coverage
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM public.test) as data";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- mapnik::box2d<double> ext = ds->envelope();
- CAPTURE(ext);
- INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
- REQUIRE(ext.minx() == -2);
- REQUIRE(ext.miny() == -2);
- REQUIRE(ext.maxx() == 5);
- REQUIRE(ext.maxy() == 4);
- }
+ auto featureset = ds->features_at_point(mapnik::coord2d(1, 1));
+ mapnik::feature_ptr feature;
+ while ((bool(feature = featureset->next()))) {
+ REQUIRE(feature->get(2).to_string() == feature->get("col_text").to_string());
+ REQUIRE(feature->get(4).to_bool() == feature->get("col+bool").to_bool());
+ REQUIRE(feature->get(5).to_double() == feature->get("colnumeric").to_double());
+ REQUIRE(feature->get(5).to_string() == feature->get("colnumeric").to_string());
+ }
+
+ featureset = all_features(ds);
+ feature = featureset->next();
+ //deactivate char tests for now: not yet implemented.
+ //add at postgis_datasource.cpp:423
+ //case 18: // char
+ //REQUIRE("A" == feature->get("col-char").to_string());
+ feature = featureset->next();
+ //REQUIRE("B" == feature->get("col-char").to_string());
+ feature = featureset->next();
+ REQUIRE(false == feature->get("col+bool").to_bool());
+ }
+
+ SECTION("Postgis cursorresultest")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM test) as data";
+ params["cursor_size"] = "2";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ auto featureset = all_features(ds);
+ CHECK(count_features(featureset) == 8);
+
+ featureset = all_features(ds);
+ mapnik::feature_ptr feature;
+ while (bool(feature = featureset->next())) {
+ CHECK(feature->size() == 10);
+ }
+
+ featureset = all_features(ds);
+ require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
+ require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Point);
+ require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPoint);
+ require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::LineString);
+ require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiLineString);
+ require_geometry(featureset->next(), 1, mapnik::geometry::geometry_types::Polygon);
+ require_geometry(featureset->next(), 2, mapnik::geometry::geometry_types::MultiPolygon);
+ require_geometry(featureset->next(), 3, mapnik::geometry::geometry_types::GeometryCollection);
+ }
+
+ SECTION("Postgis bbox query")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM public.test) as data WHERE geom && !bbox!";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ mapnik::box2d<double> ext = ds->envelope();
+ CAPTURE(ext);
+ INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
+ REQUIRE(ext.minx() == -2);
+ REQUIRE(ext.miny() == -2);
+ REQUIRE(ext.maxx() == 5);
+ REQUIRE(ext.maxy() == 4);
+ }
+
+ SECTION("Postgis query extent: full dataset")
+ {
+ //include schema to increase coverage
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM public.test) as data";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ mapnik::box2d<double> ext = ds->envelope();
+ CAPTURE(ext);
+ INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
+ REQUIRE(ext.minx() == -2);
+ REQUIRE(ext.miny() == -2);
+ REQUIRE(ext.maxx() == 5);
+ REQUIRE(ext.maxy() == 4);
+ }
/* deactivated for merging: still investigating a proper fix
- SECTION("Postgis query extent from subquery")
- {
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM test where gid=4) as data";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- mapnik::box2d<double> ext = ds->envelope();
- CAPTURE(ext);
- INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
- REQUIRE(ext.minx() == 0);
- REQUIRE(ext.miny() == 0);
- REQUIRE(ext.maxx() == 1);
- REQUIRE(ext.maxy() == 2);
- }
+ SECTION("Postgis query extent from subquery")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM test where gid=4) as data";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ mapnik::box2d<double> ext = ds->envelope();
+ CAPTURE(ext);
+ INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
+ REQUIRE(ext.minx() == 0);
+ REQUIRE(ext.miny() == 0);
+ REQUIRE(ext.maxx() == 1);
+ REQUIRE(ext.maxy() == 2);
+ }
*/
- SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'")
- {
- mapnik::parameters params(base_params);
- params["table"] = "(SELECT * FROM test where gid=4) as data";
- params["extent_from_subquery"] = "true";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- mapnik::box2d<double> ext = ds->envelope();
- CAPTURE(ext);
- INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
- REQUIRE(ext.minx() == 0);
- REQUIRE(ext.miny() == 0);
- REQUIRE(ext.maxx() == 1);
- REQUIRE(ext.maxy() == 2);
- }
+ SECTION("Postgis query extent: from subquery with 'extent_from_subquery=true'")
+ {
+ mapnik::parameters params(base_params);
+ params["table"] = "(SELECT * FROM test where gid=4) as data";
+ params["extent_from_subquery"] = "true";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ mapnik::box2d<double> ext = ds->envelope();
+ CAPTURE(ext);
+ INFO(std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
+ REQUIRE(ext.minx() == 0);
+ REQUIRE(ext.miny() == 0);
+ REQUIRE(ext.maxx() == 1);
+ REQUIRE(ext.maxy() == 2);
+ }
/* deactivated for merging: still investigating a proper fix
- SECTION("Postgis query extent: subset with 'extent_from_subquery=true' and 'scale_denominator'")
- {
- mapnik::parameters params(base_params);
- // !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000'
- // https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617
- params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data";
- params["extent_from_subquery"] = "true";
- auto ds = mapnik::datasource_cache::instance().create(params);
- REQUIRE(ds != nullptr);
- mapnik::box2d<double> ext = ds->envelope();
- CAPTURE(ext);
- INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
- REQUIRE(ext.minx() == 0);
- REQUIRE(ext.miny() == 0);
- REQUIRE(ext.maxx() == 1);
- REQUIRE(ext.maxy() == 2);
- }
+ SECTION("Postgis query extent: subset with 'extent_from_subquery=true' and 'scale_denominator'")
+ {
+ mapnik::parameters params(base_params);
+ // !!!! postgis-vt-util::z() returns 'null' when 'scale_denominator > 600000000'
+ // https://github.com/mapbox/postgis-vt-util/blob/559f073877696a6bfea41baf3e1065f9cf4d18d1/postgis-vt-util.sql#L615-L617
+ params["table"] = "(SELECT * FROM test where gid=4 AND z(!scale_denominator!) BETWEEN 0 AND 22) as data";
+ params["extent_from_subquery"] = "true";
+ auto ds = mapnik::datasource_cache::instance().create(params);
+ REQUIRE(ds != nullptr);
+ mapnik::box2d<double> ext = ds->envelope();
+ CAPTURE(ext);
+ INFO("" << std::setprecision(6) << std::fixed << ext.minx() << "/" << ext.miny() << " " << ext.maxx() << "/" << ext.maxy());
+ REQUIRE(ext.minx() == 0);
+ REQUIRE(ext.miny() == 0);
+ REQUIRE(ext.maxx() == 1);
+ REQUIRE(ext.maxy() == 2);
+ }
*/
-}
\ No newline at end of file
+
+ }
+}
diff --git a/test/unit/datasource/topojson.cpp b/test/unit/datasource/topojson.cpp
index 25f9ffd..6b1a2e1 100644
--- a/test/unit/datasource/topojson.cpp
+++ b/test/unit/datasource/topojson.cpp
@@ -21,6 +21,7 @@
*****************************************************************************/
#include "catch.hpp"
+#include "ds_test_util.hpp"
#include <mapnik/util/fs.hpp>
#include <mapnik/util/file_io.hpp>
@@ -50,7 +51,7 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to
}
-TEST_CASE("topology")
+TEST_CASE("topojson")
{
SECTION("geometry parsing")
{
@@ -72,4 +73,42 @@ TEST_CASE("topology")
}
}
}
+
+ SECTION("TopoJSON properties are properly expressed")
+ {
+ std::string filename("./test/data/topojson/escaped.topojson");
+ mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
+ mapnik::transcoder tr("utf8");
+ mapnik::topojson::topology topo;
+ REQUIRE(parse_topology(filename, topo));
+ mapnik::value_integer feature_id = 0;
+ for (auto const& geom : topo.geometries)
+ {
+ mapnik::box2d<double> bbox = mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo), geom);
+ CHECK(bbox.valid());
+ mapnik::topojson::feature_generator<mapnik::context_ptr> visitor(ctx, tr, topo, feature_id);
+ mapnik::feature_ptr feature = mapnik::util::apply_visitor(visitor, geom);
+ CHECK(feature);
+ CHECK(feature->envelope() == bbox);
+ std::initializer_list<attr> attrs = {
+ attr{"name", tr.transcode("Test")},
+ attr{"NOM_FR", tr.transcode("Québec")},
+ attr{"boolean", mapnik::value_bool("true")},
+ attr{"description", tr.transcode("Test: \u005C")},
+ attr{"double", mapnik::value_double(1.1)},
+ attr{"int", mapnik::value_integer(1)},
+ attr{"object", tr.transcode("{name:\"waka\",spaces:\"value with spaces\",int:1,double:1.1,boolean:false"
+ ",NOM_FR:\"Québec\",array:[\"string\",\"value with spaces\",3,1.1,null,true"
+ ",\"Québec\"],another_object:{name:\"nested object\"}}")},
+ attr{"spaces", tr.transcode("this has spaces")},
+ attr{"array", tr.transcode("[\"string\",\"value with spaces\",3,1.1,null,true,"
+ "\"Québec\",{name:\"object within an array\"},"
+ "[\"array\",\"within\",\"an\",\"array\"]]")},
+ attr{"empty_array", tr.transcode("[]")},
+ attr{"empty_object", tr.transcode("{}")},
+ };
+ REQUIRE_ATTRIBUTES(feature, attrs);
+ }
+ }
+
}
diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp
index fd5d78f..7504982 100644
--- a/test/unit/geometry/geometry_envelope_test.cpp
+++ b/test/unit/geometry/geometry_envelope_test.cpp
@@ -1,17 +1,19 @@
-
#include "catch.hpp"
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_envelope.hpp>
-#include <mapnik/geometry_correct.hpp>
-TEST_CASE("geometry ops - envelope") {
+namespace {
-SECTION("envelope_test - double") {
+template <typename T>
+void envelope_test()
+{
using namespace mapnik::geometry;
+ using coord_type = T;
+
{
- geometry<double> geom(point<double>(1,2));
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(geom);
+ geometry<coord_type> geom(point<coord_type>(1,2));
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == 1 );
REQUIRE( bbox.miny() == 2 );
REQUIRE( bbox.maxx() == 1 );
@@ -19,80 +21,67 @@ SECTION("envelope_test - double") {
}
{
// Test empty geom
- geometry<double> geom = mapnik::geometry::geometry_empty();
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(geom);
+ geometry<coord_type> geom = mapnik::geometry::geometry_empty();
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE_FALSE( bbox.valid() );
}
{
- line_string<double> line;
+ line_string<coord_type> line;
line.add_coord(0,0);
line.add_coord(1,1);
line.add_coord(2,2);
- geometry<double> geom(line);
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(geom);
+ geometry<coord_type> geom(line);
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == 0 );
REQUIRE( bbox.miny() == 0 );
REQUIRE( bbox.maxx() == 2 );
REQUIRE( bbox.maxy() == 2 );
}
{
- line_string<double> line;
+ line_string<coord_type> line;
line.add_coord(0,0);
line.add_coord(1,1);
line.add_coord(2,2);
- line_string<double> line2;
+ line_string<coord_type> line2;
line2.add_coord(0,0);
line2.add_coord(-1,-1);
line2.add_coord(-2,-2);
- multi_line_string<double> multi_line;
+ multi_line_string<coord_type> multi_line;
multi_line.emplace_back(std::move(line));
multi_line.emplace_back(std::move(line2));
- geometry<double> geom(multi_line);
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(geom);
+ geometry<coord_type> geom(multi_line);
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == -2 );
REQUIRE( bbox.miny() == -2 );
REQUIRE( bbox.maxx() == 2 );
REQUIRE( bbox.maxy() == 2 );
}
{
- polygon<double> poly;
- linear_ring<double> ring;
+ polygon<coord_type> poly;
+ linear_ring<coord_type> ring;
ring.add_coord(0,0);
ring.add_coord(-10,0);
ring.add_coord(-10,10);
ring.add_coord(0,10);
ring.add_coord(0,0);
poly.set_exterior_ring(std::move(ring));
- geometry<double> geom(poly);
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(geom);
+ geometry<coord_type> geom(poly);
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == -10 );
REQUIRE( bbox.miny() == 0 );
REQUIRE( bbox.maxx() == 0 );
REQUIRE( bbox.maxy() == 10 );
- multi_polygon<double> mp;
+ multi_polygon<coord_type> mp;
mp.push_back(poly);
- geometry<double> geom_mp(mp);
+ geometry<coord_type> geom_mp(mp);
bbox = mapnik::geometry::envelope(geom_mp);
REQUIRE( bbox.minx() == -10 );
REQUIRE( bbox.miny() == 0 );
REQUIRE( bbox.maxx() == 0 );
REQUIRE( bbox.maxy() == 10 );
- correct(geom);
- bbox = mapnik::geometry::envelope(geom);
- REQUIRE( bbox.minx() == -10 );
- REQUIRE( bbox.miny() == 0 );
- REQUIRE( bbox.maxx() == 0 );
- REQUIRE( bbox.maxy() == 10 );
- correct(geom_mp);
- bbox = mapnik::geometry::envelope(geom_mp);
- REQUIRE( bbox.minx() == -10 );
- REQUIRE( bbox.miny() == 0 );
- REQUIRE( bbox.maxx() == 0 );
- REQUIRE( bbox.maxy() == 10 );
-
- geometry_collection<double> gc;
+ geometry_collection<coord_type> gc;
bbox = mapnik::geometry::envelope(gc);
REQUIRE_FALSE( bbox.valid() );
gc.push_back(geom_mp);
@@ -101,7 +90,7 @@ SECTION("envelope_test - double") {
REQUIRE( bbox.miny() == 0 );
REQUIRE( bbox.maxx() == 0 );
REQUIRE( bbox.maxy() == 10 );
- gc.emplace_back(point<double>(-50,-50));
+ gc.emplace_back(point<coord_type>(-50,-50));
bbox = mapnik::geometry::envelope(gc);
REQUIRE( bbox.minx() == -50 );
REQUIRE( bbox.miny() == -50 );
@@ -111,30 +100,30 @@ SECTION("envelope_test - double") {
{
// polygon with hole
- polygon<double> poly;
- linear_ring<double> ring;
+ polygon<coord_type> poly;
+ linear_ring<coord_type> ring;
ring.add_coord(0,0);
ring.add_coord(-10,0);
ring.add_coord(-10,10);
ring.add_coord(0,10);
ring.add_coord(0,0);
poly.set_exterior_ring(std::move(ring));
- linear_ring<double> hole;
+ linear_ring<coord_type> hole;
hole.add_coord(-7,7);
hole.add_coord(-7,3);
hole.add_coord(-3,3);
hole.add_coord(-3,7);
hole.add_coord(-7,7);
poly.add_hole(std::move(hole));
- geometry<double> geom(poly);
- mapnik::box2d<double> bbox = mapnik::geometry::envelope(poly);
+ geometry<coord_type> geom(poly);
+ mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(poly);
REQUIRE( bbox.minx() == -10 );
REQUIRE( bbox.miny() == 0 );
REQUIRE( bbox.maxx() == 0 );
REQUIRE( bbox.maxy() == 10 );
// add another hole inside the first hole
// which should be considered a hit
- linear_ring<double> fill;
+ linear_ring<coord_type> fill;
fill.add_coord(-6,4);
fill.add_coord(-6,6);
fill.add_coord(-4,6);
@@ -150,3 +139,14 @@ SECTION("envelope_test - double") {
}
}
+
+TEST_CASE("geometry ops - envelope") {
+
+SECTION("envelope_test")
+{
+ envelope_test<int>();
+ envelope_test<double>();
+ envelope_test<float>();
+}
+
+}
diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp
index f8ebc4d..4ff80ab 100644
--- a/test/unit/geometry/geometry_equal.hpp
+++ b/test/unit/geometry/geometry_equal.hpp
@@ -1,4 +1,3 @@
-
#ifndef MAPNIK_UNIT_GEOMETRY_EQUAL
#define MAPNIK_UNIT_GEOMETRY_EQUAL
@@ -85,7 +84,15 @@ auto zip_crange(Conts&... conts)
#include <mapnik/geometry.hpp>
#include <mapnik/util/variant.hpp>
-using namespace mapnik::geometry;
+using mapnik::geometry::geometry;
+using mapnik::geometry::geometry_empty;
+using mapnik::geometry::point;
+using mapnik::geometry::line_string;
+using mapnik::geometry::polygon;
+using mapnik::geometry::multi_point;
+using mapnik::geometry::multi_line_string;
+using mapnik::geometry::multi_polygon;
+using mapnik::geometry::geometry_collection;
template <typename T>
void assert_g_equal(geometry<T> const& g1, geometry<T> const& g2);
diff --git a/test/unit/geometry/geometry_test_helper.cpp b/test/unit/geometry/geometry_test_helper.cpp
new file mode 100644
index 0000000..44bcce5
--- /dev/null
+++ b/test/unit/geometry/geometry_test_helper.cpp
@@ -0,0 +1,15 @@
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_envelope.hpp>
+#include <mapnik/geometry_envelope_impl.hpp>
+
+
+namespace mapnik { namespace geometry {
+// instantiate types required by geometry_envelope_test
+template mapnik::box2d<int> envelope(geometry<int> const& geom);
+template mapnik::box2d<float> envelope(geometry<float> const& geom);
+template mapnik::box2d<int> envelope(polygon<int> const& geom);
+template mapnik::box2d<float> envelope(polygon<float> const& geom);
+template mapnik::box2d<int> envelope(geometry_collection<int> const& geom);
+template mapnik::box2d<float> envelope(geometry_collection<float> const& geom);
+
+}}
diff --git a/test/unit/geometry/is_clockwise.cpp b/test/unit/geometry/is_clockwise.cpp
new file mode 100644
index 0000000..42aebf6
--- /dev/null
+++ b/test/unit/geometry/is_clockwise.cpp
@@ -0,0 +1,27 @@
+#include "catch.hpp"
+
+#include <mapnik/geometry.hpp>
+#include <mapnik/util/is_clockwise.hpp>
+
+TEST_CASE("Ring is_clockwise") {
+
+ // Input is rather thin triangle to test precision issues aren't getting in the way.
+ SECTION("Clockwise")
+ {
+ mapnik::geometry::linear_ring<double> ring;
+ ring.emplace_back(-13499697.0366658326, 4698431.85179749783);
+ ring.emplace_back(-13499697.1113113686, 4698431.85179749783);
+ ring.emplace_back(-13499697.0366658326, 4698431.92644303292);
+ ring.emplace_back(-13499697.0366658326, 4698431.85179749783);
+ REQUIRE(mapnik::util::is_clockwise(ring) == true);
+ }
+ SECTION("Anti-Clockwise")
+ {
+ mapnik::geometry::linear_ring<double> ring;
+ ring.emplace_back(-13499697.0366658326, 4698431.85179749783);
+ ring.emplace_back(-13499697.0366658326, 4698431.92644303292);
+ ring.emplace_back(-13499697.1113113686, 4698431.85179749783);
+ ring.emplace_back(-13499697.0366658326, 4698431.85179749783);
+ REQUIRE(mapnik::util::is_clockwise(ring) == false);
+ }
+}
diff --git a/test/unit/imaging/image_io_test.cpp b/test/unit/imaging/image_io_test.cpp
index c562148..18c01da 100644
--- a/test/unit/imaging/image_io_test.cpp
+++ b/test/unit/imaging/image_io_test.cpp
@@ -1,7 +1,5 @@
-
#include "catch.hpp"
-#include <iostream>
#include <cstring>
#include <mapnik/color.hpp>
#include <mapnik/image.hpp>
@@ -24,6 +22,31 @@ inline void make_directory(std::string const& dir) {
boost::filesystem::create_directories(dir);
}
+namespace {
+template <typename T>
+void check_tiny_png_image_quantising(T const& im)
+{
+ std::ostringstream ss(std::ios::binary);
+ mapnik::save_to_stream(im, ss, "png8");
+ ss.flush();
+ std::string str = ss.str();
+ std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(str.data(), str.size()));
+ auto w = reader->width();
+ auto h = reader->height();
+ CHECK(w > 0);
+ CHECK(h > 0);
+ auto im2 = mapnik::util::get<mapnik::image_rgba8>(reader->read(0, 0, w, h));
+ for (std::size_t i = 0; i < w; ++i)
+ {
+ for (std::size_t j = 0; j < h; ++j)
+ {
+ REQUIRE(im2(i,j) == im(i,j));
+ }
+ }
+}
+
+}
+
TEST_CASE("image io") {
SECTION("readers") {
@@ -186,4 +209,28 @@ SECTION("image_util : save_to_file/save_to_stream/save_to_string")
}
}
}
+
+SECTION("Quantising small (less than 3 pixel images preserve original colours")
+{
+#if defined(HAVE_PNG)
+ { // 1x1
+ mapnik::image_rgba8 im(1,1); // 1 pixel
+ im(0,0) = mapnik::color("green").rgba();
+ check_tiny_png_image_quantising(im);
+ }
+ { // 1x2
+ mapnik::image_rgba8 im(1,2); // 2 pixels
+ mapnik::fill(im, mapnik::color("red").rgba());
+ im(0,0) = mapnik::color("green").rgba();
+ check_tiny_png_image_quantising(im);
+ }
+ { // 2x1
+ mapnik::image_rgba8 im(2,1); // 2 pixels
+ mapnik::fill(im, mapnik::color("red").rgba());
+ im(0,0) = mapnik::color("green").rgba();
+ check_tiny_png_image_quantising(im);
+ }
+#endif
+} // END SECTION
+
} // END TEST_CASE
diff --git a/test/unit/imaging/tiff_io.cpp b/test/unit/imaging/tiff_io.cpp
index 1ace38f..14f9e5f 100644
--- a/test/unit/imaging/tiff_io.cpp
+++ b/test/unit/imaging/tiff_io.cpp
@@ -1,4 +1,3 @@
-
// disabled on windows due to https://github.com/mapnik/mapnik/issues/2838
// TODO - get to the bottom of why including `tiff_reader.cpp` breaks windows
// or re-write image_readers to allow `#include tiff_reader.hpp`
@@ -12,7 +11,7 @@
#include "../../../src/tiff_reader.cpp"
#define TIFF_ASSERT(filename) \
- mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename); \
+ mapnik::tiff_reader<std::filebuf> tiff_reader(filename); \
REQUIRE( tiff_reader.width() == 256 ); \
REQUIRE( tiff_reader.height() == 256 ); \
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); \
@@ -20,7 +19,7 @@
REQUIRE( reader->width() == 256 ); \
REQUIRE( reader->height() == 256 ); \
mapnik::util::file file(filename); \
- mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size()); \
+ mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size()); \
REQUIRE( tiff_reader2.width() == 256 ); \
REQUIRE( tiff_reader2.height() == 256 ); \
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size())); \
@@ -57,11 +56,13 @@
REQUIRE( subimage.width() == 1 ); \
REQUIRE( subimage.height() == 1 ); \
-TEST_CASE("tiff io") {
+TEST_CASE("tiff io")
+{
-SECTION("scan rgb8 striped") {
+SECTION("scan rgb8 striped")
+{
std::string filename("./test/data/tiff/scan_512x512_rgb8_striped.tif");
- mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename);
+ mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
REQUIRE( tiff_reader.width() == 512 );
REQUIRE( tiff_reader.height() == 512 );
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
@@ -76,7 +77,7 @@ SECTION("scan rgb8 striped") {
REQUIRE( reader->width() == 512 );
REQUIRE( reader->height() == 512 );
mapnik::util::file file(filename);
- mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size());
+ mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
REQUIRE( tiff_reader2.width() == 512 );
REQUIRE( tiff_reader2.height() == 512 );
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
@@ -91,7 +92,7 @@ SECTION("scan rgb8 striped") {
SECTION("scan rgb8 tiled") {
std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif");
- mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename);
+ mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
REQUIRE( tiff_reader.width() == 512 );
REQUIRE( tiff_reader.height() == 512 );
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
@@ -106,7 +107,7 @@ SECTION("scan rgb8 tiled") {
REQUIRE( reader->width() == 512 );
REQUIRE( reader->height() == 512 );
mapnik::util::file file(filename);
- mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size());
+ mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
REQUIRE( tiff_reader2.width() == 512 );
REQUIRE( tiff_reader2.height() == 512 );
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp
index f82c4f3..8a617df 100644
--- a/test/unit/serialization/wkb_test.cpp
+++ b/test/unit/serialization/wkb_test.cpp
@@ -16,6 +16,7 @@
#include <vector>
#include <fstream>
+#if BOOST_VERSION >= 105800
namespace {
struct spatially_equal_visitor
@@ -79,6 +80,7 @@ bool spatially_equal(mapnik::geometry::geometry<T> const& g0, mapnik::geometry::
}
}
+#endif
TEST_CASE("Well-known-geometries")
{
@@ -106,7 +108,9 @@ TEST_CASE("Well-known-geometries")
{
REQUIRE(wkt0 == wkt1);
// compare spatially (NOTE: GeometryCollection comparison also enforces strict order)
+#if BOOST_VERSION >= 105800
REQUIRE(spatially_equal(geom_0, geom_1));
+#endif
}
}
}
diff --git a/test/visual/renderer.hpp b/test/visual/renderer.hpp
index 6b033f9..7ea9198 100644
--- a/test/visual/renderer.hpp
+++ b/test/visual/renderer.hpp
@@ -38,10 +38,21 @@
#if defined(GRID_RENDERER)
#include <mapnik/grid/grid_renderer.hpp>
#endif
+
#if defined(HAVE_CAIRO)
#include <mapnik/cairo/cairo_renderer.hpp>
#include <mapnik/cairo/cairo_image_util.hpp>
+#ifdef CAIRO_HAS_SVG_SURFACE
+#include <cairo-svg.h>
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+#include <cairo-ps.h>
+#endif
+#ifdef CAIRO_HAS_PDF_SURFACE
+#include <cairo-pdf.h>
#endif
+#endif
+
#if defined(SVG_RENDERER)
#include <mapnik/svg/output/svg_renderer.hpp>
#endif
@@ -53,7 +64,7 @@ namespace visual_tests
{
template <typename ImageType>
-struct renderer_base
+struct raster_renderer_base
{
using image_type = ImageType;
@@ -80,7 +91,35 @@ struct renderer_base
}
};
-struct agg_renderer : renderer_base<mapnik::image_rgba8>
+struct vector_renderer_base
+{
+ using image_type = std::string;
+
+ static constexpr const bool support_tiles = false;
+
+ unsigned compare(image_type const & actual, boost::filesystem::path const& reference) const
+ {
+ std::ifstream stream(reference.string().c_str(), std::ios_base::in | std::ios_base::binary);
+ if (!stream)
+ {
+ throw std::runtime_error("Could not open: " + reference.string());
+ }
+ std::string expected(std::istreambuf_iterator<char>(stream.rdbuf()), std::istreambuf_iterator<char>());
+ return std::max(actual.size(), expected.size()) - std::min(actual.size(), expected.size());
+ }
+
+ void save(image_type const & image, boost::filesystem::path const& path) const
+ {
+ std::ofstream file(path.string().c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
+ if (!file)
+ {
+ throw std::runtime_error("Cannot open file for writing: " + path.string());
+ }
+ file << image;
+ }
+};
+
+struct agg_renderer : raster_renderer_base<mapnik::image_rgba8>
{
static constexpr const char * name = "agg";
@@ -94,7 +133,7 @@ struct agg_renderer : renderer_base<mapnik::image_rgba8>
};
#if defined(HAVE_CAIRO)
-struct cairo_renderer : renderer_base<mapnik::image_rgba8>
+struct cairo_renderer : raster_renderer_base<mapnik::image_rgba8>
{
static constexpr const char * name = "cairo";
@@ -111,14 +150,65 @@ struct cairo_renderer : renderer_base<mapnik::image_rgba8>
return image;
}
};
+
+using surface_create_type = cairo_surface_t *(&)(cairo_write_func_t, void *, double, double);
+
+template <surface_create_type SurfaceCreateFunction>
+struct cairo_vector_renderer : vector_renderer_base
+{
+ static cairo_status_t write(void *closure,
+ const unsigned char *data,
+ unsigned int length)
+ {
+ std::ostringstream & ss = *reinterpret_cast<std::ostringstream*>(closure);
+ ss.write(reinterpret_cast<char const *>(data), length);
+ return ss ? CAIRO_STATUS_SUCCESS : CAIRO_STATUS_WRITE_ERROR;
+ }
+
+ image_type render(mapnik::Map const & map, double scale_factor) const
+ {
+ std::ostringstream ss(std::stringstream::binary);
+ mapnik::cairo_surface_ptr image_surface(
+ SurfaceCreateFunction(write, &ss, map.width(), map.height()),
+ mapnik::cairo_surface_closer());
+ mapnik::cairo_ptr image_context(mapnik::create_context(image_surface));
+ mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map, image_context, scale_factor);
+ ren.apply();
+ cairo_surface_finish(&*image_surface);
+ return ss.str();
+ }
+};
+
+#ifdef CAIRO_HAS_SVG_SURFACE
+struct cairo_svg_renderer : cairo_vector_renderer<cairo_svg_surface_create_for_stream>
+{
+ static constexpr const char * name = "cairo-svg";
+ static constexpr const char * ext = ".svg";
+};
+#endif
+
+#ifdef CAIRO_HAS_PS_SURFACE
+struct cairo_ps_renderer : cairo_vector_renderer<cairo_ps_surface_create_for_stream>
+{
+ static constexpr const char * name = "cairo-ps";
+ static constexpr const char * ext = ".ps";
+};
+#endif
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+struct cairo_pdf_renderer : cairo_vector_renderer<cairo_pdf_surface_create_for_stream>
+{
+ static constexpr const char * name = "cairo-pdf";
+ static constexpr const char * ext = ".pdf";
+};
+#endif
#endif
#if defined(SVG_RENDERER)
-struct svg_renderer : renderer_base<std::string>
+struct svg_renderer : vector_renderer_base
{
static constexpr const char * name = "svg";
static constexpr const char * ext = ".svg";
- static constexpr const bool support_tiles = false;
image_type render(mapnik::Map const & map, double scale_factor) const
{
@@ -128,35 +218,11 @@ struct svg_renderer : renderer_base<std::string>
ren.apply();
return ss.str();
}
-
- unsigned compare(image_type const & actual, boost::filesystem::path const& reference) const
- {
- std::ifstream stream(reference.string().c_str(),std::ios_base::in|std::ios_base::binary);
- if (!stream.is_open())
- {
- throw std::runtime_error("could not open: '" + reference.string() + "'");
- }
- std::string expected(std::istreambuf_iterator<char>(stream.rdbuf()),(std::istreambuf_iterator<char>()));
- stream.close();
- return std::max(actual.size(), expected.size()) - std::min(actual.size(), expected.size());
- }
-
- void save(image_type const & image, boost::filesystem::path const& path) const
- {
- std::ofstream file(path.string().c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
- if (!file) {
- throw std::runtime_error((std::string("cannot open file for writing file ") + path.string()).c_str());
- } else {
- file << image;
- file.close();
- }
- }
-
};
#endif
#if defined(GRID_RENDERER)
-struct grid_renderer : renderer_base<mapnik::image_rgba8>
+struct grid_renderer : raster_renderer_base<mapnik::image_rgba8>
{
static constexpr const char * name = "grid";
@@ -335,6 +401,15 @@ private:
using renderer_type = mapnik::util::variant<renderer<agg_renderer>
#if defined(HAVE_CAIRO)
,renderer<cairo_renderer>
+#ifdef CAIRO_HAS_SVG_SURFACE
+ ,renderer<cairo_svg_renderer>
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+ ,renderer<cairo_ps_renderer>
+#endif
+#ifdef CAIRO_HAS_PDF_SURFACE
+ ,renderer<cairo_pdf_renderer>
+#endif
#endif
#if defined(SVG_RENDERER)
,renderer<svg_renderer>
diff --git a/test/visual/run.cpp b/test/visual/run.cpp
index 70284bc..5877279 100644
--- a/test/visual/run.cpp
+++ b/test/visual/run.cpp
@@ -48,30 +48,48 @@ namespace po = boost::program_options;
runner::renderer_container create_renderers(po::variables_map const & args,
boost::filesystem::path const & output_dir,
- bool append_all = false)
+ bool force_append = false)
{
boost::filesystem::path reference_dir(args["images-dir"].as<std::string>());
bool overwrite = args.count("overwrite");
runner::renderer_container renderers;
- if (append_all || args.count(agg_renderer::name))
+ if (force_append || args.count(agg_renderer::name))
{
renderers.emplace_back(renderer<agg_renderer>(output_dir, reference_dir, overwrite));
}
#if defined(HAVE_CAIRO)
- if (append_all || args.count(cairo_renderer::name))
+ if (force_append || args.count(cairo_renderer::name))
{
renderers.emplace_back(renderer<cairo_renderer>(output_dir, reference_dir, overwrite));
}
+#ifdef CAIRO_HAS_SVG_SURFACE
+ if (args.count(cairo_svg_renderer::name))
+ {
+ renderers.emplace_back(renderer<cairo_svg_renderer>(output_dir, reference_dir, overwrite));
+ }
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+ if (args.count(cairo_ps_renderer::name))
+ {
+ renderers.emplace_back(renderer<cairo_ps_renderer>(output_dir, reference_dir, overwrite));
+ }
+#endif
+#ifdef CAIRO_HAS_PDF_SURFACE
+ if (args.count(cairo_pdf_renderer::name))
+ {
+ renderers.emplace_back(renderer<cairo_pdf_renderer>(output_dir, reference_dir, overwrite));
+ }
+#endif
#endif
#if defined(SVG_RENDERER)
- if (append_all || args.count(svg_renderer::name))
+ if (force_append || args.count(svg_renderer::name))
{
renderers.emplace_back(renderer<svg_renderer>(output_dir, reference_dir, overwrite));
}
#endif
#if defined(GRID_RENDERER)
- if (append_all || args.count(grid_renderer::name))
+ if (force_append || args.count(grid_renderer::name))
{
renderers.emplace_back(renderer<grid_renderer>(output_dir, reference_dir, overwrite));
}
@@ -112,6 +130,15 @@ int main(int argc, char** argv)
(agg_renderer::name, "render with AGG renderer")
#if defined(HAVE_CAIRO)
(cairo_renderer::name, "render with Cairo renderer")
+#ifdef CAIRO_HAS_SVG_SURFACE
+ (cairo_svg_renderer::name, "render with Cairo SVG renderer")
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+ (cairo_ps_renderer::name, "render with Cairo PS renderer")
+#endif
+#ifdef CAIRO_HAS_PDF_SURFACE
+ (cairo_pdf_renderer::name, "render with Cairo PDF renderer")
+#endif
#endif
#if defined(SVG_RENDERER)
(svg_renderer::name, "render with SVG renderer")
@@ -183,7 +210,7 @@ int main(int argc, char** argv)
}
catch (std::exception & e)
{
- std::cerr << "Error runnig tests: " << e.what() << std::endl;
+ std::cerr << "Error running tests: " << e.what() << std::endl;
return 1;
}
diff --git a/utils/mapnik-index/mapnik-index.cpp b/utils/mapnik-index/mapnik-index.cpp
index 3e1b8bb..9b1859b 100644
--- a/utils/mapnik-index/mapnik-index.cpp
+++ b/utils/mapnik-index/mapnik-index.cpp
@@ -180,7 +180,11 @@ int main (int argc, char** argv)
{
std::clog << "processing '" << filename << "' as CSV\n";
auto result = mapnik::detail::process_csv_file(boxes, filename, manual_headers, separator, quote);
- if (!result.first) continue;
+ if (!result.first)
+ {
+ std::clog << "Error: failed to process " << filename << std::endl;
+ return EXIT_FAILURE;
+ }
extent = result.second;
}
else if (mapnik::detail::is_geojson(filename))
@@ -190,7 +194,7 @@ int main (int argc, char** argv)
if (!result.first)
{
std::clog << "Error: failed to process " << filename << std::endl;
- continue;
+ return EXIT_FAILURE;
}
extent = result.second;
}
@@ -224,6 +228,11 @@ int main (int argc, char** argv)
file.close();
}
}
+ else
+ {
+ std::clog << "Invalid extent " << extent << std::endl;
+ return EXIT_FAILURE;
+ }
}
std::clog << "done!" << std::endl;
return EXIT_SUCCESS;
diff --git a/utils/mapnik-index/process_csv_file.cpp b/utils/mapnik-index/process_csv_file.cpp
index b9834ce..a0342cf 100644
--- a/utils/mapnik-index/process_csv_file.cpp
+++ b/utils/mapnik-index/process_csv_file.cpp
@@ -46,6 +46,7 @@ namespace mapnik { namespace detail {
template <typename T>
std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
{
+ using box_type = typename T::value_type::first_type;
csv_utils::csv_file_parser p;
p.manual_headers_ = manual_headers;
p.separator_ = separator;
@@ -65,7 +66,7 @@ std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, s
else
{
std::clog << "Error : cannot mmap " << filename << std::endl;
- return std::make_pair(false, box2d<float>(p.extent_));
+ return std::make_pair(false, box_type(p.extent_));
}
#else
#if defined(_WINDOWS)
@@ -76,18 +77,18 @@ std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, s
if (!csv_file.is_open())
{
std::clog << "Error : cannot open " << filename << std::endl;
- return std::make_pair(false, box2d<float>(p.extent_));
+ return std::make_pair(false, box_type(p.extent_));
}
#endif
try
{
p.parse_csv_and_boxes(csv_file, boxes);
- return std::make_pair(true, box2d<float>(p.extent_));
+ return std::make_pair(true, box_type(p.extent_));
}
catch (std::exception const& ex)
{
std::clog << ex.what() << std::endl;
- return std::make_pair(false, box2d<float>(p.extent_));
+ return std::make_pair(false, box_type(p.extent_));
}
}
diff --git a/utils/mapnik-render/mapnik-render.cpp b/utils/mapnik-render/mapnik-render.cpp
index c399226..c172995 100644
--- a/utils/mapnik-render/mapnik-render.cpp
+++ b/utils/mapnik-render/mapnik-render.cpp
@@ -21,7 +21,7 @@ int main (int argc,char** argv)
namespace po = boost::program_options;
bool verbose = false;
- bool auto_open = true;
+ bool auto_open = false;
int return_value = 0;
std::string xml_file;
std::string img_file;
@@ -37,7 +37,7 @@ int main (int argc,char** argv)
("help,h", "produce usage message")
("version,V","print version string")
("verbose,v","verbose output")
- ("open","automatically open the file after rendering (os x only)")
+ ("open","automatically open the file after rendering")
("xml",po::value<std::string>(),"xml map to read")
("img",po::value<std::string>(),"image to render")
("scale-factor",po::value<double>(),"scale factor for rendering")
diff --git a/utils/pgsql2sqlite/pgsql2sqlite.hpp b/utils/pgsql2sqlite/pgsql2sqlite.hpp
index e339a8f..9de8867 100644
--- a/utils/pgsql2sqlite/pgsql2sqlite.hpp
+++ b/utils/pgsql2sqlite/pgsql2sqlite.hpp
@@ -352,23 +352,23 @@ void pgsql2sqlite(Connection conn,
break;
}
case 23:
- output_rec.push_back(sqlite::value_type(int4net(buf)));
+ output_rec.emplace_back(int4net(buf));
break;
case 21:
- output_rec.push_back(sqlite::value_type(int2net(buf)));
+ output_rec.emplace_back(int(int2net(buf)));
break;
case 700:
{
float val;
float4net(val,buf);
- output_rec.push_back(sqlite::value_type(val));
+ output_rec.emplace_back(double(val));
break;
}
case 701:
{
double val;
float8net(val,buf);
- output_rec.push_back(sqlite::value_type(val));
+ output_rec.emplace_back(val);
break;
}
case 1700:
@@ -377,7 +377,7 @@ void pgsql2sqlite(Connection conn,
double val;
if (mapnik::util::string2double(str,val))
{
- output_rec.push_back(sqlite::value_type(val));
+ output_rec.emplace_back(val);
}
break;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik.git
More information about the Pkg-grass-devel
mailing list