Merge branch 'master' into spirit-x3

This commit is contained in:
artemp 2016-06-23 16:47:45 +01:00
commit 392ff1a70a
276 changed files with 5509 additions and 3729 deletions

View file

@ -1,4 +1,4 @@
language: c
language: cpp
git:
depth: 10
@ -9,16 +9,12 @@ env:
- 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.6
packages:
- clang-3.6
cache:
directories:
@ -28,22 +24,32 @@ matrix:
include:
- os: linux
sudo: false
compiler: clang
env: JOBS=8 CXX="ccache clang++-3.6 -Qunused-arguments" CC="clang-3.6" MASON_PUBLISH=False BENCH=False
compiler: ": clang"
env: JOBS=8 MASON_PUBLISH=true _CXX="ccache clang++-3.8 -Qunused-arguments" _CC="clang-3.8" TRIGGER=true
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6' ]
packages: [ 'clang-3.6', 'libstdc++-4.9-dev', 'libstdc++6' ]
apt:
sources: [ 'ubuntu-toolchain-r-test']
packages: [ 'libstdc++6', 'libstdc++-5-dev']
- os: linux
sudo: false
compiler: ": clang-coverage"
env: JOBS=8 COVERAGE=true _CXX="ccache clang++-3.8 -Qunused-arguments" _CC="clang-3.8"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test']
packages: [ 'libstdc++6','libstdc++-5-dev' ]
- os: osx
compiler: clang
compiler: ": clang-osx"
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
osx_image: xcode7.3 # upgrades clang from 6 -> 7
env: JOBS=4 MASON_PUBLISH=False
env: JOBS=4 MASON_PUBLISH=true _CXX="ccache clang++ -Qunused-arguments"
before_install:
- if [[ ${_CXX:-false} != false ]]; then export CXX=${_CXX}; fi
- if [[ ${_CC:-false} != false ]]; then export CC=${_CC}; fi
- source scripts/travis-common.sh
- export PYTHONUSERBASE=$(pwd)/mason_packages/.link
- export PATH=$(pwd)/mason_packages/.link/bin:${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}
@ -52,12 +58,13 @@ 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
@ -65,6 +72,13 @@ install:
before_script:
- source bootstrap.sh
- |
if [[ $(uname -s) == 'Linux' ]]; then
mason install clang 3.8.0
export PATH=$(mason prefix clang 3.8.0)/bin:${PATH}
which clang++
export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov"
fi
- ccache --version
- ccache -p || true
- ccache --show-stats || true
@ -73,14 +87,16 @@ before_script:
script:
- export SCONSFLAGS='--debug=time'
- configure BENCHMARK=${BENCH}
- cat config.log
- make
- make test
- enabled ${COVERAGE} coverage
- 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

View file

@ -10,12 +10,16 @@ For a complete change history, see the git log.
Released:
(Packaged from )
(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)
- [TWKB](https://github.com/TWKB/) support via https://github.com/mapnik/mapnik/pull/3356 (#3355)
- Visual test runner can render SVG, PDF and Postscript with Cairo renderer (https://github.com/mapnik/mapnik/pull/3418)
- Scale factor is now applied also to `text-line-spacing` and transforms (https://github.com/mapnik/mapnik/pull/3416)
## 3.0.10
Released: February 25, 2016

View file

@ -98,7 +98,7 @@ Additional optional dependencies:
* PostgreSQL (for PostGIS plugin support)
- libpq - PostreSQL libraries
- pg_config - PostgreSQL installation capabilities
* libgdal - GDAL/OGR input (For gdal and ogr plugin support)
* libgdal - GDAL/OGR input (For gdal and ogr plugin support) (>= GDAL 2.0.2 for thread safety - https://github.com/mapnik/mapnik/issues/3339)
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
Instructions for installing many of these dependencies on

View file

@ -9,6 +9,7 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/
```
[![Build Status Linux](https://api.travis-ci.org/mapnik/mapnik.svg?branch=master)](http://travis-ci.org/mapnik/mapnik)
[![CircleCI](https://circleci.com/gh/mapnik/mapnik.svg?style=svg)](https://circleci.com/gh/mapnik/mapnik)
[![Build Status Windows](https://ci.appveyor.com/api/projects/status/hc9l7okdjtucfqqn?branch=master&svg=true)](https://ci.appveyor.com/project/Mapbox/mapnik)
[![Coverage Status](https://coveralls.io/repos/mapnik/mapnik/badge.svg?branch=master&service=github)](https://coveralls.io/github/mapnik/mapnik?branch=master)
@ -20,7 +21,7 @@ For further information see [http://mapnik.org](http://mapnik.org) and also our
# Installation
See [INSTALL.md](https://github.com/mapnik/mapnik/blob/master/INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
See [INSTALL.md](INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
# Code of Conduct
@ -28,4 +29,4 @@ Please note that this project is released with a [Contributor Code of Conduct](h
# License
Mapnik software is free and is released under the LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html_)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
Mapnik software is free and is released under the LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.

1910
SConstruct

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
environment:
msvs_toolset: 14
BOOST_VERSION: 59
BOOST_VERSION: 60
FASTBUILD: 1
matrix:
- platform: x64
@ -19,8 +19,13 @@ 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
@ -28,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

View file

@ -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>
@ -52,7 +52,6 @@ public:
}
virtual bool validate() const = 0;
virtual bool operator()() const = 0;
virtual ~test_case() {}
};
// gathers --long-option values in 'params';
@ -288,4 +287,4 @@ protected:
}
#endif // __MAPNIK_BENCH_FRAMEWORK_HPP__
#endif // MAPNIK_BENCH_FRAMEWORK_HPP

View file

@ -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

19
bootstrap.sh Normal file → Executable file
View file

@ -10,14 +10,16 @@ todo
- shrink icu data
'
MASON_VERSION="b709931"
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
export CXX=${CXX:-clang++}
export CC=${CC:-clang}
@ -28,8 +30,8 @@ function install() {
if [[ ! -d ./mason_packages/${MASON_PLATFORM_ID}/${1}/${2} ]]; then
mason install $1 $2
mason link $1 $2
if [[ $3 ]]; then
LA_FILE=$(${MASON_DIR:-~/.mason}/mason prefix $1 $2)/lib/$3.la
if [[ ${3:-false} != false ]]; then
LA_FILE=$(mason prefix $1 $2)/lib/$3.la
if [[ -f ${LA_FILE} ]]; then
perl -i -p -e 's:\Q$ENV{HOME}/build/mapbox/mason\E:$ENV{PWD}:g' ${LA_FILE}
else
@ -60,8 +62,11 @@ function install_mason_deps() {
wait
install webp 0.4.2 libwebp &
install gdal 1.11.2 libgdal &
install boost 1.59.0 &
install boost_liball 1.59.0 &
install boost 1.61.0 &
install boost_libsystem 1.61.0 &
install boost_libfilesystem 1.61.0 &
install boost_libprogram_options 1.61.0 &
install boost_libregex 1.61.0 &
install freetype 2.6 libfreetype &
install harfbuzz 0.9.41 libharfbuzz &
wait

45
circle.yml Normal file
View file

@ -0,0 +1,45 @@
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.8
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 add-apt-repository -y ppa:ubuntu-toolchain-r/test
override:
- sudo apt-get update -y
database:
pre:
- ./bootstrap.sh
- ./.mason/mason install clang ${LLVM_VERSION}.0
- ./.mason/mason link clang ${LLVM_VERSION}.0
- ./configure CC="$(pwd)/mason_packages/.link/bin/clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++-${LLVM_VERSION} -Qunused-arguments"
- make
override:
- psql -c 'create database template_postgis;'
- psql -c 'create extension postgis;' -d template_postgis
test:
override:
- make test

View file

@ -52,11 +52,11 @@ If you do not have svn installed you can grab gyp from:
Simply type:
make
make
Then to run do:
./rundemo `mapnik-config --prefix`
./rundemo `mapnik-config --prefix`
On OS X you can also create an xcode project:

View file

@ -55,7 +55,7 @@ int main ( int, char** )
try {
std::cout << " running demo ... \n";
datasource_cache::instance().register_datasources("plugins/input/");
freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.34/ttf/DejaVuSans.ttf");
freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.35/ttf/DejaVuSans.ttf");
Map m(800,600);
m.set_background(parse_color("white"));
@ -230,7 +230,7 @@ int main ( int, char** )
parameters p;
p["type"]="shape";
p["file"]="demo/data/boundaries";
p["encoding"]="latin1";
p["encoding"]="utf8";
layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance().create(p));
@ -295,7 +295,7 @@ int main ( int, char** )
parameters p;
p["type"]="shape";
p["file"]="demo/data/popplaces";
p["encoding"] = "latin1";
p["encoding"] = "utf8";
layer lyr("Populated Places");
lyr.set_srs(srs_lcc);
lyr.set_datasource(datasource_cache::instance().create(p));

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
PROJCS["Atlas of Canada Lambert Conformal Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-95.0],PARAMETER["Standard_Parallel_1",49.0],PARAMETER["Standard_Parallel_2",77.0],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]]

Binary file not shown.

View file

@ -2,15 +2,15 @@
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
@ -19,12 +19,12 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
@ -39,8 +39,8 @@ namespace agg
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_aa
{
@ -67,10 +67,10 @@ namespace agg
//==================================================rasterizer_scanline_aa
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
@ -79,20 +79,20 @@ namespace agg
//
// 3. reset()
//
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// more than one contour, but each contour must consist of at least 3
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
// is the absolute minimum of vertices that define a triangle.
// The algorithm does not check either the number of vertices nor
// coincidence of their coordinates, but in the worst case it just
// coincidence of their coordinates, but in the worst case it just
// won't draw anything.
// The orger of the vertices (clockwise or counterclockwise)
// The orger of the vertices (clockwise or counterclockwise)
// is important when using the non-zero filling rule (fill_non_zero).
// In this case the vertex order of all the contours must be the same
// if you want your intersecting polygons to be without "holes".
// You actually can use different vertices order. If the contours do not
// intersect each other the order is not important anyway. If they do,
// contours with the same vertex order will be rendered without "holes"
// You actually can use different vertices order. If the contours do not
// intersect each other the order is not important anyway. If they do,
// contours with the same vertex order will be rendered without "holes"
// while the intersecting contours with different orders will have "holes".
//
// filling_rule() and gamma() can be called anytime before "sweeping".
@ -122,7 +122,7 @@ namespace agg
};
//--------------------------------------------------------------------
rasterizer_scanline_aa() :
rasterizer_scanline_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
@ -136,8 +136,8 @@ namespace agg
}
//--------------------------------------------------------------------
template<class GammaF>
rasterizer_scanline_aa(const GammaF& gamma_function) :
template<class GammaF>
rasterizer_scanline_aa(const GammaF& gamma_function) :
m_outline(),
m_clipper(m_outline),
m_filling_rule(fill_non_zero),
@ -150,7 +150,7 @@ namespace agg
}
//--------------------------------------------------------------------
void reset();
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
@ -158,7 +158,7 @@ namespace agg
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
{
{
int i;
for(i = 0; i < aa_scale; i++)
{
@ -167,9 +167,9 @@ namespace agg
}
//--------------------------------------------------------------------
unsigned apply_gamma(unsigned cover) const
{
return m_gamma[cover];
unsigned apply_gamma(unsigned cover) const
{
return m_gamma[cover];
}
//--------------------------------------------------------------------
@ -198,7 +198,7 @@ namespace agg
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
@ -237,7 +237,7 @@ namespace agg
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
unsigned cover = 0;
while(num_cells)
{
@ -276,7 +276,7 @@ namespace agg
}
}
}
if(sl.num_spans()) break;
++m_scan_y;
}
@ -294,7 +294,7 @@ namespace agg
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
const rasterizer_scanline_aa<Clip>&
const rasterizer_scanline_aa<Clip>&
operator = (const rasterizer_scanline_aa<Clip>&);
private:
@ -321,32 +321,32 @@ namespace agg
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset()
{
m_outline.reset();
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
template<class Clip>
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
template<class Clip>
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset_clipping()
{
reset();
@ -354,7 +354,7 @@ namespace agg
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::close_polygon()
{
if(m_status == status_line_to)
@ -365,56 +365,56 @@ namespace agg
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
{
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
else
if(is_vertex(cmd))
{
line_to_d(x, y);
@ -427,32 +427,32 @@ namespace agg
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::sort()
{
if(m_auto_close) close_polygon();
@ -460,12 +460,12 @@ namespace agg
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
if(m_outline.total_cells() == 0)
{
return false;
}
@ -475,14 +475,14 @@ namespace agg
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
@ -491,7 +491,7 @@ namespace agg
}
//------------------------------------------------------------------------
template<class Clip>
template<class Clip>
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
@ -507,4 +507,3 @@ namespace agg
#endif

2
deps/mapbox/variant vendored

@ -1 +1 @@
Subproject commit 5aab5df0dc899b484c04ce9c649645787ee0bc5c
Subproject commit b5728ad76e1402c130a9330aa44b6f4b655b13b4

View file

@ -7,7 +7,7 @@ subdirs = {
'./sparsehash':{'dir':'sparsehash','glob':'*'},
'./sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'},
'../agg/include':{'dir':'agg','glob':'agg*'},
'../mapbox':{'dir':'mapbox/variant','glob':'*/*.hpp'}
'../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'}
}
if 'install' in COMMAND_LINE_TARGETS:

View file

@ -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 {

View file

@ -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
{

View file

@ -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 {

View file

@ -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 {

View file

@ -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
@ -38,9 +40,8 @@ struct trans_affine;
namespace mapnik {
/*!
* A spatial envelope (i.e. bounding box) which also defines some basic operators.
*/
// A spatial envelope (i.e. bounding box) which also defines some basic operators.
template <typename T> class MAPNIK_DECL box2d
: boost::equality_comparable<box2d<T> ,
boost::addable<box2d<T>,
@ -48,7 +49,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 +65,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 +109,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);

View file

@ -0,0 +1,496 @@
/*****************************************************************************
*
* 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/box2d.hpp>
#include <mapnik/safe_cast.hpp>
// stl
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <mapnik/config.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
#pragma GCC diagnostic pop
// agg
#include "agg_trans_affine.h"
BOOST_FUSION_ADAPT_TPL_ADT(
(T),
(mapnik::box2d)(T),
(T, T, obj.minx(), obj.set_minx(mapnik::safe_cast<T>(val)))
(T, T, obj.miny(), obj.set_miny(mapnik::safe_cast<T>(val)))
(T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast<T>(val)))
(T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast<T>(val))))
namespace mapnik
{
template <typename T>
box2d<T>::box2d()
:minx_( std::numeric_limits<T>::max()),
miny_( std::numeric_limits<T>::max()),
maxx_(-std::numeric_limits<T>::max()),
maxy_(-std::numeric_limits<T>::max()) {}
template <typename T>
box2d<T>::box2d(T minx,T miny,T maxx,T maxy)
{
init(minx,miny,maxx,maxy);
}
template <typename T>
box2d<T>::box2d(coord<T,2> const& c0, coord<T,2> const& c1)
{
init(c0.x,c0.y,c1.x,c1.y);
}
template <typename T>
box2d<T>::box2d(box2d_type const& rhs)
: minx_(rhs.minx_),
miny_(rhs.miny_),
maxx_(rhs.maxx_),
maxy_(rhs.maxy_) {}
template <typename T>
box2d<T>::box2d(box2d_type && rhs)
: minx_(std::move(rhs.minx_)),
miny_(std::move(rhs.miny_)),
maxx_(std::move(rhs.maxx_)),
maxy_(std::move(rhs.maxy_)) {}
template <typename T>
box2d<T>& box2d<T>::operator=(box2d_type other)
{
swap(*this, other);
return *this;
}
template <typename T>
box2d<T>::box2d(box2d_type const& rhs, agg::trans_affine const& tr)
{
double x0 = rhs.minx_, y0 = rhs.miny_;
double x1 = rhs.maxx_, y1 = rhs.miny_;
double x2 = rhs.maxx_, y2 = rhs.maxy_;
double x3 = rhs.minx_, y3 = rhs.maxy_;
tr.transform(&x0, &y0);
tr.transform(&x1, &y1);
tr.transform(&x2, &y2);
tr.transform(&x3, &y3);
init(static_cast<T>(x0), static_cast<T>(y0),
static_cast<T>(x2), static_cast<T>(y2));
expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
}
template <typename T>
bool box2d<T>::operator==(box2d<T> const& other) const
{
return minx_==other.minx_ &&
miny_==other.miny_ &&
maxx_==other.maxx_ &&
maxy_==other.maxy_;
}
template <typename T>
T box2d<T>::minx() const
{
return minx_;
}
template <typename T>
T box2d<T>::maxx() const
{
return maxx_;
}
template <typename T>
T box2d<T>::miny() const
{
return miny_;
}
template <typename T>
T box2d<T>::maxy() const
{
return maxy_;
}
template<typename T>
void box2d<T>::set_minx(T v)
{
minx_ = v;
}
template<typename T>
void box2d<T>::set_miny(T v)
{
miny_ = v;
}
template<typename T>
void box2d<T>::set_maxx(T v)
{
maxx_ = v;
}
template<typename T>
void box2d<T>::set_maxy(T v)
{
maxy_ = v;
}
template <typename T>
T box2d<T>::width() const
{
return maxx_-minx_;
}
template <typename T>
T box2d<T>::height() const
{
return maxy_-miny_;
}
template <typename T>
void box2d<T>::width(T w)
{
T cx=center().x;
minx_=static_cast<T>(cx-w*0.5);
maxx_=static_cast<T>(cx+w*0.5);
}
template <typename T>
void box2d<T>::height(T h)
{
T cy=center().y;
miny_=static_cast<T>(cy-h*0.5);
maxy_=static_cast<T>(cy+h*0.5);
}
template <typename T>
coord<T,2> box2d<T>::center() const
{
return coord<T,2>(static_cast<T>(0.5*(minx_+maxx_)),
static_cast<T>(0.5*(miny_+maxy_)));
}
template <typename T>
void box2d<T>::expand_to_include(coord<T,2> const& c)
{
expand_to_include(c.x,c.y);
}
template <typename T>
void box2d<T>::expand_to_include(T x,T y)
{
if (x<minx_) minx_=x;
if (x>maxx_) maxx_=x;
if (y<miny_) miny_=y;
if (y>maxy_) maxy_=y;
}
template <typename T>
void box2d<T>::expand_to_include(box2d<T> const& other)
{
if (other.minx_<minx_) minx_=other.minx_;
if (other.maxx_>maxx_) maxx_=other.maxx_;
if (other.miny_<miny_) miny_=other.miny_;
if (other.maxy_>maxy_) maxy_=other.maxy_;
}
template <typename T>
bool box2d<T>::contains(coord<T,2> const& c) const
{
return contains(c.x,c.y);
}
template <typename T>
bool box2d<T>::contains(T x,T y) const
{
return x>=minx_ && x<=maxx_ && y>=miny_ && y<=maxy_;
}
template <typename T>
bool box2d<T>::contains(box2d<T> const& other) const
{
return other.minx_>=minx_ &&
other.maxx_<=maxx_ &&
other.miny_>=miny_ &&
other.maxy_<=maxy_;
}
template <typename T>
bool box2d<T>::intersects(coord<T,2> const& c) const
{
return intersects(c.x,c.y);
}
template <typename T>
bool box2d<T>::intersects(T x,T y) const
{
return !(x>maxx_ || x<minx_ || y>maxy_ || y<miny_);
}
template <typename T>
bool box2d<T>::intersects(box2d<T> const& other) const
{
return !(other.minx_>maxx_ || other.maxx_<minx_ ||
other.miny_>maxy_ || other.maxy_<miny_);
}
template <typename T>
box2d<T> box2d<T>::intersect(box2d_type const& other) const
{
if (intersects(other))
{
T x0=std::max(minx_,other.minx_);
T y0=std::max(miny_,other.miny_);
T x1=std::min(maxx_,other.maxx_);
T y1=std::min(maxy_,other.maxy_);
return box2d<T>(x0,y0,x1,y1);
}
else
{
return box2d<T>();
}
}
template <typename T>
void box2d<T>::re_center(T cx,T cy)
{
T dx=cx-center().x;
T dy=cy-center().y;
minx_+=dx;
miny_+=dy;
maxx_+=dx;
maxy_+=dy;
}
template <typename T>
void box2d<T>::re_center(coord<T,2> const& c)
{
re_center(c.x,c.y);
}
template <typename T>
void box2d<T>::init(T x0, T y0, T x1, T y1)
{
if (x0 < x1)
{
minx_ = x0;
maxx_ = x1;
}
else
{
minx_ = x1;
maxx_ = x0;
}
if (y0 < y1)
{
miny_ = y0;
maxy_ = y1;
}
else
{
miny_ = y1;
maxy_ = y0;
}
}
template <typename T>
void box2d<T>::init(T x, T y)
{
init(x, y, x, y);
}
template <typename T>
void box2d<T>::clip(box2d_type const& other)
{
minx_ = std::max(minx_, other.minx());
miny_ = std::max(miny_, other.miny());
maxx_ = std::min(maxx_, other.maxx());
maxy_ = std::min(maxy_, other.maxy());
}
template <typename T>
void box2d<T>::pad(T padding)
{
minx_ -= padding;
miny_ -= padding;
maxx_ += padding;
maxy_ += padding;
}
template <typename T>
bool box2d<T>::from_string(std::string const& str)
{
boost::spirit::qi::lit_type lit;
boost::spirit::qi::double_type double_;
boost::spirit::ascii::space_type space;
bool r = boost::spirit::qi::phrase_parse(str.begin(),
str.end(),
double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_,
space,
*this);
return r;
}
template <typename T>
bool box2d<T>::valid() const
{
return (minx_ <= maxx_ && miny_ <= maxy_) ;
}
template <typename T>
void box2d<T>::move(T x, T y)
{
minx_ += x;
maxx_ += x;
miny_ += y;
maxy_ += y;
}
template <typename T>
std::string box2d<T>::to_string() const
{
std::ostringstream s;
if (valid())
{
s << "box2d(" << std::fixed << std::setprecision(16)
<< minx_ << ',' << miny_ << ','
<< maxx_ << ',' << maxy_ << ')';
}
else
{
s << "box2d(INVALID)";
}
return s.str();
}
template <typename T>
box2d<T>& box2d<T>::operator+=(box2d<T> const& other)
{
expand_to_include(other);
return *this;
}
template <typename T>
box2d<T> box2d<T>::operator+ (T other) const
{
return box2d<T>(minx_ - other, miny_ - other, maxx_ + other, maxy_ + other);
}
template <typename T>
box2d<T>& box2d<T>::operator+= (T other)
{
minx_ -= other;
miny_ -= other;
maxx_ += other;
maxy_ += other;
return *this;
}
template <typename T>
box2d<T>& box2d<T>::operator*=(T t)
{
coord<T,2> c = center();
T sx = static_cast<T>(0.5 * width() * t);
T sy = static_cast<T>(0.5 * height() * t);
minx_ = c.x - sx;
maxx_ = c.x + sx;
miny_ = c.y - sy;
maxy_ = c.y + sy;
return *this;
}
template <typename T>
box2d<T>& box2d<T>::operator/=(T t)
{
coord<T,2> c = center();
T sx = static_cast<T>(0.5 * width() / t);
T sy = static_cast<T>(0.5 * height() / t);
minx_ = c.x - sx;
maxx_ = c.x + sx;
miny_ = c.y - sy;
maxy_ = c.y + sy;
return *this;
}
template <typename T>
T box2d<T>::operator[] (int index) const
{
switch(index)
{
case 0:
return minx_;
case 1:
return miny_;
case 2:
return maxx_;
case 3:
return maxy_;
case -4:
return minx_;
case -3:
return miny_;
case -2:
return maxx_;
case -1:
return maxy_;
default:
throw std::out_of_range("index out of range, max value is 3, min value is -4 ");
}
}
template <typename T>
box2d<T> box2d<T>::operator*(agg::trans_affine const& tr) const
{
return box2d<T>(*this, tr);
}
template <typename T>
box2d<T>& box2d<T>::operator*=(agg::trans_affine const& tr)
{
double x0 = minx_, y0 = miny_;
double x1 = maxx_, y1 = miny_;
double x2 = maxx_, y2 = maxy_;
double x3 = minx_, y3 = maxy_;
tr.transform(&x0, &y0);
tr.transform(&x1, &y1);
tr.transform(&x2, &y2);
tr.transform(&x3, &y3);
init(static_cast<T>(x0), static_cast<T>(y0),
static_cast<T>(x2), static_cast<T>(y2));
expand_to_include(static_cast<T>(x1), static_cast<T>(y1));
expand_to_include(static_cast<T>(x3), static_cast<T>(y3));
return *this;
}
}

View file

@ -38,18 +38,20 @@
#include <mapnik/symbolizer_base.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <cairo.h>
#pragma GCC diagnostic pop
// stl
#include <memory>
// cairo
#include <cairo.h>
// stl
#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 {

View file

@ -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>

View file

@ -52,7 +52,10 @@
#define PROJ_ENVELOPE_POINTS 20
#ifndef BOOST_MPL_LIMIT_VECTOR_SIZE
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#define BOOST_MPL_LIMIT_VECTOR_SIZE 30
#else
#warning "WARNING: BOOST_MPL_LIMIT_VECTOR_SIZE is already defined. Ensure config.hpp is included before any Boost headers"
#endif
#endif // MAPNIK_CONFIG_HPP

View file

@ -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>

View file

@ -69,15 +69,15 @@ public:
static void set_severity(severity_type severity_level)
{
//#ifdef MAPNIK_THREADSAFE
// std::lock_guard<std::mutex> lock(severity_mutex_);
//#endif
severity_level_ = severity_level;
}
// per object security levels
static severity_type get_object_severity(std::string const& object_name)
{
#ifdef MAPNIK_THREADSAFE
std::lock_guard<std::mutex> lock(severity_mutex_);
#endif
severity_map::iterator it = object_severity_level_.find(object_name);
if (object_name.empty() || it == object_severity_level_.end())
{

View file

@ -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>

View file

@ -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>

View file

@ -24,43 +24,41 @@
#define MAPNIK_GEOMETRY_HPP
#include <mapnik/util/variant.hpp>
#include <mapnik/coord.hpp>
#include <vector>
#include <type_traits>
#include <cstddef>
namespace mapnik { namespace geometry {
template <typename T>
struct point
{
using value_type = T;
using coord_type = T;
point() {}
point(T x_, T y_)
: x(x_), y(y_)
{}
// temp - remove when geometry is templated on value_type
point(mapnik::coord<double, 2> const& c)
: x(c.x), y(c.y) {}
friend inline bool operator== (point<T> const& a, point<T> const& b)
{
return a.x == b.x && a.y == b.y;
}
friend inline bool operator!= (point<T> const& a, point <T> const& b)
{
return a.x != b.x || a.y != b.y;
}
value_type x;
value_type y;
coord_type x;
coord_type y;
};
template <typename T>
bool operator==(point<T> const& lhs, point<T> const& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
}
template <typename T>
bool operator!=(point<T> const& lhs, point<T> const& rhs)
{
return !(lhs == rhs);
}
template <typename T>
struct line_string : std::vector<point<T> >
{
using coord_type = T;
line_string() = default;
explicit line_string(std::size_t size)
: std::vector<point<T> >(size) {}
@ -71,6 +69,7 @@ struct line_string : std::vector<point<T> >
template <typename T>
struct linear_ring : line_string<T>
{
using coord_type = T;
linear_ring() = default;
explicit linear_ring(std::size_t size)
: line_string<T>(size) {}
@ -86,8 +85,9 @@ using rings_container = std::vector<linear_ring<T>>;
template <typename T, template <typename> class InteriorRings = rings_container>
struct polygon
{
linear_ring<T> exterior_ring;
using coord_type = T;
using rings_container = InteriorRings<T>;
linear_ring<T> exterior_ring;
rings_container interior_rings;
inline void set_exterior_ring(linear_ring<T> && ring)
@ -109,13 +109,22 @@ struct polygon
};
template <typename T>
struct multi_point : line_string<T> {};
struct multi_point : line_string<T>
{
using coord_type = T;
};
template <typename T>
struct multi_line_string : std::vector<line_string<T>> {};
struct multi_line_string : std::vector<line_string<T>>
{
using coord_type = T;
};
template <typename T>
struct multi_polygon : std::vector<polygon<T>> {};
struct multi_polygon : std::vector<polygon<T>>
{
using coord_type = T;
};
template <typename T>
struct geometry_collection;
@ -131,11 +140,11 @@ using geometry_base = mapnik::util::variant<geometry_empty,
multi_point<T>,
multi_line_string<T>,
multi_polygon<T>,
mapnik::util::recursive_wrapper<geometry_collection<T> > >;
geometry_collection<T> >;
template <typename T>
struct geometry : geometry_base<T>
{
using value_type = T;
using coord_type = T;
geometry()
: geometry_base<T>() {} // empty
@ -147,7 +156,10 @@ struct geometry : geometry_base<T>
};
template <typename T>
struct geometry_collection : std::vector<geometry<T>> {};
struct geometry_collection : std::vector<geometry<T>>
{
using coord_type = T;
};
}}

View file

@ -26,11 +26,11 @@
#include <mapnik/config.hpp>
#include <mapnik/box2d.hpp>
namespace mapnik {
namespace mapnik {
namespace geometry {
template <typename T>
MAPNIK_DECL mapnik::box2d<double> envelope(T const& geom);
MAPNIK_DECL auto envelope(T const& geom) -> box2d<typename T::coord_type>;
} // end ns geometry
} // end ns mapnik

View file

@ -28,23 +28,24 @@ namespace mapnik { namespace geometry {
namespace detail {
template <typename T>
struct geometry_envelope
{
using bbox_type = box2d<double>;
using coord_type = T;
using bbox_type = box2d<coord_type>;
bbox_type & bbox;
geometry_envelope(bbox_type & bbox_)
: bbox(bbox_) {}
template <typename T>
void operator() (T const& geom) const
template <typename U>
void operator() (U const& geom) const
{
return mapnik::util::apply_visitor(*this, geom);
}
void operator() (mapnik::geometry::geometry_empty const&) const {}
template <typename T>
void operator() (mapnik::geometry::point<T> const& pt) const
{
if (!bbox.valid())
@ -54,7 +55,6 @@ struct geometry_envelope
bbox.expand_to_include(pt.x, pt.y);
}
template <typename T>
void operator() (mapnik::geometry::line_string<T> const& line) const
{
bool first = true;
@ -72,13 +72,11 @@ struct geometry_envelope
}
}
template <typename T>
void operator() (mapnik::geometry::linear_ring<T> const& ring) const
{
(*this)(static_cast<mapnik::geometry::line_string<T> const&>(ring));
}
template <typename T>
void operator() (mapnik::geometry::polygon<T> const& poly) const
{
bool first = true;
@ -96,7 +94,6 @@ struct geometry_envelope
}
}
template <typename T>
void operator() (mapnik::geometry::multi_point<T> const& multi_point) const
{
bool first = true;
@ -114,7 +111,6 @@ struct geometry_envelope
}
}
template <typename T>
void operator() (mapnik::geometry::multi_line_string<T> const& multi_line) const
{
for (auto const& line : multi_line)
@ -123,7 +119,6 @@ struct geometry_envelope
}
}
template <typename T>
void operator() (mapnik::geometry::multi_polygon<T> const& multi_poly) const
{
for (auto const& poly : multi_poly)
@ -132,7 +127,6 @@ struct geometry_envelope
}
}
template <typename T>
void operator() (mapnik::geometry::geometry_collection<T> const& collection) const
{
for (auto const& geom : collection)
@ -145,10 +139,11 @@ struct geometry_envelope
} // end ns detail
template <typename T>
mapnik::box2d<double> envelope(T const& geom)
auto envelope(T const& geom) -> box2d<typename T::coord_type>
{
box2d<double> bbox;
detail::geometry_envelope op(bbox);
using coord_type = typename T::coord_type;
box2d<coord_type> bbox;
detail::geometry_envelope<coord_type> op(bbox);
op(geom);
return bbox;
}

View file

@ -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);
}

View file

@ -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>

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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)
{

View file

@ -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>

View file

@ -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>

View file

@ -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 {

View file

@ -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>

View file

@ -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
{

View file

@ -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 {

View file

@ -0,0 +1,68 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP
#define MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP
// mapnik
#include <mapnik/value.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/json/stringifier.hpp>
#include <mapnik/json/value_converters.hpp>
namespace mapnik { namespace json {
struct attribute_value_visitor
{
public:
attribute_value_visitor(mapnik::transcoder const& tr)
: tr_(tr) {}
mapnik::value operator()(std::string const& val) const
{
return mapnik::value(tr_.transcode(val.c_str()));
}
mapnik::value operator()(std::vector<mapnik::json::json_value> const& array) const
{
std::string str = stringifier()(array);
return mapnik::value(tr_.transcode(str.c_str()));
}
mapnik::value operator()(std::vector<std::pair<std::string, mapnik::json::json_value> > const& object) const
{
std::string str = stringifier()(object);
return mapnik::value(tr_.transcode(str.c_str()));
}
template <typename T>
mapnik::value operator()(T const& val) const
{
return mapnik::value(val);
}
mapnik::transcoder const& tr_;
};
}}
#endif //MAPNIK_JSON_ATTRIBUTE_VALUE_VISITOR_HPP

View file

@ -32,69 +32,31 @@
#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 {
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;
};
}}

View file

@ -29,17 +29,53 @@
#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)
;
@ -106,13 +148,10 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
json.value = json.object | json.array | json.string_ | json.number
;
json.pairs = json.key_value % lit(',')
json.key_value = json.string_ >> lit(':') >> json.value
;
json.key_value = (json.string_ >> lit(':') >> json.value)
;
json.object = lit('{') >> *json.pairs >> lit('}')
json.object = lit('{') >> json.key_value % lit(',') >> lit('}')
;
json.array = lit('[')

View file

@ -24,14 +24,10 @@
#define MAPNIK_FEATURE_GRAMMAR_HPP
// mapnik
#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/value.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/value_converters.hpp>
#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/json/attribute_value_visitor.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
@ -45,27 +41,6 @@ namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace fusion = boost::fusion;
class attribute_value_visitor
{
public:
attribute_value_visitor(mapnik::transcoder const& tr)
: tr_(tr) {}
mapnik::value operator()(std::string const& val) const
{
return mapnik::value(tr_.transcode(val.c_str()));
}
template <typename T>
mapnik::value operator()(T const& val) const
{
return mapnik::value(val);
}
mapnik::transcoder const& tr_;
};
struct put_property
{
using result_type = void;
@ -101,9 +76,6 @@ struct feature_grammar : qi::grammar<Iterator, void(FeatureType&), space_type>
qi::rule<Iterator, space_type> feature_type;
qi::rule<Iterator,void(FeatureType &),space_type> properties;
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;
qi::rule<Iterator, json_value(), space_type> attribute_value;
qi::rule<Iterator, qi::locals<std::int32_t>, std::string(), space_type> stringify_object;
qi::rule<Iterator, qi::locals<std::int32_t>, std::string(), space_type> stringify_array;
// functions
phoenix::function<put_property> put_property_;
phoenix::function<set_geometry_impl> set_geometry;

View file

@ -50,23 +50,22 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
using phoenix::construct;
// generic json types
json_.value = json_.object | json_.array | json_.string_ | json_.number
json_.value = json_.object | json_.array | json_.string_ | json_.number
;
json_.pairs = json_.key_value % lit(',')
;
json_.key_value = (json_.string_ > lit(':') > json_.value)
json_.key_value = json_.string_ > lit(':') > json_.value
;
json_.object = lit('{')
> *json_.pairs
> -(json_.key_value % lit(','))
> lit('}')
;
json_.array = lit('[')
> json_.value > *(lit(',') > json_.value)
> -(json_.value % lit(','))
> lit(']')
;
json_.number = json_.strict_double[_val = json_.double_converter(_1)]
| json_.int__[_val = json_.integer_converter(_1)]
| lit("true") [_val = true]
@ -95,24 +94,13 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
> lit(':') > ((lit('{') > -attributes(_r1) > lit('}')) | lit("null"))
;
attributes = (json_.string_ [_a = _1] > lit(':') > attribute_value [put_property_(_r1,_a,_1)]) % lit(',')
;
attribute_value %= json_.number | json_.string_ | stringify_object | stringify_array
;
stringify_object %= char_('{')[_a = 1 ] > *(eps(_a > 0) > (char_('{')[_a +=1] | char_('}')[_a -=1] | char_))
;
stringify_array %= char_('[')[_a = 1 ] > *(eps(_a > 0) > (char_('[')[_a +=1] | char_(']')[_a -=1] | char_))
attributes = (json_.string_ [_a = _1] > lit(':') > json_.value [put_property_(_r1,_a,_1)]) % lit(',')
;
feature.name("Feature");
feature_type.name("type");
properties.name("properties");
attributes.name("Attributes");
attribute_value.name("Attribute Value");
on_error<fail>(feature, error_handler(_1, _2, _3, _4));
}

View file

@ -31,15 +31,44 @@
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/std_pair.hpp>
#pragma GCC diagnostic pop
#include <vector>
namespace mapnik { namespace json {
namespace qi = boost::spirit::qi;
namespace standard = boost::spirit::standard;
namespace phoenix = boost::phoenix;
using space_type = standard::space_type;
using json_value = mapnik::util::variant<value_null,value_bool, value_integer, value_double, std::string>;
struct json_value;
using json_array = std::vector<json_value>;
using json_object_element = std::pair<std::string, json_value>;
using json_object = std::vector<json_object_element>;
using json_value_base = mapnik::util::variant<value_null,
value_bool,
value_integer,
value_double,
std::string,
mapnik::util::recursive_wrapper<json_array>,
mapnik::util::recursive_wrapper<json_object> >;
struct json_value : json_value_base
{
#ifdef _WINDOWS
json_value() = default;
template <typename T>
json_value(T && val)
: json_value_base(std::forward<T>(val)) {}
#else
// MSVC 2015 inheriting constructors is not working in this context (support is apparently planned)
using json_value_base::json_value_base;
#endif
};
using uchar = std::uint32_t; // a unicode code point
// unicode string grammar via boost/libs/spirit/example/qi/json/json/parser/grammar.hpp
@ -121,10 +150,14 @@ unicode_string<Iterator>::unicode_string()
escape =
('x' > hex) [push_utf8(_r1, _1)]
| ('u' > hex4) [push_utf8(_r1, _1)]
| ('U' > hex8) [push_utf8(_r1, _1)]
| char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)]
| eol // continue to next line
|
('u' > hex4) [push_utf8(_r1, _1)]
|
('U' > hex8) [push_utf8(_r1, _1)]
|
char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)]
|
eol // continue to next line
;
char_esc =
@ -132,7 +165,7 @@ unicode_string<Iterator>::unicode_string()
;
double_quoted =
'"'
'"'
> *(char_esc(_val) | (~char_('"')) [_val += _1])
> '"'
;
@ -141,18 +174,17 @@ unicode_string<Iterator>::unicode_string()
template <typename Iterator>
struct generic_json
{
qi::rule<Iterator,space_type> value;
qi::int_parser<mapnik::value_integer,10,1,-1> int__;
qi::rule<Iterator, json_value(), space_type> value;
qi::int_parser<mapnik::value_integer, 10, 1, -1> int__;
unicode_string<Iterator> string_;
qi::rule<Iterator,space_type> key_value;
qi::rule<Iterator,json_value(),space_type> number;
qi::rule<Iterator,space_type> object;
qi::rule<Iterator,space_type> array;
qi::rule<Iterator,space_type> pairs;
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
qi::rule<Iterator, json_object_element(), space_type> key_value;
qi::rule<Iterator, json_value(), space_type> number;
qi::rule<Iterator, json_object(), space_type> object;
qi::rule<Iterator, json_array(), space_type> array;
qi::real_parser<double, qi::strict_real_policies<double>> strict_double;
// conversions
boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_integer> > integer_converter;
boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_double> > double_converter;
boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_integer>> integer_converter;
boost::phoenix::function<mapnik::detail::value_converter<mapnik::value_double>> double_converter;
};
}}

View file

@ -32,6 +32,7 @@
#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

View file

@ -47,7 +47,6 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
qi::_a_type _a;
qi::_b_type _b;
qi::eps_type eps;
qi::omit_type omit;
using qi::fail;
using qi::on_error;
using phoenix::push_back;
@ -58,26 +57,26 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
json_.value = json_.object | json_.array | json_.string_ | json_.number
;
json_.pairs = json_.key_value % lit(',')
;
json_.key_value = (json_.string_ > lit(':') > json_.value)
json_.key_value = json_.string_ > lit(':') > json_.value
;
json_.object = lit('{')
> *json_.pairs
> -(json_.key_value % lit(','))
> lit('}')
;
json_.array = lit('[')
> json_.value > *(lit(',') > json_.value)
> -(json_.value % lit(','))
> lit(']')
;
json_.number = json_.strict_double
| json_.int__
| lit("true")
| lit ("false")
| lit("null")
;
geometry = lit('{')[_a = 0]
> (((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1])
|
@ -85,7 +84,7 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
|
(lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_val = _1] > lit(']'))
|
omit[json_.key_value]) % lit(',')) [create_geometry(_val,_a,_b)]
json_.key_value) % lit(',')) [create_geometry(_val,_a,_b)]
> lit('}')
;

View file

@ -32,7 +32,6 @@
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#pragma GCC diagnostic pop
@ -40,26 +39,6 @@ namespace mapnik { namespace json {
namespace qi = boost::spirit::qi;
struct set_position_impl
{
using result_type = void;
template <typename T0,typename T1>
result_type operator() (T0 & coords, T1 const& pos) const
{
if (pos) coords = *pos;
}
};
struct push_position_impl
{
using result_type = void;
template <typename T0, typename T1>
result_type operator() (T0 & coords, T1 const& pos) const
{
if (pos) coords.emplace_back(*pos);
}
};
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
struct positions_grammar :
qi::grammar<Iterator,coordinates(),space_type>
@ -70,8 +49,6 @@ struct positions_grammar :
qi::rule<Iterator, positions(), space_type> ring;
qi::rule<Iterator, std::vector<positions>(), space_type> rings;
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
boost::phoenix::function<set_position_impl> set_position;
boost::phoenix::function<push_position_impl> push_position;
};
}}

View file

@ -28,12 +28,33 @@
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
// stl
#include <iostream>
#include <string>
namespace mapnik { namespace json {
struct set_position_impl
{
using result_type = void;
template <typename T0,typename T1>
result_type operator() (T0 & coords, T1 const& pos) const
{
if (pos) coords = *pos;
}
};
struct push_position_impl
{
using result_type = void;
template <typename T0, typename T1>
result_type operator() (T0 & coords, T1 const& pos) const
{
if (pos) coords.emplace_back(*pos);
}
};
template <typename Iterator, typename ErrorHandler>
positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & error_handler)
: positions_grammar::base_type(coords,"coordinates")
@ -49,6 +70,9 @@ positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & erro
using qi::fail;
using qi::on_error;
boost::phoenix::function<set_position_impl> set_position;
boost::phoenix::function<push_position_impl> push_position;
coords = rings_array[_val = _1] | rings [_val = _1] | ring[_val = _1] | pos[set_position(_val,_1)]
;
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')

View file

@ -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*)>

View file

@ -0,0 +1,101 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2016 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_JSON_STRINGIFIER_HPP
#define MAPNIK_JSON_STRINGIFIER_HPP
// mapnik
#include <mapnik/json/generic_json.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/util/variant.hpp>
// stl
#include <string>
namespace mapnik { namespace json {
struct stringifier
{
std::string operator()(std::string const& val) const
{
return "\"" + val + "\"";
}
std::string operator()(value_null) const
{
return "null";
}
std::string operator()(value_bool val) const
{
return val ? "true" : "false";
}
std::string operator()(value_integer val) const
{
std::string str;
util::to_string(str, val);
return str;
}
std::string operator()(value_double val) const
{
std::string str;
util::to_string(str, val);
return str;
}
std::string operator()(std::vector<mapnik::json::json_value> const& array) const
{
std::string str = "[";
bool first = true;
for (auto const& val : array)
{
if (first) first = false;
else str += ",";
str += mapnik::util::apply_visitor(*this, val);
}
str += "]";
return str;
}
std::string operator()(std::vector<std::pair<std::string, mapnik::json::json_value>> const& object) const
{
std::string str = "{";
bool first = true;
for (auto const& kv : object)
{
if (first) first = false;
else str += ",";
str += kv.first;
str += ":";
str += mapnik::util::apply_visitor(*this, kv.second);
}
str += "}";
return str;
}
};
}}
#endif // MAPNIK_JSON_STRINGIFIER_HPP

View file

@ -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

View file

@ -42,35 +42,163 @@ namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
using space_type = mapnik::json::space_type;
struct create_point
{
using result_type = mapnik::topojson::point;
template <typename T0, typename T1>
result_type operator()(T0 & coord, T1 & props) const
{
mapnik::topojson::point pt;
if (coord.template is<mapnik::topojson::coordinate>())
{
auto const& coord_ = coord.template get<mapnik::topojson::coordinate>();
pt.coord = coord_;
pt.props = props;
}
return pt;
}
};
struct create_multi_point
{
using result_type = mapnik::topojson::multi_point;
template <typename T0, typename T1>
result_type operator()(T0 & coords, T1 & props) const
{
mapnik::topojson::multi_point mpt;
if (coords.template is<std::vector<mapnik::topojson::coordinate>>())
{
auto const& points = coords.template get<std::vector<mapnik::topojson::coordinate>>();
mpt. points = points;
mpt.props = props;
}
return mpt;
}
};
struct create_line_string
{
using result_type = mapnik::topojson::linestring;
template <typename T0, typename T1>
result_type operator()(T0 & arcs, T1 & props) const
{
mapnik::topojson::linestring line;
if (arcs.template is<std::vector<index_type>>())
{
auto const& arcs_ = arcs.template get<std::vector<index_type>>();
line.rings = arcs_;
line.props = props;
}
return line;
}
};
struct create_multi_line_string
{
using result_type = mapnik::topojson::multi_linestring;
template <typename T0, typename T1>
result_type operator()(T0 & arcs, T1 & props) const
{
mapnik::topojson::multi_linestring mline;
if (arcs.template is<std::vector<std::vector<index_type>>>())
{
auto const& arcs_ = arcs.template get<std::vector<std::vector<index_type>>>();
mline.lines = arcs_;
mline.props = props;
}
return mline;
}
};
struct create_polygon
{
using result_type = mapnik::topojson::polygon;
template <typename T0, typename T1>
result_type operator()(T0 & arcs, T1 & props) const
{
mapnik::topojson::polygon poly;
if (arcs.template is<std::vector<std::vector<index_type>>>())
{
auto const& arcs_ = arcs.template get<std::vector<std::vector<index_type>>>();
poly.rings = arcs_;
poly.props = props;
}
return poly;
}
};
struct create_multi_polygon
{
using result_type = mapnik::topojson::multi_polygon;
template <typename T0, typename T1>
result_type operator()(T0 & arcs, T1 & props) const
{
mapnik::topojson::multi_polygon mpoly;
if (arcs.template is<std::vector<std::vector<std::vector<index_type>>>>())
{
auto const& arcs_ = arcs.template get<std::vector<std::vector<std::vector<index_type>>>>();
mpoly.polygons = arcs_;
mpoly.props = props;
}
return mpoly;
}
};
struct create_geometry_impl
{
using result_type = mapnik::topojson::geometry;
template <typename T0, typename T1, typename T2, typename T3>
result_type operator()(T0 geom_type, T1 & coord, T2 & arcs, T3 & props) const
{
switch (geom_type)
{
case 1: //Point
return create_point()(coord, props);
case 2: //LineString
return create_line_string()(arcs, props);
case 3: //Polygon
return create_polygon()(arcs, props);
case 4: //MultiPoint
return create_multi_point()(coord, props);
case 5: //MultiLineString
return create_multi_line_string()(arcs, props);
case 6: //MultiPolygon
return create_multi_polygon()(arcs, props);
default:
break;
}
return mapnik::topojson::geometry(); //empty
}
};
using coordinates_type = util::variant<coordinate,std::vector<coordinate>>;
using arcs_type = util::variant<std::vector<index_type>, std::vector<std::vector<index_type>>, std::vector<std::vector<std::vector<index_type>>>>;
template <typename Iterator, typename ErrorHandler = json::error_handler<Iterator> >
struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
{
topojson_grammar();
private:
// generic JSON support
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;
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::arc>()> arcs;
qi::rule<Iterator, space_type, mapnik::topojson::arc()> arc;
qi::rule<Iterator, space_type, mapnik::topojson::coordinate()> coordinate;
qi::rule<Iterator, space_type, mapnik::topojson::coordinate()> coordinate_;
qi::rule<Iterator, space_type, coordinates_type()> coordinates;
qi::rule<Iterator, space_type, mapnik::topojson::transform()> transform;
qi::rule<Iterator, space_type, mapnik::topojson::bounding_box()> bbox;
qi::rule<Iterator, space_type, mapnik::topojson::geometry() > geometry;
qi::rule<Iterator, space_type, mapnik::topojson::point()> point;
qi::rule<Iterator, space_type, mapnik::topojson::multi_point()> multi_point;
qi::rule<Iterator, space_type, mapnik::topojson::linestring()> linestring;
qi::rule<Iterator, space_type, mapnik::topojson::multi_linestring()> multi_linestring;
qi::rule<Iterator, space_type, mapnik::topojson::polygon()> polygon;
qi::rule<Iterator, space_type, mapnik::topojson::multi_polygon()> multi_polygon;
qi::rule<Iterator, qi::locals<int, coordinates_type, arcs_type, properties>, mapnik::topojson::geometry(), space_type> geometry;
qi::rule<Iterator, space_type, void(std::vector<mapnik::topojson::geometry>&)> geometry_collection;
qi::rule<Iterator, space_type, std::vector<index_type>()> ring;
qi::rule<Iterator, space_type, std::vector<std::vector<index_type>>()> rings;
qi::rule<Iterator, space_type, arcs_type()> rings_array;
// properties
qi::rule<Iterator, space_type, mapnik::topojson::properties()> properties;
qi::rule<Iterator, space_type, mapnik::topojson::properties()> attributes;
qi::rule<Iterator, space_type, mapnik::json::json_value()> attribute_value;
// id
qi::rule<Iterator,space_type> id;
qi::rule<Iterator, space_type, mapnik::topojson::properties()> properties_;
qi::symbols<char, int> geometry_type_dispatch;
};
}}

View file

@ -57,42 +57,6 @@ BOOST_FUSION_ADAPT_STRUCT(
(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)
@ -101,6 +65,8 @@ BOOST_FUSION_ADAPT_STRUCT(
(boost::optional<mapnik::topojson::bounding_box>, bbox)
)
namespace mapnik { namespace topojson {
namespace qi = boost::spirit::qi;
@ -121,32 +87,43 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
qi::_3_type _3;
qi::_4_type _4;
qi::_r1_type _r1;
qi::_a_type _a;
qi::_b_type _b;
qi::_c_type _c;
qi::_d_type _d;
using qi::fail;
using qi::on_error;
using phoenix::push_back;
using phoenix::construct;
geometry_type_dispatch.add
("\"Point\"",1)
("\"LineString\"",2)
("\"Polygon\"",3)
("\"MultiPoint\"",4)
("\"MultiLineString\"",5)
("\"MultiPolygon\"",6)
("\"GeometryCollection\"",7)
;
// error handler
boost::phoenix::function<ErrorHandler> const error_handler;
// generic JSON support
json::generic_json<Iterator> json;
boost::phoenix::function<create_geometry_impl> const create_geometry;
// generic JSON types
json.value = json.object | json.array | json.string_ | json.number
;
json.pairs = json.key_value % lit(',')
json.key_value = json.string_ > lit(':') > json.value
;
json.key_value = (json.string_ >> lit(':') >> json.value)
;
json.object = lit('{') >> *json.pairs >> lit('}')
json.object = lit('{')
> -(json.key_value % lit(','))
> lit('}')
;
json.array = lit('[')
>> json.value >> *(lit(',') >> json.value)
>> lit(']')
> -(json.value % lit(','))
> lit(']')
;
json.number = json.strict_double[_val = json.double_converter(_1)]
@ -183,101 +160,58 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
>> lit('{')
>> -((omit[json.string_]
>> lit(':')
>> (geometry_collection(_val) | geometry)) % lit(','))
>> (geometry_collection(_val) | geometry[push_back(_val, _1)]) % lit(',')))
>> lit('}')
;
geometry =
point |
linestring |
polygon |
multi_point |
multi_linestring |
multi_polygon |
omit[json.object]
geometry = lit('{')[_a = 0]
> ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1])
|
(lit("\"coordinates\"") > lit(':') > coordinates[_b = _1])
|
(lit("\"arcs\"") > lit(':') > rings_array[_c = _1])
|
properties_[_d = _1]
|
json.key_value) % lit(',')
> lit('}')[_val = create_geometry(_a, _b, _c, _d)]
;
geometry_collection = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
>> -(lit(',') >> omit[bbox])
>> lit(',') >> lit("\"geometries\"") >> lit(':') >> lit('[') >> -(geometry[push_back(_r1, _1)] % lit(','))
>> lit(']')
>> lit('}')
;
point = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"Point\"")
>> -(lit(',') >> omit[bbox])
>> ((lit(',') >> lit("\"coordinates\"") >> lit(':') >> coordinate)
^ (lit(',') >> properties) /*^ (lit(',') >> omit[id])*/)
>> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
>> lit(',') >> lit("\"geometries\"") >> lit(':')
>> lit('[')
>> -(geometry[push_back(_r1, _1)] % lit(','))
>> lit(']')
>> lit('}')
;
multi_point = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"MultiPoint\"")
>> -(lit(',') >> omit[bbox])
>> ((lit(',') >> lit("\"coordinates\"") >> lit(':')
>> lit('[') >> -(coordinate % lit(',')) >> lit(']'))
^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
>> lit('}')
;
linestring = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"LineString\"")
>> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[') >> int_ >> lit(']'))
^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
>> lit('}')
;
multi_linestring = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"MultiLineString\"")
>> -(lit(',') >> omit[bbox])
>> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[')
>> -((lit('[') >> int_ >> lit(']')) % lit(',')) >> lit(']'))
^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
>> lit('}')
;
polygon = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"Polygon\"")
>> -(lit(',') >> omit[bbox])
>> ((lit(',') >> lit("\"arcs\"") >> lit(':')
>> lit('[') >> -(ring % lit(',')) >> lit(']'))
^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
>> lit('}')
;
multi_polygon = lit('{')
>> lit("\"type\"") >> lit(':') >> lit("\"MultiPolygon\"")
>> -(lit(',') >> omit[bbox])
>> ((lit(',') >> lit("\"arcs\"") >> lit(':')
>> lit('[')
>> -((lit('[') >> -(ring % lit(',')) >> lit(']')) % lit(','))
>> lit(']')) ^ (lit(',') >> properties) ^ (lit(',') >> omit[id]))
>> lit('}')
;
id = lit("\"id\"") >> lit(':') >> omit[json.value]
;
ring = lit('[') >> -(int_ % lit(',')) >> lit(']')
;
rings = lit('[') >> -(ring % lit(',')) >> lit(']')
;
rings_array = lit('[') >> -(rings % lit(',')) >> lit(']')
|
rings
|
ring
;
properties = lit("\"properties\"")
properties_ = lit("\"properties\"")
>> lit(':')
>> (( lit('{') >> attributes >> lit('}')) | json.object)
>> lit('{') >> (json.string_ >> lit(':') >> json.value) % lit(',') >> lit('}')
;
attributes = (json.string_ >> lit(':') >> attribute_value) % lit(',')
;
attribute_value %= json.number | json.string_ ;
arcs = lit("\"arcs\"") >> lit(':')
>> lit('[') >> -( arc % lit(',')) >> lit(']') ;
arc = lit('[') >> -(coordinate % lit(',')) >> lit(']') ;
arc = lit('[') >> -(coordinate_ % lit(',')) >> lit(']') ;
coordinate = lit('[') >> double_ >> lit(',') >> double_ >> lit(']');
coordinate_ = lit('[') > double_ > lit(',') > double_ > lit(']');
coordinates = (lit('[') >> coordinate_ % lit(',') > lit(']'))
| coordinate_;
topology.name("topology");
transform.name("transform");
@ -285,13 +219,9 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
arc.name("arc");
arcs.name("arcs");
json.value.name("value");
coordinate.name("coordinate");
point.name("point");
multi_point.name("multi_point");
linestring.name("linestring");
polygon.name("polygon");
multi_polygon.name("multi_polygon");
coordinate_.name("coordinate");
geometry.name("geometry");
properties_.name("properties");
geometry_collection.name("geometry_collection");
// error handler
on_error<fail>(topology, error_handler(_1, _2, _3, _4));

View file

@ -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
@ -25,7 +25,12 @@
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/json/topology.hpp>
#include <mapnik/json/attribute_value_visitor.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/geometry_adapters.hpp>
#include <mapnik/geometry_correct.hpp>
namespace mapnik { namespace topojson {
@ -35,6 +40,11 @@ struct bounding_box_visitor
: topo_(topo),
num_arcs_(topo_.arcs.size()) {}
box2d<double> operator() (mapnik::topojson::empty const&) const
{
return box2d<double>();
}
box2d<double> operator() (mapnik::topojson::point const& pt) const
{
double x = pt.coord.x;
@ -50,27 +60,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;
@ -79,50 +87,15 @@ struct bounding_box_visitor
box2d<double> operator() (mapnik::topojson::linestring const& line) const
{
box2d<double> bbox;
bool first = true;
if (num_arcs_ > 0)
{
index_type index = line.ring;
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
bool first = true;
double px = 0, py = 0;
auto const& arcs = topo_.arcs[arc_index];
for (auto pt : arcs.coordinates)
{
double x = pt.x;
double y = pt.y;
if (topo_.tr)
{
x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
}
if (first)
{
first = false;
bbox.init(x, y, x, y);
}
else
{
bbox.expand_to_include(x, y);
}
}
}
}
return bbox;
}
box2d<double> operator() (mapnik::topojson::multi_linestring const& multi_line) const
{
box2d<double> bbox;
if (num_arcs_ > 0)
{
bool first = true;
for (auto index : multi_line.rings)
for (auto index : line.rings)
{
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
double px = 0, py = 0;
auto const& arcs = topo_.arcs[arc_index];
for (auto pt : arcs.coordinates)
@ -150,6 +123,47 @@ struct bounding_box_visitor
return bbox;
}
box2d<double> operator() (mapnik::topojson::multi_linestring const& multi_line) const
{
box2d<double> bbox;
if (num_arcs_ > 0)
{
bool first = true;
for (auto const& line : multi_line.lines)
{
for (auto index : line)
{
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
double px = 0, py = 0;
auto const& arcs = topo_.arcs[arc_index];
for (auto pt : arcs.coordinates)
{
double x = pt.x;
double y = pt.y;
if (topo_.tr)
{
x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
}
if (first)
{
first = false;
bbox.init(x, y, x, y);
}
else
{
bbox.expand_to_include(x, y);
}
}
}
}
}
}
return bbox;
}
box2d<double> operator() (mapnik::topojson::polygon const& poly) const
{
box2d<double> bbox;
@ -243,6 +257,321 @@ private:
std::size_t num_arcs_;
};
namespace {
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(mapnik::json::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)
{
mapnik::geometry::line_string<double> line_string;
for (auto index : line.rings)
{
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
auto const& arcs = topo_.arcs[arc_index];
double px = 0, py = 0;
line_string.reserve(line_string.size() + arcs.coordinates.size());
for (auto pt : arcs.coordinates)
{
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;
for (auto const& line : multi_line.lines)
{
multi_line_string.reserve(multi_line_string.size() + line.size());
mapnik::geometry::line_string<double> line_string;
for (auto index : line)
{
index_type arc_index = index < 0 ? std::abs(index) - 1 : index;
if (arc_index >= 0 && arc_index < static_cast<int>(num_arcs_))
{
hit = true;
double px = 0, py = 0;
auto const& arcs = topo_.arcs[arc_index];
line_string.reserve(line_string.size() + arcs.coordinates.size());
for (auto pt : arcs.coordinates)
{
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});
}
linear_ring.reserve(linear_ring.size() + processed_coords.size());
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)
{
transform const& tr = *topo_.tr;
x = (px += x) * tr.scale_x + tr.translate_x;
y = (py += y) * tr.scale_y + tr.translate_y;
}
processed_coords.emplace_back(coordinate{x,y});
}
using namespace boost::adaptors;
linear_ring.reserve(linear_ring.size() + processed_coords.size());
if (reverse)
{
for (auto const& c : (processed_coords | reversed))
{
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

View file

@ -62,13 +62,13 @@ struct multi_point
struct linestring
{
index_type ring ;
std::vector<index_type> rings ;
boost::optional<properties> props;
};
struct multi_linestring
{
std::vector<index_type> rings;
std::vector<std::vector<index_type> > lines;
boost::optional<properties> props;
};
@ -84,7 +84,10 @@ struct multi_polygon
boost::optional<properties> props;
};
using geometry = util::variant<point,
struct empty {};
using geometry = util::variant<empty,
point,
linestring,
polygon,
multi_point,

View file

@ -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>

View file

@ -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>

View file

@ -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; } }

View file

@ -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>

View file

@ -37,8 +37,11 @@
#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>

View file

@ -29,9 +29,11 @@
#include <mapnik/util/math.hpp>
#include <mapnik/util/noncopyable.hpp>
// agg
#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 {

View file

@ -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>

View file

@ -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
{

View file

@ -38,7 +38,8 @@ using mapnik_lib_t = struct _mapnik_lib_t;
class PluginInfo : util::noncopyable
{
public:
using name_func = const char* (*) ();
using callable_returning_string = const char* (*) ();
using callable_returning_void = void (*) ();
PluginInfo (std::string const& filename,
std::string const& library_name);
~PluginInfo();

View file

@ -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)

View file

@ -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>

View file

@ -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 {

View file

@ -38,26 +38,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_;
}
@ -101,10 +102,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),
@ -116,13 +117,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_);
@ -147,13 +148,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_;
}
@ -187,11 +188,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_)
@ -206,7 +207,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_)
{
@ -214,8 +215,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)
{
@ -234,20 +235,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();
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();
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);
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)
@ -306,7 +306,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]);
}
}
@ -318,17 +318,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)
@ -338,7 +338,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)
{

View file

@ -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 {

View file

@ -41,12 +41,13 @@
#include <mapnik/color.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/image.hpp>
// boost
#include <boost/optional.hpp>
// boost
#include <memory>
// stl
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
#pragma GCC diagnostic pop
#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); }

View file

@ -61,7 +61,7 @@ void render_point_symbolizer(point_symbolizer const &sym,
agg::trans_affine tr;
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform, common.scale_factor_);
agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine recenter_tr = recenter * tr;

View file

@ -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 {

View file

@ -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
{

View file

@ -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

View file

@ -23,15 +23,21 @@
#ifndef MAPNIK_SPAN_IMAGE_FILTER_INCLUDED
#define MAPNIK_SPAN_IMAGE_FILTER_INCLUDED
#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"
#include <boost/optional.hpp>
#pragma GCC diagnostic pop
#include <limits>
#include <mapnik/safe_cast.hpp>
namespace mapnik
{

View file

@ -0,0 +1,26 @@
/*****************************************************************************
*
* 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_STRINGIFY
#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n)
#define MAPNIK_STRINGIFY_HELPER(n) #n
#endif

Some files were not shown because too many files have changed in this diff Show more