Merge branch 'master' into c++11

Conflicts:
	SConstruct
	benchmark/run.cpp
	bindings/python/mapnik_datasource.cpp
	bindings/python/mapnik_feature.cpp
	bindings/python/python_optional.hpp
	include/mapnik/css_color_grammar.hpp
	include/mapnik/expression_grammar.hpp
	include/mapnik/feature.hpp
	include/mapnik/feature_style_processor_impl.hpp
	include/mapnik/image_filter_types.hpp
	include/mapnik/image_util.hpp
	include/mapnik/json/geometry_generator_grammar.hpp
	include/mapnik/json/geometry_grammar.hpp
	include/mapnik/processed_text.hpp
	include/mapnik/tiff_io.hpp
	include/mapnik/util/geometry_svg_generator.hpp
	include/mapnik/util/geometry_wkt_generator.hpp
	include/mapnik/utils.hpp
	include/mapnik/webp_io.hpp
	include/mapnik/wkt/wkt_grammar.hpp
	plugins/input/shape/shape_datasource.cpp
	plugins/input/shape/shapefile.hpp
	src/expression_grammar.cpp
	src/expression_string.cpp
	src/image_util.cpp
	src/json/feature_collection_parser.cpp
	src/json/feature_parser.cpp
	src/miniz.c
	src/symbolizer_helpers.cpp
	src/tiff_reader.cpp
	src/webp_reader.cpp
	tests/cpp_tests/geometry_converters_test.cpp
	tests/cpp_tests/image_io_test.cpp
	tests/cpp_tests/map_request_test.cpp
	tests/python_tests/image_test.py
	tests/visual_tests/test.py
This commit is contained in:
artemp 2013-08-30 09:46:09 +01:00
commit 4f4e2b001e
923 changed files with 14314 additions and 7530 deletions

View file

@ -1,14 +1,16 @@
language: cpp
compiler: clang
compiler:
- clang
- gcc
before_install:
- echo 'yes' | sudo add-apt-repository ppa:mapnik/boost
- sudo apt-get update -qq
- sudo apt-get install -qq libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-system-dev libboost-thread-dev python-nose libicu-dev libpng-dev libjpeg-dev libtiff-dev libz-dev libfreetype6-dev libxml2-dev libproj-dev
- sudo apt-get install -qq libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-system-dev libboost-thread-dev python-nose libicu-dev libpng-dev libjpeg-dev libtiff-dev libwebp-dev libz-dev libfreetype6-dev libxml2-dev libproj-dev
script:
- ./configure DEMO=False BINDINGS='python' CPP_TESTS=False CAIRO=False INPUT_PLUGINS='' OPTIMIZATION=1 FAST=True && JOBS=2 make
- ./configure CXX=${CXX} CC=${CC} DEMO=False BINDINGS='python' CPP_TESTS=False CAIRO=False INPUT_PLUGINS='' OPTIMIZATION=1 FAST=True && JOBS=2 make
branches:
only:

View file

@ -8,10 +8,124 @@ For a complete change history, see the git log.
## Future
- Added new mapnik-config options: `git-describe`, `defines`, `includes`, `dep-includes`, and `cxxflags` (#1443)
- Fixed regression in handling `F` type dbf fields, introduced in v2.2.0.
- Added the ability to create a mapnik Feature from a geojson feature with `mapnik.Feature.from_geojson` in python.
- Added to python bindings: `has_tiff`, `has_png`, `has_webp`, `has_proj4`, `has_svg_renderer`, and `has_grid_renderer`
- Made it possible to disable compilation of `grid_renderer` with `./configure GRID_RENDERER=False` (#1962)
- Added `webp` image encoding and decoding support (#1955)
- Added `premultiplied` property on mapnik::image_32 / mapnik.Image to enable knowledge of premultiplied status of image buffer.
- Added `scale-hsla` image-filter that allows scaling colors in HSL color space. RGB is converted to HSL (hue-saturation-lightness) and then each value (and the original alpha value) is stretched based on the specified scaling values. An example syntax is `scale-hsla(0,1,0,1,0,1,0,1)` which means no change because the full range will be kept (0 for lowest, 1 for highest). Other examples are: 1) `scale-hsla(0,0,0,1,0,1,0,1)` which would force all colors to be red in hue in the same way `scale-hsla(1,1,0,1,0,1,0,1)` would, 2) `scale-hsla(0,1,1,1,0,1,0,1)` which would cause all colors to become fully saturated, 3) `scale-hsla(0,1,1,1,0,1,.5,1)` which would force no colors to be any more transparent than half, and 4) `scale-hsla(0,1,1,1,0,1,0,.5)` which would force all colors to be at least half transparent. (#1954)
## 2.2.0
Released June 3rd, 2013
(Packaged from 9231205)
Summary: The 2.2.0 release is primarily a performance and stability release. The code line represents development in the master branch since the release of 2.1.0 in Aug 2012 and therefore includes nearly a year of bug-fixes and optimizations. Nearly 500 new tests have been added bring the total coverage to 925. Shapefile and PostGIS datasources have benefited from numerous stability fixes, 64 bit integer support has been added to support OSM data in the grid renderer and in attribute filtering, and many fixes have landed for higher quality output when using a custom `scale_factor` during rendering. Critical code paths have been optimized include raster rendering, xml map loading, string to number conversion, vector reprojection when using `epsg:4326` and `epsg:3857`, `hextree` encoding, halo rendering, and rendering when using a custom `gamma`. Mapnik 2.2 also compiles faster than previous releases in the 2.x series and drops several unneeded and hard to install dependencies making builds on OS X and Windows easier than any previous release.
- Removed 3 depedencies without loosing any functionality: `ltdl`, `cairomm` and `libsigc++` (#1804,#806,#1681)
- Added 64 bit integer support in expressions, feature ids, and the grid_renderer (#1661,#1662,#1662)
- Added the ability to disable the need for various dependencies: `proj4`, `libpng`, `libtiff`, `libjpeg`
- Added faster reprojection support between `epsg:3857` and `epsg:4326` (#1705,#1703,#1579)
- Fixed concurrency problem when using cursors in postgis plugin (#1823,#1588)
- Fixed postgres connection pool leaks when using `persist_connection=false` (#1764)
- Fixed postgres connection key to respect highest value of `max_size` and `initial_size` for any layer in map (#1599)
- Fixed potential crash in wkb parsing when postgis returns null geometry (#1843)
- Fixed blurry rendering of image and SVG icons (#1316)
- Added detection of invalid srs values when loading xml (#646)
- Added support for specifying a base_path as a third, optional argument to load_xml
- Removed muffling of projection errors while rendering (#646)
- Improved logging system (https://github.com/mapnik/mapnik/wiki/Logging)
- Added support for reading images from in memory streams (#1805)
- Optimized halo rendering. When halo radius is < 1 new method will be used automatically (#1781)
- Added `text-halo-rasterizer` property. Set to `fast` for lower quality but faster
halo rendering (#1298)
halo rendering (#1298) which matched new default method when radius is < 1.
- Added support in `shape`, `sqlite`, `geojson`, and `csv` plugin for handling non-latin characters in the paths to file-based resources (#1177)
- Fixed rendering of markers when their size is greater than the specified `spacing` value (#1487)
- Fixed handling of alpha premultiplication in image scaling (#1489)
- Optimized rendering when a style with no symbolizers is encountered (#1517)
- Optimized string handling and type conversion by removing `boost::to_lower`, `boost::trim`, and `boost::lexical_cast` usage (#1687,#1687,#1633)
- Optimized alpha preserving `hextree` method for quantization of png images (#1629)
- Faster rendering of rasters by reducing memory allocation of temporary buffers (#1516)
- Fixed some raster reprojection artifacts (#1501)
- Fixed raster alignment when width != height and raster is being scaled (#1748,#1622)
- Added support for caching rasters for re-use during rendering when styling more than once per layer (#1543)
- Improved compile speeds of the code - in some cases by up to 2x and removed need for freetype dependency when building code against mapnik (#1688, #1756)
- Removed internal rule cache on `mapnik::Map` c++ object (#1723)
- Improved the scaled rendering of various map features when using `scale_factor` > 1 (#1280,#1100,#1273,#1792,#1291,#1344,#1279,#1624,#1767,#1766)
- Added C++ api for overriding scale_denominator to enable rendering at fixed scale (#1582)
- Added Layer `buffer-size` that can be used to override Map `buffer-size` to avoid
over-fetching of data that does not need to be buffered as much as other layers.
Map level `buffer-size` will be default if layers do not set the option. Renamed a
previously undocumented parameter by the same name that impacted clipping extent and
was not needed (clipping padding should likely be a symbolizer level option) (#1566)
- Fixed potential file descriptor leaks in image readers when invalid images were encountered (#1783)
- Fixed alpha handling in the `blur` and `invert` image filters (#1541)
- Fixed error reporting in the python plugin (#1422)
- Added the ability to run tests without installing with `make test-local`
- Reduced library binary size by adding support for `-fvisibility-inlines-hidden` and `-fvisibility=hidden` (#1826,#1832)
- Added `mapnik::map_request` class, a special object to allow passing mutable map objects to renderer (#1737)
- Added the ability to use `boost::hash` on `mapnik::value` types (#1729)
- Removed obsolete `geos` plugin (functionality replaced by `csv` plugin) and unmaintained `kismet` plugin (#1809,#1833)
- Added new `mapnik-config` flags: `--all-flags`, `--defines`, `--git-describe`, `--includes`, `--dep-includes`, `--cxxflags`, `--cxx` (#1443)
- Added support for unicode strings as arguments in python bindings (#163)
- Added DebugSymbolizer which is able to render the otherwise invisible collision boxes (#1366)
- Optimized rendering by reducing overhead of using `gamma` property (#1174)
- Fixed rendering artifacts when using `polygon-gamma` or `line-gamma` equal to 0 (#761,#1763)
- Fixed and optimized the display of excessive precision of some float data in labels (#430,#1697)
- Removed the `bind` option for datasources (#1654)
- Added ability to access style list from map by (name,obj) in python (#1725)
@ -21,19 +135,11 @@ For a complete change history, see the git log.
- Added support for `background-image` in cairo_renderer (#1724)
- Added Layer `buffer-size` that can be used to override Map `buffer-size` to avoid
over-fetching of data that does not need to be buffered as much as other layers.
Map level `buffer-size` will be default if layers do not set the option. Renamed a
previously undocumented parameter by the same name that impacted clipping extent and
was not needed (clipping padding should likely be a symbolizer level option) (#1566)
- Fixed building symbolizer rendering to be fully sensitive to alpha (8b66128c892 / bc8ea1c5a7a)
- Added 64 bit integer support in the grid_renderer (#1662)
- `<Filter>[attr]</Filter>` now returns false if attr is an empty string (#1665)
- Added 64 bit integer support in expressions and feature ids (#1661,#1662)
- `<Filter>[attr]!=null</Filter>` now returns true if attr is not null (#1642)
- Added support for DBF `Logical` type: #1614
@ -50,9 +156,7 @@ For a complete change history, see the git log.
- Added support for setting zlib `Z_FIXED` strategy with format string: `png:z=fixed`
- Fixed handling of transparency level option in Octree-based PNG encoding (#1556)
- Faster rendering of rasters by reducing memory allocation of temporary buffers (#1516)
- Fixed handling of transparency level option in `octree` png encoding (#1556)
- Added ability to pass a pre-created collision detector to the cairo renderer (#1444)
@ -68,6 +172,24 @@ For a complete change history, see the git log.
now the combined layer extents will be again respected: they will be clipped to the maximum-extent if possible
and only when back-projecting fails for all layers will the maximum-extent be used as a fallback (#1473)
- Compile time flag called `PLUGIN_LINKING` to allow input datasource plugins to be statically linked with the mapnik library (#249)
- Fixed `dasharray` rendering in cairo backend (#1740)
- Fixed handling of `opacity` in svg rendering (#1744)
- Fixed uneven rendering of markers along lines (#1693)
- Fixed handling of extra bytes in some shapefile fields (#1605)
- Fixed handling (finally) of null shapes and partially corrupt shapefiles (#1630,#1621)
- Added ability to re-use `mapnik::image_32` and `mapnik::grid` by exposing a `clear` method (#1571)
- Added support for writing RGB (no A) png images by using the format string of `png:t=0` (#1559)
- Added experimental support for geometry simplification at symbolizer level (#1385)
## Mapnik 2.1.0
Released Aug 23, 2012
@ -215,7 +337,7 @@ Released April 10, 2012
- Workaround for boost interprocess compile error with recent gcc versions (#950,#1001,#1082)
- Fix possible memory corruption when using hextree mode for png color reduction (#1087)
- Fix possible memory corruption when using `hextree` mode for png color reduction (#1087)
- Fixed bug in shield line placement when dx/dy are used to shift the label relative to the placement point (Matt Amos) (#908)
@ -395,14 +517,14 @@ Released March 23, 2010
- PNG: fixed png256 for large images and some improvements to reduce color corruptions ([#522](https://github.com/mapnik/mapnik/issues/522))
- PNG: Added new quantization method for indexed png format using hextree with full support for alpha
- PNG: Added new quantization method for indexed png format using `hextree` with full support for alpha
channel. Also new method has some optimizations for color gradients common when using elevation based
rasters. By default old method using octree is used. (r1680, r1683, [#477](https://github.com/mapnik/mapnik/issues/477))
rasters. By default old method using `octree` is used. (r1680, r1683, [#477](https://github.com/mapnik/mapnik/issues/477))
- PNG: Added initial support for passing options to png writter like number of colors, transparency
support, quantization method and possibly other in future using type parameter. For example
"png8:c=128:t=1:m=h" limits palette to 128 colors, uses only binary transparency (0 - none,
1 - binary, 2 - full), and new method of quantization using hextree (h - hextree, o - octree).
1 - binary, 2 - full), and new method of quantization using `hextree` (h - `hextree`, o - `octree`).
Existing type "png256" can be also written using "png8:c=256:m=o:t=2" (r1680, r1683, [#477](https://github.com/mapnik/mapnik/issues/477))

View file

@ -48,27 +48,33 @@ Mapnik Core depends on:
- regex (optionally built with icu regex support)
- program_options (optionally for mapnik command line programs)
* libicuuc >= 4.0 (ideally >= 4.2) - International Components for Unicode
* libpng >= 1.2.x - PNG graphics
* libjpeg - JPEG graphics
* libtiff - TIFF graphics
* libz - Zlib compression
* libfreetype - Freetype2 for font support (Install requires freetype-config)
* libxml2 - XML parsing (Install requires xml2-config)
* libproj - PROJ.4 projection library
Mapnik Core optionally depends on:
* libpng >= 1.2.x - PNG graphics (Default enabled, if found)
* libjpeg - JPEG graphics (Default enabled, if found)
* libtiff - TIFF graphics (Default enabled, if found)
* libwebp - WEBP graphics (Default enabled, if found)
* libproj - PROJ.4 projection library (Default enabled, if found)
Mapnik Python bindings depend on:
* Python 2.5-2.7 or >= 3.2
* Boost python
Note: Python3k is supported, see: https://github.com/mapnik/mapnik/wiki/Python3k
Note: Python 3.x is supported, see: https://github.com/mapnik/mapnik/wiki/Python3k
Optional dependencies:
Additional optional dependencies:
* Cairo - Graphics library for output formats like PDF, PS, and SVG
* Cairo >= 1.6.0 - Graphics library for output formats like PDF, PS, and SVG
- pkg-config - Required for building with cairo support
- pycairo - Python bindings for cairo
* libpq - PostgreSQL libraries (For PostGIS plugin support)
* PostgreSQL (for PostGIS plugin support)
- libpq - PostreSQL libraries
- pg_config - PostgreSQL installation capabilities
* libgdal - GDAL/OGR input (For gdal and ogr plugin support)
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
* libocci - Oracle input plugin support

View file

@ -68,7 +68,7 @@ check: test-local
demo:
@echo "*** Running rundemo.cpp…"
cd demo/c++; ./rundemo `mapnik-config --prefix`/lib/mapnik
cd demo/c++; ./rundemo `mapnik-config --prefix`
pep8:
# https://gist.github.com/1903033

View file

@ -27,4 +27,4 @@ See [INSTALL.md](https://github.com/mapnik/mapnik/blob/master/INSTALL.md) for in
# License
Mapnik software is free and is released under LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html_). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.
Mapnik software is free and is released under LGPL ([GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html_)). Please see [COPYING](https://github.com/mapnik/mapnik/blob/master/COPYING) for more information.

View file

@ -22,6 +22,7 @@ import sys
import re
import platform
from glob import glob
from copy import copy
from subprocess import Popen, PIPE
from SCons.SConf import SetCacheMode
import pickle
@ -35,6 +36,12 @@ except:
LIBDIR_SCHEMA_DEFAULT='lib'
severities = ['debug', 'warn', 'error', 'none']
DEFAULT_CC = "gcc"
DEFAULT_CXX = "g++"
if sys.platform == 'darwin':
DEFAULT_CC = "clang"
DEFAULT_CXX = "clang++"
py3 = None
# local file to hold custom user configuration variables
@ -55,14 +62,14 @@ DEFAULT_LINK_PRIORITY = ['internal','other','frameworks','user','system']
pretty_dep_names = {
'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki//OCCI',
'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',
'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/OGR',
'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
'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 required 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',
'pg':'Postgres C Library required 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',
@ -73,10 +80,11 @@ pretty_dep_names = {
'pkg-config':'pkg-config tool | more info: http://pkg-config.freedesktop.org',
'pg_config':'pg_config program | try setting PG_CONFIG SCons option',
'xml2-config':'xml2-config program | try setting XML2_CONFIG SCons option',
'libxml2':'libxml2 library | try setting XML2_CONFIG SCons option to point to location of xml2-config program',
'gdal-config':'gdal-config program | try setting GDAL_CONFIG SCons option',
'freetype-config':'freetype-config program | try setting FREETYPE_CONFIG SCons option',
'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',
'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)'
@ -95,22 +103,28 @@ PLUGINS = { # plugins with external dependencies
'rasterlite': {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'},
# todo: osm plugin does also depend on libxml2 (but there is a separate check for that)
'osm': {'default':True,'path':None,'inc':'curl/curl.h','lib':'curl','lang':'C'},
'osm': {'default':False,'path':None,'inc':'curl/curl.h','lib':'curl','lang':'C'},
# plugins without external dependencies requiring CheckLibWithHeader...
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'geojson': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
'python': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
'python': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
}
#### SCons build options and initial setup ####
env = Environment(ENV=os.environ)
def init_environment(env):
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
if os.environ.get('RANLIB'):
env['RANLIB'] = os.environ['RANLIB']
if os.environ.get('AR'):
env['AR'] = os.environ['AR']
#### SCons build options and initial setup ####
env = Environment(ENV=os.environ)
init_environment(env)
def color_print(color,text,newline=True):
# 1 - red
@ -167,10 +181,14 @@ def shortest_name(libs):
name = lib
return name
def rm_path(item,set,_env):
for i in _env[set]:
if item in i:
_env[set].remove(i)
def sort_paths(items,priority):
"""Sort paths such that compiling and linking will globally prefer custom or local libs
over system libraries by fixing up the order libs are passed to gcc and the linker.
over system libraries by fixing up the order libs are passed to the compiler and the linker.
Ideally preference could be by-target instead of global, but our SCons implementation
is not currently utilizing different SCons build env()'s as we should.
@ -240,7 +258,7 @@ def pretty_dep(dep):
if pretty:
return '%s (%s)' % (dep,pretty)
elif 'boost' in dep:
return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki//MapnikInstallation & http://www.boost.org')
return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation & http://www.boost.org')
return dep
@ -255,15 +273,15 @@ opts = Variables()
opts.AddVariables(
# Compiler options
('CXX', 'The C++ compiler to use to compile mapnik (defaults to g++).', 'g++'),
('CC', 'The C compiler used for configure checks of C libs (defaults to gcc).', 'gcc'),
('CXX', 'The C++ compiler to use to compile mapnik', DEFAULT_CXX),
('CC', 'The C compiler used for configure checks of C libs.', DEFAULT_CC),
('CUSTOM_CXXFLAGS', 'Custom C++ flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir>', ''),
('CUSTOM_DEFINES', 'Custom Compiler DEFINES, e.g. -DENABLE_THIS', ''),
('CUSTOM_CFLAGS', 'Custom C flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> (only used for configure checks)', ''),
('CUSTOM_LDFLAGS', 'Custom linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir>', ''),
EnumVariable('LINKING', "Set library format for libmapnik",'shared', ['shared','static']),
EnumVariable('RUNTIME_LINK', "Set preference for linking dependencies",'shared', ['shared','static']),
EnumVariable('OPTIMIZATION','Set g++ optimization level','3', ['0','1','2','3','4','s']),
EnumVariable('OPTIMIZATION','Set compiler optimization level','3', ['0','1','2','3','4','s']),
# Note: setting DEBUG=True will override any custom OPTIMIZATION level
BoolVariable('DEBUG', 'Compile a debug version of Mapnik', 'False'),
BoolVariable('DEBUG_UNDEFINED', 'Compile a version of Mapnik using clang/llvm undefined behavior asserts', 'False'),
@ -286,7 +304,7 @@ opts.AddVariables(
('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)', ''),
('PATH_REMOVE', 'A path prefix to exclude from all known command and compile paths', ''),
('PATH_REMOVE', 'A path prefix to exclude from all known command and compile paths (create multiple excludes separated by :)', ''),
('PATH_REPLACE', 'Two path prefixes (divided with a :) to search/replace from all known command and compile paths', ''),
# Boost variables
@ -304,8 +322,8 @@ opts.AddVariables(
('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_DEFAULT, PathVariable.PathAccept),
('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc',
PathVariable.PathAccept),
('ICU_LIB_NAME', 'The library name for icu (such as icuuc, sicuuc, or icucore)', 'icuuc', PathVariable.PathAccept),
BoolVariable('PNG', 'Build Mapnik with PNG read and write support', 'True'),
PathVariable('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include', PathVariable.PathAccept),
PathVariable('PNG_LIBS','Search path for libpng library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
@ -315,7 +333,7 @@ PathVariable.PathAccept),
BoolVariable('TIFF', 'Build Mapnik with TIFF read and write support', 'True'),
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_DEFAULT, PathVariable.PathAccept),
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'False'),
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'True'),
PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept),
PathVariable('WEBP_LIBS','Search path for libwebp library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
BoolVariable('PROJ', 'Build Mapnik with proj4 support to enable transformations between many different projections', 'True'),
@ -325,10 +343,10 @@ PathVariable.PathAccept),
# Variables affecting rendering back-ends
BoolVariable('RENDERING_STATS', 'Output rendering statistics during style processing', 'False'),
BoolVariable('GRID_RENDERER', 'build support for native grid renderer', 'True'),
BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'),
BoolVariable('CPP_TESTS', 'Compile the C++ tests', 'True'),
BoolVariable('BENCHMARK', 'Compile the C++ benchmark scripts', 'False'),
# Variables for optional dependencies
# Note: cairo and and pycairo are optional but configured automatically through pkg-config
@ -350,6 +368,9 @@ PathVariable.PathAccept),
BoolVariable('ENABLE_STATS', 'Enable global statistics during map processing', 'False'),
('DEFAULT_LOG_SEVERITY', 'The default severity of the logger (eg. ' + ', '.join(severities) + ')', 'error'),
# Plugin linking
EnumVariable('PLUGIN_LINKING', "Set plugin linking with libmapnik", 'shared', ['shared','static']),
# Other variables
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
('SYSTEM_FONTS','Provide location for python bindings to register fonts (if provided then the bundled DejaVu fonts are not installed)',''),
@ -397,6 +418,7 @@ pickle_store = [# Scons internal variables
'PLUGINS',
'ABI_VERSION',
'MAPNIK_VERSION_STRING',
'MAPNIK_VERSION',
'PLATFORM',
'BOOST_ABI',
'BOOST_APPEND',
@ -431,12 +453,14 @@ pickle_store = [# Scons internal variables
'LIBMAPNIK_DEFINES',
'LIBMAPNIK_CXXFLAGS',
'CAIRO_LIBPATHS',
'CAIRO_LINKFLAGS',
'CAIRO_ALL_LIBS',
'CAIRO_CPPPATHS',
'GRID_RENDERER',
'SVG_RENDERER',
'SQLITE_LINKFLAGS',
'BOOST_LIB_VERSION_FROM_HEADER',
'BIGINT'
'BIGINT',
'HOST'
]
# Add all other user configurable options to pickle pickle_store
@ -598,6 +622,10 @@ def get_pkg_lib(context, config, lib):
if ret:
try:
value = call(cmd,silent=True)
if ' ' in value:
parts = value.split(' ')
if len(parts) > 1:
value = parts[1]
libnames = re.findall(libpattern,value)
if libnames:
libname = libnames[0]
@ -726,25 +754,23 @@ def FindBoost(context, prefixes, thread_flag):
msg = str()
if BOOST_LIB_DIR:
msg += '\n *libs found: %s' % BOOST_LIB_DIR
msg += '\nFound boost libs: %s' % BOOST_LIB_DIR
env['BOOST_LIBS'] = BOOST_LIB_DIR
else:
env['BOOST_LIBS'] = '/usr/' + env['LIBDIR_SCHEMA']
msg += '\n *using default boost lib dir: %s' % env['BOOST_LIBS']
msg += '\nUsing default boost lib dir: %s' % env['BOOST_LIBS']
if BOOST_INCLUDE_DIR:
msg += '\n *headers found: %s' % BOOST_INCLUDE_DIR
msg += '\nFound boost headers: %s' % BOOST_INCLUDE_DIR
env['BOOST_INCLUDES'] = BOOST_INCLUDE_DIR
else:
env['BOOST_INCLUDES'] = '/usr/include'
msg += '\n *using default boost include dir: %s' % env['BOOST_INCLUDES']
msg += '\nUsing default boost include dir: %s' % env['BOOST_INCLUDES']
if not env['BOOST_TOOLKIT'] and not env['BOOST_ABI'] and not env['BOOST_VERSION']:
if BOOST_APPEND:
msg += '\n *lib naming extension found: %s' % BOOST_APPEND
msg += '\nFound boost lib name extension: %s' % BOOST_APPEND
env['BOOST_APPEND'] = BOOST_APPEND
else:
msg += '\n *no lib naming extension found'
else:
# Creating BOOST_APPEND according to the Boost library naming order,
# which goes <toolset>-<threading>-<abi>-<version>. See:
@ -759,7 +785,7 @@ def FindBoost(context, prefixes, thread_flag):
# Boost libraries.
if len(append_params) > 1:
env['BOOST_APPEND'] = '-'.join(append_params)
msg += '\n *using boost lib naming: %s' % env['BOOST_APPEND']
msg += '\nFound boost lib name extension: %s' % env['BOOST_APPEND']
env.AppendUnique(CPPPATH = os.path.realpath(env['BOOST_INCLUDES']))
env.AppendUnique(LIBPATH = os.path.realpath(env['BOOST_LIBS']))
@ -796,6 +822,32 @@ int main()
context.Result(ret)
return ret
def CheckCairoHasFreetype(context, silent=False):
if not silent:
context.Message('Checking for cairo freetype font support ... ')
context.env.AppendUnique(CPPPATH=copy(env['CAIRO_CPPPATHS']))
ret = context.TryRun("""
#include <cairo-features.h>
int main()
{
#ifdef CAIRO_HAS_FT_FONT
return 0;
#else
return 1;
#endif
}
""", '.cpp')[0]
if silent:
context.did_show_result=1
context.Result(ret)
for item in env['CAIRO_CPPPATHS']:
rm_path(item,'CPPPATH',context.env)
return ret
def GetBoostLibVersion(context):
ret = context.TryRun("""
@ -866,8 +918,7 @@ int main()
def boost_regex_has_icu(context):
if env['RUNTIME_LINK'] == 'static':
context.env.Append(LIBS='icui18n')
context.env.Append(LIBS='icudata')
context.env.AppendUnique(LIBS='icudata')
ret = context.TryRun("""
#include <boost/regex/icu.hpp>
@ -875,7 +926,7 @@ def boost_regex_has_icu(context):
int main()
{
UnicodeString ustr;
U_NAMESPACE_QUALIFIER UnicodeString ustr;
try {
boost::u32regex pattern = boost::make_u32regex(ustr);
}
@ -894,7 +945,7 @@ int main()
return True
return False
def sqlite_has_rtree(context):
def sqlite_has_rtree(context, silent=False):
""" check an sqlite3 install has rtree support.
PRAGMA compile_options;
@ -931,7 +982,10 @@ int main()
}
""", '.c')
if not silent:
context.Message('Checking if SQLite supports RTREE... ')
if silent:
context.did_show_result=1
context.Result(ret[0])
if ret[0]:
return True
@ -943,6 +997,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths,
'CheckPKGVersion' : CheckPKGVersion,
'FindBoost' : FindBoost,
'CheckBoost' : CheckBoost,
'CheckCairoHasFreetype' : CheckCairoHasFreetype,
'GetBoostLibVersion' : GetBoostLibVersion,
'GetMapnikLibVersion' : GetMapnikLibVersion,
'parse_config' : parse_config,
@ -984,8 +1039,7 @@ if not preconfigured:
color_print(1,"SCons CONFIG not found: '%s'" % conf)
# Recreate the base environment using modified `opts`
env = Environment(ENV=os.environ,options=opts)
env.Decider('MD5-timestamp')
env.SourceCode(".", None)
init_environment(env)
env['USE_CONFIG'] = True
else:
color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...')
@ -1004,11 +1058,12 @@ if not preconfigured:
env['SKIPPED_DEPS'] = []
env['HAS_CAIRO'] = False
env['CAIRO_LIBPATHS'] = []
env['CAIRO_LINKFLAGS'] = []
env['CAIRO_ALL_LIBS'] = []
env['CAIRO_CPPPATHS'] = []
env['HAS_PYCAIRO'] = False
env['HAS_LIBXML2'] = False
env['LIBMAPNIK_LIBS'] = []
env['LIBMAPNIK_LINKFLAGS'] = []
env['LIBMAPNIK_CPPATHS'] = []
env['LIBMAPNIK_DEFINES'] = []
env['LIBMAPNIK_CXXFLAGS'] = []
@ -1087,7 +1142,7 @@ if not preconfigured:
SOLARIS = env['PLATFORM'] == 'SunOS'
env['SUNCC'] = SOLARIS and env['CXX'].startswith('CC')
# If the Sun Studio C++ compiler (`CC`) is used instead of GCC.
# If the Sun Studio C++ compiler (`CC`) is used instead of gcc.
if env['SUNCC']:
env['CC'] = 'cc'
# To be compatible w/Boost everything needs to be compiled
@ -1134,15 +1189,18 @@ if not preconfigured:
# https://github.com/mapnik/mapnik/issues/913
if conf.parse_config('XML2_CONFIG',checks='--cflags'):
env['HAS_LIBXML2'] = True
else:
env['MISSING_DEPS'].append('libxml2')
LIBSHEADERS = [
REQUIRED_LIBSHEADERS = [
['z', 'zlib.h', True,'C'],
[env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'],
]
OPTIONAL_LIBSHEADERS = []
if env['JPEG']:
env.Append(CPPDEFINES = '-DHAVE_JPEG')
LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], True,'C'])
OPTIONAL_LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], False,'C','-DHAVE_JPEG'])
inc_path = env['%s_INCLUDES' % 'JPEG']
lib_path = env['%s_LIBS' % 'JPEG']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
@ -1151,8 +1209,7 @@ if not preconfigured:
env['SKIPPED_DEPS'].extend(['jpeg'])
if env['PROJ']:
env.Append(CPPDEFINES = '-DMAPNIK_USE_PROJ4')
LIBSHEADERS.append(['proj', 'proj_api.h', True,'C'])
OPTIONAL_LIBSHEADERS.append(['proj', 'proj_api.h', False,'C','-DMAPNIK_USE_PROJ4'])
inc_path = env['%s_INCLUDES' % 'PROJ']
lib_path = env['%s_LIBS' % 'PROJ']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
@ -1161,8 +1218,7 @@ if not preconfigured:
env['SKIPPED_DEPS'].extend(['proj'])
if env['PNG']:
env.Append(CPPDEFINES = '-DHAVE_PNG')
LIBSHEADERS.append(['png', 'png.h', True,'C'])
OPTIONAL_LIBSHEADERS.append(['png', 'png.h', False,'C','-DHAVE_PNG'])
inc_path = env['%s_INCLUDES' % 'PNG']
lib_path = env['%s_LIBS' % 'PNG']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
@ -1171,9 +1227,7 @@ if not preconfigured:
env['SKIPPED_DEPS'].extend(['png'])
if env['WEBP']:
env.Append(CPPDEFINES = '-DHAVE_WEBP')
LIBSHEADERS.append(['webp', 'webp/decode.h', True,'C'])
LIBSHEADERS.append(['webp', 'webp/encode.h', True,'C'])
OPTIONAL_LIBSHEADERS.append(['webp', 'webp/decode.h', False,'C','-DHAVE_WEBP'])
inc_path = env['%s_INCLUDES' % 'WEBP']
lib_path = env['%s_LIBS' % 'WEBP']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
@ -1181,10 +1235,8 @@ if not preconfigured:
else:
env['SKIPPED_DEPS'].extend(['webp'])
if env['TIFF']:
env.Append(CPPDEFINES = '-DHAVE_TIFF')
LIBSHEADERS.append(['tiff', 'tiff.h', True,'C'])
OPTIONAL_LIBSHEADERS.append(['tiff', 'tiff.h', False,'C','-DHAVE_TIFF'])
inc_path = env['%s_INCLUDES' % 'TIFF']
lib_path = env['%s_LIBS' % 'TIFF']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
@ -1194,10 +1246,10 @@ if not preconfigured:
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
if env['PRIORITIZE_LINKING']:
conf.prioritize_paths(silent=False)
conf.prioritize_paths(silent=True)
if not env['HOST']:
for libname, headers, required, lang in LIBSHEADERS:
for libname, headers, required, lang in REQUIRED_LIBSHEADERS:
if not conf.CheckLibWithHeader(libname, headers, lang):
if required:
color_print(1, 'Could not find required header or shared library for %s' % libname)
@ -1222,6 +1274,14 @@ if not preconfigured:
conf.FindBoost(BOOST_SEARCH_PREFIXES,thread_flag)
has_boost_devel = True
if not env['HOST']:
if not conf.CheckHeader(header='boost/version.hpp',language='C++'):
env['MISSING_DEPS'].append('boost development headers')
has_boost_devel = False
if has_boost_devel:
if not env['HOST']:
env['BOOST_LIB_VERSION_FROM_HEADER'] = conf.GetBoostLibVersion()
# The other required boost headers.
@ -1243,7 +1303,7 @@ if not preconfigured:
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
if env['PRIORITIZE_LINKING']:
conf.prioritize_paths()
conf.prioritize_paths(silent=True)
if not env['HOST']:
# if the user is not setting custom boost configuration
@ -1266,17 +1326,46 @@ if not preconfigured:
color_print(4,'Could not find optional header or shared library for boost %s' % libinfo[0])
env['SKIPPED_DEPS'].append('boost ' + libinfo[0])
if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']:
if not env['HOST'] and env['ICU_LIB_NAME'] not in env['MISSING_DEPS']:
# http://lists.boost.org/Archives/boost/2009/03/150076.php
# we need libicui18n if using static boost libraries, so it is
# important to try this check with the library linked
env.AppendUnique(LIBS='icui18n')
if conf.boost_regex_has_icu():
# TODO - should avoid having this be globally defined...
env.Append(CPPDEFINES = '-DBOOST_REGEX_HAS_ICU')
else:
env['SKIPPED_DEPS'].append('boost_regex_icu')
for libname, headers, required, lang, define in OPTIONAL_LIBSHEADERS:
if not env['HOST']:
if not conf.CheckLibWithHeader(libname, headers, lang):
if required:
color_print(1, 'Could not find required header or shared library for %s' % libname)
env['MISSING_DEPS'].append(libname)
else:
color_print(4, 'Could not find optional header or shared library for %s' % libname)
env['SKIPPED_DEPS'].append(libname)
else:
env.Append(CPPDEFINES = define)
else:
env.Append(CPPDEFINES = define)
env['REQUESTED_PLUGINS'] = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])]
SQLITE_HAS_RTREE = None
if env['HOST']:
SQLITE_HAS_RTREE = True
CHECK_PKG_CONFIG = conf.CheckPKGConfig('0.15.0')
if len(env['REQUESTED_PLUGINS']):
if env['HOST']:
for plugin in env['REQUESTED_PLUGINS']:
details = env['PLUGINS'][plugin]
if details['lib']:
env.AppendUnique(LIBS=details['lib'])
else:
color_print(4,'Checking for requested plugins dependencies...')
for plugin in env['REQUESTED_PLUGINS']:
details = env['PLUGINS'][plugin]
@ -1285,6 +1374,11 @@ if not preconfigured:
conf.parse_config('GDAL_CONFIG',checks='--cflags')
libname = conf.get_pkg_lib('GDAL_CONFIG','gdal')
if libname:
if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']):
env['SKIPPED_DEPS'].append('gdal')
if libname in env['LIBS']:
env['LIBS'].remove(libname)
else:
details['lib'] = libname
elif plugin == 'postgis':
conf.parse_pg_config('PG_CONFIG')
@ -1295,6 +1389,12 @@ if not preconfigured:
conf.parse_config('GDAL_CONFIG',checks='--cflags')
libname = conf.get_pkg_lib('GDAL_CONFIG','ogr')
if libname:
if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']):
if 'gdal' not in env['SKIPPED_DEPS']:
env['SKIPPED_DEPS'].append('gdal')
if libname in env['LIBS']:
env['LIBS'].remove(libname)
else:
details['lib'] = libname
elif details['path'] and details['lib'] and details['inc']:
backup = env.Clone().Dictionary()
@ -1309,11 +1409,10 @@ if not preconfigured:
env['SKIPPED_DEPS'].append(details['lib'])
if plugin == 'sqlite':
sqlite_backup = env.Clone().Dictionary()
# if statically linking, on linux we likely
# need to link sqlite to pthreads and dl
if env['RUNTIME_LINK'] == 'static':
if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('sqlite3'):
if CHECK_PKG_CONFIG and conf.CheckPKG('sqlite3'):
sqlite_env = env.Clone()
try:
sqlite_env.ParseConfig('pkg-config --static --libs sqlite3')
@ -1323,15 +1422,14 @@ if not preconfigured:
env.Append(LIBS=lib)
except OSError,e:
pass
if not conf.sqlite_has_rtree():
SQLITE_HAS_RTREE = conf.sqlite_has_rtree()
if not SQLITE_HAS_RTREE:
env.Replace(**sqlite_backup)
if details['lib'] in env['LIBS']:
env['LIBS'].remove(details['lib'])
env['SKIPPED_DEPS'].append('sqlite_rtree')
else:
env.Replace(**sqlite_backup)
elif details['lib'] and details['inc']:
if not conf.CheckLibWithHeader(details['lib'], details['inc'], details['lang']):
env['SKIPPED_DEPS'].append(details['lib'])
@ -1342,12 +1440,13 @@ if not preconfigured:
env.PrependUnique(CPPPATH = '#', delete_existing=True)
env.PrependUnique(LIBPATH = '#src', delete_existing=True)
if not env['HOST']:
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():
if not SQLITE_HAS_RTREE:
env['SKIPPED_DEPS'].append('pgsql2sqlite_rtree')
env['PGSQL2SQLITE'] = False
@ -1378,15 +1477,15 @@ if not preconfigured:
#os.path.join(c_inc,'include/libpng'),
]
)
env["CAIRO_LINKFLAGS"] = ['cairo']
env["CAIRO_ALL_LIBS"] = ['cairo']
if env['RUNTIME_LINK'] == 'static':
env["CAIRO_LINKFLAGS"].extend(
['pixman-1','expat','fontconfig','iconv']
env["CAIRO_ALL_LIBS"].extend(
['pixman-1','expat','fontconfig']
)
# todo - run actual checkLib?
env['HAS_CAIRO'] = True
else:
if not conf.CheckPKGConfig('0.15.0'):
if not CHECK_PKG_CONFIG:
env['HAS_CAIRO'] = False
env['SKIPPED_DEPS'].append('pkg-config')
env['SKIPPED_DEPS'].append('cairo')
@ -1403,7 +1502,7 @@ if not preconfigured:
cairo_env.ParseConfig(cmd)
for lib in cairo_env['LIBS']:
if not lib in env['LIBS']:
env["CAIRO_LINKFLAGS"].append(lib)
env["CAIRO_ALL_LIBS"].append(lib)
for lpath in cairo_env['LIBPATH']:
if not lpath in env['LIBPATH']:
env["CAIRO_LIBPATHS"].append(lpath)
@ -1420,6 +1519,11 @@ if not preconfigured:
else:
color_print(4,'Not building with cairo support, pass CAIRO=True to enable')
if not env['HOST'] and env['HAS_CAIRO']:
if not conf.CheckCairoHasFreetype():
env['SKIPPED_DEPS'].append('cairo')
env['HAS_CAIRO'] = False
if 'python' in env['BINDINGS'] or 'python' in env['REQUESTED_PLUGINS']:
if not os.access(env['PYTHON'], os.X_OK):
color_print(1,"Cannot run python interpreter at '%s', make sure that you have the permissions to execute it." % env['PYTHON'])
@ -1482,7 +1586,7 @@ if not preconfigured:
else:
env['PYTHON_IS_64BIT'] = False
if 'python' in env['BINDINGS']:
if has_boost_devel and 'python' in env['BINDINGS']:
if py3 and env['BOOST_PYTHON_LIB'] == 'boost_python':
env['BOOST_PYTHON_LIB'] = 'boost_python3%s' % env['BOOST_APPEND']
elif env['BOOST_PYTHON_LIB'] == 'boost_python':
@ -1493,7 +1597,7 @@ if not preconfigured:
env['MISSING_DEPS'].append('boost python')
if env['CAIRO']:
if conf.CheckPKGConfig('0.15.0') and conf.CheckPKG('pycairo'):
if CHECK_PKG_CONFIG and conf.CheckPKG('pycairo'):
env['HAS_PYCAIRO'] = True
else:
env['SKIPPED_DEPS'].extend(['pycairo'])
@ -1515,7 +1619,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: https://github.com/mapnik/mapnik/wiki//MapnikInstallation')
color_print(4,'More info: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation')
if not HELP_REQUESTED:
Exit(1)
else:
@ -1535,19 +1639,24 @@ if not preconfigured:
color_print(4,"Did not use user config file, no custom path variables will be saved...")
if env['SKIPPED_DEPS']:
color_print(3,'\nNote: will build without these OPTIONAL dependencies:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']]))
color_print(4,'\nNote: will build without these OPTIONAL dependencies:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']]))
print
# fetch the mapnik version header in order to set the
# ABI version used to build libmapnik.so on linux in src/build.py
abi = None
abi_fallback = "3.0.0-pre"
if not env['HOST']:
abi = conf.GetMapnikLibVersion()
abi_fallback = "2.2.0-pre"
if not abi:
if not env['HOST']:
color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback)
abi = abi_fallback
env['ABI_VERSION'] = abi.replace('-pre','').split('.')
abi_no_pre = abi.replace('-pre','').split('.')
env['ABI_VERSION'] = abi_no_pre
env['MAPNIK_VERSION_STRING'] = abi
env['MAPNIK_VERSION'] = str(int(abi_no_pre[0])*100000+int(abi_no_pre[1])*100+int(abi_no_pre[2]))
# Common DEFINES.
env.Append(CPPDEFINES = '-D%s' % env['PLATFORM'].upper())
@ -1566,6 +1675,16 @@ if not preconfigured:
debug_defines = ['-DDEBUG', '-DMAPNIK_DEBUG']
ndebug_defines = ['-DNDEBUG']
# c++11 support / https://github.com/mapnik/mapnik/issues/1683
# - upgrade to PHOENIX_V3 since that is needed for c++11 compile
if 'c++11' in env['CUSTOM_CXXFLAGS']:
env.Append(CPPDEFINES = '-DBOOST_SPIRIT_USE_PHOENIX_V3=1')
# - workaround boost gil channel_algorithm.hpp narrowing error
# TODO - remove when building against >= 1.55
# https://github.com/mapnik/mapnik/issues/1970
if 'clang++' in env['CXX']:
env.Append(CXXFLAGS = '-Wno-c++11-narrowing')
# Enable logging in debug mode (always) and release mode (when specified)
if env['DEFAULT_LOG_SEVERITY']:
if env['DEFAULT_LOG_SEVERITY'] not in severities:
@ -1604,13 +1723,19 @@ if not preconfigured:
env.Append(CPPDEFINES = ndebug_defines)
if not env['SUNCC']:
# Common flags for GCC.
gcc_cxx_flags = '-Wall %s %s -ftemplate-depth-300 ' % (env['WARNING_CXXFLAGS'], pthread)
if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline')
else:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -fvisibility-inlines-hidden -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts' % (env['OPTIMIZATION']))
# Common flags for CXX compiler.
common_cxx_flags = '-Wall %s %s -ftemplate-depth-300 ' % (env['WARNING_CXXFLAGS'], pthread)
# https://github.com/mapnik/mapnik/issues/1835
if sys.platform == 'darwin' and env['CXX'] == 'g++':
common_cxx_flags += '-fpermissive '
if env['DEBUG']:
env.Append(CXXFLAGS = common_cxx_flags + '-O0 -fno-inline')
else:
# TODO - add back -fvisibility-inlines-hidden
# https://github.com/mapnik/mapnik/issues/1863
env.Append(CXXFLAGS = common_cxx_flags + '-O%s -fno-strict-aliasing -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts' % (env['OPTIMIZATION']))
if env['DEBUG_UNDEFINED']:
env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv')
@ -1639,7 +1764,7 @@ if not preconfigured:
# if requested, sort LIBPATH and CPPPATH one last time before saving...
if env['PRIORITIZE_LINKING']:
conf.prioritize_paths()
conf.prioritize_paths(silent=True)
# finish config stage and pickle results
env = conf.Finish()
@ -1694,18 +1819,14 @@ if not HELP_REQUESTED:
env['ENV']['PATH'] = os.path.realpath(env['PATH']) + ':' + env['ENV']['PATH']
if env['PATH_REMOVE']:
p = env['PATH_REMOVE']
for p in env['PATH_REMOVE'].split(':'):
if p in env['ENV']['PATH']:
env['ENV']['PATH'].replace(p,'')
def rm_path(set):
for i in env[set]:
if p in i:
env[set].remove(i)
rm_path('LIBPATH')
rm_path('CPPPATH')
rm_path('CXXFLAGS')
rm_path('CAIRO_LIBPATHS')
rm_path('CAIRO_CPPPATHS')
rm_path(p,'LIBPATH',env)
rm_path(p,'CPPPATH',env)
rm_path(p,'CXXFLAGS',env)
rm_path(p,'CAIRO_LIBPATHS',env)
rm_path(p,'CAIRO_CPPPATHS',env)
if env['PATH_REPLACE']:
searches,replace = env['PATH_REPLACE'].split(':')
@ -1728,8 +1849,6 @@ if not HELP_REQUESTED:
Export('env')
plugin_base = env.Clone()
#plugin_base.Append(CXXFLAGS='-fvisibility=hidden')
#plugin_base.Append(CXXFLAGS='-fvisibility-inlines-hidden')
Export('plugin_base')
@ -1759,9 +1878,14 @@ if not HELP_REQUESTED:
# Build the requested and able-to-be-compiled input plug-ins
GDAL_BUILT = False
OGR_BUILT = False
for plugin in env['REQUESTED_PLUGINS']:
for plugin in env['PLUGINS']:
if env['PLUGIN_LINKING'] == 'static' or plugin not in env['REQUESTED_PLUGINS']:
if os.path.exists('plugins/input/%s.input' % plugin):
os.unlink('plugins/input/%s.input' % plugin)
elif plugin in env['REQUESTED_PLUGINS']:
details = env['PLUGINS'][plugin]
if details['lib'] in env['LIBS']:
if env['PLUGIN_LINKING'] == 'shared':
SConscript('plugins/input/%s/build.py' % plugin)
if plugin == 'ogr': OGR_BUILT = True
if plugin == 'gdal': GDAL_BUILT = True
@ -1771,43 +1895,47 @@ if not HELP_REQUESTED:
else:
env['LIBS'].remove(details['lib'])
elif not details['lib']:
# build internal shape and raster plugins
if env['PLUGIN_LINKING'] == 'shared':
# build internal datasource input plugins
SConscript('plugins/input/%s/build.py' % plugin)
else:
color_print(1,"Notice: dependencies not met for plugin '%s', not building..." % plugin)
# also clear out locally built target
if os.path.exists('plugins/input/%s.input' % plugin):
os.unlink('plugins/input/%s.input' % plugin)
create_uninstall_target(env, env['MAPNIK_LIB_DIR_DEST'], False)
create_uninstall_target(env, env['MAPNIK_INPUT_PLUGINS_DEST'] , False)
if 'install' in COMMAND_LINE_TARGETS:
# if statically linking plugins still make sure
# to create the dynamic plugins directory
if env['PLUGIN_LINKING'] == 'static':
if not os.path.exists(env['MAPNIK_INPUT_PLUGINS_DEST']):
os.makedirs(env['MAPNIK_INPUT_PLUGINS_DEST'])
# before installing plugins, wipe out any previously
# installed plugins that we are no longer building
if 'install' in COMMAND_LINE_TARGETS:
for plugin in PLUGINS.keys():
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(3,"Notice: removing out of date plugin: '%s'" % plugin_path)
if plugin not in env['REQUESTED_PLUGINS'] or env['PLUGIN_LINKING'] == 'static':
color_print(4,"Notice: removing out of date plugin: '%s'" % plugin_path)
os.unlink(plugin_path)
# Build the c++ rundemo app if requested
if not env['HOST']:
if env['DEMO']:
SConscript('demo/c++/build.py')
# Build shapeindex and remove its dependency from the LIBS
if not env['HOST']:
if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']:
if env['SHAPEINDEX']:
SConscript('utils/shapeindex/build.py')
# Build the pgsql2psqlite app if requested
if env['PGSQL2SQLITE']:
SConscript('utils/pgsql2sqlite/build.py')
if env['SVG2PNG']:
SConscript('utils/svg2png/build.py')
# devtools not ready for public
#SConscript('utils/ogrindex/build.py')
env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND'])
@ -1828,12 +1956,12 @@ if not HELP_REQUESTED:
SConscript('fonts/build.py')
# build C++ tests
if env['CPP_TESTS']:
SConscript('tests/cpp_tests/build.py')
if env['SVG_RENDERER']:
if env['CPP_TESTS'] and env['SVG_RENDERER']:
SConscript('tests/cpp_tests/svg_renderer_tests/build.py')
if env['BENCHMARK']:
SConscript('benchmark/build.py')
# install pkg-config script and mapnik-config script
@ -1845,11 +1973,14 @@ 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:
else:
if '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)
color_print(4,"Notice: removing out of date plugin: '%s'" % plugin_path)
os.unlink(plugin_path)
if os.path.exists('plugins/input/templates/hello.input'):
os.unlink('plugins/input/templates/hello.input')
# update linux project files
if env['PLATFORM'] == 'Linux':

View file

@ -12,7 +12,7 @@
#include <sstream>
#include <cstdio>
#include <set>
#include <memory>
#include <stdexcept>
// boost
#include <boost/version.hpp>
@ -265,7 +265,7 @@ struct test5
s.resize(s.capacity());
while (true)
{
size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%g", val_));
size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%g", val));
if (n2 <= s.size())
{
s.resize(n2);
@ -790,7 +790,10 @@ int main( int argc, char** argv)
}
{
mapnik::freetype_engine::register_fonts("./fonts", true);
bool success = mapnik::freetype_engine::register_fonts("./fonts", true);
if (!success) {
std::clog << "warning, did not register any new fonts!\n";
}
unsigned face_count = mapnik::freetype_engine::face_names().size();
test13 runner(1000,10);
benchmark(runner, (boost::format("font_engihe: created %ld faces in ") % (face_count * 1000 * 10)).str());

View file

@ -1,7 +1,7 @@
#
# This file is part of Mapnik (c++ mapping toolkit)
#
# Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
# Copyright (C) 2013 Artem Pavlenko
#
# Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@ -43,20 +43,23 @@ prefix = env['PREFIX']
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
libraries = ['mapnik',env['BOOST_PYTHON_LIB']]
py_env = env.Clone()
py_env.Append(CPPPATH = env['PYTHON_INCLUDES'])
py_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
py_env['LIBS'] = ['mapnik',env['BOOST_PYTHON_LIB']]
link_all_libs = env['LINKING'] == 'static' or env['RUNTIME_LINK'] == 'static' or (env['PLATFORM'] == 'Darwin' and not env['PYTHON_DYNAMIC_LOOKUP'])
if link_all_libs:
py_env.AppendUnique(LIBS=env['LIBMAPNIK_LIBS'])
if env['RUNTIME_LINK'] == 'static' and env['PLATFORM'] == 'Linux':
py_env.AppendUnique(LIBS='rt')
# TODO - do solaris/fedora need direct linking too?
if env['PLATFORM'] == 'Darwin':
if not env['PYTHON_DYNAMIC_LOOKUP']:
if env['PNG']:
libraries.append('png')
if env['JPEG']:
libraries.append('jpeg')
libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
if env['THREADING'] == 'multi':
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
##### Python linking on OS X is tricky ###
# Confounding problems are:
# 1) likelyhood of multiple python installs of the same major.minor version
@ -96,7 +99,6 @@ if env['PLATFORM'] == 'Darwin':
else:
# should we fall back to -lpython here?
python_link_flag = '-F/ -framework Python'
# if we are not linking to a framework then use the *nix standard approach
else:
# TODO - do we need to pass -L/?
@ -147,9 +149,6 @@ except: pass
# 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')
@ -176,15 +175,15 @@ if 'uninstall' not in COMMAND_LINE_TARGETS:
if env['HAS_CAIRO']:
py_env.Append(CPPPATH = env['CAIRO_CPPPATHS'])
py_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
if env['PLATFORM'] == 'Darwin':
py_env.Append(LIBS=env['CAIRO_LINKFLAGS'])
if link_all_libs:
py_env.Append(LIBS=env['CAIRO_ALL_LIBS'])
if env['HAS_PYCAIRO']:
py_env.ParseConfig('pkg-config --cflags pycairo')
py_env.Append(CPPDEFINES = '-DHAVE_PYCAIRO')
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)
py_env.AppendUnique(LIBS = 'boost_thread%s' % env['BOOST_APPEND'])
_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)
Depends(_mapnik, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

View file

@ -340,6 +340,53 @@ def Shapefile(**keywords):
keywords['type'] = 'shape'
return CreateDatasource(keywords)
def CSV(**keywords):
"""Create a CSV Datasource.
Required keyword arguments:
file -- path to csv
Optional keyword arguments:
inline -- inline CSV string (if provided 'file' argument will be ignored and non-needed)
base -- path prefix (default None)
encoding -- file encoding (default 'utf-8')
row_limit -- integer limit of rows to return (default: 0)
strict -- throw an error if an invalid row is encountered
escape -- The escape character to use for parsing data
quote -- The quote character to use for parsing data
separator -- The separator character to use for parsing data
headers -- A comma separated list of header names that can be set to add headers to data that lacks them
filesize_max -- The maximum filesize in MB that will be accepted
>>> from mapnik import CSV
>>> csv = CSV(file='test.csv')
>>> from mapnik import CSV
>>> csv = CSV(inline='''wkt,Name\n"POINT (120.15 48.47)","Winthrop, WA"''')
For more information see https://github.com/mapnik/mapnik/wiki/CSV-Plugin
"""
keywords['type'] = 'csv'
return CreateDatasource(keywords)
def GeoJSON(**keywords):
"""Create a GeoJSON Datasource.
Required keyword arguments:
file -- path to json
Optional keyword arguments:
encoding -- file encoding (default 'utf-8')
base -- path prefix (default None)
>>> from mapnik import GeoJSON
>>> geojson = GeoJSON(file='test.json')
"""
keywords['type'] = 'geojson'
return CreateDatasource(keywords)
def PostGIS(**keywords):
"""Create a PostGIS Datasource.
@ -558,44 +605,6 @@ def Osm(**keywords):
keywords['type'] = 'osm'
return CreateDatasource(keywords)
def Kismet(**keywords):
"""Create a Kismet Datasource.
Required keyword arguments:
host -- kismet hostname
port -- kismet port
Optional keyword arguments:
encoding -- file encoding (default 'utf-8')
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')
>>> lyr = Layer('Kismet Server Layer')
>>> lyr.datasource = datasource
"""
keywords['type'] = 'kismet'
return CreateDatasource(keywords)
def Geos(**keywords):
"""Create a GEOS Vector Datasource.
Required keyword arguments:
wkt -- inline WKT text of the geometry
Optional keyword arguments:
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)')
>>> lyr = Layer('GEOS Layer from WKT string')
>>> lyr.datasource = datasource
"""
keywords['type'] = 'geos'
return CreateDatasource(keywords)
def Python(**keywords):
"""Create a Python Datasource.

View file

@ -61,7 +61,12 @@ boost::shared_ptr<mapnik::datasource> create_datasource(dict const& d)
PyObject* temp = PyUnicode_AsUTF8String(obj.ptr());
if (temp)
{
#if PY_VERSION_HEX >= 0x03000000
char* c_str = PyBytes_AsString(temp);
#else
char* c_str = PyString_AsString(temp);
#endif
params[key] = std::string(c_str);
Py_DecRef(temp);
}

View file

@ -0,0 +1,42 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#include <boost/python.hpp>
#include "mapnik_enumeration.hpp"
#include <mapnik/debug_symbolizer.hpp>
void export_debug_symbolizer()
{
using namespace boost::python;
mapnik::enumeration_<mapnik::debug_symbolizer_mode_e>("debug_symbolizer_mode")
.value("COLLISION",mapnik::DEBUG_SYM_MODE_COLLISION)
.value("VERTEX",mapnik::DEBUG_SYM_MODE_VERTEX)
;
class_<mapnik::debug_symbolizer>("DebugSymbolizer",
init<>("Default debug Symbolizer"))
.add_property("mode",
&mapnik::debug_symbolizer::get_mode,
&mapnik::debug_symbolizer::set_mode)
;
}

View file

@ -34,8 +34,6 @@
#include <mapnik/parse_path.hpp>
#include <mapnik/value.hpp>
using mapnik::Feature;
using mapnik::expression_ptr;
using mapnik::parse_expression;
using mapnik::to_expression_string;
@ -53,15 +51,15 @@ std::string expression_to_string_(mapnik::expr_node const& expr)
return mapnik::to_expression_string(expr);
}
mapnik::value expression_evaluate_(mapnik::expr_node const& expr, mapnik::Feature const& f)
mapnik::value expression_evaluate_(mapnik::expr_node const& expr, mapnik::feature_impl const& f)
{
// will be auto-converted to proper python type by `mapnik_value_to_python`
return boost::apply_visitor(mapnik::evaluate<mapnik::Feature,mapnik::value>(f),expr);
return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value>(f),expr);
}
bool expression_evaluate_to_bool_(mapnik::expr_node const& expr, mapnik::Feature const& f)
bool expression_evaluate_to_bool_(mapnik::expr_node const& expr, mapnik::feature_impl const& f)
{
return boost::apply_visitor(mapnik::evaluate<mapnik::Feature,mapnik::value>(f),expr).to_bool();
return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value>(f),expr).to_bool();
}
// path expression
@ -75,7 +73,7 @@ std::string path_to_string_(mapnik::path_expression const& expr)
return mapnik::path_processor_type::to_string(expr);
}
std::string path_evaluate_(mapnik::path_expression const& expr, mapnik::Feature const& f)
std::string path_evaluate_(mapnik::path_expression const& expr, mapnik::feature_impl const& f)
{
return mapnik::path_processor_type::evaluate(expr, f);
}

View file

@ -32,6 +32,7 @@
// mapnik
#include <mapnik/value_types.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/feature_kv_iterator.hpp>
@ -41,24 +42,27 @@
#include <mapnik/json/feature_parser.hpp>
#include <mapnik/json/geojson_generator.hpp>
// stl
#include <stdexcept>
namespace {
using mapnik::Feature;
using mapnik::geometry_utils;
using mapnik::from_wkt;
using mapnik::context_type;
using mapnik::context_ptr;
using mapnik::feature_kv_iterator;
mapnik::geometry_type const& (mapnik::Feature::*get_geometry_by_const_ref)(std::size_t) const = &mapnik::Feature::get_geometry;
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::Feature::*get_paths_by_const_ref)() const = &mapnik::Feature::paths;
mapnik::geometry_type const& (mapnik::feature_impl::*get_geometry_by_const_ref)(std::size_t) const = &mapnik::feature_impl::get_geometry;
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::feature_impl::*get_paths_by_const_ref)() const = &mapnik::feature_impl::paths;
void feature_add_geometries_from_wkb(Feature &feature, std::string wkb)
void feature_add_geometries_from_wkb(mapnik::feature_impl &feature, std::string wkb)
{
geometry_utils::from_wkb(feature.paths(), wkb.c_str(), wkb.size());
bool result = geometry_utils::from_wkb(feature.paths(), wkb.c_str(), wkb.size());
if (!result) throw std::runtime_error("Failed to parse WKB");
}
void feature_add_geometries_from_wkt(Feature &feature, std::string wkt)
void feature_add_geometries_from_wkt(mapnik::feature_impl &feature, std::string wkt)
{
bool result = mapnik::from_wkt(wkt, feature.paths());
if (!result) throw std::runtime_error("Failed to parse WKT");
@ -76,7 +80,7 @@ mapnik::feature_ptr from_geojson_impl(std::string const& json, mapnik::context_p
return feature;
}
std::string feature_to_geojson(Feature const& feature)
std::string feature_to_geojson(mapnik::feature_impl const& feature)
{
std::string json;
mapnik::json::feature_generator g;
@ -87,22 +91,22 @@ std::string feature_to_geojson(Feature const& feature)
return json;
}
mapnik::value __getitem__(Feature const& feature, std::string const& name)
mapnik::value __getitem__(mapnik::feature_impl const& feature, std::string const& name)
{
return feature.get(name);
}
mapnik::value __getitem2__(Feature const& feature, std::size_t index)
mapnik::value __getitem2__(mapnik::feature_impl const& feature, std::size_t index)
{
return feature.get(index);
}
void __setitem__(Feature & feature, std::string const& name, mapnik::value const& val)
void __setitem__(mapnik::feature_impl & feature, std::string const& name, mapnik::value const& val)
{
feature.put_new(name,val);
}
boost::python::dict attributes(Feature const& f)
boost::python::dict attributes(mapnik::feature_impl const& f)
{
boost::python::dict attributes;
feature_kv_iterator itr = f.begin();
@ -118,14 +122,14 @@ boost::python::dict attributes(Feature const& f)
} // end anonymous namespace
struct UnicodeString_from_python_str
struct unicode_string_from_python_str
{
UnicodeString_from_python_str()
unicode_string_from_python_str()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id<UnicodeString>());
boost::python::type_id<mapnik::value_unicode_string>());
}
static void* convertible(PyObject* obj_ptr)
@ -165,9 +169,9 @@ struct UnicodeString_from_python_str
}
if (value == 0) boost::python::throw_error_already_set();
void* storage = (
(boost::python::converter::rvalue_from_python_storage<UnicodeString>*)
(boost::python::converter::rvalue_from_python_storage<mapnik::value_unicode_string>*)
data)->storage.bytes;
new (storage) UnicodeString(value);
new (storage) mapnik::value_unicode_string(value);
data->convertible = storage;
}
};
@ -205,7 +209,6 @@ struct value_null_from_python
void export_feature()
{
using namespace boost::python;
using mapnik::Feature;
// Python to mapnik::value converters
// NOTE: order matters here. For example value_null must be listed before
@ -217,7 +220,7 @@ void export_feature()
implicitly_convertible<mapnik::value_bool,mapnik::value>();
// http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/
UnicodeString_from_python_str();
unicode_string_from_python_str();
value_null_from_python();
class_<context_type,context_ptr,boost::noncopyable>
@ -225,25 +228,25 @@ void export_feature()
.def("push", &context_type::push)
;
class_<Feature,boost::shared_ptr<Feature>,
class_<mapnik::feature_impl,boost::shared_ptr<mapnik::feature_impl>,
boost::noncopyable>("Feature",init<context_ptr,mapnik::value_integer>("Default ctor."))
.def("id",&Feature::id)
.def("__str__",&Feature::to_string)
.def("id",&mapnik::feature_impl::id)
.def("__str__",&mapnik::feature_impl::to_string)
.def("add_geometries_from_wkb", &feature_add_geometries_from_wkb)
.def("add_geometries_from_wkt", &feature_add_geometries_from_wkt)
.def("add_geometry", &Feature::add_geometry)
.def("num_geometries",&Feature::num_geometries)
.def("add_geometry", &mapnik::feature_impl::add_geometry)
.def("num_geometries",&mapnik::feature_impl::num_geometries)
.def("get_geometry", make_function(get_geometry_by_const_ref,return_value_policy<reference_existing_object>()))
.def("geometries",make_function(get_paths_by_const_ref,return_value_policy<reference_existing_object>()))
.def("envelope", &Feature::envelope)
.def("has_key", &Feature::has_key)
.def("envelope", &mapnik::feature_impl::envelope)
.def("has_key", &mapnik::feature_impl::has_key)
.add_property("attributes",&attributes)
.def("__setitem__",&__setitem__)
.def("__contains__",&__getitem__)
.def("__getitem__",&__getitem__)
.def("__getitem__",&__getitem2__)
.def("__len__", &Feature::size)
.def("context",&Feature::context)
.def("__len__", &mapnik::feature_impl::size)
.def("context",&mapnik::feature_impl::context)
.def("to_geojson",&feature_to_geojson)
.def("from_geojson",from_geojson_impl)
.staticmethod("from_geojson")

View file

@ -65,10 +65,7 @@ inline mapnik::feature_ptr next(mapnik::featureset_ptr const& itr)
void export_featureset()
{
using namespace boost::python;
using mapnik::Feature;
using mapnik::Featureset;
class_<Featureset,boost::shared_ptr<Featureset>,
class_<mapnik::Featureset,boost::shared_ptr<mapnik::Featureset>,
boost::noncopyable>("Featureset",no_init)
.def("__iter__",pass_through)
.def("next",next)

View file

@ -43,6 +43,9 @@
#include <mapnik/util/geometry_to_svg.hpp>
#endif
// stl
#include <stdexcept>
namespace {
using mapnik::from_wkt;

View file

@ -20,6 +20,8 @@
*
*****************************************************************************/
#if defined(GRID_RENDERER)
// boost
#include <boost/python.hpp>
#include <boost/python/module.hpp>
@ -80,3 +82,5 @@ void export_grid()
;
}
#endif

View file

@ -20,6 +20,8 @@
*
*****************************************************************************/
#if defined(GRID_RENDERER)
// boost
#include <boost/python.hpp>
#include <boost/python/module.hpp>
@ -49,3 +51,5 @@ void export_grid_view()
)
;
}
#endif

View file

@ -272,6 +272,7 @@ void export_image()
arg("mode")=mapnik::src_over,
arg("opacity")=1.0f
))
.def("premultiplied",&image_32::premultiplied)
.def("premultiply",&image_32::premultiply)
.def("demultiply",&image_32::demultiply)
.def("set_pixel",&set_pixel)

View file

@ -62,6 +62,10 @@ void export_line_pattern_symbolizer()
.add_property("filename",
&get_filename,
&set_filename)
.add_property("offset",
&line_pattern_symbolizer::offset,
&line_pattern_symbolizer::set_offset,
"Set/get the offset")
.add_property("comp_op",
&line_pattern_symbolizer::comp_op,
&line_pattern_symbolizer::set_comp_op,

View file

@ -91,17 +91,6 @@ mapnik::featureset_ptr query_map_point(mapnik::Map const& m, int index, double x
return m.query_map_point(idx, x, y);
}
// deepcopy
/*
mapnik::Map map_deepcopy(mapnik::Map & m, boost::python::dict memo)
{
// FIXME: ignore memo for now
mapnik::Map result;
mapnik::util::deepcopy(m, result);
return result;
}
*/
void set_maximum_extent(mapnik::Map & m, boost::optional<mapnik::box2d<double> > const& box)
{
if (box)

View file

@ -30,6 +30,8 @@
#include <mapnik/parse_path.hpp>
#include "mapnik_svg.hpp"
#include "mapnik_enumeration.hpp"
#include "python_optional.hpp"
#include <mapnik/marker_cache.hpp> // for known_svg_prefix_
using mapnik::markers_symbolizer;
@ -70,16 +72,6 @@ void set_marker_type(mapnik::markers_symbolizer & symbolizer, std::string const&
}
// https://github.com/mapnik/mapnik/issues/1367
PyObject* get_fill_opacity_impl(markers_symbolizer & sym)
{
boost::optional<float> fill_opacity = sym.get_fill_opacity();
if (fill_opacity)
return ::PyFloat_FromDouble(*fill_opacity);
Py_RETURN_NONE;
}
void export_markers_symbolizer()
{
using namespace boost::python;
@ -119,7 +111,7 @@ void export_markers_symbolizer()
&markers_symbolizer::set_opacity,
"Set/get the overall opacity")
.add_property("fill_opacity",
&get_fill_opacity_impl,
&markers_symbolizer::get_fill_opacity,
&markers_symbolizer::set_fill_opacity,
"Set/get the fill opacity")
.add_property("ignore_placement",

View file

@ -28,6 +28,9 @@
//mapnik
#include <mapnik/palette.hpp>
// stl
#include <stdexcept>
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;

View file

@ -28,6 +28,7 @@
#include <mapnik/debug.hpp>
#include <mapnik/params.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
// stl
#include <iterator>
@ -82,7 +83,7 @@ struct parameters_pickle_suite : boost::python::pickle_suite
extract<std::string> ex0(obj);
extract<mapnik::value_integer> ex1(obj);
extract<double> ex2(obj);
extract<UnicodeString> ex3(obj);
extract<mapnik::value_unicode_string> ex3(obj);
// TODO - this is never hit - we need proper python string -> std::string to get invoked here
if (ex0.check())
@ -175,7 +176,7 @@ mapnik::value_holder get_param(mapnik::parameter const& p, int index)
}
}
boost::shared_ptr<mapnik::parameter> create_parameter(UnicodeString const& key, mapnik::value_holder const& value)
boost::shared_ptr<mapnik::parameter> create_parameter(mapnik::value_unicode_string const& key, mapnik::value_holder const& value)
{
std::string key_utf8;
mapnik::to_utf8(key, key_utf8);
@ -184,7 +185,7 @@ boost::shared_ptr<mapnik::parameter> create_parameter(UnicodeString const& key,
// needed for Python_Unicode to std::string (utf8) conversion
boost::shared_ptr<mapnik::parameter> create_parameter_from_string(UnicodeString const& key, UnicodeString const& ustr)
boost::shared_ptr<mapnik::parameter> create_parameter_from_string(mapnik::value_unicode_string const& key, mapnik::value_unicode_string const& ustr)
{
std::string key_utf8;
std::string ustr_utf8;

View file

@ -27,6 +27,10 @@
// boost
#include <boost/python.hpp>
// stl
#include <stdexcept>
using mapnik::proj_transform;
using mapnik::projection;

View file

@ -25,6 +25,9 @@
#include <boost/python/detail/api_placeholder.hpp>
#include <boost/python/exception_translator.hpp>
// stl
#include <stdexcept>
void register_cairo();
void export_color();
void export_coord();
@ -38,8 +41,10 @@ void export_image();
void export_image_view();
void export_gamma_method();
void export_scaling_method();
#if defined(GRID_RENDERER)
void export_grid();
void export_grid_view();
#endif
void export_map();
void export_python();
void export_expression();
@ -62,6 +67,7 @@ void export_polygon_pattern_symbolizer();
void export_raster_symbolizer();
void export_text_placement();
void export_shield_symbolizer();
void export_debug_symbolizer();
void export_font_engine();
void export_projection();
void export_proj_transform();
@ -85,12 +91,13 @@ void export_wkt_reader();
#include <mapnik/rule.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/value_error.hpp>
#include <mapnik/save_map.hpp>
#include <mapnik/scale_denominator.hpp>
#if defined(GRID_RENDERER)
#include "python_grid_utils.hpp"
#endif
#include "mapnik_value_converter.hpp"
#include "mapnik_threads.hpp"
#include "python_optional.hpp"
@ -334,11 +341,6 @@ double scale_denominator(mapnik::Map const &map, bool geographic)
}
// http://docs.python.org/c-api/exceptions.html#standard-exceptions
void config_error_translator(mapnik::config_error const & ex)
{
PyErr_SetString(PyExc_RuntimeError, ex.what());
}
void value_error_translator(mapnik::value_error const & ex)
{
PyErr_SetString(PyExc_ValueError, ex.what());
@ -369,7 +371,33 @@ std::string mapnik_version_string()
return MAPNIK_VERSION_STRING;
}
// indicator for jpeg read/write support within libmapnik
bool has_proj4()
{
#if defined(MAPNIK_USE_PROJ4)
return true;
#else
return false;
#endif
}
bool has_svg_renderer()
{
#if defined(SVG_RENDERER)
return true;
#else
return false;
#endif
}
bool has_grid_renderer()
{
#if defined(GRID_RENDERER)
return true;
#else
return false;
#endif
}
bool has_jpeg()
{
#if defined(HAVE_JPEG)
@ -379,6 +407,33 @@ bool has_jpeg()
#endif
}
bool has_png()
{
#if defined(HAVE_PNG)
return true;
#else
return false;
#endif
}
bool has_tiff()
{
#if defined(HAVE_TIFF)
return true;
#else
return false;
#endif
}
bool has_webp()
{
#if defined(HAVE_WEBP)
return true;
#else
return false;
#endif
}
// indicator for cairo rendering support inside libmapnik
bool has_cairo()
{
@ -414,7 +469,7 @@ bool has_pycairo()
}
BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_overloads, load_map, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_overloads, load_map, 2, 4)
BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4)
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
@ -430,11 +485,9 @@ BOOST_PYTHON_MODULE(_mapnik)
using mapnik::load_map_string;
using mapnik::save_map;
using mapnik::save_map_to_string;
using mapnik::render_grid;
register_exception_translator<std::exception>(&standard_error_translator);
register_exception_translator<std::out_of_range>(&out_of_range_error_translator);
register_exception_translator<mapnik::config_error>(&config_error_translator);
register_exception_translator<mapnik::value_error>(&value_error_translator);
register_exception_translator<std::runtime_error>(&runtime_error_translator);
register_cairo();
@ -452,8 +505,10 @@ BOOST_PYTHON_MODULE(_mapnik)
export_image_view();
export_gamma_method();
export_scaling_method();
#if defined(GRID_RENDERER)
export_grid();
export_grid_view();
#endif
export_expression();
export_rule();
export_style();
@ -471,6 +526,7 @@ BOOST_PYTHON_MODULE(_mapnik)
export_raster_symbolizer();
export_text_placement();
export_shield_symbolizer();
export_debug_symbolizer();
export_font_engine();
export_projection();
export_proj_transform();
@ -491,7 +547,8 @@ BOOST_PYTHON_MODULE(_mapnik)
">>> clear_cache()\n"
);
def("render_grid",&render_grid,
#if defined(GRID_RENDERER)
def("render_grid",&mapnik::render_grid,
( arg("map"),
arg("layer"),
args("key")="__id__",
@ -499,6 +556,7 @@ BOOST_PYTHON_MODULE(_mapnik)
arg("fields")=boost::python::list()
)
);
#endif
def("render_to_file",&render_to_file1,
"\n"
@ -583,9 +641,11 @@ BOOST_PYTHON_MODULE(_mapnik)
(arg("map"),arg("image"),args("layer"))
);
#if defined(GRID_RENDERER)
def("render_layer", &mapnik::render_layer_for_grid,
(arg("map"),arg("grid"),args("layer"),arg("fields")=boost::python::list())
);
#endif
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
def("render",&render3,
@ -743,7 +803,12 @@ BOOST_PYTHON_MODULE(_mapnik)
def("save_map_to_string", &save_map_to_string, save_map_to_string_overloads());
def("mapnik_version", &mapnik_version,"Get the Mapnik version number");
def("mapnik_version_string", &mapnik_version_string,"Get the Mapnik version string");
def("has_proj4", &has_proj4, "Get proj4 status");
def("has_jpeg", &has_jpeg, "Get jpeg read/write support status");
def("has_png", &has_png, "Get png read/write support status");
def("has_tiff", &has_tiff, "Get tiff read/write support status");
def("has_webp", &has_webp, "Get webp read/write support status");
def("has_grid_renderer", &has_grid_renderer, "Get grid_renderer status");
def("has_cairo", &has_cairo, "Get cairo library status");
def("has_pycairo", &has_pycairo, "Get pycairo module status");

View file

@ -34,7 +34,6 @@
using mapnik::rule;
using mapnik::expr_node;
using mapnik::expression_ptr;
using mapnik::Feature;
using mapnik::point_symbolizer;
using mapnik::line_symbolizer;
using mapnik::line_pattern_symbolizer;

View file

@ -84,7 +84,7 @@ struct NodeWrap: formatting::node, wrapper<formatting::node>
}
void apply(char_properties const& p, Feature const& feature, processed_text &output) const
void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
python_block_auto_unblock b;
this->get_override("apply")(ptr(&p), ptr(&feature), ptr(&output));
@ -122,7 +122,7 @@ struct TextNodeWrap: formatting::text_node, wrapper<formatting::text_node>
}
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
if(override o = this->get_override("apply"))
{
@ -135,7 +135,7 @@ struct TextNodeWrap: formatting::text_node, wrapper<formatting::text_node>
}
}
void default_apply(char_properties const& p, Feature const& feature, processed_text &output) const
void default_apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
formatting::text_node::apply(p, feature, output);
}
@ -143,7 +143,7 @@ struct TextNodeWrap: formatting::text_node, wrapper<formatting::text_node>
struct FormatNodeWrap: formatting::format_node, wrapper<formatting::format_node>
{
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
if(override o = this->get_override("apply"))
{
@ -156,7 +156,7 @@ struct FormatNodeWrap: formatting::format_node, wrapper<formatting::format_node>
}
}
void default_apply(char_properties const& p, Feature const& feature, processed_text &output) const
void default_apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
formatting::format_node::apply(p, feature, output);
}
@ -164,7 +164,7 @@ struct FormatNodeWrap: formatting::format_node, wrapper<formatting::format_node>
struct ExprFormatWrap: formatting::expression_format, wrapper<formatting::expression_format>
{
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
if(override o = this->get_override("apply"))
{
@ -177,7 +177,7 @@ struct ExprFormatWrap: formatting::expression_format, wrapper<formatting::expres
}
}
void default_apply(char_properties const& p, Feature const& feature, processed_text &output) const
void default_apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
formatting::expression_format::apply(p, feature, output);
}
@ -194,14 +194,17 @@ struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
ListNodeWrap(object l) : formatting::list_node(), wrapper<formatting::list_node>()
{
stl_input_iterator<formatting::node_ptr> begin(l), end;
children_.insert(children_.end(), begin, end);
while (begin != end)
{
children_.push_back(*begin);
++begin;
}
}
/* TODO: Add constructor taking variable number of arguments.
http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_function */
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
if(override o = this->get_override("apply"))
{
@ -214,7 +217,7 @@ struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
}
}
void default_apply(char_properties const& p, Feature const& feature, processed_text &output) const
void default_apply(char_properties const& p, feature_impl const& feature, processed_text &output) const
{
formatting::list_node::apply(p, feature, output);
}

View file

@ -35,11 +35,7 @@ namespace boost { namespace python {
{
PyObject * operator() (mapnik::value_integer val) const
{
#if PY_VERSION_HEX >= 0x03000000
return ::PyLong_FromLong(val);
#else
return ::PyInt_FromLong(val);
#endif
return ::PyLong_FromLongLong(val);
}
PyObject * operator() (double val) const

View file

@ -20,6 +20,8 @@
*
*****************************************************************************/
#if defined(GRID_RENDERER)
// boost
#include <boost/python.hpp>
#include <boost/scoped_array.hpp>
@ -39,6 +41,9 @@
#include "mapnik_value_converter.hpp"
#include "python_grid_utils.hpp"
// stl
#include <stdexcept>
namespace mapnik {
@ -469,3 +474,5 @@ boost::python::dict render_grid(mapnik::Map const& map,
}
}
#endif

View file

@ -22,7 +22,8 @@
#include <boost/optional/optional.hpp>
#include <boost/python.hpp>
#include <boost/noncopyable.hpp>
#include <mapnik/noncopyable.hpp>
// boost::optional<T> to/from converter from John Wiegley
@ -46,7 +47,7 @@ struct register_python_conversion
};
template <typename T>
struct python_optional : public boost::noncopyable
struct python_optional : public mapnik::noncopyable
{
struct optional_to_python
{
@ -74,7 +75,7 @@ struct python_optional : public boost::noncopyable
rvalue_from_python_stage1(source, converters);
return rvalue_from_python_stage2(source, data, converters);
}
return NULL;
return 0;
}
static void construct(PyObject * source,
@ -94,7 +95,8 @@ struct python_optional : public boost::noncopyable
}
};
explicit python_optional() {
explicit python_optional()
{
register_python_conversion<boost::optional<T>,
optional_to_python, optional_from_python>();
}
@ -199,7 +201,11 @@ struct python_optional<bool> : public mapnik::noncopyable
// This class works around a feature in boost python.
// See http://osdir.com/ml/python.c++/2003-11/msg00158.html
template <typename T, typename X1 = boost::python::detail::not_specified, typename X2 = boost::python::detail::not_specified, typename X3 = boost::python::detail::not_specified>
template <typename T,
typename X1 = boost::python::detail::not_specified,
typename X2 = boost::python::detail::not_specified,
typename X3 = boost::python::detail::not_specified>
class class_with_converter : public boost::python::class_<T, X1, X2, X3>
{
public:
@ -223,7 +229,7 @@ public:
: boost::python::class_<T, X1, X2, X3>(name, doc, i) { }
template <class D>
self& def_readwrite_convert(char const* name, D const& d, char const* doc=0)
self& def_readwrite_convert(char const* name, D const& d, char const* /*doc*/=0)
{
this->add_property(name,
boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),

View file

@ -1,4 +1,4 @@
CXXFLAGS = $(shell mapnik-config --cflags)
CXXFLAGS = $(shell mapnik-config --includes --defines --cxxflags --dep-includes)
LDFLAGS = $(shell mapnik-config --libs --dep-libs --ldflags)
OBJ = rundemo.o
@ -13,8 +13,15 @@ $(BIN) : $(OBJ)
.c.o :
$(CXX) -c $(CXXFLAGS) $<
gyp:
rm -rf ./build
gyp rundemo.gyp --depth=. -f make --generator-output=./build/
make -C ./build
build/out/Release/rundemo `mapnik-config --prefix`
.PHONY : clean
clean:
rm -f $(OBJ)
rm -f $(BIN)
rm -f ./build

81
demo/c++/README.md Normal file
View file

@ -0,0 +1,81 @@
## rundemo.cpp
This directory contains a simple c++ program demonstrating the Mapnik C++ API. It mimics the python 'rundemo.py' example with a couple exceptions.
If building on unix you can have this program automatically build by configuring Mapnik like:
./configure DEMO=True
However, this example code also should be able to be built standalone.
The following notes describe how to do that on various operating systems.
## Depends
- Mapnik library development headers
- `mapnik-config` on unix and `mapnik-config.bat` on windows
### Unix
On OS X and Linux you also need `make`.
### Windows
On windows, additional dependencies to build are:
- MSVS 2010 with C++ compiler
- Python 2.x
- gyp: https://code.google.com/p/gyp | https://github.com/springmeyer/hello-gyp
`mapnik-config.bat` should come with your Mapnik installation.
First confirm it is on your path:
mapnik-config # should give usage
To install gyp, which is pure python do:
svn checkout http://gyp.googlecode.com/svn/trunk/ gyp
cd gyp
python setup.py install
If you do not have svn installed you can grab gyp from:
https://github.com/TooTallNate/node-gyp/archive/master.zip
# unzip and extract the 'gyp' subfolder then do
cd gyp
python setup.py install
## Building the demo
### Unix
Simply type:
make
Then to run do:
./rundemo `mapnik-config --prefix`
On OS X you can also create an xcode project:
gyp rundemo.gyp --depth=. -f xcode --generator-output=./build/
xcodebuild -project ./build/rundemo.xcodeproj
./build/out/Release/rundemo `mapnik-config --prefix`
### Windows
First you need to build the visual studio solution with gyp:
C:\Python27\python.exe c:\Python27\Scripts\gyp rundemo.gyp --depth=. -f msvs -G msvs_version=2010
Then you can compile with `msbuild`:
msbuild rundemo.sln /p:Configuration="Release" /p:Platform=Win32
Then run it!
for /f %i in ('mapnik-config --prefix') do set MAPNIK_PREFIX=%i
Release\rundemo.exe %MAPNIK_PREFIX%

View file

@ -34,14 +34,14 @@ demo_env = env.Clone()
demo_env['CXXFLAGS'] = copy(env['LIBMAPNIK_CXXFLAGS'])
demo_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
if env['HAS_CAIRO']:
demo_env.PrependUnique(CPPPATH=env['CAIRO_CPPPATHS'])
demo_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
libraries = copy(env['LIBMAPNIK_LIBS'])
libraries.append('mapnik')
libraries = ['mapnik']
libraries.extend(copy(env['LIBMAPNIK_LIBS']))
rundemo = demo_env.Program('rundemo', source, LIBS=libraries, LINKFLAGS=env["CUSTOM_LDFLAGS"])
Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

42
demo/c++/common.gypi Normal file
View file

@ -0,0 +1,42 @@
{
'variables': {
'conditions': [
['OS == "mac"', {
'target_arch%': 'x64'
}, {
'target_arch%': 'ia32'
}]
]
},
'target_defaults': {
'default_configuration': 'Release',
'defines': [ ],
'conditions': [
['OS == "mac"', {
'defines': [ 'DARWIN' ]
}, {
'defines': [ 'LINUX' ]
}],
['OS == "mac" and target_arch == "x64"', {
'xcode_settings': {
'ARCHS': [ 'x86_64' ]
},
}]
],
'configurations': {
'Debug': {
'cflags': [ '-g', '-O0' ],
'xcode_settings': {
'OTHER_CFLAGS': [ '-g', '-O0' ]
}
},
'Release': {
'cflags': [ '-O3' ],
'defines': [ 'NDEBUG' ],
'xcode_settings': {
'OTHER_CFLAGS': [ '-O3' ]
}
}
}
}
}

View file

@ -1,20 +0,0 @@
This directory contains a simple c++ program demonstrating the Mapnik C++ API. It mimics the python 'rundemo.py' example with a couple exceptions.
To build it re-configure SCons with DEMO=True then rebuild::
$ python scons/scons.py configure DEMO=True
$ python scons/scons.py
The sample program will be compiled (but not installed).
To run::
$ cd demo/c++
$ ./rundemo /usr/local/lib/mapnik
For more detailed comments have a look in demo/python/rundemo.py
Have fun!
Artem.

View file

@ -34,7 +34,6 @@
#include <mapnik/expression.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/config_error.hpp>
#if defined(HAVE_CAIRO)
#include <mapnik/cairo_renderer.hpp>
@ -318,11 +317,6 @@ int main ( int argc , char** argv)
#endif
}
catch ( const mapnik::config_error & ex )
{
std::cerr << "### Configuration error: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
catch ( const std::exception & ex )
{
std::cerr << "### std::exception: " << ex.what() << std::endl;

48
demo/c++/rundemo.gyp Normal file
View file

@ -0,0 +1,48 @@
{
'includes': [ 'common.gypi' ],
'default_configuration': 'Release',
'targets': [
{
'target_name': 'rundemo',
'type': 'executable',
'sources': [
'rundemo.cpp',
],
'conditions': [
[ 'OS=="mac"', {
'libraries': [
'-lmapnik',
'-undefined dynamic_lookup'
],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS':[
'<!@(mapnik-config --cflags)'
],
'GCC_ENABLE_CPP_RTTI': 'YES',
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
}
}],
[ 'OS=="win"', {
'defines': [
'<!@(mapnik-config --defines)',
],
'libraries': [
'<!@(mapnik-config --libs)',
'<!@(mapnik-config --dep-libs)'
],
'include_dirs': [
'<!@(mapnik-config --includes)',
'<!@(mapnik-config --dep-includes)',
],
'msvs_settings': {
'VCLinkerTool': {
'AdditionalLibraryDirectories': [
'<!@(mapnik-config --ldflags)'
]
}
}
}]
]
}
],
}

View file

@ -1,25 +0,0 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>charplacement</Name>
<ElementPath>charplacement</ElementPath>
<DatasetSpecificInfo>
<FeatureCount>1</FeatureCount>
<ExtentXMin>1.00000</ExtentXMin>
<ExtentXMax>2.00000</ExtentXMax>
<ExtentYMin>1.00000</ExtentYMin>
<ExtentYMax>5.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>NAME</Name>
<ElementPath>NAME</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
<PropertyDefn>
<Name>CLASS</Name>
<ElementPath>CLASS</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View file

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="charplacement.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord>
<gml:coord><gml:X>13</gml:X><gml:Y>-13</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:charplacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>2,-1 1,-3 2,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>TRIANGLE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F1">
<ogr:geometryProperty><gml:LineString><gml:coordinates>3,-1 4,-3 3,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>TRIANGLE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F7">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-12 13,-12
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F8">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-13 2,-13 5,-13 10,-13 13,-13
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F9">
<ogr:geometryProperty><gml:LineString><gml:coordinates>6,-1 5,-3 5,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F10">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-1 8,-3 8,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F11">
<ogr:geometryProperty><gml:LineString><gml:coordinates>5,-6 5,-8 6,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F12">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-6 8,-8 7,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F13">
<ogr:geometryProperty><gml:LineString><gml:coordinates>10.055915,-1.00031738281 10.6649858,-1.077712483 11.274056,-1.26950068 11.77921,-1.55298308 12.191993,-1.92815928 12.51529,-2.369132 12.746218,-2.8329032 12.884774,-3.2968745 12.930959,-3.875339</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F14">
<ogr:geometryProperty><gml:LineString><gml:coordinates>10.0555,-8.875339 10.6645708,-8.7979439 11.273641,-8.6061557 11.778795,-8.3226733 12.191578,-7.9474971 12.514875,-7.5065244 12.745803,-7.0427532 12.884359,-6.5787819 12.930544,-6.0003174</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F15">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9.055915,-2.00031738281 9.6649858,-2.077712483 10.274056,-2.26950068 10.77921,-2.55298308 11.191993,-2.92815928 11.51529,-3.369132 11.746218,-3.8329032 11.884774,-4.2968745 11.930959,-4.875339
11.930544,-5.0003174 11.884359,-5.5787819 11.745803,-6.0427532 11.514875,-6.5065244 11.191578,-6.9474971 10.778795,-7.3226733 10.273641,-7.6061557 9.6645708,-7.7979439 9.0555,-7.875339
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F16">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9.0435048,-10.5550195 9.480786,-10.2191668 9.963148,-10.0731439 10.540222,-10.2495527 10.968444,-10.525815 11.419238,-10.8336443 12.01882,-10.9565825 12.559787,-10.7996079 12.956495,-10.4089966
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>SQUIGGLE</ogr:CLASS>
</ogr:charplacement>
<ogr:charplacement fid="F16">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-9 1.4,-10 1.8,-9 2.2,-10 2.6,-9 3.0,-10 3.4,-9 3.8,-10 4.2,-9 4.6,-10
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long ZigZag Road Name</ogr:NAME>
<ogr:CLASS>ZIGZAG</ogr:CLASS>
</ogr:charplacement>
</gml:featureMember>
</ogr:FeatureCollection>

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd"/><xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="charplacement" type="ogr:charplacement_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="charplacement_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:GeometryPropertyType" nillable="true" minOccurs="1" maxOccurs="1"/>
<xs:element name="NAME" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CLASS" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View file

@ -1,25 +0,0 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>displacement</Name>
<ElementPath>displacement</ElementPath>
<DatasetSpecificInfo>
<FeatureCount>1</FeatureCount>
<ExtentXMin>1.00000</ExtentXMin>
<ExtentXMax>2.00000</ExtentXMax>
<ExtentYMin>1.00000</ExtentYMin>
<ExtentYMax>5.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>NAME</Name>
<ElementPath>NAME</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
<PropertyDefn>
<Name>CLASS</Name>
<ElementPath>CLASS</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View file

@ -1,173 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="displacement.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord>
<gml:coord><gml:X>13</gml:X><gml:Y>-13</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-3 1,-2</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-2 2,-1</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>2,-1 3,-1</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>3,-1 4,-2</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>4,-2 4,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>4,-3 3,-4</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>3,-4 2,-4</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>2,-4 1,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>CLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>5,-3 6,-4</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>6,-4 7,-4</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-4 8,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-3 8,-2</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-2 7,-1</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-1 6,-1</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>6,-1 5,-2</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>5,-2 5,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road</ogr:NAME>
<ogr:CLASS>ANTICLOCKWISE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-6.5 2,-5.5 3,-5 4,-5 5,-5.5 6,-6.5
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name To Go Around The Whole Curve!</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-7 2,-8 3,-8.5 4,-8.5 5,-8 6,-7
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name To Go Around The Whole Curve!</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
3,-8.5 2,-9.5 1.5,-10.5 1.5,-11.5 2,-12.5 3,-13.5
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name To Go Around The Whole Curve!</ogr:NAME>
<ogr:CLASS>VERTCURVE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
4,-8.5 5,-9.5 5.5,-10.5 5.5,-11.5 5,-12.5 4,-13.5
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name To Go Around The Whole Curve!</ogr:NAME>
<ogr:CLASS>VERTCURVE</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9.2,-4 9,-3 10,-3 10.2,-4
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>PARALLELOGRAM</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9,-2 9.2,-1 10.2,-1 10,-2
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>PARALLELOGRAM</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
11,-1 11,-2 12,-2
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CORNER</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
11,-4 12,-4 12,-3
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CORNER</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
12.5,-1 13.5,-1 13.5,-2
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CORNER</ogr:CLASS>
</ogr:displacement>
<ogr:displacement fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
12.5,-4 12.5,-3 13.5,-3
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CORNER</ogr:CLASS>
</ogr:displacement>
</gml:featureMember>
</ogr:FeatureCollection>

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd"/><xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="displacement" type="ogr:displacement_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="displacement_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:GeometryPropertyType" nillable="true" minOccurs="1" maxOccurs="1"/>
<xs:element name="NAME" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CLASS" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View file

@ -1,25 +0,0 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>overlap</Name>
<ElementPath>overlap</ElementPath>
<DatasetSpecificInfo>
<FeatureCount>1</FeatureCount>
<ExtentXMin>1.00000</ExtentXMin>
<ExtentXMax>2.00000</ExtentXMax>
<ExtentYMin>1.00000</ExtentYMin>
<ExtentYMax>5.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>NAME</Name>
<ElementPath>NAME</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
<PropertyDefn>
<Name>CLASS</Name>
<ElementPath>CLASS</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View file

@ -1,127 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="overlap.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord>
<gml:coord><gml:X>13</gml:X><gml:Y>-13</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-1 1,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-3 7,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-3 7,-7</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>3,-2 3,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-7 1,-7</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>5,-2 5,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-3 12,-3</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CROSS</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>10,-1 10,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CROSS</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
10,-9 13,-9 13,-11 11,-11 11,-8
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>SELFOVERLAP</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>4,-9 4,-13</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK2</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-9 8,-13</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK2</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-11 9,-11</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK2</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>2,-9 2,-13</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK2</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>6,-9 6,-13</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>NETWORK2</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8.8,-6 8.8,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDOVER</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-6 8,-7 10,-7 10,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDUNDER</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>12.2,-6 12.2,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDOVER</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>11,-6 11,-7 13,-7 13,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDUNDER</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>12.2,-3.5 12.2,-5.5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDOVER</ogr:CLASS>
</ogr:overlap>
<ogr:overlap fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>11,-4.5 13,-4.5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Long Road Name</ogr:NAME>
<ogr:CLASS>BENDUNDER</ogr:CLASS>
</ogr:overlap>
</gml:featureMember>
</ogr:FeatureCollection>

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd"/><xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="overlap" type="ogr:overlap_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="overlap_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:GeometryPropertyType" nillable="true" minOccurs="1" maxOccurs="1"/>
<xs:element name="NAME" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CLASS" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View file

@ -1,25 +0,0 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>textspacing</Name>
<ElementPath>textspacing</ElementPath>
<DatasetSpecificInfo>
<FeatureCount>1</FeatureCount>
<ExtentXMin>1.00000</ExtentXMin>
<ExtentXMax>2.00000</ExtentXMax>
<ExtentYMin>1.00000</ExtentYMin>
<ExtentYMax>5.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>NAME</Name>
<ElementPath>NAME</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
<PropertyDefn>
<Name>CLASS</Name>
<ElementPath>CLASS</ElementPath>
<Type>String</Type>
<Width>0</Width>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="textspacing.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>0</gml:Y></gml:coord>
<gml:coord><gml:X>13</gml:X><gml:Y>-13</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:textspacing fid="F0">
<ogr:geometryProperty><gml:LineString><gml:coordinates>2,-1 1,-3 2,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>TRIANGLE</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F1">
<ogr:geometryProperty><gml:LineString><gml:coordinates>3,-1 4,-3 3,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>TRIANGLE</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F2">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-7 2,-7</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F3">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-8 3,-8</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F4">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-9 4,-9</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F5">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-10 5,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F6">
<ogr:geometryProperty><gml:LineString><gml:coordinates>1,-11 7,-11</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F7">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-12 13,-12
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F8">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
1,-13 2,-13 5,-13 10,-13 13,-13
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>STRAIGHT</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F9">
<ogr:geometryProperty><gml:LineString><gml:coordinates>6,-1 5,-3 5,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F10">
<ogr:geometryProperty><gml:LineString><gml:coordinates>7,-1 8,-3 8,-5</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F11">
<ogr:geometryProperty><gml:LineString><gml:coordinates>5,-6 5,-8 6,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F12">
<ogr:geometryProperty><gml:LineString><gml:coordinates>8,-6 8,-8 7,-10</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>BEND</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F13">
<ogr:geometryProperty><gml:LineString><gml:coordinates>10.055915,-1.00031738281 10.6649858,-1.077712483 11.274056,-1.26950068 11.77921,-1.55298308 12.191993,-1.92815928 12.51529,-2.369132 12.746218,-2.8329032 12.884774,-3.2968745 12.930959,-3.875339</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F14">
<ogr:geometryProperty><gml:LineString><gml:coordinates>10.0555,-8.875339 10.6645708,-8.7979439 11.273641,-8.6061557 11.778795,-8.3226733 12.191578,-7.9474971 12.514875,-7.5065244 12.745803,-7.0427532 12.884359,-6.5787819 12.930544,-6.0003174</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F15">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9.055915,-2.00031738281 9.6649858,-2.077712483 10.274056,-2.26950068 10.77921,-2.55298308 11.191993,-2.92815928 11.51529,-3.369132 11.746218,-3.8329032 11.884774,-4.2968745 11.930959,-4.875339
11.930544,-5.0003174 11.884359,-5.5787819 11.745803,-6.0427532 11.514875,-6.5065244 11.191578,-6.9474971 10.778795,-7.3226733 10.273641,-7.6061557 9.6645708,-7.7979439 9.0555,-7.875339
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>CURVE</ogr:CLASS>
</ogr:textspacing>
<ogr:textspacing fid="F16">
<ogr:geometryProperty><gml:LineString><gml:coordinates>
9.0435048,-10.5550195 9.480786,-10.2191668 9.963148,-10.0731439 10.540222,-10.2495527 10.968444,-10.525815 11.419238,-10.8336443 12.01882,-10.9565825 12.559787,-10.7996079 12.956495,-10.4089966
</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:NAME>Road Name</ogr:NAME>
<ogr:CLASS>SQUIGGLE</ogr:CLASS>
</ogr:textspacing>
</gml:featureMember>
</ogr:FeatureCollection>

View file

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd"/><xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="textspacing" type="ogr:textspacing_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="textspacing_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:GeometryPropertyType" nillable="true" minOccurs="1" maxOccurs="1"/>
<xs:element name="NAME" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CLASS" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View file

@ -1,3 +0,0 @@
These files are for testing various rendering parts of mapnik, they have been created by hand.
The raw files are in the raw/ folder (they were created with inkscape to assist!)
Run the regenerate.sh script to regenerate the shape files from the gml files, this requires ogr2ogr to run.

View file

@ -1,20 +0,0 @@
#!/bin/sh
rm -f textspacing.shp textspacing.shx textspacing.dbf
ogr2ogr -f "ESRI Shapefile" textspacing raw/textspacing.gml
mv textspacing/* ./
rmdir textspacing
rm -f overlap.shp overlap.shx overlap.dbf
ogr2ogr -f "ESRI Shapefile" overlap raw/overlap.gml
mv overlap/* ./
rmdir overlap
rm -f displacement.shp displacement.shx displacement.dbf
ogr2ogr -f "ESRI Shapefile" displacement raw/displacement.gml
mv displacement/* ./
rmdir displacement
rm -f charplacement.shp charplacement.shx charplacement.dbf
ogr2ogr -f "ESRI Shapefile" charplacement raw/charplacement.gml
mv charplacement/* ./
rmdir charplacement

View file

@ -25,9 +25,9 @@
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include "mainwindow.hpp"
// boost
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
int main( int argc, char **argv )

View file

@ -3,7 +3,8 @@
######################################################################
TEMPLATE = app
QT += core gui widgets
QMAKE_CXX = clang++
QMAKE_CXX = $$system(mapnik-config --cxx)
QMAKE_LINK = $$system(mapnik-config --cxx)
QMAKE_CXXFLAGS += $$system(mapnik-config --cxxflags)
QMAKE_CXXFLAGS += $$system(mapnik-config --includes --dep-includes)
QMAKE_LFLAGS += $$system(mapnik-config --libs)

View file

@ -48,8 +48,6 @@ private:
ClipperLib::Clipper m_clipper;
clipper_PolyFillType m_subjFillType;
clipper_PolyFillType m_clipFillType;
double start_x_;
double start_y_;
int Round(double val)
{
@ -69,28 +67,7 @@ public:
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType),
start_x_(0),
start_y_(0)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
}
conv_clipper(source_a_type &a,
clipper_op_e op = clipper_and,
clipper_PolyFillType subjFillType = clipper_non_zero,
clipper_PolyFillType clipFillType = clipper_non_zero,
int scaling_factor = 6) :
m_src_a(&a),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op),
m_subjFillType(subjFillType),
m_clipFillType(clipFillType),
start_x_(0),
start_y_(0)
m_clipFillType(clipFillType)
{
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
@ -99,7 +76,7 @@ public:
~conv_clipper()
{
}
unsigned type() const { return m_src_a->type(); }
void attach1(VSA &source, clipper_PolyFillType subjFillType = clipper_even_odd)
{ m_src_a = &source; m_subjFillType = subjFillType; }
void attach2(VSB &source, clipper_PolyFillType clipFillType = clipper_even_odd)
@ -277,8 +254,6 @@ bool conv_clipper<VSA, VSB>::next_vertex(double *x, double *y)
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template<class VSA, class VSB>
unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
{
@ -289,14 +264,10 @@ unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
if( next_vertex( x, y ) )
{
m_status =status_line_to;
start_x_ = *x;
start_y_ = *y;
return path_cmd_move_to;
}
else
{
*x = start_x_;
*y = start_y_;
m_status = status_stop;
return path_cmd_end_poly | path_flags_close;
}
@ -313,8 +284,6 @@ unsigned conv_clipper<VSA, VSB>::vertex(double *x, double *y)
else
{
m_status = status_move_to;
*x = start_x_;
*y = start_y_;
return path_cmd_end_poly | path_flags_close;
}
}

View file

@ -134,7 +134,7 @@ namespace agg
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
unsigned cover=0)
unsigned /*cover*/=0)
{
calc_type r = p[Order::R];
calc_type g = p[Order::G];

View file

@ -18,6 +18,9 @@
#include "agg_basics.h"
// https://github.com/mapnik/mapnik/issues/1860
#include <mapnik/config.hpp>
namespace agg
{
@ -25,7 +28,8 @@ namespace agg
//
// See Implementation agg_vpgen_clip_polygon.cpp
//
class vpgen_clip_polygon
class MAPNIK_DECL vpgen_clip_polygon
{
public:
vpgen_clip_polygon() :

View file

@ -18,6 +18,9 @@
#include "agg_basics.h"
// https://github.com/mapnik/mapnik/issues/1860
#include <mapnik/config.hpp>
namespace agg
{
@ -25,7 +28,7 @@ namespace agg
//
// See Implementation agg_vpgen_clip_polyline.cpp
//
class vpgen_clip_polyline
class MAPNIK_DECL vpgen_clip_polyline
{
public:
vpgen_clip_polyline() :

27
deps/clipper/include/clipper.hpp vendored Normal file → Executable file
View file

@ -1,8 +1,8 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 5.1.3 *
* Date : 27 February 2013 *
* Version : 5.1.5 *
* Date : 4 May 2013 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 *
* *
@ -34,6 +34,8 @@
#ifndef clipper_hpp
#define clipper_hpp
#include <mapnik/config.hpp>
#include <vector>
#include <stdexcept>
#include <cstring>
@ -103,7 +105,7 @@ private:
enum JoinType { jtSquare, jtRound, jtMiter };
bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
MAPNIK_DECL double Area(const Polygon &poly);
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true);
@ -134,7 +136,6 @@ struct TEdge {
double dx;
long64 deltaX;
long64 deltaY;
long64 tmpX;
PolyType polyType;
EdgeSide side;
int windDelta; //1 or -1 depending on winding direction
@ -211,7 +212,7 @@ typedef std::vector < HorzJoinRec* > HorzJoinList;
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
//polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase
class MAPNIK_DECL ClipperBase
{
public:
ClipperBase();
@ -232,7 +233,7 @@ protected:
EdgeList m_edges;
};
class Clipper : public virtual ClipperBase
class MAPNIK_DECL Clipper : public virtual ClipperBase
{
public:
Clipper();
@ -248,6 +249,8 @@ public:
void Clear();
bool ReverseSolution() {return m_ReverseOutput;};
void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool ForceSimple() {return m_ForceSimple;};
void ForceSimple(bool value) {m_ForceSimple = value;};
protected:
void Reset();
virtual bool ExecuteInternal();
@ -265,6 +268,7 @@ private:
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
bool m_ForceSimple;
void DisposeScanbeamList();
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
@ -287,10 +291,8 @@ private:
void ProcessHorizontal(TEdge *horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2);
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void IntersectEdges(TEdge *e1, TEdge *e2,
const IntPoint &pt, const IntersectProtects protects);
OutRec* CreateOutRec();
@ -304,12 +306,12 @@ private:
void ProcessEdgesAtTopOfScanbeam(const long64 topY);
void BuildResult(Polygons& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *OutRec);
void SetHoleState(TEdge *e, OutRec *outrec);
void DisposeIntersectNodes();
bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outRec);
void FixupOutPolygon(OutRec &outrec);
bool IsHole(TEdge *e);
void FixHoleLinkage(OutRec &outRec);
void FixHoleLinkage(OutRec &outrec);
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
void ClearJoins();
void AddHorzJoin(TEdge *e, int idx);
@ -317,6 +319,7 @@ private:
bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2);
void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
void JoinCommonEdges();
void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
};

588
deps/clipper/src/clipper.cpp vendored Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -48,12 +48,11 @@ Mapnik is licensed LGPL, which means that you are a free to use the code in any
## Copyright
Mapnik is an open source project and will always be, proudly, an open source project. Your contributions to Mapnik should be motivated by (amount other things) your desire to contribute to a community effort and by the knowledge that your open code will stay that way.
Mapnik is an open source project and will always be. Your contributions to Mapnik should be motivated by your desire to contribute to a community effort and by the knowledge that your open code will stay that way.
Artem, as the founder and leader of the Mapnik project, is the primary copyright holder and therefore also the primary contact for any current or future license questions around Mapnik. It is important that the copyright holder is respected, trusted, and known to the community so maintaining copyright with Artem is key to maintaining the project as open source.
Therefore, convention is that all new files created by any core developers or patch
authors should have a copyright declaration like:
Therefore all files created by any core developers or patch authors should have a copyright declaration like:
/*****************************************************************************
*

View file

@ -9,6 +9,9 @@ subdirs = ['','svg','wkt','grid','json','util','text_placements','formatting']
if env['SVG_RENDERER']:
subdirs.append('svg/output')
if env['GRID_RENDERER']:
subdirs.append('grid')
if 'install' in COMMAND_LINE_TARGETS:
for subdir in subdirs:
pathdir = os.path.join(base,subdir,'*.hpp')

View file

@ -25,17 +25,12 @@
// mapnik
#include <mapnik/gamma_method.hpp>
#include <mapnik/stroke.hpp>
#include <mapnik/stroke.hpp> // for line_cap_e, line_join_e, etc
// agg
#include "agg_basics.h"
#include "agg_gamma_functions.h"
#include "agg_math_stroke.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_renderer_outline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_gamma_functions.h" // for gamma_power, gamma_linear, etc
#include "agg_math_stroke.h" // for line_join_e::miter_join, etc
#include "agg_rasterizer_outline_aa.h"
namespace mapnik {

View file

@ -132,6 +132,11 @@ public:
return DEFAULT;
}
inline double scale_factor() const
{
return scale_factor_;
}
protected:
template <typename R>
void debug_draw_box(R& buf, box2d<double> const& extent,

View file

@ -47,7 +47,6 @@
#include <mapnik/text_placements/base.hpp> // for text_placements
// boost
#include <boost/concept_check.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
@ -62,12 +61,11 @@ struct expression_attributes : boost::static_visitor<void>
explicit expression_attributes(Container& names)
: names_(names) {}
void operator() (value_type const& x) const
void operator() (value_type const& /*x*/) const
{
boost::ignore_unused_variable_warning(x);
}
void operator() (geometry_type_attribute const& type) const
void operator() (geometry_type_attribute const& /*type*/) const
{
// do nothing
}
@ -107,8 +105,11 @@ private:
struct symbolizer_attributes : public boost::static_visitor<>
{
symbolizer_attributes(std::set<std::string>& names)
: names_(names), f_attr(names) {}
symbolizer_attributes(std::set<std::string>& names,
double & filter_factor)
: names_(names),
filter_factor_(filter_factor),
f_attr(names) {}
template <typename T>
void operator () (T const&) const {}
@ -199,6 +200,11 @@ struct symbolizer_attributes : public boost::static_visitor<>
{
boost::apply_visitor(f_attr,*width_expr);
}
path_expression_ptr const& filename_expr = sym.get_filename();
if (filename_expr)
{
path_processor_type::collect_attributes(*filename_expr,names_);
}
collect_transform(sym.get_image_transform());
collect_transform(sym.get_transform());
}
@ -212,10 +218,15 @@ struct symbolizer_attributes : public boost::static_visitor<>
}
collect_transform(sym.get_transform());
}
// TODO - support remaining syms
void operator () (raster_symbolizer const& sym)
{
filter_factor_ = sym.calculate_filter_factor();
}
private:
std::set<std::string>& names_;
double & filter_factor_;
expression_attributes<std::set<std::string> > f_attr;
void collect_transform(transform_list_ptr const& trans_expr)
{
@ -231,18 +242,20 @@ class attribute_collector : public mapnik::noncopyable
{
private:
std::set<std::string>& names_;
double filter_factor_;
expression_attributes<std::set<std::string> > f_attr;
public:
attribute_collector(std::set<std::string>& names)
: names_(names), f_attr(names) {}
: names_(names),
filter_factor_(1.0),
f_attr(names) {}
template <typename RuleType>
void operator() (RuleType const& r)
{
typename RuleType::symbolizers const& symbols = r.get_symbolizers();
typename RuleType::symbolizers::const_iterator symIter=symbols.begin();
symbolizer_attributes s_attr(names_);
symbolizer_attributes s_attr(names_,filter_factor_);
while (symIter != symbols.end())
{
boost::apply_visitor(s_attr,*symIter++);
@ -251,22 +264,11 @@ public:
expression_ptr const& expr = r.get_filter();
boost::apply_visitor(f_attr,*expr);
}
};
struct directive_collector : public boost::static_visitor<>
double get_filter_factor() const
{
directive_collector(double & filter_factor)
: filter_factor_(filter_factor) {}
template <typename T>
void operator () (T const&) const {}
void operator () (raster_symbolizer const& sym)
{
filter_factor_ = sym.calculate_filter_factor();
return filter_factor_;
}
private:
double & filter_factor_;
};
} // namespace mapnik

View file

@ -41,7 +41,6 @@
// cairo
#include <cairo.h>
#include <cairo-ft.h>
// stl
#include <map>
@ -60,7 +59,7 @@ typedef cairo_status_t ErrorStatus;
/// Throws the appropriate exception, if exceptions are enabled.
inline void throw_exception(ErrorStatus status)
{
throw std::runtime_error("cairo: fixme");
throw std::runtime_error(std::string("cairo: ") + cairo_status_to_string(status));
}
//We inline this because it is called so often.
@ -71,7 +70,7 @@ inline void check_status_and_throw_exception(ErrorStatus status)
}
template<class T>
void check_object_status_and_throw_exception(const T& object)
void check_object_status_and_throw_exception(T const& object)
{
check_status_and_throw_exception(object.get_status());
}

View file

@ -43,10 +43,6 @@
// boost
#include <boost/scoped_ptr.hpp>
// FIXME
// forward declare so that
// apps using mapnik do not
// need agg headers
namespace agg {
struct trans_affine;
}
@ -129,6 +125,11 @@ public:
return DEFAULT;
}
inline double scale_factor() const
{
return scale_factor_;
}
void render_marker(pixel_position const& pos,
marker const& marker,
agg::trans_affine const& mtx,

View file

@ -39,9 +39,15 @@
# pragma warning(disable : 4996) //_CRT_SECURE_NO_DEPRECATE
# endif
#else
# if __GNUC__ >= 4
# define MAPNIK_EXP __attribute__ ((visibility ("default")))
# define MAPNIK_DECL __attribute__ ((visibility ("default")))
# define MAPNIK_IMP __attribute__ ((visibility ("default")))
# else
# define MAPNIK_EXP
# define MAPNIK_IMP
# define MAPNIK_DECL
# define MAPNIK_IMP
# endif
#endif
#define PROJ_ENVELOPE_POINTS 20

View file

@ -23,6 +23,8 @@
#ifndef MAPNIK_CONFIG_ERROR_HPP
#define MAPNIK_CONFIG_ERROR_HPP
#include <mapnik/config.hpp>
#include <exception>
#include <string>

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/util/hsl.hpp>
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
@ -41,24 +42,6 @@
// stl
#include <string>
namespace mapnik {
// 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;
}
} // namespace mapnik
// boost
#include <boost/version.hpp>

View file

@ -20,8 +20,8 @@
*
*****************************************************************************/
#ifndef MAPNIK_CSS_COLOR_GRAMMAR_DEF_HPP
#define MAPNIK_CSS_COLOR_GRAMMAR_DEF_HPP
// 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.
// boost
#include <boost/version.hpp>
@ -100,5 +100,3 @@ css_color_grammar<Iterator>::css_color_grammar()
}
#endif
#endif

View file

@ -47,7 +47,7 @@ struct MAPNIK_DECL Featureset : private mapnik::noncopyable
virtual ~Featureset() {}
};
typedef MAPNIK_DECL boost::shared_ptr<Featureset> featureset_ptr;
typedef boost::shared_ptr<Featureset> featureset_ptr;
class MAPNIK_DECL datasource_exception : public std::exception
{
@ -134,6 +134,9 @@ public:
typedef boost::shared_ptr<datasource> datasource_ptr;
#ifdef MAPNIK_STATIC_PLUGINS
#define DATASOURCE_PLUGIN(classname)
#else
#define DATASOURCE_PLUGIN(classname) \
extern "C" MAPNIK_EXP const char * datasource_name() \
{ \
@ -147,6 +150,7 @@ typedef boost::shared_ptr<datasource> datasource_ptr;
{ \
delete ds; \
}
#endif
}

View file

@ -164,7 +164,7 @@ namespace mapnik {
public:
typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
void operator()(const logger::severity_type& severity, const stream_buffer &s)
void operator()(const logger::severity_type& /*severity*/, const stream_buffer &s)
{
#ifdef MAPNIK_THREADSAFE
static boost::mutex mutex;
@ -193,15 +193,19 @@ namespace mapnik {
base_log() {}
#ifdef MAPNIK_LOG
base_log(const char* object_name)
{
#ifdef MAPNIK_LOG
if (object_name != NULL)
{
object_name_ = object_name;
}
#endif
}
#else
base_log(const char* /*object_name*/)
{
}
#endif
~base_log()
{
@ -214,13 +218,20 @@ namespace mapnik {
}
template<class T>
#ifdef MAPNIK_LOG
base_log &operator<<(const T &x)
{
#ifdef MAPNIK_LOG
streambuf_ << x;
#endif
return *this;
}
#else
base_log &operator<<(const T& /*x*/)
{
return *this;
}
#endif
private:
#ifdef MAPNIK_LOG

View file

@ -25,14 +25,30 @@
#include <mapnik/config.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/enumeration.hpp>
namespace mapnik
{
enum debug_symbolizer_mode_enum {
DEBUG_SYM_MODE_COLLISION,
DEBUG_SYM_MODE_VERTEX,
debug_symbolizer_mode_enum_MAX
};
DEFINE_ENUM( debug_symbolizer_mode_e, debug_symbolizer_mode_enum );
struct MAPNIK_DECL debug_symbolizer :
public symbolizer_base
{
debug_symbolizer() : symbolizer_base() {}
debug_symbolizer();
debug_symbolizer(debug_symbolizer const& rhs);
debug_symbolizer_mode_e get_mode() const;
void set_mode(debug_symbolizer_mode_e mode);
private:
debug_symbolizer_mode_e mode_;
};
}

View file

@ -77,9 +77,9 @@ struct evaluate : boost::static_visitor<T1>
return attr.value<value_type,feature_type>(feature_);
}
value_type operator() (geometry_type_attribute const& attr) const
value_type operator() (geometry_type_attribute const& geom) const
{
return attr.value<value_type,feature_type>(feature_);
return geom.value<value_type,feature_type>(feature_);
}
value_type operator() (binary_node<tags::logical_and> const & x) const

View file

@ -26,6 +26,7 @@
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node.hpp>
@ -47,12 +48,12 @@ using standard_wide::space_type;
struct unicode_impl
{
typedef UnicodeString result_type;
typedef mapnik::value_unicode_string result_type;
explicit unicode_impl(mapnik::transcoder const& tr)
: tr_(tr) {}
UnicodeString operator()(std::string const& str) const
result_type operator()(std::string const& str) const
{
return tr_.transcode(str.c_str());
}
@ -62,7 +63,6 @@ struct unicode_impl
struct regex_match_impl
{
typedef expr_node result_type;
explicit regex_match_impl(mapnik::transcoder const& tr)

View file

@ -0,0 +1,191 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
// 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.
// mapnik
#include <mapnik/expression_node.hpp>
#include <mapnik/expression_grammar.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
// boost
#include <boost/version.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
// fwd declare
namespace mapnik {
struct attribute;
struct geometry_type_attribute;
}
namespace mapnik
{
template <typename T0,typename T1>
expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const
{
#if defined(BOOST_REGEX_HAS_ICU)
return regex_match_node(node,tr_.transcode(pattern.c_str()));
#else
return regex_match_node(node,pattern);
#endif
}
template <typename T0,typename T1,typename T2>
expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const
{
#if defined(BOOST_REGEX_HAS_ICU)
return regex_replace_node(node,tr_.transcode(pattern.c_str()),tr_.transcode(format.c_str()));
#else
return regex_replace_node(node,pattern,format);
#endif
}
template <typename Iterator>
expression_grammar<Iterator>::expression_grammar(mapnik::transcoder const& tr)
: expression_grammar::base_type(expr),
unicode_(unicode_impl(tr)),
regex_match_(regex_match_impl(tr)),
regex_replace_(regex_replace_impl(tr))
{
using boost::phoenix::construct;
using qi::_1;
using qi::_a;
using qi::_b;
using qi::_r1;
#if BOOST_VERSION > 104200
using qi::no_skip;
#endif
using qi::lexeme;
using qi::_val;
using qi::lit;
using qi::double_;
using qi::hex;
using qi::omit;
using standard_wide::char_;
using standard_wide::no_case;
expr = logical_expr.alias();
logical_expr = not_expr [_val = _1]
>>
*( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
| (( lit("or") | lit("||")) >> not_expr [_val || _1])
)
;
not_expr =
cond_expr [_val = _1 ]
| ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
;
cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
;
equality_expr =
relational_expr [_val = _1]
>> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
| (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
)
;
regex_match_expr = lit(".match")
>> lit('(')
>> ustring [_val = _1]
>> lit(')')
;
regex_replace_expr =
lit(".replace")
>> lit('(')
>> ustring [_a = _1]
>> lit(',')
>> ustring [_b = _1]
>> lit(')') [_val = regex_replace_(_r1,_a,_b)]
;
relational_expr = additive_expr[_val = _1]
>>
*( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
| ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ])
| ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
| ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ])
)
;
additive_expr = multiplicative_expr [_val = _1]
>> * ( '+' >> multiplicative_expr[_val += _1]
| '-' >> multiplicative_expr[_val -= _1]
)
;
multiplicative_expr = unary_expr [_val = _1]
>> *( '*' >> unary_expr [_val *= _1]
| '/' >> unary_expr [_val /= _1]
| '%' >> unary_expr [_val %= construct<mapnik::expr_node>(_1)] //needed by clang++ with -std=c++11
| regex_match_expr[_val = regex_match_(_val, _1)]
| regex_replace_expr(_val) [_val = _1]
)
;
unary_expr = primary_expr [_val = _1]
| '+' >> primary_expr [_val = _1]
| '-' >> primary_expr [_val = -_1]
;
primary_expr = strict_double [_val = _1]
| int__[_val = _1]
| no_case[lit("true")] [_val = true]
| no_case[lit("false")] [_val = false]
| no_case[lit("null")] [_val = value_null() ]
| no_case[geom_type][_val = _1 ]
| ustring [_val = unicode_(_1) ]
| lit("[mapnik::geometry_type]")[_val = construct<mapnik::geometry_type_attribute>()]
| attr [_val = construct<mapnik::attribute>( _1 ) ]
| '(' >> expr [_val = _1 ] >> ')'
;
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
("\\\'", '\'')("\\\"", '\"')
;
#if BOOST_VERSION > 104500
quote_char %= char_('\'') | char_('"');
ustring %= omit[quote_char[_a = _1]]
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
>> lit(_a);
attr %= '[' >> no_skip[+~char_(']')] >> ']';
#else
ustring %= lit('\'')
>> *(unesc_char | "\\x" >> hex | (char_ - lit('\'')))
>> lit('\'');
attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
#endif
}
}

View file

@ -24,6 +24,7 @@
#define MAPNIK_EXPRESSION_NODE_HPP
// mapnik
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/expression_node_types.hpp>
@ -87,7 +88,7 @@ struct binary_node
struct regex_match_node
{
regex_match_node (expr_node const& a, UnicodeString const& ustr);
regex_match_node (expr_node const& a, mapnik::value_unicode_string const& ustr);
expr_node expr;
boost::u32regex pattern;
};
@ -95,10 +96,10 @@ struct regex_match_node
struct regex_replace_node
{
regex_replace_node (expr_node const& a, UnicodeString const& ustr, UnicodeString const& f);
regex_replace_node (expr_node const& a, mapnik::value_unicode_string const& ustr, mapnik::value_unicode_string const& f);
expr_node expr;
boost::u32regex pattern;
UnicodeString format;
mapnik::value_unicode_string format;
};
#else

View file

@ -87,8 +87,8 @@ private:
map_type mapping_;
};
typedef MAPNIK_DECL context<std::map<std::string,std::size_t> > context_type;
typedef MAPNIK_DECL boost::shared_ptr<context_type> context_ptr;
typedef context<std::map<std::string,std::size_t> > context_type;
typedef boost::shared_ptr<context_type> context_ptr;
static const value default_value;
@ -307,9 +307,10 @@ inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
return out;
}
// TODO - remove at Mapnik 3.x
typedef feature_impl Feature;
typedef MAPNIK_DECL boost::shared_ptr<Feature> feature_ptr;
typedef boost::shared_ptr<feature_impl> feature_ptr;
}

View file

@ -35,11 +35,11 @@ namespace mapnik
{
struct feature_factory
{
static boost::shared_ptr<Feature> create (context_ptr const& ctx, mapnik::value_integer fid)
static boost::shared_ptr<feature_impl> create (context_ptr const& ctx, mapnik::value_integer fid)
{
//return boost::allocate_shared<Feature>(boost::pool_allocator<Feature>(),fid);
//return boost::allocate_shared<Feature>(boost::fast_pool_allocator<Feature>(),fid);
return boost::make_shared<Feature>(ctx,fid);
//return boost::allocate_shared<feature_impl>(boost::pool_allocator<feature_impl>(),fid);
//return boost::allocate_shared<feature_impl>(boost::fast_pool_allocator<feature_impl>(),fid);
return boost::make_shared<feature_impl>(ctx,fid);
}
};
}

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/datasource.hpp> // for featureset_ptr
#include <mapnik/config.hpp>
// stl
#include <set>
@ -48,7 +49,7 @@ enum eAttributeCollectionPolicy
};
template <typename Processor>
class feature_style_processor
class MAPNIK_DECL feature_style_processor
{
struct symbol_dispatch;
public:
@ -84,16 +85,13 @@ private:
/*!
* \brief renders a featureset with the given styles.
*/
void render_style(layer const& lay,
Processor & p,
void render_style(Processor & p,
feature_type_style const* style,
rule_cache const& rules,
std::string const& style_name,
featureset_ptr features,
proj_transform const& prj_trans);
Map const& m_;
double scale_factor_;
};
}

View file

@ -33,7 +33,6 @@
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/memory_datasource.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/layer.hpp>
@ -41,10 +40,10 @@
#include <mapnik/rule_cache.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/util/featureset_buffer.hpp>
// boost
#include <boost/variant/apply_visitor.hpp>
@ -53,13 +52,7 @@
// stl
#include <vector>
#include <memory>
#if defined(RENDERING_STATS)
#include <mapnik/timer.hpp>
#include <iomanip>
#include <sstream>
#endif
#include <stdexcept>
namespace mapnik
{
@ -80,11 +73,8 @@ 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)
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
@ -138,11 +128,10 @@ struct has_process
template <typename Processor>
feature_style_processor<Processor>::feature_style_processor(Map const& m, double scale_factor)
: m_(m),
scale_factor_(scale_factor)
: m_(m)
{
// https://github.com/mapnik/mapnik/issues/1100
if (scale_factor_ <= 0)
if (scale_factor <= 0)
{
throw std::runtime_error("scale_factor must be greater than 0.0");
}
@ -151,20 +140,13 @@ feature_style_processor<Processor>::feature_style_processor(Map const& m, double
template <typename Processor>
void feature_style_processor<Processor>::apply(double scale_denom)
{
#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(),true);
if (scale_denom <= 0.0)
scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic());
scale_denom *= scale_factor_;
scale_denom *= p.scale_factor();
for (auto const& lyr : m_.layers() )
{
@ -184,19 +166,9 @@ void feature_style_processor<Processor>::apply(double scale_denom)
}
}
}
catch (proj_init_error const& 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>
@ -206,12 +178,10 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr,
{
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
try
{
projection proj(m_.srs(),true);
if (scale_denom <= 0.0)
scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic());
scale_denom *= scale_factor_;
scale_denom *= p.scale_factor();
if (lyr.visible(scale_denom))
{
@ -226,11 +196,6 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr,
m_.buffer_size(),
names);
}
}
catch (proj_init_error const& ex)
{
MAPNIK_LOG_ERROR(feature_style_processor) << "feature_style_processor: proj_init_error=" << ex.what();
}
p.end_map_processing(m_);
}
@ -263,23 +228,9 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
return;
}
#if defined(RENDERING_STATS)
progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'");
#endif
projection proj1(lay.srs(),true);
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> query_ext = extent; // unbuffered
box2d<double> buffered_query_ext(query_ext); // buffered
@ -298,7 +249,8 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
// clip buffered extent by maximum extent, if supplied
boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
if (maximum_extent) {
if (maximum_extent)
{
buffered_query_ext.clip(*maximum_extent);
}
@ -357,9 +309,6 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
}
}
}
#if defined(RENDERING_STATS)
layer_timer.discard();
#endif
return;
}
@ -397,9 +346,6 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
query q(layer_ext,res,scale_denom,extent);
std::vector<feature_type_style const*> active_styles;
attribute_collector collector(names);
double filt_factor = 1.0;
directive_collector d_collector(filt_factor);
std::vector<rule_cache> rule_caches;
// iterate through all named styles collecting active styles and attribute names
for (std::string const& style_name : style_names)
@ -423,12 +369,8 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
{
cache.add_rule(r);
active_rules = true;
if (ds->type() == datasource::Vector)
{
collector(r);
}
// TODO - in the future rasters should be able to be filtered.
}
}
if (active_rules)
{
@ -455,46 +397,25 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
q.add_property_name(name);
}
}
// Update filter_factor for all enabled raster layers.
for (feature_type_style const* style : active_styles)
{
for (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)
{
for (rule::symbolizers::value_type sym : r.get_symbolizers())
{
// if multiple raster symbolizers, last will be respected
// should we warn or throw?
boost::apply_visitor(d_collector,sym);
}
q.set_filter_factor(filt_factor);
}
}
}
q.set_filter_factor(collector.get_filter_factor());
// Also query the group by attribute
std::string group_by = lay.group_by();
if (group_by != "")
std::string const& group_by = lay.group_by();
if (!group_by.empty())
{
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 != "")
// Render incrementally when the column that we group by changes value.
if (!group_by.empty())
{
featureset_ptr features = ds->features(q);
if (features) {
// Cache all features into the memory_datasource before rendering.
memory_datasource cache(ds->type(),false);
if (features)
{
boost::shared_ptr<featureset_buffer> cache = boost::make_shared<featureset_buffer>();
feature_ptr feature, prev;
while ((feature = features->next()))
{
if (prev && prev->get(group_by) != feature->get(group_by))
@ -504,44 +425,44 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
int i = 0;
for (feature_type_style const* style : active_styles)
{
render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans);
cache->prepare();
render_style(p, style, rule_caches[i], cache, prj_trans);
i++;
}
cache.clear();
cache->clear();
}
cache.push(feature);
cache->push(feature);
prev = feature;
}
int i = 0;
for (feature_type_style const* style : active_styles)
{
render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans);
cache->prepare();
render_style(p, style, rule_caches[i], cache, prj_trans);
i++;
}
}
}
else if (cache_features)
{
memory_datasource cache(ds->type(),false);
featureset_ptr features = ds->features(q);
if (features) {
// Cache all features into the memory_datasource before rendering.
boost::shared_ptr<featureset_buffer> cache = boost::make_shared<featureset_buffer>();
if (features)
{
feature_ptr feature;
while ((feature = features->next()))
{
cache.push(feature);
cache->push(feature);
}
}
int i = 0;
for (feature_type_style const* style : active_styles)
{
render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans);
++i;
cache->prepare();
render_style(p, style, rule_caches[i++], cache, prj_trans);
}
cache->clear();
}
// We only have a single style and no grouping.
else
@ -549,28 +470,19 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
int i = 0;
for (feature_type_style const* style : active_styles)
{
render_style(lay, p, style, rule_caches[i], style_names[i],
ds->features(q), prj_trans);
i++;
render_style(p, style, rule_caches[i++], ds->features(q), prj_trans);
}
}
}
#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 const* style,
rule_cache const& rc,
std::string const& style_name,
featureset_ptr features,
proj_transform const& prj_trans)
{
@ -580,49 +492,24 @@ void feature_style_processor<Processor>::render_style(
p.end_style_processing(*style);
return;
}
#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;
bool was_painted = false;
while ((feature = features->next()))
{
#if defined(RENDERING_STATS)
feature_count++;
bool feat_processed = false;
#endif
bool do_else = true;
bool do_also = false;
for (rule const* r : rc.get_if_rules() )
{
expression_ptr const& expr=r->get_filter();
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
value_type result = boost::apply_visitor(evaluate<feature_impl,value_type>(*feature),*expr);
if (result.to_bool())
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
was_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))
{
for (symbolizer const& sym : symbols)
{
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
@ -640,15 +527,8 @@ void feature_style_processor<Processor>::render_style(
{
for (rule const* r : rc.get_else_rules() )
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
was_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))
{
for (symbolizer const& sym : symbols)
@ -662,15 +542,8 @@ void feature_style_processor<Processor>::render_style(
{
for ( rule const* r : rc.get_also_rules() )
{
#if defined(RENDERING_STATS)
feat_processed = true;
#endif
p.painted(true);
was_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))
{
for (symbolizer const& sym : symbols)
@ -680,32 +553,8 @@ void feature_style_processor<Processor>::render_style(
}
}
}
#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.painted(was_painted);
p.end_style_processing(*style);
}

View file

@ -1,2 +1,8 @@
// TODO - remove this file at mapnik 3.x
#ifdef _MSC_VER
#pragma NOTE("filter_factory.hpp" is now called "expression.hpp")
#else
#warning "filter_factory.hpp" is now called "expression.hpp"
#endif
#include <mapnik/expression.hpp>

View file

@ -35,7 +35,7 @@ class filter_featureset : public Featureset
typedef T filter_type;
public:
filter_featureset(featureset_ptr fs, filter_type const& filter)
filter_featureset(featureset_ptr const& fs, filter_type const& filter)
: fs_(fs), filter_(filter) {}
feature_ptr next()

View file

@ -52,9 +52,6 @@
#include <vector>
#include <map>
// uci
#include <unicode/unistr.h>
struct FT_LibraryRec_;
namespace mapnik
@ -106,7 +103,7 @@ public:
size_type size() const;
glyph_ptr get_glyph(unsigned c) const;
char_info character_dimensions(unsigned c);
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
void get_string_info(string_info & info, mapnik::value_unicode_string const& ustr, char_properties *format);
void set_pixel_sizes(unsigned size);
void set_character_sizes(double size);
private:

View file

@ -54,6 +54,7 @@ private:
boost::optional<color> background_;
image_data_32 data_;
bool painted_;
bool premultiplied_;
public:
image_32(int width,int height);
image_32(image_32 const& rhs);
@ -72,6 +73,11 @@ public:
return painted_;
}
bool premultiplied() const
{
return premultiplied_;
}
inline void clear()
{
std::memset(data_.getData(),0,sizeof(mapnik::image_data_32::pixel_type)*data_.width()*data_.height());
@ -131,59 +137,6 @@ public:
data_(x,y)=rgba;
}
}
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
{
blendPixel2(x,y,rgba1,t,1.0); // do not change opacity
}
inline void blendPixel2(int x,int y,unsigned int rgba1,int t,double opacity)
{
if (checkBounds(x,y))
{
unsigned rgba0 = data_(x,y);
#ifdef MAPNIK_BIG_ENDIAN
unsigned a1 = (unsigned)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = (rgba1 >> 24) & 0xff;
unsigned g1 = (rgba1 >> 16 ) & 0xff;
unsigned b1 = (rgba1 >> 8) & 0xff;
unsigned a0 = (rgba0 & 0xff);
unsigned r0 = ((rgba0 >> 24 ) & 0xff) * a0;
unsigned g0 = ((rgba0 >> 16 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 8) & 0xff) * a0;
a0 = ((a1 + a0) << 8) - a0*a1;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
#else
unsigned a1 = (unsigned)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
a1 = (t*a1) / 255;
if (a1 == 0) return;
unsigned r1 = rgba1 & 0xff;
unsigned g1 = (rgba1 >> 8 ) & 0xff;
unsigned b1 = (rgba1 >> 16) & 0xff;
unsigned a0 = (rgba0 >> 24) & 0xff;
unsigned r0 = (rgba0 & 0xff) * a0;
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
a0 = ((a1 + a0) << 8) - a0*a1;
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
a0 = a0 >> 8;
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
#endif
}
}
void composite_pixel(unsigned op, int x,int y,unsigned c, unsigned cover, double opacity);

View file

@ -198,30 +198,6 @@ public:
return height_;
}
inline void blendPixel(value_type feature_id,int x,int y,unsigned int rgba1,int t)
{
blendPixel2(feature_id ,x,y,rgba1,t,1.0); // do not change opacity
}
inline void blendPixel2(value_type feature_id,int x,int y,unsigned int rgba1,int t,double opacity)
{
if (checkBounds(x,y))
{
#ifdef MAPNIK_BIG_ENDIAN
unsigned a = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
#else
unsigned a = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
#endif
// if the pixel is more than a tenth
// opaque then burn in the feature id
if (a >= 25)
{
data_(x,y) = feature_id;
}
}
}
inline void set_rectangle(value_type id,image_data_32 const& data,int x0,int y0)
{
box2d<int> ext0(0,0,width_,height_);
@ -256,7 +232,7 @@ public:
};
typedef MAPNIK_DECL hit_grid<mapnik::value_integer> grid;
typedef hit_grid<mapnik::value_integer> grid;
}
#endif //MAPNIK_GRID_HPP

View file

@ -123,7 +123,7 @@ struct raster_markers_rasterizer_dispatch_grid
sym_.get_max_error(),
sym_.get_allow_overlap());
double x, y, angle;
while (placement.get_point(x, y, angle))
while (placement.get_point(x, y, angle, sym_.get_ignore_placement()))
{
agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle);
@ -260,7 +260,7 @@ struct vector_markers_rasterizer_dispatch_grid
sym_.get_max_error(),
sym_.get_allow_overlap());
double x, y, angle;
while (placement.get_point(x, y, angle))
while (placement.get_point(x, y, angle, sym_.get_ignore_placement()))
{
agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle);

View file

@ -40,7 +40,7 @@ template<class ColorT> struct blender_gray
enum base_scale_e { base_shift = color_type::base_shift };
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover=0)
unsigned alpha, unsigned /*cover*/=0)
{
*p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
}
@ -256,7 +256,7 @@ public:
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
agg::int8u cover)
agg::int8u /*cover*/)
{
value_type* p = (value_type*)
m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
@ -588,7 +588,7 @@ public:
void blend_from_color(const SrcPixelFormatRenderer& from,
const color_type& color,
int xdst, int ydst,
int xsrc, int ysrc,
int /*xsrc*/, int ysrc,
unsigned len,
agg::int8u cover)
{
@ -615,7 +615,7 @@ public:
void blend_from_lut(const SrcPixelFormatRenderer& from,
const color_type* color_lut,
int xdst, int ydst,
int xsrc, int ysrc,
int /*xsrc*/, int ysrc,
unsigned len,
agg::int8u cover)
{

View file

@ -73,8 +73,8 @@ public:
void end_map_processing(Map const& map);
void start_layer_processing(layer const& lay, box2d<double> const& query_extent);
void end_layer_processing(layer const& lay);
void start_style_processing(feature_type_style const& st) {}
void end_style_processing(feature_type_style const& st) {}
void start_style_processing(feature_type_style const& /*st*/) {}
void end_style_processing(feature_type_style const& /*st*/) {}
void render_marker(mapnik::feature_impl & feature, unsigned int step, pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, composite_mode_e comp_op);
void process(point_symbolizer const& sym,
@ -122,6 +122,10 @@ public:
{
return DEFAULT;
}
inline double scale_factor() const
{
return scale_factor_;
}
private:
buffer_type & pixmap_;

View file

@ -79,7 +79,7 @@ public:
{
if (x_ >= data_.width()) x_=data_.width()-1;
if (y_ >= data_.height()) x_=data_.height()-1;
if (y_ >= data_.height()) y_=data_.height()-1;
if (x_ + width_ > data_.width()) width_= data_.width() - x_;
if (y_ + height_ > data_.height()) height_= data_.height() - y_;
}

View file

@ -38,7 +38,7 @@ public:
y_(y),
tol_(tol) {}
bool pass(Feature & feature)
bool pass(feature_impl & feature)
{
for (geometry_type & geom : feature.paths())
{

View file

@ -29,6 +29,8 @@
// stl
#include <cassert>
#include <cstring>
#include <stdexcept>
namespace mapnik
{
@ -37,11 +39,19 @@ template <class T> class ImageData
public:
typedef T pixel_type;
ImageData(unsigned width,unsigned height)
: width_(width),
height_(height),
pData_((width!=0 && height!=0)? static_cast<T*>(::operator new(sizeof(T)*width*height)):0)
ImageData(int width,int height)
: width_(static_cast<unsigned>(width)),
height_(static_cast<unsigned>(height))
{
if (width < 0)
{
throw std::runtime_error("negative width not allowed for image_data");
}
if (height < 0)
{
throw std::runtime_error("negative height not allowed for image_data");
}
pData_ = (width!=0 && height!=0)? static_cast<T*>(::operator new(sizeof(T)*width*height)):0;
if (pData_) std::memset(pData_,0,sizeof(T)*width_*height_);
}

View file

@ -37,6 +37,7 @@
// agg
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_color_rgba.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"
#include "agg_blur.h"
@ -401,7 +402,7 @@ template <typename Src>
void apply_filter(Src & src, agg_stack_blur const& op)
{
agg::rendering_buffer buf(src.raw_data(),src.width(),src.height(), src.width() * 4);
agg::pixfmt_rgba32 pixf(buf);
agg::pixfmt_rgba32_pre pixf(buf);
agg::stack_blur_rgba32(pixf,op.rx,op.ry);
}
@ -483,9 +484,8 @@ void apply_filter(Src & src, colorize_alpha const& op)
}
}
/*
template <typename Src>
void apply_filter(Src & src, hsla const& transform)
void apply_filter(Src & src, scale_hsla const& transform)
{
using namespace boost::gil;
bool tinting = !transform.is_identity();
@ -504,79 +504,75 @@ void apply_filter(Src & src, hsla const& transform)
uint8_t & g = get_color(src_it[x], green_t());
uint8_t & b = get_color(src_it[x], blue_t());
uint8_t & a = get_color(src_it[x], alpha_t());
double a2 = a/255.0;
double a1 = a2;
if (set_alpha && a2 > 0.01)
double r2 = static_cast<double>(r)/255.0;
double g2 = static_cast<double>(g)/255.0;
double b2 = static_cast<double>(b)/255.0;
double a2 = static_cast<double>(a)/255.0;
// demultiply
if (a2 <= 0.0)
{
r = g = b = 0;
continue;
}
else
{
r2 /= a2;
g2 /= a2;
b2 /= a2;
}
if (set_alpha)
{
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
a = static_cast<unsigned>(std::floor((a2 * 255.0) +.5));
if (a > 255) a = 255;
if (a < 0) a = 0;
if (a2 <= 0)
{
r = g = b = a = 0;
continue;
}
if (tinting && a2 > 0.01)
else if (a2 > 1)
{
a2 = 1;
a = 255;
}
else
{
a = static_cast<uint8_t>(std::floor((a2 * 255.0) +.5));
}
}
if (tinting)
{
double h;
double s;
double l;
// demultiply
if (a1 <= 0.0)
{
r = g = b = 0;
continue;
}
else if (a1 < 1)
{
r /= a1;
g /= a1;
b /= a1;
}
rgb2hsl(r,g,b,h,s,l);
rgb2hsl(r2,g2,b2,h,s,l);
double h2 = transform.h0 + (h * (transform.h1 - transform.h0));
double s2 = transform.s0 + (s * (transform.s1 - transform.s0));
double l2 = transform.l0 + (l * (transform.l1 - transform.l0));
if (h2 > 1) { std::clog << "h2: " << h2 << "\n"; h2 = 1; }
else if (h2 < 0) { std::clog << "h2: " << h2 << "\n"; h2 = 0; }
if (s2 > 1) { std::clog << "h2: " << h2 << "\n"; s2 = 1; }
else if (s2 < 0) { std::clog << "s2: " << s2 << "\n"; s2 = 0; }
if (l2 > 1) { std::clog << "h2: " << h2 << "\n"; l2 = 1; }
else if (l2 < 0) { std::clog << "l2: " << l2 << "\n"; l2 = 0; }
hsl2rgb(h2,s2,l2,r,g,b);
// premultiply
// we only work with premultiplied source,
// thus all color values must be <= alpha
r *= a2;
g *= a2;
b *= a2;
}
else
{
// demultiply
if (a1 <= 0.0)
{
r = g = b = 0;
continue;
}
else if (a1 < 1)
{
r /= a1;
g /= a1;
b /= a1;
if (h2 > 1) { h2 = 1; }
else if (h2 < 0) { h2 = 0; }
if (s2 > 1) { s2 = 1; }
else if (s2 < 0) { s2 = 0; }
if (l2 > 1) { l2 = 1; }
else if (l2 < 0) { l2 = 0; }
hsl2rgb(h2,s2,l2,r2,g2,b2);
}
// premultiply
// we only work with premultiplied source,
// thus all color values must be <= alpha
r *= a2;
g *= a2;
b *= a2;
r2 *= a2;
g2 *= a2;
b2 *= a2;
r = static_cast<uint8_t>(std::floor((r2*255.0)+.5));
g = static_cast<uint8_t>(std::floor((g2*255.0)+.5));
b = static_cast<uint8_t>(std::floor((b2*255.0)+.5));
// all color values must be <= alpha
if (r>a) r=a;
if (g>a) g=a;
if (b>a) b=a;
}
}
}
}
}
*/
template <typename Src>
void apply_filter(Src & src, gray const& op)
void apply_filter(Src & src, gray const& /*op*/)
{
using namespace boost::gil;
@ -626,14 +622,14 @@ void x_gradient_impl(Src const& src_view, Dst const& dst_view)
}
template <typename Src>
void apply_filter(Src & src, x_gradient const& op)
void apply_filter(Src & src, x_gradient const& /*op*/)
{
double_buffer<Src> tb(src);
x_gradient_impl(tb.src_view, tb.dst_view);
}
template <typename Src>
void apply_filter(Src & src, y_gradient const& op)
void apply_filter(Src & src, y_gradient const& /*op*/)
{
double_buffer<Src> tb(src);
x_gradient_impl(rotated90ccw_view(tb.src_view),
@ -641,7 +637,7 @@ void apply_filter(Src & src, y_gradient const& op)
}
template <typename Src>
void apply_filter(Src & src, invert const& op)
void apply_filter(Src & src, invert const& /*op*/)
{
using namespace boost::gil;

View file

@ -68,8 +68,8 @@ struct image_filter_grammar :
qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
qi::rule<Iterator, ContType(), qi::ascii::space_type> filter;
qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter;
//qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>,
// void(ContType&), qi::ascii::space_type> hsla_filter;
qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>,
void(ContType&), qi::ascii::space_type> scale_hsla_filter;
qi::rule<Iterator, qi::locals<mapnik::filter::colorize_alpha, mapnik::filter::color_stop>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter;
qi::rule<Iterator, qi::ascii::space_type> no_args;
qi::uint_parser< unsigned, 10, 1, 3 > radius_;

View file

@ -26,13 +26,16 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/color.hpp>
#include <mapnik/config_error.hpp>
// boost
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/variant.hpp>
// stl
#include <vector>
#include <ostream>
#include <iterator> // for std::back_insert_iterator
namespace mapnik { namespace filter {
struct blur {};
@ -53,10 +56,9 @@ struct agg_stack_blur
unsigned ry;
};
/*
struct hsla
struct scale_hsla
{
hsla(double _h0, double _h1,
scale_hsla(double _h0, double _h1,
double _s0, double _s1,
double _l0, double _l1,
double _a0, double _a1) :
@ -67,7 +69,19 @@ struct hsla
l0(_l0),
l1(_l1),
a0(_a0),
a1(_a1) {}
a1(_a1) {
if (h0 < 0 || h0 > 1 ||
h1 < 0 || h1 > 1 ||
s0 < 0 || s0 > 1 ||
s1 < 0 || s1 > 1 ||
l0 < 0 || l0 > 1 ||
l1 < 0 || l1 > 1 ||
a0 < 0 || a0 > 1 ||
a1 < 0 || a1 > 1)
{
throw config_error("scale-hsla values must be between 0 and 1");
}
}
inline bool is_identity() const {
return (h0 == 0 &&
h1 == 1 &&
@ -80,14 +94,6 @@ struct hsla
return (a0 == 0 &&
a1 == 1);
}
std::string to_string() const {
std::ostringstream s;
s << h0 << "x" << h1 << ";"
<< s0 << "x" << s1 << ";"
<< l0 << "x" << l1 << ";"
<< a0 << "x" << a1;
return s.str();
}
double h0;
double h1;
double s0;
@ -97,7 +103,6 @@ struct hsla
double a0;
double a1;
};
*/
struct color_stop
{
@ -123,7 +128,7 @@ typedef boost::variant<filter::blur,
filter::x_gradient,
filter::y_gradient,
filter::invert,
//filter::hsla,
filter::scale_hsla,
filter::colorize_alpha> filter_type;
inline std::ostream& operator<< (std::ostream& os, blur)
@ -144,16 +149,14 @@ inline std::ostream& operator<< (std::ostream& os, agg_stack_blur const& filter)
return os;
}
/*
inline std::ostream& operator<< (std::ostream& os, hsla const& filter)
inline std::ostream& operator<< (std::ostream& os, scale_hsla const& filter)
{
os << "hsla(" << filter.h0 << 'x' << filter.h1 << ':'
os << "hsla-transform(" << filter.h0 << 'x' << filter.h1 << ':'
<< filter.s0 << 'x' << filter.s1 << ':'
<< filter.l0 << 'x' << filter.l1 << ':'
<< filter.a0 << 'x' << filter.a1 << ')';
return os;
}
*/
inline std::ostream& operator<< (std::ostream& os, emboss)
{
@ -197,7 +200,27 @@ inline std::ostream& operator<< (std::ostream& os, invert)
return os;
}
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter);
template <typename Out>
struct to_string_visitor : boost::static_visitor<void>
{
to_string_visitor(Out & out)
: out_(out) {}
template <typename T>
void operator () (T const& filter_tag)
{
out_ << filter_tag;
}
Out & out_;
};
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter)
{
to_string_visitor<std::ostream> visitor(os);
boost::apply_visitor(visitor, filter);
return os;
}
MAPNIK_DECL bool generate_image_filters(std::back_insert_iterator<std::string> & sink, std::vector<filter_type> const& v);

View file

@ -64,11 +64,13 @@ public:
#if defined(HAVE_CAIRO)
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
std::string const& filename,
double scale_factor=1.0);
double scale_factor=1.0,
double scale_denominator=0.0);
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
std::string const& filename,
std::string const& type,
double scale_factor=1.0);
double scale_factor=1.0,
double scale_denominator=0.0);
#endif
template <typename T>
@ -150,6 +152,7 @@ inline bool is_webp (std::string const& filename)
return boost::algorithm::iends_with(filename,std::string(".webp"));
}
inline boost::optional<std::string> type_from_filename(std::string const& filename)
{

View file

@ -39,7 +39,7 @@ public:
data_(data)
{
if (x_ >= data_.width()) x_=data_.width()-1;
if (y_ >= data_.height()) x_=data_.height()-1;
if (y_ >= data_.height()) y_=data_.height()-1;
if (x_ + width_ > data_.width()) width_= data_.width() - x_;
if (y_ + height_ > data_.height()) height_= data_.height() - y_;
}

View file

@ -40,7 +40,7 @@ namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType> struct feature_collection_grammar;
template <typename Iterator>
class feature_collection_parser : private mapnik::noncopyable
class MAPNIK_DECL feature_collection_parser : private mapnik::noncopyable
{
typedef Iterator iterator_type;
typedef mapnik::feature_impl feature_type;

View file

@ -27,6 +27,7 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
@ -122,7 +123,7 @@ struct utf8
template <typename T>
struct result { typedef std::string type; };
std::string operator() (UnicodeString const& ustr) const
std::string operator() (mapnik::value_unicode_string const& ustr) const
{
std::string result;
to_utf8(ustr,result);
@ -234,7 +235,7 @@ struct feature_generator_grammar:
karma::rule<OutputIterator, pair_type()> pair;
karma::rule<OutputIterator, void(mapnik::value const&)> value;
karma::rule<OutputIterator, mapnik::value_null()> value_null_;
karma::rule<OutputIterator, UnicodeString()> ustring;
karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring;
typename karma::int_generator<mapnik::value_integer,10, false> int__;
// phoenix functions
phoenix::function<get_id> id_;

View file

@ -67,6 +67,31 @@ public:
mapnik::transcoder const& tr_;
};
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
struct put_property
{
typedef void result_type;
explicit put_property(mapnik::transcoder const& tr)
: tr_(tr) {}
template <typename T0,typename T1, typename T2>
result_type operator() (T0 & feature, T1 const& key, T2 const& val) const
{
mapnik::value v = boost::apply_visitor(attribute_value_visitor(tr_),val); // TODO: optimize
feature.put_new(key, v);
}
mapnik::transcoder const& tr_;
};
struct extract_geometry
{
typedef boost::ptr_vector<mapnik::geometry_type>& result_type;
template <typename T>
result_type operator() (T & feature) const
{
return feature.paths();
}
};
#else
struct put_property
{
@ -95,6 +120,7 @@ struct extract_geometry
return feature.paths();
}
};
#endif
template <typename Iterator, typename FeatureType>
struct feature_grammar :

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