Merge branch 'master' into conv_simplify

This commit is contained in:
artemp 2012-09-17 11:35:15 +01:00
commit 01ae1a179d
33 changed files with 284 additions and 215 deletions

View file

@ -8,6 +8,8 @@ For a complete change history, see the git log.
## Future ## Future
- Allow style level compositing operations to work outside of featureset extents across tiled requests (#1477)
- Support for encoding `literal` postgres types as strings 69fb17cd3/#1466 - Support for encoding `literal` postgres types as strings 69fb17cd3/#1466
- Fixed zoom_all behavior when Map maximum-extent is provided. Previously maximum-extent was used outright but - Fixed zoom_all behavior when Map maximum-extent is provided. Previously maximum-extent was used outright but

View file

@ -703,8 +703,8 @@ class _TextSymbolizer(TextSymbolizer,_injector):
if isinstance(self.properties.format_tree, FormattingText): if isinstance(self.properties.format_tree, FormattingText):
return self.properties.format_tree.text return self.properties.format_tree.text
else: else:
return None # This text symbolizer is using complex formatting features.
# There is no single expression which could be returned as name # There is no single expression which could be returned as name
raise RuntimeError("TextSymbolizer uses complex formatting features, but old compatibility interface is used to access it. Use self.properties.format_tree instead.")
@name.setter @name.setter
def name(self, name): def name(self, name):
@ -712,415 +712,287 @@ class _TextSymbolizer(TextSymbolizer,_injector):
@property @property
def text_size(self): def text_size(self):
warnings.warn("'text_size' is deprecated, use format.text_size",
DeprecationWarning, 2)
return self.format.text_size return self.format.text_size
@text_size.setter @text_size.setter
def text_size(self, text_size): def text_size(self, text_size):
warnings.warn("'text_size' is deprecated, use format.text_size",
DeprecationWarning, 2)
self.format.text_size = text_size self.format.text_size = text_size
@property @property
def face_name(self): def face_name(self):
warnings.warn("'face_name' is deprecated, use format.face_name",
DeprecationWarning, 2)
return self.format.face_name return self.format.face_name
@face_name.setter @face_name.setter
def face_name(self, face_name): def face_name(self, face_name):
warnings.warn("'face_name' is deprecated, use format.face_name",
DeprecationWarning, 2)
self.format.face_name = face_name self.format.face_name = face_name
@property @property
def fontset(self): def fontset(self):
warnings.warn("'fontset' is deprecated, use format.fontset",
DeprecationWarning, 2)
return self.format.fontset return self.format.fontset
@fontset.setter @fontset.setter
def fontset(self, fontset): def fontset(self, fontset):
warnings.warn("'fontset' is deprecated, use format.fontset",
DeprecationWarning, 2)
self.format.fontset = fontset self.format.fontset = fontset
@property @property
def character_spacing(self): def character_spacing(self):
warnings.warn("'character_spacing' is deprecated, use format.character_spacing",
DeprecationWarning, 2)
return self.format.character_spacing return self.format.character_spacing
@character_spacing.setter @character_spacing.setter
def character_spacing(self, character_spacing): def character_spacing(self, character_spacing):
warnings.warn("'character_spacing' is deprecated, use format.character_spacing",
DeprecationWarning, 2)
self.format.character_spacing = character_spacing self.format.character_spacing = character_spacing
@property @property
def line_spacing(self): def line_spacing(self):
warnings.warn("'line_spacing' is deprecated, use format.line_spacing",
DeprecationWarning, 2)
return self.format.line_spacing return self.format.line_spacing
@line_spacing.setter @line_spacing.setter
def line_spacing(self, line_spacing): def line_spacing(self, line_spacing):
warnings.warn("'line_spacing' is deprecated, use format.line_spacing",
DeprecationWarning, 2)
self.format.line_spacing = line_spacing self.format.line_spacing = line_spacing
@property @property
def text_opacity(self): def text_opacity(self):
warnings.warn("'text_opacity' is deprecated, use format.text_opacity",
DeprecationWarning, 2)
return self.format.text_opacity return self.format.text_opacity
@text_opacity.setter @text_opacity.setter
def text_opacity(self, text_opacity): def text_opacity(self, text_opacity):
warnings.warn("'text_opacity' is deprecated, use format.text_opacity",
DeprecationWarning, 2)
self.format.text_opacity = text_opacity self.format.text_opacity = text_opacity
@property @property
def wrap_char(self): def wrap_char(self):
warnings.warn("'wrap_char' is deprecated, use format.wrap_char",
DeprecationWarning, 2)
return self.format.wrap_char return self.format.wrap_char
@wrap_char.setter @wrap_char.setter
def wrap_char(self, wrap_char): def wrap_char(self, wrap_char):
warnings.warn("'wrap_char' is deprecated, use format.wrap_char",
DeprecationWarning, 2)
self.format.wrap_char = wrap_char self.format.wrap_char = wrap_char
@property @property
def wrap_character(self): def wrap_character(self):
warnings.warn("'wrap_character' is deprecated, use format.wrap_character",
DeprecationWarning, 2)
return self.format.wrap_character return self.format.wrap_character
@wrap_char.setter @wrap_char.setter
def wrap_character(self, wrap_character): def wrap_character(self, wrap_character):
warnings.warn("'wrap_char' is deprecated, use format.wrap_character",
DeprecationWarning, 2)
self.format.wrap_character = wrap_character self.format.wrap_character = wrap_character
@property @property
def wrap_before(self): def wrap_before(self):
warnings.warn("'wrap_before' is deprecated, use format.wrap_before", return self.properties.wrap_before
DeprecationWarning, 2)
return self.format.wrap_before
@wrap_before.setter @wrap_before.setter
def wrap_before(self, wrap_before): def wrap_before(self, wrap_before):
warnings.warn("'wrap_before' is deprecated, use format.wrap_before", self.properties.wrap_before = wrap_before
DeprecationWarning, 2)
self.format.wrap_before = wrap_before
@property @property
def text_transform(self): def text_transform(self):
warnings.warn("'text_transform' is deprecated, use format.text_transform",
DeprecationWarning, 2)
return self.format.text_transform return self.format.text_transform
@text_transform.setter @text_transform.setter
def text_transform(self, text_transform): def text_transform(self, text_transform):
warnings.warn("'text_transform' is deprecated, use format.text_transform",
DeprecationWarning, 2)
self.format.text_transform = text_transform self.format.text_transform = text_transform
@property @property
def fill(self): def fill(self):
warnings.warn("'fill' is deprecated, use format.fill",
DeprecationWarning, 2)
return self.format.fill return self.format.fill
@fill.setter @fill.setter
def fill(self, fill): def fill(self, fill):
warnings.warn("'fill' is deprecated, use format.fill",
DeprecationWarning, 2)
self.format.fill = fill self.format.fill = fill
@property @property
def halo_fill(self): def halo_fill(self):
warnings.warn("'halo_fill' is deprecated, use format.halo_fill",
DeprecationWarning, 2)
return self.format.halo_fill return self.format.halo_fill
@halo_fill.setter @halo_fill.setter
def halo_fill(self, halo_fill): def halo_fill(self, halo_fill):
warnings.warn("'halo_fill' is deprecated, use format.halo_fill",
DeprecationWarning, 2)
self.format.halo_fill = halo_fill self.format.halo_fill = halo_fill
@property @property
def halo_radius(self): def halo_radius(self):
warnings.warn("'halo_radius' is deprecated, use format.halo_radius",
DeprecationWarning, 2)
return self.format.halo_radius return self.format.halo_radius
@halo_radius.setter @halo_radius.setter
def halo_radius(self, halo_radius): def halo_radius(self, halo_radius):
warnings.warn("'halo_radius' is deprecated, use format.halo_radius",
DeprecationWarning, 2)
self.format.halo_radius = halo_radius self.format.halo_radius = halo_radius
@property @property
def label_placement(self): def label_placement(self):
warnings.warn("'label_placement' is deprecated, use properties.label_placement",
DeprecationWarning, 2)
return self.properties.label_placement return self.properties.label_placement
@label_placement.setter @label_placement.setter
def label_placement(self, label_placement): def label_placement(self, label_placement):
warnings.warn("'label_placement' is deprecated, use properties.label_placement",
DeprecationWarning, 2)
self.properties.label_placement = label_placement self.properties.label_placement = label_placement
@property @property
def horizontal_alignment(self): def horizontal_alignment(self):
warnings.warn("'horizontal_alignment' is deprecated, use properties.horizontal_alignment",
DeprecationWarning, 2)
return self.properties.horizontal_alignment return self.properties.horizontal_alignment
@horizontal_alignment.setter @horizontal_alignment.setter
def horizontal_alignment(self, horizontal_alignment): def horizontal_alignment(self, horizontal_alignment):
warnings.warn("'horizontal_alignment' is deprecated, use properties.horizontal_alignment",
DeprecationWarning, 2)
self.properties.horizontal_alignment = horizontal_alignment self.properties.horizontal_alignment = horizontal_alignment
@property @property
def justify_alignment(self): def justify_alignment(self):
warnings.warn("'justify_alignment' is deprecated, use properties.justify_alignment",
DeprecationWarning, 2)
return self.properties.justify_alignment return self.properties.justify_alignment
@justify_alignment.setter @justify_alignment.setter
def justify_alignment(self, justify_alignment): def justify_alignment(self, justify_alignment):
warnings.warn("'justify_alignment' is deprecated, use properties.justify_alignment",
DeprecationWarning, 2)
self.properties.justify_alignment = justify_alignment self.properties.justify_alignment = justify_alignment
@property @property
def vertical_alignment(self): def vertical_alignment(self):
warnings.warn("'vertical_alignment' is deprecated, use properties.vertical_alignment",
DeprecationWarning, 2)
return self.properties.vertical_alignment return self.properties.vertical_alignment
@vertical_alignment.setter @vertical_alignment.setter
def vertical_alignment(self, vertical_alignment): def vertical_alignment(self, vertical_alignment):
warnings.warn("'vertical_alignment' is deprecated, use properties.vertical_alignment",
DeprecationWarning, 2)
self.properties.vertical_alignment = vertical_alignment self.properties.vertical_alignment = vertical_alignment
@property @property
def orientation(self): def orientation(self):
warnings.warn("'orientation' is deprecated, use properties.orientation",
DeprecationWarning, 2)
return self.properties.orientation return self.properties.orientation
@orientation.setter @orientation.setter
def orientation(self, orientation): def orientation(self, orientation):
warnings.warn("'orientation' is deprecated, use properties.orientation",
DeprecationWarning, 2)
self.properties.orientation = orientation self.properties.orientation = orientation
@property @property
def displacement(self): def displacement(self):
warnings.warn("'displacement' is deprecated, use properties.displacement",
DeprecationWarning, 2)
return self.properties.displacement return self.properties.displacement
@displacement.setter @displacement.setter
def displacement(self, displacement): def displacement(self, displacement):
warnings.warn("'displacement' is deprecated, use properties.displacement",
DeprecationWarning, 2)
self.properties.displacement = displacement self.properties.displacement = displacement
@property @property
def label_spacing(self): def label_spacing(self):
warnings.warn("'label_spacing' is deprecated, use properties.label_spacing",
DeprecationWarning, 2)
return self.properties.label_spacing return self.properties.label_spacing
@label_spacing.setter @label_spacing.setter
def label_spacing(self, label_spacing): def label_spacing(self, label_spacing):
warnings.warn("'label_spacing' is deprecated, use properties.label_spacing",
DeprecationWarning, 2)
self.properties.label_spacing = label_spacing self.properties.label_spacing = label_spacing
@property @property
def label_position_tolerance(self): def label_position_tolerance(self):
warnings.warn("'label_position_tolerance' is deprecated, use properties.label_position_tolerance",
DeprecationWarning, 2)
return self.properties.label_position_tolerance return self.properties.label_position_tolerance
@label_position_tolerance.setter @label_position_tolerance.setter
def label_position_tolerance(self, label_position_tolerance): def label_position_tolerance(self, label_position_tolerance):
warnings.warn("'label_position_tolerance' is deprecated, use properties.label_position_tolerance",
DeprecationWarning, 2)
self.properties.label_position_tolerance = label_position_tolerance self.properties.label_position_tolerance = label_position_tolerance
@property @property
def avoid_edges(self): def avoid_edges(self):
warnings.warn("'avoid_edges' is deprecated, use properties.avoid_edges",
DeprecationWarning, 2)
return self.properties.avoid_edges return self.properties.avoid_edges
@avoid_edges.setter @avoid_edges.setter
def avoid_edges(self, avoid_edges): def avoid_edges(self, avoid_edges):
warnings.warn("'avoid_edges' is deprecated, use properties.avoid_edges",
DeprecationWarning, 2)
self.properties.avoid_edges = avoid_edges self.properties.avoid_edges = avoid_edges
@property @property
def minimum_distance(self): def minimum_distance(self):
warnings.warn("'minimum_distance' is deprecated, use properties.minimum_distance",
DeprecationWarning, 2)
return self.properties.minimum_distance return self.properties.minimum_distance
@minimum_distance.setter @minimum_distance.setter
def minimum_distance(self, minimum_distance): def minimum_distance(self, minimum_distance):
warnings.warn("'minimum_distance' is deprecated, use properties.minimum_distance",
DeprecationWarning, 2)
self.properties.minimum_distance = minimum_distance self.properties.minimum_distance = minimum_distance
@property @property
def minimum_padding(self): def minimum_padding(self):
warnings.warn("'minimum_padding' is deprecated, use properties.minimum_padding",
DeprecationWarning, 2)
return self.properties.minimum_padding return self.properties.minimum_padding
@minimum_padding.setter @minimum_padding.setter
def minimum_padding(self, minimum_padding): def minimum_padding(self, minimum_padding):
warnings.warn("'minimum_padding' is deprecated, use properties.minimum_padding",
DeprecationWarning, 2)
self.properties.minimum_padding = minimum_padding self.properties.minimum_padding = minimum_padding
@property @property
def minimum_path_length(self): def minimum_path_length(self):
warnings.warn("'minimum_path_length' is deprecated, use properties.minimum_path_length",
DeprecationWarning, 2)
return self.properties.minimum_path_length return self.properties.minimum_path_length
@minimum_path_length.setter @minimum_path_length.setter
def minimum_path_length(self, minimum_path_length): def minimum_path_length(self, minimum_path_length):
warnings.warn("'minimum_path_length' is deprecated, use properties.minimum_path_length",
DeprecationWarning, 2)
self.properties.minimum_path_length = minimum_path_length self.properties.minimum_path_length = minimum_path_length
@property @property
def maximum_angle_char_delta(self): def maximum_angle_char_delta(self):
warnings.warn("'maximum_angle_char_delta' is deprecated, use properties.maximum_angle_char_delta",
DeprecationWarning, 2)
return self.properties.maximum_angle_char_delta return self.properties.maximum_angle_char_delta
@maximum_angle_char_delta.setter @maximum_angle_char_delta.setter
def maximum_angle_char_delta(self, maximum_angle_char_delta): def maximum_angle_char_delta(self, maximum_angle_char_delta):
warnings.warn("'maximum_angle_char_delta' is deprecated, use properties.maximum_angle_char_delta",
DeprecationWarning, 2)
self.properties.maximum_angle_char_delta = maximum_angle_char_delta self.properties.maximum_angle_char_delta = maximum_angle_char_delta
@property @property
def force_odd_labels(self): def force_odd_labels(self):
warnings.warn("'force_odd_labels' is deprecated, use properties.force_odd_labels",
DeprecationWarning, 2)
return self.properties.force_odd_labels return self.properties.force_odd_labels
@force_odd_labels.setter @force_odd_labels.setter
def force_odd_labels(self, force_odd_labels): def force_odd_labels(self, force_odd_labels):
warnings.warn("'force_odd_labels' is deprecated, use properties.force_odd_labels",
DeprecationWarning, 2)
self.properties.force_odd_labels = force_odd_labels self.properties.force_odd_labels = force_odd_labels
@property @property
def allow_overlap(self): def allow_overlap(self):
warnings.warn("'allow_overlap' is deprecated, use properties.allow_overlap",
DeprecationWarning, 2)
return self.properties.allow_overlap return self.properties.allow_overlap
@allow_overlap.setter @allow_overlap.setter
def allow_overlap(self, allow_overlap): def allow_overlap(self, allow_overlap):
warnings.warn("'allow_overlap' is deprecated, use properties.allow_overlap",
DeprecationWarning, 2)
self.properties.allow_overlap = allow_overlap self.properties.allow_overlap = allow_overlap
@property @property
def text_ratio(self): def text_ratio(self):
warnings.warn("'text_ratio' is deprecated, use properties.text_ratio",
DeprecationWarning, 2)
return self.properties.text_ratio return self.properties.text_ratio
@text_ratio.setter @text_ratio.setter
def text_ratio(self, text_ratio): def text_ratio(self, text_ratio):
warnings.warn("'text_ratio' is deprecated, use properties.text_ratio",
DeprecationWarning, 2)
self.properties.text_ratio = text_ratio self.properties.text_ratio = text_ratio
@property @property
def wrap_width(self): def wrap_width(self):
warnings.warn("'wrap_width' is deprecated, use properties.wrap_width",
DeprecationWarning, 2)
return self.properties.wrap_width return self.properties.wrap_width
@wrap_width.setter @wrap_width.setter
def wrap_width(self, wrap_width): def wrap_width(self, wrap_width):
warnings.warn("'wrap_width' is deprecated, use properties.wrap_width",
DeprecationWarning, 2)
self.properties.wrap_width = wrap_width self.properties.wrap_width = wrap_width

View file

@ -33,7 +33,12 @@ using mapnik::font_set;
void export_fontset () void export_fontset ()
{ {
using namespace boost::python; using namespace boost::python;
class_<font_set>("FontSet", init<>("default fontset constructor") class_<font_set>("FontSet", init<std::string const&>("default fontset constructor")
)
.add_property("name",
make_function(&font_set::get_name,return_value_policy<copy_const_reference>()),
&font_set::set_name,
"Get/Set the name of the FontSet.\n"
) )
.def("add_face_name",&font_set::add_face_name, .def("add_face_name",&font_set::add_face_name,
(arg("name")), (arg("name")),

View file

@ -617,6 +617,7 @@ BOOST_PYTHON_MODULE(_mapnik)
def("has_pycairo", &has_pycairo, "Get pycairo module status"); def("has_pycairo", &has_pycairo, "Get pycairo module status");
python_optional<mapnik::stroke>(); python_optional<mapnik::stroke>();
python_optional<mapnik::font_set>();
python_optional<mapnik::color>(); python_optional<mapnik::color>();
python_optional<mapnik::box2d<double> >(); python_optional<mapnik::box2d<double> >();
python_optional<mapnik::composite_mode_e>(); python_optional<mapnik::composite_mode_e>();

View file

@ -402,9 +402,9 @@ void export_text_placement()
class_with_converter<char_properties> class_with_converter<char_properties>
("CharProperties") ("CharProperties")
.def_readwrite_convert("text_transform", &char_properties::text_transform) .def_readwrite_convert("text_transform", &char_properties::text_transform)
.def_readwrite_convert("fontset", &char_properties::fontset)
.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("text_size", &char_properties::text_size) .def_readwrite("text_size", &char_properties::text_size)
.def_readwrite("character_spacing", &char_properties::character_spacing) .def_readwrite("character_spacing", &char_properties::character_spacing)
.def_readwrite("line_spacing", &char_properties::line_spacing) .def_readwrite("line_spacing", &char_properties::line_spacing)

View file

@ -106,6 +106,9 @@ public:
void process(markers_symbolizer const& sym, void process(markers_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans); proj_transform const& prj_trans);
void process(debug_symbolizer const& sym,
feature_impl & feature,
proj_transform const& prj_trans);
inline bool process(rule::symbolizers const& /*syms*/, inline bool process(rule::symbolizers const& /*syms*/,
mapnik::feature_impl & /*feature*/, mapnik::feature_impl & /*feature*/,

View file

@ -0,0 +1,39 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_DEBUG_SYMBOLIZER_HPP
#define MAPNIK_DEBUG_SYMBOLIZER_HPP
#include <mapnik/config.hpp>
#include <mapnik/symbolizer.hpp>
namespace mapnik
{
struct MAPNIK_DECL debug_symbolizer :
public symbolizer_base
{
debug_symbolizer() : symbolizer_base() {}
};
}
#endif // DEBUG_SYMBOLIZER_HPP

View file

@ -256,6 +256,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
box2d<double> layer_ext = lay.envelope(); box2d<double> layer_ext = lay.envelope();
bool fw_success = false; bool fw_success = false;
bool early_return = false;
// first, try intersection of map extent forward projected into layer srs // first, try intersection of map extent forward projected into layer srs
if (prj_trans.forward(buffered_query_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext)) if (prj_trans.forward(buffered_query_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
@ -266,10 +267,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
// if no intersection and projections are also equal, early return // if no intersection and projections are also equal, early return
else if (prj_trans.equal()) else if (prj_trans.equal())
{ {
#if defined(RENDERING_STATS) early_return = true;
layer_timer.discard();
#endif
return;
} }
// next try intersection of layer extent back projected into map srs // next try intersection of layer extent back projected into map srs
else if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext)) else if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS) && buffered_query_ext.intersects(layer_ext))
@ -278,7 +276,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
// 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))
{ {
MAPNIK_LOG_DEBUG(feature_style_processor) MAPNIK_LOG_ERROR(feature_style_processor)
<< "feature_style_processor: Layer=" << lay.name() << "feature_style_processor: Layer=" << lay.name()
<< " extent=" << layer_ext << " in map projection " << " extent=" << layer_ext << " in map projection "
<< " did not reproject properly back to layer projection"; << " did not reproject properly back to layer projection";
@ -287,6 +285,31 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
else else
{ {
// if no intersection then nothing to do for layer // if no intersection then nothing to do for layer
early_return = true;
}
if (early_return)
{
// check for styles needing compositing operations applied
// https://github.com/mapnik/mapnik/issues/1477
BOOST_FOREACH(std::string const& style_name, style_names)
{
boost::optional<feature_type_style const&> style=m_.find_style(style_name);
if (!style)
{
continue;
}
if (style->comp_op() || style->image_filters().size() > 0)
{
if (style->active(scale_denom))
{
std::clog << "triggering\n";
// trigger any needed compositing ops
p.start_style_processing(*style);
p.end_style_processing(*style);
}
}
}
#if defined(RENDERING_STATS) #if defined(RENDERING_STATS)
layer_timer.discard(); layer_timer.discard();
#endif #endif
@ -344,9 +367,8 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
continue; continue;
} }
const std::vector<rule>& rules=(*style).get_rules(); std::vector<rule> const& rules=(*style).get_rules();
bool active_rules=false; bool active_rules=false;
BOOST_FOREACH(rule const& r, rules) BOOST_FOREACH(rule const& r, rules)
{ {
if (r.active(scale_denom)) if (r.active(scale_denom))
@ -444,16 +466,16 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
else if (cache_features) else if (cache_features)
{ {
memory_datasource cache;
featureset_ptr features = ds->features(q); featureset_ptr features = ds->features(q);
if (features) { if (features) {
// Cache all features into the memory_datasource before rendering. // Cache all features into the memory_datasource before rendering.
memory_datasource cache;
feature_ptr feature; feature_ptr feature;
while ((feature = features->next())) while ((feature = features->next()))
{ {
cache.push(feature); cache.push(feature);
} }
}
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style * style, active_styles)
{ {
@ -461,18 +483,14 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
cache.features(q), prj_trans, scale_denom); cache.features(q), prj_trans, scale_denom);
} }
} }
}
// We only have a single style and no grouping. // We only have a single style and no grouping.
else else
{ {
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style * style, active_styles)
{ {
featureset_ptr features = ds->features(q);
if (features) {
render_style(lay, p, style, style_names[i++], render_style(lay, p, style, style_names[i++],
features, prj_trans, scale_denom); ds->features(q), prj_trans, scale_denom);
}
} }
} }
} }
@ -495,8 +513,12 @@ void feature_style_processor<Processor>::render_style(
proj_transform const& prj_trans, proj_transform const& prj_trans,
double scale_denom) double scale_denom)
{ {
p.start_style_processing(*style); p.start_style_processing(*style);
if (!features)
{
p.end_style_processing(*style);
return;
}
#if defined(RENDERING_STATS) #if defined(RENDERING_STATS)
std::ostringstream s1; std::ostringstream s1;

View file

@ -72,17 +72,17 @@ public:
feature_type_style& operator=(feature_type_style const& rhs); feature_type_style& operator=(feature_type_style const& rhs);
void add_rule(rule const& rule); void add_rule(rule const& rule);
rules const& get_rules() const; rules const& get_rules() const;
rule_ptrs const& get_if_rules(double scale_denom); rule_ptrs const& get_if_rules(double scale_denom);
rule_ptrs const& get_else_rules(double scale_denom); rule_ptrs const& get_else_rules(double scale_denom);
rule_ptrs const& get_also_rules(double scale_denom); rule_ptrs const& get_also_rules(double scale_denom);
rules& get_rules_nonconst(); rules& get_rules_nonconst();
void set_filter_mode(filter_mode_e mode); bool active(double scale_denom) const;
void set_filter_mode(filter_mode_e mode);
filter_mode_e get_filter_mode() const; filter_mode_e get_filter_mode() const;
// filters // filters
std::vector<filter::filter_type> const& image_filters() const; std::vector<filter::filter_type> const& image_filters() const;
std::vector<filter::filter_type> & image_filters(); std::vector<filter::filter_type> & image_filters();

View file

@ -333,11 +333,11 @@ public:
return face_set; return face_set;
} }
face_set_ptr get_face_set(std::string const& name, font_set const& fset) face_set_ptr get_face_set(std::string const& name, boost::optional<font_set> fset)
{ {
if (fset.size() > 0) if (fset && fset->size() > 0)
{ {
return get_face_set(fset); return get_face_set(*fset);
} }
else else
{ {

View file

@ -35,7 +35,6 @@ namespace mapnik
class MAPNIK_DECL font_set class MAPNIK_DECL font_set
{ {
public: public:
font_set();
font_set(std::string const& name); font_set(std::string const& name);
font_set(font_set const& rhs); font_set(font_set const& rhs);
font_set& operator=(font_set const& rhs); font_set& operator=(font_set const& rhs);

View file

@ -34,6 +34,7 @@
#include <mapnik/shield_symbolizer.hpp> #include <mapnik/shield_symbolizer.hpp>
#include <mapnik/text_symbolizer.hpp> #include <mapnik/text_symbolizer.hpp>
#include <mapnik/markers_symbolizer.hpp> #include <mapnik/markers_symbolizer.hpp>
#include <mapnik/debug_symbolizer.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/expression_string.hpp> #include <mapnik/expression_string.hpp>
@ -108,6 +109,12 @@ inline bool operator==(markers_symbolizer const& lhs,
return (&lhs == &rhs); return (&lhs == &rhs);
} }
inline bool operator==(debug_symbolizer const& lhs,
debug_symbolizer const& rhs)
{
return (&lhs == &rhs);
}
typedef boost::variant<point_symbolizer, typedef boost::variant<point_symbolizer,
line_symbolizer, line_symbolizer,
line_pattern_symbolizer, line_pattern_symbolizer,
@ -117,7 +124,8 @@ typedef boost::variant<point_symbolizer,
shield_symbolizer, shield_symbolizer,
text_symbolizer, text_symbolizer,
building_symbolizer, building_symbolizer,
markers_symbolizer> symbolizer; markers_symbolizer,
debug_symbolizer> symbolizer;
class rule class rule
{ {

View file

@ -33,6 +33,7 @@
#include <map> #include <map>
// boost // boost
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace mapnik namespace mapnik
@ -58,7 +59,7 @@ struct char_properties
/** 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;
font_set fontset; boost::optional<font_set> fontset;
double text_size; double text_size;
double character_spacing; double character_spacing;
double line_spacing; //Largest total height (fontsize+line_spacing) per line is chosen double line_spacing; //Largest total height (fontsize+line_spacing) per line is chosen

View file

@ -92,7 +92,7 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base
void set_text_size(double size); void set_text_size(double size);
std::string const& get_face_name() const func_deprecated; std::string const& get_face_name() const func_deprecated;
void set_face_name(std::string face_name); void set_face_name(std::string face_name);
font_set const& get_fontset() const func_deprecated; boost::optional<font_set> const& get_fontset() const func_deprecated;
void set_fontset(font_set const& fset); void set_fontset(font_set const& fset);
color const& get_fill() const func_deprecated; color const& get_fill() const func_deprecated;
void set_fill(color const& fill); void set_fill(color const& fill);

View file

@ -339,10 +339,12 @@ void sqlite_datasource::bind() const
else else
{ {
std::ostringstream s; std::ostringstream s;
s << "Sqlite Plugin: key_field is empty for " s << "Sqlite Plugin: could not generate spatial index"
<< geometry_field_ << " for table '" << geometry_table_ << "'"
<< " and " << " as no primary key can be detected."
<< geometry_table_; << " You should either declare an INTEGER PRIMARY KEY"
<< " or set the 'key_field' option to force a"
<< " given field to be used as the primary key";
throw datasource_exception(s.str()); throw datasource_exception(s.str());
} }
} }

View file

@ -0,0 +1,64 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
// mapnik
#include <mapnik/agg_renderer.hpp>
#include <mapnik/graphics.hpp>
namespace mapnik {
void draw_rect(image_32 &pixmap, box2d<double> const& box)
{
double x0 = box.minx();
double x1 = box.maxx();
double y0 = box.miny();
double y1 = box.maxy();
unsigned color1 = 0xff0000ff;
for (double x=x0; x<x1; x++)
{
pixmap.setPixel(x, y0, color1);
pixmap.setPixel(x, y1, color1);
}
for (double y=y0; y<y1; y++)
{
pixmap.setPixel(x0, y, color1);
pixmap.setPixel(x1, y, color1);
}
}
template <typename T>
void agg_renderer<T>::process(debug_symbolizer const& sym,
mapnik::feature_impl & feature,
proj_transform const& prj_trans)
{
label_collision_detector4::query_iterator itr = detector_->begin(), end = detector_->end();
for (;itr!=end; itr++)
{
draw_rect(pixmap_, itr->box);
}
}
template void agg_renderer<image_32>::process(debug_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
}

View file

@ -259,6 +259,7 @@ source += Split(
agg/process_raster_symbolizer.cpp agg/process_raster_symbolizer.cpp
agg/process_shield_symbolizer.cpp agg/process_shield_symbolizer.cpp
agg/process_markers_symbolizer.cpp agg/process_markers_symbolizer.cpp
agg/process_debug_symbolizer.cpp
""" """
) )

View file

@ -22,6 +22,9 @@
#include <mapnik/feature_type_style.hpp> #include <mapnik/feature_type_style.hpp>
// boost
#include <boost/foreach.hpp>
namespace mapnik namespace mapnik
{ {
@ -89,6 +92,18 @@ rules& feature_type_style::get_rules_nonconst()
return rules_; return rules_;
} }
bool feature_type_style::active(double scale_denom) const
{
BOOST_FOREACH(rule const& r, rules_)
{
if (r.active(scale_denom))
{
return true;
}
}
return false;
}
void feature_type_style::set_filter_mode(filter_mode_e mode) void feature_type_style::set_filter_mode(filter_mode_e mode)
{ {
filter_mode_ = mode; filter_mode_ = mode;

View file

@ -29,8 +29,6 @@
namespace mapnik namespace mapnik
{ {
font_set::font_set()
: name_("") {}
font_set::font_set(std::string const& name) font_set::font_set(std::string const& name)
: name_(name) {} : name_(name) {}

View file

@ -264,7 +264,8 @@ void scale_image_agg(Image & target,
double ratio) double ratio)
{ {
typedef agg::pixfmt_rgba32 pixfmt; typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::pixfmt_rgba32_pre pixfmt_pre;
typedef agg::renderer_base<pixfmt_pre> renderer_base;
// define some stuff we'll use soon // define some stuff we'll use soon
agg::rasterizer_scanline_aa<> ras; agg::rasterizer_scanline_aa<> ras;
@ -280,7 +281,7 @@ void scale_image_agg(Image & target,
// initialize destination AGG buffer (with transparency) // initialize destination AGG buffer (with transparency)
agg::rendering_buffer rbuf_dst((unsigned char*)target.getBytes(), target.width(), target.height(), target.width() * 4); agg::rendering_buffer rbuf_dst((unsigned char*)target.getBytes(), target.width(), target.height(), target.width() * 4);
pixfmt pixf_dst(rbuf_dst); pixfmt_pre pixf_dst(rbuf_dst);
renderer_base rb_dst(pixf_dst); renderer_base rb_dst(pixf_dst);
rb_dst.clear(agg::rgba(0, 0, 0, 0)); rb_dst.clear(agg::rgba(0, 0, 0, 0));

View file

@ -106,6 +106,7 @@ private:
void parse_building_symbolizer(rule & rule, xml_node const& sym); void parse_building_symbolizer(rule & rule, xml_node const& sym);
void parse_raster_symbolizer(rule & rule, xml_node const& sym); void parse_raster_symbolizer(rule & rule, xml_node const& sym);
void parse_markers_symbolizer(rule & rule, xml_node const& sym); void parse_markers_symbolizer(rule & rule, xml_node const& sym);
void parse_debug_symbolizer(rule & rule, xml_node const& sym);
void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node); void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node);
bool parse_stroke(stroke & strk, xml_node const & sym); bool parse_stroke(stroke & strk, xml_node const & sym);
@ -806,6 +807,10 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r)
{ {
parse_markers_symbolizer(rule, *symIter); parse_markers_symbolizer(rule, *symIter);
} }
else if (symIter->is("DebugSymbolizer"))
{
parse_debug_symbolizer(rule, *symIter);
}
} }
style.add_rule(rule); style.add_rule(rule);
@ -1149,7 +1154,7 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym)
placement_finder->defaults.from_xml(sym, fontsets_); placement_finder->defaults.from_xml(sym, fontsets_);
} }
if (strict_ && if (strict_ &&
!placement_finder->defaults.format.fontset.size()) !placement_finder->defaults.format.fontset->size())
{ {
ensure_font_face(placement_finder->defaults.format.face_name); ensure_font_face(placement_finder->defaults.format.face_name);
} }
@ -1178,7 +1183,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
} }
placement_finder->defaults.from_xml(sym, fontsets_); placement_finder->defaults.from_xml(sym, fontsets_);
if (strict_ && if (strict_ &&
!placement_finder->defaults.format.fontset.size()) !placement_finder->defaults.format.fontset->size())
{ {
ensure_font_face(placement_finder->defaults.format.face_name); ensure_font_face(placement_finder->defaults.format.face_name);
} }
@ -1508,6 +1513,14 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym)
} }
} }
void map_parser::parse_debug_symbolizer(rule & rule, xml_node const & sym)
{
debug_symbolizer symbol;
parse_symbolizer_base(symbol, sym);
rule.append(symbol);
}
void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, void map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc,
xml_node const& node) xml_node const& node)
{ {

View file

@ -159,6 +159,10 @@ boost::optional<feature_type_style const&> Map::find_style(std::string const& na
bool Map::insert_fontset(std::string const& name, font_set const& fontset) bool Map::insert_fontset(std::string const& name, font_set const& fontset)
{ {
if (fontset.get_name() != name)
{
throw mapnik::config_error("Fontset name must match the name used to reference it on the map");
}
return fontsets_.insert(make_pair(name, fontset)).second; return fontsets_.insert(make_pair(name, fontset)).second;
} }

View file

@ -65,22 +65,22 @@ string_info &processed_text::get_string_info()
face_set_ptr faces = font_manager_.get_face_set(p.face_name, p.fontset); face_set_ptr faces = font_manager_.get_face_set(p.face_name, p.fontset);
if (faces->size() == 0) if (faces->size() == 0)
{ {
if (!p.fontset.get_name().empty()) if (p.fontset && !p.fontset->get_name().empty())
{ {
if (p.fontset.size()) if (p.fontset->size())
{ {
if (!p.face_name.empty()) if (!p.face_name.empty())
{ {
throw config_error("Unable to find specified font face '" + p.face_name + "' in font set: '" + p.fontset.get_name() + "'"); throw config_error("Unable to find specified font face '" + p.face_name + "' in font set: '" + p.fontset->get_name() + "'");
} }
else else
{ {
throw config_error("No valid font face could be loaded for font set: '" + p.fontset.get_name() + "'"); throw config_error("No valid font face could be loaded for font set: '" + p.fontset->get_name() + "'");
} }
} }
else else
{ {
throw config_error("Font set '" + p.fontset.get_name() + "' does not contain any Font face-name entries"); throw config_error("Font set '" + p.fontset->get_name() + "' does not contain any Font face-name entries");
} }
} }
else if (!p.face_name.empty()) else if (!p.face_name.empty())

View file

@ -293,11 +293,11 @@ void char_properties::from_xml(xml_node const& sym, fontset_map const& fontsets)
throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'", sym); throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'", sym);
} }
} }
if (!face_name.empty() && !fontset.get_name().empty()) if (!face_name.empty() && fontset)
{ {
throw config_error("Can't have both face-name and fontset-name", sym); throw config_error("Can't have both face-name and fontset-name", sym);
} }
if (face_name.empty() && fontset.get_name().empty()) if (face_name.empty() && !fontset)
{ {
throw config_error("Must have face-name or fontset-name", sym); throw config_error("Must have face-name or fontset-name", sym);
} }
@ -305,11 +305,9 @@ void char_properties::from_xml(xml_node const& sym, fontset_map const& fontsets)
void char_properties::to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const &dfl) const void char_properties::to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const &dfl) const
{ {
std::string const& fontset_name = fontset.get_name(); if (fontset)
std::string const& dfl_fontset_name = dfl.fontset.get_name();
if (fontset_name != dfl_fontset_name || explicit_defaults)
{ {
set_attr(node, "fontset-name", fontset_name); set_attr(node, "fontset-name", fontset->get_name());
} }
if (face_name != dfl.face_name || explicit_defaults) if (face_name != dfl.face_name || explicit_defaults)

View file

@ -173,7 +173,7 @@ void text_symbolizer::set_fontset(font_set const& fontset)
placement_options_->defaults.format.fontset = fontset; placement_options_->defaults.format.fontset = fontset;
} }
font_set const& text_symbolizer::get_fontset() const boost::optional<font_set> const& text_symbolizer::get_fontset() const
{ {
return placement_options_->defaults.format.fontset; return placement_options_->defaults.format.fontset;
} }

View file

@ -78,6 +78,8 @@ void reproject_and_scale_raster(raster & target, raster const& source,
typedef agg::pixfmt_rgba32 pixfmt; typedef agg::pixfmt_rgba32 pixfmt;
typedef pixfmt::color_type color_type; typedef pixfmt::color_type color_type;
typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::pixfmt_rgba32_pre pixfmt_pre;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
agg::rasterizer_scanline_aa<> rasterizer; agg::rasterizer_scanline_aa<> rasterizer;
agg::scanline_u8 scanline; agg::scanline_u8 scanline;
@ -85,8 +87,8 @@ void reproject_and_scale_raster(raster & target, raster const& source,
target.data_.width(), target.data_.width(),
target.data_.height(), target.data_.height(),
target.data_.width()*4); target.data_.width()*4);
pixfmt pixf(buf); pixfmt_pre pixf_pre(buf);
renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre);
rasterizer.clip_box(0, 0, target.data_.width(), target.data_.height()); rasterizer.clip_box(0, 0, target.data_.width(), target.data_.height());
agg::rendering_buffer buf_tile( agg::rendering_buffer buf_tile(
(unsigned char*)source.data_.getData(), (unsigned char*)source.data_.getData(),
@ -176,13 +178,13 @@ void reproject_and_scale_raster(raster & target, raster const& source,
<img_accessor_type, interpolator_type> <img_accessor_type, interpolator_type>
span_gen_type; span_gen_type;
span_gen_type sg(ia, interpolator); span_gen_type sg(ia, interpolator);
agg::render_scanlines_aa(rasterizer, scanline, rb, agg::render_scanlines_aa(rasterizer, scanline, rb_pre,
sa, sg); sa, sg);
} else { } else {
typedef mapnik::span_image_resample_rgba_affine typedef mapnik::span_image_resample_rgba_affine
<img_accessor_type> span_gen_type; <img_accessor_type> span_gen_type;
span_gen_type sg(ia, interpolator, filter); span_gen_type sg(ia, interpolator, filter);
agg::render_scanlines_aa(rasterizer, scanline, rb, agg::render_scanlines_aa(rasterizer, scanline, rb_pre,
sa, sg); sa, sg);
} }
} }

View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
from nose.tools import *
from utilities import execution_path
import os, mapnik
def setup():
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def test_loading_fontset_from_map():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/fontset.xml',True)
fs = m.find_fontset('book-fonts')
eq_(len(fs.names),2)
eq_(list(fs.names),['DejaVu Sans Book','DejaVu Sans Oblique'])
def test_loading_fontset_from_python():
m = mapnik.Map(256,256)
fset = mapnik.FontSet('foo')
fset.add_face_name('Comic Sans')
fset.add_face_name('Papyrus')
eq_(fset.name,'foo')
fset.name = 'my-set'
eq_(fset.name,'my-set')
m.append_fontset('my-set', fset)
sty = mapnik.Style()
rule = mapnik.Rule()
tsym = mapnik.TextSymbolizer()
eq_(tsym.fontset,None)
tsym.fontset = fset
rule.symbols.append(tsym)
sty.rules.append(rule)
m.append_style('Style',sty)
serialized_map = mapnik.save_map_to_string(m)
eq_('fontset-name="my-set"' in serialized_map,True)
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -155,7 +155,7 @@ def test_shield_symbolizer_init():
# 11c34b1: default transform list is empty, not identity matrix # 11c34b1: default transform list is empty, not identity matrix
eq_(s.transform, '') eq_(s.transform, '')
eq_(len(s.fontset.names), 0) eq_(s.fontset, None)
# ShieldSymbolizer missing image file # ShieldSymbolizer missing image file
# images paths are now PathExpressions are evaluated at runtime # images paths are now PathExpressions are evaluated at runtime

View file

@ -1,23 +0,0 @@
#!/usr/bin/env python
from nose.tools import *
from utilities import execution_path
import os, mapnik
def setup():
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def test_loading_fontset_from_map():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/fontset.xml',True)
fs = m.find_fontset('book-fonts')
eq_(len(fs.names),2)
eq_(list(fs.names),['DejaVu Sans Book','DejaVu Sans Oblique'])
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]