Merge branch 'master' into compositing

Conflicts:
	include/mapnik/util/dasharray_parser.hpp
	src/agg/process_line_symbolizer.cpp
	src/image_compositing.cpp
This commit is contained in:
Artem Pavlenko 2012-03-26 09:05:02 +01:00
commit 9840c7df4c
78 changed files with 306 additions and 204 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.
@ -11,10 +7,9 @@ Developers: Please commit along with changes.
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)
@ -31,8 +26,7 @@ Mapnik 2.1.0
- 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)
@ -121,8 +115,7 @@ Mapnik 2.0.0
- 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)
@ -165,8 +158,7 @@ Mapnik 0.7.2 Release
- 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)
@ -205,13 +197,13 @@ Mapnik 0.7.0 Release
* Valid Usages include:
<Parameter name="table">
(Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map
</Parameter>
<Parameter name="table">
(Select ST_Union(geom) as geom from table where ST_Intersects(geometry,!bbox!)) as map
</Parameter>
<Parameter name="table">
(Select * from table where geom &amp;&amp; !bbox!) as map
</Parameter>
<Parameter name="table">
(Select * from table where geom &amp;&amp; !bbox!) as map
</Parameter>
- PostGIS Plugin: Added 'scale_denominator' substitution ability in sql query string (#415/#465)
@ -307,8 +299,7 @@ Mapnik 0.7.0 Release
Mapnik 0.6.1 Release
--------------------
# Mapnik 0.6.1 Release
(Packaged from r1247)
@ -392,8 +383,7 @@ Mapnik 0.6.1 Release
Mapnik 0.6.0 Release
--------------------
# Mapnik 0.6.0 Release
(Packaged from r1066)

View file

@ -18,6 +18,9 @@ uninstall:
python scons/scons.py uninstall
test:
@python tests/visual_tests/test.py
@tests/cpp_tests/font_registration_test
@tests/cpp_tests/params_test
@python tests/run_tests.py -q
pep8:
@ -26,4 +29,7 @@ pep8:
@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 '}'
grind:
@valgrind --leak-check=full tests/cpp_tests/font_registration_test
.PHONY: clean reset uninstall test install

View file

@ -1716,7 +1716,7 @@ if not HELP_REQUESTED:
# build C++ tests
# not ready for release
#SConscript('tests/cpp_tests/build.py')
SConscript('tests/cpp_tests/build.py')
# not ready for release
#if env['SVG_RENDERER']:

View file

@ -42,6 +42,7 @@ void export_font_engine()
.def("register_fonts",&freetype_engine::register_fonts)
.def("face_names",&freetype_engine::face_names)
.staticmethod("register_font")
.staticmethod("register_fonts")
.staticmethod("face_names")
;
}

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> 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::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);
@ -482,7 +479,6 @@ void export_map()
)
.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("aspect_fix_mode",

View file

@ -116,5 +116,13 @@ void export_markers_symbolizer()
.add_property("transform",
&mapnik::get_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

@ -71,7 +71,7 @@ void set_join_caps(Stroke const& stroke_, PathType & stroke)
default:
stroke.generator().line_join(agg::bevel_join);
}
line_cap_e cap=stroke_.get_line_cap();
switch (cap)
{
@ -85,7 +85,7 @@ void set_join_caps(Stroke const& stroke_, PathType & stroke)
stroke.generator().line_cap(agg::round_cap);
}
}
}
#endif //MAPNIK_AGG_HELPERS_HPP

View file

@ -21,8 +21,13 @@
*****************************************************************************/
#ifndef MAPNIK_BOOLEAN_HPP
#define MAPNIK_BOOLEAN_HPP
// std
#include <istream>
// boost
#include <boost/algorithm/string.hpp>
namespace mapnik
{
/** Helper for class bool */
@ -36,16 +41,19 @@ public:
{
return b_;
}
boolean & operator = (boolean const& other)
{
b_ = other.b_;
return * this;
}
boolean & operator = (bool other)
{
b_ = other;
return * this;
}
private:
bool b_;
};
@ -57,6 +65,7 @@ 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" ||

View file

@ -224,13 +224,14 @@ public:
box2d<double> envelope() const
{
// TODO - cache this
box2d<double> result;
for (unsigned i=0;i<num_geometries();++i)
{
geometry_type const& geom = get_geometry(i);
if (i==0)
{
box2d<double> box = geom.envelope();
box2d<double> const& box = geom.envelope();
result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
}
else

View file

@ -169,12 +169,12 @@ public:
glyph_ptr get_glyph(unsigned c) const
{
BOOST_FOREACH ( face_ptr const& face, faces_)
BOOST_FOREACH ( face_ptr const& face, faces_)
{
FT_UInt g = face->get_char(c);
if (g) return boost::make_shared<font_glyph>(face, g);
}
// Final fallback to empty square if nothing better in any font
return boost::make_shared<font_glyph>(*faces_.begin(), 0);
}
@ -185,7 +185,7 @@ public:
void set_pixel_sizes(unsigned size)
{
BOOST_FOREACH ( face_ptr const& face, faces_)
BOOST_FOREACH ( face_ptr const& face, faces_)
{
face->set_pixel_sizes(size);
}
@ -193,7 +193,7 @@ public:
void set_character_sizes(float size)
{
BOOST_FOREACH ( face_ptr const& face, faces_)
BOOST_FOREACH ( face_ptr const& face, faces_)
{
face->set_character_sizes(size);
}

View file

@ -83,12 +83,12 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base
{
smooth_ = smooth;
}
double smooth() const
{
return smooth_;
}
private:
stroke stroke_;
line_rasterizer_e rasterizer_p_;

View file

@ -79,7 +79,6 @@ private:
box2d<double> current_extent_;
boost::optional<box2d<double> > maximum_extent_;
std::string base_path_;
parameters extra_attr_;
parameters extra_params_;
public:
@ -440,21 +439,6 @@ public:
*/
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
*/

View file

@ -23,13 +23,20 @@
#ifndef MAPNIK_PLACEMENT_FINDER_HPP
#define MAPNIK_PLACEMENT_FINDER_HPP
//mapnik
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/text_properties.hpp>
#include <mapnik/text_placements/base.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>
namespace mapnik
@ -39,6 +46,12 @@ class text_placement_info;
class string_info;
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>
class placement_finder : boost::noncopyable

View file

@ -38,14 +38,24 @@ bool parse_dasharray(Iterator first, Iterator last, std::vector<double>& dasharr
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)] % no_skip[char_(", ")] | lit("none")),
(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)

View file

@ -52,8 +52,7 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
mapnik::feature_ptr const& feature,
proj_transform const& prj_trans)
{
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
stroke const& stroke_ = sym.get_stroke();
color const& col = stroke_.get_color();
unsigned r=col.red();
@ -67,6 +66,7 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
box2d<double> ext = query_extent_ * 1.1;
if (sym.get_rasterizer() == RASTERIZER_FAST)
{
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
typedef agg::renderer_outline_aa<ren_base> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
@ -98,9 +98,9 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
{
ras_ptr->reset();
set_gamma_method(stroke_, ras_ptr);
stroker_.attach(pixf);
renderer_.attach(pixf);
//metawriter_with_properties writer = sym.get_metawriter();
for (unsigned i=0;i<feature->num_geometries();++i)
{
geometry_type & geom = feature->get_geometry(i);
@ -140,7 +140,7 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
clipped_geometry_type clipped(geom);
clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
path_type path(t_,clipped,prj_trans);
agg::conv_dash<path_type> dash(path);
dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin();
@ -186,18 +186,15 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
set_join_caps(stroke_,stroke);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
ras_ptr->add_path(stroke);
}
//if (writer.first) writer.first->add_line(path, *feature, t_, writer.second);
}
}
}
stroker_.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
stroker_.render(*ras_ptr);
//ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
//agg::render_scanlines(*ras_ptr, sl, ren);
renderer_.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
renderer_.render(*ras_ptr);
}
}

View file

@ -171,6 +171,8 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
unsigned s_a=col.alpha();
double w = sym.get_width();
double h = sym.get_height();
double rx = w/2.0;
double ry = h/2.0;
arrow arrow_;
box2d<double> extent;
@ -225,7 +227,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (sym.get_allow_overlap() ||
detector_->has_placement(label_ext))
{
agg::ellipse c(x, y, w, h);
agg::ellipse c(x, y, rx, ry);
marker.concat_path(c);
ras_ptr->add_path(marker);
ren.color(agg::rgba8(r, g, b, int(a*sym.get_opacity())));
@ -271,7 +273,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (marker_type == ELLIPSE)
{
// 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);
agg::trans_affine matrix;
matrix *= agg::trans_affine_translation(-x_t,-y_t);

View file

@ -74,7 +74,7 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
agg::scanline_u8 sl;
ras_ptr->reset();
set_gamma_method(sym,ras_ptr);
std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
boost::optional<mapnik::marker_ptr> marker;
if ( !filename.empty() )

View file

@ -67,7 +67,7 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
ras_ptr->reset();
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)

View file

@ -754,7 +754,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
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
@ -877,7 +877,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
{
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
mapnik::stroke const& stroke_ = sym.get_stroke();
cairo_context context(context_);
context.set_color(stroke_.get_color(), stroke_.get_opacity());
@ -889,7 +889,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
{
context.set_dash(stroke_.get_dash_array());
}
for (unsigned i = 0; i < feature->num_geometries(); ++i)
{
geometry_type & geom = feature->get_geometry(i);
@ -900,7 +900,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
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);
}
}

View file

@ -293,9 +293,11 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
layer_ext.clip(map_ext);
// forward project layer extent back into native projection
if (!prj_trans.forward(layer_ext, PROJ_ENVELOPE_POINTS))
{
std::clog << "WARNING: layer " << lay.name()
<< " extent " << layer_ext << " in map projection "
<< " did not reproject properly back to layer projection\n";
}
}
else
{
@ -307,14 +309,13 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
}
box2d<double> query_ext = m_.get_current_extent();
box2d<double> unbuffered_extent = m_.get_current_extent();
prj_trans.forward(query_ext, PROJ_ENVELOPE_POINTS);
double qw = query_ext.width()>0 ? query_ext.width() : 1;
double qh = query_ext.height()>0 ? query_ext.height() : 1;
query::resolution_type res(m_.width()/qw,
m_.height()/qh);
query q(layer_ext,res,scale_denom,unbuffered_extent);
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;
attribute_collector collector(names);

View file

@ -71,11 +71,10 @@ bool freetype_engine::is_font_file(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
mutex::scoped_lock lock(mutex_);
#endif
FT_Library library;
FT_Library library = 0;
FT_Error error = FT_Init_FreeType(&library);
if (error)
{
@ -83,36 +82,47 @@ bool freetype_engine::register_font(std::string const& file_name)
}
FT_Face face = 0;
int num_faces = 0;
bool success = false;
// some font files have multiple fonts in a file
// the count is in the 'root' face library[0]
// 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
error = FT_New_Face (library,file_name.c_str(),i,&face);
if (error)
{
FT_Done_FreeType(library);
return false;
break;
}
// 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
// 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);
name2file_.insert(std::make_pair(name, std::make_pair(i,file_name)));
FT_Done_Face(face);
//FT_Done_FreeType(library);
//return true;
} else {
FT_Done_Face(face);
FT_Done_FreeType(library);
}
else
{
std::ostringstream s;
s << "Error: unable to load invalid font file which lacks identifiable family and style name: '"
<< file_name << "'";
throw std::runtime_error(s.str());
s << "Warning: unable to load font file '" << file_name << "' ";
if (!face->family_name && !face->style_name)
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);
return true;
if (face)
FT_Done_Face(face);
if (library)
FT_Done_FreeType(library);
return success;
}
bool freetype_engine::register_fonts(std::string const& dir, bool recurse)
@ -126,26 +136,24 @@ bool freetype_engine::register_fonts(std::string const& dir, bool recurse)
return mapnik::freetype_engine::register_font(dir);
boost::filesystem::directory_iterator end_itr;
bool success = false;
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_VERSION == 3)
if (!register_fonts(itr->path().string(), true)) return false;
#else // v2
if (!register_fonts(itr->string(), true)) return false;
#endif
success = register_fonts(file_name, true);
}
else
else if (boost::filesystem::is_regular_file(file_name) && is_font_file(file_name))
{
#if (BOOST_FILESYSTEM_VERSION == 3)
mapnik::freetype_engine::register_font(itr->path().string());
#else // v2
mapnik::freetype_engine::register_font(itr->string());
#endif
success = mapnik::freetype_engine::register_font(file_name);
}
}
return true;
return success;
}

View file

@ -148,6 +148,9 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
h = sym.get_height()/res;
}
double rx = w/2.0;
double ry = h/2.0;
arrow arrow_;
box2d<double> extent;
@ -195,7 +198,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
if (sym.get_allow_overlap() ||
detector_.has_placement(label_ext))
{
agg::ellipse c(x, y, w, h);
agg::ellipse c(x, y, rx, ry);
agg::path_storage marker;
marker.concat_path(c);
ras_ptr->add_path(marker);
@ -232,7 +235,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
if (marker_type == ELLIPSE)
{
// 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);
agg::trans_affine matrix;
matrix *= agg::trans_affine_translation(-x_t,-y_t);

View file

@ -88,7 +88,7 @@ void composite(T1 & im, T2 & im2, composite_mode_e mode)
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;
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);

View file

@ -169,8 +169,6 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
xml_node const& map_node = pt.get_child("Map");
try
{
parameters extra_attr;
// Check if relative paths should be interpreted as relative to/from XML location
// Default is true, and map_parser::ensure_relative_to_xml will be called to modify path
optional<boolean> paths_from_xml = map_node.get_opt_attr<boolean>("paths-from-xml");
@ -243,15 +241,19 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
optional<std::string> font_directory = map_node.get_opt_attr<std::string>("font-directory");
if (font_directory)
{
extra_attr["font-directory"] = *font_directory;
freetype_engine::register_fonts(ensure_relative_to_xml(font_directory), false);
if (!freetype_engine::register_fonts(ensure_relative_to_xml(font_directory), false))
{
if (strict_)
{
throw config_error(std::string("Failed to load fonts from: ") + *font_directory);
}
}
}
optional<std::string> min_version_string = map_node.get_opt_attr<std::string>("minimum-version");
if (min_version_string)
{
extra_attr["minimum-version"] = *min_version_string;
boost::char_separator<char> sep(".");
boost::tokenizer<boost::char_separator<char> > tokens(*min_version_string, sep);
unsigned i = 0;
@ -287,8 +289,6 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
}
}
map.set_extra_attributes(extra_attr);
}
catch (const config_error & ex)
{
@ -998,7 +998,7 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym
}
void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
xml_node const & sym)
xml_node const & sym)
{
try
{
@ -1304,7 +1304,7 @@ void map_parser::parse_polygon_symbolizer(rule & rule, xml_node const & sym)
// smooth value
optional<double> smooth = sym.get_opt_attr<double>("smooth");
if (smooth) poly_sym.set_smooth(*smooth);
parse_metawriter_in_symbolizer(poly_sym, sym);
rule.append(poly_sym);
}

View file

@ -96,7 +96,6 @@ Map::Map(const Map& rhs)
current_extent_(rhs.current_extent_),
maximum_extent_(rhs.maximum_extent_),
base_path_(rhs.base_path_),
extra_attr_(rhs.extra_attr_),
extra_params_(rhs.extra_params_) {}
Map& Map::operator=(const Map& rhs)
@ -115,7 +114,6 @@ Map& Map::operator=(const Map& rhs)
aspectFixMode_=rhs.aspectFixMode_;
maximum_extent_=rhs.maximum_extent_;
base_path_=rhs.base_path_;
extra_attr_=rhs.extra_attr_;
extra_params_=rhs.extra_params_;
return *this;
}
@ -684,21 +682,6 @@ std::string Map::get_metawriter_property(std::string name) const
return result;
}
parameters const& Map::get_extra_attributes() const
{
return extra_attr_;
}
parameters& Map::get_extra_attributes()
{
return extra_attr_;
}
void Map::set_extra_attributes(parameters& attr)
{
extra_attr_ = attr;
}
parameters const& Map::get_extra_parameters() const
{
return extra_params_;

View file

@ -51,8 +51,8 @@ markers_symbolizer::markers_symbolizer()
fill_(color(0,0,255)),
spacing_(100.0),
max_error_(0.2),
width_(5.0),
height_(5.0),
width_(10.0),
height_(10.0),
stroke_(),
marker_p_(MARKER_LINE_PLACEMENT),
marker_type_(ARROW) {}
@ -65,8 +65,8 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr filename)
fill_(color(0,0,255)),
spacing_(100.0),
max_error_(0.2),
width_(5.0),
height_(5.0),
width_(10.0),
height_(10.0),
stroke_(),
marker_p_(MARKER_LINE_PLACEMENT),
marker_type_(ARROW) {}

View file

@ -26,14 +26,12 @@
#include <mapnik/placement_finder.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/text_path.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/fastmath.hpp>
#include <mapnik/text_placements/base.hpp>
#include <mapnik/ctrans.hpp>
// agg
#include "agg_path_length.h"
#include "agg_conv_clip_polyline.h"
// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
@ -674,9 +672,9 @@ void placement_finder<DetectorT>::find_line_placements(PathT & shape_path)
for (unsigned i = 0; i < current_placement->nodes_.size(); i++)
{
current_placement->nodes_[i].pos.x -=
pi.get_scale_factor() * displacement * sina;
pi.get_scale_factor() * displacement * sina;
current_placement->nodes_[i].pos.y +=
pi.get_scale_factor() * displacement * cosa;
pi.get_scale_factor() * displacement * cosa;
}
}
@ -1058,11 +1056,9 @@ void placement_finder<DetectorT>::clear_placements()
while (!envelopes_.empty()) envelopes_.pop();
}
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform2<CoordTransform,clipped_geometry_type> PathType;
typedef label_collision_detector4 DetectorType;
template class placement_finder<DetectorType>;
template void placement_finder<DetectorType>::find_point_placements<ClippedPathType>(ClippedPathType &);
template void placement_finder<DetectorType>::find_line_placements<ClippedPathType>(ClippedPathType &);
template void placement_finder<DetectorType>::find_point_placements<PathType>(PathType &);
template void placement_finder<DetectorType>::find_line_placements<PathType>(PathType &);
} // namespace

View file

@ -102,8 +102,7 @@ bool proj_transform::forward (double * x, double * y , double * z, int point_cou
}
do {
// https://github.com/mapnik/mapnik/issues/1072
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(projection::mutex_);
#endif
if (pj_transform( source_.proj_, dest_.proj_, point_count,
@ -154,8 +153,7 @@ bool proj_transform::backward (double * x, double * y , double * z, int point_co
}
do {
// https://github.com/mapnik/mapnik/issues/1072
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(projection::mutex_);
#endif

View file

@ -34,7 +34,7 @@
namespace mapnik {
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
boost::mutex projection::mutex_;
#endif
@ -84,7 +84,7 @@ std::string const& projection::params() const
void projection::forward(double & x, double &y ) const
{
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(mutex_);
#endif
projUV p;
@ -102,7 +102,7 @@ void projection::forward(double & x, double &y ) const
void projection::inverse(double & x,double & y) const
{
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(mutex_);
#endif
if (is_geographic_)
@ -120,7 +120,7 @@ void projection::inverse(double & x,double & y) const
projection::~projection()
{
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(mutex_);
#endif
if (proj_) pj_free(proj_);
@ -131,7 +131,7 @@ projection::~projection()
void projection::init()
{
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 470
#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
mutex::scoped_lock lock(mutex_);
#endif
#if PJ_VERSION >= 480

View file

@ -96,7 +96,7 @@ public:
set_attr( sym_node, "smooth", sym.smooth() );
}
}
void operator () ( line_pattern_symbolizer const& sym )
{
ptree & sym_node = rule_.push_back(
@ -765,14 +765,6 @@ void serialize_map(ptree & pt, Map const & map, bool explicit_defaults)
}
}
parameters extra_attr = map.get_extra_attributes();
parameters::const_iterator p_it = extra_attr.begin();
parameters::const_iterator p_end = extra_attr.end();
for (; p_it != p_end; ++p_it)
{
set_attr( map_node, p_it->first, p_it->second );
}
serialize_parameters( map_node, map.get_extra_parameters());
Map::const_style_iterator it = map.styles().begin();

View file

@ -226,10 +226,12 @@ void svg_parser::start_element(xmlTextReaderPtr reader)
{
parse_gradient_stop(reader);
}
#ifdef MAPNIK_DEBUG
else if (!xmlStrEqual(name, BAD_CAST "svg"))
{
std::clog << "notice: unhandled svg element: " << name << "\n";
}
#endif
}
void svg_parser::end_element(xmlTextReaderPtr reader)

View file

@ -11,6 +11,8 @@ headers = env['CPPPATH']
libraries = copy(env['LIBMAPNIK_LIBS'])
libraries.append('mapnik')
test_env.Append(CXXFLAGS='-g')
for cpp_test in glob.glob('*_test.cpp'):
test_program = test_env.Program(cpp_test.replace('.cpp',''), [cpp_test], CPPPATH=headers, LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
Depends(test_program, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))

View file

@ -6,8 +6,6 @@ using fs::path;
namespace sys = boost::system;
#include <boost/detail/lightweight_test.hpp>
//#include <boost/bind.hpp>
//#include <fstream>
#include <iostream>
#include <mapnik/font_engine_freetype.hpp>
@ -39,14 +37,23 @@ int main( int, char*[] )
// directories without fonts
std::string src("src");
// a legitimate directory will return true even it is does not
// successfully register a font...
BOOST_TEST( mapnik::freetype_engine::register_fonts(src , true ) );
face_names = mapnik::freetype_engine::face_names();
BOOST_TEST( face_names.size() == 0 );
std::clog << "number of registered fonts: " << face_names.size() << std::endl;
// an empty directory will not return true
// we need to register at least one font and not fail on any
// to return true
BOOST_TEST( mapnik::freetype_engine::register_font(src) == false );
BOOST_TEST( mapnik::freetype_engine::register_fonts(src, true) == false );
BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 );
// register unifont
// bogus, emtpy file that looks like font
BOOST_TEST( mapnik::freetype_engine::register_font("tests/data/fonts/fake.ttf") == false );
BOOST_TEST( mapnik::freetype_engine::register_fonts("tests/data/fonts/fake.ttf") == false );
BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 );
BOOST_TEST( mapnik::freetype_engine::register_font("tests/data/fonts/intentionally-broken.ttf") == false );
BOOST_TEST( mapnik::freetype_engine::register_fonts("tests/data/fonts/intentionally-broken.ttf") == false );
BOOST_TEST( mapnik::freetype_engine::face_names().size() == 0 );
// register unifont, since we know it sits in the root fonts/ dir
BOOST_TEST( mapnik::freetype_engine::register_fonts(fontdir) );
face_names = mapnik::freetype_engine::face_names();
std::clog << "number of registered fonts: " << face_names.size() << std::endl;
@ -71,7 +78,7 @@ int main( int, char*[] )
BOOST_TEST( mapnik::freetype_engine::register_fonts(fontdir, true) );
face_names = mapnik::freetype_engine::face_names();
std::clog << "number of registered fonts: " << face_names.size() << std::endl;
BOOST_TEST( face_names.size() == 21 );
BOOST_TEST( face_names.size() == 22 );
return ::boost::report_errors();
}

View file

@ -0,0 +1,57 @@
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
#include <mapnik/params.hpp>
#include <mapnik/boolean.hpp>
int main( int, char*[] )
{
mapnik::parameters params;
// true
params["bool"] = true;
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = "true";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = 1;
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = "1";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = "True";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = "on";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
params["bool"] = "yes";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == true));
// false
params["bool"] = false;
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false) );
params["bool"] = "false";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false) );
params["bool"] = 0;
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false));
params["bool"] = "0";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false));
params["bool"] = "False";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false));
params["bool"] = "off";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false));
params["bool"] = "no";
BOOST_TEST( (params.get<mapnik::boolean>("bool") && *params.get<mapnik::boolean>("bool") == false));
return ::boost::report_errors();
}

View file

Binary file not shown.

View file

@ -1,11 +1,13 @@
<Map font-directory="." minimum-version="0.0.0">
<Map font-directory="../fonts/DejaVuSansMono-BoldOblique.ttf" minimum-version="0.0.0">
<!--
font-directory and minimin-version are extra attributes known
to load_map which are and attached to the map object in order to be
carried through and respected by save map.
to load_map which are use to invoke special behavior at map loading time
if present.
They are treated as 'extra' because they have no role during map rendering
they are discarded after intial parse because they make no sense as an
in-memory map property.
-->
</Map>

View file

@ -1,5 +1,7 @@
<!-- nik2img.py -b 60 46 80 28 rtl_text_map.xml text_styles.png --><Map background-color="#eee" srs="+init=epsg:4326" minimum-version="0.7.2" font-directory="../fonts/">
<Map background-color="#eee" srs="+init=epsg:4326" minimum-version="0.7.2" font-directory="../fonts/XB Zar.ttf">
<!-- nik2img.py -b 60 46 80 28 rtl_text_map.xml text_styles.png -->
<Style name="custom_font">
<Rule>
<TextSymbolizer fill="#000" size="20" dy="-2" face-name="XB Zar Regular" halo-fill="#fff" halo-radius="2" wrap-width="50" line-spacing="3" allow-overlap="true">[NAME_FA]</TextSymbolizer>

View file

@ -0,0 +1,28 @@
#encoding: utf8
from nose.tools import *
import os,sys
from utilities import execution_path
from utilities import Todo
import 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_compare_images():
b = mapnik.Image.open('./images/support/b.png')
for name in mapnik.CompositeOp.names:
a = mapnik.Image.open('./images/support/a.png')
a.composite(b,getattr(mapnik.CompositeOp,name))
actual = '/tmp/mapnik-comp-op-test-' + name + '.png'
expected = 'images/composited/' + name + '.png'
a.save(actual)
expected_im = mapnik.Image.open(expected)
# compare them
eq_(a.tostring(),expected_im.tostring(), 'failed comparing actual (%s) and expected(%s)' % (actual,'tests/python_tests/'+ expected))
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]

View file

@ -14,20 +14,9 @@ def setup():
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def test_non_member_known_attributes():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/extra_known_map_attributes.xml')
attr = m.extra_attributes
eq_(len(attr),2)
eq_(attr['font-directory'],'.')
eq_(attr['minimum-version'],'0.0.0')
def test_arbitrary_parameters_attached_to_map():
m = mapnik.Map(256,256)
mapnik.load_map(m,'../data/good_maps/extra_arbitary_map_parameters.xml')
attr = m.extra_attributes
eq_(len(attr),0)
eq_(len(m.parameters),6)
eq_(m.parameters['key'],'value2')
eq_(m.parameters['key3'],'value3')

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -30,7 +30,6 @@ def test_map_deepcopy1():
eq_(m2.maximum_extent,m1.maximum_extent)
eq_(id(m2.has_metawriter()),id(m1.has_metawriter()))
eq_(id(m2.view_transform()),id(m1.view_transform()))
eq_(id(m2.extra_attributes),id(m1.extra_attributes))
eq_(id(m2.parameters),id(m1.parameters))
eq_(id(m2.layers),id(m1.layers))
eq_(id(m2.layers),id(m1.layers))

View file

@ -20,10 +20,10 @@ if 'osm' in mapnik.DatasourceCache.instance().plugin_names():
e = ds.envelope()
# these are hardcoded in the plugin… ugh
assert_almost_equal(e.minx, -180.0)
assert_almost_equal(e.miny, -90.0)
assert_almost_equal(e.maxx, 180.0)
assert_almost_equal(e.maxy, 90)
eq_(e.minx >= -180.0,True)
eq_(e.miny >= -90.0,True)
eq_(e.maxx <= 180.0,True)
eq_(e.maxy <= 90,True)
@raises(RuntimeError)
def test_that_nonexistant_query_field_throws(**kwargs):

View file

@ -24,6 +24,11 @@ def test_parameter():
eq_(p[0],'float')
eq_(p[1],1.0777)
p = mapnik.Parameter('bool_string','True')
eq_(p[0],'bool_string')
eq_(p[1],'True')
eq_(bool(p[1]),True)
def test_parameters():
params = mapnik.Parameters()

View file

@ -57,6 +57,8 @@ def create_grid_map(width,height):
s = mapnik.Style()
r = mapnik.Rule()
symb = mapnik.MarkersSymbolizer()
symb.width = 10
symb.height = 10
symb.allow_overlap = True
r.symbols.append(symb)

View file

@ -146,6 +146,8 @@ def test_render_grid():
s = mapnik.Style()
r = mapnik.Rule()
symb = mapnik.MarkersSymbolizer()
symb.width = 10
symb.height = 10
symb.allow_overlap = True
r.symbols.append(symb)
s.rules.append(r)

View file

@ -42,9 +42,9 @@ def compare(fn1, fn2):
def summary():
global errors
print "-"*80
print "Summary:"
if len(errors) != 0:
print "-"*80
print "Summary:"
for error in errors:
if (error[1] is None):
print "Could not verify %s: No reference image found!" % error[0]
@ -52,3 +52,7 @@ def summary():
print "%s failed: %d different pixels" % error
print "-"*80
sys.exit(1)
else:
print 'No errors detected!'
print "-"*80
sys.exit(0)

View file

@ -19,6 +19,7 @@ sizes_many_in_small_range = [(490, 100), (495, 100), (497, 100), (498, 100),
(499, 100), (500, 100), (501, 100), (502, 100), (505, 100), (510, 100)]
dirname = os.path.dirname(__file__)
files = [
{'name': "list", 'sizes': sizes_many_in_big_range},
{'name': "simple", 'sizes': sizes_many_in_big_range},

View file

@ -4,6 +4,8 @@ import sys
import os.path
from compare import compare, summary
dirname = os.path.dirname(__file__)
class MyText(mapnik.FormattingNode):
def __init__(self):
mapnik.FormattingNode.__init__(self)
@ -69,7 +71,7 @@ m.append_style('Style', style)
layer = mapnik.Layer('Layer')
layer.datasource = mapnik.Shapefile(file="data/points.shp")
layer.datasource = mapnik.Shapefile(file=os.path.join(dirname,"data/points.shp"))
layer.styles.append('Style')
m.layers.append(layer)
@ -97,9 +99,9 @@ format_trees = [
for format_tree in format_trees:
text.placements.defaults.format_tree = format_tree[1]
mapnik.render_to_file(m, os.path.join("images", 'python-%s.png' % format_tree[0]), 'png')
compare(os.path.join("images", 'python-%s.png' % format_tree[0]),
os.path.join("images", 'python-%s-reference.png' % format_tree[0])
mapnik.render_to_file(m, os.path.join(dirname,"images", 'python-%s.png' % format_tree[0]), 'png')
compare(os.path.join(dirname,"images", 'python-%s.png' % format_tree[0]),
os.path.join(dirname,"images", 'python-%s-reference.png' % format_tree[0])
)
summary()