Merge branch 'master' into harfbuzz

Conflicts:
	bindings/python/mapnik/__init__.py
	include/mapnik/font_engine_freetype.hpp
	src/load_map.cpp
This commit is contained in:
Hermann Kraus 2012-09-15 01:39:33 +02:00
commit 406904a1f6
30 changed files with 185 additions and 220 deletions

View file

@ -8,6 +8,8 @@ For a complete change history, see the git log.
## Future ## Future
- 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
now the combined layer extents will be again respected: they will be clipped to the maximum-extent if possible now the combined layer extents will be again respected: they will be clipped to the maximum-extent if possible
and only when back-projecting fails for all layers will the maximum-extent be used as a fallback (#1473) and only when back-projecting fails for all layers will the maximum-extent be used as a fallback (#1473)

View file

@ -354,7 +354,7 @@ opts.AddVariables(
# Other variables # Other variables
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'), BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
('SYSTEM_FONTS','Provide location for python bindings to register fonts (if given aborts installation of bundled DejaVu fonts)',''), ('SYSTEM_FONTS','Provide location for python bindings to register fonts (if provided then the bundled DejaVu fonts are not installed)',''),
('LIB_DIR_NAME','Name to use for the subfolder beside libmapnik where fonts and plugins are installed','mapnik'), ('LIB_DIR_NAME','Name to use for the subfolder beside libmapnik where fonts and plugins are installed','mapnik'),
PathVariable('PYTHON','Full path to Python executable used to build bindings', sys.executable), PathVariable('PYTHON','Full path to Python executable used to build bindings', sys.executable),
BoolVariable('FRAMEWORK_PYTHON', 'Link against Framework Python on Mac OS X', 'True'), BoolVariable('FRAMEWORK_PYTHON', 'Link against Framework Python on Mac OS X', 'True'),

View file

@ -693,417 +693,300 @@ class PythonDatasource(object):
return itertools.imap(make_it, features, itertools.count(1)) return itertools.imap(make_it, features, itertools.count(1))
class _TextSymbolizer(TextSymbolizer,_injector): class _TextSymbolizer(TextSymbolizer,_injector):
@property
def name(self):
if isinstance(self.properties.format_tree, FormattingText):
return self.properties.format_tree.text
else:
return None # This text symbolizer is using complex formatting features.
# There is no single expression which could be returned as name
@name.setter
def name(self, name):
self.properties.format_tree = FormattingText(name)
@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",
DeprecationWarning, 2)
return self.properties.wrap_before return self.properties.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",
DeprecationWarning, 2)
self.properties.wrap_before = wrap_before self.properties.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,8 +33,13 @@ 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")),
"Add a face-name to the fontset.\n" "Add a face-name to the fontset.\n"

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

@ -404,9 +404,9 @@ void export_text_placement()
boost::shared_ptr<char_properties> > boost::shared_ptr<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)

23
demo/simple-renderer/render.py Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
import sys
import mapnik
def render(input_file, output_file, width=800, height=800, bbox=None):
m = mapnik.Map(width, height)
mapnik.load_map(m, input_file, False)
if bbox is not None:
m.zoom_to_box(bbox)
else:
m.zoom_all()
mapnik.render_to_file(m, output_file)
if len(sys.argv) == 2:
render(sys.argv[1], "output.png")
elif len(sys.argv) == 3:
render(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 5:
render(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]))
else:
print "usage: %s style_file [output_file] [width height]" % sys.argv[0]
sys.exit(1)

View file

@ -22,15 +22,12 @@ import glob
Import('env') Import('env')
# grab all the deja vu fonts if not env['SYSTEM_FONTS']:
includes = glob.glob('*/*/*.ttf') # grab all the deja vu fonts
includes = glob.glob('*/*/*.ttf')
# grab single unifont ttf (available at http://unifoundry.com/unifont.html) # grab single unifont ttf (available at http://unifoundry.com/unifont.html)
includes.extend(glob.glob('unifont*.ttf')) includes.extend(glob.glob('unifont*.ttf'))
target_path = env['MAPNIK_FONTS_DEST']
target_path = env['MAPNIK_FONTS_DEST'] if 'uninstall' not in COMMAND_LINE_TARGETS:
env.Alias(target='install', source=env.Install(target_path, includes))
if 'uninstall' not in COMMAND_LINE_TARGETS and not env['SYSTEM_FONTS']: env['create_uninstall_target'](env, target_path)
env.Alias(target='install', source=env.Install(target_path, includes))
env['create_uninstall_target'](env, target_path)

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

@ -35,6 +35,7 @@
#include <map> #include <map>
// boost // boost
#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
@ -61,7 +62,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

@ -68,10 +68,10 @@ void agg_renderer<T>::process(raster_symbolizer const& sym,
raster target(target_ext, target_data); raster target(target_ext, target_data);
scaling_method_e scaling_method = sym.get_scaling_method(); scaling_method_e scaling_method = sym.get_scaling_method();
double filter_radius = sym.calculate_filter_factor(); double filter_radius = sym.calculate_filter_factor();
double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y;
if (!prj_trans.equal()) if (!prj_trans.equal())
{ {
double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y;
reproject_and_scale_raster(target, *source, prj_trans, reproject_and_scale_raster(target, *source, prj_trans,
offset_x, offset_y, offset_x, offset_y,
sym.get_mesh_size(), sym.get_mesh_size(),
@ -80,16 +80,18 @@ void agg_renderer<T>::process(raster_symbolizer const& sym,
} }
else else
{ {
if (scaling_method == SCALING_BILINEAR8){ if (scaling_method == SCALING_BILINEAR8)
scale_image_bilinear8<image_data_32>(target.data_,source->data_, offset_x, offset_y); {
} else { scale_image_bilinear8<image_data_32>(target.data_,source->data_, 0.0, 0.0);
} else
{
double scaling_ratio = ext.width() / source->data_.width(); double scaling_ratio = ext.width() / source->data_.width();
scale_image_agg<image_data_32>(target.data_, scale_image_agg<image_data_32>(target.data_,
source->data_, source->data_,
scaling_method, scaling_method,
scaling_ratio, scaling_ratio,
offset_x, 0.0,
offset_y, 0.0,
filter_radius); filter_radius);
} }
} }

View file

@ -1422,10 +1422,10 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
raster target(target_ext, target_data); raster target(target_ext, target_data);
scaling_method_e scaling_method = sym.get_scaling_method(); scaling_method_e scaling_method = sym.get_scaling_method();
double filter_radius = sym.calculate_filter_factor(); double filter_radius = sym.calculate_filter_factor();
double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y;
if (!prj_trans.equal()) if (!prj_trans.equal())
{ {
double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y;
reproject_and_scale_raster(target, *source, prj_trans, reproject_and_scale_raster(target, *source, prj_trans,
offset_x, offset_y, offset_x, offset_y,
sym.get_mesh_size(), sym.get_mesh_size(),
@ -1434,16 +1434,18 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
} }
else else
{ {
if (scaling_method == SCALING_BILINEAR8){ if (scaling_method == SCALING_BILINEAR8)
scale_image_bilinear8<image_data_32>(target.data_,source->data_, offset_x, offset_y); {
} else { scale_image_bilinear8<image_data_32>(target.data_,source->data_, 0.0, 0.0);
} else
{
double scaling_ratio = ext.width() / source->data_.width(); double scaling_ratio = ext.width() / source->data_.width();
scale_image_agg<image_data_32>(target.data_, scale_image_agg<image_data_32>(target.data_,
source->data_, source->data_,
scaling_method, scaling_method,
scaling_ratio, scaling_ratio,
offset_x, 0.0,
offset_y, 0.0,
filter_radius); filter_radius);
} }
} }

View file

@ -272,11 +272,11 @@ face_set_ptr face_manager<T>::get_face_set(const font_set &fset)
} }
template <typename T> template <typename T>
face_set_ptr face_manager<T>::get_face_set(const std::string &name, const font_set &fset) face_set_ptr face_manager<T>::get_face_set(const std::string &name, const 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

@ -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,8 +264,7 @@ void scale_image_agg(Image & target,
double ratio) double ratio)
{ {
typedef agg::pixfmt_rgba32 pixfmt; typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::pixfmt_rgba32_pre pixfmt_pre; typedef agg::renderer_base<pixfmt> renderer_base;
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;
@ -279,9 +278,9 @@ void scale_image_agg(Image & target,
typedef agg::image_accessor_clone<pixfmt> img_src_type; typedef agg::image_accessor_clone<pixfmt> img_src_type;
img_src_type img_src(pixf_src); img_src_type img_src(pixf_src);
// initialise 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_pre pixf_dst(rbuf_dst); pixfmt 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));
@ -294,8 +293,8 @@ void scale_image_agg(Image & target,
interpolator_type interpolator(img_mtx); interpolator_type interpolator(img_mtx);
// draw an anticlockwise polygon to render our image into // draw an anticlockwise polygon to render our image into
double scaled_width = source.width() * image_ratio; double scaled_width = target.width();
double scaled_height = source.height() * image_ratio; double scaled_height = target.height();
ras.reset(); ras.reset();
ras.move_to_d(x_off_f, y_off_f); ras.move_to_d(x_off_f, y_off_f);
ras.line_to_d(x_off_f + scaled_width, y_off_f); ras.line_to_d(x_off_f + scaled_width, y_off_f);

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

@ -367,11 +367,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);
} }
@ -379,11 +379,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

@ -117,7 +117,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,8 +78,6 @@ 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;
@ -87,8 +85,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_pre pixf_pre(buf); pixfmt pixf(buf);
renderer_base_pre rb_pre(pixf_pre); renderer_base rb(pixf);
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(),
@ -178,13 +176,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_pre, agg::render_scanlines_aa(rasterizer, scanline, rb,
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_pre, agg::render_scanlines_aa(rasterizer, scanline, rb,
sa, sg); sa, sg);
} }
} }

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]>
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" background-color="#F0CCAC">
<Style name="style" >
<Rule>
<RasterSymbolizer opacity="1" />
</Rule>
</Style>
<Layer name="raster"
srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
<StyleName>style</StyleName>
<Datasource>
<!-- https://github.com/mapnik/mapnik/issues/1471 -->
<Parameter name="file">../raster/nodata-edge.tif</Parameter>
<Parameter name="type">gdal</Parameter>
</Datasource>
</Layer>
</Map>

Binary file not shown.

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: 44 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

View file

@ -73,8 +73,8 @@ if 'shape' in mapnik.DatasourceCache.plugin_names():
# caution - will go square due to evil aspect_fix_mode backhandedness # caution - will go square due to evil aspect_fix_mode backhandedness
m.zoom_all() m.zoom_all()
#mapnik.render_to_file(m,'works2.png') #mapnik.render_to_file(m,'works2.png')
# valid that aspec_fix_mode modified the bbox # validate that aspect_fix_mode modified the bbox reasonably
eq_(m.envelope(),mapnik.Box2d(-179.999999975,-179.999999975,179.999999975,179.999999975)) eq_(str(m.envelope()),str(mapnik.Box2d(-179.999999975,-167.951396161,179.999999975,192.048603789)))
fs = m.query_point(0,-98.9264, 38.1432) # somewhere in kansas fs = m.query_point(0,-98.9264, 38.1432) # somewhere in kansas
feat = fs.next() feat = fs.next()
eq_(feat.attributes['NAME'],u'United States') eq_(feat.attributes['NAME'],u'United States')
@ -96,11 +96,11 @@ if 'shape' in mapnik.DatasourceCache.plugin_names():
m.maximum_extent = wgs84_bounds m.maximum_extent = wgs84_bounds
# caution - will go square due to evil aspect_fix_mode backhandedness # caution - will go square due to evil aspect_fix_mode backhandedness
m.zoom_all() m.zoom_all()
# valid that aspec_fix_mode modified the bbox # validate that aspect_fix_mode modified the bbox reasonably
eq_(m.envelope(),mapnik.Box2d(-179.999999975,-179.999999975,179.999999975,179.999999975)) eq_(str(m.envelope()),str(mapnik.Box2d(-179.999999975,-167.951396161,179.999999975,192.048603789)))
fs = m.query_map_point(0,55,100) # somewhere in middle of us fs = m.query_map_point(0,55,100) # somewhere in Canada
feat = fs.next() feat = fs.next()
eq_(feat.attributes['NAME'],u'United States') eq_(feat.attributes['NAME'],u'Canada')
if __name__ == "__main__": if __name__ == "__main__":
setup() setup()

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

@ -36,6 +36,20 @@ if 'gdal' in mapnik.DatasourceCache.plugin_names():
expected_im = mapnik.Image.open(expected) expected_im = mapnik.Image.open(expected)
eq_(im.tostring(),expected_im.tostring(), 'failed comparing actual (%s) and expected(%s)' % (actual,'tests/python_tests/'+ expected)) eq_(im.tostring(),expected_im.tostring(), 'failed comparing actual (%s) and expected(%s)' % (actual,'tests/python_tests/'+ expected))
# there should be no gray edges on raster
# https://github.com/mapnik/mapnik/issues/1471
def test_edge_scaling_with_nodata():
m = mapnik.Map(600,400)
mapnik.load_map(m,'../data/good_maps/raster-nodata-edge.xml')
m.zoom_all()
actual = '/tmp/mapnik-raster-nodata-edge.png'
expected = 'images/support/raster-nodata-edge.png'
im = mapnik.Image(m.width,m.height)
mapnik.render(m,im)
im.save(actual)
expected_im = mapnik.Image.open(expected)
eq_(im.tostring(),expected_im.tostring(), 'failed comparing actual (%s) and expected(%s)' % (actual,'tests/python_tests/'+ expected))
if __name__ == "__main__": if __name__ == "__main__":
setup() setup()

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]