diff --git a/.gitignore b/.gitignore index fe40dfa29..7080486b4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ tests/data/sqlite/*index demo/c++/cairo-demo.pdf demo/c++/cairo-demo.png demo/c++/cairo-demo256.png +demo/c++/cairo-demo.svg demo/c++/demo.tif demo/c++/demo.jpg demo/c++/demo.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a61da5f6..564c9b295 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,40 +9,76 @@ For a complete change history, see the git log. ## Mapnik 2.1.0 -Not yet released +Released Aug 23, 2012 -- Added support for overriding fill, stroke, and opacity for svg markers using marker properties +(Packaged from a25aac8) + +- Feature-level compositing (comp-op) for all symbolizers (except building) in AGG and Cairo renderers (#1409) + +- Style-level compositing (comp-op) (#1409) and style-level opacity for AGG renderer (#314) + +- New experimental framework for image manipulation called `image-filters` to allow things to be done across entire layer canvas like burring (#1412) + +- Support for recoloring stroke, fill, and opacity of SVG files (#1410 / #659) + +- Support for data-driven transform expressions (#664) + +- New support for offsetting geometries / parallel lines in line_symbolizer (#927/#1269) + +- New support for clipping geometries - now default enabled on all symbolizers (#1116) + +- Framework for chainable geometry transformations (called `vertex_converters`) so that you can do things like clip, smooth, and offset at the same time (#927) + +- WKT parsing now is more robust and supports multi-geometries (#745) + +- New support for outputting WKT/WKB/GeoJSON/SVG from mapnik.Geometry objects (#1411) + +- New experimental python datasource plugin (#1337) + +- New experimental geojson datasource plugin using in-memory rtree indexing (#1413) + +- Cairo rendering is now much more similiar to AGG rendering as cairo backend now supports `scale_factor` (#1280) and other fixed have landed (#1343, #1233, #1344, #1242, #687, #737, #1006, #1071) + +- mapnik::Feature objects and datasource plugins now use a `Context` to store attribute schemas to reduce the memory footprint of features (#834) + +- Added Stroke `miterlimit` (#786) + +- Python: exposed Map `background_image` (and aliased `background` to `background_color`) + +- Python: exposed BuildingSymbolizer + +- Support in the CSV plugin for reading JSON encoded geometries (#1392) + +- Increased grid encoding performance (#1315) - Added support for setting opacity dynamically on images in polygon pattern and markers symbolizers -- Added support for filtering on a features geometry type, either `point`, `linestring`, 'polygon`, +- Added support for filtering on a features geometry type, either `point`, `linestring`, `polygon`, or `collection` using the expression keyword of `[mapnik::geometry_type]` (#546) - MarkersSymbolizer width and height moved to expressions (#1102) -- Added style-level 'opacity' (#314) - -- PostGIS: Added 'simplify_geometries' option - will trigger ST_Simplify on geometries before returning to Mapnik (#1179) +- PostGIS: Added `simplify_geometries` option - will trigger ST_Simplify on geometries before returning to Mapnik (#1179) - Improved error feedback for invalid values passed to map.query_point - Fixed rendering of thin svg lines (#1129) -- Improved logging/debugging system with release logs and file redirection (#937 and partially #986, #467) +- Improved logging/debugging system with release logs and file redirection (https://github.com/mapnik/mapnik/wiki/Runtime-Logging) (#937 and partially #986, #467) - GDAL: allow setting nodata value on the fly (will override value if nodata is set in data) (#1161) - GDAL: respect nodata for paletted/colormapped images (#1160) -- PostGIS: Added a new option called 'autodetect_key_field' (by default false) that if true will - trigger autodetection of a given tables' primary key allowing for feature.id() to represent - globally unique ids. This option has no effect if the user has not manually supplied the 'key_field' option. (#804) +- PostGIS: Added a new option called `autodetect_key_field` (by default false) that if true will + trigger autodetection of the table primary key allowing for feature.id() to represent + globally unique ids. This option has no effect if the user has not manually supplied the `key_field` option. (#804) - Cairo: Add full rendering support for markers to match AGG renderer functionality (#1071) - Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentionally radii) (#1134) -- Added 'ignore-placement` attribute to markers-symbolizer (#1135) +- Added `ignore-placement` attribute to markers-symbolizer (#1135) - Removed PointDatasource - use more robust MemoryDatasource instead (#1032) @@ -58,6 +94,8 @@ Not yet released - Added support for justify-alignment=auto. This is the new default. (#1125) +- Added support for grouped rendering using the `group-by` layer option: https://github.com/mapnik/mapnik/wiki/Grouped-rendering + ## Mapnik 2.0.2 @@ -106,7 +144,7 @@ Released April 10, 2012 - Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentially radii) (#1134) -- Added 'ignore-placement` attribute to markers-symbolizer (#1135) +- Added `ignore-placement` attribute to markers-symbolizer (#1135) - Removed svn_revision info from mapnik-config and python bindings as git is now used @@ -135,7 +173,7 @@ Released September 26, 2011 - Add support for png quantization using fixed palettes (#843) -- Add AlsoFilter functionality - http://trac.mapnik.org/wiki/AlsoFilter +- Add AlsoFilter functionality - https://github.com/mapnik/mapnik/wiki/AlsoFilter - SQLite Plugin: optimize i/o using shared cache and no mutexes (#797) @@ -156,13 +194,13 @@ Released September 26, 2011 from a file that files directory is used. And a custom value can still be passed as an argument to load_map_from_string(). -- Added python function 'render_grid' to allow conversion of grid buffer to python object containing list of grid +- Added python function `render_grid` to allow conversion of grid buffer to python object containing list of grid pixels, list of keys, and a and dictionary of feature attributes. - Added new rendering backend, grid_renderer, that collects the attributes of rendered features and burns their ids into a grid buffer. -- Added optional 'maximum-extent' parameter to map object. If set will be used, instead of combined +- Added optional `maximum-extent` parameter to map object. If set will be used, instead of combined layer extents, for return value of map.zoom_all(). Useful in cases where the combined layer extents cannot possibly be projected into the map srs or the user wishes to control map bounds without modifying the extents of each layer. @@ -175,9 +213,9 @@ Released September 26, 2011 - Added support for drawing only first matching rule using filter-mode="first" in Style (#706) -- Added support to PointSymbolizer ('ignore_placement') for skipping adding placed points to collision detector (#564) +- Added support to PointSymbolizer (`ignore_placement`) for skipping adding placed points to collision detector (#564) -- Added ability to register fonts within XML using Map level 'font_directory' parameter (#168) +- Added ability to register fonts within XML using Map level `font-directory` parameter (#168) - TextSymbolizer: Change text_convert to text_transform to better match css naming (r2211) @@ -185,8 +223,8 @@ Released September 26, 2011 - Upgraded to the latest proj4 string literal for EPSG:4326 (WGS84) as global default projection (#333) -- Added 'mapnik_version_from_string()' function in python bindings to easily convert string representation - of version number to the integer format used in 'mapnik/version.hpp'. e.g. '0.7.1' --> 701. +- Added `mapnik_version_from_string()` function in python bindings to easily convert string representation + of version number to the integer format used in `mapnik/version.hpp`. e.g. `0.7.1` --> `701`. - Added xinclude (http://www.w3.org/TR/xinclude/) support to libxml2-based xml parser (oldtopos) (#567) @@ -194,7 +232,7 @@ Released September 26, 2011 - Added support for setting global alignment of polygon pattern fills (#203) -- Added support for choosing OGR layer by index number using 'layer_by_index' parameter (r1904) +- Added support for choosing OGR layer by index number using `layer_by_index` parameter (r1904) - Added support for fractional halo widths (using FT Stroker) (#93) @@ -224,7 +262,7 @@ Released Oct 18, 2011 (Packaged from bc5cabeb6a) -- Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes) +- Added forward compatibility for Mapnik 2.0 XML syntax (https://github.com/mapnik/mapnik/wiki/Mapnik2/Changes) - Build fixes to ensure boost_threads are not used unless THREADING=multi build option is used @@ -256,7 +294,7 @@ Released Oct 18, 2011 - Various fixes to sqlite, ogr, and occi driver backported from trunk. -- Ensured that '\n' triggers linebreaks in text rendering (#584) +- Ensured that `\n` triggers linebreaks in text rendering (#584) - Support for boost filesystem v3 @@ -275,13 +313,13 @@ Released March 23, 2010 - XML: Save map buffer_size when serializing map. -- SCons: Added new build options 'PRIORITIZE_LINKING' and 'LINK_PRIORITY'. The first is a boolean (default True) +- SCons: Added new build options `PRIORITIZE_LINKING` and `LINK_PRIORITY`. The first is a boolean (default True) of whether to use the new sorting implementation that gives explcit preference to custom or local paths during compile and linking that will affect builds when duplicate libraries and include directories are on the system. LINK_PRIORITY defaults to prioritizing internal sources of the mapnik source folder, then local/user installed libraries over system libraries, but the option can be customized. Sorting not only ensures that compiling and linking will more likely match the desired libraries but also gives more likelyhood to avoid - the scenario where libraries are linked that don't match the includes libmapnik compiled against. + the scenario where libraries are linked that don`t match the includes libmapnik compiled against. - XML: Fixed behavior of PolygonPatternSymbolizer and LinePatternSymbolizer whereby width, height, and type of images is actually allowed to be optionally ommitted ([#508](https://github.com/mapnik/mapnik/issues/508)). This was added in r1543 but @@ -321,26 +359,26 @@ Released January, 19 2010 * Use the gdaladdo utility to add overviews to existing GDAL datasets -- PostGIS: Added an optional 'geometry_table' parameter. The 'geometry_table' used by Mapnik to look up - metadata in the geometry_columns and calculate extents (when the 'geometry_field' and 'srid' parameters - are not supplied). If 'geometry_table' is not specified Mapnik will attempt to determine the name of the - table to query based on parsing the 'table' parameter, which may fail for complex queries with more than - one 'from' keyword. Using this parameter should allow for existing metadata and table indexes to be used - while opening the door to much more complicated subqueries being passed to the 'table' parameter without +- PostGIS: Added an optional `geometry_table` parameter. The `geometry_table` used by Mapnik to look up + metadata in the geometry_columns and calculate extents (when the `geometry_field` and `srid` parameters + are not supplied). If `geometry_table` is not specified Mapnik will attempt to determine the name of the + table to query based on parsing the `table` parameter, which may fail for complex queries with more than + one `from` keyword. Using this parameter should allow for existing metadata and table indexes to be used + while opening the door to much more complicated subqueries being passed to the `table` parameter without failing (#260, #426). -- PostGIS Plugin: Added optional 'geometry_field' and 'srid' parameters. If specified these will allow +- PostGIS Plugin: Added optional `geometry_field` and `srid` parameters. If specified these will allow Mapnik to skip several queries to try to determine these values dynamically, and can be helpful to avoid possible query failures during metadata lookup with complex subqueries as discussed in #260 and #436, but - also solvable by specifying the 'geometry_table' parameter. (r1300,#376) + also solvable by specifying the `geometry_table` parameter. (r1300,#376) -- PostGIS: Added an optional 'extent_from_subquery' parameter that when true (while the 'extent' parameter is - not provided and 'estimate_extent' is false) will direct Mapnik to calculate the extent upon the exact table - or sql provided in the 'table' parameter. If a sub-select is used for the table parameter then this will, +- PostGIS: Added an optional `extent_from_subquery` parameter that when true (while the `extent` parameter is + not provided and `estimate_extent` is false) will direct Mapnik to calculate the extent upon the exact table + or sql provided in the `table` parameter. If a sub-select is used for the table parameter then this will, in cases where the subquery limits results, provide a faster and more accurate layer extent. It will have - no effect if the 'table' parameter is simply an existing table. This parameter is false by default. (#456) + no effect if the `table` parameter is simply an existing table. This parameter is false by default. (#456) -- PostGIS Plugin: Added '!bbox!' token substitution ability in sql query string. This opens the door for various +- PostGIS Plugin: Added `!bbox!` token substitution ability in sql query string. This opens the door for various complex queries that may aggregate geometries to be kept fast by allowing proper placement of the bbox query to be used by indexes. (#415) @@ -356,7 +394,7 @@ Released January, 19 2010 (Select * from table where geom && !bbox!) as map -- PostGIS Plugin: Added 'scale_denominator' substitution ability in sql query string (#415/#465) +- PostGIS Plugin: Added `scale_denominator` substitution ability in sql query string (#415/#465) * Pass the scale_denominator token inside a subquery like: !scale_denominator! @@ -364,7 +402,7 @@ Released January, 19 2010 - PostGIS Plugin: Added support for quoted table names (r1454) (#393) -- PostGIS: Add a 'persist_connection' option (default true), that when false will release +- PostGIS: Add a `persist_connection` option (default true), that when false will release the idle psql connection after datasource goes out of scope (r1337) (#433,#434) - PostGIS: Added support for BigInt (int8) postgres type (384) @@ -385,19 +423,19 @@ Released January, 19 2010 - PNG: Added support for semi-transparency in png256 output (#477,#202) -- PolygonSymbolizer: Added 'gamma' attribute to allow for dilation of polygon edges - a solution +- PolygonSymbolizer: Added `gamma` attribute to allow for dilation of polygon edges - a solution to gap artifacts or "ghost lines" between adjacent polygons and allows for slight sharpening of the edges of non overlapping polygons. Accepts any values but 0-1 is the recommended range. -- TextSymbolizer: Large set of new attributes: 'text_transform', 'line_spacing', 'character_spacing', - 'wrap_character', 'wrap_before', 'horizontal_alignment', 'justify_alignment', and 'opacity'. +- TextSymbolizer: Large set of new attributes: `text_transform`, `line_spacing`, `character_spacing`, + `wrap_character`, `wrap_before`, `horizontal_alignment`, `justify_alignment`, and `opacity`. * More details at changesets: r1254 and r1341 -- SheildSymbolizer: Added special new attributes: 'unlock_image', 'VERTEX' placement, 'no_text' and many - attributes previously only supported in the TextSymbolizer: 'allow_overlap', 'vertical_alignment', - 'horizontal_alignment', 'justify_alignment', 'wrap_width', 'wrap_character', 'wrap_before', 'text_transform', - 'line_spacing', 'character_spacing', and 'opacity'. +- SheildSymbolizer: Added special new attributes: `unlock_image`, `VERTEX` placement, `no_text` and many + attributes previously only supported in the TextSymbolizer: `allow_overlap`, `vertical_alignment`, + `horizontal_alignment`, `justify_alignment`, `wrap_width`, `wrap_character`, `wrap_before`, `text_transform`, + `line_spacing`, `character_spacing`, and `opacity`. * More details at changeset r1341 @@ -405,42 +443,42 @@ Released January, 19 2010 - XML: Fixed memory leak in libxml2 implementation (#473) -- XML: Added function to serialize map to string, called 'mapnik.save_map_to_string()' (#396) +- XML: Added function to serialize map to string, called `mapnik.save_map_to_string()` (#396) -- XML: Added parameter to called 'minimum_version' to allow for enforcing the minimum Mapnik version +- XML: Added parameter to called `minimum_version` to allow for enforcing the minimum Mapnik version needed for XML features used in the mapfiles. Uses Major.Minor.Point syntax, for example would throw an error if the user is running Mapnik less than 0.6.1. -- XML: Added support for relative paths when using entities and 'mapnik.load_map_from_string()' (#440) +- XML: Added support for relative paths when using entities and `mapnik.load_map_from_string()` (#440) - XML: Made width and height optional for symbolizers using images (r1543) - XML: Ensured that default values for layers are not serialized in save_map() (r1366) -- XML: Added missing serialization of PointSymbolizer 'opacity' and 'allow_overlap' attributes (r1358) +- XML: Added missing serialization of PointSymbolizer `opacity` and `allow_overlap` attributes (r1358) - XML: Default text vertical_alignment now dependent on dy (#485, r1527) -- Python: Exposed ability to write to Cairo formats using 'mapnik.render_to_file()' and without pycairo (#381) +- Python: Exposed ability to write to Cairo formats using `mapnik.render_to_file()` and without pycairo (#381) - Python: Fixed potential crash if pycairo support is enabled but python-cairo module is missing (#392) -- Python: Added 'mapnik.has_pycairo()' function to test for pycairo support (r1278) (#284) +- Python: Added `mapnik.has_pycairo()` function to test for pycairo support (r1278) (#284) -- Python: Added 'mapnik.register_plugins()' and 'mapnik.register_fonts()' functions (r1256) +- Python: Added `mapnik.register_plugins()` and `mapnik.register_fonts()` functions (r1256) - Python: Pickling support for point_symbolizer (r1295) (#345) - Python: Ensured mapnik::config_errors now throw RuntimeError exception instead of UserWarning exception (#442) -- Filters: Added support for '!=' as an alias to '<>' for not-equals filters (avoids <>) (r1326) (#427) +- Filters: Added support for `!=` as an alias to `<>` for not-equals filters (avoids <>) (r1326) (#427) - SCons: Improved boost auto-detection (r1255,r1279) - SCons: Fixed support for JOBS=N and FAST=True to enable faster compiling (r1440) - SCons: Ensured that -h or --help will properly print help on custom Mapnik options before a user - has been able to properly run 'configure'. (r1514) + has been able to properly run `configure`. (r1514) - SCons: Added ability to link to custom icu library name using ICU_LIB_NAME (r1414) @@ -455,7 +493,7 @@ Released July 14, 2009 (Packaged from r1247/353ff576c7) -- Plugins: expose list of registered plugins as a 'plugin_names()' method of DatasourceCache (r1180) +- Plugins: expose list of registered plugins as a `plugin_names()` method of DatasourceCache (r1180) - XML: Fixed serialization and parsing bugs related to handling of integers and Enums (#328,#353) @@ -495,13 +533,13 @@ Released July 14, 2009 - Python: Pickling support for raster_symbolizer (r1154) (#345) -- Python: Added 'mapnik.has_cairo()' function to test for cairo support (r1152) (#284) +- Python: Added `mapnik.has_cairo()` function to test for cairo support (r1152) (#284) - Python: Exposed dash_array get method (r1151) (#317) - Python: Pickling support for Coord objects (#345) -- GDAL Plugin: Added an experimental option to open files in 'shared mode' (r1143) +- GDAL Plugin: Added an experimental option to open files in `shared mode` (r1143) - Python: Exposed RasterSymbolizer options in Python (r1139) @@ -513,13 +551,13 @@ Released July 14, 2009 - XML: Ensured relative paths in XML are interpreted relative to XML file location (r1124) (#326) -- XML: Added ability to serialize all default symbolizer values by passing third argument to save_map(m,'file.xml',True)(r1117) (#327) +- XML: Added ability to serialize all default symbolizer values by passing third argument to save_map(m,`file.xml`,True)(r1117) (#327) - Core: Added support for alpha transparency when writing to png256 (patch from Marcin Rudowski) (#202) - SCons: Ensured ABI compatibility information is embedded in libmapnik.dylib on Mac OS X (#322) -- SCons: Ensured that the full 'install_name' path would be added to libmapnik.dylib on Mac OS X (#374) +- SCons: Ensured that the full `install_name` path would be added to libmapnik.dylib on Mac OS X (#374) - Tests: Added testing framework in Python using nose (r1101-r1105) @@ -544,7 +582,7 @@ Released April 1, 2009 - OGCServer Fixed axis-ordering for WMS 1.3.0 request (r1051) (#241) -- Plugins: Added option to all plugins to support using a 'base' path argument (r1042) +- Plugins: Added option to all plugins to support using a `base` path argument (r1042) - Symbolizers: RasterSymbolizer now support composing modes for hillshading (r1027) @@ -565,7 +603,7 @@ Released April 1, 2009 - Plugins: PostGIS plugin now accepts multi-line queries (r862) - Filter parsing: Allow numbers in the filter field name. - This allows for shapefiles with columns like '1970'. + This allows for shapefiles with columns like `1970`. - Plugins: Added OGR driver for reading all OGR supported formats (kunitoki) (r836) (#170) @@ -587,7 +625,7 @@ Released April 1, 2009 - Core: Transformation is now skipped if srs values match exactly (r777) -- Symbolizers: 'min_distance' now honored for POINT placement using Text Symbolizer (r771) +- Symbolizers: `min_distance` now honored for POINT placement using Text Symbolizer (r771) - Plugins: PostGIS plugin now accepts a geometry_field,record_limit, cursor_size options (r769,r872) diff --git a/INSTALL.md b/INSTALL.md index d525be56a..c9e46de45 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -15,9 +15,9 @@ If you need to uninstall do: For more details see the 'Building' Section below. -Platform specific install guides at http://trac.mapnik.org/wiki/MapnikInstallation +Platform specific install guides at https://github.com/mapnik/mapnik/wiki/Mapnik-Installation -For troubleshooting help see http://trac.mapnik.org/wiki/InstallationTroubleshooting +For troubleshooting help see https://github.com/mapnik/mapnik/wiki/InstallationTroubleshooting ## Depends @@ -26,7 +26,7 @@ Mapnik is cross platform and runs on Linux, Mac OSX, Solaris, *BSD, and Windows. The build system should work for all posix/unix systems but for windows see: - http://trac.mapnik.org/wiki/BuildingOnWindows + https://github.com/mapnik/mapnik/wiki/BuildingOnWindows Build dependencies are: @@ -74,7 +74,7 @@ Optional dependencies: Instructions for installing many of these dependencies on various platforms can be found at the Mapnik Community Wiki -(http://trac.mapnik.org/wiki/MapnikInstallation). +(https://github.com/mapnik/mapnik/wiki/Mapnik-Installation). @@ -124,7 +124,7 @@ If you want to see configure options do: For more details on all the options see: - http://trac.mapnik.org/wiki/UsingScons + https://github.com/mapnik/mapnik/wiki/UsingScons ## Testing Installation @@ -155,11 +155,11 @@ For further tests see the `tests` folder within the Mapnik source code. ### Users -Visit http://trac.mapnik.org/wiki/LearningMapnik for basic tutorials on making maps with Mapnik using the Python bindings. +Visit https://github.com/mapnik/mapnik/wiki/LearningMapnik for basic tutorials on making maps with Mapnik using the Python bindings. ### Developers -Visit http://trac.mapnik.org/#DevelopersCorner for resources for getting involved with Mapnik development. +Read docs/contributing.markdown for resources for getting involved with Mapnik development. ## Mapnik Community @@ -168,22 +168,7 @@ Visit http://trac.mapnik.org/#DevelopersCorner for resources for getting involve Mapnik has an active community of talented users and developers making amazing maps. -If you are looking for further help on installation or usage and you can't -find what you are looking for from searching the users list archives -(http://lists.berlios.de/pipermail/mapnik-users/) or the trac wiki -(http://trac.mapnik.org/), feel free to join the Mapnik community and -introduce yourself. +Please feel free to subscribe to the community list and post on both +usage and development topics: http://mapnik.org/contact/ -You can get involved by: - - * Subscribing to the mapnik-users list: - - http://lists.berlios.de/mailman/listinfo/mapnik-users - - * Subscribing to the mapnik-developers list: - - http://lists.berlios.de/mailman/listinfo/mapnik-devel - - * Joining the #mapnik channel on irc://irc.freenode.net/mapnik - - * Signing up as a user or contributor at http://www.ohloh.net/p/mapnik/ +You can also get involved by joining the #mapnik channel on irc://irc.freenode.net/mapnik diff --git a/Makefile b/Makefile index 9ed95ef70..58b999acc 100755 --- a/Makefile +++ b/Makefile @@ -1,21 +1,24 @@ all: mapnik install: - @python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1 install + @python scons/scons.py --config=cache --implicit-cache --max-drift=1 install mapnik: - @python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1 + @python scons/scons.py --config=cache --implicit-cache --max-drift=1 clean: - python scons/scons.py -c --config=cache --implicit-deps-unchanged --max-drift=1 + @python scons/scons.py -c --config=cache --implicit-cache --max-drift=1 + @if test -e ".sconsign.dblite"; then rm ".sconsign.dblite"; fi -reset: +distclean: if test -e ".sconf_temp/"; then rm -r ".sconf_temp/"; fi if test -e ".sconsign.dblite"; then rm ".sconsign.dblite"; fi if test -e "config.cache"; then rm "config.cache"; fi +reset: distclean + uninstall: - python scons/scons.py --config=cache --implicit-deps-unchanged --max-drift=1 uninstall + python scons/scons.py --config=cache --implicit-cache --max-drift=1 uninstall test: @echo "*** Running visual tests..." @@ -27,6 +30,10 @@ test: @echo "*** Running python tests..." @python tests/run_tests.py -q +demo: + @echo "*** Running rundemo.cpp…" + cd demo/c++; ./rundemo `mapnik-config --prefix`/lib/mapnik + pep8: # https://gist.github.com/1903033 # gsed on osx @@ -43,4 +50,4 @@ render: nik2img.py $${FILE} /tmp/$$(basename $${FILE}).png; \ done -.PHONY: clean reset uninstall test install +.PHONY: clean reset uninstall test install demo diff --git a/SConstruct b/SConstruct index af5fba195..1eef0d683 100644 --- a/SConstruct +++ b/SConstruct @@ -32,10 +32,8 @@ try: except: HAS_DISTUTILS = False -if platform.uname()[4] == 'ppc64': - LIBDIR_SCHEMA='lib64' -else: - LIBDIR_SCHEMA='lib' +LIBDIR_SCHEMA_DEFAULT='lib' +severities = ['debug', 'warn', 'error', 'none'] py3 = None @@ -57,17 +55,17 @@ DEFAULT_LINK_PRIORITY = ['internal','other','frameworks','user','system'] pretty_dep_names = { - 'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: http://trac.mapnik.org/wiki/OCCI', - 'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: http://trac.mapnik.org/wiki/GDAL', - 'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: http://trac.mapnik.org/wiki/OGR', - 'geos_c':'GEOS Simple Geometry Specification C Library | configured with GEOS_LIB & GEOS_INCLUDE | more info: http://trac.mapnik.org/wiki/GEOS', + 'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki//OCCI', + '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', + 'geos_c':'GEOS Simple Geometry Specification C Library | configured with GEOS_LIB & GEOS_INCLUDE | more info: https://github.com/mapnik/mapnik/wiki//GEOS', 'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', 'cairomm':'Cairomm C++ bindings to Cairo library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', 'cairomm-version':'Cairomm version is too old (so cairo renderer will not be built), you need at least %s' % CAIROMM_MIN_VERSION, 'pycairo':'Python bindings to Cairo 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/', - 'pg':'Postgres C Library requiered for PostGIS plugin | configure with pg_config program | more info: http://trac.mapnik.org/wiki/PostGIS', - 'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: http://trac.mapnik.org/wiki/SQLite', + 'pg':'Postgres C Library requiered for PostGIS plugin | configure with pg_config program | 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', 'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES', 'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES', 'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES', @@ -82,8 +80,8 @@ pretty_dep_names = { 'gdal-config':'gdal-config program | try setting GDAL_CONFIG SCons option', 'geos-config':'geos-config program | try setting GEOS_CONFIG SCons option', 'freetype-config':'freetype-config program | try setting FREETYPE_CONFIG SCons option', - 'osm':'more info: http://trac.mapnik.org/wiki/OsmPlugin', - 'curl':'libcurl is required for the "osm" plugin - more info: http://trac.mapnik.org/wiki/OsmPlugin', + 'osm':'more info: https://github.com/mapnik/mapnik/wiki//OsmPlugin', + 'curl':'libcurl is required for the "osm" plugin - more info: https://github.com/mapnik/mapnik/wiki//OsmPlugin', '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)', 'pgsql2sqlite_rtree':'The pgsql2sqlite program requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)' @@ -142,7 +140,7 @@ def call(cmd, silent=False): if not stderr: return stdin.strip() elif not silent: - color_print(1,'Problem encounted with SCons scripts, please post bug report to: http://trac.mapnik.org\nError was: %s' % stderr) + color_print(1,'Problem encounted with SCons scripts, please post bug report to: https://github.com/mapnik/mapnik/issues \nError was: %s' % stderr) def strip_first(string,find,replace=''): if string.startswith(find): @@ -248,7 +246,7 @@ def pretty_dep(dep): if pretty: return '%s (%s)' % (dep,pretty) elif 'boost' in dep: - return '%s (%s)' % (dep,'more info see: http://trac.mapnik.org/wiki/MapnikInstallation & http://www.boost.org') + return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki//MapnikInstallation & http://www.boost.org') return dep @@ -288,6 +286,7 @@ opts.AddVariables( # Install Variables ('PREFIX', 'The install path "prefix"', '/usr/local'), + ('LIBDIR_SCHEMA', 'The library sub-directory appended to the "prefix", sometimes lib64 on 64bit linux systems', LIBDIR_SCHEMA_DEFAULT), ('PYTHON_PREFIX','Custom install path "prefix" for python bindings (default of no prefix)',''), ('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/'), ('PATH', 'A custom path (or multiple paths divided by ":") to append to the $PATH env to prioritize usage of command line programs (if multiple are present on the system)', ''), @@ -308,27 +307,29 @@ opts.AddVariables( ('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'), ('XML2_CONFIG', 'The path to the xml2-config executable.', 'xml2-config'), PathVariable('ICU_INCLUDES', 'Search path for ICU include files', '/usr/include', PathVariable.PathAccept), - PathVariable('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), ('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc'), PathVariable('HB_INCLUDES', 'Search path for HarfBuzz include files', '/usr/include', PathVariable.PathAccept), - PathVariable('HB_LIBS','Search path for HarfBuzz include files','/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('HB_LIBS','Search path for HarfBuzz include files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), ('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc'), PathVariable('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include', PathVariable.PathAccept), - PathVariable('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('PNG_LIBS','Search path for libpng library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), + PathVariable('LTDL_INCLUDES', 'Search path for libltdl (part of libtool) include files', '/usr/include', PathVariable.PathAccept), + PathVariable('LTDL_LIBS','Search path for libltdl (ltdl.h) library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), BoolVariable('JPEG', 'Build Mapnik with JPEG read and write support', 'True'), PathVariable('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include', PathVariable.PathAccept), - PathVariable('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), PathVariable('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include', PathVariable.PathAccept), - PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), - PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include', PathVariable.PathAccept), - PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), + PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/include', PathVariable.PathAccept), + PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), ('PKG_CONFIG_PATH', 'Use this path to point pkg-config to .pc files instead of the PKG_CONFIG_PATH environment setting',''), # Variables affecting rendering back-ends BoolVariable('RENDERING_STATS', 'Output rendering statistics during style processing', 'False'), - BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'), + #BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'), # Variables for optional dependencies ('GEOS_CONFIG', 'The path to the geos-config executable.', 'geos-config'), @@ -340,16 +341,16 @@ opts.AddVariables( ('GDAL_CONFIG', 'The path to the gdal-config executable for finding gdal and ogr details.', 'gdal-config'), ('PG_CONFIG', 'The path to the pg_config executable.', 'pg_config'), PathVariable('OCCI_INCLUDES', 'Search path for OCCI include files', '/usr/lib/oracle/10.2.0.3/client/include', PathVariable.PathAccept), - PathVariable('OCCI_LIBS', 'Search path for OCCI library files', '/usr/lib/oracle/10.2.0.3/client/'+ LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('OCCI_LIBS', 'Search path for OCCI library files', '/usr/lib/oracle/10.2.0.3/client/'+ LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), PathVariable('SQLITE_INCLUDES', 'Search path for SQLITE include files', '/usr/include/', PathVariable.PathAccept), - PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), PathVariable('RASTERLITE_INCLUDES', 'Search path for RASTERLITE include files', '/usr/include/', PathVariable.PathAccept), - PathVariable('RASTERLITE_LIBS', 'Search path for RASTERLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), + PathVariable('RASTERLITE_LIBS', 'Search path for RASTERLITE library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept), # Variables for logging and statistics BoolVariable('ENABLE_LOG', 'Enable logging, which is enabled by default when building in *debug*', 'False'), BoolVariable('ENABLE_STATS', 'Enable global statistics during map processing', 'False'), - ('DEFAULT_LOG_SEVERITY', 'The default severity of the logger (eg. "info", "debug", "warn", "error", "fatal", "none")', 'error'), + ('DEFAULT_LOG_SEVERITY', 'The default severity of the logger (eg. ' + ', '.join(severities), 'error'), # Other variables BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'), @@ -429,7 +430,7 @@ pickle_store = [# Scons internal variables 'CAIROMM_LIBPATHS', 'CAIROMM_LINKFLAGS', 'CAIROMM_CPPPATHS', - 'SVG_RENDERER', + #'SVG_RENDERER', 'SQLITE_LINKFLAGS', 'BOOST_LIB_VERSION_FROM_HEADER' ] @@ -661,7 +662,7 @@ def FindBoost(context, prefixes, thread_flag): prefixes.insert(0,os.path.dirname(os.path.normpath(env['BOOST_INCLUDES']))) prefixes.insert(0,os.path.dirname(os.path.normpath(env['BOOST_LIBS']))) for searchDir in prefixes: - libItems = glob(os.path.join(searchDir, LIBDIR_SCHEMA, '%s*.*' % search_lib)) + libItems = glob(os.path.join(searchDir, env['LIBDIR_SCHEMA'], '%s*.*' % search_lib)) if not libItems: libItems = glob(os.path.join(searchDir, 'lib/%s*.*' % search_lib)) incItems = glob(os.path.join(searchDir, 'include/boost*/')) @@ -680,7 +681,7 @@ def FindBoost(context, prefixes, thread_flag): msg += '\n *libs found: %s' % BOOST_LIB_DIR env['BOOST_LIBS'] = BOOST_LIB_DIR else: - env['BOOST_LIBS'] = '/usr/' + LIBDIR_SCHEMA + env['BOOST_LIBS'] = '/usr/' + env['LIBDIR_SCHEMA'] msg += '\n *using default boost lib dir: %s' % env['BOOST_LIBS'] if BOOST_INCLUDE_DIR: @@ -962,7 +963,6 @@ if not preconfigured: env['LIBMAPNIK_LIBS'] = [] env['LIBMAPNIK_CPPATHS'] = [] env['LIBMAPNIK_CXXFLAGS'] = [] - env['LIBDIR_SCHEMA'] = LIBDIR_SCHEMA env['PLUGINS'] = PLUGINS env['EXTRA_FREETYPE_LIBS'] = [] env['SQLITE_LINKFLAGS'] = [] @@ -1061,7 +1061,7 @@ if not preconfigured: # Adding the required prerequisite library directories to the include path for # compiling and the library path for linking, respectively. - for required in ('PNG', 'JPEG', 'TIFF','PROJ','ICU', 'SQLITE'): + for required in ('PNG', 'JPEG', 'TIFF','PROJ','ICU', 'SQLITE', 'LTDL'): inc_path = env['%s_INCLUDES' % required] lib_path = env['%s_LIBS' % required] env.AppendUnique(CPPPATH = os.path.realpath(inc_path)) @@ -1250,6 +1250,10 @@ if not preconfigured: env.PrependUnique(LIBPATH = '#src', delete_existing=True) if env['PGSQL2SQLITE']: + if 'sqlite3' not in env['LIBS']: + env.AppendUnique(LIBS='sqlite3') + env.AppendUnique(CPPPATH = os.path.realpath(env['SQLITE_INCLUDES'])) + env.AppendUnique(LIBPATH = os.path.realpath(env['SQLITE_LIBS'])) if not conf.sqlite_has_rtree(): env['SKIPPED_DEPS'].append('pgsql2sqlite_rtree') env['PGSQL2SQLITE'] = False @@ -1396,11 +1400,6 @@ if not preconfigured: color_print(1,'Could not find required header files for boost python') env['MISSING_DEPS'].append('boost python') - if not conf.CheckLibWithHeader(libs=[env['BOOST_PYTHON_LIB'],'python%s' % env['PYTHON_VERSION']], header='boost/python/detail/config.hpp', language='C++'): - color_print(1, 'Could not find library "%s" for boost python bindings' % env['BOOST_PYTHON_LIB']) - # failing on launchpad, so let's make it a warning for now - #env['MISSING_DEPS'].append('boost python') - if env['CAIRO']: if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('pycairo'): env['HAS_PYCAIRO'] = True @@ -1424,7 +1423,7 @@ if not preconfigured: color_print(4," $ sudo python scons/scons.py install") color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h") color_print(4,'\nTo view overall SCons help options:\n $ python scons/scons.py --help-options or -H\n') - color_print(4,'More info: http://trac.mapnik.org/wiki/MapnikInstallation') + color_print(4,'More info: https://github.com/mapnik/mapnik/wiki//MapnikInstallation') if not HELP_REQUESTED: Exit(1) else: @@ -1450,7 +1449,7 @@ if not preconfigured: # fetch the mapnik version header in order to set the # ABI version used to build libmapnik.so on linux in src/build.py abi = conf.GetMapnikLibVersion() - abi_fallback = "2.0.1-pre" + abi_fallback = "2.2.0-pre" if not abi: color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback) abi = abi_fallback @@ -1483,7 +1482,6 @@ if not preconfigured: ndebug_flags = '-DNDEBUG' # Enable logging in debug mode (always) and release mode (when specified) - severities = ['info', 'debug', 'warn', 'error', 'fatal', 'none'] if env['DEFAULT_LOG_SEVERITY']: if env['DEFAULT_LOG_SEVERITY'] not in severities: severities_list = ', '.join(["'%s'" % s for s in severities]) @@ -1667,11 +1665,6 @@ if not HELP_REQUESTED: SetOption('implicit_cache', 1) SetOption('max_drift', 1) - else: - # Set the cache mode to 'force' unless requested, avoiding hidden caching of Scons 'opts' in '.sconsign.dblite' - # This allows for a SCONS_LOCAL_CONFIG, if present, to be used as the primary means of storing paths to successful build dependencies - SetCacheMode('force') - if env['JOBS'] > 1: SetOption("num_jobs", env['JOBS']) @@ -1682,6 +1675,9 @@ if not HELP_REQUESTED: # Build the core library SConscript('src/build.py') + # Install headers + SConscript('include/build.py') + # Build the requested and able-to-be-compiled input plug-ins GDAL_BUILT = False OGR_BUILT = False @@ -1704,7 +1700,6 @@ if not HELP_REQUESTED: create_uninstall_target(env, env['MAPNIK_LIB_DIR_DEST'], False) create_uninstall_target(env, env['MAPNIK_INPUT_PLUGINS_DEST'] , False) - create_uninstall_target(env, env['MAPNIK_INPUT_PLUGINS_DEST'] , False) # before installing plugins, wipe out any previously # installed plugins that we are no longer building @@ -1713,27 +1708,28 @@ if not HELP_REQUESTED: if plugin not in env['REQUESTED_PLUGINS']: plugin_path = os.path.join(env['MAPNIK_INPUT_PLUGINS_DEST'],'%s.input' % plugin) if os.path.exists(plugin_path): - color_print(1,"Notice: removing out of date plugin: '%s'" % plugin_path) + color_print(3,"Notice: removing out of date plugin: '%s'" % plugin_path) os.unlink(plugin_path) # Build the c++ rundemo app if requested if env['DEMO']: SConscript('demo/c++/build.py') - # Build the pgsql2psqlite app if requested - if env['PGSQL2SQLITE']: - SConscript('utils/pgsql2sqlite/build.py') - # Build shapeindex and remove its dependency from the LIBS if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']: SConscript('utils/shapeindex/build.py') + # Build the pgsql2psqlite app if requested + if env['PGSQL2SQLITE']: + SConscript('utils/pgsql2sqlite/build.py') + + SConscript('utils/svg2png/build.py') + # devtools not ready for public #SConscript('utils/ogrindex/build.py') - SConscript('utils/svg2png/build.py') env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND']) else : - color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' won't be available") + color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' and other command line programs will not be available") # Build the Python bindings if 'python' in env['BINDINGS']: @@ -1752,7 +1748,8 @@ if not HELP_REQUESTED: # not ready for release SConscript('tests/cpp_tests/build.py') - # not ready for release + # not currently maintained + # https://github.com/mapnik/mapnik/issues/1438 #if env['SVG_RENDERER']: # SConscript('tests/cpp_tests/svg_renderer_tests/build.py') @@ -1765,3 +1762,8 @@ if not HELP_REQUESTED: # if requested, build the sample input plugins if env['SAMPLE_INPUT_PLUGINS']: SConscript('plugins/input/templates/helloworld/build.py') + elif 'install' in COMMAND_LINE_TARGETS: + plugin_path = os.path.join(env['MAPNIK_INPUT_PLUGINS_DEST'],'hello.input') + if os.path.exists(plugin_path): + color_print(3,"Notice: removing out of date plugin: '%s'" % plugin_path) + os.unlink(plugin_path) diff --git a/bindings/python/build.py b/bindings/python/build.py index 646b2eeaf..2a83607bf 100644 --- a/bindings/python/build.py +++ b/bindings/python/build.py @@ -17,7 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# $Id$ +# import os, re, sys, glob from subprocess import Popen, PIPE @@ -65,7 +65,7 @@ if env['PLATFORM'] == 'Darwin': # 3) the below will directly link _mapnik.so to a python version # 4) _mapnik.so must link to the same python lib as boost_python.dylib otherwise # python will Abort with a Version Mismatch error. - # See http://trac.mapnik.org/ticket/453 for the seeds of a better approach + # See https://github.com/mapnik/mapnik/issues/453 for the seeds of a better approach # for now we offer control over method of direct linking... # The default below is to link against the python dylib in the form of #/path/to/Python.framework/Python instead of -lpython @@ -86,7 +86,7 @@ if env['PLATFORM'] == 'Darwin': # /System/Library/Frameworks/Python.framework/Python/Versions/ # or # /Library/Frameworks/Python.framework/Python/Versions/ - # See: http://trac.mapnik.org/ticket/380 + # See: https://github.com/mapnik/mapnik/issues/380 link_prefix = env['PYTHON_SYS_PREFIX'] if '.framework' in link_prefix: python_link_flag = '-F%s -framework Python -Z' % os.path.dirname(link_prefix.split('.')[0]) @@ -143,8 +143,14 @@ try: os.chmod('mapnik/paths.py',0666) except: pass -# install the core mapnik python files, including '__init__.py' +# install the shared object beside the module directory +sources = glob.glob('*.cpp') + +py_env = env.Clone() +py_env.Append(CPPPATH = env['PYTHON_INCLUDES']) + if 'install' in COMMAND_LINE_TARGETS: + # install the core mapnik python files, including '__init__.py' init_files = glob.glob('mapnik/*.py') if 'mapnik/paths.py' in init_files: init_files.remove('mapnik/paths.py') @@ -154,8 +160,7 @@ if 'install' in COMMAND_LINE_TARGETS: init_mapnik2 = env.Install(target_path_deprecated, 'mapnik2/__init__.py') env.Alias(target='install', source=init_mapnik2) -# fix perms and install the custom generated 'paths.py' -if 'install' in COMMAND_LINE_TARGETS: + # fix perms and install the custom generated 'paths.py' targetp = os.path.join(target_path,'paths.py') env.Alias("install", targetp) # use env.Command rather than env.Install @@ -166,22 +171,16 @@ if 'install' in COMMAND_LINE_TARGETS: Chmod("$TARGET", 0644), ]) +if 'uninstall' not in COMMAND_LINE_TARGETS: + if env['HAS_CAIRO']: + py_env.Append(CPPPATH = env['CAIROMM_CPPPATHS']) + py_env.Append(CXXFLAGS = '-DHAVE_CAIRO') + if env['PLATFORM'] == 'Darwin': + py_env.Append(LIBS=env['CAIROMM_LINKFLAGS']) -# install the shared object beside the module directory -sources = glob.glob('*.cpp') - -py_env = env.Clone() -py_env.Append(CPPPATH = env['PYTHON_INCLUDES']) - -if env['HAS_CAIRO']: - py_env.Append(CPPPATH = env['CAIROMM_CPPPATHS']) - py_env.Append(CXXFLAGS = '-DHAVE_CAIRO') - if env['PLATFORM'] == 'Darwin': - py_env.Append(LIBS=env['CAIROMM_LINKFLAGS']) - -if env['HAS_PYCAIRO']: - py_env.ParseConfig('pkg-config --cflags pycairo') - py_env.Append(CXXFLAGS = '-DHAVE_PYCAIRO') + if env['HAS_PYCAIRO']: + py_env.ParseConfig('pkg-config --cflags pycairo') + py_env.Append(CXXFLAGS = '-DHAVE_PYCAIRO') libraries.append('boost_thread%s' % env['BOOST_APPEND']) _mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags) @@ -193,7 +192,7 @@ if env['PLATFORM'] == 'SunOS' and env['PYTHON_IS_64BIT']: cxx_module_path = os.path.join(target_path,'64') else: cxx_module_path = target_path - + if 'uninstall' not in COMMAND_LINE_TARGETS: pymapniklib = env.Install(cxx_module_path,_mapnik) py_env.Alias(target='install',source=pymapniklib) diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index fe09ab34d..06870f3b0 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -54,7 +54,7 @@ def bootstrap_env(): The settings file should be a python file with an 'env' variable that declares a dictionary of key:value pairs to push into the global process environment, if not already set, like: - + env = {'ICU_DATA':'/usr/local/share/icu/'} """ if os.path.exists(os.path.join(os.path.dirname(__file__),'mapnik_settings.py')): @@ -136,18 +136,18 @@ class _Coord(Coord,_injector): def forward(self, projection): """ - Projects the point from the geographic coordinate - space into the cartesian space. The x component is - considered to be longitude, the y component the + Projects the point from the geographic coordinate + space into the cartesian space. The x component is + considered to be longitude, the y component the latitude. - Returns the easting (x) and northing (y) as a + Returns the easting (x) and northing (y) as a coordinate pair. - Example: Project the geographic coordinates of the + Example: Project the geographic coordinates of the city center of Stuttgart into the local - map projection (GK Zone 3/DHDN, EPSG 31467) - >>> p = Projection('+init=epsg:31467') + map projection (GK Zone 3/DHDN, EPSG 31467) + >>> p = Projection('+init=epsg:31467') >>> Coord(9.1, 48.7).forward(p) Coord(3507360.12813,5395719.2749) """ @@ -155,19 +155,19 @@ class _Coord(Coord,_injector): def inverse(self, projection): """ - Projects the point from the cartesian space - into the geographic space. The x component is - considered to be the easting, the y component + Projects the point from the cartesian space + into the geographic space. The x component is + considered to be the easting, the y component to be the northing. - Returns the longitude (x) and latitude (y) as a + Returns the longitude (x) and latitude (y) as a coordinate pair. - Example: Project the cartesian coordinates of the + Example: Project the cartesian coordinates of the city center of Stuttgart in the local map projection (GK Zone 3/DHDN, EPSG 31467) into geographic coordinates: - >>> p = Projection('+init=epsg:31467') + >>> p = Projection('+init=epsg:31467') >>> Coord(3507360.12813,5395719.2749).inverse(p) Coord(9.1, 48.7) """ @@ -175,13 +175,13 @@ class _Coord(Coord,_injector): class _Box2d(Box2d,_injector): """ - Represents a spatial envelope (i.e. bounding box). + Represents a spatial envelope (i.e. bounding box). Following operators are defined for Box2d: Addition: - e1 + e2 is equvalent to e1.expand_to_include(e2) but yields + e1 + e2 is equvalent to e1.expand_to_include(e2) but yields a new envelope instead of modifying e1 Subtraction: @@ -191,7 +191,7 @@ class _Box2d(Box2d,_injector): Multiplication and division change the width and height of the envelope by the given factor without modifying its center.. - That is, e1 * x is equivalent to: + That is, e1 * x is equivalent to: e1.width(x * e1.width()) e1.height(x * e1.height()), except that a new envelope is created instead of modifying e1. @@ -207,8 +207,8 @@ class _Box2d(Box2d,_injector): def forward(self, projection): """ - Projects the envelope from the geographic space - into the cartesian space by projecting its corner + Projects the envelope from the geographic space + into the cartesian space by projecting its corner points. See also: @@ -218,8 +218,8 @@ class _Box2d(Box2d,_injector): def inverse(self, projection): """ - Projects the envelope from the cartesian space - into the geographic space by projecting its corner + Projects the envelope from the cartesian space + into the geographic space by projecting its corner points. See also: @@ -234,7 +234,7 @@ class _Projection(Projection,_injector): def forward(self,obj): """ - Projects the given object (Box2d or Coord) + Projects the given object (Box2d or Coord) from the geographic space into the cartesian space. See also: @@ -245,7 +245,7 @@ class _Projection(Projection,_injector): def inverse(self,obj): """ - Projects the given object (Box2d or Coord) + Projects the given object (Box2d or Coord) from the cartesian space into the geographic space. See also: @@ -326,7 +326,7 @@ def Shapefile(**keywords): encoding -- file encoding (default 'utf-8') >>> from mapnik import Shapefile, Layer - >>> shp = Shapefile(base='/home/mapnik/data',file='world_borders') + >>> shp = Shapefile(base='/home/mapnik/data',file='world_borders') >>> lyr = Layer('Shapefile Layer') >>> lyr.datasource = shp @@ -341,7 +341,7 @@ def PostGIS(**keywords): dbname -- database name to connect to table -- table name or subselect query - *Note: if using subselects for the 'table' value consider also + *Note: if using subselects for the 'table' value consider also passing the 'geometry_field' and 'srid' and 'extent_from_subquery' options and/or specifying the 'geometry_table' option. @@ -400,7 +400,7 @@ def Raster(**keywords): tile_stride -- if an image is in tiles, what's the increment between rows/cols (default 1) >>> from mapnik import Raster, Layer - >>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6) + >>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6) >>> lyr = Layer('Tiff Layer') >>> lyr.datasource = raster @@ -474,7 +474,7 @@ def Ogr(**keywords): encoding -- file encoding (default 'utf-8') >>> from mapnik import Ogr, Layer - >>> datasource = Ogr(base='/home/mapnik/data',file='rivers.geojson',layer='OGRGeoJSON') + >>> datasource = Ogr(base='/home/mapnik/data',file='rivers.geojson',layer='OGRGeoJSON') >>> lyr = Layer('OGR Layer from GeoJSON file') >>> lyr.datasource = datasource @@ -502,7 +502,7 @@ def SQLite(**keywords): use_spatial_index -- boolean, instruct sqlite plugin to use Rtree spatial index (default True) >>> from mapnik import SQLite, Layer - >>> sqlite = SQLite(base='/home/mapnik/data',file='osm.db',table='osm',extent='-20037508,-19929239,20037508,19929239') + >>> sqlite = SQLite(base='/home/mapnik/data',file='osm.db',table='osm',extent='-20037508,-19929239,20037508,19929239') >>> lyr = Layer('SQLite Layer') >>> lyr.datasource = sqlite @@ -522,7 +522,7 @@ def Rasterlite(**keywords): extent -- manually specified data extent (comma delimited string, default None) >>> from mapnik import Rasterlite, Layer - >>> rasterlite = Rasterlite(base='/home/mapnik/data',file='osm.db',table='osm',extent='-20037508,-19929239,20037508,19929239') + >>> rasterlite = Rasterlite(base='/home/mapnik/data',file='osm.db',table='osm',extent='-20037508,-19929239,20037508,19929239') >>> lyr = Layer('Rasterlite Layer') >>> lyr.datasource = rasterlite @@ -542,7 +542,7 @@ def Osm(**keywords): bbox -- data bounding box for fetching data (default None) >>> from mapnik import Osm, Layer - >>> datasource = Osm(file='test.osm') + >>> datasource = Osm(file='test.osm') >>> lyr = Layer('Osm Layer') >>> lyr.datasource = datasource @@ -564,7 +564,7 @@ def Kismet(**keywords): extent -- manually specified data extent (comma delimited string, default None) >>> from mapnik import Kismet, Layer - >>> datasource = Kismet(host='localhost',port=2501,extent='-179,-85,179,85') + >>> datasource = Kismet(host='localhost',port=2501,extent='-179,-85,179,85') >>> lyr = Layer('Kismet Server Layer') >>> lyr.datasource = datasource @@ -582,7 +582,7 @@ def Geos(**keywords): extent -- manually specified data extent (comma delimited string, default None) >>> from mapnik import Geos, Layer - >>> datasource = Geos(wkt='MULTIPOINT(100 100, 50 50, 0 0)') + >>> datasource = Geos(wkt='MULTIPOINT(100 100, 50 50, 0 0)') >>> lyr = Layer('GEOS Layer from WKT string') >>> lyr.datasource = datasource @@ -616,7 +616,7 @@ class PythonDatasource(object): def features(self, query): """Return an iterable which yields instances of Feature for features within the passed query. - + Required arguments: query -- a Query instance specifying the region for which features should be returned """ @@ -659,6 +659,39 @@ class PythonDatasource(object): return itertools.imap(make_it, features, itertools.count(1)) + @classmethod + def wkt_features(cls, keys, features): + """A convenience function to wrap an iterator yielding pairs of WKT format geometry and dictionaries of + key-value pairs into mapnik features. Return this from PythonDatasource.features() passing it a sequence of keys + to appear in the output and an iterator yielding features. + + For example. One might have a features() method in a derived class like the following: + + def features(self, query): + # ... create WKT features feat1 and feat2 + + return mapnik.PythonDatasource.wkt_features( + keys = ( 'name', 'author' ), + features = [ + (feat1, { 'name': 'feat1', 'author': 'alice' }), + (feat2, { 'name': 'feat2', 'author': 'bob' }), + ] + ) + + """ + ctx = Context() + [ctx.push(x) for x in keys] + + def make_it(feat, idx): + f = Feature(ctx, idx) + geom, attrs = feat + f.add_geometries_from_wkt(geom) + for k, v in attrs.iteritems(): + f[k] = v + return f + + return itertools.imap(make_it, features, itertools.count(1)) + class _TextSymbolizer(TextSymbolizer,_injector): @property def text_size(self): @@ -755,6 +788,18 @@ class _TextSymbolizer(TextSymbolizer,_injector): self.format.wrap_char = wrap_char + @property + def wrap_character(self): + warnings.warn("'wrap_character' is deprecated, use format.wrap_character", + DeprecationWarning, 2) + return self.format.wrap_character + + @wrap_char.setter + def wrap_character(self, wrap_character): + warnings.warn("'wrap_char' is deprecated, use format.wrap_character", + DeprecationWarning, 2) + self.format.wrap_character = wrap_character + @property def wrap_before(self): @@ -1072,7 +1117,7 @@ def mapnik_version_from_string(version_string): def register_plugins(path=inputpluginspath): """Register plugins located by specified path""" - DatasourceCache.instance().register_datasources(path) + DatasourceCache.register_datasources(path) def register_fonts(path=fontscollectionpath,valid_extensions=['.ttf','.otf','.ttc','.pfa','.pfb','.ttc','.dfont']): """Recursively register fonts using path argument as base directory""" diff --git a/bindings/python/mapnik_building_symbolizer.cpp b/bindings/python/mapnik_building_symbolizer.cpp new file mode 100644 index 000000000..f8892f167 --- /dev/null +++ b/bindings/python/mapnik_building_symbolizer.cpp @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2012 Artem Pavlenko, Jean-Francois Doyon + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include + +using namespace mapnik; +using mapnik::building_symbolizer; +using mapnik::color; + +void export_building_symbolizer() +{ + using namespace boost::python; + + class_("BuildingSymbolizer", + init<>("Default BuildingSymbolizer")) + .add_property("fill",make_function + (&building_symbolizer::get_fill, + return_value_policy()), + &building_symbolizer::set_fill) + .add_property("fill_opacity", + &building_symbolizer::get_opacity, + &building_symbolizer::set_opacity) + .add_property("height", + make_function(&building_symbolizer::height, + return_value_policy()), + &building_symbolizer::set_height, + "Set/get the building height") + ; + +} diff --git a/bindings/python/mapnik_datasource.cpp b/bindings/python/mapnik_datasource.cpp index ced0a53ee..09e70e1fe 100644 --- a/bindings/python/mapnik_datasource.cpp +++ b/bindings/python/mapnik_datasource.cpp @@ -81,7 +81,7 @@ boost::shared_ptr create_datasource(const dict& d) } } - return mapnik::datasource_cache::create(params, bind); + return mapnik::datasource_cache::instance()->create(params, bind); } boost::python::dict describe(boost::shared_ptr const& ds) diff --git a/bindings/python/mapnik_datasource_cache.cpp b/bindings/python/mapnik_datasource_cache.cpp index c4381837b..5592418e1 100644 --- a/bindings/python/mapnik_datasource_cache.cpp +++ b/bindings/python/mapnik_datasource_cache.cpp @@ -23,25 +23,76 @@ #include #include +namespace { + +using namespace boost::python; + +boost::shared_ptr create_datasource(const dict& d) +{ + bool bind=true; + mapnik::parameters params; + boost::python::list keys=d.keys(); + for (int i=0; i(keys[i]); + object obj = d[key]; + + if (key == "bind") + { + bind = extract(obj)(); + continue; + } + + extract ex0(obj); + extract ex1(obj); + extract ex2(obj); + + if (ex0.check()) + { + params[key] = ex0(); + } + else if (ex1.check()) + { + params[key] = ex1(); + } + else if (ex2.check()) + { + params[key] = ex2(); + } + } + + return mapnik::datasource_cache::instance()->create(params, bind); +} + +void register_datasources(std::string const& path) +{ + mapnik::datasource_cache::instance()->register_datasources(path); +} + +std::vector plugin_names() +{ + return mapnik::datasource_cache::instance()->plugin_names(); +} + +std::string plugin_directories() +{ + return mapnik::datasource_cache::instance()->plugin_directories(); +} + +} + void export_datasource_cache() { using mapnik::datasource_cache; - using mapnik::singleton; - using mapnik::CreateStatic; - using namespace boost::python; - class_,boost::noncopyable>("Singleton",no_init) - .def("instance",&singleton::instance, - return_value_policy()) - .staticmethod("instance") - ; - - class_ >, - boost::noncopyable>("DatasourceCache",no_init) - .def("create",&datasource_cache::create) + class_("DatasourceCache",no_init) + .def("create",&create_datasource) .staticmethod("create") - .def("register_datasources",&datasource_cache::register_datasources) + .def("register_datasources",®ister_datasources) .staticmethod("register_datasources") - .def("plugin_names",&datasource_cache::plugin_names) + .def("plugin_names",&plugin_names) .staticmethod("plugin_names") + .def("plugin_directories",&plugin_directories) + .staticmethod("plugin_directories") ; } diff --git a/bindings/python/mapnik_fontset.cpp b/bindings/python/mapnik_fontset.cpp index b50916229..f467d816f 100644 --- a/bindings/python/mapnik_fontset.cpp +++ b/bindings/python/mapnik_fontset.cpp @@ -30,21 +30,11 @@ using mapnik::font_set; -struct fontset_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const font_set& fs) - { - return boost::python::make_tuple(fs.get_name()); - } -}; - void export_fontset () { using namespace boost::python; class_("FontSet", init<>("default fontset constructor") ) - .def_pickle(fontset_pickle_suite()) .def("add_face_name",&font_set::add_face_name, (arg("name")), "Add a face-name to the fontset.\n" diff --git a/bindings/python/mapnik_gamma_method.cpp b/bindings/python/mapnik_gamma_method.cpp index 8ab0388ae..23b832d6d 100644 --- a/bindings/python/mapnik_gamma_method.cpp +++ b/bindings/python/mapnik_gamma_method.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include diff --git a/bindings/python/mapnik_geometry.cpp b/bindings/python/mapnik_geometry.cpp index 9369af058..17aa11389 100644 --- a/bindings/python/mapnik_geometry.cpp +++ b/bindings/python/mapnik_geometry.cpp @@ -31,12 +31,14 @@ #include #include #include +#include #include #include #if BOOST_VERSION >= 104700 #include #include +#include #endif namespace { @@ -56,30 +58,65 @@ geometry_type const& getitem_impl(path_type & p, int key) void add_wkt_impl(path_type& p, std::string const& wkt) { - bool result = mapnik::from_wkt(wkt , p); - if (!result) throw std::runtime_error("Failed to parse WKT"); + if (!mapnik::from_wkt(wkt , p)) + throw std::runtime_error("Failed to parse WKT"); } -bool add_wkb_impl(path_type& p, std::string const& wkb) +void add_wkb_impl(path_type& p, std::string const& wkb) { - return mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size()); + if (!mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size())) + throw std::runtime_error("Failed to parse WKB"); +} + +void add_geojson_impl(path_type& p, std::string const& json) +{ + if (!mapnik::json::from_geojson(json, p)) + throw std::runtime_error("Failed to parse geojson geometry"); } boost::shared_ptr from_wkt_impl(std::string const& wkt) { boost::shared_ptr paths = boost::make_shared(); - bool result = mapnik::from_wkt(wkt, *paths); - if (!result) throw std::runtime_error("Failed to parse WKT"); + if (!mapnik::from_wkt(wkt, *paths)) + throw std::runtime_error("Failed to parse WKT"); return paths; } boost::shared_ptr from_wkb_impl(std::string const& wkb) { boost::shared_ptr paths = boost::make_shared(); - mapnik::geometry_utils::from_wkb(*paths, wkb.c_str(), wkb.size()); + if (!mapnik::geometry_utils::from_wkb(*paths, wkb.c_str(), wkb.size())) + throw std::runtime_error("Failed to parse WKB"); return paths; } +boost::shared_ptr from_geojson_impl(std::string const& json) +{ + boost::shared_ptr paths = boost::make_shared(); + if (! mapnik::json::from_geojson(json, *paths)) + throw std::runtime_error("Failed to parse geojson geometry"); + return paths; +} + +mapnik::box2d envelope_impl(path_type & p) +{ + mapnik::box2d b; + bool first = true; + BOOST_FOREACH(mapnik::geometry_type const& geom, p) + { + if (first) + { + b = geom.envelope(); + first=false; + } + else + { + b.expand_to_include(geom.envelope()); + } + } + return b; +} + } inline std::string boost_version() @@ -188,6 +225,41 @@ std::string to_geojson( path_type const& geom) return json; } +std::string to_svg( geometry_type const& geom) +{ +#if BOOST_VERSION >= 104700 + std::string svg; // Use Python String directly ? + bool result = mapnik::util::to_svg(svg,geom); + if (!result) + { + throw std::runtime_error("Generate WKT failed"); + } + return svg; +#else + throw std::runtime_error("mapnik::to_wkt() requires at least boost 1.47 while your build was compiled against boost " + + boost_version()); +#endif +} + +/* +// https://github.com/mapnik/mapnik/issues/1437 +std::string to_svg2( path_type const& geom) +{ +#if BOOST_VERSION >= 104700 + std::string svg; // Use Python String directly ? + bool result = mapnik::util::to_svg(svg,geom); + if (!result) + { + throw std::runtime_error("Generate WKT failed"); + } + return svg; +#else + throw std::runtime_error("mapnik::to_svg() requires at least boost 1.47 while your build was compiled against boost " + + boost_version()); +#endif +}*/ + + void export_geometry() { using namespace boost::python; @@ -212,21 +284,27 @@ void export_geometry() .def("type",&geometry_type::type) .def("to_wkb",&to_wkb) .def("to_wkt",&to_wkt) + .def("to_svg",&to_svg) // TODO add other geometry_type methods ; class_, boost::noncopyable>("Path") .def("__getitem__", getitem_impl,return_value_policy()) .def("__len__", &path_type::size) + .def("envelope",envelope_impl) .def("add_wkt",add_wkt_impl) .def("add_wkb",add_wkb_impl) + .def("add_geojson",add_geojson_impl) .def("to_wkt",&to_wkt2) + //.def("to_svg",&to_svg2) .def("to_wkb",&to_wkb2) .def("from_wkt",from_wkt_impl) .def("from_wkb",from_wkb_impl) + .def("from_geojson",from_geojson_impl) .def("to_geojson",to_geojson) .staticmethod("from_wkt") .staticmethod("from_wkb") + .staticmethod("from_geojson") ; } diff --git a/bindings/python/mapnik_grid.cpp b/bindings/python/mapnik_grid.cpp index 87a7ef852..4bff835c8 100644 --- a/bindings/python/mapnik_grid.cpp +++ b/bindings/python/mapnik_grid.cpp @@ -32,7 +32,7 @@ using namespace boost::python; // help compiler see template definitions -static dict (*encode)( mapnik::grid const&, std::string, bool, unsigned int) = mapnik::grid_encode; +static dict (*encode)( mapnik::grid const&, std::string const& , bool, unsigned int) = mapnik::grid_encode; bool painted(mapnik::grid const& grid) { diff --git a/bindings/python/mapnik_grid_view.cpp b/bindings/python/mapnik_grid_view.cpp index 926ee18f6..aa29dda78 100644 --- a/bindings/python/mapnik_grid_view.cpp +++ b/bindings/python/mapnik_grid_view.cpp @@ -34,7 +34,7 @@ using namespace boost::python; // help compiler see template definitions -static dict (*encode)( mapnik::grid_view const&, std::string, bool, unsigned int) = mapnik::grid_encode; +static dict (*encode)( mapnik::grid_view const&, std::string const& , bool, unsigned int) = mapnik::grid_encode; void export_grid_view() { diff --git a/bindings/python/mapnik_inmem_metawriter.cpp b/bindings/python/mapnik_inmem_metawriter.cpp deleted file mode 100644 index 34760f45b..000000000 --- a/bindings/python/mapnik_inmem_metawriter.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// boost -#include -#include -#include - -// mapnik -#include - -using mapnik::metawriter_inmem; -using mapnik::metawriter_inmem_ptr; - -namespace { -std::map::const_iterator -mapnik_value_map_begin(const std::map &m) { - return m.begin(); -} - -std::map::const_iterator -mapnik_value_map_end(const std::map &m) { - return m.end(); -} -} - -void export_inmem_metawriter() { - using namespace boost::python; - - class_ > - ("MapnikProperties", "Retarded.", init<>()) - .def("__iter__", range(&mapnik_value_map_begin, &mapnik_value_map_end)) - ; - - class_ - ("MetaInstance", "Single rendered instance of meta-information.", no_init) - .def_readonly("box", &metawriter_inmem::meta_instance::box) - .def_readonly("properties", &metawriter_inmem::meta_instance::properties) - ; - - class_ - ("MetaWriterInMem", - "Collects meta-information about elements rendered.", - no_init) - .def("__iter__", range(&metawriter_inmem::inst_begin, - &metawriter_inmem::inst_end)) - ; -} diff --git a/bindings/python/mapnik_layer.cpp b/bindings/python/mapnik_layer.cpp index ae99e5971..37cc17e91 100644 --- a/bindings/python/mapnik_layer.cpp +++ b/bindings/python/mapnik_layer.cpp @@ -161,7 +161,7 @@ void export_layer() .add_property("active", &layer::active, &layer::set_active, - "Get/Set whether this layer is active and will be rendered.\n" + "Get/Set whether this layer is active and will be rendered (same as status property).\n" "\n" "Usage:\n" ">>> from mapnik import Layer\n" @@ -173,6 +173,21 @@ void export_layer() "False\n" ) + .add_property("status", + &layer::active, + &layer::set_active, + "Get/Set whether this layer is active and will be rendered.\n" + "\n" + "Usage:\n" + ">>> from mapnik import Layer\n" + ">>> lyr = Layer('My Layer','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')\n" + ">>> lyr.status\n" + "True # Active by default\n" + ">>> lyr.status = False # set False to disable layer rendering\n" + ">>> lyr.status\n" + "False\n" + ) + .add_property("clear_label_cache", &layer::clear_label_cache, &layer::set_clear_label_cache, @@ -304,6 +319,14 @@ void export_layer() ">>> lyr.srs = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over'\n" ) + .add_property("group_by", + make_function(&layer::group_by,return_value_policy()), + &layer::set_group_by, + "Get/Set the optional layer group name.\n" + "\n" + "More details at https://github.com/mapnik/mapnik/wiki/Grouped-rendering:\n" + ) + .add_property("styles", make_function(_styles_,return_value_policy()), "The styles list attached to this layer.\n" diff --git a/bindings/python/mapnik_line_pattern_symbolizer.cpp b/bindings/python/mapnik_line_pattern_symbolizer.cpp index e982edf05..527bd3547 100644 --- a/bindings/python/mapnik_line_pattern_symbolizer.cpp +++ b/bindings/python/mapnik_line_pattern_symbolizer.cpp @@ -37,7 +37,7 @@ using mapnik::parse_path; namespace { using namespace boost::python; -const std::string get_filename(line_pattern_symbolizer const& t) +std::string get_filename(line_pattern_symbolizer const& t) { return path_processor_type::to_string(*t.get_filename()); } @@ -49,17 +49,6 @@ void set_filename(line_pattern_symbolizer & t, std::string const& file_expr) } -struct line_pattern_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const line_pattern_symbolizer& l) - { - std::string filename = path_processor_type::to_string(*l.get_filename()); - // FIXME : Do we need "type" parameter at all ? - return boost::python::make_tuple(filename, guess_type(filename)); - } -}; - void export_line_pattern_symbolizer() { using namespace boost::python; @@ -67,12 +56,23 @@ void export_line_pattern_symbolizer() class_("LinePatternSymbolizer", init ("")) - //.def_pickle(line_pattern_symbolizer_pickle_suite()) .add_property("transform", mapnik::get_svg_transform, mapnik::set_svg_transform) .add_property("filename", &get_filename, &set_filename) + .add_property("comp_op", + &line_pattern_symbolizer::comp_op, + &line_pattern_symbolizer::set_comp_op, + "Set/get the comp-op") + .add_property("clip", + &line_pattern_symbolizer::clip, + &line_pattern_symbolizer::set_clip, + "Set/get the line pattern geometry's clipping status") + .add_property("smooth", + &line_pattern_symbolizer::smooth, + &line_pattern_symbolizer::set_smooth, + "smooth value (0..1.0)") ; } diff --git a/bindings/python/mapnik_line_symbolizer.cpp b/bindings/python/mapnik_line_symbolizer.cpp index e87c52bec..2c36800b7 100644 --- a/bindings/python/mapnik_line_symbolizer.cpp +++ b/bindings/python/mapnik_line_symbolizer.cpp @@ -29,16 +29,6 @@ using mapnik::line_symbolizer; using mapnik::stroke; using mapnik::color; -struct line_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const line_symbolizer& l) - { - return boost::python::make_tuple(l.get_stroke()); - } - -}; - void export_line_symbolizer() { using namespace boost::python; @@ -50,7 +40,6 @@ void export_line_symbolizer() init<>("Default LineSymbolizer - 1px solid black")) .def(init("TODO")) .def(init()) - .def_pickle(line_symbolizer_pickle_suite()) .add_property("rasterizer", &line_symbolizer::get_rasterizer, &line_symbolizer::set_rasterizer, @@ -59,6 +48,18 @@ void export_line_symbolizer() (&line_symbolizer::get_stroke, return_value_policy()), &line_symbolizer::set_stroke) + .add_property("offset", + &line_symbolizer::offset, + &line_symbolizer::set_offset, + "offset value") + .add_property("comp_op", + &line_symbolizer::comp_op, + &line_symbolizer::set_comp_op, + "Set/get the comp-op") + .add_property("clip", + &line_symbolizer::clip, + &line_symbolizer::set_clip, + "Set/get the line geometry's clipping status") .add_property("smooth", &line_symbolizer::smooth, &line_symbolizer::set_smooth, diff --git a/bindings/python/mapnik_logger.cpp b/bindings/python/mapnik_logger.cpp index 257c6e510..0f3b30949 100644 --- a/bindings/python/mapnik_logger.cpp +++ b/bindings/python/mapnik_logger.cpp @@ -39,22 +39,14 @@ void export_logger() ; enum_("severity_type") - .value("Info", logger::info) .value("Debug", logger::debug) .value("Warn", logger::warn) .value("Error", logger::error) - .value("Fatal", logger::fatal) .value("None", logger::none) ; class_ >, boost::noncopyable>("logger",no_init) - .def_readonly("Info", logger::info) - .def_readonly("Debug", logger::debug) - .def_readonly("Warn", logger::warn) - .def_readonly("Error", logger::error) - .def_readonly("Fatal", logger::fatal) - .def_readonly("None", logger::none) .def("get_severity", &logger::get_severity) .def("set_severity", &logger::set_severity) .def("get_object_severity", &logger::get_object_severity) diff --git a/bindings/python/mapnik_map.cpp b/bindings/python/mapnik_map.cpp index e2a21e674..ab0b0fd5c 100644 --- a/bindings/python/mapnik_map.cpp +++ b/bindings/python/mapnik_map.cpp @@ -28,9 +28,10 @@ // mapnik #include #include +#include +#include #include -#include -#include +//#include #include "mapnik_enumeration.hpp" using mapnik::color; @@ -39,85 +40,9 @@ using mapnik::box2d; using mapnik::layer; using mapnik::Map; -struct map_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const Map& m) - { - return boost::python::make_tuple(m.width(),m.height(),m.srs()); - } - - static boost::python::tuple - getstate(const Map& m) - { - boost::python::list l; - for (unsigned i=0;ifirst; - const mapnik::feature_type_style & style = it->second; - boost::python::tuple style_pair = boost::python::make_tuple(name,style); - s.append(style_pair); - } - - return boost::python::make_tuple(m.get_current_extent(),m.background(),l,s,m.base_path()); - } - - static void - setstate (Map& m, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 5) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 5-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - box2d ext = extract >(state[0]); - m.zoom_to_box(ext); - if (state[1]) - { - color bg = extract(state[1]); - m.set_background(bg); - } - - boost::python::list l=extract(state[2]); - for (int i=0;i(l[i])); - } - - boost::python::list s=extract(state[3]); - for (int i=0;i(s[i]); - std::string name = extract(style_pair[0]); - mapnik::feature_type_style style = extract(style_pair[1]); - m.insert_style(name, style); - } - - if (state[4]) - { - std::string base_path = extract(state[4]); - m.set_base_path(base_path); - } - } -}; - std::vector& (Map::*layers_nonconst)() = &Map::layers; std::vector const& (Map::*layers_const)() const = &Map::layers; mapnik::parameters& (Map::*params_nonconst)() = &Map::get_extra_parameters; -//boost::optional > const& (Map::*maximum_extent_const)() const = &Map::maximum_extent; mapnik::feature_type_style find_style(mapnik::Map const& m, std::string const& name) { @@ -141,26 +66,6 @@ mapnik::font_set find_fontset(mapnik::Map const& m, std::string const& name) return *fontset; } -bool has_metawriter(mapnik::Map const& m) -{ - if (m.metawriters().size() >=1) - return true; - return false; -} - -// returns empty shared_ptr when the metawriter isn't found, or is -// of the wrong type. empty pointers make it back to Python as a None. -mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) { - mapnik::metawriter_ptr metawriter = m.find_metawriter(name); - mapnik::metawriter_inmem_ptr inmem; - - if (metawriter) { - inmem = boost::dynamic_pointer_cast(metawriter); - } - - return inmem; -} - // TODO - we likely should allow indexing by negative number from python // for now, protect against negative values and kindly throw mapnik::featureset_ptr query_point(mapnik::Map const& m, int index, double x, double y) @@ -184,6 +89,7 @@ mapnik::featureset_ptr query_map_point(mapnik::Map const& m, int index, double x } // deepcopy +/* mapnik::Map map_deepcopy(mapnik::Map & m, boost::python::dict memo) { // FIXME: ignore memo for now @@ -191,6 +97,7 @@ mapnik::Map map_deepcopy(mapnik::Map & m, boost::python::dict memo) mapnik::util::deepcopy(m, result); return result; } +*/ void set_maximum_extent(mapnik::Map & m, boost::optional > const& box) { @@ -240,9 +147,6 @@ void export_map() "'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'\n" )) - .def_pickle(map_pickle_suite() - ) - .def("append_style",&Map::insert_style, (arg("style_name"),arg("style_object")), "Insert a Mapnik Style onto the map by appending it.\n" @@ -310,15 +214,6 @@ void export_map() "\n" ) - .def("has_metawriter", - has_metawriter, - "Check if the Map has any active metawriters\n" - "\n" - "Usage:\n" - ">>> m.has_metawriter()\n" - "False\n" - ) - .def("pan",&Map::pan, (arg("x"),arg("y")), "Set the Map center at a given x,y location\n" @@ -457,39 +352,8 @@ void export_map() ">>> extext = Box2d(-180.0, -90.0, 180.0, 90.0)\n" ">>> m.zoom_to_box(extent)\n" ) - .def("get_metawriter_property", &Map::get_metawriter_property, - (arg("name")), - "Reads a metawriter property.\n" - "These properties are completely user-defined and can be used to" - "create filenames, etc.\n" - "\n" - "Usage:\n" - ">>> map.set_metawriter_property(\"x\", \"10\")\n" - ">>> map.get_metawriter_property(\"x\")\n" - "10\n" - ) - .def("set_metawriter_property", &Map::set_metawriter_property, - (arg("name"),arg("value")), - "Sets a metawriter property.\n" - "These properties are completely user-defined and can be used to" - "create filenames, etc.\n" - "\n" - "Usage:\n" - ">>> map.set_metawriter_property(\"x\", str(x))\n" - ">>> map.set_metawriter_property(\"y\", str(y))\n" - ">>> map.set_metawriter_property(\"z\", str(z))\n" - "\n" - "Use a path like \"[z]/[x]/[y].json\" to create filenames.\n" - ) - .def("find_inmem_metawriter", find_inmem_metawriter, - (arg("name")), - "Gets an inmem metawriter, or None if no such metawriter " - "exists.\n" - "Use this after the map has been rendered to retrieve information " - "about the hit areas rendered on the map.\n" - ) - .def("__deepcopy__",&map_deepcopy) + //.def("__deepcopy__",&map_deepcopy) .add_property("parameters",make_function(params_nonconst,return_value_policy()),"TODO") .add_property("aspect_fix_mode", @@ -506,12 +370,30 @@ void export_map() .add_property("background",make_function (&Map::background,return_value_policy()), &Map::set_background, - "The background color of the map.\n" + "The background color of the map (same as background_color property).\n" "\n" "Usage:\n" ">>> m.background = Color('steelblue')\n" ) + .add_property("background_color",make_function + (&Map::background,return_value_policy()), + &Map::set_background, + "The background color of the map.\n" + "\n" + "Usage:\n" + ">>> m.background_color = Color('steelblue')\n" + ) + + .add_property("background_image",make_function + (&Map::background_image,return_value_policy()), + &Map::set_background_image, + "The optional background image of the map.\n" + "\n" + "Usage:\n" + ">>> m.background_image = '/path/to/image.png'\n" + ) + .add_property("base", make_function(&Map::base_path,return_value_policy()), &Map::set_base_path, diff --git a/bindings/python/mapnik_markers_symbolizer.cpp b/bindings/python/mapnik_markers_symbolizer.cpp index 9eefef2d7..08519976f 100644 --- a/bindings/python/mapnik_markers_symbolizer.cpp +++ b/bindings/python/mapnik_markers_symbolizer.cpp @@ -23,11 +23,13 @@ #include #include +#include #include #include #include #include "mapnik_svg.hpp" #include "mapnik_enumeration.hpp" +#include // for known_svg_prefix_ using mapnik::markers_symbolizer; using mapnik::symbolizer_with_image; @@ -47,45 +49,28 @@ void set_filename(mapnik::markers_symbolizer & symbolizer, std::string const& fi symbolizer.set_filename(parse_path(file_expr)); } +void set_marker_type(mapnik::markers_symbolizer & symbolizer, std::string const& marker_type) +{ + std::string filename; + if (marker_type == "ellipse") + { + filename = mapnik::marker_cache::known_svg_prefix_ + "ellipse"; + } + else if (marker_type == "arrow") + { + filename = mapnik::marker_cache::known_svg_prefix_ + "arrow"; + } + else + { + throw mapnik::value_error("Unknown marker-type: '" + marker_type + "'"); + } + symbolizer.set_filename(parse_path(filename)); } -struct markers_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(markers_symbolizer const& p) - { - std::string filename = path_processor_type::to_string(*p.get_filename()); - return boost::python::make_tuple(filename,mapnik::guess_type(filename)); - } +} - static boost::python::tuple - getstate(markers_symbolizer const& p) - { - return boost::python::make_tuple(p.get_allow_overlap(), - p.get_ignore_placement());//,p.get_opacity()); - } - - static void - setstate (markers_symbolizer& p, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 2) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 2-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - p.set_allow_overlap(extract(state[0])); - p.set_ignore_placement(extract(state[1])); - //p.set_opacity(extract(state[2])); - - } - -}; +// https://github.com/mapnik/mapnik/issues/1367 PyObject* get_fill_opacity_impl(markers_symbolizer & sym) { boost::optional fill_opacity = sym.get_fill_opacity(); @@ -107,10 +92,12 @@ void export_markers_symbolizer() class_("MarkersSymbolizer", init<>("Default Markers Symbolizer - circle")) .def (init("")) - //.def_pickle(markers_symbolizer_pickle_suite()) .add_property("filename", &get_filename, &set_filename) + .add_property("marker_type", + &get_filename, + &set_marker_type) .add_property("allow_overlap", &markers_symbolizer::get_allow_overlap, &markers_symbolizer::set_allow_overlap) @@ -156,5 +143,17 @@ void export_markers_symbolizer() &markers_symbolizer::get_marker_placement, &markers_symbolizer::set_marker_placement, "Set/get the marker placement") + .add_property("comp_op", + &markers_symbolizer::comp_op, + &markers_symbolizer::set_comp_op, + "Set/get the marker comp-op") + .add_property("clip", + &markers_symbolizer::clip, + &markers_symbolizer::set_clip, + "Set/get the marker geometry's clipping status") + .add_property("smooth", + &markers_symbolizer::smooth, + &markers_symbolizer::set_smooth, + "Set/get the marker geometry's smooth value") ; } diff --git a/bindings/python/mapnik_palette.cpp b/bindings/python/mapnik_palette.cpp index 54b0b3146..d21901735 100644 --- a/bindings/python/mapnik_palette.cpp +++ b/bindings/python/mapnik_palette.cpp @@ -27,7 +27,7 @@ //mapnik #include -static boost::shared_ptr make_palette( const std::string& palette, const std::string& format ) +static boost::shared_ptr make_palette( std::string const& palette, std::string const& format ) { mapnik::rgba_palette::palette_type type = mapnik::rgba_palette::PALETTE_RGBA; if (format == "rgb") diff --git a/bindings/python/mapnik_point_symbolizer.cpp b/bindings/python/mapnik_point_symbolizer.cpp index 2ca6c9acb..f979b9e79 100644 --- a/bindings/python/mapnik_point_symbolizer.cpp +++ b/bindings/python/mapnik_point_symbolizer.cpp @@ -38,7 +38,7 @@ using mapnik::parse_path; namespace { using namespace boost::python; -const std::string get_filename(point_symbolizer const& t) +std::string get_filename(point_symbolizer const& t) { return path_processor_type::to_string(*t.get_filename()); } @@ -50,47 +50,6 @@ void set_filename(point_symbolizer & t, std::string const& file_expr) } -struct point_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const point_symbolizer& p) - { - std::string filename = path_processor_type::to_string(*p.get_filename()); - return boost::python::make_tuple(filename,mapnik::guess_type(filename)); - } - - static boost::python::tuple - getstate(const point_symbolizer& p) - { - return boost::python::make_tuple(p.get_allow_overlap(), - p.get_opacity(), - p.get_ignore_placement(), - p.get_point_placement()); - } - - static void - setstate (point_symbolizer& p, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 4) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 4-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - p.set_allow_overlap(extract(state[0])); - p.set_opacity(extract(state[1])); - p.set_ignore_placement(extract(state[2])); - p.set_point_placement(extract(state[3])); - - } - -}; - - void export_point_symbolizer() { using namespace boost::python; @@ -103,7 +62,6 @@ void export_point_symbolizer() class_("PointSymbolizer", init<>("Default Point Symbolizer - 4x4 black square")) .def (init("")) - .def_pickle(point_symbolizer_pickle_suite()) .add_property("filename", &get_filename, &set_filename) @@ -123,5 +81,9 @@ void export_point_symbolizer() .add_property("transform", mapnik::get_svg_transform, mapnik::set_svg_transform) + .add_property("comp_op", + &point_symbolizer::comp_op, + &point_symbolizer::set_comp_op, + "Set/get the comp-op") ; } diff --git a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp index dc155c5f6..4be2f7c41 100644 --- a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp @@ -37,7 +37,7 @@ using mapnik::guess_type; namespace { using namespace boost::python; -const std::string get_filename(polygon_pattern_symbolizer const& t) +std::string get_filename(polygon_pattern_symbolizer const& t) { return path_processor_type::to_string(*t.get_filename()); } @@ -49,41 +49,6 @@ void set_filename(polygon_pattern_symbolizer & t, std::string const& file_expr) } -struct polygon_pattern_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const polygon_pattern_symbolizer& p) - { - std::string filename = path_processor_type::to_string(*p.get_filename()); - return boost::python::make_tuple(filename,guess_type(filename)); - } - - static boost::python::tuple - getstate(const polygon_pattern_symbolizer& p) - { - return boost::python::make_tuple(p.get_alignment(),p.get_gamma(),p.get_gamma_method()); - } - - static void - setstate (polygon_pattern_symbolizer& p, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 3) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 3-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - p.set_alignment(extract(state[0])); - p.set_gamma(extract(state[1])); - p.set_gamma_method(extract(state[2])); - } - -}; - void export_polygon_pattern_symbolizer() { using namespace boost::python; @@ -95,7 +60,6 @@ void export_polygon_pattern_symbolizer() class_("PolygonPatternSymbolizer", init("")) - .def_pickle(polygon_pattern_symbolizer_pickle_suite()) .add_property("alignment", &polygon_pattern_symbolizer::get_alignment, &polygon_pattern_symbolizer::set_alignment, @@ -106,6 +70,9 @@ void export_polygon_pattern_symbolizer() .add_property("filename", &get_filename, &set_filename) + .add_property("opacity", + &polygon_pattern_symbolizer::get_opacity, + &polygon_pattern_symbolizer::set_opacity) .add_property("gamma", &polygon_pattern_symbolizer::get_gamma, &polygon_pattern_symbolizer::set_gamma) @@ -113,5 +80,17 @@ void export_polygon_pattern_symbolizer() &polygon_pattern_symbolizer::get_gamma_method, &polygon_pattern_symbolizer::set_gamma_method, "Set/get the gamma correction method of the polygon") + .add_property("comp_op", + &polygon_pattern_symbolizer::comp_op, + &polygon_pattern_symbolizer::set_comp_op, + "Set/get the pattern comp-op") + .add_property("clip", + &polygon_pattern_symbolizer::clip, + &polygon_pattern_symbolizer::set_clip, + "Set/get the pattern geometry's clipping status") + .add_property("smooth", + &polygon_pattern_symbolizer::smooth, + &polygon_pattern_symbolizer::set_smooth, + "Set/get the pattern geometry's smooth value") ; } diff --git a/bindings/python/mapnik_polygon_symbolizer.cpp b/bindings/python/mapnik_polygon_symbolizer.cpp index 06f35f0d8..218cf5279 100644 --- a/bindings/python/mapnik_polygon_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_symbolizer.cpp @@ -21,47 +21,12 @@ *****************************************************************************/ #include -#include "mapnik_enumeration.hpp" #include using namespace mapnik; using mapnik::polygon_symbolizer; using mapnik::color; -struct polygon_symbolizer_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const polygon_symbolizer& p) - { - return boost::python::make_tuple(p.get_fill()); - } - - static boost::python::tuple - getstate(const polygon_symbolizer& p) - { - return boost::python::make_tuple(p.get_opacity(),p.get_gamma(),p.get_gamma_method()); - } - - static void - setstate (polygon_symbolizer& p, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 3) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 3-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - p.set_opacity(extract(state[0])); - p.set_gamma(extract(state[1])); - p.set_gamma_method(extract(state[2])); - } - -}; - void export_polygon_symbolizer() { using namespace boost::python; @@ -69,7 +34,6 @@ void export_polygon_symbolizer() class_("PolygonSymbolizer", init<>("Default PolygonSymbolizer - solid fill grey")) .def(init("TODO")) - .def_pickle(polygon_symbolizer_pickle_suite()) .add_property("fill",make_function (&polygon_symbolizer::get_fill, return_value_policy()), @@ -84,10 +48,18 @@ void export_polygon_symbolizer() &polygon_symbolizer::get_gamma_method, &polygon_symbolizer::set_gamma_method, "gamma correction method") + .add_property("comp_op", + &polygon_symbolizer::comp_op, + &polygon_symbolizer::set_comp_op, + "Set/get the polygon comp-op") + .add_property("clip", + &polygon_symbolizer::clip, + &polygon_symbolizer::set_clip, + "Set/get the polygon geometry's clipping status") .add_property("smooth", &polygon_symbolizer::smooth, &polygon_symbolizer::set_smooth, - "smooth value (0..1.0)") + "Set/get the polygon geometry's smooth value") ; } diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index f98cec7fa..8c58a09f4 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -57,6 +57,7 @@ void export_point_symbolizer(); void export_line_symbolizer(); void export_line_pattern_symbolizer(); void export_polygon_symbolizer(); +void export_building_symbolizer(); void export_polygon_pattern_symbolizer(); void export_raster_symbolizer(); void export_text_placement(); @@ -66,7 +67,6 @@ void export_projection(); void export_proj_transform(); void export_view_transform(); void export_raster_colorizer(); -void export_inmem_metawriter(); void export_label_collision_detector(); void export_logger(); @@ -205,8 +205,8 @@ void render6(const mapnik::Map& map, PycairoContext* context) void render_tile_to_file(const mapnik::Map& map, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height, - const std::string& file, - const std::string& format) + std::string const& file, + std::string const& format) { mapnik::image_32 image(width,height); render(map,image,1.0,offset_x, offset_y); @@ -214,8 +214,8 @@ void render_tile_to_file(const mapnik::Map& map, } void render_to_file1(const mapnik::Map& map, - const std::string& filename, - const std::string& format) + std::string const& filename, + std::string const& format) { if (format == "pdf" || format == "svg" || format =="ps" || format == "ARGB32" || format == "RGB24") { @@ -233,7 +233,7 @@ void render_to_file1(const mapnik::Map& map, } } -void render_to_file2(const mapnik::Map& map,const std::string& filename) +void render_to_file2(const mapnik::Map& map,std::string const& filename) { std::string format = mapnik::guess_type(filename); if (format == "pdf" || format == "svg" || format =="ps") @@ -253,8 +253,8 @@ void render_to_file2(const mapnik::Map& map,const std::string& filename) } void render_to_file3(const mapnik::Map& map, - const std::string& filename, - const std::string& format, + std::string const& filename, + std::string const& format, double scale_factor = 1.0 ) { @@ -396,6 +396,7 @@ BOOST_PYTHON_MODULE(_mapnik) export_line_symbolizer(); export_line_pattern_symbolizer(); export_polygon_symbolizer(); + export_building_symbolizer(); export_polygon_pattern_symbolizer(); export_raster_symbolizer(); export_text_placement(); @@ -407,7 +408,6 @@ BOOST_PYTHON_MODULE(_mapnik) export_coord(); export_map(); export_raster_colorizer(); - export_inmem_metawriter(); export_label_collision_detector(); export_logger(); @@ -619,6 +619,7 @@ BOOST_PYTHON_MODULE(_mapnik) python_optional(); python_optional(); python_optional >(); + python_optional(); python_optional(); python_optional(); python_optional(); diff --git a/bindings/python/mapnik_query.cpp b/bindings/python/mapnik_query.cpp index cd49ef967..f0041b8c0 100644 --- a/bindings/python/mapnik_query.cpp +++ b/bindings/python/mapnik_query.cpp @@ -32,15 +32,6 @@ using mapnik::box2d; namespace python = boost::python; -struct query_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(query const& q) - { - return boost::python::make_tuple(q.get_bbox(),q.resolution()); - } -}; - struct resolution_to_tuple { static PyObject* convert(query::resolution_type const& x) @@ -64,7 +55,6 @@ void export_query() class_("Query", "a spatial query data object", init,query::resolution_type const&,double>() ) .def(init >()) - .def_pickle(query_pickle_suite()) .add_property("resolution",make_function(&query::resolution, return_value_policy())) .add_property("bbox", make_function(&query::get_bbox, diff --git a/bindings/python/mapnik_raster_symbolizer.cpp b/bindings/python/mapnik_raster_symbolizer.cpp index 3830dd9f1..068503f60 100644 --- a/bindings/python/mapnik_raster_symbolizer.cpp +++ b/bindings/python/mapnik_raster_symbolizer.cpp @@ -29,44 +29,6 @@ using mapnik::raster_symbolizer; -struct raster_symbolizer_pickle_suite : boost::python::pickle_suite -{ - /* - static boost::python::tuple - getinitargs(const raster_symbolizer& r) - { - return boost::python::make_tuple(); - } - */ - - static boost::python::tuple - getstate(raster_symbolizer const& r) - { - return boost::python::make_tuple(r.get_mode(),r.get_scaling_method(),r.get_opacity(),r.get_filter_factor(),r.get_mesh_size()); - } - - static void - setstate (raster_symbolizer & r, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 5) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 5-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - r.set_mode(extract(state[0])); - r.set_scaling_method(extract(state[1])); - r.set_opacity(extract(state[2])); - r.set_filter_factor(extract(state[3])); - r.set_mesh_size(extract(state[4])); - } - -}; - void export_raster_symbolizer() { using namespace boost::python; @@ -74,23 +36,16 @@ void export_raster_symbolizer() class_("RasterSymbolizer", init<>("Default ctor")) - .def_pickle(raster_symbolizer_pickle_suite()) - .add_property("mode", make_function(&raster_symbolizer::get_mode,return_value_policy()), &raster_symbolizer::set_mode, - "Get/Set merging mode.\n" - "Possible values are:\n" - "normal, grain_merge, grain_merge2, multiply,\n" - "multiply2, divide, divide2, screen, and hard_light\n" - "\n" - "Usage:\n" - "\n" - ">>> from mapnik import RasterSymbolizer\n" - ">>> r = RasterSymbolizer()\n" - ">>> r.mode = 'grain_merge2'\n" + "Get/Set merging mode. (deprecated, use comp_op instead)\n" + ) + .add_property("comp_op", + &raster_symbolizer::comp_op, + &raster_symbolizer::set_comp_op, + "Set/get the raster comp-op" ) - .add_property("scaling", &raster_symbolizer::get_scaling_method, &raster_symbolizer::set_scaling_method, diff --git a/bindings/python/mapnik_rule.cpp b/bindings/python/mapnik_rule.cpp index 378e22f10..86d5d3522 100644 --- a/bindings/python/mapnik_rule.cpp +++ b/bindings/python/mapnik_rule.cpp @@ -48,108 +48,6 @@ using mapnik::markers_symbolizer; using mapnik::symbolizer; using mapnik::to_expression_string; -struct pickle_symbolizer : public boost::static_visitor<> -{ -public: - pickle_symbolizer( boost::python::list syms): - syms_(syms) {} - - template - void operator () ( T const& sym ) - { - syms_.append(sym); - } - -private: - boost::python::list syms_; -}; - - -struct extract_symbolizer : public boost::static_visitor<> -{ -public: - extract_symbolizer( rule& r): - r_(r) {} - - template - void operator () ( T const& sym ) - { - r_.append(sym); - } -private: - rule& r_; - -}; - -struct rule_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const rule& r) - { - return boost::python::make_tuple(r.get_name(),r.get_min_scale(),r.get_max_scale()); - } - - static boost::python::tuple - getstate(const rule& r) - { - boost::python::list syms; - - rule::symbolizers::const_iterator begin = r.get_symbolizers().begin(); - rule::symbolizers::const_iterator end = r.get_symbolizers().end(); - pickle_symbolizer serializer( syms ); - std::for_each( begin, end , boost::apply_visitor( serializer )); - - // We serialize filter expressions AST as strings - std::string filter_expr = to_expression_string(*r.get_filter()); - - return boost::python::make_tuple(filter_expr,r.has_else_filter(),r.has_also_filter(),syms); - } - - static void - setstate (rule& r, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 4) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 4-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - if (state[0]) - { - rule dfl; - std::string filter = extract(state[1]); - std::string default_filter = "";//dfl.get_filter()->to_string(); - if ( filter != default_filter) - { - r.set_filter(mapnik::parse_expression(filter,"utf8")); - } - } - - if (state[1]) - { - r.set_else(true); - } - - if (state[2]) - { - r.set_also(true); - } - - boost::python::list syms=extract(state[4]); - extract_symbolizer serializer( r ); - for (int i=0;i(syms[i]); - //boost::apply_visitor( serializer, symbol ); - } - } - -}; - void export_rule() { using namespace boost::python; @@ -171,7 +69,6 @@ void export_rule() class_("Rule",init<>("default constructor")) .def(init >()) - .def_pickle(rule_pickle_suite()) .add_property("name",make_function (&rule::get_name, return_value_policy()), diff --git a/bindings/python/mapnik_scaling_method.cpp b/bindings/python/mapnik_scaling_method.cpp index a5ac926c6..c237a708c 100644 --- a/bindings/python/mapnik_scaling_method.cpp +++ b/bindings/python/mapnik_scaling_method.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include diff --git a/bindings/python/mapnik_shield_symbolizer.cpp b/bindings/python/mapnik_shield_symbolizer.cpp index 10f5957cb..272b5f67d 100644 --- a/bindings/python/mapnik_shield_symbolizer.cpp +++ b/bindings/python/mapnik_shield_symbolizer.cpp @@ -75,7 +75,7 @@ void set_text_displacement(shield_symbolizer & t, boost::python::tuple arg) t.set_displacement(extract(arg[0]),extract(arg[1])); } -const std::string get_filename(shield_symbolizer const& t) +std::string get_filename(shield_symbolizer const& t) { return path_processor_type::to_string(*t.get_filename()); } @@ -96,7 +96,6 @@ void export_shield_symbolizer() unsigned, mapnik::color const&, path_expression_ptr>() ) - //.def_pickle(shield_symbolizer_pickle_suite()) .add_property("allow_overlap", &shield_symbolizer::get_allow_overlap, &shield_symbolizer::set_allow_overlap, @@ -206,5 +205,13 @@ void export_shield_symbolizer() .add_property("transform", mapnik::get_svg_transform, mapnik::set_svg_transform) + .add_property("comp_op", + &shield_symbolizer::comp_op, + &shield_symbolizer::set_comp_op, + "Set/get the comp-op") + .add_property("clip", + &shield_symbolizer::clip, + &shield_symbolizer::set_clip, + "Set/get the shield geometry's clipping status") ; } diff --git a/bindings/python/mapnik_stroke.cpp b/bindings/python/mapnik_stroke.cpp index 1f21071c3..104bb7b69 100644 --- a/bindings/python/mapnik_stroke.cpp +++ b/bindings/python/mapnik_stroke.cpp @@ -32,10 +32,9 @@ using namespace mapnik; namespace { using namespace boost::python; -list get_dashes_list(const stroke& stroke) +list get_dashes_list(stroke const& stroke) { list l; - if (stroke.has_dash()) { mapnik::dash_array const& dash = stroke.get_dash_array(); mapnik::dash_array::const_iterator iter = dash.begin(); @@ -44,67 +43,24 @@ list get_dashes_list(const stroke& stroke) l.append(make_tuple(iter->first, iter->second)); } } - return l; } + +void set_dasharray(stroke & stroke, list const& l) +{ + for (int i=0; i(l[i]); + if (len(dash) == 2) + { + double d1 = extract(dash[0]); + double d2 = extract(dash[1]); + stroke.add_dash(d1,d2); + } + } } -struct stroke_pickle_suite : boost::python::pickle_suite -{ - static boost::python::tuple - getinitargs(const stroke& s) - { - - return boost::python::make_tuple(s.get_color(),s.get_width()); - - } - - static boost::python::tuple - getstate(const stroke& s) - { - boost::python::list dashes = get_dashes_list(s); - return boost::python::make_tuple(s.get_opacity(), - dashes, - s.get_line_cap(), - s.get_line_join(), - s.get_gamma(), - s.get_gamma_method()); - } - - static void - setstate (stroke& s, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 6) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 6-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - s.set_opacity(extract(state[0])); - - if (state[1]) - { - list dashes = extract(state[1]); - for(boost::python::ssize_t i=0; i(dashes[i][0]); - double ds2 = extract(dashes[i][1]); - s.add_dash(ds1,ds2); - } - } - - s.set_line_cap(extract(state[2])); - s.set_line_join(extract(state[3])); - s.set_gamma(extract(state[4])); - s.set_gamma_method(extract(state[5])); - - } - -}; - +} void export_stroke () { @@ -132,7 +88,6 @@ void export_stroke () (arg("color"),arg("width")), "Creates a new stroke object with a specified color and width.\n") ) - .def_pickle(stroke_pickle_suite()) .add_property("color",make_function (&stroke::get_color,return_value_policy()), &stroke::set_color, @@ -159,18 +114,37 @@ void export_stroke () .add_property("line_cap", &stroke::get_line_cap, &stroke::set_line_cap, - "Gets or sets the line cap of this stroke.\n") + "Gets or sets the line cap of this stroke. (alias of linecap)\n") + .add_property("linecap", + &stroke::get_line_cap, + &stroke::set_line_cap, + "Gets or sets the linecap of this stroke.\n") .add_property("line_join", &stroke::get_line_join, &stroke::set_line_join, - "Returns the line join mode of this stroke.\n") - // todo consider providing a single get/set property + "Returns the line join mode of this stroke. (alias of linejoin)\n") + .add_property("linejoin", + &stroke::get_line_join, + &stroke::set_line_join, + "Returns the linejoin mode of this stroke.\n") + .add_property("miterlimit", + &stroke::get_miterlimit, + &stroke::set_miterlimit, + "Returns the miterlimit mode of this stroke.\n") .def("add_dash",&stroke::add_dash, (arg("length"),arg("gap")), "Adds a dash segment to the dash patterns of this stroke.\n") .def("get_dashes", get_dashes_list, "Returns the list of dash segments for this stroke.\n") + .add_property("dasharray", + get_dashes_list, + set_dasharray, + "Gets or sets dasharray string of this stroke. (alternate property to add_dash/get_dashes)\n") .add_property("dash_offset", + &stroke::dash_offset, + &stroke::set_dash_offset, + "Gets or sets dash offset of this stroke. (alias of dashoffet)\n") + .add_property("dashoffset", &stroke::dash_offset, &stroke::set_dash_offset, "Gets or sets dash offset of this stroke.\n") diff --git a/bindings/python/mapnik_style.cpp b/bindings/python/mapnik_style.cpp index c5a70dbad..ff41c84ea 100644 --- a/bindings/python/mapnik_style.cpp +++ b/bindings/python/mapnik_style.cpp @@ -25,51 +25,39 @@ #include // mapnik +#include #include "mapnik_enumeration.hpp" #include +#include // image_filter_grammar +#include // generate_image_filters using mapnik::feature_type_style; using mapnik::rules; using mapnik::rule; -struct style_pickle_suite : boost::python::pickle_suite +std::string get_image_filters(feature_type_style & style) { - static boost::python::tuple - getstate(const feature_type_style& s) + std::string filters_str; + std::back_insert_iterator sink(filters_str); + generate_image_filters(sink, style.image_filters()); + return filters_str; +} + +void set_image_filters(feature_type_style & style, std::string const& filters) +{ + std::string::const_iterator itr = filters.begin(); + std::string::const_iterator end = filters.end(); + mapnik::image_filter_grammar > filter_grammar; + bool result = boost::spirit::qi::phrase_parse(itr,end, + filter_grammar, + boost::spirit::qi::ascii::space, + style.image_filters()); + if (!result || itr!=end) { - boost::python::list rule_list; - - rules::const_iterator it = s.get_rules().begin(); - rules::const_iterator end = s.get_rules().end(); - for (; it != end; ++it) - { - rule_list.append( *it ); - } - - return boost::python::make_tuple(rule_list); + throw mapnik::value_error("failed to parse image-filters: '" + std::string(itr,end) + "'"); } - - static void - setstate (feature_type_style& s, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 1) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 1-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - boost::python::list rules = extract(state[0]); - for (int i=0; i(rules[i])); - } - } - -}; +} void export_style() { @@ -85,9 +73,6 @@ void export_style() ; class_("Style",init<>("default style constructor")) - .def_pickle(style_pickle_suite() - ) - .add_property("rules",make_function (&feature_type_style::get_rules, return_value_policy()), @@ -103,6 +88,18 @@ void export_style() &feature_type_style::get_filter_mode, &feature_type_style::set_filter_mode, "Set/get the filter mode of the style") + .add_property("opacity", + &feature_type_style::get_opacity, + &feature_type_style::set_opacity, + "Set/get the opacity of the style") + .add_property("comp_op", + &feature_type_style::comp_op, + &feature_type_style::set_comp_op, + "Set/get the comp-op (composite operation) of the style") + .add_property("image_filters", + get_image_filters, + set_image_filters, + "Set/get the comp-op (composite operation) of the style") ; } diff --git a/bindings/python/mapnik_svg.hpp b/bindings/python/mapnik_svg.hpp index bb027e63e..418ee0511 100644 --- a/bindings/python/mapnik_svg.hpp +++ b/bindings/python/mapnik_svg.hpp @@ -31,7 +31,7 @@ namespace mapnik { using namespace boost::python; template -const std::string get_svg_transform(T& symbolizer) +std::string get_svg_transform(T& symbolizer) { return symbolizer.get_image_transform_string(); } diff --git a/bindings/python/mapnik_text_placement.cpp b/bindings/python/mapnik_text_placement.cpp index 99ce24f81..25a06707e 100644 --- a/bindings/python/mapnik_text_placement.cpp +++ b/bindings/python/mapnik_text_placement.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -354,6 +354,14 @@ void export_text_placement() make_function(&get_properties, return_value_policy()), &set_properties, "Shortcut for placements.defaults") + .add_property("comp_op", + &text_symbolizer::comp_op, + &text_symbolizer::set_comp_op, + "Set/get the comp-op") + .add_property("clip", + &text_symbolizer::clip, + &text_symbolizer::set_clip, + "Set/get the text geometry's clipping status") ; @@ -390,8 +398,10 @@ void export_text_placement() set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */ ; - class_ + + class_with_converter ("CharProperties") + .def_readwrite_convert("text_transform", &char_properties::text_transform) .def(init()) //Copy constructor .def_readwrite("face_name", &char_properties::face_name) .def_readwrite("fontset", &char_properties::fontset) @@ -400,8 +410,8 @@ void export_text_placement() .def_readwrite("line_spacing", &char_properties::line_spacing) .def_readwrite("text_opacity", &char_properties::text_opacity) .def_readwrite("wrap_char", &char_properties::wrap_char) + .def_readwrite("wrap_character", &char_properties::wrap_char) .def_readwrite("wrap_before", &char_properties::wrap_before) - .def_readwrite("text_transform", &char_properties::text_transform) .def_readwrite("fill", &char_properties::fill) .def_readwrite("halo_fill", &char_properties::halo_fill) .def_readwrite("halo_radius", &char_properties::halo_radius) @@ -476,6 +486,7 @@ void export_text_placement() .def_readwrite_convert("line_spacing", &formatting::format_node::line_spacing) .def_readwrite_convert("text_opacity", &formatting::format_node::text_opacity) .def_readwrite_convert("wrap_char", &formatting::format_node::wrap_char) + .def_readwrite_convert("wrap_character", &formatting::format_node::wrap_char) .def_readwrite_convert("wrap_before", &formatting::format_node::wrap_before) .def_readwrite_convert("text_transform", &formatting::format_node::text_transform) .def_readwrite_convert("fill", &formatting::format_node::fill) @@ -515,6 +526,7 @@ void export_text_placement() .def_readwrite("line_spacing", &formatting::expression_format::line_spacing) .def_readwrite("text_opacity", &formatting::expression_format::text_opacity) .def_readwrite("wrap_char", &formatting::expression_format::wrap_char) + .def_readwrite("wrap_character", &formatting::expression_format::wrap_char) .def_readwrite("wrap_before", &formatting::expression_format::wrap_before) .def_readwrite("fill", &formatting::expression_format::fill) .def_readwrite("halo_fill", &formatting::expression_format::halo_fill) diff --git a/bindings/python/python_grid_utils.cpp b/bindings/python/python_grid_utils.cpp index f0b99f714..9652a4bce 100644 --- a/bindings/python/python_grid_utils.cpp +++ b/bindings/python/python_grid_utils.cpp @@ -233,69 +233,46 @@ void write_features(T const& grid_type, boost::python::dict& feature_data, std::vector const& key_order) { - std::string const& key = grid_type.get_key(); - std::set const& attributes = grid_type.property_names(); typename T::feature_type const& g_features = grid_type.get_grid_features(); - typename T::feature_type::const_iterator feat_itr = g_features.begin(); - typename T::feature_type::const_iterator feat_end = g_features.end(); - bool include_key = (attributes.find(key) != attributes.end()); - for (; feat_itr != feat_end; ++feat_itr) + if (g_features.size() <= 0) { + return; + } + + std::set const& attributes = grid_type.property_names(); + typename T::feature_type::const_iterator feat_end = g_features.end(); + BOOST_FOREACH ( std::string const& key_item, key_order ) + { + if (key_item.empty()) + { + continue; + } + + typename T::feature_type::const_iterator feat_itr = g_features.find(key_item); + if (feat_itr == feat_end) + { + continue; + } + + bool found = false; + boost::python::dict feat; mapnik::feature_ptr feature = feat_itr->second; - boost::optional join_value; - if (key == grid_type.key_name()) + BOOST_FOREACH ( std::string const& attr, attributes ) { - join_value = feat_itr->first; - } - else if (feature->has_key(key)) - { - join_value = feature->get(key).to_string(); - } - - if (join_value) - { - // only serialize features visible in the grid - if(std::find(key_order.begin(), key_order.end(), *join_value) != key_order.end()) { - boost::python::dict feat; - bool found = false; - if (key == grid_type.key_name()) - { - // drop key unless requested - if (include_key) { - found = true; - //TODO - add __id__ as data key? - //feat[key] = *join_value; - } - } - - feature_kv_iterator itr = feature->begin(); - feature_kv_iterator end = feature->end(); - for ( ;itr!=end; ++itr) - { - std::string const& key_name = boost::get<0>(*itr); - if (key_name == key) { - // drop key unless requested - if (include_key) { - found = true; - feat[key_name] = boost::get<1>(*itr); - } - } - else if ( (attributes.find(key_name) != attributes.end()) ) - { - found = true; - feat[key_name] = boost::get<1>(*itr); - } - } - - if (found) - { - feature_data[feat_itr->first] = feat; - } + if (attr == "__id__") + { + feat[attr.c_str()] = feature->id(); + } + else if (feature->has_key(attr)) + { + found = true; + feat[attr.c_str()] = feature->get(attr); } } - else + + if (found) { - MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties"; + feature_data[feat_itr->first] = feat; } } } @@ -342,7 +319,7 @@ void grid_encode_utf(T const& grid_type, } template -boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution) +boost::python::dict grid_encode( T const& grid, std::string const& format, bool add_features, unsigned int resolution) { if (format == "utf") { boost::python::dict json; @@ -357,16 +334,16 @@ boost::python::dict grid_encode( T const& grid, std::string format, bool add_fea } } -template boost::python::dict grid_encode( mapnik::grid const& grid, std::string format, bool add_features, unsigned int resolution); -template boost::python::dict grid_encode( mapnik::grid_view const& grid, std::string format, bool add_features, unsigned int resolution); +template boost::python::dict grid_encode( mapnik::grid const& grid, std::string const& format, bool add_features, unsigned int resolution); +template boost::python::dict grid_encode( mapnik::grid_view const& grid, std::string const& format, bool add_features, unsigned int resolution); /* new approach: key comes from grid object * grid size should be same as the map * encoding, resizing handled as method on grid object * whether features are dumped is determined by argument not 'fields' */ -void render_layer_for_grid(const mapnik::Map& map, - mapnik::grid& grid, +void render_layer_for_grid(mapnik::Map const& map, + mapnik::grid & grid, unsigned layer_idx, // TODO - layer by name or index boost::python::list const& fields) { @@ -379,11 +356,12 @@ void render_layer_for_grid(const mapnik::Map& map, throw std::runtime_error(s.str()); } - // convert python list to std::vector + // convert python list to std::set boost::python::ssize_t num_fields = boost::python::len(fields); for(boost::python::ssize_t i=0; i name(fields[i]); - if (name.check()) { + if (name.check()) + { grid.add_property_name(name()); } else @@ -396,25 +374,18 @@ void render_layer_for_grid(const mapnik::Map& map, // copy property names std::set attributes = grid.property_names(); - std::string const& key = grid.get_key(); - - // if key is special __id__ keyword - if (key == grid.key_name()) + // todo - make this a static constant + std::string known_id_key = "__id__"; + if (attributes.find(known_id_key) != attributes.end()) { - // TODO - should feature.id() be a first class attribute? - - // if __id__ is requested to be dumped out - // remove it so that datasource queries will not break - if (attributes.find(key) != attributes.end()) - { - attributes.erase(key); - } + attributes.erase(known_id_key); } - // if key is not the special __id__ keyword - else if (attributes.find(key) == attributes.end()) + + std::string join_field = grid.get_key(); + if (known_id_key != join_field && + attributes.find(join_field) == attributes.end()) { - // them make sure the datasource query includes this field - attributes.insert(key); + attributes.insert(join_field); } mapnik::grid_renderer ren(map,grid,1.0,0,0); @@ -425,7 +396,7 @@ void render_layer_for_grid(const mapnik::Map& map, /* old, original impl - to be removed after further testing * grid object is created on the fly at potentially reduced size */ -boost::python::dict render_grid(const mapnik::Map& map, +boost::python::dict render_grid(mapnik::Map const& map, unsigned layer_idx, // layer std::string const& key, // key_name unsigned int step, // resolution @@ -447,7 +418,7 @@ boost::python::dict render_grid(const mapnik::Map& map, // TODO - no need to pass step here mapnik::grid grid(grid_width,grid_height,key,step); - // convert python list to std::vector + // convert python list to std::set boost::python::ssize_t num_fields = boost::python::len(fields); for(boost::python::ssize_t i=0; i name(fields[i]); @@ -464,24 +435,18 @@ boost::python::dict render_grid(const mapnik::Map& map, // copy property names std::set attributes = grid.property_names(); - - // if key is special __id__ keyword - if (key == grid.key_name()) + // todo - make this a static constant + std::string known_id_key = "__id__"; + if (attributes.find(known_id_key) != attributes.end()) { - // TODO - should feature.id() be a first class attribute? - - // if __id__ is requested to be dumped out - // remove it so that datasource queries will not break - if (attributes.find(key) != attributes.end()) - { - attributes.erase(key); - } + attributes.erase(known_id_key); } - // if key is not the special __id__ keyword - else if (attributes.find(key) == attributes.end()) + + std::string join_field = grid.get_key(); + if (known_id_key != join_field && + attributes.find(join_field) == attributes.end()) { - // them make sure the datasource query includes this field - attributes.insert(key); + attributes.insert(join_field); } try diff --git a/bindings/python/python_grid_utils.hpp b/bindings/python/python_grid_utils.hpp index 30ed4ff43..2c4083d1b 100644 --- a/bindings/python/python_grid_utils.hpp +++ b/bindings/python/python_grid_utils.hpp @@ -64,7 +64,7 @@ void grid_encode_utf(T const& grid_type, unsigned int resolution); template -boost::python::dict grid_encode( T const& grid, std::string format, bool add_features, unsigned int resolution); +boost::python::dict grid_encode( T const& grid, std::string const& format, bool add_features, unsigned int resolution); /* new approach: key comes from grid object * grid size should be same as the map diff --git a/configure b/configure index 99d1fc22a..d609ba421 100755 --- a/configure +++ b/configure @@ -1,3 +1,3 @@ #!/bin/sh -python scons/scons.py --implicit-cache configure "$@" +python scons/scons.py --implicit-deps-changed configure "$@" diff --git a/demo/c++/build.py b/demo/c++/build.py index 9738347f9..cf3c77206 100644 --- a/demo/c++/build.py +++ b/demo/c++/build.py @@ -17,7 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# $Id$ +# import os from copy import copy @@ -40,8 +40,7 @@ if env['HAS_CAIRO']: demo_env.Append(CXXFLAGS = '-DHAVE_CAIRO') libraries = copy(env['LIBMAPNIK_LIBS']) -boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND'] -libraries.extend([boost_program_options,'mapnik']) +libraries.append('mapnik') rundemo = demo_env.Program('rundemo', source, LIBS=libraries, LINKFLAGS=env["CUSTOM_LDFLAGS"]) diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index 31e016ced..1c918ea61 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -61,7 +61,7 @@ int main ( int argc , char** argv) freetype_engine::register_font(mapnik_dir + "/fonts/DejaVuSans.ttf"); Map m(800,600); - m.set_background(color_factory::from_string("white")); + m.set_background(parse_color("white")); // create styles diff --git a/demo/python/README.txt b/demo/python/README.txt index 0963e4f27..4a13579cb 100644 --- a/demo/python/README.txt +++ b/demo/python/README.txt @@ -1,5 +1,3 @@ -# $Id$ - This directory contains a sample python script implementing the Mapnik API. The script is thoroughly commented and also acts as a mini tutorial. Reading diff --git a/demo/python/rundemo.py b/demo/python/rundemo.py index bd9639a4b..0509b8a42 100644 --- a/demo/python/rundemo.py +++ b/demo/python/rundemo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# $Id$ +# # # This file is part of Mapnik (c++ mapping toolkit) # Copyright (C) 2005 Jean-Francois Doyon diff --git a/demo/test/charplacement.py b/demo/test/charplacement.py index 6f893033f..b3a9f4555 100644 --- a/demo/test/charplacement.py +++ b/demo/test/charplacement.py @@ -42,7 +42,7 @@ road_rule.symbols.append(LineSymbolizer(road_stroke)) road_style.rules.append(road_rule); #Road text -text_symbolizer = TextSymbolizer('NAME', 'DejaVu Sans Book', 20, Color('black')) +text_symbolizer = TextSymbolizer(Expression('[NAME]'), 'DejaVu Sans Book', 20, Color('black')) text_symbolizer.label_placement=label_placement.LINE_PLACEMENT text_symbolizer.minimum_distance = 0 #text_symbolizer.max_char_angle_delta = 40 @@ -77,6 +77,6 @@ im = Image(m.width,m.height) render(m, im) # Save image to file -save_to_file('output.png', 'png',im) # true-colour RGBA +im.save('output.png') # true-colour RGBA print "Done\n" diff --git a/demo/test/displacement.py b/demo/test/displacement.py index 5e2282611..185a5f8b0 100644 --- a/demo/test/displacement.py +++ b/demo/test/displacement.py @@ -43,7 +43,7 @@ road_rule.symbols.append(LineSymbolizer(road_stroke)) road_style.rules.append(road_rule); #Road text -text_symbolizer = TextSymbolizer('NAME', 'DejaVu Sans Book', 10, Color('black')) +text_symbolizer = TextSymbolizer(Expression('[NAME]'), 'DejaVu Sans Book', 10, Color('black')) text_symbolizer.label_placement=label_placement.LINE_PLACEMENT text_symbolizer.minimum_distance = 0 #text_symbolizer.max_char_angle_delta = 40 @@ -78,6 +78,6 @@ im = Image(m.width,m.height) render(m, im) # Save image to file -save_to_file('output.png', 'png',im) # true-colour RGBA +im.save('output.png') # true-colour RGBA print "Done\n" diff --git a/demo/test/overlap.py b/demo/test/overlap.py index a1d28a9fd..291159eb7 100644 --- a/demo/test/overlap.py +++ b/demo/test/overlap.py @@ -44,7 +44,7 @@ road_rule.symbols.append(LineSymbolizer(road_stroke)) road_style.rules.append(road_rule); #Road text -text_symbolizer = TextSymbolizer('NAME', 'DejaVu Sans Book', 10, Color('black')) +text_symbolizer = TextSymbolizer(Expression('[NAME]'), 'DejaVu Sans Book', 10, Color('black')) text_symbolizer.label_placement=label_placement.LINE_PLACEMENT text_symbolizer.minimum_distance = 0 #text_symbolizer.max_char_angle_delta = 40 @@ -79,6 +79,6 @@ im = Image(m.width,m.height) render(m, im) # Save image to file -save_to_file('output.png', 'png',im) # true-colour RGBA +im.save('output.png') # true-colour RGBA print "Done\n" diff --git a/demo/test/textspacing.py b/demo/test/textspacing.py index 482ee4066..0d01e149f 100644 --- a/demo/test/textspacing.py +++ b/demo/test/textspacing.py @@ -43,7 +43,7 @@ road_rule.symbols.append(LineSymbolizer(road_stroke)) road_style.rules.append(road_rule); #Road text -text_symbolizer = TextSymbolizer('NAME', 'DejaVu Sans Book', 10, Color('black')) +text_symbolizer = TextSymbolizer(Expression('[NAME]'), 'DejaVu Sans Book', 10, Color('black')) text_symbolizer.label_placement=label_placement.LINE_PLACEMENT text_symbolizer.minimum_distance = 0 #text_symbolizer.max_char_angle_delta = 40 @@ -77,6 +77,6 @@ im = Image(m.width,m.height) render(m, im) # Save image to file -save_to_file('output.png', 'png',im) # true-colour RGBA +im.save('output.png') # true-colour RGBA print "Done\n" diff --git a/demo/viewer/about_dialog.cpp b/demo/viewer/about_dialog.cpp index 5f6fa88f5..270db196f 100644 --- a/demo/viewer/about_dialog.cpp +++ b/demo/viewer/about_dialog.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "about_dialog.hpp" diff --git a/demo/viewer/about_dialog.hpp b/demo/viewer/about_dialog.hpp index b70e27330..8411a4dc0 100644 --- a/demo/viewer/about_dialog.hpp +++ b/demo/viewer/about_dialog.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #if !defined ABOUT_DIALOG_HPP diff --git a/demo/viewer/build.py b/demo/viewer/build.py index 9db566370..ec1dacc26 100644 --- a/demo/viewer/build.py +++ b/demo/viewer/build.py @@ -17,7 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# $Id$ +# Import ('env') import os diff --git a/demo/viewer/info_dialog.cpp b/demo/viewer/info_dialog.cpp index 92b3599d3..734293d52 100644 --- a/demo/viewer/info_dialog.cpp +++ b/demo/viewer/info_dialog.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "info_dialog.hpp" diff --git a/demo/viewer/info_dialog.hpp b/demo/viewer/info_dialog.hpp index 81d550c8b..754c1a96f 100644 --- a/demo/viewer/info_dialog.hpp +++ b/demo/viewer/info_dialog.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef INFO_DIALOG_HPP diff --git a/demo/viewer/layer_info_dialog.cpp b/demo/viewer/layer_info_dialog.cpp index c223146b4..93e0072db 100644 --- a/demo/viewer/layer_info_dialog.cpp +++ b/demo/viewer/layer_info_dialog.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "layer_info_dialog.hpp" diff --git a/demo/viewer/layer_info_dialog.hpp b/demo/viewer/layer_info_dialog.hpp index 4fb8730fa..9b9d2abc2 100644 --- a/demo/viewer/layer_info_dialog.hpp +++ b/demo/viewer/layer_info_dialog.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef LAYER_INFO_DIALOG_HPP diff --git a/demo/viewer/layerdelegate.cpp b/demo/viewer/layerdelegate.cpp index fbaf101ed..73f6f17fa 100644 --- a/demo/viewer/layerdelegate.cpp +++ b/demo/viewer/layerdelegate.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include #include "layerdelegate.hpp" diff --git a/demo/viewer/layerdelegate.hpp b/demo/viewer/layerdelegate.hpp index a5442a6fc..616b6f53d 100644 --- a/demo/viewer/layerdelegate.hpp +++ b/demo/viewer/layerdelegate.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef LAYER_DELEGATE_HPP #define LAYER_DELEGATE_HPP diff --git a/demo/viewer/layerlistmodel.cpp b/demo/viewer/layerlistmodel.cpp index 68280dce1..a85645174 100644 --- a/demo/viewer/layerlistmodel.cpp +++ b/demo/viewer/layerlistmodel.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "layerlistmodel.hpp" diff --git a/demo/viewer/layerlistmodel.hpp b/demo/viewer/layerlistmodel.hpp index 6d4ec00a5..7c155d95e 100644 --- a/demo/viewer/layerlistmodel.hpp +++ b/demo/viewer/layerlistmodel.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef LAYER_LIST_MODEL_HPP diff --git a/demo/viewer/layerwidget.cpp b/demo/viewer/layerwidget.cpp index 4affb0a2c..876d6b13f 100644 --- a/demo/viewer/layerwidget.cpp +++ b/demo/viewer/layerwidget.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "layerwidget.hpp" #include diff --git a/demo/viewer/layerwidget.hpp b/demo/viewer/layerwidget.hpp index a62a91e10..a3b163c29 100644 --- a/demo/viewer/layerwidget.hpp +++ b/demo/viewer/layerwidget.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef LAYERWIDGET_HPP #define LAYERWIDGET_HPP diff --git a/demo/viewer/main.cpp b/demo/viewer/main.cpp index c5cb4ad4c..4b314a500 100644 --- a/demo/viewer/main.cpp +++ b/demo/viewer/main.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ // qt #include diff --git a/demo/viewer/mainwindow.cpp b/demo/viewer/mainwindow.cpp index 436a31ddc..996138678 100644 --- a/demo/viewer/mainwindow.cpp +++ b/demo/viewer/mainwindow.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ // stl #include @@ -40,6 +39,7 @@ #include #include #include +#include #endif // qt diff --git a/demo/viewer/mainwindow.hpp b/demo/viewer/mainwindow.hpp index 25271693b..99936da73 100644 --- a/demo/viewer/mainwindow.hpp +++ b/demo/viewer/mainwindow.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp index eb57adce9..159f556cc 100644 --- a/demo/viewer/mapwidget.cpp +++ b/demo/viewer/mapwidget.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include diff --git a/demo/viewer/mapwidget.hpp b/demo/viewer/mapwidget.hpp index 0aab462b8..11026a546 100644 --- a/demo/viewer/mapwidget.hpp +++ b/demo/viewer/mapwidget.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef MAP_WIDGET_HPP #define MAP_WIDGET_HPP diff --git a/demo/viewer/styles_model.cpp b/demo/viewer/styles_model.cpp index 4a0fd0116..3468de005 100644 --- a/demo/viewer/styles_model.cpp +++ b/demo/viewer/styles_model.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #include "styles_model.hpp" #include diff --git a/demo/viewer/styles_model.hpp b/demo/viewer/styles_model.hpp index 92bafaacd..5dfb9190f 100644 --- a/demo/viewer/styles_model.hpp +++ b/demo/viewer/styles_model.hpp @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//$Id$ #ifndef STYLE_MODEL_HPP #define STYLE_MODEL_HPP diff --git a/deps/agg/build.py b/deps/agg/build.py index 04c67735a..b33c271d7 100644 --- a/deps/agg/build.py +++ b/deps/agg/build.py @@ -15,9 +15,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -# $Id$ +# -import glob +import os +from glob import glob Import('env') @@ -28,4 +29,11 @@ if env['SUNCC']: else: cxxflags = env['CUSTOM_CXXFLAGS'] + ' -O%s -fPIC -DNDEBUG' % env['OPTIMIZATION'] -agg_env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CXXFLAGS=cxxflags, LINKFLAGS=env['CUSTOM_LDFLAGS']) \ No newline at end of file +agg_env.StaticLibrary('agg', glob('./src/' + '*.cpp'), LIBS=[], CXXFLAGS=cxxflags, LINKFLAGS=env['CUSTOM_LDFLAGS']) + +if 'install' in COMMAND_LINE_TARGETS: + inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/agg') + # TODO - restrict to just agg headers used in mapnik includes? + includes = glob('./include/*.h') + target = env.Install(inc_target, includes) + env.Alias(target='install', source=target) diff --git a/deps/agg/include/agg_pixfmt_rgba.h b/deps/agg/include/agg_pixfmt_rgba.h index 41e6923f0..6fb194091 100644 --- a/deps/agg/include/agg_pixfmt_rgba.h +++ b/deps/agg/include/agg_pixfmt_rgba.h @@ -31,11 +31,6 @@ #include "agg_color_rgba.h" #include "agg_rendering_buffer.h" -#include -#include - -#include - namespace agg { @@ -334,7 +329,7 @@ namespace agg p[Order::R] = (value_type)(sr + ((p[Order::R] * s1a + base_mask) >> base_shift)); p[Order::G] = (value_type)(sg + ((p[Order::G] * s1a + base_mask) >> base_shift)); p[Order::B] = (value_type)(sb + ((p[Order::B] * s1a + base_mask) >> base_shift)); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + ((p[Order::A] * s1a + base_mask) >> base_shift)); } }; @@ -1450,6 +1445,9 @@ namespace agg }; // colorize alpha values + // TODO - consider moving to image-filters: + // https://github.com/mapnik/mapnik/issues/1371 + /* template struct comp_op_rgba_colorize_alpha { @@ -1503,6 +1501,7 @@ namespace agg } } }; + */ // grain extract (GIMP) // E = I - M + 128 @@ -1566,36 +1565,9 @@ namespace agg base_mask = color_type::base_mask }; - static AGG_INLINE void blend_pix(value_type* p, + static void blend_pix(value_type* p, unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if (cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - - if (sa > 0) - { - using namespace boost; - using namespace gil; - using namespace hsv_color_space; - rgb8_pixel_t rgb_src(sr,sg,sb); - rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); - hsv32f_pixel_t hsv_src,hsv_dst; - color_convert(rgb_src, hsv_src); - color_convert(rgb_dst, hsv_dst); - get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); - color_convert(hsv_dst, rgb_dst); - p[Order::R] = get_color(rgb_dst,red_t()); - p[Order::G] = get_color(rgb_dst,green_t()); - p[Order::B] = get_color(rgb_dst,blue_t()); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); - } - } + unsigned sa, unsigned cover); }; template @@ -1612,36 +1584,9 @@ namespace agg base_mask = color_type::base_mask }; - static AGG_INLINE void blend_pix(value_type* p, + static void blend_pix(value_type* p, unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if (cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - - if (sa > 0) - { - using namespace boost; - using namespace gil; - using namespace hsv_color_space; - rgb8_pixel_t rgb_src(sr,sg,sb); - rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); - hsv32f_pixel_t hsv_src,hsv_dst; - color_convert( rgb_src, hsv_src); - color_convert( rgb_dst, hsv_dst); - get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); - color_convert(hsv_dst, rgb_dst); - p[Order::R] = get_color(rgb_dst,red_t()); - p[Order::G] = get_color(rgb_dst,green_t()); - p[Order::B] = get_color(rgb_dst,blue_t()); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); - } - } + unsigned sa, unsigned cover); }; template @@ -1658,37 +1603,9 @@ namespace agg base_mask = color_type::base_mask }; - static AGG_INLINE void blend_pix(value_type* p, + static void blend_pix(value_type* p, unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if (cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - - if (sa > 0) - { - using namespace boost; - using namespace gil; - using namespace hsv_color_space; - rgb8_pixel_t rgb_src(sr,sg,sb); - rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); - hsv32f_pixel_t hsv_src,hsv_dst; - color_convert( rgb_src, hsv_src); - color_convert( rgb_dst, hsv_dst); - get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); - get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); - color_convert(hsv_dst, rgb_dst); - p[Order::R] = get_color(rgb_dst,red_t()); - p[Order::G] = get_color(rgb_dst,green_t()); - p[Order::B] = get_color(rgb_dst,blue_t()); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); - } - } + unsigned sa, unsigned cover); }; @@ -1706,36 +1623,9 @@ namespace agg base_mask = color_type::base_mask }; - static AGG_INLINE void blend_pix(value_type* p, + static void blend_pix(value_type* p, unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if (cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - - if (sa > 0) - { - using namespace boost; - using namespace gil; - using namespace hsv_color_space; - rgb8_pixel_t rgb_src(sr,sg,sb); - rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); - hsv32f_pixel_t hsv_src,hsv_dst; - color_convert( rgb_src, hsv_src); - color_convert( rgb_dst, hsv_dst); - get_color(hsv_dst,value_t()) = get_color(hsv_src,value_t()); - color_convert(hsv_dst, rgb_dst); - p[Order::R] = get_color(rgb_dst,red_t()); - p[Order::G] = get_color(rgb_dst,green_t()); - p[Order::B] = get_color(rgb_dst,blue_t()); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); - } - } + unsigned sa, unsigned cover); }; //======================================================comp_op_table_rgba @@ -1790,7 +1680,7 @@ namespace agg comp_op_rgba_saturation::blend_pix, comp_op_rgba_color::blend_pix, comp_op_rgba_value::blend_pix, - comp_op_rgba_colorize_alpha::blend_pix, + //comp_op_rgba_colorize_alpha::blend_pix, 0 }; @@ -1832,7 +1722,7 @@ namespace agg comp_op_saturation, //----comp_op_saturation comp_op_color, //----comp_op_color comp_op_value, //----comp_op_value - comp_op_colorize_alpha,//----comp_op_colorize_alpha + //comp_op_colorize_alpha,//----comp_op_colorize_alpha end_of_comp_op_e }; diff --git a/deps/agg/include/agg_rendering_buffer.h b/deps/agg/include/agg_rendering_buffer.h index 5af2e6bba..e43899ecc 100644 --- a/deps/agg/include/agg_rendering_buffer.h +++ b/deps/agg/include/agg_rendering_buffer.h @@ -128,7 +128,7 @@ namespace agg private: //-------------------------------------------------------------------- - T* m_buf; // Pointer to renrdering buffer + T* m_buf; // Pointer to rendering buffer T* m_start; // Pointer to first pixel depending on stride unsigned m_width; // Width in pixels unsigned m_height; // Height in pixels @@ -258,7 +258,7 @@ namespace agg private: //-------------------------------------------------------------------- - T* m_buf; // Pointer to renrdering buffer + T* m_buf; // Pointer to rendering buffer pod_array m_rows; // Pointers to each row of the buffer unsigned m_width; // Width in pixels unsigned m_height; // Height in pixels diff --git a/deps/agg/src/agg_pixfmt_rgba.cpp b/deps/agg/src/agg_pixfmt_rgba.cpp new file mode 100644 index 000000000..7dbd42648 --- /dev/null +++ b/deps/agg/src/agg_pixfmt_rgba.cpp @@ -0,0 +1,147 @@ +#include "agg_pixfmt_rgba.h" +#include +#include +//#include + +namespace agg +{ + + +template +void comp_op_rgba_hue::blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) +{ + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert(rgb_src, hsv_src); + color_convert(rgb_dst, hsv_dst); + get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } +} + +template +void comp_op_rgba_saturation::blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) +{ + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } +} + +template +void comp_op_rgba_color::blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) +{ + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); + get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } +} + +template +void comp_op_rgba_value::blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) +{ + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,value_t()) = get_color(hsv_src,value_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } +} + + +template struct comp_op_rgba_hue; +template struct comp_op_rgba_saturation; +template struct comp_op_rgba_color; +template struct comp_op_rgba_value; + + + +} \ No newline at end of file diff --git a/docs/contributing.markdown b/docs/contributing.markdown index 6bc272f18..c6938e3e5 100644 --- a/docs/contributing.markdown +++ b/docs/contributing.markdown @@ -92,7 +92,7 @@ If you see bits of code around that do not follow these please don't hesitate to #### Use C++ style casts static_cast(value); // yes - + (int)value; // no #### Use const keyword after the type @@ -109,22 +109,29 @@ If you see bits of code around that do not follow these please don't hesitate to #### Shared pointers should be created with [boost::make_shared](http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/make_shared.html) where possible +#### Use assignment operator for zero initialized numbers + + double num = 0; // please + + double num(0); // no + + #### Function definitions should not be separated from their arguments: void foo(int a) // please - + void foo (int a) // no #### Separate arguments by a single space: void foo(int a, float b) // please - + void foo(int a,float b) // no #### Space between operators: if (a == b) // please - + if(a==b) // no #### Braces should always be used: @@ -136,7 +143,7 @@ If you see bits of code around that do not follow these please don't hesitate to if (!file) throw mapnik::datasource_exception("not found"); // no - + #### Braces should be on a separate line: diff --git a/fonts/build.py b/fonts/build.py index 99acaaae1..7105188dd 100644 --- a/fonts/build.py +++ b/fonts/build.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -# $Id$ +# import os import glob @@ -28,5 +28,9 @@ includes = glob.glob('*/*/*.ttf') # grab single unifont ttf (available at http://unifoundry.com/unifont.html) includes.extend(glob.glob('unifont*.ttf')) +target_path = env['MAPNIK_FONTS_DEST'] + if 'uninstall' not in COMMAND_LINE_TARGETS and not env['SYSTEM_FONTS']: - env.Alias(target='install', source=env.Install(env['MAPNIK_FONTS_DEST'], includes)) + env.Alias(target='install', source=env.Install(target_path, includes)) + +env['create_uninstall_target'](env, target_path) \ No newline at end of file diff --git a/include/build.py b/include/build.py new file mode 100644 index 000000000..e12e19dea --- /dev/null +++ b/include/build.py @@ -0,0 +1,19 @@ +import os +from glob import glob + +Import('env') + +base = './mapnik/' +subdirs = ['','svg','wkt','grid','json','util','text_placements','formatting'] + +#if env['SVG_RENDERER']: +# subdirs.append('svg/output') + +if 'install' in COMMAND_LINE_TARGETS: + for subdir in subdirs: + pathdir = os.path.join(base,subdir,'*.hpp') + includes = glob(pathdir) + inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/'+subdir) + env.Alias(target='install', source=env.Install(inc_target, includes)) + +env['create_uninstall_target'](env, os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/')) diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index b31dd2d9d..c96c75a02 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.hpp @@ -23,6 +23,10 @@ #ifndef MAPNIK_AGG_HELPERS_HPP #define MAPNIK_AGG_HELPERS_HPP +// mapnik +#include +#include + // agg #include "agg_basics.h" #include "agg_gamma_functions.h" diff --git a/include/mapnik/attribute_collector.hpp b/include/mapnik/attribute_collector.hpp index 81cdad888..9ad579c5f 100644 --- a/include/mapnik/attribute_collector.hpp +++ b/include/mapnik/attribute_collector.hpp @@ -102,7 +102,6 @@ struct symbolizer_attributes : public boost::static_visitor<> { if (*it) boost::apply_visitor(f_attr, **it); } - collect_metawriter(sym); collect_transform(sym.get_transform()); } @@ -113,14 +112,12 @@ struct symbolizer_attributes : public boost::static_visitor<> { path_processor_type::collect_attributes(*filename_expr,names_); } - collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); } void operator () (line_symbolizer const& sym) { - collect_metawriter(sym); collect_transform(sym.get_transform()); } @@ -131,14 +128,12 @@ struct symbolizer_attributes : public boost::static_visitor<> { path_processor_type::collect_attributes(*filename_expr,names_); } - collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); } void operator () (polygon_symbolizer const& sym) { - collect_metawriter(sym); collect_transform(sym.get_transform()); } @@ -149,7 +144,6 @@ struct symbolizer_attributes : public boost::static_visitor<> { path_processor_type::collect_attributes(*filename_expr,names_); } - collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); } @@ -169,7 +163,6 @@ struct symbolizer_attributes : public boost::static_visitor<> { path_processor_type::collect_attributes(*filename_expr,names_); } - collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); } @@ -186,7 +179,6 @@ struct symbolizer_attributes : public boost::static_visitor<> { boost::apply_visitor(f_attr,*width_expr); } - collect_metawriter(sym); collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); } @@ -198,7 +190,6 @@ struct symbolizer_attributes : public boost::static_visitor<> { boost::apply_visitor(f_attr,*height_expr); } - collect_metawriter(sym); collect_transform(sym.get_transform()); } // TODO - support remaining syms @@ -206,11 +197,6 @@ struct symbolizer_attributes : public boost::static_visitor<> private: std::set& names_; expression_attributes > f_attr; - void collect_metawriter(symbolizer_base const& sym) - { - metawriter_properties const& properties = sym.get_metawriter_properties(); - names_.insert(properties.begin(), properties.end()); - } void collect_transform(transform_list_ptr const& trans_expr) { if (trans_expr) diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index 1a47b3871..5a96e6488 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -88,7 +88,7 @@ public: void re_center(const coord& c); void init(T x0,T y0,T x1,T y1); void clip(const box2d_type &other); - bool from_string(const std::string& s); + bool from_string(std::string const& s); bool valid() const; void move(T x, T y); diff --git a/include/mapnik/building_symbolizer.hpp b/include/mapnik/building_symbolizer.hpp index 3214b7a2a..ad77d0aeb 100644 --- a/include/mapnik/building_symbolizer.hpp +++ b/include/mapnik/building_symbolizer.hpp @@ -34,11 +34,11 @@ namespace mapnik struct MAPNIK_DECL building_symbolizer : public symbolizer_base { building_symbolizer(); - building_symbolizer(color const& fill, expression_ptr height); + building_symbolizer(color const& fill, expression_ptr const& height); color const& get_fill() const; void set_fill(color const& fill); - expression_ptr height() const; - void set_height(expression_ptr height); + expression_ptr const& height() const; + void set_height(expression_ptr const& height); void set_opacity(double opacity); double get_opacity() const; diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp index ad9806276..6640086f8 100644 --- a/include/mapnik/color.hpp +++ b/include/mapnik/color.hpp @@ -47,37 +47,51 @@ private: public: color() - : red_(0xff), + : red_(0xff), green_(0xff), blue_(0xff), alpha_(0xff) {} color(unsigned red, unsigned green, unsigned blue, unsigned alpha = 0xff) - : red_(red), + : red_(red), green_(green), blue_(blue), alpha_(alpha) {} - color( std::string const& css_string); - color(const color& rhs) - : red_(rhs.red_), + : red_(rhs.red_), green_(rhs.green_), blue_(rhs.blue_), alpha_(rhs.alpha_) {} - color& operator=(const color& rhs) - { - if (this==&rhs) return *this; - red_=rhs.red_; - green_=rhs.green_; - blue_=rhs.blue_; - alpha_=rhs.alpha_; + color( std::string const& str); + + std::string to_string() const; + std::string to_hex_string() const; + + color& operator=(color const& rhs) + { + if (this==&rhs) return *this; - } + + red_ = rhs.red_; + green_ = rhs.green_; + blue_ = rhs.blue_; + alpha_ = rhs.alpha_; + + return *this; + } + + inline bool operator==(color const& rhs) const + { + return (red_== rhs.red()) && + (green_ == rhs.green()) && + (blue_ == rhs.blue()) && + (alpha_ == rhs.alpha()); + } inline unsigned red() const { @@ -123,18 +137,6 @@ public: return (alpha_ << 24) | (blue_ << 16) | (green_ << 8) | (red_) ; #endif } - - inline bool operator==(color const& rhs) const - { - return (red_== rhs.red()) && - (green_ == rhs.green()) && - (blue_ == rhs.blue()) && - (alpha_ == rhs.alpha()); - - } - - std::string to_string() const; - std::string to_hex_string() const; }; template diff --git a/include/mapnik/color_factory.hpp b/include/mapnik/color_factory.hpp index 418c244a0..312a4b3ec 100644 --- a/include/mapnik/color_factory.hpp +++ b/include/mapnik/color_factory.hpp @@ -24,27 +24,16 @@ #define MAPNIK_COLOR_FACTORY_HPP // mapnik -#include +#include +#include -// boost -#include +#include namespace mapnik { -class color; +MAPNIK_DECL mapnik::color parse_color(std::string const& str); +MAPNIK_DECL mapnik::color parse_color(std::string const& str, mapnik::css_color_grammar const& g); -template struct css_color_grammar; -class MAPNIK_DECL color_factory : boost::noncopyable -{ -public: - - static void init_from_string(color & c, std::string const& css_color); - - static bool parse_from_string(color & c, std::string const& css_color, - mapnik::css_color_grammar const& g); - - static color from_string(std::string const& css_color); -}; } #endif // MAPNIK_COLOR_FACTORY_HPP diff --git a/include/mapnik/config_error.hpp b/include/mapnik/config_error.hpp index a889bc39e..21a7542dd 100644 --- a/include/mapnik/config_error.hpp +++ b/include/mapnik/config_error.hpp @@ -39,8 +39,8 @@ public: virtual const char * what() const throw(); - void append_context(const std::string & ctx) const; - void append_context(const std::string & ctx, xml_node const& node) const; + void append_context(std::string const& ctx) const; + void append_context(std::string const& ctx, xml_node const& node) const; void append_context(xml_node const& node) const; protected: mutable std::string what_; diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp index 014c51299..e969fa3fe 100644 --- a/include/mapnik/css_color_grammar.hpp +++ b/include/mapnik/css_color_grammar.hpp @@ -37,13 +37,15 @@ #include #include -// fusion -#include -#include - // stl #include +// boost +#include +#if BOOST_VERSION >= 104500 +// fusion +#include + BOOST_FUSION_ADAPT_ADT( mapnik::color, (unsigned, unsigned, obj.red(), obj.set_red(val)) @@ -104,7 +106,19 @@ struct alpha_conv_impl }; // http://www.w3.org/TR/css3-color/#hsl-color -inline double hue_to_rgb( double m1, double m2, double h); +inline double hue_to_rgb( double m1, double m2, double h) +{ + if (h < 0.0) h = h + 1.0; + else if (h > 1) h = h - 1.0; + + if (h * 6 < 1.0) + return m1 + (m2 - m1) * h * 6.0; + if (h * 2 < 1.0) + return m2; + if (h * 3 < 2.0) + return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0; + return m1; +} struct hsl_conv_impl { @@ -161,4 +175,357 @@ struct css_color_grammar : qi::grammar } +#else // boost 1.42 compatibility + +#include + +namespace mapnik +{ +// temp workaround . TODO: adapt mapnik::color +struct css +{ + css () + : r(255),g(255),b(255),a(255) {} + css(unsigned r_,unsigned g_, unsigned b_,unsigned a_ = 0xff) + : r(r_),g(g_),b(b_),a(a_) {} + + unsigned r; + unsigned g; + unsigned b; + unsigned a; +}; + +} + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::css, + (unsigned, r) + (unsigned, g) + (unsigned, b) + (unsigned, a) + ) + +namespace mapnik +{ + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; +namespace phoenix = boost::phoenix; + +typedef boost::spirit::ascii::space_type ascii_space_type; + +struct named_colors_ : qi::symbols +{ + named_colors_() + { + add + ("aliceblue", css(240, 248, 255)) + ("antiquewhite", css(250, 235, 215)) + ("aqua", css(0, 255, 255)) + ("aquamarine", css(127, 255, 212)) + ("azure", css(240, 255, 255)) + ("beige", css(245, 245, 220)) + ("bisque", css(255, 228, 196)) + ("black", css(0, 0, 0)) + ("blanchedalmond", css(255,235,205)) + ("blue", css(0, 0, 255)) + ("blueviolet", css(138, 43, 226)) + ("brown", css(165, 42, 42)) + ("burlywood", css(222, 184, 135)) + ("cadetblue", css(95, 158, 160)) + ("chartreuse", css(127, 255, 0)) + ("chocolate", css(210, 105, 30)) + ("coral", css(255, 127, 80)) + ("cornflowerblue", css(100, 149, 237)) + ("cornsilk", css(255, 248, 220)) + ("crimson", css(220, 20, 60)) + ("cyan", css(0, 255, 255)) + ("darkblue", css(0, 0, 139)) + ("darkcyan", css(0, 139, 139)) + ("darkgoldenrod", css(184, 134, 11)) + ("darkgray", css(169, 169, 169)) + ("darkgreen", css(0, 100, 0)) + ("darkgrey", css(169, 169, 169)) + ("darkkhaki", css(189, 183, 107)) + ("darkmagenta", css(139, 0, 139)) + ("darkolivegreen", css(85, 107, 47)) + ("darkorange", css(255, 140, 0)) + ("darkorchid", css(153, 50, 204)) + ("darkred", css(139, 0, 0)) + ("darksalmon", css(233, 150, 122)) + ("darkseagreen", css(143, 188, 143)) + ("darkslateblue", css(72, 61, 139)) + ("darkslategrey", css(47, 79, 79)) + ("darkturquoise", css(0, 206, 209)) + ("darkviolet", css(148, 0, 211)) + ("deeppink", css(255, 20, 147)) + ("deepskyblue", css(0, 191, 255)) + ("dimgray", css(105, 105, 105)) + ("dimgrey", css(105, 105, 105)) + ("dodgerblue", css(30, 144, 255)) + ("firebrick", css(178, 34, 34)) + ("floralwhite", css(255, 250, 240)) + ("forestgreen", css(34, 139, 34)) + ("fuchsia", css(255, 0, 255)) + ("gainsboro", css(220, 220, 220)) + ("ghostwhite", css(248, 248, 255)) + ("gold", css(255, 215, 0)) + ("goldenrod", css(218, 165, 32)) + ("gray", css(128, 128, 128)) + ("grey", css(128, 128, 128)) + ("green", css(0, 128, 0)) + ("greenyellow", css(173, 255, 47)) + ("honeydew", css(240, 255, 240)) + ("hotpink", css(255, 105, 180)) + ("indianred", css(205, 92, 92)) + ("indigo", css(75, 0, 130)) + ("ivory", css(255, 255, 240)) + ("khaki", css(240, 230, 140)) + ("lavender", css(230, 230, 250)) + ("lavenderblush", css(255, 240, 245)) + ("lawngreen", css(124, 252, 0)) + ("lemonchiffon", css(255, 250, 205)) + ("lightblue", css(173, 216, 230)) + ("lightcoral", css(240, 128, 128)) + ("lightcyan", css(224, 255, 255)) + ("lightgoldenrodyellow", css(250, 250, 210)) + ("lightgray", css(211, 211, 211)) + ("lightgreen", css(144, 238, 144)) + ("lightgrey", css(211, 211, 211)) + ("lightpink", css(255, 182, 193)) + ("lightsalmon", css(255, 160, 122)) + ("lightseagreen", css(32, 178, 170)) + ("lightskyblue", css(135, 206, 250)) + ("lightslategray", css(119, 136, 153)) + ("lightslategrey", css(119, 136, 153)) + ("lightsteelblue", css(176, 196, 222)) + ("lightyellow", css(255, 255, 224)) + ("lime", css(0, 255, 0)) + ("limegreen", css(50, 205, 50)) + ("linen", css(250, 240, 230)) + ("magenta", css(255, 0, 255)) + ("maroon", css(128, 0, 0)) + ("mediumaquamarine", css(102, 205, 170)) + ("mediumblue", css(0, 0, 205)) + ("mediumorchid", css(186, 85, 211)) + ("mediumpurple", css(147, 112, 219)) + ("mediumseagreen", css(60, 179, 113)) + ("mediumslateblue", css(123, 104, 238)) + ("mediumspringgreen", css(0, 250, 154)) + ("mediumturquoise", css(72, 209, 204)) + ("mediumvioletred", css(199, 21, 133)) + ("midnightblue", css(25, 25, 112)) + ("mintcream", css(245, 255, 250)) + ("mistyrose", css(255, 228, 225)) + ("moccasin", css(255, 228, 181)) + ("navajowhite", css(255, 222, 173)) + ("navy", css(0, 0, 128)) + ("oldlace", css(253, 245, 230)) + ("olive", css(128, 128, 0)) + ("olivedrab", css(107, 142, 35)) + ("orange", css(255, 165, 0)) + ("orangered", css(255, 69, 0)) + ("orchid", css(218, 112, 214)) + ("palegoldenrod", css(238, 232, 170)) + ("palegreen", css(152, 251, 152)) + ("paleturquoise", css(175, 238, 238)) + ("palevioletred", css(219, 112, 147)) + ("papayawhip", css(255, 239, 213)) + ("peachpuff", css(255, 218, 185)) + ("peru", css(205, 133, 63)) + ("pink", css(255, 192, 203)) + ("plum", css(221, 160, 221)) + ("powderblue", css(176, 224, 230)) + ("purple", css(128, 0, 128)) + ("red", css(255, 0, 0)) + ("rosybrown", css(188, 143, 143)) + ("royalblue", css(65, 105, 225)) + ("saddlebrown", css(139, 69, 19)) + ("salmon", css(250, 128, 114)) + ("sandybrown", css(244, 164, 96)) + ("seagreen", css(46, 139, 87)) + ("seashell", css(255, 245, 238)) + ("sienna", css(160, 82, 45)) + ("silver", css(192, 192, 192)) + ("skyblue", css(135, 206, 235)) + ("slateblue", css(106, 90, 205)) + ("slategray", css(112, 128, 144)) + ("slategrey", css(112, 128, 144)) + ("snow", css(255, 250, 250)) + ("springgreen", css(0, 255, 127)) + ("steelblue", css(70, 130, 180)) + ("tan", css(210, 180, 140)) + ("teal", css(0, 128, 128)) + ("thistle", css(216, 191, 216)) + ("tomato", css(255, 99, 71)) + ("turquoise", css(64, 224, 208)) + ("violet", css(238, 130, 238)) + ("wheat", css(245, 222, 179)) + ("white", css(255, 255, 255)) + ("whitesmoke", css(245, 245, 245)) + ("yellow", css(255, 255, 0)) + ("yellowgreen", css(154, 205, 50)) + ("transparent", css(0, 0, 0, 0)) + ; + } +} ; + +// clipper helper + +template +inline int clip_int(int val) +{ + if (val < MIN ) return MIN; + if (val > MAX ) return MAX; + return val; +} + +struct percent_conv_impl +{ + template + struct result + { + typedef unsigned type; + }; + + unsigned operator() (double val) const + { + return clip_int<0,255>(int((255.0 * val)/100.0 + 0.5)); + } +}; + +struct alpha_conv_impl +{ + template + struct result + { + typedef unsigned type; + }; + + unsigned operator() (double val) const + { + return clip_int<0,255>(int((255.0 * val) + 0.5)); + } +}; + +struct hsl_conv_impl +{ + template + struct result + { + typedef void type; + }; + + template + void operator() (T0 & c, T1 h, T2 s, T3 l) const + { + double m1,m2; + // normalize values + h /= 360.0; + s /= 100.0; + l /= 100.0; + + if (l <= 0.5) + m2 = l * (s + 1.0); + else + m2 = l + s - l*s; + m1 = l * 2 - m2; + + double r = hue_to_rgb(m1, m2, h + 1.0/3.0); + double g = hue_to_rgb(m1, m2, h); + double b = hue_to_rgb(m1, m2, h - 1.0/3.0); + + c.r = clip_int<0,255>(int((255.0 * r) + 0.5)); + c.g = clip_int<0,255>(int((255.0 * g) + 0.5)); + c.b = clip_int<0,255>(int((255.0 * b) + 0.5)); + } +}; + + +template +struct css_color_grammar : qi::grammar +{ + + css_color_grammar() + : css_color_grammar::base_type(css_color) + + { + using qi::lit; + using qi::_val; + using qi::double_; + using qi::_1; + using qi::_a; + using qi::_b; + using qi::_c; + using ascii::no_case; + using phoenix::at_c; + + css_color %= rgba_color + | rgba_percent_color + | hsl_percent_color + | hex_color + | hex_color_small + | no_case[named]; + + hex_color %= lit('#') + >> hex2 + >> hex2 + >> hex2 + >> -hex2 + ; + + hex_color_small = lit('#') + >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] + >> -hex1[ at_c<3>(_val) = _1 | _1 << 4 ] + ; + + rgba_color = lit("rgb") >> -lit('a') + >> lit('(') + >> dec3 [at_c<0>(_val) = _1] >> ',' + >> dec3 [at_c<1>(_val) = _1] >> ',' + >> dec3 [at_c<2>(_val) = _1] + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + rgba_percent_color = lit("rgb") >> -lit('a') + >> lit('(') + >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + hsl_percent_color = lit("hsl") >> -lit('a') + >> lit('(') + >> double_ [ _a = _1] >> ',' // hue 0..360 + >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% + >> double_ [ _c = _1] >> '%' // lightness 0..100% + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 + >> lit (')') [ hsl_converter(_val,_a,_b,_c)] + ; + } + + qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; + qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; + qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; + qi::rule rgba_color; + qi::rule rgba_percent_color; + qi::rule,css(), ascii_space_type> hsl_percent_color; + qi::rule hex_color; + qi::rule hex_color_small; + qi::rule css_color; + named_colors_ named; + phoenix::function percent_converter; + phoenix::function alpha_converter; + phoenix::function hsl_converter; +}; + +} + +#endif + #endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP diff --git a/include/mapnik/css_color_grammar_def.hpp b/include/mapnik/css_color_grammar_def.hpp new file mode 100644 index 000000000..a1cf7022c --- /dev/null +++ b/include/mapnik/css_color_grammar_def.hpp @@ -0,0 +1,104 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2011 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_DEF_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_DEF_HPP + +// boost +#include + +#if BOOST_VERSION >= 104500 + +#include + +namespace mapnik +{ + +template +css_color_grammar::css_color_grammar() + : css_color_grammar::base_type(css_color) + +{ + using qi::lit; + using qi::_val; + using qi::double_; + using qi::_1; + using qi::_a; + using qi::_b; + using qi::_c; + using ascii::no_case; + using phoenix::at_c; + + css_color %= rgba_color + | rgba_percent_color + | hsl_percent_color + | hex_color + | hex_color_small + | no_case[named]; + + hex_color = lit('#') + >> hex2 [ at_c<0>(_val) = _1 ] + >> hex2 [ at_c<1>(_val) = _1 ] + >> hex2 [ at_c<2>(_val) = _1 ] + >>-hex2 [ at_c<3>(_val) = _1 ] + ; + + hex_color_small = lit('#') + >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] + >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] + >>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] + ; + + rgba_color = lit("rgb") >> -lit('a') + >> lit('(') + >> dec3 [at_c<0>(_val) = _1] >> ',' + >> dec3 [at_c<1>(_val) = _1] >> ',' + >> dec3 [at_c<2>(_val) = _1] + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + rgba_percent_color = lit("rgb") >> -lit('a') + >> lit('(') + >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' + >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) + >> lit(')') + ; + + hsl_percent_color = lit("hsl") >> -lit('a') + >> lit('(') + >> double_ [ _a = _1] >> ',' // hue 0..360 + >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% + >> double_ [ _c = _1] >> '%' // lightness 0..100% + >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 + >> lit (')') [ hsl_converter(_val,_a,_b,_c)] + ; +} + +} + +#endif + +#endif \ No newline at end of file diff --git a/include/mapnik/css_color_grammar_deprecated.hpp b/include/mapnik/css_color_grammar_deprecated.hpp deleted file mode 100644 index d2987b660..000000000 --- a/include/mapnik/css_color_grammar_deprecated.hpp +++ /dev/null @@ -1,420 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef MAPNIK_CSS_COLOR_GRAMMAR_DEPRECATED_HPP -#define MAPNIK_CSS_COLOR_GRAMMAR_DEPRECATED_HPP - -// mapnik -#include - -// spirit2 -#include -#include -#include - -// phoenix -#include -#include -#include -#include - -// fusion -#include - -// not in boost 1.41 -//#include - -// stl -#include - -//BOOST_FUSION_ADAPT_CLASS( -// mapnik::color, -// (unsigned, unsigned, obj.red(), obj.set_red(val)) -// (unsigned, unsigned, obj.green(), obj.set_green(val)) -// (unsigned, unsigned, obj.blue(), obj.set_blue(val)) -// (unsigned, unsigned, obj.alpha(), obj.set_alpha(val)) -// ) - -namespace mapnik -{ -// temp workaround . TODO: adapt mapnik::color -struct css -{ - css () - : r(255),g(255),b(255),a(255) {} - css(unsigned r_,unsigned g_, unsigned b_,unsigned a_ = 0xff) - : r(r_),g(g_),b(b_),a(a_) {} - - unsigned r; - unsigned g; - unsigned b; - unsigned a; -}; - -} - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::css, - (unsigned, r) - (unsigned, g) - (unsigned, b) - (unsigned, a) - ) - -namespace mapnik -{ - -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; -namespace phoenix = boost::phoenix; - -typedef boost::spirit::ascii::space_type ascii_space_type; - -struct named_colors_ : qi::symbols -{ - named_colors_() - { - add - ("aliceblue", css(240, 248, 255)) - ("antiquewhite", css(250, 235, 215)) - ("aqua", css(0, 255, 255)) - ("aquamarine", css(127, 255, 212)) - ("azure", css(240, 255, 255)) - ("beige", css(245, 245, 220)) - ("bisque", css(255, 228, 196)) - ("black", css(0, 0, 0)) - ("blanchedalmond", css(255,235,205)) - ("blue", css(0, 0, 255)) - ("blueviolet", css(138, 43, 226)) - ("brown", css(165, 42, 42)) - ("burlywood", css(222, 184, 135)) - ("cadetblue", css(95, 158, 160)) - ("chartreuse", css(127, 255, 0)) - ("chocolate", css(210, 105, 30)) - ("coral", css(255, 127, 80)) - ("cornflowerblue", css(100, 149, 237)) - ("cornsilk", css(255, 248, 220)) - ("crimson", css(220, 20, 60)) - ("cyan", css(0, 255, 255)) - ("darkblue", css(0, 0, 139)) - ("darkcyan", css(0, 139, 139)) - ("darkgoldenrod", css(184, 134, 11)) - ("darkgray", css(169, 169, 169)) - ("darkgreen", css(0, 100, 0)) - ("darkgrey", css(169, 169, 169)) - ("darkkhaki", css(189, 183, 107)) - ("darkmagenta", css(139, 0, 139)) - ("darkolivegreen", css(85, 107, 47)) - ("darkorange", css(255, 140, 0)) - ("darkorchid", css(153, 50, 204)) - ("darkred", css(139, 0, 0)) - ("darksalmon", css(233, 150, 122)) - ("darkseagreen", css(143, 188, 143)) - ("darkslateblue", css(72, 61, 139)) - ("darkslategrey", css(47, 79, 79)) - ("darkturquoise", css(0, 206, 209)) - ("darkviolet", css(148, 0, 211)) - ("deeppink", css(255, 20, 147)) - ("deepskyblue", css(0, 191, 255)) - ("dimgray", css(105, 105, 105)) - ("dimgrey", css(105, 105, 105)) - ("dodgerblue", css(30, 144, 255)) - ("firebrick", css(178, 34, 34)) - ("floralwhite", css(255, 250, 240)) - ("forestgreen", css(34, 139, 34)) - ("fuchsia", css(255, 0, 255)) - ("gainsboro", css(220, 220, 220)) - ("ghostwhite", css(248, 248, 255)) - ("gold", css(255, 215, 0)) - ("goldenrod", css(218, 165, 32)) - ("gray", css(128, 128, 128)) - ("grey", css(128, 128, 128)) - ("green", css(0, 128, 0)) - ("greenyellow", css(173, 255, 47)) - ("honeydew", css(240, 255, 240)) - ("hotpink", css(255, 105, 180)) - ("indianred", css(205, 92, 92)) - ("indigo", css(75, 0, 130)) - ("ivory", css(255, 255, 240)) - ("khaki", css(240, 230, 140)) - ("lavender", css(230, 230, 250)) - ("lavenderblush", css(255, 240, 245)) - ("lawngreen", css(124, 252, 0)) - ("lemonchiffon", css(255, 250, 205)) - ("lightblue", css(173, 216, 230)) - ("lightcoral", css(240, 128, 128)) - ("lightcyan", css(224, 255, 255)) - ("lightgoldenrodyellow", css(250, 250, 210)) - ("lightgray", css(211, 211, 211)) - ("lightgreen", css(144, 238, 144)) - ("lightgrey", css(211, 211, 211)) - ("lightpink", css(255, 182, 193)) - ("lightsalmon", css(255, 160, 122)) - ("lightseagreen", css(32, 178, 170)) - ("lightskyblue", css(135, 206, 250)) - ("lightslategray", css(119, 136, 153)) - ("lightslategrey", css(119, 136, 153)) - ("lightsteelblue", css(176, 196, 222)) - ("lightyellow", css(255, 255, 224)) - ("lime", css(0, 255, 0)) - ("limegreen", css(50, 205, 50)) - ("linen", css(250, 240, 230)) - ("magenta", css(255, 0, 255)) - ("maroon", css(128, 0, 0)) - ("mediumaquamarine", css(102, 205, 170)) - ("mediumblue", css(0, 0, 205)) - ("mediumorchid", css(186, 85, 211)) - ("mediumpurple", css(147, 112, 219)) - ("mediumseagreen", css(60, 179, 113)) - ("mediumslateblue", css(123, 104, 238)) - ("mediumspringgreen", css(0, 250, 154)) - ("mediumturquoise", css(72, 209, 204)) - ("mediumvioletred", css(199, 21, 133)) - ("midnightblue", css(25, 25, 112)) - ("mintcream", css(245, 255, 250)) - ("mistyrose", css(255, 228, 225)) - ("moccasin", css(255, 228, 181)) - ("navajowhite", css(255, 222, 173)) - ("navy", css(0, 0, 128)) - ("oldlace", css(253, 245, 230)) - ("olive", css(128, 128, 0)) - ("olivedrab", css(107, 142, 35)) - ("orange", css(255, 165, 0)) - ("orangered", css(255, 69, 0)) - ("orchid", css(218, 112, 214)) - ("palegoldenrod", css(238, 232, 170)) - ("palegreen", css(152, 251, 152)) - ("paleturquoise", css(175, 238, 238)) - ("palevioletred", css(219, 112, 147)) - ("papayawhip", css(255, 239, 213)) - ("peachpuff", css(255, 218, 185)) - ("peru", css(205, 133, 63)) - ("pink", css(255, 192, 203)) - ("plum", css(221, 160, 221)) - ("powderblue", css(176, 224, 230)) - ("purple", css(128, 0, 128)) - ("red", css(255, 0, 0)) - ("rosybrown", css(188, 143, 143)) - ("royalblue", css(65, 105, 225)) - ("saddlebrown", css(139, 69, 19)) - ("salmon", css(250, 128, 114)) - ("sandybrown", css(244, 164, 96)) - ("seagreen", css(46, 139, 87)) - ("seashell", css(255, 245, 238)) - ("sienna", css(160, 82, 45)) - ("silver", css(192, 192, 192)) - ("skyblue", css(135, 206, 235)) - ("slateblue", css(106, 90, 205)) - ("slategray", css(112, 128, 144)) - ("slategrey", css(112, 128, 144)) - ("snow", css(255, 250, 250)) - ("springgreen", css(0, 255, 127)) - ("steelblue", css(70, 130, 180)) - ("tan", css(210, 180, 140)) - ("teal", css(0, 128, 128)) - ("thistle", css(216, 191, 216)) - ("tomato", css(255, 99, 71)) - ("turquoise", css(64, 224, 208)) - ("violet", css(238, 130, 238)) - ("wheat", css(245, 222, 179)) - ("white", css(255, 255, 255)) - ("whitesmoke", css(245, 245, 245)) - ("yellow", css(255, 255, 0)) - ("yellowgreen", css(154, 205, 50)) - ("transparent", css(0, 0, 0, 0)) - ; - } -} ; - -// clipper helper - -template -inline int clip_int(int val) -{ - if (val < MIN ) return MIN; - if (val > MAX ) return MAX; - return val; -} - -struct percent_conv_impl -{ - template - struct result - { - typedef unsigned type; - }; - - unsigned operator() (double val) const - { - return clip_int<0,255>(int((255.0 * val)/100.0 + 0.5)); - } -}; - -struct alpha_conv_impl -{ - template - struct result - { - typedef unsigned type; - }; - - unsigned operator() (double val) const - { - return clip_int<0,255>(int((255.0 * val) + 0.5)); - } -}; - - -// http://www.w3.org/TR/css3-color/#hsl-color -inline double hue_to_rgb( double m1, double m2, double h) -{ - if (h < 0.0) h = h + 1.0; - else if (h > 1) h = h - 1.0; - - if (h * 6 < 1.0) - return m1 + (m2 - m1) * h * 6.0; - if (h * 2 < 1.0) - return m2; - if (h * 3 < 2.0) - return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0; - return m1; -} - -struct hsl_conv_impl -{ - template - struct result - { - typedef void type; - }; - - template - void operator() (T0 & c, T1 h, T2 s, T3 l) const - { - double m1,m2; - // normalize values - h /= 360.0; - s /= 100.0; - l /= 100.0; - - if (l <= 0.5) - m2 = l * (s + 1.0); - else - m2 = l + s - l*s; - m1 = l * 2 - m2; - - double r = hue_to_rgb(m1, m2, h + 1.0/3.0); - double g = hue_to_rgb(m1, m2, h); - double b = hue_to_rgb(m1, m2, h - 1.0/3.0); - - c.r = clip_int<0,255>(int((255.0 * r) + 0.5)); - c.g = clip_int<0,255>(int((255.0 * g) + 0.5)); - c.b = clip_int<0,255>(int((255.0 * b) + 0.5)); - } -}; - - -template -struct css_color_grammar : qi::grammar -{ - - css_color_grammar() - : css_color_grammar::base_type(css_color) - - { - using qi::lit; - using qi::_val; - using qi::double_; - using qi::_1; - using qi::_a; - using qi::_b; - using qi::_c; - using ascii::no_case; - using phoenix::at_c; - - css_color %= rgba_color - | rgba_percent_color - | hsl_percent_color - | hex_color - | hex_color_small - | no_case[named]; - - hex_color %= lit('#') - >> hex2 - >> hex2 - >> hex2 - >> -hex2 - ; - - hex_color_small = lit('#') - >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] - >> -hex1[ at_c<3>(_val) = _1 | _1 << 4 ] - ; - - rgba_color = lit("rgb") >> -lit('a') - >> lit('(') - >> dec3 [at_c<0>(_val) = _1] >> ',' - >> dec3 [at_c<1>(_val) = _1] >> ',' - >> dec3 [at_c<2>(_val) = _1] - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; - - rgba_percent_color = lit("rgb") >> -lit('a') - >> lit('(') - >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; - - hsl_percent_color = lit("hsl") >> -lit('a') - >> lit('(') - >> double_ [ _a = _1] >> ',' // hue 0..360 - >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% - >> double_ [ _c = _1] >> '%' // lightness 0..100% - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 - >> lit (')') [ hsl_converter(_val,_a,_b,_c)] - ; - } - - qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; - qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; - qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; - qi::rule rgba_color; - qi::rule rgba_percent_color; - qi::rule,css(), ascii_space_type> hsl_percent_color; - qi::rule hex_color; - qi::rule hex_color_small; - qi::rule css_color; - named_colors_ named; - phoenix::function percent_converter; - phoenix::function alpha_converter; - phoenix::function hsl_converter; -}; - -} - -#endif // MAPNIK_CSS_COLOR_GRAMMAR_DEPRECATED_HPP diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index b9c13f47b..309f9d6c7 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -53,7 +53,7 @@ typedef MAPNIK_DECL boost::shared_ptr featureset_ptr; class MAPNIK_DECL datasource_exception : public std::exception { public: - datasource_exception(const std::string& message = std::string("no reason")) + datasource_exception(std::string const& message) : message_(message) { } @@ -114,7 +114,7 @@ public: */ virtual void bind() const {} - virtual featureset_ptr features(const query& q) const = 0; + virtual featureset_ptr features(query const& q) const = 0; virtual featureset_ptr features_at_point(coord2d const& pt) const = 0; virtual box2d envelope() const = 0; virtual boost::optional get_geometry_type() const = 0; @@ -126,7 +126,7 @@ protected: }; typedef const char * datasource_name(); -typedef datasource* create_ds(const parameters& params, bool bind); +typedef datasource* create_ds(parameters const& params, bool bind); typedef void destroy_ds(datasource *ds); class datasource_deleter @@ -141,11 +141,11 @@ public: typedef boost::shared_ptr datasource_ptr; #define DATASOURCE_PLUGIN(classname) \ - extern "C" MAPNIK_EXP const char * datasource_name() \ + extern "C" MAPNIK_EXP const char * datasource_name() \ { \ return classname::name(); \ } \ - extern "C" MAPNIK_EXP datasource* create(const parameters ¶ms, bool bind) \ + extern "C" MAPNIK_EXP datasource* create(parameters const& params, bool bind) \ { \ return new classname(params, bind); \ } \ diff --git a/include/mapnik/datasource_cache.hpp b/include/mapnik/datasource_cache.hpp index 93ac6ea92..ebadb41f1 100644 --- a/include/mapnik/datasource_cache.hpp +++ b/include/mapnik/datasource_cache.hpp @@ -36,28 +36,28 @@ // stl #include -namespace mapnik { -class MAPNIK_DECL datasource_cache : - public singleton , - private boost::noncopyable +namespace mapnik { namespace detail { +class MAPNIK_DECL datasource_cache_impl { - friend class CreateStatic; -private: - datasource_cache(); - ~datasource_cache(); - datasource_cache(const datasource_cache&); - datasource_cache& operator=(const datasource_cache&); - static std::map > plugins_; - static bool registered_; - static bool insert(const std::string& name,const lt_dlhandle module); - static std::vector plugin_directories_; public: - static std::vector plugin_names(); - static std::string plugin_directories(); - static void register_datasources(std::string const& path); - static bool register_datasource(std::string const& path); - static boost::shared_ptr create(parameters const& params, bool bind=true); + datasource_cache_impl(); + ~datasource_cache_impl(); + std::vector plugin_names(); + std::string plugin_directories(); + void register_datasources(std::string const& path); + bool register_datasource(std::string const& path); + boost::shared_ptr create(parameters const& params, bool bind=true); +private: + std::map > plugins_; + bool registered_; + bool insert(std::string const& name,const lt_dlhandle module); + std::vector plugin_directories_; + }; } +typedef singleton datasource_cache; + +} + #endif // MAPNIK_DATASOURCE_CACHE_HPP diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp index 874c162b5..b53cc985c 100644 --- a/include/mapnik/debug.hpp +++ b/include/mapnik/debug.hpp @@ -55,12 +55,10 @@ namespace mapnik { public: enum severity_type { - info, - debug, - warn, - error, - fatal, - none + debug = 0, + warn = 1, + error = 2, + none = 3 }; typedef boost::unordered_map severity_map; @@ -81,7 +79,7 @@ namespace mapnik { } // per object security levels - static severity_type get_object_severity(const std::string& object_name) + static severity_type get_object_severity(std::string const& object_name) { severity_map::iterator it = object_severity_level_.find(object_name); if (object_name.empty() || it == object_severity_level_.end()) @@ -94,7 +92,7 @@ namespace mapnik { } } - static void set_object_severity(const std::string& object_name, + static void set_object_severity(std::string const& object_name, const severity_type& security_level) { #ifdef MAPNIK_THREADSAFE @@ -121,7 +119,7 @@ namespace mapnik { return format_; } - static void set_format(const std::string& format) + static void set_format(std::string const& format) { #ifdef MAPNIK_THREADSAFE boost::mutex::scoped_lock lock(format_mutex_); @@ -133,7 +131,7 @@ namespace mapnik { static std::string str(); // output - static void use_file(const std::string& filepath); + static void use_file(std::string const& filepath); static void use_console(); private: @@ -180,7 +178,7 @@ namespace mapnik { /* Base log class, should not log anything when no MAPNIK_LOG is defined - This is used for info/debug/warn reporting that should not output + This is used for debug/warn reporting that should not output anything when not compiling for speed. */ template