Compare commits

...

828 commits

Author SHA1 Message Date
Artem Pavlenko
bb3106d04f
Merge pull request #4480 from mapnik/configure-unbound-variable
Check for if VARS is set (ref #4478)
2024-11-04 18:21:55 +00:00
Artem Pavlenko
8ebd792258 Check for if VARS is set (ref #4478) 2024-11-04 16:39:09 +00:00
Artem Pavlenko
e7a2bacb5d update CHANGELOG for mapnik v4.0.3 release [skip ci] 2024-10-30 08:45:55 +00:00
Artem Pavlenko
05389e3c73 setting up for mapnik v4.0.3 release [skip ci] 2024-10-30 08:44:01 +00:00
Artem Pavlenko
abeace5167
Merge pull request #4479 from mapnik/empty_featureset
Empty featureset
2024-10-29 11:04:26 +00:00
Artem Pavlenko
92b1ea9ceb Commit staged changes 2024-10-29 10:19:22 +00:00
Artem Pavlenko
cd082c5872 Update version to 4.0.3 2024-10-29 09:56:03 +00:00
Artem Pavlenko
c1117a4d33 Empty featureset instead of invalid + bool is_empty(featureset_ptr) 2024-10-29 09:52:35 +00:00
Artem Pavlenko
20b154ae49 Remove 'final' specifier as it was breaking dynamic_cast<invalid_featureset*> in 'is_valid' test when building on macOS arm64
```
Apple clang version 16.0.0 (clang-1600.0.26.3)
Target: arm64-apple-darwin24.0.0
```
Also remove empty dtor as not required
2024-10-28 11:02:08 +00:00
Artem Pavlenko
379261434b Upgrade to SCons v4.8.1 2024-09-09 10:56:17 +01:00
Artem Pavlenko
3d172b94f7 Unit tests - fix #endif statement (via @bgardner-noggin) 2024-09-04 09:39:11 +01:00
Artem Pavlenko
5f327ff3c8 update CHANGELOG for mapnik v4.0.2 release [skip ci] 2024-08-21 14:00:44 +01:00
Artem Pavlenko
dc97085b31 Upgrade SCons to v4.8.0 [skip ci] 2024-08-21 13:57:11 +01:00
Artem Pavlenko
7a1663f0a2 Update version to 4.0.2 2024-08-15 11:07:05 +01:00
Artem Pavlenko
924123e9c7
Merge pull request #4470 from mapnik/cmake-soversion
CMake - set `SOVERSION` to `${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}`
2024-07-31 15:34:43 +01:00
Artem Pavlenko
75756b33f3 CMake - set SOVERSION to ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION} 2024-07-31 10:30:50 +01:00
Artem Pavlenko
f1a3d6d7da Update CHANGELOG [skip ci] 2024-07-30 11:12:51 +01:00
Artem Pavlenko
3348f97c76
Merge pull request #4468 from mapnik/bounding-box-split
Split bounding box along (0, 0) before reprojecting  [WIP] [skip ci]
2024-07-30 10:27:47 +01:00
Artem Pavlenko
a982e69525 clang-format 2024-07-29 12:35:31 +01:00
Artem Pavlenko
4f6a7a2571 Add basic forward/backward test for reprojection bounding box for epsg:3995 (WGS 84 / Arctic Polar Stereographic) 2024-07-29 11:23:39 +01:00
Artem Pavlenko
7358a66c2f mapnik::projection - add area_of_use method returning std::optional<mapnik::box2d<double>> (WGS84) [WIP] [skip ci] 2024-07-29 11:21:54 +01:00
Artem Pavlenko
727e3a1ca7 Split bounding box along (0, 0) before reprojecting [WIP] [skip ci]
(improves handling stereographic projections e.g epsg:3995)
2024-07-26 14:28:41 +01:00
Artem Pavlenko
fc029ae5a5 Update Coopyright year 2024-07-22 10:20:47 +01:00
Artem Pavlenko
4df58036aa Update version to 4.0.1 2024-07-22 09:53:04 +01:00
Artem Pavlenko
5e7b478627
Merge pull request #4456 from hummeltech/GCC14
Fix building with GCC 14
2024-07-15 15:54:03 +01:00
David Hummel
0526c603d4 Workaround for Windows builds with GCC 14 patches 2024-06-26 08:44:30 -07:00
David Hummel
2ef5003283 Fix building with GCC 14
Co-authored-by: Tom Hughes <tom@compton.nu>
2024-06-26 08:44:30 -07:00
Artem Pavlenko
eb99057a47
Merge pull request #4466 from hummeltech/GitHubActionsVCPkgCache
Speed up the GitHub Actions CI jobs
2024-06-26 10:29:52 +01:00
David Hummel
d9a6494858 Minor change to demonstrate cache usage 2024-06-25 13:23:11 -07:00
David Hummel
7f743210a0 Speed up the GitHub Actions jobs 2024-06-25 11:33:45 -07:00
Artem Pavlenko
53900d359c use MAPNIK_LIB_DIR via @hummeltech 2024-06-20 16:41:45 +01:00
Artem Pavlenko
507a834264 Merge branch 'tomhughes-libdir' 2024-06-20 16:40:52 +01:00
Tom Hughes
0e0aed3bde Use CMAKE_INSTALL_LIBDIR for libdir in pkg-config files 2024-06-19 19:44:01 +01:00
Artem Pavlenko
e7d0b85dbc
Merge pull request #4462 from hummeltech/InstallDoc
Update `INSTALL.md`
2024-06-17 09:06:20 +01:00
David Hummel
1a878af2f7 Update INSTALL.md 2024-06-16 13:01:46 -07:00
Artem Pavlenko
85801bd402 Mapnik 4.0.0 release. 2024-06-16 14:56:13 +01:00
Artem Pavlenko
02049bb811 Update publish_release.sh script [skip ci] 2024-06-16 14:53:46 +01:00
Artem Pavlenko
52bde246d2 Fix escape char (python >= v3.12) 2024-06-14 14:36:25 +01:00
Artem Pavlenko
ffcf059556
Merge pull request #4461 from hummeltech/MapnikTestsTempDir
Use `temp_directory_path` rather than hard-coded `/tmp` for `image io` tests
2024-06-14 12:45:19 +01:00
Artem Pavlenko
054c2a18a9 Downgrade to ubuntu-22.04 2024-06-14 09:41:49 +01:00
Artem Pavlenko
f91f522e71 runners - use explicit versioning + remove macos-13 2024-06-14 09:30:55 +01:00
David Hummel
9a0d7445be Use temp_directory_path rather than hard-coded /tmp for tests 2024-06-13 08:31:12 -07:00
Artem Pavlenko
63d7e51b84 Update data-visual (cairo) 2024-06-13 10:05:59 +01:00
Artem Pavlenko
3da7a3b1a1 Fix year :) 2024-06-12 16:06:42 +01:00
Artem Pavlenko
cde255852d Attempting to address #4460 by swithing to windows-19 runner 2024-06-12 16:04:48 +01:00
Artem Pavlenko
8c3048bf99 Use python3 by default 2024-06-10 15:39:10 +01:00
Artem Pavlenko
9610c4e2ad SConstruct - use pkg-config proj --variable=datadir ro determine PROJ_LIB directory 2024-06-10 15:35:30 +01:00
Artem Pavlenko
b8166f81a6 Update vcpkg-sha to ad25766aefb5313b6bc4e2a4b78a2946f84fbf66 2024-06-10 09:34:09 +01:00
Artem Pavlenko
84cd5864e7 demo/viewer - use std::optional 2024-06-07 14:12:24 +01:00
Artem Pavlenko
61cb187dbb Check if text_symbolizer has 'placement finder'(keys::text_placements) before any text processing 2024-06-04 12:15:10 +01:00
Artem Pavlenko
d7a8f1d04a clang-format 2024-06-04 12:13:02 +01:00
Artem Pavlenko
f5acdb3efd Update comment. 2024-06-04 12:11:28 +01:00
Artem Pavlenko
c87b245f71 Remove unused 'simplify_prefilter_' parameter (ref #4459) 2024-06-04 12:09:24 +01:00
Artem Pavlenko
4798be914c Set default font-size -> 16px/1em 2024-06-03 12:47:34 +01:00
Artem Pavlenko
653d8b7310 grid_view - delete assignment op 2024-05-30 09:17:14 +01:00
Artem Pavlenko
d7a490ffc2
Merge pull request #4445 from mapnik/feature/drop_boost_cpp17
replace majority of boost->std optional and boost->std string_view
2024-05-22 14:10:17 +01:00
Artem Pavlenko
2c9e55b770
Merge pull request #4458 from mapnik/delete_unused
Delete unused files
2024-05-22 11:11:21 +01:00
Mathis Logemann
9510cd68a3 delete appveyor.yml 2024-05-21 21:17:49 +02:00
Mathis Logemann
0a10de3827 delete bootstrap.sh 2024-05-21 21:17:32 +02:00
Mathis Logemann
b3dd7a0e7d delete .travis.yml 2024-05-21 21:17:16 +02:00
Artem Pavlenko
34bb44e490 clang-format 2024-05-21 09:41:19 +01:00
Artem Pavlenko
658a8bb080 symbolizer_property_value_string - handle value_bool, value_integer, value_double + dash_array 2024-05-21 09:15:50 +01:00
Mathis Logemann
21276ab2a0 use explicit type for std::array 2024-05-18 10:47:51 +02:00
Mathis Logemann
9292899240 remove boost-fileystem from vcpkg, since c++17 is min req. 2024-05-18 10:22:29 +02:00
Mathis Logemann
ab626ac052 update pre-commit and format sources 2024-05-18 10:22:29 +02:00
Mathis Logemann
7ef431ece2 use std::optional instead of boost::optional 2024-05-18 10:22:29 +02:00
Mathis Logemann
e1feef5a79 Use std::string_view instead of boost::string_view 2024-05-18 10:22:29 +02:00
Artem Pavlenko
4114824e6b pre-commit run --show-diff-on-failure --color=always --all-files 2024-05-15 10:29:13 +01:00
Artem Pavlenko
99aa246b73 Remove comment - duplicate names are OK 2024-05-15 10:25:47 +01:00
Artem Pavlenko
3a461630f7 remove extra space character for ouput (tidy) 2024-05-15 10:25:14 +01:00
Artem Pavlenko
1283ca5b77 Revive Symbolizer to json functionality 2024-05-15 10:24:27 +01:00
Artem Pavlenko
454837070d Fix typo 2024-05-14 09:10:51 +01:00
Artem Pavlenko
f89f221445
Merge pull request #4449 from hummeltech/macOSCI
`macos-latest` was migrated from `macOS 12` on `amd64` to `macOS 14` on `arm64`
2024-05-06 11:14:29 +01:00
David Hummel
09067f55fa Account for difference of PROJ_LIB 2024-05-05 13:04:14 -07:00
Artem Pavlenko
f84c30f20c
Merge pull request #4450 from mapnik/svg-refactor
Svg refactor
2024-04-30 10:07:21 +01:00
Artem Pavlenko
3176749613 clang-format
(pre-commit run --show-diff-on-failure --color=always --all-files)
2024-04-30 10:04:57 +01:00
Artem Pavlenko
e412e12599 svg_parser - cleanup + consistent push/pop attributes 2024-04-30 10:01:02 +01:00
Artem Pavlenko
77cd733258 svg_group - check parent is not nullptr 2024-04-30 09:59:35 +01:00
David Hummel
bbeac846d7 Address issues after recent upgrade to LCOV v2.1 2024-04-26 14:01:39 -07:00
David Hummel
e18643ed08 Install missing libtool package on macos-14 2024-04-26 13:16:47 -07:00
David Hummel
8afed63683 macos-latest changed from macOS 12 on amd64 to arm64
This seems to have happened around 2024.04.23

https://github.blog/changelog/2024-04-01-macos-14-sonoma-is-generally-available-and-the-latest-macos-runner-image/
2024-04-26 12:03:16 -07:00
Artem Pavlenko
6e81004cfb add const qualifier to comparison operator 2024-04-25 10:55:04 +01:00
Artem Pavlenko
0d0c471eb5
Merge pull request #4446 from hummeltech/GitHubActionsNodeJS16
Resolve `Node.js 16 actions are deprecated` GitHub Actions warnings
2024-04-23 14:16:38 +01:00
Artem Pavlenko
751c96ec4a tidy [skip ci] 2024-04-22 15:33:11 +01:00
Artem Pavlenko
7350d0a653
Merge pull request #4447 from hummeltech/MapnikTestVisual
No need to install `mapnik-test-visual`
2024-04-22 15:29:51 +01:00
Artem Pavlenko
e1d7d3deb5 Fix dasharray grammar 2024-04-22 15:22:19 +01:00
Artem Pavlenko
6e44fb052c Expose parse_dasharray method (+MAPNIK_DECL), needed by python-bindings 2024-04-22 15:05:05 +01:00
David Hummel
7c45369e88 No need to install mapnik-test-visual 2024-04-21 16:54:28 -07:00
David Hummel
754b12b008 Resolve Node.js 16 actions are deprecated warnings 2024-04-19 16:27:48 -07:00
Mathis Logemann
a85bc95135
Merge pull request #4444 from mapnik/feature/increase_min_cxx_standard
Increase min cxx standard to 17
2024-04-19 20:04:58 +02:00
Mathis Logemann
15abda8b3e [workflow] Remove unused matrix options 2024-04-19 18:20:33 +02:00
Mathis Logemann
dc5ad24ef8 Increase min cxx standard to 17 2024-04-19 18:17:01 +02:00
Artem Pavlenko
e3b0044f8e github actions - build shared libs 2024-04-19 14:17:12 +01:00
Artem Pavlenko
a8d1797bcf
Merge pull request #4442 from hummeltech/macOSLCOV
Address `lcov`/`geninfo` errors on macOS CI builds
2024-04-19 08:57:01 +01:00
Artem Pavlenko
283e2762d4
Merge pull request #4443 from hummeltech/png_io.hppMissingString
Add missing `#include <string>` to `include/mapnik/png_io.hpp`
2024-04-18 09:09:50 +01:00
David Hummel
3ef2e8e3da Address lcov/geninfo error on macOS 2024-04-17 18:12:40 -07:00
David Hummel
0ffd196010 Add missing #include <string> to include/mapnik/png_io.hpp 2024-04-17 13:43:02 -07:00
Artem Pavlenko
15f6745223
Merge pull request #4441 from mapnik/bugfix/dont_pollute_global_install
don't pollute global include dir when installing agg
2024-04-17 09:13:45 +01:00
Mathis Logemann
6c58ae3ae1 don't pollute global include dir when installing agg 2024-04-16 20:05:38 +02:00
Artem Pavlenko
0897271a8e upgrade vcpkg-sha : b4a3d89125e45bc8f80fb94bef9761d4f4e14fb9 + reduce number of runners for now. 2024-04-16 09:24:55 +01:00
Artem Pavlenko
d6fc3b1ddc Upgrade SCons to latest production release (v4.7.0) [skip ci] 2024-04-15 14:35:35 +01:00
Artem Pavlenko
5cc57566cc Fix typo in CSS color unit test 2024-04-15 14:28:22 +01:00
Artem Pavlenko
658d5e69a4
Merge pull request #4438 from mapnik/css_color_fractional_percent
css color fractional percentage values
2024-04-15 14:17:10 +01:00
Artem Pavlenko
7afaa7e6cc clang-format 2024-04-15 14:13:14 +01:00
Artem Pavlenko
5ac45af78e Allow percentage values with a fractional component (implements https://github.com/mapnik/mapnik/issues/4437)
(https://www.w3.org/TR/css-color-4/#funcdef-rgba)
2024-04-15 14:09:04 +01:00
Artem Pavlenko
93ab8b4690 Fix compiler warning - definition of implicit copy constructor for 'enumeration<mapnik::colorizer_mode_enum, &mapnik::colorizer_mode_to_string, &mapnik::colorizer_mode_from_string, &mapnik::colorizer_mode_lookup>' is deprecated because it has a user-provided copy assignment operator [-Wdeprecated-copy-with-user-provided-copy] void operator=(const enumeration& other) { value_ = other.value_; } 2024-04-12 14:20:23 +01:00
Artem Pavlenko
7864289291 Update data-visual 2024-04-04 17:37:02 +01:00
Artem Pavlenko
0708ee8724 Use pkg-config to determine static linking dependencies, default to original behaviour. 2024-04-04 11:01:17 +01:00
Artem Pavlenko
c2c6d2ed60 gdal-config - use both --libs and --dep-libs when RUNTIME_LINK
+ `ogr.input` needs `pkg-config libpq --libs --static`
2024-04-03 18:18:13 +01:00
Artem Pavlenko
83f833f1ce clang-format 2024-03-28 16:49:57 +00:00
Artem Pavlenko
7aceade7c5 Update visual-data [skip ci] 2024-03-28 16:17:05 +00:00
Artem Pavlenko
a9e0bf5bee Link to sharpyuv when 'RUNTIME_LINK'=='static' (webp) 2024-03-28 15:57:14 +00:00
Artem Pavlenko
1e4c17256a WEBP - add fallback pkg-config check if WEBP_INCLUDES and/or WEBP_LIBS aren't set. 2024-03-28 15:55:30 +00:00
Artem Pavlenko
6479059c7e Add specialisation for nodata->rgba8 conversion for mapnik::image_gray8
( fixes gdal-overview-gray8 visual test)
2024-03-28 15:33:41 +00:00
Artem Pavlenko
e394db6c8f add boost-format 2024-03-13 09:10:17 +00:00
Artem Pavlenko
fb61b3fb12 Upgrade to actions/setup-python@v5 (node 20) 2024-03-12 14:29:59 +00:00
Artem Pavlenko
493c7fd5a1 Attempting to fix deb package path 2024-03-12 13:55:23 +00:00
Artem Pavlenko
ba2125b095 Fix -> pre-commit/action@v3.0.1 2024-03-12 13:28:14 +00:00
Artem Pavlenko
6d420b0911 Upgrade to node20 actions e.g @v4 2024-03-12 13:24:34 +00:00
Artem Pavlenko
f9b9261d53 Update vcpkg-sha : e105a86c97b8ab13d4dbe3f7bd9ebc17ece31634 2024-03-12 10:58:56 +00:00
Artem Pavlenko
61b5ff26f2 tidy - remoce PROJ.4 references [skip ci] 2024-03-12 10:58:36 +00:00
Artem Pavlenko
2b932be0ca Update test data (GDAL/OGR 3.5.3) 2024-03-07 09:23:03 +00:00
Artem Pavlenko
02e3b1577c Use __APPLE__ to check OS platform 2024-03-07 09:09:56 +00:00
Artem Pavlenko
8d2388870a
Merge pull request #4364 from mapnik/svg-group-render
Svg group renderer [WIP]
2024-03-01 09:13:49 +00:00
Artem Pavlenko
62c449e6d1 Use the same flags when calling FT_Load_Glyph
+ `revive missing check_object_status_and_throw_exceptiona` in `set_font_face`
2024-03-01 09:05:05 +00:00
Artem Pavlenko
d4173b022d Merge branch 'master' into svg-group-render [skip ci] 2024-02-27 09:05:50 +00:00
Artem Pavlenko
34c95df267
Merge pull request #4432 from mapnik/geojson-empty-geometries
Geojson - empty positions arrays handling
2024-02-27 09:04:24 +00:00
Artem Pavlenko
5b08c21eb0 Actually enable 'is_empty' test + cleanup 2024-02-26 16:25:40 +00:00
Artem Pavlenko
38193817de pre-commit run --show-diff-on-failure --color=always --all-files [skip ci] 2024-02-26 14:48:49 +00:00
Artem Pavlenko
c067399041 GeoJSON unit tests - require expected geometries are "empty". 2024-02-26 14:45:59 +00:00
Artem Pavlenko
0e9f8b06a3 Fix is_empty unit test e.g if multi geometry consists of empty geometries it is "empty". 2024-02-26 14:44:19 +00:00
Artem Pavlenko
b911464472 correct 'is_empty' implementation for multi geometries 2024-02-26 14:40:36 +00:00
Artem Pavlenko
127f9ba143 add missing copy 2024-02-26 14:39:41 +00:00
Artem Pavlenko
995d3044a4 GeoJSON - allow empty arrays in "coordinates" element for Multi* geometries (ref #4431) 2024-02-26 14:01:09 +00:00
Artem Pavlenko
1da533b5e5 Fix building on Ubuntu 23.10 (add <cstdint>) [skip ci] 2024-02-23 14:11:04 +00:00
Artem Pavlenko
6350e1b259 Update test data (+visual) 2024-02-21 16:06:53 +00:00
Artem Pavlenko
dcfb2d692c SVG - improve handling of gradientUnits and gradientTransform attributes (radial gradient) + correct default values [skip ci] 2024-02-15 11:47:57 +00:00
Artem Pavlenko
1c6d14eb85 viewer.app - Increase max scale factor to 10 2024-02-09 09:19:26 +00:00
Artem Pavlenko
cc1c990a2a clang-format : pre-commit run --show-diff-on-failure --color=always --all-files
xsx
2024-02-06 09:37:48 +00:00
Artem Pavlenko
45f954c578 Merge branch 'master' into svg-group-render 2024-02-05 09:41:31 +00:00
Artem Pavlenko
4f6ab6a4a2 Fix spurious ',' in operator== 2024-02-05 09:36:56 +00:00
Artem Pavlenko
2e1b32512b
Merge pull request #4421 from hummeltech/ogr-open-options-CMake
Fix CMake build issues after OGR open_options support addition
2023-11-28 08:54:08 +00:00
Artem Pavlenko
9d5c458405
Merge pull request #4426 from geofabrik/configure-fix
Fix bugs in configure script
2023-11-24 14:05:45 +00:00
Michael Reichert
ee76817d14 Fix bugs in configure script
The script expected that the shell supports arrays but only Z shell and
Bash do so. Other shells return syntax errors.

In addition, the script expected the mapnik-settings.env file to exist
and crashed otherwise.
2023-11-24 13:46:29 +01:00
Artem Pavlenko
88652012a9
Merge pull request #4424 from geofabrik/configure
Fix configure script for variables read from mapnik-settings.env
2023-11-24 08:50:04 +00:00
Michael Reichert
a5a96aacad Fix configure script for variables read from mapnik-settings.env
Custom build variables (e.g. CXX_STD or CXX) read from
mapnik-settings.env have to be provided as command line arguments
because SCons does not respect the environment variables.
2023-11-23 22:04:58 +01:00
David Hummel
c8fd548133 Fix build issues after addition of OGR open_options support 2023-11-22 09:45:23 -07:00
Artem Pavlenko
437feebaf1
Merge pull request #4423 from hummeltech/LibXML2_2.12.0_Support
Fix broken builds with libxml2 >= v2.12.0
2023-11-21 09:16:08 +00:00
David Hummel
8cdca5f5be Fix broken builds with libxml2 >= v2.12.0
**I.E.**
```
src/libxml2_loader.cpp:91:50: error: invalid conversion from ‘const xmlError*’ {aka ‘const _xmlError*’} to ‘xmlError*’ {aka ‘_xmlError*’} [-fpermissive]
src/libxml2_loader.cpp:131:50: error: invalid conversion from ‘const xmlError*’ {aka ‘const _xmlError*’} to ‘xmlError*’ {aka ‘_xmlError*’} [-fpermissive]
```
2023-11-20 10:21:12 -07:00
Artem Pavlenko
d745e43eb1 pre-commit run --show-diff-on-failure --color=always --all-files 2023-11-17 16:33:01 +00:00
Artem Pavlenko
7d2029165e Merge branch 'geofabrik-ogr-open-options-pr' 2023-11-17 16:31:13 +00:00
Michael Reichert
2d20d5a3c5 Add support for open options in OGR input plugin 2023-11-17 11:06:18 +01:00
Artem Pavlenko
738a7f19b7 Merge branch 'master' into svg-group-render 2023-11-17 09:43:02 +00:00
Artem Pavlenko
279acf4c36
Merge pull request #4419 from geofabrik/drop-old-gdal-pr
Drop support for old versions of GDAL/OGR (older than 2.0)
2023-11-17 09:10:49 +00:00
Michael Reichert
bff4fdde77 Drop support for old versions of GDAL/OGR (older than 2.0)
Fixes #4403.

GDAL 2.0.0 was released in March 2018 (more than five years ago).
Almost all Linux distributions (apart from few long-term support versions)
should come with at least GDAL >= 2.0.
2023-11-16 20:16:05 +01:00
Artem Pavlenko
f391178af0 Upgrade to SCons 4.5.2 2023-09-22 14:38:30 +01:00
Artem Pavlenko
50f1b05f86 boost/algorithm/string/trim.hpp is needed for `trim_if' (boost 1.83) 2023-09-22 14:37:34 +01:00
Artem Pavlenko
47f7f6bd4d Merge branch 'master' into svg-group-render 2023-09-15 14:48:44 +01:00
Artem Pavlenko
d69a0902d4 Forward declaration of 'mapnik::rule' is not sufficient when building on macOS :
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
2023-09-15 14:46:29 +01:00
Artem Pavlenko
cb352ac609 Remove unused local variable 2023-09-15 14:45:18 +01:00
Artem Pavlenko
388d3fd8da Add missing scons-local-4.5.1 2023-09-15 12:34:31 +01:00
Artem Pavlenko
b7332b07a1
Merge pull request #4404 from hummeltech/include_mapnik_geometry_cstdint_header
Add cstdint header include to `include/mapnik/geometry/boost_spirit_karma_adapter.hpp`
2023-09-15 09:12:49 +01:00
David Hummel
b1282fe32c Add cstdint header include to include/mapnik/geometry/boost_spirit_karma_adapter.hpp 2023-09-14 17:38:27 -07:00
Artem Pavlenko
ee8c403779 Merge branch 'master' into svg-group-render 2023-06-12 08:29:49 +01:00
Artem Pavlenko
123232ffde
Merge pull request #4390 from mapnik/feature/updateVcpkg
Update vcpkg commit ref in the ci
2023-06-12 08:29:12 +01:00
Mathis Logemann
2445dbe063 remove boost foreach include 2023-06-11 20:10:50 +02:00
Artem Pavlenko
ed0f8dcb48 Add missing scons-local-4.5.1 2023-06-11 11:31:23 +01:00
Artem Pavlenko
f226d4fd93 Conditionally apply BOOST_SPIRIT_X3_HIDE_CXX17_WARNING if cxx_std < 17 2023-06-11 11:22:49 +01:00
Artem Pavlenko
708e2a4009 Include rule.hpp as fwd decl no longer sufficient with clang++-14
(Apple clang version 14.0.3 (clang-1403.0.22.14.1)
2023-06-11 11:20:16 +01:00
Artem Pavlenko
92426bfc8e Merge branch 'master' into svg-group-render 2023-06-11 09:49:37 +01:00
Artem Pavlenko
20acc0e656
Merge pull request #4389 from MoeSzyslak98/gcc-13-fix
add cstdint header for gcc13 compilation.
2023-06-11 09:44:02 +01:00
Mathis Logemann
6003293e25
Update build_and_test.yml 2023-06-11 08:30:42 +02:00
kian
76c5fd047d add cstdint header for gcc13 compilation. 2023-06-09 15:32:59 +03:30
Artem Pavlenko
3b81effb3e remove unused local variable 2023-04-25 14:23:08 +01:00
Artem Pavlenko
35d901072b mapnik-render: use mapnik/filesystem.hpp 2023-03-27 09:34:03 +01:00
Artem Pavlenko
e847bb738b Set USE_BOOST_FILESYSTEM=True if CXX_STD < 17 + fix typo 2023-03-26 11:36:14 +01:00
Artem Pavlenko
cd4069f91e Merge branch 'master' into svg-group-render 2023-03-20 09:03:18 +00:00
Artem Pavlenko
c4aa24496a
Merge pull request #4385 from hummeltech/C++17Build
Add build & test for `CXX_STANDARD=17` to GitHub Actions
2023-03-20 09:01:13 +00:00
Hummeltech
63f33eed4b
List advanced cached variables in CI [skip ci] 2023-03-19 14:05:58 -07:00
Hummeltech
bc09efb8f5
Fixed typo USE_BOOST_FILESYSYTEM 2023-03-19 14:01:14 -07:00
Hummeltech
bb280a2815
Fixing issues with USE_BOOST_FILESYSTEM definition 2023-03-19 13:39:20 -07:00
Hummeltech
93e488a6cf
Only test for !defined(USE_BOOST_FILESYSTEM) in filesystem.hpp 2023-03-19 09:39:13 -07:00
Hummeltech
9f88d4c3a4
Revert CMAKE_CXX_FLAGS msvc-cl change 2023-03-19 09:38:27 -07:00
David Hummel
f6cd056552 Attempting to fix Windows build with C++17 2023-03-18 09:06:34 -07:00
David Hummel
0e9996dde0 Add build & test for CXX_STANDARD=17 to GitHub Actions 2023-03-18 08:03:58 -07:00
Artem Pavlenko
fc2d27d349
Merge pull request #4384 from hummeltech/cplusplus17
Fixed check for `__cpp_lib_filesystem` in `filesystem.hpp`
2023-03-18 14:35:07 +00:00
David Hummel
e4557c016f Oops, it looks like <version> does not exist until C++20 2023-03-17 10:31:30 -07:00
David Hummel
edec46e8c3 Fixed check for '__cpp_lib_filesystem' always false until after '#include <filesystem>' 2023-03-17 10:20:24 -07:00
Artem Pavlenko
b7fdeeeb02 Move rotation struct definition into pixel_position.hpp 2023-03-15 10:29:30 +00:00
Artem Pavlenko
ecfccdd36c Merge branch 'master' into svg-group-render 2023-03-15 08:37:06 +00:00
Artem Pavlenko
338942b490
Merge pull request #4383 from mapnik/std-filesystem 2023-03-15 07:47:55 +00:00
Artem Pavlenko
00199754a2
Update test/visual/CMakeLists.txt
Co-authored-by: Mathis Logemann <mathisloge@gmail.com>
2023-03-14 16:54:04 +00:00
Artem Pavlenko
49912a423e
Update CMakeLists.txt
Co-authored-by: Mathis Logemann <mathisloge@gmail.com>
2023-03-14 16:53:37 +00:00
Artem Pavlenko
5504aea704 clang-format 2023-03-14 14:53:44 +00:00
Artem Pavlenko
779c04af06 demo/viewer - fix currentIndexChanged signal signature 2023-03-14 14:44:45 +00:00
Artem Pavlenko
a244effa91 Add mapnik/filesystem.hpp ref:https://github.com/mapnik/mapnik/pull/4383#discussion_r1131405532 2023-03-13 14:27:02 +00:00
Artem Pavlenko
45b48721fa replace std::tmpnam (deprecated) with make_unique 2023-03-13 09:34:58 +00:00
Artem Pavlenko
106a46bbf6
Update CMakeLists.txt
Co-authored-by: Mathis Logemann <mathisloge@gmail.com>
2023-03-09 21:14:54 +00:00
Artem Pavlenko
96a6fcd941
Update CMakeLists.txt
Co-authored-by: Mathis Logemann <mathisloge@gmail.com>
2023-03-09 21:14:45 +00:00
Artem Pavlenko
d680d1d7f5
Update CMakeLists.txt
Co-authored-by: Mathis Logemann <mathisloge@gmail.com>
2023-03-09 21:14:28 +00:00
Artem Pavlenko
be0b537f52 Use std::filesystem when CXX_STD >= 17 and not USE_BOOST_FILESYSTEM 2023-03-09 13:17:28 +00:00
Artem Pavlenko
a3f65197dd Merge branch 'master' into svg-group-render 2023-03-08 12:02:34 +00:00
Artem Pavlenko
c646d245b4 Upgrade SCons to v4.5.1 2023-03-08 12:01:16 +00:00
Artem Pavlenko
f36ac22f82 MAPNIK_DECL only on __GNUC__ builds
ref: error C2491: 'mapnik::feature_style_processor<Processor>::prepare_layers': definition of dllimport function not allowed
2023-03-07 11:25:52 +00:00
Artem Pavlenko
87ac079bb6 Add -fvisibility=hidden -fvisibility-inlines-hidden to mapnik target (CMake) 2023-03-07 10:02:50 +00:00
Artem Pavlenko
accb28eb80 external linking (MAPNIK_DECL) requires for -fvisibility=hidden -fvisibility-inlines-hidden to work for GCC/g++ builds 2023-03-07 10:00:18 +00:00
Artem Pavlenko
7035b3e399 small typo 2023-03-07 09:57:36 +00:00
Artem Pavlenko
692c2faa0e
Merge pull request #4382 from hummeltech/master
Add `fonts_dir` & `plugins_dir` variables to `libmapnik.pc`
2023-03-02 15:48:40 +00:00
David Hummel
db9c4bc340 Add fonts & input_plugins variables to libmapnik.pc 2023-03-01 14:48:30 -07:00
Artem Pavlenko
52b5cab584 Update data-visual 2023-02-28 10:37:15 +00:00
Artem Pavlenko
41bb612e5d Merge branch 'master' into svg-group-render 2023-02-27 11:18:48 +00:00
Artem Pavlenko
3dbeb1ee4f Use explicit boost::filesystem::path::value_type to std::string conversion (win) 2023-02-27 09:22:17 +00:00
Artem Pavlenko
21d31bf62e Fix deprecated headers warning 2023-02-27 09:17:55 +00:00
Artem Pavlenko
02445f43ed mini cleanup 2023-02-27 09:17:37 +00:00
Artem Pavlenko
1351d90d51 Use boost::filesystem when __cplusplus < 201703L 2023-02-26 14:40:00 +00:00
Artem Pavlenko
8839f5774a pre-commit run --all-files 2023-02-24 18:07:09 +00:00
Artem Pavlenko
a499989b1d add missing header 2023-02-24 18:05:01 +00:00
Artem Pavlenko
d1f16479d1 pre-commit run --all-files 2023-02-24 17:51:40 +00:00
Artem Pavlenko
5e980ec853 mapnik-render
New options :
 * --bbox -- bounding box to zoom in (expected in Map's SRS unless "--geographic" is used)
 * --geographic,-g  -- bounding box is in WGS 84 lon/lat
 * --plugins-dir -- directory contaning input plugins (default:./plugins/input)
 * --fonts-dir -- directory containing fonts (default: relative to plugins-dir or ./fonts if no plugins-dir specified)
2023-02-24 11:23:26 +00:00
Artem Pavlenko
8efaa959f0 projection - rename 'expanded' to 'definition' (PJ_PROJ_INFO) + add 'description' method 2023-02-24 09:23:52 +00:00
Artem Pavlenko
e0da4468d2
Merge pull request #4379 from mapnik/update/vcpkg-sha
Update vcpkg-sha
2023-02-03 13:54:16 +00:00
Mathis Logemann
b4f1bc09f8
Update vcpkg-sha 2023-02-03 12:38:51 +01:00
Artem Pavlenko
ce073c64c7 Merge branch 'master' into svg-group-render 2023-01-24 14:30:28 +00:00
Artem Pavlenko
b9175100bd
Merge pull request #4378 from tomhughes/stdint
Include cstdint for uint16_t
2023-01-24 14:22:21 +00:00
Artem Pavlenko
fb97fb10f7
Merge pull request #4377 from mathisloge/fix/python-mapnik-findings
move datasource_plugin into mapnik target
2023-01-24 14:21:17 +00:00
Tom Hughes
c62e03344f Include cstdint for uint16_t 2023-01-23 22:37:16 +00:00
Mathis Logemann
ccbf27400c move datasource_plugin into mapnik target 2023-01-23 16:13:32 +01:00
Artem Pavlenko
00e2027d86 Merge branch 'master' into svg-group-render 2023-01-18 09:52:43 +00:00
Artem Pavlenko
43a7d7e455 Fix compiler warning (consistent class or struct declarations) 2023-01-18 09:50:26 +00:00
Artem Pavlenko
edddd08d73 Merge branch 'master' into svg-group-render 2023-01-18 09:48:29 +00:00
Artem Pavlenko
4e064b8b8e
Merge pull request #4291 from mathisloge/feature/cmake-static
Feature/cmake static plugins
2023-01-17 11:27:42 +00:00
Mathis Logemann
7cce5ce346 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2023-01-16 19:55:02 +01:00
Artem Pavlenko
e811958745
Merge pull request #4372 from mathisloge/refactor/enumarations
Refactor/enumerations
2022-12-19 12:37:32 +00:00
Mathis Logemann
64a031a19b changelog 2022-12-16 15:36:22 +01:00
Artem Pavlenko
51b5c9604a including <memory> - "src/test_png_encoding2.cpp:6:10: error: ‘shared_ptr’ in namespace ‘std’ does not name a template type" 2022-12-12 14:23:39 +00:00
Artem Pavlenko
6afcb73135 Merge branch 'master' into svg-group-render 2022-12-12 12:10:43 +00:00
Artem Pavlenko
e27bc63887 SVG parser - update test data 2022-12-12 11:48:45 +00:00
Artem Pavlenko
f4eec2e24f pre-commit run --all-files 2022-12-12 10:46:41 +00:00
Artem Pavlenko
d29aeb2ddb SVG parser unit test - add attribute comparison framework + test data 2022-12-11 10:24:14 +00:00
Mathis Logemann
dd38dd18f9 rework enumeration<...> 2022-12-10 16:55:24 +01:00
Mathis Logemann
bc38652079 Finalize static plugins 2022-12-09 14:48:52 +01:00
Mathis Logemann
be46202511 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-11-28 08:29:20 +01:00
Artem Pavlenko
d417b8933a
Merge pull request #4366 from mathisloge/feature/refactor_actions
[CI] refactor github actions
2022-11-26 17:27:17 +00:00
Mathis Logemann
2ff1f4228d [CI] fail-fast: false 2022-11-26 16:40:16 +01:00
Mathis Logemann
d949acb925 [CI] only build if the check source code step is succesfull 2022-11-26 16:10:16 +01:00
Mathis Logemann
cbb80aa0db refactor actions 2022-11-26 16:07:44 +01:00
Artem Pavlenko
0b62415225 Export comp_op_rgba_xxx to fix linking on Windows via @mathisloge 2022-11-26 15:01:39 +00:00
Artem Pavlenko
d436c94c25 SVG cairo - push/pop group 2022-11-26 12:50:57 +00:00
Artem Pavlenko
0e5e77121c SVG - implement Cairo group renderer [WIP] [skip ci] 2022-11-26 11:13:37 +00:00
Mathis Logemann
0071eb1163 fix vcpkg for static 2022-11-26 08:36:42 +01:00
Mathis Logemann
df1ff425b7 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-11-26 08:32:20 +01:00
Artem Pavlenko
7c24ff09ee clang-format 2022-11-25 13:54:41 +00:00
Artem Pavlenko
e790aa6c06 Merge branch 'master' into svg-group-render 2022-11-25 13:48:36 +00:00
Artem Pavlenko
b7953fa68b
Merge pull request #4368 from mathisloge/fix/win-error
Fix windows build error
2022-11-25 10:57:01 +00:00
Mathis Logemann
9c873d0e95
Update ubuntu.yml 2022-11-24 22:36:17 +01:00
Artem Pavlenko
0968e12b5e
Merge pull request #4367 from mapnik/ci/vcpkg-json 2022-11-24 19:26:24 +00:00
Mathis Logemann
ae5e283df9 update proj db ref 2022-11-24 20:16:35 +01:00
Mathis Logemann
2770657ba1 fix windows build error 2022-11-24 19:41:21 +01:00
Mathis Logemann
b26d0757b7 add .cache to gitignore 2022-11-24 19:41:15 +01:00
Artem Pavlenko
8bc1aad37f SVG - convert USER_SPACE_ON_USE radial gradient values to % (fix) [WIP] [skip ci] 2022-11-24 10:35:19 +00:00
Artem Pavlenko
c3aec439a7 svg2png - check for valid opacity range 0..1 [WIP] [skip ci] 2022-11-24 10:25:09 +00:00
Artem Pavlenko
b3ed2280b6 Merge branch 'master' into svg-group-render 2022-11-24 09:55:44 +00:00
Artem Pavlenko
bfdab8879c svg2png - add top level "opacity" option e.g similar to <svg opacity="<val>"/> [WIP] [skip ci] 2022-11-23 16:18:18 +00:00
Artem Pavlenko
5f4711a019 SVG - refactor and minimise internal group usage [WIP] [skip ci] 2022-11-23 15:53:08 +00:00
Mathis Logemann
7d267b47fe Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-11-22 20:14:33 +01:00
Mathis Logemann
56312c68ad
Update vcpkg.json 2022-11-22 20:08:32 +01:00
Mathis Logemann
4fc828cf29
Merge pull request #4365 from mathisloge/ci/update_vcpkg
[CI] update vcpkg
2022-11-22 12:24:50 +01:00
Artem Pavlenko
8c04fb1262 Use feature_id in render_id [WIP] [skip ci] 2022-11-22 10:57:05 +00:00
Mathis Logemann
07789ad3cc
Update .pre-commit-config.yaml 2022-11-22 11:45:23 +01:00
Mathis Logemann
817f644c6d update pre-commit versions 2022-11-21 22:40:46 +01:00
Mathis Logemann
6183005baf [CI] update gh action runners 2022-11-21 22:28:44 +01:00
Mathis Logemann
7d414450c1 update vcpkg hash 2022-11-21 22:09:04 +01:00
Artem Pavlenko
4ef05da536 Revive 'push_explicit_style' logic. [WIP] [skip ci] 2022-11-21 19:10:12 +00:00
Artem Pavlenko
5347a1d939 format identation 2022-11-21 19:08:05 +00:00
Artem Pavlenko
0da7efdbac Fix - blend using correct 'opacity' 2022-11-21 19:06:53 +00:00
Artem Pavlenko
d4ae5ac653 SVG group renderer implementation (WIP) [skip ci] 2022-11-18 15:17:58 +00:00
Artem Pavlenko
a65d65a5ab Update .clang-format to BraceWrapping: BeforeCatch : true
run `pre-commit`
2022-11-10 15:57:38 +00:00
Artem Pavlenko
1d75721a46 Fix compiler warning -
```
include/mapnik/markers_placements/vertex_last.hpp:49:18: warning: variable 'cmd1' set but not used [-Wunused-but-set-variable]
        unsigned cmd1 = SEG_END;
                 ^
1 warning generated.
```
2022-11-04 14:39:54 +00:00
Artem Pavlenko
2a71903c75 Remove redundant BOOST_VERSION #if/endif 2022-11-04 14:07:28 +00:00
Artem Pavlenko
7e5655eef4 Use snprintf instead of sprintf (ref #4361) 2022-11-04 13:46:10 +00:00
Artem Pavlenko
5522cdd201 pre-commit run --all-files 2022-11-04 09:46:00 +00:00
Artem Pavlenko
bd018ef5ab git-clang-format 2022-11-03 11:29:50 +00:00
Artem Pavlenko
b438edd8da SVG path parser unit tests - update expected arc paths ref:98e5e64d80d921a02bc57f05c55c2e0e2426ab4d 2022-11-03 11:13:09 +00:00
Artem Pavlenko
05661e5439 Merge branch 'kkaefer-fix-svg-smooth-curve-after-arc' 2022-10-18 14:14:57 +01:00
Artem Pavlenko
02af1f606c Apply fix from #4357 to agg_path_storage 2022-10-18 14:13:35 +01:00
Artem Pavlenko
618ddef663 Merge branch 'fix-svg-smooth-curve-after-arc' of github.com:kkaefer/mapnik into kkaefer-fix-svg-smooth-curve-after-arc 2022-10-18 14:11:22 +01:00
Artem Pavlenko
fa9ee1fc61 Issue warning not an error when font face not found (ref #4354) 2022-10-18 13:56:05 +01:00
Konstantin Käfer
98e5e64d80 SVG: Fix reflection points for smooth curves after arcs
Internally, Agg/Mapnik converts arcs to curves. This means that the detection logic in the “smooth curve” command, which looks at the previous points for calculating the reflection point, mistakenly assumes that the previous commands were curve commands, even though they were in reality arc commands. To fix this, we add an explicit lineto command after every arc.
2022-10-18 12:17:05 +02:00
Artem Pavlenko
53a8e2ec2c Remove docbook directory from local SCons distribution and avoid referencing jQuery
(ref: Cross-site scripting (XSS) vulnerability in jQuery before 1.6.3)
2022-09-23 10:03:14 +01:00
Artem Pavlenko
9cf40a6144 Fix radial-distance simplification algorithm to always oupput last vertex (ref #4347) 2022-09-23 09:41:11 +01:00
Artem Pavlenko
9e8e178160 Re-enable simplify_converter tests + add radial-distance tests (#4348) 2022-09-23 09:32:06 +01:00
Artem Pavlenko
81103491b4 Fix building with boost_1_80 (#4340) 2022-08-30 10:40:25 +01:00
Mathis Logemann
ce8bd250dd better export [wip] 2022-08-25 19:59:29 +02:00
Mathis Logemann
4cd4985e75 resolve double defined symbol 2022-08-23 21:37:06 +02:00
Mathis Logemann
b9379f9024 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-08-18 20:38:47 +02:00
Mathis Logemann
e6553ef652 simplify cmake 2022-08-18 20:38:21 +02:00
Artem Pavlenko
019af0ad1d
Merge pull request #4338 from mathisloge/fix/ci-run
[CI] only run on master pushes and all PRs
2022-08-18 11:08:37 +01:00
Mathis Logemann
13c4719912 [CI] only run on master pushes and all PRs 2022-08-17 18:26:19 +02:00
Mathis Logemann
cf78c2a129 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-08-17 18:23:19 +02:00
Artem Pavlenko
a1596e4dad
Merge pull request #4333 from mapnik/cmake-install-fonts
Fix font installation logic
2022-08-17 17:19:34 +01:00
Artem Pavlenko
c8cff17fb6 Merge remote-tracking branch 'origin/cmake-install-fonts' into cmake-install-fonts 2022-08-17 17:05:19 +01:00
Artem Pavlenko
7d8be299f3 Fix font installation logic 2022-08-17 17:00:24 +01:00
Mathis Logemann
3ab8e80f2a depend on formatting 2022-08-17 17:37:43 +02:00
Mathis Logemann
eb3823aa4a precommit 2022-08-17 17:35:25 +02:00
Mathis Logemann
213be3777c Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-08-17 17:34:52 +02:00
Mathis Logemann
2b7456f54b Revert "precommit"
This reverts commit f48589738f.
2022-08-17 17:22:07 +02:00
Mathis Logemann
f48589738f precommit 2022-08-17 17:19:59 +02:00
Mathis Logemann
f6bcdac258 default crt = 0N 2022-08-17 17:16:32 +02:00
Artem Pavlenko
14a5cc7e1a
Merge pull request #4334 from mathisloge/cmake-linting
adding auto formatting
2022-08-17 14:15:13 +01:00
Mathis Logemann
54b0381f4d wip 2022-08-16 21:03:56 +02:00
Mathis Logemann
e3d8e55a79 pre-commit run -a 2022-08-16 19:00:16 +02:00
Mathis Logemann
df141876d0 disable clang-format for external deps 2022-08-16 19:00:15 +02:00
Artem Pavlenko
8abad1843a
Merge pull request #4336 from mathisloge/fix/viewer-ini
[CMake] fix generated viewer ini file
2022-08-16 14:08:20 +01:00
Mathis Logemann
13c96ab7d0 [CMake] fix generated viewer ini file 2022-08-15 21:14:16 +02:00
Mathis Logemann
69d682ef02 [clang-format] more compact extern c 2022-08-14 22:26:32 +02:00
Mathis Logemann
eb16e7a647 fix all files
format files
2022-08-14 22:26:31 +02:00
Mathis Logemann
88052447b9 pre-commit
add more hooks

add workflow
2022-08-11 22:53:03 +02:00
Artem Pavlenko
b6161dd439 Merge branch 'master' into cmake-install-fonts 2022-08-04 14:40:38 +01:00
Artem Pavlenko
9627432723 Fix -Wdeprecated-enum-enum-conversion warnings (AGG) 2022-08-04 11:25:35 +01:00
Artem Pavlenko
a9c98dff5d Fix deprecation warning (libtiff)
/usr/include/x86_64-linux-gnu/tiff.h:81:45: note: 'uint16' has been explicitly marked deprecated here
typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED;
2022-08-04 11:01:56 +01:00
Artem Pavlenko
322f6cd805 Fix font installation logic 2022-08-03 16:19:07 +01:00
Mathis Logemann
34df24f4e2 [CMake] use pkgconfig for webp; make some statements more clearly 2022-04-22 21:10:42 +02:00
Mathis Logemann
c85f8462fd [CMake] fixes for windows (WIP) 2022-04-22 15:10:49 +02:00
Mathis Logemann
59d2f21369 [CMake] remove FindCairo and use pkgconfig 2022-04-22 15:10:02 +02:00
Mathis Logemann
25012517aa [CI] add static builds 2022-04-16 11:26:34 +02:00
Mathis Logemann
503fe35817 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-04-16 11:21:05 +02:00
Artem Pavlenko
1ba1278b42
Merge pull request #4307 from josch/proj-debug
src/proj_transform.cpp: only use proj_context_errno_string for proj >= 8.0.0
2022-04-14 14:14:48 +01:00
Johannes Schauer Marin Rodrigues
01e018eb0a
src/proj_transform.cpp: only use proj_context_errno_string for proj >= 8.0.0 2022-04-14 11:52:25 +02:00
Artem Pavlenko
5c06098caf
Merge pull request #4300 from mathisloge/ci/vcpkg_2022-03-18
[CI] update vcpkg to latest hash
2022-04-13 10:00:08 +01:00
Mathis Logemann
a963ae5ea6 [CI] trigger 2022-04-12 20:51:52 +02:00
Mathis Logemann
ca269f425c Revert "[CI] update vcpkg deps"
This reverts commit 75ad499fb5.
2022-04-12 14:42:19 +02:00
Mathis Logemann
75ad499fb5 [CI] update vcpkg deps 2022-04-12 14:21:45 +02:00
Mathis Logemann
8c9e61373e Merge branch 'master' of https://github.com/mapnik/mapnik into ci/vcpkg_2022-03-18 2022-04-11 15:24:45 +02:00
Artem Pavlenko
1ce18f6698
Merge pull request #4305 from josch/proj-debug 2022-04-11 14:20:14 +01:00
Artem Pavlenko
85997107af
Merge pull request #4304 from mathisloge/fix/cairo-1.17.6 2022-04-11 14:19:20 +01:00
Mathis Logemann
2259f8da6f use unnamed workflows, move vcpkg into preset update vcpkg 2022-04-11 15:04:30 +02:00
Johannes Schauer Marin Rodrigues
4f72043bcd
src/proj_transform.cpp: improve error handling of proj_transform()
- set proj log level to PJ_LOG_ERROR
 - let error message indicate whether proj_create_crs_to_crs or
   proj_normalize_for_visualization failed
 - output proj_context_errno_string when an error is thrown
2022-04-10 11:55:04 +02:00
Mathis Logemann
6afdc89894 fix test for newer cairo 2022-04-05 10:31:26 +02:00
Mathis Logemann
1bba69b108 [CI] update vcpkg to latest hash
notable changes: * proj => v9
[CI] fix sqlite dep

[vcpkg] update hash

update vcpkg cache
2022-04-02 18:05:03 +02:00
Mathis Logemann
e00847e711 [CI] fix sqlite dep 2022-03-19 10:27:34 +01:00
Mathis Logemann
2b8eec969b PluginInfo: remove static init and exit methods
those aren't used.
2022-03-15 21:12:43 +01:00
Mathis Logemann
5ee7571761 add dlerror for plugin loading 2022-03-15 21:12:43 +01:00
Mathis Logemann
4493a06878 call mapnik::setup automatically 2022-03-15 21:12:43 +01:00
Mathis Logemann
515a7e8279 changelog 2022-03-15 21:12:43 +01:00
Mathis Logemann
bb1bc2f07b [CMake] enable msvc static crt 2022-02-18 18:48:27 +01:00
Artem Pavlenko
2d03db8ef1 Fix scons build 2022-02-15 15:40:16 +00:00
Mathis Logemann
45568e8895 [datasource] call after_load for static plugins 2022-02-14 17:34:20 +01:00
Mathis Logemann
ee63a6f055 [tests] also test when using static 2022-02-14 10:15:09 +01:00
Mathis Logemann
0f0e06c6b8 [datasource] add plugin_registered function 2022-02-14 10:14:59 +01:00
Mathis Logemann
6fcdccaf83 [CMake] fix rename MAPNIK_STATIC_PLUGINS => BUILD_SHARED_PLUGINS 2022-02-09 15:57:03 +01:00
Mathis Logemann
c0d52ced18 [Changelog] describe breaking changes 2022-02-08 16:55:42 +01:00
Mathis Logemann
f9e69b4090 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-02-08 16:49:51 +01:00
Artem Pavlenko
f3da900c35
Merge pull request #4295 from mathisloge/ci/disable-debug-mode
[CI] disable vcpkg debug mode
2022-02-08 14:09:55 +00:00
Mathis Logemann
0769303075 [CI] ubuntu: run with mono 2022-02-08 14:59:43 +01:00
Mathis Logemann
01f414de59 [CI] disable vcpkg debug mode 2022-02-08 14:54:40 +01:00
Mathis Logemann
65dde2cce3 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-02-07 15:35:45 +01:00
Mathis Logemann
49ef468e84 [CMake] add msvc EHsc option 2022-02-07 15:35:09 +01:00
Mathis Logemann
42f465f842 refactor datasource plugins
fix merge

remove old DATASOURCE_PLUGIN call

fix memory_datasource

wip

wip

fix temp return

fix install

wip before_unload

linux

remove docker

remove docker

comments

add windows error message if libmapnik=static and plugins=dynamic

fix false plugin macro

plugin default de/constructor to remove UB

simplyfy plugin targets - add fpic

fix makro

simplyfy

use unique_ptr for plugin handle

rename option static plugins

replace local init with fnc call

call setup everywhere

init datasource_static
2022-02-07 15:35:09 +01:00
Artem Pavlenko
713104c2dc
Merge pull request #4290 from mathisloge/fix/gha-upload
[GHA] use current user if PR or local repo (readonly) and vcpkg debug…
2022-02-07 14:06:05 +00:00
Artem Pavlenko
843eb3eae5
Merge pull request #4289 from mathisloge/fix/format
fix formatting of warning.hpp
2022-02-07 14:05:40 +00:00
Mathis Logemann
e75725ef37 [GHA] use current user if PR or local repo (readonly) and vcpkg debug mode
use github.actor

test readonly access?

test

test

test

readonly user

use correct toolcahin for windows
2022-02-02 20:56:01 +01:00
Mathis Logemann
d148121dad fix formatting of warning.hpp 2022-02-02 17:31:43 +01:00
Mathis Logemann
8a1f2579e9 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/cmake-static 2022-02-02 17:15:55 +01:00
Mathis Logemann
2d846dd5f3 static plugins
wip static plugins

add remaining datasources

wip

formatting
2022-02-02 16:35:49 +01:00
Artem Pavlenko
0c8352fc3e
Merge pull request #4288 from mathisloge/fix/github-actions 2022-02-02 14:32:53 +00:00
Mathis Logemann
32ca0104a7 fix gha secret name 2022-02-02 15:31:24 +01:00
Artem Pavlenko
f9b310a8ca
Merge pull request #4286 from mathisloge/feature/github-actions
add github actions
2022-02-02 14:28:23 +00:00
Mathis Logemann
cda203a83f use correct cache 2022-02-02 10:14:55 +01:00
Mathis Logemann
bff4dbd957 add github actions
use mapnik as user

drop codecov token (not needed)
2022-01-28 11:14:04 +01:00
Artem Pavlenko
d7b83c0f7d
Merge pull request #4282 from mathisloge/feature/clang-format
Feature clang format
2022-01-28 09:57:58 +00:00
Mathis Logemann
9bf8fcc823 fix color.cpp formatting 2022-01-28 10:37:38 +01:00
Mathis Logemann
779787f980 Merge branch 'master' of https://github.com/mapnik/mapnik into feature/clang-format 2022-01-28 10:31:55 +01:00
Artem Pavlenko
7df7e16c56
Merge pull request #4284 from mathisloge/fix/windows-utf8
CMake stuff, missing includes and enables tiff test on windows
2022-01-28 09:20:52 +00:00
Artem Pavlenko
dafdbb01ea
Merge pull request #4276 from mathisloge/remove_cxx11_support
remove cxx11_support.hpp
2022-01-28 09:18:53 +00:00
Mathis Logemann
7bccb2a280 Merge branch 'fix/windows-utf8' of https://github.com/mathisloge/mapnik 2022-01-27 19:18:11 +01:00
Mathis Logemann
ef062ac314 [unit-tests] mark text/nested script runs as unicode 16 2022-01-27 18:42:40 +01:00
Mathis Logemann
3b1d09702c [unit-test] enable tiff test 2022-01-27 18:40:22 +01:00
Mathis Logemann
3012ea43ee [visual-test] enable utf-8 console output for windows 2022-01-27 18:37:19 +01:00
Mathis Logemann
aee8519bac [CMake] visual test in own dir 2022-01-27 18:37:03 +01:00
Mathis Logemann
ba27149232 add missing includes 2022-01-27 18:32:21 +01:00
Mathis Logemann
08dcab617e [CMake] add benchmark run script 2022-01-27 18:31:33 +01:00
Mathis Logemann
ccd44da4a2 [CMake] fix installation 2022-01-27 18:30:13 +01:00
Mathis Logemann
c5d4bfe680 [CMake] add msvc utf-8 flag 2022-01-27 18:28:44 +01:00
Mathis Logemann
4fbaa032f0 format dir demo 2022-01-27 00:12:13 +01:00
Mathis Logemann
65035706fb format dir benchmark 2022-01-27 00:12:13 +01:00
Mathis Logemann
6dcf754077 format dir test
format dir test

fix
2022-01-27 00:12:12 +01:00
Mathis Logemann
d5a873e81c format utils 2022-01-27 00:12:12 +01:00
Mathis Logemann
e7c3d04309 format dir include and src
format all files

Revert "format all files"

This reverts commit 95d5812e49e7f916b68e786596f5a8eb5bcac414.

Revert "format some files"

This reverts commit ed3c8762d4d828b2b28e7b18809fc33f4f8ccaf5.

format all files

fix formatting in dir include

fix formatting of debug macro
2022-01-27 00:12:08 +01:00
Mathis Logemann
6fe46f61e2 add clang-format
fix clang-format

fix clang-format

adjust pointer and reference aligment

add cmake script to format all files run with: cmake -P cmake/clang-format.cmake

fix sort includes

change format cmake script
2022-01-26 23:36:12 +01:00
Mathis Logemann
61dd5dccab Merge branch 'master' of https://github.com/mapnik/mapnik 2022-01-26 00:13:21 +01:00
Artem Pavlenko
1d6350b1e5
Merge pull request #4281 from mathisloge/fix/unique_shared_ptr
use shared::ptr<T>::use_count instead of unique()
2022-01-25 12:09:52 +00:00
Mathis Logemann
9ac35a0a9c use use_count instead of unique()
This should be safe to use, since there aren't any weak_ptr's using the shared_ptr. Furthermore any async operations should be finished or guarded for multithreaded execution.
2022-01-25 10:21:27 +01:00
Artem Pavlenko
9e3bafcd4c
Merge pull request #4279 from mathisloge/fix/issue-4268
fix #4268 by adding mapped_memory_file
2022-01-25 08:54:50 +00:00
Mathis Logemann
a3ccf2967f [scons] add mapped_memory_file to source list 2022-01-24 21:21:45 +01:00
Artem Pavlenko
611fd93308
Merge pull request #4280 from mathisloge/feature/vcpkg
add vpkg.json manifest file
2022-01-24 17:04:17 +00:00
Mathis Logemann
c16aa1e5c4 add vpkg.json 2022-01-24 10:49:07 +01:00
Mathis Logemann
fe887a2c83 fix #4268 by adding mapped_memory_file 2022-01-24 10:45:32 +01:00
Mathis Logemann
26052486ee remove cxx11_support.hpp 2022-01-20 23:07:17 +01:00
Artem Pavlenko
fb06428250
Merge pull request #4275 from mathisloge/remove_make_unique_cpp11 2022-01-19 13:52:39 +00:00
Mathis Logemann
4f95463c75 remove make_unique 2022-01-19 12:42:52 +01:00
Artem Pavlenko
cf5541d180
Merge pull request #4272 from mathisloge/cite
add CITATION.cff
2021-12-14 11:44:10 +00:00
Mathis Logemann
3c2aff82bc add CITATION.cff 2021-12-14 10:49:22 +01:00
Artem Pavlenko
79901e494b
Merge pull request #4271 from mathisloge/fix/cmake_install
[CMake] do not install FindHarfbuzz.cmake
2021-12-03 14:02:53 +00:00
Mathis Logemann
7a1b441cf0 [CMake] do not install FindHarfbuzz.cmake 2021-12-03 14:48:13 +01:00
Artem Pavlenko
6d47d3b70f
Merge pull request #4270 from mathisloge/fix/cmake-proj
fix proj version detection / harfbuzz pkg-config for cmake
2021-12-03 10:54:29 +00:00
Mathis Logemann
d546cda6d5 [CMake] drop harfbuzz and use pkg-config as a backup 2021-11-20 12:53:58 +01:00
Mathis Logemann
eb4390b5a6 fix proj version detection for cmake 2021-11-19 20:04:22 +01:00
Mathis Logemann
92b1dbaf32 delete all data 2021-11-15 16:41:37 +01:00
Mathis Logemann
c5d3d9c188 wip 2021-11-15 16:39:10 +01:00
Mathis Logemann
c6619d042c check out correctly 2021-11-15 16:09:46 +01:00
Mathis Logemann
7195448334 all branches 2021-11-15 16:08:48 +01:00
Mathis Logemann
500728e51f test workflow 2021-11-15 16:08:27 +01:00
Mathis Logemann
4b66137654 initial docker 2021-11-15 15:32:58 +01:00
Artem Pavlenko
14f913d6ab
Merge pull request #4266 from mathisloge/cmake_improvments
[CMake] improve build structure
2021-11-15 14:21:13 +00:00
Mathis Logemann
a911e33d7b [CMake] add more build presets
[CMake] rename windows presets

Revert "[CMake] rename windows presets"

This reverts commit 381dcd606c0c8f4281a482ede0c8c4a9a6d912fa.

[CMake] rename windows presets
2021-11-15 11:30:59 +01:00
Mathis Logemann
fbb0ae1489 [CMake] fix building with zero plugins
[Cmake] fix null plugins

fix null
2021-11-15 00:55:58 +01:00
Mathis Logemann
7a7a8125a9 [CMake] remove obsolete statements/improve docs
[CMake] remove obsolete variables and improve docs

[CMake] remove proj env var
2021-11-15 00:40:48 +01:00
Mathis Logemann
f0940c2075 [CMake] move all build artifacts into same dir to remove the need of copy_dlls (except for plugins)
[CMake] improve BUILD_TESTING and use pkgconf for cairo on linux

[CMake] add Threads dependency to -Config
2021-11-15 00:40:47 +01:00
Artem Pavlenko
dc5f497495 catch.hpp - upgrade to v2.13.7 (to unlock c++20 support) 2021-11-02 14:16:07 +00:00
Artem Pavlenko
4eb38c1051
Merge pull request #4260 from mathisloge/windows_define
replace _WINDOWS with _WIN32
2021-10-25 10:25:50 +01:00
Mathis Logemann
e626ba2688 replace _WINDOWS with _WIN32 2021-10-21 18:22:53 +02:00
Artem Pavlenko
f2ab25cf98
Merge pull request #4257 from mathisloge/cmake-pkgconf-improv
[CMake] improve pkg-config export
2021-10-20 16:08:47 +01:00
Mathis Logemann
aa903c675f [CMake] improve pkg-config export
add needed libs

pkg-conf: move libmapnikjson and libmapnikjson to m_requires

make pkg multi config aware

update proj min ver

correct prefix

use the correct output name

add import prefixes, just in case
2021-10-20 16:23:04 +02:00
Artem Pavlenko
4695c42b51
Merge pull request #4253 from GimpMaster/master
Compile for vcpkg using VS2017
2021-10-18 15:18:48 +01:00
Artem Pavlenko
28378b81e8
Merge pull request #4254 from mathisloge/cmake_option_fix
[CMake] fix mapnik_option
2021-10-18 10:40:01 +01:00
Mathis Logemann
c551ed3a62 [CMake] fix mapnik_option 2021-10-16 08:31:19 +02:00
Mathis Logemann
aef71dbae5 [CMake] fix mapnik_option 2021-10-16 08:27:09 +02:00
Joshua Hintze
cab3ba345c -Removed unneeded macro escapes 2021-10-15 19:33:50 -06:00
Joshua Hintze
15798e6ebb -Fixed issue with VS2017 compiling 2021-10-15 19:31:45 -06:00
Artem Pavlenko
0edb018465
Merge pull request #4252 from mathisloge/cmake_mapnik_config
[CMake] Fix issues with tests, boost-regex and webp. Fix viewer qt6
2021-10-13 17:02:16 +01:00
Mathis Logemann
a89447686c remove mapnik-config 2021-10-13 17:47:38 +02:00
Mathis Logemann
5ef2e27e8e [CMake] add boost regex icu check 2021-10-13 10:16:39 +02:00
Mathis Logemann
01dccee231 Merge branch 'cmake_mapnik_config' of https://github.com/mathisloge/mapnik into cmake_mapnik_config 2021-10-13 09:04:31 +02:00
Mathis Logemann
83b4989bd4 [CMake] restore compability with 3.15 2021-10-13 09:04:26 +02:00
Mathis Logemann
561a79720e [CMake] unit-test add utilities to path 2021-10-12 23:00:48 +02:00
Mathis Logemann
6dee79f442 [CMake] mapnik::mapnik restructure. should give a better overview 2021-10-11 19:08:25 +02:00
Mathis Logemann
dea63374f4 [CMake] better logging of feature options. Output log files for better help management. ; get started with mapnik-config 2021-10-10 21:34:15 +02:00
Mathis Logemann
59f7a61661 [CMake] unit-test copy more data 2021-10-09 14:11:58 +02:00
Mathis Logemann
ba8a972254 [unit-test] fix formatting 2021-10-09 13:55:32 +02:00
Mathis Logemann
05c2278893 [CMake] add the search paths for the build executables automatically for ctest.; depend completly on the external catch2 2021-10-09 13:48:11 +02:00
Mathis Logemann
a73d2f7d94 [unit-tests] fix windows 11 path search 2021-10-09 13:46:55 +02:00
Mathis Logemann
bf6081b207 [unit-test] add std includes for external catch2 2021-10-09 13:46:24 +02:00
Mathis Logemann
ac95449ff5 [CMake] fix critical webp init 2021-10-09 09:40:44 +02:00
Mathis Logemann
56e8de6b16 [CMake] proj remove global 2021-10-09 08:44:03 +02:00
Mathis Logemann
1a5aea5653 [CMake] use pkgconf imported target for proj; see https://github.com/mapnik/mapnik/issues/4249#issuecomment-937214705 2021-10-08 20:21:18 +02:00
Mathis Logemann
a0525ddd26 [CMake] nativ harfbuzz don't publish a version. Therefore we can't depend on it. 4645c3b47c/CMakeLists.txt (L686) and following 2021-10-07 20:16:45 +02:00
Mathis Logemann
8714432a67 [viewer] fix qt6 2021-10-07 20:05:11 +02:00
Artem Pavlenko
d96b6843b3
Merge pull request #4251 from mathisloge/cmake_hotfix
[CMake] fix `mapnik_find_plugin_dir`
2021-10-06 16:10:11 +01:00
Mathis Logemann
95e210521c [CMake] fix mapnik_find_plugin_dir 2021-10-06 16:43:55 +02:00
Artem Pavlenko
6f01d7a34a
Merge pull request #4250 from mathisloge/boost_bump_1_73
bump boost version to 1.73 and fix docs
2021-10-06 14:23:05 +01:00
Mathis Logemann
feca084ed6 bump boost version to 1.73 and fix docs 2021-10-06 15:15:32 +02:00
Artem Pavlenko
a1a3a712dd
Merge pull request #4248 from mathisloge/cmake-fix
[CMake] Simplify install, add min versions and PkgConfig
2021-10-06 10:28:21 +01:00
Mathis Logemann
333e745d7b [CMake] pkg-config: generate correct library link file names 2021-10-01 20:42:57 +02:00
Mathis Logemann
8c83e15404 [CMake] fix export plugin file naming 2021-09-23 19:28:40 +02:00
Mathis Logemann
fa2fec338b [CMake] add import prefix for libmapnik
so that the resulting archive is also named libmapnik
2021-09-23 19:11:29 +02:00
Mathis Logemann
fcc7016124 add basic pkg-config exports 2021-09-23 18:46:48 +02:00
Mathis Logemann
a2d3364ec7 [CMake] add version and soversion to base libraries 2021-09-23 10:41:25 +02:00
Mathis Logemann
1c51a8e529 [CMake] add configuration dependend exports for plugin install dir.
add function to get the current plugin install dir
2021-09-23 10:33:32 +02:00
Mathis Logemann
5287c234d6 [CMake] fix resulting config when no plugins are build 2021-09-22 21:39:04 +02:00
Mathis Logemann
f1ed49edec install utilities 2021-09-22 20:49:44 +02:00
Mathis Logemann
35ea6f2a56 [CMake] refactor mapnik_install 2021-09-22 19:52:39 +02:00
Mathis Logemann
d57f0ac93a [Cmake] Fix cache description 2021-09-22 15:44:34 +02:00
Mathis Logemann
755e8d322e add minimum versions; proj include dir only as a build interface 2021-09-22 15:25:55 +02:00
Mathis Logemann
25774ac82a [CMake] unify and simplify install commands.; Add Components to targets 2021-09-22 14:41:50 +02:00
Mathis Logemann
9d4d7fd273 [CMake] do not print install targets 2021-09-22 13:19:43 +02:00
Artem Pavlenko
1ccbbf95b5
Merge pull request #4244 from mathisloge/cmake-pub-dep
[CMake] make mapnik::core a public dependency of mapnik::mapnik
2021-09-15 16:38:23 +01:00
Mathis Logemann
8bd463d4fc make mapnik::core a public dependency of mapnik::mapnik 2021-09-14 20:46:43 +02:00
Artem Pavlenko
737e7a69c2 Add includes required for building with boost_1_77 (46e3d9231c (diff-2eb9871858184271f07935b31093c2d9f70f7a219979bec85adc03db6721a182)) 2021-09-01 10:11:13 +01:00
Artem Pavlenko
69911ad9ea
Merge pull request #4191 from mathisloge/cmake-support
CMake build support
2021-08-30 09:44:14 +01:00
Mathis Logemann
f40822980e update to latest catch2 2021-08-25 17:25:23 +02:00
Mathis Logemann
02180115bf some last minor improvements 2021-08-25 16:41:57 +02:00
Artem Pavlenko
262f769ece Update test/data 2021-08-17 13:27:08 +01:00
Mathis Logemann
0198cad883 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-08-13 20:44:55 +02:00
Mathis Logemann
4b4cfca706 copy all plugins to the viewer build dir 2021-08-13 20:41:30 +02:00
Mathis Logemann
83e77559c4 update cmake docs 2021-08-13 17:21:46 +02:00
Artem Pavlenko
29eea37b38 Update test/data 2021-08-12 10:30:44 +01:00
Mathis Logemann
8500b3cd69 remove not needed include of <warning.hpp> 2021-07-24 00:58:28 +02:00
Mathis Logemann
a8d6bdcac1 [FindWebP] FOUND_VAR is deprecated 2021-07-23 18:41:30 +02:00
Mathis Logemann
fcda7021b6 Revert "found var was deprecated."
This reverts commit 6b5e4dcec2.
2021-07-23 18:41:07 +02:00
Mathis Logemann
6b5e4dcec2 found var was deprecated. 2021-07-23 18:40:57 +02:00
Mathis Logemann
001718cf73 some fixes for FindWebP 2021-07-23 18:39:42 +02:00
Mathis Logemann
872f1139db Merge branch 'cmake-support' of https://github.com/mathisloge/mapnik into cmake-support 2021-07-23 18:14:40 +02:00
Mathis Logemann
02fed92074 link with correct lib (clang) 2021-07-23 19:34:17 +02:00
Mathis Logemann
f80a7724bf delete clang toolchain(replaced by CMakePresets) 2021-07-23 18:14:37 +02:00
Mathis Logemann
ac6842656e enable qt6 or qt5 for mapnik-viewer. android could be dropped 2021-07-23 17:06:24 +02:00
Mathis Logemann
f90c684471 add missing generator to CMakePresets 2021-07-23 16:41:28 +02:00
Mathis Logemann
08791f496d add MAPNIK_STATS 2021-07-23 16:10:35 +02:00
Mathis Logemann
6739c30941 fixed some var refs 2021-07-23 16:04:25 +02:00
Mathis Logemann
42fec31784 add version again to FindWebP 2021-07-23 15:54:51 +02:00
Mathis Logemann
e2524f80df rewrite webp to add debug libraries 2021-07-23 15:48:17 +02:00
Mathis Logemann
72600b996e added missing options 2021-07-23 13:34:49 +02:00
Mathis Logemann
54e63dd9fe some docs 2021-07-22 23:05:48 +02:00
Mathis Logemann
01516c9603 fix 2021-07-22 22:56:00 +02:00
Mathis Logemann
1f6a794b43 add MAPNIK_DEBUG when using the mapnik debug configuration 2021-07-22 22:54:22 +02:00
Mathis Logemann
28d286ecb8 i really need to upgrade proj... 2021-07-22 22:46:23 +02:00
Mathis Logemann
d737569574 add presets 2021-07-22 22:45:39 +02:00
Mathis Logemann
4d3affb95d fix gdal include dir 2021-07-22 22:06:01 +02:00
Mathis Logemann
14944cd235 added some docs 2021-07-22 21:55:01 +02:00
Mathis Logemann
bbcf1c2009 add multithreaded 2021-07-22 21:45:25 +02:00
Mathis Logemann
b925abf403 fix library name 2021-07-22 21:35:12 +02:00
Mathis Logemann
03b1f18c89 make pkg-config optionally. But fail later when we actually need pkg-config as a fallback 2021-07-22 21:04:45 +02:00
Mathis Logemann
7b0aa9d3bf remove openjpeg again. was just a test 2021-07-22 20:45:16 +02:00
Mathis Logemann
3001e0c78a Revert "remove openjpeg again. was just a test."
This reverts commit bcc66a739c.
2021-07-22 20:44:36 +02:00
Mathis Logemann
bcc66a739c remove openjpeg again. was just a test. 2021-07-22 20:44:29 +02:00
Mathis Logemann
81397f84bc add debug postfix to wkt, json and mapnik.
Mapnik can be installed with multi configuration enviroment
2021-07-22 20:34:08 +02:00
Mathis Logemann
9998ca7dd9 fix gdal library variable 2021-07-22 20:17:03 +02:00
Mathis Logemann
3a2996e5b0 install mapbox headers when using NOT USE_EXTERNAL* 2021-07-21 20:20:44 +02:00
Mathis Logemann
199fd8218b this fixes a bug when including a package via pkg-config:
We will append the call to the config file to find the package
via find_package. However this does not work when the package was included
with pkg-config
2021-07-21 20:08:22 +02:00
Mathis Logemann
282986c503 fix config file naming scheme.
Only happens when using older cmake versions. But this was definitly an issue.
Target name should be the same on the file (case sensitive)
2021-07-21 20:03:42 +02:00
Mathis Logemann
e5cf5dda39 default to jpeg. 2021-07-21 18:24:40 +02:00
Mathis Logemann
c5ced60c38 fix some bugs when using ubuntu to build 2021-07-21 18:16:48 +02:00
Mathis Logemann
01159d0721 still forget proj everytime... 2021-07-07 21:11:28 +02:00
Mathis Logemann
59f9974baa TEMP: use openjpeg 2021-07-07 21:06:59 +02:00
Mathis Logemann
3397fff8ea add harfbuzz fallback 2021-07-06 22:46:07 +02:00
Mathis Logemann
cdb598e67b add harfbuzz minimum version and HarfBuzz::ICU target. probably fixes osx 2021-07-06 22:19:28 +02:00
Mathis Logemann
c5f0565654 remove subsequent boost require version calls. 2021-07-06 22:07:29 +02:00
Mathis Logemann
eb1236d5dd use proj *gr* 2021-07-06 21:32:58 +02:00
Mathis Logemann
e408bf9a22 add find harfbuzz.cmake 2021-07-06 21:32:36 +02:00
Mathis Logemann
6a19824c12 hate proj4... 2021-07-05 21:58:53 +02:00
Mathis Logemann
7a13a940df build plugins as modules. 2021-07-05 17:13:45 +02:00
Mathis Logemann
7231d06a46 ups. this shouldn't be commited 2021-07-02 22:43:01 +02:00
Mathis Logemann
7f2511632f add packaging 2021-07-02 22:26:36 +02:00
Mathis Logemann
d610671327 try install json and wkt again 2021-07-02 16:02:30 +02:00
Mathis Logemann
cdf41a3144 install sparsehash 2021-07-02 13:55:55 +02:00
Mickey Rose
51b118ef2f prevent files under scons/ from skewing repository language statistics 2021-07-02 11:00:28 +02:00
Mathis Logemann
d17abeddb7 [cmake] add folders for visual studio 2021-06-30 10:33:20 +02:00
Mathis Logemann
a7ec89a8a1 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-05-29 22:43:59 +02:00
Artem Pavlenko
0a8e353e83
Merge pull request #4230 from mapnik/c++20
C++20
2021-05-17 16:15:07 +01:00
Artem Pavlenko
0efdcafe56 make from_u8string inline 2021-05-17 16:11:53 +01:00
Artem Pavlenko
6fa2666747 Add convertion functions from_u8string to support c++20 + update tests 2021-05-17 16:11:44 +01:00
Artem Pavlenko
fb2e45c579 Upgrade to ICU 58.1 2021-04-28 17:05:24 +01:00
Mathis Logemann
4879efce58 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-04-22 19:41:35 +02:00
Mathis Logemann
5a109a99fb install dependencies only on windows and install plugins into correct dir 2021-04-22 19:41:21 +02:00
Artem Pavlenko
88a15daf93 Fix parse_svg_value 2021-04-22 11:36:10 +01:00
Artem Pavlenko
a1cb756fa0 SVG parse_svg_value: update is_percent only if parsing successful 2021-04-19 18:02:24 +01:00
Artem Pavlenko
3031b7cf6a SVG parse_svg_value/parse_font_size: re-initialise default val on parser failure 2021-04-19 08:55:39 +01:00
Artem Pavlenko
4ff25eb2a8 remove token 2021-04-16 17:26:44 +01:00
Artem Pavlenko
21fd41b9a9
Merge pull request #4225 from mapnik/svg-rendering-improvements
SVG rendering improvements
2021-04-16 09:51:25 +01:00
Artem Pavlenko
7c5f4539e1 Fix error message + update SVG parser unit test 2021-04-15 16:29:05 +01:00
Artem Pavlenko
fd204874ec svg2png - avoid writing to an empty image 2021-04-15 15:53:04 +01:00
Artem Pavlenko
654a3c1f9f SVG : refactor and simplify width/height+viewBox logic (https://www.w3.org/TR/SVG11/struct.html#SVGElement) + check font_sizes_ size before accesing last element 2021-04-15 15:38:59 +01:00
Artem Pavlenko
0feabeb7e8 SVG circle: ignore when r = 0 2021-04-13 13:48:05 +01:00
Artem Pavlenko
55370c3453 Update visual data 2021-04-13 10:26:39 +01:00
Artem Pavlenko
f293371a9d SVG rendering improvements:
* process `font-size` attributes and use them to scale `em` units
* fix default `color-stop` value
* store `viewBox` and use it to calculate `%` values correctly
* add more absolute/relative values
* default `DPI`:96
* default `font-size`: 10
* process style attributes on `<svg>` element
* use viewBox `width`, `height` and `normalized_diagonal` for relevant length values
* apply scale factor to gradient transforms
2021-04-13 09:19:33 +01:00
Artem Pavlenko
9c2132f895 Fix gradient transform calc (apply scale factor) 2021-04-13 09:17:48 +01:00
Artem Pavlenko
ff8c411749 Use DPI=96 + add absolute and relative sizes + add missing value units 2021-04-12 14:16:39 +01:00
Artem Pavlenko
4f783f61ed Init by value 2021-04-12 14:16:09 +01:00
Mathis Logemann
e1fa32f21f install dependencies. Required for windows (and ?macos?). Needs testing on linux. 2021-04-10 14:36:22 +02:00
Mathis Logemann
1929fbc0ba add an option to disable plugin and font copying 2021-04-09 15:53:21 +02:00
Mathis Logemann
02f78e4ce5 fixed Dll copying on windows; copy plugins and fonts into appropiate directories when building. 2021-04-09 15:50:50 +02:00
Mathis Logemann
b6d8f54779 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-04-06 18:38:51 +02:00
Artem Pavlenko
6bab4e56fd Move MAPNIK_DECL to the front (ref https://github.com/mapnik/mapnik/pull/4220#issuecomment-814259514) 2021-04-06 17:36:46 +01:00
Mathis Logemann
9049a7e58d Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-04-06 17:27:28 +02:00
Artem Pavlenko
8c3b9758eb
Merge pull request #4220 from mapnik/proj6
Simplify proj_transform_cache implementation
2021-04-06 11:58:44 +01:00
Artem Pavlenko
b974a4a683 Simplify proj_transform_cache implementation (ref https://github.com/mapnik/mapnik/pull/4191#issuecomment-813377082) 2021-04-06 10:30:12 +01:00
Mathis Logemann
5963c64960 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-04-01 18:17:39 +02:00
Artem Pavlenko
bb18a5ba0a
Merge pull request #4219 from mathisloge/proj_transform_fix
fixes proj_transform_cache incomplete type
2021-04-01 17:16:48 +01:00
Mathis Logemann
bed3ffb3dc fix typo grid renderer -> svg renderer 2021-04-01 18:01:43 +02:00
Mathis Logemann
ee90425de1 fixes proj_transform_cache incomplete type for gcc 2021-04-01 17:57:20 +02:00
Mathis Logemann
f57d39378d add BIGINT and MAPNIK_MEMORY_MAPPED_FILE; require cxx standard, disable compiler specific flags (CXX_EXTENSIONS) 2021-04-01 16:15:32 +02:00
Mathis Logemann
b1e1ea66f5 try fix linux take II 2021-04-01 16:03:58 +02:00
Mathis Logemann
7121bd6fbf Revert "hopefully fix unstatisfied proj_transform_cache"
This reverts commit d2066da339.
2021-04-01 15:55:57 +02:00
Mathis Logemann
d2066da339 hopefully fix unstatisfied proj_transform_cache 2021-03-31 20:25:46 +02:00
Mathis Logemann
8cd78b6945 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-03-26 20:04:30 +01:00
Artem Pavlenko
53669bc42e
Merge pull request #4202 from mapnik/proj6
Upgrade to new Proj APIs
2021-03-26 16:55:10 +00:00
Mathis Logemann
7897bb5c83 add threads to mapnik::core 2021-03-26 15:45:15 +01:00
Mathis Logemann
1367e7007f print version strings if available 2021-03-25 21:28:41 +01:00
Mathis Logemann
2b977f14c9 changed proj; add mapnik_proj_version; use boost regex icu workaround 2021-03-25 18:46:18 +01:00
Mathis Logemann
eb943d11d0 add postgis to unit tests 2021-03-25 18:42:17 +01:00
Artem Pavlenko
3489bdbe36 rename PROJ_VERSION to MAPNIK_PROJ_VERSION to avoid clashes with libproj 2021-03-25 16:38:21 +00:00
Mathis Logemann
0ab47e1fc6 Merge branch 'proj6' of https://github.com/mapnik/mapnik into cmake-support 2021-03-25 17:28:06 +01:00
Mathis Logemann
b2116fd9e9 added benchmarks; needed mutex header 2021-03-25 17:26:29 +01:00
Artem Pavlenko
f093d0cf6e Fix potential iterator out of range condition by using appropriate function (ref #4218) via @mathisloge
```
template< class InputIt1, class InputIt2, class BinaryPredicate >

bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2, InputIt2 last2,
            BinaryPredicate p );
```
2021-03-25 16:07:48 +00:00
Artem Pavlenko
5dfd1a24fc Fix potential iterator out of range condition by using appropriate function (ref #4218) via @mathisloge
```
template< class InputIt1, class InputIt2, class BinaryPredicate >

bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2, InputIt2 last2,
            BinaryPredicate p );
```
2021-03-25 16:03:15 +00:00
Mathis Logemann
c29c84327a add proj_transform_cache to source list 2021-03-25 13:34:25 +01:00
Mathis Logemann
f8b159f8ff Merge branch 'proj6' of https://github.com/mapnik/mapnik into cmake-support 2021-03-25 13:26:30 +01:00
Artem Pavlenko
503b9c5bbf Move proj_transform_cache declarations and implementaion into separate translation unit (ref VC++ C2492) 2021-03-25 12:16:15 +00:00
Mathis Logemann
0a3bb4e8bd update test data deps. somehow got messed up in last commit 2021-03-25 08:52:09 +01:00
Mathis Logemann
31c0b08548 renamed MAPNIK_USE_PROJ4 to MAPNIK_USE_PROJ and removed ACCEPT_USE_OF_DEPRECATED_PROJ_API_H 2021-03-24 23:55:12 +01:00
Mathis Logemann
59b97a57fc test data changes 2021-03-24 23:31:11 +01:00
Mathis Logemann
4eed15f87a Merge branch 'proj6' of https://github.com/mapnik/mapnik into cmake-support 2021-03-24 23:30:50 +01:00
Mathis Logemann
772e50ba79 copy basic dlls for mapnik-demo 2021-03-24 23:28:36 +01:00
Mathis Logemann
e963af53a5 find proj without config 2021-03-24 15:21:39 +01:00
Mathis Logemann
61a1248262 fix false default cmake install dir 2021-03-24 15:17:08 +01:00
Mathis Logemann
db6d1a1293 fix typo in text 2021-03-24 15:16:12 +01:00
Mathis Logemann
9835f07179 find and link icu first 2021-03-24 14:57:27 +01:00
Artem Pavlenko
c76f65a49a Add missing header (linux) 2021-03-24 11:44:56 +00:00
Artem Pavlenko
d756b534e3 Fix names and add welsh reference for good measure 2021-03-24 11:42:18 +00:00
Artem Pavlenko
2bb5bdb9fe Fix existing and add more transformation test + test for is_geographic (ref 3a302667a1) 2021-03-24 11:23:27 +00:00
Artem Pavlenko
f82ed08d6a Replace remaining MAPNIK_USE_PROJ4 -> MAPNIK_USE_PROJ 2021-03-24 11:22:32 +00:00
Artem Pavlenko
b24fc9a8da Remove proj4 related stuff 2021-03-24 11:21:50 +00:00
Artem Pavlenko
3a302667a1 Fix return value (MAPNIK_WEBMERCATOR_PROJ is not geographic SRS) 2021-03-24 09:42:52 +00:00
Artem Pavlenko
59aa5087fc upgrade libpq to 9.6.5 2021-03-22 16:03:08 +00:00
Artem Pavlenko
602948f783 Upgrade mason pkgs:
* libgdal 2.2.3
* libpng 1.6.32
* jpeg_turbo 1.5.2
* libtiff 4.0.8
2021-03-22 15:45:36 +00:00
Mathis Logemann
167461ccc4 rename internal name mapnik-core to core since the exported name would be mapnik::mapnik-core instead of mapnik::core. This fixes the issue 2021-03-19 22:51:50 +01:00
Artem Pavlenko
5afe22030f Fix proj_version on macOS 2021-03-19 16:37:21 +00:00
Artem Pavlenko
9df7afd0a3 Add 'proj_version' check + define PROJ_MIN_VERSION as 7.2.0 2021-03-19 13:24:14 +00:00
Artem Pavlenko
6af16764aa proj - add version check based on major*10000+minor*100+patch format 2021-03-19 13:22:16 +00:00
Artem Pavlenko
6b9b42f314 Declare proj_cache_ thread_local static to allow mapnik::Map to be thread-safe under certain conditions + refactor
(benchmark/src/test_rendering_shared_map.cpp)
2021-03-18 16:05:58 +00:00
Artem Pavlenko
ebbd544d75 Add text to indicate if proj_transform is internal or external (libproj) 2021-03-18 16:05:09 +00:00
Artem Pavlenko
9c7e21fa47 Re-use proj_transform as creating a new one is extremely expensive on libproj >= 6 (NOTE: epsg:4326 and epsg:3857 are special cases which use internal implementations and are not expensive to create on stack). 2021-03-18 15:32:13 +00:00
Mathis Logemann
36be4fe594 renamed target mapnik::headers to mapnik::core 2021-03-18 15:35:55 +01:00
Mathis Logemann
4604aee202 3.15 is the minium supported target. tested. 2021-03-17 23:06:49 +01:00
Mathis Logemann
4e898b2a52 added some basic READMEs 2021-03-17 22:37:46 +01:00
Mathis Logemann
ae43a49b71 add dependencies to cmake config. Provieded a new macro for better maintance 2021-03-17 22:18:21 +01:00
Mathis Logemann
a0d60f233b fixes cairo renderer debug configuration. Copied FindCairo had a lot of issues with the multiconfiguration settings. Rewrite of the whole file 2021-03-17 21:29:00 +01:00
Artem Pavlenko
199e609a79 Fix compiler warning - use non-reference type 'boost::tuples::cons<...>' 2021-03-16 11:49:53 +00:00
Artem Pavlenko
fbc6bec12a Update visual data references 2021-03-15 18:18:24 +00:00
Artem Pavlenko
56d63073b4 Update test 2021-03-15 18:10:09 +00:00
Artem Pavlenko
387d54fe9d Defer projection init 2021-03-15 18:09:21 +00:00
Artem Pavlenko
6099804559 Use POSIX definition of pi constant (M_PI) + define tau in terms of pi + better namings + remove deprecated proj4 style definitions 2021-03-15 18:06:26 +00:00
Mathis Logemann
c1d9bde886 fix find cairo 2021-03-15 10:03:26 +01:00
Mathis Logemann
f9d65edf20 oops. do not push github workflow 2021-03-15 08:57:50 +01:00
Mathis Logemann
79d369db1f Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2021-03-15 08:52:15 +01:00
Mathis Logemann
b3fb65edaa Merge branch 'master' of https://github.com/mathisloge/mapnik into cmake-support 2021-03-15 08:49:27 +01:00
Artem Pavlenko
baad6b3819 Update data and data-visual to use epsg:XXXX syntax to define SRS (old proj4 syntax is not recommended in proj >=6) 2021-03-12 16:24:11 +00:00
Artem Pavlenko
c71bcdc92d update visual tests affected by switching to well_known_srs 2021-03-12 14:39:14 +00:00
Artem Pavlenko
f432204180 Update test/data-visual 2021-03-12 13:14:31 +00:00
Artem Pavlenko
68efb709ed Fix mason version 2021-03-11 15:16:31 +00:00
Artem Pavlenko
ec880947e0 fix merge artifacts 2021-03-11 15:04:53 +00:00
Artem Pavlenko
342bf2947b Merge branch 'master' into proj6 2021-03-11 14:51:01 +00:00
Artem Pavlenko
74c79eb17c
Merge pull request #4217 from mapnik/scons-4.1.0
Scons 4.1.0
2021-03-11 14:45:32 +00:00
Artem Pavlenko
689aa4cdef Remove Proj.4 reference in preference to Proj 2021-03-11 14:11:44 +00:00
Artem Pavlenko
d9b7055cbe travis-ci - brew link postgresql postgis 2021-03-11 13:58:53 +00:00
Artem Pavlenko
b70e5adad0 remove extract token 2021-03-11 13:57:12 +00:00
Artem Pavlenko
a6ced1622c .travis.yml - use 'brew list --formula + brew link git` 2021-03-11 13:41:35 +00:00
Artem Pavlenko
13a6b0c03a .travis.yml - fix syntax typo 2021-03-11 12:40:15 +00:00
Artem Pavlenko
5f78b90572 travis-ci - revive postgis.input tests (call unlink brew pkga in script section) 2021-03-11 12:32:58 +00:00
Artem Pavlenko
466ff8c319 travis-ci - unlink all brew pkgs 2021-03-11 11:15:33 +00:00
Artem Pavlenko
e91d1ec0a5 travis-ci - brew list 2021-03-11 10:56:47 +00:00
Artem Pavlenko
93f239f5cb travis-ci print brew info proj/boost 2021-03-11 10:13:44 +00:00
Artem Pavlenko
256ee86104 unit tests - don't run projection transformations tests which require libproj when MAPNIK_USE_PROJ4 is not set 2021-03-11 09:58:24 +00:00
Artem Pavlenko
692907761a Add more diagnostic stderr 2021-03-10 16:36:13 +00:00
Artem Pavlenko
5d5cc3a5db Try building without postgis.input 2021-03-10 12:22:14 +00:00
Artem Pavlenko
f5d911968f Force remove system boost_1_74 2021-03-10 11:46:52 +00:00
Artem Pavlenko
abf05e8bc8 Remove (attempting) system boost 2021-03-10 11:37:37 +00:00
Artem Pavlenko
5d88fa4a2c Let's see if upgrading xcode to 12.2 solves the boost issue 2021-03-10 11:11:45 +00:00
Artem Pavlenko
8271bbde06 Merge branch 'master' into scons-4.1.0 2021-03-10 09:34:57 +00:00
Artem Pavlenko
0714e61545 Refactor "Query map point" unit test 2021-03-09 16:29:23 +00:00
Artem Pavlenko
ebc3dabd6d Add basic Map::query_map_point test 2021-03-09 16:14:26 +00:00
Artem Pavlenko
0e0d222ede Print mapnik::Map (useful gathering query_map_point data) 2021-03-09 16:13:20 +00:00
Artem Pavlenko
f8877e2263 Add missing &copy 2021-03-09 16:12:54 +00:00
Artem Pavlenko
eb49b5776a Fix BBOX in geographic WGS84 (epsg:4326) calc logic 2021-03-09 15:02:11 +00:00
Artem Pavlenko
977c65e9de Fix proj_transform order in Map::query_point 2021-03-09 11:33:21 +00:00
Artem Pavlenko
7cbbd7305b Map::mapnik - restore non-const access to layers + create proj_transform and cache in get_proj_transform + declare proj_cache_ mutable 2021-03-09 10:48:32 +00:00
Artem Pavlenko
8f126a1000 Fix updateData signal signature so it actually works + cleanups 2021-03-08 13:21:01 +00:00
Artem Pavlenko
fb325f527b Fix updateData signal signature so it actually works + cleanups 2021-03-08 13:19:11 +00:00
Artem Pavlenko
f1fc3c4948 Update mason version 2021-03-05 15:42:32 +00:00
Artem Pavlenko
1259b1d333 try boost 1.75.0 2021-03-05 15:37:23 +00:00
Artem Pavlenko
2cd0c91215 Attempting to fix travis-ci :D 2021-03-05 15:32:21 +00:00
Artem Pavlenko
e8c2ba7eeb travis-ci - revert back to language:generic 2021-03-05 14:22:20 +00:00
Artem Pavlenko
61a73d21e6 bootstrap.sh - boost 1.74 + remove libexpat dep 2021-03-05 14:18:03 +00:00
Artem Pavlenko
459ea9f486 travis-ci - upgrade to xcode11 2021-03-05 12:42:13 +00:00
Artem Pavlenko
3c475ab7da travis-ci - set PYTHON=python3 globally 2021-03-05 11:08:20 +00:00
Artem Pavlenko
6124b1fae8 set PYTHON env var to python3 2021-03-05 11:04:07 +00:00
Artem Pavlenko
1bc84b837a attempting to force python3 2021-03-05 10:52:33 +00:00
Artem Pavlenko
65273e7a07 .travis.yml - set language to c++ 2021-03-05 10:45:35 +00:00
Artem Pavlenko
489154b342 remove python2 stuff 2021-03-05 10:35:20 +00:00
Artem Pavlenko
84a05a6597 Upgrade to Scons 4.1.0 2021-03-05 10:18:26 +00:00
Artem Pavlenko
b532beccde mapnik::Map ctor/operator= - initialise proj transforms 2021-03-04 10:19:44 +00:00
Artem Pavlenko
554556e4d5 Add support for libproj >=8 2021-03-04 10:18:42 +00:00
Artem Pavlenko
b75737fd6a Implement proj_transform caching using boost::unordered_map which allows calling find method with compatible key type.
In this case `std::pair<boost::string_view, boost::string_view>` avoiding potentially expensive temp string keys.
(TODO: In the future use c++20 `std::unordered_map::find` transparent keys facility)
2021-03-03 15:01:58 +00:00
Artem Pavlenko
6fedae386d add c++20 2021-03-03 11:13:42 +00:00
Artem Pavlenko
11ff758c38 Add proj_transform::definition() method 2021-03-02 17:07:13 +00:00
Artem Pavlenko
a149ebed16 use std::size_t consistently (proj API) 2021-03-02 16:39:32 +00:00
Artem Pavlenko
cb75f00780 Move proj_transform initialisation to add_layer method 2021-02-25 11:05:11 +00:00
Mathis Logemann
3a6362f1a9 added clang toolchain file 2021-02-05 19:35:35 +01:00
Artem Pavlenko
c3eda40e01
Update to travis.com 2021-02-04 13:34:03 +00:00
Mathis Logemann
2009598cdc cmake do not test cmp0110 on versions less 3.19 2021-02-03 22:53:02 +01:00
Mathis Logemann
74b325e71a fix comment 2021-02-03 22:48:25 +01:00
Mathis Logemann
54a61f7553 add dlcfn on non windows systems 2021-02-03 22:47:15 +01:00
Mathis Logemann
5f02b197dd get mapnik version from mapnik/version.hpp 2021-02-03 19:43:28 +01:00
Mathis Logemann
1f73d1c771 rename boost::boost to boost::headers, added missing icu components 2021-02-03 19:29:43 +01:00
Mathis Logemann
dec9056511 remove unnecessary cmake_minimum_required from sub projects 2021-02-03 19:14:08 +01:00
Artem Pavlenko
e5c182591a use unordered_map for proj_transform caching 2021-02-01 10:57:52 +00:00
Artem Pavlenko
5c086b0cd5 Add proj_transform caching to minimise expensive initialisations calls in libproj >= 6 [WIP] 2021-01-27 09:40:28 +00:00
Mathis Logemann
0b76278adc its getting too late.. 2021-01-27 01:22:41 +01:00
Mathis Logemann
4bc99d8047 should use the ADDITIONAL_LIBARIES_PATHS var... 2021-01-27 01:20:32 +01:00
Mathis Logemann
e60d4368ed add option to disable shared lib fixup 2021-01-27 01:17:00 +01:00
Mathis Logemann
d159bec46a FindCairo: find debug release library 2021-01-27 00:42:19 +01:00
Mathis Logemann
a7c9f5b941 windows: copy all dlls. optional library dir if some dlls are not found. 2021-01-27 00:41:54 +01:00
Mathis Logemann
247ceff7a7 temporarily remove find dll. only windows specific. needs better impl 2021-01-24 19:36:01 +01:00
Mathis Logemann
953796645f enable position independent code for wkt and json 2021-01-24 19:35:21 +01:00
Mathis Logemann
14f4362bb5 better support for proj 2021-01-24 19:34:51 +01:00
Artem Pavlenko
db9829d702 Fix missing proj context and cleanup/simplify proj_transform 2021-01-22 15:23:11 +00:00
Artem Pavlenko
6cc353f8a2 Use 'proj_backward_strategy' and avoid creating an extra proj_transform 2021-01-22 15:22:18 +00:00
Artem Pavlenko
ff14ad3425 Link to libsqlite3 when required 2021-01-21 12:47:41 +00:00
Artem Pavlenko
19511463ab Include <cmath> for HUGE_VAL 2021-01-21 12:46:57 +00:00
Artem Pavlenko
d35f0596d1 Update data-visual 2021-01-21 11:01:20 +00:00
Artem Pavlenko
b1982cc68a Upgrade to latest mason + proj-v7.2.1 + sqlite-v3.34.0 2021-01-21 10:59:54 +00:00
Artem Pavlenko
88241b32ee Initial implementation of new proj7 APIs support 2021-01-15 15:21:09 +00:00
Artem Pavlenko
bec509d5b8 Merge branch 'master' into proj6 2021-01-12 15:09:10 +00:00
Artem Pavlenko
bd961c4da2 update copyright year [skip ci] 2021-01-05 14:39:07 +00:00
Artem Pavlenko
c8b8b5c1d0
Merge pull request #4194 from mathisloge/warning-fix
fix warning for unknown compiler
2020-12-17 15:49:46 +00:00
Mathis Logemann
002c6e2a5e remove vcpkg folder 2020-12-17 10:21:25 +01:00
Mathis Logemann
6a286c7ac2 Merge branch 'master' of https://github.com/mapnik/mapnik into warning-fix 2020-12-17 10:16:52 +01:00
Mathis Logemann
bf51fc8650 Merge branch 'master' of https://github.com/mapnik/mapnik into cmake-support 2020-12-17 10:14:40 +01:00
Artem Pavlenko
cb4f1ff63a
Merge pull request #4199 from mapnik/travis
upgrade dist+toolchain
2020-12-16 14:25:13 +00:00
Artem Pavlenko
176b4bf8f7 travis ci - remove glibcxx workaround check as we're building on xenial 2020-12-16 13:48:53 +00:00
Artem Pavlenko
dca32e5cf3 travis ci - downgrade to isu 57.1 and boost 1.73.0 2020-12-16 11:13:11 +00:00
Artem Pavlenko
fb6334287a re-enable glibc workaround 2020-12-11 13:02:25 +00:00
Artem Pavlenko
9127d6334e travis-ci - update to postgis-2.4 2020-12-11 12:36:37 +00:00
Artem Pavlenko
17a1c72f41 fix .travis 2020-12-11 11:47:04 +00:00
Artem Pavlenko
6f36340888 upgrade dist+toolchain 2020-12-11 11:29:51 +00:00
Artem Pavlenko
7520e16340 travis-ci - disable Linux/gcc build 2020-12-10 13:00:48 +00:00
Artem Pavlenko
9c76fdc3bb Merge remote-tracking branch 'origin/master' 2020-12-10 11:18:25 +00:00
Artem Pavlenko
006c66e488 Remove sudo : false per https://docs.travis-ci.com/user/reference/trusty#container-based-infrastructure 2020-12-03 09:14:24 +00:00
Artem Pavlenko
834c1eac44
Merge pull request #4197 from Nonemoticoner/patch-1
Fix dead link to tutorials in INSTALL.md
2020-12-02 15:44:01 +00:00
Nonemoticoner
34a42a8fa1
Fix dead link to tutorials in INSTALL.md 2020-12-01 23:10:43 +01:00
Artem Pavlenko
8e1ff0785a Merge branch 'master' into proj6 2020-11-30 15:10:13 +00:00
Mathis Logemann
cbd19b6052 use status message 2020-11-25 15:42:33 +01:00
Mathis Logemann
410393fefa do not use absolute paths for fonts/plugins 2020-11-25 13:20:07 +01:00
Mathis Logemann
b3a34de3ce some line endings 2020-11-25 12:17:31 +01:00
Mathis Logemann
f432018bdb added cache variable for lib/bin/archive output 2020-11-25 12:16:06 +01:00
Mathis Logemann
9ede58f2b7
create boilerplate code 2020-11-25 10:56:49 +01:00
Mathis Logemann
37dd7c17df update catch dep 2020-11-25 10:45:20 +01:00
Mathis Logemann
8096bd869f fix warning for unknown compiler 2020-11-25 08:47:51 +01:00
Mathis Logemann
f027667daa added correct plugin default paths 2020-11-25 08:23:41 +01:00
Artem Pavlenko
765e1ad0c6 Upgrade to ICU 58.1 + mason 2020-11-23 16:04:01 +00:00
Mathis Logemann
983087b5c5 cache var for cxx standard 2020-11-22 22:11:27 +01:00
Mathis Logemann
f6acf4c027 do not use the install interface for mapbox deps 2020-11-22 22:06:15 +01:00
Mathis Logemann
85736c4c95 name fonts correctly 2020-11-22 22:02:17 +01:00
Mathis Logemann
68528ffb28 cmake improvements 2020-11-22 22:01:33 +01:00
Mathis Logemann
29cd904c5f fix one forgotton native() 2020-11-21 19:16:47 +01:00
Mathis Logemann
f68f7e88de fixed map_xml_test 2020-11-21 19:03:55 +01:00
Mathis Logemann
45fd654898 added MAPNIK_DECL to interior and polylabel explicit template 2020-11-21 18:19:58 +01:00
Mathis Logemann
b11ef9d44b removed MAPNIK_DECL from feature_style_processor; conflicts with the feature_style_processor_impl.h 2020-11-21 18:18:21 +01:00
Mathis Logemann
691d385687 comment not workable test out 2020-11-21 18:17:32 +01:00
Mathis Logemann
99d8c3e503 fix cmake typo 2020-11-21 18:04:24 +01:00
Mathis Logemann
695ad02cb2 fix svg renderer 2020-11-21 18:01:48 +01:00
Mathis Logemann
96a8327d06 add libraries to test 2020-11-21 17:45:44 +01:00
Mathis Logemann
0eb0408cc3 add options for grid/svg renderer 2020-11-21 17:03:30 +01:00
Mathis Logemann
3eb00b9794 use feature test for <execution> 2020-11-21 15:41:03 +01:00
Mathis Logemann
096befe69e try with c++14 2020-11-21 15:34:13 +01:00
Mathis Logemann
0084628d61 use only c++17 with extensions.. 2020-11-21 15:18:31 +01:00
Mathis Logemann
07546fe098 enable c++17 and do not use c++ extensions 2020-11-21 15:10:20 +01:00
Mathis Logemann
744aa2a76a do not compile features.... 2020-11-21 15:02:07 +01:00
Mathis Logemann
9213f76d49 do not compile features if they are not set 2020-11-21 14:54:26 +01:00
Mathis Logemann
f447cad781 add initial test support 2020-11-21 13:20:04 +01:00
Mathis Logemann
9a132080b5 add proj required define 2020-11-21 12:50:11 +01:00
Mathis Logemann
8de67bc262 add support for proj4 2020-11-21 12:38:29 +01:00
Mathis Logemann
3990fbe1dd add options to enable/disable utilitys 2020-11-21 12:30:34 +01:00
Mathis Logemann
e3789e219a build utilities correctly 2020-11-21 12:24:34 +01:00
Mathis Logemann
f390a830ae remove plugins from generated targets; install includes 2020-11-21 11:40:55 +01:00
Mathis Logemann
6254f7c09e more cmake 2020-11-21 11:34:45 +01:00
Mathis Logemann
7d46eda60d more options 2020-11-21 10:09:29 +01:00
Mathis Logemann
895d89a125 optional libraries 2020-11-21 09:46:54 +01:00
Mathis Logemann
d86a90a10a more cmake 2020-11-20 21:15:27 +01:00
Mathis Logemann
e6f6d0f133 more cmake 2020-11-20 20:20:28 +01:00
Mathis Logemann
5420ccd6af now fix msvc compiler error. Why does msvc complain? 2020-11-20 20:16:27 +01:00
Mathis Logemann
621ab99961 Revert "fix mscv compiler errors"
This reverts commit fe3160ca99.
2020-11-20 20:11:42 +01:00
Mathis Logemann
fe3160ca99 fix mscv compiler errors 2020-11-20 20:02:40 +01:00
Mathis Logemann
f6b7bc0867 add string to box2d which is required by msvc 2020-11-20 19:04:30 +01:00
Mathis Logemann
945e57286b initial cmake scripts 2020-11-20 18:20:43 +01:00
Artem Pavlenko
c945dd7195 Merge branch 'mathisloge-master' 2020-11-20 10:09:30 +00:00
Mathis Logemann
16b98fe3e7 more msvc warnings 2020-11-19 17:53:44 +01:00
Mathis Logemann
a2df8b7ad2 use absolute include 2020-11-19 17:45:40 +01:00
Mathis Logemann
a06e4efcb1 Merge branch 'master' of https://github.com/mathisloge/mapnik 2020-11-19 17:25:26 +01:00
Mathis Logemann
64054fade4 compiler independent warning ignore
Signed-off-by: Mathis Logemann <mathisloge@gmail.com>
2020-11-19 17:25:10 +01:00
Mathis Logemann
75643e6f68 compiler independent warning ignore 2020-11-19 15:30:30 +01:00
Artem Pavlenko
4227fd5d69 c++ style casts 2020-11-18 16:15:59 +00:00
Artem Pavlenko
3ae38bbab1 Fix typo pos.second -> pos.size (via @mathisloge) ref #4187 2020-11-18 15:58:00 +00:00
Artem Pavlenko
309c7b3422 Update sqlite to v3.21.0 2020-10-22 16:25:53 +01:00
Artem Pavlenko
12cdc1af69 Update test values (epsg:2193) 2020-10-22 16:13:57 +01:00
Artem Pavlenko
f9b18c3614 fix proj version typo 2020-10-22 16:13:33 +01:00
Artem Pavlenko
8cba41b2d8 Upgrade to latest mason ed144f5b 2020-10-22 16:03:26 +01:00
Artem Pavlenko
5abb40e3be Update proj to 6.1.0 (travis) 2020-10-22 15:58:51 +01:00
Artem Pavlenko
c6fc956a77 Upgrade to boost 1.74 and latest mason 2020-10-19 12:27:41 +01:00
Artem Pavlenko
3a58dd89b5 Use mapnik::value_integer for id type in feature generator 2020-10-19 12:09:42 +01:00
Artem Pavlenko
a9d9f7ed99 add unit test #4177 2020-10-09 10:03:00 +01:00
Artem Pavlenko
4fbf8a054f
Merge pull request #4178 from mapnik/issue-4177
`null` properties in `Feature` object
2020-10-09 09:37:24 +01:00
Artem Pavlenko
7ecff4b693
Merge pull request #4173 from mapnik/c++17
Support for C++17 builds
2020-10-09 09:34:41 +01:00
Artem Pavlenko
7d1a559ae2 GeoJSON - allow 'null' properties in Feature objects [#4177] 2020-10-08 10:53:12 +01:00
Artem Pavlenko
fba418d20b <execution> is available starting from c++17 2020-09-10 18:00:12 +01:00
Artem Pavlenko
277de45dbc Add support to setup c++ stanfard via CXX_STD (defalt to 14) 2020-09-10 17:50:21 +01:00
Artem Pavlenko
adced85761 Implement is_solid using stdlib <algorithm> `find_if 2020-09-10 15:57:19 +01:00
Artem Pavlenko
5629a6fb6f Require c++17 support 2020-09-10 15:56:38 +01:00
Artem Pavlenko
d6d69df498 Update catch.hpp to v2.13.1 + fix tests 2020-09-10 15:34:52 +01:00
Artem Pavlenko
ea7003628f variant - update to v1.2.0 2020-08-03 15:58:37 +01:00
Artem Pavlenko
9cb1b7e37f perfect forwarding in apply_visitor alias 2020-07-13 10:26:59 +01:00
Artem Pavlenko
8913b673c3 remove unused function 2020-07-09 12:57:37 +01:00
Artem Pavlenko
6e40d4bcf7 Update to boost 1.73.0 and latest mason 2020-06-15 14:39:18 +01:00
Artem Pavlenko
4bd05cec22 Add missing include (bootstrap build) 2020-06-15 14:38:23 +01:00
Artem Pavlenko
8901fd0fa5 Dropping boost version to 1.67.0 (as 1.72.0 is missing program_options) 2020-05-12 18:54:35 +01:00
Artem Pavlenko
e45b7571a8 Update mason version to 250ac4b 2020-05-12 13:19:05 +01:00
Artem Pavlenko
1079264aea Update boost version to 1.72.0 2020-05-12 12:49:53 +01:00
Artem Pavlenko
ed1696db4a
Merge pull request #4144 from mapnik/boost_1_73
boost_1_73 support
2020-05-12 12:46:05 +01:00
Artem Pavlenko
cc78a5de78 Fix for boost < 1.70.0 (ref #4143) 2020-05-12 12:14:18 +01:00
Artem Pavlenko
a14d27f090 Attempting to fix boost_1_65_1 compile (WIP) 2020-05-12 12:00:25 +01:00
Artem Pavlenko
8f3dded093 Re-implement feature_json_generator by adapting feature_impl into boost::fusion container and removing use semantic actions (simpler code + boost_1_73 support) (ref #4143) 2020-05-11 22:18:55 +01:00
Artem Pavlenko
d0b40f62dc Relax bounding box extracting grammar (ref #4140) + unit test 2020-05-07 11:35:53 +01:00
Artem Pavlenko
9bfe888cef Add missing unit test for color::operator= and color::operator== (ref #4137) 2020-04-23 18:20:32 +01:00
Artem Pavlenko
52ae365c66 fix operator== (ref #4137) 2020-04-23 18:20:32 +01:00
Artem Pavlenko
cb638eaabf color::swap - add missing premultiplied_ (ref #4137) 2020-04-23 18:20:32 +01:00
Artem Pavlenko
3e178a2153
Merge pull request #4132 from zdila/master
add support for spacing-offset
2020-04-02 10:00:37 +01:00
Artem Pavlenko
11cbc189f3
Merge pull request #4128 from dirkvdb/master
Update SConstruct to fix osx build
2020-04-02 09:56:26 +01:00
Martin Ždila
657442947b add support for spacing-offset 2020-03-23 23:07:49 +01:00
Dirk Vanden Boer
ddd2ceae63
Update SConstruct
Fixed framework presence check to avoid TypeError:
TypeError: a bytes-like object is required, not 'str':
2020-02-27 21:03:43 +01:00
Artem Pavlenko
e3f4e76c47
Merge pull request #4124 from cpaulik/gdal-int32-support
Add Int32 support for gdal driver
2020-02-11 12:15:32 +00:00
Christoph Paulik
5a73efbb07 Add Int32 support for gdal driver 2020-02-11 12:30:03 +01:00
Artem Pavlenko
1784c4f03e
Merge pull request #4123 from mapnik/svg-css
SVG: basic CSS support
2020-02-07 14:26:10 +00:00
Artem Pavlenko
d26fc722d5 Add SVG renderer unit test - both inline and css styled octocat result in identical image (ref PR #4123) 2020-02-07 13:53:06 +00:00
Artem Pavlenko
8d73767949 css-parser-grammar: parse values into iterator_range via boost::spirit::x3::raw directive (no conversions) + cleanup 2020-02-06 11:23:02 +00:00
Artem Pavlenko
0d693b151d svg2png: use svgBBOX() to calculate output PNG dimensions when no valif width or height (or viewBox) is specified. 2020-02-05 15:06:11 +00:00
Artem Pavlenko
c69e467ad0 SVG: basic CSS styles processor (TODO: fix inefficient and redundant value=>string=>value transformations) 2020-02-05 15:03:14 +00:00
Artem Pavlenko
2ddbff46d5 add bool css_style_ member variable to control CSS style processing. 2020-02-04 17:30:58 +00:00
Artem Pavlenko
cc9e8e3db3 add missing headers 2020-02-04 15:15:32 +00:00
Artem Pavlenko
27bf941211 SVG CSS: refactor unit value symbols table into separate header + add css_data member to svg_parser 2020-02-04 15:02:41 +00:00
Artem Pavlenko
b6e567d87c SVG CSS: add basic parsing of <style> [C]DATA 2020-02-04 11:41:22 +00:00
Artem Pavlenko
4d54e81889 Use char const* as iterator type for CSS grammar 2020-02-04 11:40:52 +00:00
Artem Pavlenko
8a90551b63 SVG CSS - add <style> element handler 2020-02-04 11:25:35 +00:00
Artem Pavlenko
00b888c1ef Add CSS parser grammar + move into separate include/css and src/css dirs. 2020-02-04 10:38:34 +00:00
Artem Pavlenko
3be9ce8fa0
Merge pull request #4122 from lightmare/prevent-duplicate-flags
scons: prevent duplication of linker flags
2020-01-30 20:02:12 +00:00
Mickey Rose
be017f1945 scons: prevent duplication of linker flags 2020-01-30 18:38:20 +01:00
Mickey Rose
6f4c15d077 scons: improve parsing CUSTOM_LDFLAGS
With the help of SCons.Environment.ParseFlags, split user-supplied
CUSTOM_LDFLAGS into appropriate option lists: LIBPATH, LIBS, etc.
Known non-linker options (like -Dx -I.) will be reported and ignored,
unrecognized options will be appended to LINKFLAGS.
2020-01-30 16:32:23 +00:00
Artem Pavlenko
3dee9b634f Merge branch 'lightmare-fix-write_config' 2020-01-30 16:31:51 +00:00
Artem Pavlenko
82533b2f7a Merge branch 'fix-write_config' of https://github.com/lightmare/mapnik into lightmare-fix-write_config 2020-01-30 16:31:21 +00:00
Artem Pavlenko
0636734f8f Revert "move sparsehash out of mapnik dir"
This reverts commit 720fbc74a1.
2020-01-30 15:14:37 +00:00
Mickey Rose
39202f5ac0 mapnik-config: fix substitution of environment variables
Simply calling str(val) doesn't work, because if the value happens to
be a SCons.Util.CLVar, it may contain not just plain strings, but also
tuples appended by SCons.Environment.ParseFlags.

For example "-isysroot /foo" becomes CLVar: [("-isysroot", "/foo")]

CLVar.__str__ supports only string elements, nothing else.
2020-01-30 15:15:14 +01:00
Artem Pavlenko
26d3084ead Revert "scons: improve parsing CUSTOM_LDFLAGS" -- this change introduced env.ParseFlags which broke mason/travis integration
This reverts commit a25f53e667.

Revert "SCons.Util.CLVar:  fix __str__ method to flatten tuples + revert "add print to debug travis (temp)""

This reverts commit 2e78959435.

Revert "add print to debug travis (temp)"

This reverts commit 65dce899cb.

ref #4120
2020-01-30 09:45:13 +00:00
Artem Pavlenko
2e78959435 SCons.Util.CLVar: fix __str__ method to flatten tuples + revert "add print to debug travis (temp)" 2020-01-29 22:11:11 +00:00
Artem Pavlenko
65dce899cb add print to debug travis (temp) 2020-01-29 17:15:22 +00:00
Artem Pavlenko
b22d5d2fac update and pin deps/mapbox to latest tags: protozero 1.6.8, variant 1.1.6, polylabel 1.0.3 2020-01-29 14:35:31 +00:00
Artem Pavlenko
720fbc74a1 move sparsehash out of mapnik dir 2020-01-29 14:16:47 +00:00
Artem Pavlenko
c7d29b826f Add "darkslategray" and "rebeccapurple" named colors (ref: https://drafts.csswg.org/css-color/#typedef-color) 2020-01-24 15:26:10 +00:00
Artem Pavlenko
7e604ed8b0
Merge pull request #4113 from mapnik/svg-fixes
Svg fixes
2020-01-24 10:19:40 +00:00
Artem Pavlenko
fe893134a5
Merge pull request #4114 from sebastic/libxml2
Use pkg-config for libxml2.
2020-01-21 15:09:08 +00:00
Bas Couwenberg
c4fda867c0 Use pkg-config for libxml2. 2020-01-21 15:13:09 +01:00
2521 changed files with 506903 additions and 70314 deletions

94
.clang-format Normal file
View file

@ -0,0 +1,94 @@
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

1
.gitattributes vendored
View file

@ -1 +1,2 @@
*.svg text eol=lf *.svg text eol=lf
scons/** linguist-vendored

85
.github/actions/run_tests/action.yml vendored Normal file
View file

@ -0,0 +1,85 @@
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 Normal file
View file

@ -0,0 +1,136 @@
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 Normal file
View file

@ -0,0 +1,55 @@
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

7
.gitignore vendored
View file

@ -1,4 +1,6 @@
.DS_Store .DS_Store
.vscode
.cache
*.gcov *.gcov
*.gcda *.gcda
*.gcno *.gcno
@ -56,3 +58,8 @@ demo/viewer/ui_layer_info.h
test/standalone/*-bin test/standalone/*-bin
test/unit/run test/unit/run
test/visual/run test/visual/run
# cmake
build
.vs
CMakeUserPresets.json

16
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,16 @@
# 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]

View file

@ -1,111 +0,0 @@
language: generic
git:
depth: 10
submodules: false
env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- PREFIX=/tmp/mapnik
- secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM="
cache:
directories:
- $HOME/.ccache
dist: trusty
sudo: false
matrix:
include:
- os: linux
name: Linux gcc-6
env: >-
CXX="ccache g++-6"
CC="gcc-6"
addons:
postgresql: "9.5"
apt:
sources: [ 'ubuntu-toolchain-r-test']
packages: [ 'libstdc++-6-dev', 'g++-6', 'xutils-dev', 'postgresql-9.5-postgis-2.3' ]
- os: linux
name: Linux clang-3.9
env: >-
CXX="ccache clang++-3.9 -Qunused-arguments"
CC="clang-3.9"
ENABLE_GLIBC_WORKAROUND=true
before_install:
- export LINKFLAGS="-fuse-ld=gold-2.26"
addons:
postgresql: "9.5"
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'clang-3.9', 'libstdc++-4.9-dev', 'xutils-dev', 'postgresql-9.5-postgis-2.3' ]
- os: linux
name: Linux clang-3.9 + coverage
env: >-
CXX="ccache clang++-3.9 -Qunused-arguments"
CC="clang-3.9"
COVERAGE=true
QUIET=true
before_install:
- export LINKFLAGS="-fuse-ld=gold-2.26"
- export LLVM_COV="llvm-cov-3.9"
addons:
postgresql: "9.5"
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'clang-3.9', 'llvm-3.9', 'libstdc++-4.9-dev', 'xutils-dev', 'postgresql-9.5-postgis-2.3' ]
- os: osx
name: OSX clang
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
osx_image: xcode7.3 # upgrades clang from 6 -> 7
env: >-
CXX="ccache clang++ -Qunused-arguments"
install:
- source scripts/travis-common.sh
# workaround travis rvm bug
# http://superuser.com/questions/1044130/why-am-i-having-how-can-i-fix-this-error-shell-session-update-command-not-f
- on 'osx' rvm get head || true
- export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PATH}
- export COVERAGE=${COVERAGE:-false}
- export BENCH=${BENCH:-false}
- on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres
- on 'osx' rm -rf ${DATA_PATH}
- on 'osx' initdb ${DATA_PATH} -E utf8
- on 'osx' pg_ctl -w start -l postgres.log --pgdata ${DATA_PATH};
- on 'osx' cat postgres.log;
- on 'osx' createuser -s postgres
- psql -c 'create database template_postgis;' -U postgres
- psql -c 'create extension postgis;' -d template_postgis -U postgres
- enabled ${COVERAGE} curl -S -f https://codecov.io/bash -o codecov
- enabled ${COVERAGE} chmod +x codecov
before_script:
- export JOBS=${JOBS:-4}
- export HEAVY_JOBS=${HEAVY_JOBS:-2}
- export SCONSFLAGS='--debug=time'
- source bootstrap.sh
- ccache --version
- ccache -p || true
- ccache --show-stats || true
- commit_message_parse
script:
- git_submodule_update --init deps/
- configure BENCHMARK=${BENCH} ENABLE_GLIBC_WORKAROUND=${ENABLE_GLIBC_WORKAROUND:-false} QUIET=${QUIET:-false}
#- cat config.log => comment out to reduce log size limit on travis-ci
# we limit the `make` to 40 min
# to ensure that slow builds still upload their
# ccache results and therefore should be faster
# (and might work) for the next build
- DEADLINE=$(( $(date +%s) + 40 * 60 ))
- scripts/travis-command-wrapper.py -s "date" -i 120 --deadline="$DEADLINE" make
- test_ok && git_submodule_update --init --depth=50 test/
- test_ok && make test
- test_ok && enabled ${COVERAGE} coverage
- test_ok && enabled ${BENCH} make bench
- ./scripts/check_glibcxx.sh

View file

@ -6,12 +6,44 @@ Developers: Please commit along with changes.
For a complete change history, see the git log. For a complete change history, see the git log.
## Mapnik 4.0.3
## UNRELEASED Released October 30th, 2024
(Packaged from [05389e3c7](https://github.com/mapnik/mapnik/commit/05389e3c7))
- Remove 'final' specifier from invalid_featureset implementation
(issues with dynamic_cast<> when building using Apple clang version 16.0.0 on darwin-arm64)
- Rename invalid_featureset to empty_featureset
- Upgrade to SCons v4.8.1
- Fix unit tests e.g #endif statement (via @bgardner-noggin)
## Mapnik 4.0.2
Released August 21st, 2024
- CMake build - set `SOVERSION` to `${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}`
- Upgraded SCons build system to v4.8.0
## Mapnik 4.0.1
- Use CMAKE_INSTALL_LIBDIR for libdir in pkg-config files
- Support gcc 14
- Improved accuracy of bounding box re-projections. Automatic spliting at (0, 0) and merging results.
- Fixes missing features when using WGS 84 / Arctic Polar Stereographic (`epsg:4326 <-> epsg:3995`)
- Added `area_of_use` method to `mapnik::projection`
## Mapnik 4.0.0
#### Notice #### Notice
- Mapnik now requires C++14 compliant compiler (`-std=c++14`) - Mapnik now requires C++17 compliant compiler (`-std=c++17`)
- Mapnik now supports CMake as a build system. See [#4191](https://github.com/mapnik/mapnik/pull/4191) and the [docs](https://github.com/mapnik/mapnik/blob/master/docs/cmake-usage.md) for more info.
#### Breaking Changes
- Reworked datasource plugin system. Plugins now need to implement a class with the macros in `datasource_plugin.hpp` ([#4291](https://github.com/mapnik/mapnik/pull/4291))
- mapnik now has a global `mapnik::setup()` method which have to be called before any other functions of mapnik. Defined in `mapnik.hpp`. Currently there is a auto setup functionality. It can be disabled using the cmake option `DISABLE_MAPNIK_AUTOSETUP=ON`. Note: In order not to insert this change into every code base, it is currently still called during the dynamic initialisation time. However, if mapnik is compiled statically, this function must be called. ([#4291](https://github.com/mapnik/mapnik/pull/4291))
#### Core #### Core
@ -27,6 +59,8 @@ For a complete change history, see the git log.
- Slightly improved `sql_utils::table_from_sql` ([2587bb3](https://github.com/mapnik/mapnik/commit/2587bb3a1d8db397acfa8dcc2d332da3a8a9399f)) - Slightly improved `sql_utils::table_from_sql` ([2587bb3](https://github.com/mapnik/mapnik/commit/2587bb3a1d8db397acfa8dcc2d332da3a8a9399f))
- Added wrappers for proper quoting in SQL query construction: `sql_utils::identifier`, `sql_utils::literal` ([7b21713](https://github.com/mapnik/mapnik/commit/7b217133e2749b82c2638551045c4edbece15086)) - Added wrappers for proper quoting in SQL query construction: `sql_utils::identifier`, `sql_utils::literal` ([7b21713](https://github.com/mapnik/mapnik/commit/7b217133e2749b82c2638551045c4edbece15086))
- Added two-argument `sql_utils::unquote`, `sql_utils::unquote_copy` that also collapse inner quotes ([a4e8ea2](https://github.com/mapnik/mapnik/commit/a4e8ea21be297d89bbf36ba594d6c661a7a9ac81)) - Added two-argument `sql_utils::unquote`, `sql_utils::unquote_copy` that also collapse inner quotes ([a4e8ea2](https://github.com/mapnik/mapnik/commit/a4e8ea21be297d89bbf36ba594d6c661a7a9ac81))
- Fixed mapnik static build with static plugins ([#4291](https://github.com/mapnik/mapnik/pull/4291))
- Reworked mapnik::enumeration<...> ([#4372](https://github.com/mapnik/mapnik/pull/4372))
#### Plugins #### Plugins

34
CITATION.cff Normal file
View file

@ -0,0 +1,34 @@
# 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 Normal file
View file

@ -0,0 +1,472 @@
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)

350
CMakePresets.json Normal file
View file

@ -0,0 +1,350 @@
{
"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"
]
}
]
}

View file

@ -2,6 +2,13 @@
Mapnik runs on Linux, OS X, Windows, and BSD systems. Mapnik runs on Linux, OS X, Windows, and BSD systems.
## 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 First clone mapnik from github and initialize submodules
```bash ```bash
@ -35,8 +42,8 @@ To use a Python interpreter that is not named `python` for your build, do
something like the following instead: something like the following instead:
```bash ```bash
$ PYTHON=python2 ./configure $ PYTHON=python3 ./configure
$ make PYTHON=python2 $ 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
@ -64,15 +71,15 @@ For troubleshooting help see https://github.com/mapnik/mapnik/wiki/InstallationT
Build system dependencies are: Build system dependencies are:
* C++ compiler supporting `-std=c++11` (like >= g++ 4.8 or >= clang++ 3.4) * C++ compiler supporting `-std=c++17` (like >= g++ 9 or >= clang++ 5)
* >= 2 GB RAM (> 5 GB for g++) * \>= 2 GB RAM (> 5 GB for g++)
* Python 2.4-2.7 * Python 3
* Scons (a copy is bundled) * Scons (a copy is bundled) or CMake >= 3.15 see [docs/cmake-usage.md](./docs/cmake-usage.md)
Mapnik Core depends on: Mapnik Core depends on:
* Boost * Boost
- >= 1.47 is required and >= 1.56 recommended - \>= 1.73 is required
- These libraries are used: - These libraries are used:
- filesystem - filesystem
- system - system
@ -90,7 +97,7 @@ 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 - PROJ.4 projection library (Default enabled, if found) * libproj >= 7.2.0 - PROJ projection library (Default enabled, if found)
Additional optional dependencies: Additional optional dependencies:
@ -184,7 +191,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: http://mapbox.com/tilemill/docs/crashcourse/introduction/ learning advanced map styling: https://tilemill-project.github.io/tilemill/docs/crashcourse/introduction/
### Programmers ### Programmers

View file

@ -28,7 +28,8 @@ src/json/libmapnik-json.a:
src/renderer_common/render_thunk_extractor.os \ src/renderer_common/render_thunk_extractor.os \
src/json/libmapnik-json.a \ src/json/libmapnik-json.a \
src/wkt/libmapnik-wkt.a \ src/wkt/libmapnik-wkt.a \
src/css_color_grammar_x3.os \ src/css/css_grammar_x3.os \
src/css/css_color_grammar_x3.os \
src/expression_grammar_x3.os \ src/expression_grammar_x3.os \
src/transform_expression_grammar_x3.os \ src/transform_expression_grammar_x3.os \
src/image_filter_grammar_x3.os \ src/image_filter_grammar_x3.os \

View file

@ -8,7 +8,7 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/
_/ _/
``` ```
[![TravisCI](https://api.travis-ci.org/mapnik/mapnik.svg?branch=master)](http://travis-ci.org/mapnik/mapnik) [![TravisCI](https://api.travis-ci.com/mapnik/mapnik.svg?branch=master)](http://travis-ci.com/mapnik/mapnik)
[![codecov](https://codecov.io/gh/mapnik/mapnik/branch/master/graph/badge.svg)](https://codecov.io/gh/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. 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.

View file

@ -1,6 +1,6 @@
# This file is part of Mapnik (c++ mapping toolkit) # This file is part of Mapnik (c++ mapping toolkit)
# #
# Copyright (C) 2017 Artem Pavlenko # Copyright (C) 2024 Artem Pavlenko
# #
# Mapnik is free software; you can redistribute it and/or # Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
@ -16,15 +16,13 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from __future__ import print_function # support python2
import os import os
import sys import sys
import re import re
import platform import platform
from glob import glob from glob import glob
from copy import copy from copy import copy
from subprocess import Popen, PIPE from subprocess import run, Popen, PIPE
from SCons.SConf import SetCacheMode from SCons.SConf import SetCacheMode
import pickle import pickle
@ -34,19 +32,8 @@ try:
except: except:
HAS_DISTUTILS = False HAS_DISTUTILS = False
try: from shlex import quote as shquote
# Python 3.3+ from subprocess import DEVNULL
from shlex import quote as shquote
except:
# Python 2.7
from pipes import quote as shquote
try:
# Python 3.3+
from subprocess import DEVNULL
except:
# Python 2.7
DEVNULL = open(os.devnull, 'w')
LIBDIR_SCHEMA_DEFAULT='lib' LIBDIR_SCHEMA_DEFAULT='lib'
severities = ['debug', 'warn', 'error', 'none'] severities = ['debug', 'warn', 'error', 'none']
@ -56,8 +43,9 @@ ICU_LIBS_DEFAULT='/usr/'
DEFAULT_CC = "cc" DEFAULT_CC = "cc"
DEFAULT_CXX = "c++" DEFAULT_CXX = "c++"
DEFAULT_CXX14_CXXFLAGS = " -std=c++14 -DU_USING_ICU_NAMESPACE=0" DEFAULT_CXX_STD = "17"
DEFAULT_CXX14_LINKFLAGS = "" DEFAULT_CXX_CXXFLAGS = " -DU_USING_ICU_NAMESPACE=0"
DEFAULT_CXX_LINKFLAGS = ""
if sys.platform == 'darwin': if sys.platform == 'darwin':
# homebrew default # homebrew default
ICU_INCLUDES_DEFAULT='/usr/local/opt/icu4c/include/' ICU_INCLUDES_DEFAULT='/usr/local/opt/icu4c/include/'
@ -76,9 +64,10 @@ SCONS_CONFIGURE_CACHE = 'config.cache'
SCONF_TEMP_DIR = '.sconf_temp' SCONF_TEMP_DIR = '.sconf_temp'
# auto-search directories for boost libs/headers # auto-search directories for boost libs/headers
BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',] BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',]
BOOST_MIN_VERSION = '1.61' BOOST_MIN_VERSION = '1.73'
#CAIRO_MIN_VERSION = '1.8.0' #CAIRO_MIN_VERSION = '1.8.0'
PROJ_MIN_VERSION = (7, 2, 0)
PROJ_MIN_VERSION_STRING = "%s.%s.%s" % PROJ_MIN_VERSION
HARFBUZZ_MIN_VERSION = (0, 9, 34) HARFBUZZ_MIN_VERSION = (0, 9, 34)
HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION
@ -91,7 +80,8 @@ pretty_dep_names = {
'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/GDAL', 'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/GDAL',
'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/OGR', 'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/OGR',
'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', 'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/', 'proj':'Proj C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/',
'proj-min-version':'libproj >=%s required' % PROJ_MIN_VERSION_STRING,
'pg':'Postgres C Library required for PostGIS plugin | configure with pg_config program or configure with PG_LIBS & PG_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/PostGIS', 'pg':'Postgres C Library required for PostGIS plugin | configure with pg_config program or configure with PG_LIBS & PG_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/PostGIS',
'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite', 'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite',
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES', 'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
@ -115,7 +105,7 @@ pretty_dep_names = {
'boost_regex_icu':'libboost_regex built with optional ICU unicode support is needed for unicode regex support in mapnik.', 'boost_regex_icu':'libboost_regex built with optional ICU unicode support is needed for unicode regex support in mapnik.',
'sqlite_rtree':'The SQLite plugin requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)', 'sqlite_rtree':'The SQLite plugin requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)',
'pgsql2sqlite_rtree':'The pgsql2sqlite program requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)', 'pgsql2sqlite_rtree':'The pgsql2sqlite program requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)',
'PROJ_LIB':'The directory where proj4 stores its data files. Must exist for proj4 to work correctly', 'PROJ_LIB':'The directory where proj stores its data files. Must exist for proj to work correctly',
'GDAL_DATA':'The directory where GDAL stores its data files. Must exist for GDAL to work correctly', 'GDAL_DATA':'The directory where GDAL stores its data files. Must exist for GDAL to work correctly',
'ICU_DATA':'The directory where icu stores its data files. If ICU reports a path, it must exist. ICU can also be built without .dat files and in that case this path is empty' 'ICU_DATA':'The directory where icu stores its data files. If ICU reports a path, it must exist. ICU can also be built without .dat files and in that case this path is empty'
} }
@ -141,7 +131,6 @@ PLUGINS = { # plugins with external dependencies
def init_environment(env): def init_environment(env):
env.Decider('MD5-timestamp') env.Decider('MD5-timestamp')
env.SourceCode(".", None)
env['ORIGIN'] = Literal('$ORIGIN') env['ORIGIN'] = Literal('$ORIGIN')
env['ENV']['ORIGIN'] = '$ORIGIN' env['ENV']['ORIGIN'] = '$ORIGIN'
if os.environ.get('RANLIB'): if os.environ.get('RANLIB'):
@ -355,6 +344,7 @@ opts = Variables()
opts.AddVariables( opts.AddVariables(
# Compiler options # Compiler options
('CXX', 'The C++ compiler to use to compile mapnik', DEFAULT_CXX), ('CXX', 'The C++ compiler to use to compile mapnik', DEFAULT_CXX),
('CXX_STD', 'The C++ compiler standard (string).', DEFAULT_CXX_STD),
('CC', 'The C compiler used for configure checks of C libs.', DEFAULT_CC), ('CC', 'The C compiler used for configure checks of C libs.', DEFAULT_CC),
('CUSTOM_CXXFLAGS', 'Custom C++ flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir>', ''), ('CUSTOM_CXXFLAGS', 'Custom C++ flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir>', ''),
('CUSTOM_DEFINES', 'Custom Compiler DEFINES, e.g. -DENABLE_THIS', ''), ('CUSTOM_DEFINES', 'Custom Compiler DEFINES, e.g. -DENABLE_THIS', ''),
@ -378,7 +368,6 @@ opts.AddVariables(
BoolVariable('ENABLE_GLIBC_WORKAROUND', "Workaround known GLIBC symbol exports to allow building against libstdc++-4.8 without binaries needing throw_out_of_range_fmt", 'False'), BoolVariable('ENABLE_GLIBC_WORKAROUND', "Workaround known GLIBC symbol exports to allow building against libstdc++-4.8 without binaries needing throw_out_of_range_fmt", 'False'),
# http://www.scons.org/wiki/GoFastButton # http://www.scons.org/wiki/GoFastButton
# http://stackoverflow.com/questions/1318863/how-to-optimize-an-scons-script # http://stackoverflow.com/questions/1318863/how-to-optimize-an-scons-script
BoolVariable('FAST', "Make SCons faster at the cost of less precise dependency tracking", 'False'),
BoolVariable('PRIORITIZE_LINKING', 'Sort list of lib and inc directories to ensure preferential compiling and linking (useful when duplicate libs)', 'True'), BoolVariable('PRIORITIZE_LINKING', 'Sort list of lib and inc directories to ensure preferential compiling and linking (useful when duplicate libs)', 'True'),
('LINK_PRIORITY','Priority list in which to sort library and include paths (default order is internal, other, frameworks, user, then system - see source of `sort_paths` function for more detail)',','.join(DEFAULT_LINK_PRIORITY)), ('LINK_PRIORITY','Priority list in which to sort library and include paths (default order is internal, other, frameworks, user, then system - see source of `sort_paths` function for more detail)',','.join(DEFAULT_LINK_PRIORITY)),
@ -420,9 +409,9 @@ opts.AddVariables(
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'), BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'),
PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept), PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept),
PathVariable('WEBP_LIBS','Search path for libwebp library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), PathVariable('WEBP_LIBS','Search path for libwebp library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
BoolVariable('PROJ', 'Build Mapnik with proj4 support to enable transformations between many different projections', 'True'), BoolVariable('PROJ', 'Build Mapnik with proj support to enable transformations between many different projections', 'True'),
PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/include', PathVariable.PathAccept), PathVariable('PROJ_INCLUDES', 'Search path for libproj include files', '/usr/include', PathVariable.PathAccept),
PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), PathVariable('PROJ_LIBS', 'Search path for libproj library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
('PG_INCLUDES', 'Search path for libpq (postgres client) include files', ''), ('PG_INCLUDES', 'Search path for libpq (postgres client) include files', ''),
('PG_LIBS', 'Search path for libpq (postgres client) library files', ''), ('PG_LIBS', 'Search path for libpq (postgres client) library files', ''),
('FREETYPE_INCLUDES', 'Search path for Freetype include files', ''), ('FREETYPE_INCLUDES', 'Search path for Freetype include files', ''),
@ -478,8 +467,9 @@ opts.AddVariables(
BoolVariable('MAPNIK_RENDER', 'Compile and install a utility to render a map to an image', 'True'), BoolVariable('MAPNIK_RENDER', 'Compile and install a utility to render a map to an image', 'True'),
BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'), BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'),
BoolVariable('BIGINT', 'Compile support for 64-bit integers in mapnik::value', 'True'), BoolVariable('BIGINT', 'Compile support for 64-bit integers in mapnik::value', 'True'),
BoolVariable('USE_BOOST_FILESYSTEM','Use boost::filesytem even if `std::filesystem` is available (since c++17)', 'False'),
BoolVariable('QUIET', 'Reduce build verbosity', 'False'), BoolVariable('QUIET', 'Reduce build verbosity', 'False'),
) )
# variables to pickle after successful configure step # variables to pickle after successful configure step
# these include all scons core variables as well as custom # these include all scons core variables as well as custom
@ -487,6 +477,7 @@ opts.AddVariables(
pickle_store = [# Scons internal variables pickle_store = [# Scons internal variables
'CC', # compiler user to check if c deps compile during configure 'CC', # compiler user to check if c deps compile during configure
'CXX', # C++ compiler to compile mapnik 'CXX', # C++ compiler to compile mapnik
'CXX_STD', # C++ standard e.g 17 (as in -std=c++17)
'CFLAGS', 'CFLAGS',
'CPPDEFINES', 'CPPDEFINES',
'CPPFLAGS', # c preprocessor flags 'CPPFLAGS', # c preprocessor flags
@ -545,6 +536,7 @@ pickle_store = [# Scons internal variables
'SQLITE_LINKFLAGS', 'SQLITE_LINKFLAGS',
'BOOST_LIB_VERSION_FROM_HEADER', 'BOOST_LIB_VERSION_FROM_HEADER',
'BIGINT', 'BIGINT',
'USE_BOOST_FILESYSTEM',
'HOST', 'HOST',
'QUERIED_GDAL_DATA', 'QUERIED_GDAL_DATA',
'QUERIED_ICU_DATA', 'QUERIED_ICU_DATA',
@ -930,67 +922,44 @@ def CheckGdalData(context, silent=False):
context.Result('Failed to detect (mapnik-config will have null value)') context.Result('Failed to detect (mapnik-config will have null value)')
return value return value
def proj_version(context):
def CheckProjData(context, silent=False): context.Message('Checking for Proj version >=%s...' % PROJ_MIN_VERSION_STRING)
if not silent:
context.Message('Checking for PROJ_LIB directory...')
ret, out = context.TryRun(""" ret, out = context.TryRun("""
#include "proj.h"
// This is narly, could eventually be replaced using https://github.com/OSGeo/proj.4/pull/551] #include <stdio.h>
#include <proj_api.h> #define PROJ_VERSION_ATLEAST(major,minor,micro) \
#include <iostream> ((major)*10000+(minor)*100+(micro) <= \
#include <cstring> PROJ_VERSION_MAJOR*10000+PROJ_VERSION_MINOR*100+PROJ_VERSION_PATCH)
int main()
static void my_proj4_logger(void * user_data, int /*level*/, const char * msg)
{ {
std::string* posMsg = static_cast<std::string*>(user_data); printf("%d;%d.%d.%d", PROJ_VERSION_ATLEAST{min-version}, PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR, PROJ_VERSION_PATCH);
*posMsg += msg;
}
// https://github.com/OSGeo/gdal/blob/ddbf6d39aa4b005a77ca4f27c2d61a3214f336f8/gdal/alg/gdalapplyverticalshiftgrid.cpp#L616-L633
std::string find_proj_path(const char * pszFilename) {
std::string osMsg;
std::string osFilename;
projCtx ctx = pj_ctx_alloc();
pj_ctx_set_app_data(ctx, &osMsg);
pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR);
pj_ctx_set_logger(ctx, my_proj4_logger);
PAFile f = pj_open_lib(ctx, pszFilename, "rb");
if( f )
{
pj_ctx_fclose(ctx, f);
}
size_t nPos = osMsg.find("fopen(");
if( nPos != std::string::npos )
{
osFilename = osMsg.substr(nPos + strlen("fopen("));
nPos = osFilename.find(")");
if( nPos != std::string::npos )
osFilename = osFilename.substr(0, nPos);
}
pj_ctx_free(ctx);
return osFilename;
}
int main() {
std::string result = find_proj_path(" ");
std::cout << result;
if (result.empty()) {
return -1;
}
return 0; return 0;
} }
""".replace("{min-version}", str(PROJ_MIN_VERSION)),'.c')
if not ret:
context.Result('error (could not get version from proj.h)')
else:
ok_str, found_version_str = out.strip().split(';', 1)
major,minor,patch = found_version_str.split('.')
ret = int(ok_str), int(major)*10000+int(minor)*100+int(patch)
if ret:
context.Result('yes (found Proj %s)' % found_version_str)
else:
context.Result('no (found Proj %s)' % found_version_str)
return ret
def CheckProjData(context, silent=False):
if not silent:
context.Message('Checking for PROJ_LIB directory...')
result = run(['pkg-config', 'proj', '--variable=datadir'], stdout=PIPE)
value = result.stdout.decode('utf-8').strip()
""", '.cpp')
value = out.strip()
if silent: if silent:
context.did_show_result=1 context.did_show_result=1
if ret: if os.path.exists(value):
context.Result('pj_open_lib returned %s' % value) context.Result('`pkg-config proj --variable=datadir` returned:\n%s ' % value)
else: else:
value = None
context.Result('Failed to detect (mapnik-config will have null value)') context.Result('Failed to detect (mapnik-config will have null value)')
return value return value
@ -1227,28 +1196,29 @@ int main()
context.Result(ret) context.Result(ret)
return ret return ret
def supports_cxx14(context,silent=False): __cplusplus = {'14':'201402L', '17':'201703L', '20':'202002L'}
def supports_cxx_std (context, silent=False):
cplusplus_string = __cplusplus[env['CXX_STD']]
if not silent: if not silent:
context.Message('Checking if compiler (%s) supports -std=c++14 flag... ' % context.env.get('CXX','CXX')) context.Message('Checking if compiler (%s) supports -std=c++%s flag... ' % (context.env.get('CXX','CXX'), env['CXX_STD']))
ret, out = context.TryRun(""" ret, out = context.TryRun("""
int main() int main()
{ {
#if __cplusplus >= 201402L #if __cplusplus >= %s
return 0; return 0;
#else #else
return -1; return -1;
#endif #endif
} }
""", '.cpp') """ % cplusplus_string ,'.cpp')
if silent: if silent:
context.did_show_result=1 context.did_show_result=1
context.Result(ret) context.Result(ret)
return ret return ret
conf_tests = { 'prioritize_paths' : prioritize_paths, conf_tests = { 'prioritize_paths' : prioritize_paths,
'CheckPKGConfig' : CheckPKGConfig, 'CheckPKGConfig' : CheckPKGConfig,
'CheckPKG' : CheckPKG, 'CheckPKG' : CheckPKG,
@ -1256,6 +1226,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths,
'FindBoost' : FindBoost, 'FindBoost' : FindBoost,
'CheckBoost' : CheckBoost, 'CheckBoost' : CheckBoost,
'CheckIcuData' : CheckIcuData, 'CheckIcuData' : CheckIcuData,
'proj_version' : proj_version,
'CheckProjData' : CheckProjData, 'CheckProjData' : CheckProjData,
'CheckGdalData' : CheckGdalData, 'CheckGdalData' : CheckGdalData,
'CheckCairoHasFreetype' : CheckCairoHasFreetype, 'CheckCairoHasFreetype' : CheckCairoHasFreetype,
@ -1270,7 +1241,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths,
'harfbuzz_with_freetype_support': harfbuzz_with_freetype_support, 'harfbuzz_with_freetype_support': harfbuzz_with_freetype_support,
'boost_regex_has_icu' : boost_regex_has_icu, 'boost_regex_has_icu' : boost_regex_has_icu,
'sqlite_has_rtree' : sqlite_has_rtree, 'sqlite_has_rtree' : sqlite_has_rtree,
'supports_cxx14' : supports_cxx14, 'supports_cxx_std' : supports_cxx_std,
'CheckBoostScopedEnum' : CheckBoostScopedEnum, 'CheckBoostScopedEnum' : CheckBoostScopedEnum,
} }
@ -1287,12 +1258,7 @@ def GetMapnikLibVersion():
return version_string return version_string
if not preconfigured: if not preconfigured:
color_print(4,'Configuring build environment...') color_print(4,'Configuring build environment...')
if not env['FAST']:
SetCacheMode('force')
if env['USE_CONFIG']: if env['USE_CONFIG']:
if not env['CONFIG'].endswith('.py'): if not env['CONFIG'].endswith('.py'):
color_print(1,'SCons CONFIG file specified is not a python file, will not be read...') color_print(1,'SCons CONFIG file specified is not a python file, will not be read...')
@ -1414,23 +1380,25 @@ if not preconfigured:
# set any custom cxxflags and ldflags to come first # set any custom cxxflags and ldflags to come first
if sys.platform == 'darwin' and not env['HOST']: if sys.platform == 'darwin' and not env['HOST']:
DEFAULT_CXX14_CXXFLAGS += ' -stdlib=libc++' DEFAULT_CXX_CXXFLAGS += ' -stdlib=libc++'
DEFAULT_CXX14_LINKFLAGS = ' -stdlib=libc++' DEFAULT_CXX_LINKFLAGS = ' -stdlib=libc++'
env.Append(CPPDEFINES = env['CUSTOM_DEFINES']) env.Append(CPPDEFINES = env['CUSTOM_DEFINES'])
env.Append(CXXFLAGS = DEFAULT_CXX14_CXXFLAGS) env.Append(CXXFLAGS = "-std=c++%s %s" % (env['CXX_STD'], DEFAULT_CXX_CXXFLAGS))
env.Append(CXXFLAGS = env['CUSTOM_CXXFLAGS']) env.Append(CXXFLAGS = env['CUSTOM_CXXFLAGS'])
env.Append(CFLAGS = env['CUSTOM_CFLAGS']) env.Append(CFLAGS = env['CUSTOM_CFLAGS'])
env.Append(LINKFLAGS = DEFAULT_CXX14_LINKFLAGS) env.Append(LINKFLAGS = DEFAULT_CXX_LINKFLAGS)
custom_ldflags = env.ParseFlags(env['CUSTOM_LDFLAGS']) custom_ldflags = env.ParseFlags(env['CUSTOM_LDFLAGS'])
# ParseFlags puts everything it does not recognize into CCFLAGS,
# but let's assume the user knows better, put those in LINKFLAGS
env.Append(LINKFLAGS = custom_ldflags.pop('CCFLAGS'))
env.Append(LINKFLAGS = custom_ldflags.pop('LINKFLAGS'), env.Append(LINKFLAGS = custom_ldflags.pop('LINKFLAGS'),
LIBS = custom_ldflags.pop('LIBS')) LIBS = custom_ldflags.pop('LIBS'))
env.AppendUnique(FRAMEWORKS = custom_ldflags.pop('FRAMEWORKS'), env.AppendUnique(FRAMEWORKS = custom_ldflags.pop('FRAMEWORKS'),
LIBPATH = custom_ldflags.pop('LIBPATH'), LIBPATH = custom_ldflags.pop('LIBPATH'),
RPATH = custom_ldflags.pop('RPATH')) RPATH = custom_ldflags.pop('RPATH'))
# ParseFlags puts everything it does not recognize into CCFLAGS,
# but let's assume the user knows better: add those to LINKFLAGS.
# In order to prevent duplication of flags which ParseFlags puts
# into both CCFLAGS and LINKFLAGS, call AppendUnique.
env.AppendUnique(LINKFLAGS = custom_ldflags.pop('CCFLAGS'))
invalid_ldflags = {k:v for k,v in custom_ldflags.items() if v} invalid_ldflags = {k:v for k,v in custom_ldflags.items() if v}
if invalid_ldflags: if invalid_ldflags:
@ -1523,6 +1491,21 @@ if not preconfigured:
if env.get('XML2_LIBS'): if env.get('XML2_LIBS'):
lib_path = env['XML2_LIBS'] lib_path = env['XML2_LIBS']
env.AppendUnique(LIBPATH = fix_path(lib_path)) env.AppendUnique(LIBPATH = fix_path(lib_path))
elif CHECK_PKG_CONFIG and conf.CheckPKG('libxml-2.0'):
# libxml2 2.9.10+ doesn't use xml2-config and uses pkg-config instead
cmd = 'pkg-config libxml-2.0 --libs --cflags'
temp_env = Environment(ENV=os.environ)
try:
temp_env.ParseConfig(cmd)
for inc in temp_env['CPPPATH']:
env.AppendUnique(CPPPATH = fix_path(inc))
env['HAS_LIBXML2'] = True
for lib in temp_env['LIBS']:
env.AppendUnique(LIBPATH = fix_path(lib))
env['HAS_LIBXML2'] = True
except OSError as e:
pass
elif conf.parse_config('XML2_CONFIG',checks='--cflags'): elif conf.parse_config('XML2_CONFIG',checks='--cflags'):
env['HAS_LIBXML2'] = True env['HAS_LIBXML2'] = True
else: else:
@ -1544,7 +1527,7 @@ if not preconfigured:
env['SKIPPED_DEPS'].append('jpeg') env['SKIPPED_DEPS'].append('jpeg')
if env['PROJ']: if env['PROJ']:
OPTIONAL_LIBSHEADERS.append(['proj', 'proj_api.h', False,'C','-DMAPNIK_USE_PROJ4']) OPTIONAL_LIBSHEADERS.append(['proj', 'proj.h', False,'C','-DMAPNIK_USE_PROJ'])
inc_path = env['%s_INCLUDES' % 'PROJ'] inc_path = env['%s_INCLUDES' % 'PROJ']
lib_path = env['%s_LIBS' % 'PROJ'] lib_path = env['%s_LIBS' % 'PROJ']
env.AppendUnique(CPPPATH = fix_path(inc_path)) env.AppendUnique(CPPPATH = fix_path(inc_path))
@ -1562,11 +1545,25 @@ if not preconfigured:
env['SKIPPED_DEPS'].append('png') env['SKIPPED_DEPS'].append('png')
if env['WEBP']: if env['WEBP']:
OPTIONAL_LIBSHEADERS.append(['webp', 'webp/decode.h', False,'C','-DHAVE_WEBP']) if env.get('WEBP_LIBS') or env.get('WEBP_INCLUDES'):
inc_path = env['%s_INCLUDES' % 'WEBP'] OPTIONAL_LIBSHEADERS.append(['webp', 'webp/decode.h', False,'C','-DHAVE_WEBP'])
lib_path = env['%s_LIBS' % 'WEBP'] inc_path = env['WEBP_INCLUDES']
env.AppendUnique(CPPPATH = fix_path(inc_path)) lib_path = env['WEBP_LIBS']
env.AppendUnique(LIBPATH = fix_path(lib_path)) env.AppendUnique(CPPPATH = fix_path(inc_path))
env.AppendUnique(LIBPATH = fix_path(lib_path))
else:
cmd = 'pkg-config libwebp --libs --cflags'
if env['RUNTIME_LINK'] == 'static':
cmd += ' --static'
temp_env = Environment(ENV=os.environ)
try:
temp_env.ParseConfig(cmd)
for lib in temp_env['LIBS']:
env.AppendUnique(LIBPATH = fix_path(lib))
for inc in temp_env['CPPPATH']:
env.AppendUnique(CPPPATH = fix_path(inc))
except OSError as e:
pass
else: else:
env['SKIPPED_DEPS'].append('webp') env['SKIPPED_DEPS'].append('webp')
@ -1583,9 +1580,10 @@ if not preconfigured:
if env['PRIORITIZE_LINKING']: if env['PRIORITIZE_LINKING']:
conf.prioritize_paths(silent=True) conf.prioritize_paths(silent=True)
# test for C++14 support, which is required # test for CXX_STD support, which is required
if not env['HOST'] and not conf.supports_cxx14(): if not env['HOST'] and not conf.supports_cxx_std():
color_print(1,"C++ compiler does not support C++14 standard (-std=c++14), which is required. Please upgrade your compiler") color_print(1,"C++ compiler does not support C++%s standard (-std=c++%s), which is required."
" Please upgrade your compiler" % (env['CXX_STD'], env['CXX_STD']))
Exit(1) Exit(1)
if not env['HOST']: if not env['HOST']:
@ -1612,6 +1610,12 @@ if not preconfigured:
if env['BIGINT']: if env['BIGINT']:
env.Append(CPPDEFINES = '-DBIGINT') env.Append(CPPDEFINES = '-DBIGINT')
if int(env['CXX_STD']) < 17:
env['USE_BOOST_FILESYSTEM'] = True
if env['USE_BOOST_FILESYSTEM']:
env.Append(CPPDEFINES = '-DUSE_BOOST_FILESYSTEM')
if env['THREADING'] == 'multi': if env['THREADING'] == 'multi':
thread_flag = thread_suffix thread_flag = thread_suffix
else: else:
@ -1631,12 +1635,13 @@ if not preconfigured:
# The other required boost headers. # The other required boost headers.
BOOST_LIBSHEADERS = [ BOOST_LIBSHEADERS = [
['system', 'boost/system/system_error.hpp', True],
['filesystem', 'boost/filesystem/operations.hpp', True],
['regex', 'boost/regex.hpp', True], ['regex', 'boost/regex.hpp', True],
['program_options', 'boost/program_options.hpp', False] ['program_options', 'boost/program_options.hpp', False]
] ]
if env['USE_BOOST_FILESYSTEM']:
BOOST_LIBSHEADERS.append(['system', 'boost/system/system_error.hpp', True])
BOOST_LIBSHEADERS.append(['filesystem', 'boost/filesystem/operations.hpp', True])
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests # if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
if env['PRIORITIZE_LINKING']: if env['PRIORITIZE_LINKING']:
conf.prioritize_paths(silent=True) conf.prioritize_paths(silent=True)
@ -1695,6 +1700,13 @@ if not preconfigured:
else: else:
color_print(4, 'Could not find optional header or shared library for %s' % libname) color_print(4, 'Could not find optional header or shared library for %s' % libname)
env['SKIPPED_DEPS'].append(libname) env['SKIPPED_DEPS'].append(libname)
elif libname == 'proj':
result, version = conf.proj_version()
if not result:
env['SKIPPED_DEPS'].append('proj-min-version')
else:
env.Append(CPPDEFINES = define)
env.Append(CPPDEFINES = "-DMAPNIK_PROJ_VERSION=%d" % version)
else: else:
env.Append(CPPDEFINES = define) env.Append(CPPDEFINES = define)
else: else:
@ -2150,13 +2162,6 @@ if not HELP_REQUESTED:
Export('plugin_base') Export('plugin_base')
if env['FAST']:
# caching is 'auto' by default in SCons
# But let's also cache implicit deps...
EnsureSConsVersion(0,98)
SetOption('implicit_cache', 1)
SetOption('max_drift', 1)
# Build agg first, doesn't need anything special # Build agg first, doesn't need anything special
if env['RUNTIME_LINK'] == 'shared': if env['RUNTIME_LINK'] == 'shared':
SConscript('deps/agg/build.py') SConscript('deps/agg/build.py')

View file

@ -1,39 +0,0 @@
environment:
msvs_toolset: 14
FASTBUILD: 1
matrix:
- platform: x64
configuration: Release
os: Visual Studio 2015
#shallow_clone: true
# limit clone to latest 5 commits
clone_depth: 5
services:
- postgresql94 #if changing this, also change PATH below
install:
- SET PGUSER=postgres
- SET PGPASSWORD=Password12!
- SET PATH=C:\Program Files\PostgreSQL\9.4\bin\;%PATH%
build_script:
- scripts\build-appveyor.bat
after_build:
- 7z a visual-test-results.zip C:\tmp\mapnik-visual-images\visual-test-results
artifacts:
- path: mapnik-gyp\msbuild-summary.txt
name: msbuild-summary.txt
- path: mapnik-gyp\msbuild-errors.txt
name: msbuild-errors.txt
- path: mapnik-gyp\msbuild-warnings.txt
name: msbuild-warnings.txt
- path: visual-test-results.zip
name: visual-test-results.zip
test: off
deploy: off

52
benchmark/CMakeLists.txt Normal file
View file

@ -0,0 +1,52 @@
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
)

View file

@ -9,6 +9,7 @@ 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='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')

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]> <!DOCTYPE Map[]>
<Map <Map
srs="+init=epsg:4326" srs="epsg:4326"
background-color="#dfd8c9"> background-color="#dfd8c9">
<Style name="style"> <Style name="style">
@ -10,7 +10,7 @@
</Rule> </Rule>
</Style> </Style>
<Layer name="layer" <Layer name="layer"
srs="+init=epsg:4326"> srs="epsg:4326">
<StyleName>style</StyleName> <StyleName>style</StyleName>
<Datasource> <Datasource>
<Parameter name="file">./valid.geotiff.tif</Parameter> <Parameter name="file">./valid.geotiff.tif</Parameter>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]> <!DOCTYPE Map[]>
<Map <Map
srs="+init=epsg:4326" srs="epsg:4326"
background-color="#dfd8c9"> background-color="#dfd8c9">
<Style name="style"> <Style name="style">
@ -10,7 +10,7 @@
</Rule> </Rule>
</Style> </Style>
<Layer name="layer" <Layer name="layer"
srs="+init=epsg:4326"> srs="epsg:4326">
<StyleName>style</StyleName> <StyleName>style</StyleName>
<Datasource> <Datasource>
<Parameter name="file">./valid.geotiff.tif</Parameter> <Parameter name="file">./valid.geotiff.tif</Parameter>

View file

@ -2,6 +2,7 @@
#define MAPNIK_BENCH_FRAMEWORK_HPP #define MAPNIK_BENCH_FRAMEWORK_HPP
// mapnik // mapnik
#include <mapnik/mapnik.hpp>
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/params.hpp> #include <mapnik/params.hpp>
#include <mapnik/value/types.hpp> #include <mapnik/value/types.hpp>
@ -10,47 +11,38 @@
// stl // stl
#include <chrono> #include <chrono>
#include <cmath> // log10, round #include <cmath> // log10, round
#include <cstdio> // snprintf #include <cstdio> // snprintf
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <set>
#include <sstream>
#include <thread> #include <thread>
#include <mutex>
#include <vector> #include <vector>
namespace benchmark { namespace benchmark {
template <typename T> template<typename T>
using milliseconds = std::chrono::duration<T, std::milli>; using milliseconds = std::chrono::duration<T, std::milli>;
template <typename T> template<typename T>
using seconds = std::chrono::duration<T>; using seconds = std::chrono::duration<T>;
class test_case class test_case
{ {
protected: protected:
mapnik::parameters params_; mapnik::parameters params_;
std::size_t threads_; std::size_t threads_;
std::size_t iterations_; std::size_t iterations_;
public:
public:
test_case(mapnik::parameters const& params) test_case(mapnik::parameters const& params)
: params_(params), : params_(params)
threads_(mapnik::safe_cast<std::size_t>(*params.get<mapnik::value_integer>("threads", 0))), , 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))) , iterations_(mapnik::safe_cast<std::size_t>(*params.get<mapnik::value_integer>("iterations", 0)))
{} {}
std::size_t threads() const std::size_t threads() const { return threads_; }
{ std::size_t iterations() const { return iterations_; }
return threads_; mapnik::parameters const& params() const { return params_; }
}
std::size_t iterations() const
{
return iterations_;
}
mapnik::parameters const& params() const
{
return params_;
}
virtual bool validate() const = 0; virtual bool validate() const = 0;
virtual bool operator()() const = 0; virtual bool operator()() const = 0;
}; };
@ -58,21 +50,25 @@ public:
// gathers --long-option values in 'params'; // gathers --long-option values in 'params';
// returns the index of the first non-option argument, // returns the index of the first non-option argument,
// or negated index of an ill-formed option argument // or negated index of an ill-formed option argument
inline int parse_args(int argc, char** argv, mapnik::parameters & params) inline int parse_args(int argc, char** argv, mapnik::parameters& params)
{ {
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i)
{
const char* opt = argv[i]; const char* opt = argv[i];
if (opt[0] != '-') { if (opt[0] != '-')
{
// non-option argument, return its index // non-option argument, return its index
return i; return i;
} }
if (opt[1] != '-') { if (opt[1] != '-')
{
// we only accept --long-options, but instead of throwing, // we only accept --long-options, but instead of throwing,
// just issue a warning and let the caller decide what to do // just issue a warning and let the caller decide what to do
std::clog << argv[0] << ": invalid option '" << opt << "'\n"; std::clog << argv[0] << ": invalid option '" << opt << "'\n";
return -i; // negative means ill-formed option #i return -i; // negative means ill-formed option #i
} }
if (opt[2] == '\0') { if (opt[2] == '\0')
{
// option-list terminator '--' // option-list terminator '--'
return i + 1; return i + 1;
} }
@ -80,15 +76,18 @@ inline int parse_args(int argc, char** argv, mapnik::parameters & params)
// take option name without the leading '--' // take option name without the leading '--'
std::string key(opt + 2); std::string key(opt + 2);
size_t eq = key.find('='); size_t eq = key.find('=');
if (eq != std::string::npos) { if (eq != std::string::npos)
{
// one-argument form '--foo=bar' // one-argument form '--foo=bar'
params[key.substr(0, eq)] = key.substr(eq + 1); params[key.substr(0, eq)] = key.substr(eq + 1);
} }
else if (i + 1 < argc) { else if (i + 1 < argc)
{
// two-argument form '--foo' 'bar' // two-argument form '--foo' 'bar'
params[key] = std::string(argv[++i]); params[key] = std::string(argv[++i]);
} }
else { else
{
// missing second argument // missing second argument
std::clog << argv[0] << ": missing option '" << opt << "' value\n"; std::clog << argv[0] << ": missing option '" << opt << "' value\n";
return -i; // negative means ill-formed option #i return -i; // negative means ill-formed option #i
@ -99,7 +98,8 @@ inline int parse_args(int argc, char** argv, mapnik::parameters & params)
inline void handle_common_args(mapnik::parameters const& params) inline void handle_common_args(mapnik::parameters const& params)
{ {
if (auto severity = params.get<std::string>("log")) { if (auto severity = params.get<std::string>("log"))
{
if (*severity == "debug") if (*severity == "debug")
mapnik::logger::set_severity(mapnik::logger::debug); mapnik::logger::set_severity(mapnik::logger::debug);
else if (*severity == "warn") else if (*severity == "warn")
@ -109,37 +109,37 @@ inline void handle_common_args(mapnik::parameters const& params)
else if (*severity == "none") else if (*severity == "none")
mapnik::logger::set_severity(mapnik::logger::none); mapnik::logger::set_severity(mapnik::logger::none);
else else
std::clog << "ignoring option --log='" << *severity std::clog << "ignoring option --log='" << *severity << "' (allowed values are: debug, warn, error, none)\n";
<< "' (allowed values are: debug, warn, error, none)\n";
} }
} }
inline int handle_args(int argc, char** argv, mapnik::parameters & params) inline int handle_args(int argc, char** argv, mapnik::parameters& params)
{ {
int res = parse_args(argc, argv, params); int res = parse_args(argc, argv, params);
handle_common_args(params); handle_common_args(params);
return res; return res;
} }
#define BENCHMARK(test_class,name) \ #define BENCHMARK(test_class, name) \
int main(int argc, char** argv) \ int main(int argc, char** argv) \
{ \ { \
try \ mapnik::setup(); \
{ \ try \
mapnik::parameters params; \ { \
benchmark::handle_args(argc,argv,params); \ mapnik::parameters params; \
test_class test_runner(params); \ benchmark::handle_args(argc, argv, params); \
auto result = run(test_runner,name); \ test_class test_runner(params); \
testing::run_cleanup(); \ auto result = run(test_runner, name); \
return result; \ testing::run_cleanup(); \
} \ return result; \
catch (std::exception const& ex) \ } \
{ \ catch (std::exception const& ex) \
std::clog << ex.what() << "\n"; \ { \
testing::run_cleanup(); \ std::clog << ex.what() << "\n"; \
return -1; \ testing::run_cleanup(); \
} \ return -1; \
} \ } \
}
struct big_number_fmt struct big_number_fmt
{ {
@ -148,7 +148,9 @@ struct big_number_fmt
const char* u; const char* u;
big_number_fmt(int width, double value, int base = 1000) big_number_fmt(int width, double value, int base = 1000)
: w(width), v(value), u("") : w(width)
, v(value)
, u("")
{ {
static const char* suffixes = "\0\0k\0M\0G\0T\0P\0E\0Z\0Y\0\0"; static const char* suffixes = "\0\0k\0M\0G\0T\0P\0E\0Z\0Y\0\0";
u = suffixes; u = suffixes;
@ -164,7 +166,7 @@ struct big_number_fmt
} }
}; };
template <typename T> template<typename T>
int run(T const& test_runner, std::string const& name) int run(T const& test_runner, std::string const& name)
{ {
try try
@ -195,8 +197,7 @@ int run(T const& test_runner, std::string const& name)
std::mutex mtx_ready; std::mutex mtx_ready;
std::unique_lock<std::mutex> lock_ready(mtx_ready); std::unique_lock<std::mutex> lock_ready(mtx_ready);
auto stub = [&](T const& test_copy) auto stub = [&](T const& test_copy) {
{
// workers will wait on this mutex until the main thread // workers will wait on this mutex until the main thread
// constructs all of them and starts measuring time // constructs all of them and starts measuring time
std::unique_lock<std::mutex> my_lock(mtx_ready); std::unique_lock<std::mutex> my_lock(mtx_ready);
@ -206,14 +207,14 @@ int run(T const& test_runner, std::string const& name)
std::vector<std::thread> tg; std::vector<std::thread> tg;
tg.reserve(num_threads); tg.reserve(num_threads);
for (auto i = num_threads; i-- > 0; ) for (auto i = num_threads; i-- > 0;)
{ {
tg.emplace_back(stub, test_runner); tg.emplace_back(stub, test_runner);
} }
start = std::chrono::high_resolution_clock::now(); start = std::chrono::high_resolution_clock::now();
lock_ready.unlock(); lock_ready.unlock();
// wait for all workers to finish // wait for all workers to finish
for (auto & t : tg) for (auto& t : tg)
{ {
if (t.joinable()) if (t.joinable())
t.join(); t.join();
@ -227,7 +228,8 @@ int run(T const& test_runner, std::string const& name)
else else
{ {
start = std::chrono::high_resolution_clock::now(); start = std::chrono::high_resolution_clock::now();
do { do
{
test_runner(); test_runner();
elapsed = std::chrono::high_resolution_clock::now() - start; elapsed = std::chrono::high_resolution_clock::now() - start;
total_iters += num_iters; total_iters += num_iters;
@ -242,17 +244,24 @@ int run(T const& test_runner, std::string const& name)
std::clog << std::left << std::setw(43) << name; std::clog << std::left << std::setw(43) << name;
std::clog << std::resetiosflags(std::ios::adjustfield); std::clog << std::resetiosflags(std::ios::adjustfield);
if (num_threads > 0) { if (num_threads > 0)
std::clog << ' ' << std::setw(3) << num_threads {
<< " worker" << (num_threads > 1 ? "s" : " "); std::clog << ' ' << std::setw(3) << num_threads << " worker" << (num_threads > 1 ? "s" : " ");
} }
else { else
{
std::clog << " main thread"; std::clog << " main thread";
} }
std::snprintf(msg, sizeof(msg), std::snprintf(msg,
" %*.0f%s iters %6.0f milliseconds %*.0f%s i/t/s\n", sizeof(msg),
itersf.w, itersf.v, itersf.u, dur_total, " %*.0f%s iters %6.0f milliseconds %*.0f%s i/t/s\n",
ips.w, ips.v, ips.u); itersf.w,
itersf.v,
itersf.u,
dur_total,
ips.w,
ips.v,
ips.u);
std::clog << msg; std::clog << msg;
return 0; return 0;
} }
@ -266,18 +275,15 @@ int run(T const& test_runner, std::string const& name)
struct sequencer struct sequencer
{ {
sequencer(int argc, char** argv) sequencer(int argc, char** argv)
: exit_code_(0) : exit_code_(0)
{ {
benchmark::handle_args(argc, argv, params_); benchmark::handle_args(argc, argv, params_);
} }
int done() const int done() const { return exit_code_; }
{
return exit_code_;
}
template <typename Test, typename... Args> template<typename Test, typename... Args>
sequencer & run(std::string const& name, Args && ...args) sequencer& run(std::string const& name, Args&&... args)
{ {
// Test instance lifetime is confined to this function // Test instance lifetime is confined to this function
Test test_runner(params_, std::forward<Args>(args)...); Test test_runner(params_, std::forward<Args>(args)...);
@ -286,11 +292,11 @@ struct sequencer
return *this; // allow chaining calls return *this; // allow chaining calls
} }
protected: protected:
mapnik::parameters params_; mapnik::parameters params_;
int exit_code_; int exit_code_;
}; };
} } // namespace benchmark
#endif // MAPNIK_BENCH_FRAMEWORK_HPP #endif // MAPNIK_BENCH_FRAMEWORK_HPP

View file

@ -5,32 +5,31 @@
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/image_reader.hpp> #include <mapnik/image_reader.hpp>
namespace benchmark { namespace benchmark {
bool compare_images(std::string const& src_fn,std::string const& dest_fn) 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())
{ {
std::unique_ptr<mapnik::image_reader> reader1(mapnik::get_image_reader(dest_fn,"png")); throw mapnik::image_reader_exception("Failed to load: " + dest_fn);
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;
} }
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 #endif // MAPNIK_COMPARE_IMAGES_HPP

65
benchmark/run_benchmarks Normal file
View file

@ -0,0 +1,65 @@
#!/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

View file

@ -2,20 +2,23 @@
#include <mapnik/util/math.hpp> #include <mapnik/util/math.hpp>
template <typename T> template<typename T>
struct bench_func : benchmark::test_case struct bench_func : benchmark::test_case
{ {
T (* const func_)(T); T (*const func_)(T);
T const value_; T const value_;
bench_func(mapnik::parameters const& params, T (*func)(T), T value) bench_func(mapnik::parameters const& params, T (*func)(T), T value)
: test_case(params), func_(func), value_(value) {} : test_case(params)
, func_(func)
, value_(value)
{}
bool validate() const { return true; } bool validate() const { return true; }
bool operator() () const bool operator()() const
{ {
for (auto i = this->iterations_; i-- > 0; ) for (auto i = this->iterations_; i-- > 0;)
{ {
func_(value_); func_(value_);
} }
@ -23,47 +26,47 @@ struct bench_func : benchmark::test_case
} }
}; };
#define BENCH_FUNC1(func, value) \ #define BENCH_FUNC1(func, value) run<bench_func<double>>(#func "(" #value ")", func, value)
run<bench_func<double>>(#func "(" #value ")", func, value)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
return benchmark::sequencer(argc, argv) return benchmark::sequencer(argc, argv)
.BENCH_FUNC1(mapnik::util::normalize_angle, +3) .BENCH_FUNC1(mapnik::util::normalize_angle, +3)
.BENCH_FUNC1(mapnik::util::normalize_angle, +6) .BENCH_FUNC1(mapnik::util::normalize_angle, +6)
.BENCH_FUNC1(mapnik::util::normalize_angle, +9) .BENCH_FUNC1(mapnik::util::normalize_angle, +9)
.BENCH_FUNC1(mapnik::util::normalize_angle, +12) .BENCH_FUNC1(mapnik::util::normalize_angle, +12)
.BENCH_FUNC1(mapnik::util::normalize_angle, +15) .BENCH_FUNC1(mapnik::util::normalize_angle, +15)
.BENCH_FUNC1(mapnik::util::normalize_angle, +20) .BENCH_FUNC1(mapnik::util::normalize_angle, +20)
.BENCH_FUNC1(mapnik::util::normalize_angle, +30) .BENCH_FUNC1(mapnik::util::normalize_angle, +30)
.BENCH_FUNC1(mapnik::util::normalize_angle, +40) .BENCH_FUNC1(mapnik::util::normalize_angle, +40)
.BENCH_FUNC1(mapnik::util::normalize_angle, +50) .BENCH_FUNC1(mapnik::util::normalize_angle, +50)
.BENCH_FUNC1(mapnik::util::normalize_angle, +70) .BENCH_FUNC1(mapnik::util::normalize_angle, +70)
.BENCH_FUNC1(mapnik::util::normalize_angle, +90) .BENCH_FUNC1(mapnik::util::normalize_angle, +90)
.BENCH_FUNC1(mapnik::util::normalize_angle, +110) .BENCH_FUNC1(mapnik::util::normalize_angle, +110)
.BENCH_FUNC1(mapnik::util::normalize_angle, +130) .BENCH_FUNC1(mapnik::util::normalize_angle, +130)
.BENCH_FUNC1(mapnik::util::normalize_angle, +157) .BENCH_FUNC1(mapnik::util::normalize_angle, +157)
.BENCH_FUNC1(mapnik::util::normalize_angle, +209) .BENCH_FUNC1(mapnik::util::normalize_angle, +209)
.BENCH_FUNC1(mapnik::util::normalize_angle, +314) .BENCH_FUNC1(mapnik::util::normalize_angle, +314)
.BENCH_FUNC1(mapnik::util::normalize_angle, +628) .BENCH_FUNC1(mapnik::util::normalize_angle, +628)
.BENCH_FUNC1(mapnik::util::normalize_angle, +942) .BENCH_FUNC1(mapnik::util::normalize_angle, +942)
.BENCH_FUNC1(mapnik::util::normalize_angle, -3) .BENCH_FUNC1(mapnik::util::normalize_angle, -3)
.BENCH_FUNC1(mapnik::util::normalize_angle, -6) .BENCH_FUNC1(mapnik::util::normalize_angle, -6)
.BENCH_FUNC1(mapnik::util::normalize_angle, -9) .BENCH_FUNC1(mapnik::util::normalize_angle, -9)
.BENCH_FUNC1(mapnik::util::normalize_angle, -12) .BENCH_FUNC1(mapnik::util::normalize_angle, -12)
.BENCH_FUNC1(mapnik::util::normalize_angle, -15) .BENCH_FUNC1(mapnik::util::normalize_angle, -15)
.BENCH_FUNC1(mapnik::util::normalize_angle, -20) .BENCH_FUNC1(mapnik::util::normalize_angle, -20)
.BENCH_FUNC1(mapnik::util::normalize_angle, -30) .BENCH_FUNC1(mapnik::util::normalize_angle, -30)
.BENCH_FUNC1(mapnik::util::normalize_angle, -40) .BENCH_FUNC1(mapnik::util::normalize_angle, -40)
.BENCH_FUNC1(mapnik::util::normalize_angle, -50) .BENCH_FUNC1(mapnik::util::normalize_angle, -50)
.BENCH_FUNC1(mapnik::util::normalize_angle, -70) .BENCH_FUNC1(mapnik::util::normalize_angle, -70)
.BENCH_FUNC1(mapnik::util::normalize_angle, -90) .BENCH_FUNC1(mapnik::util::normalize_angle, -90)
.BENCH_FUNC1(mapnik::util::normalize_angle, -110) .BENCH_FUNC1(mapnik::util::normalize_angle, -110)
.BENCH_FUNC1(mapnik::util::normalize_angle, -130) .BENCH_FUNC1(mapnik::util::normalize_angle, -130)
.BENCH_FUNC1(mapnik::util::normalize_angle, -157) .BENCH_FUNC1(mapnik::util::normalize_angle, -157)
.BENCH_FUNC1(mapnik::util::normalize_angle, -209) .BENCH_FUNC1(mapnik::util::normalize_angle, -209)
.BENCH_FUNC1(mapnik::util::normalize_angle, -314) .BENCH_FUNC1(mapnik::util::normalize_angle, -314)
.BENCH_FUNC1(mapnik::util::normalize_angle, -628) .BENCH_FUNC1(mapnik::util::normalize_angle, -628)
.BENCH_FUNC1(mapnik::util::normalize_angle, -942) .BENCH_FUNC1(mapnik::util::normalize_angle, -942)
.done(); .done();
} }

View file

@ -14,15 +14,19 @@
#define FULL_ZERO_CHECK #define FULL_ZERO_CHECK
inline void ensure_zero(uint8_t * data, uint32_t size) { inline void ensure_zero(uint8_t* data, uint32_t size)
{
#ifdef FULL_ZERO_CHECK #ifdef FULL_ZERO_CHECK
for (std::size_t i=0;i<size;++i) { for (std::size_t i = 0; i < size; ++i)
if (data[i] != 0) { {
if (data[i] != 0)
{
throw std::runtime_error("found non zero value"); throw std::runtime_error("found non zero value");
} }
} }
#else #else
if (data[0] != 0) { if (data[0] != 0)
{
throw std::runtime_error("found non zero value"); throw std::runtime_error("found non zero value");
} }
#endif #endif
@ -30,274 +34,262 @@ inline void ensure_zero(uint8_t * data, uint32_t size) {
class test1 : public benchmark::test_case class test1 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test1(mapnik::parameters const& params) test1(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
// NOTE: sizeof(uint8_t) == 1 {
uint8_t *data = (uint8_t *)malloc(sizeof(uint8_t)*size_); // NOTE: sizeof(uint8_t) == 1
memcpy(data, &array_[0], size_); uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * size_);
ensure_zero(data,size_); memcpy(data, &array_[0], size_);
free(data); ensure_zero(data, size_);
} free(data);
return true; }
return true;
} }
}; };
class test1b : public benchmark::test_case class test1b : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test1b(mapnik::parameters const& params) test1b(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
// NOTE: sizeof(uint8_t) == 1 {
uint8_t *data = (uint8_t *)malloc(sizeof(uint8_t)*size_); // NOTE: sizeof(uint8_t) == 1
memset(data, 0, sizeof(uint8_t)*size_); uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * size_);
ensure_zero(data,size_); memset(data, 0, sizeof(uint8_t) * size_);
free(data); ensure_zero(data, size_);
} free(data);
return true; }
return true;
} }
}; };
class test1c : public benchmark::test_case class test1c : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test1c(mapnik::parameters const& params) test1c(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { 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); uint8_t* data = static_cast<uint8_t*>(::operator new(sizeof(uint8_t) * size_));
ensure_zero(data,size_); std::fill(data, data + size_, 0);
::operator delete(data); ensure_zero(data, size_);
} ::operator delete(data);
return true; }
return true;
} }
}; };
class test2 : public benchmark::test_case class test2 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test2(mapnik::parameters const& params) test2(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { 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_); uint8_t* data = static_cast<uint8_t*>(::operator new(sizeof(uint8_t) * size_));
ensure_zero(data,size_); memcpy(data, &array_[0], size_);
::operator delete(data),data=0; ensure_zero(data, size_);
} ::operator delete(data), data = 0;
return true; }
return true;
} }
}; };
class test3 : public benchmark::test_case class test3 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test3(mapnik::parameters const& params) test3(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::vector<uint8_t> data(size_); {
ensure_zero(&data[0],data.size()); std::vector<uint8_t> data(size_);
} ensure_zero(&data[0], data.size());
return true; }
return true;
} }
}; };
class test3b : public benchmark::test_case class test3b : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test3b(mapnik::parameters const& params) test3b(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::vector<uint8_t> data(0); {
data.resize(size_,0); std::vector<uint8_t> data(0);
ensure_zero(&data[0],data.size()); data.resize(size_, 0);
} ensure_zero(&data[0], data.size());
return true; }
return true;
} }
}; };
class test3c : public benchmark::test_case class test3c : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test3c(mapnik::parameters const& params) test3c(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::vector<uint8_t> data(0); {
data.assign(size_,0); std::vector<uint8_t> data(0);
ensure_zero(&data[0],data.size()); data.assign(size_, 0);
} ensure_zero(&data[0], data.size());
return true; }
return true;
} }
}; };
class test3d : public benchmark::test_case class test3d : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test3d(mapnik::parameters const& params) test3d(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::deque<uint8_t> data(size_); {
for (std::size_t i=0;i<size_;++i) { std::deque<uint8_t> data(size_);
if (data[i] != 0) { for (std::size_t i = 0; i < size_; ++i)
throw std::runtime_error("found non zero value"); {
} if (data[i] != 0)
} {
} throw std::runtime_error("found non zero value");
return true; }
}
}
return true;
} }
}; };
class test4 : public benchmark::test_case class test4 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test4(mapnik::parameters const& params) test4(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
uint8_t *data = (uint8_t *)calloc(size_,sizeof(uint8_t)); {
ensure_zero(data,size_); uint8_t* data = (uint8_t*)calloc(size_, sizeof(uint8_t));
free(data); ensure_zero(data, size_);
} free(data);
return true; }
return true;
} }
}; };
class test5 : public benchmark::test_case class test5 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test5(mapnik::parameters const& params) test5(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::string data(array_.begin(),array_.end()); {
ensure_zero((uint8_t *)&data[0],size_); std::string data(array_.begin(), array_.end());
} ensure_zero((uint8_t*)&data[0], size_);
return true; }
return true;
} }
}; };
class test5b : public benchmark::test_case class test5b : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<char> array_; std::vector<char> array_;
test5b(mapnik::parameters const& params) test5b(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
std::string data(&array_[0],array_.size()); {
ensure_zero((uint8_t *)&data[0],size_); std::string data(&array_[0], array_.size());
} ensure_zero((uint8_t*)&data[0], size_);
return true; }
return true;
} }
}; };
@ -308,24 +300,23 @@ public:
class test6 : public benchmark::test_case class test6 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test6(mapnik::parameters const& params) test6(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { 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_); std::valarray<uint8_t> data(static_cast<uint8_t>(0), static_cast<size_t>(size_));
} ensure_zero(&data[0], size_);
return true; }
return true;
} }
}; };
@ -335,45 +326,45 @@ public:
class test7 : public benchmark::test_case class test7 : public benchmark::test_case
{ {
public: public:
uint32_t size_; uint32_t size_;
std::vector<uint8_t> array_; std::vector<uint8_t> array_;
test7(mapnik::parameters const& params) test7(mapnik::parameters const& params)
: test_case(params), : test_case(params)
size_(*params.get<mapnik::value_integer>("size",256*256)), , size_(*params.get<mapnik::value_integer>("size", 256 * 256))
array_(size_,0) { } , array_(size_, 0)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { 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_); boost::container::static_vector<uint8_t, 256 * 256> data(size_, 0);
} ensure_zero(&data[0], size_);
return true; }
return true;
} }
}; };
#endif #endif
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
return benchmark::sequencer(argc, argv) return benchmark::sequencer(argc, argv)
.run<test4>("calloc") .run<test4>("calloc")
.run<test1>("malloc/memcpy") .run<test1>("malloc/memcpy")
.run<test1b>("malloc/memset") .run<test1b>("malloc/memset")
.run<test1c>("operator new/std::fill") .run<test1c>("operator new/std::fill")
.run<test2>("operator new/memcpy") .run<test2>("operator new/memcpy")
.run<test3>("vector(N)") .run<test3>("vector(N)")
.run<test3b>("vector/resize") .run<test3b>("vector/resize")
.run<test3c>("vector/assign") .run<test3c>("vector/assign")
.run<test3d>("deque(N)") .run<test3d>("deque(N)")
.run<test5>("std::string range") .run<test5>("std::string range")
.run<test5b>("std::string &[0]") .run<test5b>("std::string &[0]")
.run<test6>("valarray") .run<test6>("valarray")
#if BOOST_VERSION >= 105400 #if BOOST_VERSION >= 105400
.run<test7>("static_vector") .run<test7>("static_vector")
#endif #endif
.done(); .done();
} }

View file

@ -7,10 +7,12 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::string expr_; std::string expr_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))") {} , expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))")
{}
bool validate() const bool validate() const
{ {
mapnik::expression_ptr expr = mapnik::parse_expression(expr_); mapnik::expression_ptr expr = mapnik::parse_expression(expr_);
@ -18,24 +20,25 @@ public:
bool ret = (result == expr_); bool ret = (result == expr_);
if (!ret) if (!ret)
{ {
std::clog << result << " != " << expr_ << "\n"; std::clog << result << " != " << expr_ << "\n";
} }
return ret; return ret;
} }
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
mapnik::expression_ptr expr = mapnik::parse_expression(expr_); {
} mapnik::expression_ptr expr = mapnik::parse_expression(expr_);
return true; }
return true;
} }
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
test test_runner(params); test test_runner(params);
return run(test_runner,"expr parsing"); return run(test_runner, "expr parsing");
} }

View file

@ -4,9 +4,10 @@
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
{ {
std::size_t count = 0; std::size_t count = 0;
@ -22,14 +23,15 @@ public:
font_cache, font_cache,
mapnik::freetype_engine::get_mapping(), mapnik::freetype_engine::get_mapping(),
mapnik::freetype_engine::get_cache()); mapnik::freetype_engine::get_cache());
if (f) ++count; if (f)
++count;
} }
return count == expected_count; return count == expected_count;
} }
bool operator()() const bool operator()() const
{ {
std::size_t expected_count = mapnik::freetype_engine::face_names().size(); std::size_t expected_count = mapnik::freetype_engine::face_names().size();
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
std::size_t count = 0; std::size_t count = 0;
mapnik::freetype_engine::font_file_mapping_type font_file_mapping; mapnik::freetype_engine::font_file_mapping_type font_file_mapping;
@ -43,9 +45,11 @@ public:
font_cache, font_cache,
mapnik::freetype_engine::get_mapping(), mapnik::freetype_engine::get_mapping(),
mapnik::freetype_engine::get_cache()); mapnik::freetype_engine::get_cache());
if (f) ++count; if (f)
++count;
} }
if (count != expected_count) { if (count != expected_count)
{
std::clog << "warning: face creation not working as expected\n"; std::clog << "warning: face creation not working as expected\n";
} }
} }
@ -55,15 +59,16 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
bool success = mapnik::freetype_engine::register_fonts("./fonts", true); bool success = mapnik::freetype_engine::register_fonts("./fonts", true);
if (!success) { if (!success)
std::clog << "warning, did not register any new fonts!\n"; {
return -1; std::clog << "warning, did not register any new fonts!\n";
} return -1;
}
std::size_t face_count = mapnik::freetype_engine::face_names().size(); std::size_t face_count = mapnik::freetype_engine::face_names().size();
test test_runner(params); test test_runner(params);
return run(test_runner,(boost::format("font_engine: creating %ld faces") % (face_count)).str()); return run(test_runner, (boost::format("font_engine: creating %ld faces") % (face_count)).str());
} }

View file

@ -1,21 +1,18 @@
#include "bench_framework.hpp" #include "bench_framework.hpp"
#include <mapnik/font_engine_freetype.hpp> #include <mapnik/font_engine_freetype.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/foreach.hpp>
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 mapnik::freetype_engine::register_fonts("./fonts", true); }
return mapnik::freetype_engine::register_fonts("./fonts", true);
}
bool operator()() const bool operator()() const
{ {
unsigned long count = 0; unsigned long count = 0;
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
mapnik::freetype_engine::register_fonts("./fonts", true); mapnik::freetype_engine::register_fonts("./fonts", true);
count++; count++;
@ -24,4 +21,4 @@ public:
} }
}; };
BENCHMARK(test,"font registration") BENCHMARK(test, "font registration")

View file

@ -1,22 +1,20 @@
#include "bench_framework.hpp" #include "bench_framework.hpp"
#include "../plugins/input/csv/csv_getline.hpp" #include "../plugins/input/csv/csv_getline.hpp"
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
public: public:
std::string line_data_; std::string line_data_;
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
line_data_("this is one line\nand this is a second line\nand a third line") , line_data_("this is one line\nand this is a second line\nand a third line")
{ {
boost::optional<std::string> line_data = params.get<std::string>("line"); auto line_data = params.get<std::string>("line");
if (line_data) if (line_data)
{ {
line_data_ = *line_data; line_data_ = *line_data;
} }
} }
bool validate() const bool validate() const
{ {
@ -25,14 +23,15 @@ public:
std::string csv_line; std::string csv_line;
std::stringstream s; std::stringstream s;
s << line_data_; s << line_data_;
std::getline(s,csv_line,newline); std::getline(s, csv_line, newline);
if (csv_line != first) if (csv_line != first)
{ {
return true; return true;
} }
else 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"; 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; return true;
} }
@ -42,29 +41,28 @@ public:
std::string csv_line; std::string csv_line;
std::stringstream s; std::stringstream s;
s << line_data_; s << line_data_;
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
std::getline(s,csv_line,newline); std::getline(s, csv_line, newline);
} }
return true; return true;
} }
}; };
class test2 : public benchmark::test_case class test2 : public benchmark::test_case
{ {
public: public:
std::string line_data_; std::string line_data_;
test2(mapnik::parameters const& params) test2(mapnik::parameters const& params)
: test_case(params), : test_case(params)
line_data_("this is one line\nand this is a second line\nand a third line") , line_data_("this is one line\nand this is a second line\nand a third line")
{ {
boost::optional<std::string> line_data = params.get<std::string>("line"); auto line_data = params.get<std::string>("line");
if (line_data) if (line_data)
{ {
line_data_ = *line_data; line_data_ = *line_data;
} }
} }
bool validate() const bool validate() const
{ {
@ -74,14 +72,15 @@ public:
std::string csv_line; std::string csv_line;
std::stringstream s; std::stringstream s;
s << line_data_; s << line_data_;
csv_utils::getline_csv(s,csv_line,newline,quote); csv_utils::getline_csv(s, csv_line, newline, quote);
if (csv_line != first) if (csv_line != first)
{ {
return true; return true;
} }
else 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"; 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; return true;
} }
@ -92,9 +91,9 @@ public:
std::string csv_line; std::string csv_line;
std::stringstream s; std::stringstream s;
s << line_data_; s << line_data_;
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
csv_utils::getline_csv(s,csv_line,newline,quote); csv_utils::getline_csv(s, csv_line, newline, quote);
} }
return true; return true;
} }
@ -102,18 +101,19 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
int return_value = 0; int return_value = 0;
try try
{ {
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
{ {
test test_runner(params); test test_runner(params);
return_value = return_value | run(test_runner,"std::getline"); return_value = return_value | run(test_runner, "std::getline");
} }
{ {
test2 test_runner2(params); test2 test_runner2(params);
return_value = return_value | run(test_runner2,"csv_utils::getline_csv"); return_value = return_value | run(test_runner2, "csv_utils::getline_csv");
} }
} }
catch (std::exception const& ex) catch (std::exception const& ex)

View file

@ -4,34 +4,32 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::vector<std::string> images_; std::vector<std::string> images_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
images_{ , images_{"./test/data/images/dummy.jpg",
"./test/data/images/dummy.jpg", "./test/data/images/dummy.jpeg",
"./test/data/images/dummy.jpeg", "./test/data/images/dummy.png",
"./test/data/images/dummy.png", "./test/data/images/dummy.tif",
"./test/data/images/dummy.tif", "./test/data/images/dummy.tiff",
"./test/data/images/dummy.tiff", //"./test/data/images/landusepattern.jpeg", // will fail since it is a png
//"./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/images/xcode-CgBI.png", // will fail since its an invalid png "./test/data/svg/octocat.svg",
"./test/data/svg/octocat.svg", "./test/data/svg/place-of-worship-24.svg",
"./test/data/svg/place-of-worship-24.svg", "./test/data/svg/point_sm.svg",
"./test/data/svg/point_sm.svg", "./test/data/svg/point.svg",
"./test/data/svg/point.svg", "./test/data/svg/airfield-12.svg"}
"./test/data/svg/airfield-12.svg" {}
} {} bool validate() const { return true; }
bool validate() const
{
return true;
}
bool operator()() const bool operator()() const
{ {
unsigned count = 0; unsigned count = 0;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
for (auto filename : images_) for (auto filename : images_)
{ {
auto marker = mapnik::marker_cache::instance().find(filename,true); auto marker = mapnik::marker_cache::instance().find(filename, true);
} }
++count; ++count;
} }
@ -39,4 +37,4 @@ public:
} }
}; };
BENCHMARK(test,"marker cache") BENCHMARK(test, "marker cache")

View file

@ -11,43 +11,41 @@
#include <mapnik/feature_type_style.hpp> #include <mapnik/feature_type_style.hpp>
#include <memory> #include <memory>
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; }
{
return true;
}
bool operator()() const bool operator()() const
{ {
mapnik::Map m(256,256,"+init=epsg:3857"); mapnik::Map m(256, 256, "epsg:3857");
mapnik::parameters params; mapnik::parameters params;
params["type"]="memory"; params["type"] = "memory";
auto ds = std::make_shared<mapnik::memory_datasource>(params); auto ds = std::make_shared<mapnik::memory_datasource>(params);
// add whitespace to trigger phony "reprojection" // add whitespace to trigger phony "reprojection"
mapnik::layer lay("layer",m.srs() + " "); mapnik::layer lay("layer", m.srs() + " ");
lay.set_datasource(ds); lay.set_datasource(ds);
lay.add_style("style"); lay.add_style("style");
m.add_layer(lay); m.add_layer(lay);
// dummy style to ensure that layer is processed // dummy style to ensure that layer is processed
m.insert_style("style",mapnik::feature_type_style()); m.insert_style("style", mapnik::feature_type_style());
// dummy bbox, but "valid" because minx and miny are less // dummy bbox, but "valid" because minx and miny are less
// with an invalid bbox then layer.visible() returns false // with an invalid bbox then layer.visible() returns false
// and the initial rendering setup is not run // and the initial rendering setup is not run
m.zoom_to_box(mapnik::box2d<double>(-1,-1,0,0)); m.zoom_to_box(mapnik::box2d<double>(-1, -1, 0, 0));
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
mapnik::image_rgba8 im(256,256); mapnik::image_rgba8 im(256, 256);
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
ren.apply(); ren.apply();
} }
return true; return true;
} }
}; };
BENCHMARK(test,"rendering with reprojection") BENCHMARK(test, "rendering with reprojection")

View file

@ -9,23 +9,25 @@ class test_static : public benchmark::test_case
{ {
double step_; double step_;
std::uint8_t start_; std::uint8_t start_;
public:
public:
test_static(mapnik::parameters const& params) test_static(mapnik::parameters const& params)
: test_case(params), : test_case(params)
step_(STEP_NUM), , step_(STEP_NUM)
start_(START_NUM) {} , start_(START_NUM)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
double value_ = 0.0; double value_ = 0.0;
std::uint8_t x; std::uint8_t x;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
double c = static_cast<double>(start_) * value_; double c = static_cast<double>(start_) * value_;
if (c >= 256.0) c = 255.0; if (c >= 256.0)
if (c < 0.0) c = 0.0; c = 255.0;
if (c < 0.0)
c = 0.0;
x = static_cast<std::uint8_t>(c); x = static_cast<std::uint8_t>(c);
value_ += step_; value_ += step_;
} }
@ -33,35 +35,36 @@ public:
} }
}; };
using boost::numeric::positive_overflow;
using boost::numeric::negative_overflow; using boost::numeric::negative_overflow;
using boost::numeric::positive_overflow;
class test_numeric : public benchmark::test_case class test_numeric : public benchmark::test_case
{ {
double step_; double step_;
std::uint8_t start_; std::uint8_t start_;
public:
public:
test_numeric(mapnik::parameters const& params) test_numeric(mapnik::parameters const& params)
: test_case(params), : test_case(params)
step_(STEP_NUM), , step_(STEP_NUM)
start_(START_NUM) {} , start_(START_NUM)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
double value_ = 0.0; double value_ = 0.0;
std::uint8_t x; std::uint8_t x;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
try { {
try
{
x = boost::numeric_cast<std::uint8_t>(start_ * value_); x = boost::numeric_cast<std::uint8_t>(start_ * value_);
} }
catch(negative_overflow&) catch (negative_overflow&)
{ {
x = std::numeric_limits<std::uint8_t>::min(); x = std::numeric_limits<std::uint8_t>::min();
} }
catch(positive_overflow&) catch (positive_overflow&)
{ {
x = std::numeric_limits<std::uint8_t>::max(); x = std::numeric_limits<std::uint8_t>::max();
} }
@ -73,8 +76,6 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
return benchmark::sequencer(argc, argv) mapnik::setup();
.run<test_static>("static_cast") return benchmark::sequencer(argc, argv).run<test_static>("static_cast").run<test_numeric>("numeric_cast").done();
.run<test_numeric>("numeric_cast")
.done();
} }

View file

@ -14,31 +14,36 @@ struct fake_path
cont_type::iterator itr_; cont_type::iterator itr_;
fake_path(std::initializer_list<double> l) fake_path(std::initializer_list<double> l)
: fake_path(l.begin(), l.size()) { : fake_path(l.begin(), l.size())
} {}
fake_path(std::vector<double> const &v) fake_path(std::vector<double> const& v)
: fake_path(v.begin(), v.size()) { : fake_path(v.begin(), v.size())
} {}
template <typename Itr> template<typename Itr>
fake_path(Itr itr, size_t sz) { fake_path(Itr itr, size_t sz)
{
size_t num_coords = sz >> 1; size_t num_coords = sz >> 1;
vertices_.reserve(num_coords); vertices_.reserve(num_coords);
for (size_t i = 0; i < num_coords; ++i) { for (size_t i = 0; i < num_coords; ++i)
{
double x = *itr++; double x = *itr++;
double y = *itr++; double y = *itr++;
unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO; unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO;
vertices_.push_back(std::make_tuple(x, y, cmd)); vertices_.push_back(std::make_tuple(x, y, cmd));
if (i == num_coords - 1) cmd = mapnik::SEG_END; if (i == num_coords - 1)
cmd = mapnik::SEG_END;
vertices_.push_back(std::make_tuple(x, y, cmd)); vertices_.push_back(std::make_tuple(x, y, cmd));
} }
itr_ = vertices_.begin(); itr_ = vertices_.begin();
} }
unsigned vertex(double *x, double *y) { unsigned vertex(double* x, double* y)
if (itr_ == vertices_.end()) { {
if (itr_ == vertices_.end())
{
return mapnik::SEG_END; return mapnik::SEG_END;
} }
*x = std::get<0>(*itr_); *x = std::get<0>(*itr_);
@ -48,33 +53,30 @@ struct fake_path
return cmd; return cmd;
} }
void rewind(unsigned) { void rewind(unsigned) { itr_ = vertices_.begin(); }
itr_ = vertices_.begin();
}
}; };
class test_offset : public benchmark::test_case class test_offset : public benchmark::test_case
{ {
public: public:
test_offset(mapnik::parameters const& params) test_offset(mapnik::parameters const& params)
: test_case(params) {} : test_case(params)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
std::vector<double> path; std::vector<double> path;
int mysize = 2500; int mysize = 2500;
int x1 = 0; int x1 = 0;
path.reserve(mysize*2); path.reserve(mysize * 2);
for( int i = 0; i < mysize; i++ ) for (int i = 0; i < mysize; i++)
{ {
path.push_back( i ); path.push_back(i);
path.push_back( 0 ); path.push_back(0);
} }
fake_path fpath(path); fake_path fpath(path);
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
mapnik::offset_converter<fake_path> off_path(fpath); mapnik::offset_converter<fake_path> off_path(fpath);
off_path.set_offset(10); off_path.set_offset(10);
unsigned cmd; unsigned cmd;
@ -88,15 +90,15 @@ public:
} }
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
int return_value = 0; int return_value = 0;
{ {
test_offset test_runner(params); test_offset test_runner(params);
return_value = run(test_runner,"offset_test"); return_value = run(test_runner, "offset_test");
} }
return return_value; return return_value;
} }

View file

@ -4,23 +4,23 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
mapnik::image_rgba8 im_; mapnik::image_rgba8 im_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
im_(256,256) {} , im_(256, 256)
bool validate() const {}
{ bool validate() const { return true; }
return true;
}
bool operator()() const bool operator()() const
{ {
std::string out; std::string out;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
out.clear(); out.clear();
out = mapnik::save_to_string(im_,"png8:m=h:z=1"); out = mapnik::save_to_string(im_, "png8:m=h:z=1");
} }
return true; return true;
} }
}; };
BENCHMARK(test,"encoding blank png") BENCHMARK(test, "encoding blank png")

View file

@ -1,37 +1,41 @@
#include "bench_framework.hpp" #include "bench_framework.hpp"
#include "compare_images.hpp" #include "compare_images.hpp"
#include <memory>
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::shared_ptr<mapnik::image_rgba8> im_; std::shared_ptr<mapnik::image_rgba8> im_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params) { : test_case(params)
{
std::string filename("./benchmark/data/multicolor.png"); std::string filename("./benchmark/data/multicolor.png");
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"png")); std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename, "png"));
if (!reader.get()) if (!reader.get())
{ {
throw mapnik::image_reader_exception("Failed to load: " + filename); throw mapnik::image_reader_exception("Failed to load: " + filename);
} }
im_ = std::make_shared<mapnik::image_rgba8>(reader->width(),reader->height()); im_ = std::make_shared<mapnik::image_rgba8>(reader->width(), reader->height());
reader->read(0,0,*im_); reader->read(0, 0, *im_);
} }
bool validate() const bool validate() const
{ {
std::string expected("./benchmark/data/multicolor-hextree-expected.png"); std::string expected("./benchmark/data/multicolor-hextree-expected.png");
std::string actual("./benchmark/data/multicolor-hextree-actual.png"); std::string actual("./benchmark/data/multicolor-hextree-actual.png");
mapnik::save_to_file(*im_,actual, "png8:m=h:z=1"); mapnik::save_to_file(*im_, actual, "png8:m=h:z=1");
return benchmark::compare_images(actual,expected); return benchmark::compare_images(actual, expected);
} }
bool operator()() const bool operator()() const
{ {
std::string out; std::string out;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
out.clear(); out.clear();
out = mapnik::save_to_string(*im_,"png8:m=h:z=1"); out = mapnik::save_to_string(*im_, "png8:m=h:z=1");
} }
return true; return true;
} }
}; };
BENCHMARK(test,"encoding multicolor png") BENCHMARK(test, "encoding multicolor png")

View file

@ -39,30 +39,31 @@ void render(mapnik::geometry::multi_polygon<double> const& geom,
mapnik::box2d<double> const& extent, mapnik::box2d<double> const& extent,
std::string const& name) std::string const& name)
{ {
using path_type = mapnik::transform_path_adapter<mapnik::view_transform,mapnik::geometry::polygon_vertex_adapter<double>>; 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 ren_base = agg::renderer_base<agg::pixfmt_rgba32_plain>;
using renderer = agg::renderer_scanline_aa_solid<ren_base>; using renderer = agg::renderer_scanline_aa_solid<ren_base>;
mapnik::image_rgba8 im(256,256); mapnik::image_rgba8 im(256, 256);
mapnik::fill(im, mapnik::color("white")); mapnik::fill(im, mapnik::color("white"));
mapnik::box2d<double> padded_extent(155,134,665,466);//extent; mapnik::box2d<double> padded_extent(155, 134, 665, 466); // extent;
padded_extent.pad(10); padded_extent.pad(10);
mapnik::view_transform tr(im.width(),im.height(),padded_extent,0,0); 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::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
agg::pixfmt_rgba32_plain pixf(buf); agg::pixfmt_rgba32_plain pixf(buf);
ren_base renb(pixf); ren_base renb(pixf);
renderer ren(renb); renderer ren(renb);
mapnik::proj_transform prj_trans(mapnik::projection("+init=epsg:4326"),mapnik::projection("+init=epsg:4326")); mapnik::proj_transform prj_trans(mapnik::projection("epsg:4326"), mapnik::projection("epsg:4326"));
ren.color(agg::rgba8(127,127,127,255)); ren.color(agg::rgba8(127, 127, 127, 255));
agg::rasterizer_scanline_aa<> ras; agg::rasterizer_scanline_aa<> ras;
for (auto const& poly : geom) for (auto const& poly : geom)
{ {
mapnik::geometry::polygon_vertex_adapter<double> va(poly); mapnik::geometry::polygon_vertex_adapter<double> va(poly);
path_type path(tr,va,prj_trans); path_type path(tr, va, prj_trans);
ras.add_path(path); ras.add_path(path);
} }
agg::scanline_u8 sl; agg::scanline_u8 sl;
agg::render_scanlines(ras, sl, ren); agg::render_scanlines(ras, sl, ren);
mapnik::save_to_file(im,name); mapnik::save_to_file(im, name);
} }
class test1 : public benchmark::test_case class test1 : public benchmark::test_case
@ -70,15 +71,15 @@ class test1 : public benchmark::test_case
std::string wkt_in_; std::string wkt_in_;
mapnik::box2d<double> extent_; mapnik::box2d<double> extent_;
std::string expected_; std::string expected_;
public:
public:
using conv_clip = agg::conv_clip_polygon<mapnik::geometry::polygon_vertex_adapter<double>>; using conv_clip = agg::conv_clip_polygon<mapnik::geometry::polygon_vertex_adapter<double>>;
test1(mapnik::parameters const& params, test1(mapnik::parameters const& params, std::string const& wkt_in, mapnik::box2d<double> const& extent)
std::string const& wkt_in, : test_case(params)
mapnik::box2d<double> const& extent) , wkt_in_(wkt_in)
: test_case(params), , extent_(extent)
wkt_in_(wkt_in), , expected_("./benchmark/data/polygon_clipping_agg")
extent_(extent), {}
expected_("./benchmark/data/polygon_clipping_agg") {}
bool validate() const bool validate() const
{ {
mapnik::geometry::geometry<double> geom; mapnik::geometry::geometry<double> geom;
@ -99,14 +100,8 @@ public:
mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
mapnik::geometry::polygon_vertex_adapter<double> va(poly); mapnik::geometry::polygon_vertex_adapter<double> va(poly);
conv_clip clipped(va); conv_clip clipped(va);
clipped.clip_box( clipped.clip_box(extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy());
extent_.minx(),
extent_.miny(),
extent_.maxx(),
extent_.maxy());
clipped.rewind(0); clipped.rewind(0);
mapnik::geometry::polygon<double> poly2; mapnik::geometry::polygon<double> poly2;
@ -118,7 +113,8 @@ public:
{ {
if (cmd == mapnik::SEG_MOVETO) if (cmd == mapnik::SEG_MOVETO)
{ {
x0 = x; y0 = y; x0 = x;
y0 = y;
} }
if (cmd == mapnik::SEG_CLOSE) if (cmd == mapnik::SEG_CLOSE)
@ -126,7 +122,7 @@ public:
ring.emplace_back(x0, y0); ring.emplace_back(x0, y0);
break; break;
} }
ring.emplace_back(x,y); ring.emplace_back(x, y);
} }
poly2.push_back(std::move(ring)); poly2.push_back(std::move(ring));
// interior rings // interior rings
@ -135,30 +131,31 @@ public:
{ {
if (cmd == mapnik::SEG_MOVETO) if (cmd == mapnik::SEG_MOVETO)
{ {
x0 = x; y0 = y; x0 = x;
y0 = y;
} }
else if (cmd == mapnik::SEG_CLOSE) else if (cmd == mapnik::SEG_CLOSE)
{ {
ring.emplace_back(x0,y0); ring.emplace_back(x0, y0);
poly2.push_back(std::move(ring)); poly2.push_back(std::move(ring));
ring.clear(); ring.clear();
continue; continue;
} }
ring.emplace_back(x,y); ring.emplace_back(x, y);
} }
std::string expect = expected_+".png"; std::string expect = expected_ + ".png";
std::string actual = expected_+"_actual.png"; std::string actual = expected_ + "_actual.png";
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mp.emplace_back(poly2); mp.emplace_back(poly2);
auto env = mapnik::geometry::envelope(mp); auto env = mapnik::geometry::envelope(mp);
if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr))
{ {
std::clog << "generating expected image: " << expect << "\n"; std::clog << "generating expected image: " << expect << "\n";
render(mp,env,expect); render(mp, env, expect);
} }
render(mp,env,actual); render(mp, env, actual);
return benchmark::compare_images(actual,expect); return benchmark::compare_images(actual, expect);
} }
bool operator()() const bool operator()() const
{ {
@ -178,29 +175,28 @@ public:
return false; return false;
} }
bool valid = true; bool valid = true;
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
unsigned count = 0; unsigned count = 0;
mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
mapnik::geometry::polygon_vertex_adapter<double> va(poly); mapnik::geometry::polygon_vertex_adapter<double> va(poly);
conv_clip clipped(va); conv_clip clipped(va);
clipped.clip_box( clipped.clip_box(extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy());
extent_.minx(),
extent_.miny(),
extent_.maxx(),
extent_.maxy());
unsigned cmd; unsigned cmd;
double x,y; double x, y;
// NOTE: this rewind is critical otherwise // NOTE: this rewind is critical otherwise
// agg_conv_adapter_vpgen will give garbage // agg_conv_adapter_vpgen will give garbage
// values for the first vertex // values for the first vertex
clipped.rewind(0); clipped.rewind(0);
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END)
{
count++; count++;
} }
unsigned expected_count = 30; unsigned expected_count = 30;
if (count != expected_count) { if (count != expected_count)
std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; {
std::clog << "test1: clipping failed: processed " << count << " verticies but expected "
<< expected_count << "\n";
valid = false; valid = false;
} }
} }
@ -208,20 +204,19 @@ public:
} }
}; };
class test3 : public benchmark::test_case class test3 : public benchmark::test_case
{ {
std::string wkt_in_; std::string wkt_in_;
mapnik::box2d<double> extent_; mapnik::box2d<double> extent_;
std::string expected_; std::string expected_;
public:
test3(mapnik::parameters const& params, public:
std::string const& wkt_in, test3(mapnik::parameters const& params, std::string const& wkt_in, mapnik::box2d<double> const& extent)
mapnik::box2d<double> const& extent) : test_case(params)
: test_case(params), , wkt_in_(wkt_in)
wkt_in_(wkt_in), , extent_(extent)
extent_(extent), , expected_("./benchmark/data/polygon_clipping_boost")
expected_("./benchmark/data/polygon_clipping_boost") {} {}
bool validate() const bool validate() const
{ {
mapnik::geometry::geometry<double> geom; mapnik::geometry::geometry<double> geom;
@ -234,12 +229,12 @@ public:
std::clog << "empty geom!\n"; std::clog << "empty geom!\n";
return false; return false;
} }
if (!geom.is<mapnik::geometry::polygon<double> >()) if (!geom.is<mapnik::geometry::polygon<double>>())
{ {
std::clog << "not a polygon!\n"; std::clog << "not a polygon!\n";
return false; return false;
} }
mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom); mapnik::geometry::polygon<double>& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::linear_ring<double> bbox; mapnik::geometry::linear_ring<double> bbox;
@ -249,15 +244,15 @@ public:
bbox.emplace_back(extent_.maxx(), extent_.miny()); bbox.emplace_back(extent_.maxx(), extent_.miny());
bbox.emplace_back(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
std::deque<mapnik::geometry::polygon<double> > result; std::deque<mapnik::geometry::polygon<double>> result;
boost::geometry::intersection(bbox, poly, result); boost::geometry::intersection(bbox, poly, result);
std::string expect = expected_+".png"; std::string expect = expected_ + ".png";
std::string actual = expected_+"_actual.png"; std::string actual = expected_ + "_actual.png";
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
for (auto const& _geom: result) for (auto const& _geom : result)
{ {
//std::clog << boost::geometry::dsv(geom) << "\n"; // std::clog << boost::geometry::dsv(geom) << "\n";
mp.emplace_back(_geom); mp.emplace_back(_geom);
} }
mapnik::geometry::geometry<double> geom2(mp); mapnik::geometry::geometry<double> geom2(mp);
@ -265,10 +260,10 @@ public:
if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr))
{ {
std::clog << "generating expected image: " << expect << "\n"; std::clog << "generating expected image: " << expect << "\n";
render(mp,env,expect); render(mp, env, expect);
} }
render(mp,env,actual); render(mp, env, actual);
return benchmark::compare_images(actual,expect); return benchmark::compare_images(actual, expect);
} }
bool operator()() const bool operator()() const
{ {
@ -282,12 +277,12 @@ public:
std::clog << "empty geom!\n"; std::clog << "empty geom!\n";
return false; return false;
} }
if (!geom.is<mapnik::geometry::polygon<double> >()) if (!geom.is<mapnik::geometry::polygon<double>>())
{ {
std::clog << "not a polygon!\n"; std::clog << "not a polygon!\n";
return false; return false;
} }
mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom); mapnik::geometry::polygon<double>& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom);
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::linear_ring<double> bbox; mapnik::geometry::linear_ring<double> bbox;
@ -298,22 +293,25 @@ public:
bbox.emplace_back(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
bool valid = true; bool valid = true;
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
std::deque<mapnik::geometry::polygon<double> > result; std::deque<mapnik::geometry::polygon<double>> result;
boost::geometry::intersection(bbox, poly, result); boost::geometry::intersection(bbox, poly, result);
unsigned count = 0; unsigned count = 0;
for (auto const& _geom : result) for (auto const& _geom : result)
{ {
mapnik::geometry::polygon_vertex_adapter<double> va(_geom); mapnik::geometry::polygon_vertex_adapter<double> va(_geom);
unsigned cmd; unsigned cmd;
double x,y; double x, y;
while ((cmd = va.vertex(&x, &y)) != mapnik::SEG_END) { while ((cmd = va.vertex(&x, &y)) != mapnik::SEG_END)
{
++count; ++count;
} }
unsigned expected_count = 29; unsigned expected_count = 29;
if (count != expected_count) { if (count != expected_count)
std::clog << "test3: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; {
std::clog << "test3: clipping failed: processed " << count << " verticies but expected "
<< expected_count << "\n";
valid = false; valid = false;
} }
} }
@ -500,8 +498,8 @@ public:
} }
unsigned expected_count = 29; unsigned expected_count = 29;
if (count != expected_count) { if (count != expected_count) {
std::clog << "test3: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; std::clog << "test3: clipping failed: processed " << count << " verticies but expected " <<
valid = false; expected_count << "\n"; valid = false;
} }
} }
} }
@ -512,14 +510,18 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
// polygon/rect clipping // 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)) // IN : POLYGON ((155 203, 233 454, 315 340, 421 446, 463 324, 559 466, 665 253, 528 178, 394 229, 329 138, 212 134,
// RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106)) // 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
// OUT (expected) // 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)) // 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 #if 0
mapnik::box2d<double> clipping_box(181,106,631,470); mapnik::box2d<double> clipping_box(181,106,631,470);
std::string filename_("./benchmark/data/polygon.wkt"); std::string filename_("./benchmark/data/polygon.wkt");
@ -544,5 +546,5 @@ int main(int argc, char** argv)
} }
*/ */
#endif #endif
return 0;// return_value; return 0; // return_value;
} }

View file

@ -8,53 +8,52 @@ class test : public benchmark::test_case
{ {
std::string xml_; std::string xml_;
mapnik::box2d<double> extent_; mapnik::box2d<double> extent_;
public:
test(mapnik::parameters const& params, public:
std::string const& xml, test(mapnik::parameters const& params, std::string const& xml, mapnik::box2d<double> const& extent)
mapnik::box2d<double> const& extent) : test_case(params)
: test_case(params), , xml_(xml)
xml_(xml), , extent_(extent)
extent_(extent) {}
{}
bool validate() const bool validate() const
{ {
mapnik::Map m(256,256); mapnik::Map m(256, 256);
mapnik::load_map(m,xml_); mapnik::load_map(m, xml_);
m.zoom_to_box(extent_); m.zoom_to_box(extent_);
mapnik::image_rgba8 im(m.width(),m.height()); mapnik::image_rgba8 im(m.width(), m.height());
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
ren.apply(); ren.apply();
//mapnik::save_to_file(im.data(),"test.png"); // mapnik::save_to_file(im.data(),"test.png");
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
mapnik::Map m(256,256); mapnik::Map m(256, 256);
mapnik::load_map(m,xml_); mapnik::load_map(m, xml_);
m.zoom_to_box(extent_); m.zoom_to_box(extent_);
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
mapnik::image_rgba8 im(m.width(),m.height()); mapnik::image_rgba8 im(m.width(), m.height());
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
ren.apply(); ren.apply();
} }
return true; return true;
} }
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
mapnik::datasource_cache::instance().register_datasources("./plugins/input/"); mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
mapnik::box2d<double> z1(-20037508.3428,-8317435.0606,20037508.3428,18399242.7298); mapnik::box2d<double> z1(-20037508.3428, -8317435.0606, 20037508.3428, 18399242.7298);
// bbox for 16/10491/22911.png // bbox for 16/10491/22911.png
mapnik::box2d<double> z16(-13622912.929097254,6026906.8062295765,-13621689.93664469,6028129.79868214); mapnik::box2d<double> z16(-13622912.929097254, 6026906.8062295765, -13621689.93664469, 6028129.79868214);
return benchmark::sequencer(argc, argv) return benchmark::sequencer(argc, argv)
.run<test>("polygon clip render z1", "benchmark/data/polygon_rendering_clip.xml", z1) .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 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 clip render z16", "benchmark/data/polygon_rendering_clip.xml", z16)
.run<test>("polygon noclip render z16", "benchmark/data/polygon_rendering_no_clip.xml", z16) .run<test>("polygon noclip render z16", "benchmark/data/polygon_rendering_no_clip.xml", z16)
.done(); .done();
} }

View file

@ -9,46 +9,47 @@ class test : public benchmark::test_case
std::string dest_; std::string dest_;
mapnik::box2d<double> from_; mapnik::box2d<double> from_;
mapnik::box2d<double> to_; mapnik::box2d<double> to_;
bool defer_proj4_init_; bool defer_proj_init_;
public:
public:
test(mapnik::parameters const& params, test(mapnik::parameters const& params,
std::string const& src, std::string const& src,
std::string const& dest, std::string const& dest,
mapnik::box2d<double> const& from, mapnik::box2d<double> const& from,
mapnik::box2d<double> const& to, mapnik::box2d<double> const& to,
bool defer_proj) bool defer_proj)
: test_case(params), : test_case(params)
src_(src), , src_(src)
dest_(dest), , dest_(dest)
from_(from), , from_(from)
to_(to), , to_(to)
defer_proj4_init_(defer_proj) {} , defer_proj_init_(defer_proj)
{}
bool validate() const bool validate() const
{ {
mapnik::projection src(src_,defer_proj4_init_); mapnik::projection src(src_, defer_proj_init_);
mapnik::projection dest(dest_,defer_proj4_init_); mapnik::projection dest(dest_, defer_proj_init_);
mapnik::proj_transform tr(src,dest); mapnik::proj_transform tr(src, dest);
mapnik::box2d<double> bbox = from_; mapnik::box2d<double> bbox = from_;
if (!tr.forward(bbox)) return false; if (!tr.forward(bbox))
return ((std::fabs(bbox.minx() - to_.minx()) < .5) && return false;
(std::fabs(bbox.maxx() - to_.maxx()) < .5) && 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.miny() - to_.miny()) < .5) && (std::fabs(bbox.maxy() - to_.maxy()) < .5));
(std::fabs(bbox.maxy() - to_.maxy()) < .5)
);
} }
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) 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 j = -180; j < 180; j = j + 5)
{ {
for (int k=-85;k<85;k=k+5) for (int k = -85; k < 85; k = k + 5)
{ {
mapnik::projection src(src_,defer_proj4_init_); mapnik::box2d<double> box(j, k, j, k);
mapnik::projection dest(dest_,defer_proj4_init_); if (!tr.forward(box))
mapnik::proj_transform tr(src,dest); throw std::runtime_error("could not transform coords");
mapnik::box2d<double> box(j,k,j,k);
if (!tr.forward(box)) throw std::runtime_error("could not transform coords");
} }
} }
} }
@ -56,19 +57,21 @@ public:
} }
}; };
// echo -180 -60 | cs2cs -f "%.10f" +init=epsg:4326 +to +init=epsg:3857 // echo -180 -60 | cs2cs -f "%.10f" epsg:4326 +to epsg:3857
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::box2d<double> from(-180,-80,180,80); mapnik::setup();
mapnik::box2d<double> to(-20037508.3427892476,-15538711.0963092316,20037508.3427892476,15538711.0963092316); mapnik::box2d<double> from(-180, -80, 180, 80);
std::string from_str("+init=epsg:4326"); mapnik::box2d<double> to(-20037508.3427892476, -15538711.0963092316, 20037508.3427892476, 15538711.0963092316);
std::string to_str("+init=epsg:3857"); 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 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"); 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) return benchmark::sequencer(argc, argv)
.run<test>("lonlat->merc epsg", from_str, to_str, from, to, true) .run<test>("lonlat->merc epsg (internal)", from_str, to_str, from, to, true)
.run<test>("lonlat->merc literal", from_str2, to_str2, from, to, true) .run<test>("lonlat->merc literal (libproj)", from_str2, to_str2, from, to, true)
.run<test>("merc->lonlat epsg", to_str, from_str, to, from, true) .run<test>("merc->lonlat epsg (internal)", to_str, from_str, to, from, true)
.run<test>("merc->lonlat literal", to_str2, from_str2, to, from, true) .run<test>("merc->lonlat literal (libproj)", to_str2, from_str2, to, from, true)
.done(); .done();
} }

View file

@ -6,43 +6,41 @@ using quad_tree_type = mapnik::quad_tree<std::size_t>;
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; }
{
return true;
}
bool operator()() const bool operator()() const
{ {
std::random_device rd; std::random_device rd;
std::default_random_engine engine(rd()); std::default_random_engine engine(rd());
std::uniform_int_distribution<int> uniform_dist(0, 2048); std::uniform_int_distribution<int> uniform_dist(0, 2048);
quad_tree_type tree(mapnik::box2d<double>(0,0,2048,2048)); quad_tree_type tree(mapnik::box2d<double>(0, 0, 2048, 2048));
//populate // populate
for (size_t i = 0; i < iterations_; ++i) for (size_t i = 0; i < iterations_; ++i)
{ {
int cx = uniform_dist(engine); int cx = uniform_dist(engine);
int cy = uniform_dist(engine); int cy = uniform_dist(engine);
int sx = 0.2 * uniform_dist(engine); int sx = 0.2 * uniform_dist(engine);
int sy = 0.2 * uniform_dist(engine); int sy = 0.2 * uniform_dist(engine);
mapnik::box2d<double> box(cx - sx,cy - sy, cx + sx, cy + sy); mapnik::box2d<double> box(cx - sx, cy - sy, cx + sx, cy + sy);
tree.insert(i, box); tree.insert(i, box);
} }
// bounding box query // bounding box query
std::size_t count=0; std::size_t count = 0;
for (size_t i = 0; i < iterations_; ++i) for (size_t i = 0; i < iterations_; ++i)
{ {
int cx = uniform_dist(engine); int cx = uniform_dist(engine);
int cy = uniform_dist(engine); int cy = uniform_dist(engine);
int sx = 0.4 * uniform_dist(engine); int sx = 0.4 * uniform_dist(engine);
int sy = 0.4 * uniform_dist(engine); int sy = 0.4 * uniform_dist(engine);
mapnik::box2d<double> box(cx - sx,cy - sy, cx + sx, cy + sy); mapnik::box2d<double> box(cx - sx, cy - sy, cx + sx, cy + sy);
auto itr = tree.query_in_box(box); auto itr = tree.query_in_box(box);
auto end = tree.query_end(); auto end = tree.query_end();
for ( ;itr != end; ++itr) for (; itr != end; ++itr)
{ {
++count; ++count;
} }
@ -51,4 +49,4 @@ public:
} }
}; };
BENCHMARK(test,"quad_tree creation") BENCHMARK(test, "quad_tree creation")

View file

@ -15,24 +15,25 @@ class test : public benchmark::test_case
mapnik::value_integer height_; mapnik::value_integer height_;
double scale_factor_; double scale_factor_;
std::string preview_; std::string preview_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
xml_(), , xml_()
extent_(), , extent_()
width_(*params.get<mapnik::value_integer>("width",256)), , width_(*params.get<mapnik::value_integer>("width", 256))
height_(*params.get<mapnik::value_integer>("height",256)), , height_(*params.get<mapnik::value_integer>("height", 256))
scale_factor_(*params.get<mapnik::value_double>("scale_factor",1.0)), , scale_factor_(*params.get<mapnik::value_double>("scale_factor", 1.0))
preview_(*params.get<std::string>("preview","")) , preview_(*params.get<std::string>("preview", ""))
{ {
boost::optional<std::string> map = params.get<std::string>("map"); const auto map = params.get<std::string>("map");
if (!map) if (!map)
{ {
throw std::runtime_error("please provide a --map <path to xml> arg"); throw std::runtime_error("please provide a --map <path to xml> arg");
} }
xml_ = *map; xml_ = *map;
boost::optional<std::string> ext = params.get<std::string>("extent"); const auto ext = params.get<std::string>("extent");
if (ext && !ext->empty()) if (ext && !ext->empty())
{ {
if (!extent_.from_string(*ext)) if (!extent_.from_string(*ext))
@ -43,67 +44,74 @@ public:
{ {
throw std::runtime_error("please provide a --extent=<minx,miny,maxx,maxy> arg"); throw std::runtime_error("please provide a --extent=<minx,miny,maxx,maxy> arg");
}*/ }*/
}
}
bool validate() const bool validate() const
{ {
mapnik::Map m(width_,height_); mapnik::Map m(width_, height_);
mapnik::load_map(m,xml_,true); mapnik::load_map(m, xml_, true);
if (extent_.valid()) { if (extent_.valid())
{
m.zoom_to_box(extent_); m.zoom_to_box(extent_);
} else { }
else
{
m.zoom_all(); m.zoom_all();
} }
mapnik::image_rgba8 im(m.width(),m.height()); mapnik::image_rgba8 im(m.width(), m.height());
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im, scale_factor_);
ren.apply(); ren.apply();
if (!preview_.empty()) { if (!preview_.empty())
{
std::clog << "preview available at " << preview_ << "\n"; std::clog << "preview available at " << preview_ << "\n";
mapnik::save_to_file(im,preview_); mapnik::save_to_file(im, preview_);
} }
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
if (!preview_.empty()) { if (!preview_.empty())
{
return false; return false;
} }
mapnik::Map m(width_,height_); mapnik::Map m(width_, height_);
mapnik::load_map(m,xml_); mapnik::load_map(m, xml_);
if (extent_.valid()) { if (extent_.valid())
{
m.zoom_to_box(extent_); m.zoom_to_box(extent_);
} else { }
else
{
m.zoom_all(); m.zoom_all();
} }
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
mapnik::image_rgba8 im(m.width(),m.height()); mapnik::image_rgba8 im(m.width(), m.height());
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_); mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im, scale_factor_);
ren.apply(); ren.apply();
} }
return true; return true;
} }
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
int return_value = 0; int return_value = 0;
try try
{ {
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
boost::optional<std::string> name = params.get<std::string>("name"); const auto name = params.get<std::string>("name");
if (!name) if (!name)
{ {
std::clog << "please provide a name for this test\n"; std::clog << "please provide a name for this test\n";
return -1; return -1;
} }
mapnik::freetype_engine::register_fonts("./fonts/",true); mapnik::freetype_engine::register_fonts("./fonts/", true);
mapnik::datasource_cache::instance().register_datasources("./plugins/input/"); mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
{ {
test test_runner(params); test test_runner(params);
return_value = run(test_runner,*name); return_value = run(test_runner, *name);
} }
} }
catch (std::exception const& ex) catch (std::exception const& ex)

View file

@ -12,14 +12,15 @@
#include <mapnik/datasource_cache.hpp> #include <mapnik/datasource_cache.hpp>
#include <stdexcept> #include <stdexcept>
template <typename Renderer> void process_layers(Renderer & ren, template<typename Renderer>
mapnik::request const& m_req, void process_layers(Renderer& ren,
mapnik::projection const& map_proj, mapnik::request const& m_req,
std::vector<mapnik::layer> const& layers, mapnik::projection const& map_proj,
double scale_denom) std::vector<mapnik::layer> const& layers,
double scale_denom)
{ {
unsigned layers_size = layers.size(); unsigned layers_size = layers.size();
for (unsigned i=0; i < layers_size; ++i) for (unsigned i = 0; i < layers_size; ++i)
{ {
mapnik::layer const& lyr = layers[i]; mapnik::layer const& lyr = layers[i];
if (lyr.visible(scale_denom)) if (lyr.visible(scale_denom))
@ -50,27 +51,28 @@ class test : public benchmark::test_case
double scale_factor_; double scale_factor_;
std::string preview_; std::string preview_;
mutable mapnik::image_rgba8 im_; mutable mapnik::image_rgba8 im_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
xml_(), , xml_()
extent_(), , extent_()
width_(*params.get<mapnik::value_integer>("width",256)), , width_(*params.get<mapnik::value_integer>("width", 256))
height_(*params.get<mapnik::value_integer>("height",256)), , height_(*params.get<mapnik::value_integer>("height", 256))
m_(new mapnik::Map(width_,height_)), , m_(new mapnik::Map(width_, height_))
scale_factor_(*params.get<mapnik::value_double>("scale_factor",2.0)), , scale_factor_(*params.get<mapnik::value_double>("scale_factor", 2.0))
preview_(*params.get<std::string>("preview","")), , preview_(*params.get<std::string>("preview", ""))
im_(m_->width(),m_->height()) , im_(m_->width(), m_->height())
{ {
boost::optional<std::string> map = params.get<std::string>("map"); const auto map = params.get<std::string>("map");
if (!map) if (!map)
{ {
throw std::runtime_error("please provide a --map=<path to xml> arg"); throw std::runtime_error("please provide a --map=<path to xml> arg");
} }
xml_ = *map; xml_ = *map;
boost::optional<std::string> ext = params.get<std::string>("extent"); auto ext = params.get<std::string>("extent");
mapnik::load_map(*m_,xml_,true); mapnik::load_map(*m_, xml_, true);
if (ext && !ext->empty()) if (ext && !ext->empty())
{ {
if (!extent_.from_string(*ext)) if (!extent_.from_string(*ext))
@ -87,42 +89,44 @@ public:
bool validate() const bool validate() const
{ {
mapnik::request m_req(width_,height_,extent_); mapnik::request m_req(width_, height_, extent_);
mapnik::attributes variables; mapnik::attributes variables;
m_req.set_buffer_size(m_->buffer_size()); m_req.set_buffer_size(m_->buffer_size());
mapnik::projection map_proj(m_->srs(),true); mapnik::projection map_proj(m_->srs(), true);
double scale_denom = mapnik::scale_denominator(m_req.scale(),map_proj.is_geographic()); double scale_denom = mapnik::scale_denominator(m_req.scale(), map_proj.is_geographic());
scale_denom *= scale_factor_; scale_denom *= scale_factor_;
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_,m_req,variables,im_,scale_factor_); mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_, m_req, variables, im_, scale_factor_);
ren.start_map_processing(*m_); ren.start_map_processing(*m_);
std::vector<mapnik::layer> const& layers = m_->layers(); std::vector<mapnik::layer> const& layers = m_->layers();
process_layers(ren,m_req,map_proj,layers,scale_denom); process_layers(ren, m_req, map_proj, layers, scale_denom);
ren.end_map_processing(*m_); ren.end_map_processing(*m_);
if (!preview_.empty()) { if (!preview_.empty())
{
std::clog << "preview available at " << preview_ << "\n"; std::clog << "preview available at " << preview_ << "\n";
mapnik::save_to_file(im_,preview_); mapnik::save_to_file(im_, preview_);
} }
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
if (!preview_.empty()) { if (!preview_.empty())
{
return false; return false;
} }
for (unsigned i=0;i<iterations_;++i) for (unsigned i = 0; i < iterations_; ++i)
{ {
mapnik::request m_req(width_,height_,extent_); mapnik::request m_req(width_, height_, extent_);
mapnik::image_rgba8 im(m_->width(),m_->height()); mapnik::image_rgba8 im(m_->width(), m_->height());
mapnik::attributes variables; mapnik::attributes variables;
m_req.set_buffer_size(m_->buffer_size()); m_req.set_buffer_size(m_->buffer_size());
mapnik::projection map_proj(m_->srs(),true); mapnik::projection map_proj(m_->srs(), true);
double scale_denom = mapnik::scale_denominator(m_req.scale(),map_proj.is_geographic()); double scale_denom = mapnik::scale_denominator(m_req.scale(), map_proj.is_geographic());
scale_denom *= scale_factor_; scale_denom *= scale_factor_;
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_,m_req,variables,im,scale_factor_); mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_, m_req, variables, im, scale_factor_);
ren.start_map_processing(*m_); ren.start_map_processing(*m_);
std::vector<mapnik::layer> const& layers = m_->layers(); std::vector<mapnik::layer> const& layers = m_->layers();
process_layers(ren,m_req,map_proj,layers,scale_denom); process_layers(ren, m_req, map_proj, layers, scale_denom);
ren.end_map_processing(*m_); ren.end_map_processing(*m_);
bool diff = false; bool diff = false;
mapnik::image_rgba8 const& dest = im; mapnik::image_rgba8 const& dest = im;
@ -133,34 +137,36 @@ public:
const unsigned int* row_to = dest.get_row(y); const unsigned int* row_to = dest.get_row(y);
for (unsigned int x = 0; x < width_; ++x) for (unsigned int x = 0; x < width_; ++x)
{ {
if (row_from[x] != row_to[x]) diff = true; if (row_from[x] != row_to[x])
diff = true;
} }
} }
if (diff) throw std::runtime_error("images differ"); if (diff)
throw std::runtime_error("images differ");
} }
return true; return true;
} }
}; };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
int return_value = 0; int return_value = 0;
try try
{ {
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
boost::optional<std::string> name = params.get<std::string>("name"); const auto name = params.get<std::string>("name");
if (!name) if (!name)
{ {
std::clog << "please provide a name for this test\n"; std::clog << "please provide a name for this test\n";
return -1; return -1;
} }
mapnik::freetype_engine::register_fonts("./fonts/",true); mapnik::freetype_engine::register_fonts("./fonts/", true);
mapnik::datasource_cache::instance().register_datasources("./plugins/input/"); mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
{ {
test test_runner(params); test test_runner(params);
return_value = run(test_runner,*name); return_value = run(test_runner, *name);
} }
} }
catch (std::exception const& ex) catch (std::exception const& ex)

View file

@ -4,27 +4,31 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::string value_; std::string value_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
value_("true") {} , value_("true")
{}
bool validate() const bool validate() const
{ {
bool result = false; bool result = false;
mapnik::util::string2bool(value_.data(),value_.data()+value_.size(),result); mapnik::util::string2bool(value_.data(), value_.data() + value_.size(), result);
if (!result) return result; if (!result)
mapnik::util::string2bool(value_,result); return result;
mapnik::util::string2bool(value_, result);
return (result == true); return (result == true);
} }
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
bool result = false; bool result = false;
mapnik::util::string2bool(value_,result); mapnik::util::string2bool(value_, result);
mapnik::util::string2bool(value_.data(),value_.data()+value_.size(),result); mapnik::util::string2bool(value_.data(), value_.data() + value_.size(), result);
} }
return true; return true;
} }
}; };
BENCHMARK(test,"string->bool") BENCHMARK(test, "string->bool")

View file

@ -4,29 +4,36 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::string value_; std::string value_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
value_("1.23456789") {} , value_("1.23456789")
{}
bool validate() const bool validate() const
{ {
double result = 0; double result = 0;
if (!mapnik::util::string2double(value_.data(),value_.data()+value_.size(),result)) return false; if (!mapnik::util::string2double(value_.data(), value_.data() + value_.size(), result))
if (result != 1.23456789) return false; return false;
if (result != 1.23456789)
return false;
result = 0; result = 0;
if (!mapnik::util::string2double(value_,result)) return false; if (!mapnik::util::string2double(value_, result))
if (result != 1.23456789) return false; return false;
if (result != 1.23456789)
return false;
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
double result = 0; double result = 0;
mapnik::util::string2double(value_,result); mapnik::util::string2double(value_, result);
mapnik::util::string2double(value_.data(),value_.data()+value_.size(),result); mapnik::util::string2double(value_.data(), value_.data() + value_.size(), result);
} }
return true; return true;
} }
}; };
BENCHMARK(test,"string->double") BENCHMARK(test, "string->double")

View file

@ -4,29 +4,36 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::string value_; std::string value_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
value_("123456789") {} , value_("123456789")
{}
bool validate() const bool validate() const
{ {
mapnik::value_integer result = 0; mapnik::value_integer result = 0;
if (!mapnik::util::string2int(value_.data(),value_.data()+value_.size(),result)) return false; if (!mapnik::util::string2int(value_.data(), value_.data() + value_.size(), result))
if (result != 123456789) return false; return false;
if (result != 123456789)
return false;
result = 0; result = 0;
if (!mapnik::util::string2int(value_,result)) return false; if (!mapnik::util::string2int(value_, result))
if (result != 123456789) return false; return false;
if (result != 123456789)
return false;
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
mapnik::value_integer result = 0; mapnik::value_integer result = 0;
mapnik::util::string2int(value_,result); mapnik::util::string2int(value_, result);
mapnik::util::string2int(value_.data(),value_.data()+value_.size(),result); mapnik::util::string2int(value_.data(), value_.data() + value_.size(), result);
} }
return true; return true;
} }
}; };
BENCHMARK(test,"string->int") BENCHMARK(test, "string->int")

View file

@ -4,25 +4,28 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
double value_; double value_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
value_(-0.1234) {} , value_(-0.1234)
{}
bool validate() const bool validate() const
{ {
std::string s; std::string s;
mapnik::util::to_string(s,value_); mapnik::util::to_string(s, value_);
return (s == "-0.1234"); return (s == "-0.1234");
} }
bool operator()() const bool operator()() const
{ {
std::string out; std::string out;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
out.clear(); out.clear();
mapnik::util::to_string(out,value_); mapnik::util::to_string(out, value_);
} }
return true; return true;
} }
}; };
BENCHMARK(test,"to_string double->string") BENCHMARK(test, "to_string double->string")

View file

@ -4,10 +4,12 @@
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
double value_; double value_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
value_(-0.1234) {} , value_(-0.1234)
{}
bool validate() const bool validate() const
{ {
std::ostringstream s; std::ostringstream s;
@ -17,7 +19,8 @@ public:
bool operator()() const bool operator()() const
{ {
std::string out; std::string out;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
{
std::ostringstream s; std::ostringstream s;
s << value_; s << value_;
out = s.str(); out = s.str();
@ -26,4 +29,4 @@ public:
} }
}; };
BENCHMARK(test,"ostringstream double->string") BENCHMARK(test, "ostringstream double->string")

View file

@ -1,34 +1,41 @@
#include "bench_framework.hpp" #include "bench_framework.hpp"
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/util/from_u8string.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <boost/locale.hpp> #include <boost/locale.hpp>
#ifndef __linux__ #ifndef __linux__
#include <codecvt> #include <codecvt>
#endif
using mapnik::util::from_u8string;
#ifndef __linux__
class test : public benchmark::test_case class test : public benchmark::test_case
{ {
std::string utf8_; std::string utf8_;
public:
public:
test(mapnik::parameters const& params) test(mapnik::parameters const& params)
: test_case(params), : test_case(params)
utf8_(u8"שלום") {} , utf8_(from_u8string(u8"שלום"))
{}
bool validate() const bool validate() const
{ {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv; std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
std::u32string utf32 = utf32conv.from_bytes(utf8_); std::u32string utf32 = utf32conv.from_bytes(utf8_);
if (utf32.size() != 4) return false; if (utf32.size() != 4)
if (utf32[0] != 0x5e9 && return false;
utf32[1] != 0x5dc && if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
utf32[2] != 0x5d5 && return false;
utf32[3] != 0x5dd) return false;
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
std::u32string utf32; std::u32string utf32;
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv; std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
utf32 = utf32conv.from_bytes(utf8_); {
utf32 = utf32conv.from_bytes(utf8_);
} }
return true; return true;
} }
@ -39,26 +46,28 @@ public:
class test2 : public benchmark::test_case class test2 : public benchmark::test_case
{ {
std::string utf8_; std::string utf8_;
public:
public:
test2(mapnik::parameters const& params) test2(mapnik::parameters const& params)
: test_case(params), : test_case(params)
utf8_(u8"שלום") {} , utf8_(from_u8string(u8"שלום"))
{}
bool validate() const bool validate() const
{ {
std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_); std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
if (utf32.size() != 4) return false; if (utf32.size() != 4)
if (utf32[0] != 0x5e9 && return false;
utf32[1] != 0x5dc && if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
utf32[2] != 0x5d5 && return false;
utf32[3] != 0x5dd) return false;
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
std::u32string utf32; std::u32string utf32;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_); {
} utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
}
return true; return true;
} }
}; };
@ -66,28 +75,30 @@ public:
class test3 : public benchmark::test_case class test3 : public benchmark::test_case
{ {
std::string utf8_; std::string utf8_;
public:
public:
test3(mapnik::parameters const& params) test3(mapnik::parameters const& params)
: test_case(params), : test_case(params)
utf8_(u8"שלום") {} , utf8_(from_u8string(u8"שלום"))
{}
bool validate() const bool validate() const
{ {
mapnik::transcoder tr_("utf-8"); mapnik::transcoder tr_("utf-8");
mapnik::value_unicode_string utf32 = tr_.transcode(utf8_.data(),utf8_.size()); mapnik::value_unicode_string utf32 = tr_.transcode(utf8_.data(), utf8_.size());
//std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_); // std::u32string utf32 = boost::locale::conv::utf_to_utf<char32_t>(utf8_);
if (utf32.length() != 4) return false; if (utf32.length() != 4)
if (utf32[0] != 0x5e9 && return false;
utf32[1] != 0x5dc && if (utf32[0] != 0x5e9 && utf32[1] != 0x5dc && utf32[2] != 0x5d5 && utf32[3] != 0x5dd)
utf32[2] != 0x5d5 && return false;
utf32[3] != 0x5dd) return false;
return true; return true;
} }
bool operator()() const bool operator()() const
{ {
mapnik::transcoder tr_("utf-8"); mapnik::transcoder tr_("utf-8");
mapnik::value_unicode_string utf32; mapnik::value_unicode_string utf32;
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i = 0; i < iterations_; ++i)
utf32 = tr_.transcode(utf8_.data(),utf8_.size()); {
utf32 = tr_.transcode(utf8_.data(), utf8_.size());
} }
return true; return true;
} }
@ -95,18 +106,19 @@ public:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
mapnik::setup();
mapnik::parameters params; mapnik::parameters params;
benchmark::handle_args(argc,argv,params); benchmark::handle_args(argc, argv, params);
int return_value = 0; int return_value = 0;
#ifndef __linux__ #ifndef __linux__
test test_runner(params); test test_runner(params);
return_value = return_value | run(test_runner,"utf encode std::codecvt"); return_value = return_value | run(test_runner, "utf encode std::codecvt");
#else #else
std::clog << "skipping 'utf encode std::codecvt' test since <codecvt> is not supported on __linux__\n"; std::clog << "skipping 'utf encode std::codecvt' test since <codecvt> is not supported on __linux__\n";
#endif #endif
test2 test_runner2(params); test2 test_runner2(params);
return_value = return_value | run(test_runner2,"utf encode boost::locale"); return_value = return_value | run(test_runner2, "utf encode boost::locale");
test3 test_runner3(params); test3 test_runner3(params);
return_value = return_value | run(test_runner3,"utf encode ICU"); return_value = return_value | run(test_runner3, "utf encode ICU");
return return_value; return return_value;
} }

View file

@ -2,16 +2,12 @@
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; }
return true; void operator()() const {}
}
void operator()() const
{
}
}; };
BENCHMARK(test,"test name") BENCHMARK(test, "test name")

View file

@ -1,174 +0,0 @@
#!/usr/bin/env bash
: '
todo
- docs for base setup: sudo apt-get -y install zlib1g-dev make git
- shrink icu data
'
MASON_VERSION="e4c1746"
function setup_mason() {
if [[ ! -d ./.mason ]]; then
git clone https://github.com/mapbox/mason.git .mason || return
elif ! git -C .mason rev-parse -q --verify "$MASON_VERSION" >/dev/null; then
git -C .mason fetch --all || true # non-fatal
fi
git -C .mason checkout --detach "$MASON_VERSION" -- || return
case ":$PATH:" in
*":$PWD/.mason:"*) : already there ;;
*) export PATH="$PWD/.mason:$PATH" ;;
esac
export CXX=${CXX:-clang++}
export CC=${CC:-clang}
}
function install() {
MASON_PLATFORM_ID=$(mason env MASON_PLATFORM_ID)
if [[ ! -d ./mason_packages/${MASON_PLATFORM_ID}/${1}/${2} ]]; then
mason install $1 $2
if [[ ${3:-false} != false ]]; then
LA_FILE=$(mason prefix $1 $2)/lib/$3.la
if [[ -f ${LA_FILE} ]]; then
perl -i -p -e 's:\Q$ENV{HOME}/build/mapbox/mason\E:$ENV{PWD}:g' ${LA_FILE}
else
echo "$LA_FILE not found"
fi
fi
fi
# the rm here is to workaround https://github.com/mapbox/mason/issues/230
rm -f ./mason_packages/.link/mason.ini
mason link $1 $2
}
ICU_VERSION="57.1"
BOOST_VERSION="1.65.1"
function install_mason_deps() {
install ccache 3.3.1
install zlib 1.2.8
install jpeg_turbo 1.5.1 libjpeg
install libpng 1.6.28 libpng
install libtiff 4.0.7 libtiff
install libpq 9.6.2
install sqlite 3.17.0 libsqlite3
install expat 2.2.0 libexpat
install icu ${ICU_VERSION}
install proj 4.9.3 libproj
install pixman 0.34.0 libpixman-1
install cairo 1.14.8 libcairo
install webp 0.6.0 libwebp
install libgdal 2.1.3 libgdal
install boost ${BOOST_VERSION}
install boost_libsystem ${BOOST_VERSION}
install boost_libfilesystem ${BOOST_VERSION}
install boost_libprogram_options ${BOOST_VERSION}
install boost_libregex_icu57 ${BOOST_VERSION}
# technically boost thread and python are not a core dep, but installing
# here by default helps make python-mapnik builds easier
install boost_libthread ${BOOST_VERSION}
install boost_libpython ${BOOST_VERSION}
install freetype 2.7.1 libfreetype
install harfbuzz 1.4.4-ft libharfbuzz
}
MASON_LINKED_ABS=$(pwd)/mason_packages/.link
MASON_LINKED_REL=./mason_packages/.link
export C_INCLUDE_PATH="${MASON_LINKED_ABS}/include"
export CPLUS_INCLUDE_PATH="${MASON_LINKED_ABS}/include"
export LIBRARY_PATH="${MASON_LINKED_ABS}/lib"
function make_config() {
echo "
CXX = '$CXX'
CC = '$CC'
CUSTOM_CXXFLAGS = '-D_GLIBCXX_USE_CXX11_ABI=0'
RUNTIME_LINK = 'static'
INPUT_PLUGINS = 'all'
PATH = '${MASON_LINKED_REL}/bin'
PKG_CONFIG_PATH = '${MASON_LINKED_REL}/lib/pkgconfig'
PATH_REMOVE = '/usr:/usr/local'
PATH_REPLACE = '$HOME/build/mapbox/mason/mason_packages:./mason_packages'
BOOST_INCLUDES = '${MASON_LINKED_REL}/include'
BOOST_LIBS = '${MASON_LINKED_REL}/lib'
ICU_INCLUDES = '${MASON_LINKED_REL}/include'
ICU_LIBS = '${MASON_LINKED_REL}/lib'
HB_INCLUDES = '${MASON_LINKED_REL}/include'
HB_LIBS = '${MASON_LINKED_REL}/lib'
PNG_INCLUDES = '${MASON_LINKED_REL}/include/libpng16'
PNG_LIBS = '${MASON_LINKED_REL}/lib'
JPEG_INCLUDES = '${MASON_LINKED_REL}/include'
JPEG_LIBS = '${MASON_LINKED_REL}/lib'
TIFF_INCLUDES = '${MASON_LINKED_REL}/include'
TIFF_LIBS = '${MASON_LINKED_REL}/lib'
WEBP_INCLUDES = '${MASON_LINKED_REL}/include'
WEBP_LIBS = '${MASON_LINKED_REL}/lib'
PROJ_INCLUDES = '${MASON_LINKED_REL}/include'
PROJ_LIBS = '${MASON_LINKED_REL}/lib'
PG_INCLUDES = '${MASON_LINKED_REL}/include'
PG_LIBS = '${MASON_LINKED_REL}/lib'
FREETYPE_INCLUDES = '${MASON_LINKED_REL}/include/freetype2'
FREETYPE_LIBS = '${MASON_LINKED_REL}/lib'
SVG_RENDERER = True
CAIRO_INCLUDES = '${MASON_LINKED_REL}/include'
CAIRO_LIBS = '${MASON_LINKED_REL}/lib'
SQLITE_INCLUDES = '${MASON_LINKED_REL}/include'
SQLITE_LIBS = '${MASON_LINKED_REL}/lib'
BENCHMARK = True
CPP_TESTS = True
PGSQL2SQLITE = True
XMLPARSER = 'ptree'
SVG2PNG = True
"
}
# NOTE: the `mapnik-settings.env` is used by test/run (which is run by `make test`)
function setup_runtime_settings() {
echo "export PROJ_LIB=${MASON_LINKED_ABS}/share/proj" > mapnik-settings.env
echo "export ICU_DATA=${MASON_LINKED_ABS}/share/icu/${ICU_VERSION}" >> mapnik-settings.env
echo "export GDAL_DATA=${MASON_LINKED_ABS}/share/gdal" >> mapnik-settings.env
}
# turn arguments of the form NAME=VALUE into exported variables;
# any other arguments are reported and cause error return status
function export_variables() {
local arg= ret=0
for arg
do
if [[ "$arg" =~ ^[[:alpha:]][_[:alnum:]]*= ]]
then
export "$arg"
else
printf >&2 "bootstrap.sh: invalid argument: %s\n" "$arg"
ret=1
fi
done
return $ret
}
function main() {
export_variables "$@" || return
# setup_mason must not run in subshell, because it sets default
# values of CC, CXX and adds mason to PATH, which we want to keep
# when sourced
setup_mason || return
(
# this is wrapped in subshell to allow sourcing this script
# without having the terminal closed on error
set -eu
set -o pipefail
install_mason_deps
make_config > ./config.py
setup_runtime_settings
printf "\n\e[1;32m%s\e[m\n" "bootstrap successful, now run:"
echo ""
echo " ./configure && make"
echo ""
)
}
main "$@"

View file

@ -0,0 +1,23 @@
include(CheckCXXSourceRuns)
function(check_boost_regex)
set(CMAKE_REQUIRED_LIBRARIES ICU::uc ICU::data ICU::i18n Boost::headers Boost::regex)
check_cxx_source_runs([[
#include <boost/regex/icu.hpp>
#include <unicode/unistr.h>
int main()
{
U_NAMESPACE_QUALIFIER UnicodeString ustr;
try {
boost::u32regex pattern = boost::make_u32regex(ustr);
}
// an exception is fine, still indicates support is
// likely compiled into regex
catch (...) {
return 0;
}
return 0;
}
]] BOOST_REGEX_HAS_ICU)
set(BOOST_REGEX_HAS_ICU ${BOOST_REGEX_HAS_ICU} PARENT_SCOPE)
endfunction(check_boost_regex)

14
cmake/GetVersion.cmake Normal file
View file

@ -0,0 +1,14 @@
macro(get_mapnik_version)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/include/mapnik/version.hpp VERSION_FILE)
string(REGEX MATCH "MAPNIK_MAJOR_VERSION ([0-9]*)" _ ${VERSION_FILE})
set(MAPNIK_MAJOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "MAPNIK_MINOR_VERSION ([0-9]*)" _ ${VERSION_FILE})
set(MAPNIK_MINOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "MAPNIK_PATCH_VERSION ([0-9]*)" _ ${VERSION_FILE})
set(MAPNIK_PATCH_VERSION ${CMAKE_MATCH_1})
set(MAPNIK_VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION})
endmacro()

68
cmake/MapnikExport.cmake Normal file
View file

@ -0,0 +1,68 @@
include(CMakePackageConfigHelpers)
### exports mapnik cmake config files (mapnikConfigVersion and mapnikConfig)
function(mapnik_export_cmake_config)
# export mapnik configuration
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/mapnikConfigVersion.cmake"
VERSION ${MAPNIK_VERSION}
COMPATIBILITY ExactVersion
)
get_property(MAPNIK_UTILITIES GLOBAL PROPERTY MAPNIK_UTILITIES)
# generate all find_dependency and pkg_config calls
set(mapnik_find_deps)
foreach(dep IN LISTS mapnik_deps)
set(ver_comment "# ${dep} used with version ${mapnik_${dep}_version}")
set(mapnik_find_deps "${mapnik_find_deps}\n${ver_comment}\n")
if(mapnik_${dep}_find_args)
list(REMOVE_DUPLICATES mapnik_${dep}_find_args)
list(JOIN mapnik_${dep}_find_args " " m_args_joined)
set(mapnik_find_deps "${mapnik_find_deps}find_dependency(${dep} ${m_args_joined})")
else()
list(JOIN mapnik_${dep}_pkg_args " " m_args_joined)
set(mapnik_find_deps "${mapnik_find_deps}pkg_check_modules(${dep} ${m_args_joined})")
endif()
endforeach()
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/mapnikConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/mapnikConfig.cmake"
INSTALL_DESTINATION ${MAPNIK_CMAKE_DIR}
PATH_VARS MAPNIK_INCLUDE_DIR PLUGINS_INSTALL_DIR FONTS_INSTALL_DIR mapnik_find_deps MAPNIK_UTILITIES
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/mapnikConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/mapnikConfigVersion.cmake"
DESTINATION ${MAPNIK_CMAKE_DIR}
)
endfunction()
mapnik_export_cmake_config()
install(EXPORT MapnikTargets
DESTINATION ${MAPNIK_CMAKE_DIR}
FILE mapnikTargets.cmake
NAMESPACE mapnik::
)
### install plugin cmake config files ###
# Create configuration dependend files for the plugin install dirs.
# some package managers are using different paths per configuration.
string(TOLOWER "${CMAKE_BUILD_TYPE}" _build_type)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_l)
set(m_mapnik_plugin_file_name mapnikPlugins-${_build_type})
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${m_mapnik_plugin_file_name}.cmake.in" "set(MAPNIK_PLUGINS_DIR_${_build_type_l} \"@PACKAGE_PLUGINS_INSTALL_DIR@\" CACHE STRING \"\")\n")
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_CURRENT_BINARY_DIR}/${m_mapnik_plugin_file_name}.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${m_mapnik_plugin_file_name}.cmake"
PATH_VARS PLUGINS_INSTALL_DIR
INSTALL_DESTINATION ${MAPNIK_CMAKE_DIR}
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${m_mapnik_plugin_file_name}.cmake"
DESTINATION ${MAPNIK_CMAKE_DIR}
)

View file

@ -0,0 +1,92 @@
function(create_pkg_config_file _target _lib_name _description)
string(CONFIGURE [[
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/@MAPNIK_LIB_DIR@
Name: @_lib_name@
Description: @_description@
Version: @MAPNIK_VERSION@
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:@_target@>$<TARGET_PROPERTY:@_target@,$<CONFIG>_POSTFIX>
Cflags: -I"${includedir}" -I"${includedir}/mapnik" ]]
_contents @ONLY)
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
CONTENT "${_contents}"
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
DESTINATION ${MAPNIK_PKGCONF_DIR}
RENAME ${_lib_name}.pc
)
endfunction()
function(create_pkg_config_file_mapnik _lib_name _description)
get_target_property(m_compile_defs core INTERFACE_COMPILE_DEFINITIONS)
string(JOIN " -D" m_str_compile_defs ${m_compile_defs})
if(m_str_compile_defs)
set(m_str_compile_defs "-D${m_str_compile_defs}")
endif()
set(m_requires
libmapnikwkt
libmapnikjson
icu-uc
icu-i18n
harfbuzz
freetype2
)
if(USE_LIBXML2)
list(APPEND m_requires libxml-2.0)
endif()
if(USE_PNG)
list(APPEND m_requires libpng)
endif()
if(USE_JPEG)
list(APPEND m_requires libjpeg)
endif()
if(USE_TIFF)
list(APPEND m_requires libtiff-4)
endif()
if(USE_WEBP)
list(APPEND m_requires libwebp)
endif()
if(USE_CAIRO)
list(APPEND m_requires cairo)
endif()
if(USE_PROJ)
list(APPEND m_requires "proj >= ${PROJ_MIN_VERSION}")
endif()
string(JOIN " " m_requires ${m_requires})
string(CONFIGURE [[
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/@MAPNIK_LIB_DIR@
fonts_dir=${prefix}/@FONTS_INSTALL_DIR@
plugins_dir=${prefix}/@PLUGINS_INSTALL_DIR@
Name: @_lib_name@
Description: @_description@
Version: @MAPNIK_VERSION@
Requires: @m_requires@
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:mapnik>$<TARGET_PROPERTY:mapnik,$<CONFIG>_POSTFIX>
Cflags: -I"${includedir}" -I"${includedir}/mapnik" -I"${includedir}/mapnik/agg" @m_str_compile_defs@]]
_contents @ONLY)
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
CONTENT "${_contents}"
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
DESTINATION ${MAPNIK_PKGCONF_DIR}
RENAME ${_lib_name}.pc
)
endfunction()
create_pkg_config_file(wkt libmapnikwkt "wkt library")
create_pkg_config_file(json libmapnikjson "json library")
create_pkg_config_file_mapnik("libmapnik" "mapnik library")

View file

@ -0,0 +1,64 @@
function(mapnik_set_dep_version dep var)
string(TOUPPER ${dep} m_package_name_upc)
set(m_package_name ${dep})
if(${m_package_name}_VERSION_STRING)
set(${var} ${${m_package_name}_VERSION_STRING} PARENT_SCOPE)
elseif(${m_package_name}_VERSION)
set(${var} ${${m_package_name}_VERSION} PARENT_SCOPE)
elseif(${m_package_name_upc}_VERSION_STRING)
set(${var} ${${m_package_name_upc}_VERSION_STRING} PARENT_SCOPE)
elseif(${m_package_name_upc}_VERSION)
set(${var} ${${m_package_name_upc}_VERSION} PARENT_SCOPE)
endif()
endfunction()
function(mapnik_print_package_info dep)
message(STATUS "Using ${dep} version: ${mapnik_${dep}_version}")
endfunction()
macro(mapnik_find_package dep)
find_package(${dep} ${ARGN})
if(${dep}_FOUND)
list(APPEND mapnik_deps ${dep})
if(mapnik_${dep}_find_args)
list(APPEND mapnik_${dep}_find_args ${ARGN})
else()
set(mapnik_${dep}_find_args ${ARGN})
endif()
mapnik_set_dep_version(${dep} mapnik_${dep}_version)
mapnik_print_package_info(${dep})
else()
message(STATUS "not found: ${dep}")
endif()
endmacro()
macro(mapnik_pkg_check_modules dep)
pkg_check_modules(${dep} ${ARGN})
if(${dep}_FOUND)
list(APPEND mapnik_deps ${dep})
set(mapnik_${dep}_pkg_args ${ARGN})
mapnik_set_dep_version(${dep} mapnik_${dep}_version)
mapnik_print_package_info(${dep})
else()
message(STATUS "not found: ${dep}")
endif()
endmacro()
macro(mapnik_find_threads)
find_package(Threads REQUIRED)
if(CMAKE_THREAD_LIBS_INIT)
message(STATUS "Using Threads (system libraries)")
elseif(CMAKE_USE_WIN32_THREADS_INIT)
message(STATUS "Using Threads (win32 threads)")
elseif(CMAKE_USE_PTHREADS_INIT)
message(STATUS "Using Threads (pthread)")
elseif(CMAKE_HP_PTHREADS_INIT)
message(STATUS "Using Threads (HP thread)")
else()
message(STATUS "Using Threads (unknown backend)")
endif()
endmacro()

98
cmake/MapnikInstall.cmake Normal file
View file

@ -0,0 +1,98 @@
#
# Install library targets that consuming users need.
#
function(mapnik_install _target)
install(TARGETS ${_target}
EXPORT MapnikTargets
INCLUDES DESTINATION ${MAPNIK_INCLUDE_DIR}
RUNTIME DESTINATION ${MAPNIK_BIN_DIR}
COMPONENT MapnikRuntime
LIBRARY DESTINATION ${MAPNIK_LIB_DIR}
COMPONENT MapnikRuntime
NAMELINK_COMPONENT MapnikDevelopment
ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR}
COMPONENT MapnikDevelopment
)
get_target_property(TARGET_TYPE "${_target}" TYPE)
if (TARGET_TYPE STREQUAL "SHARED_LIBRARY")
set_property(GLOBAL APPEND PROPERTY TARGETS ${_target})
endif()
endfunction()
#
# Install plugins
#
function(mapnik_install_plugin _target)
if(NOT BUILD_SHARED_PLUGINS)
return()
endif()
install(TARGETS ${_target}
RUNTIME DESTINATION ${PLUGINS_INSTALL_DIR}
COMPONENT MapnikPluginRuntime
LIBRARY DESTINATION ${PLUGINS_INSTALL_DIR}
COMPONENT MapnikPluginRuntime
NAMELINK_COMPONENT MapnikPluginDevelopment
ARCHIVE DESTINATION ${PLUGINS_INSTALL_DIR}
COMPONENT MapnikPluginDevelopment
)
set_property(GLOBAL APPEND PROPERTY PLUGINS ${_target})
endfunction()
#
# Install executables. These are available via COMPONENTS in find_package
#
function(mapnik_install_utility _target)
set(_target_name "mapnikUtilityTargets_${_target}")
install(TARGETS ${_target}
EXPORT ${_target_name}
INCLUDES DESTINATION ${MAPNIK_INCLUDE_DIR}
RUNTIME DESTINATION ${MAPNIK_BIN_DIR}
COMPONENT MapnikRuntime
LIBRARY DESTINATION ${MAPNIK_LIB_DIR}
COMPONENT MapnikRuntime
NAMELINK_COMPONENT MapnikDevelopment
ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR}
COMPONENT MapnikDevelopment
)
install(EXPORT ${_target_name}
FILE ${_target_name}.cmake
NAMESPACE mapnik::
DESTINATION ${MAPNIK_CMAKE_DIR}
)
set_property(GLOBAL APPEND PROPERTY MAPNIK_UTILITIES ${_target})
endfunction()
function(mapnik_install_targets)
if(INSTALL_DEPENDENCIES AND WIN32)
# https://cmake.org/cmake/help/latest/policy/CMP0087.html
cmake_policy(SET CMP0087 NEW)
get_property(_installed_utilities GLOBAL PROPERTY MAPNIK_UTILITIES)
get_property(_installed_targets GLOBAL PROPERTY TARGETS)
get_property(_installed_plugins GLOBAL PROPERTY PLUGINS)
set(_internal_executables "")
set(_internal_libraries "")
foreach(_target IN LISTS _installed_utilities)
list(APPEND _internal_executables "\${CMAKE_INSTALL_PREFIX}/${MAPNIK_BIN_DIR}/$<TARGET_FILE_NAME:${_target}>")
endforeach()
foreach(_target IN LISTS _installed_targets)
list(APPEND _internal_libraries "\${CMAKE_INSTALL_PREFIX}/${MAPNIK_BIN_DIR}/$<TARGET_FILE_NAME:${_target}>")
endforeach()
foreach(_target IN LISTS _installed_plugins)
list(APPEND _internal_libraries "\${CMAKE_INSTALL_PREFIX}/${PLUGINS_INSTALL_DIR}/$<TARGET_FILE_NAME:${_target}>")
endforeach()
# all other executables get auto detected and fixed.
if(_internal_executables)
list(GET _internal_executables 0 _internal_executables)
endif()
INSTALL(CODE "
message(STATUS \"internal_executables: ${_internal_executables}\")
message(STATUS \"internal_libraries: ${_internal_libraries}\")
message(STATUS \"ADDITIONAL_LIBARIES_PATHS: ${ADDITIONAL_LIBARIES_PATHS}\")
include(BundleUtilities)
fixup_bundle(\"${_internal_executables}\" \"${_internal_libraries}\" \"${ADDITIONAL_LIBARIES_PATHS}\")
" COMPONENT MapnikRuntime)
endif()
endfunction()

View file

@ -0,0 +1,3 @@
set(BOOST_MIN_VERSION 1.73)
set(HARFBUZZ_MIN_VERSION 0.9.34)
set(PROJ_MIN_VERSION 7.2.0)

4
cmake/MapnikOption.cmake Normal file
View file

@ -0,0 +1,4 @@
macro(mapnik_option option_name option_description option_default_value)
option(${option_name} "${option_description}" ${option_default_value})
add_feature_info(${option_name} ${option_name} "${option_description}")
endmacro()

16
cmake/clang-format.cmake Normal file
View file

@ -0,0 +1,16 @@
function(format_dir dir)
file(GLOB_RECURSE sources
"${dir}/*.cpp"
"${dir}/*.hpp"
)
execute_process(COMMAND clang-format -style=file -i ${sources})
endfunction()
format_dir(benchmark)
format_dir(demo)
format_dir(include)
format_dir(plugins)
format_dir(src)
format_dir(test)
format_dir(utils)

View file

@ -0,0 +1,52 @@
@PACKAGE_INIT@
set_and_check(MAPNIK_INCLUDE_DIR "@PACKAGE_MAPNIK_INCLUDE_DIR@" CACHE STRING "")
set_and_check(MAPNIK_FONTS_DIR "@PACKAGE_FONTS_INSTALL_DIR@" CACHE STRING "")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/Modules/")
include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)
@mapnik_find_deps@
include("${CMAKE_CURRENT_LIST_DIR}/mapnikTargets.cmake")
set(_supported_components @MAPNIK_UTILITIES@)
foreach(_comp ${mapnik_FIND_COMPONENTS})
if (NOT _comp IN_LIST _supported_components)
set(mapnik_FOUND False)
set(mapnik_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/mapnikUtilityTargets_${_comp}.cmake")
endforeach()
get_filename_component(_plugin_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_plugin_dir}/mapnikPlugins-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
function(mapnik_find_plugin_dir PLUGIN_DIR)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_l)
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_build_type_l}}")
# only release has more then one configuration
if(NOT _plugin_dir)
set(_all_rel_cfgs RELEASE RELWITHDEBINFO MINSIZEREL)
list(FIND _all_rel_cfgs ${_build_type_l} _is_rel_cfg)
# check if the current configuration is a known release configuration
if(${_is_rel_cfg} GREATER_EQUAL 0)
foreach(_rel_cfg IN LISTS _all_rel_cfgs)
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_rel_cfg}}")
if(_plugin_dir)
break()
endif()
endforeach()
endif()
endif()
if(NOT _plugin_dir)
message(WARNING "Could not find a plugin install dir for configuration ${_build_type_l}")
endif()
set(${PLUGIN_DIR} ${_plugin_dir} PARENT_SCOPE)
endfunction()

18
cmake/pack.cmake Normal file
View file

@ -0,0 +1,18 @@
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_NAME "mapnik")
set(CPACK_PACKAGE_CONTACT "ubuntu-mathis@outlook.com")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://mapnik.org")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_GENERATOR "DEB;TGZ")
set(CPACK_SOURCE_IGNORE_FILES
\\.git/
build/
".*~$"
out/
\\.vs/
\\.vscode/
)
set(CPACK_VERBATIM_VARIABLES YES)
include(CPack)

18
configure vendored
View file

@ -1,18 +1,32 @@
#! /bin/sh #! /usr/bin/env bash
set -eu set -eu
: ${PYTHON:=python} : ${PYTHON:=python}
# Only some shells (Bash and Z shell) support arrays. Therefore,
# the following code provides an alternative for users calling the script
# with shells other than Bash or Z shell (e.g. Debian users using Dash).
THE_SHELL=$(basename $SHELL)
if [ "$THE_SHELL" != "bash" ] && [ "$THE_SHELL" != "zsh" ]; then
if [ -f mapnik-settings.env ]; then
echo "WARNING: Reading from mapnik-settings.env is supported with Bash or Z shell only."
fi
$PYTHON scons/scons.py --implicit-deps-changed configure "$@"
exit 0
fi
# mapnik-settings.env is an optional file to store # mapnik-settings.env is an optional file to store
# environment variables that should be used before # environment variables that should be used before
# running tests like PROJ_LIB, GDAL_DATA, and ICU_DATA # running tests like PROJ_LIB, GDAL_DATA, and ICU_DATA
# These do not normally need to be set except when # These do not normally need to be set except when
# building against binary versions of dependencies like # building against binary versions of dependencies like
# done via bootstrap.sh # done via bootstrap.sh
if [ -f mapnik-settings.env ]; then if [ -f mapnik-settings.env ]; then
echo "Inheriting from mapnik-settings.env" echo "Inheriting from mapnik-settings.env"
. ./mapnik-settings.env . ./mapnik-settings.env
VARS=( $(cat mapnik-settings.env) )
fi fi
$PYTHON scons/scons.py --implicit-deps-changed configure "$@" $PYTHON scons/scons.py --implicit-deps-changed configure ${VARS[*]:-} "$@"

7
demo/CMakeLists.txt Normal file
View file

@ -0,0 +1,7 @@
if(BUILD_DEMO_VIEWER)
add_subdirectory(viewer)
endif()
if(BUILD_DEMO_CPP)
add_subdirectory(c++)
endif()

6
demo/c++/CMakeLists.txt Normal file
View file

@ -0,0 +1,6 @@
add_executable(mapnik-demo rundemo.cpp)
target_link_libraries(mapnik-demo 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?)
)

View file

@ -41,7 +41,7 @@ if env['HAS_CAIRO']:
demo_env.Append(CPPDEFINES = '-DHAVE_CAIRO') demo_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
libraries = [env['MAPNIK_NAME']] libraries = [env['MAPNIK_NAME']]
libraries.extend(copy(env['LIBMAPNIK_LIBS'])) libraries.extend([copy(env['LIBMAPNIK_LIBS']), 'sqlite3', 'pthread'])
rundemo = demo_env.Program('rundemo', source, LIBS=libraries) rundemo = demo_env.Program('rundemo', source, LIBS=libraries)
Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME'])) Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,6 +20,7 @@
* *
*****************************************************************************/ *****************************************************************************/
#include <mapnik/mapnik.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
#include <mapnik/rule.hpp> #include <mapnik/rule.hpp>
@ -45,19 +46,21 @@
#include <iostream> #include <iostream>
int main(int, char**)
int main ( int, char** )
{ {
using namespace mapnik; using namespace mapnik;
const std::string srs_lcc="+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"; const std::string srs_lcc =
const std::string srs_merc="+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"; "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs";
const std::string srs_merc = "+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 "
try { "+units=m +nadgrids=@null +wktext +no_defs +over";
mapnik::setup();
try
{
std::cout << " running demo ... \n"; std::cout << " running demo ... \n";
datasource_cache::instance().register_datasources("plugins/input/"); datasource_cache::instance().register_datasources("plugins/input/");
freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.37/ttf/DejaVuSans.ttf"); freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.37/ttf/DejaVuSans.ttf");
Map m(800,600); Map m(800, 600);
m.set_background(parse_color("white")); m.set_background(parse_color("white"));
m.set_srs(srs_merc); m.set_srs(srs_merc);
// create styles // create styles
@ -93,13 +96,13 @@ int main ( int, char** )
rule r; rule r;
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(0,0,0)); put(line_sym, keys::stroke, color(0, 0, 0));
put(line_sym,keys::stroke_width,1.0); put(line_sym, keys::stroke_width, 1.0);
dash_array dash; dash_array dash;
dash.emplace_back(8,4); dash.emplace_back(8, 4);
dash.emplace_back(2,2); dash.emplace_back(2, 2);
dash.emplace_back(2,2); dash.emplace_back(2, 2);
put(line_sym,keys::stroke_dasharray,dash); put(line_sym, keys::stroke_dasharray, dash);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
provlines_style.add_rule(std::move(r)); provlines_style.add_rule(std::move(r));
@ -127,10 +130,10 @@ int main ( int, char** )
r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4")); r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(171,158,137)); put(line_sym, keys::stroke, color(171, 158, 137));
put(line_sym,keys::stroke_width,2.0); put(line_sym, keys::stroke_width, 2.0);
put(line_sym,keys::stroke_linecap,ROUND_CAP); put(line_sym, keys::stroke_linecap, line_cap_enum::ROUND_CAP);
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym, keys::stroke_linejoin, line_join_enum::ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads34_style.add_rule(std::move(r)); roads34_style.add_rule(std::move(r));
@ -144,10 +147,10 @@ int main ( int, char** )
r.set_filter(parse_expression("[CLASS] = 2")); r.set_filter(parse_expression("[CLASS] = 2"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(171,158,137)); put(line_sym, keys::stroke, color(171, 158, 137));
put(line_sym,keys::stroke_width,4.0); put(line_sym, keys::stroke_width, 4.0);
put(line_sym,keys::stroke_linecap,ROUND_CAP); put(line_sym, keys::stroke_linecap, line_cap_enum::ROUND_CAP);
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym, keys::stroke_linejoin, line_join_enum::ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads2_style_1.add_rule(std::move(r)); roads2_style_1.add_rule(std::move(r));
@ -160,10 +163,10 @@ int main ( int, char** )
r.set_filter(parse_expression("[CLASS] = 2")); r.set_filter(parse_expression("[CLASS] = 2"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(255,250,115)); put(line_sym, keys::stroke, color(255, 250, 115));
put(line_sym,keys::stroke_width,2.0); put(line_sym, keys::stroke_width, 2.0);
put(line_sym,keys::stroke_linecap,ROUND_CAP); put(line_sym, keys::stroke_linecap, line_cap_enum::ROUND_CAP);
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym, keys::stroke_linejoin, line_join_enum::ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads2_style_2.add_rule(std::move(r)); roads2_style_2.add_rule(std::move(r));
@ -177,10 +180,10 @@ int main ( int, char** )
r.set_filter(parse_expression("[CLASS] = 1")); r.set_filter(parse_expression("[CLASS] = 1"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(188,149,28)); put(line_sym, keys::stroke, color(188, 149, 28));
put(line_sym,keys::stroke_width,7.0); put(line_sym, keys::stroke_width, 7.0);
put(line_sym,keys::stroke_linecap,ROUND_CAP); put(line_sym, keys::stroke_linecap, line_cap_enum::ROUND_CAP);
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym, keys::stroke_linejoin, line_join_enum::ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads1_style_1.add_rule(std::move(r)); roads1_style_1.add_rule(std::move(r));
@ -193,10 +196,10 @@ int main ( int, char** )
r.set_filter(parse_expression("[CLASS] = 1")); r.set_filter(parse_expression("[CLASS] = 1"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(242,191,36)); put(line_sym, keys::stroke, color(242, 191, 36));
put(line_sym,keys::stroke_width,5.0); put(line_sym, keys::stroke_width, 5.0);
put(line_sym,keys::stroke_linecap,ROUND_CAP); put(line_sym, keys::stroke_linecap, line_cap_enum::ROUND_CAP);
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym, keys::stroke_linejoin, line_join_enum::ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads1_style_2.add_rule(std::move(r)); roads1_style_2.add_rule(std::move(r));
@ -212,10 +215,11 @@ int main ( int, char** )
text_placements_ptr placement_finder = std::make_shared<text_placements_dummy>(); text_placements_ptr placement_finder = std::make_shared<text_placements_dummy>();
placement_finder->defaults.format_defaults.face_name = "DejaVu Sans Book"; placement_finder->defaults.format_defaults.face_name = "DejaVu Sans Book";
placement_finder->defaults.format_defaults.text_size = 10.0; placement_finder->defaults.format_defaults.text_size = 10.0;
placement_finder->defaults.format_defaults.fill = color(0,0,0); placement_finder->defaults.format_defaults.fill = color(0, 0, 0);
placement_finder->defaults.format_defaults.halo_fill = color(255,255,200); placement_finder->defaults.format_defaults.halo_fill = color(255, 255, 200);
placement_finder->defaults.format_defaults.halo_radius = 1.0; placement_finder->defaults.format_defaults.halo_radius = 1.0;
placement_finder->defaults.set_format_tree(std::make_shared<mapnik::formatting::text_node>(parse_expression("[GEONAME]"))); placement_finder->defaults.set_format_tree(
std::make_shared<mapnik::formatting::text_node>(parse_expression("[GEONAME]")));
put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder); put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder);
r.append(std::move(text_sym)); r.append(std::move(text_sym));
} }
@ -228,9 +232,9 @@ int main ( int, char** )
// Provincial polygons // Provincial polygons
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/boundaries"; p["file"] = "demo/data/boundaries";
p["encoding"]="utf8"; p["encoding"] = "utf8";
layer lyr("Provinces"); layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
@ -242,8 +246,8 @@ int main ( int, char** )
// Drainage // Drainage
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/qcdrainage"; p["file"] = "demo/data/qcdrainage";
layer lyr("Quebec Hydrography"); layer lyr("Quebec Hydrography");
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);
@ -253,8 +257,8 @@ int main ( int, char** )
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/ontdrainage"; p["file"] = "demo/data/ontdrainage";
layer lyr("Ontario Hydrography"); layer lyr("Ontario Hydrography");
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);
@ -265,8 +269,8 @@ int main ( int, char** )
// Provincial boundaries // Provincial boundaries
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/boundaries_l"; p["file"] = "demo/data/boundaries_l";
layer lyr("Provincial borders"); layer lyr("Provincial borders");
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
@ -277,8 +281,8 @@ int main ( int, char** )
// Roads // Roads
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/roads"; p["file"] = "demo/data/roads";
layer lyr("Roads"); layer lyr("Roads");
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
@ -293,8 +297,8 @@ int main ( int, char** )
// popplaces // popplaces
{ {
parameters p; parameters p;
p["type"]="shape"; p["type"] = "shape";
p["file"]="demo/data/popplaces"; p["file"] = "demo/data/popplaces";
p["encoding"] = "utf8"; p["encoding"] = "utf8";
layer lyr("Populated Places"); layer lyr("Populated Places");
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);
@ -303,28 +307,28 @@ int main ( int, char** )
m.add_layer(lyr); m.add_layer(lyr);
} }
m.zoom_to_box(box2d<double>(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855)); m.zoom_to_box(box2d<double>(-8024477.28459, 5445190.38849, -7381388.20071, 5662941.44855));
image_rgba8 buf(m.width(),m.height()); image_rgba8 buf(m.width(), m.height());
agg_renderer<image_rgba8> ren(m,buf); agg_renderer<image_rgba8> ren(m, buf);
ren.apply(); ren.apply();
std::string msg("These maps have been rendered using AGG in the current directory:\n"); std::string msg("These maps have been rendered using AGG in the current directory:\n");
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
save_to_file(buf,"demo.jpg","jpeg"); save_to_file(buf, "demo.jpg", "jpeg");
msg += "- demo.jpg\n"; msg += "- demo.jpg\n";
#endif #endif
#ifdef HAVE_PNG #ifdef HAVE_PNG
save_to_file(buf,"demo.png","png"); save_to_file(buf, "demo.png", "png");
save_to_file(buf,"demo256.png","png8"); save_to_file(buf, "demo256.png", "png8");
msg += "- demo.png\n"; msg += "- demo.png\n";
msg += "- demo256.png\n"; msg += "- demo256.png\n";
#endif #endif
#ifdef HAVE_TIFF #ifdef HAVE_TIFF
save_to_file(buf,"demo.tif","tiff"); save_to_file(buf, "demo.tif", "tiff");
msg += "- demo.tif\n"; msg += "- demo.tif\n";
#endif #endif
#ifdef HAVE_WEBP #ifdef HAVE_WEBP
save_to_file(buf,"demo.webp","webp"); save_to_file(buf, "demo.webp", "webp");
msg += "- demo.webp\n"; msg += "- demo.webp\n";
#endif #endif
msg += "Have a look!\n"; msg += "Have a look!\n";
@ -332,8 +336,8 @@ int main ( int, char** )
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
// save to pdf/svg files // save to pdf/svg files
save_to_cairo_file(m,"cairo-demo.pdf"); save_to_cairo_file(m, "cairo-demo.pdf");
save_to_cairo_file(m,"cairo-demo.svg"); save_to_cairo_file(m, "cairo-demo.svg");
/* we could also do: /* we could also do:
@ -342,38 +346,38 @@ int main ( int, char** )
but instead let's build up a surface for more flexibility but instead let's build up a surface for more flexibility
*/ */
cairo_surface_ptr image_surface( cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m.width(), m.height()),
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,m.width(),m.height()), cairo_surface_closer());
cairo_surface_closer());
double scale_factor = 1.0; double scale_factor = 1.0;
cairo_ptr image_context(create_context(image_surface)); cairo_ptr image_context(create_context(image_surface));
mapnik::cairo_renderer<cairo_ptr> png_render(m,image_context,scale_factor); mapnik::cairo_renderer<cairo_ptr> png_render(m, image_context, scale_factor);
png_render.apply(); png_render.apply();
// we can now write to png with cairo functionality // we can now write to png with cairo functionality
cairo_surface_write_to_png(&*image_surface, "cairo-demo.png"); cairo_surface_write_to_png(&*image_surface, "cairo-demo.png");
// but we can also benefit from quantization by converting // but we can also benefit from quantization by converting
// to a mapnik image object and then saving that // to a mapnik image object and then saving that
mapnik::image_rgba8 im_data(cairo_image_surface_get_width(&*image_surface), cairo_image_surface_get_height(&*image_surface)); mapnik::image_rgba8 im_data(cairo_image_surface_get_width(&*image_surface),
cairo_image_surface_get_height(&*image_surface));
cairo_image_to_rgba8(im_data, image_surface); cairo_image_to_rgba8(im_data, image_surface);
save_to_file(im_data, "cairo-demo256.png","png8"); save_to_file(im_data, "cairo-demo256.png", "png8");
cairo_surface_finish(&*image_surface); cairo_surface_finish(&*image_surface);
std::cout << "Three maps have been rendered using Cairo in the current directory:\n" std::cout << "Three maps have been rendered using Cairo in the current directory:\n"
"- cairo-demo.png\n" "- cairo-demo.png\n"
"- cairo-demo256.png\n" "- cairo-demo256.png\n"
"- cairo-demo.pdf\n" "- cairo-demo.pdf\n"
"- cairo-demo.svg\n" "- cairo-demo.svg\n"
"Have a look!\n"; "Have a look!\n";
#endif #endif
// save map definition (data + style) // save map definition (data + style)
save_map(m, "map.xml"); save_map(m, "map.xml");
} }
catch ( std::exception const& ex ) catch (std::exception const& ex)
{ {
std::cerr << "### std::exception: " << ex.what() << std::endl; std::cerr << "### std::exception: " << ex.what() << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
catch ( ... ) catch (...)
{ {
std::cerr << "### Unknown exception." << std::endl; std::cerr << "### Unknown exception." << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;

View file

@ -0,0 +1,64 @@
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
set(PROJECT_SOURCES
about_dialog.cpp
info_dialog.cpp
layerdelegate.cpp
layerlistmodel.cpp
layerwidget.cpp
layer_info_dialog.cpp
main.cpp
mainwindow.cpp
mapwidget.cpp
styles_model.cpp
forms/about.ui
forms/info.ui
forms/layer_info.ui
mapnik_viewer.qrc
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(mapnik-viewer
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
else()
if(ANDROID)
add_library(mapnik-viewer SHARED
${PROJECT_SOURCES}
)
else()
add_executable(mapnik-viewer
${PROJECT_SOURCES}
)
endif()
endif()
set_target_properties(mapnik-viewer PROPERTIES
AUTOUIC_SEARCH_PATHS forms
AUTORCC ON
AUTOUIC ON
AUTOMOC ON
)
target_link_libraries(mapnik-viewer PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
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?)
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini
"[mapnik]
plugins_dir=${PLUGINS_INSTALL_DIR}
fonts/1/dir=${FONTS_INSTALL_DIR}
fonts/size=1"
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(mapnik-viewer)
endif()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini DESTINATION bin)
mapnik_install_utility(mapnik-viewer)

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,12 +17,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "about_dialog.hpp" #include "about_dialog.hpp"
about_dialog::about_dialog(QWidget* parent)
about_dialog::about_dialog(QWidget *parent) : QDialog(parent)
: QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,8 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#if !defined ABOUT_DIALOG_HPP #if !defined ABOUT_DIALOG_HPP
#define ABOUT_DIALOG_HPP #define ABOUT_DIALOG_HPP
@ -27,12 +25,12 @@
class about_dialog : public QDialog class about_dialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
about_dialog(QWidget * parent = 0); about_dialog(QWidget* parent = 0);
private:
Ui::Dialog ui; private:
Ui::Dialog ui;
}; };
#endif // ABOUT_DIALOG_HPP
#endif //ABOUT_DIALOG_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,24 +17,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "info_dialog.hpp" #include "info_dialog.hpp"
info_dialog::info_dialog(QVector<QPair<QString, QString>> const& info, QWidget* parent)
info_dialog::info_dialog(QVector<QPair<QString,QString> > const& info, QWidget *parent) : QDialog(parent)
: QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
ui.tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Name")); ui.tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
ui.tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("Value")); ui.tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Value"));
ui.tableWidget->setRowCount(info.size()); ui.tableWidget->setRowCount(info.size());
ui.tableWidget->setColumnCount(2); ui.tableWidget->setColumnCount(2);
for (int i=0;i<info.size();++i) for (int i = 0; i < info.size(); ++i)
{ {
QTableWidgetItem *keyItem = new QTableWidgetItem(info[i].first); QTableWidgetItem* keyItem = new QTableWidgetItem(info[i].first);
QTableWidgetItem *valueItem = new QTableWidgetItem(info[i].second); QTableWidgetItem* valueItem = new QTableWidgetItem(info[i].second);
ui.tableWidget->setItem(i,0,keyItem); ui.tableWidget->setItem(i, 0, keyItem);
ui.tableWidget->setItem(i,1,valueItem); ui.tableWidget->setItem(i, 1, valueItem);
} }
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,8 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef INFO_DIALOG_HPP #ifndef INFO_DIALOG_HPP
#define INFO_DIALOG_HPP #define INFO_DIALOG_HPP
@ -27,12 +25,12 @@
class info_dialog : public QDialog class info_dialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
info_dialog(QVector<QPair<QString,QString> > const& info,QWidget * parent = 0); info_dialog(QVector<QPair<QString, QString>> const& info, QWidget* parent = 0);
private:
Ui::InfoDialog ui; private:
Ui::InfoDialog ui;
}; };
#endif // INFO_DIALOG_HPP
#endif //INFO_DIALOG_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "layer_info_dialog.hpp" #include "layer_info_dialog.hpp"
// mapnik // mapnik
@ -26,14 +25,13 @@
#include <mapnik/params_impl.hpp> #include <mapnik/params_impl.hpp>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
layer_info_dialog::layer_info_dialog(mapnik::layer& lay, QWidget* parent)
layer_info_dialog::layer_info_dialog(mapnik::layer& lay, QWidget *parent) : QDialog(parent)
: QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
ui.tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Name")); ui.tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
ui.tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("Value")); ui.tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Value"));
// Layer name // Layer name
ui.layerNameEdit->setText(QString(lay.name().c_str())); ui.layerNameEdit->setText(QString(lay.name().c_str()));
@ -50,17 +48,17 @@ layer_info_dialog::layer_info_dialog(mapnik::layer& lay, QWidget *parent)
ui.tableWidget->setColumnCount(2); ui.tableWidget->setColumnCount(2);
mapnik::parameters::const_iterator pos; mapnik::parameters::const_iterator pos;
int index=0; int index = 0;
for (pos = ps.begin();pos != ps.end();++pos) for (pos = ps.begin(); pos != ps.end(); ++pos)
{ {
boost::optional<std::string> result; std::optional<std::string> result;
mapnik::util::apply_visitor(mapnik::value_extractor_visitor<std::string>(result),pos->second); mapnik::util::apply_visitor(mapnik::value_extractor_visitor<std::string>(result), pos->second);
if (result) if (result)
{ {
QTableWidgetItem *keyItem = new QTableWidgetItem(QString(pos->first.c_str())); QTableWidgetItem* keyItem = new QTableWidgetItem(QString(pos->first.c_str()));
QTableWidgetItem *valueItem = new QTableWidgetItem(QString((*result).c_str())); QTableWidgetItem* valueItem = new QTableWidgetItem(QString((*result).c_str()));
ui.tableWidget->setItem(index,0,keyItem); ui.tableWidget->setItem(index, 0, keyItem);
ui.tableWidget->setItem(index,1,valueItem); ui.tableWidget->setItem(index, 1, valueItem);
++index; ++index;
} }
} }
@ -69,5 +67,5 @@ layer_info_dialog::layer_info_dialog(mapnik::layer& lay, QWidget *parent)
Ui::LayerInfoDialog& layer_info_dialog::getUI() Ui::LayerInfoDialog& layer_info_dialog::getUI()
{ {
return ui; return ui;
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,28 +17,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef LAYER_INFO_DIALOG_HPP #ifndef LAYER_INFO_DIALOG_HPP
#define LAYER_INFO_DIALOG_HPP #define LAYER_INFO_DIALOG_HPP
#include "ui_layer_info.h" #include "ui_layer_info.h"
#include <QDialog> #include <QDialog>
namespace mapnik namespace mapnik {
{
class layer; class layer;
} }
class layer_info_dialog : public QDialog class layer_info_dialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
layer_info_dialog(mapnik::layer& l, QWidget * parent = 0); layer_info_dialog(mapnik::layer& l, QWidget* parent = 0);
Ui::LayerInfoDialog& getUI(); Ui::LayerInfoDialog& getUI();
private:
Ui::LayerInfoDialog ui; private:
Ui::LayerInfoDialog ui;
}; };
#endif // LAYER_INFO_DIALOG_HPP
#endif //LAYER_INFO_DIALOG_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,38 +17,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <QtGui> #include <QtGui>
#include "layerdelegate.hpp" #include "layerdelegate.hpp"
LayerDelegate::LayerDelegate(QObject *parent) LayerDelegate::LayerDelegate(QObject* parent)
: QAbstractItemDelegate(parent) : QAbstractItemDelegate(parent)
{ {}
}
void LayerDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, void LayerDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
const QModelIndex &index) const
{ {
painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(QPen(QColor(255,0,0),1)); painter->setPen(QPen(QColor(255, 0, 0), 1));
if (option.state & QStyle::State_Selected) if (option.state & QStyle::State_Selected)
painter->setBrush(QBrush(QColor(0, 0, 255, 64))); painter->setBrush(QBrush(QColor(0, 0, 255, 64)));
else else
painter->setBrush(QBrush(QColor(255, 0, 0, 64))); painter->setBrush(QBrush(QColor(255, 0, 0, 64)));
painter->drawRoundedRect(option.rect, 4, 4);
painter->drawRoundRect(option.rect,4,4);
if (option.state & QStyle::State_Selected) if (option.state & QStyle::State_Selected)
painter->setBrush(option.palette.highlightedText()); painter->setBrush(option.palette.highlightedText());
else else
painter->setBrush(QBrush(QColor(255, 120, 0, 127))); painter->setBrush(QBrush(QColor(255, 120, 0, 127)));
} }
QSize LayerDelegate::sizeHint(const QStyleOptionViewItem & /* option */, QSize LayerDelegate::sizeHint(const QStyleOptionViewItem& /* option */, const QModelIndex& /* index */) const
const QModelIndex & /* index */) const
{ {
return QSize(120,24); return QSize(120, 24);
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,12 +33,10 @@ class LayerDelegate : public QAbstractItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
LayerDelegate(QObject *parent = 0); LayerDelegate(QObject* parent = 0);
void paint(QPainter *painter, const QStyleOptionViewItem &option, void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
}; };
#endif //LAYER_DELEGATE_HPP #endif // LAYER_DELEGATE_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,27 +17,26 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "layerlistmodel.hpp" #include "layerlistmodel.hpp"
#include <QIcon> #include <QIcon>
#include <QBrush>
#include <iostream>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
using mapnik::Map; using mapnik::Map;
LayerListModel::LayerListModel(std::shared_ptr<Map> map,QObject *parent) LayerListModel::LayerListModel(std::shared_ptr<Map> map, QObject* parent)
: QAbstractListModel(parent), : QAbstractListModel(parent)
map_(map) {} , map_(map)
{}
int LayerListModel::rowCount(QModelIndex const&) const int LayerListModel::rowCount(QModelIndex const&) const
{ {
if (map_) return map_->layers().size(); if (map_)
return 0; return map_->layers().size();
return 0;
} }
QVariant LayerListModel::data(QModelIndex const& index,int role) const QVariant LayerListModel::data(QModelIndex const& index, int role) const
{ {
if (!index.isValid() || !map_) if (!index.isValid() || !map_)
return QVariant(); return QVariant();
@ -60,9 +59,16 @@ QVariant LayerListModel::data(QModelIndex const& index,int role) const
else if (role == Qt::CheckStateRole) else if (role == Qt::CheckStateRole)
{ {
if (map_->layers().at(index.row()).active()) if (map_->layers().at(index.row()).active())
return QVariant(Qt::Checked); return QVariant(Qt::Checked);
else else
return QVariant(Qt::Unchecked); return QVariant(Qt::Unchecked);
}
else if (role == Qt::ForegroundRole)
{
if (map_->layers().at(index.row()).active())
return QBrush(QColor("black"));
else
return QBrush(QColor("lightgrey"));
} }
else else
{ {
@ -70,8 +76,7 @@ QVariant LayerListModel::data(QModelIndex const& index,int role) const
} }
} }
QVariant LayerListModel::headerData(int section, Qt::Orientation orientation, QVariant LayerListModel::headerData(int section, Qt::Orientation orientation, int role) const
int role) const
{ {
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
@ -82,38 +87,37 @@ QVariant LayerListModel::headerData(int section, Qt::Orientation orientation,
return QString("TODO Row %1").arg(section); return QString("TODO Row %1").arg(section);
} }
bool LayerListModel::setData(const QModelIndex &index, bool LayerListModel::setData(const QModelIndex& index, const QVariant& value, int role)
const QVariant &value, int role)
{ {
if (!map_) return false; if (!map_)
return false;
if (index.isValid() && role == Qt::CheckStateRole) if (index.isValid() && role == Qt::CheckStateRole)
{ {
int status = value.toInt(); int status = value.toInt();
std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers()); std::vector<mapnik::layer>& layers = const_cast<std::vector<mapnik::layer>&>(map_->layers());
layers.at(index.row()).set_active(status); layers.at(index.row()).set_active(status);
emit dataChanged(index, index); emit dataChanged(index, index);
return true; return true;
} }
return false; return false;
} }
Qt::ItemFlags LayerListModel::flags(QModelIndex const& index) const Qt::ItemFlags LayerListModel::flags(QModelIndex const& index) const
{ {
Qt::ItemFlags flags = QAbstractItemModel::flags(index); Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.isValid()) if (index.isValid())
flags |= Qt::ItemIsUserCheckable; flags |= Qt::ItemIsUserCheckable;
return flags; return flags;
} }
boost::optional<mapnik::layer&> LayerListModel::map_layer(int i) boost::optional<mapnik::layer&> LayerListModel::map_layer(int i)
{ {
if (map_) if (map_)
{ {
std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers()); std::vector<mapnik::layer>& layers = const_cast<std::vector<mapnik::layer>&>(map_->layers());
if (i < int(layers.size())) if (i < int(layers.size()))
return boost::optional<mapnik::layer&>(layers[i]); return boost::optional<mapnik::layer&>(layers[i]);
} }
return boost::optional<mapnik::layer&>(); return boost::optional<mapnik::layer&>();
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,8 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef LAYER_LIST_MODEL_HPP #ifndef LAYER_LIST_MODEL_HPP
#define LAYER_LIST_MODEL_HPP #define LAYER_LIST_MODEL_HPP
@ -32,20 +30,18 @@
class LayerListModel : public QAbstractListModel class LayerListModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
LayerListModel(std::shared_ptr<mapnik::Map> map, QObject * parent = 0); LayerListModel(std::shared_ptr<mapnik::Map> map, QObject* parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex& index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
int role = Qt::DisplayRole) const; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
bool setData(const QModelIndex &index, const QVariant &value, Qt::ItemFlags flags(QModelIndex const& index) const;
int role = Qt::EditRole); boost::optional<mapnik::layer&> map_layer(int i);
Qt::ItemFlags flags(QModelIndex const& index) const;
boost::optional<mapnik::layer&> map_layer(int i);
private: private:
std::shared_ptr<mapnik::Map> map_; std::shared_ptr<mapnik::Map> map_;
}; };
#endif //LAYER_LIST_MODEL_HPP #endif // LAYER_LIST_MODEL_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "layerwidget.hpp" #include "layerwidget.hpp"
#include <qabstractitemdelegate.h> #include <qabstractitemdelegate.h>
#include <qapplication.h> #include <qapplication.h>
@ -29,72 +28,63 @@
#include <qscrollbar.h> #include <qscrollbar.h>
#include <qrubberband.h> #include <qrubberband.h>
#include <qdebug.h> #include <qdebug.h>
#include <iostream>
#include "layerlistmodel.hpp" #include "layerlistmodel.hpp"
#include "layer_info_dialog.hpp" #include "layer_info_dialog.hpp"
using namespace std;
LayerTab::LayerTab(QWidget* parent) LayerTab::LayerTab(QWidget* parent)
: QListView(parent) {} : QListView(parent)
{}
void LayerTab::paintEvent(QPaintEvent* e)
void LayerTab::paintEvent(QPaintEvent *e)
{ {
QListView::paintEvent(e); QListView::paintEvent(e);
} }
void LayerTab::dataChanged(const QModelIndex &topLeft, void LayerTab::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
const QModelIndex &bottomRight)
{ {
QListView::dataChanged(topLeft, bottomRight); emit update_mapwidget();
qDebug("FIXME : update map view!"); QListView::dataChanged(topLeft, bottomRight, roles);
emit update_mapwidget();
} }
void LayerTab::selectionChanged(const QItemSelection & selected, const QItemSelection &) void LayerTab::selectionChanged(const QItemSelection& selected, const QItemSelection&)
{ {
QModelIndexList list = selected.indexes(); QModelIndexList list = selected.indexes();
if (list.size() != 0) if (list.size() != 0)
{ {
std::cout << "SELECTED LAYER ->" << list[0].row() << "\n"; qDebug("SELECTED LAYER -> %d", list[0].row());
emit layerSelected(list[0].row()); emit layerSelected(list[0].row());
} }
} }
void LayerTab::layerInfo() void LayerTab::layerInfo()
{ {
qDebug("Layer info"); qDebug("Layer info");
QModelIndexList indexes = selectedIndexes(); QModelIndexList indexes = selectedIndexes();
if (indexes.size() > 0) if (indexes.size() > 0)
{ {
qDebug("id = %d",indexes[0].row()); qDebug("id = %d", indexes[0].row());
}
}
} }
void LayerTab::layerInfo2(QModelIndex const& index) void LayerTab::layerInfo2(QModelIndex const& index)
{ {
qDebug("LayerInfo id = %d",index.row()); qDebug("LayerInfo id = %d", index.row());
QVector<QPair<QString,QString> > params; QVector<QPair<QString, QString>> params;
QVector<QString> style_names; QVector<QString> style_names;
unsigned i = index.row(); unsigned i = index.row();
LayerListModel * model = static_cast<LayerListModel*>(this->model()); LayerListModel* model = static_cast<LayerListModel*>(this->model());
boost::optional<mapnik::layer&> layer = model->map_layer(i); boost::optional<mapnik::layer&> layer = model->map_layer(i);
if (layer) if (layer)
{ {
layer_info_dialog dlg(*layer,this); layer_info_dialog dlg(*layer, this);
dlg.exec(); dlg.exec();
} }
} }
StyleTab::StyleTab(QWidget*) StyleTab::StyleTab(QWidget*) {}
void StyleTab::contextMenuEvent(QContextMenuEvent* event)
{ {
qDebug("test");
}
void StyleTab::contextMenuEvent(QContextMenuEvent * event )
{
qDebug("test");
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef LAYERWIDGET_HPP #ifndef LAYERWIDGET_HPP
#define LAYERWIDGET_HPP #define LAYERWIDGET_HPP
@ -27,28 +26,29 @@
class LayerTab : public QListView class LayerTab : public QListView
{ {
Q_OBJECT Q_OBJECT
public: public:
LayerTab(QWidget* parent=0); LayerTab(QWidget* parent = 0);
void paintEvent(QPaintEvent *e); void paintEvent(QPaintEvent* e);
signals: signals:
void update_mapwidget(); void update_mapwidget();
void layerSelected(int) const; void layerSelected(int) const;
public slots: public slots:
void layerInfo(); void layerInfo();
void layerInfo2(QModelIndex const&); void layerInfo2(QModelIndex const&);
protected slots: protected slots:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles);
void selectionChanged(const QItemSelection & selected, const QItemSelection &); void selectionChanged(const QItemSelection& selected, const QItemSelection&);
}; };
class StyleTab : public QTreeView class StyleTab : public QTreeView
{ {
Q_OBJECT Q_OBJECT
public: public:
StyleTab(QWidget* parent=0); StyleTab(QWidget* parent = 0);
protected:
void contextMenuEvent(QContextMenuEvent * event ); protected:
void contextMenuEvent(QContextMenuEvent* event);
}; };
#endif #endif

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,36 +17,36 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
// qt // qt
#include <QApplication> #include <QApplication>
#include <QStringList> #include <QStringList>
#include <QSettings> #include <QSettings>
#include <mapnik/datasource_cache.hpp> #include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp> #include <mapnik/font_engine_freetype.hpp>
#include <mapnik/mapnik.hpp>
#include "mainwindow.hpp" #include "mainwindow.hpp"
int main( int argc, char **argv ) int main(int argc, char** argv)
{ {
using mapnik::datasource_cache; using mapnik::datasource_cache;
using mapnik::freetype_engine; using mapnik::freetype_engine;
mapnik::setup();
try try
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif #endif
QCoreApplication::setOrganizationName("Mapnik"); QCoreApplication::setOrganizationName("Mapnik");
QCoreApplication::setOrganizationDomain("mapnik.org"); QCoreApplication::setOrganizationDomain("mapnik.org");
QCoreApplication::setApplicationName("Viewer"); QCoreApplication::setApplicationName("Viewer");
QSettings settings("viewer.ini",QSettings::IniFormat); QSettings settings("viewer.ini", QSettings::IniFormat);
// register input plug-ins // register input plug-ins
QString plugins_dir = settings.value("mapnik/plugins_dir", QString plugins_dir = settings.value("mapnik/plugins_dir", QVariant("/usr/local/lib/mapnik/input/")).toString();
QVariant("/usr/local/lib/mapnik/input/")).toString();
datasource_cache::instance().register_datasources(plugins_dir.toStdString()); datasource_cache::instance().register_datasources(plugins_dir.toStdString());
// register fonts // register fonts
int count = settings.beginReadArray("mapnik/fonts"); int count = settings.beginReadArray("mapnik/fonts");
for (int index=0; index < count; ++index) for (int index = 0; index < count; ++index)
{ {
settings.setArrayIndex(index); settings.setArrayIndex(index);
QString font_dir = settings.value("dir").toString(); QString font_dir = settings.value("dir").toString();
@ -54,33 +54,37 @@ int main( int argc, char **argv )
} }
settings.endArray(); settings.endArray();
QApplication app( argc, argv ); QApplication app(argc, argv);
MainWindow window; MainWindow window;
window.show(); window.show();
if (argc > 1) window.open(argv[1]); if (argc > 1)
window.open(argv[1]);
if (argc >= 3) if (argc >= 3)
{ {
QStringList list = QString(argv[2]).split(","); QStringList list = QString(argv[2]).split(",");
if (list.size()==4) if (list.size() == 4)
{ {
bool ok; bool ok;
double x0 = list[0].toDouble(&ok); double x0 = list[0].toDouble(&ok);
double y0 = list[1].toDouble(&ok); double y0 = list[1].toDouble(&ok);
double x1 = list[2].toDouble(&ok); double x1 = list[2].toDouble(&ok);
double y1 = list[3].toDouble(&ok); double y1 = list[3].toDouble(&ok);
if (ok) window.set_default_extent(x0,y0,x1,y1); if (ok)
window.set_default_extent(x0, y0, x1, y1);
} }
} }
else else
{ {
std::shared_ptr<mapnik::Map> map = window.get_map(); std::shared_ptr<mapnik::Map> map = window.get_map();
if (map) map->zoom_all(); if (map)
map->zoom_all();
} }
if (argc == 4) if (argc == 4)
{ {
bool ok; bool ok;
double scaling_factor = QString(argv[3]).toDouble(&ok); double scaling_factor = QString(argv[3]).toDouble(&ok);
if (ok) window.set_scaling_factor(scaling_factor); if (ok)
window.set_scaling_factor(scaling_factor);
} }
return app.exec(); return app.exec();
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
// stl // stl
#include <iostream> #include <iostream>
@ -39,7 +38,7 @@
// mapnik // mapnik
#ifndef Q_MOC_RUN // QT moc chokes on BOOST_JOIN #ifndef Q_MOC_RUN // QT moc chokes on BOOST_JOIN
//#include <mapnik/config_error.hpp> // #include <mapnik/config_error.hpp>
#include <mapnik/load_map.hpp> #include <mapnik/load_map.hpp>
#include <mapnik/save_map.hpp> #include <mapnik/save_map.hpp>
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
@ -58,27 +57,27 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
MainWindow::MainWindow() MainWindow::MainWindow()
: filename_(), : filename_()
default_extent_(-20037508.3428,-20037508.3428,20037508.3428,20037508.3428) , default_extent_(-20037508.3428, -20037508.3428, 20037508.3428, 20037508.3428)
{ {
mapWidget_ = new MapWidget(this); mapWidget_ = new MapWidget(this);
QSplitter *splitter = new QSplitter(this); QSplitter* splitter = new QSplitter(this);
QTabWidget *tabWidget=new QTabWidget; QTabWidget* tabWidget = new QTabWidget;
layerTab_ = new LayerTab; layerTab_ = new LayerTab;
layerTab_->setFocusPolicy(Qt::NoFocus); layerTab_->setFocusPolicy(Qt::NoFocus);
layerTab_->setIconSize(QSize(16,16)); layerTab_->setIconSize(QSize(16, 16));
//LayerDelegate *delegate = new LayerDelegate(this); // LayerDelegate *delegate = new LayerDelegate(this);
//layerTab_->setItemDelegate(delegate); // layerTab_->setItemDelegate(delegate);
//layerTab_->setItemDelegate(new QItemDelegate(this)); // layerTab_->setItemDelegate(new QItemDelegate(this));
//layerTab_->setViewMode(QListView::IconMode); // layerTab_->setViewMode(QListView::IconMode);
layerTab_->setFlow(QListView::TopToBottom); layerTab_->setFlow(QListView::TopToBottom);
tabWidget->addTab(layerTab_,tr("Layers")); tabWidget->addTab(layerTab_, tr("Layers"));
// Styles tab // Styles tab
styleTab_ = new StyleTab; styleTab_ = new StyleTab;
tabWidget->addTab(styleTab_,tr("Styles")); tabWidget->addTab(styleTab_, tr("Styles"));
splitter->addWidget(tabWidget); splitter->addWidget(tabWidget);
splitter->addWidget(mapWidget_); splitter->addWidget(mapWidget_);
QList<int> list; QList<int> list;
@ -89,7 +88,7 @@ MainWindow::MainWindow()
mapWidget_->setFocusPolicy(Qt::StrongFocus); mapWidget_->setFocusPolicy(Qt::StrongFocus);
mapWidget_->setFocus(); mapWidget_->setFocus();
//setCentralWidget(mapWidget_); // setCentralWidget(mapWidget_);
setCentralWidget(splitter); setCentralWidget(splitter);
createActions(); createActions();
createMenus(); createMenus();
@ -97,29 +96,25 @@ MainWindow::MainWindow()
createContextMenu(); createContextMenu();
setWindowTitle(tr("Mapnik Viewer")); setWindowTitle(tr("Mapnik Viewer"));
status=new QStatusBar(this); status = new QStatusBar(this);
status->showMessage(tr("")); status->showMessage(tr(""));
setStatusBar(status); setStatusBar(status);
resize(800,600); resize(800, 600);
//connect mapview to layerlist // connect mapview to layerlist
connect(mapWidget_, SIGNAL(mapViewChanged()),layerTab_, SLOT(update())); connect(mapWidget_, SIGNAL(mapViewChanged()), layerTab_, SLOT(update()));
// slider // slider
connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int))); connect(slider_, SIGNAL(valueChanged(int)), mapWidget_, SLOT(zoomToLevel(int)));
// renderer selector // renderer selector
connect(renderer_selector_,SIGNAL(currentIndexChanged(QString const&)), connect(renderer_selector_, SIGNAL(currentIndexChanged(int)), mapWidget_, SLOT(updateRenderer(int)));
mapWidget_, SLOT(updateRenderer(QString const&)));
// scale factor // scale factor
connect(scale_factor_,SIGNAL(valueChanged(double)), connect(scale_factor_, SIGNAL(valueChanged(double)), mapWidget_, SLOT(updateScaleFactor(double)));
mapWidget_, SLOT(updateScaleFactor(double)));
// //
connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(updateMap())); connect(layerTab_, SIGNAL(update_mapwidget()), mapWidget_, SLOT(updateMap()));
connect(layerTab_,SIGNAL(layerSelected(int)), connect(layerTab_, SIGNAL(layerSelected(int)), mapWidget_, SLOT(layerSelected(int)));
mapWidget_,SLOT(layerSelected(int)));
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete mapWidget_; delete mapWidget_;
@ -141,8 +136,7 @@ void MainWindow::open(QString const& path)
{ {
if (path.isNull()) if (path.isNull())
{ {
filename_ = QFileDialog::getOpenFileName(this,tr("Open Mapnik file"), filename_ = QFileDialog::getOpenFileName(this, tr("Open Mapnik file"), currentPath, "*.xml");
currentPath,"*.xml");
} }
else else
{ {
@ -151,18 +145,15 @@ void MainWindow::open(QString const& path)
if (!filename_.isEmpty()) if (!filename_.isEmpty())
{ {
load_map_file(filename_); load_map_file(filename_);
setWindowTitle(tr("%1 - Mapnik Viewer").arg(filename_)); setWindowTitle(tr("%1 - Mapnik Viewer").arg(filename_));
} }
} }
void MainWindow::reload() void MainWindow::reload()
{ {
if (!filename_.isEmpty()) if (!filename_.isEmpty())
{ {
mapnik::box2d<double> bbox = mapWidget_->getMap()->get_current_extent(); mapnik::box2d<double> bbox = mapWidget_->getMap()->get_current_extent();
load_map_file(filename_); load_map_file(filename_);
mapWidget_->zoomToBox(bbox); mapWidget_->zoomToBox(bbox);
@ -173,28 +164,28 @@ void MainWindow::reload()
void MainWindow::save() void MainWindow::save()
{ {
QString initialPath = QDir::currentPath() + "/untitled.xml"; QString initialPath = QDir::currentPath() + "/untitled.xml";
QString filename = QFileDialog::getSaveFileName(this, tr("Save"), QString filename = QFileDialog::getSaveFileName(this,
tr("Save"),
initialPath, initialPath,
tr("%1 Files (*.xml)") tr("%1 Files (*.xml)").arg(QString("Mapnik definition")));
.arg(QString("Mapnik definition")));
if (!filename.isEmpty()) if (!filename.isEmpty())
{ {
std::cout<<"saving "<< filename.toStdString() << std::endl; std::cout << "saving " << filename.toStdString() << std::endl;
mapnik::save_map(*mapWidget_->getMap(),filename.toStdString()); mapnik::save_map(*mapWidget_->getMap(), filename.toStdString());
} }
} }
void MainWindow::load_map_file(QString const& filename) void MainWindow::load_map_file(QString const& filename)
{ {
std::cout << "loading "<< filename.toStdString() << std::endl; std::cout << "loading " << filename.toStdString() << std::endl;
unsigned width = mapWidget_->width(); unsigned width = mapWidget_->width();
unsigned height = mapWidget_->height(); unsigned height = mapWidget_->height();
std::shared_ptr<mapnik::Map> map(new mapnik::Map(width,height)); std::shared_ptr<mapnik::Map> map(new mapnik::Map(width, height));
mapWidget_->setMap(map); mapWidget_->setMap(map);
try try
{ {
mapnik::auto_cpu_timer t(std::clog, "loading map took: "); mapnik::auto_cpu_timer t(std::clog, "loading map took: ");
mapnik::load_map(*map,filename.toStdString()); mapnik::load_map(*map, filename.toStdString());
} }
catch (std::exception const& ex) catch (std::exception const& ex)
{ {
@ -204,8 +195,8 @@ void MainWindow::load_map_file(QString const& filename)
{ {
std::cerr << "Exception caught in load_map\n"; std::cerr << "Exception caught in load_map\n";
} }
layerTab_->setModel(new LayerListModel(map,this)); layerTab_->setModel(new LayerListModel(map, this));
styleTab_->setModel(new StyleModel(map,this)); styleTab_->setModel(new StyleModel(map, this));
zoom_all(); zoom_all();
} }
@ -252,15 +243,15 @@ void MainWindow::about()
void MainWindow::export_as() void MainWindow::export_as()
{ {
QAction *action = qobject_cast<QAction *>(sender()); QAction* action = qobject_cast<QAction*>(sender());
QByteArray fileFormat = action->data().toByteArray(); QByteArray fileFormat = action->data().toByteArray();
QString initialPath = QDir::currentPath() + "/map." + fileFormat; QString initialPath = QDir::currentPath() + "/map." + fileFormat;
QString fileName = QFileDialog::getSaveFileName(this, tr("Export As"), QString fileName = QFileDialog::getSaveFileName(
initialPath, this,
tr("%1 Files (*.%2);;All Files (*)") tr("Export As"),
.arg(QString(fileFormat.toUpper())) initialPath,
.arg(QString(fileFormat))); tr("%1 Files (*.%2);;All Files (*)").arg(QString(fileFormat.toUpper())).arg(QString(fileFormat)));
if (!fileName.isEmpty()) if (!fileName.isEmpty())
{ {
QPixmap const& pix = mapWidget_->pixmap(); QPixmap const& pix = mapWidget_->pixmap();
@ -270,77 +261,76 @@ void MainWindow::export_as()
void MainWindow::print() void MainWindow::print()
{ {
// Q_ASSERT(mapWidget_->pixmap());
//Q_ASSERT(mapWidget_->pixmap()); // QPrintDialog dialog(&printer, this);
//QPrintDialog dialog(&printer, this); // if (dialog.exec()) {
//if (dialog.exec()) { // QPainter painter(&printer);
// QPainter painter(&printer); // QRect rect = painter.viewport();
// QRect rect = painter.viewport(); // QSize size = mapWidget_->pixmap()->size();
// QSize size = mapWidget_->pixmap()->size(); // size.scale(rect.size(), Qt::KeepAspectRatio);
// size.scale(rect.size(), Qt::KeepAspectRatio); // painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
// painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); // painter.setWindow(mapWidget_->pixmap()->rect());
// painter.setWindow(mapWidget_->pixmap()->rect()); // painter.drawPixmap(0, 0, *mapWidget_->pixmap());
// painter.drawPixmap(0, 0, *mapWidget_->pixmap()); // }
//}
} }
void MainWindow::createActions() void MainWindow::createActions()
{ {
//exportAct = new QAction(tr("&Export as ..."),this); // exportAct = new QAction(tr("&Export as ..."),this);
//exportAct->setShortcut(tr("Ctrl+E")); // exportAct->setShortcut(tr("Ctrl+E"));
//connect(exportAct, SIGNAL(triggered()), this, SLOT(export_as())); // connect(exportAct, SIGNAL(triggered()), this, SLOT(export_as()));
zoomAllAct = new QAction(QIcon(":/images/home.png"),tr("Zoom All"),this); zoomAllAct = new QAction(QIcon(":/images/home.png"), tr("Zoom All"), this);
connect(zoomAllAct, SIGNAL(triggered()), this, SLOT(zoom_all())); connect(zoomAllAct, SIGNAL(triggered()), this, SLOT(zoom_all()));
zoomBoxAct = new QAction(QIcon(":/images/zoombox.png"),tr("Zoom To Box"),this); zoomBoxAct = new QAction(QIcon(":/images/zoombox.png"), tr("Zoom To Box"), this);
zoomBoxAct->setCheckable(true); zoomBoxAct->setCheckable(true);
connect(zoomBoxAct, SIGNAL(triggered()), this, SLOT(zoom_to_box())); connect(zoomBoxAct, SIGNAL(triggered()), this, SLOT(zoom_to_box()));
panAct = new QAction(QIcon(":/images/pan.png"),tr("Pan"),this); panAct = new QAction(QIcon(":/images/pan.png"), tr("Pan"), this);
panAct->setCheckable(true); panAct->setCheckable(true);
connect(panAct, SIGNAL(triggered()), this, SLOT(pan())); connect(panAct, SIGNAL(triggered()), this, SLOT(pan()));
infoAct = new QAction(QIcon(":/images/info.png"),tr("Info"),this); infoAct = new QAction(QIcon(":/images/info.png"), tr("Info"), this);
infoAct->setCheckable(true); infoAct->setCheckable(true);
connect(infoAct, SIGNAL(triggered()), this, SLOT(info())); connect(infoAct, SIGNAL(triggered()), this, SLOT(info()));
toolsGroup=new QActionGroup(this); toolsGroup = new QActionGroup(this);
toolsGroup->addAction(zoomBoxAct); toolsGroup->addAction(zoomBoxAct);
toolsGroup->addAction(panAct); toolsGroup->addAction(panAct);
toolsGroup->addAction(infoAct); toolsGroup->addAction(infoAct);
zoomBoxAct->setChecked(true); zoomBoxAct->setChecked(true);
openAct=new QAction(tr("Open Map definition"),this); openAct = new QAction(tr("Open Map definition"), this);
connect(openAct,SIGNAL(triggered()),this,SLOT(open())); connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct=new QAction(tr("Save Map definition"),this); saveAct = new QAction(tr("Save Map definition"), this);
connect(saveAct,SIGNAL(triggered()),this,SLOT(save())); connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
panLeftAct = new QAction(QIcon(":/images/left.png"),tr("&Pan Left"),this); panLeftAct = new QAction(QIcon(":/images/left.png"), tr("&Pan Left"), this);
connect(panLeftAct, SIGNAL(triggered()), this, SLOT(pan_left())); connect(panLeftAct, SIGNAL(triggered()), this, SLOT(pan_left()));
panRightAct = new QAction(QIcon(":/images/right.png"),tr("&Pan Right"),this); panRightAct = new QAction(QIcon(":/images/right.png"), tr("&Pan Right"), this);
connect(panRightAct, SIGNAL(triggered()), this, SLOT(pan_right())); connect(panRightAct, SIGNAL(triggered()), this, SLOT(pan_right()));
panUpAct = new QAction(QIcon(":/images/up.png"),tr("&Pan Up"),this); panUpAct = new QAction(QIcon(":/images/up.png"), tr("&Pan Up"), this);
connect(panUpAct, SIGNAL(triggered()), this, SLOT(pan_up())); connect(panUpAct, SIGNAL(triggered()), this, SLOT(pan_up()));
panDownAct = new QAction(QIcon(":/images/down.png"),tr("&Pan Down"),this); panDownAct = new QAction(QIcon(":/images/down.png"), tr("&Pan Down"), this);
connect(panDownAct, SIGNAL(triggered()), this, SLOT(pan_down())); connect(panDownAct, SIGNAL(triggered()), this, SLOT(pan_down()));
reloadAct = new QAction(QIcon(":/images/reload.png"),tr("Reload"),this); reloadAct = new QAction(QIcon(":/images/reload.png"), tr("Reload"), this);
connect(reloadAct, SIGNAL(triggered()), this, SLOT(reload())); connect(reloadAct, SIGNAL(triggered()), this, SLOT(reload()));
layerInfo = new QAction(QIcon(":/images/info.png"),tr("&Layer info"),layerTab_); layerInfo = new QAction(QIcon(":/images/info.png"), tr("&Layer info"), layerTab_);
connect(layerInfo, SIGNAL(triggered()), layerTab_,SLOT(layerInfo())); connect(layerInfo, SIGNAL(triggered()), layerTab_, SLOT(layerInfo()));
connect(layerTab_, SIGNAL(doubleClicked(QModelIndex const&)), layerTab_,SLOT(layerInfo2(QModelIndex const&))); connect(layerTab_, SIGNAL(doubleClicked(QModelIndex const&)), layerTab_, SLOT(layerInfo2(QModelIndex const&)));
foreach (QByteArray format, QImageWriter::supportedImageFormats()) foreach (QByteArray format, QImageWriter::supportedImageFormats())
{ {
QString text = tr("%1...").arg(QString(format).toUpper()); QString text = tr("%1...").arg(QString(format).toUpper());
QAction *action = new QAction(text, this); QAction* action = new QAction(text, this);
action->setData(format); action->setData(format);
connect(action, SIGNAL(triggered()), this, SLOT(export_as())); connect(action, SIGNAL(triggered()), this, SLOT(export_as()));
exportAsActs.append(action); exportAsActs.append(action);
} }
printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this); printAct = new QAction(QIcon(":/images/print.png"), tr("&Print ..."), this);
printAct->setShortcut(tr("Ctrl+E")); printAct->setShortcut(tr("Ctrl+E"));
connect(printAct, SIGNAL(triggered()), this, SLOT(print())); connect(printAct, SIGNAL(triggered()), this, SLOT(print()));
@ -348,17 +338,17 @@ void MainWindow::createActions()
exitAct->setShortcut(tr("Ctrl+Q")); exitAct->setShortcut(tr("Ctrl+Q"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
aboutAct = new QAction(QIcon(":/images/about.png"),tr("&About"), this); aboutAct = new QAction(QIcon(":/images/about.png"), tr("&About"), this);
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
} }
void MainWindow::createMenus() void MainWindow::createMenus()
{ {
exportMenu = new QMenu(tr("&Export As"), this); exportMenu = new QMenu(tr("&Export As"), this);
foreach (QAction *action, exportAsActs) foreach (QAction* action, exportAsActs)
exportMenu->addAction(action); exportMenu->addAction(action);
fileMenu = new QMenu(tr("&File"),this); fileMenu = new QMenu(tr("&File"), this);
fileMenu->addAction(openAct); fileMenu->addAction(openAct);
fileMenu->addAction(saveAct); fileMenu->addAction(saveAct);
fileMenu->addMenu(exportMenu); fileMenu->addMenu(exportMenu);
@ -397,13 +387,13 @@ void MainWindow::createToolBars()
scale_factor_ = new QDoubleSpinBox(fileToolBar); scale_factor_ = new QDoubleSpinBox(fileToolBar);
scale_factor_->setMinimum(0.1); scale_factor_->setMinimum(0.1);
scale_factor_->setMaximum(5.0); scale_factor_->setMaximum(10.0);
scale_factor_->setSingleStep(0.1); scale_factor_->setSingleStep(0.1);
scale_factor_->setValue(1.0); scale_factor_->setValue(1.0);
fileToolBar->addWidget(scale_factor_); fileToolBar->addWidget(scale_factor_);
slider_ = new QSlider(Qt::Horizontal,fileToolBar); slider_ = new QSlider(Qt::Horizontal, fileToolBar);
slider_->setRange(1,18); slider_->setRange(1, 18);
slider_->setTickPosition(QSlider::TicksBelow); slider_->setTickPosition(QSlider::TicksBelow);
slider_->setTickInterval(1); slider_->setTickInterval(1);
slider_->setTracking(false); slider_->setTracking(false);
@ -411,9 +401,7 @@ void MainWindow::createToolBars()
fileToolBar->addAction(aboutAct); fileToolBar->addAction(aboutAct);
} }
void MainWindow::set_default_extent(double x0, double y0, double x1, double y1)
void MainWindow::set_default_extent(double x0,double y0, double x1, double y1)
{ {
try try
{ {
@ -421,14 +409,15 @@ void MainWindow::set_default_extent(double x0,double y0, double x1, double y1)
if (map_ptr) if (map_ptr)
{ {
mapnik::projection prj(map_ptr->srs()); mapnik::projection prj(map_ptr->srs());
prj.forward(x0,y0); prj.forward(x0, y0);
prj.forward(x1,y1); prj.forward(x1, y1);
default_extent_=mapnik::box2d<double>(x0,y0,x1,y1); default_extent_ = mapnik::box2d<double>(x0, y0, x1, y1);
mapWidget_->zoomToBox(default_extent_); mapWidget_->zoomToBox(default_extent_);
std::cout << "SET DEFAULT EXT\n"; std::cout << "SET DEFAULT EXT:" << default_extent_ << std::endl;
} }
} }
catch (...) {} catch (...)
{}
} }
void MainWindow::set_scaling_factor(double scaling_factor) void MainWindow::set_scaling_factor(double scaling_factor)

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef MAINWINDOW_HPP #ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP #define MAINWINDOW_HPP
@ -30,7 +29,7 @@
#include "mapwidget.hpp" #include "mapwidget.hpp"
//using namespace mapnik; // using namespace mapnik;
class LayerTab; class LayerTab;
class StyleTab; class StyleTab;
@ -41,22 +40,24 @@ class QDoubleSpinBox;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
MainWindow(); MainWindow();
virtual ~MainWindow(); virtual ~MainWindow();
void set_default_extent(double x0,double y0,double x1, double y1); void set_default_extent(double x0, double y0, double x1, double y1);
void set_scaling_factor(double scaling_factor); void set_scaling_factor(double scaling_factor);
public :
public:
std::shared_ptr<mapnik::Map> get_map(); std::shared_ptr<mapnik::Map> get_map();
protected:
protected:
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
public slots: public slots:
void zoom_all(); void zoom_all();
void zoom_to_box(); void zoom_to_box();
void pan(); void pan();
void info(); void info();
void export_as(); void export_as();
void open(QString const& path = QString()); void open(QString const& path = QString());
void reload(); void reload();
void save(); void save();
void print(); void print();
@ -65,7 +66,8 @@ public slots:
void pan_right(); void pan_right();
void pan_up(); void pan_up();
void pan_down(); void pan_down();
private:
private:
void createActions(); void createActions();
void createMenus(); void createMenus();
void createToolBars(); void createToolBars();
@ -74,43 +76,42 @@ private:
QString currentPath; QString currentPath;
QString filename_; QString filename_;
QAbstractItemModel *model; QAbstractItemModel* model;
LayerTab *layerTab_; LayerTab* layerTab_;
StyleTab * styleTab_; StyleTab* styleTab_;
MapWidget * mapWidget_; MapWidget* mapWidget_;
//actions // actions
QList<QAction *> exportAsActs; QList<QAction*> exportAsActs;
QActionGroup *toolsGroup; QActionGroup* toolsGroup;
QAction *zoomAllAct; QAction* zoomAllAct;
QAction *zoomBoxAct; QAction* zoomBoxAct;
QAction *panAct; QAction* panAct;
QAction *infoAct; QAction* infoAct;
QAction *openAct; QAction* openAct;
QAction *saveAct; QAction* saveAct;
QAction *printAct; QAction* printAct;
QAction *exitAct; QAction* exitAct;
QAction *aboutAct; QAction* aboutAct;
QAction *panLeftAct; QAction* panLeftAct;
QAction *panRightAct; QAction* panRightAct;
QAction *panUpAct; QAction* panUpAct;
QAction *panDownAct; QAction* panDownAct;
QAction *reloadAct; QAction* reloadAct;
QAction *layerInfo; QAction* layerInfo;
//toolbars // toolbars
QToolBar *fileToolBar; QToolBar* fileToolBar;
QToolBar *editToolBar; QToolBar* editToolBar;
//menus // menus
QMenu *exportMenu; QMenu* exportMenu;
QMenu *fileMenu; QMenu* fileMenu;
QMenu *helpMenu; QMenu* helpMenu;
//status bar // status bar
QStatusBar *status; QStatusBar* status;
QSlider * slider_; QSlider* slider_;
QComboBox * renderer_selector_; QComboBox* renderer_selector_;
QDoubleSpinBox * scale_factor_; QDoubleSpinBox* scale_factor_;
mapnik::box2d<double> default_extent_; mapnik::box2d<double> default_extent_;
}; };
#endif // MAINWINDOW_HPP
#endif //MAINWINDOW_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,13 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <QtGui> #include <QtGui>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
#include <mapnik/projection.hpp> #include <mapnik/proj_transform.hpp>
#include <mapnik/scale_denominator.hpp> #include <mapnik/scale_denominator.hpp>
#include <mapnik/view_transform.hpp> #include <mapnik/view_transform.hpp>
#include <mapnik/transform_path_adapter.hpp> #include <mapnik/transform_path_adapter.hpp>
@ -41,153 +40,139 @@
#include "mapwidget.hpp" #include "mapwidget.hpp"
#include "info_dialog.hpp" #include "info_dialog.hpp"
using mapnik::image_rgba8;
using mapnik::Map;
using mapnik::layer;
using mapnik::box2d; using mapnik::box2d;
using mapnik::coord2d; using mapnik::coord2d;
using mapnik::feature_kv_iterator;
using mapnik::feature_ptr; using mapnik::feature_ptr;
using mapnik::view_transform; using mapnik::image_rgba8;
using mapnik::layer;
using mapnik::Map;
using mapnik::projection; using mapnik::projection;
using mapnik::scale_denominator; using mapnik::scale_denominator;
using mapnik::feature_kv_iterator; using mapnik::view_transform;
double scales [] = {279541132.014, double scales[] = {279541132.014, 139770566.007, 69885283.0036, 34942641.5018, 17471320.7509,
139770566.007, 8735660.37545, 4367830.18772, 2183915.09386, 1091957.54693, 545978.773466,
69885283.0036, 272989.386733, 136494.693366, 68247.3466832, 34123.6733416, 17061.8366708,
34942641.5018, 8530.9183354, 4265.4591677, 2132.72958385, 1066.36479192, 533.182395962};
17471320.7509,
8735660.37545,
4367830.18772,
2183915.09386,
1091957.54693,
545978.773466,
272989.386733,
136494.693366,
68247.3466832,
34123.6733416,
17061.8366708,
8530.9183354,
4265.4591677,
2132.72958385,
1066.36479192,
533.182395962};
MapWidget::MapWidget(QWidget *parent) MapWidget::MapWidget(QWidget* parent)
: QWidget(parent), : QWidget(parent)
map_(), , map_()
selected_(1), , selected_(1)
extent_(), , extent_()
cur_tool_(ZoomToBox), , cur_tool_(ZoomToBox)
start_x_(0), , start_x_(0)
start_y_(0), , start_y_(0)
end_x_(0), , end_x_(0)
end_y_(0), , end_y_(0)
drag_(false), , drag_(false)
first_(true), , first_(true)
pen_(QColor(0,0,255,96)), , pen_(QColor(0, 0, 255, 96))
selectedLayer_(-1), , selectedLayer_(-1)
scaling_factor_(1.0), , scaling_factor_(1.0)
cur_renderer_(AGG) , cur_renderer_(AGG)
{ {
pen_.setWidth(3); pen_.setWidth(3);
pen_.setCapStyle(Qt::RoundCap); pen_.setCapStyle(Qt::RoundCap);
pen_.setJoinStyle(Qt::RoundJoin); pen_.setJoinStyle(Qt::RoundJoin);
} }
void MapWidget::setTool(eTool tool) void MapWidget::setTool(eTool tool)
{ {
cur_tool_=tool; cur_tool_ = tool;
} }
void MapWidget::paintEvent(QPaintEvent*) void MapWidget::paintEvent(QPaintEvent*)
{ {
QPainter painter(this); QPainter painter(this);
if (drag_) if (drag_)
{ {
if (cur_tool_ == ZoomToBox) if (cur_tool_ == ZoomToBox)
{ {
unsigned width = end_x_-start_x_; unsigned width = end_x_ - start_x_;
unsigned height = end_y_-start_y_; unsigned height = end_y_ - start_y_;
painter.drawPixmap(QPoint(0, 0),pix_); painter.drawPixmap(QPoint(0, 0), pix_);
painter.setPen(pen_); painter.setPen(pen_);
painter.setBrush(QColor(200,200,255,128)); painter.setBrush(QColor(200, 200, 255, 128));
painter.drawRect(start_x_,start_y_,width,height); painter.drawRect(start_x_, start_y_, width, height);
} }
else if (cur_tool_ == Pan) else if (cur_tool_ == Pan)
{ {
int dx = end_x_-start_x_; int dx = end_x_ - start_x_;
int dy = end_y_-start_y_; int dy = end_y_ - start_y_;
painter.setBrush(QColor(200,200,200,128)); painter.setBrush(QColor(200, 200, 200, 128));
painter.drawRect(0,0,width(),height()); painter.drawRect(0, 0, width(), height());
painter.drawPixmap(QPoint(dx,dy),pix_); painter.drawPixmap(QPoint(dx, dy), pix_);
} }
} }
else else
{ {
painter.drawPixmap(QPoint(0, 0),pix_); painter.drawPixmap(QPoint(0, 0), pix_);
} }
painter.end(); painter.end();
} }
void MapWidget::resizeEvent(QResizeEvent * ev) void MapWidget::resizeEvent(QResizeEvent* ev)
{ {
if (map_) if (map_)
{ {
map_->resize(ev->size().width(),ev->size().height()); map_->resize(ev->size().width(), ev->size().height());
updateMap(); updateMap();
} }
} }
void MapWidget::mousePressEvent(QMouseEvent* e) void MapWidget::mousePressEvent(QMouseEvent* e)
{ {
if (e->button()==Qt::LeftButton) if (e->button() == Qt::LeftButton)
{ {
if (cur_tool_ == ZoomToBox || cur_tool_==Pan) if (cur_tool_ == ZoomToBox || cur_tool_ == Pan)
{ {
start_x_ = e->x(); start_x_ = e->x();
start_y_ = e->y(); start_y_ = e->y();
drag_=true; drag_ = true;
} }
else if (cur_tool_==Info) else if (cur_tool_ == Info)
{ {
if (map_) if (map_)
{
QVector<QPair<QString,QString> > info;
projection map_proj(map_->srs()); // map projection
double scale_denom = scale_denominator(map_->scale(),map_proj.is_geographic());
view_transform t(map_->width(),map_->height(),map_->get_current_extent());
for (unsigned index = 0; index < map_->layer_count();++index)
{ {
if (int(index) != selectedLayer_) continue; QVector<QPair<QString, QString>> info;
layer & layer = map_->layers()[index]; projection map_proj(map_->srs(), true); // map projection
if (!layer.visible(scale_denom)) continue; double scale_denom = scale_denominator(map_->scale(), map_proj.is_geographic());
std::string name = layer.name(); view_transform t(map_->width(), map_->height(), map_->get_current_extent());
double x = e->x();
double y = e->y();
std::cout << "query at " << x << "," << y << "\n";
projection layer_proj(layer.srs());
mapnik::proj_transform prj_trans(map_proj,layer_proj);
//std::auto_ptr<mapnik::memory_datasource> data(new mapnik::memory_datasource);
mapnik::featureset_ptr fs = map_->query_map_point(index,x,y);
if (fs) for (unsigned index = 0; index < map_->layer_count(); ++index)
{ {
feature_ptr feat = fs->next(); if (int(index) != selectedLayer_)
if (feat) continue;
{
feature_kv_iterator itr(*feat,true);
feature_kv_iterator end(*feat);
for ( ;itr!=end; ++itr) layer& layer = map_->layers()[index];
{ if (!layer.visible(scale_denom))
info.push_back(QPair<QString,QString>(QString(std::get<0>(*itr).c_str()), continue;
std::get<1>(*itr).to_string().c_str())); std::string name = layer.name();
} double x = e->x();
double y = e->y();
std::cout << "query at " << x << "," << y << "\n";
projection layer_proj(layer.srs(), true);
mapnik::proj_transform prj_trans(map_proj, layer_proj);
// std::auto_ptr<mapnik::memory_datasource> data(new mapnik::memory_datasource);
mapnik::featureset_ptr fs = map_->query_map_point(index, x, y);
if (fs)
{
feature_ptr feat = fs->next();
if (feat)
{
feature_kv_iterator itr(*feat, true);
feature_kv_iterator end(*feat);
for (; itr != end; ++itr)
{
info.push_back(QPair<QString, QString>(QString(std::get<0>(*itr).c_str()),
std::get<1>(*itr).to_string().c_str()));
}
#if 0 // #if 0 //
using path_type = mapnik::transform_path_adapter<mapnik::view_transform,mapnik::vertex_adapter>; using path_type = mapnik::transform_path_adapter<mapnik::view_transform,mapnik::vertex_adapter>;
@ -219,271 +204,285 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
} }
} }
#endif #endif
} }
} }
if (info.size() > 0) if (info.size() > 0)
{ {
info_dialog info_dlg(info,this); info_dialog info_dlg(info, this);
info_dlg.exec(); info_dlg.exec();
break; break;
} }
}
// remove annotation layer
map_->layers().erase(
remove_if(map_->layers().begin(), map_->layers().end(), bind(&layer::name, _1) == "*annotations*"),
map_->layers().end());
} }
}
// remove annotation layer }
map_->layers().erase(remove_if(map_->layers().begin(), else if (e->button() == Qt::RightButton)
map_->layers().end(), {
bind(&layer::name,_1) == "*annotations*") // updateMap();
, map_->layers().end()); }
}
}
}
else if (e->button()==Qt::RightButton)
{
//updateMap();
}
} }
void MapWidget::mouseMoveEvent(QMouseEvent* e) void MapWidget::mouseMoveEvent(QMouseEvent* e)
{ {
if (cur_tool_ == ZoomToBox || cur_tool_==Pan) if (cur_tool_ == ZoomToBox || cur_tool_ == Pan)
{ {
end_x_ = e->x(); end_x_ = e->x();
end_y_ = e->y(); end_y_ = e->y();
update(); update();
} }
} }
void MapWidget::mouseReleaseEvent(QMouseEvent* e) void MapWidget::mouseReleaseEvent(QMouseEvent* e)
{ {
if (e->button()==Qt::LeftButton) if (e->button() == Qt::LeftButton)
{ {
end_x_ = e->x(); end_x_ = e->x();
end_y_ = e->y(); end_y_ = e->y();
if (cur_tool_ == ZoomToBox) if (cur_tool_ == ZoomToBox)
{ {
drag_=false; drag_ = false;
if (map_) if (map_)
{ {
view_transform t(map_->width(),map_->height(),map_->get_current_extent()); view_transform t(map_->width(), map_->height(), map_->get_current_extent());
box2d<double> box = t.backward(box2d<double>(start_x_,start_y_,end_x_,end_y_)); box2d<double> box = t.backward(box2d<double>(start_x_, start_y_, end_x_, end_y_));
map_->zoom_to_box(box); map_->zoom_to_box(box);
updateMap(); updateMap();
} }
} }
else if (cur_tool_==Pan) else if (cur_tool_ == Pan)
{ {
drag_=false; drag_ = false;
if (map_) if (map_)
{ {
int cx = int(0.5 * map_->width()); int cx = int(0.5 * map_->width());
int cy = int(0.5 * map_->height()); int cy = int(0.5 * map_->height());
int dx = end_x_ - start_x_; int dx = end_x_ - start_x_;
int dy = end_y_ - start_y_; int dy = end_y_ - start_y_;
map_->pan(cx - dx ,cy - dy); map_->pan(cx - dx, cy - dy);
updateMap(); updateMap();
} }
} }
} }
} }
void MapWidget::wheelEvent(QWheelEvent* e) void MapWidget::wheelEvent(QWheelEvent* e)
{ {
if (!map_) if (!map_)
{ {
return; return;
} }
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QPointF corner(map_->width(), map_->height());
QPointF zoomCoords;
double zoom;
if (e->angleDelta().y() > 0)
{
zoom = 0.5;
QPointF center = corner / 2;
QPointF delta = e->position() - center;
zoomCoords = zoom * delta + center;
}
else
{
zoom = 2.0;
zoomCoords = corner - e->position();
}
#else
QPoint corner(map_->width(), map_->height());
QPoint zoomCoords;
double zoom;
if (e->delta() > 0)
{
zoom = 0.5;
QPoint center = corner / 2;
QPoint delta = e->pos() - center;
zoomCoords = zoom * delta + center;
}
else
{
zoom = 2.0;
zoomCoords = corner - e->pos();
}
#endif
QPoint corner(map_->width(), map_->height()); map_->pan_and_zoom(zoomCoords.x(), zoomCoords.y(), zoom);
QPoint zoomCoords; updateMap();
double zoom;
if (e->delta() > 0)
{
zoom = 0.5;
QPoint center = corner / 2;
QPoint delta = e->pos() - center;
zoomCoords = zoom * delta + center;
}
else
{
zoom = 2.0;
zoomCoords = corner - e->pos();
}
map_->pan_and_zoom(zoomCoords.x(), zoomCoords.y(), zoom);
updateMap();
} }
void MapWidget::keyPressEvent(QKeyEvent *e) void MapWidget::keyPressEvent(QKeyEvent* e)
{ {
std::cout << "key pressed:"<< e->key()<<"\n"; std::cout << "key pressed:" << e->key() << "\n";
switch (e->key()) { switch (e->key())
case Qt::Key_Minus: {
zoomOut(); case Qt::Key_Minus:
break; zoomOut();
case Qt::Key_Plus: break;
case 61: case Qt::Key_Plus:
zoomIn(); case 61:
break; zoomIn();
case 65: break;
defaultView(); case 65:
break; defaultView();
case Qt::Key_Up: break;
panUp(); case Qt::Key_Up:
break; panUp();
case Qt::Key_Down: break;
panDown(); case Qt::Key_Down:
break; panDown();
case Qt::Key_Left: break;
panLeft(); case Qt::Key_Left:
break; panLeft();
case Qt::Key_Right: break;
panRight(); case Qt::Key_Right:
break; panRight();
case 49: break;
zoomToLevel(10); case 49:
break; zoomToLevel(10);
case 50: break;
zoomToLevel(11); case 50:
break; zoomToLevel(11);
case 51: break;
zoomToLevel(12); case 51:
break; zoomToLevel(12);
case 52: break;
zoomToLevel(13); case 52:
break; zoomToLevel(13);
case 53: break;
zoomToLevel(14); case 53:
break; zoomToLevel(14);
case 54: break;
zoomToLevel(15); case 54:
break; zoomToLevel(15);
case 55: break;
zoomToLevel(16); case 55:
break; zoomToLevel(16);
case 56: break;
zoomToLevel(17); case 56:
break; zoomToLevel(17);
case 57: break;
zoomToLevel(18); case 57:
break; zoomToLevel(18);
default: break;
QWidget::keyPressEvent(e); default:
} QWidget::keyPressEvent(e);
}
} }
void MapWidget::zoomToBox(mapnik::box2d<double> const& bbox) void MapWidget::zoomToBox(mapnik::box2d<double> const& bbox)
{ {
if (map_) if (map_)
{ {
map_->zoom_to_box(bbox); map_->zoom_to_box(bbox);
updateMap(); updateMap();
} }
} }
void MapWidget::defaultView() void MapWidget::defaultView()
{ {
if (map_) if (map_)
{ {
map_->resize(width(),height()); map_->resize(width(), height());
map_->zoom_all(); map_->zoom_all();
updateMap(); updateMap();
} }
} }
void MapWidget::zoomIn() void MapWidget::zoomIn()
{ {
if (map_) if (map_)
{ {
map_->zoom(0.5); map_->zoom(0.5);
updateMap(); updateMap();
} }
} }
void MapWidget::zoomOut() void MapWidget::zoomOut()
{ {
if (map_) if (map_)
{ {
map_->zoom(2.0); map_->zoom(2.0);
updateMap(); updateMap();
} }
} }
void MapWidget::panUp() void MapWidget::panUp()
{ {
if (map_) if (map_)
{ {
double cx = 0.5*map_->width(); double cx = 0.5 * map_->width();
double cy = 0.5*map_->height(); double cy = 0.5 * map_->height();
map_->pan(int(cx),int(cy - cy*0.25)); map_->pan(int(cx), int(cy - cy * 0.25));
updateMap(); updateMap();
} }
} }
void MapWidget::panDown() void MapWidget::panDown()
{ {
if (map_) if (map_)
{ {
double cx = 0.5*map_->width(); double cx = 0.5 * map_->width();
double cy = 0.5*map_->height(); double cy = 0.5 * map_->height();
map_->pan(int(cx),int(cy + cy*0.25)); map_->pan(int(cx), int(cy + cy * 0.25));
updateMap(); updateMap();
} }
} }
void MapWidget::panLeft() void MapWidget::panLeft()
{ {
if (map_) if (map_)
{ {
double cx = 0.5*map_->width(); double cx = 0.5 * map_->width();
double cy = 0.5*map_->height(); double cy = 0.5 * map_->height();
map_->pan(int(cx - cx * 0.25),int(cy)); map_->pan(int(cx - cx * 0.25), int(cy));
updateMap(); updateMap();
} }
} }
void MapWidget::panRight() void MapWidget::panRight()
{ {
if (map_) if (map_)
{ {
double cx = 0.5*map_->width(); double cx = 0.5 * map_->width();
double cy = 0.5*map_->height(); double cy = 0.5 * map_->height();
map_->pan(int(cx + cx * 0.25),int(cy)); map_->pan(int(cx + cx * 0.25), int(cy));
updateMap(); updateMap();
} }
} }
void MapWidget::zoomToLevel(int level) void MapWidget::zoomToLevel(int level)
{ {
if ( map_ && level >= 0 && level < 19 ) if (map_ && level >= 0 && level < 19)
{ {
double scale_denom = scales[level]; double scale_denom = scales[level];
std::cerr << "scale denominator = " << scale_denom << "\n"; std::cerr << "scale denominator = " << scale_denom << "\n";
mapnik::box2d<double> ext = map_->get_current_extent(); mapnik::box2d<double> ext = map_->get_current_extent();
double width = static_cast<double>(map_->width()); double width = static_cast<double>(map_->width());
double height= static_cast<double>(map_->height()); double height = static_cast<double>(map_->height());
mapnik::coord2d pt = ext.center(); mapnik::coord2d pt = ext.center();
double res = scale_denom * 0.00028; double res = scale_denom * 0.00028;
mapnik::box2d<double> box(pt.x - 0.5 * width * res, mapnik::box2d<double> box(pt.x - 0.5 * width * res,
pt.y - 0.5 * height*res, pt.y - 0.5 * height * res,
pt.x + 0.5 * width * res, pt.x + 0.5 * width * res,
pt.y + 0.5 * height*res); pt.y + 0.5 * height * res);
map_->zoom_to_box(box); map_->zoom_to_box(box);
updateMap(); updateMap();
} }
} }
void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::string const&) void MapWidget::export_to_file(unsigned, unsigned, std::string const&, std::string const&)
{ {
//image_rgba8 image(width,height); // image_rgba8 image(width,height);
//agg_renderer renderer(map,image); // agg_renderer renderer(map,image);
//renderer.apply(); // renderer.apply();
//image.saveToFile(filename,type); // image.saveToFile(filename,type);
std::cout << "Export to file .." << std::endl; std::cout << "Export to file .." << std::endl;
} }
@ -492,25 +491,25 @@ void MapWidget::set_scaling_factor(double scaling_factor)
scaling_factor_ = scaling_factor; scaling_factor_ = scaling_factor;
} }
void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix) void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap& pix)
{ {
unsigned width=map.width(); unsigned width = map.width();
unsigned height=map.height(); unsigned height = map.height();
image_rgba8 buf(width,height); image_rgba8 buf(width, height);
mapnik::agg_renderer<image_rgba8> ren(map,buf,scaling_factor); mapnik::agg_renderer<image_rgba8> ren(map, buf, scaling_factor);
try try
{ {
mapnik::auto_cpu_timer t(std::clog, "rendering took: "); mapnik::auto_cpu_timer t(std::clog, "rendering took: ");
ren.apply(); ren.apply();
QImage image((uchar*)buf.data(),width,height,QImage::Format_ARGB32); QImage image((uchar*)buf.data(), width, height, QImage::Format_ARGB32);
pix = QPixmap::fromImage(image.rgbSwapped()); pix = QPixmap::fromImage(image.rgbSwapped());
} }
//catch (mapnik::config_error & ex) // catch (mapnik::config_error & ex)
//{ //{
// std::cerr << ex.what() << std::endl; // std::cerr << ex.what() << std::endl;
//} // }
catch (std::exception const& ex) catch (std::exception const& ex)
{ {
std::cerr << "exception: " << ex.what() << std::endl; std::cerr << "exception: " << ex.what() << std::endl;
@ -521,18 +520,16 @@ void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
} }
} }
void render_grid(mapnik::Map const& map, double scaling_factor, QPixmap& pix)
void render_grid(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
{ {
std::cerr << "Not supported" << std::endl; std::cerr << "Not supported" << std::endl;
} }
void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap& pix)
void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
{ {
// FIXME // FIXME
#ifdef HAVE_CAIRO #ifdef HAVE_CAIRO
mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32,map.width(),map.height()), mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, map.width(), map.height()),
mapnik::cairo_surface_closer()); mapnik::cairo_surface_closer());
mapnik::cairo_ptr cairo = mapnik::create_context(image_surface); mapnik::cairo_ptr cairo = mapnik::create_context(image_surface);
if (cairo) if (cairo)
@ -543,17 +540,20 @@ void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
} }
mapnik::image_rgba8 data(map.width(), map.height()); mapnik::image_rgba8 data(map.width(), map.height());
mapnik::cairo_image_to_rgba8(data, image_surface); mapnik::cairo_image_to_rgba8(data, image_surface);
QImage image((uchar*)data.bytes(),data.width(),data.height(),QImage::Format_ARGB32); QImage image((uchar*)data.bytes(), data.width(), data.height(), QImage::Format_ARGB32);
pix = QPixmap::fromImage(image.rgbSwapped()); pix = QPixmap::fromImage(image.rgbSwapped());
#endif #endif
} }
void MapWidget::updateRenderer(QString const& txt) void MapWidget::updateRenderer(int index)
{ {
if (txt == "AGG") cur_renderer_ = AGG; std::cerr << "updateRenderer:" << index << std::endl;
else if (txt == "Cairo") cur_renderer_ = Cairo; if (index == 0)
else if (txt == "Grid") cur_renderer_ = Grid; cur_renderer_ = AGG;
std::cerr << "Update renderer called" << std::endl; else if (index == 1)
cur_renderer_ = Cairo;
else if (index == 2)
cur_renderer_ = Grid;
updateMap(); updateMap();
} }
@ -565,59 +565,63 @@ void MapWidget::updateScaleFactor(double scale_factor)
void MapWidget::updateMap() void MapWidget::updateMap()
{ {
if (map_) if (map_)
{ {
if (cur_renderer_== AGG) if (cur_renderer_ == AGG)
{ {
render_agg(*map_, scaling_factor_, pix_); render_agg(*map_, scaling_factor_, pix_);
} }
else if (cur_renderer_ == Cairo) else if (cur_renderer_ == Cairo)
{ {
render_cairo(*map_, scaling_factor_, pix_); render_cairo(*map_, scaling_factor_, pix_);
} }
else if (cur_renderer_ == Grid) else if (cur_renderer_ == Grid)
{ {
render_grid(*map_, scaling_factor_, pix_); render_grid(*map_, scaling_factor_, pix_);
} }
else else
{ {
std::cerr << "Unknown renderer..." << std::endl; std::cerr << "Unknown renderer..." << std::endl;
} }
try try
{ {
projection prj(map_->srs()); // map projection projection prj(map_->srs(), true); // map projection
box2d<double> ext = map_->get_current_extent(); box2d<double> ext = map_->get_current_extent();
double x0 = ext.minx(); double x0 = ext.minx();
double y0 = ext.miny(); double y0 = ext.miny();
double x1 = ext.maxx(); double x1 = ext.maxx();
double y1 = ext.maxy(); double y1 = ext.maxy();
prj.inverse(x0,y0); double z = 0;
prj.inverse(x1,y1); std::string dest_srs = {"epsg:4326"};
std::cout << "BBOX (WGS84): " << x0 << "," << y0 << "," << x1 << "," << y1 << "\n"; mapnik::proj_transform proj_tr(map_->srs(), dest_srs);
update();
// emit signal to interested widgets proj_tr.forward(x0, y0, z);
emit mapViewChanged(); proj_tr.forward(x1, y1, z);
} std::cout << "MAP SIZE:" << map_->width() << "," << map_->height() << std::endl;
catch (...) std::cout << "BBOX (WGS84): " << x0 << "," << y0 << "," << x1 << "," << y1 << "\n";
{ update();
std::cerr << "Unknown exception caught!\n"; // emit signal to interested widgets
} emit mapViewChanged();
} }
catch (...)
{
std::cerr << "Unknown exception caught!\n";
}
}
} }
std::shared_ptr<Map> MapWidget::getMap() std::shared_ptr<Map> MapWidget::getMap()
{ {
return map_; return map_;
} }
void MapWidget::setMap(std::shared_ptr<Map> map) void MapWidget::setMap(std::shared_ptr<Map> map)
{ {
map_ = map; map_ = map;
} }
void MapWidget::layerSelected(int index) void MapWidget::layerSelected(int index)
{ {
selectedLayer_ = index; selectedLayer_ = index;
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef MAP_WIDGET_HPP #ifndef MAP_WIDGET_HPP
#define MAP_WIDGET_HPP #define MAP_WIDGET_HPP
@ -30,7 +29,6 @@
#include <string> #include <string>
#include <memory> #include <memory>
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#endif #endif
@ -39,22 +37,16 @@ class MapWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
enum eTool enum eTool {
{
ZoomToBox = 1, ZoomToBox = 1,
Pan, Pan,
Info, Info,
}; };
enum eRenderer enum eRenderer { AGG, Cairo, Grid };
{
AGG,
Cairo,
Grid
};
private: private:
std::shared_ptr<mapnik::Map> map_; std::shared_ptr<mapnik::Map> map_;
int selected_; int selected_;
QPixmap pix_; QPixmap pix_;
@ -70,11 +62,12 @@ private:
int selectedLayer_; int selectedLayer_;
double scaling_factor_; double scaling_factor_;
eRenderer cur_renderer_; eRenderer cur_renderer_;
public:
MapWidget(QWidget *parent=0); public:
MapWidget(QWidget* parent = 0);
void setTool(eTool tool); void setTool(eTool tool);
std::shared_ptr<mapnik::Map> getMap(); std::shared_ptr<mapnik::Map> getMap();
inline QPixmap const& pixmap() const { return pix_;} inline QPixmap const& pixmap() const { return pix_; }
void setMap(std::shared_ptr<mapnik::Map> map); void setMap(std::shared_ptr<mapnik::Map> map);
void defaultView(); void defaultView();
void zoomToBox(mapnik::box2d<double> const& box); void zoomToBox(mapnik::box2d<double> const& box);
@ -85,26 +78,24 @@ public:
void panUp(); void panUp();
void panDown(); void panDown();
void set_scaling_factor(double); void set_scaling_factor(double);
public slots: public slots:
void zoomToLevel(int level); void zoomToLevel(int level);
void updateMap(); void updateMap();
void layerSelected(int); void layerSelected(int);
void updateRenderer(QString const& txt); void updateRenderer(int);
void updateScaleFactor(double scale_factor); void updateScaleFactor(double scale_factor);
signals: signals:
void mapViewChanged(); void mapViewChanged();
protected:
protected:
void paintEvent(QPaintEvent* ev); void paintEvent(QPaintEvent* ev);
void resizeEvent(QResizeEvent* ev); void resizeEvent(QResizeEvent* ev);
void mousePressEvent(QMouseEvent* e); void mousePressEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e); void mouseMoveEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e);
void wheelEvent(QWheelEvent* e); void wheelEvent(QWheelEvent* e);
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent* e);
void export_to_file(unsigned width, void export_to_file(unsigned width, unsigned height, std::string const& filename, std::string const& type);
unsigned height,
std::string const& filename,
std::string const& type);
}; };
#endif // MAP_WIDGET_HPP #endif // MAP_WIDGET_HPP

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "styles_model.hpp" #include "styles_model.hpp"
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/util/variant.hpp> #include <mapnik/util/variant.hpp>
@ -39,70 +38,50 @@ class node : private mapnik::util::noncopyable
{ {
struct node_base struct node_base
{ {
virtual QString name() const=0; virtual QString name() const = 0;
virtual QIcon icon() const=0; virtual QIcon icon() const = 0;
virtual ~node_base() {} virtual ~node_base() {}
}; };
template <typename T> template<typename T>
struct wrap : public node_base struct wrap : public node_base
{ {
wrap(T const& obj) wrap(T const& obj)
: obj_(obj) {} : obj_(obj)
{}
~wrap() {} ~wrap() {}
QString name () const QString name() const { return obj_.name(); }
{
return obj_.name();
}
QIcon icon() const QIcon icon() const { return obj_.icon(); }
{
return obj_.icon();
}
T obj_; T obj_;
}; };
public: public:
template <typename T> template<typename T>
node ( T const& obj, node * parent=0) node(T const& obj, node* parent = 0)
: impl_(new wrap<T>(obj)), : impl_(new wrap<T>(obj))
parent_(parent) , parent_(parent)
{} {}
QString name() const QString name() const { return impl_->name(); }
{
return impl_->name();
}
QIcon icon() const QIcon icon() const { return impl_->icon(); }
{
return impl_->icon();
}
unsigned num_children() const unsigned num_children() const { return children_.count(); }
{
return children_.count();
}
node * child(unsigned row) const node* child(unsigned row) const { return children_.value(row); }
{
return children_.value(row);
}
node * parent() const node* parent() const { return parent_; }
{
return parent_;
}
node * add_child(node * child) node* add_child(node* child)
{ {
children_.push_back(child); children_.push_back(child);
return child; return child;
} }
int row () const int row() const
{ {
if (parent_) if (parent_)
return parent_->children_.indexOf(const_cast<node*>(this)); return parent_->children_.indexOf(const_cast<node*>(this));
@ -110,94 +89,90 @@ public:
return 0; return 0;
} }
~node() ~node() { qDeleteAll(children_); }
{
qDeleteAll(children_);
}
private: private:
const std::unique_ptr<node_base> impl_; const std::unique_ptr<node_base> impl_;
QList<node*> children_; QList<node*> children_;
node * parent_; node* parent_;
}; };
struct symbolizer_info struct symbolizer_info
{ {
QString operator() (mapnik::point_symbolizer const& sym) const QString operator()(mapnik::point_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("PointSymbolizer"); return QString("PointSymbolizer");
} }
QString operator() (mapnik::line_symbolizer const& sym) const QString operator()(mapnik::line_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("LineSymbolizer"); return QString("LineSymbolizer");
} }
QString operator() (mapnik::line_pattern_symbolizer const& sym) const QString operator()(mapnik::line_pattern_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("LinePatternSymbolizer"); return QString("LinePatternSymbolizer");
} }
QString operator() (mapnik::polygon_symbolizer const& sym) const QString operator()(mapnik::polygon_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("PolygonSymbolizer"); return QString("PolygonSymbolizer");
} }
QString operator() (mapnik::polygon_pattern_symbolizer const& sym) const QString operator()(mapnik::polygon_pattern_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("PolygonSymbolizer"); return QString("PolygonSymbolizer");
} }
QString operator() (mapnik::text_symbolizer const& sym) const QString operator()(mapnik::text_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("TextSymbolizer"); return QString("TextSymbolizer");
} }
QString operator() (mapnik::shield_symbolizer const& sym) const QString operator()(mapnik::shield_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("ShieldSymbolizer"); return QString("ShieldSymbolizer");
} }
QString operator() (mapnik::markers_symbolizer const& sym) const QString operator()(mapnik::markers_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("MarkersSymbolizer"); return QString("MarkersSymbolizer");
} }
QString operator() (mapnik::building_symbolizer const& sym) const QString operator()(mapnik::building_symbolizer const& sym) const
{ {
boost::ignore_unused_variable_warning(sym); boost::ignore_unused_variable_warning(sym);
return QString("BuildingSymbolizer"); return QString("BuildingSymbolizer");
} }
template <typename T> template<typename T>
QString operator() (T const& ) const QString operator()(T const&) const
{ {
return QString ("FIXME"); return QString("FIXME");
} }
}; };
struct symbolizer_icon struct symbolizer_icon
{ {
QIcon operator() (mapnik::polygon_symbolizer const& sym) const QIcon operator()(mapnik::polygon_symbolizer const& sym) const
{ {
QPixmap pix(16,16); QPixmap pix(16, 16);
QPainter painter(&pix); QPainter painter(&pix);
mapnik::color const& fill = mapnik::get<mapnik::color>(sym, mapnik::keys::fill); mapnik::color const& fill = mapnik::get<mapnik::color>(sym, mapnik::keys::fill);
QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha())); QBrush brush(QColor(fill.red(), fill.green(), fill.blue(), fill.alpha()));
painter.fillRect(0, 0, 16, 16, brush); painter.fillRect(0, 0, 16, 16, brush);
return QIcon(pix); return QIcon(pix);
} }
QIcon operator() (mapnik::point_symbolizer const& sym) const QIcon operator()(mapnik::point_symbolizer const& sym) const
{ {
// FIXME! // FIXME!
/* /*
@ -212,55 +187,57 @@ struct symbolizer_icon
*/ */
return QIcon(); return QIcon();
} }
QIcon operator() (mapnik::line_symbolizer const& sym) const QIcon operator()(mapnik::line_symbolizer const& sym) const
{ {
QPixmap pix(48,16); QPixmap pix(48, 16);
pix.fill(); pix.fill();
QPainter painter(&pix); QPainter painter(&pix);
//mapnik::stroke const& strk = sym.get_stroke(); // mapnik::stroke const& strk = sym.get_stroke();
mapnik::color const& col = mapnik::get<mapnik::color>(sym, mapnik::keys::stroke); mapnik::color const& col = mapnik::get<mapnik::color>(sym, mapnik::keys::stroke);
QPen pen(QColor(col.red(),col.green(),col.blue(),col.alpha())); QPen pen(QColor(col.red(), col.green(), col.blue(), col.alpha()));
pen.setWidth(mapnik::get<double>(sym, mapnik::keys::width)); pen.setWidth(mapnik::get<double>(sym, mapnik::keys::width));
painter.setPen(pen); painter.setPen(pen);
painter.drawLine(0,7,47,7); painter.drawLine(0, 7, 47, 7);
//painter.drawLine(7,15,12,0); // painter.drawLine(7,15,12,0);
//painter.drawLine(12,0,8,15); // painter.drawLine(12,0,8,15);
return QIcon(pix); return QIcon(pix);
} }
template <typename T> template<typename T>
QIcon operator() (T const& ) const QIcon operator()(T const&) const
{ {
return QIcon (":/images/filter.png"); return QIcon(":/images/filter.png");
} }
}; };
class symbolizer_node class symbolizer_node
{ {
public: public:
symbolizer_node(mapnik::symbolizer const & sym) symbolizer_node(mapnik::symbolizer const& sym)
: sym_(sym) {} : sym_(sym)
~symbolizer_node(){} {}
~symbolizer_node() {}
QString name() const QString name() const
{ {
//return QString("Symbolizer:fixme"); // return QString("Symbolizer:fixme");
return mapnik::util::apply_visitor(symbolizer_info(),sym_); return mapnik::util::apply_visitor(symbolizer_info(), sym_);
} }
QIcon icon() const QIcon icon() const
{ {
return mapnik::util::apply_visitor(symbolizer_icon(),sym_);//QIcon(":/images/filter.png"); return mapnik::util::apply_visitor(symbolizer_icon(), sym_); // QIcon(":/images/filter.png");
} }
mapnik::symbolizer const& sym_; mapnik::symbolizer const& sym_;
}; };
class rule_node class rule_node
{ {
public: public:
rule_node(QString name,mapnik::rule const & r) rule_node(QString name, mapnik::rule const& r)
: name_(name), : name_(name)
rule_(r) {} , rule_(r)
{}
~rule_node() {} ~rule_node() {}
QString name() const QString name() const
{ {
@ -268,81 +245,68 @@ public:
return QString(mapnik::to_expression_string(*filter).c_str()); return QString(mapnik::to_expression_string(*filter).c_str());
} }
QIcon icon() const QIcon icon() const { return QIcon(":/images/filter.png"); }
{
return QIcon(":/images/filter.png");
}
private: private:
QString name_; QString name_;
mapnik::rule const& rule_; mapnik::rule const& rule_;
}; };
class style_node class style_node
{ {
public: public:
style_node(QString name, mapnik::feature_type_style const& style) style_node(QString name, mapnik::feature_type_style const& style)
: name_(name), : name_(name)
style_(style) {} , style_(style)
{}
~style_node() {} ~style_node() {}
QString name() const QString name() const { return name_; }
{
return name_;
}
QIcon icon() const QIcon icon() const { return QIcon(":/images/style.png"); }
{
return QIcon(":/images/style.png");
}
private: private:
QString name_; QString name_;
mapnik::feature_type_style const& style_; mapnik::feature_type_style const& style_;
}; };
class map_node class map_node
{ {
public: public:
explicit map_node(std::shared_ptr<mapnik::Map> map) explicit map_node(std::shared_ptr<mapnik::Map> map)
: map_(map) {} : map_(map)
{}
~map_node() {} ~map_node() {}
QString name() const QString name() const { return QString("Map"); }
{
return QString("Map");
}
QIcon icon() const QIcon icon() const { return QIcon(":/images/map.png"); }
{
return QIcon(":/images/map.png");
}
private: private:
std::shared_ptr<mapnik::Map> map_; std::shared_ptr<mapnik::Map> map_;
}; };
StyleModel::StyleModel(std::shared_ptr<mapnik::Map> map, QObject * parent) StyleModel::StyleModel(std::shared_ptr<mapnik::Map> map, QObject* parent)
: QAbstractItemModel(parent), : QAbstractItemModel(parent)
root_(new node(map_node(map))) , root_(new node(map_node(map)))
{ {
using style_type = std::map<std::string,mapnik::feature_type_style>; using style_type = std::map<std::string, mapnik::feature_type_style>;
style_type const & styles = map->styles(); style_type const& styles = map->styles();
style_type::const_iterator itr = styles.begin(); style_type::const_iterator itr = styles.begin();
style_type::const_iterator end = styles.end(); style_type::const_iterator end = styles.end();
for (; itr != end; ++itr) for (; itr != end; ++itr)
{ {
node * style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()),itr->second),root_.get())); node* style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()), itr->second), root_.get()));
mapnik::rules const& rules = itr->second.get_rules(); mapnik::rules const& rules = itr->second.get_rules();
mapnik::rules::const_iterator itr2 = rules.begin(); mapnik::rules::const_iterator itr2 = rules.begin();
for ( ; itr2 != rules.end();++itr2) for (; itr2 != rules.end(); ++itr2)
{ {
node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n)); node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"), *itr2), style_n));
mapnik::rule::symbolizers::const_iterator itr3 = (*itr2).begin(); mapnik::rule::symbolizers::const_iterator itr3 = (*itr2).begin();
for ( ; itr3 !=itr2->end();++itr3) for (; itr3 != itr2->end(); ++itr3)
{ {
rule_n->add_child(new node(symbolizer_node(*itr3),rule_n)); rule_n->add_child(new node(symbolizer_node(*itr3), rule_n));
} }
} }
} }
@ -351,38 +315,39 @@ StyleModel::StyleModel(std::shared_ptr<mapnik::Map> map, QObject * parent)
StyleModel::~StyleModel() {} StyleModel::~StyleModel() {}
// interface // interface
QModelIndex StyleModel::index (int row, int col, QModelIndex const& parent) const QModelIndex StyleModel::index(int row, int col, QModelIndex const& parent) const
{ {
// qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId()); // qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId());
node * parent_node; node* parent_node;
if (!parent.isValid()) if (!parent.isValid())
parent_node = root_.get(); parent_node = root_.get();
else else
parent_node = static_cast<node*>(parent.internalPointer()); parent_node = static_cast<node*>(parent.internalPointer());
node * child_node = parent_node->child(row); node* child_node = parent_node->child(row);
if (child_node) if (child_node)
return createIndex(row,col,child_node); return createIndex(row, col, child_node);
else else
return QModelIndex(); return QModelIndex();
} }
QModelIndex StyleModel::parent (QModelIndex const& index) const QModelIndex StyleModel::parent(QModelIndex const& index) const
{ {
node * child_node = static_cast<node*>(index.internalPointer()); node* child_node = static_cast<node*>(index.internalPointer());
node * parent_node = child_node->parent(); node* parent_node = child_node->parent();
if (parent_node == root_.get()) if (parent_node == root_.get())
return QModelIndex(); return QModelIndex();
return createIndex(parent_node->row(),0,parent_node); return createIndex(parent_node->row(), 0, parent_node);
} }
int StyleModel::rowCount(QModelIndex const& parent) const int StyleModel::rowCount(QModelIndex const& parent) const
{ {
//qDebug("rowCount"); // qDebug("rowCount");
node * parent_node; node* parent_node;
if (parent.column() > 0) return 0; if (parent.column() > 0)
return 0;
if (!parent.isValid()) if (!parent.isValid())
parent_node = root_.get(); parent_node = root_.get();
else else
@ -390,25 +355,24 @@ int StyleModel::rowCount(QModelIndex const& parent) const
return parent_node->num_children(); return parent_node->num_children();
} }
int StyleModel::columnCount( QModelIndex const&) const int StyleModel::columnCount(QModelIndex const&) const
{ {
return 1; return 1;
} }
QVariant StyleModel::data(const QModelIndex & index, int role) const QVariant StyleModel::data(const QModelIndex& index, int role) const
{ {
//qDebug("data index::internalId() = %lld", index.internalId()); // qDebug("data index::internalId() = %lld", index.internalId());
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
node * cur_node = static_cast<node*>(index.internalPointer()); node* cur_node = static_cast<node*>(index.internalPointer());
if (cur_node) if (cur_node)
{ {
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
return QVariant(cur_node->name()); return QVariant(cur_node->name());
} }
else if ( role == Qt::DecorationRole) else if (role == Qt::DecorationRole)
{ {
return cur_node->icon(); return cur_node->icon();
} }

View file

@ -1,6 +1,6 @@
/* This file is part of Mapnik (c++ mapping toolkit) /* This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2024 Artem Pavlenko
* *
* Mapnik is free software; you can redistribute it and/or * Mapnik is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -17,7 +17,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef STYLE_MODEL_HPP #ifndef STYLE_MODEL_HPP
#define STYLE_MODEL_HPP #define STYLE_MODEL_HPP
@ -27,24 +26,23 @@
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#endif #endif
class node; class node;
class StyleModel : public QAbstractItemModel class StyleModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
public: public:
StyleModel(std::shared_ptr<mapnik::Map> map, QObject * parent=0); StyleModel(std::shared_ptr<mapnik::Map> map, QObject* parent = 0);
~StyleModel(); ~StyleModel();
// interface // interface
QModelIndex index (int row, int col, QModelIndex const& parent = QModelIndex()) const; QModelIndex index(int row, int col, QModelIndex const& parent = QModelIndex()) const;
QModelIndex parent (QModelIndex const& child) const; QModelIndex parent(QModelIndex const& child) const;
int rowCount( QModelIndex const& parent = QModelIndex()) const; int rowCount(QModelIndex const& parent = QModelIndex()) const;
int columnCount( QModelIndex const& parent = QModelIndex()) const; int columnCount(QModelIndex const& parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
private:
//std::shared_ptr<mapnik::Map> map_; private:
const std::unique_ptr<node> root_; // std::shared_ptr<mapnik::Map> map_;
const std::unique_ptr<node> root_;
}; };
#endif // STYLE_MODEL_HPP #endif // STYLE_MODEL_HPP

1
deps/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1 @@
add_subdirectory(agg)

1
deps/agg/.clang-format vendored Normal file
View file

@ -0,0 +1 @@
DisableFormat: true

19
deps/agg/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,19 @@
project(agg)
add_library(agg INTERFACE)
add_library(mapnik::agg ALIAS agg)
target_include_directories(agg INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(agg INTERFACE mapnik::core)
install(TARGETS agg
EXPORT MapnikTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include
)
# agg headers would be installed in the top level CMakeLists.txt

View file

@ -365,7 +365,7 @@ namespace agg
inline bool is_close(unsigned c) inline bool is_close(unsigned c)
{ {
return (c & ~(path_flags_cw | path_flags_ccw)) == return (c & ~(path_flags_cw | path_flags_ccw)) ==
(path_cmd_end_poly | path_flags_close); (path_cmd_end_poly | static_cast<path_commands_e>(path_flags_close));
} }
//------------------------------------------------------------is_next_poly //------------------------------------------------------------is_next_poly

View file

@ -436,7 +436,8 @@ struct gray16
static value_type luminance(const rgba& c) static value_type luminance(const rgba& c)
{ {
// Calculate grayscale value as per ITU-R BT.709. // Calculate grayscale value as per ITU-R BT.709.
return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b)
* static_cast<double>(base_mask)));
} }
static value_type luminance(const rgba16& c) static value_type luminance(const rgba16& c)
@ -537,13 +538,13 @@ struct gray16
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE double to_double(value_type a) static AGG_INLINE double to_double(value_type a)
{ {
return double(a) / base_mask; return static_cast<double>(a) / static_cast<double>(base_mask);
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE value_type from_double(double a) static AGG_INLINE value_type from_double(double a)
{ {
return value_type(uround(a * base_mask)); return value_type(uround(a * static_cast<double>(base_mask)));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -698,7 +699,7 @@ struct gray16
self_type gradient(self_type c, double k) const self_type gradient(self_type c, double k) const
{ {
self_type ret; self_type ret;
calc_type ik = uround(k * base_scale); calc_type ik = uround(k * static_cast<double>(base_scale));
ret.v = lerp(v, c.v, ik); ret.v = lerp(v, c.v, ik);
ret.a = lerp(a, c.a, ik); ret.a = lerp(a, c.a, ik);
return ret; return ret;
@ -949,7 +950,7 @@ struct gray32
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
{ {
return value_type(a * b / cover_mask); return value_type(a * b / static_cast<double>(cover_mask));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------

View file

@ -281,10 +281,10 @@ struct rgba8T
static void convert(rgba8T<linear>& dst, const rgba& src) static void convert(rgba8T<linear>& dst, const rgba& src)
{ {
dst.r = value_type(uround(src.r * base_mask)); dst.r = value_type(uround(src.r * static_cast<double>(base_mask)));
dst.g = value_type(uround(src.g * base_mask)); dst.g = value_type(uround(src.g * static_cast<double>(base_mask)));
dst.b = value_type(uround(src.b * base_mask)); dst.b = value_type(uround(src.b * static_cast<double>(base_mask)));
dst.a = value_type(uround(src.a * base_mask)); dst.a = value_type(uround(src.a * static_cast<double>(base_mask)));
} }
static void convert(rgba8T<sRGB>& dst, const rgba& src) static void convert(rgba8T<sRGB>& dst, const rgba& src)
@ -761,13 +761,13 @@ struct rgba16
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE double to_double(value_type a) static AGG_INLINE double to_double(value_type a)
{ {
return double(a) / base_mask; return static_cast<double>(a) / static_cast<double>(base_mask);
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE value_type from_double(double a) static AGG_INLINE value_type from_double(double a)
{ {
return value_type(uround(a * base_mask)); return value_type(uround(a * static_cast<double>(base_mask)));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -955,7 +955,7 @@ struct rgba16
AGG_INLINE self_type gradient(const self_type& c, double k) const AGG_INLINE self_type gradient(const self_type& c, double k) const
{ {
self_type ret; self_type ret;
calc_type ik = uround(k * base_mask); calc_type ik = uround(k * static_cast<double>(base_mask));
ret.r = lerp(r, c.r, ik); ret.r = lerp(r, c.r, ik);
ret.g = lerp(g, c.g, ik); ret.g = lerp(g, c.g, ik);
ret.b = lerp(b, c.b, ik); ret.b = lerp(b, c.b, ik);
@ -1194,7 +1194,7 @@ struct rgba32
//-------------------------------------------------------------------- //--------------------------------------------------------------------
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
{ {
return value_type(a * b / cover_mask); return value_type(a * b / static_cast<float>(cover_mask));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -37,7 +37,7 @@ namespace agg
private: private:
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&); conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
const conv_adaptor_vpgen<VertexSource, VPGen>& const conv_adaptor_vpgen<VertexSource, VPGen>&
operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&); operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&);
VertexSource* m_source; VertexSource* m_source;
@ -52,8 +52,8 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VertexSource, class VPGen> template<class VertexSource, class VPGen>
void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id) void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id)
{ {
m_source->rewind(path_id); m_source->rewind(path_id);
m_vpgen.reset(); m_vpgen.reset();
m_start_x = 0; m_start_x = 0;
@ -84,7 +84,7 @@ namespace agg
if(m_vertices < 0) if(m_vertices < 0)
{ {
if(m_vertices < -1) if(m_vertices < -1)
{ {
m_vertices = 0; m_vertices = 0;
return path_cmd_stop; return path_cmd_stop;
@ -98,12 +98,13 @@ namespace agg
cmd = m_source->vertex(&tx, &ty); cmd = m_source->vertex(&tx, &ty);
if(is_vertex(cmd)) if(is_vertex(cmd))
{ {
if(is_move_to(cmd)) if(is_move_to(cmd))
{ {
if(m_vpgen.auto_close() && m_vertices > 2) if(m_vpgen.auto_close() && m_vertices > 2)
{ {
m_vpgen.line_to(m_start_x, m_start_y); m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close; m_poly_flags = path_cmd_end_poly
| static_cast<path_commands_e>(path_flags_close);
m_start_x = tx; m_start_x = tx;
m_start_y = ty; m_start_y = ty;
m_vertices = -1; m_vertices = -1;
@ -114,7 +115,7 @@ namespace agg
m_start_y = ty; m_start_y = ty;
m_vertices = 1; m_vertices = 1;
} }
else else
{ {
m_vpgen.line_to(tx, ty); m_vpgen.line_to(tx, ty);
++m_vertices; ++m_vertices;
@ -141,7 +142,8 @@ namespace agg
if(m_vpgen.auto_close() && m_vertices > 2) if(m_vpgen.auto_close() && m_vertices > 2)
{ {
m_vpgen.line_to(m_start_x, m_start_y); m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close; m_poly_flags = path_cmd_end_poly
| static_cast<path_commands_e>(path_flags_close);
m_vertices = -2; m_vertices = -2;
continue; continue;
} }
@ -157,4 +159,3 @@ namespace agg
#endif #endif

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -22,24 +22,25 @@
#include "agg_array.h" #include "agg_array.h"
#include "agg_math.h" #include "agg_math.h"
#include <cstdint>
namespace agg namespace agg
{ {
// See Implementation agg_image_filters.cpp // See Implementation agg_image_filters.cpp
enum image_filter_scale_e enum image_filter_scale_e
{ {
image_filter_shift = 14, //----image_filter_shift image_filter_shift = 14, //----image_filter_shift
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
image_filter_mask = image_filter_scale - 1 //----image_filter_mask image_filter_mask = image_filter_scale - 1 //----image_filter_mask
}; };
enum image_subpixel_scale_e enum image_subpixel_scale_e
{ {
image_subpixel_shift = 8, //----image_subpixel_shift image_subpixel_shift = 8, //----image_subpixel_shift
image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
}; };
@ -58,12 +59,13 @@ namespace agg
{ {
double x = double(i) / double(image_subpixel_scale); double x = double(i) / double(image_subpixel_scale);
double y = filter.calc_weight(x); double y = filter.calc_weight(x);
m_weight_array[pivot + i] = m_weight_array[pivot + i] =
m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale); m_weight_array[pivot - i] =
static_cast<std::int16_t>(iround(y * static_cast<double>(image_filter_scale)));
} }
unsigned end = (diameter() << image_subpixel_shift) - 1; unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end]; m_weight_array[0] = m_weight_array[end];
if(normalization) if(normalization)
{ {
normalize(); normalize();
} }
@ -71,7 +73,7 @@ namespace agg
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {} image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
template<class FilterF> image_filter_lut(const FilterF& filter, template<class FilterF> image_filter_lut(const FilterF& filter,
bool normalization=true) bool normalization=true)
{ {
calculate(filter, normalization); calculate(filter, normalization);
@ -80,7 +82,7 @@ namespace agg
double radius() const { return m_radius; } double radius() const { return m_radius; }
unsigned diameter() const { return m_diameter; } unsigned diameter() const { return m_diameter; }
int start() const { return m_start; } int start() const { return m_start; }
const int16* weight_array() const { return &m_weight_array[0]; } std::int16_t const* weight_array() const { return &m_weight_array[0]; }
void normalize(); void normalize();
private: private:
@ -91,7 +93,7 @@ namespace agg
double m_radius; double m_radius;
unsigned m_diameter; unsigned m_diameter;
int m_start; int m_start;
pod_array<int16> m_weight_array; pod_array<std::int16_t> m_weight_array;
}; };
@ -150,7 +152,7 @@ namespace agg
return (2.0 * x - 3.0) * x * x + 1.0; return (2.0 * x - 3.0) * x * x + 1.0;
} }
}; };
//------------------------------------------------image_filter_quadric //------------------------------------------------image_filter_quadric
struct image_filter_quadric struct image_filter_quadric
{ {
@ -177,7 +179,7 @@ namespace agg
static double calc_weight(double x) static double calc_weight(double x)
{ {
return return
(1.0/6.0) * (1.0/6.0) *
(pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1)); (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
} }
}; };
@ -211,7 +213,7 @@ namespace agg
sum = 1.; sum = 1.;
y = x * x / 4.; y = x * x / 4.;
t = y; t = y;
for(i = 2; t > epsilon; i++) for(i = 2; t > epsilon; i++)
{ {
sum += t; sum += t;
@ -298,7 +300,7 @@ namespace agg
struct image_filter_gaussian struct image_filter_gaussian
{ {
static double radius() { return 2.0; } static double radius() { return 2.0; }
static double calc_weight(double x) static double calc_weight(double x)
{ {
return exp(-2.0 * x * x) * sqrt(2.0 / pi); return exp(-2.0 * x * x) * sqrt(2.0 / pi);
} }
@ -308,7 +310,7 @@ namespace agg
//------------------------------------------------image_filter_bessel //------------------------------------------------image_filter_bessel
struct image_filter_bessel struct image_filter_bessel
{ {
static double radius() { return 3.2383; } static double radius() { return 3.2383; }
static double calc_weight(double x) static double calc_weight(double x)
{ {
return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x); return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);

View file

@ -44,13 +44,13 @@ namespace agg
//------------------------------------------------------------------line_mr //------------------------------------------------------------------line_mr
AGG_INLINE int line_mr(int x) AGG_INLINE int line_mr(int x)
{ {
return x >> (line_subpixel_shift - line_mr_subpixel_shift); return x >> (line_subpixel_shift - static_cast<line_subpixel_scale_e>(line_mr_subpixel_shift));
} }
//-------------------------------------------------------------------line_hr //-------------------------------------------------------------------line_hr
AGG_INLINE int line_hr(int x) AGG_INLINE int line_hr(int x)
{ {
return x << (line_subpixel_shift - line_mr_subpixel_shift); return x << (line_subpixel_shift - static_cast<line_subpixel_scale_e>(line_mr_subpixel_shift));
} }
//---------------------------------------------------------------line_dbl_hr //---------------------------------------------------------------line_dbl_hr
@ -64,7 +64,7 @@ namespace agg
{ {
AGG_INLINE static int conv(double x) AGG_INLINE static int conv(double x)
{ {
return iround(x * line_subpixel_scale); return iround(x * static_cast<double>(line_subpixel_scale));
} }
}; };
@ -73,7 +73,7 @@ namespace agg
{ {
AGG_INLINE static int conv(double x) AGG_INLINE static int conv(double x)
{ {
return saturation<line_max_coord>::iround(x * line_subpixel_scale); return saturation<line_max_coord>::iround(x * static_cast<double>(line_subpixel_scale));
} }
}; };

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -92,7 +92,7 @@ namespace agg
{ {
pod_allocator<T>::deallocate( pod_allocator<T>::deallocate(
*coord_blk, *coord_blk,
block_size * 2 + block_size * 2 +
block_size / (sizeof(T) / sizeof(unsigned char))); block_size / (sizeof(T) / sizeof(unsigned char)));
--coord_blk; --coord_blk;
} }
@ -137,7 +137,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
const vertex_block_storage<T,S,P>& const vertex_block_storage<T,S,P>&
vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v) vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v)
{ {
remove_all(); remove_all();
@ -160,7 +160,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y, inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y,
unsigned cmd) unsigned cmd)
{ {
T* coord_ptr = 0; T* coord_ptr = 0;
@ -172,7 +172,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
double x, double y) double x, double y)
{ {
T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1);
@ -182,8 +182,8 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
double x, double y, double x, double y,
unsigned cmd) unsigned cmd)
{ {
unsigned block = idx >> block_shift; unsigned block = idx >> block_shift;
@ -196,7 +196,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx, inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx,
unsigned cmd) unsigned cmd)
{ {
m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd;
@ -277,7 +277,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx, inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx,
double* x, double* y) const double* x, double* y) const
{ {
unsigned nb = idx >> block_shift; unsigned nb = idx >> block_shift;
@ -298,22 +298,22 @@ namespace agg
template<class T, unsigned S, unsigned P> template<class T, unsigned S, unsigned P>
void vertex_block_storage<T,S,P>::allocate_block(unsigned nb) void vertex_block_storage<T,S,P>::allocate_block(unsigned nb)
{ {
if(nb >= m_max_blocks) if(nb >= m_max_blocks)
{ {
T** new_coords = T** new_coords =
pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2); pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2);
unsigned char** new_cmds = unsigned char** new_cmds =
(unsigned char**)(new_coords + m_max_blocks + block_pool); (unsigned char**)(new_coords + m_max_blocks + block_pool);
if(m_coord_blocks) if(m_coord_blocks)
{ {
memcpy(new_coords, memcpy(new_coords,
m_coord_blocks, m_coord_blocks,
m_max_blocks * sizeof(T*)); m_max_blocks * sizeof(T*));
memcpy(new_cmds, memcpy(new_cmds,
m_cmd_blocks, m_cmd_blocks,
m_max_blocks * sizeof(unsigned char*)); m_max_blocks * sizeof(unsigned char*));
pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2); pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
@ -322,11 +322,11 @@ namespace agg
m_cmd_blocks = new_cmds; m_cmd_blocks = new_cmds;
m_max_blocks += block_pool; m_max_blocks += block_pool;
} }
m_coord_blocks[nb] = m_coord_blocks[nb] =
pod_allocator<T>::allocate(block_size * 2 + pod_allocator<T>::allocate(block_size * 2 +
block_size / (sizeof(T) / sizeof(unsigned char))); block_size / (sizeof(T) / sizeof(unsigned char)));
m_cmd_blocks[nb] = m_cmd_blocks[nb] =
(unsigned char*)(m_coord_blocks[nb] + block_size * 2); (unsigned char*)(m_coord_blocks[nb] + block_size * 2);
m_total_blocks++; m_total_blocks++;
@ -354,8 +354,8 @@ namespace agg
public: public:
typedef T value_type; typedef T value_type;
poly_plain_adaptor() : poly_plain_adaptor() :
m_data(0), m_data(0),
m_ptr(0), m_ptr(0),
m_end(0), m_end(0),
m_closed(false), m_closed(false),
@ -363,7 +363,7 @@ namespace agg
{} {}
poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : poly_plain_adaptor(const T* data, unsigned num_points, bool closed) :
m_data(data), m_data(data),
m_ptr(data), m_ptr(data),
m_end(data + num_points * 2), m_end(data + num_points * 2),
m_closed(closed), m_closed(closed),
@ -398,7 +398,8 @@ namespace agg
if(m_closed && !m_stop) if(m_closed && !m_stop)
{ {
m_stop = true; m_stop = true;
return path_cmd_end_poly | path_flags_close; return path_cmd_end_poly
| static_cast<agg::path_commands_e>(path_flags_close);
} }
return path_cmd_stop; return path_cmd_stop;
} }
@ -421,15 +422,15 @@ namespace agg
public: public:
typedef typename Container::value_type vertex_type; typedef typename Container::value_type vertex_type;
poly_container_adaptor() : poly_container_adaptor() :
m_container(0), m_container(0),
m_index(0), m_index(0),
m_closed(false), m_closed(false),
m_stop(false) m_stop(false)
{} {}
poly_container_adaptor(const Container& data, bool closed) : poly_container_adaptor(const Container& data, bool closed) :
m_container(&data), m_container(&data),
m_index(0), m_index(0),
m_closed(closed), m_closed(closed),
m_stop(false) m_stop(false)
@ -463,7 +464,8 @@ namespace agg
if(m_closed && !m_stop) if(m_closed && !m_stop)
{ {
m_stop = true; m_stop = true;
return path_cmd_end_poly | path_flags_close; return path_cmd_end_poly
| static_cast<agg::path_commands_e>(path_flags_close);
} }
return path_cmd_stop; return path_cmd_stop;
} }
@ -483,15 +485,15 @@ namespace agg
public: public:
typedef typename Container::value_type vertex_type; typedef typename Container::value_type vertex_type;
poly_container_reverse_adaptor() : poly_container_reverse_adaptor() :
m_container(0), m_container(0),
m_index(-1), m_index(-1),
m_closed(false), m_closed(false),
m_stop(false) m_stop(false)
{} {}
poly_container_reverse_adaptor(const Container& data, bool closed) : poly_container_reverse_adaptor(const Container& data, bool closed) :
m_container(&data), m_container(&data),
m_index(-1), m_index(-1),
m_closed(closed), m_closed(closed),
m_stop(false) m_stop(false)
@ -525,7 +527,8 @@ namespace agg
if(m_closed && !m_stop) if(m_closed && !m_stop)
{ {
m_stop = true; m_stop = true;
return path_cmd_end_poly | path_flags_close; return path_cmd_end_poly
| static_cast<agg::path_commands_e>(path_flags_close);
} }
return path_cmd_stop; return path_cmd_stop;
} }
@ -556,7 +559,7 @@ namespace agg
m_coord[2] = x2; m_coord[2] = x2;
m_coord[3] = y2; m_coord[3] = y2;
} }
void init(double x1, double y1, double x2, double y2) void init(double x1, double y1, double x2, double y2)
{ {
m_coord[0] = x1; m_coord[0] = x1;
@ -594,10 +597,10 @@ namespace agg
//---------------------------------------------------------------path_base //---------------------------------------------------------------path_base
// A container to store vertices with their flags. // A container to store vertices with their flags.
// A path consists of a number of contours separated with "move_to" // A path consists of a number of contours separated with "move_to"
// commands. The path storage can keep and maintain more than one // commands. The path storage can keep and maintain more than one
// path. // path.
// To navigate to the beginning of a particular path, use rewind(path_id); // To navigate to the beginning of a particular path, use rewind(path_id);
// Where path_id is what start_new_path() returns. So, when you call // Where path_id is what start_new_path() returns. So, when you call
// start_new_path() you need to store its return value somewhere else // start_new_path() you need to store its return value somewhere else
@ -644,28 +647,28 @@ namespace agg
bool sweep_flag, bool sweep_flag,
double dx, double dy); double dx, double dy);
void curve3(double x_ctrl, double y_ctrl, void curve3(double x_ctrl, double y_ctrl,
double x_to, double y_to); double x_to, double y_to);
void curve3_rel(double dx_ctrl, double dy_ctrl, void curve3_rel(double dx_ctrl, double dy_ctrl,
double dx_to, double dy_to); double dx_to, double dy_to);
void curve3(double x_to, double y_to); void curve3(double x_to, double y_to);
void curve3_rel(double dx_to, double dy_to); void curve3_rel(double dx_to, double dy_to);
void curve4(double x_ctrl1, double y_ctrl1, void curve4(double x_ctrl1, double y_ctrl1,
double x_ctrl2, double y_ctrl2, double x_ctrl2, double y_ctrl2,
double x_to, double y_to); double x_to, double y_to);
void curve4_rel(double dx_ctrl1, double dy_ctrl1, void curve4_rel(double dx_ctrl1, double dy_ctrl1,
double dx_ctrl2, double dy_ctrl2, double dx_ctrl2, double dy_ctrl2,
double dx_to, double dy_to); double dx_to, double dy_to);
void curve4(double x_ctrl2, double y_ctrl2, void curve4(double x_ctrl2, double y_ctrl2,
double x_to, double y_to); double x_to, double y_to);
void curve4_rel(double x_ctrl2, double y_ctrl2, void curve4_rel(double x_ctrl2, double y_ctrl2,
double x_to, double y_to); double x_to, double y_to);
@ -674,8 +677,8 @@ namespace agg
// Accessors // Accessors
//-------------------------------------------------------------------- //--------------------------------------------------------------------
const container_type& vertices() const { return m_vertices; } const container_type& vertices() const { return m_vertices; }
container_type& vertices() { return m_vertices; } container_type& vertices() { return m_vertices; }
unsigned total_vertices() const; unsigned total_vertices() const;
@ -699,9 +702,9 @@ namespace agg
void rewind(unsigned path_id); void rewind(unsigned path_id);
unsigned vertex(double* x, double* y); unsigned vertex(double* x, double* y);
// Arrange the orientation of a polygon, all polygons in a path, // Arrange the orientation of a polygon, all polygons in a path,
// or in all paths. After calling arrange_orientations() or // or in all paths. After calling arrange_orientations() or
// arrange_orientations_all_paths(), all the polygons will have // arrange_orientations_all_paths(), all the polygons will have
// the same orientation, i.e. path_flags_cw or path_flags_ccw // the same orientation, i.e. path_flags_cw or path_flags_ccw
//-------------------------------------------------------------------- //--------------------------------------------------------------------
unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation);
@ -709,7 +712,7 @@ namespace agg
void arrange_orientations_all_paths(path_flags_e orientation); void arrange_orientations_all_paths(path_flags_e orientation);
void invert_polygon(unsigned start); void invert_polygon(unsigned start);
// Flip all vertices horizontally or vertically, // Flip all vertices horizontally or vertically,
// between x1 and x2, or between y1 and y2 respectively // between x1 and x2, or between y1 and y2 respectively
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void flip_x(double x1, double x2); void flip_x(double x1, double x2);
@ -717,7 +720,7 @@ namespace agg
// Concatenate path. The path is added as is. // Concatenate path. The path is added as is.
//-------------------------------------------------------------------- //--------------------------------------------------------------------
template<class VertexSource> template<class VertexSource>
void concat_path(VertexSource& vs, unsigned path_id = 0) void concat_path(VertexSource& vs, unsigned path_id = 0)
{ {
double x=0; double x=0;
@ -731,9 +734,9 @@ namespace agg
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Join path. The path is joined with the existing one, that is, // Join path. The path is joined with the existing one, that is,
// it behaves as if the pen of a plotter was always down (drawing) // it behaves as if the pen of a plotter was always down (drawing)
template<class VertexSource> template<class VertexSource>
void join_path(VertexSource& vs, unsigned path_id = 0) void join_path(VertexSource& vs, unsigned path_id = 0)
{ {
double x=0.0, y=0.0; double x=0.0, y=0.0;
@ -769,16 +772,16 @@ namespace agg
} }
while(!is_stop(cmd = vs.vertex(&x, &y))) while(!is_stop(cmd = vs.vertex(&x, &y)))
{ {
m_vertices.add_vertex(x, y, is_move_to(cmd) ? m_vertices.add_vertex(x, y, is_move_to(cmd) ?
unsigned(path_cmd_line_to) : unsigned(path_cmd_line_to) :
cmd); cmd);
} }
} }
} }
// Concatenate polygon/polyline. // Concatenate polygon/polyline.
//-------------------------------------------------------------------- //--------------------------------------------------------------------
template<class T> void concat_poly(const T* data, template<class T> void concat_poly(const T* data,
unsigned num_points, unsigned num_points,
bool closed) bool closed)
{ {
@ -788,7 +791,7 @@ namespace agg
// Join polygon/polyline continuously. // Join polygon/polyline continuously.
//-------------------------------------------------------------------- //--------------------------------------------------------------------
template<class T> void join_poly(const T* data, template<class T> void join_poly(const T* data,
unsigned num_points, unsigned num_points,
bool closed) bool closed)
{ {
@ -846,7 +849,7 @@ namespace agg
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
unsigned path_base<VC>::start_new_path() unsigned path_base<VC>::start_new_path()
{ {
if(!is_stop(m_vertices.last_command())) if(!is_stop(m_vertices.last_command()))
@ -858,7 +861,7 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::rel_to_abs(double* x, double* y) const inline void path_base<VC>::rel_to_abs(double* x, double* y) const
{ {
if(m_vertices.total_vertices()) if(m_vertices.total_vertices())
@ -870,7 +873,7 @@ namespace agg
*x += x2; *x += x2;
*y += y2; *y += y2;
} }
else if (!is_stop(m_vertices.last_command()) && else if (!is_stop(m_vertices.last_command()) &&
is_vertex(m_vertices.prev_vertex(&x2, &y2))) is_vertex(m_vertices.prev_vertex(&x2, &y2)))
{ {
*x += x2; *x += x2;
@ -880,14 +883,14 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::move_to(double x, double y) inline void path_base<VC>::move_to(double x, double y)
{ {
m_vertices.add_vertex(x, y, path_cmd_move_to); m_vertices.add_vertex(x, y, path_cmd_move_to);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::move_rel(double dx, double dy) inline void path_base<VC>::move_rel(double dx, double dy)
{ {
rel_to_abs(&dx, &dy); rel_to_abs(&dx, &dy);
@ -895,14 +898,14 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::line_to(double x, double y) inline void path_base<VC>::line_to(double x, double y)
{ {
m_vertices.add_vertex(x, y, path_cmd_line_to); m_vertices.add_vertex(x, y, path_cmd_line_to);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::line_rel(double dx, double dy) inline void path_base<VC>::line_rel(double dx, double dy)
{ {
rel_to_abs(&dx, &dy); rel_to_abs(&dx, &dy);
@ -910,14 +913,14 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::hline_to(double x) inline void path_base<VC>::hline_to(double x)
{ {
m_vertices.add_vertex(x, last_y(), path_cmd_line_to); m_vertices.add_vertex(x, last_y(), path_cmd_line_to);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::hline_rel(double dx) inline void path_base<VC>::hline_rel(double dx)
{ {
double dy = 0; double dy = 0;
@ -926,14 +929,14 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::vline_to(double y) inline void path_base<VC>::vline_to(double y)
{ {
m_vertices.add_vertex(last_x(), y, path_cmd_line_to); m_vertices.add_vertex(last_x(), y, path_cmd_line_to);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::vline_rel(double dy) inline void path_base<VC>::vline_rel(double dy)
{ {
double dx = 0; double dx = 0;
@ -942,7 +945,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::arc_to(double rx, double ry, void path_base<VC>::arc_to(double rx, double ry,
double angle, double angle,
bool large_arc_flag, bool large_arc_flag,
@ -961,7 +964,7 @@ namespace agg
// Ensure radii are valid // Ensure radii are valid
//------------------------- //-------------------------
if(rx < epsilon || ry < epsilon) if(rx < epsilon || ry < epsilon)
{ {
line_to(x, y); line_to(x, y);
return; return;
@ -978,10 +981,11 @@ namespace agg
{ {
join_path(a); join_path(a);
} }
else // We are adding an explicit line_to, even if we've already add the
{ // bezier arc to the current path. This is to prevent subsequent smooth
line_to(x, y); // bezier curves from accidentally assuming that the previous command
} // was a bezier curve as well when calculating reflection points.
line_to(x, y);
} }
else else
{ {
@ -990,7 +994,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::arc_rel(double rx, double ry, void path_base<VC>::arc_rel(double rx, double ry,
double angle, double angle,
bool large_arc_flag, bool large_arc_flag,
@ -1002,8 +1006,8 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve3(double x_ctrl, double y_ctrl, void path_base<VC>::curve3(double x_ctrl, double y_ctrl,
double x_to, double y_to) double x_to, double y_to)
{ {
m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3);
@ -1011,8 +1015,8 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl, void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl,
double dx_to, double dy_to) double dx_to, double dy_to)
{ {
rel_to_abs(&dx_ctrl, &dy_ctrl); rel_to_abs(&dx_ctrl, &dy_ctrl);
@ -1022,7 +1026,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve3(double x_to, double y_to) void path_base<VC>::curve3(double x_to, double y_to)
{ {
double x0; double x0;
@ -1030,7 +1034,7 @@ namespace agg
if(is_vertex(m_vertices.last_vertex(&x0, &y0))) if(is_vertex(m_vertices.last_vertex(&x0, &y0)))
{ {
double x_ctrl; double x_ctrl;
double y_ctrl; double y_ctrl;
unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl);
if(is_curve(cmd)) if(is_curve(cmd))
{ {
@ -1047,7 +1051,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve3_rel(double dx_to, double dy_to) void path_base<VC>::curve3_rel(double dx_to, double dy_to)
{ {
rel_to_abs(&dx_to, &dy_to); rel_to_abs(&dx_to, &dy_to);
@ -1055,9 +1059,9 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1, void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1,
double x_ctrl2, double y_ctrl2, double x_ctrl2, double y_ctrl2,
double x_to, double y_to) double x_to, double y_to)
{ {
m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
@ -1066,9 +1070,9 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1, void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1,
double dx_ctrl2, double dy_ctrl2, double dx_ctrl2, double dy_ctrl2,
double dx_to, double dy_to) double dx_to, double dy_to)
{ {
rel_to_abs(&dx_ctrl1, &dy_ctrl1); rel_to_abs(&dx_ctrl1, &dy_ctrl1);
@ -1080,8 +1084,8 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2, void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2,
double x_to, double y_to) double x_to, double y_to)
{ {
double x0; double x0;
@ -1089,7 +1093,7 @@ namespace agg
if(is_vertex(last_vertex(&x0, &y0))) if(is_vertex(last_vertex(&x0, &y0)))
{ {
double x_ctrl1; double x_ctrl1;
double y_ctrl1; double y_ctrl1;
unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1);
if(is_curve(cmd)) if(is_curve(cmd))
{ {
@ -1106,8 +1110,8 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2, void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2,
double dx_to, double dy_to) double dx_to, double dy_to)
{ {
rel_to_abs(&dx_ctrl2, &dy_ctrl2); rel_to_abs(&dx_ctrl2, &dy_ctrl2);
@ -1116,7 +1120,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::end_poly(unsigned flags) inline void path_base<VC>::end_poly(unsigned flags)
{ {
if(is_vertex(m_vertices.last_command())) if(is_vertex(m_vertices.last_command()))
@ -1126,91 +1130,91 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::close_polygon(unsigned flags) inline void path_base<VC>::close_polygon(unsigned flags)
{ {
end_poly(path_flags_close | flags); end_poly(path_flags_close | flags);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::total_vertices() const inline unsigned path_base<VC>::total_vertices() const
{ {
return m_vertices.total_vertices(); return m_vertices.total_vertices();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::last_vertex(double* x, double* y) const inline unsigned path_base<VC>::last_vertex(double* x, double* y) const
{ {
return m_vertices.last_vertex(x, y); return m_vertices.last_vertex(x, y);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const
{ {
return m_vertices.prev_vertex(x, y); return m_vertices.prev_vertex(x, y);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline double path_base<VC>::last_x() const inline double path_base<VC>::last_x() const
{ {
return m_vertices.last_x(); return m_vertices.last_x();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline double path_base<VC>::last_y() const inline double path_base<VC>::last_y() const
{ {
return m_vertices.last_y(); return m_vertices.last_y();
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const
{ {
return m_vertices.vertex(idx, x, y); return m_vertices.vertex(idx, x, y);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::command(unsigned idx) const inline unsigned path_base<VC>::command(unsigned idx) const
{ {
return m_vertices.command(idx); return m_vertices.command(idx);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::modify_vertex(unsigned idx, double x, double y) void path_base<VC>::modify_vertex(unsigned idx, double x, double y)
{ {
m_vertices.modify_vertex(idx, x, y); m_vertices.modify_vertex(idx, x, y);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd) void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd)
{ {
m_vertices.modify_vertex(idx, x, y, cmd); m_vertices.modify_vertex(idx, x, y, cmd);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::modify_command(unsigned idx, unsigned cmd) void path_base<VC>::modify_command(unsigned idx, unsigned cmd)
{ {
m_vertices.modify_command(idx, cmd); m_vertices.modify_command(idx, cmd);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline void path_base<VC>::rewind(unsigned path_id) inline void path_base<VC>::rewind(unsigned path_id)
{ {
m_iterator = path_id; m_iterator = path_id;
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
inline unsigned path_base<VC>::vertex(double* x, double* y) inline unsigned path_base<VC>::vertex(double* x, double* y)
{ {
if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop;
@ -1218,7 +1222,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
unsigned path_base<VC>::perceive_polygon_orientation(unsigned start, unsigned path_base<VC>::perceive_polygon_orientation(unsigned start,
unsigned end) unsigned end)
{ {
@ -1238,12 +1242,12 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::invert_polygon(unsigned start, unsigned end) void path_base<VC>::invert_polygon(unsigned start, unsigned end)
{ {
unsigned i; unsigned i;
unsigned tmp_cmd = m_vertices.command(start); unsigned tmp_cmd = m_vertices.command(start);
--end; // Make "end" inclusive --end; // Make "end" inclusive
// Shift all commands to one position // Shift all commands to one position
@ -1263,45 +1267,45 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::invert_polygon(unsigned start) void path_base<VC>::invert_polygon(unsigned start)
{ {
// Skip all non-vertices at the beginning // Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() && while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start; !is_vertex(m_vertices.command(start))) ++start;
// Skip all insignificant move_to // Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() && while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) && is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start; is_move_to(m_vertices.command(start+1))) ++start;
// Find the last vertex // Find the last vertex
unsigned end = start + 1; unsigned end = start + 1;
while(end < m_vertices.total_vertices() && while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end; !is_next_poly(m_vertices.command(end))) ++end;
invert_polygon(start, end); invert_polygon(start, end);
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
unsigned path_base<VC>::arrange_polygon_orientation(unsigned start, unsigned path_base<VC>::arrange_polygon_orientation(unsigned start,
path_flags_e orientation) path_flags_e orientation)
{ {
if(orientation == path_flags_none) return start; if(orientation == path_flags_none) return start;
// Skip all non-vertices at the beginning // Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() && while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start; !is_vertex(m_vertices.command(start))) ++start;
// Skip all insignificant move_to // Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() && while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) && is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start; is_move_to(m_vertices.command(start+1))) ++start;
// Find the last vertex // Find the last vertex
unsigned end = start + 1; unsigned end = start + 1;
while(end < m_vertices.total_vertices() && while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end; !is_next_poly(m_vertices.command(end))) ++end;
if(end - start > 2) if(end - start > 2)
@ -1311,7 +1315,7 @@ namespace agg
// Invert polygon, set orientation flag, and skip all end_poly // Invert polygon, set orientation flag, and skip all end_poly
invert_polygon(start, end); invert_polygon(start, end);
unsigned cmd; unsigned cmd;
while(end < m_vertices.total_vertices() && while(end < m_vertices.total_vertices() &&
is_end_poly(cmd = m_vertices.command(end))) is_end_poly(cmd = m_vertices.command(end)))
{ {
m_vertices.modify_command(end++, set_orientation(cmd, orientation)); m_vertices.modify_command(end++, set_orientation(cmd, orientation));
@ -1322,8 +1326,8 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
unsigned path_base<VC>::arrange_orientations(unsigned start, unsigned path_base<VC>::arrange_orientations(unsigned start,
path_flags_e orientation) path_flags_e orientation)
{ {
if(orientation != path_flags_none) if(orientation != path_flags_none)
@ -1342,7 +1346,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation) void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation)
{ {
if(orientation != path_flags_none) if(orientation != path_flags_none)
@ -1356,7 +1360,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::flip_x(double x1, double x2) void path_base<VC>::flip_x(double x1, double x2)
{ {
unsigned i; unsigned i;
@ -1372,7 +1376,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::flip_y(double y1, double y2) void path_base<VC>::flip_y(double y1, double y2)
{ {
unsigned i; unsigned i;
@ -1388,7 +1392,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::translate(double dx, double dy, unsigned path_id) void path_base<VC>::translate(double dx, double dy, unsigned path_id)
{ {
unsigned num_ver = m_vertices.total_vertices(); unsigned num_ver = m_vertices.total_vertices();
@ -1407,7 +1411,7 @@ namespace agg
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class VC> template<class VC>
void path_base<VC>::translate_all_paths(double dx, double dy) void path_base<VC>::translate_all_paths(double dx, double dy)
{ {
unsigned idx; unsigned idx;
@ -1440,8 +1444,8 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd) void add_vertex(double x, double y, unsigned cmd)
{ {
m_vertices.push_back(vertex_type(value_type(x), m_vertices.push_back(vertex_type(value_type(x),
value_type(y), value_type(y),
int8u(cmd))); int8u(cmd)));
} }
@ -1474,8 +1478,8 @@ namespace agg
unsigned last_command() const unsigned last_command() const
{ {
return m_vertices.size() ? return m_vertices.size() ?
m_vertices[m_vertices.size() - 1].cmd : m_vertices[m_vertices.size() - 1].cmd :
path_cmd_stop; path_cmd_stop;
} }
@ -1545,11 +1549,11 @@ namespace agg
// Example of declarations path_storage with std::vector as a container // Example of declarations path_storage with std::vector as a container
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
//#include <vector> //#include <vector>
//namespace agg //namespace agg
//{ //{
// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > path_storage; // typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > path_storage;
//} //}
#endif #endif

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -35,7 +35,7 @@ namespace agg
}; };
//--------------------------------------------------------------blender_base //--------------------------------------------------------------blender_base
template<class ColorT, class Order = void> template<class ColorT, class Order = void>
struct blender_base struct blender_base
{ {
typedef ColorT color_type; typedef ColorT color_type;
@ -47,14 +47,14 @@ namespace agg
if (cover > cover_none) if (cover > cover_none)
{ {
rgba c( rgba c(
color_type::to_double(r), color_type::to_double(r),
color_type::to_double(g), color_type::to_double(g),
color_type::to_double(b), color_type::to_double(b),
color_type::to_double(a)); color_type::to_double(a));
if (cover < cover_full) if (cover < cover_full)
{ {
double x = double(cover) / cover_full; double x = static_cast<double>(cover) / static_cast<double>(cover_full);
c.r *= x; c.r *= x;
c.g *= x; c.g *= x;
c.b *= x; c.b *= x;
@ -69,10 +69,10 @@ namespace agg
static rgba get(const value_type* p, cover_type cover = cover_full) static rgba get(const value_type* p, cover_type cover = cover_full)
{ {
return get( return get(
p[order_type::R], p[order_type::R],
p[order_type::G], p[order_type::G],
p[order_type::B], p[order_type::B],
p[order_type::A], p[order_type::A],
cover); cover);
} }

View file

@ -24,6 +24,7 @@
#ifndef AGG_PIXFMT_RGBA_INCLUDED #ifndef AGG_PIXFMT_RGBA_INCLUDED
#define AGG_PIXFMT_RGBA_INCLUDED #define AGG_PIXFMT_RGBA_INCLUDED
#include <mapnik/config.hpp>
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>
#include "agg_basics.h" #include "agg_basics.h"
@ -3166,6 +3167,10 @@ private:
extern template struct MAPNIK_DECL comp_op_rgba_hue<agg::rgba8, agg::order_rgba>;
extern template struct MAPNIK_DECL comp_op_rgba_saturation<agg::rgba8, agg::order_rgba>;
extern template struct MAPNIK_DECL comp_op_rgba_color<agg::rgba8, agg::order_rgba>;
extern template struct MAPNIK_DECL comp_op_rgba_value<agg::rgba8, agg::order_rgba>;
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
typedef blender_rgba<rgba8, order_rgba> blender_rgba32; //----blender_rgba32 typedef blender_rgba<rgba8, order_rgba> blender_rgba32; //----blender_rgba32

View file

@ -2,8 +2,8 @@
// Anti-Grain Geometry - Version 2.4 // Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// //
// Permission to copy, use, modify, sell and distribute this software // Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies. // is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied // This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose. // warranty, and with no claim as to its suitability for any purpose.
// //
@ -24,7 +24,7 @@ namespace agg
{ {
poly_max_coord = (1 << 30) - 1 //----poly_max_coord poly_max_coord = (1 << 30) - 1 //----poly_max_coord
}; };
//------------------------------------------------------------ras_conv_int //------------------------------------------------------------ras_conv_int
struct ras_conv_int struct ras_conv_int
{ {
@ -35,7 +35,7 @@ namespace agg
} }
static int xi(int v) { return v; } static int xi(int v) { return v; }
static int yi(int v) { return v; } static int yi(int v) { return v; }
static int upscale(double v) { return iround(v * poly_subpixel_scale); } static int upscale(double v) { return iround(v * static_cast<double>(poly_subpixel_scale)); }
static int downscale(int v) { return v; } static int downscale(int v) { return v; }
}; };
@ -49,9 +49,9 @@ namespace agg
} }
static int xi(int v) { return v; } static int xi(int v) { return v; }
static int yi(int v) { return v; } static int yi(int v) { return v; }
static int upscale(double v) static int upscale(double v)
{ {
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale); return saturation<poly_max_coord>::iround(v * static_cast<double>(poly_subpixel_scale));
} }
static int downscale(int v) { return v; } static int downscale(int v) { return v; }
}; };
@ -66,7 +66,7 @@ namespace agg
} }
static int xi(int v) { return v * 3; } static int xi(int v) { return v * 3; }
static int yi(int v) { return v; } static int yi(int v) { return v; }
static int upscale(double v) { return iround(v * poly_subpixel_scale); } static int upscale(double v) { return iround(v * static_cast<double>(poly_subpixel_scale)); }
static int downscale(int v) { return v; } static int downscale(int v) { return v; }
}; };
@ -78,10 +78,10 @@ namespace agg
{ {
return a * b / c; return a * b / c;
} }
static int xi(double v) { return iround(v * poly_subpixel_scale); } static int xi(double v) { return iround(v * static_cast<double>(poly_subpixel_scale)); }
static int yi(double v) { return iround(v * poly_subpixel_scale); } static int yi(double v) { return iround(v * static_cast<double>(poly_subpixel_scale)); }
static double upscale(double v) { return v; } static double upscale(double v) { return v; }
static double downscale(int v) { return v / double(poly_subpixel_scale); } static double downscale(int v) { return v / static_cast<double>(poly_subpixel_scale); }
}; };
//--------------------------------------------------------ras_conv_dbl_3x //--------------------------------------------------------ras_conv_dbl_3x
@ -92,10 +92,10 @@ namespace agg
{ {
return a * b / c; return a * b / c;
} }
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); } static int xi(double v) { return iround(v * static_cast<double>(poly_subpixel_scale) * 3); }
static int yi(double v) { return iround(v * poly_subpixel_scale); } static int yi(double v) { return iround(v * static_cast<double>(poly_subpixel_scale)); }
static double upscale(double v) { return v; } static double upscale(double v) { return v; }
static double downscale(int v) { return v / double(poly_subpixel_scale); } static double downscale(int v) { return v / static_cast<double>(poly_subpixel_scale); }
}; };
@ -111,12 +111,12 @@ namespace agg
typedef rect_base<coord_type> rect_type; typedef rect_base<coord_type> rect_type;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
rasterizer_sl_clip() : rasterizer_sl_clip() :
m_clip_box(0,0,0,0), m_clip_box(0,0,0,0),
m_x1(0), m_x1(0),
m_y1(0), m_y1(0),
m_f1(0), m_f1(0),
m_clipping(false) m_clipping(false)
{} {}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -145,8 +145,8 @@ namespace agg
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class Rasterizer> template<class Rasterizer>
AGG_INLINE void line_clip_y(Rasterizer& ras, AGG_INLINE void line_clip_y(Rasterizer& ras,
coord_type x1, coord_type y1, coord_type x1, coord_type y1,
coord_type x2, coord_type y2, coord_type x2, coord_type y2,
unsigned f1, unsigned f2) const unsigned f1, unsigned f2) const
{ {
f1 &= 10; f1 &= 10;
@ -154,7 +154,7 @@ namespace agg
if((f1 | f2) == 0) if((f1 | f2) == 0)
{ {
// Fully visible // Fully visible
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2)); ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
} }
else else
{ {
@ -192,8 +192,8 @@ namespace agg
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
ty2 = m_clip_box.y2; ty2 = m_clip_box.y2;
} }
ras.line(Conv::xi(tx1), Conv::yi(ty1), ras.line(Conv::xi(tx1), Conv::yi(ty1),
Conv::xi(tx2), Conv::yi(ty2)); Conv::xi(tx2), Conv::yi(ty2));
} }
} }
@ -288,8 +288,8 @@ namespace agg
} }
else else
{ {
ras.line(Conv::xi(m_x1), Conv::yi(m_y1), ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
Conv::xi(x2), Conv::yi(y2)); Conv::xi(x2), Conv::yi(y2));
} }
m_x1 = x2; m_x1 = x2;
m_y1 = y2; m_y1 = y2;
@ -321,10 +321,10 @@ namespace agg
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; } void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
template<class Rasterizer> template<class Rasterizer>
void line_to(Rasterizer& ras, coord_type x2, coord_type y2) void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
{ {
ras.line(m_x1, m_y1, x2, y2); ras.line(m_x1, m_y1, x2, y2);
m_x1 = x2; m_x1 = x2;
m_y1 = y2; m_y1 = y2;
} }

View file

@ -1305,7 +1305,7 @@ namespace agg
for(i = 0; i < aa_scale; i++) for(i = 0; i < aa_scale; i++)
{ {
m_gamma[i] = value_type( m_gamma[i] = value_type(
uround(gamma_function(double(i) / aa_mask) * aa_mask)); uround(gamma_function(static_cast<double>(i) / static_cast<double>(aa_mask)) * aa_mask));
} }
} }

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