Compare commits
109 commits
master
...
fix-appvey
Author | SHA1 | Date | |
---|---|---|---|
|
44e8b6d51f | ||
|
ce47610677 | ||
|
e6173385ca | ||
|
09933916d6 | ||
|
185d788ea4 | ||
|
99a7fa5044 | ||
|
de533ab712 | ||
|
125cd694b8 | ||
|
5911fe6374 | ||
|
b29e56051c | ||
|
7222129e6c | ||
|
ab783cbec4 | ||
|
baf6c9f321 | ||
|
e945eb74fe | ||
|
bc9dcdc584 | ||
|
2fd1f098f5 | ||
|
318be793f9 | ||
|
adacb16a2c | ||
|
85d7f28610 | ||
|
170e20e864 | ||
|
b53db334af | ||
|
1632018a14 | ||
|
9f4a138b8b | ||
|
149d2ca0a1 | ||
|
635af3f4a3 | ||
|
9c4613f934 | ||
|
520f3fd0a0 | ||
|
15fb2debb0 | ||
|
fa549b380a | ||
|
60d891f094 | ||
|
7caa0cffd4 | ||
|
dbbf18c752 | ||
|
a1084e0c09 | ||
|
c2fd522d0f | ||
|
dfccc5f6bb | ||
|
284842a9d3 | ||
|
40753edadc | ||
|
e0db6b9a47 | ||
|
91515cad69 | ||
|
0c232313d6 | ||
|
8665fc7313 | ||
|
08822729cc | ||
|
f8e5f146ec | ||
|
07de7155f1 | ||
|
3fbe7f61a6 | ||
|
3706fcf587 | ||
|
947ac81ee4 | ||
|
163af7a40f | ||
|
55e3e14f4d | ||
|
7483f6328c | ||
|
941a7eaf69 | ||
|
489b7f2aca | ||
|
4c22e631a7 | ||
|
2845cdc121 | ||
|
0cd3bd8737 | ||
|
85da8ef128 | ||
|
7affd674fd | ||
|
1f2de83531 | ||
|
887964ae97 | ||
|
c1267ebcd5 | ||
|
2a153c0d1f | ||
|
4f3e6f4846 | ||
|
391a9f835b | ||
|
74e66bac58 | ||
|
d2d62bc95c | ||
|
8cc7060ef1 | ||
|
e35bca7381 | ||
|
6cb3bce2d7 | ||
|
17dcffaf78 | ||
|
1a268343a9 | ||
|
7578534dc8 | ||
|
adcf611fab | ||
|
8f06db6ac0 | ||
|
401aade813 | ||
|
ab206321b5 | ||
|
5db03aeb03 | ||
|
2db538c470 | ||
|
8a3a380b3b | ||
|
ff4a1c1e9b | ||
|
7ce68e2c08 | ||
|
5b1c5f83cb | ||
|
5d28a25ad3 | ||
|
c71c1bc0a8 | ||
|
63128fdba1 | ||
|
0a5495e442 | ||
|
b5c04cc132 | ||
|
cdefee3524 | ||
|
47443526a0 | ||
|
a3b4e1f575 | ||
|
283481b347 | ||
|
fdd542a3c4 | ||
|
06201e3842 | ||
|
96ce2d8b3b | ||
|
f00470dc02 | ||
|
dd5c134f01 | ||
|
7c41b835ca | ||
|
641cd6555e | ||
|
fa2d63c601 | ||
|
204d30e58d | ||
|
8dee1a9088 | ||
|
2b3fdf1bc9 | ||
|
701a459427 | ||
|
335c3e4265 | ||
|
4cd55330dd | ||
|
b2f7bea7b5 | ||
|
d5a9322a11 | ||
|
d378ddbf66 | ||
|
27a0f3562d | ||
|
4d4ea3a576 |
79 changed files with 1472 additions and 1381 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -5,7 +5,7 @@
|
||||||
[submodule "test/data-visual"]
|
[submodule "test/data-visual"]
|
||||||
path = test/data-visual
|
path = test/data-visual
|
||||||
url = https://github.com/mapnik/test-data-visual.git
|
url = https://github.com/mapnik/test-data-visual.git
|
||||||
branch = master
|
branch = 3.0.x
|
||||||
[submodule "deps/mapbox/variant"]
|
[submodule "deps/mapbox/variant"]
|
||||||
path = deps/mapbox/variant
|
path = deps/mapbox/variant
|
||||||
url = https://github.com/mapbox/variant.git
|
url = https://github.com/mapbox/variant.git
|
||||||
|
|
56
.travis.yml
56
.travis.yml
|
@ -10,8 +10,6 @@ env:
|
||||||
- CCACHE_COMPRESS=1
|
- CCACHE_COMPRESS=1
|
||||||
- HEAVY_JOBS="2"
|
- HEAVY_JOBS="2"
|
||||||
- PREFIX=/tmp/mapnik
|
- PREFIX=/tmp/mapnik
|
||||||
- secure: "D5CLP5lbyFru788iZO8RqDenY/YsHPREvr34zCEi93xMqOTxPmME/zyuEZSyjP5ZLyf8g/fxOuPYSDbOQ1QLwNDBWxB0JomWOahyimHKrMCrMcGHCjl//2W2mE+p9VwF5VLGgfy7CskGkS49Mye37FDK0ejwuq6MDI45DsH4Fkk="
|
|
||||||
- secure: "ZPHyAVL3ID5g3KEmwcnzG9z2tAQwSx526Qd3Y6tsZ3Yj+aSagVBiZQjZGKWgNX74lymtmYKnb2Md46apWLeImt6tjB3MWTu7WwWoZRnqUligz/8Nmg4Lgo7EOCkQcjN/gpA1i+cM5b+ZKDTZYOaHO6/+DAaunQzA7/p99hw/XYg="
|
|
||||||
- secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM="
|
- secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM="
|
||||||
addons:
|
addons:
|
||||||
postgresql: "9.4"
|
postgresql: "9.4"
|
||||||
|
@ -25,24 +23,32 @@ matrix:
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
compiler: ": clang"
|
compiler: ": clang"
|
||||||
env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" TRIGGER=true
|
env: JOBS=4 CXX="ccache g++-6" CC="gcc-6"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources: [ 'ubuntu-toolchain-r-test']
|
sources: [ 'ubuntu-toolchain-r-test']
|
||||||
packages: [ 'libstdc++-5-dev', 'xutils-dev']
|
packages: [ 'libstdc++-6-dev', 'g++-6', 'xutils-dev']
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: ": clang"
|
||||||
|
env: JOBS=8 CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" TRIGGER=true
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: [ 'ubuntu-toolchain-r-test']
|
||||||
|
packages: [ 'libstdc++-4.9-dev', 'xutils-dev']
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
compiler: ": clang-coverage"
|
compiler: ": clang-coverage"
|
||||||
env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8"
|
env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources: [ 'ubuntu-toolchain-r-test']
|
sources: [ 'ubuntu-toolchain-r-test']
|
||||||
packages: ['libstdc++-5-dev', 'xutils-dev' ]
|
packages: ['libstdc++-4.9-dev', 'xutils-dev' ]
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: ": clang-osx"
|
compiler: ": clang-osx"
|
||||||
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
|
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
|
||||||
osx_image: xcode7.3 # upgrades clang from 6 -> 7
|
osx_image: xcode7.3 # upgrades clang from 6 -> 7
|
||||||
env: JOBS=4 MASON_PUBLISH=true CXX="ccache clang++ -Qunused-arguments"
|
env: JOBS=4 CXX="ccache clang++ -Qunused-arguments"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
# workaround travis rvm bug
|
# workaround travis rvm bug
|
||||||
|
@ -52,18 +58,12 @@ before_install:
|
||||||
rvm get head || true
|
rvm get head || true
|
||||||
fi
|
fi
|
||||||
- source scripts/travis-common.sh
|
- source scripts/travis-common.sh
|
||||||
- export PYTHONUSERBASE=$(pwd)/mason_packages/.link
|
- export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PATH}
|
||||||
- export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PYTHONUSERBASE}/bin:${PATH}
|
|
||||||
- export COVERAGE=${COVERAGE:-false}
|
- export COVERAGE=${COVERAGE:-false}
|
||||||
- export MASON_PUBLISH=${MASON_PUBLISH:-false}
|
|
||||||
- export BENCH=${BENCH:-false}
|
- export BENCH=${BENCH:-false}
|
||||||
- if [[ ${TRAVIS_BRANCH} != 'master' ]]; then export MASON_PUBLISH=false; fi
|
|
||||||
- if [[ ${TRAVIS_PULL_REQUEST} != 'false' ]]; then export MASON_PUBLISH=false; fi
|
|
||||||
- git_submodule_update --init --depth=10
|
- git_submodule_update --init --depth=10
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- on 'linux' export PYTHONPATH=${PYTHONUSERBASE}/lib/python2.7/site-packages
|
|
||||||
- on 'osx' export PYTHONPATH=${PYTHONUSERBASE}/lib/python/site-packages
|
|
||||||
- on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres
|
- on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres
|
||||||
- on 'osx' rm -rf ${DATA_PATH}
|
- on 'osx' rm -rf ${DATA_PATH}
|
||||||
- on 'osx' initdb ${DATA_PATH} -E utf8
|
- on 'osx' initdb ${DATA_PATH} -E utf8
|
||||||
|
@ -72,16 +72,19 @@ install:
|
||||||
- on 'osx' createuser -s postgres
|
- on 'osx' createuser -s postgres
|
||||||
- psql -c 'create database template_postgis;' -U postgres
|
- psql -c 'create database template_postgis;' -U postgres
|
||||||
- psql -c 'create extension postgis;' -d template_postgis -U postgres
|
- psql -c 'create extension postgis;' -d template_postgis -U postgres
|
||||||
- enabled ${COVERAGE} pip install --user cpp-coveralls
|
- enabled ${COVERAGE} curl -S -f https://codecov.io/bash -o codecov
|
||||||
|
- enabled ${COVERAGE} chmod +x codecov
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- source bootstrap.sh
|
- source bootstrap.sh
|
||||||
- |
|
- |
|
||||||
if [[ $(uname -s) == 'Linux' ]]; then
|
if [[ $(uname -s) == 'Linux' ]]; then
|
||||||
mason install clang 3.8.0
|
mason install clang++ 3.9.1
|
||||||
export PATH=$(mason prefix clang 3.8.0)/bin:${PATH}
|
export PATH=$(mason prefix clang++ 3.9.1)/bin:${PATH}
|
||||||
which clang++
|
mason install llvm-cov 3.9.1
|
||||||
export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov"
|
export PATH=$(mason prefix llvm-cov 3.9.1)/bin:${PATH}
|
||||||
|
which llvm-cov
|
||||||
|
export LLVM_COV="$(mason prefix llvm-cov 3.9.1)/bin/llvm-cov"
|
||||||
fi
|
fi
|
||||||
- ccache --version
|
- ccache --version
|
||||||
- ccache -p || true
|
- ccache -p || true
|
||||||
|
@ -98,14 +101,9 @@ script:
|
||||||
# (and might work) for the next build
|
# (and might work) for the next build
|
||||||
- DURATION=2400
|
- DURATION=2400
|
||||||
- scripts/travis-command-wrapper.py -s "date" -i 120 --deadline=$(( $(date +%s) + ${DURATION} )) make
|
- scripts/travis-command-wrapper.py -s "date" -i 120 --deadline=$(( $(date +%s) + ${DURATION} )) make
|
||||||
- make test
|
- RESULT=0
|
||||||
|
- make test || RESULT=$?
|
||||||
|
# we allow visual failures with g++ for now: https://github.com/mapnik/mapnik/issues/3567
|
||||||
|
- if [[ ${RESULT} != 0 ]] && [[ ${CXX} =~ 'clang++' ]]; then false; fi;
|
||||||
- enabled ${COVERAGE} coverage
|
- enabled ${COVERAGE} coverage
|
||||||
- enabled ${BENCH} make bench
|
- 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 publish;
|
|
||||||
fi
|
|
30
CHANGELOG.md
30
CHANGELOG.md
|
@ -6,6 +6,36 @@ Developers: Please commit along with changes.
|
||||||
|
|
||||||
For a complete change history, see the git log.
|
For a complete change history, see the git log.
|
||||||
|
|
||||||
|
## 3.0.x
|
||||||
|
|
||||||
|
#### Summary
|
||||||
|
|
||||||
|
- Fixed problems with high levels of overzooming in the GDAL and raster plugin where data would be slightly offset
|
||||||
|
- High levels of overzooming on raster data no longer results in the return of a transparent image.
|
||||||
|
|
||||||
|
## 3.0.13
|
||||||
|
|
||||||
|
Released: February 8, 2017
|
||||||
|
|
||||||
|
(Packaged from 2a153c0)
|
||||||
|
|
||||||
|
#### Summary
|
||||||
|
|
||||||
|
- Unbundle `unifont` font from distribution
|
||||||
|
- GeoJSON: improved parsing grammar avoiding temp synthesised attribute (#3507)
|
||||||
|
- GeoJSON: expose `num_features_to_query` datasource parameter + unit test (#3515)
|
||||||
|
- Fixed intersecting extents in different projections (PR #3525 )
|
||||||
|
- Fixed `blur` implementation by taking into account `scale_factor`
|
||||||
|
- postgis.input - use 2D box for pgraster bounding box (PR #3551)
|
||||||
|
- Fixed GroupSymbolizer PairLayout with 3+ items (#3526)
|
||||||
|
- Simplified `hash` implementation (204d30e58d3553278ab6bcda2d4122b0f13f6392)
|
||||||
|
- Simplified `mapnik::value` conversion rules (#3570)
|
||||||
|
- Changed `render_thunk_list` to `std::list<render_thunk>` (PR #3585)
|
||||||
|
- Upgraded to variant `v1.1.5`
|
||||||
|
- CSV.input - fixed `blank` line test (8a3a380b3b5c64681f2478b4f0d06f6a907f5eed)
|
||||||
|
- GeoJSON - handle empty elements in position grammar (ref #3609)
|
||||||
|
- mapnik-index - return failure on invalid bounding box (ref #3611)
|
||||||
|
|
||||||
## 3.0.12
|
## 3.0.12
|
||||||
|
|
||||||
Released: September 8, 2016
|
Released: September 8, 2016
|
||||||
|
|
|
@ -11,14 +11,6 @@ os: Visual Studio 2015
|
||||||
# limit clone to latest 5 commits
|
# limit clone to latest 5 commits
|
||||||
clone_depth: 5
|
clone_depth: 5
|
||||||
|
|
||||||
services:
|
|
||||||
- postgresql94 #if changing this, also change PATH below
|
|
||||||
|
|
||||||
install:
|
|
||||||
- SET PGUSER=postgres
|
|
||||||
- SET PGPASSWORD=Password12!
|
|
||||||
- SET PATH=C:\Program Files\PostgreSQL\9.4\bin\;%PATH%
|
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- scripts\build-appveyor.bat
|
- scripts\build-appveyor.bat
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<!DOCTYPE Map[]>
|
<!DOCTYPE Map[]>
|
||||||
<Map
|
<Map
|
||||||
srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"
|
srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"
|
||||||
font-directory="../../fonts/dejavu-fonts-ttf-2.35/ttf/DejaVuSans.ttf"
|
font-directory="../../fonts/dejavu-fonts-ttf-2.37/ttf/DejaVuSans.ttf"
|
||||||
background-color="#dfd8c9">
|
background-color="#dfd8c9">
|
||||||
|
|
||||||
<Style name="marking" filter-mode="first">
|
<Style name="marking" filter-mode="first">
|
||||||
|
|
63
bootstrap.sh
63
bootstrap.sh
|
@ -11,7 +11,7 @@ todo
|
||||||
- shrink icu data
|
- shrink icu data
|
||||||
'
|
'
|
||||||
|
|
||||||
MASON_VERSION="new-pkgs"
|
MASON_VERSION="v0.11.1"
|
||||||
|
|
||||||
function setup_mason() {
|
function setup_mason() {
|
||||||
if [[ ! -d ./.mason ]]; then
|
if [[ ! -d ./.mason ]]; then
|
||||||
|
@ -19,7 +19,7 @@ function setup_mason() {
|
||||||
(cd ./.mason && git checkout ${MASON_VERSION})
|
(cd ./.mason && git checkout ${MASON_VERSION})
|
||||||
else
|
else
|
||||||
echo "Updating to latest mason"
|
echo "Updating to latest mason"
|
||||||
(cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull)
|
(cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull origin ${MASON_VERSION})
|
||||||
fi
|
fi
|
||||||
export PATH=$(pwd)/.mason:$PATH
|
export PATH=$(pwd)/.mason:$PATH
|
||||||
export CXX=${CXX:-clang++}
|
export CXX=${CXX:-clang++}
|
||||||
|
@ -44,45 +44,37 @@ function install() {
|
||||||
mason link $1 $2
|
mason link $1 $2
|
||||||
}
|
}
|
||||||
|
|
||||||
ICU_VERSION="55.1"
|
ICU_VERSION="57.1"
|
||||||
|
|
||||||
function install_mason_deps() {
|
function install_mason_deps() {
|
||||||
FAIL=0
|
install ccache 3.3.1
|
||||||
install ccache 3.3.0 &
|
install zlib 1.2.8
|
||||||
install zlib system &
|
install jpeg_turbo 1.5.1 libjpeg
|
||||||
install jpeg_turbo 1.5.0 libjpeg &
|
install libpng 1.6.28 libpng
|
||||||
install libpng 1.6.24 libpng &
|
install libtiff 4.0.7 libtiff
|
||||||
install libtiff 4.0.6 libtiff &
|
install libpq 9.6.2
|
||||||
install libpq 9.5.2 &
|
install sqlite 3.17.0 libsqlite3
|
||||||
install sqlite 3.14.1 libsqlite3 &
|
install expat 2.2.0 libexpat
|
||||||
install expat 2.2.0 libexpat &
|
install icu ${ICU_VERSION}
|
||||||
install icu ${ICU_VERSION} &
|
install proj 4.9.3 libproj
|
||||||
install proj 4.9.2 libproj &
|
install pixman 0.34.0 libpixman-1
|
||||||
install pixman 0.34.0 libpixman-1 &
|
install cairo 1.14.8 libcairo
|
||||||
install cairo 1.14.6 libcairo &
|
install protobuf 3.2.0
|
||||||
install protobuf 2.6.1 &
|
|
||||||
# technically protobuf is not a mapnik core dep, but installing
|
# technically protobuf is not a mapnik core dep, but installing
|
||||||
# here by default helps make mapnik-vector-tile builds easier
|
# here by default helps make mapnik-vector-tile builds easier
|
||||||
install webp 0.5.1 libwebp &
|
install webp 0.6.0 libwebp
|
||||||
install gdal 2.1.1 libgdal &
|
install libgdal 2.1.3 libgdal
|
||||||
install boost 1.61.0 &
|
install boost 1.63.0
|
||||||
install boost_libsystem 1.61.0 &
|
install boost_libsystem 1.63.0
|
||||||
install boost_libfilesystem 1.61.0 &
|
install boost_libfilesystem 1.63.0
|
||||||
install boost_libprogram_options 1.61.0 &
|
install boost_libprogram_options 1.63.0
|
||||||
install boost_libregex_icu 1.61.0 &
|
install boost_libregex_icu57 1.63.0
|
||||||
# technically boost thread and python are not a core dep, but installing
|
# technically boost thread and python are not a core dep, but installing
|
||||||
# here by default helps make python-mapnik builds easier
|
# here by default helps make python-mapnik builds easier
|
||||||
install boost_libthread 1.61.0 &
|
install boost_libthread 1.63.0
|
||||||
install boost_libpython 1.61.0 &
|
install boost_libpython 1.63.0
|
||||||
install freetype 2.6.5 libfreetype &
|
install freetype 2.7.1 libfreetype
|
||||||
install harfbuzz 1.3.0 libharfbuzz &
|
install harfbuzz 1.4.4-ft libharfbuzz
|
||||||
for job in $(jobs -p)
|
|
||||||
do
|
|
||||||
wait $job || let "FAIL+=1"
|
|
||||||
done
|
|
||||||
if [[ "$FAIL" != "0" ]]; then
|
|
||||||
exit ${FAIL}
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MASON_LINKED_ABS=$(pwd)/mason_packages/.link
|
MASON_LINKED_ABS=$(pwd)/mason_packages/.link
|
||||||
|
@ -95,6 +87,7 @@ function make_config() {
|
||||||
echo "
|
echo "
|
||||||
CXX = '$CXX'
|
CXX = '$CXX'
|
||||||
CC = '$CC'
|
CC = '$CC'
|
||||||
|
CUSTOM_CXXFLAGS = '-D_GLIBCXX_USE_CXX11_ABI=0'
|
||||||
RUNTIME_LINK = 'static'
|
RUNTIME_LINK = 'static'
|
||||||
INPUT_PLUGINS = 'all'
|
INPUT_PLUGINS = 'all'
|
||||||
PATH = '${MASON_LINKED_REL}/bin'
|
PATH = '${MASON_LINKED_REL}/bin'
|
||||||
|
|
12
circle.yml
12
circle.yml
|
@ -7,11 +7,7 @@ machine:
|
||||||
JOBS: 8
|
JOBS: 8
|
||||||
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
CCACHE_TEMPDIR: /tmp/.ccache-temp
|
||||||
CCACHE_COMPRESS: 1
|
CCACHE_COMPRESS: 1
|
||||||
LLVM_VERSION: 3.8
|
LLVM_VERSION: 3.9.1
|
||||||
pre:
|
|
||||||
- echo "here"
|
|
||||||
post:
|
|
||||||
- echo "there"
|
|
||||||
|
|
||||||
checkout:
|
checkout:
|
||||||
post:
|
post:
|
||||||
|
@ -32,9 +28,9 @@ dependencies:
|
||||||
database:
|
database:
|
||||||
pre:
|
pre:
|
||||||
- ./bootstrap.sh
|
- ./bootstrap.sh
|
||||||
- ./.mason/mason install clang ${LLVM_VERSION}.0
|
- ./.mason/mason install clang++ ${LLVM_VERSION}
|
||||||
- ./.mason/mason link clang ${LLVM_VERSION}.0
|
- ./.mason/mason link clang++ ${LLVM_VERSION}
|
||||||
- ./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"
|
- ./configure CC="$(pwd)/mason_packages/.link/bin/clang" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++ -Qunused-arguments"
|
||||||
- make
|
- make
|
||||||
override:
|
override:
|
||||||
- psql -c 'create database template_postgis;'
|
- psql -c 'create database template_postgis;'
|
||||||
|
|
10
codecov.yml
Normal file
10
codecov.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
ignore:
|
||||||
|
- "mason_packages"
|
||||||
|
- "benchmark"
|
||||||
|
- "deps"
|
||||||
|
- ".sconf_temp"
|
||||||
|
- "scons"
|
||||||
|
- "test"
|
||||||
|
- "demo"
|
||||||
|
- "docs"
|
||||||
|
- "fonts"
|
|
@ -1,7 +1,6 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
# Mapnik viewer - Copyright (C) 2007 Artem Pavlenko
|
# Mapnik viewer - Copyright (C) 2007 Artem Pavlenko
|
||||||
######################################################################
|
######################################################################
|
||||||
QMAKE_MAC_SDK = macosx10.11
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += core gui widgets
|
QT += core gui widgets
|
||||||
QMAKE_CXX = $$system(mapnik-config --cxx)
|
QMAKE_CXX = $$system(mapnik-config --cxx)
|
||||||
|
|
2
deps/mapbox/variant
vendored
2
deps/mapbox/variant
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 9a115c5eb3c09509c70a57b25b283b6e1cbba919
|
Subproject commit d2588a8f1d6b5d480d228e6d8a906ce634bdea9a
|
|
@ -116,6 +116,7 @@ public:
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
void move(T x, T y);
|
void move(T x, T y);
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
|
T area() const;
|
||||||
|
|
||||||
// define some operators
|
// define some operators
|
||||||
box2d_type& operator+=(box2d_type const& other);
|
box2d_type& operator+=(box2d_type const& other);
|
||||||
|
|
|
@ -393,6 +393,11 @@ std::string box2d<T>::to_string() const
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T box2d<T>::area() const
|
||||||
|
{
|
||||||
|
return width() * height();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
box2d<T>& box2d<T>::operator+=(box2d<T> const& other)
|
box2d<T>& box2d<T>::operator+=(box2d<T> const& other)
|
||||||
|
@ -466,7 +471,7 @@ T box2d<T>::operator[] (int index) const
|
||||||
case -1:
|
case -1:
|
||||||
return maxy_;
|
return maxy_;
|
||||||
default:
|
default:
|
||||||
throw std::out_of_range("index out of range, max value is 3, min value is -4 ");
|
throw std::out_of_range(std::string("index out of range, max value is 3, min value is -4 "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,8 @@ public:
|
||||||
config_error(std::string const& what,
|
config_error(std::string const& what,
|
||||||
unsigned line_number,
|
unsigned line_number,
|
||||||
std::string const& filename);
|
std::string const& filename);
|
||||||
virtual ~config_error() throw() {}
|
virtual ~config_error() {}
|
||||||
|
virtual const char * what() const noexcept;
|
||||||
virtual const char * what() const throw();
|
|
||||||
|
|
||||||
void append_context(std::string const& ctx) const;
|
void append_context(std::string const& ctx) const;
|
||||||
void append_context(std::string const& ctx, xml_node const& node) const;
|
void append_context(std::string const& ctx, xml_node const& node) const;
|
||||||
void append_context(xml_node const& node) const;
|
void append_context(xml_node const& node) const;
|
||||||
|
|
43
include/mapnik/cxx11_support.hpp
Normal file
43
include/mapnik/cxx11_support.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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_CXX11_SUPPORT_HPP
|
||||||
|
#define MAPNIK_CXX11_SUPPORT_HPP
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <bool B, typename T, typename F>
|
||||||
|
using conditional_t = typename std::conditional<B, T, F>::type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using decay_t = typename std::decay<T>::type;
|
||||||
|
|
||||||
|
template <bool B, typename T = void>
|
||||||
|
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace mapnik
|
||||||
|
|
||||||
|
#endif // MAPNIK_CXX11_SUPPORT_HPP
|
|
@ -46,14 +46,11 @@ class MAPNIK_DECL datasource_exception : public std::exception
|
||||||
public:
|
public:
|
||||||
datasource_exception(std::string const& message)
|
datasource_exception(std::string const& message)
|
||||||
: message_(message)
|
: message_(message)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
~datasource_exception() throw()
|
~datasource_exception() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
virtual const char* what() const noexcept
|
||||||
{
|
{
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <mapnik/debug.hpp>
|
#include <mapnik/debug.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <bitset>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -45,9 +44,9 @@ public:
|
||||||
what_( _what )
|
what_( _what )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~illegal_enum_value() throw() {}
|
virtual ~illegal_enum_value() {}
|
||||||
|
|
||||||
virtual const char * what() const throw()
|
virtual const char * what() const noexcept
|
||||||
{
|
{
|
||||||
return what_.c_str();
|
return what_.c_str();
|
||||||
}
|
}
|
||||||
|
@ -190,6 +189,8 @@ public:
|
||||||
for (unsigned i = 0; i < THE_MAX; ++i)
|
for (unsigned i = 0; i < THE_MAX; ++i)
|
||||||
{
|
{
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||||
|
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||||
if (str_copy == our_strings_[i])
|
if (str_copy == our_strings_[i])
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
@ -203,6 +204,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||||
|
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||||
throw illegal_enum_value(std::string("Illegal enumeration value '") +
|
throw illegal_enum_value(std::string("Illegal enumeration value '") +
|
||||||
str + "' for enum " + our_name_);
|
str + "' for enum " + our_name_);
|
||||||
|
@ -213,6 +216,8 @@ public:
|
||||||
std::string as_string() const
|
std::string as_string() const
|
||||||
{
|
{
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||||
|
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||||
return our_strings_[value_];
|
return our_strings_[value_];
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
void get_control_points(double &x1, double &y1, double &x2, double &y2) const;
|
void get_control_points(double &x1, double &y1, double &x2, double &y2) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void swap(gradient& other) throw();
|
void swap(gradient& other) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,16 +68,6 @@ public:
|
||||||
box_elements_.push_back(box_element(box, repeat_key));
|
box_elements_.push_back(box_element(box, repeat_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear_box_elements()
|
|
||||||
{
|
|
||||||
box_elements_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline text_symbolizer_properties const& get_properties() const
|
|
||||||
{
|
|
||||||
return info_ptr_->properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_position_list const& get();
|
pixel_position_list const& get();
|
||||||
|
|
||||||
// Iterate over the given path, placing line-following labels or point labels with respect to label_spacing.
|
// Iterate over the given path, placing line-following labels or point labels with respect to label_spacing.
|
||||||
|
|
|
@ -50,9 +50,9 @@ public:
|
||||||
image_reader_exception(std::string const& message)
|
image_reader_exception(std::string const& message)
|
||||||
: message_(message) {}
|
: message_(message) {}
|
||||||
|
|
||||||
~image_reader_exception() throw() {}
|
~image_reader_exception() {}
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
virtual const char* what() const noexcept
|
||||||
{
|
{
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,9 @@ public:
|
||||||
image_writer_exception(std::string const& message)
|
image_writer_exception(std::string const& message)
|
||||||
: message_(message) {}
|
: message_(message) {}
|
||||||
|
|
||||||
~image_writer_exception() throw() {}
|
~image_writer_exception(){}
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
virtual const char* what() const noexcept
|
||||||
{
|
{
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct extract_bounding_box_grammar :
|
||||||
qi::rule<Iterator, qi::locals<Iterator>, void(boxes_type&), space_type> features;
|
qi::rule<Iterator, qi::locals<Iterator>, void(boxes_type&), space_type> features;
|
||||||
qi::rule<Iterator, qi::locals<int, box_type>, void(boxes_type&, Iterator const&), space_type> feature;
|
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, qi::locals<box_type>, box_type(), space_type> coords;
|
||||||
qi::rule<Iterator, boost::optional<position_type>(), space_type> pos;
|
qi::rule<Iterator, position_type(), space_type> pos;
|
||||||
qi::rule<Iterator, void(box_type&), space_type> ring;
|
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;
|
||||||
qi::rule<Iterator, void(box_type&), space_type> rings_array;
|
qi::rule<Iterator, void(box_type&), space_type> rings_array;
|
||||||
|
|
|
@ -42,18 +42,15 @@ struct calculate_bounding_box_impl
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
result_type operator() (T0 & bbox, T1 const& pos) const
|
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())
|
||||||
{
|
{
|
||||||
typename T0::value_type x = pos->x;
|
bbox.init(x, y);
|
||||||
typename T0::value_type y = pos->y;
|
}
|
||||||
if (!bbox.valid())
|
else
|
||||||
{
|
{
|
||||||
bbox.init(x, y);
|
bbox.expand_to_include(x, y);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bbox.expand_to_include(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -64,10 +61,10 @@ struct push_box_impl
|
||||||
template <typename T0, typename T1, typename T2, typename T3>
|
template <typename T0, typename T1, typename T2, typename T3>
|
||||||
void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
|
void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
|
||||||
{
|
{
|
||||||
if (box.valid()) boxes.emplace_back(box,
|
boxes.emplace_back(box,
|
||||||
std::make_pair(std::distance(begin,
|
std::make_pair(std::distance(begin,
|
||||||
range.begin()),
|
range.begin()),
|
||||||
std::distance(range.begin(), range.end())));
|
std::distance(range.begin(), range.end())));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,16 +129,16 @@ extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_bo
|
||||||
>> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
|
>> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
|
||||||
;
|
;
|
||||||
|
|
||||||
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
|
pos = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']')
|
ring = lit('[') >> -(pos[calculate_bounding_box(_r1,_1)] % lit(',')) >> lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
rings = lit('[') >> ring(_r1) % lit(',') > lit(']')
|
rings = lit('[') >> (ring(_r1) % lit(',') > lit(']'))
|
||||||
;
|
;
|
||||||
|
|
||||||
rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']')
|
rings_array = lit('[') >> (rings(_r1) % lit(',') > lit(']'))
|
||||||
;
|
;
|
||||||
|
|
||||||
coords.name("Coordinates");
|
coords.name("Coordinates");
|
||||||
|
|
|
@ -56,26 +56,24 @@ geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar
|
||||||
;
|
;
|
||||||
|
|
||||||
geometry_dispatch = eps[_a = geometry_type(_val)] <<
|
geometry_dispatch = eps[_a = geometry_type(_val)] <<
|
||||||
(&uint_(geometry::geometry_types::Point)[_1 = _a]
|
(&uint_(geometry::geometry_types::Point)[_1 = _a] << point)
|
||||||
<< (point | lit("null")))
|
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::LineString)[_1 = _a]
|
(&uint_(geometry::geometry_types::LineString)[_1 = _a]
|
||||||
<< (linestring | lit("null")))
|
<< (linestring | "{\"type\":\"LineString\",\"coordinates\":[]}"))
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::Polygon)[_1 = _a]
|
(&uint_(geometry::geometry_types::Polygon)[_1 = _a]
|
||||||
<< (polygon | lit("null")))
|
<< (polygon | "{\"type\":\"Polygon\",\"coordinates\":[[]]}"))
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::MultiPoint)[_1 = _a]
|
(&uint_(geometry::geometry_types::MultiPoint)[_1 = _a]
|
||||||
<< (multi_point | lit("null")))
|
<< (multi_point | "{\"type\":\"MultiPoint\",\"coordinates\":[]}"))
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::MultiLineString)[_1 = _a]
|
(&uint_(geometry::geometry_types::MultiLineString)[_1 = _a]
|
||||||
<< (multi_linestring | lit("null")))
|
<< (multi_linestring | "{\"type\":\"MultiLineString\",\"coordinates\":[[]]}"))
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a]
|
(&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a]
|
||||||
<< (multi_polygon | lit("null")))
|
<< (multi_polygon | "{\"type\":\"MultiPolygon\",\"coordinates\":[[[]]]}"))
|
||||||
|
|
|
|
||||||
(&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a]
|
(&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a] << geometry_collection)
|
||||||
<< (geometry_collection | lit("null")))
|
|
||||||
|
|
|
|
||||||
lit("null")
|
lit("null")
|
||||||
;
|
;
|
||||||
|
@ -96,7 +94,7 @@ geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar
|
||||||
;
|
;
|
||||||
point_coord = lit('[') << coordinate << lit(',') << coordinate << lit(']')
|
point_coord = lit('[') << coordinate << lit(',') << coordinate << lit(']')
|
||||||
;
|
;
|
||||||
linestring_coord = point_coord % lit(',')
|
linestring_coord = (point_coord % lit(','))
|
||||||
;
|
;
|
||||||
polygon_coord = lit('[') << exterior_ring_coord << lit(']') << interior_ring_coord
|
polygon_coord = lit('[') << exterior_ring_coord << lit(']') << interior_ring_coord
|
||||||
;
|
;
|
||||||
|
|
|
@ -43,7 +43,10 @@ struct create_point
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,21 +58,21 @@ struct create_linestring
|
||||||
|
|
||||||
void operator() (positions const& ring) const
|
void operator() (positions const& ring) const
|
||||||
{
|
{
|
||||||
|
mapnik::geometry::line_string<double> line;
|
||||||
std::size_t size = ring.size();
|
std::size_t size = ring.size();
|
||||||
if (size > 1)
|
line.reserve(size);
|
||||||
|
for (auto && pt : ring)
|
||||||
{
|
{
|
||||||
mapnik::geometry::line_string<double> line;
|
line.emplace_back(std::move(pt));
|
||||||
line.reserve(size);
|
|
||||||
for (auto && pt : ring)
|
|
||||||
{
|
|
||||||
line.emplace_back(std::move(pt));
|
|
||||||
}
|
|
||||||
geom_ = std::move(line);
|
|
||||||
}
|
}
|
||||||
|
geom_ = std::move(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
@ -106,7 +109,10 @@ struct create_polygon
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
@ -130,7 +136,10 @@ struct create_multipoint
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
@ -160,7 +169,10 @@ struct create_multilinestring
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
@ -201,7 +213,10 @@ struct create_multipolygon
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
void operator()(T const&) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
Geometry & geom_;
|
Geometry & geom_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct positions_grammar :
|
||||||
{
|
{
|
||||||
positions_grammar(ErrorHandler & error_handler);
|
positions_grammar(ErrorHandler & error_handler);
|
||||||
qi::rule<Iterator, coordinates(),space_type> coords;
|
qi::rule<Iterator, coordinates(),space_type> coords;
|
||||||
qi::rule<Iterator, boost::optional<position>(), space_type> pos;
|
qi::rule<Iterator, position(), space_type> pos;
|
||||||
qi::rule<Iterator, positions(), space_type> ring;
|
qi::rule<Iterator, positions(), space_type> ring;
|
||||||
qi::rule<Iterator, std::vector<positions>(), space_type> rings;
|
qi::rule<Iterator, std::vector<positions>(), space_type> rings;
|
||||||
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
|
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct set_position_impl
|
||||||
template <typename T0,typename T1>
|
template <typename T0,typename T1>
|
||||||
result_type operator() (T0 & coords, T1 const& pos) const
|
result_type operator() (T0 & coords, T1 const& pos) const
|
||||||
{
|
{
|
||||||
if (pos) coords = *pos;
|
coords = pos;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ struct push_position_impl
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
result_type operator() (T0 & coords, T1 const& pos) const
|
result_type operator() (T0 & coords, T1 const& pos) const
|
||||||
{
|
{
|
||||||
if (pos) coords.emplace_back(*pos);
|
coords.emplace_back(pos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,13 +75,13 @@ positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & erro
|
||||||
|
|
||||||
coords = rings_array[_val = _1] | rings [_val = _1] | ring[_val = _1] | pos[set_position(_val,_1)]
|
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(']')
|
pos = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']')
|
||||||
;
|
;
|
||||||
ring = lit('[') >> pos[push_position(_val,_1)] % lit(',') > lit(']')
|
ring = lit('[') >> -(pos[push_position(_val,_1)] % lit(',')) >> lit(']')
|
||||||
;
|
;
|
||||||
rings = lit('[') >> ring % lit(',') > lit(']')
|
rings = lit('[') >> (ring % lit(',') > lit(']'))
|
||||||
;
|
;
|
||||||
rings_array = lit('[') >> rings % lit(',') > lit(']')
|
rings_array = lit('[') >> (rings % lit(',') > lit(']'))
|
||||||
;
|
;
|
||||||
coords.name("Coordinates");
|
coords.name("Coordinates");
|
||||||
pos.name("Position");
|
pos.name("Position");
|
||||||
|
|
|
@ -77,18 +77,18 @@ struct offset_converter
|
||||||
return threshold_;
|
return threshold_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_offset(double value)
|
void set_offset(double val)
|
||||||
{
|
{
|
||||||
if (offset_ != value)
|
if (offset_ != val)
|
||||||
{
|
{
|
||||||
offset_ = value;
|
offset_ = val;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_threshold(double value)
|
void set_threshold(double val)
|
||||||
{
|
{
|
||||||
threshold_ = value;
|
threshold_ = val;
|
||||||
// no need to reset(), since threshold doesn't affect
|
// no need to reset(), since threshold doesn't affect
|
||||||
// offset vertices' computation, it only controls how
|
// offset vertices' computation, it only controls how
|
||||||
// far will we be looking for self-intersections
|
// far will we be looking for self-intersections
|
||||||
|
|
|
@ -40,15 +40,27 @@ class raster : private util::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
box2d<double> ext_;
|
box2d<double> ext_;
|
||||||
|
box2d<double> query_ext_;
|
||||||
image_any data_;
|
image_any data_;
|
||||||
double filter_factor_;
|
double filter_factor_;
|
||||||
boost::optional<double> nodata_;
|
boost::optional<double> nodata_;
|
||||||
|
|
||||||
|
template <typename ImageData>
|
||||||
|
raster(box2d<double> const& ext,
|
||||||
|
box2d<double> const& query_ext,
|
||||||
|
ImageData && data,
|
||||||
|
double filter_factor)
|
||||||
|
: ext_(ext),
|
||||||
|
query_ext_(query_ext),
|
||||||
|
data_(std::move(data)),
|
||||||
|
filter_factor_(filter_factor) {}
|
||||||
|
|
||||||
template <typename ImageData>
|
template <typename ImageData>
|
||||||
raster(box2d<double> const& ext,
|
raster(box2d<double> const& ext,
|
||||||
ImageData && data,
|
ImageData && data,
|
||||||
double filter_factor)
|
double filter_factor)
|
||||||
: ext_(ext),
|
: ext_(ext),
|
||||||
|
query_ext_(ext),
|
||||||
data_(std::move(data)),
|
data_(std::move(data)),
|
||||||
filter_factor_(filter_factor) {}
|
filter_factor_(filter_factor) {}
|
||||||
|
|
||||||
|
@ -71,7 +83,6 @@ public:
|
||||||
{
|
{
|
||||||
filter_factor_ = factor;
|
filter_factor_ = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct image_dispatcher
|
||||||
image_dispatcher(int start_x, int start_y,
|
image_dispatcher(int start_x, int start_y,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
double scale_x, double scale_y,
|
double scale_x, double scale_y,
|
||||||
|
double offset_x, double offset_y,
|
||||||
scaling_method_e method, double filter_factor,
|
scaling_method_e method, double filter_factor,
|
||||||
double opacity, composite_mode_e comp_op,
|
double opacity, composite_mode_e comp_op,
|
||||||
raster_symbolizer const& sym, feature_impl const& feature,
|
raster_symbolizer const& sym, feature_impl const& feature,
|
||||||
|
@ -63,15 +64,17 @@ struct image_dispatcher
|
||||||
height_(height),
|
height_(height),
|
||||||
scale_x_(scale_x),
|
scale_x_(scale_x),
|
||||||
scale_y_(scale_y),
|
scale_y_(scale_y),
|
||||||
|
offset_x_(offset_x),
|
||||||
|
offset_y_(offset_y),
|
||||||
method_(method),
|
method_(method),
|
||||||
filter_factor_(filter_factor),
|
filter_factor_(filter_factor),
|
||||||
opacity_(opacity),
|
opacity_(opacity),
|
||||||
comp_op_(comp_op),
|
comp_op_(comp_op),
|
||||||
sym_(sym),
|
sym_(sym),
|
||||||
feature_(feature),
|
feature_(feature),
|
||||||
composite_(composite),
|
composite_(composite),
|
||||||
nodata_(nodata),
|
nodata_(nodata),
|
||||||
need_scaling_(need_scaling) {}
|
need_scaling_(need_scaling) {}
|
||||||
|
|
||||||
void operator() (image_null const&) const {} //no-op
|
void operator() (image_null const&) const {} //no-op
|
||||||
void operator() (image_rgba8 const& data_in) const
|
void operator() (image_rgba8 const& data_in) const
|
||||||
|
@ -79,7 +82,7 @@ struct image_dispatcher
|
||||||
if (need_scaling_)
|
if (need_scaling_)
|
||||||
{
|
{
|
||||||
image_rgba8 data_out(width_, height_, true, true);
|
image_rgba8 data_out(width_, height_, true, true);
|
||||||
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, 0.0, 0.0, filter_factor_, nodata_);
|
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, offset_x_, offset_y_, filter_factor_, nodata_);
|
||||||
composite_(data_out, comp_op_, opacity_, start_x_, start_y_);
|
composite_(data_out, comp_op_, opacity_, start_x_, start_y_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -97,7 +100,7 @@ struct image_dispatcher
|
||||||
if (need_scaling_)
|
if (need_scaling_)
|
||||||
{
|
{
|
||||||
image_type data_out(width_, height_);
|
image_type data_out(width_, height_);
|
||||||
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, 0.0, 0.0, filter_factor_, nodata_);
|
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, offset_x_, offset_y_, filter_factor_, nodata_);
|
||||||
if (colorizer) colorizer->colorize(dst, data_out, nodata_, feature_);
|
if (colorizer) colorizer->colorize(dst, data_out, nodata_, feature_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -114,6 +117,8 @@ private:
|
||||||
int height_;
|
int height_;
|
||||||
double scale_x_;
|
double scale_x_;
|
||||||
double scale_y_;
|
double scale_y_;
|
||||||
|
double offset_x_;
|
||||||
|
double offset_y_;
|
||||||
scaling_method_e method_;
|
scaling_method_e method_;
|
||||||
double filter_factor_;
|
double filter_factor_;
|
||||||
double opacity_;
|
double opacity_;
|
||||||
|
@ -210,12 +215,18 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
||||||
if (source)
|
if (source)
|
||||||
{
|
{
|
||||||
box2d<double> target_ext = box2d<double>(source->ext_);
|
box2d<double> target_ext = box2d<double>(source->ext_);
|
||||||
prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
|
box2d<double> target_query_ext = box2d<double>(source->query_ext_);
|
||||||
|
if (!prj_trans.equal())
|
||||||
|
{
|
||||||
|
prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
|
||||||
|
prj_trans.backward(target_query_ext, PROJ_ENVELOPE_POINTS);
|
||||||
|
}
|
||||||
box2d<double> ext = common.t_.forward(target_ext);
|
box2d<double> ext = common.t_.forward(target_ext);
|
||||||
int start_x = static_cast<int>(std::floor(ext.minx()+.5));
|
box2d<double> query_ext = common.t_.forward(target_query_ext);
|
||||||
int start_y = static_cast<int>(std::floor(ext.miny()+.5));
|
int start_x = static_cast<int>(std::floor(query_ext.minx()+.5));
|
||||||
int end_x = static_cast<int>(std::floor(ext.maxx()+.5));
|
int start_y = static_cast<int>(std::floor(query_ext.miny()+.5));
|
||||||
int end_y = static_cast<int>(std::floor(ext.maxy()+.5));
|
int end_x = static_cast<int>(std::floor(query_ext.maxx()+.5));
|
||||||
|
int end_y = static_cast<int>(std::floor(query_ext.maxy()+.5));
|
||||||
int raster_width = end_x - start_x;
|
int raster_width = end_x - start_x;
|
||||||
int raster_height = end_y - start_y;
|
int raster_height = end_y - start_y;
|
||||||
if (raster_width > 0 && raster_height > 0)
|
if (raster_width > 0 && raster_height > 0)
|
||||||
|
@ -236,17 +247,20 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
||||||
|
|
||||||
if (!prj_trans.equal())
|
if (!prj_trans.equal())
|
||||||
{
|
{
|
||||||
double offset_x = ext.minx() - start_x;
|
// This path does not currently work and is still being figured out.
|
||||||
double offset_y = ext.miny() - start_y;
|
double offset_x = query_ext.minx() - start_x;
|
||||||
|
double offset_y = query_ext.miny() - start_y;
|
||||||
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
|
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
|
||||||
detail::image_warp_dispatcher<F> dispatcher(prj_trans, start_x, start_y, raster_width, raster_height,
|
detail::image_warp_dispatcher<F> dispatcher(prj_trans, start_x, start_y, raster_width, raster_height,
|
||||||
target_ext, source->ext_, offset_x, offset_y, mesh_size,
|
target_query_ext, source->ext_, offset_x, offset_y, mesh_size,
|
||||||
scaling_method, source->get_filter_factor(),
|
scaling_method, source->get_filter_factor(),
|
||||||
opacity, comp_op, sym, feature, composite, source->nodata());
|
opacity, comp_op, sym, feature, composite, source->nodata());
|
||||||
util::apply_visitor(dispatcher, source->data_);
|
util::apply_visitor(dispatcher, source->data_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
double offset_x = query_ext.minx() - ext.minx();
|
||||||
|
double offset_y = query_ext.miny() - ext.miny();
|
||||||
double image_ratio_x = ext.width() / source->data_.width();
|
double image_ratio_x = ext.width() / source->data_.width();
|
||||||
double image_ratio_y = ext.height() / source->data_.height();
|
double image_ratio_y = ext.height() / source->data_.height();
|
||||||
double eps = 1e-5;
|
double eps = 1e-5;
|
||||||
|
@ -256,6 +270,7 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
||||||
(std::abs(start_y) > eps);
|
(std::abs(start_y) > eps);
|
||||||
detail::image_dispatcher<F> dispatcher(start_x, start_y, raster_width, raster_height,
|
detail::image_dispatcher<F> dispatcher(start_x, start_y, raster_width, raster_height,
|
||||||
image_ratio_x, image_ratio_y,
|
image_ratio_x, image_ratio_y,
|
||||||
|
offset_x, offset_y,
|
||||||
scaling_method, source->get_filter_factor(),
|
scaling_method, source->get_filter_factor(),
|
||||||
opacity, comp_op, sym, feature, composite, source->nodata(), scale);
|
opacity, comp_op, sym, feature, composite, source->nodata(), scale);
|
||||||
util::apply_visitor(dispatcher, source->data_);
|
util::apply_visitor(dispatcher, source->data_);
|
||||||
|
|
|
@ -42,9 +42,9 @@ struct render_thunk_list_dispatch
|
||||||
{
|
{
|
||||||
offset_ = offset;
|
offset_ = offset;
|
||||||
|
|
||||||
for (render_thunk_ptr const& thunk : thunks)
|
for (render_thunk const& thunk : thunks)
|
||||||
{
|
{
|
||||||
util::apply_visitor(std::ref(*this), *thunk);
|
util::apply_visitor(std::ref(*this), thunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,8 +107,7 @@ struct text_render_thunk : util::movable
|
||||||
using render_thunk = util::variant<vector_marker_render_thunk,
|
using render_thunk = util::variant<vector_marker_render_thunk,
|
||||||
raster_marker_render_thunk,
|
raster_marker_render_thunk,
|
||||||
text_render_thunk>;
|
text_render_thunk>;
|
||||||
using render_thunk_ptr = std::unique_ptr<render_thunk>;
|
using render_thunk_list = std::list<render_thunk>;
|
||||||
using render_thunk_list = std::list<render_thunk_ptr>;
|
|
||||||
|
|
||||||
} // namespace mapnik
|
} // namespace mapnik
|
||||||
|
|
||||||
|
|
|
@ -120,11 +120,11 @@ public:
|
||||||
return algorithm_;
|
return algorithm_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_simplify_algorithm(simplify_algorithm_e value)
|
void set_simplify_algorithm(simplify_algorithm_e val)
|
||||||
{
|
{
|
||||||
if (algorithm_ != value)
|
if (algorithm_ != val)
|
||||||
{
|
{
|
||||||
algorithm_ = value;
|
algorithm_ = val;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,11 +134,11 @@ public:
|
||||||
return tolerance_;
|
return tolerance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_simplify_tolerance(double value)
|
void set_simplify_tolerance(double val)
|
||||||
{
|
{
|
||||||
if (tolerance_ != value)
|
if (tolerance_ != val)
|
||||||
{
|
{
|
||||||
tolerance_ = value;
|
tolerance_ = val;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,9 @@ public:
|
||||||
svg_parser_exception(std::string const& message)
|
svg_parser_exception(std::string const& message)
|
||||||
: message_(message) {}
|
: message_(message) {}
|
||||||
|
|
||||||
~svg_parser_exception() throw() {}
|
~svg_parser_exception() {}
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
virtual const char* what() const noexcept
|
||||||
{
|
{
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,18 +100,13 @@ struct strict_value : value_base_type
|
||||||
{
|
{
|
||||||
strict_value() = default;
|
strict_value() = default;
|
||||||
|
|
||||||
strict_value(const char* val)
|
strict_value(const char* val) noexcept(false)
|
||||||
: value_base_type(std::string(val)) {}
|
: value_base_type(std::string(val)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||||
strict_value(T const& obj)
|
|
||||||
: value_base_type(typename detail::mapnik_value_type<T>::type(obj))
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
strict_value(T && obj)
|
strict_value(T && obj)
|
||||||
noexcept(std::is_nothrow_constructible<value_base_type, T && >::value)
|
noexcept(std::is_nothrow_constructible<value_base_type, U>::value)
|
||||||
: value_base_type(std::forward<T>(obj))
|
: value_base_type(U(std::forward<T>(obj)))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,8 @@ public:
|
||||||
if (!size_) return nullptr;
|
if (!size_) return nullptr;
|
||||||
std::fseek(file_.get(), 0, SEEK_SET);
|
std::fseek(file_.get(), 0, SEEK_SET);
|
||||||
data_type buffer(new char[size_]);
|
data_type buffer(new char[size_]);
|
||||||
std::fread(buffer.get(), size_, 1, file_.get());
|
auto count = std::fread(buffer.get(), size_, 1, file_.get());
|
||||||
|
if (count != 1) return nullptr;
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -32,15 +32,7 @@ template <typename T>
|
||||||
using recursive_wrapper = typename mapbox::util::recursive_wrapper<T>;
|
using recursive_wrapper = typename mapbox::util::recursive_wrapper<T>;
|
||||||
|
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
class variant : public mapbox::util::variant<Types...>
|
using variant = typename mapbox::util::variant<Types...>;
|
||||||
{
|
|
||||||
public:
|
|
||||||
// tell spirit that this is an adapted variant
|
|
||||||
struct adapted_variant_tag;
|
|
||||||
using types = std::tuple<Types...>;
|
|
||||||
// inherit ctor's
|
|
||||||
using mapbox::util::variant<Types...>::variant;
|
|
||||||
};
|
|
||||||
|
|
||||||
// unary visitor interface
|
// unary visitor interface
|
||||||
// const
|
// const
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define MAPNIK_UTIL_VARIANT_IO_HPP
|
#define MAPNIK_UTIL_VARIANT_IO_HPP
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik { namespace util {
|
namespace mapbox { namespace util {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
|
@ -47,30 +47,20 @@ class MAPNIK_DECL value : public value_base
|
||||||
public:
|
public:
|
||||||
value() = default;
|
value() = default;
|
||||||
|
|
||||||
// conversion from type T is done via a temporary of type U, which
|
// Conversion from type T is done via a temporary value or reference
|
||||||
// is determined by mapnik_value_type;
|
// of type U, which is determined by mapnik_value_type_t.
|
||||||
// enable_if< decay<T> != value > is necessary to avoid ill-formed
|
//
|
||||||
// recursion in noexcept specifier; and it also prevents using this
|
// CAVEAT: We don't check `noexcept(conversion from T to U)`.
|
||||||
// constructor where implicitly-declared copy/move should be used
|
// But since the type U is either value_bool, value_integer,
|
||||||
// (e.g. value(value&))
|
// value_double or T &&, this conversion SHOULD NEVER throw.
|
||||||
template <typename T,
|
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||||
typename U = typename std::enable_if<
|
|
||||||
!detail::is_same_decay<T, value>::value,
|
|
||||||
detail::mapnik_value_type_decay<T>
|
|
||||||
>::type::type>
|
|
||||||
value(T && val)
|
value(T && val)
|
||||||
noexcept(noexcept(U(std::forward<T>(val))) &&
|
noexcept(std::is_nothrow_constructible<value_base, U>::value)
|
||||||
std::is_nothrow_constructible<value_base, U && >::value)
|
|
||||||
: value_base(U(std::forward<T>(val))) {}
|
: value_base(U(std::forward<T>(val))) {}
|
||||||
|
|
||||||
template <typename T,
|
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||||
typename U = typename std::enable_if<
|
|
||||||
!detail::is_same_decay<T, value>::value,
|
|
||||||
detail::mapnik_value_type_decay<T>
|
|
||||||
>::type::type>
|
|
||||||
value& operator=(T && val)
|
value& operator=(T && val)
|
||||||
noexcept(noexcept(U(std::forward<T>(val))) &&
|
noexcept(std::is_nothrow_assignable<value_base, U>::value)
|
||||||
std::is_nothrow_assignable<value_base, U && >::value)
|
|
||||||
{
|
{
|
||||||
value_base::operator=(U(std::forward<T>(val)));
|
value_base::operator=(U(std::forward<T>(val)));
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -41,9 +41,9 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~value_error() throw() {}
|
virtual ~value_error() {}
|
||||||
|
|
||||||
virtual const char * what() const throw()
|
virtual const char * what() const noexcept
|
||||||
{
|
{
|
||||||
return what_.c_str();
|
return what_.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,6 @@
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik { namespace detail {
|
||||||
|
|
||||||
inline void hash_combine(std::size_t & seed, std::size_t val)
|
|
||||||
{
|
|
||||||
seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct value_hasher
|
struct value_hasher
|
||||||
{
|
{
|
||||||
std::size_t operator() (value_null val) const
|
std::size_t operator() (value_null val) const
|
||||||
|
@ -54,11 +49,6 @@ struct value_hasher
|
||||||
return static_cast<std::size_t>(val.hashCode());
|
return static_cast<std::size_t>(val.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t operator()(value_integer val) const
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::size_t operator()(T const& val) const
|
std::size_t operator()(T const& val) const
|
||||||
{
|
{
|
||||||
|
@ -72,10 +62,7 @@ struct value_hasher
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::size_t mapnik_hash_value(T const& val)
|
std::size_t mapnik_hash_value(T const& val)
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
return util::apply_visitor(detail::value_hasher(), val);
|
||||||
detail::hash_combine(seed, util::apply_visitor(detail::value_hasher(), val));
|
|
||||||
detail::hash_combine(seed, val.which());
|
|
||||||
return seed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mapnik
|
} // namespace mapnik
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/cxx11_support.hpp>
|
||||||
#include <mapnik/pixel_types.hpp>
|
#include <mapnik/pixel_types.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <type_traits>
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
@ -152,90 +152,23 @@ inline std::istream& operator>> ( std::istream & s, value_null & )
|
||||||
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// to mapnik::value_type conversions traits
|
|
||||||
template <typename T>
|
|
||||||
struct is_value_bool
|
|
||||||
{
|
|
||||||
constexpr static bool value = std::is_same<T, bool>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
// Helper metafunction for mapnik::value construction and assignment.
|
||||||
struct is_value_integer
|
// Returns:
|
||||||
{
|
// value_bool if T is bool
|
||||||
constexpr static bool value = std::is_integral<T>::value && !std::is_same<T, bool>::value;
|
// value_integer if T is an integral type (except bool)
|
||||||
};
|
// value_double if T is a floating-point type
|
||||||
|
// T && otherwise
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename dT = decay_t<T>>
|
||||||
struct is_value_double
|
using mapnik_value_type_t =
|
||||||
{
|
conditional_t<
|
||||||
constexpr static bool value = std::is_floating_point<T>::value;
|
std::is_same<dT, bool>::value, value_bool,
|
||||||
};
|
conditional_t<
|
||||||
|
std::is_integral<dT>::value, value_integer,
|
||||||
template <typename T>
|
conditional_t<
|
||||||
struct is_value_unicode_string
|
std::is_floating_point<dT>::value, value_double,
|
||||||
{
|
T && >>>;
|
||||||
constexpr static bool value = std::is_same<T, typename mapnik::value_unicode_string>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_value_string
|
|
||||||
{
|
|
||||||
constexpr static bool value = std::is_same<T, typename std::string>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_value_null
|
|
||||||
{
|
|
||||||
constexpr static bool value = std::is_same<T, typename mapnik::value_null>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, class Enable = void>
|
|
||||||
struct mapnik_value_type
|
|
||||||
{
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
// value_null
|
|
||||||
template <typename T>
|
|
||||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_null<T>::value>::type>
|
|
||||||
{
|
|
||||||
using type = mapnik::value_null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// value_bool
|
|
||||||
template <typename T>
|
|
||||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_bool<T>::value>::type>
|
|
||||||
{
|
|
||||||
using type = mapnik::value_bool;
|
|
||||||
};
|
|
||||||
|
|
||||||
// value_integer
|
|
||||||
template <typename T>
|
|
||||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_integer<T>::value>::type>
|
|
||||||
{
|
|
||||||
using type = mapnik::value_integer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// value_double
|
|
||||||
template <typename T>
|
|
||||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::value>::type>
|
|
||||||
{
|
|
||||||
using type = mapnik::value_double;
|
|
||||||
};
|
|
||||||
|
|
||||||
// value_unicode_string
|
|
||||||
template <typename T>
|
|
||||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_unicode_string<T>::value>::type>
|
|
||||||
{
|
|
||||||
using type = mapnik::value_unicode_string const&;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using mapnik_value_type_decay = mapnik_value_type<typename std::decay<T>::type>;
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
using is_same_decay = std::is_same<typename std::decay<T>::type,
|
|
||||||
typename std::decay<U>::type>;
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#define MAPNIK_MAJOR_VERSION 3
|
#define MAPNIK_MAJOR_VERSION 3
|
||||||
#define MAPNIK_MINOR_VERSION 0
|
#define MAPNIK_MINOR_VERSION 0
|
||||||
#define MAPNIK_PATCH_VERSION 12
|
#define MAPNIK_PATCH_VERSION 13
|
||||||
|
|
||||||
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
|
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,8 @@ class MAPNIK_DECL node_not_found: public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
node_not_found(std::string const& node_name);
|
node_not_found(std::string const& node_name);
|
||||||
virtual const char* what() const throw();
|
virtual const char* what() const noexcept;
|
||||||
~node_not_found() throw ();
|
~node_not_found();
|
||||||
private:
|
private:
|
||||||
std::string node_name_;
|
std::string node_name_;
|
||||||
protected:
|
protected:
|
||||||
|
@ -65,8 +65,8 @@ class MAPNIK_DECL attribute_not_found: public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
attribute_not_found(std::string const& node_name, std::string const& attribute_name);
|
attribute_not_found(std::string const& node_name, std::string const& attribute_name);
|
||||||
virtual const char* what() const throw();
|
virtual const char* what() const noexcept;
|
||||||
~attribute_not_found() throw ();
|
~attribute_not_found();
|
||||||
private:
|
private:
|
||||||
std::string node_name_;
|
std::string node_name_;
|
||||||
std::string attribute_name_;
|
std::string attribute_name_;
|
||||||
|
@ -78,8 +78,8 @@ class MAPNIK_DECL more_than_one_child: public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
more_than_one_child(std::string const& node_name);
|
more_than_one_child(std::string const& node_name);
|
||||||
virtual const char* what() const throw();
|
virtual const char* what() const noexcept;
|
||||||
~more_than_one_child() throw ();
|
~more_than_one_child();
|
||||||
private:
|
private:
|
||||||
std::string node_name_;
|
std::string node_name_;
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -285,7 +285,10 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes)
|
||||||
{
|
{
|
||||||
auto headers = csv_utils::parse_line(csv_line, separator_, quote_);
|
auto headers = csv_utils::parse_line(csv_line, separator_, quote_);
|
||||||
// skip blank lines
|
// skip blank lines
|
||||||
if (headers.size() > 0 && headers[0].empty()) ++line_number;
|
if (headers.size() == 1 && headers[0].empty())
|
||||||
|
{
|
||||||
|
++line_number;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
|
@ -300,7 +303,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes)
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "CSV Plugin: expected a column header at line ";
|
s << "CSV Plugin: expected a column header at line ";
|
||||||
s << line_number << ", column " << index;
|
s << line_number << ", column " << index;
|
||||||
s << " - ensure this row contains valid header fields: '";
|
s << " - expected fields: '";
|
||||||
s << csv_line;
|
s << csv_line;
|
||||||
throw mapnik::datasource_exception(s.str());
|
throw mapnik::datasource_exception(s.str());
|
||||||
}
|
}
|
||||||
|
@ -338,7 +341,6 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes)
|
||||||
std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or ");
|
std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or ");
|
||||||
str += "latitude/longitude in:\n";
|
str += "latitude/longitude in:\n";
|
||||||
str += csv_line;
|
str += csv_line;
|
||||||
str += "\n - this is required for reading geometry data";
|
|
||||||
throw mapnik::datasource_exception(str);
|
throw mapnik::datasource_exception(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ plugin_env['LIBS'] = []
|
||||||
plugin_env.Append(LIBS=env['PLUGINS']['gdal']['lib'])
|
plugin_env.Append(LIBS=env['PLUGINS']['gdal']['lib'])
|
||||||
|
|
||||||
if env['RUNTIME_LINK'] == 'static':
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
cmd = 'gdal-config --dep-libs'
|
cmd = '%s --dep-libs' % plugin_env['GDAL_CONFIG']
|
||||||
plugin_env.ParseConfig(cmd)
|
plugin_env.ParseConfig(cmd)
|
||||||
|
|
||||||
# Link Library to Dependencies
|
# Link Library to Dependencies
|
||||||
|
|
|
@ -187,19 +187,9 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
int width = end_x - x_off;
|
int width = end_x - x_off;
|
||||||
int height = end_y - y_off;
|
int height = end_y - y_off;
|
||||||
|
|
||||||
// don't process almost invisible data
|
|
||||||
if (box.width() < 0.5)
|
|
||||||
{
|
|
||||||
width = 0;
|
|
||||||
}
|
|
||||||
if (box.height() < 0.5)
|
|
||||||
{
|
|
||||||
height = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate actual box2d of returned raster
|
//calculate actual box2d of returned raster
|
||||||
box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height);
|
box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height);
|
||||||
intersect = t.backward(feature_raster_extent);
|
feature_raster_extent = t.backward(feature_raster_extent);
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_;
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect;
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect;
|
||||||
|
@ -208,374 +198,380 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
|
|
||||||
if (width > 0 && height > 0)
|
if (width > 0 && height > 0)
|
||||||
{
|
{
|
||||||
double width_res = std::get<0>(q.resolution());
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << width << "," << height << ")";
|
||||||
double height_res = std::get<1>(q.resolution());
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
|
||||||
int im_width = int(width_res * intersect.width() + 0.5);
|
if (band_ > 0) // we are querying a single band
|
||||||
int im_height = int(height_res * intersect.height() + 0.5);
|
|
||||||
|
|
||||||
double filter_factor = q.get_filter_factor();
|
|
||||||
im_width = int(im_width * filter_factor + 0.5);
|
|
||||||
im_height = int(im_height * filter_factor + 0.5);
|
|
||||||
|
|
||||||
// case where we need to avoid upsampling so that the
|
|
||||||
// image can be later scaled within raster_symbolizer
|
|
||||||
if (im_width >= width || im_height >= height)
|
|
||||||
{
|
{
|
||||||
im_width = width;
|
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||||
im_height = height;
|
if (band_ > nbands_)
|
||||||
}
|
|
||||||
|
|
||||||
if (im_width > 0 && im_height > 0)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")";
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
|
|
||||||
if (band_ > 0) // we are querying a single band
|
|
||||||
{
|
{
|
||||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
std::ostringstream s;
|
||||||
if (band_ > nbands_)
|
s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands";
|
||||||
|
throw datasource_exception(s.str());
|
||||||
|
}
|
||||||
|
GDALDataType band_type = band->GetRasterDataType();
|
||||||
|
switch (band_type)
|
||||||
|
{
|
||||||
|
case GDT_Byte:
|
||||||
|
{
|
||||||
|
mapnik::image_gray8 image(width, height);
|
||||||
|
image.set(std::numeric_limits<std::uint8_t>::max());
|
||||||
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
image.data(), image.width(), image.height(),
|
||||||
|
GDT_Byte, 0, 0);
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands";
|
|
||||||
throw datasource_exception(s.str());
|
|
||||||
}
|
}
|
||||||
GDALDataType band_type = band->GetRasterDataType();
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, image, 0.0);
|
||||||
switch (band_type)
|
// set nodata value to be used in raster colorizer
|
||||||
|
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||||
|
else raster->set_nodata(raster_nodata);
|
||||||
|
feature->set_raster(raster);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GDT_Float64:
|
||||||
|
case GDT_Float32:
|
||||||
|
{
|
||||||
|
mapnik::image_gray32f image(width, height);
|
||||||
|
image.set(std::numeric_limits<float>::max());
|
||||||
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
image.data(), image.width(), image.height(),
|
||||||
|
GDT_Float32, 0, 0);
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
case GDT_Byte:
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, image, 0.0);
|
||||||
|
// set nodata value to be used in raster colorizer
|
||||||
|
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||||
|
else raster->set_nodata(raster_nodata);
|
||||||
|
feature->set_raster(raster);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GDT_UInt16:
|
||||||
|
{
|
||||||
|
mapnik::image_gray16 image(width, height);
|
||||||
|
image.set(std::numeric_limits<std::uint16_t>::max());
|
||||||
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
image.data(), image.width(), image.height(),
|
||||||
|
GDT_UInt16, 0, 0);
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
mapnik::image_gray8 image(im_width, im_height);
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
image.set(std::numeric_limits<std::uint8_t>::max());
|
}
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, image, 0.0);
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
// set nodata value to be used in raster colorizer
|
||||||
image.data(), image.width(), image.height(),
|
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||||
GDT_Byte, 0, 0);
|
else raster->set_nodata(raster_nodata);
|
||||||
if (raster_io_error == CE_Failure)
|
feature->set_raster(raster);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
case GDT_Int16:
|
||||||
|
{
|
||||||
|
mapnik::image_gray16s image(width, height);
|
||||||
|
image.set(std::numeric_limits<std::int16_t>::max());
|
||||||
|
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||||
|
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
image.data(), image.width(), image.height(),
|
||||||
|
GDT_Int16, 0, 0);
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
|
{
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, image, 0.0);
|
||||||
|
// set nodata value to be used in raster colorizer
|
||||||
|
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||||
|
else raster->set_nodata(raster_nodata);
|
||||||
|
feature->set_raster(raster);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // working with all bands
|
||||||
|
{
|
||||||
|
mapnik::image_rgba8 image(width, height);
|
||||||
|
image.set(std::numeric_limits<std::uint32_t>::max());
|
||||||
|
for (int i = 0; i < nbands_; ++i)
|
||||||
|
{
|
||||||
|
GDALRasterBand * band = dataset_.GetRasterBand(i + 1);
|
||||||
|
#ifdef MAPNIK_LOG
|
||||||
|
get_overview_meta(band);
|
||||||
|
#endif
|
||||||
|
GDALColorInterp color_interp = band->GetColorInterpretation();
|
||||||
|
switch (color_interp)
|
||||||
|
{
|
||||||
|
case GCI_RedBand:
|
||||||
|
red = band;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band";
|
||||||
|
break;
|
||||||
|
case GCI_GreenBand:
|
||||||
|
green = band;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band";
|
||||||
|
break;
|
||||||
|
case GCI_BlueBand:
|
||||||
|
blue = band;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band";
|
||||||
|
break;
|
||||||
|
case GCI_AlphaBand:
|
||||||
|
alpha = band;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band";
|
||||||
|
break;
|
||||||
|
case GCI_GrayIndex:
|
||||||
|
grey = band;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band";
|
||||||
|
break;
|
||||||
|
case GCI_PaletteIndex:
|
||||||
|
{
|
||||||
|
grey = band;
|
||||||
|
#ifdef MAPNIK_LOG
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable...";
|
||||||
|
GDALColorTable *color_table = band->GetColorTable();
|
||||||
|
|
||||||
|
if (color_table)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
int count = color_table->GetColorEntryCount();
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count;
|
||||||
|
|
||||||
|
for (int j = 0; j < count; j++)
|
||||||
|
{
|
||||||
|
const GDALColorEntry *ce = color_table->GetColorEntry (j);
|
||||||
|
if (! ce) continue;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
#endif
|
||||||
// set nodata value to be used in raster colorizer
|
|
||||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
|
||||||
else raster->set_nodata(raster_nodata);
|
|
||||||
feature->set_raster(raster);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GDT_Float64:
|
case GCI_Undefined:
|
||||||
case GDT_Float32:
|
#if GDAL_VERSION_NUM <= 1730
|
||||||
|
if (nbands_ == 4)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming alpha band)";
|
||||||
|
alpha = band;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
|
||||||
|
grey = band;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
|
||||||
|
grey = band;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (red && green && blue)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands...";
|
||||||
|
raster_nodata = red->GetNoDataValue(&raster_has_nodata);
|
||||||
|
GDALColorTable *color_table = red->GetColorTable();
|
||||||
|
bool has_nodata = nodata_value_ || raster_has_nodata;
|
||||||
|
|
||||||
|
// we can deduce the alpha channel from nodata in the Byte case
|
||||||
|
// by reusing the reading of R,G,B bands directly
|
||||||
|
if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
|
||||||
{
|
{
|
||||||
mapnik::image_gray32f image(im_width, im_height);
|
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
||||||
image.set(std::numeric_limits<float>::max());
|
// read the data in and create an alpha channel from the nodata values
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
// TODO - we assume here the nodata value for the red band applies to all bands
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
// more details about this at http://trac.osgeo.org/gdal/ticket/2734
|
||||||
image.data(), image.width(), image.height(),
|
float* imageData = (float*)image.bytes();
|
||||||
|
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
imageData, image.width(), image.height(),
|
||||||
|
GDT_Float32, 0, 0);
|
||||||
|
if (raster_io_error == CE_Failure) {
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
int len = image.width() * image.height();
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
|
||||||
|
{
|
||||||
|
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use dataset RasterIO in priority in 99.9% of the cases */
|
||||||
|
if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 )
|
||||||
|
{
|
||||||
|
int nBandsToRead = 3;
|
||||||
|
if( alpha != nullptr && alpha->GetBand() == 4 && !raster_has_nodata )
|
||||||
|
{
|
||||||
|
nBandsToRead = 4;
|
||||||
|
alpha = nullptr; // to avoid reading it again afterwards
|
||||||
|
}
|
||||||
|
raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
image.bytes(),
|
||||||
|
image.width(), image.height(), GDT_Byte,
|
||||||
|
nBandsToRead, nullptr,
|
||||||
|
4, 4 * image.width(), 1);
|
||||||
|
if (raster_io_error == CE_Failure) {
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
||||||
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
|
if (raster_io_error == CE_Failure) {
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1,
|
||||||
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
|
if (raster_io_error == CE_Failure) {
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2,
|
||||||
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
|
if (raster_io_error == CE_Failure) {
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the case we skipped initializing the alpha channel
|
||||||
|
if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
|
||||||
|
{
|
||||||
|
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
||||||
|
if( apply_nodata >= 0 && apply_nodata <= 255 )
|
||||||
|
{
|
||||||
|
int len = image.width() * image.height();
|
||||||
|
GByte* pabyBytes = (GByte*) image.bytes();
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
// TODO - we assume here the nodata value for the red band applies to all bands
|
||||||
|
// more details about this at http://trac.osgeo.org/gdal/ticket/2734
|
||||||
|
if (std::fabs(apply_nodata - pabyBytes[4*i]) < nodata_tolerance_)
|
||||||
|
pabyBytes[4*i + 3] = 0;
|
||||||
|
else
|
||||||
|
pabyBytes[4*i + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grey)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band...";
|
||||||
|
raster_nodata = grey->GetNoDataValue(&raster_has_nodata);
|
||||||
|
GDALColorTable* color_table = grey->GetColorTable();
|
||||||
|
bool has_nodata = nodata_value_ || raster_has_nodata;
|
||||||
|
if (!color_table && has_nodata)
|
||||||
|
{
|
||||||
|
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata;
|
||||||
|
// first read the data in and create an alpha channel from the nodata values
|
||||||
|
float* imageData = (float*)image.bytes();
|
||||||
|
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||||
|
imageData, image.width(), image.height(),
|
||||||
GDT_Float32, 0, 0);
|
GDT_Float32, 0, 0);
|
||||||
if (raster_io_error == CE_Failure)
|
if (raster_io_error == CE_Failure)
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
int len = image.width() * image.height();
|
||||||
// set nodata value to be used in raster colorizer
|
for (int i = 0; i < len; ++i)
|
||||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
|
||||||
else raster->set_nodata(raster_nodata);
|
|
||||||
feature->set_raster(raster);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GDT_UInt16:
|
|
||||||
{
|
|
||||||
mapnik::image_gray16 image(im_width, im_height);
|
|
||||||
image.set(std::numeric_limits<std::uint16_t>::max());
|
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
|
||||||
image.data(), image.width(), image.height(),
|
|
||||||
GDT_UInt16, 0, 0);
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
{
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
|
||||||
}
|
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
|
||||||
// set nodata value to be used in raster colorizer
|
|
||||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
|
||||||
else raster->set_nodata(raster_nodata);
|
|
||||||
feature->set_raster(raster);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
case GDT_Int16:
|
|
||||||
{
|
|
||||||
mapnik::image_gray16s image(im_width, im_height);
|
|
||||||
image.set(std::numeric_limits<std::int16_t>::max());
|
|
||||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
|
||||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
|
||||||
image.data(), image.width(), image.height(),
|
|
||||||
GDT_Int16, 0, 0);
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
|
||||||
// set nodata value to be used in raster colorizer
|
|
||||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
|
||||||
else raster->set_nodata(raster_nodata);
|
|
||||||
feature->set_raster(raster);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // working with all bands
|
|
||||||
{
|
|
||||||
mapnik::image_rgba8 image(im_width, im_height);
|
|
||||||
image.set(std::numeric_limits<std::uint32_t>::max());
|
|
||||||
for (int i = 0; i < nbands_; ++i)
|
|
||||||
{
|
|
||||||
GDALRasterBand * band = dataset_.GetRasterBand(i + 1);
|
|
||||||
#ifdef MAPNIK_LOG
|
|
||||||
get_overview_meta(band);
|
|
||||||
#endif
|
|
||||||
GDALColorInterp color_interp = band->GetColorInterpretation();
|
|
||||||
switch (color_interp)
|
|
||||||
{
|
|
||||||
case GCI_RedBand:
|
|
||||||
red = band;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band";
|
|
||||||
break;
|
|
||||||
case GCI_GreenBand:
|
|
||||||
green = band;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band";
|
|
||||||
break;
|
|
||||||
case GCI_BlueBand:
|
|
||||||
blue = band;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band";
|
|
||||||
break;
|
|
||||||
case GCI_AlphaBand:
|
|
||||||
alpha = band;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band";
|
|
||||||
break;
|
|
||||||
case GCI_GrayIndex:
|
|
||||||
grey = band;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band";
|
|
||||||
break;
|
|
||||||
case GCI_PaletteIndex:
|
|
||||||
{
|
|
||||||
grey = band;
|
|
||||||
#ifdef MAPNIK_LOG
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable...";
|
|
||||||
GDALColorTable *color_table = band->GetColorTable();
|
|
||||||
|
|
||||||
if (color_table)
|
|
||||||
{
|
{
|
||||||
int count = color_table->GetColorEntryCount();
|
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count;
|
|
||||||
|
|
||||||
for (int j = 0; j < count; j++)
|
|
||||||
{
|
|
||||||
const GDALColorEntry *ce = color_table->GetColorEntry (j);
|
|
||||||
if (! ce) continue;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GCI_Undefined:
|
|
||||||
#if GDAL_VERSION_NUM <= 1730
|
|
||||||
if (nbands_ == 4)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming alpha band)";
|
|
||||||
alpha = band;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
|
*reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
|
||||||
grey = band;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
|
|
||||||
grey = band;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (red && green && blue)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands...";
|
|
||||||
raster_nodata = red->GetNoDataValue(&raster_has_nodata);
|
|
||||||
GDALColorTable *color_table = red->GetColorTable();
|
|
||||||
bool has_nodata = nodata_value_ || raster_has_nodata;
|
|
||||||
|
|
||||||
// we can deduce the alpha channel from nodata in the Byte case
|
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
||||||
// by reusing the reading of R,G,B bands directly
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
|
if (raster_io_error == CE_Failure)
|
||||||
|
{
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1,
|
||||||
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
|
{
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2,
|
||||||
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
|
|
||||||
|
if (raster_io_error == CE_Failure)
|
||||||
|
{
|
||||||
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color_table)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table...";
|
||||||
|
for (unsigned y = 0; y < image.height(); ++y)
|
||||||
{
|
{
|
||||||
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
unsigned int* row = image.get_row(y);
|
||||||
// read the data in and create an alpha channel from the nodata values
|
for (unsigned x = 0; x < image.width(); ++x)
|
||||||
// TODO - we assume here the nodata value for the red band applies to all bands
|
|
||||||
// more details about this at http://trac.osgeo.org/gdal/ticket/2734
|
|
||||||
float* imageData = (float*)image.bytes();
|
|
||||||
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
|
|
||||||
imageData, image.width(), image.height(),
|
|
||||||
GDT_Float32, 0, 0);
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
int len = image.width() * image.height();
|
|
||||||
for (int i = 0; i < len; ++i)
|
|
||||||
{
|
{
|
||||||
if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
|
unsigned value = row[x] & 0xff;
|
||||||
|
const GDALColorEntry *ce = color_table->GetColorEntry(value);
|
||||||
|
if (ce)
|
||||||
{
|
{
|
||||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
|
// make lacking color entry fully alpha
|
||||||
}
|
// note - gdal_translate makes black
|
||||||
}
|
row[x] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* Use dataset RasterIO in priority in 99.9% of the cases */
|
|
||||||
if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 )
|
|
||||||
{
|
|
||||||
int nBandsToRead = 3;
|
|
||||||
if( alpha != nullptr && alpha->GetBand() == 4 && !raster_has_nodata )
|
|
||||||
{
|
|
||||||
nBandsToRead = 4;
|
|
||||||
alpha = nullptr; // to avoid reading it again afterwards
|
|
||||||
}
|
|
||||||
raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height,
|
|
||||||
image.bytes(),
|
|
||||||
image.width(), image.height(), GDT_Byte,
|
|
||||||
nBandsToRead, nullptr,
|
|
||||||
4, 4 * image.width(), 1);
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the case we skipped initializing the alpha channel
|
|
||||||
if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
|
|
||||||
{
|
|
||||||
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
|
||||||
if( apply_nodata >= 0 && apply_nodata <= 255 )
|
|
||||||
{
|
|
||||||
int len = image.width() * image.height();
|
|
||||||
GByte* pabyBytes = (GByte*) image.bytes();
|
|
||||||
for (int i = 0; i < len; ++i)
|
|
||||||
{
|
|
||||||
// TODO - we assume here the nodata value for the red band applies to all bands
|
|
||||||
// more details about this at http://trac.osgeo.org/gdal/ticket/2734
|
|
||||||
if (std::fabs(apply_nodata - pabyBytes[4*i]) < nodata_tolerance_)
|
|
||||||
pabyBytes[4*i + 3] = 0;
|
|
||||||
else
|
|
||||||
pabyBytes[4*i + 3] = 255;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (grey)
|
}
|
||||||
|
if (alpha)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band...";
|
||||||
|
if (!raster_has_nodata)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band...";
|
raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
||||||
raster_nodata = grey->GetNoDataValue(&raster_has_nodata);
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
GDALColorTable* color_table = grey->GetColorTable();
|
if (raster_io_error == CE_Failure) {
|
||||||
bool has_nodata = nodata_value_ || raster_has_nodata;
|
|
||||||
if (!color_table && has_nodata)
|
|
||||||
{
|
|
||||||
double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata;
|
|
||||||
// first read the data in and create an alpha channel from the nodata values
|
|
||||||
float* imageData = (float*)image.bytes();
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
|
|
||||||
imageData, image.width(), image.height(),
|
|
||||||
GDT_Float32, 0, 0);
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
int len = image.width() * image.height();
|
|
||||||
for (int i = 0; i < len; ++i)
|
|
||||||
{
|
|
||||||
if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
|
|
||||||
{
|
|
||||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
|
|
||||||
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
|
|
||||||
if (raster_io_error == CE_Failure)
|
|
||||||
{
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (color_table)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table...";
|
|
||||||
for (unsigned y = 0; y < image.height(); ++y)
|
|
||||||
{
|
|
||||||
unsigned int* row = image.get_row(y);
|
|
||||||
for (unsigned x = 0; x < image.width(); ++x)
|
|
||||||
{
|
|
||||||
unsigned value = row[x] & 0xff;
|
|
||||||
const GDALColorEntry *ce = color_table->GetColorEntry(value);
|
|
||||||
if (ce)
|
|
||||||
{
|
|
||||||
row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// make lacking color entry fully alpha
|
|
||||||
// note - gdal_translate makes black
|
|
||||||
row[x] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (alpha)
|
else
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band...";
|
MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( dataset_.GetRasterCount() > 0 && dataset_.GetRasterBand(1) )
|
||||||
|
{
|
||||||
|
// Check if we have a non-alpha mask band (for example a TIFF internal mask)
|
||||||
|
int flags = dataset_.GetRasterBand(1)->GetMaskFlags();
|
||||||
|
GDALRasterBand* mask = 0;
|
||||||
|
if (flags == GMF_PER_DATASET)
|
||||||
|
{
|
||||||
|
mask = dataset_.GetRasterBand(1)->GetMaskBand();
|
||||||
|
}
|
||||||
|
if (mask)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: found and processing mask band...";
|
||||||
if (!raster_has_nodata)
|
if (!raster_has_nodata)
|
||||||
{
|
{
|
||||||
raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
raster_io_error = mask->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
||||||
if (raster_io_error == CE_Failure) {
|
if (raster_io_error == CE_Failure) {
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
throw datasource_exception(CPLGetLastErrorMsg());
|
||||||
|
@ -583,48 +579,22 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band";
|
MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of mask band";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( dataset_.GetRasterCount() > 0 && dataset_.GetRasterBand(1) )
|
|
||||||
{
|
|
||||||
// Check if we have a non-alpha mask band (for example a TIFF internal mask)
|
|
||||||
int flags = dataset_.GetRasterBand(1)->GetMaskFlags();
|
|
||||||
GDALRasterBand* mask = 0;
|
|
||||||
if (flags == GMF_PER_DATASET)
|
|
||||||
{
|
|
||||||
mask = dataset_.GetRasterBand(1)->GetMaskBand();
|
|
||||||
}
|
|
||||||
if (mask)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: found and processing mask band...";
|
|
||||||
if (!raster_has_nodata)
|
|
||||||
{
|
|
||||||
raster_io_error = mask->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
|
|
||||||
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
|
|
||||||
if (raster_io_error == CE_Failure) {
|
|
||||||
throw datasource_exception(CPLGetLastErrorMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of mask band";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
|
||||||
// set nodata value to be used in raster colorizer
|
|
||||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
|
||||||
else raster->set_nodata(raster_nodata);
|
|
||||||
feature->set_raster(raster);
|
|
||||||
}
|
}
|
||||||
// report actual/original source nodata in feature attributes
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, image, 0.0);
|
||||||
if (raster_has_nodata)
|
// set nodata value to be used in raster colorizer
|
||||||
{
|
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||||
feature->put("nodata",raster_nodata);
|
else raster->set_nodata(raster_nodata);
|
||||||
}
|
feature->set_raster(raster);
|
||||||
return feature;
|
|
||||||
}
|
}
|
||||||
|
// report actual/original source nodata in feature attributes
|
||||||
|
if (raster_has_nodata)
|
||||||
|
{
|
||||||
|
feature->put("nodata",raster_nodata);
|
||||||
|
}
|
||||||
|
return feature;
|
||||||
}
|
}
|
||||||
return feature_ptr();
|
return feature_ptr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ plugin_env['LIBS'] = []
|
||||||
plugin_env.Append(LIBS=env['PLUGINS']['ogr']['lib'])
|
plugin_env.Append(LIBS=env['PLUGINS']['ogr']['lib'])
|
||||||
|
|
||||||
if env['RUNTIME_LINK'] == 'static':
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
cmd = 'gdal-config --dep-libs'
|
cmd = '%s --dep-libs' % plugin_env['GDAL_CONFIG']
|
||||||
plugin_env.ParseConfig(cmd)
|
plugin_env.ParseConfig(cmd)
|
||||||
|
|
||||||
# Link Library to Dependencies
|
# Link Library to Dependencies
|
||||||
|
|
|
@ -54,7 +54,9 @@ if env['PLUGIN_LINKING'] == 'shared':
|
||||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||||
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
|
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
|
||||||
libraries.insert(0,env['MAPNIK_NAME'])
|
libraries.insert(0,env['MAPNIK_NAME'])
|
||||||
|
libraries.append('icui18n')
|
||||||
libraries.append(env['ICU_LIB_NAME'])
|
libraries.append(env['ICU_LIB_NAME'])
|
||||||
|
libraries.append('icudata')
|
||||||
|
|
||||||
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
|
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
|
||||||
SHLIBPREFIX='',
|
SHLIBPREFIX='',
|
||||||
|
|
|
@ -89,33 +89,34 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
||||||
box2d<double> intersect = bbox_.intersect(curIter_->envelope());
|
box2d<double> intersect = bbox_.intersect(curIter_->envelope());
|
||||||
box2d<double> ext = t.forward(intersect);
|
box2d<double> ext = t.forward(intersect);
|
||||||
box2d<double> rem = policy_.transform(ext);
|
box2d<double> rem = policy_.transform(ext);
|
||||||
if (ext.width() > 0.5 && ext.height() > 0.5 )
|
// select minimum raster containing whole ext
|
||||||
{
|
int x_off = static_cast<int>(std::floor(ext.minx()));
|
||||||
// select minimum raster containing whole ext
|
int y_off = static_cast<int>(std::floor(ext.miny()));
|
||||||
int x_off = static_cast<int>(std::floor(ext.minx()));
|
int end_x = static_cast<int>(std::ceil(ext.maxx()));
|
||||||
int y_off = static_cast<int>(std::floor(ext.miny()));
|
int end_y = static_cast<int>(std::ceil(ext.maxy()));
|
||||||
int end_x = static_cast<int>(std::ceil(ext.maxx()));
|
|
||||||
int end_y = static_cast<int>(std::ceil(ext.maxy()));
|
|
||||||
|
|
||||||
// clip to available data
|
// clip to available data
|
||||||
if (x_off < 0) x_off = 0;
|
if (x_off >= image_width) x_off = image_width - 1;
|
||||||
if (y_off < 0) y_off = 0;
|
if (y_off >= image_width) y_off = image_width - 1;
|
||||||
if (end_x > image_width) end_x = image_width;
|
if (x_off < 0) x_off = 0;
|
||||||
if (end_y > image_height) end_y = image_height;
|
if (y_off < 0) y_off = 0;
|
||||||
|
if (end_x > image_width) end_x = image_width;
|
||||||
|
if (end_y > image_height) end_y = image_height;
|
||||||
|
|
||||||
int width = end_x - x_off;
|
int width = end_x - x_off;
|
||||||
int height = end_y - y_off;
|
int height = end_y - y_off;
|
||||||
|
if (width < 1) width = 1;
|
||||||
|
if (height < 1) height = 1;
|
||||||
|
|
||||||
// calculate actual box2d of returned raster
|
// calculate actual box2d of returned raster
|
||||||
box2d<double> feature_raster_extent(rem.minx() + x_off,
|
box2d<double> feature_raster_extent(rem.minx() + x_off,
|
||||||
rem.miny() + y_off,
|
rem.miny() + y_off,
|
||||||
rem.maxx() + x_off + width,
|
rem.maxx() + x_off + width,
|
||||||
rem.maxy() + y_off + height);
|
rem.maxy() + y_off + height);
|
||||||
intersect = t.backward(feature_raster_extent);
|
feature_raster_extent = t.backward(feature_raster_extent);
|
||||||
mapnik::image_any data = reader->read(x_off, y_off, width, height);
|
mapnik::image_any data = reader->read(x_off, y_off, width, height);
|
||||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, std::move(data), 1.0);
|
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(feature_raster_extent, intersect, std::move(data), 1.0);
|
||||||
feature->set_raster(raster);
|
feature->set_raster(raster);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ raster_info::raster_info(const raster_info& rhs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void raster_info::swap(raster_info& other) //throw()
|
void raster_info::swap(raster_info& other)
|
||||||
{
|
{
|
||||||
std::swap(file_,other.file_);
|
std::swap(file_,other.file_);
|
||||||
std::swap(format_,other.format_);
|
std::swap(format_,other.format_);
|
||||||
|
|
|
@ -137,7 +137,7 @@ const field_descriptor& dbf_file::descriptor(int col) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw()
|
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
field_descriptor const& descriptor(int col) const;
|
field_descriptor const& descriptor(int col) const;
|
||||||
void move_to(int index);
|
void move_to(int index);
|
||||||
std::string string_value(int col) const;
|
std::string string_value(int col) const;
|
||||||
void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw();
|
void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const;
|
||||||
private:
|
private:
|
||||||
void read_header();
|
void read_header();
|
||||||
int read_short();
|
int read_short();
|
||||||
|
|
|
@ -26,7 +26,7 @@ function add() {
|
||||||
CXX=${CXX:-clang++}
|
CXX=${CXX:-clang++}
|
||||||
|
|
||||||
function compile() {
|
function compile() {
|
||||||
${CXX} -o ${app} ${cpp} -Wpadded -I./ -isystem ./mason_packages/.link/include `mapnik-config --all-flags` -Ideps -Lsrc -Ideps/agg/include -Iinclude
|
${CXX} -o ${app} ${cpp} -Wpadded -I./ -I./deps/mapbox/variant/include -isystem ./mason_packages/.link/include -std=c++11 -Ideps -Lsrc -Ideps/agg/include -Iinclude
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ ${1:-unset} == "unset" ]] || [[ ${2:-unset} == "unset" ]] || [[ $@ == '-h' ]] || [[ $@ == '--help' ]]; then
|
if [[ ${1:-unset} == "unset" ]] || [[ ${2:-unset} == "unset" ]] || [[ $@ == '-h' ]] || [[ $@ == '--help' ]]; then
|
||||||
|
|
|
@ -46,15 +46,6 @@ git_submodule_update () {
|
||||||
git submodule update "$@"
|
git submodule update "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# install and call pip
|
|
||||||
pip () {
|
|
||||||
if ! which pip >/dev/null; then
|
|
||||||
easy_install --user pip && \
|
|
||||||
export PATH="$HOME/Library/Python/2.7/bin:$PATH"
|
|
||||||
fi
|
|
||||||
command pip "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# commit_message_contains TEXT
|
# commit_message_contains TEXT
|
||||||
# - returns 0 (true) if TEXT is found in commit message
|
# - returns 0 (true) if TEXT is found in commit message
|
||||||
# - case-insensitive, plain-text search, not regex
|
# - case-insensitive, plain-text search, not regex
|
||||||
|
@ -83,22 +74,16 @@ config_override () {
|
||||||
configure () {
|
configure () {
|
||||||
if enabled ${COVERAGE}; then
|
if enabled ${COVERAGE}; then
|
||||||
./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \
|
./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \
|
||||||
COVERAGE=True DEBUG=True WARNING_CXXFLAGS="-Wno-unknown-warning-option"
|
COVERAGE=True DEBUG=True
|
||||||
else
|
else
|
||||||
./configure "$@" PREFIX=${PREFIX} WARNING_CXXFLAGS="-Wno-unknown-warning-option"
|
./configure "$@" PREFIX=${PREFIX}
|
||||||
fi
|
fi
|
||||||
# print final config values, sorted and indented
|
# print final config values, sorted and indented
|
||||||
sort -sk1,1 ./config.py | sed -e 's/^/ /'
|
sort -sk1,1 ./config.py | sed -e 's/^/ /'
|
||||||
}
|
}
|
||||||
|
|
||||||
coverage () {
|
coverage () {
|
||||||
./mason_packages/.link/bin/cpp-coveralls \
|
./codecov -x "llvm-cov gcov" -Z
|
||||||
--gcov ${LLVM_COV} \
|
|
||||||
--exclude mason_packages \
|
|
||||||
--exclude .sconf_temp --exclude benchmark --exclude deps \
|
|
||||||
--exclude scons --exclude test --exclude demo --exclude docs \
|
|
||||||
--exclude fonts \
|
|
||||||
> /dev/null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger_downstream() {
|
trigger_downstream() {
|
||||||
|
|
|
@ -79,79 +79,22 @@ struct agg_renderer_process_visitor_l
|
||||||
|
|
||||||
void operator() (marker_svg const& marker) const
|
void operator() (marker_svg const& marker) const
|
||||||
{
|
{
|
||||||
using color = agg::rgba8;
|
|
||||||
using order = agg::order_rgba;
|
|
||||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
|
||||||
using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
|
|
||||||
using pattern_type = agg::line_image_pattern<pattern_filter_type>;
|
|
||||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
|
||||||
using renderer_base = agg::renderer_base<pixfmt_type>;
|
|
||||||
using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
|
|
||||||
using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
|
|
||||||
|
|
||||||
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
|
||||||
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||||
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
||||||
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
|
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
|
||||||
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
||||||
image_rgba8 image(bbox_image.width(), bbox_image.height());
|
image_rgba8 image(bbox_image.width(), bbox_image.height());
|
||||||
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
||||||
|
render(image, marker.width(), marker.height());
|
||||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
|
||||||
value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
|
||||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
|
||||||
value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
|
||||||
|
|
||||||
agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size());
|
|
||||||
pixfmt_type pixf(buf);
|
|
||||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
|
||||||
renderer_base ren_base(pixf);
|
|
||||||
agg::pattern_filter_bilinear_rgba8 filter;
|
|
||||||
|
|
||||||
pattern_source source(image, opacity);
|
|
||||||
pattern_type pattern (filter,source);
|
|
||||||
renderer_type ren(ren_base, pattern);
|
|
||||||
double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
|
|
||||||
int rast_clip_padding = static_cast<int>(std::round(half_stroke));
|
|
||||||
ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
|
|
||||||
rasterizer_type ras(ren);
|
|
||||||
|
|
||||||
agg::trans_affine tr;
|
|
||||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
|
||||||
if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
|
||||||
|
|
||||||
box2d<double> clip_box = clipping_extent(common_);
|
|
||||||
if (clip)
|
|
||||||
{
|
|
||||||
double padding = (double)(common_.query_extent_.width()/pixmap_.width());
|
|
||||||
if (half_stroke > 1)
|
|
||||||
padding *= half_stroke;
|
|
||||||
if (std::fabs(offset) > 0)
|
|
||||||
padding *= std::fabs(offset) * 1.2;
|
|
||||||
padding *= common_.scale_factor_;
|
|
||||||
clip_box.pad(padding);
|
|
||||||
}
|
|
||||||
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
|
|
||||||
affine_transform_tag,
|
|
||||||
simplify_tag,smooth_tag,
|
|
||||||
offset_transform_tag>;
|
|
||||||
|
|
||||||
vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
|
||||||
|
|
||||||
if (clip) converter.set<clip_line_tag>();
|
|
||||||
converter.set<transform_tag>(); //always transform
|
|
||||||
if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
|
|
||||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
|
||||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
|
||||||
|
|
||||||
using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer_type>;
|
|
||||||
using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
|
|
||||||
apply_vertex_converter_type apply(converter, ras);
|
|
||||||
mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator() (marker_rgba8 const& marker) const
|
void operator() (marker_rgba8 const& marker) const
|
||||||
|
{
|
||||||
|
render(marker.get_data(), marker.width(), marker.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void render(mapnik::image_rgba8 const& marker, double width, double height) const
|
||||||
{
|
{
|
||||||
using color = agg::rgba8;
|
using color = agg::rgba8;
|
||||||
using order = agg::order_rgba;
|
using order = agg::order_rgba;
|
||||||
|
@ -164,8 +107,6 @@ struct agg_renderer_process_visitor_l
|
||||||
using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
|
using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
|
||||||
|
|
||||||
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||||
mapnik::image_rgba8 const& image = marker.get_data();
|
|
||||||
|
|
||||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||||
value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
||||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||||
|
@ -178,10 +119,10 @@ struct agg_renderer_process_visitor_l
|
||||||
renderer_base ren_base(pixf);
|
renderer_base ren_base(pixf);
|
||||||
agg::pattern_filter_bilinear_rgba8 filter;
|
agg::pattern_filter_bilinear_rgba8 filter;
|
||||||
|
|
||||||
pattern_source source(image, opacity);
|
pattern_source source(marker, opacity);
|
||||||
pattern_type pattern (filter,source);
|
pattern_type pattern (filter,source);
|
||||||
renderer_type ren(ren_base, pattern);
|
renderer_type ren(ren_base, pattern);
|
||||||
double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
|
double half_stroke = std::max(width / 2.0, height / 2.0);
|
||||||
int rast_clip_padding = static_cast<int>(std::round(half_stroke));
|
int rast_clip_padding = static_cast<int>(std::round(half_stroke));
|
||||||
ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
|
ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
|
||||||
rasterizer_type ras(ren);
|
rasterizer_type ras(ren);
|
||||||
|
@ -221,7 +162,6 @@ struct agg_renderer_process_visitor_l
|
||||||
mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry());
|
mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
renderer_common & common_;
|
renderer_common & common_;
|
||||||
buffer_type & pixmap_;
|
buffer_type & pixmap_;
|
||||||
buffer_type * current_buffer_;
|
buffer_type * current_buffer_;
|
||||||
|
|
|
@ -88,123 +88,17 @@ struct agg_renderer_process_visitor_p
|
||||||
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
||||||
mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height());
|
mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height());
|
||||||
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
||||||
|
render(image);
|
||||||
agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(),
|
|
||||||
current_buffer_->height(), current_buffer_->row_size());
|
|
||||||
ras_ptr_->reset();
|
|
||||||
value_double gamma = get<value_double, keys::gamma>(sym_, feature_, common_.vars_);
|
|
||||||
gamma_method_enum gamma_method = get<gamma_method_enum, keys::gamma_method>(sym_, feature_, common_.vars_);
|
|
||||||
if (gamma != gamma_ || gamma_method != gamma_method_)
|
|
||||||
{
|
|
||||||
set_gamma_method(ras_ptr_, gamma, gamma_method);
|
|
||||||
gamma_method_ = gamma_method;
|
|
||||||
gamma_ = gamma;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
|
||||||
value_double opacity = get<double, keys::opacity>(sym_, feature_, common_.vars_);
|
|
||||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
|
||||||
value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
|
||||||
|
|
||||||
box2d<double> clip_box = clipping_extent(common_);
|
|
||||||
|
|
||||||
using color = agg::rgba8;
|
|
||||||
using order = agg::order_rgba;
|
|
||||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
|
||||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
|
||||||
|
|
||||||
using wrap_x_type = agg::wrap_mode_repeat;
|
|
||||||
using wrap_y_type = agg::wrap_mode_repeat;
|
|
||||||
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
|
||||||
wrap_x_type,
|
|
||||||
wrap_y_type>;
|
|
||||||
|
|
||||||
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
|
||||||
using ren_base = agg::renderer_base<pixfmt_type>;
|
|
||||||
|
|
||||||
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
|
||||||
agg::span_allocator<agg::rgba8>,
|
|
||||||
span_gen_type>;
|
|
||||||
|
|
||||||
pixfmt_type pixf(buf);
|
|
||||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
|
||||||
ren_base renb(pixf);
|
|
||||||
|
|
||||||
unsigned w = image.width();
|
|
||||||
unsigned h = image.height();
|
|
||||||
agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4);
|
|
||||||
agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf);
|
|
||||||
img_source_type img_src(pixf_pattern);
|
|
||||||
|
|
||||||
pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym_, feature_, common_.vars_);
|
|
||||||
unsigned offset_x=0;
|
|
||||||
unsigned offset_y=0;
|
|
||||||
|
|
||||||
if (alignment == LOCAL_ALIGNMENT)
|
|
||||||
{
|
|
||||||
double x0 = 0;
|
|
||||||
double y0 = 0;
|
|
||||||
using apply_local_alignment = detail::apply_local_alignment;
|
|
||||||
apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0);
|
|
||||||
util::apply_visitor(geometry::vertex_processor<apply_local_alignment>(apply), feature_.get_geometry());
|
|
||||||
offset_x = unsigned(current_buffer_->width() - x0);
|
|
||||||
offset_y = unsigned(current_buffer_->height() - y0);
|
|
||||||
}
|
|
||||||
|
|
||||||
span_gen_type sg(img_src, offset_x, offset_y);
|
|
||||||
|
|
||||||
agg::span_allocator<agg::rgba8> sa;
|
|
||||||
renderer_type rp(renb,sa, sg, unsigned(opacity * 255));
|
|
||||||
|
|
||||||
agg::trans_affine tr;
|
|
||||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
|
||||||
if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
|
||||||
using vertex_converter_type = vertex_converter<clip_poly_tag,
|
|
||||||
transform_tag,
|
|
||||||
affine_transform_tag,
|
|
||||||
simplify_tag,
|
|
||||||
smooth_tag>;
|
|
||||||
|
|
||||||
vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
|
||||||
|
|
||||||
|
|
||||||
if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>();
|
|
||||||
converter.set<transform_tag>(); //always transform
|
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
|
||||||
if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
|
|
||||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
|
||||||
|
|
||||||
using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer>;
|
|
||||||
using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
|
|
||||||
apply_vertex_converter_type apply(converter, *ras_ptr_);
|
|
||||||
mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry());
|
|
||||||
agg::scanline_u8 sl;
|
|
||||||
ras_ptr_->filling_rule(agg::fill_even_odd);
|
|
||||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator() (marker_rgba8 const& marker) const
|
void operator() (marker_rgba8 const& marker) const
|
||||||
{
|
{
|
||||||
using color = agg::rgba8;
|
render(marker.get_data());
|
||||||
using order = agg::order_rgba;
|
}
|
||||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
|
||||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
|
||||||
|
|
||||||
using wrap_x_type = agg::wrap_mode_repeat;
|
|
||||||
using wrap_y_type = agg::wrap_mode_repeat;
|
|
||||||
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
|
||||||
wrap_x_type,
|
|
||||||
wrap_y_type>;
|
|
||||||
|
|
||||||
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
|
||||||
using ren_base = agg::renderer_base<pixfmt_type>;
|
|
||||||
|
|
||||||
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
|
||||||
agg::span_allocator<agg::rgba8>,
|
|
||||||
span_gen_type>;
|
|
||||||
mapnik::image_rgba8 const& image = marker.get_data();
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void render(mapnik::image_rgba8 const& image) const
|
||||||
|
{
|
||||||
agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(),
|
agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(),
|
||||||
current_buffer_->height(), current_buffer_->row_size());
|
current_buffer_->height(), current_buffer_->row_size());
|
||||||
ras_ptr_->reset();
|
ras_ptr_->reset();
|
||||||
|
@ -224,6 +118,23 @@ struct agg_renderer_process_visitor_p
|
||||||
|
|
||||||
box2d<double> clip_box = clipping_extent(common_);
|
box2d<double> clip_box = clipping_extent(common_);
|
||||||
|
|
||||||
|
using color = agg::rgba8;
|
||||||
|
using order = agg::order_rgba;
|
||||||
|
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
||||||
|
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||||
|
|
||||||
|
using wrap_x_type = agg::wrap_mode_repeat;
|
||||||
|
using wrap_y_type = agg::wrap_mode_repeat;
|
||||||
|
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
||||||
|
wrap_x_type,
|
||||||
|
wrap_y_type>;
|
||||||
|
|
||||||
|
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
||||||
|
using ren_base = agg::renderer_base<pixfmt_type>;
|
||||||
|
|
||||||
|
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
||||||
|
agg::span_allocator<agg::rgba8>,
|
||||||
|
span_gen_type>;
|
||||||
|
|
||||||
pixfmt_type pixf(buf);
|
pixfmt_type pixf(buf);
|
||||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
||||||
|
@ -282,7 +193,6 @@ struct agg_renderer_process_visitor_p
|
||||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
renderer_common & common_;
|
renderer_common & common_;
|
||||||
buffer_type * current_buffer_;
|
buffer_type * current_buffer_;
|
||||||
std::unique_ptr<rasterizer> const& ras_ptr_;
|
std::unique_ptr<rasterizer> const& ras_ptr_;
|
||||||
|
|
|
@ -37,7 +37,7 @@ config_error::config_error(std::string const& what,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* config_error::what() const throw()
|
char const* config_error::what() const noexcept
|
||||||
{
|
{
|
||||||
msg_ = what_;
|
msg_ = what_;
|
||||||
if (!node_name_.empty())
|
if (!node_name_.empty())
|
||||||
|
|
|
@ -121,7 +121,7 @@ stop_array const& gradient::get_stop_array() const
|
||||||
return stops_;
|
return stops_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gradient::swap(gradient& other) throw()
|
void gradient::swap(gradient& other) noexcept
|
||||||
{
|
{
|
||||||
std::swap(gradient_type_, other.gradient_type_);
|
std::swap(gradient_type_, other.gradient_type_);
|
||||||
std::swap(stops_, other.stops_);
|
std::swap(stops_, other.stops_);
|
||||||
|
|
|
@ -90,30 +90,26 @@ struct process_layout
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bound_box layout_box;
|
auto max_diff = layout.get_max_difference();
|
||||||
int middle_ifirst = safe_cast<int>((member_boxes_.size() - 1) >> 1);
|
auto layout_box = make_horiz_pair(0, 0.0, 0, x_margin, max_diff);
|
||||||
int top_i = 0;
|
auto y_shift = 0.5 * layout_box.height();
|
||||||
int bottom_i = 0;
|
|
||||||
if (middle_ifirst % 2 == 0)
|
for (size_t i = 2; i < member_boxes_.size(); i += 2)
|
||||||
{
|
{
|
||||||
layout_box = make_horiz_pair(0, 0.0, 0, x_margin, layout.get_max_difference());
|
auto y = layout_box.maxy() + y_margin;
|
||||||
top_i = middle_ifirst - 2;
|
auto pair_box = make_horiz_pair(i, y, 1, x_margin, max_diff);
|
||||||
bottom_i = middle_ifirst + 2;
|
layout_box.expand_to_include(pair_box);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
top_i = middle_ifirst - 1;
|
|
||||||
bottom_i = middle_ifirst + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bottom_i >= 0 && top_i >= 0 && top_i < static_cast<int>(member_offsets_.size()))
|
// layout_box.center corresponds to the center of the first row;
|
||||||
{
|
// shift offsets so that the whole group is centered vertically
|
||||||
layout_box.expand_to_include(make_horiz_pair(static_cast<std::size_t>(top_i), layout_box.miny() - y_margin, -1, x_margin, layout.get_max_difference()));
|
|
||||||
layout_box.expand_to_include(make_horiz_pair(static_cast<std::size_t>(bottom_i), layout_box.maxy() + y_margin, 1, x_margin, layout.get_max_difference()));
|
|
||||||
top_i -= 2;
|
|
||||||
bottom_i += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
y_shift -= 0.5 * layout_box.height();
|
||||||
|
|
||||||
|
for (auto & offset : member_offsets_)
|
||||||
|
{
|
||||||
|
offset.y += y_shift;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -146,12 +142,12 @@ private:
|
||||||
// stores corresponding offset, and returns modified bounding box
|
// stores corresponding offset, and returns modified bounding box
|
||||||
bound_box box_offset_align(size_t i, double x, double y, int x_dir, int y_dir) const
|
bound_box box_offset_align(size_t i, double x, double y, int x_dir, int y_dir) const
|
||||||
{
|
{
|
||||||
bound_box const& box = member_boxes_[i];
|
auto box = member_boxes_[i];
|
||||||
pixel_position offset((x_dir == 0 ? x - input_origin_.x : x - (x_dir < 0 ? box.maxx() : box.minx())),
|
auto & offset = member_offsets_[i];
|
||||||
(y_dir == 0 ? y - input_origin_.y : y - (y_dir < 0 ? box.maxy() : box.miny())));
|
offset.x = x - (x_dir == 0 ? input_origin_.x : (x_dir < 0 ? box.maxx() : box.minx()));
|
||||||
|
offset.y = y - (y_dir == 0 ? input_origin_.y : (y_dir < 0 ? box.maxy() : box.miny()));
|
||||||
member_offsets_[i] = offset;
|
box.move(offset.x, offset.y);
|
||||||
return bound_box(box.minx() + offset.x, box.miny() + offset.y, box.maxx() + offset.x, box.maxy() + offset.y);
|
return box;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,6 @@ template struct MAPNIK_DECL image_dimensions<65535>;
|
||||||
|
|
||||||
} // end ns detail
|
} // end ns detail
|
||||||
|
|
||||||
template class MAPNIK_DECL image<null_t>;
|
|
||||||
template class MAPNIK_DECL image<rgba8_t>;
|
template class MAPNIK_DECL image<rgba8_t>;
|
||||||
template class MAPNIK_DECL image<gray8_t>;
|
template class MAPNIK_DECL image<gray8_t>;
|
||||||
template class MAPNIK_DECL image<gray8s_t>;
|
template class MAPNIK_DECL image<gray8s_t>;
|
||||||
|
|
|
@ -133,6 +133,7 @@ void scale_image_agg(T & target, T const& source, scaling_method_e scaling_metho
|
||||||
|
|
||||||
// create a scaling matrix
|
// create a scaling matrix
|
||||||
agg::trans_affine img_mtx;
|
agg::trans_affine img_mtx;
|
||||||
|
img_mtx *= agg::trans_affine_translation(x_off_f, y_off_f);
|
||||||
img_mtx /= agg::trans_affine_scaling(image_ratio_x, image_ratio_y);
|
img_mtx /= agg::trans_affine_scaling(image_ratio_x, image_ratio_y);
|
||||||
|
|
||||||
// create a linear interpolator for our scaling matrix
|
// create a linear interpolator for our scaling matrix
|
||||||
|
@ -141,11 +142,10 @@ void scale_image_agg(T & target, T const& source, scaling_method_e scaling_metho
|
||||||
double scaled_width = target.width();
|
double scaled_width = target.width();
|
||||||
double scaled_height = target.height();
|
double scaled_height = target.height();
|
||||||
ras.reset();
|
ras.reset();
|
||||||
ras.move_to_d(x_off_f, y_off_f);
|
ras.move_to_d(0.0, 0.0);
|
||||||
ras.line_to_d(x_off_f + scaled_width, y_off_f);
|
ras.line_to_d(scaled_width, 0.0);
|
||||||
ras.line_to_d(x_off_f + scaled_width, y_off_f + scaled_height);
|
ras.line_to_d(scaled_width, scaled_height);
|
||||||
ras.line_to_d(x_off_f, y_off_f + scaled_height);
|
ras.line_to_d(0.0, scaled_height);
|
||||||
|
|
||||||
if (scaling_method == SCALING_NEAR)
|
if (scaling_method == SCALING_NEAR)
|
||||||
{
|
{
|
||||||
using span_gen_type = typename detail::agg_scaling_traits<image_type>::span_image_filter;
|
using span_gen_type = typename detail::agg_scaling_traits<image_type>::span_image_filter;
|
||||||
|
|
|
@ -119,7 +119,6 @@ void jpeg_saver::operator() (T const& image) const
|
||||||
throw image_writer_exception("Mapnik does not support jpeg grayscale images");
|
throw image_writer_exception("Mapnik does not support jpeg grayscale images");
|
||||||
}
|
}
|
||||||
|
|
||||||
template void jpeg_saver::operator()<image_rgba8> (image_rgba8 const& image) const;
|
|
||||||
template void jpeg_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
template void jpeg_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
||||||
template void jpeg_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
template void jpeg_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
||||||
template void jpeg_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
template void jpeg_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
||||||
|
@ -130,7 +129,6 @@ template void jpeg_saver::operator()<image_gray32f> (image_gray32f const& image)
|
||||||
template void jpeg_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
template void jpeg_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
||||||
template void jpeg_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
template void jpeg_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
||||||
template void jpeg_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
template void jpeg_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
||||||
template void jpeg_saver::operator()<image_view_rgba8> (image_view_rgba8 const& image) const;
|
|
||||||
template void jpeg_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
template void jpeg_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
||||||
template void jpeg_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
template void jpeg_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
||||||
template void jpeg_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
template void jpeg_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
||||||
|
|
|
@ -316,7 +316,6 @@ void png_saver_pal::operator() (T const& image) const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template void png_saver::operator()<image_rgba8> (image_rgba8 const& image) const;
|
|
||||||
template void png_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
template void png_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
||||||
template void png_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
template void png_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
||||||
template void png_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
template void png_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
||||||
|
@ -327,7 +326,6 @@ template void png_saver::operator()<image_gray32f> (image_gray32f const& image)
|
||||||
template void png_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
template void png_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
||||||
template void png_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
template void png_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
||||||
template void png_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
template void png_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
||||||
template void png_saver::operator()<image_view_rgba8> (image_view_rgba8 const& image) const;
|
|
||||||
template void png_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
template void png_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
||||||
template void png_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
template void png_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
||||||
template void png_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
template void png_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
||||||
|
@ -338,7 +336,6 @@ template void png_saver::operator()<image_view_gray32f> (image_view_gray32f cons
|
||||||
template void png_saver::operator()<image_view_gray64> (image_view_gray64 const& image) const;
|
template void png_saver::operator()<image_view_gray64> (image_view_gray64 const& image) const;
|
||||||
template void png_saver::operator()<image_view_gray64s> (image_view_gray64s const& image) const;
|
template void png_saver::operator()<image_view_gray64s> (image_view_gray64s const& image) const;
|
||||||
template void png_saver::operator()<image_view_gray64f> (image_view_gray64f const& image) const;
|
template void png_saver::operator()<image_view_gray64f> (image_view_gray64f const& image) const;
|
||||||
template void png_saver_pal::operator()<image_rgba8> (image_rgba8 const& image) const;
|
|
||||||
template void png_saver_pal::operator()<image_gray8> (image_gray8 const& image) const;
|
template void png_saver_pal::operator()<image_gray8> (image_gray8 const& image) const;
|
||||||
template void png_saver_pal::operator()<image_gray8s> (image_gray8s const& image) const;
|
template void png_saver_pal::operator()<image_gray8s> (image_gray8s const& image) const;
|
||||||
template void png_saver_pal::operator()<image_gray16> (image_gray16 const& image) const;
|
template void png_saver_pal::operator()<image_gray16> (image_gray16 const& image) const;
|
||||||
|
@ -349,7 +346,6 @@ template void png_saver_pal::operator()<image_gray32f> (image_gray32f const& ima
|
||||||
template void png_saver_pal::operator()<image_gray64> (image_gray64 const& image) const;
|
template void png_saver_pal::operator()<image_gray64> (image_gray64 const& image) const;
|
||||||
template void png_saver_pal::operator()<image_gray64s> (image_gray64s const& image) const;
|
template void png_saver_pal::operator()<image_gray64s> (image_gray64s const& image) const;
|
||||||
template void png_saver_pal::operator()<image_gray64f> (image_gray64f const& image) const;
|
template void png_saver_pal::operator()<image_gray64f> (image_gray64f const& image) const;
|
||||||
template void png_saver_pal::operator()<image_view_rgba8> (image_view_rgba8 const& image) const;
|
|
||||||
template void png_saver_pal::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
template void png_saver_pal::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
||||||
template void png_saver_pal::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
template void png_saver_pal::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
||||||
template void png_saver_pal::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
template void png_saver_pal::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
||||||
|
|
|
@ -360,7 +360,6 @@ void webp_saver::operator() (T const& image) const
|
||||||
throw image_writer_exception("Mapnik does not support webp grayscale images");
|
throw image_writer_exception("Mapnik does not support webp grayscale images");
|
||||||
}
|
}
|
||||||
|
|
||||||
template void webp_saver::operator()<image_rgba8> (image_rgba8 const& image) const;
|
|
||||||
template void webp_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
template void webp_saver::operator()<image_gray8> (image_gray8 const& image) const;
|
||||||
template void webp_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
template void webp_saver::operator()<image_gray8s> (image_gray8s const& image) const;
|
||||||
template void webp_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
template void webp_saver::operator()<image_gray16> (image_gray16 const& image) const;
|
||||||
|
@ -371,7 +370,6 @@ template void webp_saver::operator()<image_gray32f> (image_gray32f const& image)
|
||||||
template void webp_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
template void webp_saver::operator()<image_gray64> (image_gray64 const& image) const;
|
||||||
template void webp_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
template void webp_saver::operator()<image_gray64s> (image_gray64s const& image) const;
|
||||||
template void webp_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
template void webp_saver::operator()<image_gray64f> (image_gray64f const& image) const;
|
||||||
template void webp_saver::operator()<image_view_rgba8> (image_view_rgba8 const& image) const;
|
|
||||||
template void webp_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
template void webp_saver::operator()<image_view_gray8> (image_view_gray8 const& image) const;
|
||||||
template void webp_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
template void webp_saver::operator()<image_view_gray8s> (image_view_gray8s const& image) const;
|
||||||
template void webp_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
template void webp_saver::operator()<image_view_gray16> (image_view_gray16 const& image) const;
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
template class MAPNIK_DECL image_view<image_null>;
|
|
||||||
template class MAPNIK_DECL image_view<image_rgba8>;
|
template class MAPNIK_DECL image_view<image_rgba8>;
|
||||||
template class MAPNIK_DECL image_view<image_gray8>;
|
template class MAPNIK_DECL image_view<image_gray8>;
|
||||||
template class MAPNIK_DECL image_view<image_gray8s>;
|
template class MAPNIK_DECL image_view<image_gray8s>;
|
||||||
|
|
|
@ -37,7 +37,15 @@ bool from_geojson(std::string const& json, mapnik::geometry::geometry<double> &
|
||||||
standard::space_type space;
|
standard::space_type space;
|
||||||
char const* start = json.c_str();
|
char const* start = json.c_str();
|
||||||
char const* end = start + json.length();
|
char const* end = start + json.length();
|
||||||
return qi::phrase_parse(start, end, g, space, geom);
|
try
|
||||||
|
{
|
||||||
|
if (!qi::phrase_parse(start, end, g, space, geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Can't parser GeoJSON Geometry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { return false; }
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -133,7 +133,7 @@ private:
|
||||||
void find_unused_nodes_recursive(xml_node const& node, std::string & error_text);
|
void find_unused_nodes_recursive(xml_node const& node, std::string & error_text);
|
||||||
std::string ensure_relative_to_xml(boost::optional<std::string> const& opt_path);
|
std::string ensure_relative_to_xml(boost::optional<std::string> const& opt_path);
|
||||||
void ensure_exists(std::string const& file_path);
|
void ensure_exists(std::string const& file_path);
|
||||||
void check_styles(Map const & map) const throw (config_error);
|
void check_styles(Map const & map);
|
||||||
boost::optional<color> get_opt_color_attr(boost::property_tree::ptree const& node,
|
boost::optional<color> get_opt_color_attr(boost::property_tree::ptree const& node,
|
||||||
std::string const& name);
|
std::string const& name);
|
||||||
|
|
||||||
|
@ -1155,10 +1155,14 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& node)
|
||||||
if (placement_type)
|
if (placement_type)
|
||||||
{
|
{
|
||||||
placements = placements::registry::instance().from_xml(*placement_type, node, fontsets_, true);
|
placements = placements::registry::instance().from_xml(*placement_type, node, fontsets_, true);
|
||||||
} else {
|
if (!placements)
|
||||||
placements = std::make_shared<text_placements_dummy>();
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
placements = std::make_shared<text_placements_dummy>();
|
||||||
|
placements->defaults.from_xml(node, fontsets_, true);
|
||||||
}
|
}
|
||||||
placements->defaults.from_xml(node, fontsets_, true);
|
|
||||||
if (strict_ &&
|
if (strict_ &&
|
||||||
!placements->defaults.format_defaults.fontset)
|
!placements->defaults.format_defaults.fontset)
|
||||||
{
|
{
|
||||||
|
@ -1691,7 +1695,7 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_parser::check_styles(Map const & map) const throw (config_error)
|
void map_parser::check_styles(Map const & map)
|
||||||
{
|
{
|
||||||
for (auto const & layer : map.layers())
|
for (auto const & layer : map.layers())
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,7 @@ void render_group_symbolizer(group_symbolizer const& sym,
|
||||||
|
|
||||||
// keep track of which lists of render thunks correspond to
|
// keep track of which lists of render thunks correspond to
|
||||||
// entries in the group_layout_manager.
|
// entries in the group_layout_manager.
|
||||||
std::vector<render_thunk_list> layout_thunks;
|
std::list<render_thunk_list> layout_thunks;
|
||||||
|
|
||||||
// layout manager to store and arrange bboxes of matched features
|
// layout manager to store and arrange bboxes of matched features
|
||||||
group_layout_manager layout_manager(props->get_layout());
|
group_layout_manager layout_manager(props->get_layout());
|
||||||
|
@ -182,11 +182,13 @@ void render_group_symbolizer(group_symbolizer const& sym,
|
||||||
pixel_position_list const& positions = helper.get();
|
pixel_position_list const& positions = helper.get();
|
||||||
for (pixel_position const& pos : positions)
|
for (pixel_position const& pos : positions)
|
||||||
{
|
{
|
||||||
for (size_t layout_i = 0; layout_i < layout_thunks.size(); ++layout_i)
|
size_t layout_i = 0;
|
||||||
|
for (auto const& thunks : layout_thunks)
|
||||||
{
|
{
|
||||||
pixel_position const& offset = layout_manager.offset_at(layout_i);
|
pixel_position const& offset = layout_manager.offset_at(layout_i);
|
||||||
pixel_position render_offset = pos + offset;
|
pixel_position render_offset = pos + offset;
|
||||||
render_thunks.render_list(layout_thunks[layout_i], render_offset);
|
render_thunks.render_list(thunks, render_offset);
|
||||||
|
++layout_i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct thunk_markers_renderer_context : markers_renderer_context
|
||||||
{
|
{
|
||||||
vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity,
|
vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity,
|
||||||
comp_op_, params.snap_to_pixels);
|
comp_op_, params.snap_to_pixels);
|
||||||
thunks_.push_back(std::make_unique<render_thunk>(std::move(thunk)));
|
thunks_.emplace_back(std::move(thunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render_marker(image_rgba8 const& src,
|
virtual void render_marker(image_rgba8 const& src,
|
||||||
|
@ -64,7 +64,7 @@ struct thunk_markers_renderer_context : markers_renderer_context
|
||||||
{
|
{
|
||||||
raster_marker_render_thunk thunk(src, marker_tr, params.opacity,
|
raster_marker_render_thunk thunk(src, marker_tr, params.opacity,
|
||||||
comp_op_, params.snap_to_pixels);
|
comp_op_, params.snap_to_pixels);
|
||||||
thunks_.push_back(std::make_unique<render_thunk>(std::move(thunk)));
|
thunks_.emplace_back(std::move(thunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -128,7 +128,7 @@ void render_thunk_extractor::extract_text_thunk(text_render_thunk::helper_ptr &&
|
||||||
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL);
|
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL);
|
||||||
|
|
||||||
text_render_thunk thunk(std::move(helper), opacity, comp_op, halo_rasterizer);
|
text_render_thunk thunk(std::move(helper), opacity, comp_op, halo_rasterizer);
|
||||||
thunks_.push_back(std::make_unique<render_thunk>(std::move(thunk)));
|
thunks_.emplace_back(std::move(thunk));
|
||||||
|
|
||||||
update_box();
|
update_box();
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,23 +187,26 @@ base_symbolizer_helper::base_symbolizer_helper(
|
||||||
initialize_points();
|
initialize_points();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct largest_bbox_first
|
template <typename It>
|
||||||
|
static It largest_bbox(It begin, It end)
|
||||||
{
|
{
|
||||||
bool operator() (geometry::geometry<double> const* g0, geometry::geometry<double> const* g1) const
|
if (begin == end)
|
||||||
{
|
{
|
||||||
box2d<double> b0 = geometry::envelope(*g0);
|
return end;
|
||||||
box2d<double> b1 = geometry::envelope(*g1);
|
|
||||||
return b0.width() * b0.height() > b1.width() * b1.height();
|
|
||||||
}
|
}
|
||||||
bool operator() (base_symbolizer_helper::geometry_cref const& g0,
|
It largest_geom = begin;
|
||||||
base_symbolizer_helper::geometry_cref const& g1) const
|
double largest_bbox = geometry::envelope(*largest_geom).area();
|
||||||
|
for (++begin; begin != end; ++begin)
|
||||||
{
|
{
|
||||||
// TODO - this has got to be expensive! Can we cache bbox's if there are repeated calls to same geom?
|
double bbox = geometry::envelope(*begin).area();
|
||||||
box2d<double> b0 = geometry::envelope(g0);
|
if (bbox > largest_bbox)
|
||||||
box2d<double> b1 = geometry::envelope(g1);
|
{
|
||||||
return b0.width() * b0.height() > b1.width() * b1.height();
|
largest_bbox = bbox;
|
||||||
|
largest_geom = begin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
return largest_geom;
|
||||||
|
}
|
||||||
|
|
||||||
void base_symbolizer_helper::initialize_geometries() const
|
void base_symbolizer_helper::initialize_geometries() const
|
||||||
{
|
{
|
||||||
|
@ -216,10 +219,16 @@ void base_symbolizer_helper::initialize_geometries() const
|
||||||
type == geometry::geometry_types::MultiPolygon)
|
type == geometry::geometry_types::MultiPolygon)
|
||||||
{
|
{
|
||||||
bool largest_box_only = text_props_->largest_bbox_only;
|
bool largest_box_only = text_props_->largest_bbox_only;
|
||||||
if (largest_box_only)
|
if (largest_box_only && geometries_to_process_.size() > 1)
|
||||||
{
|
{
|
||||||
geometries_to_process_.sort(largest_bbox_first());
|
auto largest_geom = largest_bbox(
|
||||||
|
geometries_to_process_.begin(),
|
||||||
|
geometries_to_process_.end());
|
||||||
geo_itr_ = geometries_to_process_.begin();
|
geo_itr_ = geometries_to_process_.begin();
|
||||||
|
if (geo_itr_ != largest_geom)
|
||||||
|
{
|
||||||
|
std::swap(*geo_itr_, *largest_geom);
|
||||||
|
}
|
||||||
geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end());
|
geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Artem Pavlenko
|
* Copyright (C) 2017 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -162,8 +162,12 @@ private:
|
||||||
tiff_reader(const tiff_reader&);
|
tiff_reader(const tiff_reader&);
|
||||||
tiff_reader& operator=(const tiff_reader&);
|
tiff_reader& operator=(const tiff_reader&);
|
||||||
void init();
|
void init();
|
||||||
void read_generic(std::size_t x,std::size_t y,image_rgba8& image);
|
|
||||||
void read_stripped(std::size_t x,std::size_t y,image_rgba8& image);
|
template <typename ImageData>
|
||||||
|
void read_generic(std::size_t x,std::size_t y, ImageData & image);
|
||||||
|
|
||||||
|
template <typename ImageData>
|
||||||
|
void read_stripped(std::size_t x,std::size_t y, ImageData & image);
|
||||||
|
|
||||||
template <typename ImageData>
|
template <typename ImageData>
|
||||||
void read_tiled(std::size_t x,std::size_t y, ImageData & image);
|
void read_tiled(std::size_t x,std::size_t y, ImageData & image);
|
||||||
|
@ -257,25 +261,24 @@ void tiff_reader<T>::init()
|
||||||
TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photometric_);
|
TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photometric_);
|
||||||
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &bands_);
|
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &bands_);
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "bits per sample: " << bps_;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "bits per sample: " << bps_ ;
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "sample format: " << sample_format_;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "sample format: " << sample_format_ ;
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "photometric: " << photometric_;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "photometric: " << photometric_ ;
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "bands: " << bands_;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "bands: " << bands_ ;
|
||||||
|
|
||||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width_);
|
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width_);
|
||||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height_);
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height_);
|
||||||
|
|
||||||
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar_config_);
|
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar_config_);
|
||||||
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression_ );
|
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression_ );
|
||||||
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip_);
|
|
||||||
|
|
||||||
std::uint16_t orientation;
|
std::uint16_t orientation;
|
||||||
if (TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation) == 0)
|
if (TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation) == 0)
|
||||||
{
|
{
|
||||||
orientation = 1;
|
orientation = 1;
|
||||||
}
|
}
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "orientation: " << orientation;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "orientation: " << orientation ;
|
||||||
|
MAPNIK_LOG_DEBUG(tiff_reader) << "planar-config: " << planar_config_ ;
|
||||||
is_tiled_ = TIFFIsTiled(tif);
|
is_tiled_ = TIFFIsTiled(tif);
|
||||||
|
|
||||||
if (is_tiled_)
|
if (is_tiled_)
|
||||||
|
@ -285,7 +288,7 @@ void tiff_reader<T>::init()
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "tiff is tiled";
|
MAPNIK_LOG_DEBUG(tiff_reader) << "tiff is tiled";
|
||||||
read_method_ = tiled;
|
read_method_ = tiled;
|
||||||
}
|
}
|
||||||
else if (TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rows_per_strip_)!=0)
|
else if (TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip_) != 0)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "tiff is stripped";
|
MAPNIK_LOG_DEBUG(tiff_reader) << "tiff is stripped";
|
||||||
read_method_ = stripped;
|
read_method_ = stripped;
|
||||||
|
@ -311,9 +314,9 @@ void tiff_reader<T>::init()
|
||||||
if (TIFFGetField(tif, 33550, &count, &pixelscale) == 1 && count == 3
|
if (TIFFGetField(tif, 33550, &count, &pixelscale) == 1 && count == 3
|
||||||
&& TIFFGetField(tif, 33922 , &count, &tilepoint) == 1 && count == 6)
|
&& TIFFGetField(tif, 33922 , &count, &tilepoint) == 1 && count == 6)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "PixelScale:" << pixelscale[0] << "," << pixelscale[1] << "," << pixelscale[2];
|
MAPNIK_LOG_DEBUG(tiff_reader) << "PixelScale:" << pixelscale[0] << "," << pixelscale[1] << "," << pixelscale[2] ;
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "TilePoint:" << tilepoint[0] << "," << tilepoint[1] << "," << tilepoint[2];
|
MAPNIK_LOG_DEBUG(tiff_reader) << "TilePoint:" << tilepoint[0] << "," << tilepoint[1] << "," << tilepoint[2] ;
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << " " << tilepoint[3] << "," << tilepoint[4] << "," << tilepoint[5];
|
MAPNIK_LOG_DEBUG(tiff_reader) << " " << tilepoint[3] << "," << tilepoint[4] << "," << tilepoint[5] ;
|
||||||
|
|
||||||
// assuming upper-left
|
// assuming upper-left
|
||||||
double lox = tilepoint[3];
|
double lox = tilepoint[3];
|
||||||
|
@ -321,7 +324,7 @@ void tiff_reader<T>::init()
|
||||||
double hix = lox + pixelscale[0] * width_;
|
double hix = lox + pixelscale[0] * width_;
|
||||||
double hiy = loy - pixelscale[1] * height_;
|
double hiy = loy - pixelscale[1] * height_;
|
||||||
bbox_.reset(box2d<double>(lox, loy, hix, hiy));
|
bbox_.reset(box2d<double>(lox, loy, hix, hiy));
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "Bounding Box:" << *bbox_;
|
MAPNIK_LOG_DEBUG(tiff_reader) << "Bounding Box:" << *bbox_ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -391,10 +394,17 @@ image_any tiff_reader<T>::read_any_gray(std::size_t x0, std::size_t y0, std::siz
|
||||||
using pixel_type = typename image_type::pixel_type;
|
using pixel_type = typename image_type::pixel_type;
|
||||||
if (read_method_ == tiled)
|
if (read_method_ == tiled)
|
||||||
{
|
{
|
||||||
image_type data(width,height);
|
image_type data(width, height);
|
||||||
read_tiled<image_type>(x0, y0, data);
|
read_tiled<image_type>(x0, y0, data);
|
||||||
return image_any(std::move(data));
|
return image_any(std::move(data));
|
||||||
}
|
}
|
||||||
|
// TODO: temp disable and default to `scanline` method for stripped images.
|
||||||
|
else if (read_method_ == stripped)
|
||||||
|
{
|
||||||
|
image_type data(width, height);
|
||||||
|
read_stripped<image_type>(x0, y0, data);
|
||||||
|
return image_any(std::move(data));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TIFF* tif = open(stream_);
|
TIFF* tif = open(stream_);
|
||||||
|
@ -407,14 +417,52 @@ image_any tiff_reader<T>::read_any_gray(std::size_t x0, std::size_t y0, std::siz
|
||||||
std::size_t start_x = x0;
|
std::size_t start_x = x0;
|
||||||
std::size_t end_x = std::min(x0 + width, width_);
|
std::size_t end_x = std::min(x0 + width, width_);
|
||||||
std::size_t element_size = sizeof(pixel_type);
|
std::size_t element_size = sizeof(pixel_type);
|
||||||
|
MAPNIK_LOG_DEBUG(tiff_reader) << "SCANLINE SIZE=" << TIFFScanlineSize(tif);
|
||||||
std::size_t size_to_allocate = (TIFFScanlineSize(tif) + element_size - 1)/element_size;
|
std::size_t size_to_allocate = (TIFFScanlineSize(tif) + element_size - 1)/element_size;
|
||||||
const std::unique_ptr<pixel_type[]> scanline(new pixel_type[size_to_allocate]);
|
std::unique_ptr<pixel_type[]> const scanline(new pixel_type[size_to_allocate]);
|
||||||
for (std::size_t y = start_y; y < end_y; ++y)
|
if (planar_config_ == PLANARCONFIG_CONTIG)
|
||||||
{
|
{
|
||||||
if (-1 != TIFFReadScanline(tif, scanline.get(), y) && (y >= y0))
|
for (std::size_t y = start_y; y < end_y; ++y)
|
||||||
{
|
{
|
||||||
pixel_type * row = data.get_row(y - y0);
|
// we have to read all scanlines sequentially from start_y
|
||||||
std::transform(scanline.get() + start_x, scanline.get() + end_x, row, [](pixel_type const& p) { return p;});
|
// to be able to use scanline interface with compressed blocks.
|
||||||
|
if (-1 != TIFFReadScanline(tif, scanline.get(), y) && (y >= y0))
|
||||||
|
{
|
||||||
|
pixel_type * row = data.get_row(y - y0);
|
||||||
|
if (bands_ == 1)
|
||||||
|
{
|
||||||
|
std::transform(scanline.get() + start_x, scanline.get() + end_x, row, [](pixel_type const& p) { return p;});
|
||||||
|
}
|
||||||
|
else if (size_to_allocate == bands_ * width_)
|
||||||
|
{
|
||||||
|
// bands_ > 1 => packed bands in grayscale image e.g an extra alpha channel.
|
||||||
|
// Just pick first one for now.
|
||||||
|
pixel_type * buf = scanline.get() + start_x * bands_;
|
||||||
|
std::size_t x_index = 0;
|
||||||
|
for (std::size_t j = 0; j < end_x * bands_; ++j)
|
||||||
|
{
|
||||||
|
if (x_index >= width) break;
|
||||||
|
if (j % bands_ == 0)
|
||||||
|
{
|
||||||
|
row[x_index++] = buf[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (planar_config_ == PLANARCONFIG_SEPARATE)
|
||||||
|
{
|
||||||
|
for (std::size_t s = 0 ; s < bands_ ; ++s)
|
||||||
|
{
|
||||||
|
for (std::size_t y = start_y; y < end_y; ++y)
|
||||||
|
{
|
||||||
|
if (-1 != TIFFReadScanline(tif, scanline.get(), y) && (y >= y0))
|
||||||
|
{
|
||||||
|
pixel_type * row = data.get_row(y - y0);
|
||||||
|
std::transform(scanline.get() + start_x, scanline.get() + end_x, row, [](pixel_type const& p) { return p;});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return image_any(std::move(data));
|
return image_any(std::move(data));
|
||||||
|
@ -446,9 +494,17 @@ struct tiff_reader_traits
|
||||||
{
|
{
|
||||||
using image_type = T;
|
using image_type = T;
|
||||||
using pixel_type = typename image_type::pixel_type;
|
using pixel_type = typename image_type::pixel_type;
|
||||||
|
|
||||||
|
constexpr static bool reverse = false;
|
||||||
static bool read_tile(TIFF * tif, std::size_t x, std::size_t y, pixel_type* buf, std::size_t tile_width, std::size_t tile_height)
|
static bool read_tile(TIFF * tif, std::size_t x, std::size_t y, pixel_type* buf, std::size_t tile_width, std::size_t tile_height)
|
||||||
{
|
{
|
||||||
return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x,y,0,0), buf, tile_width * tile_height * sizeof(pixel_type)) != -1);
|
std::uint32_t tile_size = TIFFTileSize(tif);
|
||||||
|
return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, 0, 0), buf, tile_size) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read_strip(TIFF * tif, std::size_t y, std::size_t rows_per_strip, std::size_t strip_width, pixel_type * buf)
|
||||||
|
{
|
||||||
|
return (TIFFReadEncodedStrip(tif, y/rows_per_strip, buf, -1) != -1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -456,18 +512,17 @@ struct tiff_reader_traits
|
||||||
template <>
|
template <>
|
||||||
struct tiff_reader_traits<image_rgba8>
|
struct tiff_reader_traits<image_rgba8>
|
||||||
{
|
{
|
||||||
|
using image_type = image_rgba8;
|
||||||
using pixel_type = std::uint32_t;
|
using pixel_type = std::uint32_t;
|
||||||
|
constexpr static bool reverse = true;
|
||||||
static bool read_tile(TIFF * tif, std::size_t x0, std::size_t y0, pixel_type* buf, std::size_t tile_width, std::size_t tile_height)
|
static bool read_tile(TIFF * tif, std::size_t x0, std::size_t y0, pixel_type* buf, std::size_t tile_width, std::size_t tile_height)
|
||||||
{
|
{
|
||||||
if (TIFFReadRGBATile(tif, x0, y0, buf) != -1)
|
return (TIFFReadRGBATile(tif, x0, y0, buf) != 0);
|
||||||
{
|
}
|
||||||
for (std::size_t y = 0; y < tile_height/2; ++y)
|
|
||||||
{
|
static bool read_strip(TIFF * tif, std::size_t y, std::size_t rows_per_strip, std::size_t strip_width, pixel_type * buf)
|
||||||
std::swap_ranges(buf + y * tile_width, buf + (y + 1) * tile_width, buf + (tile_height - y - 1) * tile_width);
|
{
|
||||||
}
|
return (TIFFReadRGBAStrip(tif, y, buf) != 0);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -591,7 +646,8 @@ image_any tiff_reader<T>::read(unsigned x, unsigned y, unsigned width, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void tiff_reader<T>::read_generic(std::size_t, std::size_t, image_rgba8&)
|
template <typename ImageData>
|
||||||
|
void tiff_reader<T>::read_generic(std::size_t, std::size_t, ImageData &)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("tiff_reader: TODO - tiff is not stripped or tiled");
|
throw std::runtime_error("tiff_reader: TODO - tiff is not stripped or tiled");
|
||||||
}
|
}
|
||||||
|
@ -605,7 +661,8 @@ void tiff_reader<T>::read_tiled(std::size_t x0,std::size_t y0, ImageData & image
|
||||||
TIFF* tif = open(stream_);
|
TIFF* tif = open(stream_);
|
||||||
if (tif)
|
if (tif)
|
||||||
{
|
{
|
||||||
std::unique_ptr<pixel_type[]> buf(new pixel_type[tile_width_*tile_height_]);
|
std::uint32_t tile_size = TIFFTileSize(tif);
|
||||||
|
std::unique_ptr<pixel_type[]> tile(new pixel_type[tile_size]);
|
||||||
std::size_t width = image.width();
|
std::size_t width = image.width();
|
||||||
std::size_t height = image.height();
|
std::size_t height = image.height();
|
||||||
std::size_t start_y = (y0 / tile_height_) * tile_height_;
|
std::size_t start_y = (y0 / tile_height_) * tile_height_;
|
||||||
|
@ -614,7 +671,7 @@ void tiff_reader<T>::read_tiled(std::size_t x0,std::size_t y0, ImageData & image
|
||||||
std::size_t end_x = ((x0 + width) / tile_width_ + 1) * tile_width_;
|
std::size_t end_x = ((x0 + width) / tile_width_ + 1) * tile_width_;
|
||||||
end_y = std::min(end_y, height_);
|
end_y = std::min(end_y, height_);
|
||||||
end_x = std::min(end_x, width_);
|
end_x = std::min(end_x, width_);
|
||||||
|
bool pick_first_band = (bands_ > 1) && (tile_size / (tile_width_ * tile_height_ * sizeof(pixel_type)) == bands_);
|
||||||
for (std::size_t y = start_y; y < end_y; y += tile_height_)
|
for (std::size_t y = start_y; y < end_y; y += tile_height_)
|
||||||
{
|
{
|
||||||
std::size_t ty0 = std::max(y0, y) - y;
|
std::size_t ty0 = std::max(y0, y) - y;
|
||||||
|
@ -622,56 +679,98 @@ void tiff_reader<T>::read_tiled(std::size_t x0,std::size_t y0, ImageData & image
|
||||||
|
|
||||||
for (std::size_t x = start_x; x < end_x; x += tile_width_)
|
for (std::size_t x = start_x; x < end_x; x += tile_width_)
|
||||||
{
|
{
|
||||||
if (!detail::tiff_reader_traits<ImageData>::read_tile(tif, x, y, buf.get(), tile_width_, tile_height_))
|
if (!detail::tiff_reader_traits<ImageData>::read_tile(tif, x, y, tile.get(), tile_width_, tile_height_))
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "read_tile(...) failed at " << x << "/" << y << " for " << width_ << "/" << height_ << "\n";
|
MAPNIK_LOG_DEBUG(tiff_reader) << "read_tile(...) failed at " << x << "/" << y << " for " << width_ << "/" << height_ << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (pick_first_band)
|
||||||
|
{
|
||||||
|
std::uint32_t size = tile_width_ * tile_height_ * sizeof(pixel_type);
|
||||||
|
for (std::uint32_t n = 0; n < size; ++n)
|
||||||
|
{
|
||||||
|
tile[n] = tile[n * bands_];
|
||||||
|
}
|
||||||
|
}
|
||||||
std::size_t tx0 = std::max(x0, x);
|
std::size_t tx0 = std::max(x0, x);
|
||||||
std::size_t tx1 = std::min(width + x0, x + tile_width_);
|
std::size_t tx1 = std::min(width + x0, x + tile_width_);
|
||||||
std::size_t row = y + ty0 - y0;
|
std::size_t row_index = y + ty0 - y0;
|
||||||
for (std::size_t ty = ty0; ty < ty1; ++ty, ++row)
|
|
||||||
|
if (detail::tiff_reader_traits<ImageData>::reverse)
|
||||||
{
|
{
|
||||||
image.set_row(row, tx0 - x0, tx1 - x0, &buf[ty * tile_width_ + tx0 - x]);
|
for (std::size_t ty = ty0; ty < ty1; ++ty, ++row_index)
|
||||||
|
{
|
||||||
|
// This is in reverse because the TIFFReadRGBATile reads are inverted
|
||||||
|
image.set_row(row_index, tx0 - x0, tx1 - x0, &tile[(tile_height_ - ty - 1) * tile_width_ + tx0 - x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (std::size_t ty = ty0; ty < ty1; ++ty, ++row_index)
|
||||||
|
{
|
||||||
|
image.set_row(row_index, tx0 - x0, tx1 - x0, &tile[ty * tile_width_ + tx0 - x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void tiff_reader<T>::read_stripped(std::size_t x0,std::size_t y0,image_rgba8& image)
|
template <typename ImageData>
|
||||||
|
void tiff_reader<T>::read_stripped(std::size_t x0, std::size_t y0, ImageData & image)
|
||||||
{
|
{
|
||||||
|
using pixel_type = typename detail::tiff_reader_traits<ImageData>::pixel_type;
|
||||||
TIFF* tif = open(stream_);
|
TIFF* tif = open(stream_);
|
||||||
if (tif)
|
if (tif)
|
||||||
{
|
{
|
||||||
image_rgba8 strip(width_,rows_per_strip_,false);
|
std::uint32_t strip_size = TIFFStripSize(tif);
|
||||||
std::size_t width=image.width();
|
std::unique_ptr<pixel_type[]> strip(new pixel_type[strip_size]);
|
||||||
std::size_t height=image.height();
|
std::size_t width = image.width();
|
||||||
|
std::size_t height = image.height();
|
||||||
|
|
||||||
std::size_t start_y=(y0/rows_per_strip_)*rows_per_strip_;
|
std::size_t start_y = (y0 / rows_per_strip_) * rows_per_strip_;
|
||||||
std::size_t end_y=std::min(y0+height, height_);
|
std::size_t end_y = std::min(y0 + height, height_);
|
||||||
std::size_t tx0,tx1,ty0,ty1;
|
std::size_t tx0, tx1, ty0, ty1;
|
||||||
|
|
||||||
tx0=x0;
|
tx0 = x0;
|
||||||
tx1=std::min(width+x0,width_);
|
tx1 = std::min(width + x0, width_);
|
||||||
std::size_t row = 0;
|
std::size_t row = 0;
|
||||||
for (std::size_t y=start_y; y < end_y; y+=rows_per_strip_)
|
bool pick_first_band = (bands_ > 1) && (strip_size / (width_ * rows_per_strip_ * sizeof(pixel_type)) == bands_);
|
||||||
|
for (std::size_t y = start_y; y < end_y; y += rows_per_strip_)
|
||||||
{
|
{
|
||||||
ty0 = std::max(y0,y)-y;
|
ty0 = std::max(y0, y) - y;
|
||||||
ty1 = std::min(end_y,y+rows_per_strip_)-y;
|
ty1 = std::min(end_y, y + rows_per_strip_) - y;
|
||||||
|
|
||||||
if (!TIFFReadRGBAStrip(tif,y,strip.data()))
|
if (!detail::tiff_reader_traits<ImageData>::read_strip(tif, y, rows_per_strip_, width_, strip.get()))
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(tiff_reader) << "TIFFReadRGBAStrip failed at " << y << " for " << width_ << "/" << height_ << "\n";
|
MAPNIK_LOG_DEBUG(tiff_reader) << "TIFFRead(Encoded|RGBA)Strip failed at " << y << " for " << width_ << "/" << height_ << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// This is in reverse because the TIFFReadRGBAStrip reads inverted
|
if (pick_first_band)
|
||||||
for (std::size_t ty = ty1; ty > ty0; --ty)
|
|
||||||
{
|
{
|
||||||
image.set_row(row,tx0-x0,tx1-x0,&strip.data()[(ty-1)*width_+tx0]);
|
std::uint32_t size = width_ * rows_per_strip_ * sizeof(pixel_type);
|
||||||
++row;
|
for (std::uint32_t n = 0; n < size; ++n)
|
||||||
|
{
|
||||||
|
strip[n] = strip[bands_ * n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detail::tiff_reader_traits<ImageData>::reverse)
|
||||||
|
{
|
||||||
|
std::size_t num_rows = std::min(end_y - y, static_cast<std::size_t>(rows_per_strip_));
|
||||||
|
for (std::size_t ty = ty0; ty < ty1; ++ty)
|
||||||
|
{
|
||||||
|
// This is in reverse because the TIFFReadRGBAStrip reads are inverted
|
||||||
|
image.set_row(row++, tx0 - x0, tx1 - x0, &strip[(num_rows - ty - 1) * width_ + tx0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (std::size_t ty = ty0; ty < ty1; ++ty)
|
||||||
|
{
|
||||||
|
image.set_row(row++, tx0 - x0, tx1 - x0, &strip[ty * width_ + tx0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,13 +133,13 @@ node_not_found::node_not_found(std::string const& node_name)
|
||||||
: node_name_(node_name),
|
: node_name_(node_name),
|
||||||
msg_() {}
|
msg_() {}
|
||||||
|
|
||||||
const char* node_not_found::what() const throw()
|
const char* node_not_found::what() const noexcept
|
||||||
{
|
{
|
||||||
msg_ = std::string("Node "+node_name_+ "not found");
|
msg_ = std::string("Node "+node_name_+ "not found");
|
||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
node_not_found::~node_not_found() throw() {}
|
node_not_found::~node_not_found() {}
|
||||||
|
|
||||||
|
|
||||||
attribute_not_found::attribute_not_found(std::string const& node_name,
|
attribute_not_found::attribute_not_found(std::string const& node_name,
|
||||||
|
@ -148,25 +148,25 @@ attribute_not_found::attribute_not_found(std::string const& node_name,
|
||||||
attribute_name_(attribute_name),
|
attribute_name_(attribute_name),
|
||||||
msg_() {}
|
msg_() {}
|
||||||
|
|
||||||
const char* attribute_not_found::what() const throw()
|
const char* attribute_not_found::what() const noexcept
|
||||||
{
|
{
|
||||||
msg_ = std::string("Attribute '" + attribute_name_ +"' not found in node '"+node_name_+ "'");
|
msg_ = std::string("Attribute '" + attribute_name_ +"' not found in node '"+node_name_+ "'");
|
||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_not_found::~attribute_not_found() throw() {}
|
attribute_not_found::~attribute_not_found() {}
|
||||||
|
|
||||||
more_than_one_child::more_than_one_child(std::string const& node_name)
|
more_than_one_child::more_than_one_child(std::string const& node_name)
|
||||||
: node_name_(node_name),
|
: node_name_(node_name),
|
||||||
msg_() {}
|
msg_() {}
|
||||||
|
|
||||||
const char* more_than_one_child::what() const throw()
|
const char* more_than_one_child::what() const noexcept
|
||||||
{
|
{
|
||||||
msg_ = std::string("More than one child node in node '" + node_name_ +"'");
|
msg_ = std::string("More than one child node in node '" + node_name_ +"'");
|
||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
more_than_one_child::~more_than_one_child() throw() {}
|
more_than_one_child::~more_than_one_child() {}
|
||||||
|
|
||||||
xml_node::xml_node(xml_tree &tree, std::string && name, unsigned line, bool is_text)
|
xml_node::xml_node(xml_tree &tree, std::string && name, unsigned line, bool is_text)
|
||||||
: tree_(tree),
|
: tree_(tree),
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6ce59adfc4f11b16a5dc0e2020c36dc614850989
|
Subproject commit da43561d111b3539c09dbb9622fb0743e2d99973
|
|
@ -1 +1 @@
|
||||||
Subproject commit 941db3d00920dc7aceaa6797096a7228bc7bac14
|
Subproject commit c3879224d25d01571e8e803180ae15c31bbf6b24
|
|
@ -284,16 +284,19 @@ SECTION("to string") {
|
||||||
REQUIRE( string2bool("true",val) );
|
REQUIRE( string2bool("true",val) );
|
||||||
REQUIRE( val == true );
|
REQUIRE( val == true );
|
||||||
|
|
||||||
// mapnik::value hashability
|
// mapnik::value hash() and operator== works for all T in value<Types...>
|
||||||
using values_container = std::unordered_map<mapnik::value, unsigned>;
|
mapnik::transcoder tr("utf8");
|
||||||
|
using values_container = std::unordered_map<mapnik::value, mapnik::value>;
|
||||||
values_container vc;
|
values_container vc;
|
||||||
mapnik::value val2(1);
|
mapnik::value keys[5] = {true, 123456789, 3.14159f, tr.transcode("Мапник"), mapnik::value_null()} ;
|
||||||
vc[val2] = 1;
|
for (auto const& k : keys)
|
||||||
REQUIRE( vc[1] == static_cast<int>(1) );
|
{
|
||||||
|
vc.insert({k, k});
|
||||||
|
REQUIRE( vc[k] == k );
|
||||||
|
}
|
||||||
|
|
||||||
// mapnik::value << to ostream
|
// mapnik::value << to ostream
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
mapnik::transcoder tr("utf-8");
|
|
||||||
mapnik::value_unicode_string ustr = tr.transcode("hello world!");
|
mapnik::value_unicode_string ustr = tr.transcode("hello world!");
|
||||||
mapnik::value streamable(ustr);
|
mapnik::value streamable(ustr);
|
||||||
s << streamable;
|
s << streamable;
|
||||||
|
|
|
@ -28,9 +28,11 @@
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
#include <mapnik/geometry.hpp>
|
#include <mapnik/geometry.hpp>
|
||||||
#include <mapnik/geometry_type.hpp>
|
#include <mapnik/geometry_type.hpp>
|
||||||
|
#include <mapnik/json/geometry_parser.hpp> // from_geojson
|
||||||
|
#include <mapnik/util/geometry_to_geojson.hpp>
|
||||||
#include <mapnik/util/fs.hpp>
|
#include <mapnik/util/fs.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <algorithm>
|
||||||
#include <boost/optional/optional_io.hpp>
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,6 +117,50 @@ TEST_CASE("geojson") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("GeoJSON empty Geometries handling")
|
||||||
|
{
|
||||||
|
auto valid_empty_geometries =
|
||||||
|
{
|
||||||
|
"null", // Point can't be empty
|
||||||
|
"{ \"type\": \"LineString\", \"coordinates\": [] }",
|
||||||
|
"{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ",
|
||||||
|
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }",
|
||||||
|
"{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }",
|
||||||
|
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& in : valid_empty_geometries)
|
||||||
|
{
|
||||||
|
std::string json(in);
|
||||||
|
mapnik::geometry::geometry<double> geom;
|
||||||
|
CHECK(mapnik::json::from_geojson(json, geom));
|
||||||
|
// round trip
|
||||||
|
std::string json_out;
|
||||||
|
CHECK(mapnik::util::to_geojson(json_out, geom));
|
||||||
|
json.erase(std::remove_if(
|
||||||
|
std::begin(json), std::end(json),
|
||||||
|
[](char ch) { return std::isspace(ch, std::locale{}); }
|
||||||
|
), std::end(json));
|
||||||
|
REQUIRE(json == json_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto invalid_empty_geometries =
|
||||||
|
{
|
||||||
|
"{ \"type\": \"Point\", \"coordinates\": [] }",
|
||||||
|
"{ \"type\": \"LineString\", \"coordinates\": [[]] }"
|
||||||
|
"{ \"type\": \"Polygon\", \"coordinates\": [[[]]] }",
|
||||||
|
"{ \"type\": \"MultiPoint\", \"coordinates\": [[]] }",
|
||||||
|
"{ \"type\": \"MultiLineString\", \"coordinates\": [[[]]] }",
|
||||||
|
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[[[]]]] }"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& json : invalid_empty_geometries)
|
||||||
|
{
|
||||||
|
mapnik::geometry::geometry<double> geom;
|
||||||
|
CHECK(!mapnik::json::from_geojson(json, geom));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("GeoJSON num_features_to_query")
|
SECTION("GeoJSON num_features_to_query")
|
||||||
{
|
{
|
||||||
std::string filename = "./test/data/json/featurecollection-multipleprops.geojson";
|
std::string filename = "./test/data/json/featurecollection-multipleprops.geojson";
|
||||||
|
@ -514,7 +560,8 @@ TEST_CASE("geojson") {
|
||||||
|
|
||||||
for (auto const& c_str : {"./test/data/json/feature-malformed-1.geojson",
|
for (auto const& c_str : {"./test/data/json/feature-malformed-1.geojson",
|
||||||
"./test/data/json/feature-malformed-2.geojson",
|
"./test/data/json/feature-malformed-2.geojson",
|
||||||
"./test/data/json/feature-malformed-3.geojson"})
|
"./test/data/json/feature-malformed-3.geojson",
|
||||||
|
"./test/data/json/feature-malformed-4.geojson"})
|
||||||
{
|
{
|
||||||
std::string filename(c_str);
|
std::string filename(c_str);
|
||||||
params["file"] = filename;
|
params["file"] = filename;
|
||||||
|
@ -554,43 +601,45 @@ TEST_CASE("geojson") {
|
||||||
|
|
||||||
SECTION("GeoJSON ensure mapnik::featureset::next() throws on malformed input")
|
SECTION("GeoJSON ensure mapnik::featureset::next() throws on malformed input")
|
||||||
{
|
{
|
||||||
std::string filename{"./test/data/json/featurecollection-malformed.json"};
|
|
||||||
mapnik::parameters params;
|
mapnik::parameters params;
|
||||||
params["type"] = "geojson";
|
params["type"] = "geojson";
|
||||||
params["file"] = filename;
|
for (auto const& c_str : {"./test/data/json/featurecollection-malformed.json"})
|
||||||
|
|
||||||
// cleanup in the case of a failed previous run
|
|
||||||
if (mapnik::util::exists(filename + ".index"))
|
|
||||||
{
|
{
|
||||||
mapnik::util::remove(filename + ".index");
|
std::string filename(c_str);
|
||||||
}
|
params["file"] = filename;
|
||||||
|
// cleanup in the case of a failed previous run
|
||||||
|
if (mapnik::util::exists(filename + ".index"))
|
||||||
|
{
|
||||||
|
mapnik::util::remove(filename + ".index");
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(!mapnik::util::exists(filename + ".index"));
|
CHECK(!mapnik::util::exists(filename + ".index"));
|
||||||
int ret = create_disk_index(filename);
|
int ret = create_disk_index(filename);
|
||||||
int ret_posix = (ret >> 8) & 0x000000ff;
|
int ret_posix = (ret >> 8) & 0x000000ff;
|
||||||
INFO(ret);
|
INFO(ret);
|
||||||
INFO(ret_posix);
|
INFO(ret_posix);
|
||||||
CHECK(mapnik::util::exists(filename + ".index"));
|
CHECK(mapnik::util::exists(filename + ".index"));
|
||||||
|
|
||||||
for (auto cache_features : {true,false})
|
for (auto cache_features : {true,false})
|
||||||
{
|
{
|
||||||
params["cache_features"] = cache_features;
|
params["cache_features"] = cache_features;
|
||||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||||
auto fields = ds->get_descriptor().get_descriptors();
|
auto fields = ds->get_descriptor().get_descriptors();
|
||||||
mapnik::query query(ds->envelope());
|
mapnik::query query(ds->envelope());
|
||||||
auto features = ds->features(query);
|
auto features = ds->features(query);
|
||||||
REQUIRE_THROWS(
|
REQUIRE_THROWS(
|
||||||
auto feature = features->next();
|
auto feature = features->next();
|
||||||
while (feature != nullptr)
|
while (feature != nullptr)
|
||||||
{
|
{
|
||||||
feature = features->next();
|
feature = features->next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
if (mapnik::util::exists(filename + ".index"))
|
if (mapnik::util::exists(filename + ".index"))
|
||||||
{
|
{
|
||||||
mapnik::util::remove(filename + ".index");
|
mapnik::util::remove(filename + ".index");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,280 +5,398 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/image_view.hpp>
|
||||||
#include <mapnik/image_reader.hpp>
|
#include <mapnik/image_reader.hpp>
|
||||||
#include <mapnik/util/file_io.hpp>
|
#include <mapnik/util/file_io.hpp>
|
||||||
|
#include <mapnik/util/fs.hpp>
|
||||||
|
|
||||||
#include "../../../src/tiff_reader.cpp"
|
#include "../../../src/tiff_reader.cpp"
|
||||||
|
|
||||||
#define TIFF_ASSERT(filename) \
|
#define TIFF_ASSERT(filename) \
|
||||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename); \
|
mapnik::tiff_reader<std::filebuf> tiff_reader(filename); \
|
||||||
REQUIRE( tiff_reader.width() == 256 ); \
|
REQUIRE( tiff_reader.width() == 256 ); \
|
||||||
REQUIRE( tiff_reader.height() == 256 ); \
|
REQUIRE( tiff_reader.height() == 256 ); \
|
||||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); \
|
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); \
|
||||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff")); \
|
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff")); \
|
||||||
REQUIRE( reader->width() == 256 ); \
|
REQUIRE( reader->width() == 256 ); \
|
||||||
REQUIRE( reader->height() == 256 ); \
|
REQUIRE( reader->height() == 256 ); \
|
||||||
mapnik::util::file file(filename); \
|
mapnik::util::file file(filename); \
|
||||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size()); \
|
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size()); \
|
||||||
REQUIRE( tiff_reader2.width() == 256 ); \
|
REQUIRE( tiff_reader2.width() == 256 ); \
|
||||||
REQUIRE( tiff_reader2.height() == 256 ); \
|
REQUIRE( tiff_reader2.height() == 256 ); \
|
||||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size())); \
|
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size())); \
|
||||||
REQUIRE( reader2->width() == 256 ); \
|
REQUIRE( reader2->width() == 256 ); \
|
||||||
REQUIRE( reader2->height() == 256 ); \
|
REQUIRE( reader2->height() == 256 ); \
|
||||||
|
|
||||||
#define TIFF_ASSERT_ALPHA( data ) \
|
#define TIFF_ASSERT_ALPHA( data ) \
|
||||||
REQUIRE( tiff_reader.has_alpha() == true ); \
|
REQUIRE( tiff_reader.has_alpha() == true ); \
|
||||||
REQUIRE( reader->has_alpha() == true ); \
|
REQUIRE( reader->has_alpha() == true ); \
|
||||||
REQUIRE( tiff_reader2.has_alpha() == true ); \
|
REQUIRE( tiff_reader2.has_alpha() == true ); \
|
||||||
REQUIRE( reader2->has_alpha() == true ); \
|
REQUIRE( reader2->has_alpha() == true ); \
|
||||||
REQUIRE( data.get_premultiplied() == true ); \
|
REQUIRE( data.get_premultiplied() == true ); \
|
||||||
|
|
||||||
#define TIFF_ASSERT_NO_ALPHA_RGB( data ) \
|
#define TIFF_ASSERT_NO_ALPHA_RGB( data ) \
|
||||||
REQUIRE( tiff_reader.has_alpha() == false ); \
|
REQUIRE( tiff_reader.has_alpha() == false ); \
|
||||||
REQUIRE( reader->has_alpha() == false ); \
|
REQUIRE( reader->has_alpha() == false ); \
|
||||||
REQUIRE( tiff_reader2.has_alpha() == false ); \
|
REQUIRE( tiff_reader2.has_alpha() == false ); \
|
||||||
REQUIRE( reader2->has_alpha() == false ); \
|
REQUIRE( reader2->has_alpha() == false ); \
|
||||||
REQUIRE( data.get_premultiplied() == true ); \
|
REQUIRE( data.get_premultiplied() == true ); \
|
||||||
|
|
||||||
#define TIFF_ASSERT_NO_ALPHA_GRAY( data ) \
|
#define TIFF_ASSERT_NO_ALPHA_GRAY( data ) \
|
||||||
REQUIRE( tiff_reader.has_alpha() == false ); \
|
REQUIRE( tiff_reader.has_alpha() == false ); \
|
||||||
REQUIRE( reader->has_alpha() == false ); \
|
REQUIRE( reader->has_alpha() == false ); \
|
||||||
REQUIRE( tiff_reader2.has_alpha() == false ); \
|
REQUIRE( tiff_reader2.has_alpha() == false ); \
|
||||||
REQUIRE( reader2->has_alpha() == false ); \
|
REQUIRE( reader2->has_alpha() == false ); \
|
||||||
REQUIRE( data.get_premultiplied() == false ); \
|
REQUIRE( data.get_premultiplied() == false ); \
|
||||||
|
|
||||||
#define TIFF_ASSERT_SIZE( data,reader ) \
|
#define TIFF_ASSERT_SIZE( data,reader ) \
|
||||||
REQUIRE( data.width() == reader->width() ); \
|
REQUIRE( data.width() == reader->width() ); \
|
||||||
REQUIRE( data.height() == reader->height() ); \
|
REQUIRE( data.height() == reader->height() ); \
|
||||||
|
|
||||||
#define TIFF_READ_ONE_PIXEL \
|
#define TIFF_READ_ONE_PIXEL \
|
||||||
mapnik::image_any subimage = reader->read(1, 1, 1, 1); \
|
mapnik::image_any subimage = reader->read(1, 1, 1, 1); \
|
||||||
REQUIRE( subimage.width() == 1 ); \
|
REQUIRE( subimage.width() == 1 ); \
|
||||||
REQUIRE( subimage.height() == 1 ); \
|
REQUIRE( subimage.height() == 1 ); \
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename Image>
|
||||||
|
struct test_image_traits
|
||||||
|
{
|
||||||
|
using value_type = mapnik::color;
|
||||||
|
static value_type const& get_value(mapnik::color const& c)
|
||||||
|
{
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct test_image_traits<mapnik::image_gray8>
|
||||||
|
{
|
||||||
|
using value_type = std::uint8_t;
|
||||||
|
static value_type get_value(mapnik::color const& c)
|
||||||
|
{
|
||||||
|
return c.green(); // use green channel for gray scale images
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Image>
|
||||||
|
Image generate_test_image()
|
||||||
|
{
|
||||||
|
|
||||||
|
std::size_t tile_size = 16;
|
||||||
|
Image im(64, 64);
|
||||||
|
mapnik::color colors[] = {{mapnik::color("red")},
|
||||||
|
{mapnik::color("blue")},
|
||||||
|
{mapnik::color("green")},
|
||||||
|
{mapnik::color("yellow")}};
|
||||||
|
std::size_t index = 0;
|
||||||
|
for (std::size_t j = 0; j < im.height()/tile_size; ++j)
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
for (std::size_t i = 0; i < im.width()/tile_size; ++i)
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
for (std::size_t x = 0; x < tile_size; ++x)
|
||||||
|
{
|
||||||
|
for (std::size_t y = 0; y < tile_size; ++y)
|
||||||
|
{
|
||||||
|
auto value = test_image_traits<Image>::get_value(colors[index % 4]);
|
||||||
|
mapnik::set_pixel(im, i * tile_size + x, j * tile_size + y, value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return im;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Image1, typename Image2>
|
||||||
|
bool identical(Image1 const& im1, Image2 const& im2)
|
||||||
|
{
|
||||||
|
if ((im1.width() != im2.width()) || (im1.height() != im2.height()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < im1.width(); ++i)
|
||||||
|
{
|
||||||
|
for (std::size_t j = 0; j < im1.height(); ++j)
|
||||||
|
{
|
||||||
|
if (im1(i,j) != im2(i,j)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Image>
|
||||||
|
void test_tiff_reader(std::string const& pattern)
|
||||||
|
{
|
||||||
|
// generate expected image (rgba8 or gray8)
|
||||||
|
auto im = generate_test_image<Image>();
|
||||||
|
|
||||||
|
for (auto const& path : mapnik::util::list_directory("test/data/tiff/"))
|
||||||
|
{
|
||||||
|
if (boost::iends_with(path,".tif")
|
||||||
|
&& boost::istarts_with(mapnik::util::basename(path), pattern))
|
||||||
|
{
|
||||||
|
mapnik::tiff_reader<std::filebuf> tiff_reader(path);
|
||||||
|
auto width = tiff_reader.width();
|
||||||
|
auto height = tiff_reader.height();
|
||||||
|
{
|
||||||
|
// whole image
|
||||||
|
auto tiff = tiff_reader.read(0, 0, width, height);
|
||||||
|
CHECK(tiff.is<Image>());
|
||||||
|
auto im2 = tiff.get<Image>();
|
||||||
|
REQUIRE(identical(im, im2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// portion
|
||||||
|
auto tiff = tiff_reader.read(11, 13, width - 11, height - 13);
|
||||||
|
CHECK(tiff.is<Image>());
|
||||||
|
auto im2 = tiff.get<Image>();
|
||||||
|
auto view = mapnik::image_view<Image>(11, 13, width, height, im);
|
||||||
|
REQUIRE(identical(view, im2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("tiff io")
|
TEST_CASE("tiff io")
|
||||||
{
|
{
|
||||||
|
SECTION("tiff-reader rgb8+rgba8")
|
||||||
|
{
|
||||||
|
test_tiff_reader<mapnik::image_rgba8>("tiff_rgb");
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("scan rgb8 striped")
|
SECTION("tiff-reader gray8")
|
||||||
{
|
{
|
||||||
std::string filename("./test/data/tiff/scan_512x512_rgb8_striped.tif");
|
test_tiff_reader<mapnik::image_gray8>("tiff_gray");
|
||||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
}
|
||||||
REQUIRE( tiff_reader.width() == 512 );
|
|
||||||
REQUIRE( tiff_reader.height() == 512 );
|
|
||||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 16 );
|
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_PALETTE );
|
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
|
||||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff"));
|
|
||||||
REQUIRE( reader->width() == 512 );
|
|
||||||
REQUIRE( reader->height() == 512 );
|
|
||||||
mapnik::util::file file(filename);
|
|
||||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
|
||||||
REQUIRE( tiff_reader2.width() == 512 );
|
|
||||||
REQUIRE( tiff_reader2.height() == 512 );
|
|
||||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
|
||||||
REQUIRE( reader2->width() == 512 );
|
|
||||||
REQUIRE( reader2->height() == 512 );
|
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
|
||||||
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
|
||||||
TIFF_READ_ONE_PIXEL
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("scan rgb8 tiled") {
|
SECTION("scan rgb8 striped")
|
||||||
std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif");
|
{
|
||||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
std::string filename("./test/data/tiff/scan_512x512_rgb8_striped.tif");
|
||||||
REQUIRE( tiff_reader.width() == 512 );
|
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
||||||
REQUIRE( tiff_reader.height() == 512 );
|
REQUIRE( tiff_reader.width() == 512 );
|
||||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
REQUIRE( tiff_reader.height() == 512 );
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.rows_per_strip() == 16 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_PALETTE );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_PALETTE );
|
||||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff"));
|
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
||||||
REQUIRE( reader->width() == 512 );
|
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff"));
|
||||||
REQUIRE( reader->height() == 512 );
|
REQUIRE( reader->width() == 512 );
|
||||||
mapnik::util::file file(filename);
|
REQUIRE( reader->height() == 512 );
|
||||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
mapnik::util::file file(filename);
|
||||||
REQUIRE( tiff_reader2.width() == 512 );
|
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
||||||
REQUIRE( tiff_reader2.height() == 512 );
|
REQUIRE( tiff_reader2.width() == 512 );
|
||||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
REQUIRE( tiff_reader2.height() == 512 );
|
||||||
REQUIRE( reader2->width() == 512 );
|
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
||||||
REQUIRE( reader2->height() == 512 );
|
REQUIRE( reader2->width() == 512 );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
REQUIRE( reader2->height() == 512 );
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
||||||
}
|
TIFF_READ_ONE_PIXEL
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("rgba8 striped") {
|
SECTION("scan rgb8 tiled") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_striped.tif")
|
std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif");
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 1 );
|
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.width() == 512 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
REQUIRE( tiff_reader.height() == 512 );
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_ADOBE_DEFLATE );
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
REQUIRE( tiff_reader.tile_width() == 256 );
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
REQUIRE( tiff_reader.tile_height() == 256 );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_PALETTE );
|
||||||
TIFF_ASSERT_ALPHA( data );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
TIFF_READ_ONE_PIXEL
|
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"tiff"));
|
||||||
}
|
REQUIRE( reader->width() == 512 );
|
||||||
|
REQUIRE( reader->height() == 512 );
|
||||||
|
mapnik::util::file file(filename);
|
||||||
|
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
||||||
|
REQUIRE( tiff_reader2.width() == 512 );
|
||||||
|
REQUIRE( tiff_reader2.height() == 512 );
|
||||||
|
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
||||||
|
REQUIRE( reader2->width() == 512 );
|
||||||
|
REQUIRE( reader2->height() == 512 );
|
||||||
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
|
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
||||||
|
TIFF_READ_ONE_PIXEL
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("rgba8 tiled") {
|
SECTION("rgba8 striped") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_tiled.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_striped.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 1 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_ADOBE_DEFLATE );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_ALPHA( data );
|
TIFF_ASSERT_ALPHA( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("rgb8 striped") {
|
SECTION("rgba8 tiled") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_striped.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgba8_tiled.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 10 );
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
REQUIRE( tiff_reader.tile_width() == 256 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
REQUIRE( tiff_reader.tile_height() == 256 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
TIFF_ASSERT_ALPHA( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("rgb8 tiled") {
|
SECTION("rgb8 striped") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_tiled.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_striped.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 10 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray8 striped") {
|
SECTION("rgb8 tiled") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_striped.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_rgb8_tiled.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 32 );
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
REQUIRE( tiff_reader.tile_width() == 32 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
REQUIRE( tiff_reader.tile_height() == 32 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_RGB );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray8>() == true );
|
REQUIRE( data.is<mapnik::image_rgba8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_RGB( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray8 tiled") {
|
SECTION("gray8 striped") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_tiled.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_striped.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 32 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray8>() == true );
|
REQUIRE( data.is<mapnik::image_gray8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray16 striped") {
|
SECTION("gray8 tiled") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_striped.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray8_tiled.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 16 );
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 16 );
|
REQUIRE( tiff_reader.bits_per_sample() == 8 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
REQUIRE( tiff_reader.tile_width() == 256 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
REQUIRE( tiff_reader.tile_height() == 256 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray16>() == true );
|
REQUIRE( data.is<mapnik::image_gray8>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray16 tiled") {
|
SECTION("gray16 striped") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_tiled.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_striped.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 16 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 16 );
|
REQUIRE( tiff_reader.bits_per_sample() == 16 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray16>() == true );
|
REQUIRE( data.is<mapnik::image_gray16>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray32f striped") {
|
SECTION("gray16 tiled") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_striped.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray16_tiled.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 8 );
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 32 );
|
REQUIRE( tiff_reader.bits_per_sample() == 16 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == false );
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
REQUIRE( tiff_reader.tile_width() == 0 );
|
REQUIRE( tiff_reader.tile_width() == 256 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 0 );
|
REQUIRE( tiff_reader.tile_height() == 256 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray32f>() == true );
|
REQUIRE( data.is<mapnik::image_gray16>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("gray32f tiled") {
|
SECTION("gray32f striped") {
|
||||||
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_tiled.tif")
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_striped.tif")
|
||||||
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
REQUIRE( tiff_reader.rows_per_strip() == 8 );
|
||||||
REQUIRE( tiff_reader.bits_per_sample() == 32 );
|
REQUIRE( tiff_reader.bits_per_sample() == 32 );
|
||||||
REQUIRE( tiff_reader.is_tiled() == true );
|
REQUIRE( tiff_reader.is_tiled() == false );
|
||||||
REQUIRE( tiff_reader.tile_width() == 256 );
|
REQUIRE( tiff_reader.tile_width() == 0 );
|
||||||
REQUIRE( tiff_reader.tile_height() == 256 );
|
REQUIRE( tiff_reader.tile_height() == 0 );
|
||||||
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
REQUIRE( tiff_reader.compression() == COMPRESSION_NONE );
|
||||||
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
REQUIRE( data.is<mapnik::image_gray32f>() == true );
|
REQUIRE( data.is<mapnik::image_gray32f>() == true );
|
||||||
TIFF_ASSERT_SIZE( data,reader );
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
TIFF_READ_ONE_PIXEL
|
TIFF_READ_ONE_PIXEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("gray32f tiled") {
|
||||||
|
TIFF_ASSERT("./test/data/tiff/ndvi_256x256_gray32f_tiled.tif")
|
||||||
|
REQUIRE( tiff_reader.rows_per_strip() == 0 );
|
||||||
|
REQUIRE( tiff_reader.bits_per_sample() == 32 );
|
||||||
|
REQUIRE( tiff_reader.is_tiled() == true );
|
||||||
|
REQUIRE( tiff_reader.tile_width() == 256 );
|
||||||
|
REQUIRE( tiff_reader.tile_height() == 256 );
|
||||||
|
REQUIRE( tiff_reader.photometric() == PHOTOMETRIC_MINISBLACK );
|
||||||
|
REQUIRE( tiff_reader.compression() == COMPRESSION_LZW );
|
||||||
|
mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
|
||||||
|
REQUIRE( data.is<mapnik::image_gray32f>() == true );
|
||||||
|
TIFF_ASSERT_SIZE( data,reader );
|
||||||
|
TIFF_ASSERT_NO_ALPHA_GRAY( data );
|
||||||
|
TIFF_READ_ONE_PIXEL
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,11 @@ std::pair<bool,typename T::value_type::first_type> process_geojson_file(T & boxe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (validate_features)
|
||||||
|
{
|
||||||
|
if (verbose) std::clog << "Invalid bbox encountered " << item.first << std::endl;
|
||||||
|
return std::make_pair(false, extent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(true, extent);
|
return std::make_pair(true, extent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,20 @@ source = Split(
|
||||||
program_env['CXXFLAGS'] = copy(env['LIBMAPNIK_CXXFLAGS'])
|
program_env['CXXFLAGS'] = copy(env['LIBMAPNIK_CXXFLAGS'])
|
||||||
program_env['LINKFLAGS'] = copy(env['LIBMAPNIK_LINKFLAGS'])
|
program_env['LINKFLAGS'] = copy(env['LIBMAPNIK_LINKFLAGS'])
|
||||||
program_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
|
program_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
|
||||||
|
program_env['LIBS'] = []
|
||||||
|
|
||||||
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
|
# pkg-config is more reliable than pg_config across platforms
|
||||||
|
cmd = 'pkg-config libpq --libs --static'
|
||||||
|
try:
|
||||||
|
program_env.ParseConfig(cmd)
|
||||||
|
except OSError, e:
|
||||||
|
program_env.Append(LIBS='pq')
|
||||||
|
else:
|
||||||
|
program_env.Append(LIBS='pq')
|
||||||
|
|
||||||
|
# Link Library to Dependencies
|
||||||
|
libraries = copy(program_env['LIBS'])
|
||||||
|
|
||||||
if env['HAS_CAIRO']:
|
if env['HAS_CAIRO']:
|
||||||
program_env.PrependUnique(CPPPATH=env['CAIRO_CPPPATHS'])
|
program_env.PrependUnique(CPPPATH=env['CAIRO_CPPPATHS'])
|
||||||
|
@ -46,9 +60,8 @@ if env['HAS_CAIRO']:
|
||||||
|
|
||||||
program_env.PrependUnique(CPPPATH=['#plugins/input/postgis'])
|
program_env.PrependUnique(CPPPATH=['#plugins/input/postgis'])
|
||||||
|
|
||||||
libraries = []
|
|
||||||
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
|
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
|
||||||
libraries.extend([boost_program_options,'sqlite3','pq',env['MAPNIK_NAME'],'icuuc'])
|
libraries.extend([boost_program_options,'sqlite3',env['MAPNIK_NAME'],'icuuc'])
|
||||||
|
|
||||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||||
|
@ -59,13 +72,8 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||||
if env['SQLITE_LINKFLAGS']:
|
if env['SQLITE_LINKFLAGS']:
|
||||||
program_env.Append(LINKFLAGS=env['SQLITE_LINKFLAGS'])
|
program_env.Append(LINKFLAGS=env['SQLITE_LINKFLAGS'])
|
||||||
|
|
||||||
if env['RUNTIME_LINK'] == 'static':
|
if env['RUNTIME_LINK'] == 'static' and env['PLATFORM'] == 'Linux':
|
||||||
if env['PLATFORM'] == 'Darwin':
|
libraries.append('dl')
|
||||||
libraries.extend(['ldap', 'pam', 'ssl', 'crypto', 'krb5'])
|
|
||||||
else:
|
|
||||||
# TODO - parse back into libraries variable
|
|
||||||
program_env.ParseConfig('pg_config --libs')
|
|
||||||
libraries.append('dl')
|
|
||||||
|
|
||||||
pgsql2sqlite = program_env.Program('pgsql2sqlite', source, LIBS=libraries)
|
pgsql2sqlite = program_env.Program('pgsql2sqlite', source, LIBS=libraries)
|
||||||
Depends(pgsql2sqlite, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
Depends(pgsql2sqlite, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
Loading…
Reference in a new issue