Compare commits
3 commits
master
...
style-with
Author | SHA1 | Date | |
---|---|---|---|
|
e2171b2b9c | ||
|
e9d6872764 | ||
|
d8fa8adfae |
5265 changed files with 180416 additions and 592695 deletions
|
@ -1,94 +0,0 @@
|
||||||
Language: Cpp
|
|
||||||
AccessModifierOffset: -2
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
AlignArrayOfStructures: None
|
|
||||||
AlignConsecutiveAssignments: None
|
|
||||||
AlignConsecutiveDeclarations: None
|
|
||||||
AlignConsecutiveMacros: Consecutive
|
|
||||||
AlignEscapedNewlines: Right
|
|
||||||
AlignOperands: Align
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowAllArgumentsOnNextLine: false
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
|
||||||
AllowShortBlocksOnASingleLine: Empty
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortEnumsOnASingleLine: true
|
|
||||||
AllowShortFunctionsOnASingleLine: Inline
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
|
||||||
AllowShortLambdasOnASingleLine: Inline
|
|
||||||
# AlwaysBreakAfterReturnType:
|
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
BinPackArguments: false
|
|
||||||
BitFieldColonSpacing: After
|
|
||||||
BreakBeforeBraces: Custom
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: true
|
|
||||||
AfterControlStatement: Always
|
|
||||||
AfterEnum: false # see AllowShortEnumsOnASingleLine
|
|
||||||
AfterFunction: true # see AllowShortFunctionsOnASingleLine
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterStruct: true
|
|
||||||
AfterExternBlock: false
|
|
||||||
BeforeCatch: true
|
|
||||||
BeforeElse: true
|
|
||||||
BeforeLambdaBody: false
|
|
||||||
BeforeWhile: false
|
|
||||||
SplitEmptyFunction: false
|
|
||||||
SplitEmptyRecord: false
|
|
||||||
SplitEmptyNamespace: false
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeConceptDeclarations: false
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializers: BeforeComma
|
|
||||||
BreakInheritanceList: AfterComma
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 120
|
|
||||||
CompactNamespaces: false
|
|
||||||
ContinuationIndentWidth: 2
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DeriveLineEnding: true
|
|
||||||
EmptyLineAfterAccessModifier: Leave
|
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
|
||||||
FixNamespaceComments: true
|
|
||||||
IncludeBlocks: Preserve
|
|
||||||
IndentCaseBlocks: false
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentExternBlock: NoIndent
|
|
||||||
IndentPPDirectives: None
|
|
||||||
IndentRequires: true
|
|
||||||
IndentWidth: 4
|
|
||||||
IndentWrappedFunctionNames: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
||||||
LambdaBodyIndentation: Signature
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
# PackConstructorInitializers: CurrentLine # only clang-format > 14
|
|
||||||
PointerAlignment: Left
|
|
||||||
#QualifierAlignment: Left # only clang-format > 14
|
|
||||||
ReferenceAlignment: Left
|
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: Never
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
SpaceBeforeInheritanceColon: true
|
|
||||||
Standard: c++14
|
|
||||||
BinPackParameters: false
|
|
||||||
BreakBeforeInheritanceComma: false
|
|
||||||
IncludeCategories:
|
|
||||||
# Headers in <> without extension.
|
|
||||||
- Regex: '<([A-Za-z0-9\Q/-_\E])+>'
|
|
||||||
Priority: 1
|
|
||||||
# Headers in <> from specific external libraries.
|
|
||||||
- Regex: '<(boost)\/'
|
|
||||||
Priority: 2
|
|
||||||
# Headers in <> from specific external libraries.
|
|
||||||
- Regex: '<(mapnik)\/'
|
|
||||||
Priority: 3
|
|
||||||
# Headers in <> with extension.
|
|
||||||
- Regex: '<([A-Za-z0-9.\Q/-_\E])+>'
|
|
||||||
Priority: 4
|
|
||||||
# Headers in "" with extension.
|
|
||||||
- Regex: '"([A-Za-z0-9.\Q/-_\E])+"'
|
|
||||||
Priority: 5
|
|
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -1,2 +0,0 @@
|
||||||
*.svg text eol=lf
|
|
||||||
scons/** linguist-vendored
|
|
85
.github/actions/run_tests/action.yml
vendored
85
.github/actions/run_tests/action.yml
vendored
|
@ -1,85 +0,0 @@
|
||||||
name: Run tests with coverage
|
|
||||||
description: Runs all mapnik tests with coverage
|
|
||||||
inputs:
|
|
||||||
cmake-preset:
|
|
||||||
description: The used CMake preset
|
|
||||||
required: true
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Set PROJ_LIB
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake --preset ${{ inputs.cmake-preset }} -N -L | grep -o "PROJ_LIB=.*" >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- name: Set TEST_WRAPPER (Windows)
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
shell: bash
|
|
||||||
run: |-
|
|
||||||
echo "TEST_WRAPPER=OpenCppCoverage \
|
|
||||||
--cover_children \
|
|
||||||
--export_type binary \
|
|
||||||
--modules '*.input' \
|
|
||||||
--modules '*libmapnik*' \
|
|
||||||
--modules 'mapnik*.exe' \
|
|
||||||
--quiet \
|
|
||||||
--sources '${{ github.workspace }}' \
|
|
||||||
--" >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
UPDATE: 1
|
|
||||||
run: |
|
|
||||||
${TEST_WRAPPER:-} ctest --preset ${{ inputs.cmake-preset }}
|
|
||||||
|
|
||||||
- name: Test visuals
|
|
||||||
continue-on-error: true
|
|
||||||
working-directory: build/out
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
${TEST_WRAPPER:-} ./mapnik-test-visual -j ${CTEST_PARALLEL_LEVEL} --output-dir visual-test-result
|
|
||||||
|
|
||||||
- name: Pack visual test results
|
|
||||||
working-directory: build/out
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
tar -vzcf visual-test-results.tar.gz visual-test-result
|
|
||||||
|
|
||||||
- name: Upload visual test results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ inputs.cmake-preset }}-visual-tests-${{ github.sha }}
|
|
||||||
path: build/out/visual-test-results.tar.gz
|
|
||||||
|
|
||||||
- name: Run Benchmarks (Linux & macOS)
|
|
||||||
working-directory: build/out
|
|
||||||
if: runner.os != 'Windows'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./run_benchmarks
|
|
||||||
|
|
||||||
- name: Collect coverage (Linux & macOS)
|
|
||||||
working-directory: build
|
|
||||||
if: runner.os != 'Windows'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
if [ "${RUNNER_OS}" == "macOS" ]; then
|
|
||||||
LCOV_EXTRA_OPTIONS="--ignore-errors count,gcov,inconsistent,range,unused --keep-going"
|
|
||||||
fi
|
|
||||||
lcov ${LCOV_EXTRA_OPTIONS:-} --directory . --capture --output-file coverage.info
|
|
||||||
lcov ${LCOV_EXTRA_OPTIONS:-} --remove coverage.info '/usr/*' '*/vcpkg_installed/*' '/.cache/*' '*/test/*' --output-file coverage.info
|
|
||||||
lcov ${LCOV_EXTRA_OPTIONS:-} --list coverage.info
|
|
||||||
|
|
||||||
- name: Upload coverage to Codecov (Linux & macOS)
|
|
||||||
if: runner.os != 'Windows'
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
files: build/coverage.info
|
|
||||||
|
|
||||||
- name: Upload coverage to Codecov (Windows)
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
uses: codecov/codecov-action@v4
|
|
||||||
with:
|
|
||||||
files: ctest.cov,build/out/mapnik-test-visual.cov
|
|
136
.github/workflows/build_and_test.yml
vendored
136
.github/workflows/build_and_test.yml
vendored
|
@ -1,136 +0,0 @@
|
||||||
name: Build and Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
branches-ignore:
|
|
||||||
- "no-ci-*"
|
|
||||||
|
|
||||||
env:
|
|
||||||
VCPKG_BINARY_SOURCES: clear;x-gha,readwrite
|
|
||||||
VCPKG_RELEASE: 2024.06.15
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
checkSource:
|
|
||||||
name: Check Source Code
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- uses: pre-commit/action@v3.0.1
|
|
||||||
|
|
||||||
buildAndTest:
|
|
||||||
name: >-
|
|
||||||
Build & Test
|
|
||||||
(${{ matrix.os }})
|
|
||||||
(C++ ${{ matrix.cxx-standard }})
|
|
||||||
${{ startsWith(matrix.os, 'macos-') && (matrix.os == 'macos-14' && '(ARM64)' || '(AMD64)') || '' }}
|
|
||||||
needs: checkSource
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- macos-14
|
|
||||||
- ubuntu-22.04
|
|
||||||
- windows-2022
|
|
||||||
cxx-standard:
|
|
||||||
- 17
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout Mapnik
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Checkout vcpkg
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
path: vcpkg
|
|
||||||
ref: ${{ env.VCPKG_RELEASE }}
|
|
||||||
repository: microsoft/vcpkg
|
|
||||||
|
|
||||||
- name: Export GitHub Actions cache environment variables
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
|
|
||||||
- name: Install required system packages
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
if [ "${RUNNER_OS}" == "Linux" ]; then
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install \
|
|
||||||
autoconf \
|
|
||||||
autoconf-archive \
|
|
||||||
automake \
|
|
||||||
gperf \
|
|
||||||
lcov \
|
|
||||||
libxxf86vm-dev \
|
|
||||||
ninja-build \
|
|
||||||
postgresql-client
|
|
||||||
elif [ "${RUNNER_OS}" == "macOS" ]; then
|
|
||||||
brew install \
|
|
||||||
autoconf \
|
|
||||||
autoconf-archive \
|
|
||||||
automake \
|
|
||||||
lcov \
|
|
||||||
libtool \
|
|
||||||
ninja \
|
|
||||||
vcpkg
|
|
||||||
elif [ "${RUNNER_OS}" == "Windows" ]; then
|
|
||||||
choco install \
|
|
||||||
ninja \
|
|
||||||
OpenCppCoverage
|
|
||||||
echo "C:\Program Files\OpenCppCoverage" >> ${GITHUB_PATH}
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Enable Developer Command Prompt (Windows)
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
|
|
||||||
- name: Set CMAKE_BUILD_PARALLEL_LEVEL, CTEST_PARALLEL_LEVEL & PRESET
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
PRESET=$(echo "${RUNNER_OS}" | perl -ne "print lc")-ci
|
|
||||||
if [ "${RUNNER_OS}" == "Linux" ]; then
|
|
||||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)" >> ${GITHUB_ENV}
|
|
||||||
echo "CTEST_PARALLEL_LEVEL=$(nproc)" >> ${GITHUB_ENV}
|
|
||||||
elif [ "${RUNNER_OS}" == "macOS" ]; then
|
|
||||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(sysctl -n hw.logicalcpu)" >> ${GITHUB_ENV}
|
|
||||||
echo "CTEST_PARALLEL_LEVEL=$(sysctl -n hw.logicalcpu)" >> ${GITHUB_ENV}
|
|
||||||
PRESET=${PRESET}-${{ matrix.os == 'macos-14' && 'arm64' || 'x64' }}
|
|
||||||
elif [ "${RUNNER_OS}" == "Windows" ]; then
|
|
||||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(pwsh -Command '(Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfLogicalProcessors')" >> ${GITHUB_ENV}
|
|
||||||
echo "CTEST_PARALLEL_LEVEL=$(pwsh -Command '(Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfLogicalProcessors')" >> ${GITHUB_ENV}
|
|
||||||
fi
|
|
||||||
echo "PRESET=${PRESET}" >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- name: Configure CMake
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake \
|
|
||||||
-DBUILD_SHARED_LIBS:BOOL=ON \
|
|
||||||
-DCMAKE_CXX_STANDARD:STRING=${{ matrix.cxx-standard }} \
|
|
||||||
-DUSE_MEMORY_MAPPED_FILE:BOOL=ON \
|
|
||||||
-LA \
|
|
||||||
--preset ${PRESET}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cmake \
|
|
||||||
--build \
|
|
||||||
--preset ${PRESET}
|
|
||||||
|
|
||||||
- name: Run Tests
|
|
||||||
uses: ./.github/actions/run_tests
|
|
||||||
with:
|
|
||||||
cmake-preset: ${{ env.PRESET }}
|
|
55
.github/workflows/release_linux.yml
vendored
55
.github/workflows/release_linux.yml
vendored
|
@ -1,55 +0,0 @@
|
||||||
name: Release Linux
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "*"
|
|
||||||
pull_request:
|
|
||||||
branches-ignore:
|
|
||||||
- "no-ci-*"
|
|
||||||
env:
|
|
||||||
PRESET: linux-ci-release
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: checkout mapnik
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: "recursive"
|
|
||||||
|
|
||||||
- name: "Install required system packages"
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y ninja-build\
|
|
||||||
libicu-dev \
|
|
||||||
libfreetype6-dev \
|
|
||||||
libharfbuzz-dev \
|
|
||||||
libxml2-dev \
|
|
||||||
libjpeg-dev \
|
|
||||||
libtiff-dev \
|
|
||||||
libwebp-dev \
|
|
||||||
libcairo2-dev \
|
|
||||||
libproj-dev \
|
|
||||||
libgdal-dev \
|
|
||||||
libboost-filesystem-dev \
|
|
||||||
libboost-program-options-dev \
|
|
||||||
libboost-regex-dev
|
|
||||||
|
|
||||||
- name: Configure CMake
|
|
||||||
run: cmake -LA --preset ${{ env.PRESET }}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build --preset ${{ env.PRESET }}
|
|
||||||
|
|
||||||
- name: Package
|
|
||||||
run: cmake --build --preset ${{ env.PRESET }} --target package
|
|
||||||
|
|
||||||
- name: Upload mapnik debian package
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ env.PRESET }}-deb
|
|
||||||
path: build/mapnik-*.deb
|
|
33
.gitignore
vendored
33
.gitignore
vendored
|
@ -1,19 +1,11 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode
|
|
||||||
.cache
|
|
||||||
*.gcov
|
|
||||||
*.gcda
|
|
||||||
*.gcno
|
|
||||||
*~
|
*~
|
||||||
*.o
|
*.o
|
||||||
*.pyc
|
*.pyc
|
||||||
*.os
|
*.os
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
|
||||||
*.a
|
*.a
|
||||||
*.swp
|
|
||||||
*.dylib
|
*.dylib
|
||||||
mapnik-gyp
|
|
||||||
plugins/input/*.input
|
plugins/input/*.input
|
||||||
plugins/input/templates/*.input
|
plugins/input/templates/*.input
|
||||||
demo/c++/rundemo
|
demo/c++/rundemo
|
||||||
|
@ -21,24 +13,28 @@ bindings/python/mapnik/paths.py
|
||||||
config.cache
|
config.cache
|
||||||
config.log
|
config.log
|
||||||
config.py
|
config.py
|
||||||
mapnik-settings.env
|
|
||||||
mason_packages/
|
|
||||||
.mason/
|
|
||||||
.sconf_temp/
|
.sconf_temp/
|
||||||
.sconsign.dblite
|
.sconsign.dblite
|
||||||
demo/viewer/viewer.ini
|
demo/viewer/viewer.ini
|
||||||
tests/cpp_tests/font_registration_test
|
tests/cpp_tests/font_registration_test
|
||||||
tests/python_tests/raster_colorizer_test.png
|
tests/python_tests/raster_colorizer_test.png
|
||||||
tests/python_tests/raster_colorizer_test_save.xml
|
tests/python_tests/raster_colorizer_test_save.xml
|
||||||
utils/mapnik-config/mapnik-config
|
bin/mapnik-config
|
||||||
utils/shapeindex/shapeindex
|
utils/shapeindex/shapeindex
|
||||||
utils/mapnik-index/mapnik-index
|
|
||||||
utils/ogrindex/ogrindex
|
utils/ogrindex/ogrindex
|
||||||
utils/pgsql2sqlite/pgsql2sqlite
|
utils/pgsql2sqlite/pgsql2sqlite
|
||||||
utils/svg2png/svg2png
|
utils/svg2png/svg2png
|
||||||
utils/mapnik-render/mapnik-render
|
utils/nik2img/nik2img
|
||||||
demo/python/demo*
|
demo/python/demo*
|
||||||
demo/python/map.xml
|
demo/python/map.xml
|
||||||
|
tests/cpp_tests/svg_renderer_tests/background_color_test
|
||||||
|
tests/cpp_tests/svg_renderer_tests/combined_test
|
||||||
|
tests/cpp_tests/svg_renderer_tests/compilation_test
|
||||||
|
tests/cpp_tests/svg_renderer_tests/file_output_test
|
||||||
|
tests/cpp_tests/svg_renderer_tests/file_output_test_case.svg
|
||||||
|
tests/cpp_tests/svg_renderer_tests/path_element_test
|
||||||
|
tests/cpp_tests/svg_renderer_tests/path_element_test_case_1.svg
|
||||||
|
tests/cpp_tests/svg_renderer_tests/root_element_test
|
||||||
tests/data/sqlite/*index
|
tests/data/sqlite/*index
|
||||||
demo/c++/cairo-demo.pdf
|
demo/c++/cairo-demo.pdf
|
||||||
demo/c++/cairo-demo.png
|
demo/c++/cairo-demo.png
|
||||||
|
@ -55,11 +51,4 @@ demo/viewer/release/
|
||||||
demo/viewer/ui_about.h
|
demo/viewer/ui_about.h
|
||||||
demo/viewer/ui_info.h
|
demo/viewer/ui_info.h
|
||||||
demo/viewer/ui_layer_info.h
|
demo/viewer/ui_layer_info.h
|
||||||
test/standalone/*-bin
|
tests/cpp_tests/*-bin
|
||||||
test/unit/run
|
|
||||||
test/visual/run
|
|
||||||
# cmake
|
|
||||||
build
|
|
||||||
.vs
|
|
||||||
|
|
||||||
CMakeUserPresets.json
|
|
||||||
|
|
23
.gitmodules
vendored
23
.gitmodules
vendored
|
@ -1,23 +0,0 @@
|
||||||
[submodule "test/data"]
|
|
||||||
path = test/data
|
|
||||||
url = https://github.com/mapnik/test-data.git
|
|
||||||
branch = master
|
|
||||||
[submodule "test/data-visual"]
|
|
||||||
path = test/data-visual
|
|
||||||
url = https://github.com/mapnik/test-data-visual.git
|
|
||||||
branch = master
|
|
||||||
[submodule "deps/mapbox/variant"]
|
|
||||||
path = deps/mapbox/variant
|
|
||||||
url = https://github.com/mapbox/variant.git
|
|
||||||
branch = master
|
|
||||||
[submodule "deps/mapbox/geometry"]
|
|
||||||
path = deps/mapbox/geometry
|
|
||||||
url = https://github.com/mapbox/geometry.hpp.git
|
|
||||||
branch = master
|
|
||||||
[submodule "deps/mapbox/protozero"]
|
|
||||||
path = deps/mapbox/protozero
|
|
||||||
url = https://github.com/mapbox/protozero.git
|
|
||||||
branch = master
|
|
||||||
[submodule "deps/mapbox/polylabel"]
|
|
||||||
path = deps/mapbox/polylabel
|
|
||||||
url = https://github.com/mapbox/polylabel.git
|
|
|
@ -1,16 +0,0 @@
|
||||||
# See https://pre-commit.com for more information
|
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v4.6.0
|
|
||||||
hooks:
|
|
||||||
- id: trailing-whitespace
|
|
||||||
files: ^.*\.cmake|CMakeLists\.txt$
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
files: ^.*\.cmake|CMakeLists\.txt$
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
|
||||||
rev: v18.1.3
|
|
||||||
hooks:
|
|
||||||
- id: clang-format
|
|
||||||
types_or: [c++, c]
|
|
51
.travis.yml
Normal file
51
.travis.yml
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
# - gcc
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- DEBUG=True ENABLE_LOG=True DEFAULT_LOG_SEVERITY=debug XMLPARSER="libxml2" DEMO=False BENCHMARK=False CUSTOM_CXXFLAGS="" CUSTOM_LDFLAGS=""
|
||||||
|
- DEBUG=False ENABLE_LOG=False DEFAULT_LOG_SEVERITY=none XMLPARSER="ptree" DEMO=False BENCHMARK=False CUSTOM_CXXFLAGS="" CUSTOM_LDFLAGS=""
|
||||||
|
|
||||||
|
# travis + ubuntugis with gdal and postggis leads to many potential dead-end conflicts
|
||||||
|
# the below is thanks to https://github.com/CartoDB/Windshaft/blob/d82fe08b32fc7907bbe907ab290f8a082215ae26/.travis.yml#L1
|
||||||
|
before_install:
|
||||||
|
- export PGUSER=postgres
|
||||||
|
- sudo mv /etc/apt/sources.list.d/pgdg-source.list* /tmp
|
||||||
|
- sudo apt-get -qq purge postgis* postgresql*
|
||||||
|
- sudo apt-add-repository -y ppa:cartodb/postgresql-9.3
|
||||||
|
- sudo apt-add-repository -y ppa:cartodb/gis
|
||||||
|
- sudo rm -Rf /var/lib/postgresql /etc/postgresql
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get install -q postgresql-9.3-postgis-2.1
|
||||||
|
- sudo apt-get install -q postgresql-contrib-9.3
|
||||||
|
- sudo apt-get install -q gdal-bin libgdal-dev
|
||||||
|
- echo -e "local\tall\tall\ttrust\nhost\tall\tall\t127.0.0.1/32\ttrust\nhost\tall\tall\t::1/128\ttrust" |sudo tee /etc/postgresql/9.3/main/pg_hba.conf
|
||||||
|
- sudo service postgresql restart
|
||||||
|
|
||||||
|
install:
|
||||||
|
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||||
|
# we need at least g++-4.7 for c++11 features
|
||||||
|
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get install -y ttf-wqy-microhei make libstdc++6 libstdc++-4.8-dev valgrind boost1.55 python-nose libicu-dev libproj-dev libcairo-dev python-cairo-dev libcairo-dev python-cairo-dev libpng-dev libjpeg-dev libtiff-dev libwebp-dev libz-dev libfreetype6-dev libxml2-dev libsqlite3-dev
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- psql -U postgres -c 'create database template_postgis'
|
||||||
|
- psql -U postgres -c 'create extension postgis' -d template_postgis
|
||||||
|
- if [[ "${CXX}" == 'g++' ]]; then sudo apt-get install gcc-4.8 g++-4.8; export CXX="$(which g++-4.8)"; export CC="$(which gcc-4.8)"; fi;
|
||||||
|
- if [[ "${CXX}" == 'clang++' ]]; then export CXX="$(which clang++)"; export CC="$(which clang)"; fi;
|
||||||
|
- wget http://www.freedesktop.org/software/harfbuzz/release/harfbuzz-0.9.34.tar.bz2
|
||||||
|
- tar xf harfbuzz-0.9.34.tar.bz2
|
||||||
|
- cd harfbuzz-0.9.34
|
||||||
|
- ./configure --prefix=/usr --with-icu --with-cairo=no --with-glib=no --with-gobject=no --with-graphite2=no --with-freetype --with-uniscribe=no --with-coretext=no && make && sudo make install
|
||||||
|
- cd ../
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./configure CXX="${CXX}" CC="${CC}" CUSTOM_CXXFLAGS="${CUSTOM_CXXFLAGS}" CUSTOM_LDFLAGS="${CUSTOM_LDFLAGS}" XML_PARSER="${XML_PARSER}" ENABLE_LOG="${ENABLE_LOG}" DEBUG="${DEBUG}" DEMO="${DEMO}" BENCHMARK="${BENCHMARK}" CPP_TESTS=True CAIRO=True FAST=True || cat config.log
|
||||||
|
- if [[ "${DEBUG}" == true ]]; then JOBS=2 make; else JOBS=4 make; fi;
|
||||||
|
- make test
|
||||||
|
- source localize.sh && make grind
|
||||||
|
- if [[ ${BENCHMARK} != False ]]; then make bench; fi;
|
23
AUTHORS.md
23
AUTHORS.md
|
@ -6,55 +6,39 @@ Mapnik is written by Artem Pavlenko with contributions from:
|
||||||
* AJ Ashton
|
* AJ Ashton
|
||||||
* Matt Amos
|
* Matt Amos
|
||||||
* Lucio Asnaghi
|
* Lucio Asnaghi
|
||||||
* Alexandre Bonnasseau
|
|
||||||
* Justin Bronn
|
* Justin Bronn
|
||||||
* Joel Brown
|
|
||||||
* Christopher Brown
|
* Christopher Brown
|
||||||
* Jon Burgess
|
* Jon Burgess
|
||||||
* Stephan Bösch-Plepelits
|
|
||||||
* Manel Clos
|
|
||||||
* Toby Collet
|
* Toby Collet
|
||||||
* Robert Coup
|
* Robert Coup
|
||||||
* Berteun Damman
|
* Berteun Damman
|
||||||
* Petr Dlouhy
|
* Craig de Stigter
|
||||||
* Jiri Drbalek
|
|
||||||
* Jean-Francois Doyon
|
* Jean-Francois Doyon
|
||||||
* David Eastcott
|
* David Eastcott
|
||||||
* Seth Fitzsimmons
|
|
||||||
* Sean Gillies
|
|
||||||
* Krzysztof Godlewski
|
* Krzysztof Godlewski
|
||||||
* Beau Gunderson
|
* Beau Gunderson
|
||||||
* John Hague
|
* John Hague
|
||||||
* Dominic Hargreaves
|
* Dominic Hargreaves
|
||||||
* Axel Haustant
|
|
||||||
* Aubrey Holland
|
* Aubrey Holland
|
||||||
* Jordan Hollinger
|
|
||||||
* Tom Hughes
|
* Tom Hughes
|
||||||
* Konstantin Käfer
|
* Konstantin Käfer
|
||||||
* Mak Kolybabi
|
* Mak Kolybabi
|
||||||
* Peter Körner
|
* Peter Körner
|
||||||
* Hermann Kraus
|
* Hermann Kraus
|
||||||
* Stella Laurenzo
|
* Stella Laurenzo
|
||||||
* XinGang Li
|
|
||||||
* lightmare
|
|
||||||
* David Leaver
|
* David Leaver
|
||||||
* Carlos López
|
* Carlos López
|
||||||
* Dennis Luxen
|
* Dennis Luxen
|
||||||
* Tom MacWright
|
* Tom MacWright
|
||||||
* Sara Metz
|
|
||||||
* Michal Migurski
|
* Michal Migurski
|
||||||
* Andrii Mishkovskyi
|
* Andrii Mishkovskyi
|
||||||
* Ben Moores
|
* Ben Moores
|
||||||
* Mike Morris
|
|
||||||
* Dražen Odobašić
|
* Dražen Odobašić
|
||||||
* Cameron Patrick
|
* Cameron Patrick
|
||||||
* Clint Pells
|
|
||||||
* Igor Podolskiy
|
* Igor Podolskiy
|
||||||
* Reid Priedhorsky
|
* Reid Priedhorsky
|
||||||
* Brian Quinion
|
* Brian Quinion
|
||||||
* Even Rouault
|
|
||||||
* Marcin Rudowski
|
* Marcin Rudowski
|
||||||
* Sandro Santilli
|
|
||||||
* Christopher Schmidt
|
* Christopher Schmidt
|
||||||
* Andreas Schneider
|
* Andreas Schneider
|
||||||
* Vincent Schut
|
* Vincent Schut
|
||||||
|
@ -65,13 +49,9 @@ Mapnik is written by Artem Pavlenko with contributions from:
|
||||||
* Vince Spader
|
* Vince Spader
|
||||||
* Philipp Spitzer
|
* Philipp Spitzer
|
||||||
* Dane Springmeyer
|
* Dane Springmeyer
|
||||||
* Craig de Stigter
|
|
||||||
* Dave Stubbs
|
* Dave Stubbs
|
||||||
* River Tarnell
|
* River Tarnell
|
||||||
* Cezary Tarnowski
|
|
||||||
* Blake Thompson
|
|
||||||
* Oliver Tonnhofer
|
* Oliver Tonnhofer
|
||||||
* Jochen Topf
|
|
||||||
* Alberto Valverde
|
* Alberto Valverde
|
||||||
* Martijn van Oosterhout
|
* Martijn van Oosterhout
|
||||||
* Andreas Volz
|
* Andreas Volz
|
||||||
|
@ -80,4 +60,3 @@ Mapnik is written by Artem Pavlenko with contributions from:
|
||||||
* Rich Wareham
|
* Rich Wareham
|
||||||
* Nick Whitelegg
|
* Nick Whitelegg
|
||||||
* Leslie Wu
|
* Leslie Wu
|
||||||
* Roman Galacz
|
|
||||||
|
|
1086
CHANGELOG.md
1086
CHANGELOG.md
File diff suppressed because it is too large
Load diff
34
CITATION.cff
34
CITATION.cff
|
@ -1,34 +0,0 @@
|
||||||
# This CITATION.cff file was generated with cffinit.
|
|
||||||
# Visit https://bit.ly/cffinit to generate yours today!
|
|
||||||
|
|
||||||
cff-version: 1.2.0
|
|
||||||
title: mapnik
|
|
||||||
message: >-
|
|
||||||
If you use this software, please cite it using the
|
|
||||||
metadata from this file.
|
|
||||||
type: software
|
|
||||||
authors:
|
|
||||||
- given-names: Artem
|
|
||||||
family-names: Pavlenko
|
|
||||||
identifiers:
|
|
||||||
- type: url
|
|
||||||
value: 'https://github.com/mapnik/mapnik'
|
|
||||||
description: GitHub Repository
|
|
||||||
- type: swh
|
|
||||||
value: >-
|
|
||||||
swh:1:dir:3f5758e17e9d54016ca694268da68cf6856fab58
|
|
||||||
description: Software Archive
|
|
||||||
repository-code: 'https://github.com/mapnik/mapnik'
|
|
||||||
url: 'https://mapnik.org/'
|
|
||||||
abstract: >-
|
|
||||||
Mapnik is an open source toolkit for developing
|
|
||||||
mapping applications. At the core is a C++ shared
|
|
||||||
library providing algorithms and patterns for
|
|
||||||
spatial data access and visualization.
|
|
||||||
keywords:
|
|
||||||
- mapping
|
|
||||||
- gis
|
|
||||||
- cartography
|
|
||||||
- beautiful-maps
|
|
||||||
- rendering
|
|
||||||
license: LGPL-2.1
|
|
472
CMakeLists.txt
472
CMakeLists.txt
|
@ -1,472 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.15)
|
|
||||||
# 3.15 is required since the Boost::XXXX targets was first added. https://cmake.org/cmake/help/latest/module/FindBoost.html#imported-targets
|
|
||||||
# 3.14 is required since SQLite3 Module was first added. https://cmake.org/cmake/help/latest/module/FindSQLite3.html#findsqlite3
|
|
||||||
|
|
||||||
include(cmake/GetVersion.cmake)
|
|
||||||
get_mapnik_version()
|
|
||||||
|
|
||||||
project(mapnik
|
|
||||||
VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION}
|
|
||||||
HOMEPAGE_URL "https://mapnik.org/"
|
|
||||||
DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications"
|
|
||||||
LANGUAGES CXX
|
|
||||||
)
|
|
||||||
message(STATUS "mapnik version: ${PROJECT_VERSION}")
|
|
||||||
|
|
||||||
# https://cliutils.gitlab.io/modern-cmake/chapters/features/ides.html
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|
||||||
|
|
||||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON) # with newer cmake versions put all find_package in global scope
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|
||||||
include(FeatureSummary)
|
|
||||||
include(MapnikOption)
|
|
||||||
include(MapnikMinimumVersions)
|
|
||||||
include(MapnikFindPackage)
|
|
||||||
include(MapnikInstall)
|
|
||||||
|
|
||||||
include(CTest)
|
|
||||||
add_feature_info(BUILD_TESTING BUILD_TESTING "Adds tests")
|
|
||||||
|
|
||||||
mapnik_option(INSTALL_DEPENDENCIES "if ON, all dependencies (eg. required dlls) will be copied into CMAKE_INSTALL_PREFIX/MAPNIK_BIN_DIR." ON)
|
|
||||||
mapnik_option(BUILD_SHARED_LIBS "build mapnik dynamic(ON) or static(OFF)" ON)
|
|
||||||
mapnik_option(BUILD_SHARED_PLUGINS "build dynamic plugins" ${BUILD_SHARED_LIBS}) # use BUILD_SHARED_LIBS as default option
|
|
||||||
mapnik_option(BUILD_SHARED_CRT "(only windows with msvc) use msvc shared crt" ON)
|
|
||||||
if(WIN32 AND BUILD_SHARED_PLUGINS AND NOT BUILD_SHARED_LIBS)
|
|
||||||
message(FATAL_ERROR "static libmapnik and dynamic plugins won't work correctly")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mapnik_option(USE_EXTERNAL_MAPBOX_GEOMETRY "Use a external mapnik/geometry.hpp. If off, use the submodule" OFF)
|
|
||||||
mapnik_option(USE_EXTERNAL_MAPBOX_POLYLABEL "Use a external mapnik/polylabel. If off, use the submodule" OFF)
|
|
||||||
mapnik_option(USE_EXTERNAL_MAPBOX_PROTOZERO "Use a external mapnik/protozero. If off, use the submodule" OFF)
|
|
||||||
mapnik_option(USE_EXTERNAL_MAPBOX_VARIANT "Use a external mapnik/variant. If off, use the submodule" OFF)
|
|
||||||
mapnik_option(USE_JPEG "adds jpeg support" ON)
|
|
||||||
mapnik_option(USE_PNG "adds png support" ON)
|
|
||||||
mapnik_option(USE_TIFF "adds tiff support" ON)
|
|
||||||
mapnik_option(USE_WEBP "adds webp support" ON)
|
|
||||||
mapnik_option(USE_LIBXML2 "adds libxml2 support" ON)
|
|
||||||
mapnik_option(USE_CAIRO "adds the cairo renderer" ON)
|
|
||||||
mapnik_option(USE_PROJ "adds proj support" ON)
|
|
||||||
mapnik_option(USE_GRID_RENDERER "adds grid renderer" ON)
|
|
||||||
mapnik_option(USE_SVG_RENDERER "adds svg renderer" ON)
|
|
||||||
mapnik_option(USE_BIGINT "uses 64 bit instead of 32" ON)
|
|
||||||
mapnik_option(USE_BOOST_FILESYSTEM "use boost::filesytem even if `std::filesystem` is available (since c++17)" OFF)
|
|
||||||
mapnik_option(USE_MEMORY_MAPPED_FILE "uses file cache" ON)
|
|
||||||
mapnik_option(USE_MULTITHREADED "enables the multithreaded features (threadsafe)" ON)
|
|
||||||
mapnik_option(USE_NO_ATEXIT "disable atexit" OFF)
|
|
||||||
mapnik_option(USE_NO_DLCLOSE "disable dlclose" OFF)
|
|
||||||
mapnik_option(USE_DEBUG_OUTPUT "enables some debug messages for development" OFF)
|
|
||||||
mapnik_option(USE_LOG "enables logging output. See log severity level." OFF)
|
|
||||||
# 0 = debug
|
|
||||||
# 1 = warn
|
|
||||||
# 2 = error
|
|
||||||
# 3 = none
|
|
||||||
set(USE_LOG_SEVERITY "1" CACHE STRING "sets the logging severity (only applies when USE_LOG is ON")
|
|
||||||
mapnik_option(USE_STATS "Enable statistics reporting" OFF)
|
|
||||||
|
|
||||||
mapnik_option(DISABLE_MAPNIK_AUTOSETUP "disables the autosetup. Need to call mapnik::setup() then" OFF)
|
|
||||||
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_CSV "adds plugin input csv" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_GDAL "adds plugin input gdal" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_GEOBUF "adds plugin input geobuf" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_GEOJSON "adds plugin input geojson" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_OGR "adds plugin input ogr" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_PGRASTER "adds plugin input pgraster" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_POSTGIS "adds plugin input postgis" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_RASTER "adds plugin input raster" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_SHAPE "adds plugin input shape" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_SQLITE "adds plugin input sqlite" ON)
|
|
||||||
mapnik_option(USE_PLUGIN_INPUT_TOPOJSON "adds plugin input topojson" ON)
|
|
||||||
|
|
||||||
mapnik_option(BUILD_DEMO_VIEWER "builds the demo viewer" ON)
|
|
||||||
mapnik_option(BUILD_DEMO_CPP "builds the demo c++ application" ON)
|
|
||||||
|
|
||||||
mapnik_option(BUILD_BENCHMARK "builds benchmark project" ON)
|
|
||||||
|
|
||||||
mapnik_option(BUILD_UTILITY_GEOMETRY_TO_WKB "builds the utility program geometry_to_wkb" ON)
|
|
||||||
mapnik_option(BUILD_UTILITY_MAPNIK_INDEX "builds the utility program mapnik_index" ON)
|
|
||||||
mapnik_option(BUILD_UTILITY_MAPNIK_RENDER "builds the utility program mapnik_render" ON)
|
|
||||||
mapnik_option(BUILD_UTILITY_OGRINDEX "builds the utility program ogrindex" OFF)
|
|
||||||
mapnik_option(BUILD_UTILITY_PGSQL2SQLITE "builds the utility program pgsql2sqlite" ON)
|
|
||||||
mapnik_option(BUILD_UTILITY_SHAPEINDEX "builds the utility program shapeindex" ON)
|
|
||||||
mapnik_option(BUILD_UTILITY_SVG2PNG "builds the utility program svg2png" ON)
|
|
||||||
|
|
||||||
mapnik_option(USE_BOOST_REGEX_ICU_WORKAROUND "if you don't use your system libraries and get double linked icu libraries set this to ON" OFF)
|
|
||||||
mapnik_option(USE_GLIBC_WORKAROUND "see https://github.com/mapnik/mapnik/pull/3792 if you building with libstdc++-4.9" OFF)
|
|
||||||
|
|
||||||
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
|
||||||
feature_summary(FILENAME "${CMAKE_CURRENT_BINARY_DIR}/features.log" WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
# See for more details: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html
|
|
||||||
set(MAPNIK_BIN_DIR ${CMAKE_INSTALL_BINDIR} CACHE STRING "Install directory for binaries")
|
|
||||||
set(MAPNIK_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING "Install directory for libraries")
|
|
||||||
set(MAPNIK_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING "Install directory for archives")
|
|
||||||
set(MAPNIK_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING "Install directory for the headers")
|
|
||||||
set(MAPNIK_CMAKE_DIR ${MAPNIK_LIB_DIR}/cmake/mapnik CACHE STRING "Install directory of the cmake targets")
|
|
||||||
set(MAPNIK_PKGCONF_DIR ${MAPNIK_LIB_DIR}/pkgconfig CACHE STRING "Install directory for the .pc files for pkg-config")
|
|
||||||
set(MAPNIK_OUTPUT_DIR "${CMAKE_BINARY_DIR}/out")
|
|
||||||
if(WIN32)
|
|
||||||
set(DEFAULT_PLUGINS_INSTALL_DIR ${MAPNIK_BIN_DIR}/mapnik/input)
|
|
||||||
else()
|
|
||||||
set(DEFAULT_PLUGINS_INSTALL_DIR ${MAPNIK_LIB_DIR}/mapnik/input)
|
|
||||||
endif()
|
|
||||||
set(PLUGINS_INSTALL_DIR ${DEFAULT_PLUGINS_INSTALL_DIR} CACHE STRING "installs the plugins in the specified directory")
|
|
||||||
message(STATUS "Installing plugins to ${PLUGINS_INSTALL_DIR}")
|
|
||||||
|
|
||||||
set(FONTS_INSTALL_DIR ${MAPNIK_LIB_DIR}/mapnik/fonts CACHE STRING "installs the fonts in the specified directory")
|
|
||||||
message(STATUS "Installing fonts to ${FONTS_INSTALL_DIR}")
|
|
||||||
|
|
||||||
set(MAPNIK_COMPILE_DEFS "")
|
|
||||||
set(MAPNIK_OPTIONAL_LIBS "")
|
|
||||||
set(MAPNIK_OPTIONAL_LIBS_INCLUDE "")
|
|
||||||
|
|
||||||
#############################
|
|
||||||
#############################
|
|
||||||
# Begin project configuration
|
|
||||||
#############################
|
|
||||||
#############################
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "Sets the c++ standard. c++17 is minimum.")
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) # require the specified CMAKE_CXX_STANDARD
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF CACHE STRING "Enables the compiler specific extensions.") # Fallsback to -std=c++<ver> if off
|
|
||||||
message(STATUS "Using c++${CMAKE_CXX_STANDARD}")
|
|
||||||
message(STATUS "Using c++ extensions: ${CXX_EXTENSIONS}")
|
|
||||||
|
|
||||||
# add debug postfix to the libraries
|
|
||||||
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "sets the debug library postfix on mapnik, wkt and json")
|
|
||||||
message(STATUS "postfix for debug libraries: ${CMAKE_DEBUG_POSTFIX}")
|
|
||||||
|
|
||||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<BOOL:${BUILD_SHARED_CRT}>:DLL>")
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}")
|
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}")
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib")
|
|
||||||
|
|
||||||
# needs to be before the first call of find_boost.
|
|
||||||
if(CMAKE_CXX_STANDARD VERSION_LESS 17)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS BOOST_SPIRIT_X3_HIDE_CXX17_WARNING)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_MULTITHREADED)
|
|
||||||
set(Boost_USE_MULTITHREADED ON)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_THREADSAFE)
|
|
||||||
else()
|
|
||||||
set(Boost_USE_MULTITHREADED OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
mapnik_find_package(PkgConfig REQUIRED)
|
|
||||||
mapnik_find_threads()
|
|
||||||
mapnik_find_package(ICU REQUIRED COMPONENTS uc i18n data)
|
|
||||||
|
|
||||||
mapnik_find_package(Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS regex)
|
|
||||||
if(CMAKE_CXX_STANDARD VERSION_LESS 17)
|
|
||||||
set(USE_BOOST_FILESYSTEM ON CACHE BOOL "Use boost::filesystem" FORCE)
|
|
||||||
endif()
|
|
||||||
if(USE_BOOST_FILESYSTEM)
|
|
||||||
mapnik_find_package(Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS filesystem system)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS BOOST_REGEX_HAS_ICU)
|
|
||||||
if(USE_BOOST_REGEX_ICU_WORKAROUND)
|
|
||||||
message(STATUS "using boost regex workaround")
|
|
||||||
set_property(TARGET Boost::regex PROPERTY INTERFACE_LINK_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
include(CheckBoostRegexIcu)
|
|
||||||
check_boost_regex()
|
|
||||||
if(BOOST_REGEX_HAS_ICU)
|
|
||||||
message(STATUS "boost regex has icu support")
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS BOOST_REGEX_HAS_ICU)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mapnik_find_package(Freetype REQUIRED)
|
|
||||||
|
|
||||||
# try to find harfbuzz with the native configuration and fallback to our "own" FindHarfBuzz
|
|
||||||
mapnik_find_package(harfbuzz CONFIG QUIET)
|
|
||||||
if(harfbuzz_FOUND)
|
|
||||||
message(STATUS "Found harfbuzz native cmake")
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS harfbuzz::harfbuzz)
|
|
||||||
else()
|
|
||||||
# Use pkg-config when harfbuzz is not found.
|
|
||||||
# It might be possible that in future version harfbuzz could only be found via pkg-config.
|
|
||||||
# harfbuzz related discussion: https://github.com/harfbuzz/harfbuzz/issues/2653
|
|
||||||
message(STATUS "harfbuzz not found via cmake. Searching via pkg-config...")
|
|
||||||
mapnik_pkg_check_modules(harfbuzz REQUIRED IMPORTED_TARGET harfbuzz>=${HARFBUZZ_MIN_VERSION})
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS PkgConfig::harfbuzz)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_GEOMETRY)
|
|
||||||
# this is used to provide a way to specify include dirs with CACHE VARIABLES
|
|
||||||
if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS)
|
|
||||||
message(STATUS "Searching for the include dir of mapbox/geometry.hpp")
|
|
||||||
find_path(MAPBOX_GEOMETRY_INCLUDE_DIRS "mapbox/geometry.hpp" REQUIRED)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(MAPBOX_GEOMETRY_INCLUDE_DIRS
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/geometry/include>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS)
|
|
||||||
message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_POLYLABEL)
|
|
||||||
if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS)
|
|
||||||
message(STATUS "Searching for the include dir of mapbox/polylabel")
|
|
||||||
find_path(MAPBOX_POLYLABEL_INCLUDE_DIRS "mapbox/polylabel.hpp")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(MAPBOX_POLYLABEL_INCLUDE_DIRS
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/polylabel/include>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS)
|
|
||||||
message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_PROTOZERO)
|
|
||||||
if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS)
|
|
||||||
message(STATUS "Searching for the include dir of mapbox/protozero")
|
|
||||||
find_path(MAPBOX_PROTOZERO_INCLUDE_DIRS "protozero/pbf_message.hpp")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(MAPBOX_PROTOZERO_INCLUDE_DIRS
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/protozero/include>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS)
|
|
||||||
message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_VARIANT)
|
|
||||||
if(NOT MAPBOX_VARIANT_INCLUDE_DIRS)
|
|
||||||
message(STATUS "Searching for the include dir of mapbox/variant")
|
|
||||||
find_path(MAPBOX_VARIANT_INCLUDE_DIRS "mapbox/variant.hpp")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(MAPBOX_VARIANT_INCLUDE_DIRS
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/variant/include>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT MAPBOX_VARIANT_INCLUDE_DIRS)
|
|
||||||
message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# (used by MapnikInstall.cmake. properties are needed since "set(...)" will be out of scope
|
|
||||||
set_property(GLOBAL PROPERTY TARGETS "")
|
|
||||||
set_property(GLOBAL PROPERTY PLUGINS "")
|
|
||||||
set_property(GLOBAL PROPERTY MAPNIK_UTILITIES "")
|
|
||||||
|
|
||||||
if(USE_GLIBC_WORKAROUND)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_ENABLE_GLIBC_WORKAROUND)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_BIGINT)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS BIGINT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_BOOST_FILESYSTEM)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS USE_BOOST_FILESYSTEM)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS Boost::filesystem)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_MEMORY_MAPPED_FILE)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_MEMORY_MAPPED_FILE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_NO_ATEXIT)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_NO_ATEXIT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_NO_DLCLOSE)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_NO_DLCLOSE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_DEBUG_OUTPUT)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_DEBUG)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_LOG)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_LOG MAPNIK_DEFAULT_LOG_SEVERITY=${USE_LOG_SEVERITY})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_STATS)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_STATS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_LIBXML2)
|
|
||||||
mapnik_find_package(LibXml2 REQUIRED)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_LIBXML2)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS LibXml2::LibXml2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_PNG)
|
|
||||||
mapnik_find_package(PNG REQUIRED)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_PNG)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS PNG::PNG)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_JPEG)
|
|
||||||
mapnik_find_package(JPEG REQUIRED)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_JPEG)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS JPEG::JPEG)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_TIFF)
|
|
||||||
mapnik_find_package(TIFF REQUIRED)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_TIFF)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS TIFF::TIFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_WEBP)
|
|
||||||
mapnik_pkg_check_modules(WebP REQUIRED IMPORTED_TARGET libwebp)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_WEBP)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS PkgConfig::WebP)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_CAIRO)
|
|
||||||
mapnik_pkg_check_modules(Cairo REQUIRED IMPORTED_TARGET cairo)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS HAVE_CAIRO)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS PkgConfig::Cairo)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_PROJ)
|
|
||||||
#https://proj.org/development/cmake.html
|
|
||||||
mapnik_find_package(PROJ QUIET)
|
|
||||||
# currently the cmake files are not installed, when installing proj via apt-get. So search via pkg-config
|
|
||||||
if(NOT PROJ_FOUND)
|
|
||||||
message(STATUS "PROJ not found via FindPROJ. Searching via pkg-config...")
|
|
||||||
mapnik_pkg_check_modules(PROJ REQUIRED IMPORTED_TARGET proj>=${PROJ_MIN_VERSION})
|
|
||||||
string(REGEX MATCH "([0-9]+)\.([0-9]+)\.([0-9]+)" _dummy "${PROJ_VERSION}")
|
|
||||||
set(PROJ_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
|
||||||
set(PROJ_VERSION_MINOR "${CMAKE_MATCH_2}")
|
|
||||||
set(PROJ_VERSION_PATCH "${CMAKE_MATCH_3}")
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS PkgConfig::PROJ)
|
|
||||||
else()
|
|
||||||
if(PROJ_VERSION VERSION_LESS PROJ_MIN_VERSION)
|
|
||||||
message(FATAL_ERROR "Proj needs to be at least version ${PROJ_MIN_VERSION}")
|
|
||||||
endif()
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS ${PROJ_LIBRARIES})
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS_INCLUDE $<BUILD_INTERFACE:${PROJ_INCLUDE_DIRS}>)
|
|
||||||
endif()
|
|
||||||
math(EXPR MAPNIK_PROJ_VERSION "${PROJ_VERSION_MAJOR}*10000 + ${PROJ_VERSION_MINOR}*100 + ${PROJ_VERSION_PATCH}" OUTPUT_FORMAT DECIMAL)
|
|
||||||
message(STATUS "Using mapnik PROJ version: ${MAPNIK_PROJ_VERSION}")
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_USE_PROJ MAPNIK_PROJ_VERSION=${MAPNIK_PROJ_VERSION})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_GRID_RENDERER)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS GRID_RENDERER)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_SVG_RENDERER)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS SVG_RENDERER)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT WIN32)
|
|
||||||
message(STATUS "Compiling with -DMAPNIK_HAS_DLCFN")
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_HAS_DLCFN)
|
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS ${CMAKE_DL_LIBS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT BUILD_SHARED_PLUGINS)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_STATIC_PLUGINS)
|
|
||||||
endif()
|
|
||||||
# when building static, this have to be public so that all depending libs know about
|
|
||||||
if(NOT BUILD_SHARED_LIBS)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_STATIC_DEFINE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DISABLE_MAPNIK_AUTOSETUP)
|
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_DISABLE_AUTOSETUP)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# force utf-8 source code processing
|
|
||||||
# see https://docs.microsoft.com/de-de/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-170
|
|
||||||
add_compile_options(
|
|
||||||
"$<$<CXX_COMPILER_ID:MSVC>:/utf-8>"
|
|
||||||
"$<$<CXX_COMPILER_ID:MSVC>:/EHsc>"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(core INTERFACE)
|
|
||||||
add_library(mapnik::core ALIAS core)
|
|
||||||
|
|
||||||
target_include_directories(core INTERFACE
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
||||||
$<BUILD_INTERFACE:${MAPBOX_GEOMETRY_INCLUDE_DIRS}>
|
|
||||||
$<BUILD_INTERFACE:${MAPBOX_POLYLABEL_INCLUDE_DIRS}>
|
|
||||||
$<BUILD_INTERFACE:${MAPBOX_VARIANT_INCLUDE_DIRS}>
|
|
||||||
$<BUILD_INTERFACE:${MAPBOX_PROTOZERO_INCLUDE_DIRS}>
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps>
|
|
||||||
$<INSTALL_INTERFACE:include>
|
|
||||||
${MAPNIK_OPTIONAL_LIBS_INCLUDE}
|
|
||||||
)
|
|
||||||
target_link_libraries(core INTERFACE
|
|
||||||
Threads::Threads
|
|
||||||
ICU::uc
|
|
||||||
ICU::data
|
|
||||||
ICU::i18n
|
|
||||||
Boost::headers
|
|
||||||
Boost::regex
|
|
||||||
Freetype::Freetype
|
|
||||||
${MAPNIK_OPTIONAL_LIBS}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(core INTERFACE ${MAPNIK_COMPILE_DEFS})
|
|
||||||
|
|
||||||
mapnik_install(core)
|
|
||||||
|
|
||||||
###
|
|
||||||
# forward declaring libraries to consume them when building static plugins (circle deps between mapnik <-> plugin_target)
|
|
||||||
add_library(mapnik "")
|
|
||||||
add_library(mapnik::mapnik ALIAS mapnik)
|
|
||||||
add_library(wkt STATIC "")
|
|
||||||
add_library(mapnik::wkt ALIAS wkt)
|
|
||||||
add_library(json STATIC "")
|
|
||||||
add_library(mapnik::json ALIAS json)
|
|
||||||
# end forward declaration
|
|
||||||
###
|
|
||||||
|
|
||||||
add_subdirectory(deps)
|
|
||||||
add_subdirectory(plugins)
|
|
||||||
add_subdirectory(src)
|
|
||||||
add_subdirectory(utils)
|
|
||||||
add_subdirectory(demo)
|
|
||||||
if(BUILD_BENCHMARK)
|
|
||||||
add_subdirectory(benchmark)
|
|
||||||
endif()
|
|
||||||
if(BUILD_TESTING)
|
|
||||||
add_subdirectory(test)
|
|
||||||
endif()
|
|
||||||
file(COPY fonts DESTINATION "${MAPNIK_OUTPUT_DIR}")
|
|
||||||
|
|
||||||
feature_summary(FILENAME "${CMAKE_CURRENT_BINARY_DIR}/packages.log" WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND INCLUDE_QUIET_PACKAGES)
|
|
||||||
|
|
||||||
# start package mapnik
|
|
||||||
include(MapnikExport)
|
|
||||||
include(MapnikExportPkgConfig)
|
|
||||||
|
|
||||||
install(DIRECTORY include/mapnik/ DESTINATION "${MAPNIK_INCLUDE_DIR}/mapnik")
|
|
||||||
install(DIRECTORY deps/agg/include/ DESTINATION "${MAPNIK_INCLUDE_DIR}/mapnik/agg")
|
|
||||||
install(DIRECTORY deps/mapnik DESTINATION "${MAPNIK_INCLUDE_DIR}")
|
|
||||||
file(GLOB TTF_FONT_FILES "fonts/*/*/*.ttf")
|
|
||||||
install(FILES ${TTF_FONT_FILES} DESTINATION "${FONTS_INSTALL_DIR}")
|
|
||||||
|
|
||||||
if(NOT USE_EXTERNAL_MAPBOX_GEOMETRY)
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/geometry/include/" DESTINATION "${MAPNIK_INCLUDE_DIR}")
|
|
||||||
endif()
|
|
||||||
if(NOT USE_EXTERNAL_MAPBOX_POLYLABEL)
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/polylabel/include/" DESTINATION "${MAPNIK_INCLUDE_DIR}")
|
|
||||||
endif()
|
|
||||||
if(NOT USE_EXTERNAL_MAPBOX_PROTOZERO)
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/protozero/include/" DESTINATION "${MAPNIK_INCLUDE_DIR}")
|
|
||||||
endif()
|
|
||||||
if(NOT USE_EXTERNAL_MAPBOX_VARIANT)
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/variant/include/" DESTINATION "${MAPNIK_INCLUDE_DIR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mapnik_install_targets()
|
|
||||||
|
|
||||||
include(pack)
|
|
|
@ -1,350 +0,0 @@
|
||||||
{
|
|
||||||
"version": 6,
|
|
||||||
"cmakeMinimumRequired": {
|
|
||||||
"major": 3,
|
|
||||||
"minor": 25,
|
|
||||||
"patch": 0
|
|
||||||
},
|
|
||||||
"configurePresets": [
|
|
||||||
{
|
|
||||||
"name": "use-ninja",
|
|
||||||
"hidden": true,
|
|
||||||
"generator": "Ninja",
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "default-build-dir",
|
|
||||||
"hidden": true,
|
|
||||||
"binaryDir": "${sourceDir}/build"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "debug-build",
|
|
||||||
"hidden": true,
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_BUILD_TYPE": "Debug",
|
|
||||||
"USE_DEBUG_OUTPUT": "ON",
|
|
||||||
"USE_LOG": "ON",
|
|
||||||
"USE_LOG_SEVERITY": "0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "release-with-debug-build",
|
|
||||||
"hidden": true,
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
|
||||||
"USE_DEBUG_OUTPUT": "OFF",
|
|
||||||
"USE_LOG": "OFF"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "release-build",
|
|
||||||
"hidden": true,
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_BUILD_TYPE": "Release",
|
|
||||||
"USE_DEBUG_OUTPUT": "OFF",
|
|
||||||
"USE_LOG": "OFF"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "use-clang",
|
|
||||||
"hidden": true,
|
|
||||||
"inherits": [
|
|
||||||
"default-build-dir",
|
|
||||||
"use-ninja"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_C_COMPILER": "clang",
|
|
||||||
"CMAKE_CXX_COMPILER": "clang++",
|
|
||||||
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
|
|
||||||
"CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++",
|
|
||||||
"CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "use-gcc",
|
|
||||||
"hidden": true,
|
|
||||||
"inherits": [
|
|
||||||
"default-build-dir",
|
|
||||||
"use-ninja"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_C_COMPILER": "gcc",
|
|
||||||
"CMAKE_CXX_COMPILER": "g++"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "use-msvc-cl",
|
|
||||||
"hidden": true,
|
|
||||||
"inherits": [
|
|
||||||
"default-build-dir",
|
|
||||||
"use-ninja"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_C_COMPILER": "cl",
|
|
||||||
"CMAKE_CXX_COMPILER": "cl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "use-msvc-clang-cl",
|
|
||||||
"hidden": true,
|
|
||||||
"inherits": [
|
|
||||||
"default-build-dir",
|
|
||||||
"use-ninja"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_C_COMPILER": "clang-cl",
|
|
||||||
"CMAKE_CXX_COMPILER": "clang-cl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-clang-debug",
|
|
||||||
"displayName": "Linux clang debug",
|
|
||||||
"inherits": [
|
|
||||||
"use-clang",
|
|
||||||
"debug-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-clang-release",
|
|
||||||
"displayName": "Linux clang release",
|
|
||||||
"inherits": [
|
|
||||||
"use-clang",
|
|
||||||
"release-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-gcc-debug",
|
|
||||||
"displayName": "Linux gcc debug",
|
|
||||||
"inherits": [
|
|
||||||
"use-gcc",
|
|
||||||
"debug-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-gcc-release",
|
|
||||||
"displayName": "Linux gcc release",
|
|
||||||
"inherits": [
|
|
||||||
"use-gcc",
|
|
||||||
"release-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-arch-x64",
|
|
||||||
"hidden": true,
|
|
||||||
"architecture": {
|
|
||||||
"value": "x64",
|
|
||||||
"strategy": "external"
|
|
||||||
},
|
|
||||||
"toolset": {
|
|
||||||
"value": "host=x64",
|
|
||||||
"strategy": "external"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-default",
|
|
||||||
"displayName": "Windows x64 Debug",
|
|
||||||
"hidden": true,
|
|
||||||
"inherits": [
|
|
||||||
"use-msvc-cl",
|
|
||||||
"windows-arch-x64"
|
|
||||||
],
|
|
||||||
"vendor": {
|
|
||||||
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
|
||||||
"hostOS": [
|
|
||||||
"Windows"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-debug",
|
|
||||||
"displayName": "Windows x64 Debug",
|
|
||||||
"inherits": [
|
|
||||||
"windows-default",
|
|
||||||
"debug-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-release",
|
|
||||||
"displayName": "Windows x64 Release",
|
|
||||||
"inherits": [
|
|
||||||
"windows-default",
|
|
||||||
"release-build"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ci-options",
|
|
||||||
"hidden": true,
|
|
||||||
"cacheVariables": {
|
|
||||||
"BUILD_TESTING": "ON",
|
|
||||||
"BUILD_DEMO_VIEWER": "OFF",
|
|
||||||
"DISABLE_MAPNIK_AUTOSETUP": "ON"
|
|
||||||
},
|
|
||||||
"toolchainFile": "vcpkg/scripts/buildsystems/vcpkg.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-ci",
|
|
||||||
"description": "used by the ci pipeline",
|
|
||||||
"inherits": [
|
|
||||||
"windows-release",
|
|
||||||
"ci-options"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"INSTALL_DEPENDENCIES": "ON",
|
|
||||||
"ADDITIONAL_LIBARIES_PATHS": "${sourceDir}/build/vcpkg_installed/x64-windows/bin"
|
|
||||||
},
|
|
||||||
"environment": {
|
|
||||||
"PROJ_LIB": "${sourceDir}/build/vcpkg_installed/x64-windows/share/proj"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-ci",
|
|
||||||
"description": "used by the ci pipeline",
|
|
||||||
"inherits": [
|
|
||||||
"release-with-debug-build",
|
|
||||||
"use-gcc",
|
|
||||||
"ci-options"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_CXX_FLAGS": "--coverage"
|
|
||||||
},
|
|
||||||
"environment": {
|
|
||||||
"PROJ_LIB": "${sourceDir}/build/vcpkg_installed/x64-linux/share/proj"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-ci-release",
|
|
||||||
"description": "used by the ci pipeline for releasing",
|
|
||||||
"inherits": [
|
|
||||||
"release-build",
|
|
||||||
"linux-gcc-release"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"BUILD_TESTING": "OFF",
|
|
||||||
"BUILD_DEMO_VIEWER": "OFF",
|
|
||||||
"USE_MEMORY_MAPPED_FILE": "ON"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-arm64",
|
|
||||||
"description": "used by the ci pipeline",
|
|
||||||
"inherits": [
|
|
||||||
"use-ninja",
|
|
||||||
"release-with-debug-build",
|
|
||||||
"default-build-dir",
|
|
||||||
"ci-options"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_CXX_FLAGS": "-fprofile-arcs -ftest-coverage"
|
|
||||||
},
|
|
||||||
"environment": {
|
|
||||||
"PROJ_LIB": "${sourceDir}/build/vcpkg_installed/arm64-osx/share/proj"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-x64",
|
|
||||||
"description": "used by the ci pipeline",
|
|
||||||
"inherits": [
|
|
||||||
"use-ninja",
|
|
||||||
"release-with-debug-build",
|
|
||||||
"default-build-dir",
|
|
||||||
"ci-options"
|
|
||||||
],
|
|
||||||
"cacheVariables": {
|
|
||||||
"CMAKE_CXX_FLAGS": "-fprofile-arcs -ftest-coverage"
|
|
||||||
},
|
|
||||||
"environment": {
|
|
||||||
"PROJ_LIB": "${sourceDir}/build/vcpkg_installed/x64-osx/share/proj"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"buildPresets": [
|
|
||||||
{
|
|
||||||
"name": "windows-debug",
|
|
||||||
"configurePreset": "windows-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-release",
|
|
||||||
"configurePreset": "windows-release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-clang-debug",
|
|
||||||
"configurePreset": "linux-clang-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-clang-release",
|
|
||||||
"configurePreset": "linux-clang-release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-gcc-debug",
|
|
||||||
"configurePreset": "linux-gcc-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-gcc-release",
|
|
||||||
"configurePreset": "linux-gcc-release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-ci",
|
|
||||||
"configurePreset": "windows-ci"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-ci",
|
|
||||||
"configurePreset": "linux-ci"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-ci-release",
|
|
||||||
"configurePreset": "linux-ci-release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-arm64",
|
|
||||||
"configurePreset": "macos-ci-arm64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-x64",
|
|
||||||
"configurePreset": "macos-ci-x64"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"testPresets": [
|
|
||||||
{
|
|
||||||
"name": "test-default",
|
|
||||||
"hidden": true,
|
|
||||||
"output": {
|
|
||||||
"outputOnFailure": true
|
|
||||||
},
|
|
||||||
"execution": {
|
|
||||||
"noTestsAction": "error",
|
|
||||||
"stopOnFailure": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "windows-ci",
|
|
||||||
"configurePreset": "windows-ci",
|
|
||||||
"inherits": [
|
|
||||||
"test-default"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "linux-ci",
|
|
||||||
"configurePreset": "linux-ci",
|
|
||||||
"inherits": [
|
|
||||||
"test-default"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-arm64",
|
|
||||||
"configurePreset": "macos-ci-arm64",
|
|
||||||
"inherits": [
|
|
||||||
"test-default"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "macos-ci-x64",
|
|
||||||
"configurePreset": "macos-ci-x64",
|
|
||||||
"inherits": [
|
|
||||||
"test-default"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Contributor Code of Conduct
|
|
||||||
|
|
||||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
|
||||||
|
|
||||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery
|
|
||||||
* Personal attacks
|
|
||||||
* Trolling or insulting/derogatory comments
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
|
||||||
* Other unethical or unprofessional conduct.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
|
||||||
|
|
||||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
|
98
INSTALL.md
98
INSTALL.md
|
@ -1,64 +1,25 @@
|
||||||
# Mapnik Installation
|
# Mapnik Installation
|
||||||
|
|
||||||
Mapnik runs on Linux, OS X, Windows, and BSD systems.
|
Mapnik is cross platform and runs on Linux, Mac OSX, Solaris, *BSD, and Windows.
|
||||||
|
|
||||||
## Package managers
|
|
||||||
### vcpkg
|
|
||||||
To install mapnik with vcpkg type `vcpkg install mapnik`. It will install a minimal version of mapnik and all the needed dependencies.
|
|
||||||
To install more features, type `vcpkg search mapnik` to see all available features.
|
|
||||||
|
|
||||||
## Source build
|
|
||||||
|
|
||||||
First clone mapnik from github and initialize submodules
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/mapnik/mapnik.git
|
|
||||||
cd mapnik
|
|
||||||
git submodule update --init
|
|
||||||
```
|
|
||||||
|
|
||||||
To configure and build Mapnik do:
|
To configure and build Mapnik do:
|
||||||
|
|
||||||
```bash
|
./configure
|
||||||
./configure
|
make
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
To trigger parallel compilation you can pass a JOBS value to make:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
JOBS=4 make
|
|
||||||
```
|
|
||||||
|
|
||||||
Mapnik needs > 2 GB of RAM to build. If you use parallel compilation it needs more.
|
|
||||||
|
|
||||||
If you are on a system with less memory make sure you only build with one JOB:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
JOBS=1 make
|
|
||||||
```
|
|
||||||
|
|
||||||
To use a Python interpreter that is not named `python` for your build, do
|
|
||||||
something like the following instead:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ PYTHON=python3 ./configure
|
|
||||||
$ make PYTHON=python3
|
|
||||||
```
|
|
||||||
|
|
||||||
NOTE: the above will not work on windows, rather see https://github.com/mapnik/mapnik/wiki/WindowsInstallation
|
NOTE: the above will not work on windows, rather see https://github.com/mapnik/mapnik/wiki/WindowsInstallation
|
||||||
|
|
||||||
Then to run the tests locally (without needing to install):
|
Then to run the tests locally (without needing to install):
|
||||||
|
|
||||||
make test
|
make test-local
|
||||||
|
|
||||||
Install like:
|
Install like:
|
||||||
|
|
||||||
make install
|
sudo make install
|
||||||
|
|
||||||
If you need to uninstall do:
|
If you need to uninstall do:
|
||||||
|
|
||||||
make uninstall
|
sudo make uninstall
|
||||||
|
|
||||||
For more details see the `Building` Section below.
|
For more details see the `Building` Section below.
|
||||||
|
|
||||||
|
@ -71,25 +32,26 @@ For troubleshooting help see https://github.com/mapnik/mapnik/wiki/InstallationT
|
||||||
|
|
||||||
Build system dependencies are:
|
Build system dependencies are:
|
||||||
|
|
||||||
* C++ compiler supporting `-std=c++17` (like >= g++ 9 or >= clang++ 5)
|
* C++ compiler (like g++ or clang++)
|
||||||
* \>= 2 GB RAM (> 5 GB for g++)
|
* >= 2 GB RAM
|
||||||
* Python 3
|
* Python 2.4-2.7
|
||||||
* Scons (a copy is bundled) or CMake >= 3.15 see [docs/cmake-usage.md](./docs/cmake-usage.md)
|
* Scons (a copy is bundled)
|
||||||
|
|
||||||
Mapnik Core depends on:
|
Mapnik Core depends on:
|
||||||
|
|
||||||
* Boost
|
* Boost
|
||||||
- \>= 1.73 is required
|
- >= 1.47 is required.
|
||||||
- These libraries are used:
|
- These libraries are used:
|
||||||
- filesystem
|
- filesystem
|
||||||
- system
|
- system
|
||||||
|
- thread (if mapnik threadsafe support is required, default on)
|
||||||
- regex (optionally built with icu regex support)
|
- regex (optionally built with icu regex support)
|
||||||
- program_options (optionally for mapnik command line programs)
|
- program_options (optionally for mapnik command line programs)
|
||||||
* libicuuc >= 4.0 (ideally >= 4.2) - International Components for Unicode
|
* libicuuc >= 4.0 (ideally >= 4.2) - International Components for Unicode
|
||||||
* libz - Zlib compression
|
* libz - Zlib compression
|
||||||
* libfreetype - Freetype2 for font support (Install requires freetype-config)
|
* libfreetype - Freetype2 for font support (Install requires freetype-config)
|
||||||
* libxml2 - XML parsing (Install requires xml2-config)
|
* libxml2 - XML parsing (Install requires xml2-config)
|
||||||
* libharfbuzz - an OpenType text shaping engine (>=0.9.34 needed for CSS font-feature-settings support)
|
* libharfbuzz - an OpenType text shaping engine
|
||||||
|
|
||||||
Mapnik Core optionally depends on:
|
Mapnik Core optionally depends on:
|
||||||
|
|
||||||
|
@ -97,17 +59,29 @@ Mapnik Core optionally depends on:
|
||||||
* libjpeg - JPEG graphics (Default enabled, if found)
|
* libjpeg - JPEG graphics (Default enabled, if found)
|
||||||
* libtiff - TIFF graphics (Default enabled, if found)
|
* libtiff - TIFF graphics (Default enabled, if found)
|
||||||
* libwebp - WEBP graphics (Default enabled, if found)
|
* libwebp - WEBP graphics (Default enabled, if found)
|
||||||
* libproj >= 7.2.0 - PROJ projection library (Default enabled, if found)
|
* libproj - PROJ.4 projection library (Default enabled, if found)
|
||||||
|
|
||||||
|
Mapnik Python bindings depend on:
|
||||||
|
|
||||||
|
* Python 2.5-2.7 or >= 3.2
|
||||||
|
* Boost python
|
||||||
|
* simplejson module if using <= 2.5
|
||||||
|
|
||||||
|
Note: Python 3.x is supported, see: https://github.com/mapnik/mapnik/wiki/Python3k
|
||||||
|
|
||||||
Additional optional dependencies:
|
Additional optional dependencies:
|
||||||
|
|
||||||
* Cairo >= 1.6.0 - Graphics library for output formats like PDF, PS, and SVG
|
* Cairo >= 1.6.0 - Graphics library for output formats like PDF, PS, and SVG
|
||||||
- pkg-config - Required for building with cairo support
|
- pkg-config - Required for building with cairo support
|
||||||
|
- pycairo - Python bindings for cairo
|
||||||
* PostgreSQL (for PostGIS plugin support)
|
* PostgreSQL (for PostGIS plugin support)
|
||||||
- libpq - PostreSQL libraries
|
- libpq - PostreSQL libraries
|
||||||
- pg_config - PostgreSQL installation capabilities
|
- pg_config - PostgreSQL installation capabilities
|
||||||
* libgdal - GDAL/OGR input (For gdal and ogr plugin support) (>= GDAL 2.0.2 for thread safety - https://github.com/mapnik/mapnik/issues/3339)
|
* libgdal - GDAL/OGR input (For gdal and ogr plugin support)
|
||||||
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
|
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
|
||||||
|
* libocci - Oracle input plugin support
|
||||||
|
* libcurl - OSM input plugin support
|
||||||
|
* librasterlite - Rasterlite input plugin support
|
||||||
|
|
||||||
Instructions for installing many of these dependencies on
|
Instructions for installing many of these dependencies on
|
||||||
various platforms can be found at the Mapnik Wiki:
|
various platforms can be found at the Mapnik Wiki:
|
||||||
|
@ -168,13 +142,17 @@ For more details on usage see:
|
||||||
|
|
||||||
You can run the Mapnik tests locally (without installing) like:
|
You can run the Mapnik tests locally (without installing) like:
|
||||||
|
|
||||||
make test
|
make test-local # see the Makefile for how this works
|
||||||
|
|
||||||
## Python Bindings
|
Or you can install and test like:
|
||||||
|
|
||||||
Python bindings are not included by default. You'll need to add those separately.
|
make install && make test
|
||||||
|
|
||||||
|
Many of the tests are written in python and you can run them individually like:
|
||||||
|
|
||||||
|
make install
|
||||||
|
python tests/python_tests/shapefile_test.py
|
||||||
|
|
||||||
* Build from source: https://github.com/mapnik/python-mapnik
|
|
||||||
|
|
||||||
## Learning Mapnik
|
## Learning Mapnik
|
||||||
|
|
||||||
|
@ -191,7 +169,7 @@ If you need help or want to participate starting points include:
|
||||||
### Cartographers
|
### Cartographers
|
||||||
|
|
||||||
TileMill, which uses Mapnik internally, offers great step by step tutorials for
|
TileMill, which uses Mapnik internally, offers great step by step tutorials for
|
||||||
learning advanced map styling: https://tilemill-project.github.io/tilemill/docs/crashcourse/introduction/
|
learning advanced map styling: http://mapbox.com/tilemill/docs/crashcourse/introduction/
|
||||||
|
|
||||||
### Programmers
|
### Programmers
|
||||||
|
|
||||||
|
@ -199,6 +177,6 @@ Mapnik is great for building your own mapping applications. Visit
|
||||||
https://github.com/mapnik/mapnik/wiki/LearningMapnik for basic
|
https://github.com/mapnik/mapnik/wiki/LearningMapnik for basic
|
||||||
tutorials on how to programmatically use Mapnik.
|
tutorials on how to programmatically use Mapnik.
|
||||||
|
|
||||||
### Contributors
|
### Contributers
|
||||||
|
|
||||||
Read [docs/contributing.md](docs/contributing.md) for resources for getting involved with Mapnik development.
|
Read docs/contributing.markdown for resources for getting involved with Mapnik development.
|
||||||
|
|
101
Makefile
101
Makefile
|
@ -1,68 +1,39 @@
|
||||||
|
|
||||||
OS := $(shell uname -s)
|
OS := $(shell uname -s)
|
||||||
|
|
||||||
ifeq ($(JOBS),)
|
ifeq ($(JOBS),)
|
||||||
JOBS:=1
|
JOBS:=1
|
||||||
endif
|
ifeq ($(OS),Linux)
|
||||||
|
JOBS:=$(shell grep -c ^processor /proc/cpuinfo)
|
||||||
ifeq ($(HEAVY_JOBS),)
|
endif
|
||||||
HEAVY_JOBS:=1
|
ifeq ($(OS),Darwin)
|
||||||
|
JOBS:=$(shell sysctl -n hw.ncpu)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: mapnik
|
all: mapnik
|
||||||
|
|
||||||
install:
|
install:
|
||||||
$(PYTHON) scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1 install
|
python scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1 install
|
||||||
|
|
||||||
release:
|
mapnik:
|
||||||
./scripts/publish_release.sh
|
python scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1
|
||||||
|
|
||||||
test-release:
|
|
||||||
./scripts/test_release.sh
|
|
||||||
|
|
||||||
src/json/libmapnik-json.a:
|
|
||||||
# we first build memory intensive files with -j$(HEAVY_JOBS)
|
|
||||||
$(PYTHON) scons/scons.py -j$(HEAVY_JOBS) \
|
|
||||||
--config=cache --implicit-cache --max-drift=1 \
|
|
||||||
src/renderer_common/render_group_symbolizer.os \
|
|
||||||
src/renderer_common/render_markers_symbolizer.os \
|
|
||||||
src/renderer_common/render_thunk_extractor.os \
|
|
||||||
src/json/libmapnik-json.a \
|
|
||||||
src/wkt/libmapnik-wkt.a \
|
|
||||||
src/css/css_grammar_x3.os \
|
|
||||||
src/css/css_color_grammar_x3.os \
|
|
||||||
src/expression_grammar_x3.os \
|
|
||||||
src/transform_expression_grammar_x3.os \
|
|
||||||
src/image_filter_grammar_x3.os \
|
|
||||||
src/marker_helpers.os \
|
|
||||||
src/svg/svg_transform_parser.os \
|
|
||||||
src/agg/process_line_symbolizer.os \
|
|
||||||
plugins/input/geojson/geojson_datasource.os \
|
|
||||||
src/svg/svg_path_parser.os \
|
|
||||||
src/svg/svg_parser.os \
|
|
||||||
src/svg/svg_points_parser.os \
|
|
||||||
src/svg/svg_transform_parser.os \
|
|
||||||
|
|
||||||
|
|
||||||
mapnik: src/json/libmapnik-json.a
|
|
||||||
# then install the rest with -j$(JOBS)
|
|
||||||
$(PYTHON) scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(PYTHON) scons/scons.py -j$(JOBS) -c --config=cache --implicit-cache --max-drift=1
|
@python scons/scons.py -j$(JOBS) -c --config=cache --implicit-cache --max-drift=1
|
||||||
@if test -e ".sconsign.dblite"; then rm ".sconsign.dblite"; fi
|
@if test -e ".sconsign.dblite"; then rm ".sconsign.dblite"; fi
|
||||||
@if test -e "config.log"; then rm "config.log"; fi
|
@if test -e "config.log"; then rm "config.log"; fi
|
||||||
@if test -e "config.cache"; then rm "config.cache"; fi
|
|
||||||
@if test -e ".sconf_temp/"; then rm -r ".sconf_temp/"; fi
|
@if test -e ".sconf_temp/"; then rm -r ".sconf_temp/"; fi
|
||||||
@find ./ -name "*.pyc" -exec rm {} \;
|
@find ./ -name "*.pyc" -exec rm {} \;
|
||||||
@find ./ -name "*.os" -exec rm {} \;
|
@find ./ -name "*.os" -exec rm {} \;
|
||||||
@find ./src/ -name "*.dylib" -exec rm {} \;
|
@find ./ -name "*.dylib" -exec rm {} \;
|
||||||
@find ./src/ -name "*.so" -exec rm {} \;
|
@find ./ -name "*.so" -exec rm {} \;
|
||||||
@find ./ -name "*.o" -exec rm {} \;
|
@find ./ -name "*.o" -exec rm {} \;
|
||||||
@find ./src/ -name "*.a" -exec rm {} \;
|
@find ./ -name "*.pyc" -exec rm {} \;
|
||||||
@find ./ -name "*.gcda" -exec rm {} \;
|
@if test -e "bindings/python/mapnik/paths.py"; then rm "bindings/python/mapnik/paths.py"; fi
|
||||||
@find ./ -name "*.gcno" -exec rm {} \;
|
|
||||||
|
|
||||||
distclean:
|
distclean:
|
||||||
|
@if test -e "config.cache"; then rm "config.cache"; fi
|
||||||
if test -e "config.py"; then mv "config.py" "config.py.backup"; fi
|
if test -e "config.py"; then mv "config.py" "config.py.backup"; fi
|
||||||
|
|
||||||
reset: distclean
|
reset: distclean
|
||||||
|
@ -71,18 +42,24 @@ rebuild:
|
||||||
make uninstall && make clean && time make && make install
|
make uninstall && make clean && time make && make install
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@$(PYTHON) scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1 uninstall
|
@python scons/scons.py -j$(JOBS) --config=cache --implicit-cache --max-drift=1 uninstall
|
||||||
|
|
||||||
test/data-visual:
|
test:
|
||||||
./scripts/ensure_test_data.sh
|
./run_tests
|
||||||
|
|
||||||
test/data:
|
test-local:
|
||||||
./scripts/ensure_test_data.sh
|
make test
|
||||||
|
|
||||||
test: ./test/data test/data-visual
|
test-visual:
|
||||||
@./test/run
|
bash -c "source ./localize.sh && python tests/visual_tests/test.py -q"
|
||||||
|
|
||||||
check: test
|
test-python:
|
||||||
|
bash -c "source ./localize.sh && python tests/run_tests.py -q"
|
||||||
|
|
||||||
|
test-cpp:
|
||||||
|
./tests/cpp_tests/run
|
||||||
|
|
||||||
|
check: test-local
|
||||||
|
|
||||||
bench:
|
bench:
|
||||||
./benchmark/run
|
./benchmark/run
|
||||||
|
@ -90,16 +67,16 @@ bench:
|
||||||
demo:
|
demo:
|
||||||
cd demo/c++; ./rundemo `mapnik-config --prefix`
|
cd demo/c++; ./rundemo `mapnik-config --prefix`
|
||||||
|
|
||||||
# note: pass --gen-suppressions=yes to create new suppression entries
|
pep8:
|
||||||
|
# https://gist.github.com/1903033
|
||||||
|
# gsed on osx
|
||||||
|
@pep8 -r --select=W293 -q --filename=*.py `pwd`/tests/ | xargs gsed -i 's/^[ \r\t]*$//'
|
||||||
|
@pep8 -r --select=W391 -q --filename=*.py `pwd`/tests/ | xargs gsed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}'
|
||||||
|
|
||||||
grind:
|
grind:
|
||||||
@source localize.sh && \
|
@for FILE in tests/cpp_tests/*-bin; do \
|
||||||
valgrind --suppressions=./test/unit/valgrind.supp --leak-check=full --log-fd=1 ./test/visual/run | grep definitely;
|
valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \
|
||||||
@source localize.sh && \
|
|
||||||
for FILE in test/standalone/*-bin; do \
|
|
||||||
valgrind --suppressions=./test/unit/valgrind.supp --leak-check=full --log-fd=1 $${FILE} | grep definitely; \
|
|
||||||
done
|
done
|
||||||
@source localize.sh && \
|
|
||||||
valgrind --suppressions=./test/unit/valgrind.supp --leak-check=full --log-fd=1 ./test/unit/run | grep definitely;
|
|
||||||
|
|
||||||
render:
|
render:
|
||||||
@for FILE in tests/data/good_maps/*xml; do \
|
@for FILE in tests/data/good_maps/*xml; do \
|
||||||
|
|
19
README.md
19
README.md
|
@ -8,23 +8,22 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/
|
||||||
_/
|
_/
|
||||||
```
|
```
|
||||||
|
|
||||||
[![TravisCI](https://api.travis-ci.com/mapnik/mapnik.svg?branch=master)](http://travis-ci.com/mapnik/mapnik)
|
[![Build Status](https://secure.travis-ci.org/mapnik/mapnik.png)](http://travis-ci.org/mapnik/mapnik)
|
||||||
[![codecov](https://codecov.io/gh/mapnik/mapnik/branch/master/graph/badge.svg)](https://codecov.io/gh/mapnik/mapnik)
|
|
||||||
|
|
||||||
Mapnik is an open source toolkit for developing mapping applications. At the core is a C++ shared library providing algorithms and patterns for spatial data access and visualization.
|
# What is Mapnik?
|
||||||
|
|
||||||
|
Mapnik is an open source toolkit for developing mapping applications. At the core is a C++ shared library providing algorithms and patterns for spatial data access and visualization. High-level bindings for JavaScript, Python, and Ruby facilitate rapid application development in a variety of environments.
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
Mapnik is basically a collection of geographic objects like maps, layers, datasources, features, and geometries. The library doesn't rely on any OS specific "windowing systems" and it can be deployed to any server environment. It is intended to play fair in a multi-threaded environment and is aimed primarily, but not exclusively, at web-based development.
|
Mapnik is basically a collection of geographic objects like maps, layers, datasources, features, and geometries. The library doesn't rely on any OS specific "windowing systems" and it can be deployed to any server environment. It is intended to play fair in a multi-threaded environment and is aimed primarily, but not exclusively, at web-based development.
|
||||||
|
|
||||||
For further information see [http://mapnik.org](http://mapnik.org) and also our [wiki documentation](https://github.com/mapnik/mapnik/wiki).
|
For further information see [http://mapnik.org](http://mapnik.org) and also our [wiki documentation](https://github.com/mapnik/mapnik/wiki) here on GitHub.
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
See [INSTALL.md](INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
|
See [INSTALL.md](https://github.com/mapnik/mapnik/blob/master/INSTALL.md) for installation instructions and the [Install](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) page on the wiki for guides.
|
||||||
|
|
||||||
# Code of Conduct
|
|
||||||
|
|
||||||
Please note that this project is released with a [Contributor Code of Conduct](https://github.com/mapnik/mapnik/blob/master/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
Mapnik software is free and is released under the LGPL v2.1 ([GNU Lesser General Public License, version 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
|
Mapnik software is free and is released under the LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html_)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
|
||||||
|
|
1231
SConstruct
1231
SConstruct
File diff suppressed because it is too large
Load diff
|
@ -1,52 +0,0 @@
|
||||||
project(mapnik-benchmark)
|
|
||||||
|
|
||||||
set(BENCHMARK_SRCS
|
|
||||||
src/normalize_angle.cpp
|
|
||||||
src/test_array_allocation.cpp
|
|
||||||
src/test_expression_parse.cpp
|
|
||||||
src/test_face_ptr_creation.cpp
|
|
||||||
src/test_font_registration.cpp
|
|
||||||
src/test_getline.cpp
|
|
||||||
src/test_marker_cache.cpp
|
|
||||||
src/test_noop_rendering.cpp
|
|
||||||
src/test_numeric_cast_vs_static_cast.cpp
|
|
||||||
src/test_offset_converter.cpp
|
|
||||||
src/test_png_encoding1.cpp
|
|
||||||
src/test_png_encoding2.cpp
|
|
||||||
src/test_polygon_clipping_rendering.cpp
|
|
||||||
src/test_polygon_clipping.cpp
|
|
||||||
src/test_proj_transform1.cpp
|
|
||||||
src/test_quad_tree.cpp
|
|
||||||
src/test_rendering_shared_map.cpp
|
|
||||||
src/test_rendering.cpp
|
|
||||||
src/test_to_bool.cpp
|
|
||||||
src/test_to_double.cpp
|
|
||||||
src/test_to_int.cpp
|
|
||||||
src/test_to_string1.cpp
|
|
||||||
src/test_to_string2.cpp
|
|
||||||
src/test_utf_encoding.cpp
|
|
||||||
)
|
|
||||||
function(mapnik_create_benchmark)
|
|
||||||
get_filename_component(BENCHNAME ${ARGV0} NAME_WE)
|
|
||||||
set(TARGET_NAME "mapnik-benchmark-${BENCHNAME}")
|
|
||||||
add_executable(${TARGET_NAME} ${ARGV0})
|
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE include)
|
|
||||||
target_link_libraries(${TARGET_NAME} PRIVATE
|
|
||||||
mapnik::agg
|
|
||||||
mapnik::mapnik
|
|
||||||
ICU::data ICU::i18n ICU::uc # needed for the static build (TODO: why isn't this correctly propagated from mapnik::mapnik?)
|
|
||||||
)
|
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
|
||||||
OUTPUT_NAME "${BENCHNAME}"
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
foreach(benchmark ${BENCHMARK_SRCS})
|
|
||||||
mapnik_create_benchmark(${benchmark})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
file(COPY data DESTINATION "${MAPNIK_OUTPUT_DIR}/benchmark")
|
|
||||||
file(COPY run_benchmarks
|
|
||||||
DESTINATION "${MAPNIK_OUTPUT_DIR}"
|
|
||||||
FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE GROUP_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ
|
|
||||||
)
|
|
132
benchmark/bench_framework.hpp
Normal file
132
benchmark/bench_framework.hpp
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#ifndef __MAPNIK_BENCH_FRAMEWORK_HPP__
|
||||||
|
#define __MAPNIK_BENCH_FRAMEWORK_HPP__
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/params.hpp>
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#define BOOST_CHRONO_HEADER_ONLY
|
||||||
|
#include <boost/chrono/process_cpu_clocks.hpp>
|
||||||
|
#include <boost/chrono.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
namespace benchmark {
|
||||||
|
|
||||||
|
class test_case
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
mapnik::parameters params_;
|
||||||
|
std::size_t threads_;
|
||||||
|
std::size_t iterations_;
|
||||||
|
public:
|
||||||
|
test_case(mapnik::parameters const& params)
|
||||||
|
: params_(params),
|
||||||
|
threads_(*params.get<mapnik::value_integer>("threads",0)),
|
||||||
|
iterations_(*params.get<mapnik::value_integer>("iterations",0))
|
||||||
|
{}
|
||||||
|
std::size_t threads() const
|
||||||
|
{
|
||||||
|
return threads_;
|
||||||
|
}
|
||||||
|
std::size_t iterations() const
|
||||||
|
{
|
||||||
|
return iterations_;
|
||||||
|
}
|
||||||
|
virtual bool validate() const = 0;
|
||||||
|
virtual void operator()() const = 0;
|
||||||
|
virtual ~test_case() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void handle_args(int argc, char** argv, mapnik::parameters & params)
|
||||||
|
{
|
||||||
|
if (argc > 0) {
|
||||||
|
for (int i=1;i<argc;++i) {
|
||||||
|
std::string opt(argv[i]);
|
||||||
|
// parse --foo bar
|
||||||
|
if (!opt.empty() && (opt.find("--") != 0)) {
|
||||||
|
std::string key = std::string(argv[i-1]);
|
||||||
|
if (!key.empty() && (key.find("--") == 0)) {
|
||||||
|
key = key.substr(key.find_first_not_of("-"));
|
||||||
|
params[key] = opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BENCHMARK(test_class,name) \
|
||||||
|
int main(int argc, char** argv) \
|
||||||
|
{ \
|
||||||
|
try \
|
||||||
|
{ \
|
||||||
|
mapnik::parameters params; \
|
||||||
|
benchmark::handle_args(argc,argv,params); \
|
||||||
|
test_class test_runner(params); \
|
||||||
|
return run(test_runner,name); \
|
||||||
|
} \
|
||||||
|
catch (std::exception const& ex) \
|
||||||
|
{ \
|
||||||
|
std::clog << ex.what() << "\n"; \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int run(T const& test_runner, std::string const& name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!test_runner.validate())
|
||||||
|
{
|
||||||
|
std::clog << "test did not validate: " << name << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
boost::chrono::process_cpu_clock::time_point start;
|
||||||
|
boost::chrono::process_cpu_clock::duration elapsed;
|
||||||
|
std::stringstream s;
|
||||||
|
s << name << ":"
|
||||||
|
<< std::setw(45 - (int)s.tellp()) << std::right
|
||||||
|
<< " t:" << test_runner.threads()
|
||||||
|
<< " i:" << test_runner.iterations();
|
||||||
|
if (test_runner.threads() > 0)
|
||||||
|
{
|
||||||
|
using thread_group = std::vector<std::unique_ptr<std::thread> >;
|
||||||
|
using value_type = thread_group::value_type;
|
||||||
|
thread_group tg;
|
||||||
|
for (std::size_t i=0;i<test_runner.threads();++i)
|
||||||
|
{
|
||||||
|
tg.emplace_back(new std::thread(test_runner));
|
||||||
|
}
|
||||||
|
start = boost::chrono::process_cpu_clock::now();
|
||||||
|
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
|
||||||
|
elapsed = boost::chrono::process_cpu_clock::now() - start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = boost::chrono::process_cpu_clock::now();
|
||||||
|
test_runner();
|
||||||
|
elapsed = boost::chrono::process_cpu_clock::now() - start;
|
||||||
|
}
|
||||||
|
s << std::setw(65 - (int)s.tellp()) << std::right
|
||||||
|
<< boost::chrono::duration_cast<boost::chrono::milliseconds>(elapsed) << "\n";
|
||||||
|
std::clog << s.str();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
|
std::clog << "test runner did not complete: " << ex.what() << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MAPNIK_BENCH_FRAMEWORK_HPP__
|
|
@ -8,8 +8,6 @@ test_env = env.Clone()
|
||||||
|
|
||||||
test_env['LIBS'] = [env['MAPNIK_NAME']]
|
test_env['LIBS'] = [env['MAPNIK_NAME']]
|
||||||
test_env.AppendUnique(LIBS=copy(env['LIBMAPNIK_LIBS']))
|
test_env.AppendUnique(LIBS=copy(env['LIBMAPNIK_LIBS']))
|
||||||
test_env.AppendUnique(LIBS='mapnik-wkt')
|
|
||||||
test_env.AppendUnique(LIBS='sqlite3')
|
|
||||||
if env['PLATFORM'] == 'Linux':
|
if env['PLATFORM'] == 'Linux':
|
||||||
test_env.AppendUnique(LIBS='dl')
|
test_env.AppendUnique(LIBS='dl')
|
||||||
test_env.AppendUnique(LIBS='rt')
|
test_env.AppendUnique(LIBS='rt')
|
||||||
|
@ -19,19 +17,32 @@ test_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
|
||||||
if test_env['HAS_CAIRO']:
|
if test_env['HAS_CAIRO']:
|
||||||
test_env.PrependUnique(CPPPATH=test_env['CAIRO_CPPPATHS'])
|
test_env.PrependUnique(CPPPATH=test_env['CAIRO_CPPPATHS'])
|
||||||
test_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
test_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
||||||
test_env.PrependUnique(CPPPATH='include', delete_existing=True)
|
|
||||||
test_env['LINKFLAGS'] = copy(test_env['LIBMAPNIK_LINKFLAGS'])
|
|
||||||
if env['PLATFORM'] == 'Darwin':
|
if env['PLATFORM'] == 'Darwin':
|
||||||
test_env.Append(LINKFLAGS='-F/ -framework CoreFoundation')
|
test_env.Append(LINKFLAGS='-F/ -framework CoreFoundation')
|
||||||
|
|
||||||
test_env_local = test_env.Clone()
|
test_env_local = test_env.Clone()
|
||||||
|
|
||||||
benchmarks = glob.glob("src/*.cpp")
|
#benchmarks = glob.glob('test*cpp')
|
||||||
|
benchmarks = [
|
||||||
for src in benchmarks:
|
#"test_array_allocation.cpp",
|
||||||
name, ext = os.path.splitext(os.path.basename(src))
|
#"test_png_encoding1.cpp",
|
||||||
out = os.path.join("out", name)
|
#"test_png_encoding2.cpp",
|
||||||
test_program = test_env_local.Program(out, source=[src])
|
#"test_to_string1.cpp",
|
||||||
|
#"test_to_string2.cpp",
|
||||||
|
#"test_to_bool.cpp",
|
||||||
|
#"test_to_double.cpp",
|
||||||
|
#"test_to_int.cpp",
|
||||||
|
#"test_utf_encoding.cpp"
|
||||||
|
#"test_polygon_clipping.cpp",
|
||||||
|
#"test_polygon_clipping_rendering.cpp",
|
||||||
|
"test_proj_transform1.cpp",
|
||||||
|
"test_expression_parse.cpp",
|
||||||
|
"test_face_ptr_creation.cpp",
|
||||||
|
"test_font_registration.cpp",
|
||||||
|
"test_rendering.cpp",
|
||||||
|
]
|
||||||
|
for cpp_test in benchmarks:
|
||||||
|
test_program = test_env_local.Program('out/'+cpp_test.replace('.cpp',''), source=[cpp_test])
|
||||||
if 'install' in COMMAND_LINE_TARGETS:
|
if 'install' in COMMAND_LINE_TARGETS:
|
||||||
env.Alias('install',test_program)
|
env.Alias('install',test_program)
|
||||||
#Depends(test_program, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
|
#Depends(test_program, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
51
benchmark/compare_images.hpp
Normal file
51
benchmark/compare_images.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef __MAPNIK_COMPARE_IMAGES_HPP__
|
||||||
|
#define __MAPNIK_COMPARE_IMAGES_HPP__
|
||||||
|
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/image_data.hpp>
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/image_reader.hpp>
|
||||||
|
|
||||||
|
using namespace mapnik;
|
||||||
|
|
||||||
|
namespace benchmark {
|
||||||
|
|
||||||
|
bool compare_images(std::string const& src_fn,std::string const& dest_fn)
|
||||||
|
{
|
||||||
|
std::unique_ptr<mapnik::image_reader> reader1(mapnik::get_image_reader(dest_fn,"png"));
|
||||||
|
if (!reader1.get())
|
||||||
|
{
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + dest_fn);
|
||||||
|
}
|
||||||
|
std::shared_ptr<image_32> image_ptr1 = std::make_shared<image_32>(reader1->width(),reader1->height());
|
||||||
|
reader1->read(0,0,image_ptr1->data());
|
||||||
|
|
||||||
|
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(src_fn,"png"));
|
||||||
|
if (!reader2.get())
|
||||||
|
{
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + src_fn);
|
||||||
|
}
|
||||||
|
std::shared_ptr<image_32> image_ptr2 = std::make_shared<image_32>(reader2->width(),reader2->height());
|
||||||
|
reader2->read(0,0,image_ptr2->data());
|
||||||
|
|
||||||
|
image_data_32 const& dest = image_ptr1->data();
|
||||||
|
image_data_32 const& src = image_ptr2->data();
|
||||||
|
|
||||||
|
unsigned int width = src.width();
|
||||||
|
unsigned int height = src.height();
|
||||||
|
if ((width != dest.width()) || height != dest.height()) return false;
|
||||||
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
const unsigned int* row_from = src.getRow(y);
|
||||||
|
const unsigned int* row_to = dest.getRow(y);
|
||||||
|
for (unsigned int x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if (row_from[x] != row_to[x]) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MAPNIK_COMPARE_IMAGES_HPP__
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE Map[]>
|
|
||||||
<Map
|
|
||||||
srs="epsg:4326"
|
|
||||||
background-color="#dfd8c9">
|
|
||||||
|
|
||||||
<Style name="style">
|
|
||||||
<Rule>
|
|
||||||
<RasterSymbolizer />
|
|
||||||
</Rule>
|
|
||||||
</Style>
|
|
||||||
<Layer name="layer"
|
|
||||||
srs="epsg:4326">
|
|
||||||
<StyleName>style</StyleName>
|
|
||||||
<Datasource>
|
|
||||||
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
|
||||||
<Parameter name="type">gdal</Parameter>
|
|
||||||
</Datasource>
|
|
||||||
</Layer>
|
|
||||||
|
|
||||||
</Map>
|
|
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -7,7 +7,7 @@
|
||||||
<Layer name="world" 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">
|
<Layer name="world" 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">
|
||||||
<StyleName>style</StyleName>
|
<StyleName>style</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
<Parameter name="file">../../test/data/shp/world_merc.shp</Parameter>
|
<Parameter name="file">../../tests/data/shp/world_merc.shp</Parameter>
|
||||||
<Parameter name="type">shape</Parameter>
|
<Parameter name="type">shape</Parameter>
|
||||||
</Datasource>
|
</Datasource>
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<Layer name="world" 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">
|
<Layer name="world" 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">
|
||||||
<StyleName>style</StyleName>
|
<StyleName>style</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
<Parameter name="file">../../test/data/shp/world_merc.shp</Parameter>
|
<Parameter name="file">../../tests/data/shp/world_merc.shp</Parameter>
|
||||||
<Parameter name="type">shape</Parameter>
|
<Parameter name="type">shape</Parameter>
|
||||||
</Datasource>
|
</Datasource>
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE Map[]>
|
|
||||||
<Map
|
|
||||||
srs="epsg:4326"
|
|
||||||
background-color="#dfd8c9">
|
|
||||||
|
|
||||||
<Style name="style">
|
|
||||||
<Rule>
|
|
||||||
<RasterSymbolizer />
|
|
||||||
</Rule>
|
|
||||||
</Style>
|
|
||||||
<Layer name="layer"
|
|
||||||
srs="epsg:4326">
|
|
||||||
<StyleName>style</StyleName>
|
|
||||||
<Datasource>
|
|
||||||
<Parameter name="file">./valid.geotiff.tif</Parameter>
|
|
||||||
<Parameter name="type">raster</Parameter>
|
|
||||||
</Datasource>
|
|
||||||
</Layer>
|
|
||||||
|
|
||||||
</Map>
|
|
|
@ -1,85 +1,72 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!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" background-color="#dfd8c9">
|
||||||
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.37/ttf/DejaVuSans.ttf"
|
|
||||||
background-color="#dfd8c9">
|
|
||||||
|
|
||||||
<Style name="marking" filter-mode="first">
|
<Style name="marking" filter-mode="first">
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'railways')</Filter>
|
<Filter>([class] = 'railways')</Filter>
|
||||||
<LineSymbolizer stroke="#ffffff" stroke-width="1.8" stroke-dasharray="5, 5" clip="false" />
|
<LineSymbolizer stroke="#ffffff" stroke-width="1.8" stroke-dasharray="5, 5" />
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Style name="fill" filter-mode="first">
|
<Style name="fill" filter-mode="first">
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'minorroads')</Filter>
|
<Filter>([class] = 'minorroads')</Filter>
|
||||||
<LineSymbolizer stroke-width="2.5" stroke="#ffffff" stroke-linecap="round" clip="false" />
|
<LineSymbolizer stroke-width="2.5" stroke="#ffffff" stroke-linecap="round" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'mainroads')</Filter>
|
<Filter>([class] = 'mainroads')</Filter>
|
||||||
<LineSymbolizer stroke-width="4" stroke="#ff9999" stroke-linecap="round" clip="false" />
|
<LineSymbolizer stroke-width="4" stroke="#ff9999" stroke-linecap="round" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'motorways')</Filter>
|
<Filter>([class] = 'motorways')</Filter>
|
||||||
<LineSymbolizer stroke-width="6" stroke="#ff6666" stroke-linecap="round" clip="false" />
|
<LineSymbolizer stroke-width="6" stroke="#ff6666" stroke-linecap="round" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'railways')</Filter>
|
<Filter>([class] = 'railways')</Filter>
|
||||||
<LineSymbolizer stroke-width="3" stroke="#333333" stroke-linecap="round" clip="false" />
|
<LineSymbolizer stroke-width="3" stroke="#333333" stroke-linecap="round" />
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Style name="bridge" filter-mode="first">
|
<Style name="bridge" filter-mode="first">
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'railways') and ([bridge] = 1)</Filter>
|
<Filter>([class] = 'railways') and ([bridge] = 1)</Filter>
|
||||||
<LineSymbolizer stroke-width="6" stroke="#ffffff" clip="false" />
|
<LineSymbolizer stroke-width="6" stroke="#ffffff" />
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Style name="casing" filter-mode="first">
|
<Style name="casing" filter-mode="first">
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'railways') and ([bridge] = 1)</Filter>
|
<Filter>([class] = 'railways') and ([bridge] = 1)</Filter>
|
||||||
<LineSymbolizer stroke-width="8" stroke="#333333" clip="false" />
|
<LineSymbolizer stroke-width="8" stroke="#333333" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'minorroads')</Filter>
|
<Filter>([class] = 'minorroads')</Filter>
|
||||||
<LineSymbolizer stroke-width="3" stroke="#a69269" clip="false" />
|
<LineSymbolizer stroke-width="3" stroke="#a69269" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'mainroads')</Filter>
|
<Filter>([class] = 'mainroads')</Filter>
|
||||||
<LineSymbolizer stroke-width="5" stroke="#ff0000" clip="false" />
|
<LineSymbolizer stroke-width="5" stroke="#ff0000" />
|
||||||
</Rule>
|
</Rule>
|
||||||
<Rule>
|
<Rule>
|
||||||
<Filter>([class] = 'motorways')</Filter>
|
<Filter>([class] = 'motorways')</Filter>
|
||||||
<LineSymbolizer stroke-width="8" stroke="#990000" clip="false" />
|
<LineSymbolizer stroke-width="8" stroke="#990000" />
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Style name="labels">
|
<Style name="labels">
|
||||||
<Rule>
|
<Rule>
|
||||||
<TextSymbolizer
|
<TextSymbolizer halo-rasterizer="fast" placement="line" face-name="DejaVu Sans Book" halo-radius="2" allow-overlap="true">[type]</TextSymbolizer>
|
||||||
halo-rasterizer="fast"
|
|
||||||
placement="line"
|
|
||||||
face-name="DejaVu Sans Book"
|
|
||||||
halo-radius="2"
|
|
||||||
allow-overlap="false"
|
|
||||||
clip="false"
|
|
||||||
>[type]</TextSymbolizer>
|
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
<Layer name="layer"
|
<Layer name="layer"
|
||||||
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">
|
||||||
<!--
|
|
||||||
<StyleName>casing</StyleName>
|
<StyleName>casing</StyleName>
|
||||||
<StyleName>bridge</StyleName>
|
<StyleName>bridge</StyleName>
|
||||||
<StyleName>fill</StyleName>
|
<StyleName>fill</StyleName>
|
||||||
<StyleName>marking</StyleName>
|
<StyleName>marking</StyleName>
|
||||||
-->
|
|
||||||
<StyleName>labels</StyleName>
|
<StyleName>labels</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
<!--
|
<!--
|
||||||
ogr2ogr -f CSV tests/visual_tests/data/roads.csv -lco GEOMETRY=AS_WKT tests/visual_tests/data/grouped-rendering.sqlite roads -sql "SELECT fid,geometry, type, tunnel, bridge, oneway, class, z_order, CAST((z_order / 10.0) AS INTEGER) AS z FROM roads ORDER BY z_order"
|
ogr2ogr -f CSV tests/visual_tests/data/roads.csv -lco GEOMETRY=AS_WKT tests/visual_tests/data/grouped-rendering.sqlite roads -sql "SELECT fid,geometry, type, tunnel, bridge, oneway, class, z_order, CAST((z_order / 10.0) AS INTEGER) AS z FROM roads ORDER BY z_order"
|
||||||
-->
|
-->
|
||||||
<Parameter name="file">./roads.csv</Parameter>
|
<Parameter name="file">./roads.csv</Parameter>
|
||||||
<Parameter name="extent">1477001.12245,6890242.37746,1480004.49012,6892244.62256</Parameter>
|
|
||||||
<Parameter name="type">csv</Parameter>
|
<Parameter name="type">csv</Parameter>
|
||||||
</Datasource>
|
</Datasource>
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
Binary file not shown.
|
@ -1,302 +0,0 @@
|
||||||
#ifndef MAPNIK_BENCH_FRAMEWORK_HPP
|
|
||||||
#define MAPNIK_BENCH_FRAMEWORK_HPP
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/mapnik.hpp>
|
|
||||||
#include <mapnik/debug.hpp>
|
|
||||||
#include <mapnik/params.hpp>
|
|
||||||
#include <mapnik/value/types.hpp>
|
|
||||||
#include <mapnik/safe_cast.hpp>
|
|
||||||
#include "../test/cleanup.hpp"
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <chrono>
|
|
||||||
#include <cmath> // log10, round
|
|
||||||
#include <cstdio> // snprintf
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace benchmark {
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using milliseconds = std::chrono::duration<T, std::milli>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
using seconds = std::chrono::duration<T>;
|
|
||||||
|
|
||||||
class test_case
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
mapnik::parameters params_;
|
|
||||||
std::size_t threads_;
|
|
||||||
std::size_t iterations_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test_case(mapnik::parameters const& params)
|
|
||||||
: params_(params)
|
|
||||||
, threads_(mapnik::safe_cast<std::size_t>(*params.get<mapnik::value_integer>("threads", 0)))
|
|
||||||
, iterations_(mapnik::safe_cast<std::size_t>(*params.get<mapnik::value_integer>("iterations", 0)))
|
|
||||||
{}
|
|
||||||
std::size_t threads() const { return threads_; }
|
|
||||||
std::size_t iterations() const { return iterations_; }
|
|
||||||
mapnik::parameters const& params() const { return params_; }
|
|
||||||
virtual bool validate() const = 0;
|
|
||||||
virtual bool operator()() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// gathers --long-option values in 'params';
|
|
||||||
// returns the index of the first non-option argument,
|
|
||||||
// or negated index of an ill-formed option argument
|
|
||||||
inline int parse_args(int argc, char** argv, mapnik::parameters& params)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < argc; ++i)
|
|
||||||
{
|
|
||||||
const char* opt = argv[i];
|
|
||||||
if (opt[0] != '-')
|
|
||||||
{
|
|
||||||
// non-option argument, return its index
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
if (opt[1] != '-')
|
|
||||||
{
|
|
||||||
// we only accept --long-options, but instead of throwing,
|
|
||||||
// just issue a warning and let the caller decide what to do
|
|
||||||
std::clog << argv[0] << ": invalid option '" << opt << "'\n";
|
|
||||||
return -i; // negative means ill-formed option #i
|
|
||||||
}
|
|
||||||
if (opt[2] == '\0')
|
|
||||||
{
|
|
||||||
// option-list terminator '--'
|
|
||||||
return i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// take option name without the leading '--'
|
|
||||||
std::string key(opt + 2);
|
|
||||||
size_t eq = key.find('=');
|
|
||||||
if (eq != std::string::npos)
|
|
||||||
{
|
|
||||||
// one-argument form '--foo=bar'
|
|
||||||
params[key.substr(0, eq)] = key.substr(eq + 1);
|
|
||||||
}
|
|
||||||
else if (i + 1 < argc)
|
|
||||||
{
|
|
||||||
// two-argument form '--foo' 'bar'
|
|
||||||
params[key] = std::string(argv[++i]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// missing second argument
|
|
||||||
std::clog << argv[0] << ": missing option '" << opt << "' value\n";
|
|
||||||
return -i; // negative means ill-formed option #i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return argc; // there were no non-option arguments
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void handle_common_args(mapnik::parameters const& params)
|
|
||||||
{
|
|
||||||
if (auto severity = params.get<std::string>("log"))
|
|
||||||
{
|
|
||||||
if (*severity == "debug")
|
|
||||||
mapnik::logger::set_severity(mapnik::logger::debug);
|
|
||||||
else if (*severity == "warn")
|
|
||||||
mapnik::logger::set_severity(mapnik::logger::warn);
|
|
||||||
else if (*severity == "error")
|
|
||||||
mapnik::logger::set_severity(mapnik::logger::error);
|
|
||||||
else if (*severity == "none")
|
|
||||||
mapnik::logger::set_severity(mapnik::logger::none);
|
|
||||||
else
|
|
||||||
std::clog << "ignoring option --log='" << *severity << "' (allowed values are: debug, warn, error, none)\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int handle_args(int argc, char** argv, mapnik::parameters& params)
|
|
||||||
{
|
|
||||||
int res = parse_args(argc, argv, params);
|
|
||||||
handle_common_args(params);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BENCHMARK(test_class, name) \
|
|
||||||
int main(int argc, char** argv) \
|
|
||||||
{ \
|
|
||||||
mapnik::setup(); \
|
|
||||||
try \
|
|
||||||
{ \
|
|
||||||
mapnik::parameters params; \
|
|
||||||
benchmark::handle_args(argc, argv, params); \
|
|
||||||
test_class test_runner(params); \
|
|
||||||
auto result = run(test_runner, name); \
|
|
||||||
testing::run_cleanup(); \
|
|
||||||
return result; \
|
|
||||||
} \
|
|
||||||
catch (std::exception const& ex) \
|
|
||||||
{ \
|
|
||||||
std::clog << ex.what() << "\n"; \
|
|
||||||
testing::run_cleanup(); \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct big_number_fmt
|
|
||||||
{
|
|
||||||
int w;
|
|
||||||
double v;
|
|
||||||
const char* u;
|
|
||||||
|
|
||||||
big_number_fmt(int width, double value, int base = 1000)
|
|
||||||
: w(width)
|
|
||||||
, v(value)
|
|
||||||
, u("")
|
|
||||||
{
|
|
||||||
static const char* suffixes = "\0\0k\0M\0G\0T\0P\0E\0Z\0Y\0\0";
|
|
||||||
u = suffixes;
|
|
||||||
|
|
||||||
while (v > 1 && std::log10(std::round(v)) >= width && u[2])
|
|
||||||
{
|
|
||||||
v /= base;
|
|
||||||
u += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust width for proper alignment without suffix
|
|
||||||
w += (u == suffixes);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
int run(T const& test_runner, std::string const& name)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!test_runner.validate())
|
|
||||||
{
|
|
||||||
std::clog << "test did not validate: " << name << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// run test once before timing
|
|
||||||
// if it returns false then we'll abort timing
|
|
||||||
if (!test_runner())
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::high_resolution_clock::time_point start;
|
|
||||||
std::chrono::high_resolution_clock::duration elapsed;
|
|
||||||
auto opt_min_duration = test_runner.params().template get<double>("min-duration", 0.0);
|
|
||||||
std::chrono::duration<double> min_seconds(*opt_min_duration);
|
|
||||||
auto min_duration = std::chrono::duration_cast<decltype(elapsed)>(min_seconds);
|
|
||||||
auto num_iters = test_runner.iterations();
|
|
||||||
auto num_threads = test_runner.threads();
|
|
||||||
auto total_iters = 0;
|
|
||||||
|
|
||||||
if (num_threads > 0)
|
|
||||||
{
|
|
||||||
std::mutex mtx_ready;
|
|
||||||
std::unique_lock<std::mutex> lock_ready(mtx_ready);
|
|
||||||
|
|
||||||
auto stub = [&](T const& test_copy) {
|
|
||||||
// workers will wait on this mutex until the main thread
|
|
||||||
// constructs all of them and starts measuring time
|
|
||||||
std::unique_lock<std::mutex> my_lock(mtx_ready);
|
|
||||||
my_lock.unlock();
|
|
||||||
test_copy();
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::thread> tg;
|
|
||||||
tg.reserve(num_threads);
|
|
||||||
for (auto i = num_threads; i-- > 0;)
|
|
||||||
{
|
|
||||||
tg.emplace_back(stub, test_runner);
|
|
||||||
}
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
lock_ready.unlock();
|
|
||||||
// wait for all workers to finish
|
|
||||||
for (auto& t : tg)
|
|
||||||
{
|
|
||||||
if (t.joinable())
|
|
||||||
t.join();
|
|
||||||
}
|
|
||||||
elapsed = std::chrono::high_resolution_clock::now() - start;
|
|
||||||
// this is actually per-thread count, not total, but I think
|
|
||||||
// reporting average 'iters/thread/second' is more useful
|
|
||||||
// than 'iters/second' multiplied by the number of threads
|
|
||||||
total_iters += num_iters;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
test_runner();
|
|
||||||
elapsed = std::chrono::high_resolution_clock::now() - start;
|
|
||||||
total_iters += num_iters;
|
|
||||||
} while (elapsed < min_duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
char msg[200];
|
|
||||||
double dur_total = milliseconds<double>(elapsed).count();
|
|
||||||
auto elapsed_nonzero = std::max(elapsed, decltype(elapsed){1});
|
|
||||||
big_number_fmt itersf(4, total_iters);
|
|
||||||
big_number_fmt ips(5, total_iters / seconds<double>(elapsed_nonzero).count());
|
|
||||||
|
|
||||||
std::clog << std::left << std::setw(43) << name;
|
|
||||||
std::clog << std::resetiosflags(std::ios::adjustfield);
|
|
||||||
if (num_threads > 0)
|
|
||||||
{
|
|
||||||
std::clog << ' ' << std::setw(3) << num_threads << " worker" << (num_threads > 1 ? "s" : " ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::clog << " main thread";
|
|
||||||
}
|
|
||||||
std::snprintf(msg,
|
|
||||||
sizeof(msg),
|
|
||||||
" %*.0f%s iters %6.0f milliseconds %*.0f%s i/t/s\n",
|
|
||||||
itersf.w,
|
|
||||||
itersf.v,
|
|
||||||
itersf.u,
|
|
||||||
dur_total,
|
|
||||||
ips.w,
|
|
||||||
ips.v,
|
|
||||||
ips.u);
|
|
||||||
std::clog << msg;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
std::clog << "test runner did not complete: " << ex.what() << "\n";
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sequencer
|
|
||||||
{
|
|
||||||
sequencer(int argc, char** argv)
|
|
||||||
: exit_code_(0)
|
|
||||||
{
|
|
||||||
benchmark::handle_args(argc, argv, params_);
|
|
||||||
}
|
|
||||||
|
|
||||||
int done() const { return exit_code_; }
|
|
||||||
|
|
||||||
template<typename Test, typename... Args>
|
|
||||||
sequencer& run(std::string const& name, Args&&... args)
|
|
||||||
{
|
|
||||||
// Test instance lifetime is confined to this function
|
|
||||||
Test test_runner(params_, std::forward<Args>(args)...);
|
|
||||||
// any failing test run will make exit code non-zero
|
|
||||||
exit_code_ |= benchmark::run(test_runner, name);
|
|
||||||
return *this; // allow chaining calls
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
mapnik::parameters params_;
|
|
||||||
int exit_code_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace benchmark
|
|
||||||
|
|
||||||
#endif // MAPNIK_BENCH_FRAMEWORK_HPP
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef MAPNIK_COMPARE_IMAGES_HPP
|
|
||||||
#define MAPNIK_COMPARE_IMAGES_HPP
|
|
||||||
|
|
||||||
#include <mapnik/image.hpp>
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/image_reader.hpp>
|
|
||||||
|
|
||||||
namespace benchmark {
|
|
||||||
|
|
||||||
bool compare_images(std::string const& src_fn, std::string const& dest_fn)
|
|
||||||
{
|
|
||||||
std::unique_ptr<mapnik::image_reader> reader1(mapnik::get_image_reader(dest_fn, "png"));
|
|
||||||
if (!reader1.get())
|
|
||||||
{
|
|
||||||
throw mapnik::image_reader_exception("Failed to load: " + dest_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(src_fn, "png"));
|
|
||||||
if (!reader2.get())
|
|
||||||
{
|
|
||||||
throw mapnik::image_reader_exception("Failed to load: " + src_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapnik::image_any desc_any = reader1->read(0, 0, reader1->width(), reader1->height());
|
|
||||||
const mapnik::image_any src_any = reader2->read(0, 0, reader2->width(), reader2->height());
|
|
||||||
|
|
||||||
mapnik::image_rgba8 const& dest = mapnik::util::get<mapnik::image_rgba8>(desc_any);
|
|
||||||
mapnik::image_rgba8 const& src = mapnik::util::get<mapnik::image_rgba8>(src_any);
|
|
||||||
|
|
||||||
return compare(dest, src, 0, true) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace benchmark
|
|
||||||
|
|
||||||
#endif // MAPNIK_COMPARE_IMAGES_HPP
|
|
|
@ -6,16 +6,10 @@ source ./localize.sh
|
||||||
|
|
||||||
BASE=./benchmark/out
|
BASE=./benchmark/out
|
||||||
function run {
|
function run {
|
||||||
local runner="$BASE/$1 --log=none"
|
${BASE}/$1 --threads 0 --iterations $3;
|
||||||
local threads="$2"
|
${BASE}/$1 --threads $2 --iterations $(expr $3 / $2);
|
||||||
local iters="$3"
|
|
||||||
shift 3
|
|
||||||
$runner --threads 0 --iterations $iters "$@"
|
|
||||||
if test $threads -gt 0; then
|
|
||||||
$runner --threads $threads --iterations $((iters/threads)) "$@"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
run test_getline 30 10000000
|
|
||||||
#run test_array_allocation 20 100000
|
#run test_array_allocation 20 100000
|
||||||
#run test_png_encoding1 10 1000
|
#run test_png_encoding1 10 1000
|
||||||
#run test_png_encoding2 10 50
|
#run test_png_encoding2 10 50
|
||||||
|
@ -25,13 +19,9 @@ run test_getline 30 10000000
|
||||||
#run test_polygon_clipping_rendering 10 100
|
#run test_polygon_clipping_rendering 10 100
|
||||||
run test_proj_transform1 10 100
|
run test_proj_transform1 10 100
|
||||||
run test_expression_parse 10 10000
|
run test_expression_parse 10 10000
|
||||||
run test_face_ptr_creation 10 1000
|
run test_face_ptr_creation 10 10000
|
||||||
run test_font_registration 10 100
|
run test_font_registration 10 1000
|
||||||
run test_offset_converter 10 1000
|
|
||||||
#run normalize_angle 0 1000000 --min-duration=0.2
|
|
||||||
|
|
||||||
# commented since this is really slow on travis
|
|
||||||
: '
|
|
||||||
./benchmark/out/test_rendering \
|
./benchmark/out/test_rendering \
|
||||||
--name "text rendering" \
|
--name "text rendering" \
|
||||||
--map benchmark/data/roads.xml \
|
--map benchmark/data/roads.xml \
|
||||||
|
@ -40,30 +30,3 @@ run test_offset_converter 10 1000
|
||||||
--height 600 \
|
--height 600 \
|
||||||
--iterations 20 \
|
--iterations 20 \
|
||||||
--threads 10
|
--threads 10
|
||||||
'
|
|
||||||
|
|
||||||
./benchmark/out/test_rendering \
|
|
||||||
--name "gdal tiff rendering" \
|
|
||||||
--map benchmark/data/gdal-wgs.xml \
|
|
||||||
--extent -180.0,-120.0,180.0,120.0 \
|
|
||||||
--width 600 \
|
|
||||||
--height 600 \
|
|
||||||
--iterations 20 \
|
|
||||||
--threads 10
|
|
||||||
|
|
||||||
./benchmark/out/test_rendering \
|
|
||||||
--name "raster tiff rendering" \
|
|
||||||
--map benchmark/data/raster-wgs.xml \
|
|
||||||
--extent -180.0,-120.0,180.0,120.0 \
|
|
||||||
--width 600 \
|
|
||||||
--height 600 \
|
|
||||||
--iterations 20 \
|
|
||||||
--threads 10
|
|
||||||
|
|
||||||
./benchmark/out/test_quad_tree \
|
|
||||||
--iterations 10000 \
|
|
||||||
--threads 1
|
|
||||||
|
|
||||||
./benchmark/out/test_quad_tree \
|
|
||||||
--iterations 1000 \
|
|
||||||
--threads 10
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
BASE=.
|
|
||||||
function run {
|
|
||||||
local runner="$BASE/$1 --log=none"
|
|
||||||
local threads="$2"
|
|
||||||
local iters="$3"
|
|
||||||
shift 3
|
|
||||||
$runner --threads 0 --iterations $iters "$@"
|
|
||||||
if test $threads -gt 0; then
|
|
||||||
$runner --threads $threads --iterations $((iters/threads)) "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
run test_getline 30 10000000
|
|
||||||
#run test_array_allocation 20 100000
|
|
||||||
#run test_png_encoding1 10 1000
|
|
||||||
#run test_png_encoding2 10 50
|
|
||||||
#run test_to_string1 10 100000
|
|
||||||
#run test_to_string2 10 100000
|
|
||||||
#run test_polygon_clipping 10 1000
|
|
||||||
#run test_polygon_clipping_rendering 10 100
|
|
||||||
run test_proj_transform1 10 100
|
|
||||||
run test_expression_parse 10 10000
|
|
||||||
run test_face_ptr_creation 10 1000
|
|
||||||
run test_font_registration 10 100
|
|
||||||
run test_offset_converter 10 1000
|
|
||||||
#run normalize_angle 0 1000000 --min-duration=0.2
|
|
||||||
|
|
||||||
# commented since this is really slow on travis
|
|
||||||
: '
|
|
||||||
$BASE/test_rendering \
|
|
||||||
--name "text rendering" \
|
|
||||||
--map benchmark/data/roads.xml \
|
|
||||||
--extent 1477001.12245,6890242.37746,1480004.49012,6892244.62256 \
|
|
||||||
--width 600 \
|
|
||||||
--height 600 \
|
|
||||||
--iterations 20 \
|
|
||||||
--threads 10
|
|
||||||
'
|
|
||||||
|
|
||||||
$BASE/test_rendering \
|
|
||||||
--name "gdal tiff rendering" \
|
|
||||||
--map benchmark/data/gdal-wgs.xml \
|
|
||||||
--extent -180.0,-120.0,180.0,120.0 \
|
|
||||||
--width 600 \
|
|
||||||
--height 600 \
|
|
||||||
--iterations 20 \
|
|
||||||
--threads 10
|
|
||||||
|
|
||||||
$BASE/test_rendering \
|
|
||||||
--name "raster tiff rendering" \
|
|
||||||
--map benchmark/data/raster-wgs.xml \
|
|
||||||
--extent -180.0,-120.0,180.0,120.0 \
|
|
||||||
--width 600 \
|
|
||||||
--height 600 \
|
|
||||||
--iterations 20 \
|
|
||||||
--threads 10
|
|
||||||
|
|
||||||
$BASE/test_quad_tree \
|
|
||||||
--iterations 10000 \
|
|
||||||
--threads 1
|
|
||||||
|
|
||||||
$BASE/test_quad_tree \
|
|
||||||
--iterations 1000 \
|
|
||||||
--threads 10
|
|
|
@ -1,72 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
|
|
||||||
#include <mapnik/util/math.hpp>
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bench_func : benchmark::test_case
|
|
||||||
{
|
|
||||||
T (*const func_)(T);
|
|
||||||
T const value_;
|
|
||||||
|
|
||||||
bench_func(mapnik::parameters const& params, T (*func)(T), T value)
|
|
||||||
: test_case(params)
|
|
||||||
, func_(func)
|
|
||||||
, value_(value)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool validate() const { return true; }
|
|
||||||
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (auto i = this->iterations_; i-- > 0;)
|
|
||||||
{
|
|
||||||
func_(value_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BENCH_FUNC1(func, value) run<bench_func<double>>(#func "(" #value ")", func, value)
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
return benchmark::sequencer(argc, argv)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +3)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +6)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +9)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +12)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +15)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +20)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +30)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +40)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +50)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +70)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +90)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +110)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +130)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +157)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +209)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +314)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +628)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, +942)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -3)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -6)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -9)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -12)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -15)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -20)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -30)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -40)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -50)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -70)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -90)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -110)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -130)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -157)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -209)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -314)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -628)
|
|
||||||
.BENCH_FUNC1(mapnik::util::normalize_angle, -942)
|
|
||||||
.done();
|
|
||||||
}
|
|
|
@ -1,370 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <deque>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <array>
|
|
||||||
#include <valarray>
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
#if BOOST_VERSION >= 105400
|
|
||||||
#include <boost/container/static_vector.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/17347254/why-is-allocation-and-deallocation-of-stdvector-slower-than-dynamic-array-on-m
|
|
||||||
|
|
||||||
#define FULL_ZERO_CHECK
|
|
||||||
|
|
||||||
inline void ensure_zero(uint8_t* data, uint32_t size)
|
|
||||||
{
|
|
||||||
#ifdef FULL_ZERO_CHECK
|
|
||||||
for (std::size_t i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
if (data[i] != 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("found non zero value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (data[0] != 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("found non zero value");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
class test1 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test1(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
// NOTE: sizeof(uint8_t) == 1
|
|
||||||
uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * size_);
|
|
||||||
memcpy(data, &array_[0], size_);
|
|
||||||
ensure_zero(data, size_);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test1b : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test1b(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
// NOTE: sizeof(uint8_t) == 1
|
|
||||||
uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * size_);
|
|
||||||
memset(data, 0, sizeof(uint8_t) * size_);
|
|
||||||
ensure_zero(data, size_);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test1c : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test1c(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
uint8_t* data = static_cast<uint8_t*>(::operator new(sizeof(uint8_t) * size_));
|
|
||||||
std::fill(data, data + size_, 0);
|
|
||||||
ensure_zero(data, size_);
|
|
||||||
::operator delete(data);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test2 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test2(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
uint8_t* data = static_cast<uint8_t*>(::operator new(sizeof(uint8_t) * size_));
|
|
||||||
memcpy(data, &array_[0], size_);
|
|
||||||
ensure_zero(data, size_);
|
|
||||||
::operator delete(data), data = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test3(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> data(size_);
|
|
||||||
ensure_zero(&data[0], data.size());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3b : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test3b(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> data(0);
|
|
||||||
data.resize(size_, 0);
|
|
||||||
ensure_zero(&data[0], data.size());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3c : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test3c(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> data(0);
|
|
||||||
data.assign(size_, 0);
|
|
||||||
ensure_zero(&data[0], data.size());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3d : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test3d(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::deque<uint8_t> data(size_);
|
|
||||||
for (std::size_t i = 0; i < size_; ++i)
|
|
||||||
{
|
|
||||||
if (data[i] != 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("found non zero value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test4 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test4(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
uint8_t* data = (uint8_t*)calloc(size_, sizeof(uint8_t));
|
|
||||||
ensure_zero(data, size_);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test5 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test5(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::string data(array_.begin(), array_.end());
|
|
||||||
ensure_zero((uint8_t*)&data[0], size_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test5b : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<char> array_;
|
|
||||||
test5b(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::string data(&array_[0], array_.size());
|
|
||||||
ensure_zero((uint8_t*)&data[0], size_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// C++14 dynarray<T>
|
|
||||||
// http://isocpp.org/blog/2013/04/trip-report-iso-c-spring-2013-meeting
|
|
||||||
// http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130909/088700.html
|
|
||||||
// http://stackoverflow.com/questions/17303902/any-alternative-to-stddynarray-presently-available
|
|
||||||
|
|
||||||
class test6 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test6(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::valarray<uint8_t> data(static_cast<uint8_t>(0), static_cast<size_t>(size_));
|
|
||||||
ensure_zero(&data[0], size_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if BOOST_VERSION >= 105400
|
|
||||||
// http://i42.co.uk/stuff/vecarray.htm
|
|
||||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost/container/static_vector.html
|
|
||||||
|
|
||||||
class test7 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint32_t size_;
|
|
||||||
std::vector<uint8_t> array_;
|
|
||||||
test7(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, size_(*params.get<mapnik::value_integer>("size", 256 * 256))
|
|
||||||
, array_(size_, 0)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
boost::container::static_vector<uint8_t, 256 * 256> data(size_, 0);
|
|
||||||
ensure_zero(&data[0], size_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
return benchmark::sequencer(argc, argv)
|
|
||||||
.run<test4>("calloc")
|
|
||||||
.run<test1>("malloc/memcpy")
|
|
||||||
.run<test1b>("malloc/memset")
|
|
||||||
.run<test1c>("operator new/std::fill")
|
|
||||||
.run<test2>("operator new/memcpy")
|
|
||||||
.run<test3>("vector(N)")
|
|
||||||
.run<test3b>("vector/resize")
|
|
||||||
.run<test3c>("vector/assign")
|
|
||||||
.run<test3d>("deque(N)")
|
|
||||||
.run<test5>("std::string range")
|
|
||||||
.run<test5b>("std::string &[0]")
|
|
||||||
.run<test6>("valarray")
|
|
||||||
#if BOOST_VERSION >= 105400
|
|
||||||
.run<test7>("static_vector")
|
|
||||||
#endif
|
|
||||||
.done();
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
#include <mapnik/attribute.hpp>
|
|
||||||
#include <mapnik/expression.hpp>
|
|
||||||
#include <mapnik/expression_string.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string expr_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::expression_ptr expr = mapnik::parse_expression(expr_);
|
|
||||||
std::string result = mapnik::to_expression_string(*expr);
|
|
||||||
bool ret = (result == expr_);
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
std::clog << result << " != " << expr_ << "\n";
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::expression_ptr expr = mapnik::parse_expression(expr_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
test test_runner(params);
|
|
||||||
return run(test_runner, "expr parsing");
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
|
||||||
#include <boost/format.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::size_t count = 0;
|
|
||||||
std::size_t expected_count = mapnik::freetype_engine::face_names().size();
|
|
||||||
mapnik::freetype_engine::font_file_mapping_type font_file_mapping;
|
|
||||||
mapnik::freetype_engine::font_memory_cache_type font_cache;
|
|
||||||
mapnik::font_library library;
|
|
||||||
for (std::string const& name : mapnik::freetype_engine::face_names())
|
|
||||||
{
|
|
||||||
mapnik::face_ptr f = mapnik::freetype_engine::create_face(name,
|
|
||||||
library,
|
|
||||||
font_file_mapping,
|
|
||||||
font_cache,
|
|
||||||
mapnik::freetype_engine::get_mapping(),
|
|
||||||
mapnik::freetype_engine::get_cache());
|
|
||||||
if (f)
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
return count == expected_count;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::size_t expected_count = mapnik::freetype_engine::face_names().size();
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::size_t count = 0;
|
|
||||||
mapnik::freetype_engine::font_file_mapping_type font_file_mapping;
|
|
||||||
mapnik::freetype_engine::font_memory_cache_type font_cache;
|
|
||||||
mapnik::font_library library;
|
|
||||||
for (std::string const& name : mapnik::freetype_engine::face_names())
|
|
||||||
{
|
|
||||||
mapnik::face_ptr f = mapnik::freetype_engine::create_face(name,
|
|
||||||
library,
|
|
||||||
font_file_mapping,
|
|
||||||
font_cache,
|
|
||||||
mapnik::freetype_engine::get_mapping(),
|
|
||||||
mapnik::freetype_engine::get_cache());
|
|
||||||
if (f)
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
if (count != expected_count)
|
|
||||||
{
|
|
||||||
std::clog << "warning: face creation not working as expected\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
bool success = mapnik::freetype_engine::register_fonts("./fonts", true);
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
std::clog << "warning, did not register any new fonts!\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
std::size_t face_count = mapnik::freetype_engine::face_names().size();
|
|
||||||
test test_runner(params);
|
|
||||||
return run(test_runner, (boost::format("font_engine: creating %ld faces") % (face_count)).str());
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
|
||||||
#include <boost/format.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{}
|
|
||||||
bool validate() const { return mapnik::freetype_engine::register_fonts("./fonts", true); }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
unsigned long count = 0;
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::freetype_engine::register_fonts("./fonts", true);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "font registration")
|
|
|
@ -1,125 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include "../plugins/input/csv/csv_getline.hpp"
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string line_data_;
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, line_data_("this is one line\nand this is a second line\nand a third line")
|
|
||||||
{
|
|
||||||
auto line_data = params.get<std::string>("line");
|
|
||||||
if (line_data)
|
|
||||||
{
|
|
||||||
line_data_ = *line_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::string first = line_data_.substr(line_data_.find_first_not_of('\n'));
|
|
||||||
char newline = '\n';
|
|
||||||
std::string csv_line;
|
|
||||||
std::stringstream s;
|
|
||||||
s << line_data_;
|
|
||||||
std::getline(s, csv_line, newline);
|
|
||||||
if (csv_line != first)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::clog << "Error: the parsed line (" << csv_line << ") should be a subset of the original line ("
|
|
||||||
<< line_data_ << ") (ensure you pass a line with a \\n)\n";
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
char newline = '\n';
|
|
||||||
std::string csv_line;
|
|
||||||
std::stringstream s;
|
|
||||||
s << line_data_;
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::getline(s, csv_line, newline);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test2 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string line_data_;
|
|
||||||
test2(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, line_data_("this is one line\nand this is a second line\nand a third line")
|
|
||||||
{
|
|
||||||
auto line_data = params.get<std::string>("line");
|
|
||||||
if (line_data)
|
|
||||||
{
|
|
||||||
line_data_ = *line_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::string first = line_data_.substr(line_data_.find_first_not_of('\n'));
|
|
||||||
char newline = '\n';
|
|
||||||
char quote = '"';
|
|
||||||
std::string csv_line;
|
|
||||||
std::stringstream s;
|
|
||||||
s << line_data_;
|
|
||||||
csv_utils::getline_csv(s, csv_line, newline, quote);
|
|
||||||
if (csv_line != first)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::clog << "Error: the parsed line (" << csv_line << ") should be a subset of the original line ("
|
|
||||||
<< line_data_ << ") (ensure you pass a line with a \\n)\n";
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
char newline = '\n';
|
|
||||||
char quote = '"';
|
|
||||||
std::string csv_line;
|
|
||||||
std::stringstream s;
|
|
||||||
s << line_data_;
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
csv_utils::getline_csv(s, csv_line, newline, quote);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
int return_value = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
{
|
|
||||||
test test_runner(params);
|
|
||||||
return_value = return_value | run(test_runner, "std::getline");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
test2 test_runner2(params);
|
|
||||||
return_value = return_value | run(test_runner2, "csv_utils::getline_csv");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
std::clog << ex.what() << "\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return return_value;
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/marker_cache.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::vector<std::string> images_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, images_{"./test/data/images/dummy.jpg",
|
|
||||||
"./test/data/images/dummy.jpeg",
|
|
||||||
"./test/data/images/dummy.png",
|
|
||||||
"./test/data/images/dummy.tif",
|
|
||||||
"./test/data/images/dummy.tiff",
|
|
||||||
//"./test/data/images/landusepattern.jpeg", // will fail since it is a png
|
|
||||||
//"./test/data/images/xcode-CgBI.png", // will fail since its an invalid png
|
|
||||||
"./test/data/svg/octocat.svg",
|
|
||||||
"./test/data/svg/place-of-worship-24.svg",
|
|
||||||
"./test/data/svg/point_sm.svg",
|
|
||||||
"./test/data/svg/point.svg",
|
|
||||||
"./test/data/svg/airfield-12.svg"}
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
unsigned count = 0;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
for (auto filename : images_)
|
|
||||||
{
|
|
||||||
auto marker = mapnik::marker_cache::instance().find(filename, true);
|
|
||||||
}
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
return (count == iterations_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "marker cache")
|
|
|
@ -1,51 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/map.hpp>
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/load_map.hpp>
|
|
||||||
#include <mapnik/agg_renderer.hpp>
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <mapnik/layer.hpp>
|
|
||||||
#include <mapnik/memory_datasource.hpp>
|
|
||||||
#include <mapnik/feature_type_style.hpp>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::Map m(256, 256, "epsg:3857");
|
|
||||||
|
|
||||||
mapnik::parameters params;
|
|
||||||
params["type"] = "memory";
|
|
||||||
auto ds = std::make_shared<mapnik::memory_datasource>(params);
|
|
||||||
// add whitespace to trigger phony "reprojection"
|
|
||||||
mapnik::layer lay("layer", m.srs() + " ");
|
|
||||||
lay.set_datasource(ds);
|
|
||||||
lay.add_style("style");
|
|
||||||
m.add_layer(lay);
|
|
||||||
// dummy style to ensure that layer is processed
|
|
||||||
m.insert_style("style", mapnik::feature_type_style());
|
|
||||||
// dummy bbox, but "valid" because minx and miny are less
|
|
||||||
// with an invalid bbox then layer.visible() returns false
|
|
||||||
// and the initial rendering setup is not run
|
|
||||||
m.zoom_to_box(mapnik::box2d<double>(-1, -1, 0, 0));
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::image_rgba8 im(256, 256);
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
|
|
||||||
ren.apply();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "rendering with reprojection")
|
|
|
@ -1,81 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
// boost
|
|
||||||
#include <boost/numeric/conversion/cast.hpp>
|
|
||||||
|
|
||||||
static double STEP_NUM = 0.0000000001;
|
|
||||||
static std::uint8_t START_NUM = 2;
|
|
||||||
|
|
||||||
class test_static : public benchmark::test_case
|
|
||||||
{
|
|
||||||
double step_;
|
|
||||||
std::uint8_t start_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test_static(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, step_(STEP_NUM)
|
|
||||||
, start_(START_NUM)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
double value_ = 0.0;
|
|
||||||
std::uint8_t x;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
double c = static_cast<double>(start_) * value_;
|
|
||||||
if (c >= 256.0)
|
|
||||||
c = 255.0;
|
|
||||||
if (c < 0.0)
|
|
||||||
c = 0.0;
|
|
||||||
x = static_cast<std::uint8_t>(c);
|
|
||||||
value_ += step_;
|
|
||||||
}
|
|
||||||
return static_cast<double>(x) < (static_cast<double>(start_) * value_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using boost::numeric::negative_overflow;
|
|
||||||
using boost::numeric::positive_overflow;
|
|
||||||
|
|
||||||
class test_numeric : public benchmark::test_case
|
|
||||||
{
|
|
||||||
double step_;
|
|
||||||
std::uint8_t start_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test_numeric(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, step_(STEP_NUM)
|
|
||||||
, start_(START_NUM)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
double value_ = 0.0;
|
|
||||||
std::uint8_t x;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
x = boost::numeric_cast<std::uint8_t>(start_ * value_);
|
|
||||||
}
|
|
||||||
catch (negative_overflow&)
|
|
||||||
{
|
|
||||||
x = std::numeric_limits<std::uint8_t>::min();
|
|
||||||
}
|
|
||||||
catch (positive_overflow&)
|
|
||||||
{
|
|
||||||
x = std::numeric_limits<std::uint8_t>::max();
|
|
||||||
}
|
|
||||||
value_ += step_;
|
|
||||||
}
|
|
||||||
return static_cast<double>(x) < (static_cast<double>(start_) * value_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
return benchmark::sequencer(argc, argv).run<test_static>("static_cast").run<test_numeric>("numeric_cast").done();
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/global.hpp>
|
|
||||||
#include <mapnik/coord.hpp>
|
|
||||||
#include <mapnik/vertex.hpp>
|
|
||||||
#include <mapnik/offset_converter.hpp>
|
|
||||||
|
|
||||||
struct fake_path
|
|
||||||
{
|
|
||||||
using coord_type = std::tuple<double, double, unsigned>;
|
|
||||||
using cont_type = std::vector<coord_type>;
|
|
||||||
cont_type vertices_;
|
|
||||||
cont_type::iterator itr_;
|
|
||||||
|
|
||||||
fake_path(std::initializer_list<double> l)
|
|
||||||
: fake_path(l.begin(), l.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
fake_path(std::vector<double> const& v)
|
|
||||||
: fake_path(v.begin(), v.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename Itr>
|
|
||||||
fake_path(Itr itr, size_t sz)
|
|
||||||
{
|
|
||||||
size_t num_coords = sz >> 1;
|
|
||||||
vertices_.reserve(num_coords);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_coords; ++i)
|
|
||||||
{
|
|
||||||
double x = *itr++;
|
|
||||||
double y = *itr++;
|
|
||||||
unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO;
|
|
||||||
vertices_.push_back(std::make_tuple(x, y, cmd));
|
|
||||||
if (i == num_coords - 1)
|
|
||||||
cmd = mapnik::SEG_END;
|
|
||||||
vertices_.push_back(std::make_tuple(x, y, cmd));
|
|
||||||
}
|
|
||||||
itr_ = vertices_.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned vertex(double* x, double* y)
|
|
||||||
{
|
|
||||||
if (itr_ == vertices_.end())
|
|
||||||
{
|
|
||||||
return mapnik::SEG_END;
|
|
||||||
}
|
|
||||||
*x = std::get<0>(*itr_);
|
|
||||||
*y = std::get<1>(*itr_);
|
|
||||||
unsigned cmd = std::get<2>(*itr_);
|
|
||||||
++itr_;
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rewind(unsigned) { itr_ = vertices_.begin(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class test_offset : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
test_offset(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::vector<double> path;
|
|
||||||
int mysize = 2500;
|
|
||||||
int x1 = 0;
|
|
||||||
path.reserve(mysize * 2);
|
|
||||||
for (int i = 0; i < mysize; i++)
|
|
||||||
{
|
|
||||||
path.push_back(i);
|
|
||||||
path.push_back(0);
|
|
||||||
}
|
|
||||||
fake_path fpath(path);
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::offset_converter<fake_path> off_path(fpath);
|
|
||||||
off_path.set_offset(10);
|
|
||||||
unsigned cmd;
|
|
||||||
double x, y;
|
|
||||||
while ((cmd = off_path.vertex(&x, &y)) != mapnik::SEG_END)
|
|
||||||
{
|
|
||||||
x1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return x1 > 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
int return_value = 0;
|
|
||||||
{
|
|
||||||
test_offset test_runner(params);
|
|
||||||
return_value = run(test_runner, "offset_test");
|
|
||||||
}
|
|
||||||
return return_value;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
mapnik::image_rgba8 im_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, im_(256, 256)
|
|
||||||
{}
|
|
||||||
bool validate() const { return true; }
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::string out;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
out.clear();
|
|
||||||
out = mapnik::save_to_string(im_, "png8:m=h:z=1");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "encoding blank png")
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include "compare_images.hpp"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::shared_ptr<mapnik::image_rgba8> im_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{
|
|
||||||
std::string filename("./benchmark/data/multicolor.png");
|
|
||||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, "png"));
|
|
||||||
if (!reader.get())
|
|
||||||
{
|
|
||||||
throw mapnik::image_reader_exception("Failed to load: " + filename);
|
|
||||||
}
|
|
||||||
im_ = std::make_shared<mapnik::image_rgba8>(reader->width(), reader->height());
|
|
||||||
reader->read(0, 0, *im_);
|
|
||||||
}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::string expected("./benchmark/data/multicolor-hextree-expected.png");
|
|
||||||
std::string actual("./benchmark/data/multicolor-hextree-actual.png");
|
|
||||||
mapnik::save_to_file(*im_, actual, "png8:m=h:z=1");
|
|
||||||
return benchmark::compare_images(actual, expected);
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::string out;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
out.clear();
|
|
||||||
out = mapnik::save_to_string(*im_, "png8:m=h:z=1");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "encoding multicolor png")
|
|
|
@ -1,550 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include "compare_images.hpp"
|
|
||||||
#include <mapnik/vertex.hpp>
|
|
||||||
#include <mapnik/transform_path_adapter.hpp>
|
|
||||||
#include <mapnik/view_transform.hpp>
|
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
|
||||||
#include <mapnik/projection.hpp>
|
|
||||||
#include <mapnik/proj_transform.hpp>
|
|
||||||
#include <mapnik/util/fs.hpp>
|
|
||||||
#include <mapnik/geometry.hpp>
|
|
||||||
#include <mapnik/vertex_adapters.hpp>
|
|
||||||
#include <mapnik/geometry.hpp>
|
|
||||||
#include <mapnik/geometry/boost_adapters.hpp>
|
|
||||||
#include <mapnik/geometry/envelope.hpp>
|
|
||||||
#include <mapnik/geometry/correct.hpp>
|
|
||||||
#include <mapnik/geometry/is_empty.hpp>
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/color.hpp>
|
|
||||||
// boost geometry
|
|
||||||
#include <boost/geometry.hpp>
|
|
||||||
// agg
|
|
||||||
#include "agg_conv_clip_polygon.h"
|
|
||||||
// clipper
|
|
||||||
#include "agg_path_storage.h"
|
|
||||||
// rendering
|
|
||||||
#include "agg_basics.h"
|
|
||||||
#include "agg_rendering_buffer.h"
|
|
||||||
#include "agg_pixfmt_rgba.h"
|
|
||||||
#include "agg_rasterizer_scanline_aa.h"
|
|
||||||
#include "agg_scanline_u.h"
|
|
||||||
#include "agg_renderer_scanline.h"
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
void render(mapnik::geometry::multi_polygon<double> const& geom,
|
|
||||||
mapnik::box2d<double> const& extent,
|
|
||||||
std::string const& name)
|
|
||||||
{
|
|
||||||
using path_type =
|
|
||||||
mapnik::transform_path_adapter<mapnik::view_transform, mapnik::geometry::polygon_vertex_adapter<double>>;
|
|
||||||
using ren_base = agg::renderer_base<agg::pixfmt_rgba32_plain>;
|
|
||||||
using renderer = agg::renderer_scanline_aa_solid<ren_base>;
|
|
||||||
mapnik::image_rgba8 im(256, 256);
|
|
||||||
mapnik::fill(im, mapnik::color("white"));
|
|
||||||
mapnik::box2d<double> padded_extent(155, 134, 665, 466); // extent;
|
|
||||||
padded_extent.pad(10);
|
|
||||||
mapnik::view_transform tr(im.width(), im.height(), padded_extent, 0, 0);
|
|
||||||
agg::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
|
|
||||||
agg::pixfmt_rgba32_plain pixf(buf);
|
|
||||||
ren_base renb(pixf);
|
|
||||||
renderer ren(renb);
|
|
||||||
mapnik::proj_transform prj_trans(mapnik::projection("epsg:4326"), mapnik::projection("epsg:4326"));
|
|
||||||
ren.color(agg::rgba8(127, 127, 127, 255));
|
|
||||||
agg::rasterizer_scanline_aa<> ras;
|
|
||||||
for (auto const& poly : geom)
|
|
||||||
{
|
|
||||||
mapnik::geometry::polygon_vertex_adapter<double> va(poly);
|
|
||||||
path_type path(tr, va, prj_trans);
|
|
||||||
ras.add_path(path);
|
|
||||||
}
|
|
||||||
agg::scanline_u8 sl;
|
|
||||||
agg::render_scanlines(ras, sl, ren);
|
|
||||||
mapnik::save_to_file(im, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
class test1 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string wkt_in_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
std::string expected_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using conv_clip = agg::conv_clip_polygon<mapnik::geometry::polygon_vertex_adapter<double>>;
|
|
||||||
test1(mapnik::parameters const& params, std::string const& wkt_in, mapnik::box2d<double> const& extent)
|
|
||||||
: test_case(params)
|
|
||||||
, wkt_in_(wkt_in)
|
|
||||||
, extent_(extent)
|
|
||||||
, expected_("./benchmark/data/polygon_clipping_agg")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double>>())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
|
|
||||||
mapnik::geometry::polygon_vertex_adapter<double> va(poly);
|
|
||||||
|
|
||||||
conv_clip clipped(va);
|
|
||||||
clipped.clip_box(extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy());
|
|
||||||
|
|
||||||
clipped.rewind(0);
|
|
||||||
mapnik::geometry::polygon<double> poly2;
|
|
||||||
mapnik::geometry::linear_ring<double> ring;
|
|
||||||
// exterior ring
|
|
||||||
unsigned cmd;
|
|
||||||
double x, y, x0, y0;
|
|
||||||
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END)
|
|
||||||
{
|
|
||||||
if (cmd == mapnik::SEG_MOVETO)
|
|
||||||
{
|
|
||||||
x0 = x;
|
|
||||||
y0 = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == mapnik::SEG_CLOSE)
|
|
||||||
{
|
|
||||||
ring.emplace_back(x0, y0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ring.emplace_back(x, y);
|
|
||||||
}
|
|
||||||
poly2.push_back(std::move(ring));
|
|
||||||
// interior rings
|
|
||||||
ring.clear();
|
|
||||||
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END)
|
|
||||||
{
|
|
||||||
if (cmd == mapnik::SEG_MOVETO)
|
|
||||||
{
|
|
||||||
x0 = x;
|
|
||||||
y0 = y;
|
|
||||||
}
|
|
||||||
else if (cmd == mapnik::SEG_CLOSE)
|
|
||||||
{
|
|
||||||
ring.emplace_back(x0, y0);
|
|
||||||
poly2.push_back(std::move(ring));
|
|
||||||
ring.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ring.emplace_back(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string expect = expected_ + ".png";
|
|
||||||
std::string actual = expected_ + "_actual.png";
|
|
||||||
mapnik::geometry::multi_polygon<double> mp;
|
|
||||||
mp.emplace_back(poly2);
|
|
||||||
auto env = mapnik::geometry::envelope(mp);
|
|
||||||
if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr))
|
|
||||||
{
|
|
||||||
std::clog << "generating expected image: " << expect << "\n";
|
|
||||||
render(mp, env, expect);
|
|
||||||
}
|
|
||||||
render(mp, env, actual);
|
|
||||||
return benchmark::compare_images(actual, expect);
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double>>())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool valid = true;
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
unsigned count = 0;
|
|
||||||
mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
|
|
||||||
mapnik::geometry::polygon_vertex_adapter<double> va(poly);
|
|
||||||
conv_clip clipped(va);
|
|
||||||
clipped.clip_box(extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy());
|
|
||||||
unsigned cmd;
|
|
||||||
double x, y;
|
|
||||||
// NOTE: this rewind is critical otherwise
|
|
||||||
// agg_conv_adapter_vpgen will give garbage
|
|
||||||
// values for the first vertex
|
|
||||||
clipped.rewind(0);
|
|
||||||
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
unsigned expected_count = 30;
|
|
||||||
if (count != expected_count)
|
|
||||||
{
|
|
||||||
std::clog << "test1: clipping failed: processed " << count << " verticies but expected "
|
|
||||||
<< expected_count << "\n";
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string wkt_in_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
std::string expected_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test3(mapnik::parameters const& params, std::string const& wkt_in, mapnik::box2d<double> const& extent)
|
|
||||||
: test_case(params)
|
|
||||||
, wkt_in_(wkt_in)
|
|
||||||
, extent_(extent)
|
|
||||||
, expected_("./benchmark/data/polygon_clipping_boost")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double>>())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::geometry::polygon<double>& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
|
|
||||||
mapnik::geometry::correct(poly);
|
|
||||||
|
|
||||||
mapnik::geometry::linear_ring<double> bbox;
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.miny());
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.maxy());
|
|
||||||
bbox.emplace_back(extent_.maxx(), extent_.maxy());
|
|
||||||
bbox.emplace_back(extent_.maxx(), extent_.miny());
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.miny());
|
|
||||||
|
|
||||||
std::deque<mapnik::geometry::polygon<double>> result;
|
|
||||||
boost::geometry::intersection(bbox, poly, result);
|
|
||||||
|
|
||||||
std::string expect = expected_ + ".png";
|
|
||||||
std::string actual = expected_ + "_actual.png";
|
|
||||||
mapnik::geometry::multi_polygon<double> mp;
|
|
||||||
for (auto const& _geom : result)
|
|
||||||
{
|
|
||||||
// std::clog << boost::geometry::dsv(geom) << "\n";
|
|
||||||
mp.emplace_back(_geom);
|
|
||||||
}
|
|
||||||
mapnik::geometry::geometry<double> geom2(mp);
|
|
||||||
auto env = mapnik::geometry::envelope(geom2);
|
|
||||||
if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr))
|
|
||||||
{
|
|
||||||
std::clog << "generating expected image: " << expect << "\n";
|
|
||||||
render(mp, env, expect);
|
|
||||||
}
|
|
||||||
render(mp, env, actual);
|
|
||||||
return benchmark::compare_images(actual, expect);
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double>>())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::geometry::polygon<double>& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
|
|
||||||
mapnik::geometry::correct(poly);
|
|
||||||
|
|
||||||
mapnik::geometry::linear_ring<double> bbox;
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.miny());
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.maxy());
|
|
||||||
bbox.emplace_back(extent_.maxx(), extent_.maxy());
|
|
||||||
bbox.emplace_back(extent_.maxx(), extent_.miny());
|
|
||||||
bbox.emplace_back(extent_.minx(), extent_.miny());
|
|
||||||
|
|
||||||
bool valid = true;
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::deque<mapnik::geometry::polygon<double>> result;
|
|
||||||
boost::geometry::intersection(bbox, poly, result);
|
|
||||||
unsigned count = 0;
|
|
||||||
for (auto const& _geom : result)
|
|
||||||
{
|
|
||||||
mapnik::geometry::polygon_vertex_adapter<double> va(_geom);
|
|
||||||
unsigned cmd;
|
|
||||||
double x, y;
|
|
||||||
while ((cmd = va.vertex(&x, &y)) != mapnik::SEG_END)
|
|
||||||
{
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
unsigned expected_count = 29;
|
|
||||||
if (count != expected_count)
|
|
||||||
{
|
|
||||||
std::clog << "test3: clipping failed: processed " << count << " verticies but expected "
|
|
||||||
<< expected_count << "\n";
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Commented out section because clipper moved out of mapnik core.
|
|
||||||
inline void process_polynode_branch(ClipperLib::PolyNode* polynode,
|
|
||||||
mapnik::geometry::multi_polygon<double> & mp)
|
|
||||||
{
|
|
||||||
mapnik::geometry::polygon<double> polygon;
|
|
||||||
mapnik::geometry::linear_ring<double> outer;
|
|
||||||
for (auto const& pt : polynode->Contour)
|
|
||||||
{
|
|
||||||
outer.emplace_back(static_cast<double>(pt.x),static_cast<double>(pt.y));
|
|
||||||
}
|
|
||||||
if (outer.front() != outer.back())
|
|
||||||
{
|
|
||||||
outer.emplace_back(outer.front().x, outer.front().y);
|
|
||||||
}
|
|
||||||
polygon.set_exterior_ring(std::move(outer));
|
|
||||||
for (auto * ring : polynode->Childs)
|
|
||||||
{
|
|
||||||
mapnik::geometry::linear_ring<double> inner;
|
|
||||||
for (auto const& pt : ring->Contour)
|
|
||||||
{
|
|
||||||
inner.emplace_back(static_cast<double>(pt.x),static_cast<double>(pt.y));
|
|
||||||
}
|
|
||||||
if (inner.front() != inner.back())
|
|
||||||
{
|
|
||||||
inner.emplace_back(inner.front().x, inner.front().y);
|
|
||||||
}
|
|
||||||
polygon.add_hole(std::move(inner));
|
|
||||||
}
|
|
||||||
mp.emplace_back(std::move(polygon));
|
|
||||||
for (auto * ring : polynode->Childs)
|
|
||||||
{
|
|
||||||
for (auto * sub_ring : ring->Childs)
|
|
||||||
{
|
|
||||||
process_polynode_branch(sub_ring, mp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class test4 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string wkt_in_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
std::string expected_;
|
|
||||||
public:
|
|
||||||
test4(mapnik::parameters const& params,
|
|
||||||
std::string const& wkt_in,
|
|
||||||
mapnik::box2d<double> const& extent)
|
|
||||||
: test_case(params),
|
|
||||||
wkt_in_(wkt_in),
|
|
||||||
extent_(extent),
|
|
||||||
expected_("./benchmark/data/polygon_clipping_clipper") {}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double> >())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom);
|
|
||||||
mapnik::geometry::correct(poly);
|
|
||||||
ClipperLib::Clipper clipper;
|
|
||||||
|
|
||||||
mapnik::geometry::line_string<std::int64_t> path;
|
|
||||||
for (auto const& pt : poly.exterior_ring)
|
|
||||||
{
|
|
||||||
double x = pt.x;
|
|
||||||
double y = pt.y;
|
|
||||||
path.emplace_back(static_cast<ClipperLib::cInt>(x),static_cast<ClipperLib::cInt>(y));
|
|
||||||
}
|
|
||||||
double area = ClipperLib::Area(path);
|
|
||||||
if (area > 0)
|
|
||||||
{
|
|
||||||
std::reverse(path.begin(), path.end());
|
|
||||||
}
|
|
||||||
if (!clipper.AddPath(path, ClipperLib::ptSubject, true))
|
|
||||||
{
|
|
||||||
std::clog << "ptSubject ext failed!\n";
|
|
||||||
}
|
|
||||||
for (auto const& ring : poly.interior_rings)
|
|
||||||
{
|
|
||||||
path.clear();
|
|
||||||
for (auto const& pt : ring)
|
|
||||||
{
|
|
||||||
double x = pt.x;
|
|
||||||
double y = pt.y;
|
|
||||||
path.emplace_back(static_cast<ClipperLib::cInt>(x),static_cast<ClipperLib::cInt>(y));
|
|
||||||
}
|
|
||||||
area = ClipperLib::Area(path);
|
|
||||||
if (area < 0)
|
|
||||||
{
|
|
||||||
std::reverse(path.begin(), path.end());
|
|
||||||
}
|
|
||||||
if (!clipper.AddPath(path, ClipperLib::ptSubject, true))
|
|
||||||
{
|
|
||||||
std::clog << "ptSubject ext failed!\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cerr << "path size=" << path.size() << std::endl;
|
|
||||||
mapnik::geometry::line_string<std::int64_t> clip_box;
|
|
||||||
clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.miny()));
|
|
||||||
clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.maxx()),static_cast<ClipperLib::cInt>(extent_.miny()));
|
|
||||||
clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.maxx()),static_cast<ClipperLib::cInt>(extent_.maxy()));
|
|
||||||
clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.maxy()));
|
|
||||||
clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.miny()));
|
|
||||||
|
|
||||||
if (!clipper.AddPath( clip_box, ClipperLib::ptClip, true ))
|
|
||||||
{
|
|
||||||
std::clog << "ptClip failed!\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipperLib::PolyTree polygons;
|
|
||||||
clipper.Execute(ClipperLib::ctIntersection, polygons);// ClipperLib::pftNonZero);
|
|
||||||
clipper.Clear();
|
|
||||||
mapnik::geometry::multi_polygon<double> mp;
|
|
||||||
for (auto * polynode : polygons.Childs)
|
|
||||||
{
|
|
||||||
process_polynode_branch(polynode, mp);
|
|
||||||
}
|
|
||||||
std::string expect = expected_+".png";
|
|
||||||
std::string actual = expected_+"_actual.png";
|
|
||||||
//mapnik::geometry::geometry<double> geom2(mp);
|
|
||||||
auto env = mapnik::geometry::envelope(mp);
|
|
||||||
if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr))
|
|
||||||
{
|
|
||||||
std::clog << "generating expected image: " << expect << "\n";
|
|
||||||
render(mp,env,expect);
|
|
||||||
}
|
|
||||||
render(mp,env,actual);
|
|
||||||
return benchmark::compare_images(actual,expect);
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::geometry::geometry<double> geom;
|
|
||||||
if (!mapnik::from_wkt(wkt_in_, geom))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
|
||||||
}
|
|
||||||
if (mapnik::geometry::is_empty(geom))
|
|
||||||
{
|
|
||||||
std::clog << "empty geom!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!geom.is<mapnik::geometry::polygon<double> >())
|
|
||||||
{
|
|
||||||
std::clog << "not a polygon!\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom);
|
|
||||||
mapnik::geometry::correct(poly);
|
|
||||||
|
|
||||||
bool valid = true;
|
|
||||||
for (unsigned i=0;i<iterations_;++i)
|
|
||||||
{
|
|
||||||
std::deque<mapnik::geometry::polygon<double> > result;
|
|
||||||
boost::geometry::intersection(extent_,poly,result);
|
|
||||||
|
|
||||||
unsigned count = 0;
|
|
||||||
for (auto const& geom : result)
|
|
||||||
{
|
|
||||||
mapnik::geometry::polygon_vertex_adapter<double> va(geom);
|
|
||||||
unsigned cmd;
|
|
||||||
double x,y;
|
|
||||||
while ((cmd = va.vertex(&x, &y)) != mapnik::SEG_END) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
unsigned expected_count = 29;
|
|
||||||
if (count != expected_count) {
|
|
||||||
std::clog << "test3: clipping failed: processed " << count << " verticies but expected " <<
|
|
||||||
expected_count << "\n"; valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
|
|
||||||
// polygon/rect clipping
|
|
||||||
// IN : POLYGON ((155 203, 233 454, 315 340, 421 446, 463 324, 559 466, 665 253, 528 178, 394 229, 329 138, 212 134,
|
|
||||||
// 183 228, 200 264, 155 203),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343
|
|
||||||
// 287, 249 334, 229 191, 313 190)) RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106)) OUT (expected)
|
|
||||||
// POLYGON ((181 286.6666666666667, 233 454, 315 340, 421 446, 463 324, 559 466, 631 321.3207547169811, 631
|
|
||||||
// 234.38686131386862, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 181 238.24444444444444, 181
|
|
||||||
// 286.6666666666667),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249
|
|
||||||
// 334, 229 191, 313 190))
|
|
||||||
#if 0
|
|
||||||
mapnik::box2d<double> clipping_box(181,106,631,470);
|
|
||||||
std::string filename_("./benchmark/data/polygon.wkt");
|
|
||||||
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
|
|
||||||
if (!in.is_open())
|
|
||||||
throw std::runtime_error("could not open: '" + filename_ + "'");
|
|
||||||
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
|
|
||||||
(std::istreambuf_iterator<char>()) );
|
|
||||||
int return_value = 0;
|
|
||||||
{
|
|
||||||
test1 test_runner(params,wkt_in,clipping_box);
|
|
||||||
return_value = return_value | run(test_runner,"clipping polygon with agg");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
test3 test_runner(params,wkt_in,clipping_box);
|
|
||||||
return_value = return_value | run(test_runner,"clipping polygon with boost");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
test4 test_runner(params,wkt_in,clipping_box);
|
|
||||||
return_value = return_value | run(test_runner,"clipping polygon with clipper_tree");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
return 0; // return_value;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/map.hpp>
|
|
||||||
#include <mapnik/load_map.hpp>
|
|
||||||
#include <mapnik/agg_renderer.hpp>
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string xml_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params, std::string const& xml, mapnik::box2d<double> const& extent)
|
|
||||||
: test_case(params)
|
|
||||||
, xml_(xml)
|
|
||||||
, extent_(extent)
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::Map m(256, 256);
|
|
||||||
mapnik::load_map(m, xml_);
|
|
||||||
m.zoom_to_box(extent_);
|
|
||||||
mapnik::image_rgba8 im(m.width(), m.height());
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
|
|
||||||
ren.apply();
|
|
||||||
// mapnik::save_to_file(im.data(),"test.png");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::Map m(256, 256);
|
|
||||||
mapnik::load_map(m, xml_);
|
|
||||||
m.zoom_to_box(extent_);
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::image_rgba8 im(m.width(), m.height());
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
|
|
||||||
ren.apply();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
|
||||||
mapnik::box2d<double> z1(-20037508.3428, -8317435.0606, 20037508.3428, 18399242.7298);
|
|
||||||
// bbox for 16/10491/22911.png
|
|
||||||
mapnik::box2d<double> z16(-13622912.929097254, 6026906.8062295765, -13621689.93664469, 6028129.79868214);
|
|
||||||
return benchmark::sequencer(argc, argv)
|
|
||||||
.run<test>("polygon clip render z1", "benchmark/data/polygon_rendering_clip.xml", z1)
|
|
||||||
.run<test>("polygon noclip render z1", "benchmark/data/polygon_rendering_no_clip.xml", z1)
|
|
||||||
.run<test>("polygon clip render z16", "benchmark/data/polygon_rendering_clip.xml", z16)
|
|
||||||
.run<test>("polygon noclip render z16", "benchmark/data/polygon_rendering_no_clip.xml", z16)
|
|
||||||
.done();
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/geometry/box2d.hpp>
|
|
||||||
#include <mapnik/projection.hpp>
|
|
||||||
#include <mapnik/proj_transform.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string src_;
|
|
||||||
std::string dest_;
|
|
||||||
mapnik::box2d<double> from_;
|
|
||||||
mapnik::box2d<double> to_;
|
|
||||||
bool defer_proj_init_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params,
|
|
||||||
std::string const& src,
|
|
||||||
std::string const& dest,
|
|
||||||
mapnik::box2d<double> const& from,
|
|
||||||
mapnik::box2d<double> const& to,
|
|
||||||
bool defer_proj)
|
|
||||||
: test_case(params)
|
|
||||||
, src_(src)
|
|
||||||
, dest_(dest)
|
|
||||||
, from_(from)
|
|
||||||
, to_(to)
|
|
||||||
, defer_proj_init_(defer_proj)
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::projection src(src_, defer_proj_init_);
|
|
||||||
mapnik::projection dest(dest_, defer_proj_init_);
|
|
||||||
mapnik::proj_transform tr(src, dest);
|
|
||||||
mapnik::box2d<double> bbox = from_;
|
|
||||||
if (!tr.forward(bbox))
|
|
||||||
return false;
|
|
||||||
return ((std::fabs(bbox.minx() - to_.minx()) < .5) && (std::fabs(bbox.maxx() - to_.maxx()) < .5) &&
|
|
||||||
(std::fabs(bbox.miny() - to_.miny()) < .5) && (std::fabs(bbox.maxy() - to_.maxy()) < .5));
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::projection src(src_, defer_proj_init_);
|
|
||||||
mapnik::projection dest(dest_, defer_proj_init_);
|
|
||||||
mapnik::proj_transform tr(src, dest);
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
for (int j = -180; j < 180; j = j + 5)
|
|
||||||
{
|
|
||||||
for (int k = -85; k < 85; k = k + 5)
|
|
||||||
{
|
|
||||||
mapnik::box2d<double> box(j, k, j, k);
|
|
||||||
if (!tr.forward(box))
|
|
||||||
throw std::runtime_error("could not transform coords");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// echo -180 -60 | cs2cs -f "%.10f" epsg:4326 +to epsg:3857
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::box2d<double> from(-180, -80, 180, 80);
|
|
||||||
mapnik::box2d<double> to(-20037508.3427892476, -15538711.0963092316, 20037508.3427892476, 15538711.0963092316);
|
|
||||||
std::string from_str("epsg:4326");
|
|
||||||
std::string to_str("epsg:3857");
|
|
||||||
std::string from_str2("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
|
|
||||||
std::string to_str2("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m "
|
|
||||||
"+nadgrids=@null +wktext +no_defs +over");
|
|
||||||
return benchmark::sequencer(argc, argv)
|
|
||||||
.run<test>("lonlat->merc epsg (internal)", from_str, to_str, from, to, true)
|
|
||||||
.run<test>("lonlat->merc literal (libproj)", from_str2, to_str2, from, to, true)
|
|
||||||
.run<test>("merc->lonlat epsg (internal)", to_str, from_str, to, from, true)
|
|
||||||
.run<test>("merc->lonlat literal (libproj)", to_str2, from_str2, to, from, true)
|
|
||||||
.done();
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/quad_tree.hpp>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
using quad_tree_type = mapnik::quad_tree<std::size_t>;
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool validate() const { return true; }
|
|
||||||
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::random_device rd;
|
|
||||||
std::default_random_engine engine(rd());
|
|
||||||
std::uniform_int_distribution<int> uniform_dist(0, 2048);
|
|
||||||
quad_tree_type tree(mapnik::box2d<double>(0, 0, 2048, 2048));
|
|
||||||
// populate
|
|
||||||
for (size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
int cx = uniform_dist(engine);
|
|
||||||
int cy = uniform_dist(engine);
|
|
||||||
int sx = 0.2 * uniform_dist(engine);
|
|
||||||
int sy = 0.2 * uniform_dist(engine);
|
|
||||||
mapnik::box2d<double> box(cx - sx, cy - sy, cx + sx, cy + sy);
|
|
||||||
tree.insert(i, box);
|
|
||||||
}
|
|
||||||
// bounding box query
|
|
||||||
std::size_t count = 0;
|
|
||||||
for (size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
int cx = uniform_dist(engine);
|
|
||||||
int cy = uniform_dist(engine);
|
|
||||||
int sx = 0.4 * uniform_dist(engine);
|
|
||||||
int sy = 0.4 * uniform_dist(engine);
|
|
||||||
mapnik::box2d<double> box(cx - sx, cy - sy, cx + sx, cy + sy);
|
|
||||||
auto itr = tree.query_in_box(box);
|
|
||||||
auto end = tree.query_end();
|
|
||||||
for (; itr != end; ++itr)
|
|
||||||
{
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "quad_tree creation")
|
|
|
@ -1,123 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/map.hpp>
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/load_map.hpp>
|
|
||||||
#include <mapnik/agg_renderer.hpp>
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string xml_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
mapnik::value_integer width_;
|
|
||||||
mapnik::value_integer height_;
|
|
||||||
double scale_factor_;
|
|
||||||
std::string preview_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, xml_()
|
|
||||||
, extent_()
|
|
||||||
, width_(*params.get<mapnik::value_integer>("width", 256))
|
|
||||||
, height_(*params.get<mapnik::value_integer>("height", 256))
|
|
||||||
, scale_factor_(*params.get<mapnik::value_double>("scale_factor", 1.0))
|
|
||||||
, preview_(*params.get<std::string>("preview", ""))
|
|
||||||
{
|
|
||||||
const auto map = params.get<std::string>("map");
|
|
||||||
if (!map)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("please provide a --map <path to xml> arg");
|
|
||||||
}
|
|
||||||
xml_ = *map;
|
|
||||||
|
|
||||||
const auto ext = params.get<std::string>("extent");
|
|
||||||
if (ext && !ext->empty())
|
|
||||||
{
|
|
||||||
if (!extent_.from_string(*ext))
|
|
||||||
throw std::runtime_error("could not parse `extent` string" + *ext);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("please provide a --extent=<minx,miny,maxx,maxy> arg");
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::Map m(width_, height_);
|
|
||||||
mapnik::load_map(m, xml_, true);
|
|
||||||
if (extent_.valid())
|
|
||||||
{
|
|
||||||
m.zoom_to_box(extent_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m.zoom_all();
|
|
||||||
}
|
|
||||||
mapnik::image_rgba8 im(m.width(), m.height());
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im, scale_factor_);
|
|
||||||
ren.apply();
|
|
||||||
if (!preview_.empty())
|
|
||||||
{
|
|
||||||
std::clog << "preview available at " << preview_ << "\n";
|
|
||||||
mapnik::save_to_file(im, preview_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
if (!preview_.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mapnik::Map m(width_, height_);
|
|
||||||
mapnik::load_map(m, xml_);
|
|
||||||
if (extent_.valid())
|
|
||||||
{
|
|
||||||
m.zoom_to_box(extent_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m.zoom_all();
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::image_rgba8 im(m.width(), m.height());
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im, scale_factor_);
|
|
||||||
ren.apply();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
int return_value = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
const auto name = params.get<std::string>("name");
|
|
||||||
if (!name)
|
|
||||||
{
|
|
||||||
std::clog << "please provide a name for this test\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mapnik::freetype_engine::register_fonts("./fonts/", true);
|
|
||||||
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
|
||||||
{
|
|
||||||
test test_runner(params);
|
|
||||||
return_value = run(test_runner, *name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
std::clog << ex.what() << "\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return return_value;
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/map.hpp>
|
|
||||||
#include <mapnik/image_util.hpp>
|
|
||||||
#include <mapnik/load_map.hpp>
|
|
||||||
#include <mapnik/agg_renderer.hpp>
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
|
||||||
#include <mapnik/scale_denominator.hpp>
|
|
||||||
#include <mapnik/projection.hpp>
|
|
||||||
#include <mapnik/layer.hpp>
|
|
||||||
#include <mapnik/proj_transform.hpp>
|
|
||||||
#include <mapnik/datasource_cache.hpp>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
template<typename Renderer>
|
|
||||||
void process_layers(Renderer& ren,
|
|
||||||
mapnik::request const& m_req,
|
|
||||||
mapnik::projection const& map_proj,
|
|
||||||
std::vector<mapnik::layer> const& layers,
|
|
||||||
double scale_denom)
|
|
||||||
{
|
|
||||||
unsigned layers_size = layers.size();
|
|
||||||
for (unsigned i = 0; i < layers_size; ++i)
|
|
||||||
{
|
|
||||||
mapnik::layer const& lyr = layers[i];
|
|
||||||
if (lyr.visible(scale_denom))
|
|
||||||
{
|
|
||||||
std::set<std::string> names;
|
|
||||||
mapnik::layer l(lyr);
|
|
||||||
ren.apply_to_layer(l,
|
|
||||||
ren,
|
|
||||||
map_proj,
|
|
||||||
m_req.scale(),
|
|
||||||
scale_denom,
|
|
||||||
m_req.width(),
|
|
||||||
m_req.height(),
|
|
||||||
m_req.extent(),
|
|
||||||
m_req.buffer_size(),
|
|
||||||
names);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string xml_;
|
|
||||||
mapnik::box2d<double> extent_;
|
|
||||||
mapnik::value_integer width_;
|
|
||||||
mapnik::value_integer height_;
|
|
||||||
std::shared_ptr<mapnik::Map> m_;
|
|
||||||
double scale_factor_;
|
|
||||||
std::string preview_;
|
|
||||||
mutable mapnik::image_rgba8 im_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, xml_()
|
|
||||||
, extent_()
|
|
||||||
, width_(*params.get<mapnik::value_integer>("width", 256))
|
|
||||||
, height_(*params.get<mapnik::value_integer>("height", 256))
|
|
||||||
, m_(new mapnik::Map(width_, height_))
|
|
||||||
, scale_factor_(*params.get<mapnik::value_double>("scale_factor", 2.0))
|
|
||||||
, preview_(*params.get<std::string>("preview", ""))
|
|
||||||
, im_(m_->width(), m_->height())
|
|
||||||
{
|
|
||||||
const auto map = params.get<std::string>("map");
|
|
||||||
if (!map)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("please provide a --map=<path to xml> arg");
|
|
||||||
}
|
|
||||||
xml_ = *map;
|
|
||||||
|
|
||||||
auto ext = params.get<std::string>("extent");
|
|
||||||
mapnik::load_map(*m_, xml_, true);
|
|
||||||
if (ext && !ext->empty())
|
|
||||||
{
|
|
||||||
if (!extent_.from_string(*ext))
|
|
||||||
throw std::runtime_error("could not parse `extent` string" + *ext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_->zoom_all();
|
|
||||||
extent_ = m_->get_current_extent();
|
|
||||||
std::clog << "Defaulting to max extent " << extent_ << "\n";
|
|
||||||
std::clog << " (pass --extent=<minx,miny,maxx,maxy> to restrict bounds)\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::request m_req(width_, height_, extent_);
|
|
||||||
mapnik::attributes variables;
|
|
||||||
m_req.set_buffer_size(m_->buffer_size());
|
|
||||||
mapnik::projection map_proj(m_->srs(), true);
|
|
||||||
double scale_denom = mapnik::scale_denominator(m_req.scale(), map_proj.is_geographic());
|
|
||||||
scale_denom *= scale_factor_;
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_, m_req, variables, im_, scale_factor_);
|
|
||||||
ren.start_map_processing(*m_);
|
|
||||||
std::vector<mapnik::layer> const& layers = m_->layers();
|
|
||||||
process_layers(ren, m_req, map_proj, layers, scale_denom);
|
|
||||||
ren.end_map_processing(*m_);
|
|
||||||
if (!preview_.empty())
|
|
||||||
{
|
|
||||||
std::clog << "preview available at " << preview_ << "\n";
|
|
||||||
mapnik::save_to_file(im_, preview_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
if (!preview_.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::request m_req(width_, height_, extent_);
|
|
||||||
mapnik::image_rgba8 im(m_->width(), m_->height());
|
|
||||||
mapnik::attributes variables;
|
|
||||||
m_req.set_buffer_size(m_->buffer_size());
|
|
||||||
mapnik::projection map_proj(m_->srs(), true);
|
|
||||||
double scale_denom = mapnik::scale_denominator(m_req.scale(), map_proj.is_geographic());
|
|
||||||
scale_denom *= scale_factor_;
|
|
||||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_, m_req, variables, im, scale_factor_);
|
|
||||||
ren.start_map_processing(*m_);
|
|
||||||
std::vector<mapnik::layer> const& layers = m_->layers();
|
|
||||||
process_layers(ren, m_req, map_proj, layers, scale_denom);
|
|
||||||
ren.end_map_processing(*m_);
|
|
||||||
bool diff = false;
|
|
||||||
mapnik::image_rgba8 const& dest = im;
|
|
||||||
mapnik::image_rgba8 const& src = im_;
|
|
||||||
for (unsigned int y = 0; y < height_; ++y)
|
|
||||||
{
|
|
||||||
const unsigned int* row_from = src.get_row(y);
|
|
||||||
const unsigned int* row_to = dest.get_row(y);
|
|
||||||
for (unsigned int x = 0; x < width_; ++x)
|
|
||||||
{
|
|
||||||
if (row_from[x] != row_to[x])
|
|
||||||
diff = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (diff)
|
|
||||||
throw std::runtime_error("images differ");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
int return_value = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
const auto name = params.get<std::string>("name");
|
|
||||||
if (!name)
|
|
||||||
{
|
|
||||||
std::clog << "please provide a name for this test\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mapnik::freetype_engine::register_fonts("./fonts/", true);
|
|
||||||
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
|
||||||
{
|
|
||||||
test test_runner(params);
|
|
||||||
return_value = run(test_runner, *name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
std::clog << ex.what() << "\n";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return return_value;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/util/conversions.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, value_("true")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
mapnik::util::string2bool(value_.data(), value_.data() + value_.size(), result);
|
|
||||||
if (!result)
|
|
||||||
return result;
|
|
||||||
mapnik::util::string2bool(value_, result);
|
|
||||||
return (result == true);
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
mapnik::util::string2bool(value_, result);
|
|
||||||
mapnik::util::string2bool(value_.data(), value_.data() + value_.size(), result);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "string->bool")
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/util/conversions.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, value_("1.23456789")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
double result = 0;
|
|
||||||
if (!mapnik::util::string2double(value_.data(), value_.data() + value_.size(), result))
|
|
||||||
return false;
|
|
||||||
if (result != 1.23456789)
|
|
||||||
return false;
|
|
||||||
result = 0;
|
|
||||||
if (!mapnik::util::string2double(value_, result))
|
|
||||||
return false;
|
|
||||||
if (result != 1.23456789)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
double result = 0;
|
|
||||||
mapnik::util::string2double(value_, result);
|
|
||||||
mapnik::util::string2double(value_.data(), value_.data() + value_.size(), result);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "string->double")
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/util/conversions.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, value_("123456789")
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::value_integer result = 0;
|
|
||||||
if (!mapnik::util::string2int(value_.data(), value_.data() + value_.size(), result))
|
|
||||||
return false;
|
|
||||||
if (result != 123456789)
|
|
||||||
return false;
|
|
||||||
result = 0;
|
|
||||||
if (!mapnik::util::string2int(value_, result))
|
|
||||||
return false;
|
|
||||||
if (result != 123456789)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
mapnik::value_integer result = 0;
|
|
||||||
mapnik::util::string2int(value_, result);
|
|
||||||
mapnik::util::string2int(value_.data(), value_.data() + value_.size(), result);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "string->int")
|
|
|
@ -1,31 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/util/conversions.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
double value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, value_(-0.1234)
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::string s;
|
|
||||||
mapnik::util::to_string(s, value_);
|
|
||||||
return (s == "-0.1234");
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::string out;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
out.clear();
|
|
||||||
mapnik::util::to_string(out, value_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "to_string double->string")
|
|
|
@ -1,32 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
double value_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, value_(-0.1234)
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::ostringstream s;
|
|
||||||
s << value_;
|
|
||||||
return (s.str() == "-0.1234");
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::string out;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
std::ostringstream s;
|
|
||||||
s << value_;
|
|
||||||
out = s.str();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BENCHMARK(test, "ostringstream double->string")
|
|
|
@ -1,124 +0,0 @@
|
||||||
#include "bench_framework.hpp"
|
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
#include <mapnik/util/from_u8string.hpp>
|
|
||||||
#include <mapnik/value.hpp>
|
|
||||||
#include <boost/locale.hpp>
|
|
||||||
#ifndef __linux__
|
|
||||||
#include <codecvt>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using mapnik::util::from_u8string;
|
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
class test : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string utf8_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, utf8_(from_u8string(u8"שלום"))
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
|
|
||||||
std::u32string utf32 = utf32conv.from_bytes(utf8_);
|
|
||||||
if (utf32.size() != 4)
|
|
||||||
return false;
|
|
||||||
if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::u32string utf32;
|
|
||||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
utf32 = utf32conv.from_bytes(utf8_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class test2 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string utf8_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test2(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, utf8_(from_u8string(u8"שלום"))
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
|
||||||
if (utf32.size() != 4)
|
|
||||||
return false;
|
|
||||||
if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
std::u32string utf32;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class test3 : public benchmark::test_case
|
|
||||||
{
|
|
||||||
std::string utf8_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
test3(mapnik::parameters const& params)
|
|
||||||
: test_case(params)
|
|
||||||
, utf8_(from_u8string(u8"שלום"))
|
|
||||||
{}
|
|
||||||
bool validate() const
|
|
||||||
{
|
|
||||||
mapnik::transcoder tr_("utf-8");
|
|
||||||
mapnik::value_unicode_string utf32 = tr_.transcode(utf8_.data(), utf8_.size());
|
|
||||||
// std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
|
||||||
if (utf32.length() != 4)
|
|
||||||
return false;
|
|
||||||
if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool operator()() const
|
|
||||||
{
|
|
||||||
mapnik::transcoder tr_("utf-8");
|
|
||||||
mapnik::value_unicode_string utf32;
|
|
||||||
for (std::size_t i = 0; i < iterations_; ++i)
|
|
||||||
{
|
|
||||||
utf32 = tr_.transcode(utf8_.data(), utf8_.size());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
mapnik::setup();
|
|
||||||
mapnik::parameters params;
|
|
||||||
benchmark::handle_args(argc, argv, params);
|
|
||||||
int return_value = 0;
|
|
||||||
#ifndef __linux__
|
|
||||||
test test_runner(params);
|
|
||||||
return_value = return_value | run(test_runner, "utf encode std::codecvt");
|
|
||||||
#else
|
|
||||||
std::clog << "skipping 'utf encode std::codecvt' test since <codecvt> is not supported on __linux__\n";
|
|
||||||
#endif
|
|
||||||
test2 test_runner2(params);
|
|
||||||
return_value = return_value | run(test_runner2, "utf encode boost::locale");
|
|
||||||
test3 test_runner3(params);
|
|
||||||
return_value = return_value | run(test_runner3, "utf encode ICU");
|
|
||||||
return return_value;
|
|
||||||
}
|
|
|
@ -2,12 +2,16 @@
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
class test : public benchmark::test_case
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
test(mapnik::parameters const& params)
|
test(mapnik::parameters const& params)
|
||||||
: test_case(params)
|
: test_case(params) {}
|
||||||
{}
|
bool validate() const
|
||||||
bool validate() const { return true; }
|
{
|
||||||
void operator()() const {}
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BENCHMARK(test, "test name")
|
BENCHMARK(test,"test name")
|
||||||
|
|
347
benchmark/test_array_allocation.cpp
Normal file
347
benchmark/test_array_allocation.cpp
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <array>
|
||||||
|
#include <valarray>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#if BOOST_VERSION >= 105400
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// http://stackoverflow.com/questions/17347254/why-is-allocation-and-deallocation-of-stdvector-slower-than-dynamic-array-on-m
|
||||||
|
|
||||||
|
#define FULL_ZERO_CHECK
|
||||||
|
|
||||||
|
inline void ensure_zero(uint8_t * data, uint32_t size) {
|
||||||
|
#ifdef FULL_ZERO_CHECK
|
||||||
|
for (std::size_t i=0;i<size;++i) {
|
||||||
|
if (data[i] != 0) {
|
||||||
|
throw std::runtime_error("found non zero value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (data[0] != 0) {
|
||||||
|
throw std::runtime_error("found non zero value");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class test1 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test1(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
// NOTE: sizeof(uint8_t) == 1
|
||||||
|
uint8_t *data = (uint8_t *)malloc(sizeof(uint8_t)*size_);
|
||||||
|
memcpy(data, &array_[0], size_);
|
||||||
|
ensure_zero(data,size_);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test1b : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test1b(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
// NOTE: sizeof(uint8_t) == 1
|
||||||
|
uint8_t *data = (uint8_t *)malloc(sizeof(uint8_t)*size_);
|
||||||
|
memset(data, 0, sizeof(uint8_t)*size_);
|
||||||
|
ensure_zero(data,size_);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test2 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test2(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
uint8_t * data = static_cast<uint8_t*>(::operator new(sizeof(uint8_t)*size_));
|
||||||
|
memcpy(data, &array_[0], size_);
|
||||||
|
ensure_zero(data,size_);
|
||||||
|
::operator delete(data),data=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test3 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test3(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::vector<uint8_t> data(size_);
|
||||||
|
ensure_zero(&data[0],data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class test3b : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test3b(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::vector<uint8_t> data(0);
|
||||||
|
data.resize(size_,0);
|
||||||
|
ensure_zero(&data[0],data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class test3c : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test3c(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::vector<uint8_t> data(0);
|
||||||
|
data.assign(size_,0);
|
||||||
|
ensure_zero(&data[0],data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test4 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test4(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
uint8_t *data = (uint8_t *)calloc(size_,sizeof(uint8_t));
|
||||||
|
ensure_zero(data,size_);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test5 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test5(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::string data(array_.begin(),array_.end());
|
||||||
|
ensure_zero((uint8_t *)&data[0],size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test5b : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<char> array_;
|
||||||
|
test5b(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::string data(&array_[0],array_.size());
|
||||||
|
ensure_zero((uint8_t *)&data[0],size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// C++14 dynarray<T>
|
||||||
|
// http://isocpp.org/blog/2013/04/trip-report-iso-c-spring-2013-meeting
|
||||||
|
// http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130909/088700.html
|
||||||
|
// http://stackoverflow.com/questions/17303902/any-alternative-to-stddynarray-presently-available
|
||||||
|
|
||||||
|
class test6 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test6(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::valarray<uint8_t> data(static_cast<uint8_t>(0),static_cast<size_t>(size_));
|
||||||
|
ensure_zero(&data[0],size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BOOST_VERSION >= 105400
|
||||||
|
// http://i42.co.uk/stuff/vecarray.htm
|
||||||
|
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost/container/static_vector.html
|
||||||
|
|
||||||
|
class test7 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t size_;
|
||||||
|
std::vector<uint8_t> array_;
|
||||||
|
test7(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
size_(*params.get<mapnik::value_integer>("size",256*256)),
|
||||||
|
array_(size_,0) { }
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
boost::container::static_vector<uint8_t,256*256> data(size_,0);
|
||||||
|
ensure_zero(&data[0],size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
{
|
||||||
|
test4 test_runner4(params);
|
||||||
|
run(test_runner4,"calloc");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test1 test_runner(params);
|
||||||
|
run(test_runner,"malloc/memcpy");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test1b test_runner(params);
|
||||||
|
run(test_runner,"malloc/memset");
|
||||||
|
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test2 test_runner(params);
|
||||||
|
run(test_runner,"new");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test3 test_runner(params);
|
||||||
|
run(test_runner,"vector(N)");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test3b test_runner(params);
|
||||||
|
run(test_runner,"vector/resize");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test3c test_runner(params);
|
||||||
|
run(test_runner,"vector/assign");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test5 test_runner(params);
|
||||||
|
run(test_runner,"std::string range");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test5b test_runner(params);
|
||||||
|
run(test_runner,"std::string &[0]");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test6 test_runner(params);
|
||||||
|
run(test_runner,"valarray");
|
||||||
|
}
|
||||||
|
#if BOOST_VERSION >= 105400
|
||||||
|
{
|
||||||
|
test7 test_runner(params);
|
||||||
|
run(test_runner,"static_vector");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
40
benchmark/test_expression_parse.cpp
Normal file
40
benchmark/test_expression_parse.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <mapnik/expression.hpp>
|
||||||
|
#include <mapnik/expression_string.hpp>
|
||||||
|
#include <mapnik/expression_grammar.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string expr_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::expression_ptr expr = mapnik::parse_expression(expr_,"utf-8");
|
||||||
|
std::string result = mapnik::to_expression_string(*expr);
|
||||||
|
bool ret = (result == expr_);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
std::clog << result << " != " << expr_ << "\n";
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
mapnik::expression_ptr expr = mapnik::parse_expression(expr_,"utf-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
test test_runner(params);
|
||||||
|
run(test_runner,"expr parsing");
|
||||||
|
}
|
42
benchmark/test_face_ptr_creation.cpp
Normal file
42
benchmark/test_face_ptr_creation.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
mapnik::freetype_engine engine;
|
||||||
|
unsigned long count = 0;
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
for ( std::string const& name : mapnik::freetype_engine::face_names())
|
||||||
|
{
|
||||||
|
mapnik::face_ptr f = engine.create_face(name);
|
||||||
|
if (f) ++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
bool success = mapnik::freetype_engine::register_fonts("./fonts", true);
|
||||||
|
if (!success) {
|
||||||
|
std::clog << "warning, did not register any new fonts!\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::size_t face_count = mapnik::freetype_engine::face_names().size();
|
||||||
|
test test_runner(params);
|
||||||
|
return run(test_runner,(boost::format("font_engine: creating %ld faces") % (face_count * 1000 * 10)).str());
|
||||||
|
}
|
||||||
|
|
26
benchmark/test_font_registration.cpp
Normal file
26
benchmark/test_font_registration.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return mapnik::freetype_engine::register_fonts("./fonts", true);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
unsigned long count = 0;
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
mapnik::freetype_engine::register_fonts("./fonts", true);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"font registration")
|
26
benchmark/test_png_encoding1.cpp
Normal file
26
benchmark/test_png_encoding1.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
mapnik::image_data_32 im_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
im_(256,256) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
out.clear();
|
||||||
|
out = mapnik::save_to_string(im_,"png8:m=h:z=1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"encoding blank png")
|
36
benchmark/test_png_encoding2.cpp
Normal file
36
benchmark/test_png_encoding2.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include "compare_images.hpp"
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::shared_ptr<image_32> im_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params) {
|
||||||
|
std::string filename("./benchmark/data/multicolor.png");
|
||||||
|
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"png"));
|
||||||
|
if (!reader.get())
|
||||||
|
{
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + filename);
|
||||||
|
}
|
||||||
|
im_ = std::make_shared<image_32>(reader->width(),reader->height());
|
||||||
|
reader->read(0,0,im_->data());
|
||||||
|
}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::string expected("./benchmark/data/multicolor-hextree-expected.png");
|
||||||
|
std::string actual("./benchmark/data/multicolor-hextree-actual.png");
|
||||||
|
mapnik::save_to_file(im_->data(),actual, "png8:m=h:z=1");
|
||||||
|
return benchmark::compare_images(actual,expected);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
out.clear();
|
||||||
|
out = mapnik::save_to_string(im_->data(),"png8:m=h:z=1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"encoding multicolor png")
|
320
benchmark/test_polygon_clipping.cpp
Normal file
320
benchmark/test_polygon_clipping.cpp
Normal file
|
@ -0,0 +1,320 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include "compare_images.hpp"
|
||||||
|
#include "agg_conv_clip_polygon.h"
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/vertex.hpp>
|
||||||
|
#include <mapnik/ctrans.hpp>
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
|
#include <mapnik/wkt/wkt_grammar_impl.hpp>
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/projection.hpp>
|
||||||
|
#include <mapnik/proj_transform.hpp>
|
||||||
|
#include <mapnik/util/fs.hpp>
|
||||||
|
|
||||||
|
// agg
|
||||||
|
#include "agg_conv_clip_polygon.h"
|
||||||
|
// clipper
|
||||||
|
#include "agg_conv_clipper.h"
|
||||||
|
#include "agg_path_storage.h"
|
||||||
|
// boost
|
||||||
|
#include <mapnik/polygon_clipper.hpp>
|
||||||
|
|
||||||
|
// rendering
|
||||||
|
#include "agg_basics.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
#include "agg_pixfmt_rgba.h"
|
||||||
|
#include "agg_rasterizer_scanline_aa.h"
|
||||||
|
#include "agg_scanline_u.h"
|
||||||
|
#include "agg_renderer_scanline.h"
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
void render(mapnik::geometry_type & geom,
|
||||||
|
mapnik::box2d<double> const& extent,
|
||||||
|
std::string const& name)
|
||||||
|
{
|
||||||
|
using path_type = mapnik::coord_transform<mapnik::CoordTransform,mapnik::geometry_type>;
|
||||||
|
using ren_base = agg::renderer_base<agg::pixfmt_rgba32_plain>;
|
||||||
|
using renderer = agg::renderer_scanline_aa_solid<ren_base>;
|
||||||
|
mapnik::image_32 im(256,256);
|
||||||
|
im.set_background(mapnik::color("white"));
|
||||||
|
mapnik::box2d<double> padded_extent = extent;
|
||||||
|
padded_extent.pad(10);
|
||||||
|
mapnik::CoordTransform tr(im.width(),im.height(),padded_extent,0,0);
|
||||||
|
agg::rendering_buffer buf(im.raw_data(),im.width(),im.height(), im.width() * 4);
|
||||||
|
agg::pixfmt_rgba32_plain pixf(buf);
|
||||||
|
ren_base renb(pixf);
|
||||||
|
renderer ren(renb);
|
||||||
|
ren.color(agg::rgba8(127,127,127,255));
|
||||||
|
agg::rasterizer_scanline_aa<> ras;
|
||||||
|
mapnik::proj_transform prj_trans(mapnik::projection("+init=epsg:4326"),mapnik::projection("+init=epsg:4326"));
|
||||||
|
geom.rewind(0);
|
||||||
|
path_type path(tr,geom,prj_trans);
|
||||||
|
ras.add_path(path);
|
||||||
|
agg::scanline_u8 sl;
|
||||||
|
agg::render_scanlines(ras, sl, ren);
|
||||||
|
mapnik::save_to_file(im,name);
|
||||||
|
geom.rewind(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class test1 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string wkt_in_;
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
std::string expected_;
|
||||||
|
public:
|
||||||
|
using conv_clip = agg::conv_clip_polygon<mapnik::geometry_type>;
|
||||||
|
test1(mapnik::parameters const& params,
|
||||||
|
std::string const& wkt_in,
|
||||||
|
mapnik::box2d<double> const& extent)
|
||||||
|
: test_case(params),
|
||||||
|
wkt_in_(wkt_in),
|
||||||
|
extent_(extent),
|
||||||
|
expected_("./benchmark/data/polygon_clipping_agg") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::string expected_wkt("Polygon((181 286.666667,233 454,315 340,421 446,463 324,559 466,631 321.320755,631 234.386861,528 178,394 229,329 138,212 134,183 228,200 264,181 238.244444),(313 190,440 256,470 248,510 305,533 237,613 263,553 397,455 262,405 378,343 287,249 334,229 191,313 190,313 190))");
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
if (paths.size() != 1)
|
||||||
|
{
|
||||||
|
std::clog << "paths.size() != 1\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mapnik::geometry_type & geom = paths[0];
|
||||||
|
conv_clip clipped(geom);
|
||||||
|
clipped.clip_box(
|
||||||
|
extent_.minx(),
|
||||||
|
extent_.miny(),
|
||||||
|
extent_.maxx(),
|
||||||
|
extent_.maxy());
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon);
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {
|
||||||
|
geom2.push_vertex(x,y,(mapnik::CommandType)cmd);
|
||||||
|
}
|
||||||
|
std::string expect = expected_+".png";
|
||||||
|
std::string actual = expected_+"_actual.png";
|
||||||
|
if (!mapnik::util::exists(expect))
|
||||||
|
{
|
||||||
|
std::clog << "generating expected image: " << expect << "\n";
|
||||||
|
render(geom2,geom.envelope(),expect);
|
||||||
|
}
|
||||||
|
render(geom2,geom.envelope(),actual);
|
||||||
|
return benchmark::compare_images(actual,expect);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
for (mapnik::geometry_type & geom : paths)
|
||||||
|
{
|
||||||
|
conv_clip clipped(geom);
|
||||||
|
clipped.clip_box(
|
||||||
|
extent_.minx(),
|
||||||
|
extent_.miny(),
|
||||||
|
extent_.maxx(),
|
||||||
|
extent_.maxy());
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test2 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string wkt_in_;
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
std::string expected_;
|
||||||
|
public:
|
||||||
|
using poly_clipper = agg::conv_clipper<mapnik::geometry_type, agg::path_storage>;
|
||||||
|
test2(mapnik::parameters const& params,
|
||||||
|
std::string const& wkt_in,
|
||||||
|
mapnik::box2d<double> const& extent)
|
||||||
|
: test_case(params),
|
||||||
|
wkt_in_(wkt_in),
|
||||||
|
extent_(extent),
|
||||||
|
expected_("./benchmark/data/polygon_clipping_clipper") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::string expected_wkt("Polygon((212 134,329 138,394 229,528 178,631 234.4,631 321.3,559 466,463 324,421 446,315 340,233 454,181 286.7,181 238.2,200 264,183 228),(313 190,229 191,249 334,343 287,405 378,455 262,553 397,613 263,533 237,510 305,470 248,440 256))");
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
agg::path_storage ps;
|
||||||
|
ps.move_to(extent_.minx(), extent_.miny());
|
||||||
|
ps.line_to(extent_.minx(), extent_.maxy());
|
||||||
|
ps.line_to(extent_.maxx(), extent_.maxy());
|
||||||
|
ps.line_to(extent_.maxx(), extent_.miny());
|
||||||
|
ps.close_polygon();
|
||||||
|
if (paths.size() != 1)
|
||||||
|
{
|
||||||
|
std::clog << "paths.size() != 1\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mapnik::geometry_type & geom = paths[0];
|
||||||
|
poly_clipper clipped(geom,ps,
|
||||||
|
agg::clipper_and,
|
||||||
|
agg::clipper_non_zero,
|
||||||
|
agg::clipper_non_zero,
|
||||||
|
1);
|
||||||
|
clipped.rewind(0);
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon);
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {
|
||||||
|
geom2.push_vertex(x,y,(mapnik::CommandType)cmd);
|
||||||
|
}
|
||||||
|
std::string expect = expected_+".png";
|
||||||
|
std::string actual = expected_+"_actual.png";
|
||||||
|
if (!mapnik::util::exists(expect))
|
||||||
|
{
|
||||||
|
std::clog << "generating expected image: " << expect << "\n";
|
||||||
|
render(geom2,geom.envelope(),expect);
|
||||||
|
}
|
||||||
|
render(geom2,geom.envelope(),actual);
|
||||||
|
return benchmark::compare_images(actual,expect);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
agg::path_storage ps;
|
||||||
|
ps.move_to(extent_.minx(), extent_.miny());
|
||||||
|
ps.line_to(extent_.minx(), extent_.maxy());
|
||||||
|
ps.line_to(extent_.maxx(), extent_.maxy());
|
||||||
|
ps.line_to(extent_.maxx(), extent_.miny());
|
||||||
|
ps.close_polygon();
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
for (mapnik::geometry_type & geom : paths)
|
||||||
|
{
|
||||||
|
poly_clipper clipped(geom,ps,
|
||||||
|
agg::clipper_and,
|
||||||
|
agg::clipper_non_zero,
|
||||||
|
agg::clipper_non_zero,
|
||||||
|
1);
|
||||||
|
clipped.rewind(0);
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test3 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string wkt_in_;
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
std::string expected_;
|
||||||
|
public:
|
||||||
|
using poly_clipper = mapnik::polygon_clipper<mapnik::geometry_type>;
|
||||||
|
test3(mapnik::parameters const& params,
|
||||||
|
std::string const& wkt_in,
|
||||||
|
mapnik::box2d<double> const& extent)
|
||||||
|
: test_case(params),
|
||||||
|
wkt_in_(wkt_in),
|
||||||
|
extent_(extent),
|
||||||
|
expected_("./benchmark/data/polygon_clipping_boost") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::string expected_wkt("Polygon((181 286.666667,233 454,315 340,421 446,463 324,559 466,631 321.320755,631 234.386861,528 178,394 229,329 138,212 134,183 228,200 264,181 238.244444,181 286.666667),(313 190,440 256,470 248,510 305,533 237,613 263,553 397,455 262,405 378,343 287,249 334,229 191,313 190))");
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
if (paths.size() != 1)
|
||||||
|
{
|
||||||
|
std::clog << "paths.size() != 1\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mapnik::geometry_type & geom = paths[0];
|
||||||
|
poly_clipper clipped(extent_, geom);
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon);
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {
|
||||||
|
geom2.push_vertex(x,y,(mapnik::CommandType)cmd);
|
||||||
|
}
|
||||||
|
std::string expect = expected_+".png";
|
||||||
|
std::string actual = expected_+"_actual.png";
|
||||||
|
if (!mapnik::util::exists(expect))
|
||||||
|
{
|
||||||
|
std::clog << "generating expected image: " << expect << "\n";
|
||||||
|
render(geom2,geom.envelope(),expect);
|
||||||
|
}
|
||||||
|
render(geom2,geom.envelope(),actual);
|
||||||
|
return benchmark::compare_images(actual,expect);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
for ( mapnik::geometry_type & geom : paths)
|
||||||
|
{
|
||||||
|
poly_clipper clipped(extent_, geom);
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
|
||||||
|
// polygon/rect clipping
|
||||||
|
// IN : POLYGON ((155 203, 233 454, 315 340, 421 446, 463 324, 559 466, 665 253, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 155 203),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249 334, 229 191, 313 190))
|
||||||
|
// RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106))
|
||||||
|
// OUT (expected)
|
||||||
|
// POLYGON ((181 286.6666666666667, 233 454, 315 340, 421 446, 463 324, 559 466, 631 321.3207547169811, 631 234.38686131386862, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 181 238.24444444444444, 181 286.6666666666667),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249 334, 229 191, 313 190))
|
||||||
|
|
||||||
|
mapnik::box2d<double> clipping_box(181,106,631,470);
|
||||||
|
std::string filename_("./benchmark/data/polygon.wkt");
|
||||||
|
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
|
||||||
|
if (!in.is_open())
|
||||||
|
throw std::runtime_error("could not open: '" + filename_ + "'");
|
||||||
|
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
|
||||||
|
(std::istreambuf_iterator<char>()) );
|
||||||
|
{
|
||||||
|
test1 test_runner(params,wkt_in,clipping_box);
|
||||||
|
run(test_runner,"clipping polygon with agg");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test2 test_runner(params,wkt_in,clipping_box);
|
||||||
|
run(test_runner,"clipping polygon with clipper");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test3 test_runner(params,wkt_in,clipping_box);
|
||||||
|
run(test_runner,"clipping polygon with boost");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
79
benchmark/test_polygon_clipping_rendering.cpp
Normal file
79
benchmark/test_polygon_clipping_rendering.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/load_map.hpp>
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/agg_renderer.hpp>
|
||||||
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string xml_;
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params,
|
||||||
|
std::string const& xml,
|
||||||
|
mapnik::box2d<double> const& extent)
|
||||||
|
: test_case(params),
|
||||||
|
xml_(xml),
|
||||||
|
extent_(extent)
|
||||||
|
{}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::Map m(256,256);
|
||||||
|
mapnik::load_map(m,xml_);
|
||||||
|
m.zoom_to_box(extent_);
|
||||||
|
mapnik::image_32 im(m.width(),m.height());
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||||
|
ren.apply();
|
||||||
|
//mapnik::save_to_file(im,"test.png");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
mapnik::Map m(256,256);
|
||||||
|
mapnik::load_map(m,xml_);
|
||||||
|
m.zoom_to_box(extent_);
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
mapnik::image_32 im(m.width(),m.height());
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
||||||
|
mapnik::box2d<double> z1(-20037508.3428,-8317435.0606,20037508.3428,18399242.7298);
|
||||||
|
// bbox for 16/10491/22911.png
|
||||||
|
mapnik::box2d<double> z16(-13622912.929097254,6026906.8062295765,-13621689.93664469,6028129.79868214);
|
||||||
|
{
|
||||||
|
test test_runner(params,
|
||||||
|
"benchmark/data/polygon_rendering_clip.xml",
|
||||||
|
z1);
|
||||||
|
run(test_runner,"polygon clip render z1");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test test_runner(params,
|
||||||
|
"benchmark/data/polygon_rendering_no_clip.xml",
|
||||||
|
z1);
|
||||||
|
run(test_runner,"polygon noclip render z1");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test test_runner(params,
|
||||||
|
"benchmark/data/polygon_rendering_clip.xml",
|
||||||
|
z16);
|
||||||
|
run(test_runner,"polygon clip render z16");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
test test_runner(params,
|
||||||
|
"benchmark/data/polygon_rendering_no_clip.xml",
|
||||||
|
z16);
|
||||||
|
run(test_runner,"polygon noclip render z16");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
96
benchmark/test_proj_transform1.cpp
Normal file
96
benchmark/test_proj_transform1.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
#include <mapnik/projection.hpp>
|
||||||
|
#include <mapnik/proj_transform.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string src_;
|
||||||
|
std::string dest_;
|
||||||
|
mapnik::box2d<double> from_;
|
||||||
|
mapnik::box2d<double> to_;
|
||||||
|
bool defer_proj4_init_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params,
|
||||||
|
std::string const& src,
|
||||||
|
std::string const& dest,
|
||||||
|
mapnik::box2d<double> const& from,
|
||||||
|
mapnik::box2d<double> const& to,
|
||||||
|
bool defer_proj)
|
||||||
|
: test_case(params),
|
||||||
|
src_(src),
|
||||||
|
dest_(dest),
|
||||||
|
from_(from),
|
||||||
|
to_(to),
|
||||||
|
defer_proj4_init_(defer_proj) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::projection src(src_,defer_proj4_init_);
|
||||||
|
mapnik::projection dest(dest_,defer_proj4_init_);
|
||||||
|
mapnik::proj_transform tr(src,dest);
|
||||||
|
mapnik::box2d<double> bbox = from_;
|
||||||
|
if (!tr.forward(bbox)) return false;
|
||||||
|
return ((std::fabs(bbox.minx() - to_.minx()) < .5) &&
|
||||||
|
(std::fabs(bbox.maxx() - to_.maxx()) < .5) &&
|
||||||
|
(std::fabs(bbox.miny() - to_.miny()) < .5) &&
|
||||||
|
(std::fabs(bbox.maxy() - to_.maxy()) < .5)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
for (int i=-180;i<180;i=i+5)
|
||||||
|
{
|
||||||
|
for (int j=-85;j<85;j=j+5)
|
||||||
|
{
|
||||||
|
mapnik::projection src(src_,defer_proj4_init_);
|
||||||
|
mapnik::projection dest(dest_,defer_proj4_init_);
|
||||||
|
mapnik::proj_transform tr(src,dest);
|
||||||
|
mapnik::box2d<double> box(i,j,i,j);
|
||||||
|
if (!tr.forward(box)) throw std::runtime_error("could not transform coords");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// echo -180 -60 | cs2cs -f "%.10f" +init=epsg:4326 +to +init=epsg:3857
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
mapnik::box2d<double> from(-180,-80,180,80);
|
||||||
|
mapnik::box2d<double> to(-20037508.3427892476,-15538711.0963092316,20037508.3427892476,15538711.0963092316);
|
||||||
|
std::string from_str("+init=epsg:4326");
|
||||||
|
std::string to_str("+init=epsg:3857");
|
||||||
|
std::string from_str2("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
|
||||||
|
std::string to_str2("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over");
|
||||||
|
test test_runner(params,
|
||||||
|
from_str,
|
||||||
|
to_str,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
true);
|
||||||
|
run(test_runner,"lonlat->merc epsg");
|
||||||
|
test test_runner2(params,
|
||||||
|
from_str2,
|
||||||
|
to_str2,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
true);
|
||||||
|
run(test_runner2,"lonlat->merc literal");
|
||||||
|
test test_runner3(params,
|
||||||
|
to_str,
|
||||||
|
from_str,
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
true);
|
||||||
|
run(test_runner3,"merc->lonlat epsg");
|
||||||
|
test test_runner4(params,
|
||||||
|
to_str2,
|
||||||
|
from_str2,
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
true);
|
||||||
|
return run(test_runner4,"merc->lonlat literal");
|
||||||
|
}
|
100
benchmark/test_rendering.cpp
Normal file
100
benchmark/test_rendering.cpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/load_map.hpp>
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/agg_renderer.hpp>
|
||||||
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string xml_;
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
mapnik::value_integer width_;
|
||||||
|
mapnik::value_integer height_;
|
||||||
|
std::string preview_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
xml_(),
|
||||||
|
extent_(),
|
||||||
|
width_(*params.get<mapnik::value_integer>("width",256)),
|
||||||
|
height_(*params.get<mapnik::value_integer>("height",256)),
|
||||||
|
preview_(*params.get<std::string>("preview",""))
|
||||||
|
{
|
||||||
|
boost::optional<std::string> map = params.get<std::string>("map");
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("please provide a --map=<path to xml> arg");
|
||||||
|
}
|
||||||
|
xml_ = *map;
|
||||||
|
|
||||||
|
boost::optional<std::string> ext = params.get<std::string>("extent");
|
||||||
|
if (ext && !ext->empty())
|
||||||
|
{
|
||||||
|
if (!extent_.from_string(*ext))
|
||||||
|
throw std::runtime_error("could not parse `extent` string" + *ext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("please provide a --extent=<minx,miny,maxx,maxy> arg");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::Map m(width_,height_);
|
||||||
|
mapnik::load_map(m,xml_,true);
|
||||||
|
m.zoom_to_box(extent_);
|
||||||
|
mapnik::image_32 im(m.width(),m.height());
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||||
|
ren.apply();
|
||||||
|
if (!preview_.empty()) mapnik::save_to_file(im,preview_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
mapnik::Map m(width_,height_);
|
||||||
|
mapnik::load_map(m,xml_);
|
||||||
|
m.zoom_to_box(extent_);
|
||||||
|
for (unsigned i=0;i<iterations_;++i)
|
||||||
|
{
|
||||||
|
mapnik::image_32 im(m.width(),m.height());
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
boost::optional<std::string> name = params.get<std::string>("name");
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
std::clog << "please provide a name for this test\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bool success = mapnik::freetype_engine::register_fonts("./fonts", true);
|
||||||
|
if (!success) {
|
||||||
|
std::clog << "warning, did not register any new fonts!\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
||||||
|
{
|
||||||
|
test test_runner(params);
|
||||||
|
run(test_runner,*name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
|
std::clog << ex.what() << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
29
benchmark/test_to_bool.cpp
Normal file
29
benchmark/test_to_bool.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/util/conversions.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string value_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
value_("true") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
mapnik::util::string2bool(value_.data(),value_.data()+value_.size(),result);
|
||||||
|
if (!result) return result;
|
||||||
|
mapnik::util::string2bool(value_,result);
|
||||||
|
return (result == true);
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
bool result = false;
|
||||||
|
mapnik::util::string2bool(value_,result);
|
||||||
|
mapnik::util::string2bool(value_.data(),value_.data()+value_.size(),result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"string->bool")
|
31
benchmark/test_to_double.cpp
Normal file
31
benchmark/test_to_double.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/util/conversions.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string value_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
value_("1.23456789") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
double result = 0;
|
||||||
|
if (!mapnik::util::string2double(value_.data(),value_.data()+value_.size(),result)) return false;
|
||||||
|
if (result != 1.23456789) return false;
|
||||||
|
result = 0;
|
||||||
|
if (!mapnik::util::string2double(value_,result)) return false;
|
||||||
|
if (result != 1.23456789) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
double result = 0;
|
||||||
|
mapnik::util::string2double(value_,result);
|
||||||
|
mapnik::util::string2double(value_.data(),value_.data()+value_.size(),result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"string->double")
|
31
benchmark/test_to_int.cpp
Normal file
31
benchmark/test_to_int.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/util/conversions.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string value_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
value_("123456789") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::value_integer result = 0;
|
||||||
|
if (!mapnik::util::string2int(value_.data(),value_.data()+value_.size(),result)) return false;
|
||||||
|
if (result != 123456789) return false;
|
||||||
|
result = 0;
|
||||||
|
if (!mapnik::util::string2int(value_,result)) return false;
|
||||||
|
if (result != 123456789) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
mapnik::value_integer result = 0;
|
||||||
|
mapnik::util::string2int(value_,result);
|
||||||
|
mapnik::util::string2int(value_.data(),value_.data()+value_.size(),result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"string->int")
|
27
benchmark/test_to_string1.cpp
Normal file
27
benchmark/test_to_string1.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/util/conversions.hpp>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
double value_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
value_(-0.1234) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
mapnik::util::to_string(s,value_);
|
||||||
|
return (s == "-0.1234");
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
out.clear();
|
||||||
|
mapnik::util::to_string(out,value_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"to_string double->string")
|
28
benchmark/test_to_string2.cpp
Normal file
28
benchmark/test_to_string2.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
double value_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
value_(-0.1234) {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << value_;
|
||||||
|
return (s.str() == "-0.1234");
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
std::ostringstream s;
|
||||||
|
s << value_;
|
||||||
|
out = s.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK(test,"ostringstream double->string")
|
107
benchmark/test_utf_encoding.cpp
Normal file
107
benchmark/test_utf_encoding.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <mapnik/value.hpp>
|
||||||
|
#include <boost/locale.hpp>
|
||||||
|
#ifndef __linux__
|
||||||
|
#include <codecvt>
|
||||||
|
|
||||||
|
class test : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string utf8_;
|
||||||
|
public:
|
||||||
|
test(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
utf8_(u8"שלום") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
|
||||||
|
std::u32string utf32 = utf32conv.from_bytes(utf8_);
|
||||||
|
if (utf32.size() != 4) return false;
|
||||||
|
if (utf32[0] != 0x5e9 &&
|
||||||
|
utf32[1] != 0x5dc &&
|
||||||
|
utf32[2] != 0x5d5 &&
|
||||||
|
utf32[3] != 0x5dd) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::u32string utf32;
|
||||||
|
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
utf32 = utf32conv.from_bytes(utf8_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class test2 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string utf8_;
|
||||||
|
public:
|
||||||
|
test2(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
utf8_(u8"שלום") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
||||||
|
if (utf32.size() != 4) return false;
|
||||||
|
if (utf32[0] != 0x5e9 &&
|
||||||
|
utf32[1] != 0x5dc &&
|
||||||
|
utf32[2] != 0x5d5 &&
|
||||||
|
utf32[3] != 0x5dd) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
std::u32string utf32;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class test3 : public benchmark::test_case
|
||||||
|
{
|
||||||
|
std::string utf8_;
|
||||||
|
public:
|
||||||
|
test3(mapnik::parameters const& params)
|
||||||
|
: test_case(params),
|
||||||
|
utf8_(u8"שלום") {}
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
mapnik::transcoder tr_("utf-8");
|
||||||
|
mapnik::value_unicode_string utf32 = tr_.transcode(utf8_.data(),utf8_.size());
|
||||||
|
//std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
|
||||||
|
if (utf32.length() != 4) return false;
|
||||||
|
if (utf32[0] != 0x5e9 &&
|
||||||
|
utf32[1] != 0x5dc &&
|
||||||
|
utf32[2] != 0x5d5 &&
|
||||||
|
utf32[3] != 0x5dd) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
mapnik::transcoder tr_("utf-8");
|
||||||
|
mapnik::value_unicode_string utf32;
|
||||||
|
for (std::size_t i=0;i<iterations_;++i) {
|
||||||
|
utf32 = tr_.transcode(utf8_.data(),utf8_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
benchmark::handle_args(argc,argv,params);
|
||||||
|
#ifndef __linux__
|
||||||
|
test test_runner(params);
|
||||||
|
run(test_runner,"utf encode std::codecvt");
|
||||||
|
#else
|
||||||
|
std::clog << "skipping 'utf encode std::codecvt' test since <codecvt> is not supported on __linux__\n";
|
||||||
|
#endif
|
||||||
|
test2 test_runner2(params);
|
||||||
|
run(test_runner2,"utf encode boost::locale");
|
||||||
|
test3 test_runner3(params);
|
||||||
|
return run(test_runner3,"utf encode ICU");
|
||||||
|
}
|
|
@ -3,8 +3,8 @@ import random
|
||||||
|
|
||||||
im = mapnik.Image(256,256)
|
im = mapnik.Image(256,256)
|
||||||
|
|
||||||
for x in range(im.width()):
|
for x in xrange(0,im.width()):
|
||||||
for y in range(im.height()):
|
for y in xrange(0,im.height()):
|
||||||
r = int(random.random() * 255)
|
r = int(random.random() * 255)
|
||||||
g = random.random() * 255
|
g = random.random() * 255
|
||||||
b = random.random() * 255
|
b = random.random() * 255
|
||||||
|
|
160
bin/build.py
Normal file
160
bin/build.py
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
#
|
||||||
|
# This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Artem Pavlenko
|
||||||
|
#
|
||||||
|
# Mapnik 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
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from copy import copy
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
config_env = env.Clone()
|
||||||
|
|
||||||
|
config_variables = '''#!/bin/bash
|
||||||
|
|
||||||
|
## variables
|
||||||
|
|
||||||
|
CONFIG_PREFIX="$( cd "$( dirname $( dirname "$0" ))" && pwd )"
|
||||||
|
|
||||||
|
CONFIG_MAPNIK_VERSION_STRING='%(version_string)s'
|
||||||
|
CONFIG_MAPNIK_VERSION='%(version)s'
|
||||||
|
CONFIG_GIT_REVISION='%(git_revision)s'
|
||||||
|
CONFIG_GIT_DESCRIBE='%(git_describe)s'
|
||||||
|
CONFIG_FONTS="%(fonts)s"
|
||||||
|
CONFIG_INPUT_PLUGINS="%(input_plugins)s"
|
||||||
|
CONFIG_MAPNIK_DEFINES='%(defines)s'
|
||||||
|
CONFIG_MAPNIK_LIBNAME='%(mapnik_libname)s'
|
||||||
|
CONFIG_MAPNIK_LIBPATH="%(mapnik_libpath)s"
|
||||||
|
CONFIG_DEP_LIBS='%(dep_libs)s'
|
||||||
|
CONFIG_MAPNIK_LDFLAGS="%(ldflags)s"
|
||||||
|
CONFIG_MAPNIK_INCLUDE="${CONFIG_PREFIX}/include -I${CONFIG_PREFIX}/include/mapnik/agg"
|
||||||
|
CONFIG_DEP_INCLUDES="%(dep_includes)s"
|
||||||
|
CONFIG_CXXFLAGS="%(cxxflags)s"
|
||||||
|
CONFIG_CXX='%(cxx)s'
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
def write_config(configuration,template,config_file):
|
||||||
|
template = open(template,'r').read()
|
||||||
|
open(config_file,'w').write(config_variables % configuration + template)
|
||||||
|
try:
|
||||||
|
os.chmod(config_file,0755)
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
cxxflags = ' '.join(config_env['LIBMAPNIK_CXXFLAGS'])
|
||||||
|
|
||||||
|
defines = ' '.join(config_env['LIBMAPNIK_DEFINES'])
|
||||||
|
|
||||||
|
dep_includes = ''.join([' -I%s' % i for i in config_env['CPPPATH'] if not i.startswith('#')])
|
||||||
|
|
||||||
|
dep_includes += ' '
|
||||||
|
|
||||||
|
if config_env['HAS_CAIRO']:
|
||||||
|
dep_includes += ''.join([' -I%s' % i for i in env['CAIRO_CPPPATHS'] if not i.startswith('#')])
|
||||||
|
|
||||||
|
ldflags = ''.join([' -L%s' % i for i in config_env['LIBPATH'] if not i.startswith('#')])
|
||||||
|
ldflags += config_env['LIBMAPNIK_LINKFLAGS']
|
||||||
|
|
||||||
|
dep_libs = ''.join([' -l%s' % i for i in env['LIBMAPNIK_LIBS']])
|
||||||
|
|
||||||
|
# remove local agg from public linking
|
||||||
|
dep_libs = dep_libs.replace('-lagg','')
|
||||||
|
|
||||||
|
git_revision = 'unknown'
|
||||||
|
git_describe = 'unknown'
|
||||||
|
# special GIT_REVISION/GIT_DESCRIBE files present only for official releases
|
||||||
|
# where the git directory metadata is stripped
|
||||||
|
# more info: https://github.com/mapnik/mapnik/wiki/MapnikReleaseSteps
|
||||||
|
revision_release_file = '../../GIT_REVISION'
|
||||||
|
if os.path.exists(revision_release_file):
|
||||||
|
git_revision = open(revision_release_file,'r').read()
|
||||||
|
else:
|
||||||
|
git_cmd = "git rev-list --max-count=1 HEAD"
|
||||||
|
stdin, stderr = Popen(git_cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
|
if not stderr:
|
||||||
|
git_revision = stdin.strip()
|
||||||
|
|
||||||
|
describe_release_file = '../../GIT_DESCRIBE'
|
||||||
|
if os.path.exists(describe_release_file):
|
||||||
|
git_describe = open(describe_release_file,'r').read()
|
||||||
|
else:
|
||||||
|
git_cmd = "git describe"
|
||||||
|
stdin, stderr = Popen(git_cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
|
if not stderr:
|
||||||
|
git_describe = stdin.strip()
|
||||||
|
|
||||||
|
# for fonts and input plugins we should try
|
||||||
|
# to store the relative path, if feasible
|
||||||
|
fontspath = config_env['MAPNIK_FONTS']
|
||||||
|
lib_root = os.path.join(config_env['PREFIX'], config_env['LIBDIR_SCHEMA'])
|
||||||
|
if lib_root in fontspath:
|
||||||
|
fontspath = "${CONFIG_PREFIX}/" + os.path.relpath(fontspath,config_env['PREFIX'])
|
||||||
|
inputpluginspath = config_env['MAPNIK_INPUT_PLUGINS']
|
||||||
|
if lib_root in inputpluginspath:
|
||||||
|
inputpluginspath = "${CONFIG_PREFIX}/" + os.path.relpath(inputpluginspath,config_env['PREFIX'])
|
||||||
|
|
||||||
|
lib_path = "${CONFIG_PREFIX}/" + config_env['LIBDIR_SCHEMA']
|
||||||
|
|
||||||
|
configuration = {
|
||||||
|
"git_revision": git_revision,
|
||||||
|
"git_describe": git_describe,
|
||||||
|
"version_string": config_env['MAPNIK_VERSION_STRING'],
|
||||||
|
"version": config_env['MAPNIK_VERSION'],
|
||||||
|
"mapnik_libname": env['MAPNIK_NAME'],
|
||||||
|
"mapnik_libpath": lib_path,
|
||||||
|
"ldflags": ldflags,
|
||||||
|
"dep_libs": dep_libs,
|
||||||
|
"dep_includes": dep_includes,
|
||||||
|
"fonts": fontspath,
|
||||||
|
"input_plugins": inputpluginspath,
|
||||||
|
"defines":defines,
|
||||||
|
"cxxflags":cxxflags,
|
||||||
|
"cxx":env['CXX']
|
||||||
|
}
|
||||||
|
|
||||||
|
## if we are statically linking depedencies
|
||||||
|
## then they do not need to be reported in ldflags
|
||||||
|
#if env['RUNTIME_LINK'] == 'static':
|
||||||
|
# configuration['ldflags'] = ''
|
||||||
|
# configuration['dep_libs'] = ''
|
||||||
|
|
||||||
|
template = 'mapnik-config.template.sh'
|
||||||
|
config_file = 'mapnik-config'
|
||||||
|
source = config_file
|
||||||
|
write_config(configuration,template,config_file)
|
||||||
|
target_path = os.path.normpath(os.path.join(config_env['INSTALL_PREFIX'],'bin'))
|
||||||
|
full_target = os.path.join(target_path,config_file)
|
||||||
|
|
||||||
|
Depends(full_target, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
||||||
|
if 'install' in COMMAND_LINE_TARGETS:
|
||||||
|
# we must add 'install' catch here because otherwise
|
||||||
|
# custom command will be run when not installing
|
||||||
|
env.Alias('install',full_target)
|
||||||
|
|
||||||
|
env.Command(full_target, config_file,
|
||||||
|
[
|
||||||
|
Copy("$TARGET","$SOURCE"),
|
||||||
|
Chmod("$TARGET", 0755),
|
||||||
|
])
|
||||||
|
|
||||||
|
config_env['create_uninstall_target'](env,os.path.join(target_path,config_file))
|
139
bin/mapnik-config.template.sh
Executable file
139
bin/mapnik-config.template.sh
Executable file
|
@ -0,0 +1,139 @@
|
||||||
|
|
||||||
|
## program below
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
cat <<EOF
|
||||||
|
Usage: mapnik-config [OPTION]
|
||||||
|
|
||||||
|
Known values for OPTION are:
|
||||||
|
|
||||||
|
-h --help display this help and exit
|
||||||
|
-v --version version information (MAPNIK_VERSION_STRING)
|
||||||
|
--version-number version number (MAPNIK_VERSION) (new in 2.2.0)
|
||||||
|
--git-revision git hash from "git rev-list --max-count=1 HEAD"
|
||||||
|
--git-describe git decribe output (new in 2.2.0)
|
||||||
|
--fonts default fonts directory
|
||||||
|
--input-plugins default input plugins directory
|
||||||
|
--defines pre-processor defines for Mapnik build (new in 2.2.0)
|
||||||
|
--prefix Mapnik prefix [default $CONFIG_PREFIX]
|
||||||
|
--lib-name Mapnik library name
|
||||||
|
--libs library linking information
|
||||||
|
--dep-libs library linking information for Mapnik dependencies
|
||||||
|
--ldflags library paths (-L) information
|
||||||
|
--includes include paths (-I) for Mapnik headers (new in 2.2.0)
|
||||||
|
--dep-includes include paths (-I) for Mapnik dependencies (new in 2.2.0)
|
||||||
|
--cxxflags c++ compiler flags and pre-processor defines (new in 2.2.0)
|
||||||
|
--cflags all include paths, compiler flags, and pre-processor defines (for back-compatibility)
|
||||||
|
--cxx c++ compiler used to build mapnik (new in 2.2.0)
|
||||||
|
--all-flags all compile and link flags (new in 2.2.0)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
echoerr() { echo "$@" 1>&2; }
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
usage 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case "$1" in
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
|
||||||
|
--help)
|
||||||
|
usage 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h)
|
||||||
|
usage 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v)
|
||||||
|
echo ${CONFIG_MAPNIK_VERSION_STRING}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--version)
|
||||||
|
echo ${CONFIG_MAPNIK_VERSION_STRING}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--version-number)
|
||||||
|
echo ${CONFIG_MAPNIK_VERSION}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--git-revision)
|
||||||
|
echo ${CONFIG_GIT_REVISION}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--git-describe)
|
||||||
|
echo ${CONFIG_GIT_DESCRIBE}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--fonts)
|
||||||
|
echo ${CONFIG_FONTS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--input-plugins)
|
||||||
|
echo ${CONFIG_INPUT_PLUGINS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--defines)
|
||||||
|
echo ${CONFIG_MAPNIK_DEFINES}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--prefix)
|
||||||
|
echo ${CONFIG_PREFIX}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--lib-name)
|
||||||
|
echo ${CONFIG_MAPNIK_LIBNAME}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--libs)
|
||||||
|
echo -L${CONFIG_MAPNIK_LIBPATH} -l${CONFIG_MAPNIK_LIBNAME}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--dep-libs)
|
||||||
|
echo ${CONFIG_DEP_LIBS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--ldflags)
|
||||||
|
echo ${CONFIG_MAPNIK_LDFLAGS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--includes)
|
||||||
|
echo -I${CONFIG_MAPNIK_INCLUDE}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--dep-includes)
|
||||||
|
echo ${CONFIG_DEP_INCLUDES}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--cxxflags)
|
||||||
|
echo ${CONFIG_CXXFLAGS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--cflags)
|
||||||
|
echo -I${CONFIG_MAPNIK_INCLUDE} ${CONFIG_DEP_INCLUDES} ${CONFIG_MAPNIK_DEFINES} ${CONFIG_CXXFLAGS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--cxx)
|
||||||
|
echo ${CONFIG_CXX}
|
||||||
|
;;
|
||||||
|
|
||||||
|
--all-flags)
|
||||||
|
echo -I${CONFIG_MAPNIK_INCLUDE} ${CONFIG_DEP_INCLUDES} ${CONFIG_MAPNIK_DEFINES} ${CONFIG_CXXFLAGS} -L${CONFIG_MAPNIK_LIBPATH} -l${CONFIG_MAPNIK_LIBNAME} ${CONFIG_MAPNIK_LDFLAGS} ${CONFIG_DEP_LIBS}
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
# push to stderr any invalid options
|
||||||
|
echo "unknown option $1" 1>&2;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
49
bindings/python/boost_std_shared_shim.hpp
Normal file
49
bindings/python/boost_std_shared_shim.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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_PYTHON_BOOST_STD_SHARED_SHIM
|
||||||
|
#define MAPNIK_PYTHON_BOOST_STD_SHARED_SHIM
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if BOOST_VERSION < 105300 || defined BOOST_NO_CXX11_SMART_PTR
|
||||||
|
|
||||||
|
// https://github.com/mapnik/mapnik/issues/2022
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
template<class T> const T* get_pointer(std::shared_ptr<T> const& p)
|
||||||
|
{
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> T* get_pointer(std::shared_ptr<T>& p)
|
||||||
|
{
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MAPNIK_PYTHON_BOOST_STD_SHARED_SHIM
|
206
bindings/python/build.py
Normal file
206
bindings/python/build.py
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
#
|
||||||
|
# This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Artem Pavlenko
|
||||||
|
#
|
||||||
|
# Mapnik 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
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import os, re, sys, glob
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
|
||||||
|
def call(cmd, silent=True):
|
||||||
|
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
|
if not stderr:
|
||||||
|
return stdin.strip()
|
||||||
|
elif not silent:
|
||||||
|
print stderr
|
||||||
|
|
||||||
|
def run_2to3(*args,**kwargs):
|
||||||
|
call('2to3 -w %s' % os.path.dirname(kwargs['target'][0].path))
|
||||||
|
|
||||||
|
def is_py3():
|
||||||
|
return 'True' in os.popen('''%s -c "import sys as s;s.stdout.write(str(s.version_info[0] == 3))"''' % env['PYTHON']).read().strip()
|
||||||
|
|
||||||
|
|
||||||
|
prefix = env['PREFIX']
|
||||||
|
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + env['MAPNIK_NAME'])
|
||||||
|
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
|
||||||
|
|
||||||
|
py_env = env.Clone()
|
||||||
|
py_env.Append(CPPPATH = env['PYTHON_INCLUDES'])
|
||||||
|
|
||||||
|
py_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
|
||||||
|
|
||||||
|
py_env['LIBS'] = [env['MAPNIK_NAME'],env['BOOST_PYTHON_LIB']]
|
||||||
|
|
||||||
|
link_all_libs = env['LINKING'] == 'static' or env['RUNTIME_LINK'] == 'static' or (env['PLATFORM'] == 'Darwin' and not env['PYTHON_DYNAMIC_LOOKUP'])
|
||||||
|
|
||||||
|
if link_all_libs:
|
||||||
|
py_env.AppendUnique(LIBS=env['LIBMAPNIK_LIBS'])
|
||||||
|
|
||||||
|
# even though boost_thread is no longer used in mapnik core
|
||||||
|
# we need to link in for boost_python to avoid missing symbol: _ZN5boost6detail12get_tss_dataEPKv / boost::detail::get_tss_data
|
||||||
|
py_env.AppendUnique(LIBS = 'boost_thread%s' % env['BOOST_APPEND'])
|
||||||
|
|
||||||
|
# note: on linux -lrt must be linked after thread to avoid: undefined symbol: clock_gettime
|
||||||
|
if env['RUNTIME_LINK'] == 'static' and env['PLATFORM'] == 'Linux':
|
||||||
|
py_env.AppendUnique(LIBS='rt')
|
||||||
|
|
||||||
|
# TODO - do solaris/fedora need direct linking too?
|
||||||
|
if env['PLATFORM'] == 'Darwin':
|
||||||
|
##### Python linking on OS X is tricky ###
|
||||||
|
# Confounding problems are:
|
||||||
|
# 1) likelyhood of multiple python installs of the same major.minor version
|
||||||
|
# because apple supplies python built-in and many users may have installed
|
||||||
|
# further versions using macports
|
||||||
|
# 2) boost python directly links to a python version
|
||||||
|
# 3) the below will directly link _mapnik.so to a python version
|
||||||
|
# 4) _mapnik.so must link to the same python lib as boost_python.dylib otherwise
|
||||||
|
# python will Abort with a Version Mismatch error.
|
||||||
|
# See https://github.com/mapnik/mapnik/issues/453 for the seeds of a better approach
|
||||||
|
# for now we offer control over method of direct linking...
|
||||||
|
# The default below is to link against the python dylib in the form of
|
||||||
|
#/path/to/Python.framework/Python instead of -lpython
|
||||||
|
|
||||||
|
# http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/ld.1.html
|
||||||
|
|
||||||
|
if env['PYTHON_DYNAMIC_LOOKUP']:
|
||||||
|
python_link_flag = '-undefined dynamic_lookup'
|
||||||
|
elif env['FRAMEWORK_PYTHON']:
|
||||||
|
if env['FRAMEWORK_SEARCH_PATH']:
|
||||||
|
# if the user has supplied a custom root path to search for
|
||||||
|
# a given Python framework, then use that to direct the linker
|
||||||
|
python_link_flag = '-F%s -framework Python -Z' % env['FRAMEWORK_SEARCH_PATH']
|
||||||
|
else:
|
||||||
|
# otherwise be as explicit as possible for linking to the same Framework
|
||||||
|
# as the executable we are building with (or is pointed to by the PYTHON variable)
|
||||||
|
# otherwise we may accidentally link against either:
|
||||||
|
# /System/Library/Frameworks/Python.framework/Python/Versions/
|
||||||
|
# or
|
||||||
|
# /Library/Frameworks/Python.framework/Python/Versions/
|
||||||
|
# See: https://github.com/mapnik/mapnik/issues/380
|
||||||
|
link_prefix = env['PYTHON_SYS_PREFIX']
|
||||||
|
if '.framework' in link_prefix:
|
||||||
|
python_link_flag = '-F%s -framework Python -Z' % os.path.dirname(link_prefix.split('.')[0])
|
||||||
|
elif '/System' in link_prefix:
|
||||||
|
python_link_flag = '-F/System/Library/Frameworks/ -framework Python -Z'
|
||||||
|
else:
|
||||||
|
# should we fall back to -lpython here?
|
||||||
|
python_link_flag = '-F/ -framework Python'
|
||||||
|
# if we are not linking to a framework then use the *nix standard approach
|
||||||
|
else:
|
||||||
|
# TODO - do we need to pass -L/?
|
||||||
|
python_link_flag = '-lpython%s' % env['PYTHON_VERSION']
|
||||||
|
|
||||||
|
elif env['PLATFORM'] == 'SunOS':
|
||||||
|
# make sure to explicitly link mapnik.so against
|
||||||
|
# libmapnik in its installed location
|
||||||
|
python_link_flag = '-R%s' % env['MAPNIK_LIB_BASE']
|
||||||
|
else:
|
||||||
|
# all other platforms we don't directly link python
|
||||||
|
python_link_flag = ''
|
||||||
|
|
||||||
|
paths = '''
|
||||||
|
"""Configuration paths of Mapnik fonts and input plugins (auto-generated by SCons)."""
|
||||||
|
|
||||||
|
from os.path import normpath,join,dirname
|
||||||
|
|
||||||
|
mapniklibpath = '%s'
|
||||||
|
mapniklibpath = normpath(join(dirname(__file__),mapniklibpath))
|
||||||
|
'''
|
||||||
|
|
||||||
|
paths += "inputpluginspath = join(mapniklibpath,'input')\n"
|
||||||
|
|
||||||
|
if env['SYSTEM_FONTS']:
|
||||||
|
paths += "fontscollectionpath = normpath('%s')\n" % env['SYSTEM_FONTS']
|
||||||
|
else:
|
||||||
|
paths += "fontscollectionpath = join(mapniklibpath,'fonts')\n"
|
||||||
|
|
||||||
|
paths += "__all__ = [mapniklibpath,inputpluginspath,fontscollectionpath]\n"
|
||||||
|
|
||||||
|
if not os.path.exists(env['MAPNIK_NAME']):
|
||||||
|
os.mkdir(env['MAPNIK_NAME'])
|
||||||
|
|
||||||
|
file('mapnik/paths.py','w').write(paths % (env['MAPNIK_LIB_DIR']))
|
||||||
|
|
||||||
|
# force open perms temporarily so that `sudo scons install`
|
||||||
|
# does not later break simple non-install non-sudo rebuild
|
||||||
|
try:
|
||||||
|
os.chmod('mapnik/paths.py',0666)
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
# install the shared object beside the module directory
|
||||||
|
sources = glob.glob('*.cpp')
|
||||||
|
|
||||||
|
if 'install' in COMMAND_LINE_TARGETS:
|
||||||
|
# install the core mapnik python files, including '__init__.py'
|
||||||
|
init_files = glob.glob('mapnik/*.py')
|
||||||
|
if 'mapnik/paths.py' in init_files:
|
||||||
|
init_files.remove('mapnik/paths.py')
|
||||||
|
init_module = env.Install(target_path, init_files)
|
||||||
|
env.Alias(target='install', source=init_module)
|
||||||
|
# install mapnik2 module which redirects to mapnik and issues DeprecatedWarning
|
||||||
|
init_mapnik2 = env.Install(target_path_deprecated, 'mapnik2/__init__.py')
|
||||||
|
env.Alias(target='install', source=init_mapnik2)
|
||||||
|
|
||||||
|
# fix perms and install the custom generated 'paths.py'
|
||||||
|
targetp = os.path.join(target_path,'paths.py')
|
||||||
|
env.Alias("install", targetp)
|
||||||
|
# use env.Command rather than env.Install
|
||||||
|
# to enable setting proper perms on `paths.py`
|
||||||
|
env.Command( targetp, 'mapnik/paths.py',
|
||||||
|
[
|
||||||
|
Copy("$TARGET","$SOURCE"),
|
||||||
|
Chmod("$TARGET", 0644),
|
||||||
|
])
|
||||||
|
|
||||||
|
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||||
|
if env['HAS_CAIRO']:
|
||||||
|
py_env.Append(CPPPATH = env['CAIRO_CPPPATHS'])
|
||||||
|
py_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
||||||
|
if link_all_libs:
|
||||||
|
py_env.Append(LIBS=env['CAIRO_ALL_LIBS'])
|
||||||
|
|
||||||
|
if env['HAS_PYCAIRO']:
|
||||||
|
py_env.ParseConfig('pkg-config --cflags pycairo')
|
||||||
|
py_env.Append(CPPDEFINES = '-DHAVE_PYCAIRO')
|
||||||
|
|
||||||
|
py_env.Append(LINKFLAGS=python_link_flag)
|
||||||
|
_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LDMODULEPREFIX='', LDMODULESUFFIX='.so')
|
||||||
|
|
||||||
|
Depends(_mapnik, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
||||||
|
if env['PLATFORM'] == 'SunOS' and env['PYTHON_IS_64BIT']:
|
||||||
|
# http://mail.python.org/pipermail/python-dev/2006-August/068528.html
|
||||||
|
cxx_module_path = os.path.join(target_path,'64')
|
||||||
|
else:
|
||||||
|
cxx_module_path = target_path
|
||||||
|
|
||||||
|
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||||
|
pymapniklib = env.Install(cxx_module_path,_mapnik)
|
||||||
|
py_env.Alias(target='install',source=pymapniklib)
|
||||||
|
if 'install' in COMMAND_LINE_TARGETS:
|
||||||
|
if is_py3():
|
||||||
|
env.AddPostAction(pymapniklib, run_2to3)
|
||||||
|
|
||||||
|
|
||||||
|
env['create_uninstall_target'](env, target_path)
|
||||||
|
env['create_uninstall_target'](env, target_path_deprecated)
|
||||||
|
|
1074
bindings/python/mapnik/__init__.py
Normal file
1074
bindings/python/mapnik/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
1027
bindings/python/mapnik/printing.py
Normal file
1027
bindings/python/mapnik/printing.py
Normal file
File diff suppressed because it is too large
Load diff
27
bindings/python/mapnik2/__init__.py
Normal file
27
bindings/python/mapnik2/__init__.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#
|
||||||
|
# This file is part of Mapnik (C++/Python mapping toolkit)
|
||||||
|
# Copyright (C) 2011 Artem Pavlenko
|
||||||
|
#
|
||||||
|
# Mapnik is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
# mapnik2 module (Deprecated)
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
from mapnik import *
|
||||||
|
warnings.simplefilter("default")
|
||||||
|
msg=""" mapnik2 module has been deprecated,
|
||||||
|
please use 'import mapnik' """
|
||||||
|
warnings.warn(msg, DeprecationWarning)
|
98
bindings/python/mapnik_color.cpp
Normal file
98
bindings/python/mapnik_color.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
//mapnik
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
using mapnik::color;
|
||||||
|
|
||||||
|
struct color_pickle_suite : boost::python::pickle_suite
|
||||||
|
{
|
||||||
|
static boost::python::tuple
|
||||||
|
getinitargs(const color& c)
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
return boost::python::make_tuple(c.red(),c.green(),c.blue(),c.alpha());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void export_color ()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<color>("Color", init<int,int,int,int>(
|
||||||
|
( arg("r"), arg("g"), arg("b"), arg("a") ),
|
||||||
|
"Creates a new color from its RGB components\n"
|
||||||
|
"and an alpha value.\n"
|
||||||
|
"All values between 0 and 255.\n")
|
||||||
|
)
|
||||||
|
.def(init<int,int,int>(
|
||||||
|
( arg("r"), arg("g"), arg("b") ),
|
||||||
|
"Creates a new color from its RGB components.\n"
|
||||||
|
"All values between 0 and 255.\n")
|
||||||
|
)
|
||||||
|
.def(init<std::string>(
|
||||||
|
( arg("color_string") ),
|
||||||
|
"Creates a new color from its CSS string representation.\n"
|
||||||
|
"The string may be a CSS color name (e.g. 'blue')\n"
|
||||||
|
"or a hex color string (e.g. '#0000ff').\n")
|
||||||
|
)
|
||||||
|
.add_property("r",
|
||||||
|
&color::red,
|
||||||
|
&color::set_red,
|
||||||
|
"Gets or sets the red component.\n"
|
||||||
|
"The value is between 0 and 255.\n")
|
||||||
|
.add_property("g",
|
||||||
|
&color::green,
|
||||||
|
&color::set_green,
|
||||||
|
"Gets or sets the green component.\n"
|
||||||
|
"The value is between 0 and 255.\n")
|
||||||
|
.add_property("b",
|
||||||
|
&color::blue,
|
||||||
|
&color::set_blue,
|
||||||
|
"Gets or sets the blue component.\n"
|
||||||
|
"The value is between 0 and 255.\n")
|
||||||
|
.add_property("a",
|
||||||
|
&color::alpha,
|
||||||
|
&color::set_alpha,
|
||||||
|
"Gets or sets the alpha component.\n"
|
||||||
|
"The value is between 0 and 255.\n")
|
||||||
|
.def(self == self)
|
||||||
|
.def(self != self)
|
||||||
|
.def_pickle(color_pickle_suite())
|
||||||
|
.def("__str__",&color::to_string)
|
||||||
|
.def("packed",&color::rgba)
|
||||||
|
.def("to_hex_string",&color::to_hex_string,
|
||||||
|
"Returns the hexadecimal representation of this color.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> c = Color('blue')\n"
|
||||||
|
">>> c.to_hex_string()\n"
|
||||||
|
"'#0000ff'\n")
|
||||||
|
;
|
||||||
|
}
|
66
bindings/python/mapnik_coord.cpp
Normal file
66
bindings/python/mapnik_coord.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/coord.hpp>
|
||||||
|
|
||||||
|
using mapnik::coord;
|
||||||
|
|
||||||
|
struct coord_pickle_suite : boost::python::pickle_suite
|
||||||
|
{
|
||||||
|
static boost::python::tuple
|
||||||
|
getinitargs(const coord<double,2>& c)
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
return boost::python::make_tuple(c.x,c.y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void export_coord()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<coord<double,2> >("Coord",init<double, double>(
|
||||||
|
// class docstring is in mapnik/__init__.py, class _Coord
|
||||||
|
(arg("x"), arg("y")),
|
||||||
|
"Constructs a new point with the given coordinates.\n")
|
||||||
|
)
|
||||||
|
.def_pickle(coord_pickle_suite())
|
||||||
|
.def_readwrite("x", &coord<double,2>::x,
|
||||||
|
"Gets or sets the x/lon coordinate of the point.\n")
|
||||||
|
.def_readwrite("y", &coord<double,2>::y,
|
||||||
|
"Gets or sets the y/lat coordinate of the point.\n")
|
||||||
|
.def(self == self) // __eq__
|
||||||
|
.def(self + self) // __add__
|
||||||
|
.def(self + float())
|
||||||
|
.def(float() + self)
|
||||||
|
.def(self - self) // __sub__
|
||||||
|
.def(self - float())
|
||||||
|
.def(self * float()) //__mult__
|
||||||
|
.def(float() * self)
|
||||||
|
.def(self / float()) // __div__
|
||||||
|
;
|
||||||
|
}
|
207
bindings/python/mapnik_datasource.cpp
Normal file
207
bindings/python/mapnik_datasource.cpp
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
#include <mapnik/feature_layer_desc.hpp>
|
||||||
|
#include <mapnik/memory_datasource.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
using mapnik::datasource;
|
||||||
|
using mapnik::memory_datasource;
|
||||||
|
using mapnik::layer_descriptor;
|
||||||
|
using mapnik::attribute_descriptor;
|
||||||
|
using mapnik::parameters;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
//user-friendly wrapper that uses Python dictionary
|
||||||
|
using namespace boost::python;
|
||||||
|
std::shared_ptr<mapnik::datasource> create_datasource(dict const& d)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
boost::python::list keys=d.keys();
|
||||||
|
for (int i=0; i < len(keys); ++i)
|
||||||
|
{
|
||||||
|
std::string key = extract<std::string>(keys[i]);
|
||||||
|
object obj = d[key];
|
||||||
|
if (PyUnicode_Check(obj.ptr()))
|
||||||
|
{
|
||||||
|
PyObject* temp = PyUnicode_AsUTF8String(obj.ptr());
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
char* c_str = PyBytes_AsString(temp);
|
||||||
|
#else
|
||||||
|
char* c_str = PyString_AsString(temp);
|
||||||
|
#endif
|
||||||
|
params[key] = std::string(c_str);
|
||||||
|
Py_DecRef(temp);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extract<std::string> ex0(obj);
|
||||||
|
extract<mapnik::value_integer> ex1(obj);
|
||||||
|
extract<double> ex2(obj);
|
||||||
|
if (ex0.check())
|
||||||
|
{
|
||||||
|
params[key] = ex0();
|
||||||
|
}
|
||||||
|
else if (ex1.check())
|
||||||
|
{
|
||||||
|
params[key] = ex1();
|
||||||
|
}
|
||||||
|
else if (ex2.check())
|
||||||
|
{
|
||||||
|
params[key] = ex2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapnik::datasource_cache::instance().create(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::dict describe(std::shared_ptr<mapnik::datasource> const& ds)
|
||||||
|
{
|
||||||
|
boost::python::dict description;
|
||||||
|
mapnik::layer_descriptor ld = ds->get_descriptor();
|
||||||
|
description["type"] = ds->type();
|
||||||
|
description["name"] = ld.get_name();
|
||||||
|
description["geometry_type"] = ds->get_geometry_type();
|
||||||
|
description["encoding"] = ld.get_encoding();
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::list fields(std::shared_ptr<mapnik::datasource> const& ds)
|
||||||
|
{
|
||||||
|
boost::python::list flds;
|
||||||
|
if (ds)
|
||||||
|
{
|
||||||
|
layer_descriptor ld = ds->get_descriptor();
|
||||||
|
std::vector<attribute_descriptor> const& desc_ar = ld.get_descriptors();
|
||||||
|
std::vector<attribute_descriptor>::const_iterator it = desc_ar.begin();
|
||||||
|
std::vector<attribute_descriptor>::const_iterator end = desc_ar.end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
flds.append(it->get_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flds;
|
||||||
|
}
|
||||||
|
boost::python::list field_types(std::shared_ptr<mapnik::datasource> const& ds)
|
||||||
|
{
|
||||||
|
boost::python::list fld_types;
|
||||||
|
if (ds)
|
||||||
|
{
|
||||||
|
layer_descriptor ld = ds->get_descriptor();
|
||||||
|
std::vector<attribute_descriptor> const& desc_ar = ld.get_descriptors();
|
||||||
|
std::vector<attribute_descriptor>::const_iterator it = desc_ar.begin();
|
||||||
|
std::vector<attribute_descriptor>::const_iterator end = desc_ar.end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
unsigned type = it->get_type();
|
||||||
|
if (type == mapnik::Integer)
|
||||||
|
// this crashes, so send back strings instead
|
||||||
|
//fld_types.append(boost::python::object(boost::python::handle<>(&PyInt_Type)));
|
||||||
|
fld_types.append(boost::python::str("int"));
|
||||||
|
else if (type == mapnik::Float)
|
||||||
|
fld_types.append(boost::python::str("float"));
|
||||||
|
else if (type == mapnik::Double)
|
||||||
|
fld_types.append(boost::python::str("float"));
|
||||||
|
else if (type == mapnik::String)
|
||||||
|
fld_types.append(boost::python::str("str"));
|
||||||
|
else if (type == mapnik::Boolean)
|
||||||
|
fld_types.append(boost::python::str("bool"));
|
||||||
|
else if (type == mapnik::Geometry)
|
||||||
|
fld_types.append(boost::python::str("geometry"));
|
||||||
|
else if (type == mapnik::Object)
|
||||||
|
fld_types.append(boost::python::str("object"));
|
||||||
|
else
|
||||||
|
fld_types.append(boost::python::str("unknown"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fld_types;
|
||||||
|
}}
|
||||||
|
|
||||||
|
mapnik::parameters const& (mapnik::datasource::*params_const)() const = &mapnik::datasource::params;
|
||||||
|
|
||||||
|
|
||||||
|
void export_datasource()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
enum_<mapnik::datasource::datasource_t>("DataType")
|
||||||
|
.value("Vector",mapnik::datasource::Vector)
|
||||||
|
.value("Raster",mapnik::datasource::Raster)
|
||||||
|
;
|
||||||
|
|
||||||
|
enum_<mapnik::datasource::geometry_t>("DataGeometryType")
|
||||||
|
.value("Point",mapnik::datasource::Point)
|
||||||
|
.value("LineString",mapnik::datasource::LineString)
|
||||||
|
.value("Polygon",mapnik::datasource::Polygon)
|
||||||
|
.value("Collection",mapnik::datasource::Collection)
|
||||||
|
;
|
||||||
|
|
||||||
|
class_<datasource,std::shared_ptr<datasource>,
|
||||||
|
boost::noncopyable>("Datasource",no_init)
|
||||||
|
.def("type",&datasource::type)
|
||||||
|
.def("geometry_type",&datasource::get_geometry_type)
|
||||||
|
.def("describe",&describe)
|
||||||
|
.def("envelope",&datasource::envelope)
|
||||||
|
.def("features",&datasource::features)
|
||||||
|
.def("fields",&fields)
|
||||||
|
.def("field_types",&field_types)
|
||||||
|
.def("features_at_point",&datasource::features_at_point, (arg("coord"),arg("tolerance")=0))
|
||||||
|
.def("params",make_function(params_const,return_value_policy<copy_const_reference>()),
|
||||||
|
"The configuration parameters of the data source. "
|
||||||
|
"These vary depending on the type of data source.")
|
||||||
|
.def(self == self)
|
||||||
|
;
|
||||||
|
|
||||||
|
def("CreateDatasource",&create_datasource);
|
||||||
|
|
||||||
|
class_<memory_datasource,
|
||||||
|
bases<datasource>, std::shared_ptr<memory_datasource>,
|
||||||
|
boost::noncopyable>("MemoryDatasourceBase", init<parameters>())
|
||||||
|
.def("add_feature",&memory_datasource::push,
|
||||||
|
"Adds a Feature:\n"
|
||||||
|
">>> ms = MemoryDatasource()\n"
|
||||||
|
">>> feature = Feature(1)\n"
|
||||||
|
">>> ms.add_feature(Feature(1))\n")
|
||||||
|
.def("num_features",&memory_datasource::size)
|
||||||
|
;
|
||||||
|
|
||||||
|
implicitly_convertible<std::shared_ptr<memory_datasource>,std::shared_ptr<datasource> >();
|
||||||
|
}
|
98
bindings/python/mapnik_datasource_cache.cpp
Normal file
98
bindings/python/mapnik_datasource_cache.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
|
#include <mapnik/params.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
std::shared_ptr<mapnik::datasource> create_datasource(const dict& d)
|
||||||
|
{
|
||||||
|
mapnik::parameters params;
|
||||||
|
boost::python::list keys=d.keys();
|
||||||
|
for (int i=0; i<len(keys); ++i)
|
||||||
|
{
|
||||||
|
std::string key = extract<std::string>(keys[i]);
|
||||||
|
object obj = d[key];
|
||||||
|
extract<std::string> ex0(obj);
|
||||||
|
extract<mapnik::value_integer> ex1(obj);
|
||||||
|
extract<double> ex2(obj);
|
||||||
|
|
||||||
|
if (ex0.check())
|
||||||
|
{
|
||||||
|
params[key] = ex0();
|
||||||
|
}
|
||||||
|
else if (ex1.check())
|
||||||
|
{
|
||||||
|
params[key] = ex1();
|
||||||
|
}
|
||||||
|
else if (ex2.check())
|
||||||
|
{
|
||||||
|
params[key] = ex2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapnik::datasource_cache::instance().create(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_datasources(std::string const& path)
|
||||||
|
{
|
||||||
|
mapnik::datasource_cache::instance().register_datasources(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> plugin_names()
|
||||||
|
{
|
||||||
|
return mapnik::datasource_cache::instance().plugin_names();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string plugin_directories()
|
||||||
|
{
|
||||||
|
return mapnik::datasource_cache::instance().plugin_directories();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_datasource_cache()
|
||||||
|
{
|
||||||
|
using mapnik::datasource_cache;
|
||||||
|
class_<datasource_cache,
|
||||||
|
boost::noncopyable>("DatasourceCache",no_init)
|
||||||
|
.def("create",&create_datasource)
|
||||||
|
.staticmethod("create")
|
||||||
|
.def("register_datasources",®ister_datasources)
|
||||||
|
.staticmethod("register_datasources")
|
||||||
|
.def("plugin_names",&plugin_names)
|
||||||
|
.staticmethod("plugin_names")
|
||||||
|
.def("plugin_directories",&plugin_directories)
|
||||||
|
.staticmethod("plugin_directories")
|
||||||
|
;
|
||||||
|
}
|
88
bindings/python/mapnik_enumeration.hpp
Normal file
88
bindings/python/mapnik_enumeration.hpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* 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_PYTHON_BINDING_ENUMERATION_INCLUDED
|
||||||
|
#define MAPNIK_PYTHON_BINDING_ENUMERATION_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/python/converter/registered.hpp> // for registered
|
||||||
|
#include <boost/python/enum.hpp> // for enum_
|
||||||
|
#include <boost/python/implicit.hpp> // for implicitly_convertible
|
||||||
|
#include <boost/python/to_python_converter.hpp>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
template <typename EnumWrapper>
|
||||||
|
class enumeration_ :
|
||||||
|
public boost::python::enum_<typename EnumWrapper::native_type>
|
||||||
|
{
|
||||||
|
// some short cuts
|
||||||
|
using base_type = boost::python::enum_<typename EnumWrapper::native_type>;
|
||||||
|
using native_type = typename EnumWrapper::native_type;
|
||||||
|
public:
|
||||||
|
enumeration_() :
|
||||||
|
base_type( EnumWrapper::get_name().c_str() )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
enumeration_(const char * python_alias) :
|
||||||
|
base_type( python_alias )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
enumeration_(const char * python_alias, const char * doc) :
|
||||||
|
base_type( python_alias, doc )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct converter
|
||||||
|
{
|
||||||
|
static PyObject* convert(EnumWrapper const& v)
|
||||||
|
{
|
||||||
|
// Redirect conversion to a static method of our base class's
|
||||||
|
// base class. A free template converter will not work because
|
||||||
|
// the base_type::base typedef is protected.
|
||||||
|
// Lets hope MSVC agrees that this is legal C++
|
||||||
|
using namespace boost::python::converter;
|
||||||
|
return base_type::base::to_python(
|
||||||
|
registered<native_type>::converters.m_class_object
|
||||||
|
, static_cast<long>( v ));
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
boost::python::implicitly_convertible<native_type, EnumWrapper>();
|
||||||
|
boost::python::to_python_converter<EnumWrapper, converter >();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < EnumWrapper::MAX; ++i)
|
||||||
|
{
|
||||||
|
// Register the strings already defined for this enum.
|
||||||
|
base_type::value( EnumWrapper::get_string( i ), native_type( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace mapnik
|
||||||
|
|
||||||
|
#endif // MAPNIK_PYTHON_BINDING_ENUMERATION_INCLUDED
|
45
bindings/python/mapnik_enumeration_wrapper_converter.hpp
Normal file
45
bindings/python/mapnik_enumeration_wrapper_converter.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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_BINDINGS_PYTHON_ENUMERATION_WRAPPPER
|
||||||
|
#define MAPNIK_BINDINGS_PYTHON_ENUMERATION_WRAPPPER
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost { namespace python {
|
||||||
|
|
||||||
|
struct mapnik_enumeration_wrapper_to_python
|
||||||
|
{
|
||||||
|
static PyObject* convert(mapnik::enumeration_wrapper const& v)
|
||||||
|
{
|
||||||
|
return ::PyLong_FromLongLong(v.value); // FIXME: this is a temp hack!!
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // MAPNIK_BINDINGS_PYTHON_ENUMERATION_WRAPPPER
|
297
bindings/python/mapnik_envelope.cpp
Normal file
297
bindings/python/mapnik_envelope.cpp
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
#include <mapnik/value_error.hpp>
|
||||||
|
|
||||||
|
using mapnik::coord;
|
||||||
|
using mapnik::box2d;
|
||||||
|
|
||||||
|
struct envelope_pickle_suite : boost::python::pickle_suite
|
||||||
|
{
|
||||||
|
static boost::python::tuple
|
||||||
|
getinitargs(const box2d<double>& e)
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
return boost::python::make_tuple(e.minx(),e.miny(),e.maxx(),e.maxy());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
box2d<double> from_string(std::string const& s)
|
||||||
|
{
|
||||||
|
box2d<double> bbox;
|
||||||
|
bool success = bbox.from_string(s);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
return bbox;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Could not parse bbox from string: '" << s << "'";
|
||||||
|
throw mapnik::value_error(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//define overloads here
|
||||||
|
void (box2d<double>::*width_p1)(double) = &box2d<double>::width;
|
||||||
|
double (box2d<double>::*width_p2)() const = &box2d<double>::width;
|
||||||
|
|
||||||
|
void (box2d<double>::*height_p1)(double) = &box2d<double>::height;
|
||||||
|
double (box2d<double>::*height_p2)() const = &box2d<double>::height;
|
||||||
|
|
||||||
|
void (box2d<double>::*expand_to_include_p1)(double,double) = &box2d<double>::expand_to_include;
|
||||||
|
void (box2d<double>::*expand_to_include_p2)(coord<double,2> const& ) = &box2d<double>::expand_to_include;
|
||||||
|
void (box2d<double>::*expand_to_include_p3)(box2d<double> const& ) = &box2d<double>::expand_to_include;
|
||||||
|
|
||||||
|
bool (box2d<double>::*contains_p1)(double,double) const = &box2d<double>::contains;
|
||||||
|
bool (box2d<double>::*contains_p2)(coord<double,2> const&) const = &box2d<double>::contains;
|
||||||
|
bool (box2d<double>::*contains_p3)(box2d<double> const&) const = &box2d<double>::contains;
|
||||||
|
|
||||||
|
//intersects
|
||||||
|
bool (box2d<double>::*intersects_p1)(double,double) const = &box2d<double>::intersects;
|
||||||
|
bool (box2d<double>::*intersects_p2)(coord<double,2> const&) const = &box2d<double>::intersects;
|
||||||
|
bool (box2d<double>::*intersects_p3)(box2d<double> const&) const = &box2d<double>::intersects;
|
||||||
|
|
||||||
|
// intersect
|
||||||
|
box2d<double> (box2d<double>::*intersect)(box2d<double> const&) const = &box2d<double>::intersect;
|
||||||
|
|
||||||
|
// re_center
|
||||||
|
void (box2d<double>::*re_center_p1)(double,double) = &box2d<double>::re_center;
|
||||||
|
void (box2d<double>::*re_center_p2)(coord<double,2> const& ) = &box2d<double>::re_center;
|
||||||
|
|
||||||
|
// clip
|
||||||
|
void (box2d<double>::*clip)(box2d<double> const&) = &box2d<double>::clip;
|
||||||
|
|
||||||
|
// pad
|
||||||
|
void (box2d<double>::*pad)(double) = &box2d<double>::pad;
|
||||||
|
|
||||||
|
// deepcopy
|
||||||
|
box2d<double> box2d_deepcopy(box2d<double> & obj, boost::python::dict memo)
|
||||||
|
{
|
||||||
|
// FIXME::ignore memo for now
|
||||||
|
box2d<double> result(obj);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_envelope()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<box2d<double> >("Box2d",
|
||||||
|
// class docstring is in mapnik/__init__.py, class _Coord
|
||||||
|
init<double,double,double,double>(
|
||||||
|
(arg("minx"),arg("miny"),arg("maxx"),arg("maxy")),
|
||||||
|
"Constructs a new envelope from the coordinates\n"
|
||||||
|
"of its lower left and upper right corner points.\n"))
|
||||||
|
.def(init<>("Equivalent to Box2d(0, 0, -1, -1).\n"))
|
||||||
|
.def(init<const coord<double,2>&, const coord<double,2>&>(
|
||||||
|
(arg("ll"),arg("ur")),
|
||||||
|
"Equivalent to Box2d(ll.x, ll.y, ur.x, ur.y).\n"))
|
||||||
|
.def("from_string",from_string)
|
||||||
|
.staticmethod("from_string")
|
||||||
|
.add_property("minx", &box2d<double>::minx,
|
||||||
|
"X coordinate for the lower left corner")
|
||||||
|
.add_property("miny", &box2d<double>::miny,
|
||||||
|
"Y coordinate for the lower left corner")
|
||||||
|
.add_property("maxx", &box2d<double>::maxx,
|
||||||
|
"X coordinate for the upper right corner")
|
||||||
|
.add_property("maxy", &box2d<double>::maxy,
|
||||||
|
"Y coordinate for the upper right corner")
|
||||||
|
.def("center", &box2d<double>::center,
|
||||||
|
"Returns the coordinates of the center of the bounding box.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.center()\n"
|
||||||
|
"Coord(50, 50)\n")
|
||||||
|
.def("center", re_center_p1,
|
||||||
|
(arg("x"), arg("y")),
|
||||||
|
"Moves the envelope so that the given coordinates become its new center.\n"
|
||||||
|
"The width and the height are preserved.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.center(60, 60)\n"
|
||||||
|
">>> e.center()\n"
|
||||||
|
"Coord(60.0,60.0)\n"
|
||||||
|
">>> (e.width(), e.height())\n"
|
||||||
|
"(100.0, 100.0)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(10.0, 10.0, 110.0, 110.0)\n"
|
||||||
|
)
|
||||||
|
.def("center", re_center_p2,
|
||||||
|
(arg("Coord")),
|
||||||
|
"Moves the envelope so that the given coordinates become its new center.\n"
|
||||||
|
"The width and the height are preserved.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.center(Coord60, 60)\n"
|
||||||
|
">>> e.center()\n"
|
||||||
|
"Coord(60.0,60.0)\n"
|
||||||
|
">>> (e.width(), e.height())\n"
|
||||||
|
"(100.0, 100.0)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(10.0, 10.0, 110.0, 110.0)\n"
|
||||||
|
)
|
||||||
|
.def("clip", clip,
|
||||||
|
(arg("other")),
|
||||||
|
"Clip the envelope based on the bounds of another envelope.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> c = Box2d(-50, -50, 50, 50)\n"
|
||||||
|
">>> e.clip(c)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(0.0,0.0,50.0,50.0\n"
|
||||||
|
)
|
||||||
|
.def("pad", pad,
|
||||||
|
(arg("padding")),
|
||||||
|
"Pad the envelope based on a padding value.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.pad(10)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(-10.0,-10.0,110.0,110.0\n"
|
||||||
|
)
|
||||||
|
.def("width", width_p1,
|
||||||
|
(arg("new_width")),
|
||||||
|
"Sets the width to new_width of the envelope preserving its center.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.width(120)\n"
|
||||||
|
">>> e.center()\n"
|
||||||
|
"Coord(50.0,50.0)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(-10.0, 0.0, 110.0, 100.0)\n"
|
||||||
|
)
|
||||||
|
.def("width", width_p2,
|
||||||
|
"Returns the width of this envelope.\n"
|
||||||
|
)
|
||||||
|
.def("height", height_p1,
|
||||||
|
(arg("new_height")),
|
||||||
|
"Sets the height to new_height of the envelope preserving its center.\n"
|
||||||
|
"\n "
|
||||||
|
"Example:\n"
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.height(120)\n"
|
||||||
|
">>> e.center()\n"
|
||||||
|
"Coord(50.0,50.0)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(0.0, -10.0, 100.0, 110.0)\n"
|
||||||
|
)
|
||||||
|
.def("height", height_p2,
|
||||||
|
"Returns the height of this envelope.\n"
|
||||||
|
)
|
||||||
|
.def("expand_to_include",expand_to_include_p1,
|
||||||
|
(arg("x"),arg("y")),
|
||||||
|
"Expands this envelope to include the point given by x and y.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n",
|
||||||
|
">>> e = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e.expand_to_include(110, 110)\n"
|
||||||
|
">>> e\n"
|
||||||
|
"Box2d(0.0, 00.0, 110.0, 110.0)\n"
|
||||||
|
)
|
||||||
|
.def("expand_to_include",expand_to_include_p2,
|
||||||
|
(arg("p")),
|
||||||
|
"Equivalent to expand_to_include(p.x, p.y)\n"
|
||||||
|
)
|
||||||
|
.def("expand_to_include",expand_to_include_p3,
|
||||||
|
(arg("other")),
|
||||||
|
"Equivalent to:\n"
|
||||||
|
" expand_to_include(other.minx, other.miny)\n"
|
||||||
|
" expand_to_include(other.maxx, other.maxy)\n"
|
||||||
|
)
|
||||||
|
.def("contains",contains_p1,
|
||||||
|
(arg("x"),arg("y")),
|
||||||
|
"Returns True iff this envelope contains the point\n"
|
||||||
|
"given by x and y.\n"
|
||||||
|
)
|
||||||
|
.def("contains",contains_p2,
|
||||||
|
(arg("p")),
|
||||||
|
"Equivalent to contains(p.x, p.y)\n"
|
||||||
|
)
|
||||||
|
.def("contains",contains_p3,
|
||||||
|
(arg("other")),
|
||||||
|
"Equivalent to:\n"
|
||||||
|
" contains(other.minx, other.miny) and contains(other.maxx, other.maxy)\n"
|
||||||
|
)
|
||||||
|
.def("intersects",intersects_p1,
|
||||||
|
(arg("x"),arg("y")),
|
||||||
|
"Returns True iff this envelope intersects the point\n"
|
||||||
|
"given by x and y.\n"
|
||||||
|
"\n"
|
||||||
|
"Note: For points, intersection is equivalent\n"
|
||||||
|
"to containment, i.e. the following holds:\n"
|
||||||
|
" e.contains(x, y) == e.intersects(x, y)\n"
|
||||||
|
)
|
||||||
|
.def("intersects",intersects_p2,
|
||||||
|
(arg("p")),
|
||||||
|
"Equivalent to contains(p.x, p.y)\n")
|
||||||
|
.def("intersects",intersects_p3,
|
||||||
|
(arg("other")),
|
||||||
|
"Returns True iff this envelope intersects the other envelope,\n"
|
||||||
|
"This relationship is symmetric."
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> e1 = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e2 = Box2d(50, 50, 150, 150)\n"
|
||||||
|
">>> e1.intersects(e2)\n"
|
||||||
|
"True\n"
|
||||||
|
">>> e1.contains(e2)\n"
|
||||||
|
"False\n"
|
||||||
|
)
|
||||||
|
.def("intersect",intersect,
|
||||||
|
(arg("other")),
|
||||||
|
"Returns the overlap of this envelope and the other envelope\n"
|
||||||
|
"as a new envelope.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> e1 = Box2d(0, 0, 100, 100)\n"
|
||||||
|
">>> e2 = Box2d(50, 50, 150, 150)\n"
|
||||||
|
">>> e1.intersect(e2)\n"
|
||||||
|
"Box2d(50.0, 50.0, 100.0, 100.0)\n"
|
||||||
|
)
|
||||||
|
.def(self == self) // __eq__
|
||||||
|
.def(self != self) // __neq__
|
||||||
|
.def(self + self) // __add__
|
||||||
|
.def(self * float()) // __mult__
|
||||||
|
.def(float() * self)
|
||||||
|
.def(self / float()) // __div__
|
||||||
|
.def("__getitem__",&box2d<double>::operator[])
|
||||||
|
.def("valid",&box2d<double>::valid)
|
||||||
|
.def_pickle(envelope_pickle_suite())
|
||||||
|
.def("__deepcopy__", &box2d_deepcopy)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
105
bindings/python/mapnik_expression.cpp
Normal file
105
bindings/python/mapnik_expression.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
#include "python_to_value.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <mapnik/util/variant.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/expression.hpp>
|
||||||
|
#include <mapnik/expression_string.hpp>
|
||||||
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
|
#include <mapnik/parse_path.hpp>
|
||||||
|
#include <mapnik/value.hpp>
|
||||||
|
|
||||||
|
using mapnik::expression_ptr;
|
||||||
|
using mapnik::parse_expression;
|
||||||
|
using mapnik::to_expression_string;
|
||||||
|
using mapnik::path_expression_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
// expression
|
||||||
|
expression_ptr parse_expression_(std::string const& wkt)
|
||||||
|
{
|
||||||
|
return parse_expression(wkt,"utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expression_to_string_(mapnik::expr_node const& expr)
|
||||||
|
{
|
||||||
|
return mapnik::to_expression_string(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::value expression_evaluate_(mapnik::expr_node const& expr, mapnik::feature_impl const& f, boost::python::dict const& d)
|
||||||
|
{
|
||||||
|
// will be auto-converted to proper python type by `mapnik_value_to_python`
|
||||||
|
return mapnik::util::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value,mapnik::attributes>(f,mapnik::dict2attr(d)),expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expression_evaluate_to_bool_(mapnik::expr_node const& expr, mapnik::feature_impl const& f, boost::python::dict const& d)
|
||||||
|
{
|
||||||
|
return mapnik::util::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value,mapnik::attributes>(f,mapnik::dict2attr(d)),expr).to_bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
// path expression
|
||||||
|
path_expression_ptr parse_path_(std::string const& path)
|
||||||
|
{
|
||||||
|
return mapnik::parse_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_to_string_(mapnik::path_expression const& expr)
|
||||||
|
{
|
||||||
|
return mapnik::path_processor_type::to_string(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_evaluate_(mapnik::path_expression const& expr, mapnik::feature_impl const& f)
|
||||||
|
{
|
||||||
|
return mapnik::path_processor_type::evaluate(expr, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_expression()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<mapnik::expr_node ,boost::noncopyable>("Expression",
|
||||||
|
"TODO"
|
||||||
|
"",no_init)
|
||||||
|
.def("evaluate", &expression_evaluate_,(arg("feature"),arg("variables")=boost::python::dict()))
|
||||||
|
.def("to_bool", &expression_evaluate_to_bool_,(arg("feature"),arg("variables")=boost::python::dict()))
|
||||||
|
.def("__str__",&expression_to_string_);
|
||||||
|
;
|
||||||
|
|
||||||
|
def("Expression",&parse_expression_,(arg("expr")),"Expression string");
|
||||||
|
|
||||||
|
class_<mapnik::path_expression ,boost::noncopyable>("PathExpression",
|
||||||
|
"TODO"
|
||||||
|
"",no_init)
|
||||||
|
.def("evaluate", &path_evaluate_) // note: "pass" is a reserved word in Python
|
||||||
|
.def("__str__",&path_to_string_);
|
||||||
|
;
|
||||||
|
|
||||||
|
def("PathExpression",&parse_path_,(arg("expr")),"PathExpression string");
|
||||||
|
}
|
252
bindings/python/mapnik_feature.cpp
Normal file
252
bindings/python/mapnik_feature.cpp
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/python/iterator.hpp>
|
||||||
|
#include <boost/python/call_method.hpp>
|
||||||
|
#include <boost/python/tuple.hpp>
|
||||||
|
#include <boost/python/to_python_converter.hpp>
|
||||||
|
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/feature_factory.hpp>
|
||||||
|
#include <mapnik/feature_kv_iterator.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
#include <mapnik/wkb.hpp>
|
||||||
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
|
#include <mapnik/json/feature_parser.hpp>
|
||||||
|
#include <mapnik/json/feature_generator.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using mapnik::geometry_utils;
|
||||||
|
using mapnik::context_type;
|
||||||
|
using mapnik::context_ptr;
|
||||||
|
using mapnik::feature_kv_iterator;
|
||||||
|
|
||||||
|
mapnik::geometry_type const& (mapnik::feature_impl::*get_geometry_by_const_ref)(std::size_t) const = &mapnik::feature_impl::get_geometry;
|
||||||
|
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::feature_impl::*get_paths_by_const_ref)() const = &mapnik::feature_impl::paths;
|
||||||
|
|
||||||
|
void feature_add_geometries_from_wkb(mapnik::feature_impl & feature, std::string wkb)
|
||||||
|
{
|
||||||
|
bool result = geometry_utils::from_wkb(feature.paths(), wkb.c_str(), wkb.size());
|
||||||
|
if (!result) throw std::runtime_error("Failed to parse WKB");
|
||||||
|
}
|
||||||
|
|
||||||
|
void feature_add_geometries_from_wkt(mapnik::feature_impl & feature, std::string const& wkt)
|
||||||
|
{
|
||||||
|
bool result = mapnik::from_wkt(wkt, feature.paths());
|
||||||
|
if (!result) throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::feature_ptr from_geojson_impl(std::string const& json, mapnik::context_ptr const& ctx)
|
||||||
|
{
|
||||||
|
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
|
||||||
|
if (!mapnik::json::from_geojson(json,*feature))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson feature");
|
||||||
|
}
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string feature_to_geojson(mapnik::feature_impl const& feature)
|
||||||
|
{
|
||||||
|
std::string json;
|
||||||
|
if (!mapnik::json::to_geojson(json,feature))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to generate GeoJSON");
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::value __getitem__(mapnik::feature_impl const& feature, std::string const& name)
|
||||||
|
{
|
||||||
|
return feature.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::value __getitem2__(mapnik::feature_impl const& feature, std::size_t index)
|
||||||
|
{
|
||||||
|
return feature.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __setitem__(mapnik::feature_impl & feature, std::string const& name, mapnik::value const& val)
|
||||||
|
{
|
||||||
|
feature.put_new(name,val);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::dict attributes(mapnik::feature_impl const& f)
|
||||||
|
{
|
||||||
|
boost::python::dict attributes;
|
||||||
|
feature_kv_iterator itr = f.begin();
|
||||||
|
feature_kv_iterator end = f.end();
|
||||||
|
|
||||||
|
for ( ;itr!=end; ++itr)
|
||||||
|
{
|
||||||
|
attributes[std::get<0>(*itr)] = std::get<1>(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
struct unicode_string_from_python_str
|
||||||
|
{
|
||||||
|
unicode_string_from_python_str()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back(
|
||||||
|
&convertible,
|
||||||
|
&construct,
|
||||||
|
boost::python::type_id<mapnik::value_unicode_string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
if (!(
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
PyBytes_Check(obj_ptr)
|
||||||
|
#else
|
||||||
|
PyString_Check(obj_ptr)
|
||||||
|
#endif
|
||||||
|
|| PyUnicode_Check(obj_ptr)))
|
||||||
|
return 0;
|
||||||
|
return obj_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
boost::python::converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
char * value=0;
|
||||||
|
if (PyUnicode_Check(obj_ptr)) {
|
||||||
|
PyObject *encoded = PyUnicode_AsEncodedString(obj_ptr, "utf8", "replace");
|
||||||
|
if (encoded) {
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
value = PyBytes_AsString(encoded);
|
||||||
|
#else
|
||||||
|
value = PyString_AsString(encoded);
|
||||||
|
#endif
|
||||||
|
Py_DecRef(encoded);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
value = PyBytes_AsString(obj_ptr);
|
||||||
|
#else
|
||||||
|
value = PyString_AsString(obj_ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (value == 0) boost::python::throw_error_already_set();
|
||||||
|
void* storage = (
|
||||||
|
(boost::python::converter::rvalue_from_python_storage<mapnik::value_unicode_string>*)
|
||||||
|
data)->storage.bytes;
|
||||||
|
new (storage) mapnik::value_unicode_string(value);
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct value_null_from_python
|
||||||
|
{
|
||||||
|
value_null_from_python()
|
||||||
|
{
|
||||||
|
boost::python::converter::registry::push_back(
|
||||||
|
&convertible,
|
||||||
|
&construct,
|
||||||
|
boost::python::type_id<mapnik::value_null>());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* convertible(PyObject* obj_ptr)
|
||||||
|
{
|
||||||
|
if (obj_ptr == Py_None) return obj_ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void construct(
|
||||||
|
PyObject* obj_ptr,
|
||||||
|
boost::python::converter::rvalue_from_python_stage1_data* data)
|
||||||
|
{
|
||||||
|
if (obj_ptr != Py_None) boost::python::throw_error_already_set();
|
||||||
|
void* storage = (
|
||||||
|
(boost::python::converter::rvalue_from_python_storage<mapnik::value_null>*)
|
||||||
|
data)->storage.bytes;
|
||||||
|
new (storage) mapnik::value_null();
|
||||||
|
data->convertible = storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void export_feature()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
// Python to mapnik::value converters
|
||||||
|
// NOTE: order matters here. For example value_null must be listed before
|
||||||
|
// bool otherwise Py_None will be interpreted as bool (false)
|
||||||
|
implicitly_convertible<mapnik::value_unicode_string,mapnik::value>();
|
||||||
|
implicitly_convertible<mapnik::value_null,mapnik::value>();
|
||||||
|
implicitly_convertible<mapnik::value_integer,mapnik::value>();
|
||||||
|
implicitly_convertible<mapnik::value_double,mapnik::value>();
|
||||||
|
implicitly_convertible<mapnik::value_bool,mapnik::value>();
|
||||||
|
|
||||||
|
// http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/
|
||||||
|
unicode_string_from_python_str();
|
||||||
|
value_null_from_python();
|
||||||
|
|
||||||
|
class_<context_type,context_ptr,boost::noncopyable>
|
||||||
|
("Context",init<>("Default ctor."))
|
||||||
|
.def("push", &context_type::push)
|
||||||
|
;
|
||||||
|
|
||||||
|
class_<mapnik::feature_impl,std::shared_ptr<mapnik::feature_impl>,
|
||||||
|
boost::noncopyable>("Feature",init<context_ptr,mapnik::value_integer>("Default ctor."))
|
||||||
|
.def("id",&mapnik::feature_impl::id)
|
||||||
|
.def("add_geometries_from_wkb", &feature_add_geometries_from_wkb)
|
||||||
|
.def("add_geometries_from_wkt", &feature_add_geometries_from_wkt)
|
||||||
|
.def("add_geometry", &mapnik::feature_impl::add_geometry)
|
||||||
|
.def("num_geometries",&mapnik::feature_impl::num_geometries)
|
||||||
|
.def("get_geometry", make_function(get_geometry_by_const_ref,return_value_policy<reference_existing_object>()))
|
||||||
|
.def("geometries",make_function(get_paths_by_const_ref,return_value_policy<reference_existing_object>()))
|
||||||
|
.def("envelope", &mapnik::feature_impl::envelope)
|
||||||
|
.def("has_key", &mapnik::feature_impl::has_key)
|
||||||
|
.add_property("attributes",&attributes)
|
||||||
|
.def("__setitem__",&__setitem__)
|
||||||
|
.def("__contains__",&__getitem__)
|
||||||
|
.def("__getitem__",&__getitem__)
|
||||||
|
.def("__getitem__",&__getitem2__)
|
||||||
|
.def("__len__", &mapnik::feature_impl::size)
|
||||||
|
.def("context",&mapnik::feature_impl::context)
|
||||||
|
.def("to_geojson",&feature_to_geojson)
|
||||||
|
.def("from_geojson",from_geojson_impl)
|
||||||
|
.staticmethod("from_geojson")
|
||||||
|
;
|
||||||
|
}
|
88
bindings/python/mapnik_featureset.cpp
Normal file
88
bindings/python/mapnik_featureset.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
inline list features(mapnik::featureset_ptr const& itr)
|
||||||
|
{
|
||||||
|
list l;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
mapnik::feature_ptr fp = itr->next();
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l.append(fp);
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object pass_through(object const& o) { return o; }
|
||||||
|
|
||||||
|
inline mapnik::feature_ptr next(mapnik::featureset_ptr const& itr)
|
||||||
|
{
|
||||||
|
mapnik::feature_ptr f = itr->next();
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_StopIteration, "No more features.");
|
||||||
|
boost::python::throw_error_already_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_featureset()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<mapnik::Featureset,std::shared_ptr<mapnik::Featureset>,
|
||||||
|
boost::noncopyable>("Featureset",no_init)
|
||||||
|
.def("__iter__",pass_through)
|
||||||
|
.def("next",next)
|
||||||
|
.add_property("features",features,
|
||||||
|
"The list of features.\n"
|
||||||
|
"\n"
|
||||||
|
"Usage:\n"
|
||||||
|
">>> m.query_map_point(0, 10, 10)\n"
|
||||||
|
"<mapnik._mapnik.Featureset object at 0x1004d2938>\n"
|
||||||
|
">>> fs = m.query_map_point(0, 10, 10)\n"
|
||||||
|
">>> for f in fs.features:\n"
|
||||||
|
">>> print f\n"
|
||||||
|
"<mapnik.Feature object at 0x105e64140>\n"
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
54
bindings/python/mapnik_font_engine.cpp
Normal file
54
bindings/python/mapnik_font_engine.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <mapnik/utils.hpp>
|
||||||
|
|
||||||
|
void export_font_engine()
|
||||||
|
{
|
||||||
|
using mapnik::freetype_engine;
|
||||||
|
using mapnik::singleton;
|
||||||
|
using mapnik::CreateStatic;
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<singleton<freetype_engine,CreateStatic>,boost::noncopyable>("Singleton",no_init)
|
||||||
|
.def("instance",&singleton<freetype_engine,CreateStatic>::instance,
|
||||||
|
return_value_policy<reference_existing_object>())
|
||||||
|
.staticmethod("instance")
|
||||||
|
;
|
||||||
|
|
||||||
|
class_<freetype_engine,bases<singleton<freetype_engine,CreateStatic> >,
|
||||||
|
boost::noncopyable>("FontEngine",no_init)
|
||||||
|
.def("register_font",&freetype_engine::register_font)
|
||||||
|
.def("register_fonts",&freetype_engine::register_fonts)
|
||||||
|
.def("face_names",&freetype_engine::face_names)
|
||||||
|
.staticmethod("register_font")
|
||||||
|
.staticmethod("register_fonts")
|
||||||
|
.staticmethod("face_names")
|
||||||
|
;
|
||||||
|
}
|
58
bindings/python/mapnik_fontset.cpp
Normal file
58
bindings/python/mapnik_fontset.cpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
//mapnik
|
||||||
|
#include <mapnik/font_set.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
using mapnik::font_set;
|
||||||
|
|
||||||
|
void export_fontset ()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
class_<font_set>("FontSet", init<std::string const&>("default fontset constructor")
|
||||||
|
)
|
||||||
|
.add_property("name",
|
||||||
|
make_function(&font_set::get_name,return_value_policy<copy_const_reference>()),
|
||||||
|
&font_set::set_name,
|
||||||
|
"Get/Set the name of the FontSet.\n"
|
||||||
|
)
|
||||||
|
.def("add_face_name",&font_set::add_face_name,
|
||||||
|
(arg("name")),
|
||||||
|
"Add a face-name to the fontset.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> fs = Fontset('book-fonts')\n"
|
||||||
|
">>> fs.add_face_name('DejaVu Sans Book')\n")
|
||||||
|
.add_property("names",make_function
|
||||||
|
(&font_set::get_face_names,
|
||||||
|
return_value_policy<reference_existing_object>()),
|
||||||
|
"List of face names belonging to a FontSet.\n"
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
41
bindings/python/mapnik_gamma_method.cpp
Normal file
41
bindings/python/mapnik_gamma_method.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <mapnik/symbolizer_enumerations.hpp>
|
||||||
|
#include "mapnik_enumeration.hpp"
|
||||||
|
|
||||||
|
void export_gamma_method()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
mapnik::enumeration_<mapnik::gamma_method_e>("gamma_method")
|
||||||
|
.value("POWER", mapnik::GAMMA_POWER)
|
||||||
|
.value("LINEAR",mapnik::GAMMA_LINEAR)
|
||||||
|
.value("NONE", mapnik::GAMMA_NONE)
|
||||||
|
.value("THRESHOLD", mapnik::GAMMA_THRESHOLD)
|
||||||
|
.value("MULTIPLY", mapnik::GAMMA_MULTIPLY)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
36
bindings/python/mapnik_generator_grammars.cpp
Normal file
36
bindings/python/mapnik_generator_grammars.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Artem Pavlenko, Jean-Francois Doyon
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
|
||||||
|
#include <mapnik/json/feature_generator_grammar_impl.hpp>
|
||||||
|
#include <mapnik/json/geometry_generator_grammar_impl.hpp>
|
||||||
|
#include <mapnik/svg/geometry_svg_generator_impl.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using sink_type = std::back_insert_iterator<std::string>;
|
||||||
|
template struct mapnik::json::feature_generator_grammar<sink_type>;
|
||||||
|
template struct mapnik::json::geometry_generator_grammar<sink_type>;
|
||||||
|
template struct mapnik::json::multi_geometry_generator_grammar<sink_type>;
|
||||||
|
template struct mapnik::svg::svg_path_generator<sink_type, mapnik::geometry_type>;
|
||||||
|
template struct mapnik::wkt::wkt_generator<sink_type, mapnik::geometry_type>;
|
||||||
|
template struct mapnik::wkt::wkt_multi_generator<sink_type, mapnik::geometry_container>;
|
276
bindings/python/mapnik_geometry.cpp
Normal file
276
bindings/python/mapnik_geometry.cpp
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
|
||||||
|
#include "boost_std_shared_shim.hpp"
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/python/exception_translator.hpp>
|
||||||
|
#include <boost/python/manage_new_object.hpp>
|
||||||
|
#include <boost/python/iterator.hpp>
|
||||||
|
#include <boost/ptr_container/ptr_vector.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/wkt/wkt_factory.hpp> // from_wkt
|
||||||
|
#include <mapnik/util/geometry_to_wkt.hpp>
|
||||||
|
#include <mapnik/json/geometry_parser.hpp> // from_geojson
|
||||||
|
#include <mapnik/util/geometry_to_geojson.hpp>
|
||||||
|
#include <mapnik/util/geometry_to_svg.hpp>
|
||||||
|
#include <mapnik/wkb.hpp>
|
||||||
|
#include <mapnik/util/geometry_to_wkb.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
mapnik::geometry_type const& getitem_impl(mapnik::geometry_container & p, int key)
|
||||||
|
{
|
||||||
|
if (key >=0 && key < static_cast<int>(p.size()))
|
||||||
|
return p[key];
|
||||||
|
PyErr_SetString(PyExc_IndexError, "Index is out of range");
|
||||||
|
throw boost::python::error_already_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_wkt_impl(mapnik::geometry_container& p, std::string const& wkt)
|
||||||
|
{
|
||||||
|
if (!mapnik::from_wkt(wkt , p))
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_wkb_impl(mapnik::geometry_container& p, std::string const& wkb)
|
||||||
|
{
|
||||||
|
if (!mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size()))
|
||||||
|
throw std::runtime_error("Failed to parse WKB");
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_geojson_impl(mapnik::geometry_container& paths, std::string const& json)
|
||||||
|
{
|
||||||
|
if (!mapnik::json::from_geojson(json, paths))
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<mapnik::geometry_container> from_wkt_impl(std::string const& wkt)
|
||||||
|
{
|
||||||
|
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
|
||||||
|
if (!mapnik::from_wkt(wkt, *paths))
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<mapnik::geometry_container> from_wkb_impl(std::string const& wkb)
|
||||||
|
{
|
||||||
|
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
|
||||||
|
if (!mapnik::geometry_utils::from_wkb(*paths, wkb.c_str(), wkb.size()))
|
||||||
|
throw std::runtime_error("Failed to parse WKB");
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<mapnik::geometry_container> from_geojson_impl(std::string const& json)
|
||||||
|
{
|
||||||
|
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
|
||||||
|
if (!mapnik::json::from_geojson(json, *paths))
|
||||||
|
throw std::runtime_error("Failed to parse geojson geometry");
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::box2d<double> envelope_impl(mapnik::geometry_container & p)
|
||||||
|
{
|
||||||
|
mapnik::box2d<double> b;
|
||||||
|
bool first = true;
|
||||||
|
for (mapnik::geometry_type const& geom : p)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
b = geom.envelope();
|
||||||
|
first=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b.expand_to_include(geom.envelope());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string boost_version()
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* to_wkb(mapnik::geometry_type const& geom, mapnik::util::wkbByteOrder byte_order)
|
||||||
|
{
|
||||||
|
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,byte_order);
|
||||||
|
if (wkb)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
::PyBytes_FromStringAndSize
|
||||||
|
#else
|
||||||
|
::PyString_FromStringAndSize
|
||||||
|
#endif
|
||||||
|
((const char*)wkb->buffer(),wkb->size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* to_wkb2( mapnik::geometry_container const& p, mapnik::util::wkbByteOrder byte_order)
|
||||||
|
{
|
||||||
|
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(p,byte_order);
|
||||||
|
if (wkb)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
::PyBytes_FromStringAndSize
|
||||||
|
#else
|
||||||
|
::PyString_FromStringAndSize
|
||||||
|
#endif
|
||||||
|
((const char*)wkb->buffer(),wkb->size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_wkt(mapnik::geometry_type const& geom)
|
||||||
|
{
|
||||||
|
std::string wkt;
|
||||||
|
if (!mapnik::util::to_wkt(wkt,geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate WKT failed");
|
||||||
|
}
|
||||||
|
return wkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_wkt2(mapnik::geometry_container const& geom)
|
||||||
|
{
|
||||||
|
std::string wkt;
|
||||||
|
if (!mapnik::util::to_wkt(wkt,geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate WKT failed");
|
||||||
|
}
|
||||||
|
return wkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_geojson(mapnik::geometry_type const& geom)
|
||||||
|
{
|
||||||
|
std::string wkt;
|
||||||
|
if (!mapnik::util::to_geojson(wkt,geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate JSON failed");
|
||||||
|
}
|
||||||
|
return wkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_geojson2(mapnik::geometry_container const& geom)
|
||||||
|
{
|
||||||
|
std::string wkt;
|
||||||
|
if (!mapnik::util::to_geojson(wkt,geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate JSON failed");
|
||||||
|
}
|
||||||
|
return wkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_svg(mapnik::geometry_type const& geom)
|
||||||
|
{
|
||||||
|
std::string svg;
|
||||||
|
if (!mapnik::util::to_svg(svg,geom))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate SVG failed");
|
||||||
|
}
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// https://github.com/mapnik/mapnik/issues/1437
|
||||||
|
std::string to_svg2( mapnik::geometry_container const& geom)
|
||||||
|
{
|
||||||
|
std::string svg; // Use Python String directly ?
|
||||||
|
bool result = mapnik::util::to_svg(svg,geom);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Generate WKT failed");
|
||||||
|
}
|
||||||
|
return svg;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
void export_geometry()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
enum_<mapnik::geometry_type::types>("GeometryType")
|
||||||
|
.value("Point",mapnik::geometry_type::types::Point)
|
||||||
|
.value("LineString",mapnik::geometry_type::types::LineString)
|
||||||
|
.value("Polygon",mapnik::geometry_type::types::Polygon)
|
||||||
|
;
|
||||||
|
|
||||||
|
enum_<mapnik::util::wkbByteOrder>("wkbByteOrder")
|
||||||
|
.value("XDR",mapnik::util::wkbXDR)
|
||||||
|
.value("NDR",mapnik::util::wkbNDR)
|
||||||
|
;
|
||||||
|
|
||||||
|
using mapnik::geometry_type;
|
||||||
|
class_<mapnik::geometry_type, std::shared_ptr<mapnik::geometry_type>, boost::noncopyable>("Geometry2d",no_init)
|
||||||
|
.def("envelope",&mapnik::geometry_type::envelope)
|
||||||
|
// .def("__str__",&mapnik::geometry_type::to_string)
|
||||||
|
.def("type",&mapnik::geometry_type::type)
|
||||||
|
.def("to_wkb",&to_wkb)
|
||||||
|
.def("to_wkt",&to_wkt)
|
||||||
|
.def("to_geojson",&to_geojson)
|
||||||
|
.def("to_svg",&to_svg)
|
||||||
|
// TODO add other geometry_type methods
|
||||||
|
;
|
||||||
|
|
||||||
|
class_<mapnik::geometry_container, std::shared_ptr<mapnik::geometry_container>, boost::noncopyable>("Path")
|
||||||
|
.def("__getitem__", getitem_impl,return_value_policy<reference_existing_object>())
|
||||||
|
.def("__len__", &mapnik::geometry_container::size)
|
||||||
|
.def("envelope",envelope_impl)
|
||||||
|
.def("add_wkt",add_wkt_impl)
|
||||||
|
.def("add_wkb",add_wkb_impl)
|
||||||
|
.def("add_geojson",add_geojson_impl)
|
||||||
|
.def("to_wkt",&to_wkt2)
|
||||||
|
//.def("to_svg",&to_svg2)
|
||||||
|
.def("to_wkb",&to_wkb2)
|
||||||
|
.def("from_wkt",from_wkt_impl)
|
||||||
|
.def("from_wkb",from_wkb_impl)
|
||||||
|
.def("from_geojson",from_geojson_impl)
|
||||||
|
.def("to_geojson",&to_geojson2)
|
||||||
|
.staticmethod("from_wkt")
|
||||||
|
.staticmethod("from_wkb")
|
||||||
|
.staticmethod("from_geojson")
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue