stay in sync with master

This commit is contained in:
Dane Springmeyer 2012-04-09 17:58:44 -07:00
commit c0c6962780
491 changed files with 8744 additions and 5326 deletions

3
.gitignore vendored
View file

@ -39,7 +39,8 @@ tests/data/sqlite/*index
demo/c++/cairo-demo.pdf demo/c++/cairo-demo.pdf
demo/c++/cairo-demo.png demo/c++/cairo-demo.png
demo/c++/cairo-demo256.png demo/c++/cairo-demo256.png
demo/c++/demo.tif
demo/c++/demo.jpg demo/c++/demo.jpg
demo/c++/demo.png demo/c++/demo.png
demo/c++/demo256.png demo/c++/demo256.png
tests/cpp_tests/*-bin

View file

@ -1,8 +1,4 @@
# $Id: CHANGELOG 776 2008-12-7 01:30:27Z dane $ # Mapnik Changelog
----------------
Mapnik Changelog
----------------
A simple log of core changes affecting Mapnik usage. A simple log of core changes affecting Mapnik usage.
@ -11,10 +7,21 @@ Developers: Please commit along with changes.
For a complete change history, see the SVN log. For a complete change history, see the SVN log.
Mapnik 2.1.0 ## Mapnik 2.1.0
------------
- Removed mutex locking during reprojection if using >= proj 4.7 (#1072) - GDAL: allow setting nodata value on the fly (will override value if nodata is set in data) (#1161)
- GDAL: respect nodata for paletted/colormapped images (#1160)
- PostGIS: Added a new option called 'autodetect_key_field' (by default false) that if true will
trigger autodetection of a given tables' primary key allowing for feature.id() to represent
globally unique ids. This option has no effect if the user has not manually supplied the 'key_field' option. (#804)
- Cairo: Add full rendering support for markers to match AGG renderer functionality (#1071)
- Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentionally radii) (#1134)
- Added 'ignore-placement` attribute to markers-symbolizer (#1135)
- Removed PointDatasource - use more robust MemoryDatasource instead (#1032) - Removed PointDatasource - use more robust MemoryDatasource instead (#1032)
@ -26,11 +33,47 @@ Mapnik 2.1.0
- Added <layer_by_sql> parameter in OGR plugin to select a layer by SQL query (besides name or index): see http://www.gdal.org/ogr/ogr_sql.html for specifications (kunitoki) (#472) - Added <layer_by_sql> parameter in OGR plugin to select a layer by SQL query (besides name or index): see http://www.gdal.org/ogr/ogr_sql.html for specifications (kunitoki) (#472)
- Added suppport for output maps as tiff files (addresses #967 partially) - Added support for output maps as tiff files (addresses #967 partially)
- Added support for justify-alignment=auto. This is the new default. (#1125)
Mapnik 2.0.0 ## Mapnik 2.0.1
------------
(Packaged from 5cd3cb2efdaf7e9990a57e8e00b652a81aaa39ae)
- Support for PostGIS 2.0 (#956,#1083)
- Switched back to "libmapnik" and "import mapnik" rather than "mapnik2" (mapnik2 will still work from python) (#941)
- Restored Python 2.5 compatibility (#904)
- Fixed `mapnik-config --version` (#903)
- Cairo: Add full rendering support for markers to match AGG renderer functionality (#1071)
- Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentially radii) (#1134)
- Added 'ignore-placement` attribute to markers-symbolizer (#1135)
- Removed svn_revision info from mapnik-config and python bindings as git is now used
- Removed OGCServer from core - now at https://github.com/mapnik/OGCServer (e7f6267)
- Fixed SQLite open stability across platforms/versions (#854)
- 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)
- Fixed bug in shield line placement when dx/dy are used to shift the label relative to the placement point (Matt Amos) (#908)
- Fix to avoid modifying a feature if an attribute is requested that does not exist (0f5ab18ed)
- Fixed ability to save to jpeg format from python (7387afd9) (#896)
## Mapnik 2.0.0
- Add minimum-path-length property to text_symbolizer to allow labels to be placed only on lines of a certain length (#865) - Add minimum-path-length property to text_symbolizer to allow labels to be placed only on lines of a certain length (#865)
@ -119,8 +162,7 @@ Mapnik 2.0.0
- Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553) - Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553)
Mapnik 0.7.2 Release # Mapnik 0.7.2 Release
--------------------
- Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes) - Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes)
@ -163,8 +205,7 @@ Mapnik 0.7.2 Release
- Fixed reading of label_position_tolerance on text_symbolizer and height for building_symbolizer - Fixed reading of label_position_tolerance on text_symbolizer and height for building_symbolizer
Mapnik 0.7.0 Release # Mapnik 0.7.0 Release
--------------------
(Packaged from r1574) (Packaged from r1574)
@ -203,13 +244,13 @@ Mapnik 0.7.0 Release
* Valid Usages include: * Valid Usages include:
<Parameter name="table"> <Parameter name="table">
(Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map (Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map
</Parameter> </Parameter>
<Parameter name="table"> <Parameter name="table">
(Select * from table where geom &amp;&amp; !bbox!) as map (Select * from table where geom &amp;&amp; !bbox!) as map
</Parameter> </Parameter>
- PostGIS Plugin: Added 'scale_denominator' substitution ability in sql query string (#415/#465) - PostGIS Plugin: Added 'scale_denominator' substitution ability in sql query string (#415/#465)
@ -305,8 +346,7 @@ Mapnik 0.7.0 Release
Mapnik 0.6.1 Release # Mapnik 0.6.1 Release
--------------------
(Packaged from r1247) (Packaged from r1247)
@ -390,8 +430,7 @@ Mapnik 0.6.1 Release
Mapnik 0.6.0 Release # Mapnik 0.6.0 Release
--------------------
(Packaged from r1066) (Packaged from r1066)

View file

@ -18,6 +18,13 @@ uninstall:
python scons/scons.py uninstall python scons/scons.py uninstall
test: test:
@echo "*** Running visual tests…"
@python tests/visual_tests/test.py -q
@echo "*** Running C++ tests..."
@for FILE in tests/cpp_tests/*-bin; do \
$${FILE}; \
done
@echo "*** Running python tests..."
@python tests/run_tests.py -q @python tests/run_tests.py -q
pep8: pep8:
@ -26,4 +33,9 @@ pep8:
@pep8 -r --select=W293 -q --filename=*.py `pwd`/tests/ | xargs gsed -i 's/^[ \r\t]*$//' @pep8 -r --select=W293 -q --filename=*.py `pwd`/tests/ | xargs gsed -i 's/^[ \r\t]*$//'
@pep8 -r --select=W391 -q --filename=*.py `pwd`/tests/ | xargs gsed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' @pep8 -r --select=W391 -q --filename=*.py `pwd`/tests/ | xargs gsed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}'
grind:
@for FILE in tests/cpp_tests/*-bin; do \
valgrind --leak-check=full --log-fd=1 $${FILE} | grep definitely; \
done
.PHONY: clean reset uninstall test install .PHONY: clean reset uninstall test install

View file

@ -15,8 +15,6 @@
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# $Id$
import os import os
@ -325,7 +323,7 @@ opts.AddVariables(
# Variables affecting rendering back-ends # Variables affecting rendering back-ends
BoolVariable('RENDERING_STATS', 'Output rendering statistics during style processing', 'False'), BoolVariable('RENDERING_STATS', 'Output rendering statistics during style processing', 'False'),
BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'), BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'),
BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'), BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'),
@ -345,7 +343,12 @@ opts.AddVariables(
PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
PathVariable('RASTERLITE_INCLUDES', 'Search path for RASTERLITE include files', '/usr/include/', PathVariable.PathAccept), PathVariable('RASTERLITE_INCLUDES', 'Search path for RASTERLITE include files', '/usr/include/', PathVariable.PathAccept),
PathVariable('RASTERLITE_LIBS', 'Search path for RASTERLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept), PathVariable('RASTERLITE_LIBS', 'Search path for RASTERLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
# Variables for logging and statistics
BoolVariable('ENABLE_LOG', 'Enable logging, which is enabled by default when building in *debug*', 'False'),
BoolVariable('ENABLE_STATS', 'Enable global statistics during map processing', 'False'),
('LOG_FORMAT_STRING', 'The format string used before log output string, piped through strftime (max length of 255 characters)', 'Mapnik LOG> %Y-%m-%d %H:%M:%S:'),
# Other variables # Other variables
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'), 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 given aborts installation of bundled DejaVu fonts)',''), ('SYSTEM_FONTS','Provide location for python bindings to register fonts (if given aborts installation of bundled DejaVu fonts)',''),
@ -359,7 +362,7 @@ opts.AddVariables(
EnumVariable('THREADING','Set threading support','multi', ['multi','single']), EnumVariable('THREADING','Set threading support','multi', ['multi','single']),
EnumVariable('XMLPARSER','Set xml parser','libxml2', ['libxml2','ptree']), EnumVariable('XMLPARSER','Set xml parser','libxml2', ['libxml2','ptree']),
('JOBS', 'Set the number of parallel compilations', "1", lambda key, value, env: int(value), int), ('JOBS', 'Set the number of parallel compilations', "1", lambda key, value, env: int(value), int),
BoolVariable('DEMO', 'Compile demo c++ application', 'False'), BoolVariable('DEMO', 'Compile demo c++ application', 'True'),
BoolVariable('PGSQL2SQLITE', 'Compile and install a utility to convert postgres tables to sqlite', 'False'), BoolVariable('PGSQL2SQLITE', 'Compile and install a utility to convert postgres tables to sqlite', 'False'),
BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'), BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'),
BoolVariable('SAMPLE_INPUT_PLUGINS', 'Compile and install sample plugins', 'False'), BoolVariable('SAMPLE_INPUT_PLUGINS', 'Compile and install sample plugins', 'False'),
@ -768,7 +771,7 @@ def GetMapnikLibVersion(context):
int main() int main()
{ {
std::cout << MAPNIK_VERSION << std::endl; std::cout << MAPNIK_VERSION_STRING << std::endl;
return 0; return 0;
} }
@ -778,11 +781,7 @@ int main()
context.Result(ret[0]) context.Result(ret[0])
if not ret[1]: if not ret[1]:
return [] return []
version = int(ret[1].strip()) return ret[1].strip()
patch_level = version % 100
minor_version = version / 100 % 1000
major_version = version / 100000
return [major_version,minor_version,patch_level]
def icu_at_least_four_two(context): def icu_at_least_four_two(context):
ret = context.TryRun(""" ret = context.TryRun("""
@ -814,6 +813,9 @@ int main()
return False return False
def boost_regex_has_icu(context): def boost_regex_has_icu(context):
if env['RUNTIME_LINK'] == 'static':
context.env.Append(LIBS='icui18n')
context.env.Append(LIBS='icudata')
ret = context.TryRun(""" ret = context.TryRun("""
#include <boost/regex/icu.hpp> #include <boost/regex/icu.hpp>
@ -1072,7 +1074,7 @@ if not preconfigured:
# libxml2 should be optional but is currently not # libxml2 should be optional but is currently not
# https://github.com/mapnik/mapnik/issues/913 # https://github.com/mapnik/mapnik/issues/913
if conf.parse_config('XML2_CONFIG'): if conf.parse_config('XML2_CONFIG',checks='--cflags'):
env['HAS_LIBXML2'] = True env['HAS_LIBXML2'] = True
LIBSHEADERS = [ LIBSHEADERS = [
@ -1164,7 +1166,7 @@ if not preconfigured:
env.Append(CXXFLAGS = '-DBOOST_REGEX_HAS_ICU') env.Append(CXXFLAGS = '-DBOOST_REGEX_HAS_ICU')
else: else:
env['SKIPPED_DEPS'].append('boost_regex_icu') env['SKIPPED_DEPS'].append('boost_regex_icu')
env['REQUESTED_PLUGINS'] = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])] env['REQUESTED_PLUGINS'] = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])]
if len(env['REQUESTED_PLUGINS']): if len(env['REQUESTED_PLUGINS']):
@ -1382,14 +1384,13 @@ if not preconfigured:
# fetch the mapnik version header in order to set the # fetch the mapnik version header in order to set the
# ABI version used to build libmapnik.so on linux in src/build.py # ABI version used to build libmapnik.so on linux in src/build.py
abi = conf.GetMapnikLibVersion() abi = conf.GetMapnikLibVersion()
abi_fallback = [2,0,0] abi_fallback = "2.0.1-pre"
if not abi: if not abi:
color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback) color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback)
env['ABI_VERSION'] = abi_fallback abi = abi_fallback
else:
env['ABI_VERSION'] = abi
env['MAPNIK_VERSION_STRING'] = '.'.join(['%d' % i for i in env['ABI_VERSION']])
env['ABI_VERSION'] = abi.replace('-pre','').split('.')
env['MAPNIK_VERSION_STRING'] = abi
# Common C++ flags. # Common C++ flags.
if env['THREADING'] == 'multi': if env['THREADING'] == 'multi':
@ -1411,10 +1412,29 @@ if not preconfigured:
pthread = '-pthread' pthread = '-pthread'
# Common debugging flags. # Common debugging flags.
debug_flags = '-g -DDEBUG -DMAPNIK_DEBUG' # http://lists.fedoraproject.org/pipermail/devel/2010-November/144952.html
debug_flags = '-g -fno-omit-frame-pointer -DDEBUG -DMAPNIK_DEBUG'
ndebug_flags = '-DNDEBUG' ndebug_flags = '-DNDEBUG'
# Enable logging in debug mode (always) and release mode (when specified)
log_enabled = ' -DMAPNIK_LOG -DMAPNIK_LOG_FORMAT="%s"' % env['LOG_FORMAT_STRING']
if env['DEBUG']:
debug_flags += log_enabled
else:
if env['ENABLE_LOG']:
ndebug_flags += log_enabled
# Enable statistics reporting
if env['ENABLE_STATS']:
debug_flags += ' -DMAPNIK_STATS'
ndebug_flags += ' -DMAPNIK_STATS'
# Add rdynamic to allow using statics between application and plugins
# http://stackoverflow.com/questions/8623657/multiple-instances-of-singleton-across-shared-libraries-on-linux
if env['PLATFORM'] != 'Darwin':
env.MergeFlags('-rdynamic')
# Customizing the C++ compiler flags depending on: # Customizing the C++ compiler flags depending on:
# (1) the C++ compiler used; and # (1) the C++ compiler used; and
# (2) whether debug binaries are requested. # (2) whether debug binaries are requested.
@ -1719,7 +1739,7 @@ if not HELP_REQUESTED:
# build C++ tests # build C++ tests
# not ready for release # not ready for release
#SConscript('tests/cpp_tests/build.py') SConscript('tests/cpp_tests/build.py')
# not ready for release # not ready for release
#if env['SVG_RENDERER']: #if env['SVG_RENDERER']:

View file

@ -120,7 +120,7 @@ class _Coord(Coord,_injector):
Returns the easting (x) and northing (y) as a Returns the easting (x) and northing (y) as a
coordinate pair. coordinate pair.
Example: Project the geographic coordinates of the Example: Project the geographic coordinates of the
city center of Stuttgart into the local city center of Stuttgart into the local
map projection (GK Zone 3/DHDN, EPSG 31467) map projection (GK Zone 3/DHDN, EPSG 31467)
@ -136,7 +136,7 @@ class _Coord(Coord,_injector):
into the geographic space. The x component is into the geographic space. The x component is
considered to be the easting, the y component considered to be the easting, the y component
to be the northing. to be the northing.
Returns the longitude (x) and latitude (y) as a Returns the longitude (x) and latitude (y) as a
coordinate pair. coordinate pair.
@ -153,8 +153,8 @@ class _Coord(Coord,_injector):
class _Box2d(Box2d,_injector): class _Box2d(Box2d,_injector):
""" """
Represents a spatial envelope (i.e. bounding box). Represents a spatial envelope (i.e. bounding box).
Following operators are defined for Box2d: Following operators are defined for Box2d:
Addition: Addition:
@ -285,12 +285,12 @@ def Datasource(**keywords):
Create a Mapnik Datasource using a dictionary of parameters. Create a Mapnik Datasource using a dictionary of parameters.
Keywords must include: Keywords must include:
type='plugin_name' # e.g. type='gdal' type='plugin_name' # e.g. type='gdal'
See the convenience factory methods of each input plugin for See the convenience factory methods of each input plugin for
details on additional required keyword arguments. details on additional required keyword arguments.
""" """
return CreateDatasource(keywords) return CreateDatasource(keywords)
@ -322,7 +322,7 @@ def PostGIS(**keywords):
Required keyword arguments: Required keyword arguments:
dbname -- database name to connect to dbname -- database name to connect to
table -- table name or subselect query table -- table name or subselect query
*Note: if using subselects for the 'table' value consider also *Note: if using subselects for the 'table' value consider also
passing the 'geometry_field' and 'srid' and 'extent_from_subquery' passing the 'geometry_field' and 'srid' and 'extent_from_subquery'
options and/or specifying the 'geometry_table' option. options and/or specifying the 'geometry_table' option.
@ -572,13 +572,6 @@ def Geos(**keywords):
keywords['type'] = 'geos' keywords['type'] = 'geos'
return CreateDatasource(keywords) return CreateDatasource(keywords)
def mapnik_version_string(version=mapnik_version()):
"""Return the Mapnik version as a string."""
patch_level = version % 100
minor_version = version / 100 % 1000
major_version = version / 100000
return '%s.%s.%s' % ( major_version, minor_version,patch_level)
def mapnik_version_from_string(version_string): def mapnik_version_from_string(version_string):
"""Return the Mapnik version from a string.""" """Return the Mapnik version from a string."""
n = version_string.split('.') n = version_string.split('.')
@ -599,113 +592,3 @@ def register_fonts(path=fontscollectionpath,valid_extensions=['.ttf','.otf','.tt
# auto-register known plugins and fonts # auto-register known plugins and fonts
register_plugins() register_plugins()
register_fonts() register_fonts()
# Explicitly export API members to avoid namespace pollution
# and ensure correct documentation processing
__all__ = [
# classes
'CharProperties',
'Color',
'Coord',
'Palette',
#'ColorBand',
'CompositeOp',
'DatasourceCache',
'MemoryDatasource',
'Box2d',
'Feature',
'Featureset',
'FontEngine',
'FontSet',
'FormattingNode',
'FormattingText',
'FormattingFormat',
'FormattingList',
'FormattingExpressionFormat',
'Geometry2d',
'Image',
'ImageView',
'Grid',
'GridView',
'Layer',
'Layers',
'LinePatternSymbolizer',
'LineSymbolizer',
'Map',
'MarkersSymbolizer',
'Names',
'Path',
'Parameter',
'Parameters',
'PointSymbolizer',
'PolygonPatternSymbolizer',
'PolygonSymbolizer',
'ProcessedText',
'ProjTransform',
'Projection',
'Query',
'RasterSymbolizer',
'RasterColorizer',
'Rule', 'Rules',
'ShieldSymbolizer',
'Singleton',
'Stroke',
'Style',
'Symbolizer',
'Symbolizers',
'TextPlacements',
'TextPlacementInfo',
'TextSymbolizer',
'TextSymbolizerProperties',
'ViewTransform',
# enums
'aspect_fix_mode',
'point_placement',
'label_placement',
'line_cap',
'line_join',
'text_transform',
'vertical_alignment',
'horizontal_alignment',
'justify_alignment',
'pattern_alignment',
'filter_mode',
# functions
# datasources
'Datasource',
'CreateDatasource',
'Shapefile',
'PostGIS',
'Raster',
'Gdal',
'Occi',
'Ogr',
'SQLite',
'Osm',
'Kismet',
# version and environment
'mapnik_version_string',
'mapnik_version',
'has_cairo',
'has_pycairo',
# factory methods
'Expression',
'PathExpression',
# load/save/render
'load_map',
'render_stats',
'load_map_from_string',
'save_map',
'save_map_to_string',
'render',
'render_grid',
'render_tile_to_file',
'render_to_file',
# other
'register_plugins',
'register_fonts',
'scale_denominator',
# deprecated
'Filter',
'Envelope',
]

View file

@ -43,7 +43,7 @@ except ImportError:
class centering: class centering:
"""Style of centering to use with the map, the default is constrained """Style of centering to use with the map, the default is constrained
none: map will be placed flush with the margin/box in the top left corner none: map will be placed flush with the margin/box in the top left corner
constrained: map will be centered on the most constrained axis (for a portrait page constrained: map will be centered on the most constrained axis (for a portrait page
and a square map this will be horizontally) and a square map this will be horizontally)
@ -167,7 +167,7 @@ def sequence_scale(scale,scale_sequence):
"""Default scale helper, this rounds scale to a 'sensible' value""" """Default scale helper, this rounds scale to a 'sensible' value"""
factor = math.floor(math.log10(scale)) factor = math.floor(math.log10(scale))
norm = scale/(10**factor) norm = scale/(10**factor)
for s in scale_sequence: for s in scale_sequence:
if norm <= s: if norm <= s:
return s*10**factor return s*10**factor
@ -199,7 +199,7 @@ def deg_min_sec_scale(scale):
return x return x
else: else:
return x return x
def format_deg_min_sec(value): def format_deg_min_sec(value):
deg = math.floor(value) deg = math.floor(value)
min = math.floor((value-deg)/(1.0/60)) min = math.floor((value-deg)/(1.0/60))
@ -219,12 +219,12 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
opens the given multipage PDF and converts each page to be a layer in a single page PDF opens the given multipage PDF and converts each page to be a layer in a single page PDF
layer_names should be a sequence of the user visible names of the layers, if not given layer_names should be a sequence of the user visible names of the layers, if not given
or if shorter than num pages generic names will be given to the unnamed layers or if shorter than num pages generic names will be given to the unnamed layers
if output_name is not provided a temporary file will be used for the conversion which if output_name is not provided a temporary file will be used for the conversion which
will then be copied back over the source file. will then be copied back over the source file.
requires pyPdf >= 1.13 to be available""" requires pyPdf >= 1.13 to be available"""
if not HAS_PYPDF: if not HAS_PYPDF:
raise Exception("pyPdf Not available") raise Exception("pyPdf Not available")
@ -235,13 +235,13 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
else: else:
(outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename))
outfile = os.fdopen(outfd,'wb') outfile = os.fdopen(outfd,'wb')
i = pyPdf.PdfFileReader(infile) i = pyPdf.PdfFileReader(infile)
o = pyPdf.PdfFileWriter() o = pyPdf.PdfFileWriter()
template_page_size = i.pages[0].mediaBox template_page_size = i.pages[0].mediaBox
op = o.addBlankPage(width=template_page_size.getWidth(),height=template_page_size.getHeight()) op = o.addBlankPage(width=template_page_size.getWidth(),height=template_page_size.getHeight())
contentkey = pyPdf.generic.NameObject('/Contents') contentkey = pyPdf.generic.NameObject('/Contents')
resourcekey = pyPdf.generic.NameObject('/Resources') resourcekey = pyPdf.generic.NameObject('/Resources')
propertieskey = pyPdf.generic.NameObject('/Properties') propertieskey = pyPdf.generic.NameObject('/Properties')
@ -249,7 +249,7 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
op[resourcekey] = pyPdf.generic.DictionaryObject() op[resourcekey] = pyPdf.generic.DictionaryObject()
properties = pyPdf.generic.DictionaryObject() properties = pyPdf.generic.DictionaryObject()
ocgs = pyPdf.generic.ArrayObject() ocgs = pyPdf.generic.ArrayObject()
for (i, p) in enumerate(i.pages): for (i, p) in enumerate(i.pages):
# first start an OCG for the layer # first start an OCG for the layer
ocgname = pyPdf.generic.NameObject('/oc%d' % i) ocgname = pyPdf.generic.NameObject('/oc%d' % i)
@ -262,9 +262,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
p[pyPdf.generic.NameObject('/Contents')].append(ocgend) p[pyPdf.generic.NameObject('/Contents')].append(ocgend)
else: else:
p[pyPdf.generic.NameObject('/Contents')] = pyPdf.generic.ArrayObject((ocgstart,p['/Contents'],ocgend)) p[pyPdf.generic.NameObject('/Contents')] = pyPdf.generic.ArrayObject((ocgstart,p['/Contents'],ocgend))
op.mergePage(p) op.mergePage(p)
ocg = pyPdf.generic.DictionaryObject() ocg = pyPdf.generic.DictionaryObject()
ocg[pyPdf.generic.NameObject('/Type')] = pyPdf.generic.NameObject('/OCG') ocg[pyPdf.generic.NameObject('/Type')] = pyPdf.generic.NameObject('/OCG')
if len(layer_names) > i: if len(layer_names) > i:
@ -274,9 +274,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
indirect_ocg = o._addObject(ocg) indirect_ocg = o._addObject(ocg)
properties[ocgname] = indirect_ocg properties[ocgname] = indirect_ocg
ocgs.append(indirect_ocg) ocgs.append(indirect_ocg)
op[resourcekey][propertieskey] = o._addObject(properties) op[resourcekey][propertieskey] = o._addObject(properties)
ocproperties = pyPdf.generic.DictionaryObject() ocproperties = pyPdf.generic.DictionaryObject()
ocproperties[pyPdf.generic.NameObject('/OCGs')] = ocgs ocproperties[pyPdf.generic.NameObject('/OCGs')] = ocgs
defaultview = pyPdf.generic.DictionaryObject() defaultview = pyPdf.generic.DictionaryObject()
@ -289,16 +289,16 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
else: else:
defaultview[pyPdf.generic.NameObject('/Order')] = pyPdf.generic.ArrayObject(reversed(ocgs)) defaultview[pyPdf.generic.NameObject('/Order')] = pyPdf.generic.ArrayObject(reversed(ocgs))
defaultview[pyPdf.generic.NameObject('/OFF')] = pyPdf.generic.ArrayObject() defaultview[pyPdf.generic.NameObject('/OFF')] = pyPdf.generic.ArrayObject()
ocproperties[pyPdf.generic.NameObject('/D')] = o._addObject(defaultview) ocproperties[pyPdf.generic.NameObject('/D')] = o._addObject(defaultview)
o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = o._addObject(ocproperties) o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = o._addObject(ocproperties)
o.write(outfile) o.write(outfile)
outfile.close() outfile.close()
infile.close() infile.close()
if not output_name: if not output_name:
os.rename(outfilename, filename) os.rename(outfilename, filename)
@ -318,7 +318,7 @@ class PDFPrinter:
is_latlon=False, is_latlon=False,
use_ocg_layers=False): use_ocg_layers=False):
"""Creates a cairo surface and context to render a PDF with. """Creates a cairo surface and context to render a PDF with.
pagesize: tuple of page size in meters, see predefined sizes in pagessizes dict (default a4) pagesize: tuple of page size in meters, see predefined sizes in pagessizes dict (default a4)
margin: page margin in meters (default 0.01) margin: page margin in meters (default 0.01)
box: box within the page to render the map into (will not render over margin). This should be box: box within the page to render the map into (will not render over margin). This should be
@ -348,54 +348,54 @@ class PDFPrinter:
self._centering = centering self._centering = centering
self._is_latlon = is_latlon self._is_latlon = is_latlon
self._use_ocg_layers = use_ocg_layers self._use_ocg_layers = use_ocg_layers
self._s = None self._s = None
self._layer_names = [] self._layer_names = []
self._filename = None self._filename = None
self.map_box = None self.map_box = None
self.scale = None self.scale = None
# don't both to round the scale if they are not preserving the aspect ratio # don't both to round the scale if they are not preserving the aspect ratio
if not preserve_aspect: if not preserve_aspect:
self._scale = any_scale self._scale = any_scale
if percent_box: if percent_box:
self._box = Box2d(percent_box[0]*pagesize[0],percent_box[1]*pagesize[1], self._box = Box2d(percent_box[0]*pagesize[0],percent_box[1]*pagesize[1],
percent_box[2]*pagesize[0],percent_box[3]*pagesize[1]) percent_box[2]*pagesize[0],percent_box[3]*pagesize[1])
if not HAS_PYCAIRO_MODULE: if not HAS_PYCAIRO_MODULE:
raise Exception("PDF rendering only available when pycairo is available") raise Exception("PDF rendering only available when pycairo is available")
self.font_name = "DejaVu Sans" self.font_name = "DejaVu Sans"
def finish(self): def finish(self):
if self._s: if self._s:
self._s.finish() self._s.finish()
self._s = None self._s = None
if self._use_ocg_layers: if self._use_ocg_layers:
convert_pdf_pages_to_layers(self._filename,layer_names=self._layer_names + ["Legend and Information"],reverse_all_but_last=True) convert_pdf_pages_to_layers(self._filename,layer_names=self._layer_names + ["Legend and Information"],reverse_all_but_last=True)
def add_geospatial_pdf_header(self,m,filename,epsg=None,wkt=None): def add_geospatial_pdf_header(self,m,filename,epsg=None,wkt=None):
""" Postprocessing step to add geospatial PDF information to PDF file as per """ Postprocessing step to add geospatial PDF information to PDF file as per
PDF standard 1.7 extension level 3 (also in draft PDF v2 standard at time of writing) PDF standard 1.7 extension level 3 (also in draft PDF v2 standard at time of writing)
one of either the epsg code or wkt text for the projection must be provided one of either the epsg code or wkt text for the projection must be provided
Should be called *after* the page has had .finish() called""" Should be called *after* the page has had .finish() called"""
if HAS_PYPDF and (epsg or wkt): if HAS_PYPDF and (epsg or wkt):
infile=file(filename,'rb') infile=file(filename,'rb')
(outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename))
outfile = os.fdopen(outfd,'wb') outfile = os.fdopen(outfd,'wb')
i=pyPdf.PdfFileReader(infile) i=pyPdf.PdfFileReader(infile)
o=pyPdf.PdfFileWriter() o=pyPdf.PdfFileWriter()
# preserve OCProperties at document root if we have one # preserve OCProperties at document root if we have one
if i.trailer['/Root'].has_key(pyPdf.generic.NameObject('/OCProperties')): if i.trailer['/Root'].has_key(pyPdf.generic.NameObject('/OCProperties')):
o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = i.trailer['/Root'].getObject()[pyPdf.generic.NameObject('/OCProperties')] o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = i.trailer['/Root'].getObject()[pyPdf.generic.NameObject('/OCProperties')]
for p in i.pages: for p in i.pages:
gcs = pyPdf.generic.DictionaryObject() gcs = pyPdf.generic.DictionaryObject()
gcs[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/PROJCS') gcs[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/PROJCS')
@ -403,7 +403,7 @@ class PDFPrinter:
gcs[pyPdf.generic.NameObject('/EPSG')]=pyPdf.generic.NumberObject(int(epsg)) gcs[pyPdf.generic.NameObject('/EPSG')]=pyPdf.generic.NumberObject(int(epsg))
if wkt: if wkt:
gcs[pyPdf.generic.NameObject('/WKT')]=pyPdf.generic.TextStringObject(wkt) gcs[pyPdf.generic.NameObject('/WKT')]=pyPdf.generic.TextStringObject(wkt)
measure = pyPdf.generic.DictionaryObject() measure = pyPdf.generic.DictionaryObject()
measure[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Measure') measure[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Measure')
measure[pyPdf.generic.NameObject('/Subtype')]=pyPdf.generic.NameObject('/GEO') measure[pyPdf.generic.NameObject('/Subtype')]=pyPdf.generic.NameObject('/GEO')
@ -414,7 +414,7 @@ class PDFPrinter:
measure[pyPdf.generic.NameObject('/Bounds')]=bounds measure[pyPdf.generic.NameObject('/Bounds')]=bounds
measure[pyPdf.generic.NameObject('/LPTS')]=bounds measure[pyPdf.generic.NameObject('/LPTS')]=bounds
gpts=pyPdf.generic.ArrayObject() gpts=pyPdf.generic.ArrayObject()
proj=Projection(m.srs) proj=Projection(m.srs)
env=m.envelope() env=m.envelope()
for x in ((env.minx, env.miny), (env.minx, env.maxy), (env.maxx, env.maxy), (env.maxx, env.miny)): for x in ((env.minx, env.miny), (env.minx, env.maxy), (env.maxx, env.maxy), (env.maxx, env.miny)):
@ -423,31 +423,31 @@ class PDFPrinter:
gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.y))) gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.y)))
gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.x))) gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.x)))
measure[pyPdf.generic.NameObject('/GPTS')]=gpts measure[pyPdf.generic.NameObject('/GPTS')]=gpts
vp=pyPdf.generic.DictionaryObject() vp=pyPdf.generic.DictionaryObject()
vp[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Viewport') vp[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Viewport')
bbox=pyPdf.generic.ArrayObject() bbox=pyPdf.generic.ArrayObject()
for x in self.map_box: for x in self.map_box:
bbox.append(pyPdf.generic.FloatObject(str(x))) bbox.append(pyPdf.generic.FloatObject(str(x)))
vp[pyPdf.generic.NameObject('/BBox')]=bbox vp[pyPdf.generic.NameObject('/BBox')]=bbox
vp[pyPdf.generic.NameObject('/Measure')]=measure vp[pyPdf.generic.NameObject('/Measure')]=measure
vpa = pyPdf.generic.ArrayObject() vpa = pyPdf.generic.ArrayObject()
vpa.append(vp) vpa.append(vp)
p[pyPdf.generic.NameObject('/VP')]=vpa p[pyPdf.generic.NameObject('/VP')]=vpa
o.addPage(p) o.addPage(p)
o.write(outfile) o.write(outfile)
infile=None infile=None
outfile.close() outfile.close()
os.rename(outfilename,filename) os.rename(outfilename,filename)
def get_context(self): def get_context(self):
"""allow access so that extra 'bits' can be rendered to the page directly""" """allow access so that extra 'bits' can be rendered to the page directly"""
return cairo.Context(self._s) return cairo.Context(self._s)
def get_width(self): def get_width(self):
return self._pagesize[0] return self._pagesize[0]
@ -456,7 +456,7 @@ class PDFPrinter:
def get_margin(self): def get_margin(self):
return self._margin return self._margin
def write_text(self,ctx,text,box_width=None,size=10, fill_color=(0.0, 0.0, 0.0), alignment=None): def write_text(self,ctx,text,box_width=None,size=10, fill_color=(0.0, 0.0, 0.0), alignment=None):
if HAS_PANGOCAIRO_MODULE: if HAS_PANGOCAIRO_MODULE:
(attr,t,accel) = pango.parse_markup(text) (attr,t,accel) = pango.parse_markup(text)
@ -474,7 +474,7 @@ class PDFPrinter:
pctx.set_source_rgb(*fill_color) pctx.set_source_rgb(*fill_color)
pctx.show_layout(l) pctx.show_layout(l)
return l.get_pixel_extents()[0] return l.get_pixel_extents()[0]
else: else:
ctx.rel_move_to(0,size) ctx.rel_move_to(0,size)
ctx.select_font_face(self.font_name, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.select_font_face(self.font_name, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
@ -489,18 +489,18 @@ class PDFPrinter:
elif HAS_PYCAIRO_MODULE: elif HAS_PYCAIRO_MODULE:
return cairo.Context(self._s) return cairo.Context(self._s)
return None return None
def _get_render_area(self): def _get_render_area(self):
"""return a bounding box with the area of the page we are allowed to render out map to """return a bounding box with the area of the page we are allowed to render out map to
in page coordinates (i.e. meters) in page coordinates (i.e. meters)
""" """
# take off our page margins # take off our page margins
render_area = Box2d(self._margin,self._margin,self._pagesize[0]-self._margin,self._pagesize[1]-self._margin) render_area = Box2d(self._margin,self._margin,self._pagesize[0]-self._margin,self._pagesize[1]-self._margin)
#then if user specified a box to render get intersection with that #then if user specified a box to render get intersection with that
if self._box: if self._box:
return render_area.intersect(self._box) return render_area.intersect(self._box)
return render_area return render_area
def _get_render_area_size(self): def _get_render_area_size(self):
@ -513,7 +513,7 @@ class PDFPrinter:
available_area = self._get_render_area_size() available_area = self._get_render_area_size()
map_aspect = m.envelope().width()/m.envelope().height() map_aspect = m.envelope().width()/m.envelope().height()
page_aspect = available_area[0]/available_area[1] page_aspect = available_area[0]/available_area[1]
return map_aspect > page_aspect return map_aspect > page_aspect
def _get_meta_info_corner(self,render_size,m): def _get_meta_info_corner(self,render_size,m):
@ -526,7 +526,7 @@ class PDFPrinter:
else: else:
x += render_size[0]+0.005 x += render_size[0]+0.005
y = self._margin y = self._margin
return (x,y) return (x,y)
def _get_render_corner(self,render_size,m): def _get_render_corner(self,render_size,m):
@ -535,9 +535,9 @@ class PDFPrinter:
x=available_area[0] x=available_area[0]
y=available_area[1] y=available_area[1]
h_is_contrained = self._is_h_contrained(m) h_is_contrained = self._is_h_contrained(m)
if (self._centering == centering.both or if (self._centering == centering.both or
self._centering == centering.horizontal or self._centering == centering.horizontal or
(self._centering == centering.constrained and h_is_contrained) or (self._centering == centering.constrained and h_is_contrained) or
@ -550,26 +550,26 @@ class PDFPrinter:
(self._centering == centering.unconstrained and h_is_contrained)): (self._centering == centering.unconstrained and h_is_contrained)):
y+=(available_area.height()-render_size[1])/2 y+=(available_area.height()-render_size[1])/2
return (x,y) return (x,y)
def _get_map_pixel_size(self, width_page_m, height_page_m): def _get_map_pixel_size(self, width_page_m, height_page_m):
"""for a given map size in paper coordinates return a tuple of the map 'pixel' size we """for a given map size in paper coordinates return a tuple of the map 'pixel' size we
should create at the defined resolution""" should create at the defined resolution"""
return (int(m2px(width_page_m,self._resolution)), int(m2px(height_page_m,self._resolution))) return (int(m2px(width_page_m,self._resolution)), int(m2px(height_page_m,self._resolution)))
def render_map(self,m, filename): def render_map(self,m, filename):
"""Render the given map to filename""" """Render the given map to filename"""
# store this for later so we can post process the PDF # store this for later so we can post process the PDF
self._filename = filename self._filename = filename
# work out the best scale to render out map at given the available space # work out the best scale to render out map at given the available space
(eff_width,eff_height) = self._get_render_area_size() (eff_width,eff_height) = self._get_render_area_size()
map_aspect = m.envelope().width()/m.envelope().height() map_aspect = m.envelope().width()/m.envelope().height()
page_aspect = eff_width/eff_height page_aspect = eff_width/eff_height
scalex=m.envelope().width()/eff_width scalex=m.envelope().width()/eff_width
scaley=m.envelope().height()/eff_height scaley=m.envelope().height()/eff_height
scale=max(scalex,scaley) scale=max(scalex,scaley)
rounded_mapscale=self._scale(scale) rounded_mapscale=self._scale(scale)
@ -581,26 +581,26 @@ class PDFPrinter:
maph=mapw*(1/map_aspect) maph=mapw*(1/map_aspect)
else: else:
mapw=maph*map_aspect mapw=maph*map_aspect
# set the map size so that raster elements render at the correct resolution # set the map size so that raster elements render at the correct resolution
m.resize(*self._get_map_pixel_size(mapw,maph)) m.resize(*self._get_map_pixel_size(mapw,maph))
# calculate the translation for the map starting point # calculate the translation for the map starting point
(tx,ty) = self._get_render_corner((mapw,maph),m) (tx,ty) = self._get_render_corner((mapw,maph),m)
# create our cairo surface and context and then render the map into it # create our cairo surface and context and then render the map into it
self._s = cairo.PDFSurface(filename, m2pt(self._pagesize[0]),m2pt(self._pagesize[1])) self._s = cairo.PDFSurface(filename, m2pt(self._pagesize[0]),m2pt(self._pagesize[1]))
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
for l in m.layers: for l in m.layers:
# extract the layer names for naming layers if we use OCG # extract the layer names for naming layers if we use OCG
self._layer_names.append(l.name) self._layer_names.append(l.name)
layer_map = Map(m.width,m.height,m.srs) layer_map = Map(m.width,m.height,m.srs)
layer_map.layers.append(l) layer_map.layers.append(l)
for s in l.styles: for s in l.styles:
layer_map.append_style(s,m.find_style(s)) layer_map.append_style(s,m.find_style(s))
layer_map.zoom_to_box(m.envelope()) layer_map.zoom_to_box(m.envelope())
def render_map(): def render_map():
ctx.save() ctx.save()
ctx.translate(m2pt(tx),m2pt(ty)) ctx.translate(m2pt(tx),m2pt(ty))
@ -608,7 +608,7 @@ class PDFPrinter:
ctx.scale(72.0/self._resolution,72.0/self._resolution) ctx.scale(72.0/self._resolution,72.0/self._resolution)
render(layer_map, ctx) render(layer_map, ctx)
ctx.restore() ctx.restore()
# antimeridian # antimeridian
render_map() render_map()
if self._is_latlon and (m.envelope().minx < -180 or m.envelope().maxx > 180): if self._is_latlon and (m.envelope().minx < -180 or m.envelope().maxx > 180):
@ -621,10 +621,10 @@ class PDFPrinter:
render_map() render_map()
# restore the original env # restore the original env
m.zoom_to_box(old_env) m.zoom_to_box(old_env)
if self._use_ocg_layers: if self._use_ocg_layers:
self._s.show_page() self._s.show_page()
self.scale = rounded_mapscale self.scale = rounded_mapscale
self.map_box = Box2d(tx,ty,tx+mapw,ty+maph) self.map_box = Box2d(tx,ty,tx+mapw,ty+maph)
@ -640,7 +640,7 @@ class PDFPrinter:
if p2.inverse(m.envelope().center()).y > latlon_bounds.maxy: if p2.inverse(m.envelope().center()).y > latlon_bounds.maxy:
latlon_bounds = Box2d(latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.maxx,latlon_bounds.miny+360) latlon_bounds = Box2d(latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.maxx,latlon_bounds.miny+360)
latlon_mapwidth = latlon_bounds.width() latlon_mapwidth = latlon_bounds.width()
# render an extra 20% so we generally won't miss the ends of lines # render an extra 20% so we generally won't miss the ends of lines
latlon_buffer = 0.2*latlon_mapwidth latlon_buffer = 0.2*latlon_mapwidth
@ -649,7 +649,7 @@ class PDFPrinter:
else: else:
latlon_divsize = deg_min_sec_scale(latlon_mapwidth/7.0) latlon_divsize = deg_min_sec_scale(latlon_mapwidth/7.0)
latlon_interpsize = latlon_mapwidth/m.width latlon_interpsize = latlon_mapwidth/m.width
self._render_lat_lon_axis(m,p2,latlon_bounds.minx,latlon_bounds.maxx,latlon_bounds.miny,latlon_bounds.maxy,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,True) self._render_lat_lon_axis(m,p2,latlon_bounds.minx,latlon_bounds.maxx,latlon_bounds.miny,latlon_bounds.maxy,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,True)
self._render_lat_lon_axis(m,p2,latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.minx,latlon_bounds.maxx,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,False) self._render_lat_lon_axis(m,p2,latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.minx,latlon_bounds.maxx,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,False)
@ -658,21 +658,21 @@ class PDFPrinter:
ctx.set_source_rgb(1,0,0) ctx.set_source_rgb(1,0,0)
ctx.set_line_width(1) ctx.set_line_width(1)
latlon_labelsize = 6 latlon_labelsize = 6
ctx.translate(m2pt(self.map_box.minx),m2pt(self.map_box.miny)) ctx.translate(m2pt(self.map_box.minx),m2pt(self.map_box.miny))
ctx.rectangle(0,0,m2pt(self.map_box.width()),m2pt(self.map_box.height())) ctx.rectangle(0,0,m2pt(self.map_box.width()),m2pt(self.map_box.height()))
ctx.clip() ctx.clip()
ctx.select_font_face("DejaVu", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.select_font_face("DejaVu", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
ctx.set_font_size(latlon_labelsize) ctx.set_font_size(latlon_labelsize)
box_top = self.map_box.height() box_top = self.map_box.height()
if not is_x_axis: if not is_x_axis:
ctx.translate(m2pt(self.map_box.width()/2),m2pt(self.map_box.height()/2)) ctx.translate(m2pt(self.map_box.width()/2),m2pt(self.map_box.height()/2))
ctx.rotate(-math.pi/2) ctx.rotate(-math.pi/2)
ctx.translate(-m2pt(self.map_box.height()/2),-m2pt(self.map_box.width()/2)) ctx.translate(-m2pt(self.map_box.height()/2),-m2pt(self.map_box.width()/2))
box_top = self.map_box.width() box_top = self.map_box.width()
for xvalue in round_grid_generator(x1 - latlon_buffer,x2 + latlon_buffer,latlon_divsize): for xvalue in round_grid_generator(x1 - latlon_buffer,x2 + latlon_buffer,latlon_divsize):
yvalue = y1 - latlon_buffer yvalue = y1 - latlon_buffer
start_cross = None start_cross = None
@ -693,12 +693,12 @@ class PDFPrinter:
ctx.move_to(start.x,start.y) ctx.move_to(start.x,start.y)
ctx.line_to(end.x,end.y) ctx.line_to(end.x,end.y)
ctx.stroke() ctx.stroke()
if cmp(start.y, 0) != cmp(end.y,0): if cmp(start.y, 0) != cmp(end.y,0):
start_cross = end.x start_cross = end.x
if cmp(start.y,m2pt(self.map_box.height())) != cmp(end.y, m2pt(self.map_box.height())): if cmp(start.y,m2pt(self.map_box.height())) != cmp(end.y, m2pt(self.map_box.height())):
end_cross = end.x end_cross = end.x
if dec_degrees: if dec_degrees:
line_text = "%g" % (xvalue) line_text = "%g" % (xvalue)
else: else:
@ -712,19 +712,19 @@ class PDFPrinter:
def render_on_map_scale(self,m): def render_on_map_scale(self,m):
(div_size,page_div_size) = self._get_sensible_scalebar_size(m) (div_size,page_div_size) = self._get_sensible_scalebar_size(m)
first_value_x = (math.floor(m.envelope().minx / div_size) + 1) * div_size first_value_x = (math.floor(m.envelope().minx / div_size) + 1) * div_size
first_value_x_percent = (first_value_x-m.envelope().minx)/m.envelope().width() first_value_x_percent = (first_value_x-m.envelope().minx)/m.envelope().width()
self._render_scale_axis(first_value_x,first_value_x_percent,self.map_box.minx,self.map_box.maxx,page_div_size,div_size,self.map_box.miny,self.map_box.maxy,True) self._render_scale_axis(first_value_x,first_value_x_percent,self.map_box.minx,self.map_box.maxx,page_div_size,div_size,self.map_box.miny,self.map_box.maxy,True)
first_value_y = (math.floor(m.envelope().miny / div_size) + 1) * div_size first_value_y = (math.floor(m.envelope().miny / div_size) + 1) * div_size
first_value_y_percent = (first_value_y-m.envelope().miny)/m.envelope().height() first_value_y_percent = (first_value_y-m.envelope().miny)/m.envelope().height()
self._render_scale_axis(first_value_y,first_value_y_percent,self.map_box.miny,self.map_box.maxy,page_div_size,div_size,self.map_box.minx,self.map_box.maxx,False) self._render_scale_axis(first_value_y,first_value_y_percent,self.map_box.miny,self.map_box.maxy,page_div_size,div_size,self.map_box.minx,self.map_box.maxx,False)
if self._use_ocg_layers: if self._use_ocg_layers:
self._s.show_page() self._s.show_page()
self._layer_names.append("Coordinate Grid Overlay") self._layer_names.append("Coordinate Grid Overlay")
def _get_sensible_scalebar_size(self,m,width=-1): def _get_sensible_scalebar_size(self,m,width=-1):
# aim for about 8 divisions across the map # aim for about 8 divisions across the map
# also make sure we can fit the bar with in page area width if specified # also make sure we can fit the bar with in page area width if specified
@ -744,7 +744,7 @@ class PDFPrinter:
ctx.set_source_rgb(*stroke_color) ctx.set_source_rgb(*stroke_color)
ctx.rectangle(x,y,w,h) ctx.rectangle(x,y,w,h)
ctx.stroke() ctx.stroke()
if text: if text:
ctx.move_to(x+1,y) ctx.move_to(x+1,y)
self.write_text(ctx,text,fill_color=[1-z for z in fill_color],size=h-2) self.write_text(ctx,text,fill_color=[1-z for z in fill_color],size=h-2)
@ -758,14 +758,14 @@ class PDFPrinter:
label_value = first-div_size label_value = first-div_size
if self._is_latlon and label_value < -180: if self._is_latlon and label_value < -180:
label_value += 360 label_value += 360
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
if not is_x_axis: if not is_x_axis:
ctx.translate(m2pt(self.map_box.center().x),m2pt(self.map_box.center().y)) ctx.translate(m2pt(self.map_box.center().x),m2pt(self.map_box.center().y))
ctx.rotate(-math.pi/2) ctx.rotate(-math.pi/2)
ctx.translate(-m2pt(self.map_box.center().y),-m2pt(self.map_box.center().x)) ctx.translate(-m2pt(self.map_box.center().y),-m2pt(self.map_box.center().x))
while value < end: while value < end:
ctx.move_to(m2pt(value),m2pt(boundary_start)) ctx.move_to(m2pt(value),m2pt(boundary_start))
ctx.line_to(m2pt(value),m2pt(boundary_end)) ctx.line_to(m2pt(value),m2pt(boundary_end))
@ -775,7 +775,7 @@ class PDFPrinter:
for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)):
self._render_box(ctx,m2pt(prev),bar,m2pt(value-prev),border_size,text,fill_color=fill) self._render_box(ctx,m2pt(prev),bar,m2pt(value-prev),border_size,text,fill_color=fill)
prev = value prev = value
value+=page_div_size value+=page_div_size
fill = [1-z for z in fill] fill = [1-z for z in fill]
@ -787,18 +787,18 @@ class PDFPrinter:
for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)):
self._render_box(ctx,m2pt(prev),bar,m2pt(end-prev),border_size,fill_color=fill) self._render_box(ctx,m2pt(prev),bar,m2pt(end-prev),border_size,fill_color=fill)
def render_scale(self,m,ctx=None,width=0.05): def render_scale(self,m,ctx=None,width=0.05):
""" m: map to render scale for """ m: map to render scale for
ctx: A cairo context to render the scale to. If this is None (the default) then ctx: A cairo context to render the scale to. If this is None (the default) then
automatically create a context and choose the best location for the scale bar. automatically create a context and choose the best location for the scale bar.
width: Width of area available to render scale bar in (in m) width: Width of area available to render scale bar in (in m)
will return the size of the rendered scale block in pts will return the size of the rendered scale block in pts
""" """
(w,h) = (0,0) (w,h) = (0,0)
# don't render scale if we are lat lon # don't render scale if we are lat lon
# dont report scale if we have warped the aspect ratio # dont report scale if we have warped the aspect ratio
if self._preserve_aspect and not self._is_latlon: if self._preserve_aspect and not self._is_latlon:
@ -808,15 +808,15 @@ class PDFPrinter:
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
(tx,ty) = self._get_meta_info_corner((self.map_box.width(),self.map_box.height()),m) (tx,ty) = self._get_meta_info_corner((self.map_box.width(),self.map_box.height()),m)
ctx.translate(tx,ty) ctx.translate(tx,ty)
(div_size,page_div_size) = self._get_sensible_scalebar_size(m, width/box_count) (div_size,page_div_size) = self._get_sensible_scalebar_size(m, width/box_count)
div_unit = "m" div_unit = "m"
if div_size > 1000: if div_size > 1000:
div_size /= 1000 div_size /= 1000
div_unit = "km" div_unit = "km"
text = "0%s" % div_unit text = "0%s" % div_unit
ctx.save() ctx.save()
if width > 0: if width > 0:
@ -846,7 +846,7 @@ class PDFPrinter:
text_ext=self.write_text(ctx,"Scale 1:%d" % self.scale,box_width=box_width,size=font_size, alignment=alignment) text_ext=self.write_text(ctx,"Scale 1:%d" % self.scale,box_width=box_width,size=font_size, alignment=alignment)
h+=text_ext[3]+2 h+=text_ext[3]+2
return (w,h) return (w,h)
def render_legend(self,m, page_break=False, ctx=None, collumns=1,width=None, height=None, item_per_rule=False, attribution={}, legend_item_box_size=(0.015,0.0075)): def render_legend(self,m, page_break=False, ctx=None, collumns=1,width=None, height=None, item_per_rule=False, attribution={}, legend_item_box_size=(0.015,0.0075)):
@ -858,7 +858,7 @@ class PDFPrinter:
collumns: number of collumns available in legend box collumns: number of collumns available in legend box
attribution: additional text that will be rendered in gray under the layer name. keyed by layer name attribution: additional text that will be rendered in gray under the layer name. keyed by layer name
legend_item_box_size: two tuple with width and height of legend item box size in meters legend_item_box_size: two tuple with width and height of legend item box size in meters
will return the size of the rendered block in pts will return the size of the rendered block in pts
""" """
@ -879,7 +879,7 @@ class PDFPrinter:
else: else:
cwidth = None cwidth = None
current_collumn = 0 current_collumn = 0
processed_layers = [] processed_layers = []
for l in reversed(m.layers): for l in reversed(m.layers):
have_layer_header = False have_layer_header = False
@ -888,7 +888,7 @@ class PDFPrinter:
if layer_title in processed_layers: if layer_title in processed_layers:
continue continue
processed_layers.append(layer_title) processed_layers.append(layer_title)
# check through the features to find which combinations of styles are active # check through the features to find which combinations of styles are active
# for each unique combination add a legend entry # for each unique combination add a legend entry
for f in l.datasource.all_features(): for f in l.datasource.all_features():
@ -913,20 +913,20 @@ class PDFPrinter:
active_rules = tuple(active_rules) active_rules = tuple(active_rules)
if added_styles.has_key(active_rules): if added_styles.has_key(active_rules):
continue continue
added_styles[active_rules] = (f,rule_text) added_styles[active_rules] = (f,rule_text)
if not item_per_rule: if not item_per_rule:
break break
else: else:
added_styles[l] = (None,None) added_styles[l] = (None,None)
legend_items = added_styles.keys() legend_items = added_styles.keys()
legend_items.sort() legend_items.sort()
for li in legend_items: for li in legend_items:
if True: if True:
(f,rule_text) = added_styles[li] (f,rule_text) = added_styles[li]
legend_map_size = (int(m2pt(legend_item_box_size[0])),int(m2pt(legend_item_box_size[1]))) legend_map_size = (int(m2pt(legend_item_box_size[0])),int(m2pt(legend_item_box_size[1])))
lemap=Map(legend_map_size[0],legend_map_size[1],srs=m.srs) lemap=Map(legend_map_size[0],legend_map_size[1],srs=m.srs)
if m.background: if m.background:
@ -967,11 +967,11 @@ class PDFPrinter:
for s in l.styles: for s in l.styles:
lelayer.styles.append(s) lelayer.styles.append(s)
lemap.layers.append(lelayer) lemap.layers.append(lelayer)
if f is None or f.envelope().width() != 0: if f is None or f.envelope().width() != 0:
lemap.zoom_all() lemap.zoom_all()
lemap.zoom(1.1) lemap.zoom(1.1)
item_size = legend_map_size[1] item_size = legend_map_size[1]
if not have_layer_header: if not have_layer_header:
item_size += 8 item_size += 8
@ -998,7 +998,7 @@ class PDFPrinter:
ctx.save() ctx.save()
render(lemap, ctx) render(lemap, ctx)
ctx.restore() ctx.restore()
ctx.rectangle(0,0,*legend_map_size) ctx.rectangle(0,0,*legend_map_size)
ctx.set_source_rgb(0.5,0.5,0.5) ctx.set_source_rgb(0.5,0.5,0.5)
ctx.set_line_width(1) ctx.set_line_width(1)
@ -1017,12 +1017,12 @@ class PDFPrinter:
if attribution.has_key(layer_title): if attribution.has_key(layer_title):
e=self.write_text(ctx, attribution[layer_title], m2pt(cwidth-legend_item_box_size[0]-0.005), 6, fill_color=(0.5,0.5,0.5)) e=self.write_text(ctx, attribution[layer_title], m2pt(cwidth-legend_item_box_size[0]-0.005), 6, fill_color=(0.5,0.5,0.5))
legend_text_size += e[3] legend_text_size += e[3]
if legend_text_size > legend_entry_size: if legend_text_size > legend_entry_size:
legend_entry_size=legend_text_size legend_entry_size=legend_text_size
y+=legend_entry_size +2 y+=legend_entry_size +2
if y > h: if y > h:
h = y h = y
return (w,h) return (w,h)

View file

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

View file

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

View file

@ -19,10 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/python/detail/api_placeholder.hpp> #include <boost/python/detail/api_placeholder.hpp>
// stl // stl
#include <sstream> #include <sstream>
#include <vector> #include <vector>

View file

@ -20,8 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/python.hpp> #include <boost/python.hpp>
#include <mapnik/datasource_cache.hpp> #include <mapnik/datasource_cache.hpp>

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id: mapnik_envelope.cc 27 2005-03-30 21:45:40Z pavlenko $
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>

View file

@ -19,9 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/variant.hpp>
// mapnik // mapnik
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
@ -30,7 +32,6 @@
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <boost/variant.hpp>
using mapnik::Feature; using mapnik::Feature;
using mapnik::expression_ptr; using mapnik::expression_ptr;

View file

@ -19,13 +19,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost // boost
#include <boost/python/suite/indexing/indexing_suite.hpp> #include <boost/python/suite/indexing/indexing_suite.hpp>
//#include <boost/python/suite/indexing/map_indexing_suite.hpp> //#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/iterator.hpp> #include <boost/python/iterator.hpp>
#include <boost/python/call_method.hpp> #include <boost/python/call_method.hpp>
#include <boost/python/tuple.hpp> #include <boost/python/tuple.hpp>

View file

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

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/python.hpp> #include <boost/python.hpp>
#include <mapnik/font_engine_freetype.hpp> #include <mapnik/font_engine_freetype.hpp>
@ -42,6 +41,7 @@ void export_font_engine()
.def("register_fonts",&freetype_engine::register_fonts) .def("register_fonts",&freetype_engine::register_fonts)
.def("face_names",&freetype_engine::face_names) .def("face_names",&freetype_engine::face_names)
.staticmethod("register_font") .staticmethod("register_font")
.staticmethod("register_fonts")
.staticmethod("face_names") .staticmethod("face_names")
; ;
} }

View file

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

View file

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

View file

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

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
extern "C" extern "C"
{ {
@ -125,7 +124,7 @@ bool painted(mapnik::image_32 const& im)
void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c) void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c)
{ {
im.setPixel(x, y, c.rgba()); im.setPixel(x, y, c.rgba());
} }
boost::shared_ptr<image_32> open_from_file(std::string const& filename) boost::shared_ptr<image_32> open_from_file(std::string const& filename)
{ {

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
extern "C" extern "C"
{ {

View file

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

View file

@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id: mapnik_layer.cc 17 2005-03-08 23:58:43Z pavlenko $
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>
@ -54,7 +52,7 @@ struct layer_pickle_suite : boost::python::pickle_suite
{ {
s.append(style_names[i]); s.append(style_names[i]);
} }
return boost::python::make_tuple(l.clear_label_cache(),l.getMinZoom(),l.getMaxZoom(),l.isQueryable(),l.datasource()->params(),l.cache_features(),s); return boost::python::make_tuple(l.clear_label_cache(),l.min_zoom(),l.max_zoom(),l.queryable(),l.datasource()->params(),l.cache_features(),s);
} }
static void static void
@ -72,11 +70,11 @@ struct layer_pickle_suite : boost::python::pickle_suite
l.set_clear_label_cache(extract<bool>(state[0])); l.set_clear_label_cache(extract<bool>(state[0]));
l.setMinZoom(extract<double>(state[1])); l.set_min_zoom(extract<double>(state[1]));
l.setMaxZoom(extract<double>(state[2])); l.set_max_zoom(extract<double>(state[2]));
l.setQueryable(extract<bool>(state[3])); l.set_queryable(extract<bool>(state[3]));
mapnik::parameters params = extract<parameters>(state[4]); mapnik::parameters params = extract<parameters>(state[4]);
l.set_datasource(datasource_cache::instance()->create(params)); l.set_datasource(datasource_cache::instance()->create(params));
@ -128,7 +126,7 @@ void export_layer()
"box2d(-1.0,-1.0,0.0,0.0) # default until a datasource is loaded\n" "box2d(-1.0,-1.0,0.0,0.0) # default until a datasource is loaded\n"
) )
.def("visible", &layer::isVisible, .def("visible", &layer::visible,
"Return True if this layer's data is active and visible at a given scale.\n" "Return True if this layer's data is active and visible at a given scale.\n"
"\n" "\n"
"Otherwise returns False.\n" "Otherwise returns False.\n"
@ -149,8 +147,8 @@ void export_layer()
) )
.add_property("active", .add_property("active",
&layer::isActive, &layer::active,
&layer::setActive, &layer::set_active,
"Get/Set whether this layer is active and will be rendered.\n" "Get/Set whether this layer is active and will be rendered.\n"
"\n" "\n"
"Usage:\n" "Usage:\n"
@ -199,8 +197,8 @@ void export_layer()
) )
.add_property("maxzoom", .add_property("maxzoom",
&layer::getMaxZoom, &layer::max_zoom,
&layer::setMaxZoom, &layer::set_max_zoom,
"Get/Set the maximum zoom lever of the layer.\n" "Get/Set the maximum zoom lever of the layer.\n"
"\n" "\n"
"Usage:\n" "Usage:\n"
@ -214,8 +212,8 @@ void export_layer()
) )
.add_property("minzoom", .add_property("minzoom",
&layer::getMinZoom, &layer::min_zoom,
&layer::setMinZoom, &layer::set_min_zoom,
"Get/Set the minimum zoom lever of the layer.\n" "Get/Set the minimum zoom lever of the layer.\n"
"\n" "\n"
"Usage:\n" "Usage:\n"
@ -244,8 +242,8 @@ void export_layer()
) )
.add_property("queryable", .add_property("queryable",
&layer::isQueryable, &layer::queryable,
&layer::setQueryable, &layer::set_queryable,
"Get/Set whether this layer is queryable.\n" "Get/Set whether this layer is queryable.\n"
"\n" "\n"
"Usage:\n" "Usage:\n"

View file

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

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/python.hpp> #include <boost/python.hpp>
#include "mapnik_enumeration.hpp" #include "mapnik_enumeration.hpp"
@ -62,5 +61,9 @@ void export_line_symbolizer()
(&line_symbolizer::get_stroke, (&line_symbolizer::get_stroke,
return_value_policy<copy_const_reference>()), return_value_policy<copy_const_reference>()),
&line_symbolizer::set_stroke) &line_symbolizer::set_stroke)
.add_property("smooth",
&line_symbolizer::smooth,
&line_symbolizer::set_smooth,
"smooth value (0..1.0)")
; ;
} }

View file

@ -0,0 +1,133 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#include <boost/python.hpp>
#include <mapnik/debug.hpp>
using mapnik::logger::severity;
using mapnik::logger::format;
using mapnik::logger::output;
void set_severity(const severity::type& s)
{
severity::set(s);
}
severity::type get_severity()
{
return severity::get();
}
void set_object_severity(const std::string& object_name, const severity::type& s)
{
severity::set_object(object_name, s);
}
severity::type get_object_severity(const std::string& object_name)
{
return severity::get_object(object_name);
}
void export_logger()
{
using namespace boost::python;
enum_<mapnik::logger::severity::type>("SeverityType")
.value("Info", severity::info)
.value("Debug", severity::debug)
.value("Warn", severity::warn)
.value("Error", severity::error)
.value("Fatal", severity::fatal)
.value("None", severity::none)
;
/*
using mapnik::singleton;
using mapnik::CreateStatic;
using namespace boost::python;
class_<singleton<severity,CreateStatic>,boost::noncopyable>("Singleton",no_init)
.def("instance",&singleton<severity,CreateStatic>::instance,
return_value_policy<reference_existing_object>())
.staticmethod("instance")
;
class_<severity,bases<singleton<severity,CreateStatic> >,
boost::noncopyable>("Severity",no_init)
.def("get",&severity::get)
.def("set",&severity::set)
.def("get_object",&severity::get_object)
.def("set_object",&severity::set_object)
.staticmethod("get")
.staticmethod("set")
.staticmethod("get_object")
.staticmethod("set_object")
;
*/
def("set_severity", &set_severity,
"\n"
"Set global logger severity.\n"
"\n"
"Usage:\n"
">>> from mapnik import SeverityType, set_severity\n"
">>> set_severity(SeverityType.None)\n"
">>> set_severity(SeverityType.Info)\n"
">>> set_severity(SeverityType.Debug)\n"
">>> set_severity(SeverityType.Warn)\n"
">>> set_severity(SeverityType.Error)\n"
">>> set_severity(SeverityType.Fatal)\n"
);
def("get_severity", &get_severity,
"\n"
"Get global logger severity.\n"
"\n"
"Usage:\n"
">>> from mapnik import get_severity\n"
">>> get_severity()\n"
);
def("set_object_severity", &set_object_severity,
"\n"
"Set logger severity for a single object.\n"
"\n"
"Usage:\n"
">>> from mapnik import SeverityType, set_object_severity\n"
">>> set_object_severity('ogr', SeverityType.None)\n"
">>> set_object_severity('gdal', SeverityType.Info)\n"
">>> set_object_severity('cairo_renderer', SeverityType.Debug)\n"
">>> set_object_severity('agg_renderer', SeverityType.Warn)\n"
">>> set_object_severity('bindings', SeverityType.Error)\n"
);
def("get_object_severity", &get_object_severity,
"\n"
"Get logger severity for a single object.\n"
"\n"
"Usage:\n"
">>> from mapnik import get_object_severity"
">>> get_object_severity('ogr')\n"
);
}

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id: mapnik_map.cc 17 2005-03-08 23:58:43Z pavlenko $
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>
@ -62,7 +61,7 @@ struct map_pickle_suite : boost::python::pickle_suite
Map::const_style_iterator end = m.styles().end(); Map::const_style_iterator end = m.styles().end();
for (; it != end; ++it) for (; it != end; ++it)
{ {
const std::string & name = it->first; std::string const& name = it->first;
const mapnik::feature_type_style & style = it->second; const mapnik::feature_type_style & style = it->second;
boost::python::tuple style_pair = boost::python::make_tuple(name,style); boost::python::tuple style_pair = boost::python::make_tuple(name,style);
s.append(style_pair); s.append(style_pair);
@ -117,10 +116,8 @@ struct map_pickle_suite : boost::python::pickle_suite
std::vector<layer>& (Map::*layers_nonconst)() = &Map::layers; std::vector<layer>& (Map::*layers_nonconst)() = &Map::layers;
std::vector<layer> const& (Map::*layers_const)() const = &Map::layers; std::vector<layer> const& (Map::*layers_const)() const = &Map::layers;
mapnik::parameters& (Map::*attr_nonconst)() = &Map::get_extra_attributes;
mapnik::parameters& (Map::*params_nonconst)() = &Map::get_extra_parameters; mapnik::parameters& (Map::*params_nonconst)() = &Map::get_extra_parameters;
boost::optional<mapnik::box2d<double> > const& (Map::*maximum_extent_const)() const = &Map::maximum_extent;
mapnik::feature_type_style find_style(mapnik::Map const& m, std::string const& name) mapnik::feature_type_style find_style(mapnik::Map const& m, std::string const& name)
{ {
@ -153,7 +150,7 @@ bool has_metawriter(mapnik::Map const& m)
// returns empty shared_ptr when the metawriter isn't found, or is // returns empty shared_ptr when the metawriter isn't found, or is
// of the wrong type. empty pointers make it back to Python as a None. // of the wrong type. empty pointers make it back to Python as a None.
mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map &m, const std::string &name) { mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) {
mapnik::metawriter_ptr metawriter = m.find_metawriter(name); mapnik::metawriter_ptr metawriter = m.find_metawriter(name);
mapnik::metawriter_inmem_ptr inmem; mapnik::metawriter_inmem_ptr inmem;
@ -195,6 +192,18 @@ mapnik::Map map_deepcopy(mapnik::Map & m, boost::python::dict memo)
return result; return result;
} }
// TODO - find a simplier way to set optional to uninitialized
void set_maximum_extent(mapnik::Map & m, boost::optional<mapnik::box2d<double> > const& box)
{
if (box)
{
m.set_maximum_extent(*box);
}
else
{
m.maximum_extent().reset();
}
}
void export_map() void export_map()
{ {
@ -482,7 +491,6 @@ void export_map()
) )
.def("__deepcopy__",&map_deepcopy) .def("__deepcopy__",&map_deepcopy)
.add_property("extra_attributes",make_function(attr_nonconst,return_value_policy<reference_existing_object>()),"TODO")
.add_property("parameters",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO") .add_property("parameters",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO")
.add_property("aspect_fix_mode", .add_property("aspect_fix_mode",
@ -554,8 +562,8 @@ void export_map()
) )
.add_property("maximum_extent",make_function .add_property("maximum_extent",make_function
(&Map::maximum_extent,return_value_policy<copy_const_reference>()), (maximum_extent_const,return_value_policy<copy_const_reference>()),
&Map::set_maximum_extent, &set_maximum_extent,
"The maximum extent of the map.\n" "The maximum extent of the map.\n"
"\n" "\n"
"Usage:\n" "Usage:\n"

View file

@ -19,9 +19,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/python.hpp> #include <boost/python.hpp>
#include <mapnik/graphics.hpp> #include <mapnik/graphics.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/markers_symbolizer.hpp> #include <mapnik/markers_symbolizer.hpp>
@ -60,7 +60,8 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite
static boost::python::tuple static boost::python::tuple
getstate(markers_symbolizer const& p) getstate(markers_symbolizer const& p)
{ {
return boost::python::make_tuple(p.get_allow_overlap());//,p.get_opacity()); return boost::python::make_tuple(p.get_allow_overlap(),
p.get_ignore_placement());//,p.get_opacity());
} }
static void static void
@ -77,7 +78,8 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite
} }
p.set_allow_overlap(extract<bool>(state[0])); p.set_allow_overlap(extract<bool>(state[0]));
//p.set_opacity(extract<float>(state[1])); p.set_ignore_placement(extract<bool>(state[1]));
//p.set_opacity(extract<float>(state[2]));
} }
@ -108,8 +110,19 @@ void export_markers_symbolizer()
&markers_symbolizer::get_opacity, &markers_symbolizer::get_opacity,
&markers_symbolizer::set_opacity, &markers_symbolizer::set_opacity,
"Set/get the text opacity") "Set/get the text opacity")
.add_property("ignore_placement",
&markers_symbolizer::get_ignore_placement,
&markers_symbolizer::set_ignore_placement)
.add_property("transform", .add_property("transform",
&mapnik::get_svg_transform<markers_symbolizer>, &mapnik::get_svg_transform<markers_symbolizer>,
&mapnik::set_svg_transform<markers_symbolizer>) &mapnik::set_svg_transform<markers_symbolizer>)
.add_property("width",
&markers_symbolizer::get_width,
&markers_symbolizer::set_width,
"Set/get the marker width")
.add_property("height",
&markers_symbolizer::get_height,
&markers_symbolizer::set_height,
"Set/get the marker height")
; ;
} }

View file

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

View file

@ -25,6 +25,7 @@
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
// mapnik // mapnik
#include <mapnik/debug.hpp>
#include <mapnik/params.hpp> #include <mapnik/params.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
@ -102,7 +103,7 @@ struct parameters_pickle_suite : boost::python::pickle_suite
} }
else else
{ {
std::clog << "could not unpickle key: " << key << "\n"; MAPNIK_LOG_DEBUG(bindings) << "parameters_pickle_suite: Could not unpickle key=" << key;
} }
} }
} }

View file

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

View file

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

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/python.hpp> #include <boost/python.hpp>
#include "mapnik_enumeration.hpp" #include "mapnik_enumeration.hpp"
@ -84,7 +83,11 @@ void export_polygon_symbolizer()
.add_property("gamma_method", .add_property("gamma_method",
&polygon_symbolizer::get_gamma_method, &polygon_symbolizer::get_gamma_method,
&polygon_symbolizer::set_gamma_method, &polygon_symbolizer::set_gamma_method,
"Set/get the gamma correction method of the polygon") "gamma correction method")
.add_property("smooth",
&polygon_symbolizer::smooth,
&polygon_symbolizer::set_smooth,
"smooth value (0..1.0)")
; ;
} }

View file

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

View file

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

View file

@ -67,6 +67,7 @@ void export_view_transform();
void export_raster_colorizer(); void export_raster_colorizer();
void export_inmem_metawriter(); void export_inmem_metawriter();
void export_label_collision_detector(); void export_label_collision_detector();
void export_logger();
#include <mapnik/version.hpp> #include <mapnik/version.hpp>
#include <mapnik/value_error.hpp> #include <mapnik/value_error.hpp>
@ -289,6 +290,11 @@ unsigned mapnik_version()
return MAPNIK_VERSION; return MAPNIK_VERSION;
} }
std::string mapnik_version_string()
{
return MAPNIK_VERSION_STRING;
}
// indicator for jpeg read/write support within libmapnik // indicator for jpeg read/write support within libmapnik
bool has_jpeg() bool has_jpeg()
{ {
@ -391,6 +397,7 @@ BOOST_PYTHON_MODULE(_mapnik)
export_raster_colorizer(); export_raster_colorizer();
export_inmem_metawriter(); export_inmem_metawriter();
export_label_collision_detector(); export_label_collision_detector();
export_logger();
def("render_grid",&render_grid, def("render_grid",&render_grid,
( arg("map"), ( arg("map"),
@ -583,6 +590,7 @@ BOOST_PYTHON_MODULE(_mapnik)
def("save_map_to_string", &save_map_to_string, save_map_to_string_overloads()); 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", &mapnik_version,"Get the Mapnik version number");
def("mapnik_version_string", &mapnik_version_string,"Get the Mapnik version string");
def("has_jpeg", &has_jpeg, "Get jpeg read/write support status"); def("has_jpeg", &has_jpeg, "Get jpeg read/write support status");
def("has_cairo", &has_cairo, "Get cairo library status"); def("has_cairo", &has_cairo, "Get cairo library status");
def("has_pycairo", &has_pycairo, "Get pycairo module status"); def("has_pycairo", &has_pycairo, "Get pycairo module status");

View file

@ -19,11 +19,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
// mapnik
#include <mapnik/query.hpp> #include <mapnik/query.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
using mapnik::query; using mapnik::query;
using mapnik::box2d; using mapnik::box2d;

View file

@ -19,10 +19,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
// mapnik
#include <mapnik/raster_colorizer.hpp> #include <mapnik/raster_colorizer.hpp>
using mapnik::raster_colorizer; using mapnik::raster_colorizer;

View file

@ -19,9 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
// mapnik
#include <mapnik/raster_symbolizer.hpp> #include <mapnik/raster_symbolizer.hpp>
using mapnik::raster_symbolizer; using mapnik::raster_symbolizer;

View file

@ -19,13 +19,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/python/implicit.hpp> #include <boost/python/implicit.hpp>
#include <boost/python/detail/api_placeholder.hpp> #include <boost/python/detail/api_placeholder.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
// mapnik
#include <mapnik/rule.hpp> #include <mapnik/rule.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/expression_string.hpp> #include <mapnik/expression_string.hpp>

View file

@ -20,9 +20,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
// mapnik
#include <mapnik/shield_symbolizer.hpp> #include <mapnik/shield_symbolizer.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/path_expression_grammar.hpp> #include <mapnik/path_expression_grammar.hpp>

View file

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

View file

@ -19,11 +19,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
// mapnik
#include "mapnik_enumeration.hpp" #include "mapnik_enumeration.hpp"
#include <mapnik/feature_type_style.hpp> #include <mapnik/feature_type_style.hpp>

View file

@ -19,10 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp> #include <boost/python.hpp>
// mapnik
//symbolizer typdef here rather than mapnik/symbolizer.hpp //symbolizer typdef here rather than mapnik/symbolizer.hpp
#include <mapnik/rule.hpp> #include <mapnik/rule.hpp>

View file

@ -40,15 +40,15 @@
using namespace mapnik; using namespace mapnik;
/* Notes: /* Notes:
Overriding functions in inherited classes: Overriding functions in inherited classes:
boost.python documentation doesn't really tell you how to do it. boost.python documentation doesn't really tell you how to do it.
But this helps: But this helps:
http://www.gamedev.net/topic/446225-inheritance-in-boostpython/ http://www.gamedev.net/topic/446225-inheritance-in-boostpython/
register_ptr_to_python is required for wrapped classes, but not for unwrapped. register_ptr_to_python is required for wrapped classes, but not for unwrapped.
Functions don't have to be members of the class, but can also be Functions don't have to be members of the class, but can also be
normal functions taking a ref to the class as first parameter. normal functions taking a ref to the class as first parameter.
*/ */
namespace { namespace {
@ -251,8 +251,7 @@ struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
struct TextPlacementsWrap: text_placements, wrapper<text_placements> struct TextPlacementsWrap: text_placements, wrapper<text_placements>
{ {
text_placement_info_ptr get_placement_info(double scale_factor_, dimension_type dim, text_placement_info_ptr get_placement_info(double scale_factor_) const
bool has_dimensions_) const
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
return this->get_override("get_placement_info")(); return this->get_override("get_placement_info")();
@ -262,8 +261,8 @@ struct TextPlacementsWrap: text_placements, wrapper<text_placements>
struct TextPlacementInfoWrap: text_placement_info, wrapper<text_placement_info> struct TextPlacementInfoWrap: text_placement_info, wrapper<text_placement_info>
{ {
TextPlacementInfoWrap(text_placements const* parent, TextPlacementInfoWrap(text_placements const* parent,
double scale_factor_, dimension_type dim, bool has_dimensions_) double scale_factor_)
: text_placement_info(parent, scale_factor_, dim, has_dimensions_) : text_placement_info(parent, scale_factor_)
{ {
} }
@ -330,6 +329,7 @@ void export_text_placement()
.value("LEFT",J_LEFT) .value("LEFT",J_LEFT)
.value("MIDDLE",J_MIDDLE) .value("MIDDLE",J_MIDDLE)
.value("RIGHT",J_RIGHT) .value("RIGHT",J_RIGHT)
.value("AUTO", J_AUTO)
; ;
enumeration_<text_transform_e>("text_transform") enumeration_<text_transform_e>("text_transform")
@ -340,7 +340,7 @@ void export_text_placement()
; ;
class_<text_symbolizer>("TextSymbolizer", class_<text_symbolizer>("TextSymbolizer",
init<>()) init<>())
.def(init<expression_ptr, std::string const&, unsigned, color const&>()) .def(init<expression_ptr, std::string const&, unsigned, color const&>())
.add_property("placements", .add_property("placements",
&text_symbolizer::get_placement_options, &text_symbolizer::get_placement_options,
@ -358,7 +358,7 @@ void export_text_placement()
class_with_converter<text_symbolizer_properties> class_with_converter<text_symbolizer_properties>
("TextSymbolizerProperties") ("TextSymbolizerProperties")
.def_readwrite_convert("label_placement", &text_symbolizer_properties::label_placement) .def_readwrite_convert("label_placement", &text_symbolizer_properties::label_placement)
.def_readwrite_convert("horizontal_alignment", &text_symbolizer_properties::halign) .def_readwrite_convert("horizontal_alignment", &text_symbolizer_properties::halign)
.def_readwrite_convert("justify_alignment", &text_symbolizer_properties::jalign) .def_readwrite_convert("justify_alignment", &text_symbolizer_properties::jalign)
@ -382,15 +382,15 @@ void export_text_placement()
.add_property ("format_tree", .add_property ("format_tree",
&text_symbolizer_properties::format_tree, &text_symbolizer_properties::format_tree,
&text_symbolizer_properties::set_format_tree); &text_symbolizer_properties::set_format_tree);
/* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python. /* from_xml, to_xml operate on mapnik's internal XML tree and don't make sense in python.
add_expressions isn't useful in python either. The result is only needed by add_expressions isn't useful in python either. The result is only needed by
attribute_collector (which isn't exposed in python) and attribute_collector (which isn't exposed in python) and
it just calls add_expressions of the associated formatting tree. it just calls add_expressions of the associated formatting tree.
set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */ set_old_style expression is just a compatibility wrapper and doesn't need to be exposed in python. */
; ;
class_<char_properties> class_<char_properties>
("CharProperties") ("CharProperties")
.def(init<char_properties const&>()) //Copy constructor .def(init<char_properties const&>()) //Copy constructor
.def_readwrite("face_name", &char_properties::face_name) .def_readwrite("face_name", &char_properties::face_name)
.def_readwrite("fontset", &char_properties::fontset) .def_readwrite("fontset", &char_properties::fontset)
@ -408,9 +408,9 @@ void export_text_placement()
; ;
class_<TextPlacementsWrap, class_<TextPlacementsWrap,
boost::shared_ptr<TextPlacementsWrap>, boost::shared_ptr<TextPlacementsWrap>,
boost::noncopyable> boost::noncopyable>
("TextPlacements") ("TextPlacements")
.def_readwrite("defaults", &text_placements::defaults) .def_readwrite("defaults", &text_placements::defaults)
.def("get_placement_info", pure_virtual(&text_placements::get_placement_info)) .def("get_placement_info", pure_virtual(&text_placements::get_placement_info))
/* TODO: add_expressions() */ /* TODO: add_expressions() */
@ -418,49 +418,42 @@ void export_text_placement()
register_ptr_to_python<boost::shared_ptr<text_placements> >(); register_ptr_to_python<boost::shared_ptr<text_placements> >();
class_<TextPlacementInfoWrap, class_<TextPlacementInfoWrap,
boost::shared_ptr<TextPlacementInfoWrap>, boost::shared_ptr<TextPlacementInfoWrap>,
boost::noncopyable> boost::noncopyable>
("TextPlacementInfo", ("TextPlacementInfo",
init<text_placements const*, double, dimension_type, bool>()) init<text_placements const*, double>())
.def("next", pure_virtual(&text_placement_info::next)) .def("next", pure_virtual(&text_placement_info::next))
.def("get_actual_label_spacing", &text_placement_info::get_actual_label_spacing) .def("get_actual_label_spacing", &text_placement_info::get_actual_label_spacing)
.def("get_actual_minimum_distance", &text_placement_info::get_actual_minimum_distance) .def("get_actual_minimum_distance", &text_placement_info::get_actual_minimum_distance)
.def("get_actual_minimum_padding", &text_placement_info::get_actual_minimum_padding) .def("get_actual_minimum_padding", &text_placement_info::get_actual_minimum_padding)
.def_readwrite("properties", &text_placement_info::properties) .def_readwrite("properties", &text_placement_info::properties)
.def_readwrite("scale_factor", &text_placement_info::scale_factor) .def_readwrite("scale_factor", &text_placement_info::scale_factor)
.def_readwrite("has_dimensions", &text_placement_info::has_dimensions)
.def_readwrite("dimensions", &text_placement_info::dimensions)
.def_readwrite("collect_extents", &text_placement_info::collect_extents)
.def_readwrite("extents", &text_placement_info::extents)
.def_readwrite("additional_boxes", &text_placement_info::additional_boxes)
.def_readwrite("envelopes", &text_placement_info::envelopes)
// .def_readwrite("placements", &text_placement_info::placements)
; ;
register_ptr_to_python<boost::shared_ptr<text_placement_info> >(); register_ptr_to_python<boost::shared_ptr<text_placement_info> >();
class_<processed_text, class_<processed_text,
boost::shared_ptr<processed_text>, boost::shared_ptr<processed_text>,
boost::noncopyable> boost::noncopyable>
("ProcessedText", no_init) ("ProcessedText", no_init)
.def("push_back", &processed_text::push_back) .def("push_back", &processed_text::push_back)
.def("clear", &processed_text::clear) .def("clear", &processed_text::clear)
; ;
class_<expression_set, class_<expression_set,
boost::shared_ptr<expression_set>, boost::shared_ptr<expression_set>,
boost::noncopyable> boost::noncopyable>
("ExpressionSet") ("ExpressionSet")
.def("insert", &insert_expression); .def("insert", &insert_expression);
; ;
//TODO: Python namespace //TODO: Python namespace
class_<NodeWrap, class_<NodeWrap,
boost::shared_ptr<NodeWrap>, boost::shared_ptr<NodeWrap>,
boost::noncopyable> boost::noncopyable>
("FormattingNode") ("FormattingNode")
.def("apply", pure_virtual(&formatting::node::apply)) .def("apply", pure_virtual(&formatting::node::apply))
.def("add_expressions", .def("add_expressions",
&formatting::node::add_expressions, &formatting::node::add_expressions,
@ -470,10 +463,10 @@ void export_text_placement()
class_<TextNodeWrap, class_<TextNodeWrap,
boost::shared_ptr<TextNodeWrap>, boost::shared_ptr<TextNodeWrap>,
bases<formatting::node>, bases<formatting::node>,
boost::noncopyable> boost::noncopyable>
("FormattingText", init<expression_ptr>()) ("FormattingText", init<expression_ptr>())
.def(init<std::string>()) .def(init<std::string>())
.def("apply", &formatting::text_node::apply, &TextNodeWrap::default_apply) .def("apply", &formatting::text_node::apply, &TextNodeWrap::default_apply)
.add_property("text", .add_property("text",
@ -484,10 +477,10 @@ void export_text_placement()
class_with_converter<FormatNodeWrap, class_with_converter<FormatNodeWrap,
boost::shared_ptr<FormatNodeWrap>, boost::shared_ptr<FormatNodeWrap>,
bases<formatting::node>, bases<formatting::node>,
boost::noncopyable> boost::noncopyable>
("FormattingFormat") ("FormattingFormat")
.def_readwrite_convert("text_size", &formatting::format_node::text_size) .def_readwrite_convert("text_size", &formatting::format_node::text_size)
.def_readwrite_convert("face_name", &formatting::format_node::face_name) .def_readwrite_convert("face_name", &formatting::format_node::face_name)
.def_readwrite_convert("character_spacing", &formatting::format_node::character_spacing) .def_readwrite_convert("character_spacing", &formatting::format_node::character_spacing)
@ -507,10 +500,10 @@ void export_text_placement()
register_ptr_to_python<boost::shared_ptr<formatting::format_node> >(); register_ptr_to_python<boost::shared_ptr<formatting::format_node> >();
class_<ListNodeWrap, class_<ListNodeWrap,
boost::shared_ptr<ListNodeWrap>, boost::shared_ptr<ListNodeWrap>,
bases<formatting::node>, bases<formatting::node>,
boost::noncopyable> boost::noncopyable>
("FormattingList", init<>()) ("FormattingList", init<>())
.def(init<list>()) .def(init<list>())
.def("append", &formatting::list_node::push_back) .def("append", &formatting::list_node::push_back)
.def("apply", &formatting::list_node::apply, &ListNodeWrap::default_apply) .def("apply", &formatting::list_node::apply, &ListNodeWrap::default_apply)
@ -518,15 +511,15 @@ void export_text_placement()
.def("__getitem__", &ListNodeWrap::get_item) .def("__getitem__", &ListNodeWrap::get_item)
.def("__setitem__", &ListNodeWrap::set_item) .def("__setitem__", &ListNodeWrap::set_item)
.def("append", &ListNodeWrap::append) .def("append", &ListNodeWrap::append)
; ;
register_ptr_to_python<boost::shared_ptr<formatting::list_node> >(); register_ptr_to_python<boost::shared_ptr<formatting::list_node> >();
class_<ExprFormatWrap, class_<ExprFormatWrap,
boost::shared_ptr<ExprFormatWrap>, boost::shared_ptr<ExprFormatWrap>,
bases<formatting::node>, bases<formatting::node>,
boost::noncopyable> boost::noncopyable>
("FormattingExpressionFormat") ("FormattingExpressionFormat")
.def_readwrite("text_size", &formatting::expression_format::text_size) .def_readwrite("text_size", &formatting::expression_format::text_size)
.def_readwrite("face_name", &formatting::expression_format::face_name) .def_readwrite("face_name", &formatting::expression_format::face_name)
.def_readwrite("character_spacing", &formatting::expression_format::character_spacing) .def_readwrite("character_spacing", &formatting::expression_format::character_spacing)

View file

@ -29,8 +29,8 @@ namespace mapnik {
class python_thread class python_thread
{ {
/* Docs: /* Docs:
http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
*/ */
public: public:
static void unblock() static void unblock()
{ {
@ -38,8 +38,8 @@ public:
if (state.get()) if (state.get())
{ {
std::cerr << "ERROR: Python threads are already unblocked. " std::cerr << "ERROR: Python threads are already unblocked. "
"Unblocking again will loose the current state and " "Unblocking again will loose the current state and "
"might crash later. Aborting!\n"; "might crash later. Aborting!\n";
abort(); //This is a serious error and can't be handled in any other sane way abort(); //This is a serious error and can't be handled in any other sane way
} }
#endif #endif
@ -59,9 +59,9 @@ public:
if (thread_support && !state.get()) if (thread_support && !state.get())
{ {
std::cerr << "ERROR: Trying to restore python thread state, " std::cerr << "ERROR: Trying to restore python thread state, "
"but no state is saved. Can't continue and also " "but no state is saved. Can't continue and also "
"can't raise an exception because the python " "can't raise an exception because the python "
"interpreter might be non-function. Aborting!\n"; "interpreter might be non-function. Aborting!\n";
abort(); abort();
} }
#endif #endif

View file

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

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO) #if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)

View file

@ -28,6 +28,7 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
// mapnik // mapnik
#include <mapnik/debug.hpp>
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/grid/grid_util.hpp> #include <mapnik/grid/grid_util.hpp>
@ -271,7 +272,7 @@ static void write_features(T const& grid_type,
} }
else else
{ {
std::clog << "should not get here: key '" << key << "' not found in grid feature properties\n"; MAPNIK_LOG_DEBUG(bindings) << "write_features: Should not get here: key " << key << " not found in grid feature properties";
} }
} }
} }

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#include <boost/optional/optional.hpp> #include <boost/optional/optional.hpp>
#include <boost/python.hpp> #include <boost/python.hpp>
@ -102,8 +101,8 @@ struct python_optional : public boost::noncopyable
/** This class works around a bug in boost python. /** This class works around a bug in boost python.
See http://osdir.com/ml/python.c++/2003-11/msg00158.html 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> class class_with_converter : public boost::python::class_<T, X1, X2, X3>
{ {
@ -131,8 +130,8 @@ public:
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, this->add_property(name,
boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()), boost::python::make_getter(d, boost::python::return_value_policy<boost::python::return_by_value>()),
boost::python::make_setter(d, boost::python::default_call_policies())); boost::python::make_setter(d, boost::python::default_call_policies()));
return *this; return *this;
} }
}; };

View file

@ -1,5 +1,3 @@
CXX = g++
CXXFLAGS = $(shell mapnik-config --cflags) CXXFLAGS = $(shell mapnik-config --cflags)
LDFLAGS = $(shell mapnik-config --libs --dep-libs --ldflags) LDFLAGS = $(shell mapnik-config --libs --dep-libs --ldflags)

View file

@ -47,7 +47,6 @@ rundemo = demo_env.Program('rundemo', source, LIBS=libraries, LINKFLAGS=env["CUS
Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME'])) Depends(rundemo, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
# we don't install this app because the datasource paths are relative # build locally if installing
# and we're not going to install the sample data. if 'install' in COMMAND_LINE_TARGETS:
#env.Install(install_prefix + '/bin', rundemo) env.Alias('install',rundemo)
#env.Alias('install', install_prefix + '/bin')

View file

@ -70,7 +70,7 @@ int main ( int argc , char** argv)
provpoly_style.add_rule(provpoly_rule_on); provpoly_style.add_rule(provpoly_rule_on);
rule provpoly_rule_qc; rule provpoly_rule_qc;
provpoly_rule_qc.set_filter(parse_expression("[NOM_FR] = 'Québec'")); provpoly_rule_qc.set_filter(parse_expression("[NOM_FR] = 'Québec'"));
provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203))); provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203)));
provpoly_style.add_rule(provpoly_rule_qc); provpoly_style.add_rule(provpoly_rule_qc);
@ -175,6 +175,7 @@ int main ( int argc , char** argv)
parameters p; parameters p;
p["type"]="shape"; p["type"]="shape";
p["file"]="../data/boundaries"; p["file"]="../data/boundaries";
p["encoding"]="latin1";
layer lyr("Provinces"); layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance()->create(p)); lyr.set_datasource(datasource_cache::instance()->create(p));

View file

@ -138,7 +138,9 @@ qcdrain_lyr.datasource = mapnik.Shapefile(file='../data/qcdrainage')
qcdrain_style = mapnik.Style() qcdrain_style = mapnik.Style()
qcdrain_rule = mapnik.Rule() qcdrain_rule = mapnik.Rule()
qcdrain_rule.filter = mapnik.Expression('[HYC] = 8') qcdrain_rule.filter = mapnik.Expression('[HYC] = 8')
qcdrain_rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255))) sym = mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255))
sym.smooth = 1.0 # very smooth
qcdrain_rule.symbols.append(sym)
qcdrain_style.rules.append(qcdrain_rule) qcdrain_style.rules.append(qcdrain_rule)
m.append_style('drainage', qcdrain_style) m.append_style('drainage', qcdrain_style)

View file

@ -49,7 +49,7 @@ QVariant LayerListModel::data(QModelIndex const& index,int role) const
else if (role == Qt::DecorationRole) else if (role == Qt::DecorationRole)
{ {
double scale = map_->scale(); double scale = map_->scale();
if (map_->layers().at(index.row()).isVisible(scale)) if (map_->layers().at(index.row()).visible(scale))
{ {
return QIcon(":/images/globe.png"); return QIcon(":/images/globe.png");
} }
@ -60,7 +60,7 @@ QVariant LayerListModel::data(QModelIndex const& index,int role) const
} }
else if (role == Qt::CheckStateRole) else if (role == Qt::CheckStateRole)
{ {
if (map_->layers().at(index.row()).isActive()) if (map_->layers().at(index.row()).active())
return QVariant(Qt::Checked); return QVariant(Qt::Checked);
else else
return QVariant(Qt::Unchecked); return QVariant(Qt::Unchecked);
@ -92,7 +92,7 @@ bool LayerListModel::setData(const QModelIndex &index,
{ {
int status = value.toInt(); int status = value.toInt();
std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers()); std::vector<mapnik::layer> & layers = const_cast<std::vector<mapnik::layer>& >(map_->layers());
layers.at(index.row()).setActive(status); layers.at(index.row()).set_active(status);
emit dataChanged(index, index); emit dataChanged(index, index);
return true; return true;
} }

View file

@ -30,6 +30,7 @@
#include <mapnik/ctrans.hpp> #include <mapnik/ctrans.hpp>
#include <mapnik/memory_datasource.hpp> #include <mapnik/memory_datasource.hpp>
#include <mapnik/feature_kv_iterator.hpp> #include <mapnik/feature_kv_iterator.hpp>
#include <mapnik/config_error.hpp>
#include "mapwidget.hpp" #include "mapwidget.hpp"
#include "info_dialog.hpp" #include "info_dialog.hpp"
@ -157,7 +158,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
if (int(index) != selectedLayer_) continue; if (int(index) != selectedLayer_) continue;
layer & layer = map_->layers()[index]; layer & layer = map_->layers()[index];
if (!layer.isVisible(scale_denom)) continue; if (!layer.visible(scale_denom)) continue;
std::string name = layer.name(); std::string name = layer.name();
double x = e->x(); double x = e->x();
double y = e->y(); double y = e->y();
@ -487,7 +488,7 @@ void MapWidget::updateMap()
} }
catch (mapnik::config_error & ex) catch (mapnik::config_error & ex)
{ {
std::cerr << ex.what() << std::endl; std::cerr << ex.what() << std::endl;
} }
catch (...) catch (...)
{ {

View file

@ -95,6 +95,18 @@ If you see bits of code around that do not follow these please don't hesitate to
(int)value; // no (int)value; // no
#### Use const keyword after the type
std::string const& variable_name // preferred, for consistency
const std::string & variable_name // no
#### Pass built-in types by value, all others by const&
void my_function(int double val); // if int, char, double, etc pass by value
void my_function(std::string const& val); // if std::string or user type, pass by const&
#### Shared pointers should be created with [boost::make_shared](http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/make_shared.html) where possible #### Shared pointers should be created with [boost::make_shared](http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/make_shared.html) where possible
#### Function definitions should not be separated from their arguments: #### Function definitions should not be separated from their arguments:

View file

@ -0,0 +1,91 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_AGG_HELPERS_HPP
#define MAPNIK_AGG_HELPERS_HPP
#include "agg_gamma_functions.h"
#include "agg_math_stroke.h"
namespace mapnik {
template <typename T0, typename T1>
void set_gamma_method(T0 const& obj, T1 & ras_ptr)
{
switch (obj.get_gamma_method())
{
case GAMMA_POWER:
ras_ptr->gamma(agg::gamma_power(obj.get_gamma()));
break;
case GAMMA_LINEAR:
ras_ptr->gamma(agg::gamma_linear(0.0, obj.get_gamma()));
break;
case GAMMA_NONE:
ras_ptr->gamma(agg::gamma_none());
break;
case GAMMA_THRESHOLD:
ras_ptr->gamma(agg::gamma_threshold(obj.get_gamma()));
break;
case GAMMA_MULTIPLY:
ras_ptr->gamma(agg::gamma_multiply(obj.get_gamma()));
break;
default:
ras_ptr->gamma(agg::gamma_power(obj.get_gamma()));
}
}
template <typename Stroke,typename PathType>
void set_join_caps(Stroke const& stroke_, PathType & stroke)
{
line_join_e join=stroke_.get_line_join();
switch (join)
{
case MITER_JOIN:
stroke.generator().line_join(agg::miter_join);
break;
case MITER_REVERT_JOIN:
stroke.generator().line_join(agg::miter_join);
break;
case ROUND_JOIN:
stroke.generator().line_join(agg::round_join);
break;
default:
stroke.generator().line_join(agg::bevel_join);
}
line_cap_e cap=stroke_.get_line_cap();
switch (cap)
{
case BUTT_CAP:
stroke.generator().line_cap(agg::butt_cap);
break;
case SQUARE_CAP:
stroke.generator().line_cap(agg::square_cap);
break;
default:
stroke.generator().line_cap(agg::round_cap);
}
}
}
#endif //MAPNIK_AGG_HELPERS_HPP

View file

@ -29,10 +29,6 @@
#include <mapnik/font_engine_freetype.hpp> #include <mapnik/font_engine_freetype.hpp>
#include <mapnik/label_collision_detector.hpp> #include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
//#include <mapnik/marker.hpp>
// agg
//#include "agg_trans_affine.h"
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
@ -67,10 +63,10 @@ public:
~agg_renderer(); ~agg_renderer();
void start_map_processing(Map const& map); void start_map_processing(Map const& map);
void end_map_processing(Map const& map); void end_map_processing(Map const& map);
void start_layer_processing(layer const& lay); void start_layer_processing(layer const& lay, box2d<double> const& query_extent);
void end_layer_processing(layer const& lay); void end_layer_processing(layer const& lay);
void render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity); void render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity);
void process(point_symbolizer const& sym, void process(point_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans); proj_transform const& prj_trans);
@ -123,7 +119,7 @@ private:
face_manager<freetype_engine> font_manager_; face_manager<freetype_engine> font_manager_;
boost::shared_ptr<label_collision_detector4> detector_; boost::shared_ptr<label_collision_detector4> detector_;
boost::scoped_ptr<rasterizer> ras_ptr; boost::scoped_ptr<rasterizer> ras_ptr;
box2d<double> query_extent_;
void setup(Map const &m); void setup(Map const &m);
}; };
} }

View file

@ -0,0 +1,99 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_BOOLEAN_HPP
#define MAPNIK_BOOLEAN_HPP
// std
#include <istream>
// boost
#include <boost/algorithm/string.hpp>
namespace mapnik
{
/** Helper for class bool */
class boolean {
public:
boolean(): b_(false) {}
boolean(bool b) : b_(b) {}
boolean(boolean const& b) : b_(b.b_) {}
operator bool() const
{
return b_;
}
boolean & operator = (boolean const& other)
{
b_ = other.b_;
return * this;
}
boolean & operator = (bool other)
{
b_ = other;
return * this;
}
private:
bool b_;
};
/** Special stream input operator for boolean values */
template <typename charT, typename traits>
std::basic_istream<charT, traits> &
operator >> ( std::basic_istream<charT, traits> & s, boolean & b )
{
std::string word;
s >> word;
boost::algorithm::to_lower(word);
if ( s )
{
if ( word == "true" || word == "yes" || word == "on" ||
word == "1")
{
b = true;
}
else if ( word == "false" || word == "no" || word == "off" ||
word == "0")
{
b = false;
}
else
{
s.setstate( std::ios::failbit );
}
}
return s;
}
template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, boolean const& b )
{
s << ( b ? "true" : "false" );
return s;
}
}
#endif // MAPNIK_BOOLEAN_HPP

View file

@ -78,7 +78,7 @@ protected:
public: public:
~cairo_renderer_base(); ~cairo_renderer_base();
void start_map_processing(Map const& map); void start_map_processing(Map const& map);
void start_layer_processing(layer const& lay); void start_layer_processing(layer const& lay, box2d<double> const& query_extent);
void end_layer_processing(layer const& lay); void end_layer_processing(layer const& lay);
void process(point_symbolizer const& sym, void process(point_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
@ -123,7 +123,7 @@ public:
} }
protected: protected:
void render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & mtx, double opacity=1.0); void render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & mtx, double opacity=1.0, bool recenter=true);
Map const& m_; Map const& m_;
Cairo::RefPtr<Cairo::Context> context_; Cairo::RefPtr<Cairo::Context> context_;
@ -132,6 +132,7 @@ protected:
face_manager<freetype_engine> font_manager_; face_manager<freetype_engine> font_manager_;
cairo_face_manager face_manager_; cairo_face_manager face_manager_;
label_collision_detector4 detector_; label_collision_detector4 detector_;
box2d<double> query_extent_;
}; };
template <typename T> template <typename T>

View file

@ -31,11 +31,24 @@ struct char_properties;
class char_info { class char_info {
public: public:
char_info(unsigned c_, double width_, double ymax_, double ymin_, double line_height_) char_info(unsigned c_, double width_, double ymax_, double ymin_, double line_height_)
: c(c_), width(width_), line_height(line_height_), ymin(ymin_), ymax(ymax_) : c(c_),
width(width_),
line_height(line_height_),
ymin(ymin_),
ymax(ymax_),
avg_height(ymax_-ymin_),
format()
{ {
} }
char_info() char_info()
: c(0), width(0), line_height(0), ymin(0), ymax(0) : c(0),
width(0),
line_height(0),
ymin(0),
ymax(0),
avg_height(0),
format()
{ {
} }

View file

@ -137,6 +137,14 @@ public:
std::string to_hex_string() const; std::string to_hex_string() const;
}; };
template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
{
std::string hex_string( c.to_string() );
s << hex_string;
return s;
}
} }

View file

@ -25,134 +25,26 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/color.hpp>
#include <mapnik/config_error.hpp>
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/version.hpp>
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
#if BOOST_VERSION >= 104500
#include <mapnik/css_color_grammar.hpp>
namespace mapnik { namespace mapnik {
class color;
template <typename Iterator> struct css_color_grammar;
class MAPNIK_DECL color_factory : boost::noncopyable class MAPNIK_DECL color_factory : boost::noncopyable
{ {
public: public:
static void init_from_string(color & c, std::string const& css_color) static void init_from_string(color & c, std::string const& css_color);
{
typedef std::string::const_iterator iterator_type;
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
css_color_grammar g;
iterator_type first = css_color.begin();
iterator_type last = css_color.end();
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
c);
if (!result)
{
throw config_error(std::string("Failed to parse color value: ") +
"Expected a CSS color, but got '" + css_color + "'");
}
}
static bool parse_from_string(color & c, std::string const& css_color, static bool parse_from_string(color & c, std::string const& css_color,
mapnik::css_color_grammar<std::string::const_iterator> const& g) mapnik::css_color_grammar<std::string::const_iterator> const& g);
{
std::string::const_iterator first = css_color.begin();
std::string::const_iterator last = css_color.end();
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
c);
return result && (first == last);
}
static color from_string(std::string const& css_color) static color from_string(std::string const& css_color);
{
color c;
init_from_string(c,css_color);
return c;
}
}; };
} }
#else
#include <mapnik/css_color_grammar_deprecated.hpp>
namespace mapnik {
class MAPNIK_DECL color_factory : boost::noncopyable
{
public:
static bool parse_from_string(color & c, std::string const& css_color,
mapnik::css_color_grammar<std::string::const_iterator> const& g)
{
std::string::const_iterator first = css_color.begin();
std::string::const_iterator last = css_color.end();
mapnik::css css_;
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
css_);
if (result && (first == last))
{
c.set_red(css_.r);
c.set_green(css_.g);
c.set_blue(css_.b);
c.set_alpha(css_.a);
return true;
}
return false;
}
static void init_from_string(color & c, std::string const& css_color)
{
typedef std::string::const_iterator iterator_type;
typedef mapnik::css_color_grammar<iterator_type> css_color_grammar;
css_color_grammar g;
iterator_type first = css_color.begin();
iterator_type last = css_color.end();
mapnik::css css_;
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
css_);
if (!result)
{
throw config_error(std::string("Failed to parse color value: ") +
"Expected a CSS color, but got '" + css_color + "'");
}
c.set_red(css_.r);
c.set_green(css_.g);
c.set_blue(css_.b);
c.set_alpha(css_.a);
}
static color from_string(std::string const& css_color)
{
color c;
init_from_string(c,css_color);
return c;
}
};
}
#endif
#endif // MAPNIK_COLOR_FACTORY_HPP #endif // MAPNIK_COLOR_FACTORY_HPP

View file

@ -25,8 +25,6 @@
// Windows DLL support // Windows DLL support
#define MAPNIK_SUPPORTS_GRID_RENDERER
#ifdef _WINDOWS #ifdef _WINDOWS
# define MAPNIK_EXP __declspec (dllexport) # define MAPNIK_EXP __declspec (dllexport)
# define MAPNIK_IMP __declspec (dllimport) # define MAPNIK_IMP __declspec (dllimport)

View file

@ -28,30 +28,28 @@
namespace mapnik { namespace mapnik {
class xml_node;
class config_error : public std::exception class config_error : public std::exception
{ {
public: public:
config_error() {} config_error(std::string const& what);
config_error(std::string const& what, xml_node const& node);
config_error( const std::string & what ) : config_error(std::string const& what, unsigned line_number, std::string const& filename);
what_( what )
{
}
virtual ~config_error() throw() {} virtual ~config_error() throw() {}
virtual const char * what() const throw() virtual const char * what() const throw();
{
return what_.c_str();
}
void append_context(const std::string & ctx) const
{
what_ += " " + ctx;
}
void append_context(const std::string & ctx) const;
void append_context(const std::string & ctx, xml_node const& node) const;
void append_context(xml_node const& node) const;
protected: protected:
mutable std::string what_; mutable std::string what_;
mutable unsigned line_number_;
mutable std::string file_;
mutable std::string node_name_;
mutable std::string msg_;
}; };
} }
#endif // MAPNIK_CONFIG_ERROR_HPP #endif // MAPNIK_CONFIG_ERROR_HPP

View file

@ -24,6 +24,7 @@
#define MAPNIK_CTRANS_HPP #define MAPNIK_CTRANS_HPP
// mapnik // mapnik
#include <mapnik/debug.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/vertex.hpp> #include <mapnik/vertex.hpp>
#include <mapnik/coord_array.hpp> #include <mapnik/coord_array.hpp>
@ -72,16 +73,16 @@ template <typename Transform, typename Geometry>
struct MAPNIK_DECL coord_transform2 struct MAPNIK_DECL coord_transform2
{ {
typedef std::size_t size_type; typedef std::size_t size_type;
typedef typename Geometry::value_type value_type; //typedef typename Geometry::value_type value_type;
coord_transform2(Transform const& t, coord_transform2(Transform const& t,
Geometry const& geom, Geometry & geom,
proj_transform const& prj_trans) proj_transform const& prj_trans)
: t_(t), : t_(t),
geom_(geom), geom_(geom),
prj_trans_(prj_trans) {} prj_trans_(prj_trans) {}
unsigned vertex(double *x, double *y) const unsigned vertex(double *x, double *y)
{ {
unsigned command = SEG_MOVETO; unsigned command = SEG_MOVETO;
bool ok = false; bool ok = false;
@ -115,7 +116,7 @@ struct MAPNIK_DECL coord_transform2
private: private:
Transform const& t_; Transform const& t_;
Geometry const& geom_; Geometry & geom_;
proj_transform const& prj_trans_; proj_transform const& prj_trans_;
}; };
@ -239,10 +240,10 @@ struct MAPNIK_DECL coord_transform_parallel
angle_a = atan2((m_pre_y-m_cur_y),(m_pre_x-m_cur_x)); angle_a = atan2((m_pre_y-m_cur_y),(m_pre_x-m_cur_x));
dx_pre = cos(angle_a + pi_by_2); dx_pre = cos(angle_a + pi_by_2);
dy_pre = sin(angle_a + pi_by_2); dy_pre = sin(angle_a + pi_by_2);
#ifdef MAPNIK_DEBUG
std::clog << "offsetting line by: " << offset_ << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: Offsetting line by=" << offset_;
std::clog << "initial dx=" << (dx_pre * offset_) << " dy=" << (dy_pre * offset_) << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: Initial dx=" << (dx_pre * offset_) << ",dy=" << (dy_pre * offset_);
#endif
*x = m_pre_x + (dx_pre * offset_); *x = m_pre_x + (dx_pre * offset_);
*y = m_pre_y + (dy_pre * offset_); *y = m_pre_y + (dy_pre * offset_);
m_status = process; m_status = process;
@ -289,15 +290,14 @@ struct MAPNIK_DECL coord_transform_parallel
} }
else // skip sharp spikes else // skip sharp spikes
{ {
#ifdef MAPNIK_LOG
#ifdef MAPNIK_DEBUG
dx_curr = cos(angle_a + pi_by_2); dx_curr = cos(angle_a + pi_by_2);
dy_curr = sin(angle_a + pi_by_2); dy_curr = sin(angle_a + pi_by_2);
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre; sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
std::clog << "angle a: " << angle_a << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: angle a=" << angle_a;
std::clog << "angle b: " << angle_b << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: angle b=" << angle_b;
std::clog << "h: " << h << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: h=" << h;
std::clog << "sin_curve: " << sin_curve << "\n"; MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: sin_curve=" << sin_curve;
#endif #endif
m_status = process; m_status = process;
break; break;
@ -309,21 +309,19 @@ struct MAPNIK_DECL coord_transform_parallel
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre; sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
cos_curve = -dx_pre*dx_curr-dy_pre*dy_curr; cos_curve = -dx_pre*dx_curr-dy_pre*dy_curr;
#ifdef MAPNIK_DEBUG MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: sin_curve value=" << sin_curve;
std::clog << "sin_curve value: " << sin_curve << "\n";
#endif
if(sin_curve > -0.3 && sin_curve < 0.3) { if(sin_curve > -0.3 && sin_curve < 0.3) {
angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x)); angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x));
h = tan((angle_b - angle_a)/2.0); h = tan((angle_b - angle_a)/2.0);
*x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_); *x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_);
*y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_); *y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_);
} else { } else {
if (angle_b - angle_a > 0) if (angle_b - angle_a > 0)
h = -1.0*(1.0+cos_curve)/sin_curve; h = -1.0*(1.0+cos_curve)/sin_curve;
else else
h = (1.0+cos_curve)/sin_curve; h = (1.0+cos_curve)/sin_curve;
*x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_; *x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_;
*y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_; *y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_;
} }
*/ */
@ -380,20 +378,27 @@ class CoordTransform
private: private:
int width_; int width_;
int height_; int height_;
double sx_;
double sy_;
box2d<double> extent_; box2d<double> extent_;
double offset_x_; double offset_x_;
double offset_y_; double offset_y_;
double sx_;
double sy_;
public: public:
CoordTransform(int width, int height, const box2d<double>& extent, CoordTransform(int width, int height, const box2d<double>& extent,
double offset_x = 0, double offset_y = 0) double offset_x = 0, double offset_y = 0)
: width_(width), height_(height), extent_(extent), : width_(width),
offset_x_(offset_x), offset_y_(offset_y) height_(height),
extent_(extent),
offset_x_(offset_x),
offset_y_(offset_y),
sx_(1.0),
sy_(1.0)
{ {
sx_ = static_cast<double>(width_) / extent_.width(); if (extent_.width() > 0)
sy_ = static_cast<double>(height_) / extent_.height(); sx_ = static_cast<double>(width_) / extent_.width();
if (extent_.height() > 0)
sy_ = static_cast<double>(height_) / extent_.height();
} }
inline int width() const inline int width() const

View file

@ -45,25 +45,30 @@ typedef MAPNIK_DECL boost::shared_ptr<Feature> feature_ptr;
struct MAPNIK_DECL Featureset : private boost::noncopyable struct MAPNIK_DECL Featureset : private boost::noncopyable
{ {
virtual feature_ptr next()=0; virtual feature_ptr next() = 0;
virtual ~Featureset() {}; virtual ~Featureset() {}
}; };
typedef MAPNIK_DECL boost::shared_ptr<Featureset> featureset_ptr; typedef MAPNIK_DECL boost::shared_ptr<Featureset> featureset_ptr;
class MAPNIK_DECL datasource_exception : public std::exception class MAPNIK_DECL datasource_exception : public std::exception
{ {
private:
std::string message_;
public: public:
datasource_exception(const std::string& message=std::string("no reason")) datasource_exception(const std::string& message = std::string("no reason"))
:message_(message) {} : message_(message)
{
}
~datasource_exception() throw()
{
}
~datasource_exception() throw() {}
virtual const char* what() const throw() virtual const char* what() const throw()
{ {
return message_.c_str(); return message_.c_str();
} }
private:
std::string message_;
}; };
class MAPNIK_DECL datasource : private boost::noncopyable class MAPNIK_DECL datasource : private boost::noncopyable
@ -82,9 +87,10 @@ public:
}; };
datasource (parameters const& params) datasource (parameters const& params)
: params_(params), : params_(params),
is_bound_(false) is_bound_(false)
{} {
}
/*! /*!
* @brief Get the configuration parameters of the data source. * @brief Get the configuration parameters of the data source.
@ -102,19 +108,19 @@ public:
* @brief Get the type of the datasource * @brief Get the type of the datasource
* @return The type of the datasource (Vector or Raster) * @return The type of the datasource (Vector or Raster)
*/ */
virtual datasource_t type() const=0; virtual datasource_t type() const = 0;
/*! /*!
* @brief Connect to the datasource * @brief Connect to the datasource
*/ */
virtual void bind() const {}; virtual void bind() const {}
virtual featureset_ptr features(const query& q) const=0; virtual featureset_ptr features(const query& q) const = 0;
virtual featureset_ptr features_at_point(coord2d const& pt) const=0; virtual featureset_ptr features_at_point(coord2d const& pt) const = 0;
virtual box2d<double> envelope() const=0; virtual box2d<double> envelope() const = 0;
virtual boost::optional<geometry_t> get_geometry_type() const=0; virtual boost::optional<geometry_t> get_geometry_type() const = 0;
virtual layer_descriptor get_descriptor() const=0; virtual layer_descriptor get_descriptor() const = 0;
virtual ~datasource() {}; virtual ~datasource() {}
protected: protected:
parameters params_; parameters params_;
mutable bool is_bound_; mutable bool is_bound_;
@ -124,7 +130,6 @@ typedef std::string datasource_name();
typedef datasource* create_ds(const parameters& params, bool bind); typedef datasource* create_ds(const parameters& params, bool bind);
typedef void destroy_ds(datasource *ds); typedef void destroy_ds(datasource *ds);
class datasource_deleter class datasource_deleter
{ {
public: public:
@ -136,7 +141,6 @@ public:
typedef boost::shared_ptr<datasource> datasource_ptr; typedef boost::shared_ptr<datasource> datasource_ptr;
#define DATASOURCE_PLUGIN(classname) \ #define DATASOURCE_PLUGIN(classname) \
extern "C" MAPNIK_EXP std::string datasource_name() \ extern "C" MAPNIK_EXP std::string datasource_name() \
{ \ { \
@ -149,8 +153,7 @@ typedef boost::shared_ptr<datasource> datasource_ptr;
extern "C" MAPNIK_EXP void destroy(datasource *ds) \ extern "C" MAPNIK_EXP void destroy(datasource *ds) \
{ \ { \
delete ds; \ delete ds; \
} \ }
//
} }

279
include/mapnik/debug.hpp Normal file
View file

@ -0,0 +1,279 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_DEBUG_HPP
#define MAPNIK_DEBUG_HPP
// mapnik (should not depend on anything that need to use this)
#include <mapnik/config.hpp>
#include <mapnik/utils.hpp>
// boost
#include <boost/utility.hpp>
#include <boost/unordered_map.hpp>
#ifdef MAPNIK_THREADSAFE
#include <boost/thread/mutex.hpp>
#endif
// std
#include <iostream>
#include <sstream>
#include <ostream>
#include <fstream>
#include <string>
namespace mapnik {
namespace logger {
class MAPNIK_DECL severity :
public singleton<severity,CreateStatic>,
private boost::noncopyable
{
public:
enum type
{
info,
debug,
warn,
error,
fatal,
none
};
typedef boost::unordered_map<std::string, type> severity_map;
// globally get security level
static type get()
{
return severity_level_;
}
// globally set security level
static void set(const type& severity_level)
{
#ifdef MAPNIK_THREADSAFE
boost::mutex::scoped_lock lock(mutex_);
#endif
severity_level_ = severity_level;
}
// per object get security level
static type get_object(const std::string& object_name)
{
severity_map::iterator it = object_severity_level_.find(object_name);
if (object_name.empty() || it == object_severity_level_.end())
{
return severity_level_;
}
else
{
return it->second;
}
}
// per object set security level
static void set_object(const std::string& object_name,
const type& security_level)
{
#ifdef MAPNIK_THREADSAFE
boost::mutex::scoped_lock lock(mutex_);
#endif
if (! object_name.empty())
{
object_severity_level_[object_name] = security_level;
}
}
private:
static type severity_level_;
static severity_map object_severity_level_;
#ifdef MAPNIK_THREADSAFE
static boost::mutex mutex_;
#endif
};
class MAPNIK_DECL format :
public singleton<format,CreateStatic>,
private boost::noncopyable
{
public:
static std::string get()
{
return format_;
}
static void set(const std::string& format)
{
#ifdef MAPNIK_THREADSAFE
boost::mutex::scoped_lock lock(mutex_);
#endif
format_ = format;
}
static std::string str();
private:
static std::string format_;
#ifdef MAPNIK_THREADSAFE
static boost::mutex mutex_;
#endif
};
class MAPNIK_DECL output :
public singleton<output,CreateStatic>,
private boost::noncopyable
{
public:
static void use_file(const std::string& filepath);
static void use_console();
private:
static std::ofstream file_output_;
static std::string file_name_;
static std::streambuf* saved_buf_;
};
template<class Ch, class Tr, class A>
class clog_sink
{
public:
typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
void operator()(const stream_buffer &s)
{
#ifdef MAPNIK_THREADSAFE
static boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
#endif
std::clog << format::str() << " " << s.str() << std::endl;
}
};
template<template <class Ch, class Tr, class A> class OutputPolicy,
severity::type Severity,
class Ch = char,
class Tr = std::char_traits<Ch>,
class A = std::allocator<Ch> >
class base_log : public boost::noncopyable
{
public:
typedef OutputPolicy<Ch, Tr, A> output_policy;
base_log() {}
base_log(const char* object_name)
{
#ifdef MAPNIK_LOG
if (object_name != NULL)
{
object_name_ = object_name;
}
#endif
}
~base_log()
{
#ifdef MAPNIK_LOG
if (check_severity())
{
output_policy()(streambuf_);
}
#endif
}
template<class T>
base_log &operator<<(const T &x)
{
#ifdef MAPNIK_LOG
streambuf_ << x;
#endif
return *this;
}
private:
#ifdef MAPNIK_LOG
inline bool check_severity()
{
return Severity >= severity::get_object(object_name_);
}
typename output_policy::stream_buffer streambuf_;
std::string object_name_;
#endif
};
typedef base_log<clog_sink, severity::info> base_log_info;
typedef base_log<clog_sink, severity::debug> base_log_debug;
typedef base_log<clog_sink, severity::warn> base_log_warn;
typedef base_log<clog_sink, severity::error> base_log_error;
typedef base_log<clog_sink, severity::fatal> base_log_fatal;
}
class MAPNIK_DECL info : public logger::base_log_info {
public:
info() : logger::base_log_info() {}
info(const char* object_name) : logger::base_log_info(object_name) {}
};
class MAPNIK_DECL debug : public logger::base_log_debug {
public:
debug() : logger::base_log_debug() {}
debug(const char* object_name) : logger::base_log_debug(object_name) {}
};
class MAPNIK_DECL warn : public logger::base_log_warn {
public:
warn() : logger::base_log_warn() {}
warn(const char* object_name) : logger::base_log_warn(object_name) {}
};
class MAPNIK_DECL error : public logger::base_log_error {
public:
error() : logger::base_log_error() {}
error(const char* object_name) : logger::base_log_error(object_name) {}
};
class MAPNIK_DECL fatal : public logger::base_log_fatal {
public:
fatal() : logger::base_log_fatal() {}
fatal(const char* object_name) : logger::base_log_fatal(object_name) {}
};
#define MAPNIK_LOG_INFO(s) mapnik::info(#s)
#define MAPNIK_LOG_DEBUG(s) mapnik::debug(#s)
#define MAPNIK_LOG_WARN(s) mapnik::warn(#s)
#define MAPNIK_LOG_ERROR(s) mapnik::error(#s)
#define MAPNIK_LOG_FATAL(s) mapnik::fatal(#s)
}
#endif // MAPNIK_DEBUG_HPP

View file

@ -25,6 +25,7 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
// stl // stl
#include <vector> #include <vector>
@ -37,9 +38,10 @@ namespace mapnik {
class illegal_enum_value : public std::exception class illegal_enum_value : public std::exception
{ {
public: public:
illegal_enum_value() {} illegal_enum_value():
what_() {}
illegal_enum_value( const std::string & what ) : illegal_enum_value( std::string const& what ) :
what_( what ) what_( what )
{ {
} }
@ -72,7 +74,7 @@ protected:
* underscores (<i>_</i>) and dashes (<i>-</i>). * underscores (<i>_</i>) and dashes (<i>-</i>).
* *
* *
* @warning At the moment the verify() method is called during static initialization. * @warning At the moment the verify_mapnik_enum() method is called during static initialization.
* It quits the application with exit code 1 if any error is detected. The other solution * It quits the application with exit code 1 if any error is detected. The other solution
* i thought of is to do the checks at compile time (using boost::mpl). * i thought of is to do the checks at compile time (using boost::mpl).
* *
@ -138,21 +140,27 @@ template <class ENUM, int THE_MAX>
class MAPNIK_DECL enumeration { class MAPNIK_DECL enumeration {
public: public:
typedef ENUM native_type; typedef ENUM native_type;
enumeration() {};
enumeration( ENUM v ) : value_(v) {} enumeration()
enumeration( const enumeration & other ) : value_(other.value_) {} : value_() {}
enumeration( ENUM v )
: value_(v) {}
enumeration( const enumeration & other )
: value_(other.value_) {}
/** Assignment operator for native enum values. */ /** Assignment operator for native enum values. */
void operator=(ENUM v) void operator=(ENUM v)
{ {
value_ = v; value_ = v;
} }
/** Assignment operator. */ /** Assignment operator. */
void operator=(const enumeration & other) void operator=(const enumeration & other)
{ {
value_ = other.value_; value_ = other.value_;
} }
/** Conversion operator for native enum values. */ /** Conversion operator for native enum values. */
operator ENUM() const operator ENUM() const
@ -164,14 +172,16 @@ public:
{ {
MAX = THE_MAX MAX = THE_MAX
}; };
ENUM max() const ENUM max() const
{ {
return THE_MAX; return THE_MAX;
} }
/** Converts @p str to an enum. /** Converts @p str to an enum.
* @throw illegal_enum_value @p str is not a legal identifier. * @throw illegal_enum_value @p str is not a legal identifier.
* */ * */
void from_string(const std::string & str) void from_string(std::string const& str)
{ {
for (unsigned i = 0; i < THE_MAX; ++i) for (unsigned i = 0; i < THE_MAX; ++i)
{ {
@ -245,32 +255,36 @@ public:
/** Performs some simple checks and quits the application if /** Performs some simple checks and quits the application if
* any error is detected. Tries to print helpful error messages. * any error is detected. Tries to print helpful error messages.
*/ */
static bool verify(const char * filename, unsigned line_no) static bool verify_mapnik_enum(const char * filename, unsigned line_no)
{ {
for (unsigned i = 0; i < THE_MAX; ++i) for (unsigned i = 0; i < THE_MAX; ++i)
{ {
if (our_strings_[i] == 0 ) if (our_strings_[i] == 0 )
{ {
std::cerr << "### FATAL: Not enough strings for enum " MAPNIK_LOG_FATAL(enumeration)
<< our_name_ << " defined in file '" << filename << "### FATAL: Not enough strings for enum "
<< "' at line " << line_no << std::endl; << our_name_ << " defined in file '" << filename
<< "' at line " << line_no;
//std::exit(1); //std::exit(1);
} }
} }
if ( std::string("") != our_strings_[THE_MAX]) if ( std::string("") != our_strings_[THE_MAX])
{ {
std::cerr << "### FATAL: The string array for enum " << our_name_ MAPNIK_LOG_FATAL(enumeration)
<< " defined in file '" << filename << "' at line " << line_no << "### FATAL: The string array for enum " << our_name_
<< " has too many items or is not terminated with an " << " defined in file '" << filename << "' at line " << line_no
<< "empty string." << std::endl; << " has too many items or is not terminated with an "
<< "empty string";
//std::exit(1); //std::exit(1);
} }
return true; return true;
} }
static const std::string & get_full_qualified_name()
static std::string const& get_full_qualified_name()
{ {
return our_name_; return our_name_;
} }
static std::string get_name() static std::string get_name()
{ {
std::string::size_type idx = our_name_.find_last_of(":"); std::string::size_type idx = our_name_.find_last_of(":");
@ -281,6 +295,7 @@ public:
return our_name_.substr( idx + 1 ); return our_name_.substr( idx + 1 );
} }
} }
private: private:
ENUM value_; ENUM value_;
static const char ** our_strings_ ; static const char ** our_strings_ ;
@ -318,13 +333,13 @@ operator>>(std::istream & is, mapnik::enumeration<ENUM, THE_MAX> & e)
#define DEFINE_ENUM( name, e) \ #define DEFINE_ENUM( name, e) \
typedef enumeration<e, e ## _MAX> name typedef enumeration<e, e ## _MAX> name
/** Helper macro. Runs the verify() method during static initialization. /** Helper macro. Runs the verify_mapnik_enum() method during static initialization.
* @relates mapnik::enumeration * @relates mapnik::enumeration
*/ */
#define IMPLEMENT_ENUM( name, strings ) \ #define IMPLEMENT_ENUM( name, strings ) \
template <> const char ** name ::our_strings_ = strings; \ template <> const char ** name ::our_strings_ = strings; \
template <> std::string name ::our_name_ = #name; \ template <> std::string name ::our_name_ = #name; \
template <> bool name ::our_verified_flag_( name ::verify(__FILE__, __LINE__)); template <> bool name ::our_verified_flag_( name ::verify_mapnik_enum(__FILE__, __LINE__));
#endif // MAPNIK_ENUMERATION_HPP #endif // MAPNIK_ENUMERATION_HPP

View file

@ -26,7 +26,6 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/expression_node.hpp> #include <mapnik/expression_node.hpp>
#include <mapnik/expression_grammar.hpp>
// stl // stl
#include <string> #include <string>
@ -35,6 +34,7 @@ namespace mapnik
{ {
typedef boost::shared_ptr<expr_node> expression_ptr; typedef boost::shared_ptr<expr_node> expression_ptr;
template <typename Iterator> struct expression_grammar;
class expression_factory class expression_factory
{ {

View file

@ -229,7 +229,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
("\\\'", '\'')("\\\"", '\"') ("\\\'", '\'')("\\\"", '\"')
; ;
#if BOOST_VERSION > 104500 #if BOOST_VERSION > 104500
quote_char %= char_('\'') | char_('"'); quote_char %= char_('\'') | char_('"');
ustring %= omit[quote_char[_a = _1]] ustring %= omit[quote_char[_a = _1]]
@ -237,7 +237,7 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
>> lit(_a); >> lit(_a);
attr %= '[' >> no_skip[+~char_(']')] >> ']'; attr %= '[' >> no_skip[+~char_(']')] >> ']';
#else #else
ustring %= lit('\'') ustring %= lit('\'')
>> *(unesc_char | "\\x" >> hex | (char_ - lit('\''))) >> *(unesc_char | "\\x" >> hex | (char_ - lit('\'')))
>> lit('\''); >> lit('\'');
attr %= '[' >> lexeme[+(char_ - ']')] >> ']'; attr %= '[' >> lexeme[+(char_ - ']')] >> ']';

View file

@ -99,9 +99,11 @@ public:
feature_impl(context_ptr const& ctx, int id) feature_impl(context_ptr const& ctx, int id)
: id_(id), : id_(id),
ctx_(ctx), ctx_(ctx),
data_(ctx_->mapping_.size()) data_(ctx_->mapping_.size()),
{} geom_cont_(),
raster_()
{}
inline int id() const { return id_;} inline int id() const { return id_;}
@ -161,25 +163,25 @@ public:
{ {
context_type::map_type::const_iterator itr = ctx_->mapping_.find(key); context_type::map_type::const_iterator itr = ctx_->mapping_.find(key);
if (itr != ctx_->mapping_.end()) if (itr != ctx_->mapping_.end())
return get(itr->second); return get(itr->second);
else else
throw std::out_of_range(std::string("Key does not exist: '") + key + "'"); throw std::out_of_range(std::string("Key does not exist: '") + key + "'");
} }
value_type const& get(std::size_t index) const value_type const& get(std::size_t index) const
{ {
if (index < data_.size()) if (index < data_.size())
return data_[index]; return data_[index];
throw std::out_of_range("Index out of range"); throw std::out_of_range("Index out of range");
} }
boost::optional<value_type const&> get_optional(std::size_t index) const boost::optional<value_type const&> get_optional(std::size_t index) const
{ {
if (index < data_.size()) if (index < data_.size())
return boost::optional<value_type const&>(data_[index]); return boost::optional<value_type const&>(data_[index]);
return boost::optional<value_type const&>(); return boost::optional<value_type const&>();
} }
std::size_t size() const std::size_t size() const
{ {
return data_.size(); return data_.size();
@ -222,13 +224,14 @@ public:
box2d<double> envelope() const box2d<double> envelope() const
{ {
// TODO - cache this
box2d<double> result; box2d<double> result;
for (unsigned i=0;i<num_geometries();++i) for (unsigned i=0;i<num_geometries();++i)
{ {
geometry_type const& geom = get_geometry(i); geometry_type const& geom = get_geometry(i);
if (i==0) if (i==0)
{ {
box2d<double> box = geom.envelope(); box2d<double> const& box = geom.envelope();
result.init(box.minx(),box.miny(),box.maxx(),box.maxy()); result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
} }
else else
@ -271,7 +274,7 @@ public:
if (index < data_.size()) if (index < data_.size())
{ {
ss << " " << itr->first << ":" << data_[itr->second] << std::endl; ss << " " << itr->first << ":" << data_[itr->second] << std::endl;
} }
} }
ss << ")" << std::endl; ss << ")" << std::endl;
return ss.str(); return ss.str();
@ -280,9 +283,9 @@ public:
private: private:
int id_; int id_;
context_ptr ctx_; context_ptr ctx_;
cont_type data_;
boost::ptr_vector<geometry_type> geom_cont_; boost::ptr_vector<geometry_type> geom_cont_;
raster_ptr raster_; raster_ptr raster_;
cont_type data_;
}; };

View file

@ -24,12 +24,14 @@
#define MAPNIK_FONT_ENGINE_FREETYPE_HPP #define MAPNIK_FONT_ENGINE_FREETYPE_HPP
// mapnik // mapnik
#include <mapnik/debug.hpp>
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/utils.hpp> #include <mapnik/utils.hpp>
#include <mapnik/ctrans.hpp> #include <mapnik/ctrans.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/text_path.hpp>
#include <mapnik/font_set.hpp> #include <mapnik/font_set.hpp>
#include <mapnik/char_info.hpp>
#include <mapnik/pixel_position.hpp>
// freetype2 // freetype2
extern "C" extern "C"
@ -45,6 +47,7 @@ extern "C"
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <boost/foreach.hpp>
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#endif #endif
@ -56,9 +59,14 @@ extern "C"
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
// uci
#include <unicode/unistr.h>
namespace mapnik namespace mapnik
{ {
class font_face; class font_face;
class text_path;
class string_info;
typedef boost::shared_ptr<font_face> face_ptr; typedef boost::shared_ptr<font_face> face_ptr;
@ -131,10 +139,8 @@ public:
~font_face() ~font_face()
{ {
#ifdef MAPNIK_DEBUG MAPNIK_LOG_DEBUG(font_engine_freetype) << "font_face: Clean up face \"" << family_name() << " " << style_name() << "\"";
std::clog << "~font_face: Clean up face \"" << family_name()
<< " " << style_name() << "\"" << std::endl;
#endif
FT_Done_Face(face_); FT_Done_Face(face_);
} }
@ -146,7 +152,8 @@ class MAPNIK_DECL font_face_set : private boost::noncopyable
{ {
public: public:
font_face_set(void) font_face_set(void)
: faces_() {} : faces_(),
dimension_cache_() {}
void add(face_ptr face) void add(face_ptr face)
{ {
@ -161,11 +168,10 @@ public:
glyph_ptr get_glyph(unsigned c) const glyph_ptr get_glyph(unsigned c) const
{ {
for (std::vector<face_ptr>::const_iterator face = faces_.begin(); face != faces_.end(); ++face) BOOST_FOREACH ( face_ptr const& face, faces_)
{ {
FT_UInt g = (*face)->get_char(c); FT_UInt g = face->get_char(c);
if (g) return boost::make_shared<font_glyph>(face, g);
if (g) return boost::make_shared<font_glyph>(*face, g);
} }
// Final fallback to empty square if nothing better in any font // Final fallback to empty square if nothing better in any font
@ -178,17 +184,17 @@ public:
void set_pixel_sizes(unsigned size) void set_pixel_sizes(unsigned size)
{ {
for (std::vector<face_ptr>::iterator face = faces_.begin(); face != faces_.end(); ++face) BOOST_FOREACH ( face_ptr const& face, faces_)
{ {
(*face)->set_pixel_sizes(size); face->set_pixel_sizes(size);
} }
} }
void set_character_sizes(float size) void set_character_sizes(float size)
{ {
for (std::vector<face_ptr>::iterator face = faces_.begin(); face != faces_.end(); ++face) BOOST_FOREACH ( face_ptr const& face, faces_)
{ {
(*face)->set_character_sizes(size); face->set_character_sizes(size);
} }
} }
private: private:
@ -218,9 +224,8 @@ public:
~stroker() ~stroker()
{ {
#ifdef MAPNIK_DEBUG MAPNIK_LOG_DEBUG(font_engine_freetype) << "stroker: Destroy stroker=" << s_;
std::clog << "~stroker: destroy stroker:" << s_ << std::endl;
#endif
FT_Stroker_Done(s_); FT_Stroker_Done(s_);
} }
private: private:
@ -256,7 +261,7 @@ template <typename T>
class MAPNIK_DECL face_manager : private boost::noncopyable class MAPNIK_DECL face_manager : private boost::noncopyable
{ {
typedef T font_engine_type; typedef T font_engine_type;
typedef std::map<std::string,face_ptr> faces; typedef std::map<std::string,face_ptr> face_ptr_cache_type;
public: public:
face_manager(T & engine) face_manager(T & engine)
@ -265,9 +270,9 @@ public:
face_ptr get_face(std::string const& name) face_ptr get_face(std::string const& name)
{ {
typename faces::iterator itr; face_ptr_cache_type::iterator itr;
itr = faces_.find(name); itr = face_ptr_cache_.find(name);
if (itr != faces_.end()) if (itr != face_ptr_cache_.end())
{ {
return itr->second; return itr->second;
} }
@ -276,7 +281,7 @@ public:
face_ptr face = engine_.create_face(name); face_ptr face = engine_.create_face(name);
if (face) if (face)
{ {
faces_.insert(make_pair(name,face)); face_ptr_cache_.insert(make_pair(name,face));
} }
return face; return face;
} }
@ -301,10 +306,12 @@ public:
if (face_ptr face = get_face(*name)) if (face_ptr face = get_face(*name))
{ {
face_set->add(face); face_set->add(face);
} else { }
#ifdef MAPNIK_DEBUG else
std::cerr << "Failed to find face '" << *name << "' in font set '" << fset.get_name() << "'\n"; {
#endif MAPNIK_LOG_ERROR(font_engine_freetype)
<< "Failed to find face '" << *name
<< "' in font set '" << fset.get_name() << "'\n";
} }
} }
return face_set; return face_set;
@ -328,7 +335,7 @@ public:
} }
private: private:
faces faces_; face_ptr_cache_type face_ptr_cache_;
font_engine_type & engine_; font_engine_type & engine_;
stroker_ptr stroker_; stroker_ptr stroker_;
}; };

View file

@ -36,6 +36,7 @@ namespace mapnik {
typedef std::set<expression_ptr> expression_set; typedef std::set<expression_ptr> expression_set;
class processed_text; class processed_text;
class xml_node;
struct char_properties; struct char_properties;
namespace formatting { namespace formatting {
@ -48,7 +49,7 @@ class node
public: public:
virtual ~node() {} virtual ~node() {}
virtual void to_xml(boost::property_tree::ptree &xml) const; virtual void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(boost::property_tree::ptree const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const = 0; virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const = 0;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
}; };

View file

@ -31,7 +31,7 @@ namespace formatting {
class expression_format: public node { class expression_format: public node {
public: public:
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(boost::property_tree::ptree const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
@ -51,7 +51,7 @@ public:
private: private:
node_ptr child_; node_ptr child_;
static expression_ptr get_expression(boost::property_tree::ptree const& xml, std::string name); static expression_ptr get_expression(xml_node const& xml, std::string name);
}; };
} //ns formatting } //ns formatting
} //ns mapnik } //ns mapnik

View file

@ -31,7 +31,7 @@ namespace formatting {
class format_node: public node { class format_node: public node {
public: public:
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(boost::property_tree::ptree const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;

View file

@ -38,16 +38,16 @@ namespace mapnik
namespace formatting namespace formatting
{ {
typedef node_ptr (*from_xml_function_ptr)(boost::property_tree::ptree const& xml); typedef node_ptr (*from_xml_function_ptr)(xml_node const& xml);
class registry : public singleton<registry, CreateStatic>, class registry : public singleton<registry, CreateStatic>,
private boost::noncopyable private boost::noncopyable
{ {
public: public:
registry(); registry();
~registry() {} ~registry() {}
void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false); void register_name(std::string name, from_xml_function_ptr ptr, bool overwrite=false);
node_ptr from_xml(std::string name, boost::property_tree::ptree const& xml); node_ptr from_xml(xml_node const& xml);
private: private:
std::map<std::string, from_xml_function_ptr> map_; std::map<std::string, from_xml_function_ptr> map_;
}; };

View file

@ -31,7 +31,7 @@ public:
text_node(expression_ptr text): node(), text_(text) {} text_node(expression_ptr text): node(), text_(text) {}
text_node(std::string text): node(), text_(parse_expression(text)) {} text_node(std::string text): node(), text_(parse_expression(text)) {}
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(boost::property_tree::ptree const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const; virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef MAPNIK_GAMMA_METHOD_HPP #ifndef MAPNIK_GAMMA_METHOD_HPP
#define MAPNIK_GAMMA_METHOD_HPP #define MAPNIK_GAMMA_METHOD_HPP

View file

@ -390,7 +390,7 @@ public:
} }
return false; return false;
} }
}; };
typedef geometry<double,vertex_vector> geometry_type; typedef geometry<double,vertex_vector> geometry_type;

View file

@ -25,6 +25,7 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/image_data.hpp> #include <mapnik/image_data.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/grid/grid_view.hpp> #include <mapnik/grid/grid_view.hpp>
@ -72,7 +73,6 @@ private:
public: public:
hit_grid(int width, int height, std::string const& key, unsigned int resolution) hit_grid(int width, int height, std::string const& key, unsigned int resolution)
:width_(width), :width_(width),
height_(height), height_(height),
@ -136,7 +136,7 @@ public:
} }
else else
{ {
std::clog << "should not get here: key '" << key_ << "' not found in feature properties\n"; MAPNIK_LOG_DEBUG(grid) << "hit_grid: Should not get here: key '" << key_ << "' not found in feature properties";
} }
} }
@ -153,7 +153,7 @@ public:
} }
else else
{ {
std::clog << "### Warning: key '" << key_ << "' was blank for " << *feature << "\n"; MAPNIK_LOG_DEBUG(grid) << "hit_grid: Warning - key '" << key_ << "' was blank for " << *feature;
} }
} }

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef MAPNIK_GRID_RASTERIZER_HPP #ifndef MAPNIK_GRID_RASTERIZER_HPP
#define MAPNIK_GRID_RASTERIZER_HPP #define MAPNIK_GRID_RASTERIZER_HPP

View file

@ -20,8 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef GRID_RENDERER_HPP #ifndef GRID_RENDERER_HPP
#define GRID_RENDERER_HPP #define GRID_RENDERER_HPP
@ -32,7 +30,6 @@
#include <mapnik/label_collision_detector.hpp> #include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
//#include <mapnik/marker.hpp> //#include <mapnik/marker.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
// boost // boost
@ -63,7 +60,7 @@ public:
~grid_renderer(); ~grid_renderer();
void start_map_processing(Map const& map); void start_map_processing(Map const& map);
void end_map_processing(Map const& map); void end_map_processing(Map const& map);
void start_layer_processing(layer const& lay); void start_layer_processing(layer const& lay, box2d<double> const& query_extent);
void end_layer_processing(layer const& lay); void end_layer_processing(layer const& lay);
void render_marker(mapnik::feature_ptr const& feature, unsigned int step, pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity); void render_marker(mapnik::feature_ptr const& feature, unsigned int step, pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity);

View file

@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef MAPNIK_GRID_RENDERING_BUFFER_HPP #ifndef MAPNIK_GRID_RENDERING_BUFFER_HPP
#define MAPNIK_GRID_RENDERING_BUFFER_HPP #define MAPNIK_GRID_RENDERING_BUFFER_HPP

View file

@ -20,8 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef MAPNIK_GRID_VIEW_HPP #ifndef MAPNIK_GRID_VIEW_HPP
#define MAPNIK_GRID_VIEW_HPP #define MAPNIK_GRID_VIEW_HPP
@ -34,6 +32,7 @@
// boost // boost
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
// stl // stl
#include <map> #include <map>
#include <set> #include <set>

View file

@ -160,7 +160,7 @@ public:
~hextree() ~hextree()
{} {}
void setMaxColors(unsigned max_colors) void setMaxColors(unsigned max_colors)
{ {
max_colors_ = max_colors; max_colors_ = max_colors;
@ -335,7 +335,7 @@ public:
sorted_pal_.reserve(colors_); sorted_pal_.reserve(colors_);
create_palette_rek(sorted_pal_, root_.get()); create_palette_rek(sorted_pal_, root_.get());
// sort palette for binary searching in quantization // sort palette for binary searching in quantization
#if BOOST_VERSION >= 104600 #if BOOST_VERSION >= 104600
boost::sort(sorted_pal_, rgba::mean_sort_cmp()); boost::sort(sorted_pal_, rgba::mean_sort_cmp());

View file

@ -24,11 +24,6 @@
#define MAPNIK_IMAGE_COMPOSITING_HPP #define MAPNIK_IMAGE_COMPOSITING_HPP
// agg // agg
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h"
namespace mapnik namespace mapnik
{ {
@ -69,116 +64,7 @@ enum composite_mode_e
}; };
template <typename T1, typename T2> template <typename T1, typename T2>
void composite(T1 & im, T2 & im2, composite_mode_e mode) void composite(T1 & im, T2 & im2, composite_mode_e mode);
{
typedef agg::rgba8 color;
typedef agg::order_bgra order;
typedef agg::pixel32_type pixel_type;
typedef agg::comp_op_adaptor_rgba<color, order> blender_type;
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> renderer_type;
typedef agg::comp_op_adaptor_rgba<color, order> blender_type;
typedef agg::renderer_base<pixfmt_type> renderer_type;
agg::rendering_buffer source(im.getBytes(),im.width(),im.height(),im.width() * 4);
agg::rendering_buffer mask(im2.getBytes(),im2.width(),im2.height(),im2.width() * 4);
agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixf(source);
agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixf_mask(mask);
switch(mode)
{
case clear :
pixf.comp_op(agg::comp_op_clear);
break;
case src:
pixf.comp_op(agg::comp_op_src);
break;
case dst:
pixf.comp_op(agg::comp_op_dst);
break;
case src_over:
pixf.comp_op(agg::comp_op_src_over);
break;
case dst_over:
pixf.comp_op(agg::comp_op_dst_over);
break;
case src_in:
pixf.comp_op(agg::comp_op_src_in);
break;
case dst_in:
pixf.comp_op(agg::comp_op_dst_in);
break;
case src_out:
pixf.comp_op(agg::comp_op_src_out);
break;
case dst_out:
pixf.comp_op(agg::comp_op_dst_out);
break;
case src_atop:
pixf.comp_op(agg::comp_op_src_atop);
break;
case dst_atop:
pixf.comp_op(agg::comp_op_dst_atop);
break;
case _xor:
pixf.comp_op(agg::comp_op_xor);
break;
case plus:
pixf.comp_op(agg::comp_op_plus);
break;
case minus:
pixf.comp_op(agg::comp_op_minus);
break;
case multiply:
pixf.comp_op(agg::comp_op_multiply);
break;
case screen:
pixf.comp_op(agg::comp_op_screen);
break;
case overlay:
pixf.comp_op(agg::comp_op_overlay);
break;
case darken:
pixf.comp_op(agg::comp_op_darken);
break;
case lighten:
pixf.comp_op(agg::comp_op_lighten);
break;
case color_dodge:
pixf.comp_op(agg::comp_op_color_dodge);
break;
case color_burn:
pixf.comp_op(agg::comp_op_color_burn);
break;
case hard_light:
pixf.comp_op(agg::comp_op_hard_light);
break;
case soft_light:
pixf.comp_op(agg::comp_op_soft_light);
break;
case difference:
pixf.comp_op(agg::comp_op_difference);
break;
case exclusion:
pixf.comp_op(agg::comp_op_exclusion);
break;
case contrast:
pixf.comp_op(agg::comp_op_contrast);
break;
case invert:
pixf.comp_op(agg::comp_op_invert);
break;
case invert_rgb:
pixf.comp_op(agg::comp_op_invert_rgb);
break;
}
renderer_type ren(pixf);
agg::renderer_base<pixfmt_type> rb(pixf);
rb.blend_from(pixf_mask,0,0,0,255);
} }
}
#endif // MAPNIK_IMAGE_COMPOSITING_HPP #endif // MAPNIK_IMAGE_COMPOSITING_HPP

View file

@ -147,7 +147,7 @@ inline boost::optional<std::string> type_from_filename(std::string const& filena
return result_type(); return result_type();
} }
inline std::string guess_type( const std::string & filename ) inline std::string guess_type( std::string const& filename )
{ {
std::string::size_type idx = filename.find_last_of("."); std::string::size_type idx = filename.find_last_of(".");
if ( idx != std::string::npos ) { if ( idx != std::string::npos ) {

View file

@ -1,26 +1,34 @@
#ifndef DUMP_XML_HPP #ifndef DUMP_XML_HPP
#define DUMP_XML_HPP #define DUMP_XML_HPP
#include <boost/property_tree/ptree.hpp> #include <mapnik/xml_node.hpp>
/* Debug dump ptree XML representation. /* Debug dump ptree XML representation.
*/ */
void dump_xml(boost::property_tree::ptree const& xml, unsigned level=0) void dump_xml(xml_node const& xml, unsigned level=0)
{ {
std::string indent; std::string indent;
int i; unsigned i;
for (i=0; i<level; i++) for (i=0; i<level; i++)
{ {
indent += " "; indent += " ";
} }
if (xml.data().length()) std::cout << indent << "data: '" << xml.data() << "'\n"; xml_node::attribute_map const& attr = xml.get_attributes();
boost::property_tree::ptree::const_iterator itr = xml.begin(); std::cerr << indent <<"[" << xml.name();
boost::property_tree::ptree::const_iterator end = xml.end(); xml_node::attribute_map::const_iterator aitr = attr.begin();
xml_node::attribute_map::const_iterator aend = attr.end();
for (;aitr!=aend; aitr++)
{
std::cerr << " (" << aitr->first << ", " << aitr->second.value << ", " << aitr->second.processed << ")";
}
std::cerr << "]" << "\n";
if (xml.is_text()) std::cerr << indent << "text: '" << xml.text() << "'\n";
xml_node::const_iterator itr = xml.begin();
xml_node::const_iterator end = xml.end();
for (; itr!=end; itr++) for (; itr!=end; itr++)
{ {
std::cout << indent <<"[" << itr->first << "]" << "\n"; dump_xml(*itr, level+1);
dump_xml(itr->second, level+1);
std::cout << indent << "[/" << itr->first << "]" << "\n";
} }
std::cerr << indent << "[/" << xml.name() << "]" << "\n";
} }

View file

@ -266,12 +266,12 @@ struct feature_grammar :
// //
; ;
coordinates = eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)) coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)))
| eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)) | (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)))
| eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)) | (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)))
| eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1)) | (eps(_r2 == 4) > multipoint_coordinates(extract_geometry_(_r1)))
| eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)) | (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)))
| eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)) | (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)))
; ;
point_coordinates = eps[ _a = new_<geometry_type>(Point) ] point_coordinates = eps[ _a = new_<geometry_type>(Point) ]
@ -316,7 +316,7 @@ struct feature_grammar :
on_error<fail> on_error<fail>
( (
feature feature
, std::cerr , std::clog
<< phoenix::val("Error! Expecting ") << phoenix::val("Error! Expecting ")
<< _4 // what failed? << _4 // what failed?
<< phoenix::val(" here: \"") << phoenix::val(" here: \"")

View file

@ -20,8 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id$
#ifndef MAPNIK_JSON_GEOMETRY_GENERATOR_GRAMMAR_HPP #ifndef MAPNIK_JSON_GEOMETRY_GENERATOR_GRAMMAR_HPP
#define MAPNIK_JSON_GEOMETRY_GENERATOR_GRAMMAR_HPP #define MAPNIK_JSON_GEOMETRY_GENERATOR_GRAMMAR_HPP
@ -30,6 +28,7 @@
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/vertex_iterator.hpp> #include <mapnik/util/vertex_iterator.hpp>
#include <mapnik/util/container_adapter.hpp> #include <mapnik/util/container_adapter.hpp>
// boost // boost
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>

View file

@ -39,7 +39,7 @@ struct label_collision_detector
{ {
typedef std::vector<box2d<double> > label_placements; typedef std::vector<box2d<double> > label_placements;
bool has_plasement(box2d<double> const& box) bool has_placement(box2d<double> const& box)
{ {
label_placements::const_iterator itr=labels_.begin(); label_placements::const_iterator itr=labels_.begin();
for( ; itr !=labels_.end();++itr) for( ; itr !=labels_.end();++itr)
@ -134,7 +134,7 @@ public:
}; };
//quad tree based label collission detector so labels dont appear within a given distance //quad tree based label collision detector so labels dont appear within a given distance
class label_collision_detector4 : boost::noncopyable class label_collision_detector4 : boost::noncopyable
{ {
public: public:

View file

@ -88,44 +88,44 @@ public:
std::vector<std::string>& styles(); std::vector<std::string>& styles();
/*! /*!
* @param maxZoom The minimum zoom level to set * @param max_zoom The minimum zoom level to set
*/ */
void setMinZoom(double minZoom); void set_min_zoom(double min_zoom);
/*! /*!
* @param maxZoom The maximum zoom level to set * @param max_zoom The maximum zoom level to set
*/ */
void setMaxZoom(double maxZoom); void set_max_zoom(double max_zoom);
/*! /*!
* @return the minimum zoom level of the layer. * @return the minimum zoom level of the layer.
*/ */
double getMinZoom() const; double min_zoom() const;
/*! /*!
* @return the maximum zoom level of the layer. * @return the maximum zoom level of the layer.
*/ */
double getMaxZoom() const; double max_zoom() const;
/*! /*!
* @brief Set whether this layer is active and will be rendered. * @brief Set whether this layer is active and will be rendered.
*/ */
void setActive(bool active); void set_active(bool active);
/*! /*!
* @return whether this layer is active and will be rendered. * @return whether this layer is active and will be rendered.
*/ */
bool isActive() const; bool active() const;
/*! /*!
* @brief Set whether this layer is queryable. * @brief Set whether this layer is queryable.
*/ */
void setQueryable(bool queryable); void set_queryable(bool queryable);
/*! /*!
* @return whether this layer is queryable or not. * @return whether this layer is queryable or not.
*/ */
bool isQueryable() const; bool queryable() const;
/*! /*!
* @brief Get the visability for a specific scale. * @brief Get the visability for a specific scale.
@ -139,7 +139,7 @@ public:
* or * or
* scale < maxzoom + 1e-6 * scale < maxzoom + 1e-6
*/ */
bool isVisible(double scale) const; bool visible(double scale) const;
/*! /*!
* @param clear_cache Set whether this layer's labels are cached. * @param clear_cache Set whether this layer's labels are cached.
@ -195,8 +195,8 @@ private:
std::string name_; std::string name_;
std::string srs_; std::string srs_;
double minZoom_; double min_zoom_;
double maxZoom_; double max_zoom_;
bool active_; bool active_;
bool queryable_; bool queryable_;
bool clear_label_cache_; bool clear_label_cache_;

View file

@ -44,17 +44,20 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base
explicit line_symbolizer() explicit line_symbolizer()
: symbolizer_base(), : symbolizer_base(),
stroke_(), stroke_(),
rasterizer_p_(RASTERIZER_FULL) {} rasterizer_p_(RASTERIZER_FULL),
smooth_(0.0) {}
line_symbolizer(stroke const& stroke) line_symbolizer(stroke const& stroke)
: symbolizer_base(), : symbolizer_base(),
stroke_(stroke), stroke_(stroke),
rasterizer_p_(RASTERIZER_FULL) {} rasterizer_p_(RASTERIZER_FULL),
smooth_(0.0) {}
line_symbolizer(color const& pen,float width=1.0) line_symbolizer(color const& pen,float width=1.0)
: symbolizer_base(), : symbolizer_base(),
stroke_(pen,width), stroke_(pen,width),
rasterizer_p_(RASTERIZER_FULL) {} rasterizer_p_(RASTERIZER_FULL),
smooth_(0.0) {}
stroke const& get_stroke() const stroke const& get_stroke() const
{ {
@ -76,9 +79,20 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base
return rasterizer_p_; return rasterizer_p_;
} }
void set_smooth(double smooth)
{
smooth_ = smooth;
}
double smooth() const
{
return smooth_;
}
private: private:
stroke stroke_; stroke stroke_;
line_rasterizer_e rasterizer_p_; line_rasterizer_e rasterizer_p_;
double smooth_;
}; };
} }

View file

@ -25,6 +25,7 @@
// mapnik // mapnik
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/config.hpp> // for MAPNIK_DECL
// stl // stl
#include <string> #include <string>
@ -32,7 +33,7 @@
namespace mapnik namespace mapnik
{ {
MAPNIK_DECL void load_map(Map & map, std::string const& filename, bool strict = false); MAPNIK_DECL void load_map(Map & map, std::string const& filename, bool strict = false);
MAPNIK_DECL void load_map_string(Map & map, std::string const& str, bool strict = false, std::string const& base_path=""); MAPNIK_DECL void load_map_string(Map & map, std::string const& str, bool strict = false, std::string base_path="");
} }
#endif // MAPNIK_LOAD_MAP_HPP #endif // MAPNIK_LOAD_MAP_HPP

View file

@ -79,7 +79,6 @@ private:
box2d<double> current_extent_; box2d<double> current_extent_;
boost::optional<box2d<double> > maximum_extent_; boost::optional<box2d<double> > maximum_extent_;
std::string base_path_; std::string base_path_;
parameters extra_attr_;
parameters extra_params_; parameters extra_params_;
public: public:
@ -338,6 +337,10 @@ public:
*/ */
boost::optional<box2d<double> > const& maximum_extent() const; boost::optional<box2d<double> > const& maximum_extent() const;
/*! \brief Get the non-const map maximum extent as box2d<double>
*/
boost::optional<box2d<double> > & maximum_extent();
/*! \brief Get the map base path where paths should be relative to. /*! \brief Get the map base path where paths should be relative to.
*/ */
std::string const& base_path() const; std::string const& base_path() const;
@ -440,21 +443,6 @@ public:
*/ */
std::string get_metawriter_property(std::string name) const; std::string get_metawriter_property(std::string name) const;
/*!
* @brief Get extra valid attributes of the Map that are not true members
*/
parameters const& get_extra_attributes() const;
/*!
* @brief Get non-const extra valid attributes of the Map that are not true members
*/
parameters& get_extra_attributes();
/*!
* @brief Set extra attributes of the Map
*/
void set_extra_attributes(parameters& attr);
/*! /*!
* @brief Get extra, arbitrary Parameters attached to the Map * @brief Get extra, arbitrary Parameters attached to the Map
*/ */

View file

@ -49,6 +49,7 @@ struct MAPNIK_DECL mapped_memory_cache :
static boost::unordered_map<std::string,mapped_region_ptr> cache_; static boost::unordered_map<std::string,mapped_region_ptr> cache_;
static bool insert(std::string const& key, mapped_region_ptr); static bool insert(std::string const& key, mapped_region_ptr);
static boost::optional<mapped_region_ptr> find(std::string const& key, bool update_cache = false); static boost::optional<mapped_region_ptr> find(std::string const& key, bool update_cache = false);
static void clear();
}; };
} }

View file

@ -25,14 +25,7 @@
// mapnik // mapnik
#include <mapnik/utils.hpp> #include <mapnik/utils.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
// agg
#include "agg_path_storage.h"
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
@ -43,7 +36,7 @@
namespace mapnik namespace mapnik
{ {
using namespace mapnik::svg; class marker;
typedef boost::shared_ptr<marker> marker_ptr; typedef boost::shared_ptr<marker> marker_ptr;
@ -57,6 +50,7 @@ struct MAPNIK_DECL marker_cache :
static boost::unordered_map<std::string,marker_ptr> cache_; static boost::unordered_map<std::string,marker_ptr> cache_;
static bool insert(std::string const& key, marker_ptr); static bool insert(std::string const& key, marker_ptr);
static boost::optional<marker_ptr> find(std::string const& key, bool update_cache = false); static boost::optional<marker_ptr> find(std::string const& key, bool update_cache = false);
static void clear();
}; };
} }

View file

@ -56,6 +56,8 @@ public:
explicit markers_symbolizer(); explicit markers_symbolizer();
markers_symbolizer(path_expression_ptr filename); markers_symbolizer(path_expression_ptr filename);
markers_symbolizer(markers_symbolizer const& rhs); markers_symbolizer(markers_symbolizer const& rhs);
void set_ignore_placement(bool ignore_placement);
bool get_ignore_placement() const;
void set_allow_overlap(bool overlap); void set_allow_overlap(bool overlap);
bool get_allow_overlap() const; bool get_allow_overlap() const;
void set_spacing(double spacing); void set_spacing(double spacing);
@ -76,6 +78,7 @@ public:
marker_type_e get_marker_type() const; marker_type_e get_marker_type() const;
private: private:
bool ignore_placement_;
bool allow_overlap_; bool allow_overlap_;
color fill_; color fill_;
double spacing_; double spacing_;

View file

@ -24,6 +24,7 @@
#define MAPNIK_MEMORY_FEATURESET_HPP #define MAPNIK_MEMORY_FEATURESET_HPP
// mapnik // mapnik
#include <mapnik/debug.hpp>
#include <mapnik/memory_datasource.hpp> #include <mapnik/memory_datasource.hpp>
// boost // boost
@ -52,11 +53,12 @@ public:
{ {
while (pos_ != end_) while (pos_ != end_)
{ {
for (unsigned i=0; i<(*pos_)->num_geometries();++i) { for (unsigned i=0; i<(*pos_)->num_geometries();++i)
{
geometry_type & geom = (*pos_)->get_geometry(i); geometry_type & geom = (*pos_)->get_geometry(i);
#ifdef MAPNIK_DEBUG
std::clog << "bbox_=" << bbox_ << ", geom.envelope=" << geom.envelope() << "\n"; MAPNIK_LOG_DEBUG(memory_featureset) << "memory_featureset: BBox=" << bbox_ << ",Envelope=" << geom.envelope();
#endif
if (bbox_.intersects(geom.envelope())) if (bbox_.intersects(geom.envelope()))
{ {
return *pos_++; return *pos_++;

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