diff --git a/.gitignore b/.gitignore index 1da77f7c9..5d2536c3e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,8 @@ tests/data/sqlite/*index demo/c++/cairo-demo.pdf demo/c++/cairo-demo.png demo/c++/cairo-demo256.png +demo/c++/demo.tif demo/c++/demo.jpg demo/c++/demo.png demo/c++/demo256.png - +tests/cpp_tests/*-bin diff --git a/AUTHORS.md b/AUTHORS.md index 95563bce7..ebba1681f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,60 +2,60 @@ Mapnik is written by Artem Pavlenko with contributions from: -Andy Allen -AJ Ashton -Matt Amos -Lucio Asnaghi -Justin Bronn -Christopher Brown -Jon Burgess -Toby Collet -Robert Coup -Berteun Damman -Craig de Stigter -Jean-Francois Doyon -David Eastcott -Krzysztof Godlewski -Beau Gunderson -John Hague -Dominic Hargreaves -Aubrey Holland -Tom Hughes -Konstantin Käfer -Mak Kolybabi -Peter Körner -Hermann Kraus -Stella Laurenzo -David Leaver -Carlos López -Dennis Luxen -Tom MacWright -Michal Migurski -Andrii Mishkovskyi -Ben Moores -Dražen OdobaÅ¡ić -Cameron Patrick -Igor Podolskiy -Reid Priedhorsky -Brian Quinion -Marcin Rudowski -Christopher Schmidt -Andreas Schneider -Vincent Schut -Ehud Shabtai -David Siegel -Steve Singer -Paul Smith -Vince Spader -Philipp Spitzer -Dane Springmeyer -Dave Stubbs -River Tarnell -Oliver Tonnhofer -Alberto Valverde -Martijn van Oosterhout -Andreas Volz -Lennard voor den Dag -Shaun Walbridge -Nick Whitelegg -Leslie Wu +* Andy Allen +* AJ Ashton +* Matt Amos +* Lucio Asnaghi +* Justin Bronn +* Christopher Brown +* Jon Burgess +* Toby Collet +* Robert Coup +* Berteun Damman +* Craig de Stigter +* Jean-Francois Doyon +* David Eastcott +* Krzysztof Godlewski +* Beau Gunderson +* John Hague +* Dominic Hargreaves +* Aubrey Holland +* Tom Hughes +* Konstantin Käfer +* Mak Kolybabi +* Peter Körner +* Hermann Kraus +* Stella Laurenzo +* David Leaver +* Carlos López +* Dennis Luxen +* Tom MacWright +* Michal Migurski +* Andrii Mishkovskyi +* Ben Moores +* Dražen OdobaÅ¡ić +* Cameron Patrick +* Igor Podolskiy +* Reid Priedhorsky +* Brian Quinion +* Marcin Rudowski +* Christopher Schmidt +* Andreas Schneider +* Vincent Schut +* Ehud Shabtai +* David Siegel +* Steve Singer +* Paul Smith +* Vince Spader +* Philipp Spitzer +* Dane Springmeyer +* Dave Stubbs +* River Tarnell +* Oliver Tonnhofer +* Alberto Valverde +* Martijn van Oosterhout +* Andreas Volz +* Lennard voor den Dag +* Shaun Walbridge +* Nick Whitelegg +* Leslie Wu diff --git a/CHANGELOG.md b/CHANGELOG.md index 66bc71981..50e982d7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,27 @@ For a complete change history, see the SVN log. ## Mapnik 2.1.0 -- Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentially radii) +- PostGIS: Added 'simplify_geometries' option - will trigger ST_Simplify on geometries before returning to Mapnik (#1179) + +- Improved error feedback for invalid values passed to map.query_point + +- Fixed rendering of thin svg lines (#1129) + +- Improved logging/debugging system with release logs and file redirection (#937 and partially #986, #467) + +- 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) @@ -26,6 +46,41 @@ For a complete change history, see the SVN log. - Added support for justify-alignment=auto. This is the new default. (#1125) +## 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) diff --git a/Makefile b/Makefile index 624f1cb69..47761360c 100755 --- a/Makefile +++ b/Makefile @@ -18,9 +18,13 @@ uninstall: python scons/scons.py uninstall test: - @python tests/visual_tests/test.py - @tests/cpp_tests/font_registration_test - @tests/cpp_tests/params_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 pep8: @@ -30,6 +34,8 @@ pep8: @pep8 -r --select=W391 -q --filename=*.py `pwd`/tests/ | xargs gsed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' grind: - @valgrind --leak-check=full tests/cpp_tests/font_registration_test + @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 diff --git a/SConstruct b/SConstruct index c014b9bb5..d7c15f752 100644 --- a/SConstruct +++ b/SConstruct @@ -15,8 +15,6 @@ # 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 -# -# $Id$ import os @@ -98,7 +96,7 @@ PLUGINS = { # plugins with external dependencies 'rasterlite': {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'}, # todo: osm plugin does also depend on libxml2 (but there is a separate check for that) - 'osm': {'default':False,'path':None,'inc':'curl/curl.h','lib':'curl','lang':'C'}, + 'osm': {'default':True,'path':None,'inc':'curl/curl.h','lib':'curl','lang':'C'}, # plugins without external dependencies requiring CheckLibWithHeader... 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, @@ -244,7 +242,6 @@ else: LIBDIR_SCHEMA='lib' - def pretty_dep(dep): pretty = pretty_dep_names.get(dep) if pretty: @@ -325,7 +322,7 @@ opts.AddVariables( # Variables affecting rendering back-ends BoolVariable('RENDERING_STATS', 'Output rendering statistics during style processing', 'False'), - + BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'), BoolVariable('SVG_RENDERER', 'build support for native svg renderer', 'False'), @@ -345,7 +342,12 @@ opts.AddVariables( 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_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'), + ('DEFAULT_LOG_SEVERITY', 'The default severity of the logger (eg. "info", "debug", "warn", "error", "fatal", "none")', 'error'), + # Other variables BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'), ('SYSTEM_FONTS','Provide location for python bindings to register fonts (if given aborts installation of bundled DejaVu fonts)',''), @@ -359,7 +361,7 @@ opts.AddVariables( EnumVariable('THREADING','Set threading support','multi', ['multi','single']), EnumVariable('XMLPARSER','Set xml parser','libxml2', ['libxml2','ptree']), ('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('COLOR_PRINT', 'Print build status information in color', 'True'), BoolVariable('SAMPLE_INPUT_PLUGINS', 'Compile and install sample plugins', 'False'), @@ -810,6 +812,9 @@ int main() return False def boost_regex_has_icu(context): + if env['RUNTIME_LINK'] == 'static': + context.env.Append(LIBS='icui18n') + context.env.Append(LIBS='icudata') ret = context.TryRun(""" #include @@ -1160,7 +1165,7 @@ if not preconfigured: env.Append(CXXFLAGS = '-DBOOST_REGEX_HAS_ICU') else: env['SKIPPED_DEPS'].append('boost_regex_icu') - + env['REQUESTED_PLUGINS'] = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])] if len(env['REQUESTED_PLUGINS']): @@ -1408,10 +1413,40 @@ if not preconfigured: # Common debugging flags. # http://lists.fedoraproject.org/pipermail/devel/2010-November/144952.html debug_flags = '-g -fno-omit-frame-pointer -DDEBUG -DMAPNIK_DEBUG' - ndebug_flags = '-DNDEBUG' - - + + # Enable logging in debug mode (always) and release mode (when specified) + if env['DEFAULT_LOG_SEVERITY']: + severities = ['info', 'debug', 'warn', 'error', 'fatal', 'none'] + if env['DEFAULT_LOG_SEVERITY'] not in severities: + color_print(1,"Cannot set default logger severity to '%s', available options are 'info', 'debug', 'warn', 'error', 'fatal', 'none'." % env['DEFAULT_LOG_SEVERITY']) + Exit(1) + else: + log_severity = severities.index(env['DEFAULT_LOG_SEVERITY']) + else: + if env['DEBUG']: + log_severity = 1 # debug + else: + log_severity = 3 # error + + log_enabled = ' -DMAPNIK_LOG -DMAPNIK_DEFAULT_LOG_SEVERITY=%d' % log_severity + + 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' and env['CXX'] == 'g++': + env.MergeFlags('-rdynamic') + # Customizing the C++ compiler flags depending on: # (1) the C++ compiler used; and # (2) whether debug binaries are requested. @@ -1696,7 +1731,7 @@ if not HELP_REQUESTED: # devtools not ready for public #SConscript('utils/ogrindex/build.py') - #SConscript('utils/svg2png/build.py') + SConscript('utils/svg2png/build.py') env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND']) else : color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' won't be available") diff --git a/bindings/python/mapnik_color.cpp b/bindings/python/mapnik_color.cpp index 1b6e34fb2..82611ff48 100644 --- a/bindings/python/mapnik_color.cpp +++ b/bindings/python/mapnik_color.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_coord.cpp b/bindings/python/mapnik_coord.cpp index 103dad3f8..b9b4e6277 100644 --- a/bindings/python/mapnik_coord.cpp +++ b/bindings/python/mapnik_coord.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_datasource.cpp b/bindings/python/mapnik_datasource.cpp index d7b83040e..f89b4eb01 100644 --- a/bindings/python/mapnik_datasource.cpp +++ b/bindings/python/mapnik_datasource.cpp @@ -19,10 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ + // boost #include #include + // stl #include #include diff --git a/bindings/python/mapnik_datasource_cache.cpp b/bindings/python/mapnik_datasource_cache.cpp index 6b62b7129..c4381837b 100644 --- a/bindings/python/mapnik_datasource_cache.cpp +++ b/bindings/python/mapnik_datasource_cache.cpp @@ -20,8 +20,6 @@ * *****************************************************************************/ -//$Id$ - #include #include diff --git a/bindings/python/mapnik_envelope.cpp b/bindings/python/mapnik_envelope.cpp index 5aa35a0bf..099f319cc 100644 --- a/bindings/python/mapnik_envelope.cpp +++ b/bindings/python/mapnik_envelope.cpp @@ -19,7 +19,6 @@ * 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 #include diff --git a/bindings/python/mapnik_expression.cpp b/bindings/python/mapnik_expression.cpp index d95d5879b..b75281394 100644 --- a/bindings/python/mapnik_expression.cpp +++ b/bindings/python/mapnik_expression.cpp @@ -19,9 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include +#include + // mapnik #include #include @@ -30,7 +32,6 @@ #include #include -#include using mapnik::Feature; using mapnik::expression_ptr; diff --git a/bindings/python/mapnik_feature.cpp b/bindings/python/mapnik_feature.cpp index e55842e26..c4d7f75b6 100644 --- a/bindings/python/mapnik_feature.cpp +++ b/bindings/python/mapnik_feature.cpp @@ -19,13 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost - #include //#include - #include #include #include diff --git a/bindings/python/mapnik_featureset.cpp b/bindings/python/mapnik_featureset.cpp index c7f4722d3..21eb7b796 100644 --- a/bindings/python/mapnik_featureset.cpp +++ b/bindings/python/mapnik_featureset.cpp @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include + // mapnik #include #include diff --git a/bindings/python/mapnik_font_engine.cpp b/bindings/python/mapnik_font_engine.cpp index 1b2596e3c..5f4160756 100644 --- a/bindings/python/mapnik_font_engine.cpp +++ b/bindings/python/mapnik_font_engine.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include diff --git a/bindings/python/mapnik_geometry.cpp b/bindings/python/mapnik_geometry.cpp index 06aa96207..cd2506628 100644 --- a/bindings/python/mapnik_geometry.cpp +++ b/bindings/python/mapnik_geometry.cpp @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_grid.cpp b/bindings/python/mapnik_grid.cpp index 2cfce2b7b..95a20efaf 100644 --- a/bindings/python/mapnik_grid.cpp +++ b/bindings/python/mapnik_grid.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_grid_view.cpp b/bindings/python/mapnik_grid_view.cpp index bb39a5b88..926ee18f6 100644 --- a/bindings/python/mapnik_grid_view.cpp +++ b/bindings/python/mapnik_grid_view.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_image.cpp b/bindings/python/mapnik_image.cpp index b67af2b2e..42274ef65 100644 --- a/bindings/python/mapnik_image.cpp +++ b/bindings/python/mapnik_image.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ extern "C" { diff --git a/bindings/python/mapnik_image_view.cpp b/bindings/python/mapnik_image_view.cpp index 9e07a29e6..f3cf2e44f 100644 --- a/bindings/python/mapnik_image_view.cpp +++ b/bindings/python/mapnik_image_view.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ extern "C" { diff --git a/bindings/python/mapnik_inmem_metawriter.cpp b/bindings/python/mapnik_inmem_metawriter.cpp index 44ebbdd08..34760f45b 100644 --- a/bindings/python/mapnik_inmem_metawriter.cpp +++ b/bindings/python/mapnik_inmem_metawriter.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_layer.cpp b/bindings/python/mapnik_layer.cpp index 512d895b4..0b2e8d63b 100644 --- a/bindings/python/mapnik_layer.cpp +++ b/bindings/python/mapnik_layer.cpp @@ -19,8 +19,6 @@ * 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 #include diff --git a/bindings/python/mapnik_line_pattern_symbolizer.cpp b/bindings/python/mapnik_line_pattern_symbolizer.cpp index aae24bac0..e982edf05 100644 --- a/bindings/python/mapnik_line_pattern_symbolizer.cpp +++ b/bindings/python/mapnik_line_pattern_symbolizer.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include diff --git a/bindings/python/mapnik_line_symbolizer.cpp b/bindings/python/mapnik_line_symbolizer.cpp index 9c7053b90..93f96e693 100644 --- a/bindings/python/mapnik_line_symbolizer.cpp +++ b/bindings/python/mapnik_line_symbolizer.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include "mapnik_enumeration.hpp" diff --git a/bindings/python/mapnik_logger.cpp b/bindings/python/mapnik_logger.cpp new file mode 100644 index 000000000..257c6e510 --- /dev/null +++ b/bindings/python/mapnik_logger.cpp @@ -0,0 +1,79 @@ +/***************************************************************************** + * + * 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 +#include +#include +#include "mapnik_enumeration.hpp" + +void export_logger() +{ + using mapnik::logger; + using mapnik::singleton; + using mapnik::CreateStatic; + using namespace boost::python; + + class_,boost::noncopyable>("Singleton",no_init) + .def("instance",&singleton::instance, + return_value_policy()) + .staticmethod("instance") + ; + + enum_("severity_type") + .value("Info", logger::info) + .value("Debug", logger::debug) + .value("Warn", logger::warn) + .value("Error", logger::error) + .value("Fatal", logger::fatal) + .value("None", logger::none) + ; + + class_ >, + boost::noncopyable>("logger",no_init) + .def_readonly("Info", logger::info) + .def_readonly("Debug", logger::debug) + .def_readonly("Warn", logger::warn) + .def_readonly("Error", logger::error) + .def_readonly("Fatal", logger::fatal) + .def_readonly("None", logger::none) + .def("get_severity", &logger::get_severity) + .def("set_severity", &logger::set_severity) + .def("get_object_severity", &logger::get_object_severity) + .def("set_object_severity", &logger::set_object_severity) + .def("clear_object_severity", &logger::clear_object_severity) + .def("get_format", &logger::get_format) + .def("set_format", &logger::set_format) + .def("str", &logger::str) + .def("use_file", &logger::use_file) + .def("use_console", &logger::use_console) + .staticmethod("get_severity") + .staticmethod("set_severity") + .staticmethod("get_object_severity") + .staticmethod("set_object_severity") + .staticmethod("clear_object_severity") + .staticmethod("get_format") + .staticmethod("set_format") + .staticmethod("str") + .staticmethod("use_file") + .staticmethod("use_console") + ; +} diff --git a/bindings/python/mapnik_map.cpp b/bindings/python/mapnik_map.cpp index 542cc08f3..3bc1ca983 100644 --- a/bindings/python/mapnik_map.cpp +++ b/bindings/python/mapnik_map.cpp @@ -19,7 +19,6 @@ * 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 #include @@ -118,6 +117,7 @@ struct map_pickle_suite : boost::python::pickle_suite std::vector& (Map::*layers_nonconst)() = &Map::layers; std::vector const& (Map::*layers_const)() const = &Map::layers; mapnik::parameters& (Map::*params_nonconst)() = &Map::get_extra_parameters; +boost::optional > const& (Map::*maximum_extent_const)() const = &Map::maximum_extent; mapnik::feature_type_style find_style(mapnik::Map const& m, std::string const& name) { @@ -150,7 +150,7 @@ bool has_metawriter(mapnik::Map const& m) // returns empty shared_ptr when the metawriter isn't found, or is // of the wrong type. empty pointers make it back to Python as a None. -mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map &m, std::string const&name) { +mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) { mapnik::metawriter_ptr metawriter = m.find_metawriter(name); mapnik::metawriter_inmem_ptr inmem; @@ -192,6 +192,18 @@ mapnik::Map map_deepcopy(mapnik::Map & m, boost::python::dict memo) return result; } +// TODO - find a simplier way to set optional to uninitialized +void set_maximum_extent(mapnik::Map & m, boost::optional > const& box) +{ + if (box) + { + m.set_maximum_extent(*box); + } + else + { + m.maximum_extent().reset(); + } +} void export_map() { @@ -550,8 +562,8 @@ void export_map() ) .add_property("maximum_extent",make_function - (&Map::maximum_extent,return_value_policy()), - &Map::set_maximum_extent, + (maximum_extent_const,return_value_policy()), + &set_maximum_extent, "The maximum extent of the map.\n" "\n" "Usage:\n" diff --git a/bindings/python/mapnik_markers_symbolizer.cpp b/bindings/python/mapnik_markers_symbolizer.cpp index 17d860f11..aad93b7f7 100644 --- a/bindings/python/mapnik_markers_symbolizer.cpp +++ b/bindings/python/mapnik_markers_symbolizer.cpp @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include + #include #include #include @@ -124,5 +124,15 @@ void export_markers_symbolizer() &markers_symbolizer::get_height, &markers_symbolizer::set_height, "Set/get the marker height") + .add_property("fill", + make_function(&markers_symbolizer::get_fill, + return_value_policy()), + &markers_symbolizer::set_fill, + "Set/get the marker fill color") + .add_property("stroke", + make_function(&markers_symbolizer::get_stroke, + return_value_policy()), + &markers_symbolizer::set_stroke, + "Set/get the marker stroke (outline)") ; } diff --git a/bindings/python/mapnik_palette.cpp b/bindings/python/mapnik_palette.cpp index 4e6c39666..54b0b3146 100644 --- a/bindings/python/mapnik_palette.cpp +++ b/bindings/python/mapnik_palette.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_parameters.cpp b/bindings/python/mapnik_parameters.cpp index 5a015c0ae..e90487193 100644 --- a/bindings/python/mapnik_parameters.cpp +++ b/bindings/python/mapnik_parameters.cpp @@ -25,6 +25,7 @@ #include // mapnik +#include #include #include #include @@ -102,7 +103,7 @@ struct parameters_pickle_suite : boost::python::pickle_suite } else { - std::clog << "could not unpickle key: " << key << "\n"; + MAPNIK_LOG_DEBUG(bindings) << "parameters_pickle_suite: Could not unpickle key=" << key; } } } diff --git a/bindings/python/mapnik_point_symbolizer.cpp b/bindings/python/mapnik_point_symbolizer.cpp index ddd10bf41..2ca6c9acb 100644 --- a/bindings/python/mapnik_point_symbolizer.cpp +++ b/bindings/python/mapnik_point_symbolizer.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include "mapnik_enumeration.hpp" diff --git a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp index 6aee342b8..dc155c5f6 100644 --- a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include diff --git a/bindings/python/mapnik_polygon_symbolizer.cpp b/bindings/python/mapnik_polygon_symbolizer.cpp index dd809ac5d..06f35f0d8 100644 --- a/bindings/python/mapnik_polygon_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_symbolizer.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include "mapnik_enumeration.hpp" diff --git a/bindings/python/mapnik_proj_transform.cpp b/bindings/python/mapnik_proj_transform.cpp index ed5e7c9a0..7dec3b36b 100644 --- a/bindings/python/mapnik_proj_transform.cpp +++ b/bindings/python/mapnik_proj_transform.cpp @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // mapnik #include + // boost #include diff --git a/bindings/python/mapnik_projection.cpp b/bindings/python/mapnik_projection.cpp index f555ab11a..54fba845f 100644 --- a/bindings/python/mapnik_projection.cpp +++ b/bindings/python/mapnik_projection.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ -//boost +// boost #include // mapnik diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 4a4f5c4c9..6020d3b16 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -67,6 +67,7 @@ void export_view_transform(); void export_raster_colorizer(); void export_inmem_metawriter(); void export_label_collision_detector(); +void export_logger(); #include #include @@ -386,6 +387,7 @@ BOOST_PYTHON_MODULE(_mapnik) export_raster_colorizer(); export_inmem_metawriter(); export_label_collision_detector(); + export_logger(); def("render_grid",&render_grid, ( arg("map"), diff --git a/bindings/python/mapnik_query.cpp b/bindings/python/mapnik_query.cpp index 08133b17a..f2b5c368f 100644 --- a/bindings/python/mapnik_query.cpp +++ b/bindings/python/mapnik_query.cpp @@ -19,11 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include + +// mapnik #include #include + using mapnik::query; using mapnik::box2d; diff --git a/bindings/python/mapnik_raster_colorizer.cpp b/bindings/python/mapnik_raster_colorizer.cpp index 0aa43b3f2..7d9d6b755 100644 --- a/bindings/python/mapnik_raster_colorizer.cpp +++ b/bindings/python/mapnik_raster_colorizer.cpp @@ -19,10 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include #include + +// mapnik #include using mapnik::raster_colorizer; diff --git a/bindings/python/mapnik_raster_symbolizer.cpp b/bindings/python/mapnik_raster_symbolizer.cpp index 63a18b851..dacaea5de 100644 --- a/bindings/python/mapnik_raster_symbolizer.cpp +++ b/bindings/python/mapnik_raster_symbolizer.cpp @@ -19,9 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include + +// mapnik #include using mapnik::raster_symbolizer; diff --git a/bindings/python/mapnik_rule.cpp b/bindings/python/mapnik_rule.cpp index 528a87a63..378e22f10 100644 --- a/bindings/python/mapnik_rule.cpp +++ b/bindings/python/mapnik_rule.cpp @@ -19,13 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include #include #include #include +// mapnik #include #include #include diff --git a/bindings/python/mapnik_shield_symbolizer.cpp b/bindings/python/mapnik_shield_symbolizer.cpp index 41eff7536..28ae7083e 100644 --- a/bindings/python/mapnik_shield_symbolizer.cpp +++ b/bindings/python/mapnik_shield_symbolizer.cpp @@ -20,9 +20,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include + +// mapnik #include #include #include diff --git a/bindings/python/mapnik_stroke.cpp b/bindings/python/mapnik_stroke.cpp index a75f614c6..1f21071c3 100644 --- a/bindings/python/mapnik_stroke.cpp +++ b/bindings/python/mapnik_stroke.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/mapnik_style.cpp b/bindings/python/mapnik_style.cpp index 1ab130c04..9437e87d5 100644 --- a/bindings/python/mapnik_style.cpp +++ b/bindings/python/mapnik_style.cpp @@ -19,11 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include #include +// mapnik #include "mapnik_enumeration.hpp" #include diff --git a/bindings/python/mapnik_symbolizer.cpp b/bindings/python/mapnik_symbolizer.cpp index 625efe7a2..ec25d7ea7 100644 --- a/bindings/python/mapnik_symbolizer.cpp +++ b/bindings/python/mapnik_symbolizer.cpp @@ -19,10 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ +// boost #include +// mapnik //symbolizer typdef here rather than mapnik/symbolizer.hpp #include diff --git a/bindings/python/mapnik_view_transform.cpp b/bindings/python/mapnik_view_transform.cpp index 7a9da32d5..090e65f9c 100644 --- a/bindings/python/mapnik_view_transform.cpp +++ b/bindings/python/mapnik_view_transform.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ // boost #include diff --git a/bindings/python/python_cairo.cpp b/bindings/python/python_cairo.cpp index e5420c1b1..ee6c900c3 100644 --- a/bindings/python/python_cairo.cpp +++ b/bindings/python/python_cairo.cpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO) diff --git a/bindings/python/python_grid_utils.hpp b/bindings/python/python_grid_utils.hpp index 09b72573c..031adb46c 100644 --- a/bindings/python/python_grid_utils.hpp +++ b/bindings/python/python_grid_utils.hpp @@ -28,6 +28,7 @@ #include // mapnik +#include #include #include #include @@ -271,7 +272,7 @@ static void write_features(T const& grid_type, } 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"; } } } diff --git a/bindings/python/python_optional.hpp b/bindings/python/python_optional.hpp index 7707f0053..29c1990db 100644 --- a/bindings/python/python_optional.hpp +++ b/bindings/python/python_optional.hpp @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -//$Id$ #include #include diff --git a/demo/c++/Makefile b/demo/c++/Makefile index 09ba0378c..d30b71b40 100644 --- a/demo/c++/Makefile +++ b/demo/c++/Makefile @@ -1,5 +1,3 @@ -CXX = g++ - CXXFLAGS = $(shell mapnik-config --cflags) LDFLAGS = $(shell mapnik-config --libs --dep-libs --ldflags) diff --git a/demo/c++/build.py b/demo/c++/build.py index a9b87265c..9738347f9 100644 --- a/demo/c++/build.py +++ b/demo/c++/build.py @@ -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'])) -# we don't install this app because the datasource paths are relative -# and we're not going to install the sample data. -#env.Install(install_prefix + '/bin', rundemo) -#env.Alias('install', install_prefix + '/bin') +# build locally if installing +if 'install' in COMMAND_LINE_TARGETS: + env.Alias('install',rundemo) diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index cb6c26c90..eb22729e9 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -70,7 +70,7 @@ int main ( int argc , char** argv) provpoly_style.add_rule(provpoly_rule_on); 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_style.add_rule(provpoly_rule_qc); @@ -175,6 +175,7 @@ int main ( int argc , char** argv) parameters p; p["type"]="shape"; p["file"]="../data/boundaries"; + p["encoding"]="latin1"; layer lyr("Provinces"); lyr.set_datasource(datasource_cache::instance()->create(p)); diff --git a/include/mapnik/cairo_renderer.hpp b/include/mapnik/cairo_renderer.hpp index e0a3d53b5..bd09ac0a0 100644 --- a/include/mapnik/cairo_renderer.hpp +++ b/include/mapnik/cairo_renderer.hpp @@ -125,7 +125,7 @@ public: } 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_; Cairo::RefPtr context_; diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index f038eee47..6713fd39d 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -24,6 +24,7 @@ #define MAPNIK_CTRANS_HPP // mapnik +#include #include #include #include @@ -254,10 +255,10 @@ struct MAPNIK_DECL coord_transform_parallel angle_a = atan2((m_pre_y-m_cur_y),(m_pre_x-m_cur_x)); dx_pre = cos(angle_a + pi_by_2); dy_pre = sin(angle_a + pi_by_2); -#ifdef MAPNIK_DEBUG - std::clog << "offsetting line by: " << offset_ << "\n"; - std::clog << "initial dx=" << (dx_pre * offset_) << " dy=" << (dy_pre * offset_) << "\n"; -#endif + + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: Offsetting line by=" << offset_; + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: Initial dx=" << (dx_pre * offset_) << ",dy=" << (dy_pre * offset_); + *x = m_pre_x + (dx_pre * offset_); *y = m_pre_y + (dy_pre * offset_); m_status = process; @@ -304,15 +305,14 @@ struct MAPNIK_DECL coord_transform_parallel } else // skip sharp spikes { - -#ifdef MAPNIK_DEBUG +#ifdef MAPNIK_LOG dx_curr = cos(angle_a + pi_by_2); dy_curr = sin(angle_a + pi_by_2); sin_curve = dx_curr*dy_pre-dy_curr*dx_pre; - std::clog << "angle a: " << angle_a << "\n"; - std::clog << "angle b: " << angle_b << "\n"; - std::clog << "h: " << h << "\n"; - std::clog << "sin_curve: " << sin_curve << "\n"; + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: angle a=" << angle_a; + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: angle b=" << angle_b; + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: h=" << h; + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: sin_curve=" << sin_curve; #endif m_status = process; break; @@ -324,21 +324,19 @@ struct MAPNIK_DECL coord_transform_parallel sin_curve = dx_curr*dy_pre-dy_curr*dx_pre; cos_curve = -dx_pre*dx_curr-dy_pre*dy_curr; - #ifdef MAPNIK_DEBUG - std::clog << "sin_curve value: " << sin_curve << "\n"; - #endif + MAPNIK_LOG_DEBUG(ctrans) << "coord_transform_parallel: sin_curve value=" << sin_curve; if(sin_curve > -0.3 && sin_curve < 0.3) { - angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x)); - h = tan((angle_b - angle_a)/2.0); - *x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_); - *y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_); + angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x)); + h = tan((angle_b - angle_a)/2.0); + *x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_); + *y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_); } else { - if (angle_b - angle_a > 0) - h = -1.0*(1.0+cos_curve)/sin_curve; - else - h = (1.0+cos_curve)/sin_curve; - *x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_; - *y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_; + if (angle_b - angle_a > 0) + h = -1.0*(1.0+cos_curve)/sin_curve; + else + h = (1.0+cos_curve)/sin_curve; + *x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_; + *y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_; } */ diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index 5cfd1bde5..6ae828a94 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -45,25 +45,30 @@ typedef MAPNIK_DECL boost::shared_ptr feature_ptr; struct MAPNIK_DECL Featureset : private boost::noncopyable { - virtual feature_ptr next()=0; - virtual ~Featureset() {}; + virtual feature_ptr next() = 0; + virtual ~Featureset() {} }; typedef MAPNIK_DECL boost::shared_ptr featureset_ptr; class MAPNIK_DECL datasource_exception : public std::exception { -private: - std::string message_; public: - datasource_exception(const std::string& message=std::string("no reason")) - :message_(message) {} + datasource_exception(const std::string& message = std::string("no reason")) + : message_(message) + { + } + + ~datasource_exception() throw() + { + } - ~datasource_exception() throw() {} virtual const char* what() const throw() { return message_.c_str(); } +private: + std::string message_; }; class MAPNIK_DECL datasource : private boost::noncopyable @@ -82,9 +87,10 @@ public: }; datasource (parameters const& params) - : params_(params), + : params_(params), is_bound_(false) - {} + { + } /*! * @brief Get the configuration parameters of the data source. @@ -102,19 +108,19 @@ public: * @brief Get the type of the datasource * @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 */ - virtual void bind() const {}; + virtual void bind() const {} - virtual featureset_ptr features(const query& q) const=0; - virtual featureset_ptr features_at_point(coord2d const& pt) const=0; - virtual box2d envelope() const=0; - virtual boost::optional get_geometry_type() const=0; - virtual layer_descriptor get_descriptor() const=0; - virtual ~datasource() {}; + virtual featureset_ptr features(const query& q) const = 0; + virtual featureset_ptr features_at_point(coord2d const& pt) const = 0; + virtual box2d envelope() const = 0; + virtual boost::optional get_geometry_type() const = 0; + virtual layer_descriptor get_descriptor() const = 0; + virtual ~datasource() {} protected: parameters params_; mutable bool is_bound_; @@ -124,7 +130,6 @@ typedef std::string datasource_name(); typedef datasource* create_ds(const parameters& params, bool bind); typedef void destroy_ds(datasource *ds); - class datasource_deleter { public: @@ -136,7 +141,6 @@ public: typedef boost::shared_ptr datasource_ptr; - #define DATASOURCE_PLUGIN(classname) \ extern "C" MAPNIK_EXP std::string datasource_name() \ { \ @@ -149,8 +153,7 @@ typedef boost::shared_ptr datasource_ptr; extern "C" MAPNIK_EXP void destroy(datasource *ds) \ { \ delete ds; \ - } \ - // + } } diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp new file mode 100644 index 000000000..874c162b5 --- /dev/null +++ b/include/mapnik/debug.hpp @@ -0,0 +1,340 @@ +/***************************************************************************** + * + * 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 +#include + +// boost +#include +#include +#ifdef MAPNIK_THREADSAFE +#include +#endif + +// std +#include +#include +#include +#include +#include + + +namespace mapnik { + + /* + Global logger class that holds the configuration of severity, format + and file/console redirection. + */ + class MAPNIK_DECL logger : + public singleton, + private boost::noncopyable + { + public: + enum severity_type + { + info, + debug, + warn, + error, + fatal, + none + }; + + typedef boost::unordered_map severity_map; + + // global security level + static severity_type get_severity() + { + return severity_level_; + } + + static void set_severity(const severity_type& severity_level) + { +#ifdef MAPNIK_THREADSAFE + boost::mutex::scoped_lock lock(severity_mutex_); +#endif + + severity_level_ = severity_level; + } + + // per object security levels + static severity_type get_object_severity(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; + } + } + + static void set_object_severity(const std::string& object_name, + const severity_type& security_level) + { +#ifdef MAPNIK_THREADSAFE + boost::mutex::scoped_lock lock(severity_mutex_); +#endif + if (! object_name.empty()) + { + object_severity_level_[object_name] = security_level; + } + } + + static void clear_object_severity() + { +#ifdef MAPNIK_THREADSAFE + boost::mutex::scoped_lock lock(severity_mutex_); +#endif + + object_severity_level_.clear(); + } + + // format + static std::string get_format() + { + return format_; + } + + static void set_format(const std::string& format) + { +#ifdef MAPNIK_THREADSAFE + boost::mutex::scoped_lock lock(format_mutex_); +#endif + format_ = format; + } + + // interpolate the format string for output + static std::string str(); + + // output + static void use_file(const std::string& filepath); + static void use_console(); + + private: + static severity_type severity_level_; + static severity_map object_severity_level_; + static bool severity_env_check_; + + static std::string format_; + static bool format_env_check_; + + static std::ofstream file_output_; + static std::string file_name_; + static std::streambuf* saved_buf_; + +#ifdef MAPNIK_THREADSAFE + static boost::mutex severity_mutex_; + static boost::mutex format_mutex_; +#endif + }; + + + namespace detail { + + /* + Default sink, it regulates access to clog + */ + template + class clog_sink + { + public: + typedef std::basic_ostringstream stream_buffer; + + void operator()(const logger::severity_type& severity, const stream_buffer &s) + { +#ifdef MAPNIK_THREADSAFE + static boost::mutex mutex; + boost::mutex::scoped_lock lock(mutex); +#endif + std::clog << logger::str() << " " << s.str() << std::endl; + } + }; + + + /* + Base log class, should not log anything when no MAPNIK_LOG is defined + + This is used for info/debug/warn reporting that should not output + anything when not compiling for speed. + */ + template