This commit is contained in:
Dane Springmeyer 2012-03-27 18:56:52 -04:00
commit 9d1afbbfc6
293 changed files with 4114 additions and 2863 deletions

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,9 @@ 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) - Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentially radii)
- Removed PointDatasource - use more robust MemoryDatasource instead (#1032) - Removed PointDatasource - use more robust MemoryDatasource instead (#1032)
@ -26,11 +21,12 @@ 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.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 +115,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 +158,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 +197,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 +299,7 @@ Mapnik 0.7.0 Release
Mapnik 0.6.1 Release # Mapnik 0.6.1 Release
--------------------
(Packaged from r1247) (Packaged from r1247)
@ -390,8 +383,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,9 @@ uninstall:
python scons/scons.py uninstall python scons/scons.py uninstall
test: test:
@python tests/visual_tests/test.py
@tests/cpp_tests/font_registration_test
@tests/cpp_tests/params_test
@python tests/run_tests.py -q @python tests/run_tests.py -q
pep8: pep8:
@ -26,4 +29,7 @@ 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:
@valgrind --leak-check=full tests/cpp_tests/font_registration_test
.PHONY: clean reset uninstall test install .PHONY: clean reset uninstall test install

View file

@ -768,7 +768,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 +778,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("""
@ -1072,7 +1068,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 = [
@ -1382,14 +1378,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,7 +1406,9 @@ 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'
@ -1719,7 +1716,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

@ -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('.')
@ -598,112 +591,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',
'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

@ -42,6 +42,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

@ -54,7 +54,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 +72,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 +128,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 +149,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 +199,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 +214,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 +244,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

@ -62,5 +62,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

@ -117,11 +117,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;
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)
{ {
boost::optional<mapnik::feature_type_style const&> style = m.find_style(name); boost::optional<mapnik::feature_type_style const&> style = m.find_style(name);
@ -482,7 +479,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",

View file

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

@ -84,7 +84,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

@ -279,6 +279,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()
{ {
@ -573,6 +578,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

@ -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 {
@ -261,7 +261,7 @@ 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_) double scale_factor_)
: text_placement_info(parent, scale_factor_) : text_placement_info(parent, scale_factor_)
{ {
@ -329,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")
@ -339,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,
@ -357,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)
@ -381,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)
@ -407,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() */
@ -417,10 +418,10 @@ 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>()) 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)
@ -432,27 +433,27 @@ void export_text_placement()
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,
@ -462,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",
@ -476,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)
@ -499,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)
@ -510,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

@ -102,8 +102,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 +131,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

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

@ -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,7 +63,7 @@ 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);
@ -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,
@ -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

@ -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,31 +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);
what_() {} config_error(std::string const& what, xml_node const& node);
config_error(std::string const& what, unsigned line_number, std::string const& filename);
config_error( std::string const& what ) :
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(std::string const& 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

@ -72,16 +72,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 +115,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_;
}; };
@ -397,9 +397,9 @@ public:
sx_(1.0), sx_(1.0),
sy_(1.0) sy_(1.0)
{ {
if (extent_.width()) if (extent_.width() > 0)
sx_ = static_cast<double>(width_) / extent_.width(); sx_ = static_cast<double>(width_) / extent_.width();
if (extent_.height()) if (extent_.height() > 0)
sy_ = static_cast<double>(height_) / extent_.height(); sy_ = static_cast<double>(height_) / extent_.height();
} }

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

@ -99,11 +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_(), geom_cont_(),
raster_() raster_()
{} {}
inline int id() const { return id_;} inline int id() const { return id_;}
@ -224,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

View file

@ -46,6 +46,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
@ -153,7 +154,7 @@ class MAPNIK_DECL font_face_set : private boost::noncopyable
public: public:
font_face_set(void) font_face_set(void)
: faces_(), : faces_(),
dimension_cache_() {} dimension_cache_() {}
void add(face_ptr face) void add(face_ptr face)
{ {
@ -168,11 +169,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
@ -185,17 +185,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:
@ -263,7 +263,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)
@ -272,9 +272,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;
} }
@ -283,7 +283,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;
} }
@ -335,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

@ -63,7 +63,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

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

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

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

@ -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:
@ -440,21 +439,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

@ -30,6 +30,7 @@
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace mapnik { namespace mapnik {
class xml_node;
/** /**
* Creates a metawriter with the properties specified in the property * Creates a metawriter with the properties specified in the property
@ -37,7 +38,7 @@ namespace mapnik {
* metawriters, but should provide an easy point to make them a * metawriters, but should provide an easy point to make them a
* proper factory method if this is wanted in the future. * proper factory method if this is wanted in the future.
*/ */
metawriter_ptr metawriter_create(const boost::property_tree::ptree &pt); metawriter_ptr metawriter_create(xml_node const& pt);
/** /**
* Writes properties into the given property tree representing the * Writes properties into the given property tree representing the

View file

@ -26,7 +26,6 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/config_error.hpp>
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>

View file

@ -23,13 +23,20 @@
#ifndef MAPNIK_PLACEMENT_FINDER_HPP #ifndef MAPNIK_PLACEMENT_FINDER_HPP
#define MAPNIK_PLACEMENT_FINDER_HPP #define MAPNIK_PLACEMENT_FINDER_HPP
//mapnik // mapnik
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/text_properties.hpp> #include <mapnik/text_properties.hpp>
#include <mapnik/text_placements/base.hpp> #include <mapnik/text_placements/base.hpp>
#include <mapnik/symbolizer_helpers.hpp> #include <mapnik/symbolizer_helpers.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/ctrans.hpp>
//stl
// agg
#include "agg_conv_clip_polyline.h"
// stl
#include <queue> #include <queue>
namespace mapnik namespace mapnik
@ -39,6 +46,12 @@ class text_placement_info;
class string_info; class string_info;
class text_path; class text_path;
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> ClippedPathType;
typedef coord_transform2<CoordTransform,geometry_type> PathType;
typedef label_collision_detector4 DetectorType;
template <typename DetectorT> template <typename DetectorT>
class placement_finder : boost::noncopyable class placement_finder : boost::noncopyable
@ -124,19 +137,20 @@ private:
text_symbolizer_properties const& p; text_symbolizer_properties const& p;
text_placement_info const& pi; text_placement_info const& pi;
/** Length of the longest line after linebreaks. /** Length of the longest line after linebreaks.
* Before find_line_breaks() this is the total length of the string. * Before find_line_breaks() this is the total length of the string.
*/ */
double string_width_; double string_width_;
/** Height of the string after linebreaks. /** Height of the string after linebreaks.
* Before find_line_breaks() this is the total length of the string. * Before find_line_breaks() this is the total length of the string.
*/ */
double string_height_; double string_height_;
/** Height of the tallest font in the first line not including line spacing. /** Height of the tallest font in the first line not including line spacing.
* Used to determine the correct offset for the first line. * Used to determine the correct offset for the first line.
*/ */
double first_line_space_; double first_line_space_;
vertical_alignment_e valign_; vertical_alignment_e valign_;
horizontal_alignment_e halign_; horizontal_alignment_e halign_;
justify_alignment_e jalign_;
std::vector<unsigned> line_breaks_; std::vector<unsigned> line_breaks_;
std::vector<std::pair<double, double> > line_sizes_; std::vector<std::pair<double, double> > line_sizes_;
std::queue< box2d<double> > envelopes_; std::queue< box2d<double> > envelopes_;

View file

@ -35,7 +35,7 @@ namespace mapnik
struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base
{ {
polygon_symbolizer(); polygon_symbolizer();
polygon_symbolizer(color const& fill); explicit polygon_symbolizer(color const& fill);
color const& get_fill() const; color const& get_fill() const;
void set_fill(color const& fill); void set_fill(color const& fill);
void set_opacity(double opacity); void set_opacity(double opacity);
@ -44,12 +44,14 @@ struct MAPNIK_DECL polygon_symbolizer : public symbolizer_base
double get_gamma() const; double get_gamma() const;
void set_gamma_method(gamma_method_e gamma_method); void set_gamma_method(gamma_method_e gamma_method);
gamma_method_e get_gamma_method() const; gamma_method_e get_gamma_method() const;
void set_smooth(double smooth);
double smooth() const;
private: private:
color fill_; color fill_;
double opacity_; double opacity_;
double gamma_; double gamma_;
gamma_method_e gamma_method_; gamma_method_e gamma_method_;
double smooth_;
}; };
} }

View file

@ -23,450 +23,17 @@
#ifndef MAPNIK_PTREE_HELPERS_HPP #ifndef MAPNIK_PTREE_HELPERS_HPP
#define MAPNIK_PTREE_HELPERS_HPP #define MAPNIK_PTREE_HELPERS_HPP
// mapnik
#include <mapnik/enumeration.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/util/conversions.hpp>
// boost // boost
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/optional.hpp>
#include <boost/lexical_cast.hpp>
// stl
#include <iostream>
#include <sstream>
namespace mapnik { namespace mapnik {
template <typename T>
inline boost::optional<T> fast_cast(std::string const& value);
template <typename T>
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute,
T const& default_value);
template <typename T>
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute);
template <typename T>
T get_value(boost::property_tree::ptree const& node, std::string const& name);
template <typename T>
boost::optional<T> get_optional(boost::property_tree::ptree const& node, std::string const& name,
bool is_attribute);
template <typename T>
boost::optional<T> get_opt_attr( boost::property_tree::ptree const& node,
std::string const& name)
{
return get_optional<T>( node, name, true);
}
template <typename T>
boost::optional<T> get_opt_child( boost::property_tree::ptree const& node,
std::string const& name)
{
return get_optional<T>( node, name, false);
}
template <typename T>
T get_attr( boost::property_tree::ptree const& node, std::string const& name,
T const& default_value )
{
return get<T>( node, name, true, default_value);
}
template <typename T>
T get_attr( boost::property_tree::ptree const& node, std::string const& name )
{
return get<T>( node, name, true );
}
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;
}
/** 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;
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;
}
template <typename T> template <typename T>
void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v) void set_attr(boost::property_tree::ptree & pt, std::string const& name, T const& v)
{ {
pt.put("<xmlattr>." + name, v); pt.put("<xmlattr>." + name, v);
} }
class boolean;
template <typename T>
struct name_trait
{
static std::string name()
{
return "<unknown>";
}
// missing name_trait for type ...
// if you get here you are probably using a new type
// in the XML file. Just add a name trait for the new
// type below.
BOOST_STATIC_ASSERT( sizeof(T) == 0 );
};
#define DEFINE_NAME_TRAIT( type, type_name ) \
template <> \
struct name_trait<type> \
{ \
static std::string name() { return std::string("type ") + type_name; } \
};
DEFINE_NAME_TRAIT( double, "double")
DEFINE_NAME_TRAIT( float, "float")
DEFINE_NAME_TRAIT( unsigned, "unsigned")
DEFINE_NAME_TRAIT( boolean, "boolean")
DEFINE_NAME_TRAIT( int, "integer" )
DEFINE_NAME_TRAIT( std::string, "string" )
DEFINE_NAME_TRAIT( color, "color" )
template <typename ENUM, int MAX>
struct name_trait< mapnik::enumeration<ENUM, MAX> >
{
typedef enumeration<ENUM, MAX> Enum;
static std::string name()
{
std::string value_list("one of [");
for (unsigned i = 0; i < Enum::MAX; ++i)
{
value_list += Enum::get_string( i );
if ( i + 1 < Enum::MAX ) value_list += ", ";
}
value_list += "]";
return value_list;
}
};
template <typename T>
inline boost::optional<T> fast_cast(std::string const& value)
{
try
{
return boost::lexical_cast<T>( value );
}
catch (boost::bad_lexical_cast const& ex)
{
return boost::optional<T>();
}
}
template <>
inline boost::optional<int> fast_cast(std::string const& value)
{
int result;
if (mapnik::conversions::string2int(value,result))
return boost::optional<int>(result);
return boost::optional<int>();
}
template <>
inline boost::optional<double> fast_cast(std::string const& value)
{
double result;
if (mapnik::conversions::string2double(value,result))
return boost::optional<double>(result);
return boost::optional<double>();
}
template <>
inline boost::optional<float> fast_cast(std::string const& value)
{
float result;
if (mapnik::conversions::string2float(value,result))
return boost::optional<float>(result);
return boost::optional<float>();
}
template <typename T>
T get(boost::property_tree::ptree const& node,
std::string const& name,
bool is_attribute,
T const& default_value)
{
boost::optional<std::string> str;
if (is_attribute)
{
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name );
}
else
{
str = node.get_optional<std::string>(name + ".<xmltext>");
}
if ( str )
{
boost::optional<T> result = fast_cast<T>(*str);
if (result)
{
return *result;
}
else
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
name + "'. Expected " + name_trait<T>::name() +
" but got '" + *str + "'");
}
}
else
{
return default_value;
}
}
template <>
inline color get(boost::property_tree::ptree const& node,
std::string const& name,
bool is_attribute,
color const& default_value)
{
boost::optional<std::string> str;
if (is_attribute)
{
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name );
}
else
{
str = node.get_optional<std::string>(name + ".<xmltext>");
}
if ( str )
{
try
{
return mapnik::color_factory::from_string((*str).c_str());
}
catch (...)
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
name + "'. Expected " + name_trait<color>::name() +
" but got '" + *str + "'");
}
}
else
{
return default_value;
}
}
template <typename T>
T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute)
{
boost::optional<std::string> str;
if (is_attribute)
{
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
}
else
{
str = node.get_optional<std::string>(name + ".<xmltext>");
}
if ( ! str )
{
throw config_error(std::string("Required ") +
(is_attribute ? "attribute " : "child node ") +
"'" + name + "' is missing");
}
boost::optional<T> result = fast_cast<T>(*str);
if (result)
{
return *result;
}
else
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
name + "'. Expected " + name_trait<T>::name() +
" but got '" + *str + "'");
}
}
template <typename T>
T get_value(boost::property_tree::ptree const& node, std::string const& name)
{
try
{
/* NOTE: get_child works as long as there is only one child with that name.
If this function is used this used this condition must always be satisfied.
*/
return node.get_child("<xmltext>").get_value<T>();
}
catch (boost::property_tree::ptree_bad_path)
{
/* If the XML parser did not find any non-empty data element the is no
<xmltext> node. But we don't want to fail here but simply return a
default constructed value of the requested type.
*/
return T();
}
catch (...)
{
throw config_error(std::string("Failed to parse ") +
name + ". Expected " + name_trait<T>::name() +
" but got '" + node.data() + "'");
}
}
template <typename T>
boost::optional<T> get_optional(boost::property_tree::ptree const& node,
std::string const& name,
bool is_attribute)
{
boost::optional<std::string> str;
if (is_attribute)
{
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
}
else
{
str = node.get_optional<std::string>(name + ".<xmltext>");
}
boost::optional<T> result;
if ( str )
{
result = fast_cast<T>(*str);
if (!result)
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
name + "'. Expected " + name_trait<T>::name() +
" but got '" + *str + "'");
}
}
return result;
}
template <>
inline boost::optional<std::string> get_optional(boost::property_tree::ptree const& node,
std::string const& name,
bool is_attribute)
{
if (is_attribute)
{
return node.get_optional<std::string>( std::string("<xmlattr>.") + name);
}
else
{
return node.get_optional<std::string>(name + ".<xmltext>");
}
}
template <>
inline boost::optional<color> get_optional(boost::property_tree::ptree const& node,
std::string const& name,
bool is_attribute)
{
boost::optional<std::string> str;
if (is_attribute)
{
str = node.get_optional<std::string>( std::string("<xmlattr>.") + name);
}
else
{
str = node.get_optional<std::string>(name + ".<xmltext>");
}
boost::optional<color> result;
if ( str )
{
try
{
result = mapnik::color_factory::from_string((*str).c_str());
}
catch (...)
{
throw config_error(std::string("Failed to parse ") +
(is_attribute ? "attribute" : "child node") + " '" +
name + "'. Expected " + name_trait<color>::name() +
" but got '" + *str + "'");
}
}
return result;
}
static inline bool has_child(boost::property_tree::ptree const& node, std::string const& name)
{
boost::optional<std::string> str = node.get_optional<std::string>(name);
return str;
}
} // end of namespace mapnik } // end of namespace mapnik
#endif // MAPNIK_PTREE_HELPERS_HPP #endif // MAPNIK_PTREE_HELPERS_HPP

View file

@ -39,7 +39,6 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/enumeration.hpp> #include <mapnik/enumeration.hpp>

View file

@ -55,7 +55,8 @@ public:
double scale_factor, double scale_factor,
CoordTransform const& t, CoordTransform const& t,
FaceManagerT &font_manager, FaceManagerT &font_manager,
DetectorT &detector) DetectorT &detector,
box2d<double> const& query_extent)
: sym_(sym), : sym_(sym),
feature_(feature), feature_(feature),
prj_trans_(prj_trans), prj_trans_(prj_trans),
@ -64,6 +65,7 @@ public:
detector_(detector), detector_(detector),
writer_(sym.get_metawriter()), writer_(sym.get_metawriter()),
dims_(0, 0, width, height), dims_(0, 0, width, height),
query_extent_(query_extent),
text_(font_manager, scale_factor), text_(font_manager, scale_factor),
angle_(0.0), angle_(0.0),
placement_valid_(false), placement_valid_(false),
@ -100,7 +102,7 @@ protected:
DetectorT & detector_; DetectorT & detector_;
metawriter_with_properties writer_; metawriter_with_properties writer_;
box2d<double> dims_; box2d<double> dims_;
box2d<double> const& query_extent_;
//Processing //Processing
processed_text text_; processed_text text_;
/* Using list instead of vector, because we delete random elements and need iterators to stay valid. */ /* Using list instead of vector, because we delete random elements and need iterators to stay valid. */
@ -137,10 +139,11 @@ public:
unsigned width, unsigned width,
unsigned height, unsigned height,
double scale_factor, double scale_factor,
CoordTransform const& t, CoordTransform const &t,
FaceManagerT & font_manager, FaceManagerT &font_manager,
DetectorT & detector) : DetectorT &detector,
text_symbolizer_helper<FaceManagerT, DetectorT>(sym, feature, prj_trans, width, height, scale_factor, t, font_manager, detector), box2d<double> const& query_extent) :
text_symbolizer_helper<FaceManagerT, DetectorT>(sym, feature, prj_trans, width, height, scale_factor, t, font_manager, detector, query_extent),
sym_(sym) sym_(sym)
{ {
this->points_on_line_ = true; this->points_on_line_ = true;

View file

@ -38,7 +38,7 @@ public:
text_symbolizer_properties & add(); text_symbolizer_properties & add();
text_symbolizer_properties & get(unsigned i); text_symbolizer_properties & get(unsigned i);
unsigned size() const; unsigned size() const;
static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets); static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets);
private: private:
std::vector<text_symbolizer_properties> list_; std::vector<text_symbolizer_properties> list_;
friend class text_placement_info_list; friend class text_placement_info_list;

View file

@ -39,17 +39,17 @@ namespace placements
{ {
typedef text_placements_ptr (*from_xml_function_ptr)( typedef text_placements_ptr (*from_xml_function_ptr)(
boost::property_tree::ptree const& xml, fontset_map const & fontsets); xml_node const& xml, fontset_map const & fontsets);
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);
text_placements_ptr from_xml(std::string name, text_placements_ptr from_xml(std::string name,
boost::property_tree::ptree const& xml, xml_node const& xml,
fontset_map const & fontsets); fontset_map const & fontsets);
private: private:
std::map<std::string, from_xml_function_ptr> map_; std::map<std::string, from_xml_function_ptr> map_;

View file

@ -52,7 +52,7 @@ public:
text_placement_info_ptr get_placement_info(double scale_factor) const; text_placement_info_ptr get_placement_info(double scale_factor) const;
void set_positions(std::string positions); void set_positions(std::string positions);
std::string get_positions(); std::string get_positions();
static text_placements_ptr from_xml(boost::property_tree::ptree const &xml, fontset_map const & fontsets); static text_placements_ptr from_xml(xml_node const &xml, fontset_map const & fontsets);
private: private:
std::string positions_; std::string positions_;
std::vector<directions_t> direction_; std::vector<directions_t> direction_;

View file

@ -54,7 +54,7 @@ struct char_properties
{ {
char_properties(); char_properties();
/** Construct object from XML. */ /** Construct object from XML. */
void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets); void from_xml(xml_node const &sym, fontset_map const & fontsets);
/** Write object to XML ptree. */ /** Write object to XML ptree. */
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const; void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
std::string face_name; std::string face_name;
@ -110,6 +110,7 @@ enum justify_alignment
J_LEFT = 0, J_LEFT = 0,
J_MIDDLE, J_MIDDLE,
J_RIGHT, J_RIGHT,
J_AUTO,
justify_alignment_MAX justify_alignment_MAX
}; };
@ -124,7 +125,7 @@ struct text_symbolizer_properties
{ {
text_symbolizer_properties(); text_symbolizer_properties();
/** Load all values from XML ptree. */ /** Load all values from XML ptree. */
void from_xml(boost::property_tree::ptree const &sym, fontset_map const & fontsets); void from_xml(xml_node const &sym, fontset_map const & fontsets);
/** Save all values to XML ptree (but does not create a new parent node!). */ /** Save all values to XML ptree (but does not create a new parent node!). */
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const; void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;

View file

@ -20,26 +20,25 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef MAPNIK_CONVERSIONS_UTIL_HPP #ifndef MAPNIK_UTIL_CONVERSIONS_HPP
#define MAPNIK_CONVERSIONS_UTIL_HPP #define MAPNIK_UTIL_CONVERSIONS_HPP
// mapnik // mapnik
// stl // stl
#include <string> #include <string>
namespace mapnik { namespace conversions { namespace mapnik { namespace util {
bool string2int(const char * value, int & result); bool string2int(const char * value, int & result);
bool string2int(std::string const& value, int & result); bool string2int(std::string const& value, int & result);
bool string2double(std::string const& value, double & result); bool string2double(std::string const& value, double & result);
bool string2double(const char * value, double & result); bool string2double(const char * value, double & result);
bool string2float(std::string const& value, float & result); bool string2float(std::string const& value, float & result);
bool string2float(const char * value, float & result); bool string2float(const char * value, float & result);
} }}
}
#endif // MAPNIK_CONVERSIONS_UTIL_HPP #endif // MAPNIK_UTIL_CONVERSIONS_HPP

View file

@ -0,0 +1,69 @@
/*****************************************************************************
*
* 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_UTIL_DASHARRAY_PARSER_HPP
#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace mapnik { namespace util {
template <typename Iterator>
bool parse_dasharray(Iterator first, Iterator last, std::vector<double>& dasharray)
{
using qi::double_;
using qi::phrase_parse;
using qi::_1;
using qi::lit;
using qi::char_;
#if BOOST_VERSION > 104200
using qi::no_skip;
#else
using qi::lexeme;
#endif
using phoenix::push_back;
// SVG
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
// no support for 'percentage' as viewport is unknown at load_map
//
bool r = phrase_parse(first, last,
(double_[push_back(phoenix::ref(dasharray), _1)] %
#if BOOST_VERSION > 104200
no_skip[char_(", ")]
#else
lexeme[char_(", ")]
#endif
| lit("none")),
qi::ascii::space);
if (first != last)
return false;
return r;
}
}}
#endif // MAPNIK_UTIL_DASHARRAY_PARSER_HPP

View file

@ -26,7 +26,6 @@
// mapnik // mapnik
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
// boost // boost
#include <boost/variant.hpp> #include <boost/variant.hpp>

View file

@ -23,6 +23,28 @@
#ifndef MAPNIK_VERSION_HPP #ifndef MAPNIK_VERSION_HPP
#define MAPNIK_VERSION_HPP #define MAPNIK_VERSION_HPP
#define MAPNIK_VERSION 200000 #define MAPNIK_VERSION_IS_RELEASE 0
#define MAPNIK_MAJOR_VERSION 2
#define MAPNIK_MINOR_VERSION 1
#define MAPNIK_PATCH_VERSION 0
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
#ifndef MAPNIK_STRINGIFY
#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n)
#define MAPNIK_STRINGIFY_HELPER(n) #n
#endif
#if MAPNIK_VERSION_IS_RELEASE
# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION)
#else
# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \
MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION) "-pre"
#endif
#endif // MAPNIK_VERSION_HPP #endif // MAPNIK_VERSION_HPP

View file

@ -23,16 +23,14 @@
#ifndef MAPNIK_LIBXML2_LOADER_HPP #ifndef MAPNIK_LIBXML2_LOADER_HPP
#define MAPNIK_LIBXML2_LOADER_HPP #define MAPNIK_LIBXML2_LOADER_HPP
// boost
#include <boost/property_tree/ptree.hpp>
// stl // stl
#include <string> #include <string>
namespace mapnik namespace mapnik
{ {
void read_xml2( std::string const & filename, boost::property_tree::ptree & pt); class xml_node;
void read_xml2_string( std::string const & str, boost::property_tree::ptree & pt, std::string const & base_path=""); void read_xml(std::string const & filename, xml_node &node);
void read_xml_string(std::string const & str, xml_node &node, std::string const & base_path="");
} }
#endif // MAPNIK_LIBXML2_LOADER_HPP #endif // MAPNIK_LIBXML2_LOADER_HPP

137
include/mapnik/xml_node.hpp Normal file
View file

@ -0,0 +1,137 @@
/*****************************************************************************
*
* 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_XML_NODE_H
#define MAPNIK_XML_NODE_H
//mapnik
#include <mapnik/boolean.hpp>
//boost
#include <boost/optional.hpp>
//stl
#include <list>
#include <string>
#include <map>
#include <exception>
namespace mapnik
{
class xml_tree;
class xml_attribute
{
public:
xml_attribute(std::string const& value);
std::string value;
mutable bool processed;
};
class node_not_found: public std::exception
{
public:
node_not_found(std::string node_name);
virtual const char* what() const throw();
~node_not_found() throw ();
private:
std::string node_name_;
};
class attribute_not_found: public std::exception
{
public:
attribute_not_found(std::string const& node_name, std::string const& attribute_name);
virtual const char* what() const throw();
~attribute_not_found() throw ();
private:
std::string node_name_;
std::string attribute_name_;
};
class more_than_one_child: public std::exception
{
public:
more_than_one_child(std::string const& node_name);
virtual const char* what() const throw();
~more_than_one_child() throw ();
private:
std::string node_name_;
};
class xml_node
{
public:
typedef std::list<xml_node>::const_iterator const_iterator;
typedef std::map<std::string, xml_attribute> attribute_map;
xml_node(xml_tree &tree, std::string name, unsigned line=0, bool text_node = false);
std::string const& name() const;
std::string const& text() const;
std::string const& filename() const;
bool is_text() const;
bool is(std::string const& name) const;
xml_node &add_child(std::string const& name, unsigned line=0, bool text_node = false);
void add_attribute(std::string const& name, std::string const& value);
attribute_map const& get_attributes() const;
bool processed() const;
void set_processed(bool processed) const;
unsigned line() const;
const_iterator begin() const;
const_iterator end() const;
xml_node & get_child(std::string const& name);
xml_node const& get_child(std::string const& name) const;
xml_node const* get_opt_child(std::string const& name) const;
bool has_child(std::string const& name) const;
template <typename T>
boost::optional<T> get_opt_attr(std::string const& name) const;
template <typename T>
T get_attr(std::string const& name, T const& default_value) const;
template <typename T>
T get_attr(std::string const& name) const;
std::string get_text() const;
template <typename T>
T get_value() const;
private:
xml_tree &tree_;
std::string name_;
std::list<xml_node> children_;
attribute_map attributes_;
bool text_node_;
unsigned line_;
mutable bool processed_;
static std::string xml_text;
};
} //ns mapnik
#endif // MAPNIK_XML_NODE_H

View file

@ -0,0 +1,62 @@
/*****************************************************************************
*
* 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_XML_TREE_H
#define MAPNIK_XML_TREE_H
//mapnik
#include <mapnik/xml_node.hpp>
#include <mapnik/expression_grammar.hpp>
// boost
#include <boost/format.hpp>
#if BOOST_VERSION >= 104500
#include <mapnik/css_color_grammar.hpp>
#else
#include <mapnik/css_color_grammar_deprecated.hpp>
#endif
//stl
#include <string>
namespace mapnik
{
class xml_tree
{
public:
xml_tree(std::string const& encoding="utf8");
void set_filename(std::string fn);
std::string const& filename() const;
xml_node &root();
private:
xml_node node_;
std::string file_;
transcoder tr_;
public:
mapnik::css_color_grammar<std::string::const_iterator> color_grammar;
mapnik::expression_grammar<std::string::const_iterator> expr_grammar;
};
} //ns mapnik
#endif // MAPNIK_XML_TREE_H

View file

@ -6,6 +6,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
// mapnik // mapnik
#include <mapnik/feature_layer_desc.hpp> #include <mapnik/feature_layer_desc.hpp>
@ -14,7 +15,7 @@
#include <mapnik/memory_featureset.hpp> #include <mapnik/memory_featureset.hpp>
#include <mapnik/wkt/wkt_factory.hpp> #include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp> #include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/ptree_helpers.hpp> // mapnik::boolean #include <mapnik/boolean.hpp>
// stl // stl
#include <sstream> #include <sstream>
@ -45,7 +46,8 @@ csv_datasource::csv_datasource(parameters const& params, bool bind)
manual_headers_(boost::trim_copy(*params_.get<std::string>("headers", ""))), manual_headers_(boost::trim_copy(*params_.get<std::string>("headers", ""))),
strict_(*params_.get<mapnik::boolean>("strict", false)), strict_(*params_.get<mapnik::boolean>("strict", false)),
quiet_(*params_.get<mapnik::boolean>("quiet", false)), quiet_(*params_.get<mapnik::boolean>("quiet", false)),
filesize_max_(*params_.get<float>("filesize_max", 20.0)) // MB filesize_max_(*params_.get<float>("filesize_max", 20.0)), // MB
ctx_(boost::make_shared<mapnik::context_type>())
{ {
/* TODO: /* TODO:
general: general:
@ -391,7 +393,6 @@ void csv_datasource::parse_csv(T& stream,
bool extent_initialized = false; bool extent_initialized = false;
std::size_t num_headers = headers_.size(); std::size_t num_headers = headers_.size();
ctx_ = boost::make_shared<mapnik::context_type>();
for (std::size_t i = 0; i < headers_.size(); ++i) for (std::size_t i = 0; i < headers_.size(); ++i)
{ {
ctx_->push(headers_[i]); ctx_->push(headers_[i]);

View file

@ -25,7 +25,7 @@
#include "gdal_featureset.hpp" #include "gdal_featureset.hpp"
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <gdal_version.h> #include <gdal_version.h>

View file

@ -30,7 +30,7 @@
#include <cstdarg> #include <cstdarg>
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
// boost // boost

View file

@ -33,7 +33,7 @@
#include <cstdio> #include <cstdio>
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
// boost // boost
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>

View file

@ -25,7 +25,7 @@
#include "occi_featureset.hpp" #include "occi_featureset.hpp"
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/sql_utils.hpp> #include <mapnik/sql_utils.hpp>
// boost // boost

View file

@ -33,7 +33,7 @@
#include <gdal_version.h> #include <gdal_version.h>
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
// boost // boost

View file

@ -52,6 +52,7 @@ DATASOURCE_PLUGIN(osm_datasource)
osm_datasource::osm_datasource(const parameters& params, bool bind) osm_datasource::osm_datasource(const parameters& params, bool bind)
: datasource (params), : datasource (params),
extent_(),
type_(datasource::Vector), type_(datasource::Vector),
desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding", "utf-8")) desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding", "utf-8"))
{ {
@ -71,13 +72,11 @@ void osm_datasource::bind() const
std::string url = *params_.get<std::string>("url", ""); std::string url = *params_.get<std::string>("url", "");
std::string bbox = *params_.get<std::string>("bbox", ""); std::string bbox = *params_.get<std::string>("bbox", "");
bool do_process = false;
// load the data // load the data
// if we supplied a filename, load from file
if (url != "" && bbox != "") if (url != "" && bbox != "")
{ {
// otherwise if we supplied a url and a bounding box, load from the url // if we supplied a url and a bounding box, load from the url
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "Osm Plugin: loading_from_url: url=" << url << " bbox=" << bbox << std::endl; std::clog << "Osm Plugin: loading_from_url: url=" << url << " bbox=" << bbox << std::endl;
#endif #endif
@ -85,44 +84,40 @@ void osm_datasource::bind() const
{ {
throw datasource_exception("Error loading from URL"); throw datasource_exception("Error loading from URL");
} }
do_process = true;
} }
else if (osm_filename != "") else if (osm_filename != "")
{ {
if ((osm_data_= dataset_deliverer::load_from_file(osm_filename, parser)) == NULL) // if we supplied a filename, load from file
if ((osm_data_ = dataset_deliverer::load_from_file(osm_filename, parser)) == NULL)
{ {
std::ostringstream s; std::ostringstream s;
s << "OSM Plugin: Error loading from file '" << osm_filename << "'"; s << "OSM Plugin: Error loading from file '" << osm_filename << "'";
throw datasource_exception(s.str()); throw datasource_exception(s.str());
} }
} else {
do_process = true; throw datasource_exception("OSM Plugin: Neither 'file' nor 'url' and 'bbox' specified");
} }
if (do_process == true)
osm_tag_types tagtypes;
tagtypes.add_type("maxspeed", mapnik::Integer);
tagtypes.add_type("z_order", mapnik::Integer);
osm_data_->rewind();
// Need code to get the attributes of all the data
std::set<std::string> keys = osm_data_->get_keys();
// Add the attributes to the datasource descriptor - assume they are
// all of type String
for (std::set<std::string>::iterator i = keys.begin(); i != keys.end(); i++)
{ {
osm_tag_types tagtypes; desc_.add_descriptor(attribute_descriptor(*i, tagtypes.get_type(*i)));
tagtypes.add_type("maxspeed", mapnik::Integer);
tagtypes.add_type("z_order", mapnik::Integer);
osm_data_->rewind();
// Need code to get the attributes of all the data
std::set<std::string> keys = osm_data_->get_keys();
// Add the attributes to the datasource descriptor - assume they are
// all of type String
for (std::set<std::string>::iterator i = keys.begin(); i != keys.end(); i++)
{
desc_.add_descriptor(attribute_descriptor(*i, tagtypes.get_type(*i)));
}
// Get the bounds of the data and set extent_ accordingly
bounds b = osm_data_->get_bounds();
extent_ = box2d<double>(b.w, b.s, b.e, b.n);
} }
// Get the bounds of the data and set extent_ accordingly
bounds b = osm_data_->get_bounds();
extent_ = box2d<double>(b.w, b.s, b.e, b.n);
is_bound_ = true; is_bound_ = true;
} }
@ -149,7 +144,7 @@ layer_descriptor osm_datasource::get_descriptor() const
featureset_ptr osm_datasource::features(const query& q) const featureset_ptr osm_datasource::features(const query& q) const
{ {
if (! is_bound_) bind(); if (!is_bound_) bind();
filter_in_box filter(q.get_bbox()); filter_in_box filter(q.get_bbox());
// so we need to filter osm features by bbox here... // so we need to filter osm features by bbox here...
@ -162,7 +157,7 @@ featureset_ptr osm_datasource::features(const query& q) const
featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const
{ {
if (! is_bound_) bind(); if (!is_bound_) bind();
filter_at_point filter(pt); filter_at_point filter(pt);
// collect all attribute names // collect all attribute names
@ -185,8 +180,7 @@ featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const
box2d<double> osm_datasource::envelope() const box2d<double> osm_datasource::envelope() const
{ {
if (! is_bound_) bind(); if (!is_bound_) bind();
return extent_; return extent_;
} }

View file

@ -103,6 +103,11 @@ void osmparser::startElement(xmlTextReaderPtr reader, const xmlChar *name)
xmlFree(xk); xmlFree(xk);
xmlFree(xv); xmlFree(xv);
} }
if (xmlTextReaderIsEmptyElement(reader))
{
// Fake endElement for empty nodes
endElement(name);
}
} }
void osmparser::endElement(const xmlChar* name) void osmparser::endElement(const xmlChar* name)

View file

@ -26,7 +26,7 @@
// mapnik // mapnik
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/sql_utils.hpp> #include <mapnik/sql_utils.hpp>
#include <mapnik/util/conversions.hpp> #include <mapnik/util/conversions.hpp>
@ -175,7 +175,7 @@ void postgis_datasource::bind() const
if (srid_c != NULL) if (srid_c != NULL)
{ {
int result; int result;
if (mapnik::conversions::string2int(srid_c,result)) if (mapnik::util::string2int(srid_c,result))
srid_ = result; srid_ = result;
} }
} }
@ -205,7 +205,7 @@ void postgis_datasource::bind() const
if (srid_c != NULL) if (srid_c != NULL)
{ {
int result; int result;
if (mapnik::conversions::string2int(srid_c,result)) if (mapnik::util::string2int(srid_c,result))
srid_ = result; srid_ = result;
} }
} }
@ -681,22 +681,22 @@ box2d<double> postgis_datasource::envelope() const
shared_ptr<ResultSet> rs = conn->executeQuery(s.str()); shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
if (rs->next() && !rs->isNull(0)) if (rs->next() && !rs->isNull(0))
{ {
double lox; double lox;
double loy; double loy;
double hix; double hix;
double hiy; double hiy;
if (mapnik::conversions::string2double(rs->getValue(0),lox) && if (mapnik::util::string2double(rs->getValue(0),lox) &&
mapnik::conversions::string2double(rs->getValue(1),loy) && mapnik::util::string2double(rs->getValue(1),loy) &&
mapnik::conversions::string2double(rs->getValue(2),hix) && mapnik::util::string2double(rs->getValue(2),hix) &&
mapnik::conversions::string2double(rs->getValue(3),hiy)) mapnik::util::string2double(rs->getValue(3),hiy))
{ {
extent_.init(lox,loy,hix,hiy); extent_.init(lox,loy,hix,hiy);
extent_initialized_ = true; extent_initialized_ = true;
} }
else else
{ {
std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl; std::clog << boost::format("Postgis Plugin: warning: could not determine extent from query: %s\n") % s.str() << std::endl;
} }
} }
rs->close(); rs->close();
} }

View file

@ -162,7 +162,7 @@ feature_ptr postgis_featureset::next()
{ {
std::string str = mapnik::sql_utils::numeric2string(buf); std::string str = mapnik::sql_utils::numeric2string(buf);
double val; double val;
if (mapnik::conversions::string2double(str,val)) if (mapnik::util::string2double(str,val))
feature->put(name,val); feature->put(name,val);
} }
else else

View file

@ -48,9 +48,9 @@ raster_featureset<LookupPolicy>::raster_featureset(LookupPolicy const& policy,
extent_(extent), extent_(extent),
bbox_(q.get_bbox()), bbox_(q.get_bbox()),
curIter_(policy_.begin()), curIter_(policy_.begin()),
endIter_(policy_.end()) endIter_(policy_.end()),
ctx_(boost::make_shared<mapnik::context_type>())
{ {
ctx_ = boost::make_shared<mapnik::context_type>();
} }
template <typename LookupPolicy> template <typename LookupPolicy>

View file

@ -29,7 +29,7 @@
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
using mapnik::datasource; using mapnik::datasource;

View file

@ -127,7 +127,7 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature & f)
if (col>=0 && col<num_fields_) if (col>=0 && col<num_fields_)
{ {
std::string name=fields_[col].name_; std::string const& name=fields_[col].name_;
switch (fields_[col].type_) switch (fields_[col].type_)
{ {

View file

@ -44,12 +44,12 @@ shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
std::string const& shape_name, std::string const& shape_name,
int row_limit) int row_limit)
: filter_(filter), : filter_(filter),
ctx_(boost::make_shared<mapnik::context_type>()),
shape_(shape), shape_(shape),
tr_(new transcoder(encoding)), tr_(new transcoder(encoding)),
row_limit_(row_limit), row_limit_(row_limit),
count_(0) count_(0)
{ {
ctx_ = boost::make_shared<mapnik::context_type>();
shape_.shp().skip(100); shape_.shp().skip(100);
setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_); setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_);

View file

@ -26,7 +26,7 @@
#include "sqlite_utils.hpp" #include "sqlite_utils.hpp"
// mapnik // mapnik
#include <mapnik/ptree_helpers.hpp> #include <mapnik/boolean.hpp>
#include <mapnik/sql_utils.hpp> #include <mapnik/sql_utils.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp> #include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/wkb.hpp> #include <mapnik/wkb.hpp>

View file

@ -24,9 +24,9 @@
// mapnik // mapnik
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/font_set.hpp> #include <mapnik/font_set.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
@ -201,16 +201,18 @@ void agg_renderer<T>::end_map_processing(Map const& )
} }
template <typename T> template <typename T>
void agg_renderer<T>::start_layer_processing(layer const& lay) void agg_renderer<T>::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
{ {
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "start layer processing : " << lay.name() << "\n"; std::clog << "start layer processing : " << lay.name() << "\n";
std::clog << "datasource = " << lay.datasource().get() << "\n"; std::clog << "datasource = " << lay.datasource().get() << "\n";
std::clog << "query_extent = " << query_extent << "\n";
#endif #endif
if (lay.clear_label_cache()) if (lay.clear_label_cache())
{ {
detector_->clear(); detector_->clear();
} }
query_extent_ = query_extent;
} }
template <typename T> template <typename T>
@ -246,7 +248,7 @@ void agg_renderer<T>::render_marker(pixel_position const& pos, marker const& mar
mtx *= agg::trans_affine_scaling(scale_factor_); mtx *= agg::trans_affine_scaling(scale_factor_);
// render the marker at the center of the marker box // render the marker at the center of the marker box
mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height()); mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height());
using namespace mapnik::svg;
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source()); vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer<svg_path_adapter, svg_renderer<svg_path_adapter,

View file

@ -26,6 +26,7 @@
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/agg_pattern_source.hpp> #include <mapnik/agg_pattern_source.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/line_pattern_symbolizer.hpp> #include <mapnik/line_pattern_symbolizer.hpp>
@ -42,6 +43,7 @@
#include "agg_span_allocator.h" #include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h" #include "agg_span_pattern_rgba.h"
#include "agg_renderer_outline_image.h" #include "agg_renderer_outline_image.h"
#include "agg_conv_clip_polyline.h"
namespace mapnik { namespace mapnik {
@ -50,7 +52,8 @@ void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type; typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
@ -74,6 +77,7 @@ void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
if (!pat) return; if (!pat) return;
box2d<double> ext = query_extent_ * 1.1;
renderer_base ren_base(pixf); renderer_base ren_base(pixf);
agg::pattern_filter_bilinear_rgba8 filter; agg::pattern_filter_bilinear_rgba8 filter;
pattern_source source(*(*pat)); pattern_source source(*(*pat));
@ -82,15 +86,17 @@ void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
// TODO - should be sensitive to buffer size // TODO - should be sensitive to buffer size
ren.clip_box(0,0,width_,height_); ren.clip_box(0,0,width_,height_);
rasterizer_type ras(ren); rasterizer_type ras(ren);
metawriter_with_properties writer = sym.get_metawriter(); //metawriter_with_properties writer = sym.get_metawriter();
for (unsigned i=0;i<feature->num_geometries();++i) for (unsigned i=0;i<feature->num_geometries();++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
path_type path(t_,geom,prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
path_type path(t_,clipped,prj_trans);
ras.add_path(path); ras.add_path(path);
if (writer.first) writer.first->add_line(path, *feature, t_, writer.second); //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second);
} }
} }
} }

View file

@ -23,6 +23,7 @@
// mapnik // mapnik
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/line_symbolizer.hpp> #include <mapnik/line_symbolizer.hpp>
@ -38,8 +39,8 @@
#include "agg_conv_dash.h" #include "agg_conv_dash.h"
#include "agg_renderer_outline_aa.h" #include "agg_renderer_outline_aa.h"
#include "agg_rasterizer_outline_aa.h" #include "agg_rasterizer_outline_aa.h"
#include "agg_conv_clip_polyline.h"
#include "agg_conv_smooth_poly1.h"
// stl // stl
#include <string> #include <string>
@ -51,7 +52,6 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef coord_transform2<CoordTransform,geometry_type> path_type;
stroke const& stroke_ = sym.get_stroke(); stroke const& stroke_ = sym.get_stroke();
color const& col = stroke_.get_color(); color const& col = stroke_.get_color();
@ -63,13 +63,15 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
agg::pixfmt_rgba32_plain pixf(buf); agg::pixfmt_rgba32_plain pixf(buf);
box2d<double> ext = query_extent_ * 1.1;
if (sym.get_rasterizer() == RASTERIZER_FAST) if (sym.get_rasterizer() == RASTERIZER_FAST)
{ {
typedef agg::renderer_outline_aa<ren_base> renderer_type; typedef agg::renderer_outline_aa<ren_base> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
agg::line_profile_aa profile; agg::line_profile_aa profile;
//agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_none());
profile.width(stroke_.get_width() * scale_factor_); profile.width(stroke_.get_width() * scale_factor_);
ren_base base_ren(pixf); ren_base base_ren(pixf);
renderer_type ren(base_ren, profile); renderer_type ren(base_ren, profile);
@ -81,10 +83,12 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
for (unsigned i=0;i<feature->num_geometries();++i) for (unsigned i=0;i<feature->num_geometries();++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
path_type path(t_,geom,prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
path_type path(t_,clipped,prj_trans);
ras.add_path(path); ras.add_path(path);
} }
} }
@ -98,97 +102,98 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
ren_base renb(pixf); ren_base renb(pixf);
renderer ren(renb); renderer ren(renb);
ras_ptr->reset(); ras_ptr->reset();
switch (stroke_.get_gamma_method())
{
case GAMMA_POWER:
ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
break;
case GAMMA_LINEAR:
ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma()));
break;
case GAMMA_NONE:
ras_ptr->gamma(agg::gamma_none());
break;
case GAMMA_THRESHOLD:
ras_ptr->gamma(agg::gamma_threshold(stroke_.get_gamma()));
break;
case GAMMA_MULTIPLY:
ras_ptr->gamma(agg::gamma_multiply(stroke_.get_gamma()));
break;
default:
ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
}
metawriter_with_properties writer = sym.get_metawriter(); set_gamma_method(stroke_, ras_ptr);
//metawriter_with_properties writer = sym.get_metawriter();
for (unsigned i=0;i<feature->num_geometries();++i) for (unsigned i=0;i<feature->num_geometries();++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
path_type path(t_,geom,prj_trans);
if (stroke_.has_dash()) if (stroke_.has_dash())
{ {
agg::conv_dash<path_type> dash(path); if (sym.smooth() > 0.0)
dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin();
dash_array::const_iterator end = d.end();
for (;itr != end;++itr)
{ {
dash.add_dash(itr->first * scale_factor_, typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
itr->second * scale_factor_); typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::conv_smooth_poly1_curve<path_type> smooth_type;
clipped_geometry_type clipped(geom);
clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
path_type path(t_,clipped,prj_trans);
smooth_type smooth(path);
smooth.smooth_value(sym.smooth());
agg::conv_dash<smooth_type> dash(smooth);
dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin();
dash_array::const_iterator end = d.end();
for (;itr != end;++itr)
{
dash.add_dash(itr->first * scale_factor_,
itr->second * scale_factor_);
}
agg::conv_stroke<agg::conv_dash<smooth_type > > stroke(dash);
set_join_caps(stroke_,stroke);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
} }
agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
line_join_e join=stroke_.get_line_join();
if ( join == MITER_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == MITER_REVERT_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == ROUND_JOIN)
stroke.generator().line_join(agg::round_join);
else else
stroke.generator().line_join(agg::bevel_join); {
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
line_cap_e cap=stroke_.get_line_cap(); typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
if (cap == BUTT_CAP) clipped_geometry_type clipped(geom);
stroke.generator().line_cap(agg::butt_cap); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
else if (cap == SQUARE_CAP) path_type path(t_,clipped,prj_trans);
stroke.generator().line_cap(agg::square_cap);
else
stroke.generator().line_cap(agg::round_cap);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
agg::conv_dash<path_type> dash(path);
dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin();
dash_array::const_iterator end = d.end();
for (;itr != end;++itr)
{
dash.add_dash(itr->first * scale_factor_,
itr->second * scale_factor_);
}
agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
set_join_caps(stroke_,stroke);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
}
} }
else else
{ {
agg::conv_stroke<path_type> stroke(path); if (sym.smooth() > 0.0)
line_join_e join=stroke_.get_line_join(); {
if ( join == MITER_JOIN) typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
stroke.generator().line_join(agg::miter_join); typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
else if( join == MITER_REVERT_JOIN) typedef agg::conv_smooth_poly1_curve<path_type> smooth_type;
stroke.generator().line_join(agg::miter_join); clipped_geometry_type clipped(geom);
else if( join == ROUND_JOIN) clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
stroke.generator().line_join(agg::round_join); path_type path(t_,clipped,prj_trans);
smooth_type smooth(path);
smooth.smooth_value(sym.smooth());
agg::conv_stroke<smooth_type> stroke(smooth);
set_join_caps(stroke_,stroke);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
}
else else
stroke.generator().line_join(agg::bevel_join); {
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
line_cap_e cap=stroke_.get_line_cap(); typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
if (cap == BUTT_CAP) clipped_geometry_type clipped(geom);
stroke.generator().line_cap(agg::butt_cap); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
else if (cap == SQUARE_CAP) path_type path(t_,clipped,prj_trans);
stroke.generator().line_cap(agg::square_cap); agg::conv_stroke<path_type> stroke(path);
else set_join_caps(stroke_,stroke);
stroke.generator().line_cap(agg::round_cap); stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
stroke.generator().miter_limit(4.0); ras_ptr->add_path(stroke);
stroke.generator().width(stroke_.get_width() * scale_factor_); }
ras_ptr->add_path(stroke); //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second);
if (writer.first) writer.first->add_line(path, *feature, t_, writer.second);
} }
} }
} }

View file

@ -25,6 +25,7 @@
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/svg/svg_renderer.hpp> #include <mapnik/svg/svg_renderer.hpp>
#include <mapnik/svg/svg_path_adapter.hpp> #include <mapnik/svg/svg_path_adapter.hpp>
@ -41,7 +42,7 @@
#include "agg_path_storage.h" #include "agg_path_storage.h"
#include "agg_ellipse.h" #include "agg_ellipse.h"
#include "agg_conv_stroke.h" #include "agg_conv_stroke.h"
#include "agg_conv_clip_polyline.h"
namespace mapnik { namespace mapnik {
@ -50,7 +51,9 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::pixfmt_rgba32_plain pixfmt; typedef agg::pixfmt_rgba32_plain pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
@ -104,7 +107,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
for (unsigned i=0; i<feature->num_geometries(); ++i) for (unsigned i=0; i<feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
// TODO - merge this code with point_symbolizer rendering // TODO - merge this code with point_symbolizer rendering
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1) if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
{ {
@ -131,7 +134,9 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
} }
else else
{ {
path_type path(t_,geom,prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_, markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
sym.get_spacing() * scale_factor_, sym.get_spacing() * scale_factor_,
sym.get_max_error(), sym.get_max_error(),
@ -166,6 +171,8 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
unsigned s_a=col.alpha(); unsigned s_a=col.alpha();
double w = sym.get_width(); double w = sym.get_width();
double h = sym.get_height(); double h = sym.get_height();
double rx = w/2.0;
double ry = h/2.0;
arrow arrow_; arrow arrow_;
box2d<double> extent; box2d<double> extent;
@ -206,7 +213,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
for (unsigned i=0; i<feature->num_geometries(); ++i) for (unsigned i=0; i<feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
//if (geom.num_points() <= 1) continue; //if (geom.num_points() <= 1) continue;
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1) if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
{ {
@ -220,7 +227,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (sym.get_allow_overlap() || if (sym.get_allow_overlap() ||
detector_->has_placement(label_ext)) detector_->has_placement(label_ext))
{ {
agg::ellipse c(x, y, w, h); agg::ellipse c(x, y, rx, ry);
marker.concat_path(c); marker.concat_path(c);
ras_ptr->add_path(marker); ras_ptr->add_path(marker);
ren.color(agg::rgba8(r, g, b, int(a*sym.get_opacity()))); ren.color(agg::rgba8(r, g, b, int(a*sym.get_opacity())));
@ -239,7 +246,8 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity()))); ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
agg::render_scanlines(*ras_ptr, sl_line, ren); agg::render_scanlines(*ras_ptr, sl_line, ren);
} }
detector_->insert(label_ext); if (!sym.get_ignore_placement())
detector_->insert(label_ext);
if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second);
} }
} }
@ -249,7 +257,9 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (marker_type == ARROW) if (marker_type == ARROW)
marker.concat_path(arrow_); marker.concat_path(arrow_);
path_type path(t_,geom,prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_, markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
sym.get_spacing() * scale_factor_, sym.get_spacing() * scale_factor_,
sym.get_max_error(), sym.get_max_error(),
@ -263,7 +273,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (marker_type == ELLIPSE) if (marker_type == ELLIPSE)
{ {
// todo proper bbox - this is buggy // todo proper bbox - this is buggy
agg::ellipse c(x_t, y_t, w, h); agg::ellipse c(x_t, y_t, rx, ry);
marker.concat_path(c); marker.concat_path(c);
agg::trans_affine matrix; agg::trans_affine matrix;
matrix *= agg::trans_affine_translation(-x_t,-y_t); matrix *= agg::trans_affine_translation(-x_t,-y_t);

View file

@ -26,6 +26,7 @@
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/metawriter.hpp> #include <mapnik/metawriter.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>

View file

@ -23,7 +23,9 @@
// mapnik // mapnik
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
@ -38,8 +40,7 @@
#include "agg_span_allocator.h" #include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h" #include "agg_span_pattern_rgba.h"
#include "agg_image_accessors.h" #include "agg_image_accessors.h"
#include "agg_conv_clip_polygon.h"
namespace mapnik { namespace mapnik {
@ -48,7 +49,8 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::wrap_mode_repeat wrap_y_type;
@ -71,26 +73,7 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
agg::scanline_u8 sl; agg::scanline_u8 sl;
ras_ptr->reset(); ras_ptr->reset();
switch (sym.get_gamma_method()) set_gamma_method(sym,ras_ptr);
{
case GAMMA_POWER:
ras_ptr->gamma(agg::gamma_power(sym.get_gamma()));
break;
case GAMMA_LINEAR:
ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma()));
break;
case GAMMA_NONE:
ras_ptr->gamma(agg::gamma_none());
break;
case GAMMA_THRESHOLD:
ras_ptr->gamma(agg::gamma_threshold(sym.get_gamma()));
break;
case GAMMA_MULTIPLY:
ras_ptr->gamma(agg::gamma_multiply(sym.get_gamma()));
break;
default:
ras_ptr->gamma(agg::gamma_power(sym.get_gamma()));
}
std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
boost::optional<mapnik::marker_ptr> marker; boost::optional<mapnik::marker_ptr> marker;
@ -133,9 +116,11 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
if (align == LOCAL_ALIGNMENT) if (align == LOCAL_ALIGNMENT)
{ {
double x0=0,y0=0; double x0=0,y0=0;
if (num_geometries>0) if (num_geometries>0) // FIXME: hmm...?
{ {
path_type path(t_,feature->get_geometry(0),prj_trans); clipped_geometry_type clipped(feature->get_geometry(0));
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
path.vertex(&x0,&y0); path.vertex(&x0,&y0);
} }
offset_x = unsigned(width_-x0); offset_x = unsigned(width_-x0);
@ -144,15 +129,17 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
span_gen_type sg(img_src, offset_x, offset_y); span_gen_type sg(img_src, offset_x, offset_y);
renderer_type rp(renb,sa, sg); renderer_type rp(renb,sa, sg);
metawriter_with_properties writer = sym.get_metawriter(); //metawriter_with_properties writer = sym.get_metawriter();
for (unsigned i=0;i<num_geometries;++i) for (unsigned i=0;i<num_geometries;++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 2) if (geom.num_points() > 2)
{ {
path_type path(t_,geom,prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
ras_ptr->add_path(path); ras_ptr->add_path(path);
if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second); //if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second);
} }
} }
agg::render_scanlines(*ras_ptr, sl, rp); agg::render_scanlines(*ras_ptr, sl, rp);

View file

@ -23,6 +23,7 @@
// mapnik // mapnik
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/polygon_symbolizer.hpp> #include <mapnik/polygon_symbolizer.hpp>
@ -34,7 +35,8 @@
#include "agg_scanline_u.h" #include "agg_scanline_u.h"
// for polygon_symbolizer // for polygon_symbolizer
#include "agg_renderer_scanline.h" #include "agg_renderer_scanline.h"
#include "agg_conv_clip_polygon.h"
#include "agg_conv_smooth_poly1.h"
// stl // stl
#include <string> #include <string>
@ -45,7 +47,6 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer; typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
@ -60,40 +61,42 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
unsigned g=fill_.green(); unsigned g=fill_.green();
unsigned b=fill_.blue(); unsigned b=fill_.blue();
unsigned a=fill_.alpha(); unsigned a=fill_.alpha();
renb.clip_box(0,0,width_,height_); //renb.clip_box(0,0,width_,height_);
renderer ren(renb); renderer ren(renb);
ras_ptr->reset(); ras_ptr->reset();
switch (sym.get_gamma_method())
{
case GAMMA_POWER:
ras_ptr->gamma(agg::gamma_power(sym.get_gamma()));
break;
case GAMMA_LINEAR:
ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma()));
break;
case GAMMA_NONE:
ras_ptr->gamma(agg::gamma_none());
break;
case GAMMA_THRESHOLD:
ras_ptr->gamma(agg::gamma_threshold(sym.get_gamma()));
break;
case GAMMA_MULTIPLY:
ras_ptr->gamma(agg::gamma_multiply(sym.get_gamma()));
break;
default:
ras_ptr->gamma(agg::gamma_power(sym.get_gamma()));
}
metawriter_with_properties writer = sym.get_metawriter(); set_gamma_method(sym,ras_ptr);
//metawriter_with_properties writer = sym.get_metawriter();
box2d<double> inflated_extent = query_extent_ * 1.1;
for (unsigned i=0;i<feature->num_geometries();++i) for (unsigned i=0;i<feature->num_geometries();++i)
{ {
geometry_type const& geom=feature->get_geometry(i); geometry_type & geom=feature->get_geometry(i);
if (geom.num_points() > 2) if (geom.num_points() > 2)
{ {
path_type path(t_,geom,prj_trans); if (sym.smooth() > 0.0)
ras_ptr->add_path(path); {
if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second); typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::conv_smooth_poly1_curve<path_type> smooth_type;
clipped_geometry_type clipped(geom);
clipped.clip_box(inflated_extent.minx(),inflated_extent.miny(),inflated_extent.maxx(),inflated_extent.maxy());
path_type path(t_,clipped,prj_trans);
smooth_type smooth(path);
smooth.smooth_value(sym.smooth());
ras_ptr->add_path(smooth);
}
else
{
typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
ras_ptr->add_path(path);
}
//if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second);
} }
} }
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity()))); ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));

View file

@ -46,7 +46,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
sym, *feature, prj_trans, sym, *feature, prj_trans,
width_, height_, width_, height_,
scale_factor_, scale_factor_,
t_, font_manager_, *detector_); t_, font_manager_, *detector_, query_extent_);
text_renderer<T> ren(pixmap_, font_manager_, *(font_manager_.get_stroker())); text_renderer<T> ren(pixmap_, font_manager_, *(font_manager_.get_stroker()));

View file

@ -38,7 +38,7 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
sym, *feature, prj_trans, sym, *feature, prj_trans,
width_, height_, width_, height_,
scale_factor_, scale_factor_,
t_, font_manager_, *detector_); t_, font_manager_, *detector_, query_extent_);
text_renderer<T> ren(pixmap_, font_manager_, *(font_manager_.get_stroker())); text_renderer<T> ren(pixmap_, font_manager_, *(font_manager_.get_stroker()));

View file

@ -73,6 +73,7 @@ if env['THREADING'] == 'multi':
if env['RUNTIME_LINK'] == 'static': if env['RUNTIME_LINK'] == 'static':
if 'icuuc' in env['ICU_LIB_NAME']: if 'icuuc' in env['ICU_LIB_NAME']:
lib_env['LIBS'].append('icudata') lib_env['LIBS'].append('icudata')
lib_env['LIBS'].append('icui18n')
else: else:
if env['INTERNAL_LIBAGG']: if env['INTERNAL_LIBAGG']:
lib_env['LIBS'].insert(0, 'agg') lib_env['LIBS'].insert(0, 'agg')
@ -83,7 +84,7 @@ else:
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
mapnik_libname = 'libmapnik.dylib' mapnik_libname = 'libmapnik.dylib'
else: else:
mapnik_libname = 'libmapnik.so.' + ("%d.%d" % (ABI_VERSION[0],ABI_VERSION[1])) mapnik_libname = 'libmapnik.so.' + ("%d.%d" % (int(ABI_VERSION[0]),int(ABI_VERSION[1])))
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
if env['FULL_LIB_PATH']: if env['FULL_LIB_PATH']:
@ -91,7 +92,7 @@ if env['PLATFORM'] == 'Darwin':
else: else:
lib_path = mapnik_libname lib_path = mapnik_libname
mapnik_lib_link_flag += ' -Wl,-install_name,%s' % lib_path mapnik_lib_link_flag += ' -Wl,-install_name,%s' % lib_path
_d = {'version':env['MAPNIK_VERSION_STRING']} _d = {'version':env['MAPNIK_VERSION_STRING'].replace('-pre','')}
mapnik_lib_link_flag += ' -current_version %(version)s -compatibility_version %(version)s' % _d mapnik_lib_link_flag += ' -current_version %(version)s -compatibility_version %(version)s' % _d
elif env['PLATFORM'] == 'SunOS': elif env['PLATFORM'] == 'SunOS':
if env['CXX'].startswith('CC'): if env['CXX'].startswith('CC'):
@ -105,6 +106,7 @@ source = Split(
""" """
color.cpp color.cpp
conversions.cpp conversions.cpp
image_compositing.cpp
box2d.cpp box2d.cpp
building_symbolizer.cpp building_symbolizer.cpp
datasource_cache.cpp datasource_cache.cpp
@ -178,6 +180,8 @@ source = Split(
text_placements/list.cpp text_placements/list.cpp
text_placements/simple.cpp text_placements/simple.cpp
text_properties.cpp text_properties.cpp
xml_tree.cpp
config_error.cpp
""" """
) )
@ -299,7 +303,7 @@ if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
env2 = lib_env.Clone() env2 = lib_env.Clone()
env2.Append(CXXFLAGS = '-DHAVE_LIBXML2') env2.Append(CXXFLAGS = '-DHAVE_LIBXML2')
libmapnik_cxxflags.append('-DHAVE_LIBXML2') libmapnik_cxxflags.append('-DHAVE_LIBXML2')
fixup = ['load_map.cpp','libxml2_loader.cpp'] fixup = ['libxml2_loader.cpp']
for cpp in fixup: for cpp in fixup:
if cpp in source: if cpp in source:
source.remove(cpp) source.remove(cpp)
@ -307,6 +311,12 @@ if env['XMLPARSER'] == 'libxml2' and env['HAS_LIBXML2']:
source.insert(0,env2.StaticObject(cpp)) source.insert(0,env2.StaticObject(cpp))
else: else:
source.insert(0,env2.SharedObject(cpp)) source.insert(0,env2.SharedObject(cpp))
else:
source += Split(
"""
rapidxml_loader.cpp
"""
)
if env['CUSTOM_LDFLAGS']: if env['CUSTOM_LDFLAGS']:
linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], mapnik_lib_link_flag) linkflags = '%s %s' % (env['CUSTOM_LDFLAGS'], mapnik_lib_link_flag)
@ -334,7 +344,7 @@ if env['PLATFORM'] != 'Darwin':
major, minor, micro = ABI_VERSION major, minor, micro = ABI_VERSION
soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), major, minor, micro) soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), int(major), int(minor), int(micro))
target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], soFile) target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], soFile)
if 'uninstall' not in COMMAND_LINE_TARGETS: if 'uninstall' not in COMMAND_LINE_TARGETS:
@ -345,7 +355,7 @@ if env['PLATFORM'] != 'Darwin':
# Install symlinks # Install symlinks
target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),major, minor)) target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),int(major), int(minor)))
target2 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], os.path.basename(str(mapnik[0]))) target2 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], os.path.basename(str(mapnik[0])))
if 'uninstall' not in COMMAND_LINE_TARGETS: if 'uninstall' not in COMMAND_LINE_TARGETS:
if 'install' in COMMAND_LINE_TARGETS: if 'install' in COMMAND_LINE_TARGETS:

View file

@ -29,8 +29,8 @@
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/markers_placement.hpp> #include <mapnik/markers_placement.hpp>
#include <mapnik/arrow.hpp> #include <mapnik/arrow.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/svg/svg_path_adapter.hpp> #include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_path_attributes.hpp> #include <mapnik/svg/svg_path_attributes.hpp>
@ -50,6 +50,11 @@
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
// agg
#include "agg_conv_clip_polyline.h"
#include "agg_conv_clip_polygon.h"
#include "agg_conv_smooth_poly1.h"
// stl // stl
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
#include <iostream> #include <iostream>
@ -249,8 +254,7 @@ cairo_face_ptr cairo_face_manager::get_face(face_ptr face)
} }
else else
{ {
entry = cairo_face_ptr(new cairo_face(font_engine_, face)); entry = boost::make_shared<cairo_face>(font_engine_, face);
cache_.insert(std::make_pair(face, entry)); cache_.insert(std::make_pair(face, entry));
} }
@ -628,7 +632,7 @@ cairo_renderer_base::cairo_renderer_base(Map const& m, Cairo::RefPtr<Cairo::Cont
: m_(m), : m_(m),
context_(context), context_(context),
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
font_engine_(new freetype_engine()), font_engine_(boost::make_shared<freetype_engine>()),
font_manager_(*font_engine_), font_manager_(*font_engine_),
face_manager_(font_engine_,font_manager_), face_manager_(font_engine_,font_manager_),
detector_(box2d<double>(-m.buffer_size() ,-m.buffer_size() , m.width() + m.buffer_size() ,m.height() + m.buffer_size())) detector_(box2d<double>(-m.buffer_size() ,-m.buffer_size() , m.width() + m.buffer_size() ,m.height() + m.buffer_size()))
@ -696,16 +700,18 @@ void cairo_renderer_base::start_map_processing(Map const& map)
context_->show_page(); context_->show_page();
} }
void cairo_renderer_base::start_layer_processing(layer const& lay) void cairo_renderer_base::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
{ {
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "start layer processing : " << lay.name() << "\n"; std::clog << "start layer processing : " << lay.name() << "\n";
std::clog << "datasource = " << lay.datasource().get() << "\n"; std::clog << "datasource = " << lay.datasource().get() << "\n";
std::clog << "query_extent = " << query_extent << "\n";
#endif #endif
if (lay.clear_label_cache()) if (lay.clear_label_cache())
{ {
detector_.clear(); detector_.clear();
} }
query_extent_ = query_extent;
} }
void cairo_renderer_base::end_layer_processing(layer const&) void cairo_renderer_base::end_layer_processing(layer const&)
@ -719,24 +725,40 @@ void cairo_renderer_base::start_map_processing(Map const& map)
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type;
cairo_context context(context_); cairo_context context(context_);
context.set_color(sym.get_fill(), sym.get_opacity()); context.set_color(sym.get_fill(), sym.get_opacity());
box2d<double> inflated_extent = query_extent_ * 1.1;
for (unsigned i = 0; i < feature->num_geometries(); ++i) for (unsigned i = 0; i < feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 2) if (geom.num_points() > 2)
{ {
path_type path(t_, geom, prj_trans); if (sym.smooth() > 0.0)
{
context.add_path(path); typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
context.fill(); typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
typedef agg::conv_smooth_poly1_curve<path_type> smooth_type;
clipped_geometry_type clipped(geom);
clipped.clip_box(inflated_extent.minx(),inflated_extent.miny(),inflated_extent.maxx(),inflated_extent.maxy());
path_type path(t_,clipped,prj_trans);
smooth_type smooth(path);
smooth.smooth_value(sym.smooth());
context.add_agg_path(smooth);
}
else
{
typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
context.add_path(path);
}
} }
} }
// fill polygon
context.fill();
} }
void cairo_renderer_base::process(building_symbolizer const& sym, void cairo_renderer_base::process(building_symbolizer const& sym,
@ -853,35 +875,36 @@ void cairo_renderer_base::start_map_processing(Map const& map)
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
cairo_context context(context_);
mapnik::stroke const& stroke_ = sym.get_stroke(); mapnik::stroke const& stroke_ = sym.get_stroke();
cairo_context context(context_);
context.set_color(stroke_.get_color(), stroke_.get_opacity()); context.set_color(stroke_.get_color(), stroke_.get_opacity());
context.set_line_join(stroke_.get_line_join());
context.set_line_cap(stroke_.get_line_cap());
context.set_miter_limit(4.0);
context.set_line_width(stroke_.get_width());
if (stroke_.has_dash())
{
context.set_dash(stroke_.get_dash_array());
}
for (unsigned i = 0; i < feature->num_geometries(); ++i) for (unsigned i = 0; i < feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
cairo_context context(context_); //cairo_context context(context_);
path_type path(t_, geom, prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
if (stroke_.has_dash())
{
context.set_dash(stroke_.get_dash_array());
}
context.set_line_join(stroke_.get_line_join());
context.set_line_cap(stroke_.get_line_cap());
context.set_miter_limit(4.0);
context.set_line_width(stroke_.get_width());
context.add_path(path); context.add_path(path);
context.stroke();
} }
} }
context.stroke();
} }
void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity) void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity)
@ -903,7 +926,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
mapnik::path_ptr vmarker = *marker.get_vector_data(); mapnik::path_ptr vmarker = *marker.get_vector_data();
using namespace mapnik::svg;
agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes(); agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes();
for(unsigned i = 0; i < attributes_.size(); ++i) for(unsigned i = 0; i < attributes_.size(); ++i)
{ {
@ -1054,8 +1077,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
sym, *feature, prj_trans, sym, *feature, prj_trans,
detector_.extent().width(), detector_.extent().height(), detector_.extent().width(), detector_.extent().height(),
1.0 /*scale_factor*/, 1.0 /*scale_factor*/,
t_, font_manager_, detector_); t_, font_manager_, detector_, query_extent_);
cairo_context context(context_); cairo_context context(context_);
while (helper.next()) { while (helper.next()) {
@ -1075,7 +1097,8 @@ void cairo_renderer_base::start_map_processing(Map const& map)
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true); boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true);
@ -1093,11 +1116,14 @@ void cairo_renderer_base::start_map_processing(Map const& map)
for (unsigned i = 0; i < feature->num_geometries(); ++i) for (unsigned i = 0; i < feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
path_type path(t_, geom, prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
double length(0); double length(0);
double x0(0), y0(0); double x0(0), y0(0);
double x, y; double x, y;
@ -1144,7 +1170,8 @@ void cairo_renderer_base::start_map_processing(Map const& map)
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
cairo_context context(context_); cairo_context context(context_);
std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
@ -1159,12 +1186,13 @@ void cairo_renderer_base::start_map_processing(Map const& map)
for (unsigned i = 0; i < feature->num_geometries(); ++i) for (unsigned i = 0; i < feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 2) if (geom.num_points() > 2)
{ {
path_type path(t_, geom, prj_trans); clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
context.add_path(path); context.add_path(path);
context.fill(); context.fill();
} }
@ -1229,10 +1257,11 @@ void cairo_renderer_base::start_map_processing(Map const& map)
for (unsigned i = 0; i < feature->num_geometries(); ++i) for (unsigned i = 0; i < feature->num_geometries(); ++i)
{ {
geometry_type const& geom = feature->get_geometry(i); geometry_type & geom = feature->get_geometry(i);
if (geom.num_points() > 1) if (geom.num_points() > 1)
{ {
path_type path(t_, geom, prj_trans); path_type path(t_, geom, prj_trans);
markers_placement<path_type, label_collision_detector4> placement(path, arrow_.extent(), detector_, sym.get_spacing(), sym.get_max_error(), sym.get_allow_overlap()); markers_placement<path_type, label_collision_detector4> placement(path, arrow_.extent(), detector_, sym.get_spacing(), sym.get_max_error(), sym.get_allow_overlap());
@ -1252,7 +1281,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
mapnik::feature_ptr const& feature, mapnik::feature_ptr const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper(sym, *feature, prj_trans, detector_.extent().width(), detector_.extent().height(), 1.0 /*scale_factor*/, t_, font_manager_, detector_); text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper(sym, *feature, prj_trans, detector_.extent().width(), detector_.extent().height(), 1.0 /*scale_factor*/, t_, font_manager_, detector_, query_extent_);
cairo_context context(context_); cairo_context context(context_);

View file

@ -25,11 +25,23 @@
// mapnik // mapnik
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/color_factory.hpp> #include <mapnik/color_factory.hpp>
#include <mapnik/config_error.hpp>
// boost // boost
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/version.hpp>
// stl // stl
#include <sstream> #include <sstream>
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
#if BOOST_VERSION >= 104500
#include <mapnik/css_color_grammar.hpp>
#else
#include <mapnik/css_color_grammar_deprecated.hpp>
#endif
namespace mapnik { namespace mapnik {
color::color( std::string const& css_string) color::color( std::string const& css_string)
@ -81,5 +93,90 @@ std::string color::to_hex_string() const
} }
} }
/****************************************************************************/
void color_factory::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();
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
#if BOOST_VERSION >= 104500
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 + "'");
}
#else
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);
#endif
}
bool color_factory::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();
// boost 1.41 -> 1.44 compatibility, to be removed in mapnik 2.1 (dane)
#if BOOST_VERSION >= 104500
bool result =
boost::spirit::qi::phrase_parse(first,
last,
g,
boost::spirit::ascii::space,
c);
return result && (first == last);
#else
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;
#endif
}
color color_factory::from_string(std::string const& css_color)
{
color c;
init_from_string(c, css_color);
return c;
}
} }

55
src/config_error.cpp Normal file
View file

@ -0,0 +1,55 @@
#include <mapnik/config_error.hpp>
#include <mapnik/xml_tree.hpp>
namespace mapnik
{
config_error::config_error(std::string const& what)
: what_(what), line_number_(0), file_(), node_name_(), msg_()
{
}
config_error::config_error(std::string const& what, xml_node const& node)
: what_(what), line_number_(node.line()), file_(node.filename()), node_name_(node.name()), msg_()
{
}
config_error::config_error(std::string const& what, unsigned line_number, std::string const& filename)
: what_(what), line_number_(line_number), file_(filename), node_name_(), msg_()
{
}
char const* config_error::what() const throw()
{
std::stringstream s;
s << file_;
if (line_number_ > 0) s << " line " << line_number_;
if (!node_name_.empty()) s << " in node "<< node_name_;
if (line_number_ > 0 || !file_.empty()) s << ": ";
s << what_;
msg_ = s.str(); //Avoid returning pointer to dead object
return msg_.c_str();
}
void config_error::append_context(std::string const& ctx) const
{
what_ += " " + ctx;
}
void config_error::append_context(std::string const& ctx, xml_node const& node) const
{
append_context(ctx);
append_context(node);
}
void config_error::append_context(xml_node const& node) const
{
if (!line_number_) line_number_ = node.line();
if (node_name_.empty()) node_name_ = node.name();
if (file_.empty()) file_ = node.filename();
}
}

View file

@ -23,21 +23,21 @@
// boost // boost
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \ #define BOOST_SPIRIT_AUTO(domain_, name, expr) \
typedef boost::proto::result_of:: \ typedef boost::proto::result_of:: \
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \ deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
BOOST_SPIRIT_ASSERT_MATCH( \ BOOST_SPIRIT_ASSERT_MATCH( \
boost::spirit::domain_::domain, name##_expr_type); \ boost::spirit::domain_::domain, name##_expr_type); \
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \ BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
namespace mapnik { namespace conversions { namespace mapnik { namespace util {
using namespace boost::spirit; using namespace boost::spirit;
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_); BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_)
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_); BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_)
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_); BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_)
bool string2int(const char * value, int & result) bool string2int(const char * value, int & result)
{ {

View file

@ -24,6 +24,7 @@
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/config_error.hpp> #include <mapnik/config_error.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/expression_grammar.hpp>
// boost // boost
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -50,8 +51,8 @@ expression_ptr expression_factory::compile(std::string const& str,transcoder con
} }
bool expression_factory::parse_from_string(expression_ptr const& expr, bool expression_factory::parse_from_string(expression_ptr const& expr,
std::string const& str, std::string const& str,
mapnik::expression_grammar<std::string::const_iterator> const& g) mapnik::expression_grammar<std::string::const_iterator> const& g)
{ {
std::string::const_iterator itr = str.begin(); std::string::const_iterator itr = str.begin();
std::string::const_iterator end = str.end(); std::string::const_iterator end = str.end();

View file

@ -112,7 +112,7 @@ void feature_style_processor<Processor>::apply()
BOOST_FOREACH ( layer const& lyr, m_.layers() ) BOOST_FOREACH ( layer const& lyr, m_.layers() )
{ {
if (lyr.isVisible(scale_denom)) if (lyr.visible(scale_denom))
{ {
std::set<std::string> names; std::set<std::string> names;
apply_to_layer(lyr, p, proj, scale_denom, names); apply_to_layer(lyr, p, proj, scale_denom, names);
@ -146,7 +146,7 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::se
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic()); double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
scale_denom *= scale_factor_; scale_denom *= scale_factor_;
if (lyr.isVisible(scale_denom)) if (lyr.visible(scale_denom))
{ {
apply_to_layer(lyr, p, proj, scale_denom, names); apply_to_layer(lyr, p, proj, scale_denom, names);
} }
@ -203,7 +203,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
return; return;
} }
p.start_layer_processing(lay);
#if defined(RENDERING_STATS) #if defined(RENDERING_STATS)
progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'"); progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'");
@ -248,9 +248,11 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
layer_ext.clip(map_ext); layer_ext.clip(map_ext);
// forward project layer extent back into native projection // forward project layer extent back into native projection
if (!prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS)) if (!prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS))
{
std::clog << "WARNING: layer " << lay.name() std::clog << "WARNING: layer " << lay.name()
<< " extent " << layer_ext << " in map projection " << " extent " << layer_ext << " in map projection "
<< " did not reproject properly back to layer projection\n"; << " did not reproject properly back to layer projection\n";
}
} }
else else
{ {
@ -262,13 +264,14 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
box2d<double> query_ext = m_.get_current_extent(); box2d<double> query_ext = m_.get_current_extent();
box2d<double> unbuffered_extent = m_.get_current_extent();
prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS); prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS);
query::resolution_type res(m_.width()/query_ext.width(), double qw = query_ext.width()>0 ? query_ext.width() : 1;
m_.height()/query_ext.height()); double qh = query_ext.height()>0 ? query_ext.height() : 1;
query::resolution_type res(m_.width()/qw,
query q(layer_ext,res,scale_denom,unbuffered_extent); m_.height()/qh);
query q(layer_ext,res,scale_denom,m_.get_current_extent());
p.start_layer_processing(lay, query_ext);
std::vector<feature_type_style*> active_styles; std::vector<feature_type_style*> active_styles;
attribute_collector collector(names); attribute_collector collector(names);
double filt_factor = 1; double filt_factor = 1;

View file

@ -30,6 +30,7 @@
// boost // boost
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>
#include <sstream> #include <sstream>
// icu // icu
@ -70,11 +71,10 @@ bool freetype_engine::is_font_file(std::string const& file_name)
bool freetype_engine::register_font(std::string const& file_name) bool freetype_engine::register_font(std::string const& file_name)
{ {
if (!boost::filesystem::is_regular_file(file_name) || !is_font_file(file_name)) return false;
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
mutex::scoped_lock lock(mutex_); mutex::scoped_lock lock(mutex_);
#endif #endif
FT_Library library; FT_Library library = 0;
FT_Error error = FT_Init_FreeType(&library); FT_Error error = FT_Init_FreeType(&library);
if (error) if (error)
{ {
@ -82,36 +82,47 @@ bool freetype_engine::register_font(std::string const& file_name)
} }
FT_Face face = 0; FT_Face face = 0;
int num_faces = 0;
bool success = false;
// some font files have multiple fonts in a file // some font files have multiple fonts in a file
// the count is in the 'root' face library[0] // the count is in the 'root' face library[0]
// see the FT_FaceRec in freetype.h // see the FT_FaceRec in freetype.h
for ( int i = 0; face == 0 || i < face->num_faces; i++ ) { for ( int i = 0; face == 0 || i < num_faces; i++ ) {
// if face is null then this is the first face // if face is null then this is the first face
error = FT_New_Face (library,file_name.c_str(),i,&face); error = FT_New_Face (library,file_name.c_str(),i,&face);
if (error) if (error)
{ {
FT_Done_FreeType(library); break;
return false;
} }
// store num_faces locally, after FT_Done_Face it can not be accessed any more
if (!num_faces)
num_faces = face->num_faces;
// some fonts can lack names, skip them // some fonts can lack names, skip them
// http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec
if (face->family_name && face->style_name) { if (face->family_name && face->style_name)
{
success = true;
std::string name = std::string(face->family_name) + " " + std::string(face->style_name); std::string name = std::string(face->family_name) + " " + std::string(face->style_name);
name2file_.insert(std::make_pair(name, std::make_pair(i,file_name))); name2file_.insert(std::make_pair(name, std::make_pair(i,file_name)));
FT_Done_Face(face); }
//FT_Done_FreeType(library); else
//return true; {
} else {
FT_Done_Face(face);
FT_Done_FreeType(library);
std::ostringstream s; std::ostringstream s;
s << "Error: unable to load invalid font file which lacks identifiable family and style name: '" s << "Warning: unable to load font file '" << file_name << "' ";
<< file_name << "'"; if (!face->family_name && !face->style_name)
throw std::runtime_error(s.str()); s << "which lacks both a family name and style name";
else if (face->family_name)
s << "which reports a family name of '" << std::string(face->family_name) << "' and lacks a style name";
else if (face->style_name)
s << "which reports a style name of '" << std::string(face->style_name) << "' and lacks a family name";
std::clog << s.str() << std::endl;
} }
} }
FT_Done_FreeType(library); if (face)
return true; FT_Done_Face(face);
if (library)
FT_Done_FreeType(library);
return success;
} }
bool freetype_engine::register_fonts(std::string const& dir, bool recurse) bool freetype_engine::register_fonts(std::string const& dir, bool recurse)
@ -125,26 +136,24 @@ bool freetype_engine::register_fonts(std::string const& dir, bool recurse)
return mapnik::freetype_engine::register_font(dir); return mapnik::freetype_engine::register_font(dir);
boost::filesystem::directory_iterator end_itr; boost::filesystem::directory_iterator end_itr;
bool success = false;
for (boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr) for (boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr)
{ {
#if (BOOST_FILESYSTEM_VERSION == 3)
std::string const& file_name = itr->path().string();
#else // v2
std::string const& file_name = itr->string();
#endif
if (boost::filesystem::is_directory(*itr) && recurse) if (boost::filesystem::is_directory(*itr) && recurse)
{ {
#if (BOOST_FILESYSTEM_VERSION == 3) success = register_fonts(file_name, true);
if (!register_fonts(itr->path().string(), true)) return false;
#else // v2
if (!register_fonts(itr->string(), true)) return false;
#endif
} }
else else if (boost::filesystem::is_regular_file(file_name) && is_font_file(file_name))
{ {
#if (BOOST_FILESYSTEM_VERSION == 3) success = mapnik::freetype_engine::register_font(file_name);
mapnik::freetype_engine::register_font(itr->path().string());
#else // v2
mapnik::freetype_engine::register_font(itr->string());
#endif
} }
} }
return true; return success;
} }
@ -178,7 +187,7 @@ face_ptr freetype_engine::create_face(std::string const& family_name)
&face); &face);
if (!error) if (!error)
{ {
return face_ptr (new font_face(face)); return boost::make_shared<font_face>(face);
} }
} }
return face_ptr(); return face_ptr();
@ -190,7 +199,7 @@ stroker_ptr freetype_engine::create_stroker()
FT_Error error = FT_Stroker_New(library_, &s); FT_Error error = FT_Stroker_New(library_, &s);
if (!error) if (!error)
{ {
return stroker_ptr(new stroker(s)); return boost::make_shared<stroker>(s);
} }
return stroker_ptr(); return stroker_ptr();
} }

View file

@ -23,6 +23,7 @@
#include <mapnik/formatting/base.hpp> #include <mapnik/formatting/base.hpp>
#include <mapnik/formatting/list.hpp> #include <mapnik/formatting/list.hpp>
#include <mapnik/formatting/registry.hpp> #include <mapnik/formatting/registry.hpp>
#include <mapnik/xml_node.hpp>
// boost // boost
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
@ -38,18 +39,18 @@ void node::to_xml(boost::property_tree::ptree &xml) const
#endif #endif
} }
node_ptr node::from_xml(boost::property_tree::ptree const& xml) node_ptr node::from_xml(xml_node const& xml)
{ {
list_node *list = new list_node(); list_node *list = new list_node();
node_ptr list_ptr(list); node_ptr list_ptr(list);
boost::property_tree::ptree::const_iterator itr = xml.begin(); xml_node::const_iterator itr = xml.begin();
boost::property_tree::ptree::const_iterator end = xml.end(); xml_node::const_iterator end = xml.end();
for (; itr != end; ++itr) { for (; itr != end; ++itr) {
if (itr->first == "<xmlcomment>" || itr->first == "<xmlattr>" || itr->first == "Placement") if (itr->name() == "Placement")
{ {
continue; continue;
} }
node_ptr n = registry::instance()->from_xml(itr->first, itr->second); node_ptr n = registry::instance()->from_xml(*itr);
if (n) list->push_back(n); if (n) list->push_back(n);
} }
if (list->get_children().size() == 1) { if (list->get_children().size() == 1) {

View file

@ -27,6 +27,7 @@
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/text_properties.hpp> #include <mapnik/text_properties.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/xml_node.hpp>
// boost // boost
@ -37,7 +38,7 @@ namespace formatting
using boost::property_tree::ptree; using boost::property_tree::ptree;
void expression_format::to_xml(boost::property_tree::ptree &xml) const void expression_format::to_xml(boost::property_tree::ptree &xml) const
{ {
ptree &new_node = xml.push_back(ptree::value_type("Format", ptree()))->second; ptree &new_node = xml.push_back(ptree::value_type("ExpressionFormat", ptree()))->second;
if (face_name) set_attr(new_node, "face-name", to_expression_string(*face_name)); if (face_name) set_attr(new_node, "face-name", to_expression_string(*face_name));
if (text_size) set_attr(new_node, "size", to_expression_string(*text_size)); if (text_size) set_attr(new_node, "size", to_expression_string(*text_size));
if (character_spacing) set_attr(new_node, "character-spacing", to_expression_string*character_spacing); if (character_spacing) set_attr(new_node, "character-spacing", to_expression_string*character_spacing);
@ -51,7 +52,7 @@ void expression_format::to_xml(boost::property_tree::ptree &xml) const
if (child_) child_->to_xml(new_node); if (child_) child_->to_xml(new_node);
} }
node_ptr expression_format::from_xml(ptree const& xml) node_ptr expression_format::from_xml(xml_node const& xml)
{ {
expression_format *n = new expression_format(); expression_format *n = new expression_format();
node_ptr np(n); node_ptr np(n);
@ -72,9 +73,9 @@ node_ptr expression_format::from_xml(ptree const& xml)
return np; return np;
} }
expression_ptr expression_format::get_expression(ptree const& xml, std::string name) expression_ptr expression_format::get_expression(xml_node const& xml, std::string name)
{ {
boost::optional<std::string> tmp = get_opt_attr<std::string>(xml, name); boost::optional<std::string> tmp = xml.get_opt_attr<std::string>(name);
if (tmp) return parse_expression(*tmp); if (tmp) return parse_expression(*tmp);
return expression_ptr(); return expression_ptr();
} }
@ -84,25 +85,25 @@ void expression_format::apply(char_properties const& p, const Feature &feature,
{ {
char_properties new_properties = p; char_properties new_properties = p;
if (face_name) new_properties.face_name = if (face_name) new_properties.face_name =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *face_name).to_string(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *face_name).to_string();
if (text_size) new_properties.text_size = if (text_size) new_properties.text_size =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_size).to_double(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_size).to_double();
if (character_spacing) new_properties.character_spacing = if (character_spacing) new_properties.character_spacing =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_double(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_double();
if (line_spacing) new_properties.line_spacing = if (line_spacing) new_properties.line_spacing =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *line_spacing).to_double(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *line_spacing).to_double();
if (text_opacity) new_properties.text_opacity = if (text_opacity) new_properties.text_opacity =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_opacity).to_double(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_opacity).to_double();
if (wrap_before) new_properties.wrap_before = if (wrap_before) new_properties.wrap_before =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *wrap_before).to_bool(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *wrap_before).to_bool();
if (wrap_char) new_properties.wrap_char = if (wrap_char) new_properties.wrap_char =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_unicode()[0]; boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_unicode()[0];
// if (fill) new_properties.fill = // if (fill) new_properties.fill =
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *fill).to_color(); // boost::apply_visitor(evaluate<Feature,value_type>(feature), *fill).to_color();
// if (halo_fill) new_properties.halo_fill = // if (halo_fill) new_properties.halo_fill =
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_fill).to_color(); // boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_fill).to_color();
if (halo_radius) new_properties.halo_radius = if (halo_radius) new_properties.halo_radius =
boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_radius).to_double(); boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_radius).to_double();
if (child_) { if (child_) {
child_->apply(new_properties, feature, output); child_->apply(new_properties, feature, output);

View file

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
#include <mapnik/formatting/format.hpp> #include <mapnik/formatting/format.hpp>
#include <mapnik/ptree_helpers.hpp> #include <mapnik/ptree_helpers.hpp>
#include <mapnik/xml_node.hpp>
namespace mapnik { namespace mapnik {
using boost::property_tree::ptree; using boost::property_tree::ptree;
@ -44,7 +45,7 @@ void format_node::to_xml(ptree &xml) const
} }
node_ptr format_node::from_xml(ptree const& xml) node_ptr format_node::from_xml(xml_node const& xml)
{ {
format_node *n = new format_node(); format_node *n = new format_node();
node_ptr np(n); node_ptr np(n);
@ -52,19 +53,19 @@ node_ptr format_node::from_xml(ptree const& xml)
node_ptr child = node::from_xml(xml); node_ptr child = node::from_xml(xml);
n->set_child(child); n->set_child(child);
n->face_name = get_opt_attr<std::string>(xml, "face-name"); n->face_name = xml.get_opt_attr<std::string>("face-name");
/*TODO: Fontset is problematic. We don't have the fontsets pointer here... */ /*TODO: Fontset is problematic. We don't have the fontsets pointer here... */
n->text_size = get_opt_attr<unsigned>(xml, "size"); n->text_size = xml.get_opt_attr<unsigned>("size");
n->character_spacing = get_opt_attr<unsigned>(xml, "character-spacing"); n->character_spacing = xml.get_opt_attr<unsigned>("character-spacing");
n->line_spacing = get_opt_attr<unsigned>(xml, "line-spacing"); n->line_spacing = xml.get_opt_attr<unsigned>("line-spacing");
n->text_opacity = get_opt_attr<double>(xml, "opactity"); n->text_opacity = xml.get_opt_attr<double>("opactity");
boost::optional<boolean> wrap = get_opt_attr<boolean>(xml, "wrap-before"); boost::optional<boolean> wrap = xml.get_opt_attr<boolean>("wrap-before");
if (wrap) n->wrap_before = *wrap; if (wrap) n->wrap_before = *wrap;
n->wrap_char = get_opt_attr<unsigned>(xml, "wrap-character"); n->wrap_char = xml.get_opt_attr<unsigned>("wrap-character");
n->text_transform = get_opt_attr<text_transform_e>(xml, "text-transform"); n->text_transform = xml.get_opt_attr<text_transform_e>("text-transform");
n->fill = get_opt_attr<color>(xml, "fill"); n->fill = xml.get_opt_attr<color>("fill");
n->halo_fill = get_opt_attr<color>(xml, "halo-fill"); n->halo_fill = xml.get_opt_attr<color>("halo-fill");
n->halo_radius = get_opt_attr<double>(xml, "halo-radius"); n->halo_radius = xml.get_opt_attr<double>("halo-radius");
return np; return np;
} }

View file

@ -24,6 +24,8 @@
#include <mapnik/formatting/text.hpp> #include <mapnik/formatting/text.hpp>
#include <mapnik/formatting/format.hpp> #include <mapnik/formatting/format.hpp>
#include <mapnik/formatting/expression.hpp> #include <mapnik/formatting/expression.hpp>
#include <mapnik/xml_node.hpp>
#include <mapnik/config_error.hpp>
namespace mapnik namespace mapnik
{ {
@ -46,10 +48,11 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o
} }
} }
node_ptr registry::from_xml(std::string name, const boost::property_tree::ptree &xml) node_ptr registry::from_xml(xml_node const& xml)
{ {
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(name); std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(xml.name());
if (itr == map_.end()) throw config_error("Unknown element '" + name + "'"); if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'", xml);
xml.set_processed(true);
return itr->second(xml); return itr->second(xml);
} }
} //ns formatting } //ns formatting

View file

@ -26,9 +26,7 @@
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/text_properties.hpp> #include <mapnik/text_properties.hpp>
#include <mapnik/processed_text.hpp> #include <mapnik/processed_text.hpp>
#include <mapnik/xml_node.hpp>
// boost
#include <boost/algorithm/string.hpp>
namespace mapnik namespace mapnik
{ {
@ -45,12 +43,11 @@ void text_node::to_xml(ptree &xml) const
} }
node_ptr text_node::from_xml(boost::property_tree::ptree const& xml) node_ptr text_node::from_xml(xml_node const& xml)
{ {
std::string data = xml.data(); std::string data = xml.text();
boost::trim(data);
if (data.empty()) return node_ptr(); //No text if (data.empty()) return node_ptr(); //No text
return node_ptr(new text_node(parse_expression(data, "utf8"))); return boost::make_shared<text_node>(parse_expression(data, "utf8"));
} }
void text_node::apply(char_properties const& p, Feature const& feature, processed_text &output) const void text_node::apply(char_properties const& p, Feature const& feature, processed_text &output) const

View file

@ -29,9 +29,9 @@
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/font_set.hpp> #include <mapnik/font_set.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
@ -97,11 +97,12 @@ void grid_renderer<T>::end_map_processing(Map const& )
} }
template <typename T> template <typename T>
void grid_renderer<T>::start_layer_processing(layer const& lay) void grid_renderer<T>::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
{ {
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "start layer processing : " << lay.name() << "\n"; std::clog << "start layer processing : " << lay.name() << "\n";
std::clog << "datasource = " << lay.datasource().get() << "\n"; std::clog << "datasource = " << lay.datasource().get() << "\n";
std::clog << "query_extent = " << query_extent << "\n";
#endif #endif
if (lay.clear_label_cache()) if (lay.clear_label_cache())
{ {
@ -144,7 +145,7 @@ void grid_renderer<T>::render_marker(mapnik::feature_ptr const& feature, unsigne
mtx *= agg::trans_affine_scaling(scale_factor_*(1.0/step)); mtx *= agg::trans_affine_scaling(scale_factor_*(1.0/step));
// render the marker at the center of the marker box // render the marker at the center of the marker box
mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height()); mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height());
using namespace mapnik::svg;
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source()); vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer<svg_path_adapter, svg_renderer<svg_path_adapter,

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