[mapnik] 01/05: Imported Upstream version 3.0.11+ds
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Apr 2 01:09:16 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 d34dadb098fac6b41dffd57cec44c558137fdf78
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Apr 2 01:36:47 2016 +0200
Imported Upstream version 3.0.11+ds
---
.travis.yml | 60 +-
CHANGELOG.md | 11 +
Makefile | 15 +-
SConstruct | 16 +-
appveyor.yml | 14 +-
benchmark/bench_framework.hpp | 117 ++-
benchmark/compare_images.hpp | 15 +-
benchmark/run | 13 +-
benchmark/test_getline.cpp | 6 +-
bootstrap.sh | 10 +-
circle.yml | 49 ++
include/mapnik/agg_helpers.hpp | 4 +-
include/mapnik/agg_pattern_source.hpp | 4 +-
include/mapnik/agg_rasterizer.hpp | 5 +-
include/mapnik/agg_render_marker.hpp | 4 +-
include/mapnik/box2d.hpp | 18 +-
include/mapnik/cairo/cairo_context.hpp | 12 +-
include/mapnik/color.hpp | 4 +-
include/mapnik/coord.hpp | 4 +-
include/mapnik/css_color_grammar.hpp | 244 +-----
include/mapnik/css_color_grammar_impl.hpp | 230 +++++
include/mapnik/csv/csv_grammar.hpp | 44 +-
.../csv_grammar_impl.hpp} | 62 +-
.../csv_types.hpp} | 14 +-
include/mapnik/expression_grammar.hpp | 75 +-
include/mapnik/expression_grammar_impl.hpp | 71 +-
include/mapnik/expression_node.hpp | 2 +
include/mapnik/feature_kv_iterator.hpp | 4 +-
include/mapnik/feature_type_style.hpp | 4 +-
include/mapnik/global.hpp | 16 +-
include/mapnik/gradient.hpp | 4 +-
include/mapnik/grid/grid_rasterizer.hpp | 4 +
include/mapnik/grid/grid_render_marker.hpp | 5 +-
include/mapnik/grid/grid_renderer_base.hpp | 6 +-
include/mapnik/grid/grid_rendering_buffer.hpp | 4 +
include/mapnik/hextree.hpp | 26 +-
include/mapnik/image_compositing.hpp | 4 +-
include/mapnik/image_filter.hpp | 5 +-
include/mapnik/image_filter_grammar.hpp | 9 +-
include/mapnik/image_filter_grammar_impl.hpp | 3 +
include/mapnik/image_options.hpp | 5 +
include/mapnik/image_reader.hpp | 6 +-
include/mapnik/image_scaling.hpp | 5 +-
include/mapnik/image_scaling_traits.hpp | 4 +-
include/mapnik/json/error_handler.hpp | 9 +-
.../mapnik/json/extract_bounding_box_grammar.hpp | 62 +-
.../json/extract_bounding_box_grammar_impl.hpp | 50 +-
include/mapnik/json/feature_grammar.hpp | 9 +-
include/mapnik/json/geometry_generator_grammar.hpp | 2 +-
.../json/geometry_generator_grammar_impl.hpp | 1 +
include/mapnik/json/geometry_grammar.hpp | 4 +-
include/mapnik/json/geometry_grammar_impl.hpp | 6 +-
include/mapnik/json/geometry_parser.hpp | 18 +-
include/mapnik/json/geometry_util.hpp | 1 +
.../{agg_rasterizer.hpp => json/positions.hpp} | 20 +-
include/mapnik/json/positions_grammar.hpp | 12 +-
include/mapnik/json/positions_grammar_impl.hpp | 2 +-
.../mapnik/json/properties_generator_grammar.hpp | 13 +-
include/mapnik/json/symbolizer_grammar.hpp | 216 -----
include/mapnik/json/topojson_grammar.hpp | 8 +-
include/mapnik/json/topojson_grammar_impl.hpp | 115 ++-
include/mapnik/json/topojson_utils.hpp | 368 +++++++-
include/mapnik/json/topology.hpp | 73 --
include/mapnik/label_collision_detector.hpp | 4 +-
include/mapnik/map.hpp | 4 +-
include/mapnik/mapped_memory_cache.hpp | 5 +
include/mapnik/marker.hpp | 4 +-
include/mapnik/marker_helpers.hpp | 96 +--
include/mapnik/markers_placement.hpp | 118 ++-
include/mapnik/markers_placements/basic.hpp | 104 +++
include/mapnik/markers_placements/interior.hpp | 24 +-
include/mapnik/markers_placements/line.hpp | 30 +-
include/mapnik/markers_placements/point.hpp | 123 +--
.../mapnik/markers_placements/vertext_first.hpp | 24 +-
include/mapnik/markers_placements/vertext_last.hpp | 21 +-
include/mapnik/params.hpp | 5 +-
include/mapnik/path_expression_grammar_impl.hpp | 5 +-
include/mapnik/png_io.hpp | 28 +-
include/mapnik/projection.hpp | 4 +-
include/mapnik/ptree_helpers.hpp | 4 +-
include/mapnik/quad_tree.hpp | 80 +-
include/mapnik/raster.hpp | 5 +-
include/mapnik/raster_colorizer.hpp | 11 +-
.../renderer_common/process_raster_symbolizer.hpp | 4 +-
include/mapnik/simplify.hpp | 4 +-
include/mapnik/simplify_converter.hpp | 2 +-
include/mapnik/span_image_filter.hpp | 45 +-
...id_rendering_buffer.hpp => stringify_macro.hpp} | 19 +-
include/mapnik/svg/geometry_svg_generator.hpp | 6 +-
include/mapnik/svg/output/svg_output_grammars.hpp | 45 -
.../mapnik/svg/output/svg_output_grammars_impl.hpp | 45 +
include/mapnik/svg/svg_converter.hpp | 4 +-
include/mapnik/svg/svg_path_adapter.hpp | 4 +-
include/mapnik/svg/svg_path_attributes.hpp | 12 +-
include/mapnik/svg/svg_path_commands.hpp | 223 ++---
include/mapnik/svg/svg_path_grammar.hpp | 135 +--
include/mapnik/svg/svg_path_grammar_impl.hpp | 112 +++
include/mapnik/svg/svg_path_parser.hpp | 28 +-
include/mapnik/svg/svg_points_grammar.hpp | 50 +-
...nts_grammar.hpp => svg_points_grammar_impl.hpp} | 65 +-
include/mapnik/svg/svg_renderer_agg.hpp | 4 +-
include/mapnik/svg/svg_transform_grammar.hpp | 247 +-----
include/mapnik/svg/svg_transform_grammar_impl.hpp | 172 ++++
include/mapnik/symbolizer.hpp | 4 +-
include/mapnik/text/face.hpp | 6 +-
include/mapnik/text/font_feature_settings.hpp | 8 +-
include/mapnik/text/formatting/layout.hpp | 3 +
include/mapnik/text/glyph_positions.hpp | 4 +-
include/mapnik/text/harfbuzz_shaper.hpp | 6 +-
include/mapnik/text/icu_shaper.hpp | 5 +-
include/mapnik/text/itemizer.hpp | 4 +-
include/mapnik/text/properties_util.hpp | 7 +-
include/mapnik/text/renderer.hpp | 7 +-
include/mapnik/text/scrptrun.hpp | 3 +
include/mapnik/text/symbolizer_helpers.hpp | 2 +-
include/mapnik/text/text_properties.hpp | 4 +-
include/mapnik/tiff_io.hpp | 6 +
include/mapnik/transform_expression.hpp | 6 +-
include/mapnik/transform_processor.hpp | 5 +-
include/mapnik/unicode.hpp | 4 +
include/mapnik/util/const_rendering_buffer.hpp | 3 +
include/mapnik/util/file_io.hpp | 7 +-
include/mapnik/util/geometry_to_ds_type.hpp | 7 +-
include/mapnik/util/geometry_to_geojson.hpp | 11 +-
include/mapnik/util/path_iterator.hpp | 5 +-
include/mapnik/util/spatial_index.hpp | 41 +-
include/mapnik/util/variant.hpp | 6 +-
include/mapnik/value.hpp | 920 +-------------------
include/mapnik/value_hash.hpp | 4 +-
include/mapnik/value_types.hpp | 5 +-
include/mapnik/version.hpp | 9 +-
include/mapnik/vertex_adapters.hpp | 185 +---
include/mapnik/vertex_cache.hpp | 4 +-
include/mapnik/vertex_converters.hpp | 6 +-
include/mapnik/warning_ignore.hpp | 23 +-
.../{warning_ignore.hpp => warning_ignore_agg.hpp} | 13 +-
include/mapnik/well_known_srs.hpp | 7 +-
include/mapnik/wkb.hpp | 8 +-
include/mapnik/wkt/wkt_generator_grammar.hpp | 1 -
include/mapnik/wkt/wkt_generator_grammar_impl.hpp | 8 +-
include/mapnik/wkt/wkt_grammar.hpp | 3 +-
include/mapnik/wkt/wkt_grammar_impl.hpp | 6 +-
include/mapnik/xml_node.hpp | 4 +-
mason_latest.sh | 37 +-
plugins/input/csv/build.py | 1 +
plugins/input/csv/csv_datasource.cpp | 348 ++------
plugins/input/csv/csv_datasource.hpp | 23 +-
plugins/input/csv/csv_featureset.cpp | 6 +-
plugins/input/csv/csv_featureset.hpp | 5 +-
plugins/input/csv/csv_getline.hpp | 72 ++
plugins/input/csv/csv_index_featureset.cpp | 6 +-
plugins/input/csv/csv_index_featureset.hpp | 4 +-
plugins/input/csv/csv_inline_featureset.cpp | 6 +-
plugins/input/csv/csv_inline_featureset.hpp | 5 +-
plugins/input/csv/csv_utils.cpp | 507 +++++++++++
plugins/input/csv/csv_utils.hpp | 321 +------
plugins/input/gdal/gdal_datasource.cpp | 41 +-
plugins/input/gdal/gdal_datasource.hpp | 3 +-
plugins/input/gdal/gdal_featureset.cpp | 7 +-
plugins/input/gdal/gdal_featureset.hpp | 5 +-
plugins/input/geojson/geojson_datasource.cpp | 14 +-
plugins/input/geojson/geojson_index_featureset.cpp | 1 -
.../geojson/geojson_memory_index_featureset.cpp | 1 -
plugins/input/pgraster/pgraster_wkb_reader.cpp | 15 +-
plugins/input/postgis/postgis_datasource.cpp | 113 ++-
plugins/input/postgis/postgis_datasource.hpp | 7 +
plugins/input/postgis/postgis_featureset.cpp | 16 +-
plugins/input/postgis/postgis_featureset.hpp | 4 +-
plugins/input/topojson/topojson_datasource.cpp | 2 +-
plugins/input/topojson/topojson_featureset.cpp | 335 +-------
scripts/build-appveyor.bat | 6 +-
scripts/travis-common.sh | 41 +-
src/agg/agg_renderer.cpp | 9 +-
src/agg/process_building_symbolizer.cpp | 5 +-
src/agg/process_debug_symbolizer.cpp | 4 +-
src/agg/process_dot_symbolizer.cpp | 4 +-
src/agg/process_group_symbolizer.cpp | 4 +-
src/agg/process_line_pattern_symbolizer.cpp | 6 +-
src/agg/process_line_symbolizer.cpp | 5 +-
src/agg/process_markers_symbolizer.cpp | 4 +-
src/agg/process_point_symbolizer.cpp | 4 +-
src/agg/process_polygon_pattern_symbolizer.cpp | 5 +-
src/agg/process_polygon_symbolizer.cpp | 5 +-
src/agg/process_raster_symbolizer.cpp | 4 +-
src/box2d.cpp | 50 +-
src/build.py | 7 +
src/cairo/process_polygon_pattern_symbolizer.cpp | 3 +-
src/debug.cpp | 10 +-
src/feature_kv_iterator.cpp | 4 +
src/font_engine_freetype.cpp | 18 +-
src/fs.cpp | 5 +-
src/grid/grid_renderer.cpp | 8 +-
src/grid/process_building_symbolizer.cpp | 4 +-
src/grid/process_group_symbolizer.cpp | 4 +-
src/grid/process_line_pattern_symbolizer.cpp | 5 +-
src/grid/process_line_symbolizer.cpp | 5 +-
src/grid/process_markers_symbolizer.cpp | 4 +-
src/grid/process_point_symbolizer.cpp | 4 +-
src/grid/process_polygon_pattern_symbolizer.cpp | 11 +-
src/grid/process_polygon_symbolizer.cpp | 4 +-
src/grid/process_shield_symbolizer.cpp | 5 +-
src/image_compositing.cpp | 5 +-
src/image_scaling.cpp | 5 +-
src/image_util.cpp | 5 +-
.../json/mapnik_geometry_to_geojson.cpp | 9 +-
.../json/mapnik_json_geometry_parser.cpp | 12 +-
.../json/mapnik_json_positions_grammar.cpp | 16 +-
src/load_map.cpp | 8 +-
src/map.cpp | 2 +-
src/marker_cache.cpp | 4 +-
src/marker_helpers.cpp | 141 ++++
src/palette.cpp | 10 +-
src/plugin.cpp | 2 +
src/rapidxml_loader.cpp | 6 +-
src/raster_colorizer.cpp | 2 +-
src/renderer_common/render_markers_symbolizer.cpp | 232 +++---
src/renderer_common/render_pattern.cpp | 3 +
src/svg/svg_parser.cpp | 6 +-
src/svg/svg_path_parser.cpp | 43 +-
src/svg/svg_points_parser.cpp | 33 +-
src/svg/svg_transform_parser.cpp | 37 +-
src/text/face.cpp | 9 +-
src/text/font_library.cpp | 5 +
src/text/formatting/format.cpp | 4 +-
src/text/formatting/layout.cpp | 4 +-
src/text/formatting/list.cpp | 4 +-
src/text/formatting/text.cpp | 4 +-
src/text/placements/list.cpp | 4 +-
src/text/scrptrun.cpp | 3 +
src/text/text_layout.cpp | 5 +-
src/text/text_properties.cpp | 4 +-
src/twkb.cpp | 387 +++++++++
src/unicode.cpp | 12 +-
src/value.cpp | 928 +++++++++++++++++++++
src/vertex_adapters.cpp | 213 +++++
src/warp.cpp | 4 +-
src/well_known_srs.cpp | 4 +-
src/wkb.cpp | 22 +-
test/build.py | 2 +
test/cleanup.hpp | 5 +
test/run | 32 +-
test/unit/color/css_color.cpp | 1 +
test/unit/core/box2d_test.cpp | 1 +
test/unit/core/comparison_test.cpp | 1 +
test/unit/core/conversions_test.cpp | 1 +
test/unit/core/exceptions_test.cpp | 1 +
test/unit/core/expressions_test.cpp | 8 +
test/unit/core/params_test.cpp | 1 +
test/unit/core/value_test.cpp | 1 +
test/unit/data/well-known-geometries.test | 13 +
test/unit/datasource/csv.cpp | 37 +-
test/unit/datasource/ds_test_util.hpp | 25 +
test/unit/datasource/geojson.cpp | 19 -
test/unit/datasource/topojson.cpp | 75 ++
test/unit/font/fontset_runtime_test.cpp | 1 +
test/unit/geometry/centroid.cpp | 1 +
test/unit/geometry/geometry.cpp | 6 +-
test/unit/geometry/geometry_envelope_test.cpp | 1 +
test/unit/geometry/geometry_equal.hpp | 6 +
test/unit/geometry/geometry_hit_test.cpp | 1 +
test/unit/geometry/geometry_is_simple.cpp | 1 +
test/unit/geometry/geometry_is_valid.cpp | 1 +
test/unit/geometry/geometry_reprojection.cpp | 1 +
test/unit/geometry/geometry_strategy_test.cpp | 1 +
test/unit/geometry/has_empty.cpp | 1 +
test/unit/geometry/is_empty.cpp | 1 +
test/unit/geometry/remove_empty.cpp | 1 +
test/unit/imaging/image.cpp | 1 +
test/unit/imaging/image_apply_opacity.cpp | 1 +
test/unit/imaging/image_filter.cpp | 1 +
test/unit/imaging/image_io_test.cpp | 33 +-
test/unit/imaging/image_is_solid.cpp | 1 +
test/unit/imaging/image_painted_test.cpp | 1 +
test/unit/imaging/image_premultiply.cpp | 1 +
test/unit/imaging/image_set_pixel.cpp | 1 +
test/unit/imaging/image_view.cpp | 1 +
test/unit/numerics/enumeration.cpp | 1 +
test/unit/numerics/safe_cast.cpp | 1 +
test/unit/pixel/agg_blend_src_over_test.cpp | 1 +
test/unit/pixel/palette.cpp | 1 +
test/unit/projection/proj_transform.cpp | 1 +
.../unit/serialization/parse_hex.hpp | 26 +-
test/unit/serialization/wkb_formats_test.cpp | 5 -
test/unit/serialization/wkb_test.cpp | 113 +++
test/unit/serialization/xml_parser_trim.cpp | 1 +
test/unit/svg/svg_parser_test.cpp | 4 +-
test/unit/svg/svg_path_parser_test.cpp | 2 +-
test/unit/svg/util.hpp | 2 +-
test/unit/symbolizer/symbolizer_test.cpp | 1 +
test/unit/text/shaping.cpp | 1 +
test/unit/vertex_adapter/clipping_test.cpp | 1 +
test/unit/vertex_adapter/line_offset_test.cpp | 1 +
test/unit/vertex_adapter/offset_converter.cpp | 1 +
.../vertex_adapter/simplify_converters_test.cpp | 1 +
test/unit/vertex_adapter/vertex_adapter.cpp | 1 +
utils/mapnik-config/build.py | 5 -
utils/mapnik-index/build.py | 5 +-
utils/mapnik-index/mapnik-index.cpp | 10 +-
utils/mapnik-index/process_csv_file.cpp | 191 +----
utils/mapnik-index/process_csv_file.hpp | 2 +-
utils/mapnik-index/process_geojson_file.cpp | 36 +-
utils/mapnik-index/process_geojson_file.hpp | 2 +-
utils/pgsql2sqlite/main.cpp | 7 +-
utils/pgsql2sqlite/sqlite.hpp | 5 +-
utils/shapeindex/build.py | 4 +-
utils/shapeindex/shapeindex.cpp | 15 +-
utils/svg2png/svg2png.cpp | 4 +
307 files changed, 5830 insertions(+), 4788 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index bce7b05..13cf1f2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,20 @@
language: c
-sudo: false
-
git:
depth: 10
submodules: false
env:
global:
+ - CCACHE_TEMPDIR=/tmp/.ccache-temp
+ - CCACHE_COMPRESS=1
+ - HEAVY_JOBS="2"
+ - PREFIX=/tmp/mapnik
- secure: "N3a5nzzsgpuu45k8qWdYsHNxrSnqeAGLTOYpfYoAH7B94vuf7pa7XV1tQjXbxrnx2D6ryTdtUtyRKwy7zXbwXxGt4DpczWEo8f6DUd6+obAp3kdnXABg2Sj4oA7KMs0F0CmoADy0jdUZD5YyOJHu64LCIIgzEQ9q49PFMNbU3IE="
- secure: "iQYPNpMtejcgYeUkWZGIWz1msIco5qydJrhZTSCQOYahAQerdT7q5WZEpEo3G6IWOGgO1eo7GFuY8DvqQjw1+jC9b9mhkRNdo3LhGTKS9Gsbl5Q27k0rjlaFZmmQHrfPlQJwhfAIp+KLugHtQw5bCoLh+95E3j0F0DayF1tuJ3s="
+ - secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM="
addons:
postgresql: "9.4"
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-precise-3.5
- packages:
- - clang-3.5
cache:
directories:
@@ -26,35 +23,31 @@ cache:
matrix:
include:
- os: linux
- compiler: clang
- env: JOBS=8 CXX="ccache clang++-3.5 -Qunused-arguments" CC="clang-3.5" MASON_PUBLISH=true BENCH=True
+ sudo: false
+ compiler: ": clang"
+ env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.5 -Qunused-arguments" CC="clang-3.5" TRIGGER=true
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ]
packages: [ 'clang-3.5' ]
- # OOM killer knocking out build on render_markers_symbolizer.cpp
- #
- #- os: linux
- # compiler: gcc
- # env: JOBS=6 CXX="ccache g++-4.9" CC="gcc-4.9"
- # addons:
- # apt:
- # sources: [ 'ubuntu-toolchain-r-test' ]
- # packages: [ 'gcc-4.9', 'g++-4.9', 'libstdc++-4.9-dev', 'libstdc++6' ]
+ - 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"
+ addons:
+ apt:
+ sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ]
+ packages: [ 'clang-3.5', 'llvm-3.5-dev' ]
- os: osx
compiler: clang
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
- osx_image: xcode7.2 # upgrades clang from 6 -> 7
- env: JOBS=8 MASON_PUBLISH=true HEAVY_JOBS=3
- - os: osx
- compiler: clang
- osx_image: xcode7.2 # upgrades clang from 6 -> 7
- env: JOBS=8 COVERAGE=true HEAVY_JOBS=3
+ osx_image: xcode7.3 # upgrades clang from 6 -> 7
+ env: JOBS=4 MASON_PUBLISH=true
before_install:
- source scripts/travis-common.sh
- export PYTHONUSERBASE=$(pwd)/mason_packages/.link
- - export PATH=${PYTHONUSERBASE}/bin:${PATH}
+ - export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PYTHONUSERBASE}/bin:${PATH}
- export COVERAGE=${COVERAGE:-false}
- export MASON_PUBLISH=${MASON_PUBLISH:-false}
- export BENCH=${BENCH:-false}
@@ -63,11 +56,14 @@ 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' brew rm postgis --force
- - on 'osx' brew install postgis --force
- - on 'osx' pg_ctl -w start -l postgres.log --pgdata /usr/local/var/postgres
+ - on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres
+ - on 'osx' rm -rf ${DATA_PATH}
+ - on 'osx' initdb ${DATA_PATH} -E utf8
+ - on 'osx' pg_ctl -w start -l postgres.log --pgdata ${DATA_PATH};
+ - on 'osx' cat postgres.log;
- on 'osx' createuser -s postgres
- psql -c 'create database template_postgis;' -U postgres
- psql -c 'create extension postgis;' -d template_postgis -U postgres
@@ -75,6 +71,9 @@ install:
before_script:
- source bootstrap.sh
+ - ccache --version
+ - ccache -p || true
+ - ccache --show-stats || true
- commit_message_parse
script:
@@ -86,8 +85,9 @@ script:
- enabled ${BENCH} make bench
after_success:
+ - enabled ${TRIGGER} trigger_downstream
- if enabled ${MASON_PUBLISH}; then
+ source ./.mason/mason.sh &&
./mason_latest.sh build &&
- ./mason_latest.sh link &&
./mason_latest.sh publish;
fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7c6078..762cee9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,17 @@ Developers: Please commit along with changes.
For a complete change history, see the git log.
+## 3.0.11
+
+Released:
+
+(Packaged from 8d9dc27)
+
+#### Summary
+
+ - 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)
+
## 3.0.10
Released: February 25, 2016
diff --git a/Makefile b/Makefile
index 777303d..fd3a2ad 100755
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,8 @@ release:
git clone --depth 1 --branch v$${MAPNIK_VERSION} git at github.com:mapnik/mapnik.git $${TARBALL_NAME} && \
cd $${TARBALL_NAME} && \
git checkout "tags/v$${MAPNIK_VERSION}" && \
- git submodule update --depth 1 --init && \
+ git submodule update --depth 100 --init && \
+ rm -rf deps/mapbox/variant/.git && \
rm -rf test/data/.git && \
rm -rf test/data/.gitignore && \
rm -rf test/data-visual/.git && \
@@ -53,6 +54,16 @@ src/json/libmapnik-json.a:
src/expression_grammar.os \
src/transform_expression_grammar.os \
src/image_filter_grammar.os \
+ src/marker_helpers.os \
+ src/svg/svg_transform_parser.os \
+ src/agg/process_line_symbolizer.os \
+ plugins/input/geojson/geojson_datasource.os \
+ utils/mapnik-index/process_geojson_file.o \
+ src/svg/svg_path_parser.os \
+ src/svg/svg_parser.os \
+ src/svg/svg_points_parser.os \
+ src/svg/svg_transform_parser.os \
+
mapnik: src/json/libmapnik-json.a
# then install the rest with -j$(JOBS)
@@ -70,6 +81,8 @@ clean:
@find ./src/ -name "*.so" -exec rm {} \;
@find ./ -name "*.o" -exec rm {} \;
@find ./src/ -name "*.a" -exec rm {} \;
+ @find ./ -name "*.gcda" -exec rm {} \;
+ @find ./ -name "*.gcno" -exec rm {} \;
distclean:
if test -e "config.py"; then mv "config.py" "config.py.backup"; fi
diff --git a/SConstruct b/SConstruct
index 2b851e4..dacc950 100644
--- a/SConstruct
+++ b/SConstruct
@@ -293,6 +293,7 @@ opts.AddVariables(
EnumVariable('OPTIMIZATION','Set compiler optimization level','3', ['0','1','2','3','4','s']),
# Note: setting DEBUG=True will override any custom OPTIMIZATION level
BoolVariable('DEBUG', 'Compile a debug version of Mapnik', 'False'),
+ BoolVariable('COVERAGE', 'Compile a libmapnik and plugins with --coverage', 'False'),
BoolVariable('DEBUG_UNDEFINED', 'Compile a version of Mapnik using clang/llvm undefined behavior asserts', 'False'),
BoolVariable('DEBUG_SANITIZE', 'Compile a version of Mapnik using clang/llvm address sanitation', 'False'),
ListVariable('INPUT_PLUGINS','Input drivers to include',DEFAULT_PLUGINS,PLUGINS.keys()),
@@ -303,6 +304,7 @@ opts.AddVariables(
('CONFIG', "The path to the python file in which to save user configuration options. Currently : '%s'" % SCONS_LOCAL_CONFIG,SCONS_LOCAL_CONFIG),
BoolVariable('USE_CONFIG', "Use SCons user '%s' file (will also write variables after successful configuration)", 'True'),
BoolVariable('NO_ATEXIT', 'Will prevent Singletons from being deleted atexit of main thread', 'False'),
+ BoolVariable('NO_DLCLOSE', 'Will prevent plugins from being unloaded', 'False'),
# http://www.scons.org/wiki/GoFastButton
# http://stackoverflow.com/questions/1318863/how-to-optimize-an-scons-script
BoolVariable('FAST', "Make SCons faster at the cost of less precise dependency tracking", 'False'),
@@ -317,7 +319,6 @@ opts.AddVariables(
('PATH_REMOVE', 'A path prefix to exclude from all known command and compile paths (create multiple excludes separated by :)', ''),
('PATH_REPLACE', 'Two path prefixes (divided with a :) to search/replace from all known command and compile paths', ''),
('MAPNIK_NAME', 'Name of library', 'mapnik'),
- BoolVariable('MAPNIK_BUNDLED_SHARE_DIRECTORY', 'For portable packaging: instruct mapnik-config to report relative paths to bundled GDAL_DATA, PROJ_LIB, and ICU_DATA','False'),
# Boost variables
# default is '/usr/include', see FindBoost method below
@@ -1139,6 +1140,9 @@ if not preconfigured:
else:
mode = 'release mode'
+ if env['COVERAGE']:
+ mode += ' (with coverage)'
+
env['PLATFORM'] = platform.uname()[0]
color_print(4,"Configuring on %s in *%s*..." % (env['PLATFORM'],mode))
@@ -1727,6 +1731,9 @@ if not preconfigured:
if env['NO_ATEXIT']:
env.Append(CPPDEFINES = '-DMAPNIK_NO_ATEXIT')
+ if env['NO_DLCLOSE'] or env['COVERAGE']:
+ env.Append(CPPDEFINES = '-DMAPNIK_NO_DLCLOSE')
+
# Mac OSX (Darwin) special settings
if env['PLATFORM'] == 'Darwin':
pthread = ''
@@ -1786,10 +1793,11 @@ if not preconfigured:
# Common flags for g++/clang++ CXX compiler.
# TODO: clean up code more to make -Wextra -Wsign-compare -Wsign-conversion -Wconversion viable
+ # -Wfloat-equal -Wold-style-cast -Wexit-time-destructors -Wglobal-constructors -Wreserved-id-macro -Wheader-hygiene -Wmissing-noreturn
common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread)
if 'clang++' in env['CXX']:
- common_cxx_flags += ' -Wno-unsequenced '
+ common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene '
if env['DEBUG']:
env.Append(CXXFLAGS = common_cxx_flags + '-O0')
@@ -1891,6 +1899,10 @@ if not HELP_REQUESTED:
plugin_base = env.Clone()
+ if env['COVERAGE']:
+ plugin_base.Append(LINKFLAGS='--coverage')
+ plugin_base.Append(CXXFLAGS='--coverage')
+
Export('plugin_base')
if env['FAST']:
diff --git a/appveyor.yml b/appveyor.yml
index ea7af41..f236021 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,9 +12,20 @@ os: Visual Studio 2015
# limit clone to latest 5 commits
clone_depth: 5
+services:
+ - postgresql94 #if changing this, also change PATH below
+
install:
+ - SET PGUSER=postgres
+ - SET PGPASSWORD=Password12!
+ - SET PATH=C:\Program Files\PostgreSQL\9.4\bin\;%PATH%
+
+build_script:
- scripts\build-appveyor.bat
+after_build:
+ - 7z a mapnik-visual-images.zip C:\tmp\mapnik-visual-images
+
artifacts:
- path: mapnik-gyp\msbuild-summary.txt
name: msbuild-summary.txt
@@ -22,7 +33,8 @@ artifacts:
name: msbuild-errors.txt
- path: mapnik-gyp\msbuild-warnings.txt
name: msbuild-warnings.txt
+ - path: mapnik-visual-images.zip
+ name: mapnik-visual-images.zip
-build: off
test: off
deploy: off
diff --git a/benchmark/bench_framework.hpp b/benchmark/bench_framework.hpp
index 34c63a8..a3de4fd 100644
--- a/benchmark/bench_framework.hpp
+++ b/benchmark/bench_framework.hpp
@@ -1,5 +1,5 @@
-#ifndef __MAPNIK_BENCH_FRAMEWORK_HPP__
-#define __MAPNIK_BENCH_FRAMEWORK_HPP__
+#ifndef MAPNIK_BENCH_FRAMEWORK_HPP
+#define MAPNIK_BENCH_FRAMEWORK_HPP
// mapnik
#include <mapnik/debug.hpp>
@@ -10,6 +10,7 @@
// stl
#include <chrono>
+#include <cmath> // log10, round
#include <cstdio> // snprintf
#include <iostream>
#include <set>
@@ -19,6 +20,12 @@
namespace benchmark {
+template <typename T>
+using milliseconds = std::chrono::duration<T, std::milli>;
+
+template <typename T>
+using seconds = std::chrono::duration<T>;
+
class test_case
{
protected:
@@ -45,7 +52,6 @@ public:
}
virtual bool validate() const = 0;
virtual bool operator()() const = 0;
- virtual ~test_case() {}
};
// gathers --long-option values in 'params';
@@ -92,7 +98,7 @@ inline int parse_args(int argc, char** argv, mapnik::parameters & params)
inline void handle_common_args(mapnik::parameters const& params)
{
- if (auto severity = params.get<std::string>("log-severity")) {
+ if (auto severity = params.get<std::string>("log")) {
if (*severity == "debug")
mapnik::logger::set_severity(mapnik::logger::debug);
else if (*severity == "warn")
@@ -102,7 +108,7 @@ inline void handle_common_args(mapnik::parameters const& params)
else if (*severity == "none")
mapnik::logger::set_severity(mapnik::logger::none);
else
- std::clog << "ignoring option --log-severity='" << *severity
+ std::clog << "ignoring option --log='" << *severity
<< "' (allowed values are: debug, warn, error, none)\n";
}
}
@@ -134,6 +140,29 @@ inline int handle_args(int argc, char** argv, mapnik::parameters & params)
} \
} \
+struct big_number_fmt
+{
+ int w;
+ double v;
+ const char* u;
+
+ big_number_fmt(int width, double value, int base = 1000)
+ : w(width), v(value), u("")
+ {
+ static const char* suffixes = "\0\0k\0M\0G\0T\0P\0E\0Z\0Y\0\0";
+ u = suffixes;
+
+ while (v > 1 && std::log10(std::round(v)) >= width && u[2])
+ {
+ v /= base;
+ u += 2;
+ }
+
+ // adjust width for proper alignment without suffix
+ w += (u == suffixes);
+ }
+};
+
template <typename T>
int run(T const& test_runner, std::string const& name)
{
@@ -156,21 +185,43 @@ int run(T const& test_runner, std::string const& name)
auto opt_min_duration = test_runner.params().template get<double>("min-duration", 0.0);
std::chrono::duration<double> min_seconds(*opt_min_duration);
auto min_duration = std::chrono::duration_cast<decltype(elapsed)>(min_seconds);
- std::size_t loops = 0;
+ auto num_iters = test_runner.iterations();
+ auto num_threads = test_runner.threads();
+ auto total_iters = 0;
- if (test_runner.threads() > 0)
+ if (num_threads > 0)
{
- using thread_group = std::vector<std::unique_ptr<std::thread> >;
- using value_type = thread_group::value_type;
- thread_group tg;
- for (std::size_t i=0;i<test_runner.threads();++i)
+ std::mutex mtx_ready;
+ std::unique_lock<std::mutex> lock_ready(mtx_ready);
+
+ auto stub = [&](T const& test_copy)
{
- tg.emplace_back(new std::thread(test_runner));
+ // workers will wait on this mutex until the main thread
+ // constructs all of them and starts measuring time
+ std::unique_lock<std::mutex> my_lock(mtx_ready);
+ my_lock.unlock();
+ test_copy();
+ };
+
+ std::vector<std::thread> tg;
+ tg.reserve(num_threads);
+ for (auto i = num_threads; i-- > 0; )
+ {
+ tg.emplace_back(stub, test_runner);
}
start = std::chrono::high_resolution_clock::now();
- std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
+ lock_ready.unlock();
+ // wait for all workers to finish
+ for (auto & t : tg)
+ {
+ if (t.joinable())
+ t.join();
+ }
elapsed = std::chrono::high_resolution_clock::now() - start;
- loops = 1;
+ // this is actually per-thread count, not total, but I think
+ // reporting average 'iters/thread/second' is more useful
+ // than 'iters/second' multiplied by the number of threads
+ total_iters += num_iters;
}
else
{
@@ -178,39 +229,25 @@ int run(T const& test_runner, std::string const& name)
do {
test_runner();
elapsed = std::chrono::high_resolution_clock::now() - start;
- ++loops;
+ total_iters += num_iters;
} while (elapsed < min_duration);
}
- double iters = loops * test_runner.iterations();
- double dur_total = std::chrono::duration<double, std::milli>(elapsed).count();
- double dur_avg = dur_total / iters;
- char iters_unit = ' ';
char msg[200];
-
- if (iters >= 1e7) iters *= 1e-6, iters_unit = 'M';
- else if (iters >= 1e4) iters *= 1e-3, iters_unit = 'k';
+ double dur_total = milliseconds<double>(elapsed).count();
+ auto elapsed_nonzero = std::max(elapsed, decltype(elapsed){1});
+ big_number_fmt itersf(4, total_iters);
+ big_number_fmt ips(5, total_iters / seconds<double>(elapsed_nonzero).count());
std::snprintf(msg, sizeof(msg),
- "%-43s %3zu threads %4.0f%c iters %6.0f milliseconds",
+ "%-43s %3zu threads %*.0f%s iters %6.0f milliseconds %*.0f%s i/s\n",
name.c_str(),
- test_runner.threads(),
- iters, iters_unit,
- dur_total);
+ num_threads,
+ itersf.w, itersf.v, itersf.u,
+ dur_total,
+ ips.w, ips.v, ips.u
+ );
std::clog << msg;
-
- // log average time per iteration, currently only for non-threaded runs
- if (test_runner.threads() == 0)
- {
- char unit = 'm';
- if (dur_avg < 1e-5) dur_avg *= 1e+9, unit = 'p';
- else if (dur_avg < 1e-2) dur_avg *= 1e+6, unit = 'n';
- else if (dur_avg < 1e+1) dur_avg *= 1e+3, unit = 'u';
- std::snprintf(msg, sizeof(msg), " %4.0f%cs/iter", dur_avg, unit);
- std::clog << msg;
- }
-
- std::clog << "\n";
return 0;
}
catch (std::exception const& ex)
@@ -250,4 +287,4 @@ protected:
}
-#endif // __MAPNIK_BENCH_FRAMEWORK_HPP__
+#endif // MAPNIK_BENCH_FRAMEWORK_HPP
diff --git a/benchmark/compare_images.hpp b/benchmark/compare_images.hpp
index fb0e4ac..ff90e01 100644
--- a/benchmark/compare_images.hpp
+++ b/benchmark/compare_images.hpp
@@ -1,11 +1,10 @@
-#ifndef __MAPNIK_COMPARE_IMAGES_HPP__
-#define __MAPNIK_COMPARE_IMAGES_HPP__
+#ifndef MAPNIK_COMPARE_IMAGES_HPP
+#define MAPNIK_COMPARE_IMAGES_HPP
#include <mapnik/image.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_reader.hpp>
-using namespace mapnik;
namespace benchmark {
@@ -23,15 +22,15 @@ namespace benchmark {
throw mapnik::image_reader_exception("Failed to load: " + src_fn);
}
- const image_any desc_any = reader1->read(0,0,reader1->width(), reader1->height());
- const image_any src_any = reader2->read(0,0,reader2->width(), reader2->height());
+ const mapnik::image_any desc_any = reader1->read(0,0,reader1->width(), reader1->height());
+ const mapnik::image_any src_any = reader2->read(0,0,reader2->width(), reader2->height());
- image_rgba8 const& dest = util::get<image_rgba8>(desc_any);
- image_rgba8 const& src = util::get<image_rgba8>(src_any);
+ mapnik::image_rgba8 const& dest = mapnik::util::get<mapnik::image_rgba8>(desc_any);
+ mapnik::image_rgba8 const& src = mapnik::util::get<mapnik::image_rgba8>(src_any);
return compare(dest, src, 0, true) == 0;
}
}
-#endif // __MAPNIK_COMPARE_IMAGES_HPP__
+#endif // MAPNIK_COMPARE_IMAGES_HPP
diff --git a/benchmark/run b/benchmark/run
index 00285b2..6a8fdd9 100755
--- a/benchmark/run
+++ b/benchmark/run
@@ -6,8 +6,14 @@ source ./localize.sh
BASE=./benchmark/out
function run {
- ${BASE}/$1 --threads 0 --iterations $3;
- ${BASE}/$1 --threads $2 --iterations $(expr $3 / $2);
+ local runner="$BASE/$1 --log=none"
+ local threads="$2"
+ local iters="$3"
+ shift 3
+ $runner --threads 0 --iterations $iters "$@"
+ if test $threads -gt 0; then
+ $runner --threads $threads --iterations $((iters/threads)) "$@"
+ fi
}
run test_getline 30 10000000
#run test_array_allocation 20 100000
@@ -23,6 +29,8 @@ run test_face_ptr_creation 10 1000
run test_font_registration 10 100
run test_offset_converter 10 1000
+# commented since this is really slow on travis
+: '
./benchmark/out/test_rendering \
--name "text rendering" \
--map benchmark/data/roads.xml \
@@ -31,6 +39,7 @@ run test_offset_converter 10 1000
--height 600 \
--iterations 20 \
--threads 10
+'
./benchmark/out/test_rendering \
--name "gdal tiff rendering" \
diff --git a/benchmark/test_getline.cpp b/benchmark/test_getline.cpp
index 1791b06..ed21c04 100644
--- a/benchmark/test_getline.cpp
+++ b/benchmark/test_getline.cpp
@@ -1,7 +1,7 @@
#include "bench_framework.hpp"
-#include <cstring>
-#include <cstdlib>
-#include "../plugins/input/csv/csv_utils.hpp"
+#include "../plugins/input/csv/csv_getline.hpp"
+
+
class test : public benchmark::test_case
{
diff --git a/bootstrap.sh b/bootstrap.sh
old mode 100644
new mode 100755
index f565d01..3a64709
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -10,12 +10,15 @@ todo
- shrink icu data
'
+MASON_VERSION="694d08c"
+
function setup_mason() {
if [[ ! -d ./.mason ]]; then
- git clone --depth 1 https://github.com/mapbox/mason.git ./.mason
+ git clone https://github.com/mapbox/mason.git ./.mason
+ (cd ./.mason && git checkout ${MASON_VERSION})
else
echo "Updating to latest mason"
- (cd ./.mason && git pull)
+ (cd ./.mason && git fetch && git checkout ${MASON_VERSION})
fi
export MASON_DIR=$(pwd)/.mason
export PATH=$(pwd)/.mason:$PATH
@@ -28,7 +31,7 @@ function install() {
if [[ ! -d ./mason_packages/${MASON_PLATFORM_ID}/${1}/${2} ]]; then
mason install $1 $2
mason link $1 $2
- if [[ $3 ]]; then
+ if [[ ${3:-false} != false ]]; then
LA_FILE=$(${MASON_DIR:-~/.mason}/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}
@@ -42,6 +45,7 @@ function install() {
ICU_VERSION="55.1"
function install_mason_deps() {
+ install ccache 3.2.4 &
install jpeg_turbo 1.4.0 libjpeg &
install libpng 1.6.20 libpng &
install libtiff 4.0.4beta libtiff &
diff --git a/circle.yml b/circle.yml
new file mode 100644
index 0000000..e7c12d7
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,49 @@
+machine:
+ xcode:
+ version: 7.3
+ environment:
+ XCODE_SCHEME: "no"
+ XCODE_WORKSPACE: "no"
+ JOBS: 8
+ CCACHE_TEMPDIR: /tmp/.ccache-temp
+ CCACHE_COMPRESS: 1
+ LLVM_VERSION: 3.7
+ pre:
+ - echo "here"
+ post:
+ - echo "there"
+
+checkout:
+ post:
+ - git submodule update --init
+
+dependencies:
+ cache_directories:
+ - "~/.ccache"
+ - "~/.apt-cache"
+ - "mason_packages"
+ 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}
+
+database:
+ pre:
+ - ./bootstrap.sh
+ - ./configure CC="clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache clang++-${LLVM_VERSION} -Qunused-arguments"
+ - make
+ override:
+ - psql -c 'create database template_postgis;'
+ - psql -c 'create extension postgis;' -d template_postgis
+
+test:
+ override:
+ - make test
diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp
index 139405c..ff87ce0 100644
--- a/include/mapnik/agg_helpers.hpp
+++ b/include/mapnik/agg_helpers.hpp
@@ -26,8 +26,10 @@
// mapnik
#include <mapnik/symbolizer_enumerations.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_gamma_functions.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/agg_pattern_source.hpp b/include/mapnik/agg_pattern_source.hpp
index a000020..42dd7f3 100644
--- a/include/mapnik/agg_pattern_source.hpp
+++ b/include/mapnik/agg_pattern_source.hpp
@@ -27,8 +27,10 @@
#include <mapnik/image.hpp>
#include <mapnik/util/noncopyable.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_color_rgba.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/agg_rasterizer.hpp b/include/mapnik/agg_rasterizer.hpp
index 51cf4cd..66da59f 100644
--- a/include/mapnik/agg_rasterizer.hpp
+++ b/include/mapnik/agg_rasterizer.hpp
@@ -26,8 +26,11 @@
// mapnik
#include <mapnik/util/noncopyable.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/agg_render_marker.hpp b/include/mapnik/agg_render_marker.hpp
index 65e531c..283807a 100644
--- a/include/mapnik/agg_render_marker.hpp
+++ b/include/mapnik/agg_render_marker.hpp
@@ -30,7 +30,8 @@
#include <mapnik/safe_cast.hpp>
#include <mapnik/util/const_rendering_buffer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_color_rgba.h"
#include "agg_renderer_base.h"
#include "agg_renderer_scanline.h"
@@ -43,6 +44,7 @@
#include "agg_pixfmt_rgba.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_interpolator_linear.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp
index 4471c28..a790c1d 100644
--- a/include/mapnik/box2d.hpp
+++ b/include/mapnik/box2d.hpp
@@ -27,8 +27,10 @@
#include <mapnik/config.hpp>
#include <mapnik/coord.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/operators.hpp>
+#pragma GCC diagnostic pop
// agg
// forward declare so that apps using mapnik do not need agg headers
@@ -48,7 +50,8 @@ template <typename T> class MAPNIK_DECL box2d
boost::multipliable2<box2d<T>, T > > > >
{
public:
- using box2d_type = box2d<T>;
+ using value_type = T;
+ using box2d_type = box2d<value_type>;
private:
T minx_;
T miny_;
@@ -63,12 +66,22 @@ private:
swap(lhs.maxy_, rhs.maxy_);
}
public:
+
box2d();
box2d(T minx,T miny,T maxx,T maxy);
box2d(coord<T,2> const& c0, coord<T,2> const& c1);
box2d(box2d_type const& rhs);
box2d(box2d_type const& rhs, agg::trans_affine const& tr);
+ // move
box2d(box2d_type&& rhs);
+ // converting ctor
+ template <typename T1>
+ explicit box2d(box2d<T1> other)
+ : minx_(static_cast<value_type>(other.minx())),
+ miny_(static_cast<value_type>(other.miny())),
+ maxx_(static_cast<value_type>(other.maxx())),
+ maxy_(static_cast<value_type>(other.maxy()))
+ {}
box2d_type& operator=(box2d_type other);
T minx() const;
T miny() const;
@@ -97,6 +110,7 @@ public:
void re_center(T cx,T cy);
void re_center(coord<T,2> const& c);
void init(T x0,T y0,T x1,T y1);
+ void init(T x, T y);
void clip(box2d_type const& other);
void pad(T padding);
bool from_string(std::string const& str);
diff --git a/include/mapnik/cairo/cairo_context.hpp b/include/mapnik/cairo/cairo_context.hpp
index 3f065db..9733efb 100644
--- a/include/mapnik/cairo/cairo_context.hpp
+++ b/include/mapnik/cairo/cairo_context.hpp
@@ -38,18 +38,20 @@
#include <mapnik/symbolizer_base.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
-// stl
-#include <memory>
-
-// cairo
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <cairo.h>
+#pragma GCC diagnostic pop
// stl
+#include <memory>
#include <map>
#include <stdexcept>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp
index 690803a..434a9cf 100644
--- a/include/mapnik/color.hpp
+++ b/include/mapnik/color.hpp
@@ -27,8 +27,10 @@
#include <mapnik/config.hpp>
#include <mapnik/global.hpp>
-//boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/operators.hpp>
+#pragma GCC diagnostic pop
// stl
#include <sstream>
diff --git a/include/mapnik/coord.hpp b/include/mapnik/coord.hpp
index fcdfa90..f8ea3f1 100644
--- a/include/mapnik/coord.hpp
+++ b/include/mapnik/coord.hpp
@@ -23,8 +23,10 @@
#ifndef MAPNIK_COORD_HPP
#define MAPNIK_COORD_HPP
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/operators.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
template <typename T,int dim>
diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp
index 21e6391..8fbdeaa 100644
--- a/include/mapnik/css_color_grammar.hpp
+++ b/include/mapnik/css_color_grammar.hpp
@@ -32,261 +32,25 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/qi_action.hpp>
-#include <boost/spirit/include/qi_lexeme.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-#include <boost/spirit/include/phoenix_fusion.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/fusion/include/adapt_adt.hpp>
#pragma GCC diagnostic pop
// stl
#include <string>
-BOOST_FUSION_ADAPT_ADT(
- mapnik::color,
- (unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast<uint8_t>(val)))
- (unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast<uint8_t>(val)))
- (unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast<uint8_t>(val)))
- (unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast<uint8_t>(val)))
- )
-
namespace mapnik
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
-namespace phoenix = boost::phoenix;
using ascii_space_type = boost::spirit::ascii::space_type;
-struct named_colors_ : qi::symbols<char,color>
-{
- named_colors_()
- {
- add
- ("aliceblue", color(240, 248, 255))
- ("antiquewhite", color(250, 235, 215))
- ("aqua", color(0, 255, 255))
- ("aquamarine", color(127, 255, 212))
- ("azure", color(240, 255, 255))
- ("beige", color(245, 245, 220))
- ("bisque", color(255, 228, 196))
- ("black", color(0, 0, 0))
- ("blanchedalmond", color(255,235,205))
- ("blue", color(0, 0, 255))
- ("blueviolet", color(138, 43, 226))
- ("brown", color(165, 42, 42))
- ("burlywood", color(222, 184, 135))
- ("cadetblue", color(95, 158, 160))
- ("chartreuse", color(127, 255, 0))
- ("chocolate", color(210, 105, 30))
- ("coral", color(255, 127, 80))
- ("cornflowerblue", color(100, 149, 237))
- ("cornsilk", color(255, 248, 220))
- ("crimson", color(220, 20, 60))
- ("cyan", color(0, 255, 255))
- ("darkblue", color(0, 0, 139))
- ("darkcyan", color(0, 139, 139))
- ("darkgoldenrod", color(184, 134, 11))
- ("darkgray", color(169, 169, 169))
- ("darkgreen", color(0, 100, 0))
- ("darkgrey", color(169, 169, 169))
- ("darkkhaki", color(189, 183, 107))
- ("darkmagenta", color(139, 0, 139))
- ("darkolivegreen", color(85, 107, 47))
- ("darkorange", color(255, 140, 0))
- ("darkorchid", color(153, 50, 204))
- ("darkred", color(139, 0, 0))
- ("darksalmon", color(233, 150, 122))
- ("darkseagreen", color(143, 188, 143))
- ("darkslateblue", color(72, 61, 139))
- ("darkslategrey", color(47, 79, 79))
- ("darkturquoise", color(0, 206, 209))
- ("darkviolet", color(148, 0, 211))
- ("deeppink", color(255, 20, 147))
- ("deepskyblue", color(0, 191, 255))
- ("dimgray", color(105, 105, 105))
- ("dimgrey", color(105, 105, 105))
- ("dodgerblue", color(30, 144, 255))
- ("firebrick", color(178, 34, 34))
- ("floralwhite", color(255, 250, 240))
- ("forestgreen", color(34, 139, 34))
- ("fuchsia", color(255, 0, 255))
- ("gainsboro", color(220, 220, 220))
- ("ghostwhite", color(248, 248, 255))
- ("gold", color(255, 215, 0))
- ("goldenrod", color(218, 165, 32))
- ("gray", color(128, 128, 128))
- ("grey", color(128, 128, 128))
- ("green", color(0, 128, 0))
- ("greenyellow", color(173, 255, 47))
- ("honeydew", color(240, 255, 240))
- ("hotpink", color(255, 105, 180))
- ("indianred", color(205, 92, 92))
- ("indigo", color(75, 0, 130))
- ("ivory", color(255, 255, 240))
- ("khaki", color(240, 230, 140))
- ("lavender", color(230, 230, 250))
- ("lavenderblush", color(255, 240, 245))
- ("lawngreen", color(124, 252, 0))
- ("lemonchiffon", color(255, 250, 205))
- ("lightblue", color(173, 216, 230))
- ("lightcoral", color(240, 128, 128))
- ("lightcyan", color(224, 255, 255))
- ("lightgoldenrodyellow", color(250, 250, 210))
- ("lightgray", color(211, 211, 211))
- ("lightgreen", color(144, 238, 144))
- ("lightgrey", color(211, 211, 211))
- ("lightpink", color(255, 182, 193))
- ("lightsalmon", color(255, 160, 122))
- ("lightseagreen", color(32, 178, 170))
- ("lightskyblue", color(135, 206, 250))
- ("lightslategray", color(119, 136, 153))
- ("lightslategrey", color(119, 136, 153))
- ("lightsteelblue", color(176, 196, 222))
- ("lightyellow", color(255, 255, 224))
- ("lime", color(0, 255, 0))
- ("limegreen", color(50, 205, 50))
- ("linen", color(250, 240, 230))
- ("magenta", color(255, 0, 255))
- ("maroon", color(128, 0, 0))
- ("mediumaquamarine", color(102, 205, 170))
- ("mediumblue", color(0, 0, 205))
- ("mediumorchid", color(186, 85, 211))
- ("mediumpurple", color(147, 112, 219))
- ("mediumseagreen", color(60, 179, 113))
- ("mediumslateblue", color(123, 104, 238))
- ("mediumspringgreen", color(0, 250, 154))
- ("mediumturquoise", color(72, 209, 204))
- ("mediumvioletred", color(199, 21, 133))
- ("midnightblue", color(25, 25, 112))
- ("mintcream", color(245, 255, 250))
- ("mistyrose", color(255, 228, 225))
- ("moccasin", color(255, 228, 181))
- ("navajowhite", color(255, 222, 173))
- ("navy", color(0, 0, 128))
- ("oldlace", color(253, 245, 230))
- ("olive", color(128, 128, 0))
- ("olivedrab", color(107, 142, 35))
- ("orange", color(255, 165, 0))
- ("orangered", color(255, 69, 0))
- ("orchid", color(218, 112, 214))
- ("palegoldenrod", color(238, 232, 170))
- ("palegreen", color(152, 251, 152))
- ("paleturquoise", color(175, 238, 238))
- ("palevioletred", color(219, 112, 147))
- ("papayawhip", color(255, 239, 213))
- ("peachpuff", color(255, 218, 185))
- ("peru", color(205, 133, 63))
- ("pink", color(255, 192, 203))
- ("plum", color(221, 160, 221))
- ("powderblue", color(176, 224, 230))
- ("purple", color(128, 0, 128))
- ("red", color(255, 0, 0))
- ("rosybrown", color(188, 143, 143))
- ("royalblue", color(65, 105, 225))
- ("saddlebrown", color(139, 69, 19))
- ("salmon", color(250, 128, 114))
- ("sandybrown", color(244, 164, 96))
- ("seagreen", color(46, 139, 87))
- ("seashell", color(255, 245, 238))
- ("sienna", color(160, 82, 45))
- ("silver", color(192, 192, 192))
- ("skyblue", color(135, 206, 235))
- ("slateblue", color(106, 90, 205))
- ("slategray", color(112, 128, 144))
- ("slategrey", color(112, 128, 144))
- ("snow", color(255, 250, 250))
- ("springgreen", color(0, 255, 127))
- ("steelblue", color(70, 130, 180))
- ("tan", color(210, 180, 140))
- ("teal", color(0, 128, 128))
- ("thistle", color(216, 191, 216))
- ("tomato", color(255, 99, 71))
- ("turquoise", color(64, 224, 208))
- ("violet", color(238, 130, 238))
- ("wheat", color(245, 222, 179))
- ("white", color(255, 255, 255))
- ("whitesmoke", color(245, 245, 245))
- ("yellow", color(255, 255, 0))
- ("yellowgreen", color(154, 205, 50))
- ("transparent", color(0, 0, 0, 0))
- ;
- }
-} ;
-
-struct percent_conv_impl
-{
- template <typename T>
- struct result
- {
- using type = unsigned;
- };
-
- unsigned operator() (double val) const
- {
- return safe_cast<uint8_t>(std::lround((255.0 * val)/100.0));
- }
-};
-
-struct alpha_conv_impl
-{
- template <typename T>
- struct result
- {
- using type = unsigned;
- };
-
- unsigned operator() (double val) const
- {
- return safe_cast<uint8_t>(std::lround((255.0 * val)));
- }
-};
-
-struct hsl_conv_impl
-{
- template<typename T>
- struct result
- {
- using type = void;
- };
-
- template <typename T0,typename T1, typename T2, typename T3>
- void operator() (T0 & c, T1 h, T2 s, T3 l) const
- {
- double m1,m2;
- // normalize values
- h /= 360.0;
- s /= 100.0;
- l /= 100.0;
-
- if (l <= 0.5)
- {
- m2 = l * (s + 1.0);
- }
- else
- {
- m2 = l + s - l*s;
- }
- m1 = l * 2 - m2;
-
- double r = hue_to_rgb(m1, m2, h + 1.0/3.0);
- double g = hue_to_rgb(m1, m2, h);
- double b = hue_to_rgb(m1, m2, h - 1.0/3.0);
-
- c.set_red(safe_cast<uint8_t>(std::lround(255.0 * r)));
- c.set_green(safe_cast<uint8_t>(std::lround(255.0 * g)));
- c.set_blue(safe_cast<uint8_t>(std::lround(255.0 * b)));
- }
-};
-
-
template <typename Iterator>
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
{
+ // ctor
css_color_grammar();
+ // rules
qi::uint_parser< unsigned, 16, 2, 2 > hex2 ;
qi::uint_parser< unsigned, 16, 1, 1 > hex1 ;
qi::uint_parser< unsigned, 10, 1, 3 > dec3 ;
@@ -296,10 +60,6 @@ struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
qi::rule<Iterator, color(), ascii_space_type> hex_color;
qi::rule<Iterator, color(), ascii_space_type> hex_color_small;
qi::rule<Iterator, color(), ascii_space_type> css_color;
- named_colors_ named;
- phoenix::function<percent_conv_impl> percent_converter;
- phoenix::function<alpha_conv_impl> alpha_converter;
- phoenix::function<hsl_conv_impl> hsl_converter;
};
}
diff --git a/include/mapnik/css_color_grammar_impl.hpp b/include/mapnik/css_color_grammar_impl.hpp
index c978194..22fa744 100644
--- a/include/mapnik/css_color_grammar_impl.hpp
+++ b/include/mapnik/css_color_grammar_impl.hpp
@@ -22,10 +22,234 @@
// NOTE: This is an implementation header file and is only meant to be included
// from implementation files. It therefore doesn't have an include guard.
+// mapnik
#include <mapnik/css_color_grammar.hpp>
+// boost
+#pragma GCC diagnostic push
+#include <boost/fusion/include/adapt_adt.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#pragma GCC diagnostic pop
+
+
+BOOST_FUSION_ADAPT_ADT(
+ mapnik::color,
+ (unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast<uint8_t>(val)))
+ (unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast<uint8_t>(val)))
+ (unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast<uint8_t>(val)))
+ (unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast<uint8_t>(val)))
+ )
namespace mapnik
{
+namespace phoenix = boost::phoenix;
+
+struct percent_conv_impl
+{
+ using result_type = unsigned;
+ unsigned operator() (double val) const
+ {
+ return safe_cast<uint8_t>(std::lround((255.0 * val)/100.0));
+ }
+};
+
+struct alpha_conv_impl
+{
+ using result_type = unsigned;
+ unsigned operator() (double val) const
+ {
+ return safe_cast<uint8_t>(std::lround((255.0 * val)));
+ }
+};
+
+struct hsl_conv_impl
+{
+ using result_type = void;
+ template <typename T0,typename T1, typename T2, typename T3>
+ void operator() (T0 & c, T1 h, T2 s, T3 l) const
+ {
+ double m1,m2;
+ // normalize values
+ h /= 360.0;
+ s /= 100.0;
+ l /= 100.0;
+
+ if (l <= 0.5)
+ {
+ m2 = l * (s + 1.0);
+ }
+ else
+ {
+ m2 = l + s - l*s;
+ }
+ m1 = l * 2 - m2;
+
+ double r = hue_to_rgb(m1, m2, h + 1.0/3.0);
+ double g = hue_to_rgb(m1, m2, h);
+ double b = hue_to_rgb(m1, m2, h - 1.0/3.0);
+
+ c.set_red(safe_cast<uint8_t>(std::lround(255.0 * r)));
+ c.set_green(safe_cast<uint8_t>(std::lround(255.0 * g)));
+ c.set_blue(safe_cast<uint8_t>(std::lround(255.0 * b)));
+ }
+};
+
+struct named_colors : qi::symbols<char,color>
+{
+ named_colors()
+ {
+ add
+ ("aliceblue", color(240, 248, 255))
+ ("antiquewhite", color(250, 235, 215))
+ ("aqua", color(0, 255, 255))
+ ("aquamarine", color(127, 255, 212))
+ ("azure", color(240, 255, 255))
+ ("beige", color(245, 245, 220))
+ ("bisque", color(255, 228, 196))
+ ("black", color(0, 0, 0))
+ ("blanchedalmond", color(255,235,205))
+ ("blue", color(0, 0, 255))
+ ("blueviolet", color(138, 43, 226))
+ ("brown", color(165, 42, 42))
+ ("burlywood", color(222, 184, 135))
+ ("cadetblue", color(95, 158, 160))
+ ("chartreuse", color(127, 255, 0))
+ ("chocolate", color(210, 105, 30))
+ ("coral", color(255, 127, 80))
+ ("cornflowerblue", color(100, 149, 237))
+ ("cornsilk", color(255, 248, 220))
+ ("crimson", color(220, 20, 60))
+ ("cyan", color(0, 255, 255))
+ ("darkblue", color(0, 0, 139))
+ ("darkcyan", color(0, 139, 139))
+ ("darkgoldenrod", color(184, 134, 11))
+ ("darkgray", color(169, 169, 169))
+ ("darkgreen", color(0, 100, 0))
+ ("darkgrey", color(169, 169, 169))
+ ("darkkhaki", color(189, 183, 107))
+ ("darkmagenta", color(139, 0, 139))
+ ("darkolivegreen", color(85, 107, 47))
+ ("darkorange", color(255, 140, 0))
+ ("darkorchid", color(153, 50, 204))
+ ("darkred", color(139, 0, 0))
+ ("darksalmon", color(233, 150, 122))
+ ("darkseagreen", color(143, 188, 143))
+ ("darkslateblue", color(72, 61, 139))
+ ("darkslategrey", color(47, 79, 79))
+ ("darkturquoise", color(0, 206, 209))
+ ("darkviolet", color(148, 0, 211))
+ ("deeppink", color(255, 20, 147))
+ ("deepskyblue", color(0, 191, 255))
+ ("dimgray", color(105, 105, 105))
+ ("dimgrey", color(105, 105, 105))
+ ("dodgerblue", color(30, 144, 255))
+ ("firebrick", color(178, 34, 34))
+ ("floralwhite", color(255, 250, 240))
+ ("forestgreen", color(34, 139, 34))
+ ("fuchsia", color(255, 0, 255))
+ ("gainsboro", color(220, 220, 220))
+ ("ghostwhite", color(248, 248, 255))
+ ("gold", color(255, 215, 0))
+ ("goldenrod", color(218, 165, 32))
+ ("gray", color(128, 128, 128))
+ ("grey", color(128, 128, 128))
+ ("green", color(0, 128, 0))
+ ("greenyellow", color(173, 255, 47))
+ ("honeydew", color(240, 255, 240))
+ ("hotpink", color(255, 105, 180))
+ ("indianred", color(205, 92, 92))
+ ("indigo", color(75, 0, 130))
+ ("ivory", color(255, 255, 240))
+ ("khaki", color(240, 230, 140))
+ ("lavender", color(230, 230, 250))
+ ("lavenderblush", color(255, 240, 245))
+ ("lawngreen", color(124, 252, 0))
+ ("lemonchiffon", color(255, 250, 205))
+ ("lightblue", color(173, 216, 230))
+ ("lightcoral", color(240, 128, 128))
+ ("lightcyan", color(224, 255, 255))
+ ("lightgoldenrodyellow", color(250, 250, 210))
+ ("lightgray", color(211, 211, 211))
+ ("lightgreen", color(144, 238, 144))
+ ("lightgrey", color(211, 211, 211))
+ ("lightpink", color(255, 182, 193))
+ ("lightsalmon", color(255, 160, 122))
+ ("lightseagreen", color(32, 178, 170))
+ ("lightskyblue", color(135, 206, 250))
+ ("lightslategray", color(119, 136, 153))
+ ("lightslategrey", color(119, 136, 153))
+ ("lightsteelblue", color(176, 196, 222))
+ ("lightyellow", color(255, 255, 224))
+ ("lime", color(0, 255, 0))
+ ("limegreen", color(50, 205, 50))
+ ("linen", color(250, 240, 230))
+ ("magenta", color(255, 0, 255))
+ ("maroon", color(128, 0, 0))
+ ("mediumaquamarine", color(102, 205, 170))
+ ("mediumblue", color(0, 0, 205))
+ ("mediumorchid", color(186, 85, 211))
+ ("mediumpurple", color(147, 112, 219))
+ ("mediumseagreen", color(60, 179, 113))
+ ("mediumslateblue", color(123, 104, 238))
+ ("mediumspringgreen", color(0, 250, 154))
+ ("mediumturquoise", color(72, 209, 204))
+ ("mediumvioletred", color(199, 21, 133))
+ ("midnightblue", color(25, 25, 112))
+ ("mintcream", color(245, 255, 250))
+ ("mistyrose", color(255, 228, 225))
+ ("moccasin", color(255, 228, 181))
+ ("navajowhite", color(255, 222, 173))
+ ("navy", color(0, 0, 128))
+ ("oldlace", color(253, 245, 230))
+ ("olive", color(128, 128, 0))
+ ("olivedrab", color(107, 142, 35))
+ ("orange", color(255, 165, 0))
+ ("orangered", color(255, 69, 0))
+ ("orchid", color(218, 112, 214))
+ ("palegoldenrod", color(238, 232, 170))
+ ("palegreen", color(152, 251, 152))
+ ("paleturquoise", color(175, 238, 238))
+ ("palevioletred", color(219, 112, 147))
+ ("papayawhip", color(255, 239, 213))
+ ("peachpuff", color(255, 218, 185))
+ ("peru", color(205, 133, 63))
+ ("pink", color(255, 192, 203))
+ ("plum", color(221, 160, 221))
+ ("powderblue", color(176, 224, 230))
+ ("purple", color(128, 0, 128))
+ ("red", color(255, 0, 0))
+ ("rosybrown", color(188, 143, 143))
+ ("royalblue", color(65, 105, 225))
+ ("saddlebrown", color(139, 69, 19))
+ ("salmon", color(250, 128, 114))
+ ("sandybrown", color(244, 164, 96))
+ ("seagreen", color(46, 139, 87))
+ ("seashell", color(255, 245, 238))
+ ("sienna", color(160, 82, 45))
+ ("silver", color(192, 192, 192))
+ ("skyblue", color(135, 206, 235))
+ ("slateblue", color(106, 90, 205))
+ ("slategray", color(112, 128, 144))
+ ("slategrey", color(112, 128, 144))
+ ("snow", color(255, 250, 250))
+ ("springgreen", color(0, 255, 127))
+ ("steelblue", color(70, 130, 180))
+ ("tan", color(210, 180, 140))
+ ("teal", color(0, 128, 128))
+ ("thistle", color(216, 191, 216))
+ ("tomato", color(255, 99, 71))
+ ("turquoise", color(64, 224, 208))
+ ("violet", color(238, 130, 238))
+ ("wheat", color(245, 222, 179))
+ ("white", color(255, 255, 255))
+ ("whitesmoke", color(245, 245, 245))
+ ("yellow", color(255, 255, 0))
+ ("yellowgreen", color(154, 205, 50))
+ ("transparent", color(0, 0, 0, 0))
+ ;
+ }
+};
template <typename Iterator>
css_color_grammar<Iterator>::css_color_grammar()
@@ -42,6 +266,12 @@ css_color_grammar<Iterator>::css_color_grammar()
qi::lexeme_type lexeme;
ascii::no_case_type no_case;
using phoenix::at_c;
+ // symbols
+ named_colors named;
+ // functions
+ phoenix::function<percent_conv_impl> percent_converter;
+ phoenix::function<alpha_conv_impl> alpha_converter;
+ phoenix::function<hsl_conv_impl> hsl_converter;
css_color %= rgba_color
| rgba_percent_color
diff --git a/include/mapnik/csv/csv_grammar.hpp b/include/mapnik/csv/csv_grammar.hpp
index 6edecad..240f11c 100644
--- a/include/mapnik/csv/csv_grammar.hpp
+++ b/include/mapnik/csv/csv_grammar.hpp
@@ -20,20 +20,15 @@
*
*****************************************************************************/
-#ifndef MAPNIK_CVS_GRAMMAR_HPP
-#define MAPNIK_CVS_GRAMMAR_HPP
-
-//#define BOOST_SPIRIT_DEBUG
+#ifndef MAPNIK_CSV_GRAMMAR_HPP
+#define MAPNIK_CSV_GRAMMAR_HPP
+#include <mapnik/csv/csv_types.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
namespace mapnik {
namespace qi = boost::spirit::qi;
-using csv_value = std::string;
-using csv_line = std::vector<csv_value>;
-using csv_data = std::vector<csv_line>;
struct csv_white_space_skipper : qi::primitive_parser<csv_white_space_skipper>
{
@@ -70,36 +65,7 @@ struct csv_white_space_skipper : qi::primitive_parser<csv_white_space_skipper>
template <typename Iterator, typename Skipper = csv_white_space_skipper>
struct csv_line_grammar : qi::grammar<Iterator, csv_line(char, char), Skipper>
{
- csv_line_grammar()
- : csv_line_grammar::base_type(line)
- {
- qi::_r1_type _r1;
- qi::_r2_type _r2;
- qi::lit_type lit;
- qi::char_type char_;
- unesc_char.add
- ("\\a", '\a')
- ("\\b", '\b')
- ("\\f", '\f')
- ("\\n", '\n')
- ("\\r", '\r')
- ("\\t", '\t')
- ("\\v", '\v')
- ("\\\\",'\\')
- ("\\\'", '\'')
- ("\\\"", '\"')
- ("\"\"", '\"') // double quote
- ;
- line = -lit("\n\r") >> column(_r1, _r2) % lit(_r1)
- ;
- column = quoted(_r2) | *(char_ - lit(_r1))
- ;
- quoted = lit(_r1) > text(_r1) > lit(_r1) // support unmatched quotes or not (??)
- ;
- text = *(unesc_char | (char_ - lit(_r1)))
- ;
- BOOST_SPIRIT_DEBUG_NODES((line)(column)(quoted));
- }
+ csv_line_grammar();
private:
qi::rule<Iterator, csv_line(char, char), Skipper> line;
qi::rule<Iterator, csv_value(char, char)> column; // no-skip
@@ -110,4 +76,4 @@ private:
}
-#endif // MAPNIK_CVS_GRAMMAR_HPP
+#endif // MAPNIK_CSV_GRAMMAR_HPP
diff --git a/include/mapnik/path_expression_grammar_impl.hpp b/include/mapnik/csv/csv_grammar_impl.hpp
similarity index 50%
copy from include/mapnik/path_expression_grammar_impl.hpp
copy to include/mapnik/csv/csv_grammar_impl.hpp
index bc2fcfb..5608354 100644
--- a/include/mapnik/path_expression_grammar_impl.hpp
+++ b/include/mapnik/csv/csv_grammar_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
@@ -20,40 +20,42 @@
*
*****************************************************************************/
-// mapnik
-#include <mapnik/path_expression_grammar.hpp>
-#include <mapnik/attribute.hpp>
+#include <mapnik/csv/csv_grammar.hpp>
-// boost
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_object.hpp>
-#include <boost/spirit/include/phoenix_stl.hpp>
+namespace mapnik {
-namespace mapnik
-{
+namespace qi = boost::spirit::qi;
-template <typename Iterator>
-path_expression_grammar<Iterator>::path_expression_grammar()
- : path_expression_grammar::base_type(expr)
+template <typename Iterator, typename Skipper>
+csv_line_grammar<Iterator, Skipper>::csv_line_grammar()
+ : csv_line_grammar::base_type(line)
{
- standard_wide::char_type char_;
- qi::_1_type _1;
- qi::_val_type _val;
+ qi::_r1_type _r1;
+ qi::_r2_type _r2;
qi::lit_type lit;
- qi::lexeme_type lexeme;
- using phoenix::push_back;
- using boost::phoenix::construct;
-
- expr =
- * (
- str [ push_back(_val, _1)]
- |
- ( '[' >> attr [ push_back(_val, construct<mapnik::attribute>( _1 )) ] >> ']')
- )
+ qi::char_type char_;
+ unesc_char.add
+ ("\\a", '\a')
+ ("\\b", '\b')
+ ("\\f", '\f')
+ ("\\n", '\n')
+ ("\\r", '\r')
+ ("\\t", '\t')
+ ("\\v", '\v')
+ ("\\\\",'\\')
+ ("\\\'", '\'')
+ ("\\\"", '\"')
+ ("\"\"", '\"') // double quote
;
-
- attr %= +(char_ - ']');
- str %= lexeme[+(char_ -'[')];
+ line = -lit("\r") > -lit("\n") > column(_r1, _r2) % lit(_r1)
+ ;
+ column = quoted(_r2) | *(char_ - lit(_r1))
+ ;
+ quoted = lit(_r1) > text(_r1) > lit(_r1) // support unmatched quotes or not (??)
+ ;
+ text = *(unesc_char | (char_ - lit(_r1)))
+ ;
+ BOOST_SPIRIT_DEBUG_NODES((line)(column)(quoted));
}
-}
+} // namespace mapnik
diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/include/mapnik/csv/csv_types.hpp
similarity index 79%
copy from include/mapnik/grid/grid_rendering_buffer.hpp
copy to include/mapnik/csv/csv_types.hpp
index 4282e3b..5359c3d 100644
--- a/include/mapnik/grid/grid_rendering_buffer.hpp
+++ b/include/mapnik/csv/csv_types.hpp
@@ -20,16 +20,18 @@
*
*****************************************************************************/
-#ifndef MAPNIK_GRID_RENDERING_BUFFER_HPP
-#define MAPNIK_GRID_RENDERING_BUFFER_HPP
+#ifndef MAPNIK_CSV_TYPES_HPP
+#define MAPNIK_CSV_TYPES_HPP
-#include <mapnik/grid/grid.hpp>
-#include "agg_rendering_buffer.h"
+#include <string>
+#include <vector>
namespace mapnik {
-using grid_rendering_buffer = agg::row_ptr_cache<mapnik::grid::value_type>;
+using csv_value = std::string;
+using csv_line = std::vector<csv_value>;
+using csv_data = std::vector<csv_line>;
}
-#endif //MAPNIK_AGG_RASTERIZER_HPP
+#endif // MAPNIK_CSV_TYPES_HPP
diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp
index ea65425..ad35589 100644
--- a/include/mapnik/expression_grammar.hpp
+++ b/include/mapnik/expression_grammar.hpp
@@ -25,88 +25,18 @@
// mapnik
#include <mapnik/config.hpp>
-#include <mapnik/value_types.hpp>
-#include <mapnik/unicode.hpp>
#include <mapnik/expression_node.hpp>
-#include <mapnik/function_call.hpp>
-
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/support_locals.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/fusion/adapted/struct.hpp>
#pragma GCC diagnostic pop
-BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call,
- (mapnik::unary_function_impl, fun)
- (mapnik::unary_function_call::argument_type, arg))
-
-BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call,
- (mapnik::binary_function_impl, fun)
- (mapnik::binary_function_call::argument_type, arg1)
- (mapnik::binary_function_call::argument_type, arg2))
-
namespace mapnik
{
namespace qi = boost::spirit::qi;
namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type;
-struct unicode_impl
-{
- template <typename T>
- struct result
- {
- using type = mapnik::value_unicode_string;
- };
-
- explicit unicode_impl(mapnik::transcoder const& tr)
- : tr_(tr) {}
-
- mapnik::value_unicode_string operator()(std::string const& str) const
- {
- return tr_.transcode(str.c_str());
- }
-
- mapnik::transcoder const& tr_;
-};
-
-struct regex_match_impl
-{
- template <typename T>
- struct result
- {
- using type = expr_node;
- };
-
- explicit regex_match_impl(mapnik::transcoder const& tr)
- : tr_(tr) {}
-
- template <typename T0,typename T1>
- expr_node operator() (T0 & node, T1 const& pattern) const;
-
- mapnik::transcoder const& tr_;
-};
-
-struct regex_replace_impl
-{
-
- template <typename T>
- struct result
- {
- using type = expr_node;
- };
-
- explicit regex_replace_impl(mapnik::transcoder const& tr)
- : tr_(tr) {}
-
- template <typename T0,typename T1,typename T2>
- expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const;
-
- mapnik::transcoder const& tr_;
-};
-
template <typename T>
struct integer_parser
{
@@ -139,9 +69,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
typename integer_parser<mapnik::value_integer>::type int__;
mapnik::transcoder tr_;
- boost::phoenix::function<unicode_impl> unicode_;
- boost::phoenix::function<regex_match_impl> regex_match_;
- boost::phoenix::function<regex_replace_impl> regex_replace_;
+
rule_type expr;
rule_type equality_expr;
rule_type cond_expr;
@@ -159,6 +87,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
qi::rule<Iterator, std::string() , space_type> attr;
qi::rule<Iterator, std::string() , space_type> global_attr;
qi::rule<Iterator, std::string(), qi::locals<char> > quoted_ustring;
+ qi::rule<Iterator, std::string()> unquoted_ustring;
qi::rule<Iterator, std::string(), space_type> ustring;
qi::symbols<char const, char const> unesc_char;
diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp
index 8202fca..40be6b9 100644
--- a/include/mapnik/expression_grammar_impl.hpp
+++ b/include/mapnik/expression_grammar_impl.hpp
@@ -32,11 +32,21 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
-#include <boost/spirit/include/qi.hpp>
+#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
#pragma GCC diagnostic pop
+BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call,
+ (mapnik::unary_function_impl, fun)
+ (mapnik::unary_function_call::argument_type, arg))
+
+BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call,
+ (mapnik::binary_function_impl, fun)
+ (mapnik::binary_function_call::argument_type, arg1)
+ (mapnik::binary_function_call::argument_type, arg2))
+
// fwd declare
namespace mapnik {
struct attribute;
@@ -46,6 +56,44 @@ namespace mapnik {
namespace mapnik
{
+struct unicode_impl
+{
+ using result_type = mapnik::value_unicode_string;
+ explicit unicode_impl(mapnik::transcoder const& tr)
+ : tr_(tr) {}
+
+ mapnik::value_unicode_string operator()(std::string const& str) const
+ {
+ return tr_.transcode(str.c_str());
+ }
+
+ mapnik::transcoder const& tr_;
+};
+
+struct regex_match_impl
+{
+ using result_type = expr_node;
+ explicit regex_match_impl(mapnik::transcoder const& tr)
+ : tr_(tr) {}
+
+ template <typename T0,typename T1>
+ expr_node operator() (T0 & node, T1 const& pattern) const;
+
+ mapnik::transcoder const& tr_;
+};
+
+struct regex_replace_impl
+{
+ using result_type = expr_node;
+ explicit regex_replace_impl(mapnik::transcoder const& tr)
+ : tr_(tr) {}
+
+ template <typename T0,typename T1,typename T2>
+ expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const;
+
+ mapnik::transcoder const& tr_;
+};
+
unary_function_types::unary_function_types()
{
add
@@ -83,10 +131,7 @@ expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const
template <typename Iterator>
expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
: expression_grammar::base_type(expr),
- tr_(encoding),
- unicode_(unicode_impl(tr_)),
- regex_match_(regex_match_impl(tr_)),
- regex_replace_(regex_replace_impl(tr_))
+ tr_(encoding)
{
qi::_1_type _1;
qi::_a_type _a;
@@ -105,6 +150,10 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
using boost::phoenix::construct;
using boost::phoenix::if_else;
+ boost::phoenix::function<unicode_impl> unicode = unicode_impl(tr_);
+ boost::phoenix::function<regex_match_impl> regex_match = regex_match_impl(tr_);
+ boost::phoenix::function<regex_replace_impl> regex_replace = regex_replace_impl(tr_);
+
constant.add
("null", mapnik::value_null())
("false", mapnik::value_bool(false))
@@ -119,7 +168,7 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
;
expr = logical_expr [_val = _1]
- | ustring [_val = unicode_(_1)]
+ //| ustring [_val = unicode(_1)]
;
logical_expr = not_expr [_val = _1]
@@ -156,7 +205,7 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
>> quoted_ustring [_a = _1]
>> lit(',')
>> quoted_ustring [_b = _1]
- >> lit(')') [_val = regex_replace_(_r1,_a,_b)]
+ >> lit(')') [_val = regex_replace(_r1,_a,_b)]
;
relational_expr = additive_expr[_val = _1]
@@ -178,7 +227,7 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
>> *( '*' >> unary_expr [_val *= _1]
| '/' >> unary_expr [_val /= _1]
| '%' >> unary_expr [_val %= construct<mapnik::expr_node>(_1)] //needed by clang++ with -std=c++11
- | regex_match_expr[_val = regex_match_(_val, _1)]
+ | regex_match_expr[_val = regex_match(_val, _1)]
| regex_replace_expr(_val) [_val = _1]
)
;
@@ -198,7 +247,7 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
primary_expr = strict_double [_val = _1]
| int__[_val = _1]
| no_case[constant] [_val = _1]
- | quoted_ustring [_val = unicode_(_1)]
+ | quoted_ustring [_val = unicode(_1)]
| attr [if_else(_1 == "mapnik::geometry_type",
_val = construct<mapnik::geometry_type_attribute>(),
_val = construct<mapnik::attribute>(_1))]
@@ -206,6 +255,9 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
| unary_function_expr [_val = _1]
| binary_function_expr [_val = _1]
| '(' > logical_expr [_val = _1 ] > ')'
+ // TODO: this is a backward compatibility hack to allow unquoted strings
+ | unquoted_ustring [_val = unicode(_1)]
+ // ^ https://github.com/mapnik/mapnik/pull/3389
;
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
@@ -218,6 +270,7 @@ expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
quoted_ustring %= omit[quote_char[_a = _1]]
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
>> lit(_a);
+ unquoted_ustring %= no_skip[alpha >> *alnum] - lit("not");
attr %= '[' >> no_skip[+~char_(']')] >> ']';
global_attr %= '@' >> no_skip[alpha >> * (alnum | char_('-'))];
diff --git a/include/mapnik/expression_node.hpp b/include/mapnik/expression_node.hpp
index 7731414..6fdad8f 100644
--- a/include/mapnik/expression_node.hpp
+++ b/include/mapnik/expression_node.hpp
@@ -31,6 +31,8 @@
#include <mapnik/attribute.hpp>
#include <mapnik/function_call.hpp>
#include <mapnik/expression_node_types.hpp>
+// stl
+#include <memory>
namespace mapnik
{
diff --git a/include/mapnik/feature_kv_iterator.hpp b/include/mapnik/feature_kv_iterator.hpp
index 37093a8..77b292f 100644
--- a/include/mapnik/feature_kv_iterator.hpp
+++ b/include/mapnik/feature_kv_iterator.hpp
@@ -27,12 +27,14 @@
#include <mapnik/config.hpp>
#include <mapnik/value.hpp>
#include <mapnik/util/variant.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/filter_iterator.hpp>
+#pragma GCC diagnostic pop
// stl
#include <map>
diff --git a/include/mapnik/feature_type_style.hpp b/include/mapnik/feature_type_style.hpp
index 68240af..9f9f1ae 100644
--- a/include/mapnik/feature_type_style.hpp
+++ b/include/mapnik/feature_type_style.hpp
@@ -29,8 +29,10 @@
#include <mapnik/image_filter_types.hpp>
#include <mapnik/image_compositing.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <vector>
diff --git a/include/mapnik/global.hpp b/include/mapnik/global.hpp
index aa5be35..39a8c5f 100644
--- a/include/mapnik/global.hpp
+++ b/include/mapnik/global.hpp
@@ -99,14 +99,14 @@ inline void read_int32_xdr(const char* data, std::int32_t & val)
// read double XDR (big endian)
inline void read_double_xdr(const char* data, double & val)
{
- std::int64_t bits = ((std::int64_t)data[7] & 0xff) |
- ((std::int64_t)data[6] & 0xff) << 8 |
- ((std::int64_t)data[5] & 0xff) << 16 |
- ((std::int64_t)data[4] & 0xff) << 24 |
- ((std::int64_t)data[3] & 0xff) << 32 |
- ((std::int64_t)data[2] & 0xff) << 40 |
- ((std::int64_t)data[1] & 0xff) << 48 |
- ((std::int64_t)data[0] & 0xff) << 56 ;
+ std::int64_t bits = (static_cast<std::int64_t>(data[7]) & 0xff) |
+ (static_cast<std::int64_t>(data[6]) & 0xff) << 8 |
+ (static_cast<std::int64_t>(data[5]) & 0xff) << 16 |
+ (static_cast<std::int64_t>(data[4]) & 0xff) << 24 |
+ (static_cast<std::int64_t>(data[3]) & 0xff) << 32 |
+ (static_cast<std::int64_t>(data[2]) & 0xff) << 40 |
+ (static_cast<std::int64_t>(data[1]) & 0xff) << 48 |
+ (static_cast<std::int64_t>(data[0]) & 0xff) << 56 ;
std::memcpy(&val,&bits,8);
}
diff --git a/include/mapnik/gradient.hpp b/include/mapnik/gradient.hpp
index f151ebe..ae9acb5 100644
--- a/include/mapnik/gradient.hpp
+++ b/include/mapnik/gradient.hpp
@@ -23,8 +23,10 @@
#ifndef MAPNIK_GRADIENT_HPP
#define MAPNIK_GRADIENT_HPP
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include <agg_trans_affine.h>
+#pragma GCC diagnostic pop
// mapnik
#include <mapnik/color.hpp>
diff --git a/include/mapnik/grid/grid_rasterizer.hpp b/include/mapnik/grid/grid_rasterizer.hpp
index 98a6dd3..6129447 100644
--- a/include/mapnik/grid/grid_rasterizer.hpp
+++ b/include/mapnik/grid/grid_rasterizer.hpp
@@ -24,7 +24,11 @@
#define MAPNIK_GRID_RASTERIZER_HPP
#include <mapnik/util/noncopyable.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/grid/grid_render_marker.hpp b/include/mapnik/grid/grid_render_marker.hpp
index 8f345e3..5ad5fea 100644
--- a/include/mapnik/grid/grid_render_marker.hpp
+++ b/include/mapnik/grid/grid_render_marker.hpp
@@ -26,7 +26,8 @@
// mapnik
#include <mapnik/feature.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
#include "agg_image_filters.h"
@@ -34,7 +35,7 @@
#include "agg_span_allocator.h"
#include "agg_image_accessors.h"
#include "agg_span_image_filter_gray.h"
-
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/grid/grid_renderer_base.hpp b/include/mapnik/grid/grid_renderer_base.hpp
index 1000083..bcc2e18 100644
--- a/include/mapnik/grid/grid_renderer_base.hpp
+++ b/include/mapnik/grid/grid_renderer_base.hpp
@@ -24,11 +24,11 @@
#define MAPNIK_GRID_RENDERER_BASE_HPP
#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include "agg_renderer_base.h"
+#include <mapnik/warning_ignore_agg.hpp>
#include <mapnik/grid/grid_pixel.hpp>
-#pragma GCC diagnostic pop
#include <mapnik/grid/grid_pixfmt.hpp>
+#include "agg_renderer_base.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/include/mapnik/grid/grid_rendering_buffer.hpp
index 4282e3b..8ab12cf 100644
--- a/include/mapnik/grid/grid_rendering_buffer.hpp
+++ b/include/mapnik/grid/grid_rendering_buffer.hpp
@@ -24,7 +24,11 @@
#define MAPNIK_GRID_RENDERING_BUFFER_HPP
#include <mapnik/grid/grid.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp
index 4664624..5d8adc1 100644
--- a/include/mapnik/hextree.hpp
+++ b/include/mapnik/hextree.hpp
@@ -365,20 +365,20 @@ private:
if (r->count>0)
{
printf("%d: (+%d/%d/%.5f) (%d %d %d %d)\n",
- id, (int)r->count, (int)r->pixel_count, r->reduce_cost,
- (int)round(gamma(r->reds / r->count, gamma_)),
- (int)round(gamma(r->greens / r->count, gamma_)),
- (int)round(gamma(r->blues / r->count, gamma_)),
- (int)(r->alphas / r->count));
+ id, static_cast<int>(r->count), static_cast<int>(r->pixel_count), r->reduce_cost,
+ static_cast<int>(round(gamma(r->reds / r->count, gamma_))),
+ static_cast<int>(round(gamma(r->greens / r->count, gamma_))),
+ static_cast<int>(round(gamma(r->blues / r->count, gamma_))),
+ static_cast<int>((r->alphas / r->count)));
}
else
{
printf("%d: (%d/%d/%.5f) (%d %d %d %d)\n", id,
- (int)r->count, (int)r->pixel_count, r->reduce_cost,
- (int)round(gamma(r->reds / r->pixel_count, gamma_)),
- (int)round(gamma(r->greens / r->pixel_count, gamma_)),
- (int)round(gamma(r->blues / r->pixel_count, gamma_)),
- (int)(r->alphas / r->pixel_count));
+ static_cast<int>(r->count), static_cast<int>(r->pixel_count), r->reduce_cost,
+ static_cast<int>(round(gamma(r->reds / r->pixel_count, gamma_))),
+ static_cast<int>(round(gamma(r->greens / r->pixel_count, gamma_))),
+ static_cast<int>(round(gamma(r->blues / r->pixel_count, gamma_))),
+ static_cast<int>((r->alphas / r->pixel_count)));
}
for (unsigned idx=0; idx < 16; ++idx)
{
@@ -399,9 +399,9 @@ private:
std::uint8_t a = std::uint8_t(itr->alphas/float(count));
if (a > InsertPolicy::MAX_ALPHA) a = 255;
if (a < InsertPolicy::MIN_ALPHA) a = 0;
- palette.push_back(rgba((std::uint8_t)round(gamma(itr->reds / count, gamma_)),
- (std::uint8_t)round(gamma(itr->greens / count, gamma_)),
- (std::uint8_t)round(gamma(itr->blues / count, gamma_)), a));
+ palette.push_back(rgba(static_cast<std::uint8_t>(round(gamma(itr->reds / count, gamma_))),
+ static_cast<std::uint8_t>(round(gamma(itr->greens / count, gamma_))),
+ static_cast<std::uint8_t>(round(gamma(itr->blues / count, gamma_))), a));
}
for (unsigned idx=0; idx < 16; ++idx)
{
diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp
index 2967be7..82b89a3 100644
--- a/include/mapnik/image_compositing.hpp
+++ b/include/mapnik/image_compositing.hpp
@@ -26,8 +26,10 @@
#include <mapnik/config.hpp>
#include <mapnik/image.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp
index 9b0b754..a96d4cd 100644
--- a/include/mapnik/image_filter.hpp
+++ b/include/mapnik/image_filter.hpp
@@ -34,7 +34,8 @@
#include <boost/gil/gil_all.hpp>
#pragma GCC diagnostic pop
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_color_rgba.h"
@@ -42,6 +43,8 @@
#include "agg_scanline_u.h"
#include "agg_blur.h"
#include "agg_gradient_lut.h"
+#pragma GCC diagnostic pop
+
// stl
#include <cmath>
diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp
index 7ab2d12..ca96116 100644
--- a/include/mapnik/image_filter_grammar.hpp
+++ b/include/mapnik/image_filter_grammar.hpp
@@ -47,12 +47,7 @@ namespace qi = boost::spirit::qi;
struct percent_offset_impl
{
- template <typename T>
- struct result
- {
- using type = double;
- };
-
+ using result_type = double;
double operator() (double val) const
{
double result = std::abs(val/100.0);
@@ -79,11 +74,9 @@ struct image_filter_grammar :
css_color_grammar<Iterator> css_color_;
qi::rule<Iterator, filter::color_stop(), qi::ascii::space_type> color_stop_;
qi::rule<Iterator, double(), qi::ascii::space_type> color_stop_offset;
- phoenix::function<percent_offset_impl> percent_offset;
private:
alternative_type & add(std::string const& symbol);
-
static constexpr unsigned max_alternatives = 16;
unsigned num_alternatives = 0;
alternative_type alternative_storage[max_alternatives];
diff --git a/include/mapnik/image_filter_grammar_impl.hpp b/include/mapnik/image_filter_grammar_impl.hpp
index 98de711..bf17700 100644
--- a/include/mapnik/image_filter_grammar_impl.hpp
+++ b/include/mapnik/image_filter_grammar_impl.hpp
@@ -64,6 +64,9 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
using phoenix::push_back;
using phoenix::construct;
+ // functions
+ phoenix::function<percent_offset_impl> percent_offset;
+
start = -(filter % *lit(','))
;
diff --git a/include/mapnik/image_options.hpp b/include/mapnik/image_options.hpp
index fc8f9f1..d44b2bf 100644
--- a/include/mapnik/image_options.hpp
+++ b/include/mapnik/image_options.hpp
@@ -25,7 +25,12 @@
#include <map>
#include <string>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
+
namespace mapnik {
diff --git a/include/mapnik/image_reader.hpp b/include/mapnik/image_reader.hpp
index a15d7c9..6c1c232 100644
--- a/include/mapnik/image_reader.hpp
+++ b/include/mapnik/image_reader.hpp
@@ -29,8 +29,12 @@
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/factory.hpp>
#include <mapnik/box2d.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
+
// stl
#include <stdexcept>
#include <string>
diff --git a/include/mapnik/image_scaling.hpp b/include/mapnik/image_scaling.hpp
index ddae368..461e99f 100644
--- a/include/mapnik/image_scaling.hpp
+++ b/include/mapnik/image_scaling.hpp
@@ -30,8 +30,11 @@
// stl
#include <iosfwd>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
+
namespace mapnik
{
diff --git a/include/mapnik/image_scaling_traits.hpp b/include/mapnik/image_scaling_traits.hpp
index 81ddf54..b8daff1 100644
--- a/include/mapnik/image_scaling_traits.hpp
+++ b/include/mapnik/image_scaling_traits.hpp
@@ -28,7 +28,8 @@
#include <mapnik/image_scaling.hpp>
#include <mapnik/span_image_filter.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_image_accessors.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
@@ -36,6 +37,7 @@
#include "agg_span_image_filter_gray.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_interpolator_linear.h"
+#pragma GCC diagnostic pop
namespace mapnik { namespace detail {
diff --git a/include/mapnik/json/error_handler.hpp b/include/mapnik/json/error_handler.hpp
index 46a92c8..1e66427 100644
--- a/include/mapnik/json/error_handler.hpp
+++ b/include/mapnik/json/error_handler.hpp
@@ -24,13 +24,18 @@
#define MAPNIK_JSON_ERROR_HANDLER_HPP
#include <mapnik/config.hpp>
+
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
-#include <boost/spirit/home/qi.hpp>
-#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/qi/nonterminal/error_handler.hpp>
+namespace boost { namespace spirit { struct info; } }
#pragma GCC diagnostic pop
+
// mapnik
+#ifdef MAPNIK_LOG
#include <mapnik/debug.hpp>
+#endif
+
// stl
#include <cassert>
#include <string>
diff --git a/include/mapnik/json/extract_bounding_box_grammar.hpp b/include/mapnik/json/extract_bounding_box_grammar.hpp
index 7d0b7a1..906e712 100644
--- a/include/mapnik/json/extract_bounding_box_grammar.hpp
+++ b/include/mapnik/json/extract_bounding_box_grammar.hpp
@@ -32,73 +32,31 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/fusion/adapted/std_tuple.hpp>
#pragma GCC diagnostic pop
-// stl
-#include <tuple>
-
namespace mapnik { namespace json {
-using position_type = mapnik::geometry::point<double>;
-using boxes_type = std::vector<std::pair<box2d<double>, std::pair<std::size_t, std::size_t>>>;
-
namespace qi = boost::spirit::qi;
-struct calculate_bounding_box_impl
-{
- using result_type = void;
- template <typename T0, typename T1>
- result_type operator() (T0 & bbox, T1 const& pos) const
- {
- if (pos)
- {
- double x = pos->x;
- double y = pos->y;
- if (!bbox.valid())
- {
- bbox.init(x, y, x, y); //TODO: add init(x,y) convinience method
- }
- else
- {
- bbox.expand_to_include(x, y);
- }
- }
- }
-};
-
-struct push_box_impl
-{
- using result_type = void;
- template <typename T0, typename T1, typename T2, typename T3>
- void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
- {
- if (box.valid()) boxes.emplace_back(box, std::make_pair(std::distance(begin, range.begin()), std::distance(range.begin(), range.end())));
- }
-};
-
-template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
+template <typename Iterator, typename Boxes, typename ErrorHandler = error_handler<Iterator> >
struct extract_bounding_box_grammar :
- qi::grammar<Iterator, void(boxes_type&), space_type>
+ qi::grammar<Iterator, void(Boxes&), space_type>
{
+ using position_type = mapnik::geometry::point<double>;
+ using boxes_type = Boxes;
+ using box_type = typename Boxes::value_type::first_type;
extract_bounding_box_grammar();
// rules
qi::rule<Iterator, void(boxes_type&), space_type> start;
qi::rule<Iterator, qi::locals<Iterator>, void(boxes_type&), space_type> features;
- qi::rule<Iterator, qi::locals<int, box2d<double>>, void(boxes_type&, Iterator const&), space_type> feature;
- qi::rule<Iterator, qi::locals<box2d<double>>, box2d<double>(), space_type> coords;
+ qi::rule<Iterator, qi::locals<int, box_type>, void(boxes_type&, Iterator const&), space_type> feature;
+ qi::rule<Iterator, qi::locals<box_type>, box_type(), space_type> coords;
qi::rule<Iterator, boost::optional<position_type>(), space_type> pos;
- qi::rule<Iterator, void(box2d<double>&), space_type> ring;
- qi::rule<Iterator, void(box2d<double>&), space_type> rings;
- qi::rule<Iterator, void(box2d<double>&), space_type> rings_array;
+ qi::rule<Iterator, void(box_type&), space_type> ring;
+ qi::rule<Iterator, void(box_type&), space_type> rings;
+ qi::rule<Iterator, void(box_type&), space_type> rings_array;
// generic JSON support
json::generic_json<Iterator> json;
- // phoenix functions
- boost::phoenix::function<push_box_impl> push_box;
- boost::phoenix::function<calculate_bounding_box_impl> calculate_bounding_box;
- // error handler
- boost::phoenix::function<ErrorHandler> const error_handler;
};
}}
diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
index a6d3218..8a7fc33 100644
--- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
+++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
@@ -22,24 +22,60 @@
// mapnik
#include <mapnik/json/extract_bounding_box_grammar.hpp>
-
+#include <mapnik/geometry_fusion_adapted.hpp>
// boost
#include <boost/spirit/include/qi_omit.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
// stl
#include <iostream>
#include <string>
namespace mapnik { namespace json {
+struct calculate_bounding_box_impl
+{
+ using result_type = void;
+ template <typename T0, typename T1>
+ result_type operator() (T0 & bbox, T1 const& pos) const
+ {
+ if (pos)
+ {
+ typename T0::value_type x = pos->x;
+ typename T0::value_type y = pos->y;
+ if (!bbox.valid())
+ {
+ bbox.init(x, y);
+ }
+ else
+ {
+ bbox.expand_to_include(x, y);
+ }
+ }
+ }
+};
+
+struct push_box_impl
+{
+ using result_type = void;
+ template <typename T0, typename T1, typename T2, typename T3>
+ void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
+ {
+ if (box.valid()) boxes.emplace_back(box,
+ std::make_pair(std::distance(begin,
+ range.begin()),
+ std::distance(range.begin(), range.end())));
+ }
+};
+
namespace repo = boost::spirit::repository;
-template <typename Iterator, typename ErrorHandler>
-extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_grammar()
- : extract_bounding_box_grammar::base_type(start,"bounding boxes")
+template <typename Iterator, typename Boxes, typename ErrorHandler>
+extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_box_grammar()
+ : extract_bounding_box_grammar::base_type(start, "GeoJSON bounding boxes")
{
qi::lit_type lit;
qi::double_type double_;
@@ -61,6 +97,12 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
using qi::fail;
using qi::on_error;
+ // phoenix functions
+ boost::phoenix::function<push_box_impl> push_box;
+ boost::phoenix::function<calculate_bounding_box_impl> calculate_bounding_box;
+ // error handler
+ boost::phoenix::function<ErrorHandler> const error_handler;
+
start = features(_r1)
;
diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp
index a4bdfa1..ae59e3b 100644
--- a/include/mapnik/json/feature_grammar.hpp
+++ b/include/mapnik/json/feature_grammar.hpp
@@ -89,13 +89,10 @@ struct set_geometry_impl
}
};
-template <typename Iterator, typename FeatureType, typename ErrorHandler = error_handler<Iterator> >
-struct feature_grammar :
- qi::grammar<Iterator, void(FeatureType&),
- space_type>
+template <typename Iterator, typename FeatureType, typename ErrorHandler = error_handler<Iterator>>
+struct feature_grammar : qi::grammar<Iterator, void(FeatureType&), space_type>
{
- feature_grammar(mapnik::transcoder const& tr);
-
+ explicit feature_grammar(mapnik::transcoder const& tr);
// generic JSON
generic_json<Iterator> json_;
// geoJSON
diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp
index eb484b6..0e31465 100644
--- a/include/mapnik/json/geometry_generator_grammar.hpp
+++ b/include/mapnik/json/geometry_generator_grammar.hpp
@@ -27,12 +27,12 @@
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_type.hpp>
-#include <mapnik/geometry_fusion_adapted.hpp>
// boost
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunc
#include <boost/spirit/home/karma/domain.hpp>
#pragma GCC diagnostic pop
diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp
index 62d6a85..87a60db 100644
--- a/include/mapnik/json/geometry_generator_grammar_impl.hpp
+++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp
@@ -24,6 +24,7 @@
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/util/spirit_transform_attribute.hpp>
#include <mapnik/geometry_types.hpp>
+#include <mapnik/geometry_fusion_adapted.hpp>
// boost
#pragma GCC diagnostic push
diff --git a/include/mapnik/json/geometry_grammar.hpp b/include/mapnik/json/geometry_grammar.hpp
index 800a48b..4b0d119 100644
--- a/include/mapnik/json/geometry_grammar.hpp
+++ b/include/mapnik/json/geometry_grammar.hpp
@@ -30,9 +30,11 @@
#include <mapnik/json/positions_grammar.hpp>
#include <mapnik/json/geometry_util.hpp>
-// spirit::qi
+#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
namespace mapnik { namespace json {
diff --git a/include/mapnik/json/geometry_grammar_impl.hpp b/include/mapnik/json/geometry_grammar_impl.hpp
index 90f09bf..3c5693f 100644
--- a/include/mapnik/json/geometry_grammar_impl.hpp
+++ b/include/mapnik/json/geometry_grammar_impl.hpp
@@ -24,12 +24,10 @@
#include <mapnik/config.hpp>
#include <mapnik/json/error_handler.hpp>
#include <mapnik/json/geometry_grammar.hpp>
-#include <mapnik/json/positions_grammar_impl.hpp>
-
+#include <mapnik/geometry_fusion_adapted.hpp>
// boost
-#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>
namespace mapnik { namespace json {
diff --git a/include/mapnik/json/geometry_parser.hpp b/include/mapnik/json/geometry_parser.hpp
index c83901d..761c193 100644
--- a/include/mapnik/json/geometry_parser.hpp
+++ b/include/mapnik/json/geometry_parser.hpp
@@ -24,25 +24,13 @@
#define MAPNIK_JSON_GEOMETRY_PARSER_HPP
// mapnik
+#include <mapnik/geometry.hpp>
-
-#include <mapnik/json/geometry_grammar.hpp>
-
-// boost
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
+#include <string>
namespace mapnik { namespace json {
-inline bool from_geojson(std::string const& json, mapnik::geometry::geometry<double> & geom)
-{
- using namespace boost::spirit;
- static const geometry_grammar<char const*> g;
- standard::space_type space;
- char const* start = json.c_str();
- char const* end = start + json.length();
- return qi::phrase_parse(start, end, g, space, geom);
-}
+bool from_geojson(std::string const& json, mapnik::geometry::geometry<double> & geom);
}}
diff --git a/include/mapnik/json/geometry_util.hpp b/include/mapnik/json/geometry_util.hpp
index 6e8fb67..cf538ae 100644
--- a/include/mapnik/json/geometry_util.hpp
+++ b/include/mapnik/json/geometry_util.hpp
@@ -25,6 +25,7 @@
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_correct.hpp>
+#include <mapnik/json/positions.hpp>
namespace mapnik { namespace json {
diff --git a/include/mapnik/agg_rasterizer.hpp b/include/mapnik/json/positions.hpp
similarity index 69%
copy from include/mapnik/agg_rasterizer.hpp
copy to include/mapnik/json/positions.hpp
index 51cf4cd..9ad10f9 100644
--- a/include/mapnik/agg_rasterizer.hpp
+++ b/include/mapnik/json/positions.hpp
@@ -20,19 +20,21 @@
*
*****************************************************************************/
-#ifndef MAPNIK_AGG_RASTERIZER_HPP
-#define MAPNIK_AGG_RASTERIZER_HPP
+#ifndef MAPNIK_JSON_POSITIONS_HPP
+#define MAPNIK_JSON_POSITIONS_HPP
// mapnik
-#include <mapnik/util/noncopyable.hpp>
+#include <mapnik/util/variant.hpp>
+#include <mapnik/geometry.hpp>
-// agg
-#include "agg_rasterizer_scanline_aa.h"
+namespace mapnik { namespace json {
-namespace mapnik {
+struct empty {};
-struct rasterizer : agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_int_sat>, util::noncopyable {};
+using position = mapnik::geometry::point<double>;
+using positions = std::vector<position>;
+using coordinates = util::variant<empty, position, positions, std::vector<positions>, std::vector<std::vector<positions> > > ;
-}
+}}
-#endif // MAPNIK_AGG_RASTERIZER_HPP
+#endif // MAPNIK_JSON_POSITIONS_HPP
diff --git a/include/mapnik/json/positions_grammar.hpp b/include/mapnik/json/positions_grammar.hpp
index 1535422..bc81046 100644
--- a/include/mapnik/json/positions_grammar.hpp
+++ b/include/mapnik/json/positions_grammar.hpp
@@ -25,29 +25,19 @@
// mapnik
#include <mapnik/util/variant.hpp>
+#include <mapnik/json/positions.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/error_handler.hpp>
#include <mapnik/geometry.hpp>
-#include <mapnik/geometry_fusion_adapted.hpp>
-
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/fusion/adapted/std_tuple.hpp>
#pragma GCC diagnostic pop
-// stl
-#include <tuple>
namespace mapnik { namespace json {
-struct empty {};
-
-using position = mapnik::geometry::point<double>;
-using positions = std::vector<position>;
-using coordinates = util::variant<empty, position, positions, std::vector<positions>, std::vector<std::vector<positions> > > ;
-
namespace qi = boost::spirit::qi;
struct set_position_impl
diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp
index 1347675..90df172 100644
--- a/include/mapnik/json/positions_grammar_impl.hpp
+++ b/include/mapnik/json/positions_grammar_impl.hpp
@@ -22,7 +22,7 @@
// mapnik
#include <mapnik/json/positions_grammar.hpp>
-
+#include <mapnik/geometry_fusion_adapted.hpp>
// boost
#include <boost/spirit/include/qi_omit.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
diff --git a/include/mapnik/json/properties_generator_grammar.hpp b/include/mapnik/json/properties_generator_grammar.hpp
index e0f7be6..69145b8 100644
--- a/include/mapnik/json/properties_generator_grammar.hpp
+++ b/include/mapnik/json/properties_generator_grammar.hpp
@@ -25,23 +25,20 @@
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
-#include <mapnik/feature_kv_iterator.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/karma.hpp>
-#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_fusion.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-#include <boost/fusion/adapted/std_tuple.hpp>
-#include <boost/fusion/include/at.hpp>
-#include <boost/fusion/include/cons.hpp>
#pragma GCC diagnostic pop
+#include <string>
+#include <tuple>
+
namespace mapnik { namespace json {
+namespace karma = boost::spirit::karma;
+
template <typename OutputIterator>
struct escaped_string
: karma::grammar<OutputIterator, std::string(char const*)>
diff --git a/include/mapnik/json/symbolizer_grammar.hpp b/include/mapnik/json/symbolizer_grammar.hpp
deleted file mode 100644
index 494b81f..0000000
--- a/include/mapnik/json/symbolizer_grammar.hpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 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_SYMBOLIZER_GRAMMAR_HPP
-#define MAPNIK_SYMBOLIZER_GRAMMAR_HPP
-
-#include <mapnik/config.hpp>
-
-// boost
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-
-// mapnik
-#include <mapnik/util/variant.hpp>
-#include <mapnik/symbolizer.hpp>
-#include <mapnik/symbolizer_utils.hpp>
-#include <mapnik/json/error_handler.hpp>
-#include <mapnik/json/generic_json.hpp>
-
-namespace mapnik { namespace json {
-
-namespace qi = boost::spirit::qi;
-namespace phoenix = boost::phoenix;
-namespace fusion = boost::fusion;
-namespace standard_wide = boost::spirit::standard_wide;
-using standard_wide::space_type;
-
-template <typename Symbolizer>
-struct json_value_visitor
-{
- json_value_visitor(Symbolizer & sym, mapnik::keys key)
- : sym_(sym), key_(key) {}
-
- void operator() (value_bool val) const
- {
- put<value_bool>(sym_, key_, val);
- }
-
- void operator() (value_integer val) const
- {
- put<value_integer>(sym_, key_, val);
- }
-
- void operator() (value_double val) const
- {
- put<value_double>(sym_, key_, val);
- }
-
- void operator() (std::string const& val) const
- {
- set_property(sym_, key_, val);
- }
-
- template <typename T>
- void operator() (T const& val) const
- {
- std::cerr << std::get<0>(get_meta(key_)) << ":" << val << std::endl;
- //put<T>(sym_, key_, val);
- }
-
- Symbolizer & sym_;
- keys key_;
-};
-
-template <typename T>
-struct put_property_visitor
-{
- using value_type = T;
-
- put_property_visitor(mapnik::keys key, value_type const& val)
- : key_(key), val_(val) {}
-
- template <typename Symbolizer>
- void operator() (Symbolizer & sym) const
- {
- mapnik::util::apply_visitor(json_value_visitor<Symbolizer>(sym, key_), val_);
- }
-
- keys key_;
- value_type const& val_;
-};
-
-struct put_property
-{
- using result_type = void;
- template <typename T0,typename T1, typename T2>
- result_type operator() (T0 & sym, T1 const& name, T2 const& val) const
- {
- try
- {
- mapnik::util::apply_visitor(put_property_visitor<T2>(get_key(name),val), sym);
- }
- catch (std::runtime_error const& err)
- {
- std::cerr << err.what() << std::endl;
- }
- }
-};
-
-template <typename Iterator, typename ErrorHandler = error_handler<Iterator>>
-struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
-{
- using json_value_type = util::variant<value_null,value_bool,value_integer,value_double, std::string>;
- symbolizer_grammar()
- : symbolizer_grammar::base_type(sym, "symbolizer"),
- json_()
- {
- qi::lit_type lit;
- qi::double_type double_;
- qi::int_type int_;
- qi::no_skip_type no_skip;
- qi::_val_type _val;
- qi::_a_type _a;
- qi::_r1_type _r1;
- qi::_1_type _1;
- standard_wide::char_type char_;
- using phoenix::construct;
-
- // 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_.object = lit('{')
- >> *json_.pairs
- >> lit('}')
- ;
-
- json_.array = lit('[')
- >> json_.value >> *(lit(',') >> json_.value)
- >> lit(']')
- ;
-
- json_.number %= json_.strict_double
- | json_.int__
- | lit("true") [_val = true]
- | lit ("false") [_val = false]
- | lit("null")[_val = construct<value_null>()]
- ;
- json_.unesc_char.add
- ("\\\"", '\"') // quotation mark
- ("\\\\", '\\') // reverse solidus
- ("\\/", '/') // solidus
- ("\\b", '\b') // backspace
- ("\\f", '\f') // formfeed
- ("\\n", '\n') // newline
- ("\\r", '\r') // carrige return
- ("\\t", '\t') // tab
- ;
-
- json_.string_ %= lit('"') >> no_skip[*(json_.unesc_char | "\\u" >> json_.hex4 | (char_ - lit('"')))] >> lit('"')
- ;
-
- sym = lit('{')
- >> lit("\"type\"") >> lit(':')
- >> (lit("\"PointSymbolizer\"")[_val = construct<point_symbolizer>()]
- |
- lit("\"LineSymbolizer\"")[_val = construct<line_symbolizer>()]
- |
- lit("\"PolygonSymbolizer\"")[_val = construct<polygon_symbolizer>()]
- )
- >> lit(',')
- >> lit("\"properties\"") >> lit(':')
- >> ((lit('{') >> *property(_val) >> lit('}')) | lit("null"))
- >> lit('}')
- ;
-
- property = (json_.string_ [_a = _1] >> lit(':') >> property_value [put_property_(_r1,_a,_1)]) % lit(',')
- ;
-
- property_value %= json_.number | json_.string_ ;
-
-
- }
-
- // generic JSON
- generic_json<Iterator> json_;
- // symbolizer
- qi::rule<Iterator, space_type, mapnik::symbolizer()> sym;
- qi::rule<Iterator,qi::locals<std::string>, void(mapnik::symbolizer&),space_type> property;
- qi::rule<Iterator, space_type, json_value_type()> property_value;
-
- phoenix::function<put_property> put_property_;
- // error
- //qi::on_error<qi::fail>(sym, error_handler(_1, _2, _3, _4));
-};
-
-
-}}
-
-#endif // MAPNIK_SYMBOLIZER_GRAMMAR_HPP
diff --git a/include/mapnik/json/topojson_grammar.hpp b/include/mapnik/json/topojson_grammar.hpp
index be64b91..eec2bb4 100644
--- a/include/mapnik/json/topojson_grammar.hpp
+++ b/include/mapnik/json/topojson_grammar.hpp
@@ -25,14 +25,12 @@
// mapnik
#include <mapnik/json/error_handler.hpp>
-#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/topology.hpp>
#include <mapnik/json/value_converters.hpp>
#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
// stl
@@ -51,7 +49,7 @@ struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
topojson_grammar();
private:
// generic JSON support
- json::generic_json<Iterator> json_;
+ json::generic_json<Iterator> json;
// topoJSON
qi::rule<Iterator, space_type, mapnik::topojson::topology()> topology;
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::geometry>()> objects;
@@ -68,17 +66,13 @@ private:
qi::rule<Iterator, space_type, mapnik::topojson::polygon()> polygon;
qi::rule<Iterator, space_type, mapnik::topojson::multi_polygon()> multi_polygon;
qi::rule<Iterator, space_type, void(std::vector<mapnik::topojson::geometry>&)> geometry_collection;
-
qi::rule<Iterator, space_type, std::vector<index_type>()> ring;
-
// 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;
- // error handler
- boost::phoenix::function<ErrorHandler> const error_handler;
};
}}
diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp
index 90e3f1a..ca86079 100644
--- a/include/mapnik/json/topojson_grammar_impl.hpp
+++ b/include/mapnik/json/topojson_grammar_impl.hpp
@@ -21,6 +21,85 @@
*****************************************************************************/
#include <mapnik/json/topojson_grammar.hpp>
+#include <mapnik/json/generic_json.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/adapted/std_tuple.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#pragma GCC diagnostic pop
+
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::topojson::coordinate,
+ (double, x)
+ (double, y)
+ )
+
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::topojson::arc,
+ (std::list<mapnik::topojson::coordinate>, coordinates)
+ )
+
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::topojson::transform,
+ (double, scale_x)
+ (double, scale_y)
+ (double, translate_x)
+ (double, translate_y)
+ )
+
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::topojson::bounding_box,
+ (double, minx)
+ (double, miny)
+ (double, maxx)
+ (double, maxy)
+ )
+
+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)
+ (boost::optional<mapnik::topojson::transform>, tr)
+ (boost::optional<mapnik::topojson::bounding_box>, bbox)
+ )
namespace mapnik { namespace topojson {
@@ -46,26 +125,30 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
using qi::on_error;
using phoenix::push_back;
using phoenix::construct;
- // generic json types
- json_.value = json_.object | json_.array | json_.string_ | json_.number
+
+ // error handler
+ boost::phoenix::function<ErrorHandler> const error_handler;
+
+ // generic JSON types
+ json.value = json.object | json.array | json.string_ | json.number
;
- json_.pairs = json_.key_value % lit(',')
+ 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.pairs >> lit('}')
;
- json_.array = lit('[')
- >> json_.value >> *(lit(',') >> json_.value)
+ json.array = lit('[')
+ >> json.value >> *(lit(',') >> json.value)
>> lit(']')
;
- json_.number = json_.strict_double[_val = json_.double_converter(_1)]
- | json_.int__[_val = json_.integer_converter(_1)]
+ json.number = json.strict_double[_val = json.double_converter(_1)]
+ | json.int__[_val = json.integer_converter(_1)]
| lit("true")[_val = true]
| lit("false")[_val = false]
| lit("null")[_val = construct<value_null>()]
@@ -96,7 +179,7 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
objects = lit("\"objects\"")
>> lit(':')
>> lit('{')
- >> -((omit[json_.string_]
+ >> -((omit[json.string_]
>> lit(':')
>> (geometry_collection(_val) | geometry)) % lit(','))
>> lit('}')
@@ -109,7 +192,7 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
multi_point |
multi_linestring |
multi_polygon |
- omit[json_.object]
+ omit[json.object]
;
geometry_collection = lit('{')
@@ -171,7 +254,7 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
>> lit('}')
;
- id = lit("\"id\"") >> lit(':') >> omit[json_.value]
+ id = lit("\"id\"") >> lit(':') >> omit[json.value]
;
ring = lit('[') >> -(int_ % lit(',')) >> lit(']')
@@ -179,13 +262,13 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
properties = lit("\"properties\"")
>> lit(':')
- >> (( lit('{') >> attributes >> lit('}')) | json_.object)
+ >> (( lit('{') >> attributes >> lit('}')) | json.object)
;
- attributes = (json_.string_ >> lit(':') >> attribute_value) % lit(',')
+ attributes = (json.string_ >> lit(':') >> attribute_value) % lit(',')
;
- attribute_value %= json_.number | json_.string_ ;
+ attribute_value %= json.number | json.string_ ;
arcs = lit("\"arcs\"") >> lit(':')
>> lit('[') >> -( arc % lit(',')) >> lit(']') ;
@@ -199,7 +282,7 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
objects.name("objects");
arc.name("arc");
arcs.name("arcs");
- json_.value.name("value");
+ json.value.name("value");
coordinate.name("coordinate");
point.name("point");
diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp
index be6a83a..c4de306 100644
--- a/include/mapnik/json/topojson_utils.hpp
+++ b/include/mapnik/json/topojson_utils.hpp
@@ -25,7 +25,11 @@
// mapnik
#include <mapnik/box2d.hpp>
+#include <mapnik/unicode.hpp>
#include <mapnik/json/topology.hpp>
+#include <mapnik/feature_factory.hpp>
+#include <mapnik/geometry_adapters.hpp>
+#include <mapnik/geometry_correct.hpp>
namespace mapnik { namespace topojson {
@@ -50,27 +54,25 @@ struct bounding_box_visitor
box2d<double> operator() (mapnik::topojson::multi_point const& multi_pt) const
{
box2d<double> bbox;
- if (num_arcs_ > 0)
+ bool first = true;
+ double px = 0, py = 0;
+ for (auto const& pt : multi_pt.points)
{
- bool first = true;
- for (auto const& pt : multi_pt.points)
+ double x = pt.x;
+ double y = pt.y;
+ if (topo_.tr)
{
- double x = pt.x;
- double y = pt.y;
- if (topo_.tr)
- {
- x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y; // TODO : delta encoded ?
- }
- if (first)
- {
- first = false;
- bbox.init(x,y,x,y);
- }
- else
- {
- bbox.expand_to_include(x,y);
- }
+ 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;
@@ -243,6 +245,334 @@ private:
std::size_t num_arcs_;
};
+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)
+{
+ if ( geom.props)
+ {
+ 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)));
+ }
+ }
+}
+
+}
+
+template <typename Context>
+struct feature_generator
+{
+ feature_generator(Context & ctx, mapnik::transcoder const& tr, topology const& topo, std::size_t feature_id)
+ : ctx_(ctx),
+ tr_(tr),
+ topo_(topo),
+ num_arcs_(topo.arcs.size()),
+ feature_id_(feature_id) {}
+
+ feature_ptr operator() (point const& pt) const
+ {
+ mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
+ double x = pt.coord.x;
+ double y = pt.coord.y;
+ if (topo_.tr)
+ {
+ x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
+ y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ }
+ mapnik::geometry::point<double> point(x, y);
+ feature->set_geometry(std::move(point));
+ assign_properties(*feature, pt, tr_);
+ return feature;
+ }
+
+ feature_ptr operator() (multi_point const& multi_pt) const
+ {
+ mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
+ mapnik::geometry::multi_point<double> multi_point;
+ multi_point.reserve(multi_pt.points.size());
+ for (auto const& pt : multi_pt.points)
+ {
+ double x = pt.x;
+ double y = pt.y;
+ if (topo_.tr)
+ {
+ x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
+ y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
+ }
+ multi_point.add_coord(x, y);
+ }
+ feature->set_geometry(std::move(multi_point));
+ assign_properties(*feature, multi_pt, tr_);
+ return feature;
+ }
+
+ feature_ptr operator() (linestring const& line) const
+ {
+ 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());
+
+ 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;
+ }
+ line_string.add_coord(x,y);
+ }
+ feature->set_geometry(std::move(line_string));
+ assign_properties(*feature, line, tr_);
+ }
+ }
+ return feature;
+ }
+
+ feature_ptr operator() (multi_linestring const& multi_line) const
+ {
+ mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
+ if (num_arcs_ > 0)
+ {
+ 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)
+ {
+ index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
+ {
+ 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)
+ {
+ 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);
+ }
+ multi_line_string.push_back(std::move(line_string));
+ }
+ }
+ if (hit)
+ {
+ feature->set_geometry(std::move(multi_line_string));
+ assign_properties(*feature, multi_line, tr_);
+ }
+ }
+ return feature;
+ }
+
+ feature_ptr operator() (polygon const& poly) const
+ {
+ mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
+ if (num_arcs_ > 0)
+ {
+ std::vector<mapnik::topojson::coordinate> processed_coords;
+ mapnik::geometry::polygon<double> polygon;
+ if (poly.rings.size() > 1) polygon.interior_rings.reserve(poly.rings.size() - 1);
+ bool first = true;
+ bool hit = false;
+ for (auto const& ring : poly.rings)
+ {
+ mapnik::geometry::linear_ring<double> linear_ring;
+ for (auto const& index : ring)
+ {
+ double px = 0, py = 0;
+ bool reverse = index < 0;
+ index_type arc_index = reverse ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
+ {
+ hit = true;
+ auto const& arcs = topo_.arcs[arc_index];
+ auto const& coords = arcs.coordinates;
+ processed_coords.clear();
+ processed_coords.reserve(coords.size());
+ for (auto const& pt : coords )
+ {
+ double x = pt.x;
+ double y = pt.y;
+
+ if (topo_.tr)
+ {
+ 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});
+ }
+
+ if (reverse)
+ {
+ for (auto const& c : processed_coords | boost::adaptors::reversed)
+ {
+ linear_ring.emplace_back(c.x, c.y);
+ }
+ }
+ else
+ {
+ for (auto const& c : processed_coords)
+ {
+ linear_ring.emplace_back(c.x, c.y);
+ }
+ }
+ }
+ }
+ if (first)
+ {
+ first = false;
+ polygon.set_exterior_ring(std::move(linear_ring));
+ }
+ else
+ {
+ polygon.add_hole(std::move(linear_ring));
+ }
+ }
+ if (hit)
+ {
+ mapnik::geometry::correct(polygon);
+ feature->set_geometry(std::move(polygon));
+ assign_properties(*feature, poly, tr_);
+ }
+ }
+ return feature;
+ }
+
+ feature_ptr operator() (multi_polygon const& multi_poly) const
+ {
+ mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
+ if (num_arcs_ > 0)
+ {
+ std::vector<mapnik::topojson::coordinate> processed_coords;
+ mapnik::geometry::multi_polygon<double> multi_polygon;
+ multi_polygon.reserve(multi_poly.polygons.size());
+ bool hit = false;
+ for (auto const& poly : multi_poly.polygons)
+ {
+ bool first = true;
+ mapnik::geometry::polygon<double> polygon;
+ if (poly.size() > 1) polygon.interior_rings.reserve(poly.size() - 1);
+
+ for (auto const& ring : poly)
+ {
+ mapnik::geometry::linear_ring<double> linear_ring;
+ for (auto const& index : ring)
+ {
+ double px = 0, py = 0;
+ bool reverse = index < 0;
+ index_type arc_index = reverse ? std::abs(index) - 1 : index;
+ if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
+ {
+ hit = true;
+ auto const& arcs = topo_.arcs[arc_index];
+ auto const& coords = arcs.coordinates;
+ processed_coords.clear();
+ processed_coords.reserve(coords.size());
+ for (auto const& pt : coords )
+ {
+ 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;
+ }
+ processed_coords.emplace_back(coordinate{x,y});
+ }
+
+ using namespace boost::adaptors;
+
+ if (reverse)
+ {
+ for (auto const& c : (processed_coords | reversed))
+ {
+ linear_ring.add_coord(c.x, c.y);
+ }
+ }
+ else
+ {
+ for (auto const& c : processed_coords)
+ {
+ linear_ring.add_coord(c.x, c.y);
+ }
+ }
+ }
+ }
+ if (first)
+ {
+ first = false;
+ polygon.set_exterior_ring(std::move(linear_ring));
+ }
+ else
+ {
+ polygon.add_hole(std::move(linear_ring));
+ }
+ }
+ multi_polygon.push_back(std::move(polygon));
+ }
+ if (hit)
+ {
+ mapnik::geometry::correct(multi_polygon);
+ feature->set_geometry(std::move(multi_polygon));
+ assign_properties(*feature, multi_poly, tr_);
+ }
+ }
+ return feature;
+ }
+
+ template<typename T>
+ feature_ptr operator() (T const& ) const
+ {
+ return feature_ptr();
+ }
+
+ Context & ctx_;
+ mapnik::transcoder const& tr_;
+ topology const& topo_;
+ std::size_t num_arcs_;
+ std::size_t feature_id_;
+};
+
+
}}
#endif //MAPNIK_TOPOJSON_UTILS_HPP
diff --git a/include/mapnik/json/topology.hpp b/include/mapnik/json/topology.hpp
index b859cfc..05f35b4 100644
--- a/include/mapnik/json/topology.hpp
+++ b/include/mapnik/json/topology.hpp
@@ -28,8 +28,6 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
-#include <boost/fusion/include/adapt_struct.hpp>
-#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/optional.hpp>
#pragma GCC diagnostic pop
@@ -126,75 +124,4 @@ struct topology
}}
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::coordinate,
- (double, x)
- (double, y)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::arc,
- (std::list<mapnik::topojson::coordinate>, coordinates)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::transform,
- (double, scale_x)
- (double, scale_y)
- (double, translate_x)
- (double, translate_y)
- )
-
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::topojson::bounding_box,
- (double, minx)
- (double, miny)
- (double, maxx)
- (double, maxy)
- )
-
-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)
- (boost::optional<mapnik::topojson::transform>, tr)
- (boost::optional<mapnik::topojson::bounding_box>, bbox)
- )
-
#endif // MAPNIK_TOPOLOGY_HPP
diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp
index 6846180..f751f31 100644
--- a/include/mapnik/label_collision_detector.hpp
+++ b/include/mapnik/label_collision_detector.hpp
@@ -28,8 +28,10 @@
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/value_types.hpp>
-// icu
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/unistr.h>
+#pragma GCC diagnostic pop
// stl
#include <vector>
diff --git a/include/mapnik/map.hpp b/include/mapnik/map.hpp
index 23ea96a..9f58279 100644
--- a/include/mapnik/map.hpp
+++ b/include/mapnik/map.hpp
@@ -34,8 +34,10 @@
#include <mapnik/image_compositing.hpp>
#include <mapnik/font_engine_freetype.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <map>
diff --git a/include/mapnik/mapped_memory_cache.hpp b/include/mapnik/mapped_memory_cache.hpp
index c67d63a..1ac8d87 100644
--- a/include/mapnik/mapped_memory_cache.hpp
+++ b/include/mapnik/mapped_memory_cache.hpp
@@ -31,7 +31,12 @@
#include <memory>
#include <string>
#include <unordered_map>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
+
namespace boost { namespace interprocess { class mapped_region; } }
diff --git a/include/mapnik/marker.hpp b/include/mapnik/marker.hpp
index 8ba117e..1feb0fe 100644
--- a/include/mapnik/marker.hpp
+++ b/include/mapnik/marker.hpp
@@ -29,8 +29,10 @@
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/util/variant.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_array.h"
+#pragma GCC diagnostic pop
// stl
#include <memory>
diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp
index 49c011a..8ba3c6f 100644
--- a/include/mapnik/marker_helpers.hpp
+++ b/include/mapnik/marker_helpers.hpp
@@ -36,9 +36,12 @@
#include <mapnik/vertex_processor.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/renderer_common/render_markers_symbolizer.hpp>
+#include <mapnik/vertex_converters.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
// stl
#include <memory>
@@ -158,84 +161,29 @@ void setup_transform_scaling(agg::trans_affine & tr,
attributes const& vars,
symbolizer_base const& sym);
+using vertex_converter_type = vertex_converter<clip_line_tag,
+ clip_poly_tag,
+ transform_tag,
+ affine_transform_tag,
+ simplify_tag,
+ smooth_tag,
+ offset_transform_tag>;
+
// Apply markers to a feature with multiple geometries
-template <typename Converter, typename Processor>
-void apply_markers_multi(feature_impl const& feature, attributes const& vars, Converter & converter, Processor & proc, symbolizer_base const& sym)
-{
- using apply_vertex_converter_type = detail::apply_vertex_converter<Converter,Processor>;
- using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
+template <typename Processor>
+void apply_markers_multi(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, Processor & proc, symbolizer_base const& sym);
- auto const& geom = feature.get_geometry();
- geometry::geometry_types type = geometry::geometry_type(geom);
- if (type == geometry::geometry_types::Point
- || type == geometry::geometry_types::LineString
- || type == geometry::geometry_types::Polygon)
- {
- apply_vertex_converter_type apply(converter, proc);
- mapnik::util::apply_visitor(vertex_processor_type(apply), geom);
- }
- else
- {
+using vector_dispatch_type = vector_markers_dispatch<mapnik::label_collision_detector4>;
+using raster_dispatch_type = raster_markers_dispatch<mapnik::label_collision_detector4>;
- marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum, keys::markers_multipolicy>(sym, feature, vars);
- marker_placement_enum placement = get<marker_placement_enum, keys::markers_placement_type>(sym, feature, vars);
+extern template void apply_markers_multi<vector_dispatch_type>(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, vector_dispatch_type & proc, symbolizer_base const& sym);
+
+extern template void apply_markers_multi<raster_dispatch_type>(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, raster_dispatch_type & proc, symbolizer_base const& sym);
- if (placement == MARKER_POINT_PLACEMENT &&
- multi_policy == MARKER_WHOLE_MULTI)
- {
- geometry::point<double> pt;
- // test if centroid is contained by bounding box
- if (geometry::centroid(geom, pt) && converter.disp_.args_.bbox.contains(pt.x, pt.y))
- {
- // unset any clipping since we're now dealing with a point
- converter.template unset<clip_poly_tag>();
- geometry::point_vertex_adapter<double> va(pt);
- converter.apply(va, proc);
- }
- }
- else if ((placement == MARKER_POINT_PLACEMENT || placement == MARKER_INTERIOR_PLACEMENT) &&
- multi_policy == MARKER_LARGEST_MULTI)
- {
- // Only apply to path with largest envelope area
- // TODO: consider using true area for polygon types
- if (type == geometry::geometry_types::MultiPolygon)
- {
- geometry::multi_polygon<double> const& multi_poly = mapnik::util::get<geometry::multi_polygon<double> >(geom);
- double maxarea = 0;
- geometry::polygon<double> const* largest = 0;
- for (geometry::polygon<double> const& poly : multi_poly)
- {
- box2d<double> bbox = geometry::envelope(poly);
- double area = bbox.width() * bbox.height();
- if (area > maxarea)
- {
- maxarea = area;
- largest = &poly;
- }
- }
- if (largest)
- {
- geometry::polygon_vertex_adapter<double> va(*largest);
- converter.apply(va, proc);
- }
- }
- else
- {
- MAPNIK_LOG_WARN(marker_symbolizer) << "TODO: if you get here -> open an issue";
- }
- }
- else
- {
- if (multi_policy != MARKER_EACH_MULTI && placement != MARKER_POINT_PLACEMENT)
- {
- MAPNIK_LOG_WARN(marker_symbolizer) << "marker_multi_policy != 'each' has no effect with marker_placement != 'point'";
- }
- apply_vertex_converter_type apply(converter, proc);
- mapnik::util::apply_visitor(vertex_processor_type(apply), geom);
- }
- }
-}
}
diff --git a/include/mapnik/markers_placement.hpp b/include/mapnik/markers_placement.hpp
index 3e7e3e4..0d43191 100644
--- a/include/mapnik/markers_placement.hpp
+++ b/include/mapnik/markers_placement.hpp
@@ -29,7 +29,6 @@
#include <mapnik/markers_placements/vertext_first.hpp>
#include <mapnik/markers_placements/vertext_last.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
-#include <mapnik/util/variant.hpp>
namespace mapnik
{
@@ -38,70 +37,99 @@ template <typename Locator, typename Detector>
class markers_placement_finder : util::noncopyable
{
public:
- using markers_placement = util::variant<markers_point_placement<Locator, Detector>,
- markers_line_placement<Locator, Detector>,
- markers_interior_placement<Locator, Detector>,
- markers_vertex_first_placement<Locator, Detector>,
- markers_vertex_last_placement<Locator, Detector>>;
-
- class get_point_visitor
- {
- public:
- get_point_visitor(double &x, double &y, double &angle, bool ignore_placement)
- : x_(x), y_(y), angle_(angle), ignore_placement_(ignore_placement)
- {
- }
-
- template <typename T>
- bool operator()(T &placement) const
- {
- return placement.get_point(x_, y_, angle_, ignore_placement_);
- }
-
- private:
- double &x_, &y_, &angle_;
- bool ignore_placement_;
- };
-
markers_placement_finder(marker_placement_e placement_type,
Locator &locator,
Detector &detector,
markers_placement_params const& params)
- : placement_(create(placement_type, locator, detector, params))
+ : placement_type_(placement_type)
{
+ switch (placement_type)
+ {
+ default:
+ case MARKER_POINT_PLACEMENT:
+ construct(&point_, locator, detector, params);
+ break;
+ case MARKER_INTERIOR_PLACEMENT:
+ construct(&interior_, locator, detector, params);
+ break;
+ case MARKER_LINE_PLACEMENT:
+ construct(&line_, locator, detector, params);
+ break;
+ case MARKER_VERTEX_FIRST_PLACEMENT:
+ construct(&vertex_first_, locator, detector, params);
+ break;
+ case MARKER_VERTEX_LAST_PLACEMENT:
+ construct(&vertex_last_, locator, detector, params);
+ break;
+ }
}
- // Get next point where the marker should be placed. Returns true if a place is found, false if none is found.
- bool get_point(double &x, double &y, double &angle, bool ignore_placement)
+ ~markers_placement_finder()
{
- return util::apply_visitor(get_point_visitor(x, y, angle, ignore_placement), placement_);
+ switch (placement_type_)
+ {
+ default:
+ case MARKER_POINT_PLACEMENT:
+ destroy(&point_);
+ break;
+ case MARKER_INTERIOR_PLACEMENT:
+ destroy(&interior_);
+ break;
+ case MARKER_LINE_PLACEMENT:
+ destroy(&line_);
+ break;
+ case MARKER_VERTEX_FIRST_PLACEMENT:
+ destroy(&vertex_first_);
+ break;
+ case MARKER_VERTEX_LAST_PLACEMENT:
+ destroy(&vertex_last_);
+ break;
+ }
}
-private:
- // Factory function for particular placement implementations.
- static markers_placement create(marker_placement_e placement_type,
- Locator &locator,
- Detector &detector,
- markers_placement_params const& params)
+ // Get next point where the marker should be placed. Returns true if a place is found, false if none is found.
+ bool get_point(double &x, double &y, double &angle, bool ignore_placement)
{
- switch (placement_type)
+ switch (placement_type_)
{
+ default:
case MARKER_POINT_PLACEMENT:
- return markers_point_placement<Locator, Detector>(locator,detector,params);
+ return point_.get_point(x, y, angle, ignore_placement);
case MARKER_INTERIOR_PLACEMENT:
- return markers_interior_placement<Locator, Detector>(locator,detector,params);
+ return interior_.get_point(x, y, angle, ignore_placement);
case MARKER_LINE_PLACEMENT:
- return markers_line_placement<Locator, Detector>(locator,detector,params);
+ return line_.get_point(x, y, angle, ignore_placement);
case MARKER_VERTEX_FIRST_PLACEMENT:
- return markers_vertex_first_placement<Locator, Detector>(locator,detector,params);
+ return vertex_first_.get_point(x, y, angle, ignore_placement);
case MARKER_VERTEX_LAST_PLACEMENT:
- return markers_vertex_last_placement<Locator, Detector>(locator,detector,params);
- default: // point
- return markers_point_placement<Locator, Detector>(locator,detector,params);
+ return vertex_last_.get_point(x, y, angle, ignore_placement);
}
}
- markers_placement placement_;
+private:
+ marker_placement_e const placement_type_;
+
+ union
+ {
+ markers_point_placement<Locator, Detector> point_;
+ markers_line_placement<Locator, Detector> line_;
+ markers_interior_placement<Locator, Detector> interior_;
+ markers_vertex_first_placement<Locator, Detector> vertex_first_;
+ markers_vertex_last_placement<Locator, Detector> vertex_last_;
+ };
+
+ template <typename T>
+ static T* construct(T* what, Locator & locator, Detector & detector,
+ markers_placement_params const& params)
+ {
+ return new(what) T(locator, detector, params);
+ }
+
+ template <typename T>
+ static void destroy(T* what)
+ {
+ what->~T();
+ }
};
}
diff --git a/include/mapnik/markers_placements/basic.hpp b/include/mapnik/markers_placements/basic.hpp
new file mode 100644
index 0000000..abcef5e
--- /dev/null
+++ b/include/mapnik/markers_placements/basic.hpp
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ *
+ * 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_MARKERS_PLACEMENTS_BASIC_HPP
+#define MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP
+
+// mapnik
+#include <mapnik/box2d.hpp>
+#include <mapnik/symbolizer_enumerations.hpp>
+#include <mapnik/util/math.hpp>
+#include <mapnik/util/noncopyable.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
+#include "agg_basics.h"
+#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
+
+namespace mapnik {
+
+struct markers_placement_params
+{
+ box2d<double> size;
+ agg::trans_affine tr;
+ double spacing;
+ double max_error;
+ bool allow_overlap;
+ bool avoid_edges;
+ direction_enum direction;
+};
+
+class markers_basic_placement : util::noncopyable
+{
+public:
+ markers_basic_placement(markers_placement_params const& params)
+ : params_(params)
+ {
+ }
+
+protected:
+ markers_placement_params const& params_;
+
+ // Rotates the size_ box and translates the position.
+ box2d<double> perform_transform(double angle, double dx, double dy) const
+ {
+ auto tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy);
+ return box2d<double>(params_.size, tr);
+ }
+
+ bool set_direction(double & angle) const
+ {
+ switch (params_.direction)
+ {
+ case DIRECTION_UP:
+ angle = 0;
+ return true;
+ case DIRECTION_DOWN:
+ angle = M_PI;
+ return true;
+ case DIRECTION_AUTO:
+ if (std::fabs(util::normalize_angle(angle)) > 0.5 * M_PI)
+ angle += M_PI;
+ return true;
+ case DIRECTION_AUTO_DOWN:
+ if (std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI)
+ angle += M_PI;
+ return true;
+ case DIRECTION_LEFT:
+ angle += M_PI;
+ return true;
+ case DIRECTION_LEFT_ONLY:
+ angle += M_PI;
+ return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
+ case DIRECTION_RIGHT_ONLY:
+ return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
+ case DIRECTION_RIGHT:
+ default:
+ return true;
+ }
+ }
+};
+
+} // namespace mapnik
+
+#endif // MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP
diff --git a/include/mapnik/markers_placements/interior.hpp b/include/mapnik/markers_placements/interior.hpp
index 93b5e34..6a2705e 100644
--- a/include/mapnik/markers_placements/interior.hpp
+++ b/include/mapnik/markers_placements/interior.hpp
@@ -33,14 +33,8 @@ template <typename Locator, typename Detector>
class markers_interior_placement : public markers_point_placement<Locator, Detector>
{
public:
- markers_interior_placement(Locator &locator, Detector &detector, markers_placement_params const& params)
- : markers_point_placement<Locator, Detector>(locator, detector, params)
- {
- }
-
- markers_interior_placement(markers_interior_placement && rhs)
- : markers_point_placement<Locator, Detector>(std::move(rhs))
- {}
+ using point_placement = markers_point_placement<Locator, Detector>;
+ using point_placement::point_placement;
bool get_point(double &x, double &y, double &angle, bool ignore_placement)
{
@@ -51,7 +45,7 @@ public:
if (this->locator_.type() == geometry::geometry_types::Point)
{
- return markers_point_placement<Locator, Detector>::get_point(x, y, angle, ignore_placement);
+ return point_placement::get_point(x, y, angle, ignore_placement);
}
if (this->locator_.type() == geometry::geometry_types::LineString)
@@ -73,20 +67,10 @@ public:
angle = 0;
- box2d<double> box = this->perform_transform(angle, x, y);
- if (this->params_.avoid_edges && !this->detector_.extent().contains(box))
+ if (!this->push_to_detector(x, y, angle, ignore_placement))
{
return false;
}
- if (!this->params_.allow_overlap && !this->detector_.has_placement(box))
- {
- return false;
- }
-
- if (!ignore_placement)
- {
- this->detector_.insert(box);
- }
this->done_ = true;
return true;
diff --git a/include/mapnik/markers_placements/line.hpp b/include/mapnik/markers_placements/line.hpp
index fe2c2bd..bc99cc9 100644
--- a/include/mapnik/markers_placements/line.hpp
+++ b/include/mapnik/markers_placements/line.hpp
@@ -35,29 +35,23 @@ template <typename Locator, typename Detector>
class markers_line_placement : public markers_point_placement<Locator, Detector>
{
public:
- markers_line_placement(Locator &locator, Detector &detector, markers_placement_params const& params)
- : markers_point_placement<Locator, Detector>(locator, detector, params),
+ using point_placement = markers_point_placement<Locator, Detector>;
+ using point_placement::point_placement;
+
+ markers_line_placement(Locator & locator, Detector & detector,
+ markers_placement_params const& params)
+ : point_placement(locator, detector, params),
first_point_(true),
spacing_(0.0),
marker_width_((params.size * params.tr).width()),
path_(locator)
{
spacing_ = params.spacing < 1 ? 100 : params.spacing;
- rewind();
}
- markers_line_placement(markers_line_placement && rhs)
- : markers_point_placement<Locator, Detector>(std::move(rhs)),
- first_point_(std::move(rhs.first_point_)),
- spacing_(std::move(rhs.spacing_)),
- marker_width_(std::move(rhs.marker_width_)),
- path_(std::move(rhs.path_))
- {}
-
void rewind()
{
- this->locator_.rewind(0);
- this->done_ = false;
+ point_placement::rewind();
first_point_ = true;
}
@@ -70,7 +64,7 @@ public:
if (this->locator_.type() == geometry::geometry_types::Point)
{
- return markers_point_placement<Locator, Detector>::get_point(x, y, angle, ignore_placement);
+ return point_placement::get_point(x, y, angle, ignore_placement);
}
double move = spacing_;
@@ -102,16 +96,10 @@ public:
{
continue;
}
- box2d<double> box = this->perform_transform(angle, x, y);
- if ((this->params_.avoid_edges && !this->detector_.extent().contains(box))
- || (!this->params_.allow_overlap && !this->detector_.has_placement(box)))
+ if (!this->push_to_detector(x, y, angle, ignore_placement))
{
continue;
}
- if (!ignore_placement)
- {
- this->detector_.insert(box);
- }
return true;
}
}
diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp
index 13f174d..6e2f1da 100644
--- a/include/mapnik/markers_placements/point.hpp
+++ b/include/mapnik/markers_placements/point.hpp
@@ -23,53 +23,26 @@
#ifndef MAPNIK_MARKERS_PLACEMENTS_POINT_HPP
#define MAPNIK_MARKERS_PLACEMENTS_POINT_HPP
-#include <mapnik/box2d.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/geometry_types.hpp>
-#include <mapnik/util/math.hpp>
-#include <mapnik/label_collision_detector.hpp>
-#include <mapnik/symbolizer_enumerations.hpp>
-#include <mapnik/util/noncopyable.hpp>
-
-#include "agg_basics.h"
-#include "agg_trans_affine.h"
-
-#include <cmath>
+#include <mapnik/markers_placements/basic.hpp>
namespace mapnik {
-struct markers_placement_params
-{
- box2d<double> size;
- agg::trans_affine tr;
- double spacing;
- double max_error;
- bool allow_overlap;
- bool avoid_edges;
- direction_enum direction;
-};
-
template <typename Locator, typename Detector>
-class markers_point_placement : util::noncopyable
+class markers_point_placement : public markers_basic_placement
{
public:
- markers_point_placement(Locator &locator, Detector &detector, markers_placement_params const& params)
- : locator_(locator),
+ markers_point_placement(Locator & locator, Detector & detector,
+ markers_placement_params const& params)
+ : markers_basic_placement(params),
+ locator_(locator),
detector_(detector),
- params_(params),
done_(false)
{
- rewind();
+ locator_.rewind(0);
}
- markers_point_placement(markers_point_placement && rhs)
- : locator_(rhs.locator_),
- detector_(rhs.detector_),
- params_(rhs.params_),
- done_(rhs.done_)
- {}
-
-
// Start again at first marker. Returns the same list of markers only works when they were NOT added to the detector.
void rewind()
{
@@ -80,90 +53,66 @@ public:
// Get next point where the marker should be placed. Returns true if a place is found, false if none is found.
bool get_point(double &x, double &y, double &angle, bool ignore_placement)
{
- if (done_)
+ if (this->done_)
{
return false;
}
- if (locator_.type() == geometry::geometry_types::LineString)
+ if (this->locator_.type() == geometry::geometry_types::LineString)
{
- if (!label::middle_point(locator_, x, y))
+ if (!label::middle_point(this->locator_, x, y))
{
- done_ = true;
+ this->done_ = true;
return false;
}
}
else
{
- if (!label::centroid(locator_, x, y))
+ if (!label::centroid(this->locator_, x, y))
{
- done_ = true;
+ this->done_ = true;
return false;
}
}
angle = 0;
- box2d<double> box = perform_transform(angle, x, y);
- if (params_.avoid_edges && !detector_.extent().contains(box))
- {
- return false;
- }
- if (!params_.allow_overlap && !detector_.has_placement(box))
+ if (!this->push_to_detector(x, y, angle, ignore_placement))
{
return false;
}
- if (!ignore_placement)
- {
- detector_.insert(box);
- }
-
- done_ = true;
+ this->done_ = true;
return true;
}
protected:
- Locator &locator_;
- Detector &detector_;
- markers_placement_params const& params_;
+ Locator & locator_;
+ Detector & detector_;
bool done_;
- // Rotates the size_ box and translates the position.
- box2d<double> perform_transform(double angle, double dx, double dy)
- {
- agg::trans_affine tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy);
- return box2d<double>(params_.size, tr);
- }
-
- bool set_direction(double & angle)
+ // Checks transformed box placement with collision detector.
+ // returns false if the box:
+ // - a) isn't wholly inside extent and avoid_edges == true
+ // - b) collides with something and allow_overlap == false
+ // otherwise returns true, and if ignore_placement == false,
+ // also adds the box to collision detector
+ bool push_to_detector(double x, double y, double angle, bool ignore_placement)
{
- switch (params_.direction)
+ auto box = perform_transform(angle, x, y);
+ if (params_.avoid_edges && !detector_.extent().contains(box))
+ {
+ return false;
+ }
+ if (!params_.allow_overlap && !detector_.has_placement(box))
+ {
+ return false;
+ }
+ if (!ignore_placement)
{
- case DIRECTION_UP:
- angle = .0;
- return true;
- case DIRECTION_DOWN:
- angle = M_PI;
- return true;
- case DIRECTION_AUTO:
- angle = (std::fabs(util::normalize_angle(angle)) > 0.5 * M_PI) ? (angle + M_PI) : angle;
- return true;
- case DIRECTION_AUTO_DOWN:
- angle = (std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI) ? (angle + M_PI) : angle;
- return true;
- case DIRECTION_LEFT:
- angle += M_PI;
- return true;
- case DIRECTION_LEFT_ONLY:
- angle += M_PI;
- return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
- case DIRECTION_RIGHT_ONLY:
- return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
- case DIRECTION_RIGHT:
- default:
- return true;
+ detector_.insert(box);
}
+ return true;
}
};
diff --git a/include/mapnik/markers_placements/vertext_first.hpp b/include/mapnik/markers_placements/vertext_first.hpp
index bcdac2b..ce1b415 100644
--- a/include/mapnik/markers_placements/vertext_first.hpp
+++ b/include/mapnik/markers_placements/vertext_first.hpp
@@ -31,14 +31,8 @@ template <typename Locator, typename Detector>
class markers_vertex_first_placement : public markers_point_placement<Locator, Detector>
{
public:
- markers_vertex_first_placement(Locator &locator, Detector &detector, markers_placement_params const& params)
- : markers_point_placement<Locator, Detector>(locator, detector, params)
- {
- }
-
- markers_vertex_first_placement(markers_vertex_first_placement && rhs)
- : markers_point_placement<Locator, Detector>(std::move(rhs))
- {}
+ using point_placement = markers_point_placement<Locator, Detector>;
+ using point_placement::point_placement;
bool get_point(double &x, double &y, double &angle, bool ignore_placement)
{
@@ -49,7 +43,7 @@ public:
if (this->locator_.type() == mapnik::geometry::geometry_types::Point)
{
- return markers_point_placement<Locator, Detector>::get_point(x, y, angle, ignore_placement);
+ return point_placement::get_point(x, y, angle, ignore_placement);
}
double x0, y0;
@@ -75,20 +69,10 @@ public:
}
}
- box2d<double> box = this->perform_transform(angle, x, y);
- if (this->params_.avoid_edges && !this->detector_.extent().contains(box))
+ if (!this->push_to_detector(x, y, angle, ignore_placement))
{
return false;
}
- if (!this->params_.allow_overlap && !this->detector_.has_placement(box))
- {
- return false;
- }
-
- if (!ignore_placement)
- {
- this->detector_.insert(box);
- }
this->done_ = true;
return true;
diff --git a/include/mapnik/markers_placements/vertext_last.hpp b/include/mapnik/markers_placements/vertext_last.hpp
index 4d57130..62c94a6 100644
--- a/include/mapnik/markers_placements/vertext_last.hpp
+++ b/include/mapnik/markers_placements/vertext_last.hpp
@@ -31,13 +31,8 @@ template <typename Locator, typename Detector>
class markers_vertex_last_placement : public markers_point_placement<Locator, Detector>
{
public:
- markers_vertex_last_placement(Locator &locator, Detector &detector, markers_placement_params const& params)
- : markers_point_placement<Locator, Detector>(locator, detector, params)
- {}
-
- markers_vertex_last_placement(markers_vertex_last_placement && rhs)
- : markers_point_placement<Locator, Detector>(std::move(rhs))
- {}
+ using point_placement = markers_point_placement<Locator, Detector>;
+ using point_placement::point_placement;
bool get_point(double &x, double &y, double &angle, bool ignore_placement)
{
@@ -80,21 +75,11 @@ public:
}
}
- box2d<double> box = this->perform_transform(angle, x, y);
- if (this->params_.avoid_edges && !this->detector_.extent().contains(box))
- {
- return false;
- }
- if (!this->params_.allow_overlap && !this->detector_.has_placement(box))
+ if (!this->push_to_detector(x, y, angle, ignore_placement))
{
return false;
}
- if (!ignore_placement)
- {
- this->detector_.insert(box);
- }
-
this->done_ = true;
return true;
}
diff --git a/include/mapnik/params.hpp b/include/mapnik/params.hpp
index a154cf7..a38fa54 100644
--- a/include/mapnik/params.hpp
+++ b/include/mapnik/params.hpp
@@ -27,8 +27,11 @@
#include <mapnik/config.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/util/variant.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/include/mapnik/path_expression_grammar_impl.hpp b/include/mapnik/path_expression_grammar_impl.hpp
index bc2fcfb..22002bf 100644
--- a/include/mapnik/path_expression_grammar_impl.hpp
+++ b/include/mapnik/path_expression_grammar_impl.hpp
@@ -24,10 +24,13 @@
#include <mapnik/path_expression_grammar.hpp>
#include <mapnik/attribute.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp
index f17f857..051ea6b 100644
--- a/include/mapnik/png_io.hpp
+++ b/include/mapnik/png_io.hpp
@@ -29,17 +29,19 @@
#include <mapnik/hextree.hpp>
#include <mapnik/image.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
// zlib
#include <zlib.h> // for Z_DEFAULT_COMPRESSION
-// boost
-
-
extern "C"
{
#include <png.h>
}
+#pragma GCC diagnostic pop
+
#define MAX_OCTREE_LEVELS 4
namespace mapnik {
@@ -99,10 +101,10 @@ void save_as_png(T1 & file,
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
- png_destroy_write_struct(&png_ptr,(png_infopp)0);
+ png_destroy_write_struct(&png_ptr,static_cast<png_infopp>(0));
return;
}
- jmp_buf* jmp_context = (jmp_buf*) png_get_error_ptr(png_ptr);
+ jmp_buf* jmp_context = static_cast<jmp_buf*>(png_get_error_ptr(png_ptr));
if (jmp_context)
{
png_destroy_write_struct(&png_ptr, &info_ptr);
@@ -120,7 +122,7 @@ void save_as_png(T1 & file,
const std::unique_ptr<png_bytep[]> row_pointers(new png_bytep[image.height()]);
for (unsigned int i = 0; i < image.height(); i++)
{
- row_pointers[i] = (png_bytep)image.get_row(i);
+ row_pointers[i] = const_cast<png_bytep>(reinterpret_cast<const unsigned char *>(image.get_row(i)));
}
png_set_rows(png_ptr, info_ptr, row_pointers.get());
png_write_png(png_ptr, info_ptr, (opts.trans_mode == 0) ? PNG_TRANSFORM_STRIP_FILLER_AFTER : PNG_TRANSFORM_IDENTITY, nullptr);
@@ -161,7 +163,7 @@ void reduce_8(T const& in,
break;
}
}
- if (idx>=0 && idx<(int)alpha.size())
+ if (idx>=0 && idx < static_cast<int>(alpha.size()))
{
alpha[idx]+=U2ALPHA(val);
alphaCount[idx]++;
@@ -212,7 +214,7 @@ void reduce_4(T const& in,
break;
}
}
- if (idx>=0 && idx<(int)alpha.size())
+ if (idx>=0 && idx < static_cast<int>(alpha.size()))
{
alpha[idx]+=U2ALPHA(val);
alphaCount[idx]++;
@@ -273,10 +275,10 @@ void save_as_png(T & file, std::vector<mapnik::rgb> const& palette,
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
- png_destroy_write_struct(&png_ptr,(png_infopp)0);
+ png_destroy_write_struct(&png_ptr,static_cast<png_infopp>(0));
return;
}
- jmp_buf* jmp_context = (jmp_buf*) png_get_error_ptr(png_ptr);
+ jmp_buf* jmp_context = static_cast<jmp_buf*>(png_get_error_ptr(png_ptr));
if (jmp_context)
{
png_destroy_write_struct(&png_ptr, &info_ptr);
@@ -310,14 +312,14 @@ void save_as_png(T & file, std::vector<mapnik::rgb> const& palette,
}
if (alphaSize>0)
{
- png_set_tRNS(png_ptr, info_ptr, (png_bytep)&trans[0], alphaSize, 0);
+ png_set_tRNS(png_ptr, info_ptr, static_cast<png_bytep>(&trans[0]), alphaSize, 0);
}
}
png_write_info(png_ptr, info_ptr);
for (unsigned i=0;i<height;i++)
{
- png_write_row(png_ptr,(png_bytep)image.get_row(i));
+ png_write_row(png_ptr,const_cast<png_bytep>(image.get_row(i)));
}
png_write_end(png_ptr, info_ptr);
@@ -352,7 +354,7 @@ void save_as_png8_oct(T1 & file,
{
for (unsigned x = 0; x < width; ++x)
{
- unsigned val = U2ALPHA((unsigned)image.get_row(y)[x]);
+ unsigned val = U2ALPHA(static_cast<unsigned>(image.get_row(y)[x]));
alphaHist[val]++;
meanAlpha += val;
if (val>0 && val<255)
diff --git a/include/mapnik/projection.hpp b/include/mapnik/projection.hpp
index cb4284f..0869bb2 100644
--- a/include/mapnik/projection.hpp
+++ b/include/mapnik/projection.hpp
@@ -27,8 +27,10 @@
#include <mapnik/config.hpp>
#include <mapnik/well_known_srs.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/include/mapnik/ptree_helpers.hpp b/include/mapnik/ptree_helpers.hpp
index 3062d71..6a9c91e 100644
--- a/include/mapnik/ptree_helpers.hpp
+++ b/include/mapnik/ptree_helpers.hpp
@@ -26,8 +26,10 @@
// stl
#include <string>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/quad_tree.hpp b/include/mapnik/quad_tree.hpp
index d60ee5d..c15f09f 100644
--- a/include/mapnik/quad_tree.hpp
+++ b/include/mapnik/quad_tree.hpp
@@ -36,26 +36,27 @@
namespace mapnik
{
-template <typename T>
+template <typename T0, typename T1 = box2d<double>>
class quad_tree : util::noncopyable
{
- using value_type = T;
+ using value_type = T0;
+ using bbox_type = T1;
struct node
{
- using cont_type = std::vector<T>;
+ using cont_type = std::vector<T0>;
using iterator = typename cont_type::iterator;
using const_iterator = typename cont_type::const_iterator;
- box2d<double> extent_;
+ bbox_type extent_;
cont_type cont_;
node * children_[4];
- explicit node(box2d<double> const& ext)
+ explicit node(bbox_type const& ext)
: extent_(ext)
{
std::fill(children_, children_ + 4, nullptr);
}
- box2d<double> const& extent() const
+ bbox_type const& extent() const
{
return extent_;
}
@@ -99,10 +100,10 @@ class quad_tree : util::noncopyable
public:
using iterator = typename nodes_type::iterator;
using const_iterator = typename nodes_type::const_iterator;
- using result_type = typename std::vector<std::reference_wrapper<T> >;
+ using result_type = typename std::vector<std::reference_wrapper<value_type> >;
using query_iterator = typename result_type::iterator;
- explicit quad_tree(box2d<double> const& ext,
+ explicit quad_tree(bbox_type const& ext,
unsigned int max_depth = 8,
double ratio = 0.55)
: max_depth_(max_depth),
@@ -114,13 +115,13 @@ public:
root_ = nodes_[0].get();
}
- void insert(T data, box2d<double> const& box)
+ void insert(value_type data, bbox_type const& box)
{
- unsigned int depth=0;
- do_insert_data(data,box,root_,depth);
+ unsigned int depth = 0;
+ do_insert_data(data, box, root_, depth);
}
- query_iterator query_in_box(box2d<double> const& box)
+ query_iterator query_in_box(bbox_type const& box)
{
query_result_.clear();
query_node(box, query_result_, root_);
@@ -145,13 +146,13 @@ public:
void clear ()
{
- box2d<double> ext = root_->extent_;
+ bbox_type ext = root_->extent_;
nodes_.clear();
nodes_.push_back(std::make_unique<node>(ext));
root_ = nodes_[0].get();
}
- box2d<double> const& extent() const
+ bbox_type const& extent() const
{
return root_->extent_;
}
@@ -185,11 +186,11 @@ public:
}
private:
- void query_node(box2d<double> const& box, result_type & result, node * node_) const
+ void query_node(bbox_type const& box, result_type & result, node * node_) const
{
if (node_)
{
- box2d<double> const& node_extent = node_->extent();
+ bbox_type const& node_extent = node_->extent();
if (box.intersects(node_extent))
{
for (auto & n : *node_)
@@ -204,7 +205,7 @@ private:
}
}
- void do_insert_data(T data, box2d<double> const& box, node * n, unsigned int& depth)
+ void do_insert_data(value_type data, bbox_type const& box, node * n, unsigned int& depth)
{
if (++depth >= max_depth_)
{
@@ -212,8 +213,8 @@ private:
}
else
{
- box2d<double> const& node_extent = n->extent();
- box2d<double> ext[4];
+ bbox_type const& node_extent = n->extent();
+ bbox_type ext[4];
split_box(node_extent,ext);
for (int i = 0; i < 4; ++i)
{
@@ -232,20 +233,19 @@ private:
}
}
- void split_box(box2d<double> const& node_extent,box2d<double> * ext)
+ void split_box(bbox_type const& node_extent,bbox_type * ext)
{
- double width=node_extent.width();
- double height=node_extent.height();
-
- double lox=node_extent.minx();
- double loy=node_extent.miny();
- double hix=node_extent.maxx();
- double hiy=node_extent.maxy();
-
- ext[0]=box2d<double>(lox,loy,lox + width * ratio_,loy + height * ratio_);
- ext[1]=box2d<double>(hix - width * ratio_,loy,hix,loy + height * ratio_);
- ext[2]=box2d<double>(lox,hiy - height*ratio_,lox + width * ratio_,hiy);
- ext[3]=box2d<double>(hix - width * ratio_,hiy - height*ratio_,hix,hiy);
+ typename bbox_type::value_type width = node_extent.width();
+ typename bbox_type::value_type height = node_extent.height();
+ typename bbox_type::value_type lox = node_extent.minx();
+ typename bbox_type::value_type loy = node_extent.miny();
+ typename bbox_type::value_type hix = node_extent.maxx();
+ typename bbox_type::value_type hiy = node_extent.maxy();
+
+ ext[0] = bbox_type(lox, loy, lox + width * ratio_, loy + height * ratio_);
+ ext[1] = bbox_type(hix - width * ratio_, loy, hix, loy + height * ratio_);
+ ext[2] = bbox_type(lox, hiy - height * ratio_, lox + width * ratio_, hiy);
+ ext[3] = bbox_type(hix - width * ratio_, hiy - height * ratio_, hix, hiy);
}
void trim_tree(node *& n)
@@ -304,7 +304,7 @@ private:
{
if (n->children_[i])
{
- offset +=sizeof(box2d<double>) + (n->children_[i]->cont_.size() * sizeof(value_type)) + 3 * sizeof(int);
+ offset +=sizeof(bbox_type) + (n->children_[i]->cont_.size() * sizeof(value_type)) + 3 * sizeof(int);
offset +=subnode_offset(n->children_[i]);
}
}
@@ -316,17 +316,17 @@ private:
{
if (n)
{
- int offset=subnode_offset(n);
- int shape_count=n->cont_.size();
- int recsize=sizeof(box2d<double>) + 3 * sizeof(int) + shape_count * sizeof(value_type);
+ int offset = subnode_offset(n);
+ int shape_count = n->cont_.size();
+ int recsize = sizeof(bbox_type) + 3 * sizeof(int) + shape_count * sizeof(value_type);
std::unique_ptr<char[]> node_record(new char[recsize]);
std::memset(node_record.get(), 0, recsize);
std::memcpy(node_record.get(), &offset, 4);
- std::memcpy(node_record.get() + 4, &n->extent_, sizeof(box2d<double>));
- std::memcpy(node_record.get() + 36, &shape_count, 4);
+ std::memcpy(node_record.get() + 4, &n->extent_, sizeof(bbox_type));
+ std::memcpy(node_record.get() + 4 + sizeof(bbox_type), &shape_count, 4);
for (int i=0; i < shape_count; ++i)
{
- memcpy(node_record.get() + 40 + i * sizeof(value_type), &(n->cont_[i]),sizeof(value_type));
+ memcpy(node_record.get() + 8 + sizeof(bbox_type) + i * sizeof(value_type), &(n->cont_[i]), sizeof(value_type));
}
int num_subnodes=0;
for (int i = 0; i < 4; ++i)
@@ -336,7 +336,7 @@ private:
++num_subnodes;
}
}
- std::memcpy(node_record.get() + 40 + shape_count * sizeof(value_type),&num_subnodes,4);
+ std::memcpy(node_record.get() + 8 + sizeof(bbox_type) + shape_count * sizeof(value_type), &num_subnodes, 4);
out.write(node_record.get(),recsize);
for (int i = 0; i < 4; ++i)
{
diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp
index 311c06c..02022d3 100644
--- a/include/mapnik/raster.hpp
+++ b/include/mapnik/raster.hpp
@@ -28,8 +28,11 @@
#include <mapnik/image_any.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/util/variant.hpp>
- // boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp
index c1e83ab..86a85de 100644
--- a/include/mapnik/raster_colorizer.hpp
+++ b/include/mapnik/raster_colorizer.hpp
@@ -41,12 +41,13 @@
#include <mapnik/color.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/image.hpp>
- // boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
-// boost
-#include <memory>
+#pragma GCC diagnostic pop
-// stl
+#include <memory>
#include <vector>
namespace mapnik
@@ -164,7 +165,7 @@ public:
void set_default_mode(colorizer_mode mode)
{
- default_mode_ = (mode == COLORIZER_INHERIT) ? COLORIZER_LINEAR:(colorizer_mode_enum)mode;
+ default_mode_ = (mode == COLORIZER_INHERIT) ? COLORIZER_LINEAR : static_cast<colorizer_mode_enum>(mode);
}
void set_default_mode_enum(colorizer_mode_enum mode) { set_default_mode(mode); }
diff --git a/include/mapnik/renderer_common/process_raster_symbolizer.hpp b/include/mapnik/renderer_common/process_raster_symbolizer.hpp
index f8ce32d..7ca90a0 100644
--- a/include/mapnik/renderer_common/process_raster_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_raster_symbolizer.hpp
@@ -32,13 +32,15 @@
#include <mapnik/proj_transform.hpp>
#include <mapnik/feature.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/simplify.hpp b/include/mapnik/simplify.hpp
index 71b7711..dd75fcf 100644
--- a/include/mapnik/simplify.hpp
+++ b/include/mapnik/simplify.hpp
@@ -7,8 +7,10 @@
// stl
#include <string>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/simplify_converter.hpp b/include/mapnik/simplify_converter.hpp
index 92f81b4..2488425 100644
--- a/include/mapnik/simplify_converter.hpp
+++ b/include/mapnik/simplify_converter.hpp
@@ -41,7 +41,7 @@ struct weighted_vertex : private util::noncopyable
vertex2d const& A = prev->coord;
vertex2d const& B = next->coord;
vertex2d const& C = coord;
- return std::abs((double)((A.x - C.x) * (B.y - A.y) - (A.x - B.x) * (C.y - A.y))) / 2.0;
+ return std::abs(static_cast<double>((A.x - C.x) * (B.y - A.y) - (A.x - B.x) * (C.y - A.y))) / 2.0;
}
struct ascending_sort
diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp
index 972558c..c0a9adb 100644
--- a/include/mapnik/span_image_filter.hpp
+++ b/include/mapnik/span_image_filter.hpp
@@ -23,10 +23,18 @@
#ifndef MAPNIK_SPAN_IMAGE_FILTER_INCLUDED
#define MAPNIK_SPAN_IMAGE_FILTER_INCLUDED
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
+#include <mapnik/safe_cast.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
+#include "agg_span_image_filter_gray.h"
+#include "agg_span_image_filter_rgba.h"
+#pragma GCC diagnostic pop
#include <limits>
@@ -79,16 +87,19 @@ public:
{
base_type::interpolator().coordinates(&x, &y);
- int src_x = x >> agg::image_subpixel_shift;
- int src_y = y >> agg::image_subpixel_shift;
- const value_type* pix = reinterpret_cast<const value_type*>(base_type::source().span(src_x, src_y, 0));
- if (nodata_value_ && *nodata_value_ == *pix)
+ if (nodata_value_)
{
- span->v = *nodata_value_;
- span->a = base_mask;
- ++span;
- ++base_type::interpolator();
- continue;
+ int src_x = x >> agg::image_subpixel_shift;
+ int src_y = y >> agg::image_subpixel_shift;
+ const value_type* pix = reinterpret_cast<const value_type*>(base_type::source().span(src_x, src_y, 1));
+ if (*nodata_value_ == *pix)
+ {
+ span->v = *nodata_value_;
+ span->a = base_mask;
+ ++span;
+ ++base_type::interpolator();
+ continue;
+ }
}
x += base_type::filter_dx_int() - radius_x;
@@ -131,19 +142,15 @@ public:
fg_ptr = reinterpret_cast<const value_type*>(base_type::source().next_y());
}
- fg /= total_weight;
- if (fg < std::numeric_limits<value_type>::min())
- {
- span->v = std::numeric_limits<value_type>::min();
- }
- else if (fg > std::numeric_limits<value_type>::max())
+ if (total_weight == 0)
{
- span->v = std::numeric_limits<value_type>::max();
+ span->v = *nodata_value_;
}
else
{
- span->v = static_cast<value_type>(fg);
+ span->v = safe_cast<value_type>(fg / total_weight);
}
+
span->a = base_mask;
++span;
diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/include/mapnik/stringify_macro.hpp
similarity index 74%
copy from include/mapnik/grid/grid_rendering_buffer.hpp
copy to include/mapnik/stringify_macro.hpp
index 4282e3b..41f9474 100644
--- a/include/mapnik/grid/grid_rendering_buffer.hpp
+++ b/include/mapnik/stringify_macro.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
@@ -20,16 +20,7 @@
*
*****************************************************************************/
-#ifndef MAPNIK_GRID_RENDERING_BUFFER_HPP
-#define MAPNIK_GRID_RENDERING_BUFFER_HPP
-
-#include <mapnik/grid/grid.hpp>
-#include "agg_rendering_buffer.h"
-
-namespace mapnik {
-
-using grid_rendering_buffer = agg::row_ptr_cache<mapnik::grid::value_type>;
-
-}
-
-#endif //MAPNIK_AGG_RASTERIZER_HPP
+#ifndef MAPNIK_STRINGIFY
+#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n)
+#define MAPNIK_STRINGIFY_HELPER(n) #n
+#endif
\ No newline at end of file
diff --git a/include/mapnik/svg/geometry_svg_generator.hpp b/include/mapnik/svg/geometry_svg_generator.hpp
index 11aa5c9..7594c26 100644
--- a/include/mapnik/svg/geometry_svg_generator.hpp
+++ b/include/mapnik/svg/geometry_svg_generator.hpp
@@ -36,15 +36,13 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/karma.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#pragma GCC diagnostic pop
+#include <tuple>
// adapted to conform to the concepts
// required by Karma to be recognized as a container of
diff --git a/include/mapnik/svg/output/svg_output_grammars.hpp b/include/mapnik/svg/output/svg_output_grammars.hpp
index 769671b..5657e26 100644
--- a/include/mapnik/svg/output/svg_output_grammars.hpp
+++ b/include/mapnik/svg/output/svg_output_grammars.hpp
@@ -40,53 +40,8 @@ namespace mapnik { namespace svg {
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/karma_nonterminal.hpp>
#include <boost/spirit/include/karma_rule.hpp>
-#include <boost/fusion/adapted/struct.hpp>
#pragma GCC diagnostic pop
-/*!
- * mapnik::svg::path_output_attributes is adapted as a fusion sequence
- * in order to be used directly by the svg_path_attributes_grammar (below).
- *
- * This adaptation is the primary reason why the attributes are stored in
- * this structure before being passed to the generate_path method.
- */
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::svg::path_output_attributes,
- (std::string, fill_color_)
- (double, fill_opacity_)
- (std::string, stroke_color_)
- (double, stroke_opacity_)
- (double, stroke_width_)
- (std::string, stroke_linecap_)
- (std::string, stroke_linejoin_)
- (double, stroke_dashoffset_)
- );
-
-/*!
- * mapnik::svg::rect_output_attributes is adapted as a fusion sequence
- * in order to be used directly by the svg_rect_attributes_grammar (below).
- */
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::svg::rect_output_attributes,
- (int, x_)
- (int, y_)
- (unsigned, width_)
- (unsigned, height_)
- (std::string, fill_color_)
- );
-
-/*!
- * mapnik::svg::root_output_attributes is adapted as a fusion sequence
- * in order to be used directly by the svg_root_attributes_grammar (below).
- */
-BOOST_FUSION_ADAPT_STRUCT(
- mapnik::svg::root_output_attributes,
- (unsigned, width_)
- (unsigned, height_)
- (double, svg_version_)
- (std::string, svg_namespace_url_)
- );
-
namespace mapnik { namespace svg {
using namespace boost::spirit;
diff --git a/include/mapnik/svg/output/svg_output_grammars_impl.hpp b/include/mapnik/svg/output/svg_output_grammars_impl.hpp
index cbce919..ef856a0 100644
--- a/include/mapnik/svg/output/svg_output_grammars_impl.hpp
+++ b/include/mapnik/svg/output/svg_output_grammars_impl.hpp
@@ -30,8 +30,53 @@
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/std_pair.hpp>
+#include <boost/fusion/adapted/struct.hpp>
#pragma GCC diagnostic pop
+/*!
+ * mapnik::svg::path_output_attributes is adapted as a fusion sequence
+ * in order to be used directly by the svg_path_attributes_grammar (below).
+ *
+ * This adaptation is the primary reason why the attributes are stored in
+ * this structure before being passed to the generate_path method.
+ */
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::svg::path_output_attributes,
+ (std::string, fill_color_)
+ (double, fill_opacity_)
+ (std::string, stroke_color_)
+ (double, stroke_opacity_)
+ (double, stroke_width_)
+ (std::string, stroke_linecap_)
+ (std::string, stroke_linejoin_)
+ (double, stroke_dashoffset_)
+ );
+
+/*!
+ * mapnik::svg::rect_output_attributes is adapted as a fusion sequence
+ * in order to be used directly by the svg_rect_attributes_grammar (below).
+ */
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::svg::rect_output_attributes,
+ (int, x_)
+ (int, y_)
+ (unsigned, width_)
+ (unsigned, height_)
+ (std::string, fill_color_)
+ );
+
+/*!
+ * mapnik::svg::root_output_attributes is adapted as a fusion sequence
+ * in order to be used directly by the svg_root_attributes_grammar (below).
+ */
+BOOST_FUSION_ADAPT_STRUCT(
+ mapnik::svg::root_output_attributes,
+ (unsigned, width_)
+ (unsigned, height_)
+ (double, svg_version_)
+ (std::string, svg_namespace_url_)
+ );
+
namespace mapnik { namespace svg {
using namespace boost::spirit;
diff --git a/include/mapnik/svg/svg_converter.hpp b/include/mapnik/svg/svg_converter.hpp
index 50d7708..9cf3c9c 100644
--- a/include/mapnik/svg/svg_converter.hpp
+++ b/include/mapnik/svg/svg_converter.hpp
@@ -29,7 +29,8 @@
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/safe_cast.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
@@ -37,6 +38,7 @@
#include "agg_conv_curve.h"
#include "agg_color_rgba.h"
#include "agg_bounding_rect.h"
+#pragma GCC diagnostic pop
// stl
#include <stdexcept>
diff --git a/include/mapnik/svg/svg_path_adapter.hpp b/include/mapnik/svg/svg_path_adapter.hpp
index 3b09af4..8b4fb6b 100644
--- a/include/mapnik/svg/svg_path_adapter.hpp
+++ b/include/mapnik/svg/svg_path_adapter.hpp
@@ -28,10 +28,12 @@
#include <mapnik/box2d.hpp>
#include <mapnik/safe_cast.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_math.h"
#include "agg_array.h"
#include "agg_bezier_arc.h"
+#pragma GCC diagnostic pop
// stl
#include <cmath>
diff --git a/include/mapnik/svg/svg_path_attributes.hpp b/include/mapnik/svg/svg_path_attributes.hpp
index d1b48aa..80bf463 100644
--- a/include/mapnik/svg/svg_path_attributes.hpp
+++ b/include/mapnik/svg/svg_path_attributes.hpp
@@ -23,15 +23,17 @@
#ifndef MAPNIK_SVG_PATH_ATTRIBUTES_HPP
#define MAPNIK_SVG_PATH_ATTRIBUTES_HPP
-// agg
-#include "agg_math_stroke.h"
-#include "agg_color_rgba.h"
-#include "agg_trans_affine.h"
-
// mapnik
#include <mapnik/gradient.hpp>
#include <mapnik/symbolizer_base.hpp> // dash_array
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
+#include "agg_math_stroke.h"
+#include "agg_color_rgba.h"
+#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
+
namespace mapnik {
namespace svg {
diff --git a/include/mapnik/svg/svg_path_commands.hpp b/include/mapnik/svg/svg_path_commands.hpp
index cf69e13..7e7ab5f 100644
--- a/include/mapnik/svg/svg_path_commands.hpp
+++ b/include/mapnik/svg/svg_path_commands.hpp
@@ -29,241 +29,130 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
#pragma GCC diagnostic pop
-namespace mapnik { namespace svg {
+namespace mapnik {
+namespace svg {
-using namespace boost::fusion;
inline double deg2rad(double deg)
{
- return (M_PI * deg)/180.0;
+ return (M_PI * deg) / 180.0;
}
-template <typename PathType>
struct move_to
{
+ using result_type = void;
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit move_to(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1>
- void operator() (T0 v, T1 rel) const
+ template <typename PathType, typename T0, typename T1>
+ void operator()(PathType& path, T0 v, T1 rel) const
{
- path_.move_to(at_c<0>(v),at_c<1>(v),rel); // impl
+ path.move_to(boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v), rel); // impl
}
-
- PathType & path_;
};
-template <typename PathType>
struct hline_to
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit hline_to(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1>
- void operator() (T0 const& x, T1 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1>
+ void operator()(PathType& path, T0 const& x, T1 rel) const
{
- path_.hline_to(x,rel);
+ path.hline_to(x, rel);
}
-
- PathType & path_;
};
-
-template <typename PathType>
struct vline_to
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit vline_to(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1>
- void operator() (T0 const& y, T1 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1>
+ void operator()(PathType& path, T0 const& y, T1 rel) const
{
- path_.vline_to(y,rel);
+ path.vline_to(y, rel);
}
-
- PathType & path_;
};
-template <typename PathType>
struct line_to
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit line_to(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1>
- void operator() (T0 const& v, T1 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1>
+ void operator()(PathType& path, T0 const& v, T1 rel) const
{
- path_.line_to(at_c<0>(v),at_c<1>(v),rel); // impl
+ path.line_to(boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v), rel); // impl
}
-
- PathType & path_;
};
-
-template <typename PathType>
struct curve4
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit curve4(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1,typename T2, typename T3>
- void operator() (T0 const& v0, T1 const& v1, T2 const& v2, T3 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1, typename T2, typename T3>
+ void operator()(PathType& path, T0 const& v0, T1 const& v1, T2 const& v2, T3 rel) const
{
- path_.curve4(at_c<0>(v0),at_c<1>(v0),
- at_c<0>(v1),at_c<1>(v1),
- at_c<0>(v2),at_c<1>(v2),
- rel); // impl
+ path.curve4(boost::fusion::at_c<0>(v0), boost::fusion::at_c<1>(v0),
+ boost::fusion::at_c<0>(v1), boost::fusion::at_c<1>(v1),
+ boost::fusion::at_c<0>(v2), boost::fusion::at_c<1>(v2),
+ rel); // impl
}
-
- PathType & path_;
};
-
-template <typename PathType>
struct curve4_smooth
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit curve4_smooth(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1,typename T2>
- void operator() (T0 const& v0, T1 const& v1, T2 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1, typename T2>
+ void operator()(PathType& path, T0 const& v0, T1 const& v1, T2 rel) const
{
- path_.curve4(at_c<0>(v0),at_c<1>(v0),
- at_c<0>(v1),at_c<1>(v1),
- rel); // impl
+ path.curve4(boost::fusion::at_c<0>(v0), boost::fusion::at_c<1>(v0),
+ boost::fusion::at_c<0>(v1), boost::fusion::at_c<1>(v1),
+ rel); // impl
}
- PathType & path_;
};
-template <typename PathType>
struct curve3
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit curve3(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1,typename T2>
- void operator() (T0 const& v0, T1 const& v1, T2 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1, typename T2>
+ void operator()(PathType& path, T0 const& v0, T1 const& v1, T2 rel) const
{
- path_.curve3(at_c<0>(v0),at_c<1>(v0),
- at_c<0>(v1),at_c<1>(v1),
- rel); // impl
+ path.curve3(boost::fusion::at_c<0>(v0), boost::fusion::at_c<1>(v0),
+ boost::fusion::at_c<0>(v1), boost::fusion::at_c<1>(v1),
+ rel); // impl
}
-
- PathType & path_;
};
-template <typename PathType>
struct curve3_smooth
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit curve3_smooth(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1>
- void operator() (T0 const& v0, T1 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1>
+ void operator()(PathType& path, T0 const& v0, T1 rel) const
{
- path_.curve3(at_c<0>(v0),at_c<1>(v0),
- rel); // impl
+ path.curve3(boost::fusion::at_c<0>(v0), boost::fusion::at_c<1>(v0),
+ rel); // impl
}
-
- PathType & path_;
};
-template <typename PathType>
struct arc_to
{
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit arc_to(PathType & path)
- : path_(path) {}
-
- template <typename T0, typename T1,typename T2, typename T3, typename T4, typename T5>
- void operator() (T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
+ using result_type = void;
+ template <typename PathType, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
+ void operator()(PathType& path, T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
{
- path_.arc_to(at_c<0>(rv),at_c<1>(rv),
- deg2rad(angle),large_arc_flag,sweep_flag,
- at_c<0>(v),at_c<1>(v),
- rel);
+ path.arc_to(boost::fusion::at_c<0>(rv), boost::fusion::at_c<1>(rv),
+ deg2rad(angle), large_arc_flag, sweep_flag,
+ boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v),
+ rel);
}
-
- PathType & path_;
};
-template <typename PathType>
struct close
{
using result_type = void;
-
- explicit close(PathType & path)
- : path_(path) {}
-
- void operator()() const
+ template <typename PathType>
+ void operator()(PathType& path) const
{
- path_.close_subpath();
+ path.close_subpath();
}
-
- PathType & path_;
};
-
-}}
-
+} // namespace svg
+} // namespace mapnik
#endif // MAPNIK_SVG_COMMANDS_HPP
diff --git a/include/mapnik/svg/svg_path_grammar.hpp b/include/mapnik/svg/svg_path_grammar.hpp
index 93d27f1..a65b272 100644
--- a/include/mapnik/svg/svg_path_grammar.hpp
+++ b/include/mapnik/svg/svg_path_grammar.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
@@ -23,116 +23,39 @@
#ifndef MAPNIK_SVG_PATH_GRAMMAR_HPP
#define MAPNIK_SVG_PATH_GRAMMAR_HPP
-// mapnik
-#include <mapnik/svg/svg_path_commands.hpp>
-
// spirit
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace svg {
- using namespace boost::spirit;
- using namespace boost::phoenix;
-
- template <typename Iterator, typename SkipType, typename PathType>
- struct svg_path_grammar : qi::grammar<Iterator,SkipType>
- {
- explicit svg_path_grammar(PathType & path)
- : svg_path_grammar::base_type(start),
- move_to_(move_to<PathType>(path)),
- hline_to_(hline_to<PathType>(path)),
- vline_to_(vline_to<PathType>(path)),
- line_to_(line_to<PathType>(path)),
- curve4_(curve4<PathType>(path)),
- curve4_smooth_(curve4_smooth<PathType>(path)),
- curve3_(curve3<PathType>(path)),
- curve3_smooth_(curve3_smooth<PathType>(path)),
- arc_to_(arc_to<PathType>(path)),
- close_(close<PathType>(path))
- {
- qi::_1_type _1;
- qi::_2_type _2;
- qi::_3_type _3;
- qi::_4_type _4;
- qi::_5_type _5;
- qi::_a_type _a;
- qi::lit_type lit;
- qi::double_type double_;
- qi::int_type int_;
- qi::no_case_type no_case;
-
- start = +cmd;
- cmd = M >> *drawto_cmd;
- drawto_cmd = L | H | V | C | S | Q | T | A | Z;
-
- M = (lit('M')[_a = false] | lit('m')[_a = true] )
- >> coord[move_to_(_1,_a)] // move_to
- >> *(-lit(',') >> coord [ line_to_(_1,_a) ] ); // *line_to
-
- H = (lit('H')[_a = false] | lit('h')[_a = true])
- >> (double_[ hline_to_(_1,_a) ] % -lit(',')) ; // +hline_to
-
- V = (lit('V')[_a = false] | lit('v')[_a = true])
- >> (double_ [ vline_to_(_1,_a) ] % -lit(',')); // +vline_to
-
- L = (lit('L')[_a = false] | lit('l')[_a = true])
- >> (coord [ line_to_(_1,_a) ] % -lit(',')); // +line_to
-
- C = (lit('C')[_a = false] | lit('c')[_a = true])
- >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord) [ curve4_(_1,_2,_3,_a) ] % -lit(',')); // +curve4
-
- S = (lit('S')[_a = false] | lit('s')[_a = true])
- >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto)
-
- Q = (lit('Q')[_a = false] | lit('q')[_a = true])
- >> ((coord >> -lit(',') >> coord) [ curve3_(_1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto)
-
- T = (lit('T')[_a = false] | lit('t')[_a = true])
- >> ((coord ) [ curve3_smooth_(_1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto)
-
- A = (lit('A')[_a = false] | lit('a')[_a = true])
- >> ((coord >> -lit(',') >> double_ >> -lit(',')
- >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) [arc_to_(_1,_2,_3,_4,_5,_a)] % -lit(',')); // arc_to;
-
- Z = no_case[lit('z')] [close_()]; // close path
-
- coord = double_ >> -lit(',') >> double_;
- }
-
- // rules
- qi::rule<Iterator,SkipType> start;
- qi::rule<Iterator,SkipType> cmd;
- qi::rule<Iterator,SkipType> drawto_cmd;
- qi::rule<Iterator,qi::locals<bool>,SkipType> M; // M,m
- qi::rule<Iterator,qi::locals<bool>,SkipType> L; // L,l
- qi::rule<Iterator,qi::locals<bool>,SkipType> H; // H,h
- qi::rule<Iterator,qi::locals<bool>,SkipType> V; // V,v
- qi::rule<Iterator,qi::locals<bool>,SkipType> C; // C,c
- qi::rule<Iterator,qi::locals<bool>,SkipType> S; // S,s
- qi::rule<Iterator,qi::locals<bool>,SkipType> Q; // Q,q
- qi::rule<Iterator,qi::locals<bool>,SkipType> T; // T,t
- qi::rule<Iterator,qi::locals<bool>,SkipType> A; // A,a
- qi::rule<Iterator,SkipType> Z; // Z,z
-
- qi::rule<Iterator,boost::fusion::vector2<double,double>(),SkipType> coord;
-
- // commands
- function<move_to<PathType> > move_to_;
- function<hline_to<PathType> > hline_to_;
- function<vline_to<PathType> > vline_to_;
- function<line_to<PathType> > line_to_;
- function<curve4<PathType> > curve4_;
- function<curve4_smooth<PathType> > curve4_smooth_;
- function<curve3<PathType> > curve3_;
- function<curve3_smooth<PathType> > curve3_smooth_;
- function<arc_to<PathType> > arc_to_;
- function<close<PathType> > close_;
- };
-
- }}
+using namespace boost::spirit;
+
+template <typename Iterator, typename PathType, typename SkipType>
+struct svg_path_grammar : qi::grammar<Iterator, void(PathType&), SkipType>
+{
+ // ctor
+ svg_path_grammar();
+ // rules
+ qi::rule<Iterator, void(PathType&), SkipType> start;
+ qi::rule<Iterator, void(PathType&), SkipType> cmd;
+ qi::rule<Iterator, void(PathType&), SkipType> drawto_cmd;
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> M; // M,m
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> L; // L,l
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> H; // H,h
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> V; // V,v
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> C; // C,c
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> S; // S,s
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> Q; // Q,q
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> T; // T,t
+ qi::rule<Iterator, qi::locals<bool>, void(PathType&), SkipType> A; // A,a
+ qi::rule<Iterator, void(PathType&), SkipType> Z; // Z,z
+ qi::rule<Iterator, boost::fusion::vector2<double, double>(), SkipType> coord;
+};
+
+}}
#endif // MAPNIK_SVG_PATH_GRAMMAR_HPP
diff --git a/include/mapnik/svg/svg_path_grammar_impl.hpp b/include/mapnik/svg/svg_path_grammar_impl.hpp
new file mode 100644
index 0000000..5d5fd1a
--- /dev/null
+++ b/include/mapnik/svg/svg_path_grammar_impl.hpp
@@ -0,0 +1,112 @@
+/*****************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+
+// NOTE: This is an implementation header file and is only meant to be included
+// from implementation files. It therefore doesn't have an include guard.
+
+// mapnik
+#include <mapnik/svg/svg_path_grammar.hpp>
+#include <mapnik/svg/svg_path_commands.hpp>
+
+// spirit
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#pragma GCC diagnostic pop
+
+namespace mapnik { namespace svg {
+
+using namespace boost::spirit;
+using namespace boost::phoenix;
+
+
+template <typename Iterator, typename PathType, typename SkipType>
+svg_path_grammar<Iterator, PathType, SkipType>::svg_path_grammar()
+ : svg_path_grammar::base_type(start)
+{
+ qi::_1_type _1;
+ qi::_2_type _2;
+ qi::_3_type _3;
+ qi::_4_type _4;
+ qi::_5_type _5;
+ qi::_a_type _a;
+ qi::lit_type lit;
+ qi::_r1_type _r1;
+ qi::double_type double_;
+ qi::int_type int_;
+ qi::no_case_type no_case;
+
+ // commands
+ function<move_to> move_to_;
+ function<hline_to> hline_to_;
+ function<vline_to> vline_to_;
+ function<line_to> line_to_;
+ function<curve4> curve4_;
+ function<curve4_smooth> curve4_smooth_;
+ function<curve3> curve3_;
+ function<curve3_smooth> curve3_smooth_;
+ function<arc_to> arc_to_;
+ function<close> close_;
+ //
+ start = +cmd(_r1);
+
+ cmd = M(_r1) >> *drawto_cmd(_r1);
+
+ drawto_cmd = L(_r1) | H(_r1) | V(_r1) | C(_r1) | S(_r1) | Q(_r1) | T(_r1) | A(_r1) | Z(_r1);
+
+ M = (lit('M')[_a = false] | lit('m')[_a = true]) >> coord[move_to_(_r1, _1, _a)] // move_to
+ >> *(-lit(',') >> coord[line_to_(_r1, _1, _a)]); // *line_to
+
+ H = (lit('H')[_a = false] | lit('h')[_a = true])
+ >> (double_[ hline_to_(_r1, _1,_a) ] % -lit(',')) ; // +hline_to
+
+ V = (lit('V')[_a = false] | lit('v')[_a = true])
+ >> (double_ [ vline_to_(_r1, _1,_a) ] % -lit(',')); // +vline_to
+
+ L = (lit('L')[_a = false] | lit('l')[_a = true])
+ >> (coord [ line_to_(_r1, _1, _a) ] % -lit(',')); // +line_to
+
+ C = (lit('C')[_a = false] | lit('c')[_a = true])
+ >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord)[curve4_(_r1, _1, _2, _3, _a)] % -lit(',')); // +curve4
+
+ S = (lit('S')[_a = false] | lit('s')[_a = true])
+ >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_r1, _1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto)
+
+ Q = (lit('Q')[_a = false] | lit('q')[_a = true])
+ >> ((coord >> -lit(',') >> coord) [ curve3_(_r1, _1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto)
+
+ T = (lit('T')[_a = false] | lit('t')[_a = true])
+ >> ((coord ) [ curve3_smooth_(_r1, _1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto)
+
+ A = (lit('A')[_a = false] | lit('a')[_a = true])
+ >> ((coord >> -lit(',') >> double_ >> -lit(',') >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord)
+ [arc_to_(_r1, _1, _2, _3, _4, _5, _a)] % -lit(',')); // arc_to;
+
+ Z = no_case[lit('z')] [close_(_r1)]; // close path
+
+ coord = double_ >> -lit(',') >> double_;
+}
+
+} // namespace svg
+} // namespace mapnik
diff --git a/include/mapnik/svg/svg_path_parser.hpp b/include/mapnik/svg/svg_path_parser.hpp
index 35303f9..5633b2e 100644
--- a/include/mapnik/svg/svg_path_parser.hpp
+++ b/include/mapnik/svg/svg_path_parser.hpp
@@ -23,20 +23,32 @@
#ifndef MAPNIK_SVG_PATH_PARSER_HPP
#define MAPNIK_SVG_PATH_PARSER_HPP
+// mapnik
#include <mapnik/config.hpp>
+#include <mapnik/svg/svg_converter.hpp>
+#include <mapnik/svg/svg_path_attributes.hpp>
+// stl
#include <string>
-namespace mapnik { namespace svg {
+namespace mapnik {
+namespace svg {
- template <typename PathType>
- bool parse_path(const char * wkt, PathType & p);
+template <typename PathType>
+bool parse_path(const char* wkt, PathType& p);
- template <typename PathType>
- bool parse_points(const char * wkt, PathType & p);
+template <typename PathType>
+bool parse_points(const char* wkt, PathType& p);
+
+template <typename TransformType>
+bool MAPNIK_DECL parse_svg_transform(const char* wkt, TransformType& tr);
+
+//
+extern template bool MAPNIK_DECL parse_path<svg_converter_type>(const char*, svg_converter_type&);
+extern template bool MAPNIK_DECL parse_points<svg_converter_type>(const char*, svg_converter_type&);
+extern template bool MAPNIK_DECL parse_svg_transform<svg_converter_type>(const char*, svg_converter_type&);
+}
+}
- template <typename TransformType>
- bool MAPNIK_DECL parse_svg_transform(const char * wkt, TransformType & tr);
-}}
#endif // MAPNIK_SVG_PATH_PARSER_HPP
diff --git a/include/mapnik/svg/svg_points_grammar.hpp b/include/mapnik/svg/svg_points_grammar.hpp
index 94602cc..afbe7ee 100644
--- a/include/mapnik/svg/svg_points_grammar.hpp
+++ b/include/mapnik/svg/svg_points_grammar.hpp
@@ -29,46 +29,22 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
#pragma GCC diagnostic pop
namespace mapnik { namespace svg {
- using namespace boost::spirit;
- using namespace boost::phoenix;
-
- template <typename Iterator, typename SkipType, typename PathType>
- struct svg_points_grammar : qi::grammar<Iterator,SkipType>
- {
- explicit svg_points_grammar(PathType & path)
- : svg_points_grammar::base_type(start),
- move_to_(move_to<PathType>(path)),
- line_to_(line_to<PathType>(path)),
- close_(close<PathType>(path))
- {
- qi::_1_type _1;
- qi::lit_type lit;
- qi::double_type double_;
-
- start = coord[move_to_(_1,false)] // move_to
- >> *(-lit(',') >> coord [ line_to_(_1,false) ] ); // *line_to
-
- coord = double_ >> -lit(',') >> double_;
- }
-
- // rules
- qi::rule<Iterator,SkipType> start;
- qi::rule<Iterator,boost::fusion::vector2<double,double>(),SkipType> coord;
-
- // commands
- function<move_to<PathType> > move_to_;
- function<line_to<PathType> > line_to_;
- function<close<PathType> > close_;
- };
-
- }}
-
+using namespace boost::spirit;
+using namespace boost::phoenix;
+
+template <typename Iterator, typename PathType, typename SkipType>
+struct svg_points_grammar : qi::grammar<Iterator, void(PathType&), SkipType>
+{
+ // ctor
+ svg_points_grammar();
+ // rules
+ qi::rule<Iterator, void(PathType&), SkipType> start;
+ qi::rule<Iterator, boost::fusion::vector2<double, double>(), SkipType> coord;
+};
+}}
#endif // SVG_POINTS_GRAMMAR_HPP
diff --git a/include/mapnik/svg/svg_points_grammar.hpp b/include/mapnik/svg/svg_points_grammar_impl.hpp
similarity index 54%
copy from include/mapnik/svg/svg_points_grammar.hpp
copy to include/mapnik/svg/svg_points_grammar_impl.hpp
index 94602cc..5d56f7e 100644
--- a/include/mapnik/svg/svg_points_grammar.hpp
+++ b/include/mapnik/svg/svg_points_grammar_impl.hpp
@@ -20,10 +20,10 @@
*
*****************************************************************************/
-#ifndef SVG_POINTS_GRAMMAR_HPP
-#define SVG_POINTS_GRAMMAR_HPP
-
+// NOTE: This is an implementation header file and is only meant to be included
+// from implementation files. It therefore doesn't have an include guard.
// mapnik
+#include <mapnik/svg/svg_points_grammar.hpp>
#include <mapnik/svg/svg_path_commands.hpp>
#pragma GCC diagnostic push
@@ -36,39 +36,26 @@
namespace mapnik { namespace svg {
- using namespace boost::spirit;
- using namespace boost::phoenix;
-
- template <typename Iterator, typename SkipType, typename PathType>
- struct svg_points_grammar : qi::grammar<Iterator,SkipType>
- {
- explicit svg_points_grammar(PathType & path)
- : svg_points_grammar::base_type(start),
- move_to_(move_to<PathType>(path)),
- line_to_(line_to<PathType>(path)),
- close_(close<PathType>(path))
- {
- qi::_1_type _1;
- qi::lit_type lit;
- qi::double_type double_;
-
- start = coord[move_to_(_1,false)] // move_to
- >> *(-lit(',') >> coord [ line_to_(_1,false) ] ); // *line_to
-
- coord = double_ >> -lit(',') >> double_;
- }
-
- // rules
- qi::rule<Iterator,SkipType> start;
- qi::rule<Iterator,boost::fusion::vector2<double,double>(),SkipType> coord;
-
- // commands
- function<move_to<PathType> > move_to_;
- function<line_to<PathType> > line_to_;
- function<close<PathType> > close_;
- };
-
- }}
-
-
-#endif // SVG_POINTS_GRAMMAR_HPP
+using namespace boost::spirit;
+using namespace boost::phoenix;
+
+template <typename Iterator, typename PathType, typename SkipType>
+svg_points_grammar<Iterator, PathType,SkipType>::svg_points_grammar()
+ : svg_points_grammar::base_type(start)
+{
+ qi::_1_type _1;
+ qi::_r1_type _r1;
+ qi::lit_type lit;
+ qi::double_type double_;
+ // commands
+ function<move_to> move_to_;
+ function<line_to> line_to_;
+ function<close> close_;
+
+ start = coord[move_to_(_r1, _1, false)] // move_to
+ >> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to
+
+ coord = double_ >> -lit(',') >> double_;
+}
+
+}}
diff --git a/include/mapnik/svg/svg_renderer_agg.hpp b/include/mapnik/svg/svg_renderer_agg.hpp
index 3c714cd..d99575b 100644
--- a/include/mapnik/svg/svg_renderer_agg.hpp
+++ b/include/mapnik/svg/svg_renderer_agg.hpp
@@ -37,7 +37,8 @@
#pragma GCC diagnostic pop
#endif
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
@@ -57,6 +58,7 @@
#include "agg_gradient_lut.h"
#include "agg_gamma_lut.h"
#include "agg_span_interpolator_linear.h"
+#pragma GCC diagnostic pop
namespace mapnik {
namespace svg {
diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp
index 1465f3a..895112d 100644
--- a/include/mapnik/svg/svg_transform_grammar.hpp
+++ b/include/mapnik/svg/svg_transform_grammar.hpp
@@ -26,240 +26,31 @@
// mapnik
#include <mapnik/global.hpp>
-// agg
-#include <agg_trans_affine.h>
-
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_function.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-#include <boost/spirit/include/phoenix_object.hpp>
#pragma GCC diagnostic pop
namespace mapnik { namespace svg {
- using namespace boost::spirit;
- using namespace boost::fusion;
- using namespace boost::phoenix;
-
- inline double deg2rad(double d)
- {
- return M_PI * d / 180.0;
- }
-
- template <typename TransformType>
- struct process_matrix
- {
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit process_matrix( TransformType & tr)
- :tr_(tr) {}
-
- void operator () (double a, double b, double c, double d, double e, double f) const
- {
- tr_ = agg::trans_affine(a,b,c,d,e,f) * tr_;
- }
-
- TransformType & tr_;
- };
-
- template <typename TransformType>
- struct process_rotate
- {
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit process_rotate( TransformType & tr)
- :tr_(tr) {}
-
- template <typename T0,typename T1,typename T2>
- void operator () (T0 a, T1 cx, T2 cy) const
- {
- if (cx == 0.0 && cy == 0.0)
- {
- tr_ = agg::trans_affine_rotation(deg2rad(a)) * tr_;
- }
- else
- {
- agg::trans_affine t = agg::trans_affine_translation(-cx,-cy);
- t *= agg::trans_affine_rotation(deg2rad(a));
- t *= agg::trans_affine_translation(cx, cy);
- tr_ = t * tr_;
- }
- }
-
- TransformType & tr_;
- };
-
- template <typename TransformType>
- struct process_translate
- {
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit process_translate( TransformType & tr)
- :tr_(tr) {}
-
- template <typename T0,typename T1>
- void operator () (T0 tx, T1 ty) const
- {
- if (ty) tr_ = agg::trans_affine_translation(tx,*ty) * tr_;
- else tr_ = agg::trans_affine_translation(tx,0.0) * tr_;
- }
-
- TransformType & tr_;
- };
-
- template <typename TransformType>
- struct process_scale
- {
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit process_scale( TransformType & tr)
- :tr_(tr) {}
-
- template <typename T0,typename T1>
- void operator () (T0 sx, T1 sy) const
- {
- if (sy) tr_ = agg::trans_affine_scaling(sx,*sy) * tr_;
- else tr_ = agg::trans_affine_scaling(sx,sx) * tr_;
- }
-
- TransformType & tr_;
- };
-
-
- template <typename TransformType>
- struct process_skew
- {
- template <typename T0>
- struct result
- {
- using type = void;
- };
-
- explicit process_skew( TransformType & tr)
- :tr_(tr) {}
-
- template <typename T0,typename T1>
- void operator () (T0 skew_x, T1 skew_y) const
- {
- tr_ = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr_;
- }
-
- TransformType & tr_;
- };
-
- // commented as this does not appear used and crashes clang when used with pch
- /*
- struct print_action
- {
- template <typename T>
- void operator()(T const& c, qi::unused_type, qi::unused_type) const
- {
- MAPNIK_LOG_DEBUG(svg) << typeid(c).name();
- }
- };
- */
-
- template <typename Iterator, typename SkipType, typename TransformType>
- struct svg_transform_grammar : qi::grammar<Iterator,SkipType>
- {
- explicit svg_transform_grammar(TransformType & tr)
- : svg_transform_grammar::base_type(start),
- matrix_action(process_matrix<TransformType>(tr)),
- rotate_action(process_rotate<TransformType>(tr)),
- translate_action(process_translate<TransformType>(tr)),
- scale_action(process_scale<TransformType>(tr)),
- skew_action(process_skew<TransformType>(tr))
- {
- qi::_1_type _1;
- qi::_2_type _2;
- qi::_3_type _3;
- qi::_4_type _4;
- qi::_5_type _5;
- qi::_6_type _6;
- qi::_a_type _a;
- qi::_b_type _b;
- qi::_c_type _c;
- qi::lit_type lit;
- qi::double_type double_;
- qi::no_case_type no_case;
-
- start = +transform_ ;
-
- transform_ = matrix | rotate | translate | scale | rotate | skewX | skewY ;
-
- matrix = no_case[lit("matrix")]
- >> lit('(')
- >> (
- double_ >> -lit(',')
- >> double_ >> -lit(',')
- >> double_ >> -lit(',')
- >> double_ >> -lit(',')
- >> double_ >> -lit(',')
- >> double_) [ matrix_action(_1,_2,_3,_4,_5,_6) ]
- >> lit(')')
- ;
-
- translate = no_case[lit("translate")]
- >> lit('(')
- >> (double_ >> -lit(',')
- >> -double_) [ translate_action(_1,_2) ]
- >> lit(')');
-
- scale = no_case[lit("scale")]
- >> lit('(')
- >> (double_ >> -lit(',')
- >> -double_ )[ scale_action(_1,_2)]
- >> lit(')');
-
- rotate = no_case[lit("rotate")]
- >> lit('(')
- >> double_[_a = _1] >> -lit(',')
- >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1])
- >> lit(')') [ rotate_action(_a,_b,_c)];
-
- skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_1, 0.0)] >> lit(')');
-
- skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(0.0, _1)] >> lit(')');
-
- }
-
- // rules
- qi::rule<Iterator,SkipType> start;
- qi::rule<Iterator,SkipType> transform_;
- qi::rule<Iterator,SkipType> matrix;
- qi::rule<Iterator,SkipType> translate;
- qi::rule<Iterator,SkipType> scale;
- qi::rule<Iterator,qi::locals<double,double,double>, SkipType> rotate;
- qi::rule<Iterator,SkipType> skewX;
- qi::rule<Iterator,SkipType> skewY;
-
- // actions
- function<process_matrix<TransformType> > matrix_action;
- function<process_rotate<TransformType> > rotate_action;
- function<process_translate<TransformType> > translate_action;
- function<process_scale<TransformType> > scale_action;
- function<process_skew<TransformType> > skew_action;
- };
-
- }}
+using namespace boost::spirit;
+
+template <typename Iterator, typename TransformType, typename SkipType>
+struct svg_transform_grammar : qi::grammar<Iterator, void(TransformType&), SkipType>
+{
+ // ctor
+ svg_transform_grammar();
+ // rules
+ qi::rule<Iterator, void(TransformType&), SkipType> start;
+ qi::rule<Iterator, void(TransformType&), SkipType> transform_;
+ qi::rule<Iterator, void(TransformType&), SkipType> matrix;
+ qi::rule<Iterator, void(TransformType&), SkipType> translate;
+ qi::rule<Iterator, void(TransformType&), SkipType> scale;
+ qi::rule<Iterator, qi::locals<double, double, double>, void(TransformType&), SkipType> rotate;
+ qi::rule<Iterator, void(TransformType&), SkipType> skewX;
+ qi::rule<Iterator, void(TransformType&), SkipType> skewY;
+};
+
+}}
#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP
diff --git a/include/mapnik/svg/svg_transform_grammar_impl.hpp b/include/mapnik/svg/svg_transform_grammar_impl.hpp
new file mode 100644
index 0000000..65c05ab
--- /dev/null
+++ b/include/mapnik/svg/svg_transform_grammar_impl.hpp
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 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
+ *
+ *****************************************************************************/
+
+// NOTE: This is an implementation header file and is only meant to be included
+// from implementation files. It therefore doesn't have an include guard.
+// mapnik
+#include <mapnik/svg/svg_transform_grammar.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
+#include <agg_trans_affine.h>
+#pragma GCC diagnostic pop
+
+namespace mapnik { namespace svg {
+
+using namespace boost::spirit;
+using namespace boost::fusion;
+using namespace boost::phoenix;
+
+inline double deg2rad(double d)
+{
+ return M_PI * d / 180.0;
+}
+
+struct process_matrix
+{
+ using result_type = void;
+ template <typename TransformType>
+ void operator () (TransformType & tr, double a, double b, double c, double d, double e, double f) const
+ {
+ tr = agg::trans_affine(a,b,c,d,e,f) * tr;
+ }
+};
+
+struct process_rotate
+{
+ using result_type = void;
+
+ template <typename TransformType, typename T0,typename T1,typename T2>
+ void operator () (TransformType & tr, T0 a, T1 cx, T2 cy) const
+ {
+ if (cx == 0.0 && cy == 0.0)
+ {
+ tr = agg::trans_affine_rotation(deg2rad(a)) * tr;
+ }
+ else
+ {
+ agg::trans_affine t = agg::trans_affine_translation(-cx,-cy);
+ t *= agg::trans_affine_rotation(deg2rad(a));
+ t *= agg::trans_affine_translation(cx, cy);
+ tr = t * tr;
+ }
+ }
+};
+
+struct process_translate
+{
+ using result_type = void;
+ template <typename TransformType, typename T0,typename T1>
+ void operator () (TransformType & tr, T0 tx, T1 ty) const
+ {
+ if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr;
+ else tr = agg::trans_affine_translation(tx,0.0) * tr;
+ }
+};
+
+struct process_scale
+{
+ using result_type = void;
+ template <typename TransformType, typename T0,typename T1>
+ void operator () (TransformType & tr, T0 sx, T1 sy) const
+ {
+ if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr;
+ else tr = agg::trans_affine_scaling(sx,sx) * tr;
+ }
+};
+
+
+struct process_skew
+{
+ using result_type = void;
+
+ template <typename TransformType, typename T0,typename T1>
+ void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const
+ {
+ tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr;
+ }
+};
+
+template <typename Iterator, typename TransformType, typename SkipType>
+svg_transform_grammar<Iterator, TransformType, SkipType>::svg_transform_grammar()
+ : svg_transform_grammar::base_type(start)
+{
+ qi::_1_type _1;
+ qi::_2_type _2;
+ qi::_3_type _3;
+ qi::_4_type _4;
+ qi::_5_type _5;
+ qi::_6_type _6;
+ qi::_a_type _a;
+ qi::_b_type _b;
+ qi::_c_type _c;
+ qi::_r1_type _r1;
+ qi::lit_type lit;
+ qi::double_type double_;
+ qi::no_case_type no_case;
+
+ // actions
+ function<process_matrix> matrix_action;
+ function<process_rotate> rotate_action;
+ function<process_translate> translate_action;
+ function<process_scale> scale_action;
+ function<process_skew> skew_action;
+
+ start = +transform_(_r1) ;
+
+ transform_ = matrix(_r1) | rotate(_r1) | translate(_r1) | scale(_r1) | rotate(_r1) | skewX(_r1) | skewY (_r1) ;
+
+ matrix = no_case[lit("matrix")] >> lit('(')
+ >> (double_ >> -lit(',')
+ >> double_ >> -lit(',')
+ >> double_ >> -lit(',')
+ >> double_ >> -lit(',')
+ >> double_ >> -lit(',')
+ >> double_)[matrix_action(_r1, _1, _2, _3, _4, _5, _6)] >> lit(')');
+
+ translate = no_case[lit("translate")]
+ >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')');
+
+ scale = no_case[lit("scale")]
+ >> lit('(') >> (double_ >> -lit(',') >> -double_)[scale_action(_r1, _1, _2)] >> lit(')');
+
+ rotate = no_case[lit("rotate")]
+ >> lit('(')
+ >> double_[_a = _1] >> -lit(',')
+ >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1])
+ >> lit(')') [ rotate_action(_r1, _a,_b,_c)];
+
+ skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')');
+
+ skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')');
+
+}
+
+}}
diff --git a/include/mapnik/symbolizer.hpp b/include/mapnik/symbolizer.hpp
index 39d650d..9308ecd 100644
--- a/include/mapnik/symbolizer.hpp
+++ b/include/mapnik/symbolizer.hpp
@@ -51,8 +51,10 @@
#include <map>
#include <tuple>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/text/face.hpp b/include/mapnik/text/face.hpp
index 87692ca..3d797a1 100644
--- a/include/mapnik/text/face.hpp
+++ b/include/mapnik/text/face.hpp
@@ -27,7 +27,9 @@
#include <mapnik/text/glyph_info.hpp>
#include <mapnik/util/noncopyable.hpp>
-// freetype2
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
extern "C"
{
#include <ft2build.h>
@@ -35,6 +37,8 @@ extern "C"
#include FT_STROKER_H
}
+#pragma GCC diagnostic pop
+
//stl
#include <memory>
#include <string>
diff --git a/include/mapnik/text/font_feature_settings.hpp b/include/mapnik/text/font_feature_settings.hpp
index 9d945fb..8bc3e33 100644
--- a/include/mapnik/text/font_feature_settings.hpp
+++ b/include/mapnik/text/font_feature_settings.hpp
@@ -31,8 +31,11 @@
#include <memory>
#include <limits>
#include <ostream>
-// harfbuzz
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <harfbuzz/hb.h>
+#pragma GCC diagnostic pop
// EqualityComparable
inline bool operator==(hb_feature_t const& lhs, hb_feature_t const& rhs)
@@ -86,7 +89,10 @@ inline bool operator==(font_feature_settings const& lhs, font_feature_settings c
constexpr unsigned int font_feature_range_global_start = 0u;
static const unsigned int font_feature_range_global_end = std::numeric_limits<unsigned int>::max();
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
constexpr hb_feature_t font_feature_liga_off = { HB_TAG('l', 'i', 'g', 'a'), 0, font_feature_range_global_start, font_feature_range_global_end };
+#pragma GCC diagnostic pop
} // mapnik namespace
diff --git a/include/mapnik/text/formatting/layout.hpp b/include/mapnik/text/formatting/layout.hpp
index dd7f4b0..6892ce7 100644
--- a/include/mapnik/text/formatting/layout.hpp
+++ b/include/mapnik/text/formatting/layout.hpp
@@ -26,7 +26,10 @@
#include <mapnik/text/formatting/base.hpp>
#include <mapnik/text/text_properties.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace formatting {
diff --git a/include/mapnik/text/glyph_positions.hpp b/include/mapnik/text/glyph_positions.hpp
index 72314c3..aa08e33 100644
--- a/include/mapnik/text/glyph_positions.hpp
+++ b/include/mapnik/text/glyph_positions.hpp
@@ -30,8 +30,10 @@
#include <mapnik/marker_cache.hpp>
#include <mapnik/text/glyph_info.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
//stl
#include <vector>
diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp
index 0f23bc8..8b574b0 100644
--- a/include/mapnik/text/harfbuzz_shaper.hpp
+++ b/include/mapnik/text/harfbuzz_shaper.hpp
@@ -36,12 +36,12 @@
#include <list>
#include <type_traits>
-// harfbuzz
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
-
-// icu
#include <unicode/uscript.h>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp
index bcd822b..39bc590 100644
--- a/include/mapnik/text/icu_shaper.hpp
+++ b/include/mapnik/text/icu_shaper.hpp
@@ -36,11 +36,12 @@
// stl
#include <list>
-// icu
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/unistr.h>
#include <unicode/ushape.h>
#include <unicode/schriter.h>
-
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/text/itemizer.hpp b/include/mapnik/text/itemizer.hpp
index b858944..5087ce0 100644
--- a/include/mapnik/text/itemizer.hpp
+++ b/include/mapnik/text/itemizer.hpp
@@ -34,10 +34,12 @@
#include <list>
#include <vector>
-// ICU
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/unistr.h>
#include <unicode/uscript.h>
#include <unicode/ubidi.h>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/include/mapnik/text/properties_util.hpp b/include/mapnik/text/properties_util.hpp
index 0fff84e..5b92ed3 100644
--- a/include/mapnik/text/properties_util.hpp
+++ b/include/mapnik/text/properties_util.hpp
@@ -26,11 +26,14 @@
#include <mapnik/symbolizer_base.hpp>
#include <mapnik/xml_node.hpp>
#include <mapnik/config_error.hpp>
-#include <boost/optional.hpp>
+
#include <string>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/optional.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace detail {
diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp
index a4cd76e..692ada3 100644
--- a/include/mapnik/text/renderer.hpp
+++ b/include/mapnik/text/renderer.hpp
@@ -28,7 +28,10 @@
#include <mapnik/image_compositing.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
#include <mapnik/util/noncopyable.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
#include <agg_trans_affine.h>
// freetype2
@@ -39,6 +42,8 @@ extern "C"
#include FT_STROKER_H
}
+#pragma GCC diagnostic pop
+
namespace mapnik
{
diff --git a/include/mapnik/text/scrptrun.hpp b/include/mapnik/text/scrptrun.hpp
index 67942b0..7c8063b 100644
--- a/include/mapnik/text/scrptrun.hpp
+++ b/include/mapnik/text/scrptrun.hpp
@@ -17,9 +17,12 @@
#ifndef __SCRPTRUN_H
#define __SCRPTRUN_H
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/utypes.h>
#include <unicode/uobject.h>
#include <unicode/uscript.h>
+#pragma GCC diagnostic pop
struct ScriptRecord
{
diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp
index 8a44bdd..6d6fbdc 100644
--- a/include/mapnik/text/symbolizer_helpers.hpp
+++ b/include/mapnik/text/symbolizer_helpers.hpp
@@ -59,7 +59,7 @@ struct placement_finder_adapter
};
-using vertex_converter_type = vertex_converter<clip_line_tag , transform_tag, affine_transform_tag, simplify_tag, smooth_tag>;
+using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag>;
class base_symbolizer_helper
{
diff --git a/include/mapnik/text/text_properties.hpp b/include/mapnik/text/text_properties.hpp
index 654921e..511ba3a 100644
--- a/include/mapnik/text/text_properties.hpp
+++ b/include/mapnik/text/text_properties.hpp
@@ -36,9 +36,11 @@
// stl
#include <map>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp
index df2b25a..b801429 100644
--- a/include/mapnik/tiff_io.hpp
+++ b/include/mapnik/tiff_io.hpp
@@ -28,6 +28,9 @@
#include <mapnik/image_any.hpp>
#include <mapnik/util/variant.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
extern "C"
{
#include <tiffio.h>
@@ -35,6 +38,9 @@ extern "C"
#define RealTIFFClose TIFFClose
}
+#pragma GCC diagnostic pop
+
+
//std
#include <memory>
diff --git a/include/mapnik/transform_expression.hpp b/include/mapnik/transform_expression.hpp
index 9714b1e..b43f691 100644
--- a/include/mapnik/transform_expression.hpp
+++ b/include/mapnik/transform_expression.hpp
@@ -30,11 +30,13 @@
#include <mapnik/expression_node_types.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/util/variant.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
-// fusion
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
+#pragma GCC diagnostic pop
// stl
#include <vector>
diff --git a/include/mapnik/transform_processor.hpp b/include/mapnik/transform_processor.hpp
index 2e4bfa3..b1d8eab 100644
--- a/include/mapnik/transform_processor.hpp
+++ b/include/mapnik/transform_processor.hpp
@@ -29,8 +29,11 @@
#include <mapnik/transform_expression.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/util/variant.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include <agg_trans_affine.h>
+#pragma GCC diagnostic pop
// stl
#include <cmath>
diff --git a/include/mapnik/unicode.hpp b/include/mapnik/unicode.hpp
index 59401ab..f3b270c 100644
--- a/include/mapnik/unicode.hpp
+++ b/include/mapnik/unicode.hpp
@@ -45,6 +45,10 @@ public:
private:
UConverter * conv_;
};
+
+// convinience method
+void MAPNIK_DECL to_utf8(mapnik::value_unicode_string const& input, std::string & target);
+
}
#endif // MAPNIK_UNICODE_HPP
diff --git a/include/mapnik/util/const_rendering_buffer.hpp b/include/mapnik/util/const_rendering_buffer.hpp
index 360eea5..97b98ca 100644
--- a/include/mapnik/util/const_rendering_buffer.hpp
+++ b/include/mapnik/util/const_rendering_buffer.hpp
@@ -25,7 +25,10 @@
#include <mapnik/safe_cast.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
+#pragma GCC diagnostic pop
#include <cstdint>
diff --git a/include/mapnik/util/file_io.hpp b/include/mapnik/util/file_io.hpp
index d3ffe90..b8bc22f 100644
--- a/include/mapnik/util/file_io.hpp
+++ b/include/mapnik/util/file_io.hpp
@@ -58,11 +58,16 @@ public:
}
}
- inline bool open() const
+ inline bool is_open() const
{
return file_ ? true : false;
}
+ explicit operator bool() const
+ {
+ return this->is_open();
+ }
+
inline std::FILE * get() const
{
return file_.get();
diff --git a/include/mapnik/util/geometry_to_ds_type.hpp b/include/mapnik/util/geometry_to_ds_type.hpp
index 58fc89d..e09808f 100644
--- a/include/mapnik/util/geometry_to_ds_type.hpp
+++ b/include/mapnik/util/geometry_to_ds_type.hpp
@@ -28,8 +28,13 @@
#include <mapnik/geometry.hpp>
#include <mapnik/datasource_geometry_type.hpp>
#include <mapnik/util/variant.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace util {
diff --git a/include/mapnik/util/geometry_to_geojson.hpp b/include/mapnik/util/geometry_to_geojson.hpp
index 5cccb09..71c867e 100644
--- a/include/mapnik/util/geometry_to_geojson.hpp
+++ b/include/mapnik/util/geometry_to_geojson.hpp
@@ -24,18 +24,13 @@
#define MAPNIK_GEOMETRY_TO_GEOJSON_HPP
// mapnik
+#include <mapnik/geometry.hpp>
-#include <mapnik/json/geometry_generator_grammar.hpp>
+#include <string>
namespace mapnik { namespace util {
-inline bool to_geojson(std::string & json, mapnik::geometry::geometry<double> const& geom)
-{
- using sink_type = std::back_insert_iterator<std::string>;
- static const mapnik::json::geometry_generator_grammar<sink_type, mapnik::geometry::geometry<double> > grammar;
- sink_type sink(json);
- return boost::spirit::karma::generate(sink, grammar, geom);
-}
+bool to_geojson(std::string & json, mapnik::geometry::geometry<double> const& geom);
}}
diff --git a/include/mapnik/util/path_iterator.hpp b/include/mapnik/util/path_iterator.hpp
index 319c346..19b69ce 100644
--- a/include/mapnik/util/path_iterator.hpp
+++ b/include/mapnik/util/path_iterator.hpp
@@ -26,8 +26,11 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/path.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/iterator/iterator_facade.hpp>
+#pragma GCC diagnostic pop
// stl
#include <tuple>
diff --git a/include/mapnik/util/spatial_index.hpp b/include/mapnik/util/spatial_index.hpp
index d207dba..7206677 100644
--- a/include/mapnik/util/spatial_index.hpp
+++ b/include/mapnik/util/spatial_index.hpp
@@ -47,12 +47,13 @@ bool check_spatial_index(InputStream& in)
return (std::strncmp(header, "mapnik-index",12) == 0);
}
-template <typename Value, typename Filter, typename InputStream>
+template <typename Value, typename Filter, typename InputStream, typename BBox = box2d<double> >
class spatial_index
{
+ using bbox_type = BBox;
public:
static void query(Filter const& filter, InputStream& in,std::vector<Value>& pos);
- static box2d<double> bounding_box( InputStream& in );
+ static bbox_type bounding_box( InputStream& in );
static void query_first_n(Filter const& filter, InputStream & in, std::vector<Value>& pos, std::size_t count);
private:
spatial_index();
@@ -60,25 +61,25 @@ private:
spatial_index(spatial_index const&);
spatial_index& operator=(spatial_index const&);
static int read_ndr_integer(InputStream& in);
- static void read_envelope(InputStream& in, box2d<double>& envelope);
+ static void read_envelope(InputStream& in, bbox_type& envelope);
static void query_node(Filter const& filter, InputStream& in, std::vector<Value> & results);
static void query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value> & results, std::size_t count);
};
-template <typename Value, typename Filter, typename InputStream>
-box2d<double> spatial_index<Value, Filter, InputStream>::bounding_box(InputStream& in)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+BBox spatial_index<Value, Filter, InputStream, BBox>::bounding_box(InputStream& in)
{
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
if (!check_spatial_index(in)) throw std::runtime_error("Invalid index file (regenerate with shapeindex)");
in.seekg(16 + 4, std::ios::beg);
- box2d<double> box;
+ typename spatial_index<Value, Filter, InputStream, BBox>::bbox_type box;
read_envelope(in, box);
in.seekg(0, std::ios::beg);
return box;
}
-template <typename Value, typename Filter, typename InputStream>
-void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+void spatial_index<Value, Filter, InputStream, BBox>::query(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
if (!check_spatial_index(in)) throw std::runtime_error("Invalid index file (regenerate with shapeindex)");
@@ -86,11 +87,11 @@ void spatial_index<Value, Filter, InputStream>::query(Filter const& filter, Inpu
query_node(filter, in, results);
}
-template <typename Value, typename Filter, typename InputStream>
-void spatial_index<Value, Filter, InputStream>::query_node(Filter const& filter, InputStream& in, std::vector<Value>& results)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+void spatial_index<Value, Filter, InputStream, BBox>::query_node(Filter const& filter, InputStream& in, std::vector<Value>& results)
{
int offset = read_ndr_integer(in);
- box2d<double> node_ext;
+ typename spatial_index<Value, Filter, InputStream, BBox>::bbox_type node_ext;
read_envelope(in, node_ext);
int num_shapes = read_ndr_integer(in);
if (!filter.pass(node_ext))
@@ -113,8 +114,8 @@ void spatial_index<Value, Filter, InputStream>::query_node(Filter const& filter,
}
}
-template <typename Value, typename Filter, typename InputStream>
-void spatial_index<Value, Filter, InputStream>::query_first_n(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+void spatial_index<Value, Filter, InputStream, BBox>::query_first_n(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
{
static_assert(std::is_standard_layout<Value>::value, "Values stored in quad-tree must be standard layout type");
if (!check_spatial_index(in)) throw std::runtime_error("Invalid index file (regenerate with shapeindex)");
@@ -122,12 +123,12 @@ void spatial_index<Value, Filter, InputStream>::query_first_n(Filter const& filt
query_first_n_impl(filter, in, results, count);
}
-template <typename Value, typename Filter, typename InputStream>
-void spatial_index<Value, Filter, InputStream>::query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+void spatial_index<Value, Filter, InputStream, BBox>::query_first_n_impl(Filter const& filter, InputStream& in, std::vector<Value>& results, std::size_t count)
{
if (results.size() == count) return;
int offset = read_ndr_integer(in);
- box2d<double> node_ext;
+ typename spatial_index<Value, Filter, InputStream, BBox>::bbox_type node_ext;
read_envelope(in, node_ext);
int num_shapes = read_ndr_integer(in);
if (!filter.pass(node_ext))
@@ -149,16 +150,16 @@ void spatial_index<Value, Filter, InputStream>::query_first_n_impl(Filter const&
}
}
-template <typename Value, typename Filter, typename InputStream>
-int spatial_index<Value, Filter, InputStream>::read_ndr_integer(InputStream& in)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+int spatial_index<Value, Filter, InputStream, BBox>::read_ndr_integer(InputStream& in)
{
char b[4];
in.read(b, 4);
return (b[0] & 0xff) | (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
}
-template <typename Value, typename Filter, typename InputStream>
-void spatial_index<Value, Filter, InputStream>::read_envelope(InputStream& in, box2d<double>& envelope)
+template <typename Value, typename Filter, typename InputStream, typename BBox>
+void spatial_index<Value, Filter, InputStream, BBox>::read_envelope(InputStream& in, BBox& envelope)
{
in.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
}
diff --git a/include/mapnik/util/variant.hpp b/include/mapnik/util/variant.hpp
index 61832a0..05dddec 100644
--- a/include/mapnik/util/variant.hpp
+++ b/include/mapnik/util/variant.hpp
@@ -24,9 +24,13 @@
#define MAPNIK_UTIL_VARIANT_HPP
#include <mapnik/config.hpp>
-#include <boost/mpl/vector.hpp> // spirit support
#include <mapbox/variant/variant.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/mpl/vector.hpp> // spirit support
+#pragma GCC diagnostic pop
+
namespace mapnik { namespace util {
template <typename T>
diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp
index c6a95d3..3bd59b4 100644
--- a/include/mapnik/value.hpp
+++ b/include/mapnik/value.hpp
@@ -24,805 +24,25 @@
#define MAPNIK_VALUE_HPP
// mapnik
+#include <mapnik/config.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value_hash.hpp>
-#include <mapnik/util/conversions.hpp>
#include <mapnik/util/variant.hpp>
-// stl
-#include <string>
-#include <cmath>
-#include <memory>
-
-#include <iosfwd>
-#include <cstddef>
-#include <new>
-#include <type_traits>
-
-// icu
-#include <unicode/unistr.h>
-#include <unicode/ustring.h>
namespace mapnik {
using value_base = util::variant<value_null, value_bool, value_integer,value_double, value_unicode_string>;
-inline void to_utf8(mapnik::value_unicode_string const& input, std::string & target)
-{
- target.clear(); // mimic previous target.assign(...) semantics
- input.toUTF8String(target); // this appends to target
-}
-
-namespace detail {
-
-namespace {
-template <typename T, typename U>
-struct both_arithmetic : std::integral_constant<bool,
- std::is_arithmetic<T>::value &&
- std::is_arithmetic<U>::value > {};
-
-struct equals
-{
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- return false;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- -> decltype(lhs == rhs)
- {
- return lhs == rhs;
- }
-};
-
-struct not_equal
-{
- // back compatibility shim to equate empty string with null for != test
- // https://github.com/mapnik/mapnik/issues/1859
- // TODO - consider removing entire specialization at Mapnik 3.1.x
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- if (rhs.isEmpty()) return false;
- return true;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- ->decltype(lhs != rhs)
- {
- return lhs != rhs;
- }
-};
-
-struct greater_than
-{
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- return false;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- ->decltype(lhs > rhs)
- {
- return lhs > rhs;
- }
-};
-
-struct greater_or_equal
-{
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- return false;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- ->decltype(lhs >= rhs)
- {
- return lhs >= rhs;
- }
-};
-
-struct less_than
-{
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- return false;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- ->decltype(lhs < rhs)
- {
- return lhs < rhs;
- }
-};
-
-struct less_or_equal
-{
- static bool apply(value_null, value_unicode_string const& rhs)
- {
- return false;
- }
-
- template <typename T>
- static auto apply(T const& lhs, T const& rhs)
- ->decltype(lhs <= rhs)
- {
- return lhs <= rhs;
- }
-};
-
-}
-
-template <typename Op, bool default_result>
-struct comparison
-{
- // special case for unicode_strings (fixes MSVC C4800)
- bool operator() (value_unicode_string const& lhs,
- value_unicode_string const& rhs) const
- {
- return Op::apply(lhs, rhs) ? true : false;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // special case for unicode_string and value_null
- //////////////////////////////////////////////////////////////////////////
-
- bool operator() (value_null const& lhs, value_unicode_string const& rhs) const
- {
- return Op::apply(lhs, rhs);
- }
- //////////////////////////////////////////////////////////////////////////
-
-
- // same types
- template <typename T>
- bool operator() (T lhs, T rhs) const
- {
- return Op::apply(lhs, rhs);
- }
-
- // both types are arithmetic - promote to the common type
- template <typename T, typename U, typename std::enable_if<both_arithmetic<T,U>::value, int>::type = 0>
- bool operator() (T const& lhs, U const& rhs) const
- {
- using common_type = typename std::common_type<T,U>::type;
- return Op::apply(static_cast<common_type>(lhs),static_cast<common_type>(rhs));
- }
-
- //
- template <typename T, typename U, typename std::enable_if<!both_arithmetic<T,U>::value, int>::type = 0>
- bool operator() (T const& lhs, U const& rhs) const
- {
- return default_result;
- }
-};
-
-template <typename V>
-struct add
-{
- using value_type = V;
- value_type operator() (value_unicode_string const& lhs ,
- value_unicode_string const& rhs ) const
- {
- return lhs + rhs;
- }
-
- value_type operator() (value_null const& lhs ,
- value_null const& rhs) const
- {
- return lhs;
- }
-
- value_type operator() (value_unicode_string const& lhs, value_null) const
- {
- return lhs;
- }
-
- value_type operator() (value_null, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename L>
- value_type operator() (L const& lhs, value_null const&) const
- {
- return lhs;
- }
-
- template <typename R>
- value_type operator() (value_null const&, R const& rhs) const
- {
- return rhs;
- }
-
- template <typename L>
- value_type operator() (L const& lhs , value_unicode_string const& rhs) const
- {
- std::string val;
- if (util::to_string(val,lhs))
- return value_unicode_string(val.c_str()) + rhs;
- return rhs;
- }
-
- template <typename R>
- value_type operator() (value_unicode_string const& lhs, R const& rhs) const
- {
- std::string val;
- if (util::to_string(val,rhs))
- return lhs + value_unicode_string(val.c_str());
- return lhs;
- }
-
- template <typename T1, typename T2>
- value_type operator() (T1 const& lhs, T2 const& rhs) const
- {
- return typename std::common_type<T1,T2>::type{ lhs + rhs };
- }
-
- value_type operator() (value_bool lhs, value_bool rhs) const
- {
- return value_integer(lhs + rhs);
- }
-};
-
-template <typename V>
-struct sub
-{
- using value_type = V;
-
- value_type operator() (value_null const& lhs ,
- value_null const& rhs) const
- {
- return lhs;
- }
-
- value_type operator() (value_null, value_unicode_string const& rhs) const
- {
- return rhs;
- }
- value_type operator() (value_unicode_string const& lhs, value_null) const
- {
- return lhs;
- }
-
- template <typename R>
- value_type operator() (value_unicode_string const& lhs, R const&) const
- {
- return lhs;
- }
-
- template <typename L>
- value_type operator() (L const&, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename L>
- value_type operator() (L const& lhs, value_null const&) const
- {
- return lhs;
- }
-
- template <typename R>
- value_type operator() (value_null const&, R const& rhs) const
- {
- return rhs;
- }
-
- template <typename T>
- value_type operator() (T lhs, T rhs) const
- {
- return lhs - rhs ;
- }
-
- value_type operator() (value_unicode_string const&,
- value_unicode_string const&) const
- {
- return value_type();
- }
-
- template <typename T1, typename T2>
- value_type operator() (T1 const& lhs, T2 const& rhs) const
- {
- return typename std::common_type<T1,T2>::type{ lhs - rhs };
- }
-
-
- value_type operator() (value_bool lhs, value_bool rhs) const
- {
- return value_integer(lhs - rhs);
- }
-};
-
-template <typename V>
-struct mult
-{
- using value_type = V;
-
- value_type operator() (value_null const& lhs ,
- value_null const& rhs) const
- {
- return lhs;
- }
-
- value_type operator() (value_unicode_string const& lhs, value_null) const
- {
- return lhs;
- }
-
- value_type operator() (value_null, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename L>
- value_type operator() (L const& lhs, value_null const&) const
- {
- return lhs;
- }
-
- template <typename R>
- value_type operator() (value_null const&, R const& rhs) const
- {
- return rhs;
- }
-
- template <typename R>
- value_type operator() (value_unicode_string const& lhs, R const&) const
- {
- return lhs;
- }
-
- template <typename L>
- value_type operator() (L const&, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename T>
- value_type operator() (T lhs, T rhs) const
- {
- return lhs * rhs;
- }
-
- value_type operator() (value_unicode_string const&,
- value_unicode_string const&) const
- {
- return value_type();
- }
-
- template <typename T1, typename T2>
- value_type operator() (T1 const& lhs, T2 const& rhs) const
- {
- return typename std::common_type<T1,T2>::type{ lhs * rhs };
- }
-
- value_type operator() (value_bool lhs, value_bool rhs) const
- {
- return value_integer(lhs * rhs);
- }
-};
-
-template <typename V>
-struct div
-{
- using value_type = V;
-
- value_type operator() (value_null const& lhs ,
- value_null const& rhs) const
- {
- return lhs;
- }
-
- value_type operator() (value_unicode_string const& lhs, value_null) const
- {
- return lhs;
- }
-
- value_type operator() (value_null, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename L>
- value_type operator() (L const& lhs, value_null const&) const
- {
- return lhs;
- }
-
- template <typename R>
- value_type operator() (value_null const&, R const& rhs) const
- {
- return rhs;
- }
-
- template <typename T>
- value_type operator() (T lhs, T rhs) const
- {
- if (rhs == 0) return value_type();
- return lhs / rhs;
- }
-
- value_type operator() (value_bool lhs, value_bool rhs) const
- {
- if (rhs == 0) return lhs;
- return value_integer(lhs) / value_integer(rhs);
- }
-
- value_type operator() (value_unicode_string const&,
- value_unicode_string const&) const
- {
- return value_type();
- }
-
- template <typename R>
- value_type operator() (value_unicode_string const& lhs, R const&) const
- {
- return lhs;
- }
-
- template <typename L>
- value_type operator() (L const&, value_unicode_string const& rhs) const
- {
- return rhs;
- }
-
- template <typename T1, typename T2>
- value_type operator() (T1 const& lhs, T2 const& rhs) const
- {
- if (rhs == 0) return value_type();
- using common_type = typename std::common_type<T1,T2>::type;
- return common_type(lhs)/common_type(rhs);
- }
-};
-
-template <typename V>
-struct mod
-{
- using value_type = V;
-
- template <typename T1, typename T2>
- value_type operator() (T1 const& lhs, T2 const&) const
- {
- return lhs;
- }
-
- template <typename T>
- value_type operator() (T lhs, T rhs) const
- {
- return lhs % rhs;
- }
-
- value_type operator() (value_unicode_string const&,
- value_unicode_string const&) const
- {
- return value_type();
- }
-
- value_type operator() (value_bool,
- value_bool) const
- {
- return false;
- }
-
- value_type operator() (value_double lhs, value_integer rhs) const
- {
- return std::fmod(lhs, static_cast<value_double>(rhs));
- }
-
- value_type operator() (value_integer lhs, value_double rhs) const
- {
- return std::fmod(static_cast<value_double>(lhs), rhs);
- }
-
- value_type operator() (value_double lhs, value_double rhs) const
- {
- return std::fmod(lhs, rhs);
- }
-};
-
-template <typename V>
-struct negate
-{
- using value_type = V;
-
- template <typename T>
- value_type operator() (T val) const
- {
- return -val;
- }
-
- value_type operator() (value_null val) const
- {
- return val;
- }
-
- value_type operator() (value_bool val) const
- {
- return val ? value_integer(-1) : value_integer(0);
- }
-
- value_type operator() (value_unicode_string const&) const
- {
- return value_type();
- }
-};
-
-// converters
-template <typename T>
-struct convert {};
-
-template <>
-struct convert<value_bool>
-{
- value_bool operator() (value_bool val) const
- {
- return val;
- }
-
- value_bool operator() (value_unicode_string const& ustr) const
- {
- return !ustr.isEmpty();
- }
-
- value_bool operator() (value_null const&) const
- {
- return false;
- }
-
- template <typename T>
- value_bool operator() (T val) const
- {
- return val > 0 ? true : false;
- }
-};
-
-template <>
-struct convert<value_double>
-{
- value_double operator() (value_double val) const
- {
- return val;
- }
-
- value_double operator() (value_integer val) const
- {
- return static_cast<value_double>(val);
- }
-
- value_double operator() (value_bool val) const
- {
- return static_cast<value_double>(val);
- }
-
- value_double operator() (std::string const& val) const
- {
- value_double result;
- if (util::string2double(val,result))
- return result;
- return 0;
- }
-
- value_double operator() (value_unicode_string const& val) const
- {
- std::string utf8;
- val.toUTF8String(utf8);
- return operator()(utf8);
- }
-
- value_double operator() (value_null const&) const
- {
- return 0.0;
- }
-};
-
-template <>
-struct convert<value_integer>
-{
- value_integer operator() (value_integer val) const
- {
- return val;
- }
-
- value_integer operator() (value_double val) const
- {
- return static_cast<value_integer>(rint(val));
- }
-
- value_integer operator() (value_bool val) const
- {
- return static_cast<value_integer>(val);
- }
-
- value_integer operator() (std::string const& val) const
- {
- value_integer result;
- if (util::string2int(val,result))
- return result;
- return value_integer(0);
- }
-
- value_integer operator() (value_unicode_string const& val) const
- {
- std::string utf8;
- val.toUTF8String(utf8);
- return operator()(utf8);
- }
-
- value_integer operator() (value_null const&) const
- {
- return value_integer(0);
- }
-};
-
-template <>
-struct convert<std::string>
-{
- template <typename T>
- std::string operator() (T val) const
- {
- std::string str;
- util::to_string(str, val);
- return str;
- }
-
- // specializations
- std::string operator() (value_unicode_string const& val) const
- {
- std::string utf8;
- val.toUTF8String(utf8);
- return utf8;
- }
-
- std::string operator() (value_double val) const
- {
- std::string str;
- util::to_string(str, val); // TODO set precision(16)
- return str;
- }
-
- std::string operator() (value_bool val) const
- {
- return val ? "true": "false";
- }
-
- std::string operator() (value_null const&) const
- {
- return std::string();
- }
-};
-
-struct to_unicode_impl
-{
-
- template <typename T>
- value_unicode_string operator() (T val) const
- {
- std::string str;
- util::to_string(str,val);
- return value_unicode_string(str.c_str());
- }
-
- // specializations
- value_unicode_string const& operator() (value_unicode_string const& val) const
- {
- return val;
- }
-
- value_unicode_string operator() (value_double val) const
- {
- std::string str;
- util::to_string(str,val);
- return value_unicode_string(str.c_str());
- }
-
- value_unicode_string operator() (value_bool val) const
- {
- return value_unicode_string(val ? "true" : "false");
- }
-
- value_unicode_string operator() (value_null const&) const
- {
- return value_unicode_string();
- }
-};
-
-struct to_expression_string_impl
-{
- struct EscapingByteSink : U_NAMESPACE_QUALIFIER ByteSink
- {
- std::string dest_;
- char quote_;
-
- explicit EscapingByteSink(char quote)
- : quote_(quote)
- {}
-
- virtual void Append(const char* data, int32_t n)
- {
- // reserve enough room to hold the appended chunk and quotes;
- // if another chunk follows, or any character needs escaping,
- // the string will grow naturally
- if (dest_.empty())
- {
- dest_.reserve(2 + static_cast<std::size_t>(n));
- dest_.append(1, quote_);
- }
- else
- {
- dest_.reserve(dest_.size() + n + 1);
- }
-
- for (auto end = data + n; data < end; ++data)
- {
- if (*data == '\\' || *data == quote_)
- dest_.append(1, '\\');
- dest_.append(1, *data);
- }
- }
-
- virtual void Flush()
- {
- if (dest_.empty())
- dest_.append(2, quote_);
- else
- dest_.append(1, quote_);
- }
- };
-
- explicit to_expression_string_impl(char quote = '\'')
- : quote_(quote) {}
-
- std::string operator() (value_unicode_string const& val) const
- {
- EscapingByteSink sink(quote_);
- val.toUTF8(sink);
- return sink.dest_;
- }
-
- std::string operator() (value_integer val) const
- {
- std::string output;
- util::to_string(output,val);
- return output;
- }
-
- std::string operator() (value_double val) const
- {
- std::string output;
- util::to_string(output,val); // TODO precision(16)
- return output;
- }
-
- std::string operator() (value_bool val) const
- {
- return val ? "true" : "false";
- }
-
- std::string operator() (value_null const&) const
- {
- return "null";
- }
-
- const char quote_;
-};
-
-
-} // namespace detail
-
namespace value_adl_barrier {
-class value : public value_base
+class MAPNIK_DECL value : public value_base
{
- friend const value operator+(value const&,value const&);
- friend const value operator-(value const&,value const&);
- friend const value operator*(value const&,value const&);
- friend const value operator/(value const&,value const&);
- friend const value operator%(value const&,value const&);
+ friend MAPNIK_DECL value operator+(value const&,value const&);
+ friend MAPNIK_DECL value operator-(value const&,value const&);
+ friend MAPNIK_DECL value operator*(value const&,value const&);
+ friend MAPNIK_DECL value operator/(value const&,value const&);
+ friend MAPNIK_DECL value operator%(value const&,value const&);
public:
value() = default;
@@ -856,104 +76,32 @@ public:
return *this;
}
- bool operator==(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::equals, false>(), *this, other);
- }
+ bool operator==(value const& other) const;
+ bool operator!=(value const& other) const;
+ bool operator>(value const& other) const;
+ bool operator>=(value const& other) const;
+ bool operator<(value const& other) const;
+ bool operator<=(value const& other) const;
- bool operator!=(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::not_equal, true>(), *this, other);
- }
-
- bool operator>(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::greater_than, false>(), *this, other);
- }
-
- bool operator>=(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::greater_or_equal, false>(), *this, other);
- }
-
- bool operator<(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::less_than, false>(), *this, other);
- }
-
- bool operator<=(value const& other) const
- {
- return util::apply_visitor(detail::comparison<detail::less_or_equal, false>(), *this, other);
- }
-
- value operator- () const
- {
- return util::apply_visitor(detail::negate<value>(), *this);
- }
+ value operator-() const;
bool is_null() const;
- template <typename T>
- T convert() const
- {
- return util::apply_visitor(detail::convert<T>(),*this);
- }
-
- value_bool to_bool() const
- {
- return util::apply_visitor(detail::convert<value_bool>(),*this);
- }
-
- std::string to_expression_string(char quote = '\'') const
- {
- return util::apply_visitor(detail::to_expression_string_impl(quote),*this);
- }
-
- std::string to_string() const
- {
- return util::apply_visitor(detail::convert<std::string>(),*this);
- }
+ template <typename T> T convert() const;
- value_unicode_string to_unicode() const
- {
- return util::apply_visitor(detail::to_unicode_impl(),*this);
- }
-
- value_double to_double() const
- {
- return util::apply_visitor(detail::convert<value_double>(),*this);
- }
-
- value_integer to_int() const
- {
- return util::apply_visitor(detail::convert<value_integer>(),*this);
- }
+ value_bool to_bool() const;
+ std::string to_expression_string(char quote = '\'') const;
+ std::string to_string() const;
+ value_unicode_string to_unicode() const;
+ value_double to_double() const;
+ value_integer to_int() const;
};
-inline const value operator+(value const& p1,value const& p2)
-{
- return value(util::apply_visitor(detail::add<value>(),p1, p2));
-}
-
-inline const value operator-(value const& p1,value const& p2)
-{
- return value(util::apply_visitor(detail::sub<value>(),p1, p2));
-}
-
-inline const value operator*(value const& p1,value const& p2)
-{
- return value(util::apply_visitor(detail::mult<value>(),p1, p2));
-}
-
-inline const value operator/(value const& p1,value const& p2)
-{
- return value(util::apply_visitor(detail::div<value>(),p1, p2));
-}
-
-inline const value operator%(value const& p1,value const& p2)
-{
- return value(util::apply_visitor(detail::mod<value>(),p1, p2));
-}
+MAPNIK_DECL value operator+(value const& p1,value const& p2);
+MAPNIK_DECL value operator-(value const& p1,value const& p2);
+MAPNIK_DECL value operator*(value const& p1,value const& p2);
+MAPNIK_DECL value operator/(value const& p1,value const& p2);
+MAPNIK_DECL value operator%(value const& p1,value const& p2);
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits>&
@@ -972,36 +120,28 @@ inline std::size_t hash_value(value const& val)
} // namespace value_adl_barrier
-using value_adl_barrier::value;
+using value = value_adl_barrier::value;
namespace detail {
-
struct is_null_visitor
{
- bool operator() (value const& val) const
+ bool operator()(value const& val) const
{
return val.is_null();
}
- bool operator() (value_null const&) const
+ bool operator()(value_null const&) const
{
return true;
}
template <typename T>
- bool operator() (T const&) const
+ bool operator()(T const&) const
{
return false;
}
};
-
} // namespace detail
-
-inline bool value::is_null() const
-{
- return util::apply_visitor(mapnik::detail::is_null_visitor(), *this);
-}
-
} // namespace mapnik
// support for std::unordered_xxx
diff --git a/include/mapnik/value_hash.hpp b/include/mapnik/value_hash.hpp
index c1f1d60..b050e37 100644
--- a/include/mapnik/value_hash.hpp
+++ b/include/mapnik/value_hash.hpp
@@ -30,8 +30,10 @@
// stl
#include <functional>
-// icu
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/unistr.h>
+#pragma GCC diagnostic pop
namespace mapnik { namespace detail {
diff --git a/include/mapnik/value_types.hpp b/include/mapnik/value_types.hpp
index 85a015b..235133a 100644
--- a/include/mapnik/value_types.hpp
+++ b/include/mapnik/value_types.hpp
@@ -27,8 +27,11 @@
#include <mapnik/config.hpp>
#include <mapnik/pixel_types.hpp>
-// icu
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/uversion.h> // for U_NAMESPACE_QUALIFIER
+#pragma GCC diagnostic pop
// stl
#include <type_traits>
diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp
index a105bec..e1a367b 100644
--- a/include/mapnik/version.hpp
+++ b/include/mapnik/version.hpp
@@ -23,17 +23,14 @@
#ifndef MAPNIK_VERSION_HPP
#define MAPNIK_VERSION_HPP
+#include <mapnik/stringify_macro.hpp>
+
#define MAPNIK_MAJOR_VERSION 3
#define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 10
+#define MAPNIK_PATCH_VERSION 11
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
-#ifndef MAPNIK_STRINGIFY
-#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n)
-#define MAPNIK_STRINGIFY_HELPER(n) #n
-#endif
-
#define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION)
diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp
index ae5f0d4..3a41bee 100644
--- a/include/mapnik/vertex_adapters.hpp
+++ b/include/mapnik/vertex_adapters.hpp
@@ -34,32 +34,10 @@ struct point_vertex_adapter
{
using value_type = typename point<T>::value_type;
- point_vertex_adapter(point<T> const& pt)
- : pt_(pt),
- first_(true) {}
-
- unsigned vertex(value_type * x, value_type * y) const
- {
- if (first_)
- {
- *x = pt_.x;
- *y = pt_.y;
- first_ = false;
- return mapnik::SEG_MOVETO;
- }
- return mapnik::SEG_END;
- }
-
- void rewind(unsigned) const
- {
- first_ = true;
- }
-
- inline geometry_types type () const
- {
- return geometry_types::Point;
- }
-
+ point_vertex_adapter(point<T> const& pt);
+ unsigned vertex(value_type * x, value_type * y) const;
+ void rewind(unsigned) const;
+ geometry_types type () const;
point<T> const& pt_;
mutable bool first_;
};
@@ -68,110 +46,23 @@ template <typename T>
struct line_string_vertex_adapter
{
using value_type = typename point<T>::value_type;
- line_string_vertex_adapter(line_string<T> const& line)
- : line_(line),
- current_index_(0),
- end_index_(line.size())
- {}
-
- unsigned vertex(value_type * x, value_type * y) const
- {
- if (current_index_ != end_index_)
- {
- point<T> const& coord = line_[current_index_++];
- *x = coord.x;
- *y = coord.y;
- if (current_index_ == 1)
- {
- return mapnik::SEG_MOVETO;
- }
- else
- {
- return mapnik::SEG_LINETO;
- }
- }
- return mapnik::SEG_END;
- }
-
- void rewind(unsigned) const
- {
- current_index_ = 0;
- }
-
- inline geometry_types type () const
- {
- return geometry_types::LineString;
- }
-
+ line_string_vertex_adapter(line_string<T> const& line);
+ unsigned vertex(value_type * x, value_type * y) const;
+ void rewind(unsigned) const;
+ geometry_types type () const;
line_string<T> const& line_;
mutable std::size_t current_index_;
- const std::size_t end_index_;
-
+ const std::size_t end_index_;
};
template <typename T>
struct polygon_vertex_adapter
{
using value_type = typename point<T>::value_type;
- polygon_vertex_adapter(polygon<T> const& poly)
- : poly_(poly),
- rings_itr_(0),
- rings_end_(poly_.interior_rings.size() + 1),
- current_index_(0),
- end_index_((rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0),
- start_loop_(true) {}
-
- void rewind(unsigned) const
- {
- rings_itr_ = 0;
- rings_end_ = poly_.interior_rings.size() + 1;
- current_index_ = 0;
- end_index_ = (rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0;
- start_loop_ = true;
- }
-
- unsigned vertex(value_type * x, value_type * y) const
- {
- if (rings_itr_ == rings_end_)
- {
- return mapnik::SEG_END;
- }
- if (current_index_ < end_index_)
- {
- point<T> const& coord = (rings_itr_ == 0) ?
- poly_.exterior_ring[current_index_++] : poly_.interior_rings[rings_itr_- 1][current_index_++];
- *x = coord.x;
- *y = coord.y;
- if (start_loop_)
- {
- start_loop_= false;
- return mapnik::SEG_MOVETO;
- }
- if (current_index_ == end_index_)
- {
- *x = 0;
- *y = 0;
- return mapnik::SEG_CLOSE;
- }
- return mapnik::SEG_LINETO;
- }
- else if (++rings_itr_ != rings_end_)
- {
- current_index_ = 0;
- end_index_ = poly_.interior_rings[rings_itr_ - 1].size();
- point<T> const& coord = poly_.interior_rings[rings_itr_ - 1][current_index_++];
- *x = coord.x;
- *y = coord.y;
- return mapnik::SEG_MOVETO;
- }
- return mapnik::SEG_END;
- }
-
- inline geometry_types type () const
- {
- return geometry_types::Polygon;
- }
-
+ polygon_vertex_adapter(polygon<T> const& poly);
+ void rewind(unsigned) const;
+ unsigned vertex(value_type * x, value_type * y) const;
+ geometry_types type () const;
private:
polygon<T> const& poly_;
mutable std::size_t rings_itr_;
@@ -185,47 +76,10 @@ template <typename T>
struct ring_vertex_adapter
{
using value_type = typename point<T>::value_type;
- ring_vertex_adapter(linear_ring<T> const& ring)
- : ring_(ring),
- current_index_(0),
- end_index_(ring_.size()),
- start_loop_(true) {}
-
- void rewind(unsigned) const
- {
- current_index_ = 0;
- end_index_ = ring_.size();
- start_loop_ = true;
- }
-
- unsigned vertex(value_type * x, value_type * y) const
- {
- if (current_index_ < end_index_)
- {
- auto const& coord = ring_[current_index_++];
- *x = coord.x;
- *y = coord.y;
- if (start_loop_)
- {
- start_loop_= false;
- return mapnik::SEG_MOVETO;
- }
- if (current_index_ == end_index_)
- {
- *x = 0;
- *y = 0;
- return mapnik::SEG_CLOSE;
- }
- return mapnik::SEG_LINETO;
- }
- return mapnik::SEG_END;
- }
-
- inline geometry_types type () const
- {
- return geometry_types::Polygon;
- }
-
+ ring_vertex_adapter(linear_ring<T> const& ring);
+ void rewind(unsigned) const;
+ unsigned vertex(value_type * x, value_type * y) const;
+ geometry_types type () const;
private:
linear_ring<T> const& ring_;
mutable std::size_t current_index_;
@@ -233,6 +87,11 @@ private:
mutable bool start_loop_;
};
+extern template struct MAPNIK_DECL point_vertex_adapter<double>;
+extern template struct MAPNIK_DECL line_string_vertex_adapter<double>;
+extern template struct MAPNIK_DECL polygon_vertex_adapter<double>;
+extern template struct MAPNIK_DECL ring_vertex_adapter<double>;
+
template <typename T>
struct vertex_adapter_traits {};
diff --git a/include/mapnik/vertex_cache.hpp b/include/mapnik/vertex_cache.hpp
index a0a32e9..9df786e 100644
--- a/include/mapnik/vertex_cache.hpp
+++ b/include/mapnik/vertex_cache.hpp
@@ -28,8 +28,10 @@
#include <mapnik/config.hpp>
#include <mapnik/util/noncopyable.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
+#pragma GCC diagnostic pop
// stl
#include <vector>
diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp
index f10f720..ba18294 100644
--- a/include/mapnik/vertex_converters.hpp
+++ b/include/mapnik/vertex_converters.hpp
@@ -37,7 +37,8 @@
#include <mapnik/symbolizer_keys.hpp>
#include <mapnik/symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_math_stroke.h"
#include "agg_trans_affine.h"
#include "agg_conv_clip_polygon.h"
@@ -46,6 +47,7 @@
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
#include "agg_conv_transform.h"
+#pragma GCC diagnostic pop
// stl
#include <type_traits>
@@ -275,7 +277,7 @@ template <typename Dispatcher, typename... ConverterTypes>
struct converters_helper;
template <typename Dispatcher, typename Current, typename... ConverterTypes>
-struct converters_helper<Dispatcher,Current,ConverterTypes...>
+struct converters_helper<Dispatcher, Current, ConverterTypes...>
{
template <typename Converter>
static void set(Dispatcher & disp, std::size_t state)
diff --git a/include/mapnik/warning_ignore.hpp b/include/mapnik/warning_ignore.hpp
index a9856b9..62b7899 100644
--- a/include/mapnik/warning_ignore.hpp
+++ b/include/mapnik/warning_ignore.hpp
@@ -32,4 +32,25 @@
#pragma GCC diagnostic ignored "-Wc++11-narrowing"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wsign-compare"
-#pragma GCC diagnostic ignored "-Wconversion"
\ No newline at end of file
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic"
+#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic ignored "-Wdocumentation"
+#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wdeprecated"
+#pragma GCC diagnostic ignored "-Wpadded"
+#pragma GCC diagnostic ignored "-Wc++98-compat"
+#pragma GCC diagnostic ignored "-Wreserved-id-macro"
+#pragma GCC diagnostic ignored "-Wweak-vtables"
+#pragma GCC diagnostic ignored "-Wextra-semi"
+#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic"
+#pragma GCC diagnostic ignored "-Wglobal-constructors"
+#pragma GCC diagnostic ignored "-Wheader-hygiene"
+#pragma GCC diagnostic ignored "-Wexit-time-destructors"
+#pragma GCC diagnostic ignored "-Wswitch-enum"
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#pragma GCC diagnostic ignored "-Wcovered-switch-default"
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+
diff --git a/include/mapnik/warning_ignore.hpp b/include/mapnik/warning_ignore_agg.hpp
similarity index 77%
copy from include/mapnik/warning_ignore.hpp
copy to include/mapnik/warning_ignore_agg.hpp
index a9856b9..2f44c5c 100644
--- a/include/mapnik/warning_ignore.hpp
+++ b/include/mapnik/warning_ignore_agg.hpp
@@ -23,13 +23,10 @@
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
-#pragma GCC diagnostic ignored "-Wunsequenced"
-#pragma GCC diagnostic ignored "-Wunused-function"
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#pragma GCC diagnostic ignored "-Wredeclared-class-member"
-#pragma GCC diagnostic ignored "-Wunused-local-typedef"
-#pragma GCC diagnostic ignored "-Wshadow"
-#pragma GCC diagnostic ignored "-Wc++11-narrowing"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wsign-compare"
-#pragma GCC diagnostic ignored "-Wconversion"
\ No newline at end of file
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wpadded"
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic ignored "-Wshadow"
+
diff --git a/include/mapnik/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp
index eeb478e..e8349e7 100644
--- a/include/mapnik/well_known_srs.hpp
+++ b/include/mapnik/well_known_srs.hpp
@@ -28,8 +28,10 @@
#include <mapnik/enumeration.hpp>
#include <mapnik/geometry.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <cmath>
@@ -63,7 +65,8 @@ boost::optional<bool> is_known_geographic(std::string const& srs);
static inline bool lonlat2merc(double * x, double * y , int point_count)
{
- for(int i=0; i<point_count; i++) {
+ for(int i=0; i<point_count; ++i)
+ {
if (x[i] > 180) x[i] = 180;
else if (x[i] < -180) x[i] = -180;
if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE;
diff --git a/include/mapnik/wkb.hpp b/include/mapnik/wkb.hpp
index 53f1e85..98b3d30 100644
--- a/include/mapnik/wkb.hpp
+++ b/include/mapnik/wkb.hpp
@@ -60,9 +60,11 @@ class MAPNIK_DECL geometry_utils : private util::noncopyable
{
public:
- static mapnik::geometry::geometry<double> from_wkb(const char* wkb,
- std::size_t size,
- wkbFormat format = wkbGeneric);
+ static geometry::geometry<double> from_wkb(char const* wkb,
+ std::size_t size,
+ wkbFormat format = wkbGeneric);
+
+ static geometry::geometry<double> from_twkb(char const* twkb, std::size_t size);
};
}
diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp
index 0c89601..892e551 100644
--- a/include/mapnik/wkt/wkt_generator_grammar.hpp
+++ b/include/mapnik/wkt/wkt_generator_grammar.hpp
@@ -27,7 +27,6 @@
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_type.hpp>
-#include <mapnik/geometry_fusion_adapted.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp
index 7205db6..8d950ed 100644
--- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp
+++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp
@@ -20,11 +20,15 @@
*
*****************************************************************************/
-#include <mapnik/geometry.hpp>
+// mapnik
#include <mapnik/wkt/wkt_generator_grammar.hpp>
#include <mapnik/util/spirit_transform_attribute.hpp>
-// boost
+#include <mapnik/geometry_fusion_adapted.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/phoenix.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace wkt {
diff --git a/include/mapnik/wkt/wkt_grammar.hpp b/include/mapnik/wkt/wkt_grammar.hpp
index a91f436..9d23f81 100644
--- a/include/mapnik/wkt/wkt_grammar.hpp
+++ b/include/mapnik/wkt/wkt_grammar.hpp
@@ -24,9 +24,8 @@
#define MAPNIK_WKT_GRAMMAR_HPP
// mapnik
+#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp>
-#include <mapnik/geometry_fusion_adapted.hpp>
-
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/assert.hpp>
diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp
index 85a9274..d244413 100644
--- a/include/mapnik/wkt/wkt_grammar_impl.hpp
+++ b/include/mapnik/wkt/wkt_grammar_impl.hpp
@@ -20,14 +20,18 @@
*
*****************************************************************************/
-#include <mapnik/config.hpp>
#include <mapnik/wkt/wkt_grammar.hpp>
+#include <mapnik/geometry_fusion_adapted.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/phoenix/object/construct.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace wkt {
diff --git a/include/mapnik/xml_node.hpp b/include/mapnik/xml_node.hpp
index 1c36021..bf7130c 100644
--- a/include/mapnik/xml_node.hpp
+++ b/include/mapnik/xml_node.hpp
@@ -26,8 +26,10 @@
//mapnik
#include <mapnik/config.hpp> // for MAPNIK_DECL
-//boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
//stl
#include <list>
diff --git a/mason_latest.sh b/mason_latest.sh
index 62a0c94..7b3e02a 100755
--- a/mason_latest.sh
+++ b/mason_latest.sh
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
+set -eu
+
MASON_NAME=mapnik
MASON_VERSION=latest
MASON_LIB_FILE=lib/libmapnik-wkt.a
@@ -13,21 +15,38 @@ function mason_load_source {
function mason_compile {
HERE=$(pwd)
make install
- if [[ `uname` == 'Darwin' ]]; then
- install_name_tool -id @loader_path/libmapnik.dylib ${MASON_PREFIX}"/lib/libmapnik.dylib";
+ # this is to adapt to when mapnik is not installed in MASON_PREFIX
+ # originally (to make it easier to publish locally as a stopgap)
+ MAPNIK_PREFIX=$(mapnik-config --prefix)
+ if [[ ${MAPNIK_PREFIX} != ${MASON_PREFIX} ]]; then
+ mkdir -p ${MASON_PREFIX}/lib
+ mkdir -p ${MASON_PREFIX}/include
+ mkdir -p ${MASON_PREFIX}/bin
+ cp -r ${MAPNIK_PREFIX}/lib/*mapnik* ${MASON_PREFIX}/lib/
+ cp -r ${MAPNIK_PREFIX}/include/mapnik ${MASON_PREFIX}/include/
+ cp -r ${MAPNIK_PREFIX}/bin/mapnik* ${MASON_PREFIX}/bin/
+ cp -r ${MAPNIK_PREFIX}/bin/shapeindex ${MASON_PREFIX}/bin/
+ fi
+ if [[ $(uname -s) == 'Darwin' ]]; then
+ install_name_tool -id @loader_path/lib/libmapnik.dylib ${MASON_PREFIX}"/lib/libmapnik.dylib";
PLUGINDIR=${MASON_PREFIX}"/lib/mapnik/input/*.input";
for f in $PLUGINDIR; do
echo $f;
- echo `basename $f`;
- install_name_tool -id plugins/input/`basename $f` $f;
- install_name_tool -change ${MASON_PREFIX}"/lib/libmapnik.dylib" @loader_path/../../libmapnik.dylib $f;
+ echo $(basename $f);
+ install_name_tool -id plugins/input/$(basename $f) $f;
+ install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../../lib/libmapnik.dylib $f;
+ done;
+ BINDIR=${MASON_PREFIX}"/bin/*";
+ for f in $BINDIR; do
+ echo $f;
+ echo $(basename $f);
+ if [[ $(file $f) =~ 'Mach-O' ]]; then
+ install_name_tool -id bin/$(basename $f) $f;
+ install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../lib/libmapnik.dylib $f;
+ fi
done;
fi;
python -c "data=open('$MASON_PREFIX/bin/mapnik-config','r').read();open('$MASON_PREFIX/bin/mapnik-config','w').write(data.replace('$HERE','.'))"
- mkdir -p ${MASON_PREFIX}/share/icu
- cp -r $GDAL_DATA ${MASON_PREFIX}/share/
- cp -r $PROJ_LIB ${MASON_PREFIX}/share/
- cp -r $ICU_DATA/*dat ${MASON_PREFIX}/share/icu/
find ${MASON_PREFIX} -name "*.pyc" -exec rm {} \;
}
diff --git a/plugins/input/csv/build.py b/plugins/input/csv/build.py
index edc3ae0..91675a1 100644
--- a/plugins/input/csv/build.py
+++ b/plugins/input/csv/build.py
@@ -39,6 +39,7 @@ else:
plugin_sources = Split(
"""
+ %(PLUGIN_NAME)s_utils.cpp
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
%(PLUGIN_NAME)s_inline_featureset.cpp
diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp
index 19aa16c..6c1ff10 100644
--- a/plugins/input/csv/csv_datasource.cpp
+++ b/plugins/input/csv/csv_datasource.cpp
@@ -21,6 +21,7 @@
*****************************************************************************/
#include "csv_utils.hpp"
+#include "csv_getline.hpp"
#include "csv_datasource.hpp"
#include "csv_featureset.hpp"
#include "csv_inline_featureset.hpp"
@@ -36,9 +37,12 @@
#include <mapnik/memory_featureset.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/util/trim.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_adapters.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/util/fs.hpp>
+#include <mapnik/make_unique.hpp>
#include <mapnik/util/spatial_index.hpp>
#include <mapnik/geom_util.hpp>
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
@@ -65,21 +69,13 @@ DATASOURCE_PLUGIN(csv_datasource)
csv_datasource::csv_datasource(parameters const& params)
: datasource(params),
desc_(csv_datasource::name(), *params.get<std::string>("encoding", "utf-8")),
- extent_(),
- filename_(),
- row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
- inline_string_(),
- separator_(0),
- quote_(0),
- headers_(),
- manual_headers_(mapnik::util::trim_copy(*params.get<std::string>("headers", ""))),
- strict_(*params.get<mapnik::boolean_type>("strict", false)),
ctx_(std::make_shared<mapnik::context_type>()),
- extent_initialized_(false),
- tree_(nullptr),
- locator_(),
- has_disk_index_(false)
+ tree_(nullptr)
{
+ row_limit_ = *params.get<mapnik::value_integer>("row_limit", 0);
+ manual_headers_ = mapnik::util::trim_copy(*params.get<std::string>("headers", ""));
+ strict_ = *params.get<mapnik::boolean_type>("strict", false);
+
auto quote_param = params.get<std::string>("quote");
if (quote_param)
{
@@ -170,297 +166,89 @@ csv_datasource::csv_datasource(parameters const& params)
csv_datasource::~csv_datasource() {}
-template <typename T>
-void csv_datasource::parse_csv(T & stream)
+void csv_datasource::parse_csv(std::istream & csv_file)
{
- auto file_length = detail::file_length(stream);
- // set back to start
- stream.seekg(0, std::ios::beg);
- char newline;
- bool has_newline;
- char detected_quote;
- char detected_separator;
- std::tie(newline, has_newline, detected_separator, detected_quote) = detail::autodect_csv_flavour(stream, file_length);
- if (quote_ == 0) quote_ = detected_quote;
- if (separator_ == 0) separator_ = detected_separator;
-
- // set back to start
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: separator: '" << separator_
- << "' quote: '" << quote_ << "'";
-
- // rewind stream
- stream.seekg(0, std::ios::beg);
- //
- std::string csv_line;
- csv_utils::getline_csv(stream, csv_line, newline, quote_);
- stream.seekg(0, std::ios::beg);
- int line_number = 0;
- if (!manual_headers_.empty())
- {
- std::size_t index = 0;
- auto headers = csv_utils::parse_line(manual_headers_, separator_, quote_);
- for (auto const& header : headers)
- {
- detail::locate_geometry_column(header, index++, locator_);
- headers_.push_back(header);
- }
- }
- else // parse first line as headers
- {
- while (csv_utils::getline_csv(stream, csv_line, newline, quote_))
- {
- try
- {
- auto headers = csv_utils::parse_line(csv_line, separator_, quote_);
- // skip blank lines
- std::string val;
- if (headers.size() > 0 && headers[0].empty()) ++line_number;
- else
- {
- std::size_t index = 0;
- for (auto const& header : headers)
- {
- val = mapnik::util::trim_copy(header);
- if (val.empty())
- {
- if (strict_)
- {
- std::ostringstream s;
- s << "CSV Plugin: expected a column header at line ";
- s << line_number << ", column " << index;
- s << " - ensure this row contains valid header fields: '";
- s << csv_line;
- throw mapnik::datasource_exception(s.str());
- }
- else
- {
- // create a placeholder for the empty header
- std::ostringstream s;
- s << "_" << index;
- headers_.push_back(s.str());
- }
- }
- else
- {
- detail::locate_geometry_column(val, index, locator_);
- headers_.push_back(val);
- }
- ++index;
- }
- ++line_number;
- break;
- }
- }
- catch (std::exception const& ex)
- {
- std::string s("CSV Plugin: error parsing headers: ");
- s += ex.what();
- throw mapnik::datasource_exception(s);
- }
- }
- }
-
- std::size_t num_headers = headers_.size();
- if (!detail::valid(locator_, num_headers))
- {
- std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or ");
- str += "latitude/longitude in:\n";
- str += csv_line;
- str += "\n - this is required for reading geometry data";
- throw mapnik::datasource_exception(str);
- }
-
- mapnik::value_integer feature_count = 0;
- bool extent_started = false;
+ std::vector<item_type> boxes;
+ csv_utils::csv_file_parser::parse_csv_and_boxes(csv_file, boxes);
std::for_each(headers_.begin(), headers_.end(),
[ & ](std::string const& header){ ctx_->push(header); });
- mapnik::transcoder tr(desc_.get_encoding());
-
- auto pos = stream.tellg();
- // handle rare case of a single line of data and user-provided headers
- // where a lack of a newline will mean that csv_utils::getline_csv returns false
- bool is_first_row = false;
-
- if (!has_newline)
+ if (!has_disk_index_)
{
- stream.setstate(std::ios::failbit);
- pos = 0;
- if (!csv_line.empty())
- {
- is_first_row = true;
- }
+ // bulk insert initialise r-tree
+ tree_ = std::make_unique<spatial_index_type>(boxes);
}
+}
- std::vector<item_type> boxes;
- while (is_first_row || csv_utils::getline_csv(stream, csv_line, newline, quote_))
- {
- ++line_number;
- if ((row_limit_ > 0) && (line_number > row_limit_))
- {
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: row limit hit, exiting at feature: " << feature_count;
- break;
- }
- auto record_offset = pos;
- auto record_size = csv_line.length();
- pos = stream.tellg();
- is_first_row = false;
+void csv_datasource::add_feature(mapnik::value_integer index,
+ mapnik::csv_line const & values)
+{
+ if (index != 1) return;
- // skip blank lines
- if (record_size <= 10)
+ for (std::size_t i = 0; i < values.size(); ++i)
+ {
+ std::string const& header = headers_.at(i);
+ std::string value = mapnik::util::trim_copy(values[i]);
+ int value_length = value.length();
+ if (locator_.index == i && (locator_.type == csv_utils::geometry_column_locator::WKT
+ || locator_.type == csv_utils::geometry_column_locator::GEOJSON)) continue;
+
+ // First we detect likely strings,
+ // then try parsing likely numbers,
+ // then try converting to bool,
+ // finally falling back to string type.
+
+ // An empty string or a string of "null" will be parsed
+ // as a string rather than a true null value.
+ // Likely strings are either empty values, very long values
+ // or values with leading zeros like 001 (which are not safe
+ // to assume are numbers)
+
+ bool matched = false;
+ bool has_dot = value.find(".") != std::string::npos;
+ if (value.empty() || (value_length > 20) || (value_length > 1 && !has_dot && value[0] == '0'))
{
- std::string trimmed = csv_line;
- boost::trim_if(trimmed,boost::algorithm::is_any_of("\",'\r\n "));
- if (trimmed.empty())
- {
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: empty row encountered at line: " << line_number;
- continue;
- }
+ matched = true;
+ desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::String));
}
-
- try
+ else if (csv_utils::is_likely_number(value))
{
- auto const* line_start = csv_line.data();
- auto const* line_end = line_start + csv_line.size();
- auto values = csv_utils::parse_line(line_start, line_end, separator_, quote_, num_headers);
- unsigned num_fields = values.size();
- if (num_fields != num_headers)
+ bool has_e = value.find("e") != std::string::npos;
+ if (has_dot || has_e)
{
- std::ostringstream s;
- s << "CSV Plugin: # of columns(" << num_fields << ")";
- if (num_fields > num_headers)
+ double float_val = 0.0;
+ if (mapnik::util::string2double(value,float_val))
{
- s << " > ";
+ matched = true;
+ desc_.add_descriptor(mapnik::attribute_descriptor(header,mapnik::Double));
}
- else
- {
- s << " < ";
- }
- s << "# of headers(" << num_headers << ") parsed";
- throw mapnik::datasource_exception(s.str());
}
-
- auto geom = detail::extract_geometry(values, locator_);
- if (!geom.is<mapnik::geometry::geometry_empty>())
+ else
{
- auto box = mapnik::geometry::envelope(geom);
- boxes.emplace_back(std::move(box), make_pair(record_offset, record_size));
- if (!extent_initialized_)
+ mapnik::value_integer int_val = 0;
+ if (mapnik::util::string2int(value,int_val))
{
- if (!extent_started)
- {
- extent_started = true;
- extent_ = mapnik::geometry::envelope(geom);
- }
- else
- {
- extent_.expand_to_include(mapnik::geometry::envelope(geom));
- }
- }
- if (++feature_count != 1) continue;
- auto beg = values.begin();
- for (std::size_t i = 0; i < num_headers; ++i)
- {
- std::string const& header = headers_.at(i);
- std::string value = mapnik::util::trim_copy(*beg++);
- int value_length = value.length();
- if (locator_.index == i && (locator_.type == detail::geometry_column_locator::WKT
- || locator_.type == detail::geometry_column_locator::GEOJSON)) continue;
-
- // First we detect likely strings,
- // then try parsing likely numbers,
- // then try converting to bool,
- // finally falling back to string type.
-
- // An empty string or a string of "null" will be parsed
- // as a string rather than a true null value.
- // Likely strings are either empty values, very long values
- // or values with leading zeros like 001 (which are not safe
- // to assume are numbers)
-
- bool matched = false;
- bool has_dot = value.find(".") != std::string::npos;
- if (value.empty() || (value_length > 20) || (value_length > 1 && !has_dot && value[0] == '0'))
- {
- matched = true;
- desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::String));
- }
- else if (csv_utils::is_likely_number(value))
- {
- bool has_e = value.find("e") != std::string::npos;
- if (has_dot || has_e)
- {
- double float_val = 0.0;
- if (mapnik::util::string2double(value,float_val))
- {
- matched = true;
- desc_.add_descriptor(mapnik::attribute_descriptor(header,mapnik::Double));
- }
- }
- else
- {
- mapnik::value_integer int_val = 0;
- if (mapnik::util::string2int(value,int_val))
- {
- matched = true;
- desc_.add_descriptor(mapnik::attribute_descriptor(header,mapnik::Integer));
- }
- }
- }
- if (!matched)
- {
- // NOTE: we don't use mapnik::util::string2bool
- // here because we don't want to treat 'on' and 'off'
- // as booleans, only 'true' and 'false'
- if (csv_utils::ignore_case_equal(value, "true") || csv_utils::ignore_case_equal(value, "false"))
- {
- desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::Boolean));
- }
- else // fallback to normal string
- {
- desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::String));
- }
- }
+ matched = true;
+ desc_.add_descriptor(mapnik::attribute_descriptor(header,mapnik::Integer));
}
}
- else
- {
- std::ostringstream s;
- s << "CSV Plugin: expected geometry column: could not parse row "
- << line_number << " "
- << values.at(locator_.index) << "'";
- throw mapnik::datasource_exception(s.str());
- }
- }
- catch (mapnik::datasource_exception const& ex )
- {
- if (strict_) throw ex;
- else
- {
- MAPNIK_LOG_ERROR(csv) << ex.what() << " at line: " << line_number;
- }
}
- catch (std::exception const& ex)
+ if (!matched)
{
- std::ostringstream s;
- s << "CSV Plugin: unexpected error parsing line: " << line_number
- << " - found " << headers_.size() << " with values like: " << csv_line << "\n"
- << " and got error like: " << ex.what();
- if (strict_)
+ // NOTE: we don't use mapnik::util::string2bool
+ // here because we don't want to treat 'on' and 'off'
+ // as booleans, only 'true' and 'false'
+ if (csv_utils::ignore_case_equal(value, "true") || csv_utils::ignore_case_equal(value, "false"))
{
- throw mapnik::datasource_exception(s.str());
+ desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::Boolean));
}
- else
+ else // fallback to normal string
{
- MAPNIK_LOG_ERROR(csv) << s.str();
+ desc_.add_descriptor(mapnik::attribute_descriptor(header, mapnik::String));
}
}
- // return early if *.index is present
- if (has_disk_index_) return;
}
- // bulk insert initialise r-tree
- tree_ = std::make_unique<spatial_index_type>(boxes);
}
const char * csv_datasource::name()
@@ -483,8 +271,8 @@ mapnik::layer_descriptor csv_datasource::get_descriptor() const
return desc_;
}
-template <typename T>
-boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type_impl(T & stream) const
+boost::optional<mapnik::datasource_geometry_t>
+csv_datasource::get_geometry_type_impl(std::istream & stream) const
{
boost::optional<mapnik::datasource_geometry_t> result;
if (tree_)
@@ -505,7 +293,7 @@ boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type
try
{
auto values = csv_utils::parse_line(str, separator_, quote_);
- auto geom = detail::extract_geometry(values, locator_);
+ auto geom = csv_utils::extract_geometry(values, locator_);
result = mapnik::util::to_ds_type(geom);
if (result)
{
@@ -548,7 +336,7 @@ boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type
try
{
auto values = csv_utils::parse_line(str, separator_, quote_);
- auto geom = detail::extract_geometry(values, locator_);
+ auto geom = csv_utils::extract_geometry(values, locator_);
result = mapnik::util::to_ds_type(geom);
if (result)
{
diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp
index ac2482f..71cf2ea 100644
--- a/plugins/input/csv/csv_datasource.hpp
+++ b/plugins/input/csv/csv_datasource.hpp
@@ -32,6 +32,7 @@
#include <mapnik/coord.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/value_types.hpp>
+#include "csv_utils.hpp"
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
@@ -41,8 +42,8 @@
#pragma GCC diagnostic pop
// stl
+#include <iosfwd>
#include <vector>
-#include <deque>
#include <string>
template <std::size_t Max, std::size_t Min>
@@ -67,7 +68,8 @@ struct options_type<csv_linear<Max,Min> >
};
}}}}}
-class csv_datasource : public mapnik::datasource
+class csv_datasource : public mapnik::datasource,
+ private csv_utils::csv_file_parser
{
public:
using box_type = mapnik::box2d<double>;
@@ -84,26 +86,15 @@ public:
mapnik::layer_descriptor get_descriptor() const;
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
private:
- template <typename T>
- void parse_csv(T & stream);
- template <typename T>
- boost::optional<mapnik::datasource_geometry_t> get_geometry_type_impl(T & stream) const;
+ void parse_csv(std::istream & );
+ virtual void add_feature(mapnik::value_integer index, mapnik::csv_line const & values);
+ boost::optional<mapnik::datasource_geometry_t> get_geometry_type_impl(std::istream & ) const;
mapnik::layer_descriptor desc_;
- mapnik::box2d<double> extent_;
std::string filename_;
- mapnik::value_integer row_limit_;
std::string inline_string_;
- char separator_;
- char quote_;
- std::vector<std::string> headers_;
- std::string manual_headers_;
- bool strict_;
mapnik::context_ptr ctx_;
- bool extent_initialized_;
std::unique_ptr<spatial_index_type> tree_;
- detail::geometry_column_locator locator_;
- bool has_disk_index_;
};
#endif // MAPNIK_CSV_DATASOURCE_HPP
diff --git a/plugins/input/csv/csv_featureset.cpp b/plugins/input/csv/csv_featureset.cpp
index 5017c82..1518112 100644
--- a/plugins/input/csv/csv_featureset.cpp
+++ b/plugins/input/csv/csv_featureset.cpp
@@ -31,7 +31,7 @@
#include <vector>
#include <deque>
-csv_featureset::csv_featureset(std::string const& filename, detail::geometry_column_locator const& locator, char separator, char quote,
+csv_featureset::csv_featureset(std::string const& filename, locator_type const& locator, char separator, char quote,
std::vector<std::string> const& headers, mapnik::context_ptr const& ctx, array_type && index_array)
:
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
@@ -72,12 +72,12 @@ csv_featureset::~csv_featureset() {}
mapnik::feature_ptr csv_featureset::parse_feature(char const* beg, char const* end)
{
auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size());
- auto geom = detail::extract_geometry(values, locator_);
+ auto geom = csv_utils::extract_geometry(values, locator_);
if (!geom.is<mapnik::geometry::geometry_empty>())
{
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_));
feature->set_geometry(std::move(geom));
- detail::process_properties(*feature, headers_, values, locator_, tr_);
+ csv_utils::process_properties(*feature, headers_, values, locator_, tr_);
return feature;
}
return mapnik::feature_ptr();
diff --git a/plugins/input/csv/csv_featureset.hpp b/plugins/input/csv/csv_featureset.hpp
index 8fbf77b..8828fa4 100644
--- a/plugins/input/csv/csv_featureset.hpp
+++ b/plugins/input/csv/csv_featureset.hpp
@@ -28,7 +28,6 @@
#include "csv_utils.hpp"
#include "csv_datasource.hpp"
#include <deque>
-#include <cstdio>
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
#pragma GCC diagnostic push
@@ -41,7 +40,7 @@
class csv_featureset : public mapnik::Featureset
{
- using locator_type = detail::geometry_column_locator;
+ using locator_type = csv_utils::geometry_column_locator;
public:
using array_type = std::deque<csv_datasource::item_type>;
csv_featureset(std::string const& filename,
@@ -70,7 +69,7 @@ private:
array_type::const_iterator index_end_;
mapnik::context_ptr ctx_;
mapnik::value_integer feature_id_ = 0;
- detail::geometry_column_locator const& locator_;
+ locator_type const& locator_;
mapnik::transcoder tr_;
};
diff --git a/plugins/input/csv/csv_getline.hpp b/plugins/input/csv/csv_getline.hpp
new file mode 100644
index 0000000..9dfe5de
--- /dev/null
+++ b/plugins/input/csv/csv_getline.hpp
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 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_CSV_GETLINE_HPP
+#define MAPNIK_CSV_GETLINE_HPP
+
+#include <string>
+#include <istream>
+#include <streambuf>
+
+namespace csv_utils
+{
+
+template <class CharT, class Traits, class Allocator>
+std::basic_istream<CharT, Traits>& getline_csv(std::istream& is, std::basic_string<CharT,Traits,Allocator>& s, CharT delim, CharT quote)
+{
+ typename std::basic_string<CharT,Traits,Allocator>::size_type nread = 0;
+ typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
+ if (sentry)
+ {
+ std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+ s.clear();
+ bool has_quote = false;
+ while (nread < s.max_size())
+ {
+ int c1 = buf->sbumpc();
+ if (Traits::eq_int_type(c1, Traits::eof()))
+ {
+ is.setstate(std::ios_base::eofbit);
+ break;
+ }
+ else
+ {
+ ++nread;
+ CharT c = Traits::to_char_type(c1);
+ if (Traits::eq(c, quote))
+ has_quote = !has_quote;
+ if (!Traits::eq(c, delim) || has_quote)
+ s.push_back(c);
+ else
+ break;// Character is extracted but not appended.
+ }
+ }
+ }
+ if (nread == 0 || nread >= s.max_size())
+ is.setstate(std::ios_base::failbit);
+
+ return is;
+}
+
+}
+
+#endif // MAPNIK_CSV_GETLINE_HPP
diff --git a/plugins/input/csv/csv_index_featureset.cpp b/plugins/input/csv/csv_index_featureset.cpp
index c064579..e94f41b 100644
--- a/plugins/input/csv/csv_index_featureset.cpp
+++ b/plugins/input/csv/csv_index_featureset.cpp
@@ -37,7 +37,7 @@
csv_index_featureset::csv_index_featureset(std::string const& filename,
mapnik::filter_in_box const& filter,
- detail::geometry_column_locator const& locator,
+ locator_type const& locator,
char separator,
char quote,
std::vector<std::string> const& headers,
@@ -89,12 +89,12 @@ csv_index_featureset::~csv_index_featureset() {}
mapnik::feature_ptr csv_index_featureset::parse_feature(char const* beg, char const* end)
{
auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size());
- auto geom = detail::extract_geometry(values, locator_);
+ auto geom = csv_utils::extract_geometry(values, locator_);
if (!geom.is<mapnik::geometry::geometry_empty>())
{
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_));
feature->set_geometry(std::move(geom));
- detail::process_properties(*feature, headers_, values, locator_, tr_);
+ csv_utils::process_properties(*feature, headers_, values, locator_, tr_);
return feature;
}
return mapnik::feature_ptr();
diff --git a/plugins/input/csv/csv_index_featureset.hpp b/plugins/input/csv/csv_index_featureset.hpp
index 1a2c637..e57a356 100644
--- a/plugins/input/csv/csv_index_featureset.hpp
+++ b/plugins/input/csv/csv_index_featureset.hpp
@@ -41,7 +41,7 @@
class csv_index_featureset : public mapnik::Featureset
{
using value_type = std::pair<std::size_t, std::size_t>;
- using locator_type = detail::geometry_column_locator;
+ using locator_type = csv_utils::geometry_column_locator;
public:
csv_index_featureset(std::string const& filename,
@@ -60,7 +60,7 @@ private:
std::vector<std::string> headers_;
mapnik::context_ptr ctx_;
mapnik::value_integer feature_id_ = 0;
- detail::geometry_column_locator const& locator_;
+ locator_type const& locator_;
mapnik::transcoder tr_;
#if defined (MAPNIK_MEMORY_MAPPED_FILE)
using file_source_type = boost::interprocess::ibufferstream;
diff --git a/plugins/input/csv/csv_inline_featureset.cpp b/plugins/input/csv/csv_inline_featureset.cpp
index 195574b..2d91efc 100644
--- a/plugins/input/csv/csv_inline_featureset.cpp
+++ b/plugins/input/csv/csv_inline_featureset.cpp
@@ -33,7 +33,7 @@
#include <deque>
csv_inline_featureset::csv_inline_featureset(std::string const& inline_string,
- detail::geometry_column_locator const& locator,
+ locator_type const& locator,
char separator,
char quote,
std::vector<std::string> const& headers,
@@ -57,12 +57,12 @@ mapnik::feature_ptr csv_inline_featureset::parse_feature(std::string const& str)
auto const* start = str.data();
auto const* end = start + str.size();
auto values = csv_utils::parse_line(start, end, separator_, quote_, headers_.size());
- auto geom = detail::extract_geometry(values, locator_);
+ auto geom = csv_utils::extract_geometry(values, locator_);
if (!geom.is<mapnik::geometry::geometry_empty>())
{
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_));
feature->set_geometry(std::move(geom));
- detail::process_properties(*feature, headers_, values, locator_, tr_);
+ csv_utils::process_properties(*feature, headers_, values, locator_, tr_);
return feature;
}
return mapnik::feature_ptr();
diff --git a/plugins/input/csv/csv_inline_featureset.hpp b/plugins/input/csv/csv_inline_featureset.hpp
index 3da9f63..4873cec 100644
--- a/plugins/input/csv/csv_inline_featureset.hpp
+++ b/plugins/input/csv/csv_inline_featureset.hpp
@@ -28,11 +28,10 @@
#include "csv_utils.hpp"
#include "csv_datasource.hpp"
#include <deque>
-#include <cstdio>
class csv_inline_featureset : public mapnik::Featureset
{
- using locator_type = detail::geometry_column_locator;
+ using locator_type = csv_utils::geometry_column_locator;
public:
using array_type = std::deque<csv_datasource::item_type>;
csv_inline_featureset(std::string const& inline_string,
@@ -55,7 +54,7 @@ private:
array_type::const_iterator index_end_;
mapnik::context_ptr ctx_;
mapnik::value_integer feature_id_ = 0;
- detail::geometry_column_locator const& locator_;
+ locator_type const& locator_;
mapnik::transcoder tr_;
};
diff --git a/plugins/input/csv/csv_utils.cpp b/plugins/input/csv/csv_utils.cpp
new file mode 100644
index 0000000..217276f
--- /dev/null
+++ b/plugins/input/csv/csv_utils.cpp
@@ -0,0 +1,507 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 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
+ *
+ *****************************************************************************/
+
+// mapnik
+#include <mapnik/debug.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_correct.hpp>
+#include <mapnik/wkt/wkt_factory.hpp>
+#include <mapnik/json/geometry_parser.hpp>
+#include <mapnik/util/conversions.hpp>
+#include <mapnik/util/trim.hpp>
+#include <mapnik/datasource.hpp>
+// csv grammar
+#include <mapnik/csv/csv_grammar_impl.hpp>
+//
+#include "csv_getline.hpp"
+#include "csv_utils.hpp"
+
+#include <fstream>
+#include <string>
+#include <cstdio>
+#include <algorithm>
+
+namespace csv_utils {
+namespace detail {
+
+std::size_t file_length(std::istream & stream)
+{
+ stream.seekg(0, std::ios::end);
+ return stream.tellg();
+}
+
+std::tuple<char, bool, char, char> autodetect_csv_flavour(std::istream & stream, std::size_t file_length)
+{
+ // autodetect newlines/quotes/separators
+ char newline = '\n'; // default
+ bool has_newline = false;
+ bool has_single_quote = false;
+ char quote = '"'; // default
+ char separator = ','; // default
+ // local counters
+ int num_commas = 0;
+ int num_tabs = 0;
+ int num_pipes = 0;
+ int num_semicolons = 0;
+
+ static std::size_t const max_size = 4000;
+ std::size_t size = std::min(file_length, max_size);
+ std::vector<char> buffer;
+ buffer.resize(size);
+ stream.read(buffer.data(), size);
+ for (auto c : buffer)
+ {
+ switch (c)
+ {
+ case '\r':
+ newline = '\r';
+ has_newline = true;
+ break;
+ case '\n':
+ has_newline = true;
+ break;
+ case '\'':
+ if (!has_single_quote)
+ {
+ quote = c;
+ has_single_quote = true;
+ }
+ break;
+ case ',':
+ if (!has_newline) ++num_commas;
+ break;
+ case '\t':
+ if (!has_newline) ++num_tabs;
+ break;
+ case '|':
+ if (!has_newline) ++num_pipes;
+ break;
+ case ';':
+ if (!has_newline) ++num_semicolons;
+ break;
+ }
+ }
+ // detect separator
+ if (num_tabs > 0 && num_tabs > num_commas)
+ {
+ separator = '\t';
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected tab separator";
+ }
+ else // pipes/semicolons
+ {
+ if (num_pipes > num_commas)
+ {
+ separator = '|';
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected '|' separator";
+ }
+ else if (num_semicolons > num_commas)
+ {
+ separator = ';';
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected ';' separator";
+ }
+ }
+
+ if (has_newline && has_single_quote)
+ {
+ std::istringstream ss(std::string(buffer.begin(), buffer.end()));
+ std::size_t num_columns = 0;
+ for (std::string line; csv_utils::getline_csv(ss, line, newline, quote); )
+ {
+ if (size < file_length && ss.eof())
+ {
+ // we can't be sure that last line
+ // is not truncated so skip it
+ break;
+ }
+ if (line.size() == 0 || (line.size() == 1 && line[0] == char(0xa))) continue; // empty lines are not interesting
+ auto num_quotes = std::count(line.begin(), line.end(), quote);
+ if (num_quotes % 2 != 0)
+ {
+ quote = '"';
+ break;
+ }
+ auto columns = csv_utils::parse_line(line, separator, quote);
+ if (num_columns > 0 && num_columns != columns.size())
+ {
+ quote = '"';
+ break;
+ }
+ num_columns = columns.size();
+ }
+ }
+ return std::make_tuple(newline, has_newline, separator, quote);
+}
+
+void locate_geometry_column(std::string const& header, std::size_t index, geometry_column_locator & locator)
+{
+ std::string lower_val(header);
+ std::transform(lower_val.begin(), lower_val.end(), lower_val.begin(), ::tolower);
+ if (lower_val == "wkt" || (lower_val.find("geom") != std::string::npos))
+ {
+ locator.type = geometry_column_locator::WKT;
+ locator.index = index;
+ }
+ else if (lower_val == "geojson")
+ {
+ locator.type = geometry_column_locator::GEOJSON;
+ locator.index = index;
+ }
+ else if (lower_val == "x" || lower_val == "lon"
+ || lower_val == "lng" || lower_val == "long"
+ || (lower_val.find("longitude") != std::string::npos))
+ {
+ locator.index = index;
+ locator.type = geometry_column_locator::LON_LAT;
+ }
+
+ else if (lower_val == "y"
+ || lower_val == "lat"
+ || (lower_val.find("latitude") != std::string::npos))
+ {
+ locator.index2 = index;
+ locator.type = geometry_column_locator::LON_LAT;
+ }
+}
+
+bool valid(geometry_column_locator const& locator, std::size_t max_size)
+{
+ if (locator.type == geometry_column_locator::UNKNOWN) return false;
+ if (locator.index >= max_size) return false;
+ if (locator.type == geometry_column_locator::LON_LAT && locator.index2 >= max_size) return false;
+ return true;
+}
+
+} // namespace detail
+
+static const mapnik::csv_line_grammar<char const*> line_g;
+static const mapnik::csv_white_space_skipper skipper{};
+
+mapnik::csv_line parse_line(char const* start, char const* end, char separator, char quote, std::size_t num_columns)
+{
+ mapnik::csv_line values;
+ if (num_columns > 0) values.reserve(num_columns);
+ if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values))
+ {
+ throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end));
+ }
+ return values;
+}
+
+mapnik::csv_line parse_line(std::string const& line_str, char separator, char quote)
+{
+ auto start = line_str.c_str();
+ auto end = start + line_str.length();
+ return parse_line(start, end, separator, quote, 0);
+}
+
+
+bool is_likely_number(std::string const& value)
+{
+ return (std::strspn( value.c_str(), "e-.+0123456789" ) == value.size());
+}
+
+struct ignore_case_equal_pred
+{
+ bool operator () (unsigned char a, unsigned char b) const
+ {
+ return std::tolower(a) == std::tolower(b);
+ }
+};
+
+bool ignore_case_equal(std::string const& s0, std::string const& s1)
+{
+ return std::equal(s0.begin(), s0.end(),
+ s1.begin(), ignore_case_equal_pred());
+}
+
+void csv_file_parser::add_feature(mapnik::value_integer, mapnik::csv_line const & )
+{
+ // no-op by default
+}
+
+template <typename T>
+void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes)
+{
+ using boxes_type = T;
+ using box_type = typename boxes_type::value_type::first_type;
+
+ auto file_length = detail::file_length(csv_file);
+ // set back to start
+ csv_file.seekg(0, std::ios::beg);
+ char newline;
+ bool has_newline;
+ char detected_quote;
+ char detected_separator;
+ std::tie(newline, has_newline, detected_separator, detected_quote) = detail::autodetect_csv_flavour(csv_file, file_length);
+ if (quote_ == 0) quote_ = detected_quote;
+ if (separator_ == 0) separator_ = detected_separator;
+
+ // set back to start
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: separator: '" << separator_
+ << "' quote: '" << quote_ << "'";
+
+ // rewind stream
+ csv_file.seekg(0, std::ios::beg);
+ //
+ std::string csv_line;
+ csv_utils::getline_csv(csv_file, csv_line, newline, quote_);
+ csv_file.seekg(0, std::ios::beg);
+ int line_number = 0;
+ if (!manual_headers_.empty())
+ {
+ std::size_t index = 0;
+ auto headers = csv_utils::parse_line(manual_headers_, separator_, quote_);
+ headers_.reserve(headers.size());
+ for (auto const& header : headers)
+ {
+ detail::locate_geometry_column(header, index++, locator_);
+ headers_.push_back(header);
+ }
+ }
+ else // parse first line as headers
+ {
+ while (csv_utils::getline_csv(csv_file, csv_line, newline, quote_))
+ {
+ try
+ {
+ auto headers = csv_utils::parse_line(csv_line, separator_, quote_);
+ // skip blank lines
+ if (headers.size() > 0 && headers[0].empty()) ++line_number;
+ else
+ {
+ std::size_t index = 0;
+ headers_.reserve(headers.size());
+ for (auto & header : headers)
+ {
+ mapnik::util::trim(header);
+ if (header.empty())
+ {
+ if (strict_)
+ {
+ std::ostringstream s;
+ s << "CSV Plugin: expected a column header at line ";
+ s << line_number << ", column " << index;
+ s << " - ensure this row contains valid header fields: '";
+ s << csv_line;
+ throw mapnik::datasource_exception(s.str());
+ }
+ else
+ {
+ // create a placeholder for the empty header
+ std::ostringstream s;
+ s << "_" << index;
+ headers_.push_back(s.str());
+ }
+ }
+ else
+ {
+ detail::locate_geometry_column(header, index, locator_);
+ headers_.push_back(header);
+ }
+ ++index;
+ }
+ ++line_number;
+ break;
+ }
+ }
+ catch (std::exception const& ex)
+ {
+ std::string s("CSV Plugin: error parsing headers: ");
+ s += ex.what();
+ throw mapnik::datasource_exception(s);
+ }
+ }
+ }
+
+ std::size_t num_headers = headers_.size();
+ if (!detail::valid(locator_, num_headers))
+ {
+ std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or ");
+ str += "latitude/longitude in:\n";
+ str += csv_line;
+ str += "\n - this is required for reading geometry data";
+ throw mapnik::datasource_exception(str);
+ }
+
+ mapnik::value_integer feature_count = 0;
+ auto pos = csv_file.tellg();
+ // handle rare case of a single line of data and user-provided headers
+ // where a lack of a newline will mean that csv_utils::getline_csv returns false
+ bool is_first_row = false;
+
+ if (!has_newline)
+ {
+ csv_file.setstate(std::ios::failbit);
+ pos = 0;
+ if (!csv_line.empty())
+ {
+ is_first_row = true;
+ }
+ }
+
+ while (is_first_row || csv_utils::getline_csv(csv_file, csv_line, newline, quote_))
+ {
+ ++line_number;
+ if ((row_limit_ > 0) && (line_number > row_limit_))
+ {
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: row limit hit, exiting at feature: " << feature_count;
+ break;
+ }
+ auto record_offset = pos;
+ auto record_size = csv_line.length();
+ pos = csv_file.tellg();
+ is_first_row = false;
+
+ // skip blank lines
+ if (record_size <= 10)
+ {
+ std::string trimmed = csv_line;
+ boost::trim_if(trimmed, boost::algorithm::is_any_of("\",'\r\n "));
+ if (trimmed.empty())
+ {
+ MAPNIK_LOG_DEBUG(csv) << "csv_datasource: empty row encountered at line: " << line_number;
+ continue;
+ }
+ }
+
+ try
+ {
+ auto const* line_start = csv_line.data();
+ auto const* line_end = line_start + csv_line.size();
+ auto values = csv_utils::parse_line(line_start, line_end, separator_, quote_, num_headers);
+ unsigned num_fields = values.size();
+ if (num_fields != num_headers)
+ {
+ std::ostringstream s;
+ s << "CSV Plugin: # of columns(" << num_fields << ")";
+ if (num_fields > num_headers)
+ {
+ s << " > ";
+ }
+ else
+ {
+ s << " < ";
+ }
+ s << "# of headers(" << num_headers << ") parsed";
+ throw mapnik::datasource_exception(s.str());
+ }
+
+ auto geom = extract_geometry(values, locator_);
+ if (!geom.is<mapnik::geometry::geometry_empty>())
+ {
+ auto box = mapnik::geometry::envelope(geom);
+ if (!extent_initialized_)
+ {
+ if (extent_.valid())
+ extent_.expand_to_include(box);
+ else
+ extent_ = box;
+ }
+ boxes.emplace_back(box_type(box), make_pair(record_offset, record_size));
+ add_feature(++feature_count, values);
+ }
+ else
+ {
+ std::ostringstream s;
+ s << "CSV Plugin: expected geometry column: could not parse row "
+ << line_number << " "
+ << values.at(locator_.index) << "'";
+ throw mapnik::datasource_exception(s.str());
+ }
+ }
+ catch (mapnik::datasource_exception const& ex )
+ {
+ if (strict_) throw ex;
+ else
+ {
+ MAPNIK_LOG_ERROR(csv) << ex.what() << " at line: " << line_number;
+ }
+ }
+ catch (std::exception const& ex)
+ {
+ std::ostringstream s;
+ s << "CSV Plugin: unexpected error parsing line: " << line_number
+ << " - found " << headers_.size() << " with values like: " << csv_line << "\n"
+ << " and got error like: " << ex.what();
+ if (strict_)
+ {
+ throw mapnik::datasource_exception(s.str());
+ }
+ else
+ {
+ MAPNIK_LOG_ERROR(csv) << s.str();
+ }
+ }
+ // return early if *.index is present
+ if (has_disk_index_) return;
+ }
+}
+
+
+mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> const& row, geometry_column_locator const& locator)
+{
+ mapnik::geometry::geometry<double> geom;
+ if (locator.type == geometry_column_locator::WKT)
+ {
+ auto wkt_value = row.at(locator.index);
+ if (mapnik::from_wkt(wkt_value, geom))
+ {
+ // correct orientations ..
+ mapnik::geometry::correct(geom);
+ }
+ else
+ {
+ throw mapnik::datasource_exception("Failed to parse WKT: '" + wkt_value + "'");
+ }
+ }
+ else if (locator.type == geometry_column_locator::GEOJSON)
+ {
+
+ auto json_value = row.at(locator.index);
+ if (!mapnik::json::from_geojson(json_value, geom))
+ {
+ throw mapnik::datasource_exception("Failed to parse GeoJSON: '" + json_value + "'");
+ }
+ }
+ else if (locator.type == geometry_column_locator::LON_LAT)
+ {
+ double x, y;
+ auto long_value = row.at(locator.index);
+ auto lat_value = row.at(locator.index2);
+ if (!mapnik::util::string2double(long_value,x))
+ {
+ throw mapnik::datasource_exception("Failed to parse Longitude: '" + long_value + "'");
+ }
+ if (!mapnik::util::string2double(lat_value,y))
+ {
+ throw mapnik::datasource_exception("Failed to parse Latitude: '" + lat_value + "'");
+ }
+ geom = mapnik::geometry::point<double>(x,y);
+ }
+ return geom;
+}
+
+template void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, std::vector<std::pair<mapnik::box2d<double>, std::pair<std::size_t, std::size_t>>> & boxes);
+
+template void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, std::vector<std::pair<mapnik::box2d<float>, std::pair<std::size_t, std::size_t>>> & boxes);
+
+} // namespace csv_utils
diff --git a/plugins/input/csv/csv_utils.hpp b/plugins/input/csv/csv_utils.hpp
index 4171d45..df976e3 100644
--- a/plugins/input/csv/csv_utils.hpp
+++ b/plugins/input/csv/csv_utils.hpp
@@ -24,220 +24,26 @@
#define MAPNIK_CSV_UTILS_DATASOURCE_HPP
// mapnik
-#include <mapnik/debug.hpp>
+#include <mapnik/box2d.hpp>
#include <mapnik/geometry.hpp>
-#include <mapnik/geometry_correct.hpp>
-#include <mapnik/wkt/wkt_factory.hpp>
-#include <mapnik/json/geometry_parser.hpp>
+#include <mapnik/value_types.hpp>
#include <mapnik/util/conversions.hpp>
-#include <mapnik/csv/csv_grammar.hpp>
#include <mapnik/util/trim.hpp>
-#include <mapnik/datasource.hpp>
-
-#pragma GCC diagnostic push
-#include <mapnik/warning_ignore.hpp>
-#include <boost/algorithm/string.hpp>
-#pragma GCC diagnostic pop
+#include <mapnik/csv/csv_types.hpp>
+// std
+#include <iosfwd>
#include <string>
-#include <cstdio>
-#include <algorithm>
-
-namespace csv_utils
-{
-
-static const mapnik::csv_line_grammar<char const*> line_g;
-static const mapnik::csv_white_space_skipper skipper{};
-
-template <typename Iterator>
-static mapnik::csv_line parse_line(Iterator start, Iterator end, char separator, char quote, std::size_t num_columns)
-{
- mapnik::csv_line values;
- if (num_columns > 0) values.reserve(num_columns);
- if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values))
- {
- throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end));
- }
- return values;
-}
-
-static inline mapnik::csv_line parse_line(std::string const& line_str, char separator, char quote)
-{
- auto start = line_str.c_str();
- auto end = start + line_str.length();
- return parse_line(start, end, separator, quote, 0);
-}
-
-static inline bool is_likely_number(std::string const& value)
-{
- return (std::strspn( value.c_str(), "e-.+0123456789" ) == value.size());
-}
-
-struct ignore_case_equal_pred
-{
- bool operator () (unsigned char a, unsigned char b) const
- {
- return std::tolower(a) == std::tolower(b);
- }
-};
-
-inline bool ignore_case_equal(std::string const& s0, std::string const& s1)
-{
- return std::equal(s0.begin(), s0.end(),
- s1.begin(), ignore_case_equal_pred());
-}
-
-template <class CharT, class Traits, class Allocator>
-std::basic_istream<CharT, Traits>& getline_csv(std::istream& is, std::basic_string<CharT,Traits,Allocator>& s, CharT delim, CharT quote)
-{
- typename std::basic_string<CharT,Traits,Allocator>::size_type nread = 0;
- typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
- if (sentry)
- {
- std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
- s.clear();
- bool has_quote = false;
- while (nread < s.max_size())
- {
- int c1 = buf->sbumpc();
- if (Traits::eq_int_type(c1, Traits::eof()))
- {
- is.setstate(std::ios_base::eofbit);
- break;
- }
- else
- {
- ++nread;
- CharT c = Traits::to_char_type(c1);
- if (Traits::eq(c, quote))
- has_quote = !has_quote;
- if (!Traits::eq(c, delim) || has_quote)
- s.push_back(c);
- else
- break;// Character is extracted but not appended.
- }
- }
- }
- if (nread == 0 || nread >= s.max_size())
- is.setstate(std::ios_base::failbit);
-
- return is;
-}
-
-}
+#include <vector>
+namespace csv_utils {
-namespace detail {
+mapnik::csv_line parse_line(char const* start, char const* end, char separator, char quote, std::size_t num_columns);
+mapnik::csv_line parse_line(std::string const& line_str, char separator, char quote);
-template <typename T>
-std::size_t file_length(T & stream)
-{
- stream.seekg(0, std::ios::end);
- return stream.tellg();
-}
+bool is_likely_number(std::string const& value);
-template <typename T>
-std::tuple<char, bool, char, char> autodect_csv_flavour(T & stream, std::size_t file_length)
-{
- // autodetect newlines/quotes/separators
- char newline = '\n'; // default
- bool has_newline = false;
- bool has_single_quote = false;
- char quote = '"'; // default
- char separator = ','; // default
- // local counters
- int num_commas = 0;
- int num_tabs = 0;
- int num_pipes = 0;
- int num_semicolons = 0;
-
- static std::size_t const max_size = 4000;
- std::size_t size = std::min(file_length, max_size);
- std::vector<char> buffer;
- buffer.resize(size);
- stream.read(buffer.data(), size);
- for (auto c : buffer)
- {
- switch (c)
- {
- case '\r':
- newline = '\r';
- has_newline = true;
- break;
- case '\n':
- has_newline = true;
- break;
- case '\'':
- if (!has_single_quote)
- {
- quote = c;
- has_single_quote = true;
- }
- break;
- case ',':
- if (!has_newline) ++num_commas;
- break;
- case '\t':
- if (!has_newline) ++num_tabs;
- break;
- case '|':
- if (!has_newline) ++num_pipes;
- break;
- case ';':
- if (!has_newline) ++num_semicolons;
- break;
- }
- }
- // detect separator
- if (num_tabs > 0 && num_tabs > num_commas)
- {
- separator = '\t';
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected tab separator";
- }
- else // pipes/semicolons
- {
- if (num_pipes > num_commas)
- {
- separator = '|';
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected '|' separator";
- }
- else if (num_semicolons > num_commas)
- {
- separator = ';';
- MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected ';' separator";
- }
- }
-
- if (has_newline && has_single_quote)
- {
- std::istringstream ss(std::string(buffer.begin(), buffer.end()));
- std::size_t num_columns = 0;
- for (std::string line; csv_utils::getline_csv(ss, line, newline, quote); )
- {
- if (size < file_length && ss.eof())
- {
- // we can't be sure last line
- // is not truncated so skip it
- break;
- }
- if (line.size() == 0) continue; // empty lines are not interesting
- auto num_quotes = std::count(line.begin(), line.end(), quote);
- if (num_quotes % 2 != 0)
- {
- quote = '"';
- break;
- }
- auto columns = csv_utils::parse_line(line, separator, quote);
- if (num_columns > 0 && num_columns != columns.size())
- {
- quote = '"';
- break;
- }
- num_columns = columns.size();
- }
- }
- return std::make_tuple(newline, has_newline, separator, quote);
-}
+bool ignore_case_equal(std::string const& s0, std::string const& s1);
struct geometry_column_locator
{
@@ -249,87 +55,8 @@ struct geometry_column_locator
std::size_t index2;
};
-static inline void locate_geometry_column(std::string const& header, std::size_t index, geometry_column_locator & locator)
-{
- std::string lower_val(header);
- std::transform(lower_val.begin(), lower_val.end(), lower_val.begin(), ::tolower);
- if (lower_val == "wkt" || (lower_val.find("geom") != std::string::npos))
- {
- locator.type = geometry_column_locator::WKT;
- locator.index = index;
- }
- else if (lower_val == "geojson")
- {
- locator.type = geometry_column_locator::GEOJSON;
- locator.index = index;
- }
- else if (lower_val == "x" || lower_val == "lon"
- || lower_val == "lng" || lower_val == "long"
- || (lower_val.find("longitude") != std::string::npos))
- {
- locator.index = index;
- locator.type = geometry_column_locator::LON_LAT;
- }
- else if (lower_val == "y"
- || lower_val == "lat"
- || (lower_val.find("latitude") != std::string::npos))
- {
- locator.index2 = index;
- locator.type = geometry_column_locator::LON_LAT;
- }
-}
-
-static inline bool valid(geometry_column_locator const& locator, std::size_t max_size)
-{
- if (locator.type == geometry_column_locator::UNKNOWN) return false;
- if (locator.index >= max_size) return false;
- if (locator.type == geometry_column_locator::LON_LAT && locator.index2 >= max_size) return false;
- return true;
-}
-
-static inline mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> const& row, geometry_column_locator const& locator)
-{
- mapnik::geometry::geometry<double> geom;
- if (locator.type == geometry_column_locator::WKT)
- {
- auto wkt_value = row.at(locator.index);
- if (mapnik::from_wkt(wkt_value, geom))
- {
- // correct orientations ..
- mapnik::geometry::correct(geom);
- }
- else
- {
- throw mapnik::datasource_exception("Failed to parse WKT: '" + wkt_value + "'");
- }
- }
- else if (locator.type == geometry_column_locator::GEOJSON)
- {
-
- auto json_value = row.at(locator.index);
- if (!mapnik::json::from_geojson(json_value, geom))
- {
- throw mapnik::datasource_exception("Failed to parse GeoJSON: '" + json_value + "'");
- }
- }
- else if (locator.type == geometry_column_locator::LON_LAT)
- {
- double x, y;
- auto long_value = row.at(locator.index);
- auto lat_value = row.at(locator.index2);
- if (!mapnik::util::string2double(long_value,x))
- {
- throw mapnik::datasource_exception("Failed to parse Longitude: '" + long_value + "'");
- }
- if (!mapnik::util::string2double(lat_value,y))
- {
- throw mapnik::datasource_exception("Failed to parse Latitude: '" + lat_value + "'");
- }
- geom = mapnik::geometry::point<double>(x,y);
- }
- return geom;
-}
+mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> const& row, geometry_column_locator const& locator);
template <typename Feature, typename Headers, typename Values, typename Locator, typename Transcoder>
void process_properties(Feature & feature, Headers const& headers, Values const& values, Locator const& locator, Transcoder const& tr)
@@ -348,8 +75,8 @@ void process_properties(Feature & feature, Headers const& headers, Values const&
std::string value = mapnik::util::trim_copy(*val_beg++);
int value_length = value.length();
- if (locator.index == i && (locator.type == detail::geometry_column_locator::WKT
- || locator.type == detail::geometry_column_locator::GEOJSON) ) continue;
+ if (locator.index == i && (locator.type == geometry_column_locator::WKT
+ || locator.type == geometry_column_locator::GEOJSON) ) continue;
bool matched = false;
@@ -401,7 +128,25 @@ void process_properties(Feature & feature, Headers const& headers, Values const&
}
}
+struct csv_file_parser
+{
+ template <typename T>
+ void parse_csv_and_boxes(std::istream & csv_file, T & boxes);
+
+ virtual void add_feature(mapnik::value_integer index, mapnik::csv_line const & values);
+
+ std::vector<std::string> headers_;
+ std::string manual_headers_;
+ geometry_column_locator locator_;
+ mapnik::box2d<double> extent_;
+ mapnik::value_integer row_limit_ = 0;
+ char separator_ = '\0';
+ char quote_ = '\0';
+ bool strict_ = false;
+ bool extent_initialized_ = false;
+ bool has_disk_index_ = false;
+};
-}// ns detail
+} // namespace csv_utils
#endif // MAPNIK_CSV_UTILS_DATASOURCE_HPP
diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp
index 8a06a92..07cec47 100644
--- a/plugins/input/gdal/gdal_datasource.cpp
+++ b/plugins/input/gdal/gdal_datasource.cpp
@@ -45,21 +45,27 @@ using mapnik::layer_descriptor;
using mapnik::datasource_exception;
+static bool GDALAllRegister_once_()
+{
+ static bool const quiet_unused = (GDALAllRegister(), true);
+ return quiet_unused;
+}
+
gdal_datasource::gdal_datasource(parameters const& params)
: datasource(params),
- dataset_(nullptr),
+ dataset_(nullptr, &GDALClose),
desc_(gdal_datasource::name(), "utf-8"),
nodata_value_(params.get<double>("nodata")),
nodata_tolerance_(*params.get<double>("nodata_tolerance",1e-12))
{
MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource: Initializing...";
+ GDALAllRegister_once_();
+
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "gdal_datasource::init");
#endif
- GDALAllRegister();
-
boost::optional<std::string> file = params.get<std::string>("file");
if (! file) throw datasource_exception("missing <file> parameter");
@@ -79,12 +85,14 @@ gdal_datasource::gdal_datasource(parameters const& params)
#if GDAL_VERSION_NUM >= 1600
if (shared_dataset_)
{
- dataset_ = reinterpret_cast<GDALDataset*>(GDALOpenShared((dataset_name_).c_str(), GA_ReadOnly));
+ auto ds = GDALOpenShared(dataset_name_.c_str(), GA_ReadOnly);
+ dataset_.reset(static_cast<GDALDataset*>(ds));
}
else
#endif
{
- dataset_ = reinterpret_cast<GDALDataset*>(GDALOpen((dataset_name_).c_str(), GA_ReadOnly));
+ auto ds = GDALOpen(dataset_name_.c_str(), GA_ReadOnly);
+ dataset_.reset(static_cast<GDALDataset*>(ds));
}
if (! dataset_)
@@ -92,7 +100,7 @@ gdal_datasource::gdal_datasource(parameters const& params)
throw datasource_exception(CPLGetLastErrorMsg());
}
- MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: opened Dataset=" << dataset_;
+ MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: opened Dataset=" << dataset_.get();
nbands_ = dataset_->GetRasterCount();
width_ = dataset_->GetRasterXSize();
@@ -182,8 +190,7 @@ gdal_datasource::gdal_datasource(parameters const& params)
gdal_datasource::~gdal_datasource()
{
- MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Closing Dataset=" << dataset_;
- GDALClose(dataset_);
+ MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Closing Dataset=" << dataset_.get();
}
datasource::datasource_t gdal_datasource::type() const
@@ -217,12 +224,9 @@ featureset_ptr gdal_datasource::features(query const& q) const
mapnik::progress_timer __stats__(std::clog, "gdal_datasource::features");
#endif
- gdal_query gq = q;
-
- // TODO - move to std::make_shared, but must reduce # of args to <= 9
- return featureset_ptr(new gdal_featureset(*dataset_,
+ return std::make_shared<gdal_featureset>(*dataset_,
band_,
- gq,
+ gdal_query(q),
extent_,
width_,
height_,
@@ -230,7 +234,7 @@ featureset_ptr gdal_datasource::features(query const& q) const
dx_,
dy_,
nodata_value_,
- nodata_tolerance_));
+ nodata_tolerance_);
}
featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) const
@@ -239,12 +243,9 @@ featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol)
mapnik::progress_timer __stats__(std::clog, "gdal_datasource::features_at_point");
#endif
- gdal_query gq = pt;
-
- // TODO - move to std::make_shared, but must reduce # of args to <= 9
- return featureset_ptr(new gdal_featureset(*dataset_,
+ return std::make_shared<gdal_featureset>(*dataset_,
band_,
- gq,
+ gdal_query(pt),
extent_,
width_,
height_,
@@ -252,5 +253,5 @@ featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol)
dx_,
dy_,
nodata_value_,
- nodata_tolerance_));
+ nodata_tolerance_);
}
diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp
index 7e7b221..3fc3036 100644
--- a/plugins/input/gdal/gdal_datasource.hpp
+++ b/plugins/input/gdal/gdal_datasource.hpp
@@ -55,8 +55,7 @@ public:
boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
mapnik::layer_descriptor get_descriptor() const;
private:
- GDALDataset* open_dataset() const;
- GDALDataset* dataset_;
+ std::unique_ptr<GDALDataset, decltype(&GDALClose)> dataset_;
mapnik::box2d<double> extent_;
std::string dataset_name_;
int band_;
diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp
index 968fc6d..fe1fe64 100644
--- a/plugins/input/gdal/gdal_featureset.cpp
+++ b/plugins/input/gdal/gdal_featureset.cpp
@@ -21,7 +21,7 @@
*****************************************************************************/
// mapnik
-#include <mapnik/make_unique.hpp>
+#include <mapnik/datasource.hpp>
#include <mapnik/global.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/image.hpp>
@@ -29,7 +29,6 @@
#include <mapnik/view_transform.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
-#include <mapnik/util/variant.hpp>
// stl
#include <cmath>
@@ -39,8 +38,6 @@
#include "gdal_featureset.hpp"
#include <gdal_priv.h>
-using mapnik::query;
-using mapnik::coord2d;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::view_transform;
@@ -77,8 +74,6 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
gdal_featureset::~gdal_featureset()
{
- MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Closing Dataset=" << &dataset_;
-
}
feature_ptr gdal_featureset::next()
diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp
index b909211..639028b 100644
--- a/plugins/input/gdal/gdal_featureset.hpp
+++ b/plugins/input/gdal/gdal_featureset.hpp
@@ -24,13 +24,12 @@
#define GDAL_FEATURESET_HPP
// mapnik
-#include <mapnik/feature.hpp>
+#include <mapnik/featureset.hpp>
+#include <mapnik/query.hpp>
#include <mapnik/util/variant.hpp>
// boost
#include <boost/optional.hpp>
-#include "gdal_datasource.hpp"
-
class GDALDataset;
class GDALRasterBand;
diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp
index d63e243..e9456f8 100644
--- a/plugins/input/geojson/geojson_datasource.cpp
+++ b/plugins/input/geojson/geojson_datasource.cpp
@@ -151,7 +151,7 @@ geojson_datasource::geojson_datasource(parameters const& params)
cache_features_ = *params.get<mapnik::boolean_type>("cache_features", true);
#if !defined(MAPNIK_MEMORY_MAPPED_FILE)
mapnik::util::file file(filename_);
- if (!file.open())
+ if (!file)
{
throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
}
@@ -192,12 +192,14 @@ geojson_datasource::geojson_datasource(parameters const& params)
}
namespace {
+using box_type = box2d<double>;
+using boxes_type = std::vector<std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
using base_iterator_type = char const*;
const mapnik::transcoder geojson_datasource_static_tr("utf8");
const mapnik::json::feature_collection_grammar<base_iterator_type,mapnik::feature_impl> geojson_datasource_static_fc_grammar(geojson_datasource_static_tr);
const mapnik::json::feature_grammar_callback<base_iterator_type,mapnik::feature_impl> geojson_datasource_static_feature_callback_grammar(geojson_datasource_static_tr);
const mapnik::json::feature_grammar<base_iterator_type, mapnik::feature_impl> geojson_datasource_static_feature_grammar(geojson_datasource_static_tr);
-const mapnik::json::extract_bounding_box_grammar<base_iterator_type> geojson_datasource_static_bbox_grammar;
+const mapnik::json::extract_bounding_box_grammar<base_iterator_type, boxes_type> geojson_datasource_static_bbox_grammar;
}
void geojson_datasource::initialise_descriptor(mapnik::feature_ptr const& feature)
@@ -230,7 +232,7 @@ void geojson_datasource::initialise_disk_index(std::string const& filename)
std::ifstream>::query_first_n(filter, index, positions, num_features_to_query_);
mapnik::util::file file(filename_);
- if (!file.open()) throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
+ if (!file) throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
for (auto const& pos : positions)
{
@@ -257,7 +259,7 @@ void geojson_datasource::initialise_disk_index(std::string const& filename)
template <typename Iterator>
void geojson_datasource::initialise_index(Iterator start, Iterator end)
{
- mapnik::json::boxes_type boxes;
+ boxes_type boxes;
boost::spirit::standard::space_type space;
Iterator itr = start;
if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space))
@@ -454,7 +456,7 @@ boost::optional<mapnik::datasource_geometry_t> geojson_datasource::get_geometry_
mapnik::util::file file(filename_);
- if (!file.open()) throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
+ if (!file) throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
for (auto const& pos : positions)
{
@@ -508,7 +510,7 @@ boost::optional<mapnik::datasource_geometry_t> geojson_datasource::get_geometry_
else
{
mapnik::util::file file(filename_);
- if (!file.open())
+ if (!file)
{
throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
}
diff --git a/plugins/input/geojson/geojson_index_featureset.cpp b/plugins/input/geojson/geojson_index_featureset.cpp
index bdf7f8a..4cd1398 100644
--- a/plugins/input/geojson/geojson_index_featureset.cpp
+++ b/plugins/input/geojson/geojson_index_featureset.cpp
@@ -24,7 +24,6 @@
#include "geojson_index_featureset.hpp"
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
-#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/json/feature_grammar.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/util/spatial_index.hpp>
diff --git a/plugins/input/geojson/geojson_memory_index_featureset.cpp b/plugins/input/geojson/geojson_memory_index_featureset.cpp
index 61c5053..32b8513 100644
--- a/plugins/input/geojson/geojson_memory_index_featureset.cpp
+++ b/plugins/input/geojson/geojson_memory_index_featureset.cpp
@@ -23,7 +23,6 @@
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
-#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/json/feature_grammar.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/geometry_is_empty.hpp>
diff --git a/plugins/input/pgraster/pgraster_wkb_reader.cpp b/plugins/input/pgraster/pgraster_wkb_reader.cpp
index 87f71c0..b97d0cd 100644
--- a/plugins/input/pgraster/pgraster_wkb_reader.cpp
+++ b/plugins/input/pgraster/pgraster_wkb_reader.cpp
@@ -183,17 +183,16 @@ mapnik::raster_ptr read_data_band(mapnik::box2d<double> const& bbox,
{
mapnik::image_gray32f image(width, height);
float* data = image.data();
- double val;
- val = reader(); // nodata value, need to read anyway
+ double nodataval = reader();
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x) {
- val = reader();
+ double val = reader();
int off = y * width + x;
data[off] = val;
}
}
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);
- if ( hasnodata ) raster->set_nodata(val);
+ if ( hasnodata ) raster->set_nodata(nodataval);
return raster;
}
@@ -270,15 +269,13 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
image.set(0xffffffff);
- int val;
- int nodataval;
uint8_t * data = image.bytes();
int ps = 4; // sizeof(image::pixel_type)
int off;
- nodataval = reader(); // nodata value, need to read anyway
+ int nodataval = reader();
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x) {
- val = reader();
+ int val = reader();
// Apply harsh type clipping rules ala GDAL
if ( val < 0 ) val = 0;
if ( val > 255 ) val = 255;
@@ -298,7 +295,7 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
}
}
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);
- if ( hasnodata ) raster->set_nodata(val);
+ if ( hasnodata ) raster->set_nodata(nodataval);
return raster;
}
diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp
index d95aa33..909cd58 100644
--- a/plugins/input/postgis/postgis_datasource.cpp
+++ b/plugins/input/postgis/postgis_datasource.cpp
@@ -88,6 +88,17 @@ postgis_datasource::postgis_datasource(parameters const& params)
extent_from_subquery_(*params.get<mapnik::boolean_type>("extent_from_subquery", false)),
max_async_connections_(*params_.get<mapnik::value_integer>("max_async_connection", 1)),
asynchronous_request_(false),
+ twkb_encoding_(false),
+ twkb_rounding_adjustment_(*params_.get<mapnik::value_double>("twkb_rounding_adjustment", 0.0)),
+ simplify_snap_ratio_(*params_.get<mapnik::value_double>("simplify_snap_ratio", 1.0/40.0)),
+ // 1/20 of pixel seems to be a good compromise to avoid
+ // drop of collapsed polygons.
+ // See https://github.com/mapnik/mapnik/issues/1639
+ // See http://trac.osgeo.org/postgis/ticket/2093
+ simplify_dp_ratio_(*params_.get<mapnik::value_double>("simplify_dp_ratio", 1.0/20.0)),
+ simplify_prefilter_(*params_.get<mapnik::value_double>("simplify_prefilter", 0.0)),
+ simplify_dp_preserve_(false),
+ simplify_clip_resolution_(*params_.get<mapnik::value_double>("simplify_clip_resolution", 0.0)),
// TODO - use for known tokens too: "(@\\w+|!\\w+!)"
pattern_(boost::regex("(@\\w+)",boost::regex::normal | boost::regbase::icase)),
// params below are for testing purposes only and may be removed at any time
@@ -130,6 +141,12 @@ postgis_datasource::postgis_datasource(parameters const& params)
boost::optional<mapnik::boolean_type> simplify_opt = params.get<mapnik::boolean_type>("simplify_geometries", false);
simplify_geometries_ = simplify_opt && *simplify_opt;
+ boost::optional<mapnik::boolean_type> twkb_opt = params.get<mapnik::boolean_type>("twkb_encoding", false);
+ twkb_encoding_ = twkb_opt && *twkb_opt;
+
+ boost::optional<mapnik::boolean_type> simplify_preserve_opt = params.get<mapnik::boolean_type>("simplify_dp_preserve", false);
+ simplify_dp_preserve_ = simplify_preserve_opt && *simplify_preserve_opt;
+
ConnectionManager::instance().registerPool(creator_, *initial_size, pool_max_size_);
CnxPool_ptr pool = ConnectionManager::instance().getPool(creator_.id());
if (pool)
@@ -794,25 +811,91 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
const double px_gw = 1.0 / std::get<0>(q.resolution());
const double px_gh = 1.0 / std::get<1>(q.resolution());
+ const double px_sz = std::min(px_gw, px_gh);
- s << "SELECT ST_AsBinary(";
+ if (twkb_encoding_)
+ {
+ // This will only work against PostGIS 2.2, or a back-patched version
+ // that has (a) a ST_Simplify with a "preserve collapsed" flag and
+ // (b) a ST_RemoveRepeatedPoints with a tolerance parameter and
+ // (c) a ST_AsTWKB implementation
- if (simplify_geometries_) {
- s << "ST_Simplify(";
- }
+ // What number of decimals of rounding does the pixel size imply?
+ const int twkb_rounding = -1 * std::lround(log10(px_sz) + twkb_rounding_adjustment_) + 1;
+ // And what's that in map units?
+ const double twkb_tolerance = pow(10.0, -1.0 * twkb_rounding);
- s << "\"" << geometryColumn_ << "\"";
+ s << "SELECT ST_AsTWKB(";
+ s << "ST_Simplify(";
+ s << "ST_RemoveRepeatedPoints(";
- if (simplify_geometries_) {
- // 1/20 of pixel seems to be a good compromise to avoid
- // drop of collapsed polygons.
- // See https://github.com/mapnik/mapnik/issues/1639
- const double tolerance = std::min(px_gw, px_gh) / 20.0;
- s << ", " << tolerance << ")";
+ if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
+ {
+ s << "ST_ClipByBox2D(";
+ }
+ s << "\"" << geometryColumn_ << "\"";
+
+ // ! ST_ClipByBox2D()
+ if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
+ {
+ s << "," << sql_bbox(box) << ")";
+ }
+
+ // ! ST_RemoveRepeatedPoints()
+ s << "," << twkb_tolerance << ")";
+ // ! ST_Simplify(), with parameter to keep collapsed geometries
+ s << "," << twkb_tolerance << ",true)";
+ // ! ST_TWKB()
+ s << "," << twkb_rounding << ") AS geom";
}
+ else
+ {
+ s << "SELECT ST_AsBinary(";
+ if (simplify_geometries_)
+ {
+ s << "ST_Simplify(";
+ }
+ if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
+ {
+ s << "ST_ClipByBox2D(";
+ }
+ if (simplify_geometries_ && simplify_snap_ratio_ > 0.0)
+ {
+ s<< "ST_SnapToGrid(";
+ }
+
+ // Geometry column!
+ s << "\"" << geometryColumn_ << "\"";
- s << ") AS geom";
+ // ! ST_SnapToGrid()
+ if (simplify_geometries_ && simplify_snap_ratio_ > 0.0)
+ {
+ const double tolerance = px_sz * simplify_snap_ratio_;
+ s << "," << tolerance << ")";
+ }
+ // ! ST_ClipByBox2D()
+ if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
+ {
+ s << "," << sql_bbox(box) << ")";
+ }
+
+ // ! ST_Simplify()
+ if (simplify_geometries_)
+ {
+ const double tolerance = px_sz * simplify_dp_ratio_;
+ s << ", " << tolerance;
+ // Add parameter to ST_Simplify to keep collapsed geometries
+ if (simplify_dp_preserve_)
+ {
+ s << ", true";
+ }
+ s << ")";
+ }
+
+ // ! ST_AsBinary()
+ s << ") AS geom";
+ }
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
std::set<std::string> const& props = q.property_names();
std::set<std::string>::const_iterator pos = props.begin();
@@ -854,7 +937,8 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
}
std::shared_ptr<IResultSet> rs = get_resultset(conn, s.str(), pool, proc_ctx);
- return std::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty(), key_field_as_attribute_);
+ return std::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty(),
+ key_field_as_attribute_, twkb_encoding_);
}
@@ -941,7 +1025,8 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
}
std::shared_ptr<IResultSet> rs = get_resultset(conn, s.str(), pool);
- return std::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty(), key_field_as_attribute_);
+ return std::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty(),
+ key_field_as_attribute_, twkb_encoding_);
}
}
diff --git a/plugins/input/postgis/postgis_datasource.hpp b/plugins/input/postgis/postgis_datasource.hpp
index 2f5d24f..80ba894 100644
--- a/plugins/input/postgis/postgis_datasource.hpp
+++ b/plugins/input/postgis/postgis_datasource.hpp
@@ -119,6 +119,13 @@ private:
bool estimate_extent_;
int max_async_connections_;
bool asynchronous_request_;
+ bool twkb_encoding_;
+ mapnik::value_double twkb_rounding_adjustment_;
+ mapnik::value_double simplify_snap_ratio_;
+ mapnik::value_double simplify_dp_ratio_;
+ mapnik::value_double simplify_prefilter_;
+ bool simplify_dp_preserve_;
+ mapnik::value_double simplify_clip_resolution_;
boost::regex pattern_;
int intersect_min_scale_;
int intersect_max_scale_;
diff --git a/plugins/input/postgis/postgis_featureset.cpp b/plugins/input/postgis/postgis_featureset.cpp
index 6d417be..25e2b6b 100644
--- a/plugins/input/postgis/postgis_featureset.cpp
+++ b/plugins/input/postgis/postgis_featureset.cpp
@@ -49,14 +49,16 @@ postgis_featureset::postgis_featureset(std::shared_ptr<IResultSet> const& rs,
context_ptr const& ctx,
std::string const& encoding,
bool key_field,
- bool key_field_as_attribute)
+ bool key_field_as_attribute,
+ bool twkb_encoding)
: rs_(rs),
ctx_(ctx),
tr_(new transcoder(encoding)),
totalGeomSize_(0),
feature_id_(1),
key_field_(key_field),
- key_field_as_attribute_(key_field_as_attribute)
+ key_field_as_attribute_(key_field_as_attribute),
+ twkb_encoding_(twkb_encoding)
{
}
@@ -123,8 +125,14 @@ feature_ptr postgis_featureset::next()
int size = rs_->getFieldLength(0);
const char *data = rs_->getValue(0);
- mapnik::geometry::geometry<double> geometry = geometry_utils::from_wkb(data, size);
- feature->set_geometry(std::move(geometry));
+ if (twkb_encoding_ )
+ {
+ feature->set_geometry(geometry_utils::from_twkb(data, size));
+ }
+ else
+ {
+ feature->set_geometry(geometry_utils::from_wkb(data, size));
+ }
totalGeomSize_ += size;
unsigned num_attrs = ctx_->size() + 1;
diff --git a/plugins/input/postgis/postgis_featureset.hpp b/plugins/input/postgis/postgis_featureset.hpp
index 4984ec9..9ef8cb3 100644
--- a/plugins/input/postgis/postgis_featureset.hpp
+++ b/plugins/input/postgis/postgis_featureset.hpp
@@ -44,7 +44,8 @@ public:
context_ptr const& ctx,
std::string const& encoding,
bool key_field,
- bool key_field_as_attribute);
+ bool key_field_as_attribute,
+ bool twkb_encoding);
feature_ptr next();
~postgis_featureset();
@@ -56,6 +57,7 @@ private:
mapnik::value_integer feature_id_;
bool key_field_;
bool key_field_as_attribute_;
+ bool twkb_encoding_;
};
#endif // POSTGIS_FEATURESET_HPP
diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp
index f9ba8ec..4c4e6b5 100644
--- a/plugins/input/topojson/topojson_datasource.cpp
+++ b/plugins/input/topojson/topojson_datasource.cpp
@@ -166,7 +166,7 @@ topojson_datasource::topojson_datasource(parameters const& params)
else
{
mapnik::util::file file(filename_);
- if (!file.open())
+ if (!file)
{
throw mapnik::datasource_exception("TopoJSON Plugin: could not open: '" + filename_ + "'");
}
diff --git a/plugins/input/topojson/topojson_featureset.cpp b/plugins/input/topojson/topojson_featureset.cpp
index 9e7c23e..36dbdf9 100644
--- a/plugins/input/topojson/topojson_featureset.cpp
+++ b/plugins/input/topojson/topojson_featureset.cpp
@@ -21,13 +21,8 @@
*****************************************************************************/
// mapnik
-#include <mapnik/feature.hpp>
-#include <mapnik/feature_factory.hpp>
#include <mapnik/json/topology.hpp>
-#include <mapnik/util/variant.hpp>
-#include <mapnik/geometry_adapters.hpp>
-#include <mapnik/geometry_correct.hpp>
-
+#include <mapnik/json/topojson_utils.hpp>
// stl
#include <string>
#include <vector>
@@ -40,334 +35,6 @@
#include "topojson_featureset.hpp"
-namespace mapnik { namespace topojson {
-
-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)
-{
- if ( geom.props)
- {
- 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)));
- }
- }
-}
-
-template <typename Context>
-struct feature_generator
-{
- feature_generator(Context & ctx, mapnik::transcoder const& tr, topology const& topo, std::size_t feature_id)
- : ctx_(ctx),
- tr_(tr),
- topo_(topo),
- num_arcs_(topo.arcs.size()),
- feature_id_(feature_id) {}
-
- feature_ptr operator() (point const& pt) const
- {
- mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
- double x = pt.coord.x;
- double y = pt.coord.y;
- if (topo_.tr)
- {
- x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
- }
- mapnik::geometry::point<double> point(x, y);
- feature->set_geometry(std::move(point));
- assign_properties(*feature, pt, tr_);
- return feature;
- }
-
- feature_ptr operator() (multi_point const& multi_pt) const
- {
- mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
- mapnik::geometry::multi_point<double> multi_point;
- multi_point.reserve(multi_pt.points.size());
- for (auto const& pt : multi_pt.points)
- {
- double x = pt.x;
- double y = pt.y;
- if (topo_.tr)
- {
- x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
- y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
- }
- multi_point.add_coord(x, y);
- }
- feature->set_geometry(std::move(multi_point));
- assign_properties(*feature, multi_pt, tr_);
- return feature;
- }
-
- feature_ptr operator() (linestring const& line) const
- {
- 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());
-
- 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;
- }
- line_string.add_coord(x,y);
- }
- feature->set_geometry(std::move(line_string));
- assign_properties(*feature, line, tr_);
- }
- }
- return feature;
- }
-
- feature_ptr operator() (multi_linestring const& multi_line) const
- {
- mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
- if (num_arcs_ > 0)
- {
- 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)
- {
- index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
- {
- 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)
- {
- 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);
- }
- multi_line_string.push_back(std::move(line_string));
- }
- }
- if (hit)
- {
- feature->set_geometry(std::move(multi_line_string));
- assign_properties(*feature, multi_line, tr_);
- }
- }
- return feature;
- }
-
- feature_ptr operator() (polygon const& poly) const
- {
- mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
- if (num_arcs_ > 0)
- {
- std::vector<mapnik::topojson::coordinate> processed_coords;
- mapnik::geometry::polygon<double> polygon;
- if (poly.rings.size() > 1) polygon.interior_rings.reserve(poly.rings.size() - 1);
- bool first = true;
- bool hit = false;
- for (auto const& ring : poly.rings)
- {
- mapnik::geometry::linear_ring<double> linear_ring;
- for (auto const& index : ring)
- {
- double px = 0, py = 0;
- bool reverse = index < 0;
- index_type arc_index = reverse ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
- {
- hit = true;
- auto const& arcs = topo_.arcs[arc_index];
- auto const& coords = arcs.coordinates;
- processed_coords.clear();
- processed_coords.reserve(coords.size());
- for (auto const& pt : coords )
- {
- double x = pt.x;
- double y = pt.y;
-
- if (topo_.tr)
- {
- 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});
- }
-
- if (reverse)
- {
- for (auto const& c : processed_coords | boost::adaptors::reversed)
- {
- linear_ring.emplace_back(c.x, c.y);
- }
- }
- else
- {
- for (auto const& c : processed_coords)
- {
- linear_ring.emplace_back(c.x, c.y);
- }
- }
- }
- }
- if (first)
- {
- first = false;
- polygon.set_exterior_ring(std::move(linear_ring));
- }
- else
- {
- polygon.add_hole(std::move(linear_ring));
- }
- }
- if (hit)
- {
- mapnik::geometry::correct(polygon);
- feature->set_geometry(std::move(polygon));
- assign_properties(*feature, poly, tr_);
- }
- }
- return feature;
- }
-
- feature_ptr operator() (multi_polygon const& multi_poly) const
- {
- mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_));
- if (num_arcs_ > 0)
- {
- std::vector<mapnik::topojson::coordinate> processed_coords;
- mapnik::geometry::multi_polygon<double> multi_polygon;
- multi_polygon.reserve(multi_poly.polygons.size());
- bool hit = false;
- for (auto const& poly : multi_poly.polygons)
- {
- bool first = true;
- mapnik::geometry::polygon<double> polygon;
- if (poly.size() > 1) polygon.interior_rings.reserve(poly.size() - 1);
-
- for (auto const& ring : poly)
- {
- mapnik::geometry::linear_ring<double> linear_ring;
- for (auto const& index : ring)
- {
- double px = 0, py = 0;
- bool reverse = index < 0;
- index_type arc_index = reverse ? std::abs(index) - 1 : index;
- if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
- {
- hit = true;
- auto const& arcs = topo_.arcs[arc_index];
- auto const& coords = arcs.coordinates;
- processed_coords.clear();
- processed_coords.reserve(coords.size());
- for (auto const& pt : coords )
- {
- 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;
- }
- processed_coords.emplace_back(coordinate{x,y});
- }
-
- using namespace boost::adaptors;
-
- if (reverse)
- {
- for (auto const& c : (processed_coords | reversed))
- {
- linear_ring.add_coord(c.x, c.y);
- }
- }
- else
- {
- for (auto const& c : processed_coords)
- {
- linear_ring.add_coord(c.x, c.y);
- }
- }
- }
- }
- if (first)
- {
- first = false;
- polygon.set_exterior_ring(std::move(linear_ring));
- }
- else
- {
- polygon.add_hole(std::move(linear_ring));
- }
- }
- multi_polygon.push_back(std::move(polygon));
- }
- if (hit)
- {
- mapnik::geometry::correct(multi_polygon);
- feature->set_geometry(std::move(multi_polygon));
- assign_properties(*feature, multi_poly, tr_);
- }
- }
- return feature;
- }
-
- template<typename T>
- feature_ptr operator() (T const& ) const
- {
- return feature_ptr();
- }
-
- Context & ctx_;
- mapnik::transcoder const& tr_;
- topology const& topo_;
- std::size_t num_arcs_;
- std::size_t feature_id_;
-};
-
-}}
-
topojson_featureset::topojson_featureset(mapnik::topojson::topology const& topo,
mapnik::transcoder const& tr,
array_type && index_array)
diff --git a/scripts/build-appveyor.bat b/scripts/build-appveyor.bat
index 3c8b3d0..84088d4 100644
--- a/scripts/build-appveyor.bat
+++ b/scripts/build-appveyor.bat
@@ -22,14 +22,16 @@ ECHO msvs_toolset^: %msvs_toolset%
SET BUILD_TYPE=%configuration%
SET BUILDPLATFORM=%platform%
SET TOOLS_VERSION=%msvs_toolset%.0
+SET ICU_VERSION=56.1
+ECHO ICU_VERSION^: %ICU_VERSION%
IF DEFINED APPVEYOR (ECHO on AppVeyor) ELSE (ECHO NOT on AppVeyor)
ECHO ========
SET PATH=C:\Python27;%PATH%
SET PATH=C:\Program Files\7-Zip;%PATH%
-::update submodule variant
-git submodule update --init deps/mapbox/variant
+::update submodules (variant + test data)
+git submodule update --init
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
diff --git a/scripts/travis-common.sh b/scripts/travis-common.sh
index cfdc57f..15b38dd 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]'; then
+ if commit_message_contains '[skip tests]' || [[ $(uname -s) == 'Darwin' ]]; then
config_override "CPP_TESTS = False"
fi
if commit_message_contains '[skip utils]'; then
@@ -81,19 +81,10 @@ config_override () {
configure () {
if enabled ${COVERAGE}; then
- ./configure "$@" PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \
- CUSTOM_LDFLAGS='--coverage' CUSTOM_CXXFLAGS='--coverage' \
- CUSTOM_CFLAGS='--coverage' DEBUG=True
- elif enabled ${MASON_PUBLISH}; then
- export MASON_NAME=mapnik
- export MASON_VERSION=latest
- export MASON_LIB_FILE=lib/libmapnik-wkt.a
- source ./.mason/mason.sh
- ./configure "$@" PREFIX=${MASON_PREFIX} \
- PATH_REPLACE='' MAPNIK_BUNDLED_SHARE_DIRECTORY=True \
- RUNTIME_LINK='static'
+ ./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \
+ COVERAGE=True DEBUG=True WARNING_CXXFLAGS="-Wno-unknown-warning-option"
else
- ./configure "$@"
+ ./configure "$@" PREFIX=${PREFIX} WARNING_CXXFLAGS="-Wno-unknown-warning-option"
fi
# print final config values, sorted and indented
sort -sk1,1 ./config.py | sed -e 's/^/ /'
@@ -101,9 +92,29 @@ configure () {
coverage () {
./mason_packages/.link/bin/cpp-coveralls \
- --build-root . --gcov-options '\-lp' --exclude mason_packages \
+ --gcov /usr/bin/llvm-cov-${LLVM_VERSION} \
+ --build-root . --gcov-options '\-lp' \
+ --exclude mason_packages \
--exclude .sconf_temp --exclude benchmark --exclude deps \
--exclude scons --exclude test --exclude demo --exclude docs \
- --exclude fonts --exclude utils \
+ --exclude fonts \
> /dev/null
}
+
+trigger_downstream() {
+ body="{
+ \"request\": {
+ \"message\": \"Triggered build: Mapnik core commit ${TRAVIS_COMMIT}\",
+ \"branch\":\"master\"
+ }
+ }
+ "
+
+ curl -s -X POST \
+ -H "Content-Type: application/json" \
+ -H "Accept: application/json" \
+ -H "Travis-API-Version: 3" \
+ -H "Authorization: token ${TRAVIS_TRIGGER_TOKEN}" \
+ -d "$body" \
+ https://api.travis-ci.org/repo/mapnik%2Fpython-mapnik/requests
+}
diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp
index 9fbcdca..f144cea 100644
--- a/src/agg/agg_renderer.cpp
+++ b/src/agg/agg_renderer.cpp
@@ -43,7 +43,9 @@
#include <mapnik/image_filter.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_any.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_color_rgba.h"
@@ -53,9 +55,12 @@
#include "agg_span_allocator.h"
#include "agg_image_accessors.h"
#include "agg_span_image_filter_rgba.h"
+#pragma GCC diagnostic pop
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
// stl
#include <cmath>
diff --git a/src/agg/process_building_symbolizer.cpp b/src/agg/process_building_symbolizer.cpp
index aabba77..d27b68b 100644
--- a/src/agg/process_building_symbolizer.cpp
+++ b/src/agg/process_building_symbolizer.cpp
@@ -33,10 +33,12 @@
#include <mapnik/expression.hpp>
#include <mapnik/renderer_common/process_building_symbolizer.hpp>
#include <mapnik/transform_path_adapter.hpp>
+
// stl
#include <deque>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_color_rgba.h"
@@ -45,6 +47,7 @@
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_conv_stroke.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/agg/process_debug_symbolizer.cpp b/src/agg/process_debug_symbolizer.cpp
index 2016c45..3c3f898 100644
--- a/src/agg/process_debug_symbolizer.cpp
+++ b/src/agg/process_debug_symbolizer.cpp
@@ -33,7 +33,8 @@
#include <mapnik/agg_helpers.hpp>
#include <mapnik/util/is_clockwise.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_color_rgba.h"
@@ -41,6 +42,7 @@
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_conv_stroke.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_dot_symbolizer.cpp b/src/agg/process_dot_symbolizer.cpp
index cc37586..cfb58c6 100644
--- a/src/agg/process_dot_symbolizer.cpp
+++ b/src/agg/process_dot_symbolizer.cpp
@@ -33,7 +33,8 @@
#include <mapnik/proj_transform.hpp>
#include <mapnik/image_compositing.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_ellipse.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
@@ -41,6 +42,7 @@
#include "agg_renderer_scanline.h"
#include "agg_color_rgba.h"
#include "agg_renderer_base.h"
+#pragma GCC diagnostic pop
namespace mapnik { namespace detail {
diff --git a/src/agg/process_group_symbolizer.cpp b/src/agg/process_group_symbolizer.cpp
index 010d3f1..6ba5605 100644
--- a/src/agg/process_group_symbolizer.cpp
+++ b/src/agg/process_group_symbolizer.cpp
@@ -35,8 +35,10 @@
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_converter.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp
index f5045c5..3b947a4 100644
--- a/src/agg/process_line_pattern_symbolizer.cpp
+++ b/src/agg/process_line_pattern_symbolizer.cpp
@@ -37,7 +37,10 @@
#include <mapnik/renderer_common/clipping_extent.hpp>
#include <mapnik/renderer_common/render_pattern.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
-// agg
+
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_pixfmt_rgba.h"
#include "agg_color_rgba.h"
@@ -50,6 +53,7 @@
#include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h"
#include "agg_renderer_outline_image.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp
index b3a01c7..9bace25 100644
--- a/src/agg/process_line_symbolizer.cpp
+++ b/src/agg/process_line_symbolizer.cpp
@@ -32,7 +32,9 @@
#include <mapnik/renderer_common/clipping_extent.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/geometry_type.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
@@ -45,6 +47,7 @@
#include "agg_conv_dash.h"
#include "agg_renderer_outline_aa.h"
#include "agg_rasterizer_outline_aa.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp
index b229f01..3fc122d 100644
--- a/src/agg/process_markers_symbolizer.cpp
+++ b/src/agg/process_markers_symbolizer.cpp
@@ -33,7 +33,8 @@
#include <mapnik/renderer_common/clipping_extent.hpp>
#include <mapnik/renderer_common/render_markers_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_renderer_base.h"
#include "agg_renderer_scanline.h"
@@ -44,6 +45,7 @@
#include "agg_scanline_u.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp
index 1da740f..bb54db5 100644
--- a/src/agg/process_point_symbolizer.cpp
+++ b/src/agg/process_point_symbolizer.cpp
@@ -34,8 +34,10 @@
#include <mapnik/pixel_position.hpp>
#include <mapnik/renderer_common/process_point_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp
index 8e340a9..e654886 100644
--- a/src/agg/process_polygon_pattern_symbolizer.cpp
+++ b/src/agg/process_polygon_pattern_symbolizer.cpp
@@ -39,7 +39,9 @@
#include <mapnik/renderer_common/render_pattern.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/renderer_common/pattern_alignment.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
@@ -52,6 +54,7 @@
#include "agg_span_pattern_rgba.h"
#include "agg_image_accessors.h"
#include "agg_conv_clip_polygon.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp
index 9af6d4a..bd2d2bc 100644
--- a/src/agg/process_polygon_symbolizer.cpp
+++ b/src/agg/process_polygon_symbolizer.cpp
@@ -32,7 +32,9 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/renderer_common/process_polygon_symbolizer.hpp>
#include <mapnik/renderer_common/clipping_extent.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
@@ -40,6 +42,7 @@
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/agg/process_raster_symbolizer.cpp b/src/agg/process_raster_symbolizer.cpp
index 0105e9b..746a5cc 100644
--- a/src/agg/process_raster_symbolizer.cpp
+++ b/src/agg/process_raster_symbolizer.cpp
@@ -38,9 +38,11 @@
// stl
#include <cmath>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/box2d.cpp b/src/box2d.cpp
index 26e6929..7d54233 100644
--- a/src/box2d.cpp
+++ b/src/box2d.cpp
@@ -299,33 +299,43 @@ void box2d<T>::re_center(coord<T,2> const& c)
}
template <typename T>
-void box2d<T>::init(T x0,T y0,T x1,T y1)
+void box2d<T>::init(T x0, T y0, T x1, T y1)
{
- if (x0<x1)
+ if (x0 < x1)
{
- minx_=x0;maxx_=x1;
+ minx_ = x0;
+ maxx_ = x1;
}
else
{
- minx_=x1;maxx_=x0;
+ minx_ = x1;
+ maxx_ = x0;
}
- if (y0<y1)
+ if (y0 < y1)
{
- miny_=y0;maxy_=y1;
+ miny_ = y0;
+ maxy_ = y1;
}
else
{
- miny_=y1;maxy_=y0;
+ 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());
+ 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>
@@ -337,7 +347,6 @@ void box2d<T>::pad(T padding)
maxy_ += padding;
}
-
template <typename T>
bool box2d<T>::from_string(std::string const& str)
{
@@ -346,8 +355,7 @@ bool box2d<T>::from_string(std::string const& str)
boost::spirit::ascii::space_type space;
bool r = boost::spirit::qi::phrase_parse(str.begin(),
str.end(),
- double_ >> -lit(',') >> double_ >> -lit(',')
- >> double_ >> -lit(',') >> double_,
+ double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_,
space,
*this);
return r;
@@ -372,9 +380,16 @@ template <typename T>
std::string box2d<T>::to_string() const
{
std::ostringstream s;
- s << "box2d(" << std::fixed << std::setprecision(16)
- << minx_ << ',' << miny_ << ','
- << maxx_ << ',' << maxy_ << ')';
+ if (valid())
+ {
+ s << "box2d(" << std::fixed << std::setprecision(16)
+ << minx_ << ',' << miny_ << ','
+ << maxx_ << ',' << maxy_ << ')';
+ }
+ else
+ {
+ s << "box2d(INVALID)";
+ }
return s.str();
}
@@ -480,6 +495,7 @@ box2d<T>& box2d<T>::operator*=(agg::trans_affine const& tr)
}
template class box2d<int>;
+template class box2d<float>;
template class box2d<double>;
}
diff --git a/src/build.py b/src/build.py
index c405eb1..6dd0f24 100644
--- a/src/build.py
+++ b/src/build.py
@@ -62,6 +62,10 @@ system = 'boost_system%s' % env['BOOST_APPEND']
lib_env['LIBS'] = [filesystem,
regex]
+if env['COVERAGE']:
+ lib_env.Append(LINKFLAGS='--coverage')
+ lib_env.Append(CXXFLAGS='--coverage')
+
if env['HAS_CAIRO']:
lib_env.Append(LIBS=env['CAIRO_ALL_LIBS'])
@@ -201,6 +205,7 @@ source = Split(
rule.cpp
save_map.cpp
wkb.cpp
+ twkb.cpp
projection.cpp
proj_transform.cpp
scale_denominator.cpp
@@ -221,6 +226,7 @@ source = Split(
warp.cpp
css_color_grammar.cpp
vertex_cache.cpp
+ vertex_adapters.cpp
text/font_library.cpp
text/text_layout.cpp
text/text_line.cpp
@@ -257,6 +263,7 @@ source = Split(
renderer_common/render_pattern.cpp
renderer_common/render_thunk_extractor.cpp
math.cpp
+ value.cpp
"""
)
diff --git a/src/cairo/process_polygon_pattern_symbolizer.cpp b/src/cairo/process_polygon_pattern_symbolizer.cpp
index aa7b0ca..c2b211f 100644
--- a/src/cairo/process_polygon_pattern_symbolizer.cpp
+++ b/src/cairo/process_polygon_pattern_symbolizer.cpp
@@ -124,8 +124,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
agg::trans_affine tr;
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); }
- using vertex_converter_type = vertex_converter<
- clip_poly_tag,
+ using vertex_converter_type = vertex_converter<clip_poly_tag,
transform_tag,
affine_transform_tag,
simplify_tag,
diff --git a/src/debug.cpp b/src/debug.cpp
index 169272f..d1ae15f 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -22,6 +22,7 @@
// mapnik
#include <mapnik/debug.hpp>
+#include <mapnik/stringify_macro.hpp>
// stl
#include <ctime>
@@ -74,14 +75,7 @@ logger::severity_type logger::severity_level_ {
logger::severity_map logger::object_severity_level_ = logger::severity_map();
-
-// format
-
-#define __xstr__(s) __str__(s)
-#define __str__(s) #s
-std::string logger::format_ = __xstr__(MAPNIK_LOG_FORMAT);
-#undef __xstr__
-#undef __str__
+std::string logger::format_ = MAPNIK_STRINGIFY(MAPNIK_LOG_FORMAT);
std::string logger::str()
{
diff --git a/src/feature_kv_iterator.cpp b/src/feature_kv_iterator.cpp
index 8fdba82..4ae3842 100644
--- a/src/feature_kv_iterator.cpp
+++ b/src/feature_kv_iterator.cpp
@@ -22,7 +22,11 @@
#include <mapnik/feature_kv_iterator.hpp>
#include <mapnik/feature.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp
index efe654b..a14e6b6 100644
--- a/src/font_engine_freetype.cpp
+++ b/src/font_engine_freetype.cpp
@@ -33,11 +33,6 @@
#include <mapnik/warning_ignore.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/optional.hpp>
-#pragma GCC diagnostic pop
-
-// stl
-#include <algorithm>
-#include <stdexcept>
// freetype2
extern "C"
@@ -47,6 +42,11 @@ extern "C"
#include FT_STROKER_H
#include FT_MODULE_H
}
+#pragma GCC diagnostic pop
+
+// stl
+#include <algorithm>
+#include <stdexcept>
namespace mapnik
@@ -75,7 +75,7 @@ unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *
if (count <= 0) return 0;
FILE * file = static_cast<FILE *>(stream->descriptor.pointer);
std::fseek (file , offset , SEEK_SET);
- return std::fread ((char*)buffer, 1, count, file);
+ return std::fread(reinterpret_cast<unsigned char*>(buffer), 1, count, file);
}
bool freetype_engine::register_font(std::string const& file_name)
@@ -93,7 +93,7 @@ bool freetype_engine::register_font_impl(std::string const& file_name,
{
MAPNIK_LOG_DEBUG(font_engine_freetype) << "registering: " << file_name;
mapnik::util::file file(file_name);
- if (!file.open()) return false;
+ if (!file) return false;
FT_Face face = 0;
FT_Open_Args args;
@@ -258,7 +258,7 @@ bool freetype_engine::can_open(std::string const& face_name,
}
if (!found_font_file) return false;
mapnik::util::file file(itr->second.second);
- if (!file.open()) return false;
+ if (!file) return false;
FT_Face face = 0;
FT_Open_Args args;
FT_StreamRec streamRec;
@@ -332,7 +332,7 @@ face_ptr freetype_engine::create_face(std::string const& family_name,
if (found_font_file)
{
mapnik::util::file file(itr->second.second);
- if (file.open())
+ if (file)
{
#ifdef MAPNIK_THREADSAFE
std::lock_guard<std::mutex> lock(mutex_);
diff --git a/src/fs.cpp b/src/fs.cpp
index 9c87d97..6403453 100644
--- a/src/fs.cpp
+++ b/src/fs.cpp
@@ -24,9 +24,12 @@
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/util/fs.hpp>
-// boost
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/filesystem/operations.hpp> // for absolute, exists, etc
#include <boost/filesystem/path.hpp> // for path, operator/
+#pragma GCC diagnostic pop
// stl
#include <stdexcept>
diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp
index 33d10ee..fd970f5 100644
--- a/src/grid/grid_renderer.cpp
+++ b/src/grid/grid_renderer.cpp
@@ -47,11 +47,15 @@
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/pixel_position.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/math/special_functions/round.hpp>
+#pragma GCC diagnostic pop
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/grid/process_building_symbolizer.cpp b/src/grid/process_building_symbolizer.cpp
index e6649da..13ee8d4 100644
--- a/src/grid/process_building_symbolizer.cpp
+++ b/src/grid/process_building_symbolizer.cpp
@@ -39,11 +39,13 @@
// stl
#include <deque>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
#include "agg_conv_stroke.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/grid/process_group_symbolizer.cpp b/src/grid/process_group_symbolizer.cpp
index a93ea9d..ba7f48e 100644
--- a/src/grid/process_group_symbolizer.cpp
+++ b/src/grid/process_group_symbolizer.cpp
@@ -37,8 +37,10 @@
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/renderer_common/render_group_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/grid/process_line_pattern_symbolizer.cpp b/src/grid/process_line_pattern_symbolizer.cpp
index dc370f7..af54ac5 100644
--- a/src/grid/process_line_pattern_symbolizer.cpp
+++ b/src/grid/process_line_pattern_symbolizer.cpp
@@ -35,12 +35,15 @@
#include <mapnik/vertex_processor.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/grid/process_line_symbolizer.cpp b/src/grid/process_line_symbolizer.cpp
index c569f6b..b65dd85 100644
--- a/src/grid/process_line_symbolizer.cpp
+++ b/src/grid/process_line_symbolizer.cpp
@@ -32,12 +32,15 @@
#include <mapnik/vertex_processor.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
#include <mapnik/geometry_type.hpp>
-// agg
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/grid/process_markers_symbolizer.cpp b/src/grid/process_markers_symbolizer.cpp
index 2fa71c8..3809232 100644
--- a/src/grid/process_markers_symbolizer.cpp
+++ b/src/grid/process_markers_symbolizer.cpp
@@ -55,10 +55,12 @@ porting notes -->
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/renderer_common/render_markers_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/grid/process_point_symbolizer.cpp b/src/grid/process_point_symbolizer.cpp
index 130fc1f..6032800 100644
--- a/src/grid/process_point_symbolizer.cpp
+++ b/src/grid/process_point_symbolizer.cpp
@@ -36,8 +36,10 @@
#include <mapnik/pixel_position.hpp>
#include <mapnik/renderer_common/process_point_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/grid/process_polygon_pattern_symbolizer.cpp b/src/grid/process_polygon_pattern_symbolizer.cpp
index 06408a8..03e27c6 100644
--- a/src/grid/process_polygon_pattern_symbolizer.cpp
+++ b/src/grid/process_polygon_pattern_symbolizer.cpp
@@ -36,10 +36,12 @@
#include <mapnik/parse_path.hpp>
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
@@ -76,7 +78,12 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
}
- using vertex_converter_type = vertex_converter<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag>;
+ using vertex_converter_type = vertex_converter<clip_poly_tag,
+ transform_tag,
+ affine_transform_tag,
+ simplify_tag,
+ smooth_tag>;
+
vertex_converter_type converter(common_.query_extent_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (prj_trans.equal() && clip) converter.set<clip_poly_tag>();
diff --git a/src/grid/process_polygon_symbolizer.cpp b/src/grid/process_polygon_symbolizer.cpp
index 3e1f089..ab85262 100644
--- a/src/grid/process_polygon_symbolizer.cpp
+++ b/src/grid/process_polygon_symbolizer.cpp
@@ -34,10 +34,12 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/renderer_common/process_polygon_symbolizer.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/src/grid/process_shield_symbolizer.cpp b/src/grid/process_shield_symbolizer.cpp
index 50bc820..0463bee 100644
--- a/src/grid/process_shield_symbolizer.cpp
+++ b/src/grid/process_shield_symbolizer.cpp
@@ -33,8 +33,11 @@
#include <mapnik/text/renderer.hpp>
#include <mapnik/text/glyph_positions.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#include "agg_gamma_functions.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp
index 925f56e..a8f9bba 100644
--- a/src/image_compositing.cpp
+++ b/src/image_compositing.cpp
@@ -33,7 +33,8 @@
#include <boost/bimap.hpp>
#pragma GCC diagnostic pop
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
@@ -41,7 +42,7 @@
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_color_rgba.h"
-
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/image_scaling.cpp b/src/image_scaling.cpp
index f0cc450..413948c 100644
--- a/src/image_scaling.cpp
+++ b/src/image_scaling.cpp
@@ -25,14 +25,14 @@
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_scaling_traits.hpp>
-// boost
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/bimap.hpp>
#pragma GCC diagnostic pop
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_image_accessors.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
@@ -47,6 +47,7 @@
#include "agg_span_interpolator_linear.h"
#include "agg_trans_affine.h"
#include "agg_image_filters.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/image_util.cpp b/src/image_util.cpp
index 43c5991..1fec8b1 100644
--- a/src/image_util.cpp
+++ b/src/image_util.cpp
@@ -38,13 +38,14 @@
#include <mapnik/safe_cast.hpp>
#ifdef SSE_MATH
#include <mapnik/sse.hpp>
-
#endif
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_color_rgba.h"
+#pragma GCC diagnostic pop
// stl
#include <string>
diff --git a/include/mapnik/util/geometry_to_geojson.hpp b/src/json/mapnik_geometry_to_geojson.cpp
similarity index 86%
copy from include/mapnik/util/geometry_to_geojson.hpp
copy to src/json/mapnik_geometry_to_geojson.cpp
index 5cccb09..ab26180 100644
--- a/include/mapnik/util/geometry_to_geojson.hpp
+++ b/src/json/mapnik_geometry_to_geojson.cpp
@@ -20,16 +20,13 @@
*
*****************************************************************************/
-#ifndef MAPNIK_GEOMETRY_TO_GEOJSON_HPP
-#define MAPNIK_GEOMETRY_TO_GEOJSON_HPP
-
// mapnik
-
+#include <mapnik/util/geometry_to_geojson.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
namespace mapnik { namespace util {
-inline bool to_geojson(std::string & json, mapnik::geometry::geometry<double> const& geom)
+bool to_geojson(std::string & json, mapnik::geometry::geometry<double> const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::json::geometry_generator_grammar<sink_type, mapnik::geometry::geometry<double> > grammar;
@@ -38,5 +35,3 @@ inline bool to_geojson(std::string & json, mapnik::geometry::geometry<double> co
}
}}
-
-#endif // MAPNIK_GEOMETRY_TO_GEOJSON_HPP
diff --git a/include/mapnik/json/geometry_parser.hpp b/src/json/mapnik_json_geometry_parser.cpp
similarity index 84%
copy from include/mapnik/json/geometry_parser.hpp
copy to src/json/mapnik_json_geometry_parser.cpp
index c83901d..278d2c4 100644
--- a/include/mapnik/json/geometry_parser.hpp
+++ b/src/json/mapnik_json_geometry_parser.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
@@ -20,12 +20,8 @@
*
*****************************************************************************/
-#ifndef MAPNIK_JSON_GEOMETRY_PARSER_HPP
-#define MAPNIK_JSON_GEOMETRY_PARSER_HPP
-
-// mapnik
-
+#include <mapnik/json/geometry_parser.hpp>
#include <mapnik/json/geometry_grammar.hpp>
// boost
@@ -34,7 +30,7 @@
namespace mapnik { namespace json {
-inline bool from_geojson(std::string const& json, mapnik::geometry::geometry<double> & geom)
+bool from_geojson(std::string const& json, mapnik::geometry::geometry<double> & geom)
{
using namespace boost::spirit;
static const geometry_grammar<char const*> g;
@@ -45,5 +41,3 @@ inline bool from_geojson(std::string const& json, mapnik::geometry::geometry<dou
}
}}
-
-#endif // MAPNIK_JSON_GEOMETRY_PARSER_HPP
diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/src/json/mapnik_json_positions_grammar.cpp
similarity index 77%
copy from include/mapnik/grid/grid_rendering_buffer.hpp
copy to src/json/mapnik_json_positions_grammar.cpp
index 4282e3b..a13f0e3 100644
--- a/include/mapnik/grid/grid_rendering_buffer.hpp
+++ b/src/json/mapnik_json_positions_grammar.cpp
@@ -20,16 +20,8 @@
*
*****************************************************************************/
-#ifndef MAPNIK_GRID_RENDERING_BUFFER_HPP
-#define MAPNIK_GRID_RENDERING_BUFFER_HPP
+#include <mapnik/json/positions_grammar_impl.hpp>
+#include <string>
-#include <mapnik/grid/grid.hpp>
-#include "agg_rendering_buffer.h"
-
-namespace mapnik {
-
-using grid_rendering_buffer = agg::row_ptr_cache<mapnik::grid::value_type>;
-
-}
-
-#endif //MAPNIK_AGG_RASTERIZER_HPP
+using iterator_type = char const*;
+template struct mapnik::json::positions_grammar<iterator_type>;
diff --git a/src/load_map.cpp b/src/load_map.cpp
index 6e15ba2..f217082 100644
--- a/src/load_map.cpp
+++ b/src/load_map.cpp
@@ -59,18 +59,22 @@
#include <mapnik/evaluate_global_attributes.hpp>
#include <mapnik/boolean.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
#include <boost/tokenizer.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/static_assert.hpp>
+#pragma GCC diagnostic pop
// stl
#include <algorithm>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
+#pragma GCC diagnostic pop
using boost::tokenizer;
diff --git a/src/map.cpp b/src/map.cpp
index c44735c..3aff557 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -307,7 +307,7 @@ bool Map::load_fonts()
continue;
}
mapnik::util::file file(file_path);
- if (file.open())
+ if (file)
{
auto item = font_memory_cache_.emplace(file_path, std::make_pair(file.data(),file.size()));
if (item.second) result = true;
diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp
index 9e40622..6fef861 100644
--- a/src/marker_cache.cpp
+++ b/src/marker_cache.cpp
@@ -39,9 +39,11 @@
#include <boost/algorithm/string.hpp>
#pragma GCC diagnostic pop
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/marker_helpers.cpp b/src/marker_helpers.cpp
index cf37cdb..dc9f679 100644
--- a/src/marker_helpers.cpp
+++ b/src/marker_helpers.cpp
@@ -23,9 +23,13 @@
// mapnik
#include <mapnik/marker_helpers.hpp>
#include <mapnik/svg/svg_converter.hpp>
+#include <mapnik/label_collision_detector.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_ellipse.h"
#include "agg_color_rgba.h"
+#pragma GCC diagnostic pop
namespace mapnik {
@@ -158,5 +162,142 @@ void setup_transform_scaling(agg::trans_affine & tr,
}
}
+template <typename Processor>
+void apply_markers_single(vertex_converter_type & converter, Processor & proc,
+ geometry::geometry<double> const& geom, geometry::geometry_types type)
+{
+ if (type == geometry::geometry_types::Point)
+ {
+ geometry::point_vertex_adapter<double> va(geom.get<geometry::point<double>>());
+ converter.apply(va, proc);
+ }
+ else if (type == geometry::geometry_types::LineString)
+ {
+ geometry::line_string_vertex_adapter<double> va(geom.get<geometry::line_string<double>>());
+ converter.apply(va, proc);
+ }
+ else if (type == geometry::geometry_types::Polygon)
+ {
+ geometry::polygon_vertex_adapter<double> va(geom.get<geometry::polygon<double>>());
+ converter.apply(va, proc);
+ }
+ else if (type == geometry::geometry_types::MultiPoint)
+ {
+ for (auto const& pt : geom.get<geometry::multi_point<double>>())
+ {
+ geometry::point_vertex_adapter<double> va(pt);
+ converter.apply(va, proc);
+ }
+ }
+ else if (type == geometry::geometry_types::MultiLineString)
+ {
+ for (auto const& line : geom.get<geometry::multi_line_string<double>>())
+ {
+ geometry::line_string_vertex_adapter<double> va(line);
+ converter.apply(va, proc);
+ }
+ }
+ else if (type == geometry::geometry_types::MultiPolygon)
+ {
+ for (auto const& poly : geom.get<geometry::multi_polygon<double>>())
+ {
+ geometry::polygon_vertex_adapter<double> va(poly);
+ converter.apply(va, proc);
+ }
+ }
+}
+
+template <typename Processor>
+void apply_markers_multi(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, Processor & proc, symbolizer_base const& sym)
+{
+ auto const& geom = feature.get_geometry();
+ geometry::geometry_types type = geometry::geometry_type(geom);
+
+ if (type == geometry::geometry_types::Point
+ ||
+ type == geometry::geometry_types::LineString
+ ||
+ type == geometry::geometry_types::Polygon)
+ {
+ apply_markers_single(converter, proc, geom, type);
+ }
+ else
+ {
+
+ marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum, keys::markers_multipolicy>(sym, feature, vars);
+ marker_placement_enum placement = get<marker_placement_enum, keys::markers_placement_type>(sym, feature, vars);
+
+ if (placement == MARKER_POINT_PLACEMENT &&
+ multi_policy == MARKER_WHOLE_MULTI)
+ {
+ geometry::point<double> pt;
+ // test if centroid is contained by bounding box
+ if (geometry::centroid(geom, pt) && converter.disp_.args_.bbox.contains(pt.x, pt.y))
+ {
+ // unset any clipping since we're now dealing with a point
+ converter.template unset<clip_poly_tag>();
+ geometry::point_vertex_adapter<double> va(pt);
+ converter.apply(va, proc);
+ }
+ }
+ else if ((placement == MARKER_POINT_PLACEMENT || placement == MARKER_INTERIOR_PLACEMENT) &&
+ multi_policy == MARKER_LARGEST_MULTI)
+ {
+ // Only apply to path with largest envelope area
+ // TODO: consider using true area for polygon types
+ if (type == geometry::geometry_types::MultiPolygon)
+ {
+ geometry::multi_polygon<double> const& multi_poly = mapnik::util::get<geometry::multi_polygon<double> >(geom);
+ double maxarea = 0;
+ geometry::polygon<double> const* largest = 0;
+ for (geometry::polygon<double> const& poly : multi_poly)
+ {
+ box2d<double> bbox = geometry::envelope(poly);
+ double area = bbox.width() * bbox.height();
+ if (area > maxarea)
+ {
+ maxarea = area;
+ largest = &poly;
+ }
+ }
+ if (largest)
+ {
+ geometry::polygon_vertex_adapter<double> va(*largest);
+ converter.apply(va, proc);
+ }
+ }
+ else
+ {
+ MAPNIK_LOG_WARN(marker_symbolizer) << "TODO: if you get here -> open an issue";
+ }
+ }
+ else
+ {
+ if (multi_policy != MARKER_EACH_MULTI && placement != MARKER_POINT_PLACEMENT)
+ {
+ MAPNIK_LOG_WARN(marker_symbolizer) << "marker_multi_policy != 'each' has no effect with marker_placement != 'point'";
+ }
+ if (type == geometry::geometry_types::GeometryCollection)
+ {
+ for (auto const& g : geom.get<geometry::geometry_collection<double>>())
+ {
+ apply_markers_single(converter, proc, g, geometry::geometry_type(g));
+ }
+ }
+ else
+ {
+ apply_markers_single(converter, proc, geom, type);
+ }
+ }
+ }
+}
+template void apply_markers_multi<vector_dispatch_type>(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, vector_dispatch_type & proc,
+ symbolizer_base const& sym);
+
+template void apply_markers_multi<raster_dispatch_type>(feature_impl const& feature, attributes const& vars,
+ vertex_converter_type & converter, raster_dispatch_type & proc,
+ symbolizer_base const& sym);
} // end namespace mapnik
diff --git a/src/palette.cpp b/src/palette.cpp
index 54e4346..4c3807d 100644
--- a/src/palette.cpp
+++ b/src/palette.cpp
@@ -37,8 +37,8 @@ rgb::rgb(rgba const& c)
// ordering by mean(a,r,g,b), a, r, g, b
bool rgba::mean_sort_cmp::operator() (const rgba& x, const rgba& y) const
{
- int t1 = (int)x.a + x.r + x.g + x.b;
- int t2 = (int)y.a + y.r + y.g + y.b;
+ int t1 = x.a + x.r + x.g + x.b;
+ int t2 = y.a + y.r + y.g + y.b;
if (t1 != t2) return t1 < t2;
// https://github.com/mapnik/mapnik/issues/1087
@@ -97,9 +97,9 @@ std::string rgba_palette::to_string() const
str << std::hex << std::setfill('0');
for (unsigned i = 0; i < length; i++) {
str << " #";
- str << std::setw(2) << (unsigned)rgb_pal_[i].r;
- str << std::setw(2) << (unsigned)rgb_pal_[i].g;
- str << std::setw(2) << (unsigned)rgb_pal_[i].b;
+ str << std::setw(2) << static_cast<unsigned>(rgb_pal_[i].r);
+ str << std::setw(2) << static_cast<unsigned>(rgb_pal_[i].g);
+ str << std::setw(2) << static_cast<unsigned>(rgb_pal_[i].b);
if (i < alphaLength) str << std::setw(2) << alpha_pal_[i];
}
str << "]";
diff --git a/src/plugin.cpp b/src/plugin.cpp
index 7b05728..af9bef3 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -93,7 +93,9 @@ PluginInfo::~PluginInfo()
*/
if (module_->dl && name_ != "gdal" && name_ != "ogr")
{
+#ifndef MAPNIK_NO_DLCLOSE
dlclose(module_->dl),module_->dl=0;
+#endif
}
#endif
delete module_;
diff --git a/src/rapidxml_loader.cpp b/src/rapidxml_loader.cpp
index c0a631f..94e8294 100644
--- a/src/rapidxml_loader.cpp
+++ b/src/rapidxml_loader.cpp
@@ -28,12 +28,16 @@
#include <mapnik/config_error.hpp>
#include <mapnik/util/fs.hpp>
#include <mapnik/xml_loader.hpp>
-#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
#include <mapnik/xml_node.hpp>
#include <mapnik/util/trim.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/util/utf_conv_win.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
+#pragma GCC diagnostic pop
+
// stl
#include <iostream>
#include <fstream>
diff --git a/src/raster_colorizer.cpp b/src/raster_colorizer.cpp
index 22d3ee8..2c43df6 100644
--- a/src/raster_colorizer.cpp
+++ b/src/raster_colorizer.cpp
@@ -149,7 +149,7 @@ void raster_colorizer::colorize(image_rgba8 & out, T const& in,
inline unsigned interpolate(unsigned start, unsigned end, float fraction)
{
- return static_cast<unsigned>(fraction * ((float)end - (float)start) + start);
+ return static_cast<unsigned>(fraction * (static_cast<float>(end) - static_cast<float>(start)) + static_cast<float>(start));
}
unsigned raster_colorizer::get_color(float value) const
diff --git a/src/renderer_common/render_markers_symbolizer.cpp b/src/renderer_common/render_markers_symbolizer.cpp
index 12da737..2ecc51b 100644
--- a/src/renderer_common/render_markers_symbolizer.cpp
+++ b/src/renderer_common/render_markers_symbolizer.cpp
@@ -20,9 +20,9 @@
*
*****************************************************************************/
+#include <mapnik/label_collision_detector.hpp>
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
-#include <mapnik/vertex_converters.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/marker_helpers.hpp>
#include <mapnik/geometry_type.hpp>
@@ -39,14 +39,6 @@ struct render_marker_symbolizer_visitor
using vector_dispatch_type = vector_markers_dispatch<Detector>;
using raster_dispatch_type = raster_markers_dispatch<Detector>;
- using vertex_converter_type = vertex_converter<clip_line_tag,
- clip_poly_tag,
- transform_tag,
- affine_transform_tag,
- simplify_tag,
- smooth_tag,
- offset_transform_tag>;
-
render_marker_symbolizer_visitor(std::string const& filename,
markers_symbolizer const& sym,
mapnik::feature_impl & feature,
@@ -62,134 +54,131 @@ struct render_marker_symbolizer_visitor
clip_box_(clip_box),
renderer_context_(renderer_context) {}
+ svg_attribute_type const& get_marker_attributes(svg_path_ptr const& stock_marker,
+ svg_attribute_type & custom_attr) const
+ {
+ auto const& stock_attr = stock_marker->attributes();
+ if (push_explicit_style(stock_attr, custom_attr, sym_, feature_, common_.vars_))
+ return custom_attr;
+ else
+ return stock_attr;
+ }
+
+ template <typename Marker, typename Dispatch>
+ void render_marker(Marker const& mark, Dispatch & rasterizer_dispatch) const
+ {
+ auto const& vars = common_.vars_;
+
+ agg::trans_affine geom_tr;
+ if (auto geometry_transform = get_optional<transform_type>(sym_, keys::geometry_transform))
+ {
+ evaluate_transform(geom_tr, feature_, vars, *geometry_transform, common_.scale_factor_);
+ }
+
+ vertex_converter_type converter(clip_box_,
+ sym_,
+ common_.t_,
+ prj_trans_,
+ geom_tr,
+ feature_,
+ vars,
+ common_.scale_factor_);
+
+ bool clip = get<value_bool, keys::clip>(sym_, feature_, vars);
+ double offset = get<value_double, keys::offset>(sym_, feature_, vars);
+ double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, vars);
+ double smooth = get<value_double, keys::smooth>(sym_, feature_, vars);
+
+ if (clip)
+ {
+ geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
+ switch (type)
+ {
+ case geometry::geometry_types::Polygon:
+ case geometry::geometry_types::MultiPolygon:
+ converter.template set<clip_poly_tag>();
+ break;
+ case geometry::geometry_types::LineString:
+ case geometry::geometry_types::MultiLineString:
+ converter.template set<clip_line_tag>();
+ break;
+ default:
+ // silence warning: 4 enumeration values not handled in switch
+ break;
+ }
+ }
+
+ converter.template set<transform_tag>(); //always transform
+ if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
+ converter.template set<affine_transform_tag>(); // optional affine transform
+ if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
+ if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
+
+ apply_markers_multi(feature_, vars, converter, rasterizer_dispatch, sym_);
+ }
+
void operator() (marker_null const&) const {}
void operator() (marker_svg const& mark) const
{
using namespace mapnik::svg;
- bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
- double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
- double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
- double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
// https://github.com/mapnik/mapnik/issues/1316
bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_);
- agg::trans_affine geom_tr;
- auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
- if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
boost::optional<svg_path_ptr> const& stock_vector_marker = mark.get_data();
+ svg_path_ptr marker_ptr = *stock_vector_marker;
+ bool is_ellipse = false;
+
+ svg_attribute_type s_attributes;
+ auto const& r_attributes = get_marker_attributes(*stock_vector_marker, s_attributes);
// special case for simple ellipse markers
// to allow for full control over rx/ry dimensions
if (filename_ == "shape://ellipse"
&& (has_key(sym_,keys::width) || has_key(sym_,keys::height)))
{
- svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
- vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
- svg_path_adapter svg_path(stl_storage);
- build_ellipse(sym_, feature_, common_.vars_, *marker_ellipse, svg_path);
- svg_attribute_type s_attributes;
- bool result = push_explicit_style( (*stock_vector_marker)->attributes(), s_attributes, sym_, feature_, common_.vars_);
- auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
- if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
- vector_dispatch_type rasterizer_dispatch(marker_ellipse,
- svg_path,
- result ? s_attributes : (*stock_vector_marker)->attributes(),
- image_tr,
- sym_,
- *common_.detector_,
- common_.scale_factor_,
- feature_,
- common_.vars_,
- snap_to_pixels,
- renderer_context_);
-
- vertex_converter_type converter(clip_box_,
- sym_,
- common_.t_,
- prj_trans_,
- geom_tr,
- feature_,
- common_.vars_,
- common_.scale_factor_);
- if (clip)
- {
- geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
- if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
- converter.template set<clip_poly_tag>();
- else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
- converter.template set<clip_line_tag>();
- }
-
- converter.template set<transform_tag>(); //always transform
- if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
- converter.template set<affine_transform_tag>(); // optional affine transform
- if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
- if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
- apply_markers_multi(feature_, common_.vars_, converter, rasterizer_dispatch, sym_);
+ marker_ptr = std::make_shared<svg_storage_type>();
+ is_ellipse = true;
}
else
{
box2d<double> const& bbox = mark.bounding_box();
setup_transform_scaling(image_tr, bbox.width(), bbox.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);
- vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
- svg_path_adapter svg_path(stl_storage);
- svg_attribute_type s_attributes;
- bool result = push_explicit_style( (*stock_vector_marker)->attributes(), s_attributes, sym_, feature_, common_.vars_);
- vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
- svg_path,
- result ? s_attributes : (*stock_vector_marker)->attributes(),
- image_tr,
- sym_,
- *common_.detector_,
- common_.scale_factor_,
- feature_,
- common_.vars_,
- snap_to_pixels,
- renderer_context_);
-
- vertex_converter_type converter(clip_box_,
- sym_,
- common_.t_,
- prj_trans_,
- geom_tr,
- feature_,
- common_.vars_,
- common_.scale_factor_);
- if (clip)
- {
- geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
- if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
- converter.template set<clip_poly_tag>();
- else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
- converter.template set<clip_line_tag>();
- }
+ }
+
+ vertex_stl_adapter<svg_path_storage> stl_storage(marker_ptr->source());
+ svg_path_adapter svg_path(stl_storage);
- converter.template set<transform_tag>(); //always transform
- if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
- converter.template set<affine_transform_tag>(); // optional affine transform
- if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
- if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
- apply_markers_multi(feature_, common_.vars_, converter, rasterizer_dispatch, sym_);
+ if (is_ellipse)
+ {
+ build_ellipse(sym_, feature_, common_.vars_, *marker_ptr, svg_path);
}
+
+ if (auto image_transform = get_optional<transform_type>(sym_, keys::image_transform))
+ {
+ evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
+ }
+
+ vector_dispatch_type rasterizer_dispatch(marker_ptr,
+ svg_path,
+ r_attributes,
+ image_tr,
+ sym_,
+ *common_.detector_,
+ common_.scale_factor_,
+ feature_,
+ common_.vars_,
+ snap_to_pixels,
+ renderer_context_);
+
+ render_marker(mark, rasterizer_dispatch);
}
void operator() (marker_rgba8 const& mark) const
{
- using namespace mapnik::svg;
- bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
- double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
- double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
- double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
-
- agg::trans_affine geom_tr;
- auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
- if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
@@ -210,30 +199,7 @@ struct render_marker_symbolizer_visitor
common_.vars_,
renderer_context_);
-
- vertex_converter_type converter(clip_box_,
- sym_,
- common_.t_,
- prj_trans_,
- geom_tr,
- feature_,
- common_.vars_,
- common_.scale_factor_);
-
- if (clip)
- {
- geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
- if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
- converter.template set<clip_poly_tag>();
- else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
- converter.template set<clip_line_tag>();
- }
- converter.template set<transform_tag>(); //always transform
- if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
- converter.template set<affine_transform_tag>(); // optional affine transform
- if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
- if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
- apply_markers_multi(feature_, common_.vars_, converter, rasterizer_dispatch, sym_);
+ render_marker(mark, rasterizer_dispatch);
}
private:
@@ -279,7 +245,7 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
box2d<double> const& clip_box,
markers_renderer_context & renderer_context)
{
- using Detector = decltype(*common.detector_);
+ using Detector = label_collision_detector4;
using RendererType = renderer_common;
using ContextType = markers_renderer_context;
using VisitorType = detail::render_marker_symbolizer_visitor<Detector,
diff --git a/src/renderer_common/render_pattern.cpp b/src/renderer_common/render_pattern.cpp
index 06477d4..5e6f958 100644
--- a/src/renderer_common/render_pattern.cpp
+++ b/src/renderer_common/render_pattern.cpp
@@ -28,12 +28,15 @@
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/agg_rasterizer.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_color_rgba.h"
#include "agg_color_gray.h"
#include "agg_scanline_u.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp
index 6613d5c..2483bae 100644
--- a/src/svg/svg_parser.cpp
+++ b/src/svg/svg_parser.cpp
@@ -30,10 +30,14 @@
#include <mapnik/util/file_io.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/util/dasharray_parser.hpp>
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_ellipse.h"
#include "agg_rounded_rect.h"
#include "agg_span_gradient.h"
#include "agg_color_rgba.h"
+#pragma GCC diagnostic pop
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
@@ -150,7 +154,7 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent)
("pc", DPI/6.0)
("mm", DPI/25.4)
("cm", DPI/2.54)
- ("in", (double)DPI)
+ ("in", static_cast<double>(DPI))
;
const char* cur = str; // phrase_parse modifies the first iterator
const char* end = str + std::strlen(str);
diff --git a/src/svg/svg_path_parser.cpp b/src/svg/svg_path_parser.cpp
index 986f99b..52f95ef 100644
--- a/src/svg/svg_path_parser.cpp
+++ b/src/svg/svg_path_parser.cpp
@@ -21,32 +21,29 @@
*****************************************************************************/
// mapnik
-#include <mapnik/svg/svg_path_attributes.hpp>
-#include <mapnik/svg/svg_path_parser.hpp>
-#include <mapnik/svg/svg_path_grammar.hpp>
-#include <mapnik/svg/svg_converter.hpp>
-
-// agg
-#include "agg_path_storage.h"
+#include <mapnik/svg/svg_path_parser.hpp>
+#include <mapnik/svg/svg_path_grammar_impl.hpp>
// stl
-#include <string>
#include <cstring>
+#include <string>
-namespace mapnik { namespace svg {
+namespace mapnik {
+namespace svg {
- template <typename PathType>
- bool parse_path(const char* wkt, PathType & p)
- {
- using namespace boost::spirit;
- using iterator_type = const char*;
- using skip_type = ascii::space_type;
- svg_path_grammar<iterator_type,skip_type,PathType> g(p);
- iterator_type first = wkt;
- iterator_type last = wkt + std::strlen(wkt);
- bool status = qi::phrase_parse(first, last, g, skip_type());
- return (status && (first == last));
- }
- template bool MAPNIK_DECL parse_path<svg_converter_type>(const char*, svg_converter_type&);
+template <typename PathType>
+bool parse_path(const char* wkt, PathType& p)
+{
+ using namespace boost::spirit;
+ using iterator_type = const char*;
+ using skip_type = ascii::space_type;
+ static const svg_path_grammar<iterator_type, PathType, skip_type> g;
+ iterator_type first = wkt;
+ iterator_type last = wkt + std::strlen(wkt);
+ bool status = qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type());
+ return (status && (first == last));
+}
+template bool MAPNIK_DECL parse_path<svg_converter_type>(const char*, svg_converter_type&);
-}}
+} // namespace svg
+} // namespace mapnik
diff --git a/src/svg/svg_points_parser.cpp b/src/svg/svg_points_parser.cpp
index 99de4c9..3e292ba 100644
--- a/src/svg/svg_points_parser.cpp
+++ b/src/svg/svg_points_parser.cpp
@@ -22,26 +22,27 @@
// mapnik
#include <mapnik/svg/svg_path_parser.hpp>
-#include <mapnik/svg/svg_points_grammar.hpp>
-#include <mapnik/svg/svg_converter.hpp>
+#include <mapnik/svg/svg_points_grammar_impl.hpp>
// stl
#include <string>
#include <cstring>
-namespace mapnik { namespace svg {
+namespace mapnik {
+namespace svg {
- template <typename PathType>
- bool parse_points(const char* wkt, PathType & p)
- {
- using namespace boost::spirit;
- using iterator_type = const char* ;
- using skip_type = ascii::space_type;
- svg_points_grammar<iterator_type,skip_type,PathType> g(p);
- iterator_type first = wkt;
- iterator_type last = wkt + std::strlen(wkt);
- return qi::phrase_parse(first, last, g, skip_type());
- }
+template <typename PathType>
+bool parse_points(const char* wkt, PathType& p)
+{
+ using namespace boost::spirit;
+ using iterator_type = const char*;
+ using skip_type = ascii::space_type;
+ static const svg_points_grammar<iterator_type, PathType, skip_type> g;
+ iterator_type first = wkt;
+ iterator_type last = wkt + std::strlen(wkt);
+ return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type());
+}
- template bool parse_points<svg_converter_type>(const char*, svg_converter_type&);
+template bool parse_points<svg_converter_type>(const char*, svg_converter_type&);
- }}
+} // namespace svg
+} // namespace mapnik
diff --git a/src/svg/svg_transform_parser.cpp b/src/svg/svg_transform_parser.cpp
index f41b7b1..7b90ca4 100644
--- a/src/svg/svg_transform_parser.cpp
+++ b/src/svg/svg_transform_parser.cpp
@@ -21,27 +21,28 @@
*****************************************************************************/
// mapnik
-#include <mapnik/svg/svg_path_parser.hpp>
-#include <mapnik/svg/svg_transform_grammar.hpp>
+#include <mapnik/config.hpp>
+#include <mapnik/svg/svg_transform_grammar_impl.hpp>
// stl
#include <string>
#include <cstring>
-namespace mapnik { namespace svg {
+namespace mapnik {
+namespace svg {
- template <typename TransformType>
- bool parse_svg_transform(const char * wkt, TransformType & p)
- {
- using namespace boost::spirit;
- using iterator_type = const char *;
- using skip_type = ascii::space_type;
- // TODO - make it possible for this to be static const
- // by avoiding ctor taking arg - https://github.com/mapnik/mapnik/pull/2231
- svg_transform_grammar<iterator_type,skip_type,TransformType> g(p);
- iterator_type first = wkt;
- iterator_type last = wkt + std::strlen(wkt);
- return qi::phrase_parse(first, last, g, skip_type());
- }
+template <typename TransformType>
+bool parse_svg_transform(const char* wkt, TransformType& tr)
+{
+ using namespace boost::spirit;
+ using iterator_type = const char*;
+ using skip_type = ascii::space_type;
+ static const svg_transform_grammar<iterator_type, TransformType, skip_type> g;
+ iterator_type first = wkt;
+ iterator_type last = wkt + std::strlen(wkt);
+ return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(tr)), skip_type());
+}
- template MAPNIK_DECL bool parse_svg_transform<agg::trans_affine>(const char*, agg::trans_affine&);
-}}
+template bool MAPNIK_DECL parse_svg_transform<agg::trans_affine>(const char*, agg::trans_affine&);
+
+} // namespace svg
+} // namespace mapnik
diff --git a/src/text/face.cpp b/src/text/face.cpp
index 79f35d8..1d3ad78 100644
--- a/src/text/face.cpp
+++ b/src/text/face.cpp
@@ -23,11 +23,16 @@
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
extern "C"
{
#include FT_GLYPH_H
}
+#pragma GCC diagnostic pop
+
namespace mapnik
{
@@ -36,7 +41,7 @@ font_face::font_face(FT_Face face)
bool font_face::set_character_sizes(double size)
{
- return (FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0) == 0);
+ return (FT_Set_Char_Size(face_,0,static_cast<FT_F26Dot6>(size * (1<<6)),0,0) == 0);
}
bool font_face::set_unscaled_character_sizes()
@@ -108,7 +113,7 @@ void font_face_set::set_unscaled_character_sizes()
void stroker::init(double radius)
{
- FT_Stroker_Set(s_, (FT_Fixed) (radius * (1<<6)),
+ FT_Stroker_Set(s_, static_cast<FT_Fixed>(radius * (1<<6)),
FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND,
0);
diff --git a/src/text/font_library.cpp b/src/text/font_library.cpp
index 2bdb4ba..37fd6a4 100644
--- a/src/text/font_library.cpp
+++ b/src/text/font_library.cpp
@@ -28,6 +28,9 @@
#include <cstdlib>
#include <stdexcept>
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
// freetype2
extern "C"
{
@@ -36,6 +39,8 @@ extern "C"
#include FT_MODULE_H
}
+#pragma GCC diagnostic pop
+
namespace {
void* _Alloc_Func(FT_Memory, long size)
diff --git a/src/text/formatting/format.cpp b/src/text/formatting/format.cpp
index 8e0fef5..8a6a8cc 100644
--- a/src/text/formatting/format.cpp
+++ b/src/text/formatting/format.cpp
@@ -30,9 +30,11 @@
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/xml_node.hpp>
-//boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace formatting {
diff --git a/src/text/formatting/layout.cpp b/src/text/formatting/layout.cpp
index 19da033..ef908c5 100644
--- a/src/text/formatting/layout.cpp
+++ b/src/text/formatting/layout.cpp
@@ -35,8 +35,10 @@
#include <mapnik/text/properties_util.hpp>
#include <mapnik/boolean.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik { namespace formatting {
diff --git a/src/text/formatting/list.cpp b/src/text/formatting/list.cpp
index 89e9d23..4bf7c4d 100644
--- a/src/text/formatting/list.cpp
+++ b/src/text/formatting/list.cpp
@@ -25,8 +25,10 @@
#include <mapnik/feature.hpp>
#include <mapnik/symbolizer.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
using boost::property_tree::ptree;
diff --git a/src/text/formatting/text.cpp b/src/text/formatting/text.cpp
index c24aab1..3158f20 100644
--- a/src/text/formatting/text.cpp
+++ b/src/text/formatting/text.cpp
@@ -30,8 +30,10 @@
#include <mapnik/text/text_layout.hpp>
#include <mapnik/debug.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/text/placements/list.cpp b/src/text/placements/list.cpp
index 65c729b..7d609f2 100644
--- a/src/text/placements/list.cpp
+++ b/src/text/placements/list.cpp
@@ -24,8 +24,10 @@
#include <mapnik/text/placements/list.hpp>
#include <mapnik/xml_node.hpp>
-//boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/text/scrptrun.cpp b/src/text/scrptrun.cpp
index 37a02e7..0cbb2c8 100644
--- a/src/text/scrptrun.cpp
+++ b/src/text/scrptrun.cpp
@@ -14,8 +14,11 @@
* http://source.icu-project.org/repos/icu/icu/trunk/license.html
*/
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/utypes.h>
#include <unicode/uscript.h>
+#pragma GCC diagnostic pop
#include <mapnik/text/scrptrun.hpp>
diff --git a/src/text/text_layout.cpp b/src/text/text_layout.cpp
index ff37d28..3a3818c 100644
--- a/src/text/text_layout.cpp
+++ b/src/text/text_layout.cpp
@@ -29,8 +29,11 @@
#include <mapnik/text/harfbuzz_shaper.hpp>
#include <mapnik/make_unique.hpp>
-// ICU
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/brkiter.h>
+#pragma GCC diagnostic pop
+
#include <algorithm>
namespace mapnik
diff --git a/src/text/text_properties.cpp b/src/text/text_properties.cpp
index 4b08c10..ef5b9af 100644
--- a/src/text/text_properties.cpp
+++ b/src/text/text_properties.cpp
@@ -34,8 +34,10 @@
#include <mapnik/boolean.hpp>
#include <mapnik/make_unique.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
namespace mapnik
{
diff --git a/src/twkb.cpp b/src/twkb.cpp
new file mode 100644
index 0000000..f1928e5
--- /dev/null
+++ b/src/twkb.cpp
@@ -0,0 +1,387 @@
+/*****************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+
+
+// mapnik
+#include <mapnik/wkb.hpp>
+#include <mapnik/feature.hpp>
+#include <mapnik/geom_util.hpp>
+#include <mapnik/util/noncopyable.hpp>
+#include <mapnik/geometry_correct.hpp>
+#include <cmath>
+
+namespace mapnik { namespace detail {
+
+struct twkb_reader : mapnik::util::noncopyable
+{
+private:
+ const char *twkb_;
+ size_t size_;
+ unsigned int pos_;
+ // Metadata on the geometry we are parsing
+ uint8_t twkb_type_;
+ uint8_t has_bbox_;
+ uint8_t has_size_;
+ uint8_t has_idlist_;
+ uint8_t has_z_;
+ uint8_t has_m_;
+ uint8_t is_empty_;
+ // Precision factors to convert ints to double
+ double factor_xy_;
+ double factor_z_;
+ double factor_m_;
+ // An array to keep delta values from 4 dimensions
+ int64_t coord_x_;
+ int64_t coord_y_;
+ int64_t coord_z_;
+ int64_t coord_m_;
+
+public:
+ enum twkbGeometryType : std::uint8_t
+ {
+ twkbPoint = 1,
+ twkbLineString = 2,
+ twkbPolygon = 3,
+ twkbMultiPoint = 4,
+ twkbMultiLineString = 5,
+ twkbMultiPolygon = 6,
+ twkbGeometryCollection = 7
+ };
+
+ twkb_reader(char const* twkb, size_t size)
+ : twkb_(twkb), size_(size), pos_(0), twkb_type_(0), // Geometry type
+ has_bbox_(0), // Bounding box?
+ has_size_(0), // Size attribute?
+ has_idlist_(0), // Presence of X/Y
+ has_z_(0), // Presence of Z
+ has_m_(0), // Presence of M
+ is_empty_(0), // Empty?
+ factor_xy_(0.0), // Expansion factor for X/Y
+ factor_z_(0.0), // Expansion factor for Z
+ factor_m_(0.0) // Expansion factor for M
+ {}
+
+ mapnik::geometry::geometry<double> read()
+ {
+ mapnik::geometry::geometry<double> geom = mapnik::geometry::geometry_empty();
+ // Read the metadata bytes, populating all the
+ // information about optional fields, extended (z/m) dimensions
+ // expansion factors and so on
+ read_header();
+
+ // Each new read call has to reset the coordinate accumulators
+ coord_x_ = 0; // Accumulation register (x)
+ coord_y_ = 0; // Accumulation register (y)
+ coord_z_ = 0; // Accumulation register (z)
+ coord_m_ = 0; // Accumulation register (m)
+
+ // If the geometry is empty, add nothing to the paths array
+ if (is_empty_)
+ return geom;
+
+ // Read the [optional] size information
+ if (has_size_)
+ size_ = read_unsigned_integer();
+
+ // Read the [optional] bounding box information
+ if (has_bbox_) read_bbox();
+
+ switch (twkb_type_)
+ {
+ case twkbPoint:
+ geom = read_point();
+ break;
+ case twkbLineString:
+ geom = read_linestring();
+ break;
+ case twkbPolygon:
+ geom = read_polygon();
+ break;
+ case twkbMultiPoint:
+ geom = read_multipoint();
+ break;
+ case twkbMultiLineString:
+ geom = read_multilinestring();
+ break;
+ case twkbMultiPolygon:
+ geom = read_multipolygon();
+ break;
+ case twkbGeometryCollection:
+ geom = read_collection();
+ default:
+ break;
+ }
+ return geom;
+ }
+
+private:
+ int64_t unzigzag64(uint64_t val)
+ {
+ if (val & 0x01)
+ return -1 * (int64_t)((val + 1) >> 1);
+ else
+ return (int64_t)(val >> 1);
+ }
+
+ int32_t unzigzag32(uint32_t val)
+ {
+ if (val & 0x01) return -1 * (int32_t)((val + 1) >> 1);
+ else return (int32_t)(val >> 1);
+ }
+
+ int8_t unzigzag8(uint8_t val)
+ {
+ if (val & 0x01) return -1 * (int8_t)((val + 1) >> 1);
+ else return (int8_t)(val >> 1);
+ }
+
+ // Read from signed 64bit varint
+ int64_t read_signed_integer() { return unzigzag64(read_unsigned_integer()); }
+
+ // Read from unsigned 64bit varint
+ uint64_t read_unsigned_integer()
+ {
+ uint64_t nVal = 0;
+ int nShift = 0;
+ uint8_t nByte;
+
+ // Check so we don't read beyond the twkb
+ while (pos_ < size_)
+ {
+ nByte = twkb_[pos_];
+ // We get here when there is more to read in the input varInt
+ // Here we take the least significant 7 bits of the read
+ // byte and put it in the most significant place in the result variable.
+ nVal |= ((uint64_t)(nByte & 0x7f)) << nShift;
+ // move the "cursor" of the input buffer step (8 bits)
+ pos_++;
+ // move the cursor in the resulting variable (7 bits)
+ nShift += 7;
+ // Hibit isn't set, so this is the last byte
+ if (!(nByte & 0x80)) {
+ return nVal;
+ }
+ }
+ return 0;
+ }
+
+ // Every TWKB geometry starts with a metadata header
+ //
+ // type_and_dims byte
+ // metadata_header byte
+ // [extended_dims] byte
+ // [size] uvarint
+ // [bounds] bbox
+ //
+ void read_header()
+ {
+ uint8_t type_precision = twkb_[pos_++];
+ uint8_t metadata = twkb_[pos_++];
+ twkb_type_ = type_precision & 0x0F;
+ int8_t precision = unzigzag8((type_precision & 0xF0) >> 4);
+ factor_xy_ = std::pow(10, static_cast<double>(precision));
+ has_bbox_ = metadata & 0x01;
+ has_size_ = (metadata & 0x02) >> 1;
+ has_idlist_ = (metadata & 0x04) >> 2;
+ uint8_t zm = (metadata & 0x08) >> 3;
+ is_empty_ = (metadata & 0x10) >> 4;
+
+ // Flag for higher dimensions means read a third byte
+ // of extended dimension information
+ if (zm)
+ {
+ zm = twkb_[pos_++];
+ // Strip Z/M presence and precision from ext byte
+ has_z_ = (zm & 0x01);
+ has_m_ = (zm & 0x02) >> 1;
+ // Convert the precision into factor
+ int8_t precision_z = (zm & 0x1C) >> 2;
+ int8_t precision_m = (zm & 0xE0) >> 5;
+ factor_z_ = pow(10, (double)precision_z);
+ factor_m_ = pow(10, (double)precision_m);
+ }
+ }
+
+ void read_bbox()
+ {
+ // we have nowhere to store this box information
+ // for now, so we'll just move the read head forward
+ // an appropriate number of times
+ if (has_bbox_)
+ {
+ read_signed_integer(); // uint64_t xmin
+ read_signed_integer(); // uint64_t xdelta
+ read_signed_integer(); // uint64_t ymin
+ read_signed_integer(); // uint64_t ydelta
+ if (has_z_)
+ {
+ read_signed_integer(); // uint64_t zmin
+ read_signed_integer(); // uint64_t zdelta
+ }
+ if (has_m_)
+ {
+ read_signed_integer(); // uint64_t mmin
+ read_signed_integer(); // uint64_t mdelta
+ }
+ }
+ }
+
+ void read_idlist(unsigned int num_ids)
+ {
+ // we have nowhere to store this id information
+ // for now, so we'll just move the read head
+ // forward an appropriate number of times
+ if (has_idlist_)
+ {
+ for (unsigned int i = 0; i < num_ids; ++i)
+ {
+ read_signed_integer(); // uint64_t id
+ }
+ }
+ }
+
+ template <typename Ring>
+ void read_coords(Ring & ring, std::size_t num_points)
+ {
+ for (std::size_t i = 0; i < num_points; ++i)
+ {
+ coord_x_ += read_signed_integer();
+ coord_y_ += read_signed_integer();
+ ring.emplace_back( coord_x_ / factor_xy_, coord_y_ / factor_xy_);
+ // Skip Z and M
+ if (has_z_) coord_z_ += read_signed_integer();
+ if (has_m_) coord_m_ += read_signed_integer();
+ }
+ }
+
+ mapnik::geometry::point<double> read_point()
+ {
+ coord_x_ += read_signed_integer();
+ coord_y_ += read_signed_integer();
+ double x = coord_x_ / factor_xy_;
+ double y = coord_y_ / factor_xy_;
+ return mapnik::geometry::point<double>(x, y);
+ }
+
+ mapnik::geometry::multi_point<double> read_multipoint()
+ {
+ mapnik::geometry::multi_point<double> multi_point;
+ unsigned int num_points = read_unsigned_integer();
+ if (has_idlist_) read_idlist(num_points);
+
+ if (num_points > 0)
+ {
+ multi_point.reserve(num_points);
+ for (unsigned int i = 0; i < num_points; ++i)
+ {
+ multi_point.emplace_back(read_point());
+ }
+ }
+ return multi_point;
+ }
+
+ mapnik::geometry::line_string<double> read_linestring()
+ {
+ mapnik::geometry::line_string<double> line;
+ unsigned int num_points = read_unsigned_integer();
+ if (num_points > 0)
+ {
+ line.reserve(num_points);
+ read_coords<mapnik::geometry::line_string<double>>(line, num_points);
+ }
+ return line;
+ }
+
+ mapnik::geometry::multi_line_string<double> read_multilinestring()
+ {
+ mapnik::geometry::multi_line_string<double> multi_line;
+ unsigned int num_lines = read_unsigned_integer();
+ if (has_idlist_) read_idlist(num_lines);
+ multi_line.reserve(num_lines);
+ for (unsigned int i = 0; i < num_lines; ++i)
+ {
+ multi_line.push_back(read_linestring());
+ }
+ return multi_line;
+ }
+
+ mapnik::geometry::polygon<double> read_polygon()
+ {
+ unsigned int num_rings = read_unsigned_integer();
+ mapnik::geometry::polygon<double> poly;
+ if (num_rings > 1)
+ {
+ poly.interior_rings.reserve(num_rings - 1);
+ }
+
+ for (unsigned int i = 0; i < num_rings; ++i)
+ {
+ mapnik::geometry::linear_ring<double> ring;
+ unsigned int num_points = read_unsigned_integer();
+ if (num_points > 0)
+ {
+ ring.reserve(num_points);
+ read_coords<mapnik::geometry::linear_ring<double>>(ring, num_points);
+ }
+ if ( i == 0) poly.set_exterior_ring(std::move(ring));
+ else poly.add_hole(std::move(ring));
+ }
+ return poly;
+ }
+
+ mapnik::geometry::multi_polygon<double> read_multipolygon()
+ {
+ mapnik::geometry::multi_polygon<double> multi_poly;
+ unsigned int num_polys = read_unsigned_integer();
+ if (has_idlist_) read_idlist(num_polys);
+ for (unsigned int i = 0; i < num_polys; ++i)
+ {
+ multi_poly.push_back(read_polygon());
+ }
+ return multi_poly;
+ }
+
+ mapnik::geometry::geometry_collection<double> read_collection()
+ {
+ unsigned int num_geometries = read_unsigned_integer();
+ mapnik::geometry::geometry_collection<double> collection;
+ if (has_idlist_) read_idlist(num_geometries);
+ for (unsigned int i = 0; i < num_geometries; ++i)
+ {
+ collection.push_back(read());
+ }
+ return collection;
+ }
+};
+
+} // namespace detail
+
+mapnik::geometry::geometry<double> geometry_utils::from_twkb(const char* wkb, std::size_t size)
+{
+ detail::twkb_reader reader(wkb, size);
+ mapnik::geometry::geometry<double> geom(reader.read());
+ // note: this will only be applied to polygons
+ mapnik::geometry::correct(geom);
+ return geom;
+}
+
+} // namespace mapnik
diff --git a/src/unicode.cpp b/src/unicode.cpp
index dac9b29..c96c589 100644
--- a/src/unicode.cpp
+++ b/src/unicode.cpp
@@ -27,8 +27,10 @@
// std
#include <stdexcept>
-// icu
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <unicode/ucnv.h>
+#pragma GCC diagnostic pop
namespace mapnik {
@@ -60,4 +62,12 @@ transcoder::~transcoder()
{
if (conv_) ucnv_close(conv_);
}
+
+
+void to_utf8(mapnik::value_unicode_string const& input, std::string & target)
+{
+ target.clear(); // mimic previous target.assign(...) semantics
+ input.toUTF8String(target); // this appends to target
+}
+
}
diff --git a/src/value.cpp b/src/value.cpp
new file mode 100644
index 0000000..a3c8770
--- /dev/null
+++ b/src/value.cpp
@@ -0,0 +1,928 @@
+/*****************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+
+// mapnik
+#include <mapnik/value.hpp>
+#include <mapnik/value_types.hpp>
+#include <mapnik/util/conversions.hpp>
+
+// stl
+#include <cmath>
+#include <string>
+#include <type_traits>
+// icu
+#include <unicode/unistr.h>
+#include <unicode/ustring.h>
+
+namespace mapnik {
+
+namespace detail {
+
+namespace {
+template <typename T, typename U>
+struct both_arithmetic : std::integral_constant<bool,
+ std::is_arithmetic<T>::value &&
+ std::is_arithmetic<U>::value> {};
+
+struct equals
+{
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ return false;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs == rhs)
+ {
+ return lhs == rhs;
+ }
+};
+
+struct not_equal
+{
+ // back compatibility shim to equate empty string with null for != test
+ // https://github.com/mapnik/mapnik/issues/1859
+ // TODO - consider removing entire specialization at Mapnik 3.1.x
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ if (rhs.isEmpty()) return false;
+ return true;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs != rhs)
+ {
+ return lhs != rhs;
+ }
+};
+
+struct greater_than
+{
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ return false;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs > rhs)
+ {
+ return lhs > rhs;
+ }
+};
+
+struct greater_or_equal
+{
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ return false;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs >= rhs)
+ {
+ return lhs >= rhs;
+ }
+};
+
+struct less_than
+{
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ return false;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs < rhs)
+ {
+ return lhs < rhs;
+ }
+};
+
+struct less_or_equal
+{
+ static bool apply(value_null, value_unicode_string const& rhs)
+ {
+ return false;
+ }
+
+ template <typename T>
+ static auto apply(T const& lhs, T const& rhs)
+ -> decltype(lhs <= rhs)
+ {
+ return lhs <= rhs;
+ }
+};
+}
+
+template <typename Op, bool default_result>
+struct comparison
+{
+ // special case for unicode_strings (fixes MSVC C4800)
+ bool operator()(value_unicode_string const& lhs,
+ value_unicode_string const& rhs) const
+ {
+ return Op::apply(lhs, rhs) ? true : false;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // special case for unicode_string and value_null
+ //////////////////////////////////////////////////////////////////////////
+
+ bool operator()(value_null const& lhs, value_unicode_string const& rhs) const
+ {
+ return Op::apply(lhs, rhs);
+ }
+ //////////////////////////////////////////////////////////////////////////
+
+ // same types
+ template <typename T>
+ bool operator()(T lhs, T rhs) const
+ {
+ return Op::apply(lhs, rhs);
+ }
+
+ // both types are arithmetic - promote to the common type
+ template <typename T, typename U, typename std::enable_if<both_arithmetic<T, U>::value, int>::type = 0>
+ bool operator()(T const& lhs, U const& rhs) const
+ {
+ using common_type = typename std::common_type<T, U>::type;
+ return Op::apply(static_cast<common_type>(lhs), static_cast<common_type>(rhs));
+ }
+
+ //
+ template <typename T, typename U, typename std::enable_if<!both_arithmetic<T, U>::value, int>::type = 0>
+ bool operator()(T const& lhs, U const& rhs) const
+ {
+ return default_result;
+ }
+};
+
+template <typename V>
+struct add
+{
+ using value_type = V;
+ value_type operator()(value_unicode_string const& lhs,
+ value_unicode_string const& rhs) const
+ {
+ return lhs + rhs;
+ }
+
+ value_type operator()(value_null const& lhs,
+ value_null const& rhs) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_unicode_string const& lhs, value_null) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_null, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const& lhs, value_null const&) const
+ {
+ return lhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_null const&, R const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const& lhs, value_unicode_string const& rhs) const
+ {
+ std::string val;
+ if (util::to_string(val, lhs))
+ return value_unicode_string(val.c_str()) + rhs;
+ return rhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_unicode_string const& lhs, R const& rhs) const
+ {
+ std::string val;
+ if (util::to_string(val, rhs))
+ return lhs + value_unicode_string(val.c_str());
+ return lhs;
+ }
+
+ template <typename T1, typename T2>
+ value_type operator()(T1 const& lhs, T2 const& rhs) const
+ {
+ return typename std::common_type<T1, T2>::type{lhs + rhs};
+ }
+
+ value_type operator()(value_bool lhs, value_bool rhs) const
+ {
+ return value_integer(lhs + rhs);
+ }
+};
+
+template <typename V>
+struct sub
+{
+ using value_type = V;
+
+ value_type operator()(value_null const& lhs,
+ value_null const& rhs) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_null, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+ value_type operator()(value_unicode_string const& lhs, value_null) const
+ {
+ return lhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_unicode_string const& lhs, R const&) const
+ {
+ return lhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const&, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const& lhs, value_null const&) const
+ {
+ return lhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_null const&, R const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename T>
+ value_type operator()(T lhs, T rhs) const
+ {
+ return lhs - rhs;
+ }
+
+ value_type operator()(value_unicode_string const&,
+ value_unicode_string const&) const
+ {
+ return value_type();
+ }
+
+ template <typename T1, typename T2>
+ value_type operator()(T1 const& lhs, T2 const& rhs) const
+ {
+ return typename std::common_type<T1, T2>::type{lhs - rhs};
+ }
+
+ value_type operator()(value_bool lhs, value_bool rhs) const
+ {
+ return value_integer(lhs - rhs);
+ }
+};
+
+template <typename V>
+struct mult
+{
+ using value_type = V;
+
+ value_type operator()(value_null const& lhs,
+ value_null const& rhs) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_unicode_string const& lhs, value_null) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_null, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const& lhs, value_null const&) const
+ {
+ return lhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_null const&, R const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_unicode_string const& lhs, R const&) const
+ {
+ return lhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const&, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename T>
+ value_type operator()(T lhs, T rhs) const
+ {
+ return lhs * rhs;
+ }
+
+ value_type operator()(value_unicode_string const&,
+ value_unicode_string const&) const
+ {
+ return value_type();
+ }
+
+ template <typename T1, typename T2>
+ value_type operator()(T1 const& lhs, T2 const& rhs) const
+ {
+ return typename std::common_type<T1, T2>::type{lhs * rhs};
+ }
+
+ value_type operator()(value_bool lhs, value_bool rhs) const
+ {
+ return value_integer(lhs * rhs);
+ }
+};
+
+template <typename V>
+struct div
+{
+ using value_type = V;
+
+ value_type operator()(value_null const& lhs,
+ value_null const& rhs) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_unicode_string const& lhs, value_null) const
+ {
+ return lhs;
+ }
+
+ value_type operator()(value_null, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const& lhs, value_null const&) const
+ {
+ return lhs;
+ }
+
+ template <typename R>
+ value_type operator()(value_null const&, R const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename T>
+ value_type operator()(T lhs, T rhs) const
+ {
+ if (rhs == 0) return value_type();
+ return lhs / rhs;
+ }
+
+ value_type operator()(value_bool lhs, value_bool rhs) const
+ {
+ if (rhs == 0) return lhs;
+ return value_integer(lhs) / value_integer(rhs);
+ }
+
+ value_type operator()(value_unicode_string const&,
+ value_unicode_string const&) const
+ {
+ return value_type();
+ }
+
+ template <typename R>
+ value_type operator()(value_unicode_string const& lhs, R const&) const
+ {
+ return lhs;
+ }
+
+ template <typename L>
+ value_type operator()(L const&, value_unicode_string const& rhs) const
+ {
+ return rhs;
+ }
+
+ template <typename T1, typename T2>
+ value_type operator()(T1 const& lhs, T2 const& rhs) const
+ {
+ if (rhs == 0) return value_type();
+ using common_type = typename std::common_type<T1, T2>::type;
+ return common_type(lhs) / common_type(rhs);
+ }
+};
+
+template <typename V>
+struct mod
+{
+ using value_type = V;
+
+ template <typename T1, typename T2>
+ value_type operator()(T1 const& lhs, T2 const&) const
+ {
+ return lhs;
+ }
+
+ template <typename T>
+ value_type operator()(T lhs, T rhs) const
+ {
+ return lhs % rhs;
+ }
+
+ value_type operator()(value_unicode_string const&,
+ value_unicode_string const&) const
+ {
+ return value_type();
+ }
+
+ value_type operator()(value_bool,
+ value_bool) const
+ {
+ return false;
+ }
+
+ value_type operator()(value_double lhs, value_integer rhs) const
+ {
+ return std::fmod(lhs, static_cast<value_double>(rhs));
+ }
+
+ value_type operator()(value_integer lhs, value_double rhs) const
+ {
+ return std::fmod(static_cast<value_double>(lhs), rhs);
+ }
+
+ value_type operator()(value_double lhs, value_double rhs) const
+ {
+ return std::fmod(lhs, rhs);
+ }
+};
+
+template <typename V>
+struct negate
+{
+ using value_type = V;
+
+ template <typename T>
+ value_type operator()(T val) const
+ {
+ return -val;
+ }
+
+ value_type operator()(value_null val) const
+ {
+ return val;
+ }
+
+ value_type operator()(value_bool val) const
+ {
+ return val ? value_integer(-1) : value_integer(0);
+ }
+
+ value_type operator()(value_unicode_string const&) const
+ {
+ return value_type();
+ }
+};
+
+// converters
+template <typename T>
+struct convert
+{
+};
+
+template <>
+struct convert<value_bool>
+{
+ value_bool operator()(value_bool val) const
+ {
+ return val;
+ }
+
+ value_bool operator()(value_unicode_string const& ustr) const
+ {
+ return !ustr.isEmpty();
+ }
+
+ value_bool operator()(value_null const&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ value_bool operator()(T val) const
+ {
+ return val > 0 ? true : false;
+ }
+};
+
+template <>
+struct convert<value_double>
+{
+ value_double operator()(value_double val) const
+ {
+ return val;
+ }
+
+ value_double operator()(value_integer val) const
+ {
+ return static_cast<value_double>(val);
+ }
+
+ value_double operator()(value_bool val) const
+ {
+ return static_cast<value_double>(val);
+ }
+
+ value_double operator()(std::string const& val) const
+ {
+ value_double result;
+ if (util::string2double(val, result))
+ return result;
+ return 0;
+ }
+
+ value_double operator()(value_unicode_string const& val) const
+ {
+ std::string utf8;
+ val.toUTF8String(utf8);
+ return operator()(utf8);
+ }
+
+ value_double operator()(value_null const&) const
+ {
+ return 0.0;
+ }
+};
+
+template <>
+struct convert<value_integer>
+{
+ value_integer operator()(value_integer val) const
+ {
+ return val;
+ }
+
+ value_integer operator()(value_double val) const
+ {
+ return static_cast<value_integer>(rint(val));
+ }
+
+ value_integer operator()(value_bool val) const
+ {
+ return static_cast<value_integer>(val);
+ }
+
+ value_integer operator()(std::string const& val) const
+ {
+ value_integer result;
+ if (util::string2int(val, result))
+ return result;
+ return value_integer(0);
+ }
+
+ value_integer operator()(value_unicode_string const& val) const
+ {
+ std::string utf8;
+ val.toUTF8String(utf8);
+ return operator()(utf8);
+ }
+
+ value_integer operator()(value_null const&) const
+ {
+ return value_integer(0);
+ }
+};
+
+template <>
+struct convert<std::string>
+{
+ template <typename T>
+ std::string operator()(T val) const
+ {
+ std::string str;
+ util::to_string(str, val);
+ return str;
+ }
+
+ // specializations
+ std::string operator()(value_unicode_string const& val) const
+ {
+ std::string utf8;
+ val.toUTF8String(utf8);
+ return utf8;
+ }
+
+ std::string operator()(value_double val) const
+ {
+ std::string str;
+ util::to_string(str, val); // TODO set precision(16)
+ return str;
+ }
+
+ std::string operator()(value_bool val) const
+ {
+ return val ? "true" : "false";
+ }
+
+ std::string operator()(value_null const&) const
+ {
+ return std::string();
+ }
+};
+
+struct to_unicode_impl
+{
+
+ template <typename T>
+ value_unicode_string operator()(T val) const
+ {
+ std::string str;
+ util::to_string(str, val);
+ return value_unicode_string(str.c_str());
+ }
+
+ // specializations
+ value_unicode_string const& operator()(value_unicode_string const& val) const
+ {
+ return val;
+ }
+
+ value_unicode_string operator()(value_double val) const
+ {
+ std::string str;
+ util::to_string(str, val);
+ return value_unicode_string(str.c_str());
+ }
+
+ value_unicode_string operator()(value_bool val) const
+ {
+ return value_unicode_string(val ? "true" : "false");
+ }
+
+ value_unicode_string operator()(value_null const&) const
+ {
+ return value_unicode_string();
+ }
+};
+
+struct to_expression_string_impl
+{
+ struct EscapingByteSink : U_NAMESPACE_QUALIFIER ByteSink
+ {
+ std::string dest_;
+ char quote_;
+
+ explicit EscapingByteSink(char quote)
+ : quote_(quote)
+ {
+ }
+
+ virtual void Append(const char* data, int32_t n)
+ {
+ // reserve enough room to hold the appended chunk and quotes;
+ // if another chunk follows, or any character needs escaping,
+ // the string will grow naturally
+ if (dest_.empty())
+ {
+ dest_.reserve(2 + static_cast<std::size_t>(n));
+ dest_.append(1, quote_);
+ }
+ else
+ {
+ dest_.reserve(dest_.size() + n + 1);
+ }
+
+ for (auto end = data + n; data < end; ++data)
+ {
+ if (*data == '\\' || *data == quote_)
+ dest_.append(1, '\\');
+ dest_.append(1, *data);
+ }
+ }
+
+ virtual void Flush()
+ {
+ if (dest_.empty())
+ dest_.append(2, quote_);
+ else
+ dest_.append(1, quote_);
+ }
+ };
+
+ explicit to_expression_string_impl(char quote = '\'')
+ : quote_(quote) {}
+
+ std::string operator()(value_unicode_string const& val) const
+ {
+ // toUTF8(sink) doesn't Flush() the sink if the source string
+ // is empty -- we must return a pair of quotes in that case
+ // https://github.com/mapnik/mapnik/issues/3362
+ if (val.isEmpty())
+ {
+ return std::string(2, quote_);
+ }
+ EscapingByteSink sink(quote_);
+ val.toUTF8(sink);
+ return sink.dest_;
+ }
+
+ std::string operator()(value_integer val) const
+ {
+ std::string output;
+ util::to_string(output, val);
+ return output;
+ }
+
+ std::string operator()(value_double val) const
+ {
+ std::string output;
+ util::to_string(output, val); // TODO precision(16)
+ return output;
+ }
+
+ std::string operator()(value_bool val) const
+ {
+ return val ? "true" : "false";
+ }
+
+ std::string operator()(value_null const&) const
+ {
+ return "null";
+ }
+
+ const char quote_;
+};
+
+} // ns detail
+
+namespace value_adl_barrier {
+
+bool value::operator==(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::equals, false>(), *this, other);
+}
+
+bool value::operator!=(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::not_equal, true>(), *this, other);
+}
+
+bool value::operator>(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::greater_than, false>(), *this, other);
+}
+
+bool value::operator>=(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::greater_or_equal, false>(), *this, other);
+}
+
+bool value::operator<(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::less_than, false>(), *this, other);
+}
+
+bool value::operator<=(value const& other) const
+{
+ return util::apply_visitor(detail::comparison<detail::less_or_equal, false>(), *this, other);
+}
+
+value value::operator-() const
+{
+ return util::apply_visitor(detail::negate<value>(), *this);
+}
+
+value_bool value::to_bool() const
+{
+ return util::apply_visitor(detail::convert<value_bool>(), *this);
+}
+
+std::string value::to_expression_string(char quote) const
+{
+ return util::apply_visitor(detail::to_expression_string_impl(quote), *this);
+}
+
+std::string value::to_string() const
+{
+ return util::apply_visitor(detail::convert<std::string>(), *this);
+}
+
+value_unicode_string value::to_unicode() const
+{
+ return util::apply_visitor(detail::to_unicode_impl(), *this);
+}
+
+value_double value::to_double() const
+{
+ return util::apply_visitor(detail::convert<value_double>(), *this);
+}
+
+value_integer value::to_int() const
+{
+ return util::apply_visitor(detail::convert<value_integer>(), *this);
+}
+
+bool value::is_null() const
+{
+ return util::apply_visitor(mapnik::detail::is_null_visitor(), *this);
+}
+
+template <>
+value_double value::convert() const
+{
+ return util::apply_visitor(detail::convert<value_double>(), *this);
+}
+
+template <>
+value_integer value::convert() const
+{
+ return util::apply_visitor(detail::convert<value_integer>(), *this);
+}
+
+template <>
+value_bool value::convert() const
+{
+ return util::apply_visitor(detail::convert<value_bool>(), *this);
+}
+
+template <>
+std::string value::convert() const
+{
+ return util::apply_visitor(detail::convert<std::string>(), *this);
+}
+
+//
+value operator+(value const& p1, value const& p2)
+{
+ return value(util::apply_visitor(detail::add<value>(), p1, p2));
+}
+
+value operator-(value const& p1, value const& p2)
+{
+ return value(util::apply_visitor(detail::sub<value>(), p1, p2));
+}
+
+value operator*(value const& p1, value const& p2)
+{
+ return value(util::apply_visitor(detail::mult<value>(), p1, p2));
+}
+
+value operator/(value const& p1, value const& p2)
+{
+ return value(util::apply_visitor(detail::div<value>(), p1, p2));
+}
+
+value operator%(value const& p1, value const& p2)
+{
+ return value(util::apply_visitor(detail::mod<value>(), p1, p2));
+}
+
+} // namespace value_adl_barrier
+} // namespace mapnik
diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp
new file mode 100644
index 0000000..06be6c2
--- /dev/null
+++ b/src/vertex_adapters.cpp
@@ -0,0 +1,213 @@
+/*****************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+
+#include <mapnik/vertex_adapters.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_types.hpp>
+#include <mapnik/vertex.hpp>
+
+namespace mapnik { namespace geometry {
+
+// point adapter
+template <typename T>
+point_vertex_adapter<T>::point_vertex_adapter(point<T> const& pt)
+ : pt_(pt),
+ first_(true) {}
+
+template <typename T>
+unsigned point_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+{
+ if (first_)
+ {
+ *x = pt_.x;
+ *y = pt_.y;
+ first_ = false;
+ return mapnik::SEG_MOVETO;
+ }
+ return mapnik::SEG_END;
+}
+
+template <typename T>
+void point_vertex_adapter<T>::rewind(unsigned) const
+{
+ first_ = true;
+}
+
+template <typename T>
+geometry_types point_vertex_adapter<T>::type () const
+{
+ return geometry_types::Point;
+}
+
+// line_string adapter
+template <typename T>
+line_string_vertex_adapter<T>::line_string_vertex_adapter(line_string<T> const& line)
+ : line_(line),
+ current_index_(0),
+ end_index_(line.size())
+{}
+
+template <typename T>
+unsigned line_string_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+{
+ if (current_index_ != end_index_)
+ {
+ point<T> const& coord = line_[current_index_++];
+ *x = coord.x;
+ *y = coord.y;
+ if (current_index_ == 1)
+ {
+ return mapnik::SEG_MOVETO;
+ }
+ else
+ {
+ return mapnik::SEG_LINETO;
+ }
+ }
+ return mapnik::SEG_END;
+}
+
+template <typename T>
+void line_string_vertex_adapter<T>::rewind(unsigned) const
+{
+ current_index_ = 0;
+}
+
+template <typename T>
+geometry_types line_string_vertex_adapter<T>::type() const
+{
+ return geometry_types::LineString;
+}
+
+template <typename T>
+polygon_vertex_adapter<T>::polygon_vertex_adapter(polygon<T> const& poly)
+ : poly_(poly),
+ rings_itr_(0),
+ rings_end_(poly_.interior_rings.size() + 1),
+ current_index_(0),
+ end_index_((rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0),
+ start_loop_(true) {}
+
+template <typename T>
+void polygon_vertex_adapter<T>::rewind(unsigned) const
+{
+ rings_itr_ = 0;
+ rings_end_ = poly_.interior_rings.size() + 1;
+ current_index_ = 0;
+ end_index_ = (rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0;
+ start_loop_ = true;
+}
+template <typename T>
+unsigned polygon_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+{
+ if (rings_itr_ == rings_end_)
+ {
+ return mapnik::SEG_END;
+ }
+ if (current_index_ < end_index_)
+ {
+ point<T> const& coord = (rings_itr_ == 0) ?
+ poly_.exterior_ring[current_index_++] : poly_.interior_rings[rings_itr_- 1][current_index_++];
+ *x = coord.x;
+ *y = coord.y;
+ if (start_loop_)
+ {
+ start_loop_= false;
+ return mapnik::SEG_MOVETO;
+ }
+ if (current_index_ == end_index_)
+ {
+ *x = 0;
+ *y = 0;
+ return mapnik::SEG_CLOSE;
+ }
+ return mapnik::SEG_LINETO;
+ }
+ else if (++rings_itr_ != rings_end_)
+ {
+ current_index_ = 0;
+ end_index_ = poly_.interior_rings[rings_itr_ - 1].size();
+ point<T> const& coord = poly_.interior_rings[rings_itr_ - 1][current_index_++];
+ *x = coord.x;
+ *y = coord.y;
+ return mapnik::SEG_MOVETO;
+ }
+ return mapnik::SEG_END;
+}
+
+template <typename T>
+geometry_types polygon_vertex_adapter<T>::type () const
+{
+ return geometry_types::Polygon;
+}
+
+// ring adapter
+template <typename T>
+ring_vertex_adapter<T>::ring_vertex_adapter(linear_ring<T> const& ring)
+ : ring_(ring),
+ current_index_(0),
+ end_index_(ring_.size()),
+ start_loop_(true) {}
+
+template <typename T>
+void ring_vertex_adapter<T>::rewind(unsigned) const
+{
+ current_index_ = 0;
+ end_index_ = ring_.size();
+ start_loop_ = true;
+}
+
+template <typename T>
+unsigned ring_vertex_adapter<T>::vertex(value_type * x, value_type * y) const
+{
+ if (current_index_ < end_index_)
+ {
+ auto const& coord = ring_[current_index_++];
+ *x = coord.x;
+ *y = coord.y;
+ if (start_loop_)
+ {
+ start_loop_= false;
+ return mapnik::SEG_MOVETO;
+ }
+ if (current_index_ == end_index_)
+ {
+ *x = 0;
+ *y = 0;
+ return mapnik::SEG_CLOSE;
+ }
+ return mapnik::SEG_LINETO;
+ }
+ return mapnik::SEG_END;
+}
+template <typename T>
+geometry_types ring_vertex_adapter<T>::type () const
+{
+ return geometry_types::Polygon;
+}
+
+template struct point_vertex_adapter<double>;
+template struct line_string_vertex_adapter<double>;
+template struct polygon_vertex_adapter<double>;
+template struct ring_vertex_adapter<double>;
+
+}}
diff --git a/src/warp.cpp b/src/warp.cpp
index 4a468a8..29cfa44 100644
--- a/src/warp.cpp
+++ b/src/warp.cpp
@@ -31,7 +31,8 @@
#include <mapnik/raster.hpp>
#include <mapnik/proj_transform.hpp>
-// agg
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_image_filters.h"
#include "agg_trans_bilinear.h"
#include "agg_span_interpolator_linear.h"
@@ -45,6 +46,7 @@
#include "agg_span_allocator.h"
#include "agg_image_accessors.h"
#include "agg_renderer_scanline.h"
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/well_known_srs.cpp b/src/well_known_srs.cpp
index d3296ef..445d84a 100644
--- a/src/well_known_srs.cpp
+++ b/src/well_known_srs.cpp
@@ -25,8 +25,10 @@
#include <mapnik/util/trim.hpp>
#include <mapnik/enumeration.hpp>
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
+#pragma GCC diagnostic pop
namespace mapnik {
diff --git a/src/wkb.cpp b/src/wkb.cpp
index 19b31ca..94c1fcc 100644
--- a/src/wkb.cpp
+++ b/src/wkb.cpp
@@ -103,13 +103,13 @@ public:
switch (format_)
{
case wkbSpatiaLite:
- byteOrder_ = (wkbByteOrder) wkb_[1];
+ byteOrder_ = static_cast<wkbByteOrder>(wkb_[1]);
pos_ = 39;
break;
case wkbGeneric:
default:
- byteOrder_ = (wkbByteOrder) wkb_[0];
+ byteOrder_ = static_cast<wkbByteOrder>(wkb_[0]);
pos_ = 1;
break;
}
@@ -124,8 +124,12 @@ public:
switch (type)
{
case wkbPoint:
- geom = read_point();
+ {
+ auto pt = read_point();
+ if (!std::isnan(pt.x) && !std::isnan(pt.y))
+ geom = std::move(pt);
break;
+ }
case wkbLineString:
geom = read_linestring();
break;
@@ -146,11 +150,19 @@ public:
break;
case wkbPointZ:
case wkbPointM:
- geom = read_point<true>();
+ {
+ auto pt = read_point<true>();
+ if (!std::isnan(pt.x) && !std::isnan(pt.y))
+ geom = std::move(pt);
break;
+ }
case wkbPointZM:
- geom = read_point<true,true>();
+ {
+ auto pt = read_point<true,true>();
+ if (!std::isnan(pt.x) && !std::isnan(pt.y))
+ geom = std::move(pt);
break;
+ }
case wkbLineStringZ:
case wkbLineStringM:
geom = read_linestring<true>();
diff --git a/test/build.py b/test/build.py
index c600d01..78fd934 100644
--- a/test/build.py
+++ b/test/build.py
@@ -9,6 +9,8 @@ test_env = env.Clone()
if not env['CPP_TESTS']:
for cpp_test_bin in glob.glob('./*/*-bin'):
os.unlink(cpp_test_bin)
+ if os.path.exists('./unit/run'): os.unlink('./unit/run')
+ if os.path.exists('./visual/run'): os.unlink('./visual/run')
else:
test_env['LIBS'] = [env['MAPNIK_NAME']]
test_env.AppendUnique(LIBS='mapnik-wkt')
diff --git a/test/cleanup.hpp b/test/cleanup.hpp
index f175e72..c775915 100644
--- a/test/cleanup.hpp
+++ b/test/cleanup.hpp
@@ -1,6 +1,9 @@
#ifndef TEST_MEMORY_CLEANUP
#define TEST_MEMORY_CLEANUP
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
+
#if defined(HAVE_LIBXML2)
#include <libxml/parser.h>
#include <libxml/entities.h>
@@ -16,6 +19,8 @@
#include <proj_api.h>
#endif
+#pragma GCC diagnostic pop
+
namespace testing {
inline void run_cleanup()
diff --git a/test/run b/test/run
index cd45c68..f623609 100755
--- a/test/run
+++ b/test/run
@@ -9,30 +9,48 @@ source ./localize.sh
function run_step { >&2 echo -e "\033[1m\033[34m* $1\033[0m"; }
function run_substep { >&2 echo -e "\033[1m\033[36m* $1\033[0m"; }
function run_success { >&2 echo -e "\033[1m\033[32m* $1\033[0m"; }
+function run_warn { >&2 echo -e "\033[1m\033[31m* $1\033[0m"; }
run_step "Starting Mapnik tests"
+ran_a_test=false
if [ -d "test/data" ]; then
run_substep "Running C++ Unit tests..."
- ./test/unit/run
- failures=$((failures+$?))
+ if [[ -f ./test/unit/run ]]; then
+ ./test/unit/run
+ failures=$((failures+$?))
+ ran_a_test=true
+ else
+ run_warn "Skipping unit tests since they were not built"
+ fi
run_substep "Running standalone C++ tests..."
+ found_test=false
if [ -n "$(find test/standalone/ -maxdepth 1 -name '*-bin' -print -quit)" ]; then
for FILE in test/standalone/*-bin; do
- ${FILE};
+ found_test=true
+ ran_a_test=true
+ ${FILE};
failures=$((failures+$?))
done
fi
+ if [[ $found_test == false ]]; then
+ run_warn "Skipping standalone tests since they were not built"
+ fi
if [ -d "test/data-visual/styles" ]; then
run_substep "Running visual tests..."
if [ -z "$JOBS" ]; then
JOBS=1
fi
- ./test/visual/run -j $JOBS
- failures=$((failures+$?))
+ if [[ -f ./test/visual/run ]]; then
+ ./test/visual/run -j $JOBS
+ ran_a_test=true
+ failures=$((failures+$?))
+ else
+ run_warn "Skipping visual tests since they were not built"
+ fi
else
echo "Notice: Skipping visual tests, the visual tests data are not present under the standard directory \"test/data-visual\"."
fi
@@ -41,4 +59,8 @@ else
echo "Notice: Skipping all tests, the test data are not present under the standard directory \"test/data\"."
fi
+if [[ $ran_a_test == false ]]; then
+ run_warn "**** WARNING: no tests were run ****"
+fi
+
exit $failures
diff --git a/test/unit/color/css_color.cpp b/test/unit/color/css_color.cpp
index 54c90e7..f1bc171 100644
--- a/test/unit/color/css_color.cpp
+++ b/test/unit/color/css_color.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/css_color_grammar.hpp>
#include <mapnik/css_color_grammar_impl.hpp>
diff --git a/test/unit/core/box2d_test.cpp b/test/unit/core/box2d_test.cpp
index 14cbb48..8385bba 100644
--- a/test/unit/core/box2d_test.cpp
+++ b/test/unit/core/box2d_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/coord.hpp>
diff --git a/test/unit/core/comparison_test.cpp b/test/unit/core/comparison_test.cpp
index 41b524c..7e8e8e4 100644
--- a/test/unit/core/comparison_test.cpp
+++ b/test/unit/core/comparison_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/value_types.hpp>
diff --git a/test/unit/core/conversions_test.cpp b/test/unit/core/conversions_test.cpp
index ba0c223..43592af 100644
--- a/test/unit/core/conversions_test.cpp
+++ b/test/unit/core/conversions_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/value_types.hpp>
diff --git a/test/unit/core/exceptions_test.cpp b/test/unit/core/exceptions_test.cpp
index 46abcce..16ed519 100644
--- a/test/unit/core/exceptions_test.cpp
+++ b/test/unit/core/exceptions_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
diff --git a/test/unit/core/expressions_test.cpp b/test/unit/core/expressions_test.cpp
index 72490a2..64cdd9e 100644
--- a/test/unit/core/expressions_test.cpp
+++ b/test/unit/core/expressions_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch_ext.hpp"
#include <mapnik/expression.hpp>
@@ -87,6 +88,7 @@ TEST_CASE("expressions")
// integer
TRY_CHECK(parse_and_dump("123") == "123");
// unicode
+ TRY_CHECK(parse_and_dump("''") == "''");
TRY_CHECK(parse_and_dump("'single-quoted string'") == "'single-quoted string'");
TRY_CHECK(parse_and_dump("\"double-quoted string\"") == "'double-quoted string'");
TRY_CHECK(parse_and_dump("'escaped \\' apostrophe'") == "'escaped \\' apostrophe'");
@@ -180,4 +182,10 @@ TEST_CASE("expressions")
// 'Québec' =~ m:^Q\S*$:
TRY_CHECK(eval(" [name].match('^Q\\S*$') ") == true);
TRY_CHECK(parse_and_dump(" [name].match('^Q\\S*$') ") == "[name].match('^Q\\S*$')");
+
+ // string & value concatenation
+ // this should evaluate as two strings concatenating, but currently fails
+ TRY_CHECK(eval("Hello + '!'") == eval("'Hello!'"));
+ // this should evaulate as a combination of an int value and string, but fails
+ TRY_CHECK(eval("[int]+m") == eval("'123m'"));
}
diff --git a/test/unit/core/params_test.cpp b/test/unit/core/params_test.cpp
index 677de7a..3131f0c 100644
--- a/test/unit/core/params_test.cpp
+++ b/test/unit/core/params_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
diff --git a/test/unit/core/value_test.cpp b/test/unit/core/value_test.cpp
index 0480154..cdb64db 100644
--- a/test/unit/core/value_test.cpp
+++ b/test/unit/core/value_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/value_types.hpp>
diff --git a/test/unit/data/well-known-geometries.test b/test/unit/data/well-known-geometries.test
new file mode 100644
index 0000000..1c6273b
--- /dev/null
+++ b/test/unit/data/well-known-geometries.test
@@ -0,0 +1,13 @@
+POINT (30 10);\x01010000000000000000003e400000000000002440;\x01003c14
+LINESTRING (30 10, 10 30, 40 40);\x0102000000030000000000000000003e40000000000000244000000000000024400000000000003e4000000000000044400000000000004440;\x0200033c1427283c14
+POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10));\x010300000001000000050000000000000000003e4000000000000024400000000000004440000000000000444000000000000034400000000000004440000000000000244000000000000034400000000000003e400000000000002440;\x030001053c14143c270013272813
+POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10),(20 30, 35 35, 30 20, 20 30));\x0103000000020000000500000000000000008041400000000000002440000000000080464000000000008046400000000000002e40000000000000444000000000000024400000000000003440000000000080414000000000000024400400000000000000000034400000000000003e40000000000080414000000000008041400000000000003e40000000000000344000000000000034400000000000003e40;\x03000205461414463b0909273213041d281e0a091d1314
+MULTIPOINT ((10 40), (40 30), (20 20), (30 10));\x010400000004000000010100000000000000000024400000000000004440010100000000000000000044400000000000003e4001010000000000000000003440000000000000344001010000000000000000003e400000000000002440;\x04000414503c1327131413
+MULTIPOINT (10 40, 40 30, 20 20, 30 10);\x010400000004000000010100000000000000000024400000000000004440010100000000000000000044400000000000003e4001010000000000000000003440000000000000344001010000000000000000003e400000000000002440;\x04000414503c1327131413
+MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10));\x010500000002000000010200000003000000000000000000244000000000000024400000000000003440000000000000344000000000000024400000000000004440010200000004000000000000000000444000000000000044400000000000003e400000000000003e40000000000000444000000000000034400000000000003e400000000000002440;\x05000203141414141328043c00131314131313
+MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)));\x010600000002000000010300000001000000040000000000000000003e40000000000000344000000000008046400000000000004440000000000000244000000000000044400000000000003e400000000000003440010300000001000000050000000000000000002e4000000000000014400000000000004440000000000000244000000000000024400000000000003440000000000000144000000000000024400000000000002e400000000000001440;\x06000201043c281e284500282701051d1d320a3b1409131409
+MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20)));\x01060000000200000001030000000100000004000000000000000000444000000000000044400000000000003440000000000080464000000000008046400000000000003e4000000000000044400000000000004440010300000002000000060000000000000000003440000000000080414000000000000024400000000000003e40000000000000244000000000000024400000000000003e400000000000001440000000000080464000000000000034400000000000003 [...]
+GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10));\x010700000002000000010100000000000000000010400000000000001840010200000002000000000000000000104000000000000018400000000000001c400000000000002440;\x0700020100080c020002080c0608
+POINT EMPTY;\x0101000000000000000000f87f000000000000f87f;\x0110
+LINESTRING EMPTY;\x010200000000000000;\x0210
+POLYGON EMPTY;\x010300000000000000;\x0310
diff --git a/test/unit/datasource/csv.cpp b/test/unit/datasource/csv.cpp
index 3f466ff..6142185 100644
--- a/test/unit/datasource/csv.cpp
+++ b/test/unit/datasource/csv.cpp
@@ -24,6 +24,7 @@
#include "ds_test_util.hpp"
#include <mapnik/map.hpp>
+#include <mapnik/unicode.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/geometry.hpp>
@@ -79,31 +80,11 @@ mapnik::datasource_ptr get_csv_ds(std::string const& file_name, bool strict = tr
return ds;
}
-int create_disk_index(std::string const& filename, bool silent = true)
-{
- std::string cmd;
- if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
- {
- cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
- }
- cmd += "mapnik-index " + filename;
- if (silent)
- {
-#ifndef _WINDOWS
- cmd += " 2>/dev/null";
-#else
- cmd += " 2> nul";
-#endif
- }
- return std::system(cmd.c_str());
-}
-
} // anonymous namespace
-static const std::string csv_plugin("./plugins/input/csv.input");
-
TEST_CASE("csv") {
+ std::string csv_plugin("./plugins/input/csv.input");
if (mapnik::util::exists(csv_plugin))
{
// make the tests silent since we intentionally test error conditions that are noisy
@@ -161,7 +142,7 @@ TEST_CASE("csv") {
int ret_posix = (ret >> 8) & 0x000000ff;
INFO(ret);
INFO(ret_posix);
- require_fail = (path == "test/data/csv/warns/feature_id_counting.csv") ? false : true;
+ require_fail = (boost::iends_with(path,"feature_id_counting.csv")) ? false : true;
if (!require_fail)
{
REQUIRE(mapnik::util::exists(path + ".index"));
@@ -208,7 +189,7 @@ TEST_CASE("csv") {
int ret_posix = (ret >> 8) & 0x000000ff;
INFO(ret);
INFO(ret_posix);
- if (path != "test/data/csv/more_headers_than_column_values.csv") // mapnik-index won't create *.index for 0 features
+ if (!boost::iends_with(path,"more_headers_than_column_values.csv")) // mapnik-index won't create *.index for 0 features
{
CHECK(mapnik::util::exists(path + ".index"));
}
@@ -896,7 +877,15 @@ TEST_CASE("csv") {
auto feature = all_features(ds)->next();
REQUIRE(bool(feature));
REQUIRE(feature->has_key("Name"));
- CHECK(feature->get("Name") == ustring(name.c_str()));
+ std::string utf8;
+ mapnik::transcoder tr("utf-8");
+ ustring expected_string = tr.transcode(name.c_str());
+ mapnik::value val(expected_string);
+ mapnik::to_utf8(expected_string,utf8);
+ INFO(feature->get("Name"));
+ INFO(utf8);
+ INFO(val);
+ CHECK(feature->get("Name") == val);
}
} // END SECTION
diff --git a/test/unit/datasource/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp
index bfa5b17..6e1c222 100644
--- a/test/unit/datasource/ds_test_util.hpp
+++ b/test/unit/datasource/ds_test_util.hpp
@@ -20,6 +20,10 @@
*
*****************************************************************************/
+
+#ifndef MAPNIK_UNIT_DATSOURCE_UTIL
+#define MAPNIK_UNIT_DATSOURCE_UTIL
+
#include "catch.hpp"
#include <mapnik/datasource.hpp>
@@ -176,4 +180,25 @@ inline void require_geometry(mapnik::feature_ptr feature,
CHECK(feature_count(feature->get_geometry()) == num_parts);
}
+inline int create_disk_index(std::string const& filename, bool silent = true)
+{
+ std::string cmd;
+ if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
+ {
+ cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
+ }
+ cmd += "mapnik-index " + filename;
+ if (silent)
+ {
+#ifndef _WINDOWS
+ cmd += " 2>/dev/null";
+#else
+ cmd += " 2> nul";
+#endif
+ }
+ return std::system(cmd.c_str());
+}
+
}
+
+#endif // MAPNIK_UNIT_DATSOURCE_UTIL
diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp
index e8c0a90..0b0f205 100644
--- a/test/unit/datasource/geojson.cpp
+++ b/test/unit/datasource/geojson.cpp
@@ -62,25 +62,6 @@ std::pair<mapnik::datasource_ptr,mapnik::feature_ptr> fetch_first_feature(std::s
return std::make_pair(ds,feature);
}
-int create_disk_index(std::string const& filename, bool silent = true)
-{
- std::string cmd;
- if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
- {
- cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
- }
- cmd += "mapnik-index " + filename;
- if (silent)
- {
-#ifndef _WINDOWS
- cmd += " 2>/dev/null";
-#else
- cmd += " 2> nul";
-#endif
- }
- return std::system(cmd.c_str());
-}
-
}
TEST_CASE("geojson") {
diff --git a/test/unit/datasource/topojson.cpp b/test/unit/datasource/topojson.cpp
new file mode 100644
index 0000000..25f9ffd
--- /dev/null
+++ b/test/unit/datasource/topojson.cpp
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ *
+ * 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
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+
+#include <mapnik/util/fs.hpp>
+#include <mapnik/util/file_io.hpp>
+#include <mapnik/json/topology.hpp>
+#include <mapnik/json/topojson_grammar.hpp>
+#include <mapnik/json/topojson_utils.hpp>
+
+namespace {
+
+using iterator_type = std::string::const_iterator;
+const mapnik::topojson::topojson_grammar<iterator_type> grammar;
+
+bool parse_topology(std::string const& filename, mapnik::topojson::topology & topo)
+{
+ mapnik::util::file file(filename);
+ std::string buffer;
+ buffer.resize(file.size());
+ std::fread(&buffer[0], buffer.size(), 1, file.get());
+ if (!file) return false;
+ boost::spirit::standard::space_type space;
+ iterator_type itr = buffer.begin();
+ iterator_type end = buffer.end();
+ bool result = boost::spirit::qi::phrase_parse(itr, end, grammar, space, topo);
+ return (result && (itr == end));
+}
+
+
+}
+
+TEST_CASE("topology")
+{
+ SECTION("geometry parsing")
+ {
+ mapnik::value_integer feature_id = 0;
+ mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
+ mapnik::transcoder tr("utf8");
+ for (auto const& path : mapnik::util::list_directory("test/data/topojson/"))
+ {
+ mapnik::topojson::topology topo;
+ REQUIRE(parse_topology(path, topo));
+ 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);
+ }
+ }
+ }
+}
diff --git a/test/unit/font/fontset_runtime_test.cpp b/test/unit/font/fontset_runtime_test.cpp
index e5a6211..bfbae27 100644
--- a/test/unit/font/fontset_runtime_test.cpp
+++ b/test/unit/font/fontset_runtime_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/memory_datasource.hpp>
diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp
index 1e58aad..cdfbd6e 100644
--- a/test/unit/geometry/centroid.cpp
+++ b/test/unit/geometry/centroid.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry_centroid.hpp>
diff --git a/test/unit/geometry/geometry.cpp b/test/unit/geometry/geometry.cpp
index 556f6ca..53c1e2e 100644
--- a/test/unit/geometry/geometry.cpp
+++ b/test/unit/geometry/geometry.cpp
@@ -9,7 +9,7 @@ TEST_CASE("geometry") {
SECTION("json point") {
mapnik::util::file input("./test/data/json/point1.json");
- REQUIRE( input.open() );
+ REQUIRE( input );
mapnik::geometry::geometry<double> geom;
REQUIRE( input.data() );
std::string json_string(input.data().get(), input.size());
@@ -24,7 +24,7 @@ SECTION("json point") {
SECTION("json point reversed") {
mapnik::util::file input("./test/data/json/point2.json");
- REQUIRE( input.open() );
+ REQUIRE( input );
mapnik::geometry::geometry<double> geom;
REQUIRE( input.data() );
std::string json_string(input.data().get(), input.size());
@@ -37,7 +37,7 @@ SECTION("json point reversed") {
SECTION("json point reversed + extra attributes") {
mapnik::util::file input("./test/data/json/point3.json");
- REQUIRE( input.open() );
+ REQUIRE( input );
mapnik::geometry::geometry<double> geom;
REQUIRE( input.data() );
std::string json_string(input.data().get(), input.size());
diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp
index d23c976..fd5d78f 100644
--- a/test/unit/geometry/geometry_envelope_test.cpp
+++ b/test/unit/geometry/geometry_envelope_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry.hpp>
diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp
index 3907149..f8ebc4d 100644
--- a/test/unit/geometry/geometry_equal.hpp
+++ b/test/unit/geometry/geometry_equal.hpp
@@ -1,3 +1,7 @@
+
+#ifndef MAPNIK_UNIT_GEOMETRY_EQUAL
+#define MAPNIK_UNIT_GEOMETRY_EQUAL
+
#include "catch.hpp"
// boost
@@ -214,3 +218,5 @@ void assert_g_equal(T const& g1, T const& g2)
{
return geometry_equal_visitor()(g1,g2);
}
+
+#endif // MAPNIK_UNIT_GEOMETRY_EQUAL
diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp
index 7552d01..3b21407 100644
--- a/test/unit/geometry/geometry_hit_test.cpp
+++ b/test/unit/geometry/geometry_hit_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry.hpp>
diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp
index 1170350..5548058 100644
--- a/test/unit/geometry/geometry_is_simple.cpp
+++ b/test/unit/geometry/geometry_is_simple.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <boost/version.hpp>
diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp
index c36549b..de1ee4c 100644
--- a/test/unit/geometry/geometry_is_valid.cpp
+++ b/test/unit/geometry/geometry_is_valid.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry.hpp>
diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp
index dad9e29..c8ec362 100644
--- a/test/unit/geometry/geometry_reprojection.cpp
+++ b/test/unit/geometry/geometry_reprojection.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include "geometry_equal.hpp"
diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp
index 50acb72..c08e828 100644
--- a/test/unit/geometry/geometry_strategy_test.cpp
+++ b/test/unit/geometry/geometry_strategy_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include "geometry_equal.hpp"
diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp
index a240c6f..b7fcab1 100644
--- a/test/unit/geometry/has_empty.cpp
+++ b/test/unit/geometry/has_empty.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry_is_empty.hpp>
diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp
index bb6a634..949b2b2 100644
--- a/test/unit/geometry/is_empty.cpp
+++ b/test/unit/geometry/is_empty.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry_is_empty.hpp>
diff --git a/test/unit/geometry/remove_empty.cpp b/test/unit/geometry/remove_empty.cpp
index 1523754..93881c8 100644
--- a/test/unit/geometry/remove_empty.cpp
+++ b/test/unit/geometry/remove_empty.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/geometry_remove_empty.hpp>
diff --git a/test/unit/imaging/image.cpp b/test/unit/imaging/image.cpp
index 9800860..2024953 100644
--- a/test/unit/imaging/image.cpp
+++ b/test/unit/imaging/image.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_apply_opacity.cpp b/test/unit/imaging/image_apply_opacity.cpp
index 09f8dd1..512097c 100644
--- a/test/unit/imaging/image_apply_opacity.cpp
+++ b/test/unit/imaging/image_apply_opacity.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_filter.cpp b/test/unit/imaging/image_filter.cpp
index 2b43c4d..5329ea4 100644
--- a/test/unit/imaging/image_filter.cpp
+++ b/test/unit/imaging/image_filter.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_io_test.cpp b/test/unit/imaging/image_io_test.cpp
index f2463f8..c562148 100644
--- a/test/unit/imaging/image_io_test.cpp
+++ b/test/unit/imaging/image_io_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
@@ -13,7 +14,15 @@
#include <mapnik/cairo/cairo_image_util.hpp>
#endif
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/format.hpp>
+#include <boost/filesystem/convenience.hpp>
+#pragma GCC diagnostic pop
+
+inline void make_directory(std::string const& dir) {
+ boost::filesystem::create_directories(dir);
+}
TEST_CASE("image io") {
@@ -143,25 +152,33 @@ SECTION("image_util : save_to_file/save_to_stream/save_to_string")
supported_types.push_back(std::make_tuple("webp","webp"));
#endif
+ std::string directory_name("/tmp/mapnik-tests/");
+ make_directory(directory_name);
+ REQUIRE(mapnik::util::exists(directory_name));
+
for (auto const& info : supported_types)
{
std::string extension;
std::string format;
std::tie(extension, format) = info;
- std::string filename = (boost::format("/tmp/mapnik-%1%.%2%") % named_color % extension).str();
+ std::string filename = (boost::format(directory_name + "mapnik-%1%.%2%") % named_color % extension).str();
mapnik::save_to_file(im, filename);
std::string str = mapnik::save_to_string(im, format);
std::ostringstream ss;
mapnik::save_to_stream(im, ss, format);
CHECK(str.length() == ss.str().length());
- std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, extension));
- unsigned w = reader->width();
- unsigned h = reader->height();
- auto im2 = reader->read(0, 0, w, h);
- CHECK(im2.size() == im.size());
- if (extension == "png" || extension == "tiff")
+ // wrap reader in scope to ensure the file handle is
+ // released before we try to remove the file
{
- CHECK(0 == std::memcmp(im2.bytes(), im.bytes(), im.width() * im.height()));
+ std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, extension));
+ unsigned w = reader->width();
+ unsigned h = reader->height();
+ auto im2 = reader->read(0, 0, w, h);
+ CHECK(im2.size() == im.size());
+ if (extension == "png" || extension == "tiff")
+ {
+ CHECK(0 == std::memcmp(im2.bytes(), im.bytes(), im.width() * im.height()));
+ }
}
if (mapnik::util::exists(filename))
{
diff --git a/test/unit/imaging/image_is_solid.cpp b/test/unit/imaging/image_is_solid.cpp
index 5bc8217..ffc527e 100644
--- a/test/unit/imaging/image_is_solid.cpp
+++ b/test/unit/imaging/image_is_solid.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_painted_test.cpp b/test/unit/imaging/image_painted_test.cpp
index 5d0b403..3705f2e 100644
--- a/test/unit/imaging/image_painted_test.cpp
+++ b/test/unit/imaging/image_painted_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
diff --git a/test/unit/imaging/image_premultiply.cpp b/test/unit/imaging/image_premultiply.cpp
index 3a5e2a1..813d21c 100644
--- a/test/unit/imaging/image_premultiply.cpp
+++ b/test/unit/imaging/image_premultiply.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_set_pixel.cpp b/test/unit/imaging/image_set_pixel.cpp
index 3488e00..d234765 100644
--- a/test/unit/imaging/image_set_pixel.cpp
+++ b/test/unit/imaging/image_set_pixel.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/imaging/image_view.cpp b/test/unit/imaging/image_view.cpp
index 25dbacf..db129d7 100644
--- a/test/unit/imaging/image_view.cpp
+++ b/test/unit/imaging/image_view.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/numerics/enumeration.cpp b/test/unit/numerics/enumeration.cpp
index 3c15993..64a6afc 100644
--- a/test/unit/numerics/enumeration.cpp
+++ b/test/unit/numerics/enumeration.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/enumeration.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
diff --git a/test/unit/numerics/safe_cast.cpp b/test/unit/numerics/safe_cast.cpp
index b6cba62..cb743df 100644
--- a/test/unit/numerics/safe_cast.cpp
+++ b/test/unit/numerics/safe_cast.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/safe_cast.hpp>
diff --git a/test/unit/pixel/agg_blend_src_over_test.cpp b/test/unit/pixel/agg_blend_src_over_test.cpp
index 60846f7..f457703 100644
--- a/test/unit/pixel/agg_blend_src_over_test.cpp
+++ b/test/unit/pixel/agg_blend_src_over_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
diff --git a/test/unit/pixel/palette.cpp b/test/unit/pixel/palette.cpp
index c45d068..a1e74d2 100644
--- a/test/unit/pixel/palette.cpp
+++ b/test/unit/pixel/palette.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/palette.hpp>
diff --git a/test/unit/projection/proj_transform.cpp b/test/unit/projection/proj_transform.cpp
index d2a3789..95c9595 100644
--- a/test/unit/projection/proj_transform.cpp
+++ b/test/unit/projection/proj_transform.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/projection.hpp>
diff --git a/include/mapnik/util/geometry_to_geojson.hpp b/test/unit/serialization/parse_hex.hpp
similarity index 63%
copy from include/mapnik/util/geometry_to_geojson.hpp
copy to test/unit/serialization/parse_hex.hpp
index 5cccb09..48c70a5 100644
--- a/include/mapnik/util/geometry_to_geojson.hpp
+++ b/test/unit/serialization/parse_hex.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
@@ -20,23 +20,25 @@
*
*****************************************************************************/
-#ifndef MAPNIK_GEOMETRY_TO_GEOJSON_HPP
-#define MAPNIK_GEOMETRY_TO_GEOJSON_HPP
+#ifndef MAPNIK_PARSE_HEX_HPP
+#define MAPNIK_PARSE_HEX_HPP
-// mapnik
-
-#include <mapnik/json/geometry_generator_grammar.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/qi_char_.hpp>
namespace mapnik { namespace util {
-inline bool to_geojson(std::string & json, mapnik::geometry::geometry<double> const& geom)
+template <typename Out>
+bool parse_hex(std::string const& input, Out & output)
{
- using sink_type = std::back_insert_iterator<std::string>;
- static const mapnik::json::geometry_generator_grammar<sink_type, mapnik::geometry::geometry<double> > grammar;
- sink_type sink(json);
- return boost::spirit::karma::generate(sink, grammar, geom);
+ boost::spirit::qi::lit_type lit;
+ auto itr = input.begin();
+ auto end = input.end();
+ using hex2 = boost::spirit::qi::uint_parser< unsigned, 16, 2, 2 >;
+ return boost::spirit::qi::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output);
}
}}
-#endif // MAPNIK_GEOMETRY_TO_GEOJSON_HPP
+
+#endif // MAPNIK_PARSE_HEX_HPP
diff --git a/test/unit/serialization/wkb_formats_test.cpp b/test/unit/serialization/wkb_formats_test.cpp
index 1f3a82e..bc0c171 100644
--- a/test/unit/serialization/wkb_formats_test.cpp
+++ b/test/unit/serialization/wkb_formats_test.cpp
@@ -2,11 +2,9 @@
#include <iostream>
#include <mapnik/wkb.hpp>
-#include <mapnik/feature.hpp>
#include <mapnik/geometry_is_valid.hpp>
#include <mapnik/geometry_is_simple.hpp>
#include <mapnik/geometry_correct.hpp>
-#include <mapnik/feature_factory.hpp>
#include <boost/version.hpp>
TEST_CASE("geometry formats") {
@@ -55,9 +53,6 @@ SECTION("wkb") {
unsigned char sq_invalid_blob[] = {
0x23, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x23 };
- mapnik::context_ptr ctx(new mapnik::context_type);
- mapnik::feature_ptr feature = mapnik::feature_factory::create(ctx, 1);
-
// test of parsing wkb geometries
try {
diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp
new file mode 100644
index 0000000..f82c4f3
--- /dev/null
+++ b/test/unit/serialization/wkb_test.cpp
@@ -0,0 +1,113 @@
+#include "catch.hpp"
+// mapnik
+#include <mapnik/wkb.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_adapters.hpp>
+#include <mapnik/geometry_is_empty.hpp>
+#include <mapnik/util/geometry_to_wkt.hpp>
+// bool
+#include <boost/version.hpp>
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/policies/compare.hpp>
+// stl
+#include "parse_hex.hpp"
+#include <iostream>
+#include <string>
+#include <vector>
+#include <fstream>
+
+namespace {
+
+struct spatially_equal_visitor
+{
+ using result_type = bool;
+
+ result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const
+ {
+ return true;
+ }
+
+ result_type operator() (mapnik::geometry::geometry_collection<double> const& lhs, mapnik::geometry::geometry_collection<double> const& rhs) const
+ {
+ std::size_t size0 = lhs.size();
+ std::size_t size1 = rhs.size();
+ if (size0 != size1) return false;
+ for (std::size_t index = 0; index < size0 ; ++index)
+ {
+ if (!mapnik::util::apply_visitor(*this, lhs[index], rhs[index]))
+ return false;
+ }
+ return true;
+ }
+
+ result_type operator() (mapnik::geometry::multi_point<double> const& lhs, mapnik::geometry::multi_point<double> const& rhs) const
+ {
+ std::size_t size0 = lhs.size();
+ std::size_t size1 = rhs.size();
+ if (size0 != size1) return false;
+ auto tmp0 = lhs;
+ auto tmp1 = rhs;
+ std::sort(tmp0.begin(), tmp0.end(), boost::geometry::less<mapnik::geometry::point<double>>());
+ std::sort(tmp1.begin(), tmp1.end(), boost::geometry::less<mapnik::geometry::point<double>>());
+ for (std::size_t index = 0; index < size0 ; ++index)
+ {
+ if (!boost::geometry::equals(tmp0[index], tmp1[index])) return false;
+ }
+ return true;
+ }
+
+ template <typename T>
+ result_type operator() (T const& lhs, T const& rhs) const
+ {
+ if (mapnik::geometry::is_empty(lhs) && mapnik::geometry::is_empty(rhs))
+ return true; //Empty geometries of the same type are considered to be spatially equal
+ return boost::geometry::equals(lhs, rhs);
+ }
+
+ template <typename T0, typename T1>
+ result_type operator() (T0 const& lhs, T1 const& rhs) const
+ {
+ return false;
+ }
+
+};
+
+template <typename T>
+bool spatially_equal(mapnik::geometry::geometry<T> const& g0, mapnik::geometry::geometry<T> const& g1)
+{
+ return mapnik::util::apply_visitor(spatially_equal_visitor(), g0, g1);
+}
+
+}
+
+TEST_CASE("Well-known-geometries")
+{
+ SECTION("wkb")
+ {
+ std::string filename("test/unit/data/well-known-geometries.test");
+ std::ifstream is(filename.c_str(),std::ios_base::in | std::ios_base::binary);
+ if (!is) throw std::runtime_error("could not open: '" + filename + "'");
+
+ for (std::string line; std::getline(is, line,'\n');)
+ {
+ std::vector<std::string> columns;
+ boost::split(columns, line, boost::is_any_of(";"));
+ REQUIRE(columns.size() == 3);
+ std::vector<char> wkb, twkb;
+ REQUIRE(mapnik::util::parse_hex(columns[1], wkb));
+ REQUIRE(mapnik::util::parse_hex(columns[2], twkb));
+ mapnik::geometry::geometry<double> geom_0 = mapnik::geometry_utils::from_wkb(wkb.data(), wkb.size(), mapnik::wkbAuto);
+ mapnik::geometry::geometry<double> geom_1 = mapnik::geometry_utils::from_twkb(twkb.data(), twkb.size());
+ // compare WKTs
+ std::string wkt0, wkt1;
+ REQUIRE(mapnik::util::to_wkt(wkt0, geom_0));
+ REQUIRE(mapnik::util::to_wkt(wkt1, geom_1));
+ if (!mapnik::geometry::is_empty(geom_0) && !mapnik::geometry::is_empty(geom_1))
+ {
+ REQUIRE(wkt0 == wkt1);
+ // compare spatially (NOTE: GeometryCollection comparison also enforces strict order)
+ REQUIRE(spatially_equal(geom_0, geom_1));
+ }
+ }
+ }
+}
diff --git a/test/unit/serialization/xml_parser_trim.cpp b/test/unit/serialization/xml_parser_trim.cpp
index afd2824..0a556e9 100644
--- a/test/unit/serialization/xml_parser_trim.cpp
+++ b/test/unit/serialization/xml_parser_trim.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/xml_tree.hpp>
diff --git a/test/unit/svg/svg_parser_test.cpp b/test/unit/svg/svg_parser_test.cpp
index 3fee6a4..0e38304 100644
--- a/test/unit/svg/svg_parser_test.cpp
+++ b/test/unit/svg/svg_parser_test.cpp
@@ -317,7 +317,7 @@ TEST_CASE("SVG parser") {
std::make_tuple(0, 10,2),
std::make_tuple(0, 10,95)};
- REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(),detail::vertex_equal<3>()));
+ REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(),vertex_equal<3>()));
}
SECTION("SVG viewbox fallback")
@@ -377,7 +377,7 @@ TEST_CASE("SVG parser") {
std::make_tuple(0, 10,2),
std::make_tuple(0, 10,95)};
- REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(),detail::vertex_equal<3>()));
+ REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(),vertex_equal<3>()));
}
SECTION("SVG beveled <rect>")
diff --git a/test/unit/svg/svg_path_parser_test.cpp b/test/unit/svg/svg_path_parser_test.cpp
index db13d2b..21a094c 100644
--- a/test/unit/svg/svg_path_parser_test.cpp
+++ b/test/unit/svg/svg_path_parser_test.cpp
@@ -50,7 +50,7 @@ void test_path_parser(std::string const& str, Expected const& expected)
vec.emplace_back(x, y, cmd);
//std::cerr << "std::make_tuple(" << x << ", " << y << ", " << cmd << ")," << std::endl;
}
- REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(), detail::vertex_equal<3>()));
+ REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(), vertex_equal<3>()));
}
} // anonymous ns
diff --git a/test/unit/svg/util.hpp b/test/unit/svg/util.hpp
index f8d9b5f..bbfcc11 100644
--- a/test/unit/svg/util.hpp
+++ b/test/unit/svg/util.hpp
@@ -25,7 +25,7 @@
#include <cmath>
-namespace detail {
+namespace {
template <int N = 6>
struct vertex_equal
diff --git a/test/unit/symbolizer/symbolizer_test.cpp b/test/unit/symbolizer/symbolizer_test.cpp
index 3af0532..1b7c269 100644
--- a/test/unit/symbolizer/symbolizer_test.cpp
+++ b/test/unit/symbolizer/symbolizer_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <iostream>
diff --git a/test/unit/text/shaping.cpp b/test/unit/text/shaping.cpp
index 2e2701b..d9da17e 100644
--- a/test/unit/text/shaping.cpp
+++ b/test/unit/text/shaping.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/text/icu_shaper.hpp>
#include <mapnik/text/harfbuzz_shaper.hpp>
diff --git a/test/unit/vertex_adapter/clipping_test.cpp b/test/unit/vertex_adapter/clipping_test.cpp
index 29a3e42..2239e26 100644
--- a/test/unit/vertex_adapter/clipping_test.cpp
+++ b/test/unit/vertex_adapter/clipping_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/vertex_adapter/line_offset_test.cpp b/test/unit/vertex_adapter/line_offset_test.cpp
index eba472f..dcb8dc6 100644
--- a/test/unit/vertex_adapter/line_offset_test.cpp
+++ b/test/unit/vertex_adapter/line_offset_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/vertex_adapter/offset_converter.cpp b/test/unit/vertex_adapter/offset_converter.cpp
index 8c2780d..9255f7d 100644
--- a/test/unit/vertex_adapter/offset_converter.cpp
+++ b/test/unit/vertex_adapter/offset_converter.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
// mapnik
diff --git a/test/unit/vertex_adapter/simplify_converters_test.cpp b/test/unit/vertex_adapter/simplify_converters_test.cpp
index a86f8d5..b43bb93 100644
--- a/test/unit/vertex_adapter/simplify_converters_test.cpp
+++ b/test/unit/vertex_adapter/simplify_converters_test.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
//#include <mapnik/wkt/wkt_factory.hpp>
diff --git a/test/unit/vertex_adapter/vertex_adapter.cpp b/test/unit/vertex_adapter/vertex_adapter.cpp
index 4505faa..da3e815 100644
--- a/test/unit/vertex_adapter/vertex_adapter.cpp
+++ b/test/unit/vertex_adapter/vertex_adapter.cpp
@@ -1,3 +1,4 @@
+
#include "catch.hpp"
#include <mapnik/vertex_adapters.hpp>
diff --git a/utils/mapnik-config/build.py b/utils/mapnik-config/build.py
index bf3e5b3..e4178ba 100644
--- a/utils/mapnik-config/build.py
+++ b/utils/mapnik-config/build.py
@@ -131,11 +131,6 @@ mapnik_bundled_gdal_data = ''
mapnik_bundled_proj_data = ''
mapnik_bundled_icu_data = ''
-if config_env.get('MAPNIK_BUNDLED_SHARE_DIRECTORY'):
- mapnik_bundled_gdal_data = 'lib/mapnik/share/gdal'
- mapnik_bundled_proj_data = 'lib/mapnik/share/proj'
- mapnik_bundled_icu_data = 'lib/mapnik/share/icu'
-
configuration = {
"git_revision": git_revision,
"git_describe": git_describe,
diff --git a/utils/mapnik-index/build.py b/utils/mapnik-index/build.py
index 5bb1770..358ce5f 100644
--- a/utils/mapnik-index/build.py
+++ b/utils/mapnik-index/build.py
@@ -24,18 +24,19 @@ import glob
from copy import copy
Import ('env')
+Import ('plugin_base')
-program_env = env.Clone()
+program_env = plugin_base.Clone()
source = Split(
"""
mapnik-index.cpp
process_csv_file.cpp
process_geojson_file.cpp
+ ../../plugins/input/csv/csv_utils.cpp
"""
)
-#headers = ['#plugins/input/shape'] + env['CPPPATH']
headers = env['CPPPATH']
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
diff --git a/utils/mapnik-index/mapnik-index.cpp b/utils/mapnik-index/mapnik-index.cpp
index f6f72be..3e1b8bb 100644
--- a/utils/mapnik-index/mapnik-index.cpp
+++ b/utils/mapnik-index/mapnik-index.cpp
@@ -163,7 +163,7 @@ int main (int argc, char** argv)
std::clog << "max tree depth:" << depth << std::endl;
std::clog << "split ratio:" << ratio << std::endl;
- using box_type = mapnik::box2d<double>;
+ using box_type = mapnik::box2d<float>;
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
for (auto const& filename : files_to_process)
@@ -175,7 +175,7 @@ int main (int argc, char** argv)
}
std::vector<item_type> boxes;
- mapnik::box2d<double> extent;
+ box_type extent;
if (mapnik::detail::is_csv(filename))
{
std::clog << "processing '" << filename << "' as CSV\n";
@@ -198,10 +198,12 @@ int main (int argc, char** argv)
if (extent.valid())
{
std::clog << extent << std::endl;
- mapnik::quad_tree<std::pair<std::size_t, std::size_t>> tree(extent, depth, ratio);
+ mapnik::box2d<double> extent_d(extent.minx(), extent.miny(), extent.maxx(), extent.maxy());
+ mapnik::quad_tree<std::pair<std::size_t, std::size_t>> tree(extent_d, depth, ratio);
for (auto const& item : boxes)
{
- tree.insert(std::get<1>(item), std::get<0>(item));
+ auto ext_f = std::get<0>(item);
+ tree.insert(std::get<1>(item), mapnik::box2d<double>(ext_f.minx(), ext_f.miny(), ext_f.maxx(), ext_f.maxy()));
}
std::fstream file((filename + ".index").c_str(),
diff --git a/utils/mapnik-index/process_csv_file.cpp b/utils/mapnik-index/process_csv_file.cpp
index 92c0728..b9834ce 100644
--- a/utils/mapnik-index/process_csv_file.cpp
+++ b/utils/mapnik-index/process_csv_file.cpp
@@ -21,13 +21,16 @@
*****************************************************************************/
#include "process_csv_file.hpp"
+#include "../../plugins/input/csv/csv_getline.hpp"
#include "../../plugins/input/csv/csv_utils.hpp"
+#include <mapnik/datasource.hpp>
#include <mapnik/geometry_envelope.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
+#include <boost/algorithm/string.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
#pragma GCC diagnostic pop
@@ -35,13 +38,19 @@
#endif
#include <fstream>
+#include <iostream>
+#include <sstream>
namespace mapnik { namespace detail {
template <typename T>
-std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
+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)
{
- mapnik::box2d<double> extent;
+ csv_utils::csv_file_parser p;
+ p.manual_headers_ = manual_headers;
+ p.separator_ = separator;
+ p.quote_ = quote;
+
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
using file_source_type = boost::interprocess::ibufferstream;
file_source_type csv_file;
@@ -56,7 +65,7 @@ std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& fil
else
{
std::clog << "Error : cannot mmap " << filename << std::endl;
- return std::make_pair(false, extent);
+ return std::make_pair(false, box2d<float>(p.extent_));
}
#else
#if defined(_WINDOWS)
@@ -67,182 +76,24 @@ std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& fil
if (!csv_file.is_open())
{
std::clog << "Error : cannot open " << filename << std::endl;
- return std::make_pair(false, extent);
+ return std::make_pair(false, box2d<float>(p.extent_));
}
#endif
- auto file_length = ::detail::file_length(csv_file);
- // set back to start
- csv_file.seekg(0, std::ios::beg);
- char newline;
- bool has_newline;
- char detected_quote;
- char detected_separator;
- std::tie(newline, has_newline, detected_separator, detected_quote) = ::detail::autodect_csv_flavour(csv_file, file_length);
- if (quote == 0) quote = detected_quote;
- if (separator == 0) separator = detected_separator;
- // set back to start
- csv_file.seekg(0, std::ios::beg);
- std::string csv_line;
- csv_utils::getline_csv(csv_file, csv_line, newline, quote);
- csv_file.seekg(0, std::ios::beg);
- int line_number = 0;
-
- ::detail::geometry_column_locator locator;
- std::vector<std::string> headers;
- std::clog << "Parsing CSV using SEPARATOR=" << separator << " QUOTE=" << quote << std::endl;
- if (!manual_headers.empty())
- {
- std::size_t index = 0;
- headers = csv_utils::parse_line(manual_headers, separator, quote);
- for (auto const& header : headers)
- {
- ::detail::locate_geometry_column(header, index++, locator);
- headers.push_back(header);
- }
- }
- else // parse first line as headers
- {
- while (csv_utils::getline_csv(csv_file,csv_line,newline, quote))
- {
- try
- {
- headers = csv_utils::parse_line(csv_line, separator, quote);
- // skip blank lines
- if (headers.size() > 0 && headers[0].empty()) ++line_number;
- else
- {
- std::size_t index = 0;
- for (auto & header : headers)
- {
- mapnik::util::trim(header);
- if (header.empty())
- {
- // create a placeholder for the empty header
- std::ostringstream s;
- s << "_" << index;
- header = s.str();
- }
- else
- {
- ::detail::locate_geometry_column(header, index, locator);
- }
- ++index;
- }
- ++line_number;
- break;
- }
- }
- catch (std::exception const& ex)
- {
- std::string s("CSV index: error parsing headers: ");
- s += ex.what();
- std::clog << s << std::endl;
- return std::make_pair(false, extent);
- }
- }
- }
-
- std::size_t num_headers = headers.size();
- if (!::detail::valid(locator, num_headers))
- {
- std::clog << "CSV index: could not detect column(s) with the name(s) of wkt, geojson, x/y, or "
- << "latitude/longitude in:\n"
- << csv_line
- << "\n - this is required for reading geometry data"
- << std::endl;
- return std::make_pair(false, extent);
- }
-
- auto pos = csv_file.tellg();
-
- // handle rare case of a single line of data and user-provided headers
- // where a lack of a newline will mean that csv_utils::getline_csv returns false
- bool is_first_row = false;
- if (!has_newline)
+ try
{
- csv_file.setstate(std::ios::failbit);
- pos = 0;
- if (!csv_line.empty())
- {
- is_first_row = true;
- }
+ p.parse_csv_and_boxes(csv_file, boxes);
+ return std::make_pair(true, box2d<float>(p.extent_));
}
- while (is_first_row || csv_utils::getline_csv(csv_file, csv_line, newline, quote))
+ catch (std::exception const& ex)
{
- ++line_number;
- auto record_offset = pos;
- auto record_size = csv_line.length();
- pos = csv_file.tellg();
- is_first_row = false;
- // skip blank lines
- if (record_size <= 10)
- {
- std::string trimmed = csv_line;
- boost::trim_if(trimmed, boost::algorithm::is_any_of("\",'\r\n "));
- if (trimmed.empty())
- {
- std::clog << "CSV index: empty row encountered at line: " << line_number << std::endl;
- continue;
- }
- }
- try
- {
- auto const* start_line = csv_line.data();
- auto const* end_line = start_line + csv_line.size();
- auto values = csv_utils::parse_line(start_line, end_line, separator, quote, num_headers);
- unsigned num_fields = values.size();
- if (num_fields != num_headers)
- {
- std::ostringstream s;
- s << "CSV Plugin: # of columns(" << num_fields << ")";
- if (num_fields > num_headers)
- {
- s << " > ";
- }
- else
- {
- s << " < ";
- }
- s << "# of headers(" << num_headers << ") parsed";
- throw mapnik::datasource_exception(s.str());
- }
-
- auto geom = ::detail::extract_geometry(values, locator);
- if (!geom.is<mapnik::geometry::geometry_empty>())
- {
- auto box = mapnik::geometry::envelope(geom);
- if (!extent.valid()) extent = box;
- else extent.expand_to_include(box);
- boxes.emplace_back(std::move(box), make_pair(record_offset, record_size));
- }
- else
- {
- std::ostringstream s;
- s << "CSV Index: expected geometry column: could not parse row "
- << line_number << " "
- << values[locator.index] << "'";
- throw mapnik::datasource_exception(s.str());
- }
- }
- catch (mapnik::datasource_exception const& ex )
- {
- std::clog << ex.what() << " at line: " << line_number << std::endl;
- }
- catch (std::exception const& ex)
- {
- std::ostringstream s;
- s << "CSV Index: unexpected error parsing line: " << line_number
- << " - found " << headers.size() << " with values like: " << csv_line << "\n"
- << " and got error like: " << ex.what();
- std::clog << s.str() << std::endl;
- }
+ std::clog << ex.what() << std::endl;
+ return std::make_pair(false, box2d<float>(p.extent_));
}
- return std::make_pair(true, extent);;
}
-using box_type = mapnik::box2d<double>;
+using box_type = mapnik::box2d<float>;
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
using boxes_type = std::vector<item_type>;
-template std::pair<bool,box2d<double>> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
+template std::pair<bool,box_type> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
}}
diff --git a/utils/mapnik-index/process_csv_file.hpp b/utils/mapnik-index/process_csv_file.hpp
index f84393d..395bf55 100644
--- a/utils/mapnik-index/process_csv_file.hpp
+++ b/utils/mapnik-index/process_csv_file.hpp
@@ -29,7 +29,7 @@
namespace mapnik { namespace detail {
template <typename T>
-std::pair<bool, box2d<double>> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote);
+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);
}}
diff --git a/utils/mapnik-index/process_geojson_file.cpp b/utils/mapnik-index/process_geojson_file.cpp
index ac0fa92..4455318 100644
--- a/utils/mapnik-index/process_geojson_file.cpp
+++ b/utils/mapnik-index/process_geojson_file.cpp
@@ -21,11 +21,6 @@
*****************************************************************************/
#include "process_geojson_file.hpp"
-#include <mapnik/geometry.hpp>
-#include <mapnik/geometry_envelope.hpp>
-#include <mapnik/geometry_adapters.hpp>
-#include <mapnik/util/file_io.hpp>
-#include <mapnik/util/utf_conv_win.hpp>
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
#pragma GCC diagnostic push
@@ -35,40 +30,46 @@
#include <boost/spirit/include/qi.hpp>
#pragma GCC diagnostic pop
#include <mapnik/mapped_memory_cache.hpp>
+#else
+#include <mapnik/util/file_io.hpp>
#endif
-#include <mapnik/json/positions_grammar.hpp>
#include <mapnik/json/extract_bounding_box_grammar_impl.hpp>
#include <mapnik/json/feature_collection_grammar_impl.hpp>
namespace {
+
+template <typename T>
struct feature_validate_callback
{
- feature_validate_callback(mapnik::box2d<double> const& box)
+ feature_validate_callback(mapnik::box2d<T> const& box)
: box_(box) {}
void operator() (mapnik::feature_ptr const& f) const
{
- if (box_ != f->envelope())
+ if (box_ != box_)
{
throw std::runtime_error("Bounding boxes mismatch validation feature");
}
}
- mapnik::box2d<double> const& box_;
+ mapnik::box2d<T> const& box_;
};
+using box_type = mapnik::box2d<float>;
+using boxes_type = std::vector<std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
using base_iterator_type = char const*;
-const mapnik::json::extract_bounding_box_grammar<base_iterator_type> geojson_datasource_static_bbox_grammar;
+const mapnik::json::extract_bounding_box_grammar<base_iterator_type, boxes_type> geojson_datasource_static_bbox_grammar;
const mapnik::transcoder tr("utf8");
-const mapnik::json::feature_grammar_callback<base_iterator_type, mapnik::feature_impl, feature_validate_callback> fc_grammar(tr);
+const mapnik::json::feature_grammar_callback<base_iterator_type, mapnik::feature_impl, feature_validate_callback<float>> fc_grammar(tr);
}
namespace mapnik { namespace detail {
template <typename T>
-std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose)
+std::pair<bool,typename T::value_type::first_type> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose)
{
- mapnik::box2d<double> extent;
+ using box_type = typename T::value_type::first_type;
+ box_type extent;
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
mapnik::mapped_region_ptr mapped_region;
boost::optional<mapnik::mapped_region_ptr> memory =
@@ -86,7 +87,7 @@ std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const&
char const* end = start + mapped_region->get_size();
#else
mapnik::util::file file(filename);
- if (!file.open())
+ if (!file)
{
std::clog << "Error : cannot open " << filename << std::endl;
return std::make_pair(false, extent);
@@ -125,7 +126,7 @@ std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const&
{
base_iterator_type feat_itr = start + item.second.first;
base_iterator_type feat_end = feat_itr + item.second.second;
- feature_validate_callback callback(item.first);
+ feature_validate_callback<float> callback(item.first);
bool result = boost::spirit::qi::phrase_parse(feat_itr, feat_end, (fc_grammar)
(boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)),
space);
@@ -140,9 +141,6 @@ std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const&
return std::make_pair(true, extent);
}
-using box_type = mapnik::box2d<double>;
-using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
-using boxes_type = std::vector<item_type>;
-template std::pair<bool,box2d<double>> process_geojson_file(boxes_type&, std::string const&, bool, bool);
+template std::pair<bool,box_type> process_geojson_file(boxes_type&, std::string const&, bool, bool);
}}
diff --git a/utils/mapnik-index/process_geojson_file.hpp b/utils/mapnik-index/process_geojson_file.hpp
index aba4911..a377d23 100644
--- a/utils/mapnik-index/process_geojson_file.hpp
+++ b/utils/mapnik-index/process_geojson_file.hpp
@@ -29,7 +29,7 @@
namespace mapnik { namespace detail {
template <typename T>
-std::pair<bool, box2d<double>> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose);
+std::pair<bool, typename T::value_type::first_type> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose);
}}
diff --git a/utils/pgsql2sqlite/main.cpp b/utils/pgsql2sqlite/main.cpp
index 39ced62..81eff63 100644
--- a/utils/pgsql2sqlite/main.cpp
+++ b/utils/pgsql2sqlite/main.cpp
@@ -26,10 +26,13 @@
#include <mapnik/wkb.hpp>
#include "connection_manager.hpp"
-// boost
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
-#include <memory>
#include <boost/program_options.hpp>
+#pragma GCC diagnostic pop
+
+#include <memory>
//stl
#include <iostream>
diff --git a/utils/pgsql2sqlite/sqlite.hpp b/utils/pgsql2sqlite/sqlite.hpp
index 07d2128..be4e4a3 100644
--- a/utils/pgsql2sqlite/sqlite.hpp
+++ b/utils/pgsql2sqlite/sqlite.hpp
@@ -24,8 +24,11 @@
#include <mapnik/util/variant.hpp>
// boost
#include <memory>
-//sqlite3
+
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore.hpp>
#include <sqlite3.h>
+#pragma GCC diagnostic pop
//stl
#ifdef MAPNIK_DEBUG
diff --git a/utils/shapeindex/build.py b/utils/shapeindex/build.py
index 9f7de74..2a4c2ab 100644
--- a/utils/shapeindex/build.py
+++ b/utils/shapeindex/build.py
@@ -25,7 +25,9 @@ from copy import copy
Import ('env')
-program_env = env.Clone()
+Import ('plugin_base')
+
+program_env = plugin_base.Clone()
source = Split(
"""
diff --git a/utils/shapeindex/shapeindex.cpp b/utils/shapeindex/shapeindex.cpp
index f54508c..9dcff11 100644
--- a/utils/shapeindex/shapeindex.cpp
+++ b/utils/shapeindex/shapeindex.cpp
@@ -72,13 +72,13 @@ int main (int argc,char** argv)
if (vm.count("version"))
{
std::clog << "version 0.3.0" <<std::endl;
- return 1;
+ return EXIT_FAILURE;
}
if (vm.count("help"))
{
std::clog << desc << std::endl;
- return 1;
+ return EXIT_FAILURE;
}
if (vm.count("verbose"))
{
@@ -105,7 +105,7 @@ int main (int argc,char** argv)
catch (std::exception const& ex)
{
std::clog << "Error: " << ex.what() << std::endl;
- return -1;
+ return EXIT_FAILURE;
}
std::clog << "max tree depth:" << depth << std::endl;
@@ -114,7 +114,7 @@ int main (int argc,char** argv)
if (shape_files.size() == 0)
{
std::clog << "no shape files to index" << std::endl;
- return 0;
+ return EXIT_FAILURE;
}
for (auto const& filename : shape_files)
{
@@ -164,6 +164,11 @@ int main (int argc,char** argv)
std::clog << "type=" << shape_type << std::endl;
std::clog << "extent:" << extent << std::endl;
+ if (!extent.valid() || std::isnan(extent.width()) || std::isnan(extent.height()))
+ {
+ std::clog << "Invalid extent aborting..." << std::endl;
+ return EXIT_FAILURE;
+ }
int pos = 50;
shx.seek(pos * 2);
mapnik::quad_tree<mapnik::detail::node> tree(extent, depth, ratio);
@@ -278,5 +283,5 @@ int main (int argc,char** argv)
}
std::clog << "done!" << std::endl;
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/utils/svg2png/svg2png.cpp b/utils/svg2png/svg2png.cpp
index c7fe797..b78f53b 100644
--- a/utils/svg2png/svg2png.cpp
+++ b/utils/svg2png/svg2png.cpp
@@ -40,12 +40,16 @@
#include <boost/program_options.hpp>
#pragma GCC diagnostic pop
+#pragma GCC diagnostic push
+#include <mapnik/warning_ignore_agg.hpp>
#include "agg_rasterizer_scanline_aa.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"
+#pragma GCC diagnostic pop
+
struct main_marker_visitor
{
--
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