Merge branch 'master' into harfbuzz

Conflicts:
	bindings/python/mapnik_text_placement.cpp
	include/mapnik/font_engine_freetype.hpp
	include/mapnik/map.hpp
	include/mapnik/metawriter.hpp
	include/mapnik/metawriter_inmem.hpp
	include/mapnik/metawriter_json.hpp
	include/mapnik/placement_finder.hpp
	include/mapnik/symbolizer.hpp
	include/mapnik/symbolizer_helpers.hpp
	include/mapnik/text_properties.hpp
	src/agg/process_shield_symbolizer.cpp
	src/build.py
	src/cairo_renderer.cpp
	src/feature_style_processor.cpp
	src/grid/process_shield_symbolizer.cpp
	src/metawriter.cpp
	src/metawriter_inmem.cpp
	src/placement_finder.cpp
	src/processed_text.cpp
	src/symbolizer_helpers.cpp
	tests/visual_tests/images/lines-shield-200-reference.png
	tests/visual_tests/images/lines-shield-400-reference.png
	tests/visual_tests/images/lines-shield-600-reference.png
	tests/visual_tests/images/lines-shield-800-reference.png
	tests/visual_tests/styles/formatting.xml
	tests/visual_tests/test.py
This commit is contained in:
Hermann Kraus 2012-09-07 19:07:31 +02:00
commit 85e075b8ea
572 changed files with 9499 additions and 5913 deletions

1
.gitignore vendored
View file

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

View file

@ -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
</Parameter>
- 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 <Map> called 'minimum_version' to allow for enforcing the minimum Mapnik version
- XML: Added parameter to <Map> 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
<Map minimum_version="0.6.1"> 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 &lt;&gt;) (r1326) (#427)
- Filters: Added support for `!=` as an alias to `<>` for not-equals filters (avoids &lt;&gt;) (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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 <boost/python.hpp>
#include <mapnik/building_symbolizer.hpp>
using namespace mapnik;
using mapnik::building_symbolizer;
using mapnik::color;
void export_building_symbolizer()
{
using namespace boost::python;
class_<building_symbolizer>("BuildingSymbolizer",
init<>("Default BuildingSymbolizer"))
.add_property("fill",make_function
(&building_symbolizer::get_fill,
return_value_policy<copy_const_reference>()),
&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<copy_const_reference>()),
&building_symbolizer::set_height,
"Set/get the building height")
;
}

View file

@ -81,7 +81,7 @@ boost::shared_ptr<mapnik::datasource> 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<mapnik::datasource> const& ds)

View file

@ -23,25 +23,76 @@
#include <boost/python.hpp>
#include <mapnik/datasource_cache.hpp>
namespace {
using namespace boost::python;
boost::shared_ptr<mapnik::datasource> create_datasource(const dict& d)
{
bool bind=true;
mapnik::parameters params;
boost::python::list keys=d.keys();
for (int i=0; i<len(keys); ++i)
{
std::string key = extract<std::string>(keys[i]);
object obj = d[key];
if (key == "bind")
{
bind = extract<bool>(obj)();
continue;
}
extract<std::string> ex0(obj);
extract<int> ex1(obj);
extract<double> ex2(obj);
if (ex0.check())
{
params[key] = ex0();
}
else if (ex1.check())
{
params[key] = ex1();
}
else if (ex2.check())
{
params[key] = ex2();
}
}
return mapnik::datasource_cache::instance()->create(params, bind);
}
void register_datasources(std::string const& path)
{
mapnik::datasource_cache::instance()->register_datasources(path);
}
std::vector<std::string> plugin_names()
{
return mapnik::datasource_cache::instance()->plugin_names();
}
std::string plugin_directories()
{
return mapnik::datasource_cache::instance()->plugin_directories();
}
}
void export_datasource_cache()
{
using mapnik::datasource_cache;
using mapnik::singleton;
using mapnik::CreateStatic;
using namespace boost::python;
class_<singleton<datasource_cache,CreateStatic>,boost::noncopyable>("Singleton",no_init)
.def("instance",&singleton<datasource_cache,CreateStatic>::instance,
return_value_policy<reference_existing_object>())
.staticmethod("instance")
;
class_<datasource_cache,bases<singleton<datasource_cache,CreateStatic> >,
boost::noncopyable>("DatasourceCache",no_init)
.def("create",&datasource_cache::create)
class_<datasource_cache,
boost::noncopyable>("DatasourceCache",no_init)
.def("create",&create_datasource)
.staticmethod("create")
.def("register_datasources",&datasource_cache::register_datasources)
.def("register_datasources",&register_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")
;
}

View file

@ -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_<font_set>("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"

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>

View file

@ -31,12 +31,14 @@
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/json/geometry_parser.hpp>
#include <mapnik/json/geojson_generator.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 104700
#include <mapnik/util/geometry_to_wkb.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#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<path_type> from_wkt_impl(std::string const& wkt)
{
boost::shared_ptr<path_type> paths = boost::make_shared<path_type>();
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<path_type> from_wkb_impl(std::string const& wkb)
{
boost::shared_ptr<path_type> paths = boost::make_shared<path_type>();
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<path_type> from_geojson_impl(std::string const& json)
{
boost::shared_ptr<path_type> paths = boost::make_shared<path_type>();
if (! mapnik::json::from_geojson(json, *paths))
throw std::runtime_error("Failed to parse geojson geometry");
return paths;
}
mapnik::box2d<double> envelope_impl(path_type & p)
{
mapnik::box2d<double> 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_<path_type, boost::shared_ptr<path_type>, boost::noncopyable>("Path")
.def("__getitem__", getitem_impl,return_value_policy<reference_existing_object>())
.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")
;
}

View file

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

View file

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

View file

@ -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 <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
// mapnik
#include <mapnik/metawriter_inmem.hpp>
using mapnik::metawriter_inmem;
using mapnik::metawriter_inmem_ptr;
namespace {
std::map<std::string, mapnik::value>::const_iterator
mapnik_value_map_begin(const std::map<std::string, mapnik::value> &m) {
return m.begin();
}
std::map<std::string, mapnik::value>::const_iterator
mapnik_value_map_end(const std::map<std::string, mapnik::value> &m) {
return m.end();
}
}
void export_inmem_metawriter() {
using namespace boost::python;
class_<std::map<std::string, mapnik::value> >
("MapnikProperties", "Retarded.", init<>())
.def("__iter__", range(&mapnik_value_map_begin, &mapnik_value_map_end))
;
class_<metawriter_inmem::meta_instance>
("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_<metawriter_inmem, metawriter_inmem_ptr, boost::noncopyable>
("MetaWriterInMem",
"Collects meta-information about elements rendered.",
no_init)
.def("__iter__", range(&metawriter_inmem::inst_begin,
&metawriter_inmem::inst_end))
;
}

View file

@ -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<copy_const_reference>()),
&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<reference_existing_object>()),
"The styles list attached to this layer.\n"

View file

@ -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_<line_pattern_symbolizer>("LinePatternSymbolizer",
init<path_expression_ptr>
("<image file expression>"))
//.def_pickle(line_pattern_symbolizer_pickle_suite())
.add_property("transform",
mapnik::get_svg_transform<line_pattern_symbolizer>,
mapnik::set_svg_transform<line_pattern_symbolizer>)
.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)")
;
}

View file

@ -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<stroke const&>("TODO"))
.def(init<color const& ,float>())
.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<reference_existing_object>()),
&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,

View file

@ -39,22 +39,14 @@ void export_logger()
;
enum_<mapnik::logger::severity_type>("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_<logger,bases<singleton<logger,CreateStatic> >,
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)

View file

@ -28,9 +28,10 @@
// mapnik
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/metawriter_inmem.hpp>
#include <mapnik/util/deepcopy.hpp>
//#include <mapnik/util/deepcopy.hpp>
#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;i<m.layer_count();++i)
{
l.append(m.getLayer(i));
}
boost::python::list s;
Map::const_style_iterator it = m.styles().begin();
Map::const_style_iterator end = m.styles().end();
for (; it != end; ++it)
{
std::string const& name = it->first;
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<double> ext = extract<box2d<double> >(state[0]);
m.zoom_to_box(ext);
if (state[1])
{
color bg = extract<color>(state[1]);
m.set_background(bg);
}
boost::python::list l=extract<boost::python::list>(state[2]);
for (int i=0;i<len(l);++i)
{
m.addLayer(extract<layer>(l[i]));
}
boost::python::list s=extract<boost::python::list>(state[3]);
for (int i=0;i<len(s);++i)
{
boost::python::tuple style_pair=extract<boost::python::tuple>(s[i]);
std::string name = extract<std::string>(style_pair[0]);
mapnik::feature_type_style style = extract<mapnik::feature_type_style>(style_pair[1]);
m.insert_style(name, style);
}
if (state[4])
{
std::string base_path = extract<std::string>(state[4]);
m.set_base_path(base_path);
}
}
};
std::vector<layer>& (Map::*layers_nonconst)() = &Map::layers;
std::vector<layer> const& (Map::*layers_const)() const = &Map::layers;
mapnik::parameters& (Map::*params_nonconst)() = &Map::get_extra_parameters;
//boost::optional<mapnik::box2d<double> > 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<mapnik::metawriter_inmem>(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<mapnik::box2d<double> > 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()
"<mapnik._mapnik.Style object at 0x654f0>\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<reference_existing_object>()),"TODO")
.add_property("aspect_fix_mode",
@ -506,12 +370,30 @@ void export_map()
.add_property("background",make_function
(&Map::background,return_value_policy<copy_const_reference>()),
&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<copy_const_reference>()),
&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<copy_const_reference>()),
&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<copy_const_reference>()),
&Map::set_base_path,

View file

@ -23,11 +23,13 @@
#include <boost/python.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/parse_path.hpp>
#include "mapnik_svg.hpp"
#include "mapnik_enumeration.hpp"
#include <mapnik/marker_cache.hpp> // 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<bool>(state[0]));
p.set_ignore_placement(extract<bool>(state[1]));
//p.set_opacity(extract<float>(state[2]));
}
};
// https://github.com/mapnik/mapnik/issues/1367
PyObject* get_fill_opacity_impl(markers_symbolizer & sym)
{
boost::optional<float> fill_opacity = sym.get_fill_opacity();
@ -107,10 +92,12 @@ void export_markers_symbolizer()
class_<markers_symbolizer>("MarkersSymbolizer",
init<>("Default Markers Symbolizer - circle"))
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
//.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")
;
}

View file

@ -27,7 +27,7 @@
//mapnik
#include <mapnik/palette.hpp>
static boost::shared_ptr<mapnik::rgba_palette> make_palette( const std::string& palette, const std::string& format )
static boost::shared_ptr<mapnik::rgba_palette> make_palette( std::string const& palette, std::string const& format )
{
mapnik::rgba_palette::palette_type type = mapnik::rgba_palette::PALETTE_RGBA;
if (format == "rgb")

View file

@ -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<bool>(state[0]));
p.set_opacity(extract<float>(state[1]));
p.set_ignore_placement(extract<bool>(state[2]));
p.set_point_placement(extract<point_placement_e>(state[3]));
}
};
void export_point_symbolizer()
{
using namespace boost::python;
@ -103,7 +62,6 @@ void export_point_symbolizer()
class_<point_symbolizer>("PointSymbolizer",
init<>("Default Point Symbolizer - 4x4 black square"))
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
.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<point_symbolizer>,
mapnik::set_svg_transform<point_symbolizer>)
.add_property("comp_op",
&point_symbolizer::comp_op,
&point_symbolizer::set_comp_op,
"Set/get the comp-op")
;
}

View file

@ -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<pattern_alignment_e>(state[0]));
p.set_gamma(extract<float>(state[1]));
p.set_gamma_method(extract<gamma_method_e>(state[2]));
}
};
void export_polygon_pattern_symbolizer()
{
using namespace boost::python;
@ -95,7 +60,6 @@ void export_polygon_pattern_symbolizer()
class_<polygon_pattern_symbolizer>("PolygonPatternSymbolizer",
init<path_expression_ptr>("<path_expression_ptr>"))
.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")
;
}

View file

@ -21,47 +21,12 @@
*****************************************************************************/
#include <boost/python.hpp>
#include "mapnik_enumeration.hpp"
#include <mapnik/polygon_symbolizer.hpp>
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<float>(state[0]));
p.set_gamma(extract<float>(state[1]));
p.set_gamma_method(extract<gamma_method_e>(state[2]));
}
};
void export_polygon_symbolizer()
{
using namespace boost::python;
@ -69,7 +34,6 @@ void export_polygon_symbolizer()
class_<polygon_symbolizer>("PolygonSymbolizer",
init<>("Default PolygonSymbolizer - solid fill grey"))
.def(init<color const&>("TODO"))
.def_pickle(polygon_symbolizer_pickle_suite())
.add_property("fill",make_function
(&polygon_symbolizer::get_fill,
return_value_policy<copy_const_reference>()),
@ -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")
;
}

View file

@ -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<mapnik::stroke>();
python_optional<mapnik::color>();
python_optional<mapnik::box2d<double> >();
python_optional<mapnik::composite_mode_e>();
python_optional<mapnik::datasource::geometry_t>();
python_optional<std::string>();
python_optional<unsigned>();

View file

@ -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>("Query", "a spatial query data object",
init<box2d<double>,query::resolution_type const&,double>() )
.def(init<box2d<double> >())
.def_pickle(query_pickle_suite())
.add_property("resolution",make_function(&query::resolution,
return_value_policy<copy_const_reference>()))
.add_property("bbox", make_function(&query::get_bbox,

View file

@ -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<std::string>(state[0]));
r.set_scaling_method(extract<mapnik::scaling_method_e>(state[1]));
r.set_opacity(extract<float>(state[2]));
r.set_filter_factor(extract<float>(state[3]));
r.set_mesh_size(extract<unsigned>(state[4]));
}
};
void export_raster_symbolizer()
{
using namespace boost::python;
@ -74,23 +36,16 @@ void export_raster_symbolizer()
class_<raster_symbolizer>("RasterSymbolizer",
init<>("Default ctor"))
.def_pickle(raster_symbolizer_pickle_suite())
.add_property("mode",
make_function(&raster_symbolizer::get_mode,return_value_policy<copy_const_reference>()),
&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,

View file

@ -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 <typename T>
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 <typename T>
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<std::string>(state[1]);
std::string default_filter = "<TODO>";//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<boost::python::list>(state[4]);
extract_symbolizer serializer( r );
for (int i=0;i<len(syms);++i)
{
//symbolizer symbol = extract<symbolizer>(syms[i]);
//boost::apply_visitor( serializer, symbol );
}
}
};
void export_rule()
{
using namespace boost::python;
@ -171,7 +69,6 @@ void export_rule()
class_<rule>("Rule",init<>("default constructor"))
.def(init<std::string const&,
boost::python::optional<double,double> >())
.def_pickle(rule_pickle_suite())
.add_property("name",make_function
(&rule::get_name,
return_value_policy<copy_const_reference>()),

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <boost/python.hpp>

View file

@ -75,7 +75,7 @@ void set_text_displacement(shield_symbolizer & t, boost::python::tuple arg)
t.set_displacement(extract<double>(arg[0]),extract<double>(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<shield_symbolizer>,
mapnik::set_svg_transform<shield_symbolizer>)
.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")
;
}

View file

@ -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<len(l); ++i)
{
boost::python::tuple dash = extract<boost::python::tuple>(l[i]);
if (len(dash) == 2)
{
double d1 = extract<double>(dash[0]);
double d2 = extract<double>(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<float>(state[0]));
if (state[1])
{
list dashes = extract<list>(state[1]);
for(boost::python::ssize_t i=0; i<len(dashes); i++) {
double ds1 = extract<double>(dashes[i][0]);
double ds2 = extract<double>(dashes[i][1]);
s.add_dash(ds1,ds2);
}
}
s.set_line_cap(extract<line_cap_e>(state[2]));
s.set_line_join(extract<line_join_e>(state[3]));
s.set_gamma(extract<double>(state[4]));
s.set_gamma_method(extract<gamma_method_e>(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<copy_const_reference>()),
&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")

View file

@ -25,51 +25,39 @@
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
// mapnik
#include <mapnik/value_error.hpp>
#include "mapnik_enumeration.hpp"
#include <mapnik/feature_type_style.hpp>
#include <mapnik/image_filter_grammar.hpp> // image_filter_grammar
#include <mapnik/image_filter_types.hpp> // 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<std::string> 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<std::string::const_iterator,
std::vector<mapnik::filter::filter_type> > 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<boost::python::list>(state[0]);
for (int i=0; i<len(rules); ++i)
{
s.add_rule(extract<rule>(rules[i]));
}
}
};
}
void export_style()
{
@ -85,9 +73,6 @@ void export_style()
;
class_<feature_type_style>("Style",init<>("default style constructor"))
.def_pickle(style_pickle_suite()
)
.add_property("rules",make_function
(&feature_type_style::get_rules,
return_value_policy<reference_existing_object>()),
@ -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")
;
}

View file

@ -31,7 +31,7 @@ namespace mapnik {
using namespace boost::python;
template <class T>
const std::string get_svg_transform(T& symbolizer)
std::string get_svg_transform(T& symbolizer)
{
return symbolizer.get_image_transform_string();
}

View file

@ -28,7 +28,7 @@
#include <mapnik/formatting/text.hpp>
#include <mapnik/formatting/list.hpp>
#include <mapnik/formatting/format.hpp>
#include <mapnik/formatting/expression.hpp>
#include <mapnik/formatting/expression_format.hpp>
#include <mapnik/text/layout.hpp>
#include <mapnik/expression_string.hpp>
#include <mapnik/text_symbolizer.hpp>
@ -354,6 +354,14 @@ void export_text_placement()
make_function(&get_properties, return_value_policy<reference_existing_object>()),
&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_<char_properties>
class_with_converter<char_properties>
("CharProperties")
.def_readwrite_convert("text_transform", &char_properties::text_transform)
.def(init<char_properties const&>()) //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)

View file

@ -233,69 +233,46 @@ void write_features(T const& grid_type,
boost::python::dict& feature_data,
std::vector<typename T::lookup_type> const& key_order)
{
std::string const& key = grid_type.get_key();
std::set<std::string> 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<std::string> 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<std::string> 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 <typename T>
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<num_fields; i++) {
boost::python::extract<std::string> 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<std::string> 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<mapnik::grid> 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<num_fields; i++) {
boost::python::extract<std::string> name(fields[i]);
@ -464,24 +435,18 @@ boost::python::dict render_grid(const mapnik::Map& map,
// copy property names
std::set<std::string> 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

View file

@ -64,7 +64,7 @@ void grid_encode_utf(T const& grid_type,
unsigned int resolution);
template <typename T>
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

2
configure vendored
View file

@ -1,3 +1,3 @@
#!/bin/sh
python scons/scons.py --implicit-cache configure "$@"
python scons/scons.py --implicit-deps-changed configure "$@"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "about_dialog.hpp"

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#if !defined ABOUT_DIALOG_HPP

View file

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

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "info_dialog.hpp"

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#ifndef INFO_DIALOG_HPP

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "layer_info_dialog.hpp"

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#ifndef LAYER_INFO_DIALOG_HPP

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include <QtGui>
#include "layerdelegate.hpp"

View file

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

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "layerlistmodel.hpp"

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#ifndef LAYER_LIST_MODEL_HPP

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "layerwidget.hpp"
#include <qabstractitemdelegate.h>

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#ifndef LAYERWIDGET_HPP
#define LAYERWIDGET_HPP

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
// qt
#include <QApplication>

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
// stl
#include <iostream>
@ -40,6 +39,7 @@
#include <mapnik/config_error.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/save_map.hpp>
#include <mapnik/projection.hpp>
#endif
// qt

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include <QtGui>

View file

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

View file

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//$Id$
#include "styles_model.hpp"
#include <mapnik/expression_string.hpp>

View file

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

14
deps/agg/build.py vendored
View file

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

View file

@ -31,11 +31,6 @@
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"
#include <boost/gil/gil_all.hpp>
#include <boost/gil/extension/toolbox/hsv.hpp>
#include <iostream>
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 <typename ColorT, typename Order>
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 <typename ColorT, typename Order>
@ -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 <typename ColorT, typename Order>
@ -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<ColorT,Order>::blend_pix,
comp_op_rgba_color<ColorT,Order>::blend_pix,
comp_op_rgba_value<ColorT,Order>::blend_pix,
comp_op_rgba_colorize_alpha<ColorT,Order>::blend_pix,
//comp_op_rgba_colorize_alpha<ColorT,Order>::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
};

View file

@ -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<T*> m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels

147
deps/agg/src/agg_pixfmt_rgba.cpp vendored Normal file
View file

@ -0,0 +1,147 @@
#include "agg_pixfmt_rgba.h"
#include <boost/gil/gil_all.hpp>
#include <boost/gil/extension/toolbox/hsv.hpp>
//#include <iostream>
namespace agg
{
template<class ColorT, class Order>
void comp_op_rgba_hue<ColorT,Order>::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<class ColorT, class Order>
void comp_op_rgba_saturation<ColorT,Order>::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<class ColorT, class Order>
void comp_op_rgba_color<ColorT,Order>::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<class ColorT, class Order>
void comp_op_rgba_value<ColorT,Order>::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<agg::rgba8, agg::order_rgba>;
template struct comp_op_rgba_saturation<agg::rgba8, agg::order_rgba>;
template struct comp_op_rgba_color<agg::rgba8, agg::order_rgba>;
template struct comp_op_rgba_value<agg::rgba8, agg::order_rgba>;
}

View file

@ -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<int>(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:

View file

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

19
include/build.py Normal file
View file

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

View file

@ -23,6 +23,10 @@
#ifndef MAPNIK_AGG_HELPERS_HPP
#define MAPNIK_AGG_HELPERS_HPP
// mapnik
#include <mapnik/gamma_method.hpp>
#include <mapnik/stroke.hpp>
// agg
#include "agg_basics.h"
#include "agg_gamma_functions.h"

View file

@ -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<std::string>& names_;
expression_attributes<std::set<std::string> > 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)

View file

@ -88,7 +88,7 @@ public:
void re_center(const coord<T,2>& 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);

View file

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

View file

@ -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 <typename charT, typename traits>

View file

@ -24,27 +24,16 @@
#define MAPNIK_COLOR_FACTORY_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/color.hpp>
#include <mapnik/css_color_grammar.hpp>
// boost
#include <boost/utility.hpp>
#include <string>
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<std::string::const_iterator> const& g);
template <typename Iterator> 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<std::string::const_iterator> const& g);
static color from_string(std::string const& css_color);
};
}
#endif // MAPNIK_COLOR_FACTORY_HPP

View file

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

View file

@ -37,13 +37,15 @@
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
// fusion
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
// stl
#include <string>
// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104500
// fusion
#include <boost/fusion/include/adapt_adt.hpp>
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<Iterator, color(), ascii_space_type>
}
#else // boost 1.42 compatibility
#include <boost/fusion/include/adapt_struct.hpp>
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<char,css>
{
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 <int MIN,int MAX>
inline int clip_int(int val)
{
if (val < MIN ) return MIN;
if (val > MAX ) return MAX;
return val;
}
struct percent_conv_impl
{
template <typename T>
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 <typename T>
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<typename T0,typename T1, typename T2, typename T3>
struct result
{
typedef void type;
};
template <typename T0,typename T1, typename T2, typename T3>
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 <typename Iterator>
struct css_color_grammar : qi::grammar<Iterator, css(), ascii_space_type>
{
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<Iterator, css(), ascii_space_type> rgba_color;
qi::rule<Iterator, css(), ascii_space_type> rgba_percent_color;
qi::rule<Iterator, qi::locals<double,double,double>,css(), ascii_space_type> hsl_percent_color;
qi::rule<Iterator, css(), ascii_space_type> hex_color;
qi::rule<Iterator, css(), ascii_space_type> hex_color_small;
qi::rule<Iterator, css(), ascii_space_type> css_color;
named_colors_ named;
phoenix::function<percent_conv_impl> percent_converter;
phoenix::function<alpha_conv_impl> alpha_converter;
phoenix::function<hsl_conv_impl> hsl_converter;
};
}
#endif
#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP

View file

@ -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 <boost/version.hpp>
#if BOOST_VERSION >= 104500
#include <mapnik/css_color_grammar.hpp>
namespace mapnik
{
template <typename Iterator>
css_color_grammar<Iterator>::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

View file

@ -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 <mapnik/color.hpp>
// spirit2
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
// phoenix
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
// fusion
#include <boost/fusion/include/adapt_struct.hpp>
// not in boost 1.41
//#include <boost/fusion/include/adapt_class.hpp>
// stl
#include <string>
//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<char,css>
{
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 <int MIN,int MAX>
inline int clip_int(int val)
{
if (val < MIN ) return MIN;
if (val > MAX ) return MAX;
return val;
}
struct percent_conv_impl
{
template <typename T>
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 <typename T>
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<typename T0,typename T1, typename T2, typename T3>
struct result
{
typedef void type;
};
template <typename T0,typename T1, typename T2, typename T3>
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 <typename Iterator>
struct css_color_grammar : qi::grammar<Iterator, css(), ascii_space_type>
{
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<Iterator, css(), ascii_space_type> rgba_color;
qi::rule<Iterator, css(), ascii_space_type> rgba_percent_color;
qi::rule<Iterator, qi::locals<double,double,double>,css(), ascii_space_type> hsl_percent_color;
qi::rule<Iterator, css(), ascii_space_type> hex_color;
qi::rule<Iterator, css(), ascii_space_type> hex_color_small;
qi::rule<Iterator, css(), ascii_space_type> css_color;
named_colors_ named;
phoenix::function<percent_conv_impl> percent_converter;
phoenix::function<alpha_conv_impl> alpha_converter;
phoenix::function<hsl_conv_impl> hsl_converter;
};
}
#endif // MAPNIK_CSS_COLOR_GRAMMAR_DEPRECATED_HPP

View file

@ -53,7 +53,7 @@ typedef MAPNIK_DECL boost::shared_ptr<Featureset> 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<double> envelope() const = 0;
virtual boost::optional<geometry_t> 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> 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 &params, bool bind) \
extern "C" MAPNIK_EXP datasource* create(parameters const& params, bool bind) \
{ \
return new classname(params, bind); \
} \

View file

@ -36,28 +36,28 @@
// stl
#include <map>
namespace mapnik {
class MAPNIK_DECL datasource_cache :
public singleton <datasource_cache,CreateStatic>,
private boost::noncopyable
namespace mapnik { namespace detail {
class MAPNIK_DECL datasource_cache_impl
{
friend class CreateStatic<datasource_cache>;
private:
datasource_cache();
~datasource_cache();
datasource_cache(const datasource_cache&);
datasource_cache& operator=(const datasource_cache&);
static std::map<std::string,boost::shared_ptr<PluginInfo> > plugins_;
static bool registered_;
static bool insert(const std::string& name,const lt_dlhandle module);
static std::vector<std::string> plugin_directories_;
public:
static std::vector<std::string> 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<datasource> create(parameters const& params, bool bind=true);
datasource_cache_impl();
~datasource_cache_impl();
std::vector<std::string> plugin_names();
std::string plugin_directories();
void register_datasources(std::string const& path);
bool register_datasource(std::string const& path);
boost::shared_ptr<datasource> create(parameters const& params, bool bind=true);
private:
std::map<std::string,boost::shared_ptr<PluginInfo> > plugins_;
bool registered_;
bool insert(std::string const& name,const lt_dlhandle module);
std::vector<std::string> plugin_directories_;
};
}
typedef singleton<detail::datasource_cache_impl, CreateStatic> datasource_cache;
}
#endif // MAPNIK_DATASOURCE_CACHE_HPP

View file

@ -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<std::string, severity_type> 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<template <class Ch, class Tr, class A> class OutputPolicy,
@ -240,7 +238,7 @@ namespace mapnik {
/*
Base log class that always log, regardless of MAPNIK_LOG.
This is used for error/fatal reporting that should always log something
This is used for error reporting that should always log something
*/
template<template <class Ch, class Tr, class A> class OutputPolicy,
logger::severity_type Severity,
@ -288,20 +286,18 @@ namespace mapnik {
};
typedef base_log<clog_sink, logger::info> base_log_info;
typedef base_log<clog_sink, logger::debug> base_log_debug;
typedef base_log<clog_sink, logger::warn> base_log_warn;
typedef base_log_always<clog_sink, logger::error> base_log_error;
typedef base_log_always<clog_sink, logger::fatal> base_log_fatal;
} // namespace detail
// real interfaces
class MAPNIK_DECL info : public detail::base_log_info {
class MAPNIK_DECL warn : public detail::base_log_warn {
public:
info() : detail::base_log_info() {}
info(const char* object_name) : detail::base_log_info(object_name) {}
warn() : detail::base_log_warn() {}
warn(const char* object_name) : detail::base_log_warn(object_name) {}
};
class MAPNIK_DECL debug : public detail::base_log_debug {
@ -310,31 +306,16 @@ namespace mapnik {
debug(const char* object_name) : detail::base_log_debug(object_name) {}
};
class MAPNIK_DECL warn : public detail::base_log_warn {
public:
warn() : detail::base_log_warn() {}
warn(const char* object_name) : detail::base_log_warn(object_name) {}
};
class MAPNIK_DECL error : public detail::base_log_error {
public:
error() : detail::base_log_error() {}
error(const char* object_name) : detail::base_log_error(object_name) {}
};
class MAPNIK_DECL fatal : public detail::base_log_fatal {
public:
fatal() : detail::base_log_fatal() {}
fatal(const char* object_name) : detail::base_log_fatal(object_name) {}
};
// logging helpers
#define MAPNIK_LOG_INFO(s) mapnik::info(#s)
#define MAPNIK_LOG_DEBUG(s) mapnik::debug(#s)
#define MAPNIK_LOG_WARN(s) mapnik::warn(#s)
#define MAPNIK_LOG_ERROR(s) mapnik::error(#s)
#define MAPNIK_LOG_FATAL(s) mapnik::fatal(#s)
}
#endif // MAPNIK_DEBUG_HPP

View file

@ -261,7 +261,7 @@ public:
{
if (our_strings_[i] == 0 )
{
MAPNIK_LOG_FATAL(enumeration)
MAPNIK_LOG_ERROR(enumeration)
<< "### FATAL: Not enough strings for enum "
<< our_name_ << " defined in file '" << filename
<< "' at line " << line_no;
@ -270,7 +270,7 @@ public:
}
if ( std::string("") != our_strings_[THE_MAX])
{
MAPNIK_LOG_FATAL(enumeration)
MAPNIK_LOG_ERROR(enumeration)
<< "### FATAL: The string array for enum " << our_name_
<< " defined in file '" << filename << "' at line " << line_no
<< " has too many items or is not terminated with an "

View file

@ -26,6 +26,7 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/expression_node.hpp>
#include <mapnik/expression_grammar.hpp>
// stl
#include <string>
@ -34,19 +35,11 @@ namespace mapnik
{
typedef boost::shared_ptr<expr_node> expression_ptr;
template <typename Iterator> struct expression_grammar;
class expression_factory
{
public:
static expression_ptr compile(std::string const& str,transcoder const& tr);
static bool parse_from_string(expression_ptr const& expr,
std::string const& str,
mapnik::expression_grammar<std::string::const_iterator> const& g);
};
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt, std::string const& encoding);
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt);
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt, std::string const& encoding = "UTF8");
MAPNIK_DECL expression_ptr parse_expression (std::string const& wkt,
mapnik::expression_grammar<std::string::const_iterator> const& g);
}

View file

@ -76,7 +76,7 @@ public:
return map_.erase(key)==1;
}
product_type* create_object(const key_type& key,const std::string& file)
product_type* create_object(const key_type& key,std::string const& file)
{
typename product_map::const_iterator pos=map_.find(key);
if (pos!=map_.end())

View file

@ -25,10 +25,8 @@
// mapnik
#include <mapnik/map.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/memory_datasource.hpp>
// stl
#include <set>
#include <string>
@ -40,6 +38,7 @@ namespace mapnik
class Map;
class layer;
class projection;
class proj_transform;
template <typename Processor>
class feature_style_processor
@ -58,15 +57,6 @@ public:
*/
void apply(mapnik::layer const& lyr, std::set<std::string>& names);
private:
/*!
* @return initialize metawriters for a given map and projection.
*/
void start_metawriters(Map const& m_, projection const& proj);
/*!
* @return stop metawriters that were previously initialized.
*/
void stop_metawriters(Map const& m_);
/*!
* @return render a layer given a projection and scale.
*/

View file

@ -0,0 +1,628 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
// NOTE: This is an implementation header file and is only meant to be included
// from implementation files. It therefore doesn't have an include guard. To
// create a custom feature_style_processor, include this file and instantiate
// the template with the desired template arguments.
// mapnik
#include <mapnik/feature_style_processor.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/memory_datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/grid/grid_renderer.hpp>
// boost
#include <boost/foreach.hpp>
#include <boost/concept_check.hpp>
// stl
#include <vector>
#if defined(HAVE_CAIRO)
#include <mapnik/cairo_renderer.hpp>
#endif
#if defined(SVG_RENDERER)
#include <mapnik/svg/output/svg_renderer.hpp>
#endif
#if defined(RENDERING_STATS)
#include <mapnik/timer.hpp>
#include <iomanip>
#include <sstream>
#endif
namespace mapnik
{
template <typename T0,typename T1> struct has_process;
template <bool>
struct process_impl
{
template <typename T0, typename T1, typename T2, typename T3>
static void process(T0 & ren, T1 const& sym, T2 & f, T3 const& tr)
{
ren.process(sym,f,tr);
}
};
template <> // No-op specialization
struct process_impl<false>
{
template <typename T0, typename T1, typename T2, typename T3>
static void process(T0 & ren, T1 const& sym, T2 & f, T3 const& tr)
{
boost::ignore_unused_variable_warning(ren);
boost::ignore_unused_variable_warning(f);
boost::ignore_unused_variable_warning(tr);
#ifdef MAPNIK_DEBUG
std::clog << "NO-OP ...\n";
#endif
}
};
/** Calls the renderer's process function,
* \param output Renderer
* \param f Feature to process
* \param prj_trans Projection
* \param sym Symbolizer object
*/
template <typename Processor>
struct feature_style_processor<Processor>::symbol_dispatch : public boost::static_visitor<>
{
symbol_dispatch (Processor & output,
mapnik::feature_impl & f,
proj_transform const& prj_trans)
: output_(output),
f_(f),
prj_trans_(prj_trans) {}
template <typename T>
void operator () (T const& sym) const
{
process_impl<has_process<Processor,T>::value>::process(output_,sym,f_,prj_trans_);
}
Processor & output_;
mapnik::feature_impl & f_;
proj_transform const& prj_trans_;
};
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];
template <typename T0, typename T1, void (T0::*)(T1 const&, mapnik::feature_impl &, proj_transform const&) >
struct process_memfun_helper {};
template <typename T0, typename T1> no_tag has_process_helper(...);
template <typename T0, typename T1> yes_tag has_process_helper(process_memfun_helper<T0, T1, &T0::process>* p);
template<typename T0,typename T1>
struct has_process
{
typedef typename T0::processor_impl_type processor_impl_type;
BOOST_STATIC_CONSTANT(bool
, value = sizeof(has_process_helper<processor_impl_type,T1>(0)) == sizeof(yes_tag)
);
};
template <typename Processor>
feature_style_processor<Processor>::feature_style_processor(Map const& m, double scale_factor)
: m_(m), scale_factor_(scale_factor)
{
}
template <typename Processor>
void feature_style_processor<Processor>::apply()
{
#if defined(RENDERING_STATS)
std::clog << "\n//-- starting rendering timer...\n";
mapnik::progress_timer t(std::clog, "total map rendering");
#endif
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
try
{
projection proj(m_.srs());
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
scale_denom *= scale_factor_;
BOOST_FOREACH ( layer const& lyr, m_.layers() )
{
if (lyr.visible(scale_denom))
{
std::set<std::string> names;
apply_to_layer(lyr, p, proj, scale_denom, names);
}
}
}
catch (proj_init_error& ex)
{
MAPNIK_LOG_ERROR(feature_style_processor) << "feature_style_processor: proj_init_error=" << ex.what();
}
p.end_map_processing(m_);
#if defined(RENDERING_STATS)
t.stop();
std::clog << "//-- rendering timer stopped...\n\n";
#endif
}
template <typename Processor>
void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::set<std::string>& names)
{
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
try
{
projection proj(m_.srs());
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
scale_denom *= scale_factor_;
if (lyr.visible(scale_denom))
{
apply_to_layer(lyr, p, proj, scale_denom, names);
}
}
catch (proj_init_error& ex)
{
MAPNIK_LOG_ERROR(feature_style_processor) << "feature_style_processor: proj_init_error=" << ex.what();
}
p.end_map_processing(m_);
}
template <typename Processor>
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
projection const& proj0,
double scale_denom,
std::set<std::string>& names)
{
std::vector<std::string> const& style_names = lay.styles();
unsigned int num_styles = style_names.size();
if (! num_styles)
{
MAPNIK_LOG_DEBUG(feature_style_processor) << "feature_style_processor: No style for layer=" << lay.name();
return;
}
mapnik::datasource_ptr ds = lay.datasource();
if (! ds)
{
MAPNIK_LOG_DEBUG(feature_style_processor) << "feature_style_processor: No datasource for layer=" << lay.name();
return;
}
#if defined(RENDERING_STATS)
progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'");
#endif
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);
#if defined(RENDERING_STATS)
if (! prj_trans.equal())
{
std::clog << "notice: reprojecting layer: '" << lay.name() << "' from/to:\n\t'"
<< lay.srs() << "'\n\t'"
<< m_.srs() << "'\n";
}
#endif
box2d<double> buffered_query_ext = m_.get_buffered_extent(); // buffered
// clip buffered extent by maximum extent, if supplied
boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
if (maximum_extent) {
buffered_query_ext.clip(*maximum_extent);
}
box2d<double> layer_ext = lay.envelope();
bool fw_success = false;
// first, try intersection of map extent forward projected into layer srs
if (prj_trans.forward(buffered_query_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
{
fw_success = true;
layer_ext.clip(buffered_query_ext);
}
// if no intersection and projections are also equal, early return
else if (prj_trans.equal())
{
#if defined(RENDERING_STATS)
layer_timer.discard();
#endif
return;
}
// next try intersection of layer extent back projected into map srs
else if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
{
layer_ext.clip(buffered_query_ext);
// forward project layer extent back into native projection
if (! prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS))
{
MAPNIK_LOG_DEBUG(feature_style_processor)
<< "feature_style_processor: Layer=" << lay.name()
<< " extent=" << layer_ext << " in map projection "
<< " did not reproject properly back to layer projection";
}
}
else
{
// if no intersection then nothing to do for layer
#if defined(RENDERING_STATS)
layer_timer.discard();
#endif
return;
}
// if we've got this far, now prepare the unbuffered extent
// which is used as a bbox for clipping geometries
box2d<double> query_ext = m_.get_current_extent(); // unbuffered
if (maximum_extent)
{
query_ext.clip(*maximum_extent);
}
box2d<double> layer_ext2 = lay.envelope();
if (fw_success)
{
if (prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS))
{
layer_ext2.clip(query_ext);
}
}
else
{
if (prj_trans.backward(layer_ext2, PROJ_ENVELOPE_POINTS))
{
layer_ext2.clip(query_ext);
prj_trans.forward(layer_ext2, PROJ_ENVELOPE_POINTS);
}
}
p.start_layer_processing(lay, layer_ext2);
double qw = query_ext.width()>0 ? query_ext.width() : 1;
double qh = query_ext.height()>0 ? query_ext.height() : 1;
query::resolution_type res(m_.width()/qw,
m_.height()/qh);
query q(layer_ext,res,scale_denom,m_.get_current_extent());
std::vector<feature_type_style*> active_styles;
attribute_collector collector(names);
double filt_factor = 1.0;
directive_collector d_collector(filt_factor);
// iterate through all named styles collecting active styles and attribute names
BOOST_FOREACH(std::string const& style_name, style_names)
{
boost::optional<feature_type_style const&> style=m_.find_style(style_name);
if (!style)
{
MAPNIK_LOG_DEBUG(feature_style_processor)
<< "feature_style_processor: Style=" << style_name
<< " required for layer=" << lay.name() << " does not exist.";
continue;
}
const std::vector<rule>& rules=(*style).get_rules();
bool active_rules=false;
BOOST_FOREACH(rule const& r, rules)
{
if (r.active(scale_denom))
{
active_rules = true;
if (ds->type() == datasource::Vector)
{
collector(r);
}
// TODO - in the future rasters should be able to be filtered.
}
}
if (active_rules)
{
active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
}
}
// Don't even try to do more work if there are no active styles.
if (active_styles.size() > 0)
{
// push all property names
BOOST_FOREACH(std::string const& name, names)
{
q.add_property_name(name);
}
// Update filter_factor for all enabled raster layers.
BOOST_FOREACH (feature_type_style * style, active_styles)
{
BOOST_FOREACH(rule const& r, style->get_rules())
{
if (r.active(scale_denom) &&
ds->type() == datasource::Raster &&
ds->params().get<double>("filter_factor",0.0) == 0.0)
{
rule::symbolizers const& symbols = r.get_symbolizers();
rule::symbolizers::const_iterator symIter = symbols.begin();
rule::symbolizers::const_iterator symEnd = symbols.end();
while (symIter != symEnd)
{
// if multiple raster symbolizers, last will be respected
// should we warn or throw?
boost::apply_visitor(d_collector,*symIter++);
}
q.set_filter_factor(filt_factor);
}
}
}
// Also query the group by attribute
std::string group_by = lay.group_by();
if (group_by != "")
{
q.add_property_name(group_by);
}
bool cache_features = lay.cache_features() && active_styles.size() > 1;
// Render incrementally when the column that we group by
// changes value.
if (group_by != "")
{
featureset_ptr features = ds->features(q);
if (features) {
// Cache all features into the memory_datasource before rendering.
memory_datasource cache;
feature_ptr feature, prev;
while ((feature = features->next()))
{
if (prev && prev->get(group_by) != feature->get(group_by))
{
// We're at a value boundary, so render what we have
// up to this point.
int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles)
{
render_style(lay, p, style, style_names[i++],
cache.features(q), prj_trans, scale_denom);
}
cache.clear();
}
cache.push(feature);
prev = feature;
}
int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles)
{
render_style(lay, p, style, style_names[i++],
cache.features(q), prj_trans, scale_denom);
}
}
}
else if (cache_features)
{
featureset_ptr features = ds->features(q);
if (features) {
// Cache all features into the memory_datasource before rendering.
memory_datasource cache;
feature_ptr feature;
while ((feature = features->next()))
{
cache.push(feature);
}
int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles)
{
render_style(lay, p, style, style_names[i++],
cache.features(q), prj_trans, scale_denom);
}
}
}
// We only have a single style and no grouping.
else
{
int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles)
{
featureset_ptr features = ds->features(q);
if (features) {
render_style(lay, p, style, style_names[i++],
features, prj_trans, scale_denom);
}
}
}
}
#if defined(RENDERING_STATS)
layer_timer.stop();
#endif
p.end_layer_processing(lay);
}
template <typename Processor>
void feature_style_processor<Processor>::render_style(
layer const& lay,
Processor & p,
feature_type_style* style,
std::string const& style_name,
featureset_ptr features,
proj_transform const& prj_trans,
double scale_denom)
{
p.start_style_processing(*style);
#if defined(RENDERING_STATS)
std::ostringstream s1;
s1 << "rendering style for layer: '" << lay.name()
<< "' and style '" << style_name << "'";
mapnik::progress_timer style_timer(std::clog, s1.str());
int feature_processed_count = 0;
int feature_count = 0;
#endif
feature_ptr feature;
while ((feature = features->next()))
{
#if defined(RENDERING_STATS)
feature_count++;
bool feat_processed = false;
#endif
bool do_else = true;
bool do_also = false;
BOOST_FOREACH(rule * r, style->get_if_rules(scale_denom) )
{
expression_ptr const& expr=r->get_filter();
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
if (result.to_bool())
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
do_else=false;
do_also=true;
rule::symbolizers const& symbols = r->get_symbolizers();
// if the underlying renderer is not able to process the complete set of symbolizers,
// process one by one.
if(!p.process(symbols,*feature,prj_trans))
{
BOOST_FOREACH (symbolizer const& sym, symbols)
{
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
}
}
if (style->get_filter_mode() == FILTER_FIRST)
{
// Stop iterating over rules and proceed with next feature.
break;
}
}
}
if (do_else)
{
BOOST_FOREACH( rule * r, style->get_else_rules(scale_denom) )
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
rule::symbolizers const& symbols = r->get_symbolizers();
// if the underlying renderer is not able to process the complete set of symbolizers,
// process one by one.
if(!p.process(symbols,*feature,prj_trans))
{
BOOST_FOREACH (symbolizer const& sym, symbols)
{
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
}
}
}
}
if (do_also)
{
BOOST_FOREACH( rule * r, style->get_also_rules(scale_denom) )
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
rule::symbolizers const& symbols = r->get_symbolizers();
// if the underlying renderer is not able to process the complete set of symbolizers,
// process one by one.
if(!p.process(symbols,*feature,prj_trans))
{
BOOST_FOREACH (symbolizer const& sym, symbols)
{
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
}
}
}
}
#if defined(RENDERING_STATS)
if (feat_processed)
feature_processed_count++;
#endif
}
#if defined(RENDERING_STATS)
style_timer.stop();
// done with style
std::ostringstream s;
if (feature_count > 0)
{
double perc_processed = ((double)feature_processed_count/(double)feature_count)*100.0;
s << "percent rendered: " << perc_processed << "% - " << feature_processed_count
<< " rendered for " << feature_count << " queried for ";
s << std::setw(15 - (int)s.tellp()) << " layer '" << lay.name() << "' and style '" << style_name << "'\n";
}
else
{
s << "" << std::setw(15) << "- no features returned from query for layer '" << lay.name() << "' and style '" << style_name << "'\n";
}
std::clog << s.str();
style_timer.discard();
#endif
p.end_style_processing(*style);
}
}

View file

@ -71,7 +71,16 @@ class MAPNIK_DECL freetype_engine
{
public:
static bool is_font_file(std::string const& file_name);
/*! \brief register a font file
* @param file_name path to a font file.
* @return bool - true if at least one face was successfully registered in the file.
*/
static bool register_font(std::string const& file_name);
/*! \brief register a font file
* @param file_name - path to a directory containing fonts or subdirectories.
* @param recurse - default false, whether to search for fonts in sub directories.
* @return bool - true if at least one face was successfully registered.
*/
static bool register_fonts(std::string const& dir, bool recurse = false);
static std::vector<std::string> face_names();
static std::map<std::string,std::pair<int,std::string> > const& get_mapping();

View file

@ -40,6 +40,7 @@ public:
font_set(font_set const& rhs);
font_set& operator=(font_set const& rhs);
unsigned size() const;
void set_name(std::string const& name);
std::string const& get_name() const;
void add_face_name(std::string);
std::vector<std::string> const& get_face_names() const;

View file

@ -276,10 +276,10 @@ bool middle_point(PathType & path, double & x, double & y)
template <typename PathType>
bool centroid(PathType & path, double & x, double & y)
{
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
double x0 = 0.0;
double y0 = 0.0;
double x1 = 0.0;
double y1 = 0.0;
double start_x;
double start_y;
@ -290,9 +290,9 @@ bool centroid(PathType & path, double & x, double & y)
start_x = x0;
start_y = y0;
double atmp = 0;
double xtmp = 0;
double ytmp = 0;
double atmp = 0.0;
double xtmp = 0.0;
double ytmp = 0.0;
unsigned count = 1;
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
@ -310,10 +310,9 @@ bool centroid(PathType & path, double & x, double & y)
++count;
}
if (count == 1)
{
x = start_x;
y = start_y;
if (count <= 2) {
x = (start_x + x0) * 0.5;
y = (start_y + y0) * 0.5;
return true;
}
@ -368,14 +367,15 @@ bool hit_test(PathType & path, double x, double y, double tol)
}
template <typename PathType>
void interior_position(PathType & path, double & x, double & y)
bool interior_position(PathType & path, double & x, double & y)
{
// start with the centroid
label::centroid(path, x,y);
if (!label::centroid(path, x,y))
return false;
// if we are not a polygon, or the default is within the polygon we are done
if (hit_test(path,x,y,0.001))
return;
return true;
// otherwise we find a horizontal line across the polygon and then return the
// center of the widest intersection between the polygon and the line.
@ -422,7 +422,7 @@ void interior_position(PathType & path, double & x, double & y)
}
// no intersections we just return the default
if (intersections.empty())
return;
return true;
x0=intersections[0];
double max_width = 0;
for (unsigned ii = 1; ii < intersections.size(); ++ii)
@ -437,6 +437,7 @@ void interior_position(PathType & path, double & x, double & y)
break;
}
}
return true;
}
}}

View file

@ -25,7 +25,7 @@
// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/box2d.hpp>
// boost
#include <boost/shared_ptr.hpp>
@ -126,6 +126,14 @@ public:
push_vertex(x,y,SEG_CLOSE);
}
void close()
{
if (cont_.size() > 3)
{
cont_.set_command(cont_.size() - 1, SEG_CLOSE);
}
}
unsigned vertex(double* x, double* y) const
{
return cont_.get_vertex(itr_++,x,y);

View file

@ -0,0 +1,285 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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_GRID_MARKER_HELPERS_HPP
#define MAPNIK_GRID_MARKER_HELPERS_HPP
// mapnik
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/markers_placement.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geom_util.hpp>
// agg
#include "agg_renderer_scanline.h"
#include "agg_scanline_bin.h"
#include "agg_image_filters.h"
#include "agg_trans_bilinear.h"
#include "agg_span_allocator.h"
#include "agg_image_accessors.h"
#include "agg_span_image_filter_gray.h"
namespace mapnik {
template <typename BufferType, typename Rasterizer, typename PixFmt, typename RendererBase, typename RendererType, typename Detector, typename PixMapType>
struct raster_markers_rasterizer_dispatch_grid
{
typedef mapnik::gray32 color_type;
typedef typename RendererBase::pixfmt_type pixfmt_type;
raster_markers_rasterizer_dispatch_grid(BufferType & render_buffer,
Rasterizer & ras,
image_data_32 const& src,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
PixMapType & pixmap)
: buf_(render_buffer),
pixf_(buf_),
renb_(pixf_),
ras_(ras),
src_(src),
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
scale_factor_(scale_factor),
feature_(feature),
pixmap_(pixmap),
placed_(false)
{
// TODO - support basic binary operators
//pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
}
template <typename T>
void add_path(T & path)
{
marker_placement_e placement_method = sym_.get_marker_placement();
box2d<double> bbox_(0,0, src_.width(),src_.height());
if (placement_method != MARKER_LINE_PLACEMENT)
{
double x = 0;
double y = 0;
if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
return;
}
else
{
if (!label::centroid(path, x, y))
return;
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
box2d<double> transformed_bbox = bbox_ * matrix;
if (sym_.get_allow_overlap() ||
detector_.has_placement(transformed_bbox))
{
render_raster_marker(matrix);
if (!sym_.get_ignore_placement())
{
detector_.insert(transformed_bbox);
}
if (!placed_)
{
pixmap_.add_feature(feature_);
placed_ = true;
}
}
}
else
{
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
sym_.get_spacing() * scale_factor_,
sym_.get_max_error(),
sym_.get_allow_overlap());
double x, y, angle;
while (placement.get_point(x, y, angle))
{
agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle);
matrix.translate(x, y);
render_raster_marker(matrix);
if (!placed_)
{
pixmap_.add_feature(feature_);
placed_ = true;
}
}
}
}
void render_raster_marker(agg::trans_affine const& marker_tr)
{
double width = src_.width();
double height = src_.height();
double p[8];
p[0] = 0; p[1] = 0;
p[2] = width; p[3] = 0;
p[4] = width; p[5] = height;
p[6] = 0; p[7] = height;
marker_tr.transform(&p[0], &p[1]);
marker_tr.transform(&p[2], &p[3]);
marker_tr.transform(&p[4], &p[5]);
marker_tr.transform(&p[6], &p[7]);
ras_.move_to_d(p[0],p[1]);
ras_.line_to_d(p[2],p[3]);
ras_.line_to_d(p[4],p[5]);
ras_.line_to_d(p[6],p[7]);
RendererType ren(renb_);
ren.color(mapnik::gray32(feature_.id()));
agg::render_scanlines(ras_, sl_, ren);
}
private:
agg::scanline_bin sl_;
BufferType & buf_;
PixFmt pixf_;
RendererBase renb_;
Rasterizer & ras_;
image_data_32 const& src_;
agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_;
Detector & detector_;
double scale_factor_;
mapnik::feature_impl & feature_;
PixMapType & pixmap_;
bool placed_;
};
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector, typename PixMapType>
struct vector_markers_rasterizer_dispatch_grid
{
typedef typename SvgRenderer::renderer_base renderer_base;
typedef typename renderer_base::pixfmt_type pixfmt_type;
vector_markers_rasterizer_dispatch_grid(BufferType & render_buffer,
SvgRenderer & svg_renderer,
Rasterizer & ras,
box2d<double> const& bbox,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
PixMapType & pixmap)
: buf_(render_buffer),
pixf_(buf_),
renb_(pixf_),
svg_renderer_(svg_renderer),
ras_(ras),
bbox_(bbox),
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
scale_factor_(scale_factor),
feature_(feature),
pixmap_(pixmap),
placed_(false)
{
// TODO
//pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
}
template <typename T>
void add_path(T & path)
{
marker_placement_e placement_method = sym_.get_marker_placement();
if (placement_method != MARKER_LINE_PLACEMENT)
{
double x = 0;
double y = 0;
if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
return;
}
else
{
if (!label::centroid(path, x, y))
return;
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
box2d<double> transformed_bbox = bbox_ * matrix;
if (sym_.get_allow_overlap() ||
detector_.has_placement(transformed_bbox))
{
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, sym_.get_opacity(), bbox_);
if (!sym_.get_ignore_placement())
{
detector_.insert(transformed_bbox);
}
if (!placed_)
{
pixmap_.add_feature(feature_);
placed_ = true;
}
}
}
else
{
markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_,
sym_.get_spacing() * scale_factor_,
sym_.get_max_error(),
sym_.get_allow_overlap());
double x, y, angle;
while (placement.get_point(x, y, angle))
{
agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle);
matrix.translate(x, y);
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, sym_.get_opacity(), bbox_);
if (!placed_)
{
pixmap_.add_feature(feature_);
placed_ = true;
}
}
}
}
private:
agg::scanline_bin sl_;
BufferType & buf_;
pixfmt_type pixf_;
renderer_base renb_;
SvgRenderer & svg_renderer_;
Rasterizer & ras_;
box2d<double> const& bbox_;
agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_;
Detector & detector_;
double scale_factor_;
mapnik::feature_impl & feature_;
PixMapType & pixmap_;
bool placed_;
};
}
#endif

View file

@ -74,8 +74,8 @@ enum composite_mode_e
hue,
saturation,
_color,
_value,
colorize_alpha
_value
//colorize_alpha
};
MAPNIK_DECL boost::optional<composite_mode_e> comp_op_from_string(std::string const& name);

View file

@ -363,9 +363,6 @@ void apply_filter(Src const& src, Dst & dst, FilterTag filter_tag)
rgba8_view_t dst_view = interleaved_view(dst.width(),dst.height(),
(rgba8_pixel_t*) dst.raw_data(),
dst.width()*4);
typedef boost::mpl::vector<red_t,green_t,blue_t> channels;
apply_convolution_3x3(src_view,dst_view,filter_tag);
}

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