Merge branch '2.3.x' of github.com:mapnik/mapnik

Conflicts:
	src/deepcopy.cpp
	src/expression.cpp
	src/rule.cpp
This commit is contained in:
Dane Springmeyer 2013-11-13 20:00:13 -08:00
commit 03fdf7e596
30 changed files with 175 additions and 323 deletions

View file

@ -779,17 +779,17 @@ int main( int argc, char** argv)
}
{
test3 runner(1000000,10);
test3 runner(100000,10);
benchmark(runner,"double to string conversion with std::ostringstream");
}
{
test4 runner(1000000,10);
test4 runner(100000,10);
benchmark(runner,"double to string conversion with mapnik::util_to_string");
}
{
test5 runner(1000000,10);
test5 runner(100000,10);
benchmark(runner,"double to string conversion with snprintf");
}

View file

@ -35,7 +35,6 @@
#include <mapnik/projection.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/feature_type_style.hpp>
//#include <mapnik/util/deepcopy.hpp>
#include "mapnik_enumeration.hpp"
using mapnik::color;
@ -372,7 +371,6 @@ void export_map()
">>> m.zoom_to_box(extent)\n"
)
//.def("__deepcopy__",&map_deepcopy)
.add_property("parameters",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO")
.add_property("aspect_fix_mode",

View file

@ -65,7 +65,7 @@ private:
public:
feature_type_style();
feature_type_style(feature_type_style const& rhs, bool deep_copy = false);
feature_type_style(feature_type_style const& rhs);
feature_type_style& operator=(feature_type_style const& rhs);

View file

@ -112,7 +112,7 @@ public:
*/
Map(int width, int height, std::string const& srs=MAPNIK_LONGLAT_PROJ);
/*! \brief Copy Constructur.
/*! \brief Copy Constructor.
*
* @param rhs Map to copy from.
*/

View file

@ -145,7 +145,7 @@ public:
rule(std::string const& name,
double min_scale_denominator = 0,
double max_scale_denominator = std::numeric_limits<double>::infinity());
rule(const rule& rhs, bool deep_copy = false);
rule(rule const& rhs);
rule& operator=(rule const& rhs);
bool operator==(rule const& other);

View file

@ -1,35 +0,0 @@
/*****************************************************************************
*
* 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_DEEPCOPY_HPP
#define MAPNIK_DEEPCOPY_HPP
#include <mapnik/map.hpp>
namespace mapnik { namespace util {
// poor man deepcopy implementation
void deepcopy(Map const& map_in, Map & map_out);
}}
#endif // MAPNIK_DEEPSOPY_HPP

View file

@ -55,6 +55,18 @@ public:
close();
}
void abort()
{
if(conn_ && conn_->isPending() )
{
MAPNIK_LOG_DEBUG(postgis) << "AsyncResultSet: aborting pending connection - " << conn_.get();
// there is no easy way to abort a pending connection, so we close it : this will ensure that
// the connection will be recycled in the pool
conn_->close();
}
}
virtual void close()
{
if (!is_closed_)
@ -63,6 +75,10 @@ public:
is_closed_ = true;
if (conn_)
{
if(conn_->isPending())
{
abort();
}
conn_.reset();
}
}

View file

@ -44,7 +44,8 @@ class Connection
public:
Connection(std::string const& connection_str,boost::optional<std::string> const& password)
: cursorId(0),
closed_(false)
closed_(false),
pending_(false)
{
std::string connect_with_pass = connection_str;
if (password && !password->empty())
@ -52,6 +53,7 @@ public:
connect_with_pass += " password=" + *password;
}
conn_ = PQconnectdb(connect_with_pass.c_str());
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: postgresql connection create - " << this;
if (PQstatus(conn_) != CONNECTION_OK)
{
std::string err_msg = "Postgis Plugin: ";
@ -59,6 +61,8 @@ public:
err_msg += "\nConnection string: '";
err_msg += connection_str;
err_msg += "'\n";
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: creation failed, closing connection - " << this;
close();
throw mapnik::datasource_exception(err_msg);
}
}
@ -68,7 +72,7 @@ public:
if (! closed_)
{
PQfinish(conn_);
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: postgresql connection closed - " << conn_;
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: postgresql connection closed - " << this;
closed_ = true;
}
}
@ -154,6 +158,7 @@ public:
close();
throw mapnik::datasource_exception(err_msg);
}
pending_ = true;
return result;
}
@ -202,12 +207,17 @@ public:
return (!closed_) && (PQstatus(conn_) != CONNECTION_BAD);
}
bool isPending() const
{
return pending_;
}
void close()
{
if (! closed_)
{
PQfinish(conn_);
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: datasource closed, also closing connection - " << conn_;
MAPNIK_LOG_DEBUG(postgis) << "postgis_connection: closing connection (close)- " << this;
closed_ = true;
}
}
@ -223,8 +233,9 @@ private:
PGconn *conn_;
int cursorId;
bool closed_;
bool pending_;
void clearAsyncResult(PGresult *result) const
void clearAsyncResult(PGresult *result)
{
// Clear all pending results
while(result)
@ -232,6 +243,7 @@ private:
PQclear(result);
result = PQgetResult(conn_);
}
pending_ = false;
}
};

View file

@ -138,7 +138,6 @@ source = Split(
datasource_cache.cpp
datasource_cache_static.cpp
debug.cpp
deepcopy.cpp
expression_node.cpp
expression_grammar.cpp
expression_string.cpp

View file

@ -1,137 +0,0 @@
/*****************************************************************************
*
* 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/feature_type_style.hpp>
#include <mapnik/map.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/params.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/util/deepcopy.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/building_symbolizer.hpp>
#include <mapnik/line_symbolizer.hpp>
#include <mapnik/line_pattern_symbolizer.hpp>
#include <mapnik/polygon_symbolizer.hpp>
#include <mapnik/polygon_pattern_symbolizer.hpp>
#include <mapnik/point_symbolizer.hpp>
#include <mapnik/raster_symbolizer.hpp>
#include <mapnik/shield_symbolizer.hpp>
#include <mapnik/text_symbolizer.hpp>
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/debug_symbolizer.hpp>
// boost
#include <boost/optional.hpp>
namespace mapnik { namespace util {
// poor man's deepcopy implementation
void deepcopy(Map const& map_in, Map & map_out)
{
// * width_(rhs.width_),
// * height_(rhs.height_),
// * srs_(rhs.srs_),
// * buffer_size_(rhs.buffer_size_),
// * background_(rhs.background_),
// * background_image_(rhs.background_image_),
// * styles_(rhs.styles_),
// fontsets_(rhs.fontsets_),
// * layers_(rhs.layers_),
// aspectFixMode_(rhs.aspectFixMode_),
// 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_)
// width, height
map_out.resize(map_in.width(), map_in.height());
// srs
map_out.set_srs(map_in.srs());
// buffer_size
map_out.set_buffer_size(map_in.buffer_size());
// background
boost::optional<color> background = map_in.background();
if (background)
{
map_out.set_background(*background);
}
// background_image
boost::optional<std::string> background_image = map_in.background_image();
if (background_image)
{
map_out.set_background_image(*background_image);
}
map_out.set_background_image_comp_op(map_in.background_image_comp_op());
map_out.set_background_image_opacity(map_in.background_image_opacity());
// maximum extent
boost::optional<box2d<double> > max_extent = map_in.maximum_extent();
if (max_extent)
{
map_out.set_maximum_extent(*max_extent);
}
// base_path
map_out.set_base_path(map_in.base_path());
// fontsets
typedef std::map<std::string,font_set> fontsets;
for (fontsets::value_type const& kv : map_in.fontsets())
{
map_out.insert_fontset(kv.first,kv.second);
}
for ( layer const& lyr_in : map_in.layers())
{
layer lyr_out(lyr_in);
datasource_ptr ds_in = lyr_in.datasource();
if (ds_in)
{
parameters p(ds_in->params());
// TODO : re-use datasource extent if already set.
datasource_ptr ds_out = datasource_cache::instance().create(p);
if (ds_out)
{
lyr_out.set_datasource(ds_out);
}
}
map_out.addLayer(lyr_out);
}
typedef std::map<std::string, feature_type_style> style_cont;
typedef style_cont::value_type value_type;
style_cont const& styles = map_in.styles();
for ( value_type const& kv : styles )
{
feature_type_style const& style_in = kv.second;
feature_type_style style_out(style_in,true); // deep copy
map_out.insert_style(kv.first, style_out);
}
}
}}

View file

@ -43,13 +43,13 @@ expression_ptr parse_expression(std::string const& str, std::string const& encod
expression_ptr parse_expression(std::string const& str,
mapnik::expression_grammar<std::string::const_iterator> const& g)
{
expr_node node;
expression_ptr node = std::make_shared<expr_node>();
std::string::const_iterator itr = str.begin();
std::string::const_iterator end = str.end();
bool r = boost::spirit::qi::phrase_parse(itr, end, g, boost::spirit::standard_wide::space, node);
bool r = boost::spirit::qi::phrase_parse(itr, end, g, boost::spirit::standard_wide::space, *node);
if (r && itr == end)
{
return std::make_shared<expr_node>(node);
return node;
}
else
{

View file

@ -46,32 +46,24 @@ feature_type_style::feature_type_style()
opacity_(1.0f)
{}
feature_type_style::feature_type_style(feature_type_style const& rhs, bool deep_copy)
: filter_mode_(rhs.filter_mode_),
feature_type_style::feature_type_style(feature_type_style const& rhs)
: rules_(rhs.rules_),
filter_mode_(rhs.filter_mode_),
filters_(rhs.filters_),
direct_filters_(rhs.direct_filters_),
comp_op_(rhs.comp_op_),
opacity_(rhs.opacity_)
{
if (!deep_copy) {
rules_ = rhs.rules_;
} else {
rules::const_iterator it = rhs.rules_.begin(),
end = rhs.rules_.end();
for(; it != end; ++it) {
rules_.push_back(rule(*it, deep_copy));
}
}
}
feature_type_style& feature_type_style::operator=(feature_type_style const& rhs)
feature_type_style& feature_type_style::operator=(feature_type_style const& other)
{
if (this == &rhs) return *this;
rules_=rhs.rules_;
filters_ = rhs.filters_;
direct_filters_ = rhs.direct_filters_;
comp_op_ = rhs.comp_op_;
opacity_= rhs.opacity_;
if (this == &other) return *this;
rules_ = other.rules_;
filters_ = other.filters_;
direct_filters_ = other.direct_filters_;
comp_op_ = other.comp_op_;
opacity_ = other.opacity_;
return *this;
}

View file

@ -40,64 +40,10 @@
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/debug_symbolizer.hpp>
// boost
#include <memory>
#include <boost/concept_check.hpp>
// stl
#include <memory>
#include <limits>
namespace {
struct deepcopy_symbolizer : public boost::static_visitor<>
{
void operator () (mapnik::raster_symbolizer & sym) const
{
mapnik::raster_colorizer_ptr old_colorizer = sym.get_colorizer();
mapnik::raster_colorizer_ptr new_colorizer = mapnik::raster_colorizer_ptr();
new_colorizer->set_stops(old_colorizer->get_stops());
new_colorizer->set_default_mode(old_colorizer->get_default_mode());
new_colorizer->set_default_color(old_colorizer->get_default_color());
new_colorizer->set_epsilon(old_colorizer->get_epsilon());
sym.set_colorizer(new_colorizer);
}
void operator () (mapnik::text_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (mapnik::shield_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (mapnik::building_symbolizer & sym) const
{
copy_height_ptr(sym);
}
template <typename T> void operator () (T &sym) const
{
boost::ignore_unused_variable_warning(sym);
}
template <class T>
void copy_text_ptr(T & sym) const
{
boost::ignore_unused_variable_warning(sym);
MAPNIK_LOG_WARN(rule) << "rule: deep copying TextSymbolizers is broken!";
}
template <class T>
void copy_height_ptr(T & sym) const
{
std::string height_expr = mapnik::to_expression_string(*sym.height());
sym.set_height(mapnik::parse_expression(height_expr,"utf8"));
}
};
}
namespace mapnik
{
@ -106,7 +52,7 @@ rule::rule()
min_scale_(0),
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(std::make_shared<mapnik::expr_node>(true)),
filter_(std::make_shared<expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
@ -117,31 +63,19 @@ rule::rule(std::string const& name,
min_scale_(min_scale_denominator),
max_scale_(max_scale_denominator),
syms_(),
filter_(std::make_shared<mapnik::expr_node>(true)),
filter_(std::make_shared<expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
rule::rule(const rule& rhs, bool deep_copy)
rule::rule(rule const& rhs)
: name_(rhs.name_),
min_scale_(rhs.min_scale_),
max_scale_(rhs.max_scale_),
syms_(rhs.syms_),
filter_(rhs.filter_),
filter_(std::make_shared<expr_node>(*rhs.filter_)),
else_filter_(rhs.else_filter_),
also_filter_(rhs.also_filter_)
{
if (deep_copy) {
std::string expr = to_expression_string(*filter_);
filter_ = parse_expression(expr,"utf8");
symbolizers::const_iterator it = syms_.begin();
symbolizers::const_iterator end = syms_.end();
for(; it != end; ++it)
{
boost::apply_visitor(deepcopy_symbolizer(),*it);
}
}
}
rule& rule::operator=(rule const& rhs)

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -5,11 +5,19 @@ from utilities import execution_path, run_all
import os, sys, glob, mapnik
default_logging_severity = mapnik.logger.get_severity()
def setup():
# make the tests silent to suppress unsupported params from harfbuzz tests
# TODO: remove this after harfbuzz branch merges
mapnik.logger.set_severity(mapnik.severity_type.None)
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def teardown():
mapnik.logger.set_severity(default_logging_severity)
def test_broken_files():
default_logging_severity = mapnik.logger.get_severity()
mapnik.logger.set_severity(mapnik.severity_type.None)

View file

@ -1,43 +0,0 @@
#!/usr/bin/env python
from nose.tools import *
from utilities import execution_path, run_all
from copy import deepcopy
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_map_deepcopy1():
# m1 = mapnik.Map(256,256)
# m1.append_style('style',mapnik.Style())
# m1.append_fontset('fontset',mapnik.FontSet())
# m2 = deepcopy(m1)
# eq_(m2.width, m1.width)
# eq_(m2.height, m2.height)
# eq_(m2.srs, m1.srs)
# eq_(m2.base, m1.base)
# eq_(m2.background, m1.background)
# eq_(m2.buffer_size, m1.buffer_size)
# eq_(m2.aspect_fix_mode, m1.aspect_fix_mode)
# eq_(m2.envelope(),m1.envelope())
# eq_(m2.buffered_envelope(),m1.buffered_envelope())
# eq_(m2.scale(),m1.scale())
# eq_(m2.scale_denominator(),m1.scale_denominator())
# eq_(m2.maximum_extent,m1.maximum_extent)
# eq_(id(m2.view_transform()),id(m1.view_transform()))
# eq_(id(m2.parameters),id(m1.parameters))
# eq_(id(m2.layers),id(m1.layers))
# eq_(id(m2.layers),id(m1.layers))
# eq_(id(m2.find_fontset('fontset')),id(m2.find_fontset('fontset')))
# # fails for some reason on linux (not osx)
# # but non-critical for now
# #eq_(id(m2.find_style('style')),id(m2.find_style('style')))
if __name__ == "__main__":
setup()
run_all(eval(x) for x in dir() if x.startswith("test_"))

View file

@ -701,6 +701,63 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
count += 1
eq_(count,8)
def test_psql_error_should_give_back_connections_opened_for_lower_layers_to_the_pool():
map1 = mapnik.Map(600,300)
s = mapnik.Style()
r = mapnik.Rule()
r.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color('#f2eff9')))
s.rules.append(r)
map1.append_style('style',s)
# This layer will fail after a while
buggy_s = mapnik.Style()
buggy_r = mapnik.Rule()
buggy_r.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color('#ff0000')))
buggy_r.filter = mapnik.Filter("[fips] = 'FR'")
buggy_s.rules.append(buggy_r)
map1.append_style('style for buggy layer',buggy_s)
buggy_layer = mapnik.Layer('this layer is buggy at runtime')
# We ensure the query wille be long enough
buggy_layer.datasource = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(SELECT geom as geom, pg_sleep(0.1), fips::int from world_merc) as failure_tabl',
max_async_connection=2, max_size=2,asynchronous_request = True, geometry_field='geom')
buggy_layer.styles.append('style for buggy layer')
# The query for this layer will be sent, then the previous layer will raise an exception before results are read
forced_canceled_layer = mapnik.Layer('this layer will be canceled when an exception stops map rendering')
forced_canceled_layer.datasource = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='world_merc',
max_async_connection=2, max_size=2, asynchronous_request = True, geometry_field='geom')
forced_canceled_layer.styles.append('style')
map1.layers.append(buggy_layer)
map1.layers.append(forced_canceled_layer)
map1.zoom_all()
map2 = mapnik.Map(600,300)
map2.background = mapnik.Color('steelblue')
s = mapnik.Style()
r = mapnik.Rule()
r.symbols.append(mapnik.LineSymbolizer(mapnik.Color('rgb(50%,50%,50%)'),0.1))
r.symbols.append(mapnik.LineSymbolizer(mapnik.Color('rgb(50%,50%,50%)'),0.1))
s.rules.append(r)
map2.append_style('style',s)
layer1 = mapnik.Layer('layer1')
layer1.datasource = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='world_merc',
max_async_connection=2, max_size=2, asynchronous_request = True, geometry_field='geom')
layer1.styles.append('style')
map2.layers.append(layer1)
map2.zoom_all()
# We expect this to trigger a PSQL error
try:
mapnik.render_to_file(map1,'world.png', 'png')
# Test must fail if error was not raised just above
eq_(False,True)
except RuntimeError:
pass
# This used to raise an exception before correction of issue 2042
mapnik.render_to_file(map2,'world2.png', 'png')
atexit.register(postgis_takedown)
if __name__ == "__main__":

View file

@ -173,6 +173,49 @@ def test_render_with_scale_factor_zero_throws():
im = mapnik.Image(256, 256)
mapnik.render(m,im,0.0)
def test_render_with_detector():
ds = mapnik.MemoryDatasource()
context = mapnik.Context()
geojson = '{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 0, 0 ] } }'
ds.add_feature(mapnik.Feature.from_geojson(geojson,context))
s = mapnik.Style()
r = mapnik.Rule()
lyr = mapnik.Layer('point')
lyr.datasource = ds
lyr.styles.append('point')
symb = mapnik.MarkersSymbolizer()
symb.allow_overlap = False
r.symbols.append(symb)
s.rules.append(r)
m = mapnik.Map(256,256)
m.append_style('point',s)
m.layers.append(lyr)
m.zoom_to_box(mapnik.Box2d(-180,-85,180,85))
im = mapnik.Image(256, 256)
mapnik.render(m,im)
expected_file = './images/support/marker-in-center.png'
actual_file = '/tmp/' + os.path.basename(expected_file)
#im.save(expected_file,'png8')
im.save(actual_file,'png8')
actual = mapnik.Image.open(expected_file)
expected = mapnik.Image.open(expected_file)
eq_(actual.tostring(),expected.tostring(), 'failed comparing actual (%s) and expected (%s)' % (actual_file,expected_file))
# now render will a collision detector that should
# block out the placement of this point
detector = mapnik.LabelCollisionDetector(m)
eq_(detector.extent(),mapnik.Box2d(-0.0,-0.0,m.width,m.height))
eq_(detector.extent(),mapnik.Box2d(-0.0,-0.0,256.0,256.0))
eq_(detector.boxes(),[])
detector.insert(detector.extent())
eq_(detector.boxes(),[detector.extent()])
im2 = mapnik.Image(256, 256)
mapnik.render_with_detector(m, im2, detector)
expected_file_collision = './images/support/marker-in-center-not-placed.png'
#im2.save(expected_file_collision,'png8')
actual_file = '/tmp/' + os.path.basename(expected_file_collision)
im2.save(actual_file,'png8')
if 'shape' in mapnik.DatasourceCache.plugin_names():
def test_render_with_scale_factor():
@ -185,10 +228,10 @@ if 'shape' in mapnik.DatasourceCache.plugin_names():
mapnik.render(m,im,size)
expected_file = './images/support/marker-text-line-scale-factor-%s.png' % size
actual_file = '/tmp/' + os.path.basename(expected_file)
im.save(actual_file,'png8')
#im.save(expected_file,'png8')
im.save(actual_file,'png32')
#im.save(expected_file,'png32')
# we save and re-open here so both png8 images are ready as full color png
actual = mapnik.Image.open(expected_file)
actual = mapnik.Image.open(actual_file)
expected = mapnik.Image.open(expected_file)
eq_(actual.tostring(),expected.tostring(), 'failed comparing actual (%s) and expected (%s)' % (actual_file,expected_file))

View file

@ -6,11 +6,19 @@ import tempfile
import os, sys, glob, mapnik
default_logging_severity = mapnik.logger.get_severity()
def setup():
# make the tests silent to suppress unsupported params from harfbuzz tests
# TODO: remove this after harfbuzz branch merges
mapnik.logger.set_severity(mapnik.severity_type.None)
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
def teardown():
mapnik.logger.set_severity(default_logging_severity)
def compare_map(xml):
m = mapnik.Map(256, 256)
absolute_base = os.path.abspath(os.path.dirname(xml))