Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
d6cbdd3412
33 changed files with 1078 additions and 304 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -35,3 +35,10 @@ tests/cpp_tests/svg_renderer_tests/path_element_test
|
|||
tests/cpp_tests/svg_renderer_tests/path_element_test_case_1.svg
|
||||
tests/cpp_tests/svg_renderer_tests/root_element_test
|
||||
tests/data/sqlite/*index
|
||||
demo/c++/cairo-demo.pdf
|
||||
demo/c++/cairo-demo.png
|
||||
demo/c++/cairo-demo256.png
|
||||
demo/c++/demo.jpg
|
||||
demo/c++/demo.png
|
||||
demo/c++/demo256.png
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
#include "mapnik_value_converter.hpp"
|
||||
|
||||
mapnik::geometry_type & (mapnik::Feature::*get_geom1)(unsigned) = &mapnik::Feature::get_geometry;
|
||||
|
||||
|
@ -95,9 +94,11 @@ namespace boost { namespace python {
|
|||
|
||||
template <class Class>
|
||||
static void
|
||||
extension_def(Class& /*cl*/)
|
||||
extension_def(Class& cl)
|
||||
{
|
||||
|
||||
cl
|
||||
.def("get", &get)
|
||||
;
|
||||
}
|
||||
|
||||
static data_type&
|
||||
|
@ -106,12 +107,25 @@ namespace boost { namespace python {
|
|||
typename Container::iterator i = container.props().find(i_);
|
||||
if (i == container.end())
|
||||
{
|
||||
PyErr_SetString(PyExc_KeyError, "Invalid key");
|
||||
PyErr_SetString(PyExc_KeyError, i_.c_str());
|
||||
throw_error_already_set();
|
||||
}
|
||||
// will be auto-converted to proper python type by `mapnik_value_to_python`
|
||||
return i->second;
|
||||
}
|
||||
|
||||
static data_type
|
||||
get(Container& container, index_type i_)
|
||||
{
|
||||
typename Container::iterator i = container.props().find(i_);
|
||||
if (i != container.end())
|
||||
{
|
||||
// will be auto-converted to proper python type by `mapnik_value_to_python`
|
||||
return i->second;
|
||||
}
|
||||
return mapnik::value_null();
|
||||
}
|
||||
|
||||
static void
|
||||
set_item(Container& container, index_type i, data_type const& v)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/util/geometry_to_wkb.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -47,19 +48,47 @@ geometry_type const& getitem_impl(path_type & p, int key)
|
|||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
void from_wkt_impl(path_type& p, std::string const& wkt)
|
||||
void add_wkt_impl(path_type& p, std::string const& wkt)
|
||||
{
|
||||
bool result = mapnik::from_wkt(wkt , p);
|
||||
if (!result) throw std::runtime_error("Failed to parse WKT");
|
||||
}
|
||||
|
||||
void from_wkb_impl(path_type& p, std::string const& wkb)
|
||||
void add_wkb_impl(path_type& p, std::string const& wkb)
|
||||
{
|
||||
mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size(), true);
|
||||
}
|
||||
|
||||
boost::shared_ptr<path_type> from_wkt_impl(std::string const& wkt)
|
||||
{
|
||||
boost::shared_ptr<path_type> paths = boost::make_shared<path_type>();
|
||||
bool result = mapnik::from_wkt(wkt, *paths);
|
||||
if (!result) throw std::runtime_error("Failed to parse WKT");
|
||||
return paths;
|
||||
}
|
||||
|
||||
boost::shared_ptr<path_type> from_wkb_impl(std::string const& wkb)
|
||||
{
|
||||
boost::shared_ptr<path_type> paths = boost::make_shared<path_type>();
|
||||
mapnik::geometry_utils::from_wkb(*paths, wkb.c_str(), wkb.size(), true);
|
||||
return paths;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyObject* to_wkb( geometry_type const& geom)
|
||||
{
|
||||
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::util::wkbXDR);
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyBytes_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
((const char*)wkb->buffer(),wkb->size());
|
||||
}
|
||||
|
||||
|
||||
void export_geometry()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
@ -78,14 +107,19 @@ void export_geometry()
|
|||
.def("envelope",&geometry_type::envelope)
|
||||
// .def("__str__",&geometry_type::to_string)
|
||||
.def("type",&geometry_type::type)
|
||||
.def("to_wkb",&to_wkb)
|
||||
// TODO add other geometry_type methods
|
||||
;
|
||||
|
||||
class_<path_type,boost::noncopyable>("Path")
|
||||
class_<path_type, boost::shared_ptr<path_type>, boost::noncopyable>("Path")
|
||||
.def("__getitem__", getitem_impl,return_value_policy<reference_existing_object>())
|
||||
.def("__len__", &path_type::size)
|
||||
.def("add_wkt",add_wkt_impl)
|
||||
.def("add_wkb",add_wkb_impl)
|
||||
.def("from_wkt",from_wkt_impl)
|
||||
.def("from_wkb",from_wkb_impl)
|
||||
.staticmethod("from_wkt")
|
||||
.staticmethod("from_wkb")
|
||||
;
|
||||
|
||||
}
|
||||
|
|
|
@ -119,6 +119,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)
|
||||
{
|
||||
|
@ -173,6 +175,7 @@ mapnik::featureset_ptr query_map_point(mapnik::Map const& m, int index, double x
|
|||
return m.query_map_point(idx, x, y);
|
||||
}
|
||||
|
||||
|
||||
void export_map()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
@ -449,7 +452,8 @@ void export_map()
|
|||
"about the hit areas rendered on the map.\n"
|
||||
)
|
||||
|
||||
.def("extra_attributes",&Map::get_extra_attributes,return_value_policy<copy_const_reference>(),"TODO")
|
||||
.add_property("extra_attributes",make_function(attr_nonconst,return_value_policy<reference_existing_object>()),"TODO")
|
||||
.add_property("params",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO")
|
||||
|
||||
.add_property("aspect_fix_mode",
|
||||
&Map::get_aspect_fix_mode,
|
||||
|
|
|
@ -48,6 +48,6 @@ void export_palette ()
|
|||
( arg("palette"), arg("type")),
|
||||
"Creates a new color palette from a file\n"
|
||||
)*/
|
||||
.def( "__init__", boost::python::make_constructor( &make_palette))
|
||||
.def( "__init__", boost::python::make_constructor(make_palette))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
|
||||
* 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
|
||||
|
@ -19,50 +19,26 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
//$Id: mapnik_parameters.cpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
// boost
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
|
||||
using mapnik::parameter;
|
||||
using mapnik::parameters;
|
||||
|
||||
struct pickle_value : public boost::static_visitor<>
|
||||
{
|
||||
public:
|
||||
pickle_value( boost::python::list vals):
|
||||
vals_(vals) {}
|
||||
|
||||
void operator () ( int val )
|
||||
{
|
||||
vals_.append(val);
|
||||
}
|
||||
|
||||
void operator () ( double val )
|
||||
{
|
||||
vals_.append(val);
|
||||
}
|
||||
|
||||
void operator () ( std::string val )
|
||||
{
|
||||
vals_.append(val);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::python::list vals_;
|
||||
|
||||
};
|
||||
|
||||
struct parameter_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static boost::python::tuple
|
||||
getinitargs(const parameter& p)
|
||||
{
|
||||
using namespace boost::python;
|
||||
return boost::python::make_tuple(p.first,boost::get<std::string>(p.second));
|
||||
return boost::python::make_tuple(p.first,p.second);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -76,11 +52,7 @@ struct parameters_pickle_suite : boost::python::pickle_suite
|
|||
parameters::const_iterator pos=p.begin();
|
||||
while(pos!=p.end())
|
||||
{
|
||||
boost::python::list vals;
|
||||
pickle_value serializer( vals );
|
||||
mapnik::value_holder val = pos->second;
|
||||
boost::apply_visitor( serializer, val );
|
||||
d[pos->first] = vals[0];
|
||||
d[pos->first] = pos->second;
|
||||
++pos;
|
||||
}
|
||||
return boost::python::make_tuple(d);
|
||||
|
@ -107,7 +79,9 @@ struct parameters_pickle_suite : boost::python::pickle_suite
|
|||
extract<std::string> ex0(obj);
|
||||
extract<int> ex1(obj);
|
||||
extract<double> ex2(obj);
|
||||
extract<UnicodeString> ex3(obj);
|
||||
|
||||
// TODO - this is never hit - we need proper python string -> std::string to get invoked here
|
||||
if (ex0.check())
|
||||
{
|
||||
p[key] = ex0();
|
||||
|
@ -120,72 +94,131 @@ struct parameters_pickle_suite : boost::python::pickle_suite
|
|||
{
|
||||
p[key] = ex2();
|
||||
}
|
||||
|
||||
/*
|
||||
extract_value serializer( p, key );
|
||||
mapnik::value_holder val = extract<mapnik::value_holder>(d[key]);
|
||||
boost::apply_visitor( serializer, val );
|
||||
*/
|
||||
else if (ex3.check())
|
||||
{
|
||||
std::string buffer;
|
||||
mapnik::to_utf8(ex3(),buffer);
|
||||
p[key] = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::clog << "could not unpickle key: " << key << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
boost::python::dict dict_params(parameters& p)
|
||||
|
||||
mapnik::value_holder get_params_by_key1(mapnik::parameters const& p, std::string const& key)
|
||||
{
|
||||
boost::python::dict d;
|
||||
parameters::const_iterator pos=p.begin();
|
||||
while(pos!=p.end())
|
||||
parameters::const_iterator pos = p.find(key);
|
||||
if (pos != p.end())
|
||||
{
|
||||
boost::python::list vals;
|
||||
pickle_value serializer( vals );
|
||||
mapnik::value_holder val = pos->second;
|
||||
boost::apply_visitor( serializer, val );
|
||||
d[pos->first] = vals[0];
|
||||
++pos;
|
||||
// will be auto-converted to proper python type by `mapnik_params_to_python`
|
||||
return pos->second;
|
||||
}
|
||||
return d;
|
||||
return mapnik::value_null();
|
||||
}
|
||||
|
||||
boost::python::list list_params(parameters& p)
|
||||
mapnik::value_holder get_params_by_key2(mapnik::parameters const& p, std::string const& key)
|
||||
{
|
||||
boost::python::list l;
|
||||
parameters::const_iterator pos=p.begin();
|
||||
while(pos!=p.end())
|
||||
parameters::const_iterator pos = p.find(key);
|
||||
if (pos == p.end())
|
||||
{
|
||||
boost::python::list vals;
|
||||
pickle_value serializer( vals );
|
||||
mapnik::value_holder val = pos->second;
|
||||
boost::apply_visitor( serializer, val );
|
||||
l.append(boost::python::make_tuple(pos->first,vals[0]));
|
||||
++pos;
|
||||
PyErr_SetString(PyExc_KeyError, key.c_str());
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
return l;
|
||||
// will be auto-converted to proper python type by `mapnik_params_to_python`
|
||||
return pos->second;
|
||||
}
|
||||
|
||||
boost::python::dict dict_param(parameter& p)
|
||||
mapnik::parameter get_params_by_index(mapnik::parameters const& p, int index)
|
||||
{
|
||||
boost::python::dict d;
|
||||
d[p.first] = boost::get<std::string>(p.second);
|
||||
return d;
|
||||
if (index < 0 || index > p.size())
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "Index is out of range");
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
boost::python::tuple tuple_param(parameter& p)
|
||||
parameters::const_iterator itr = p.begin();
|
||||
parameters::const_iterator end = p.end();
|
||||
|
||||
unsigned idx = 0;
|
||||
while (itr != p.end())
|
||||
{
|
||||
return boost::python::make_tuple(p.first,boost::get<std::string>(p.second));
|
||||
if (idx == index)
|
||||
{
|
||||
return *itr;
|
||||
}
|
||||
++idx;
|
||||
++itr;
|
||||
}
|
||||
PyErr_SetString(PyExc_IndexError, "Index is out of range");
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
void add_parameter(mapnik::parameters & p, mapnik::parameter const& param)
|
||||
{
|
||||
p[param.first] = param.second;
|
||||
}
|
||||
|
||||
mapnik::value_holder get_param(mapnik::parameter const& p, int index)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
return p.first;
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
return p.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "Index is out of range");
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<mapnik::parameter> create_parameter_from_string(std::string const& key, std::string const& value)
|
||||
{
|
||||
return boost::make_shared<mapnik::parameter>(key,mapnik::value_holder(value));
|
||||
}
|
||||
|
||||
boost::shared_ptr<mapnik::parameter> create_parameter_from_int(std::string const& key, int value)
|
||||
{
|
||||
return boost::make_shared<mapnik::parameter>(key,mapnik::value_holder(value));
|
||||
}
|
||||
|
||||
boost::shared_ptr<mapnik::parameter> create_parameter_from_float(std::string const& key, double value)
|
||||
{
|
||||
return boost::make_shared<mapnik::parameter>(key,mapnik::value_holder(value));
|
||||
}
|
||||
|
||||
|
||||
void export_parameters()
|
||||
{
|
||||
using namespace boost::python;
|
||||
class_<parameter>("Parameter",init<std::string,std::string>())
|
||||
class_<parameter,boost::shared_ptr<parameter> >("Parameter",no_init)
|
||||
.def("__init__", make_constructor(create_parameter_from_string),
|
||||
"Create a mapnik.Parameter from a pair of values, the first being a string\n"
|
||||
"and the second being either a string, and integer, or a float")
|
||||
.def("__init__", make_constructor(create_parameter_from_int),
|
||||
"Create a mapnik.Parameter from a pair of values, the first being a string\n"
|
||||
"and the second being either a string, and integer, or a float")
|
||||
.def("__init__", make_constructor(create_parameter_from_float),
|
||||
"Create a mapnik.Parameter from a pair of values, the first being a string\n"
|
||||
"and the second being either a string, and integer, or a float")
|
||||
.def_pickle(parameter_pickle_suite())
|
||||
.def("as_dict",dict_param)
|
||||
.def("as_tuple",tuple_param)
|
||||
.def("__getitem__",get_param)
|
||||
;
|
||||
|
||||
class_<parameters>("Parameters",init<>())
|
||||
.def_pickle(parameters_pickle_suite())
|
||||
.def("as_dict",dict_params)
|
||||
.def("as_list",list_params)
|
||||
.def("get",get_params_by_key1)
|
||||
.def("__getitem__",get_params_by_key2)
|
||||
.def("__getitem__",get_params_by_index)
|
||||
.def("__len__",¶meters::size)
|
||||
.def("append",add_parameter)
|
||||
.def("iteritems",iterator<parameters>())
|
||||
;
|
||||
}
|
||||
|
|
|
@ -83,24 +83,13 @@ void export_label_collision_detector();
|
|||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/save_map.hpp>
|
||||
#include "python_grid_utils.hpp"
|
||||
#include "mapnik_value_converter.hpp"
|
||||
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
#include <pycairo.h>
|
||||
static Pycairo_CAPI_t *Pycairo_CAPI;
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct mapnik_value_to_python
|
||||
{
|
||||
static PyObject* convert(mapnik::value const& v)
|
||||
{
|
||||
return boost::apply_visitor(value_converter(),v.base());
|
||||
}
|
||||
};
|
||||
}}
|
||||
|
||||
void render(const mapnik::Map& map,
|
||||
mapnik::image_32& image,
|
||||
double scale_factor = 1.0,
|
||||
|
@ -651,5 +640,6 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
|
||||
register_ptr_to_python<mapnik::expression_ptr>();
|
||||
register_ptr_to_python<mapnik::path_expression_ptr>();
|
||||
to_python_converter<mapnik::value_holder,mapnik_param_to_python>();
|
||||
to_python_converter<mapnik::value,mapnik_value_to_python>();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <boost/implicit_cast.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct value_converter : public boost::static_visitor<PyObject*>
|
||||
{
|
||||
PyObject * operator() (int val) const
|
||||
|
@ -48,6 +49,13 @@ namespace boost { namespace python {
|
|||
return ::PyBool_FromLong(val);
|
||||
}
|
||||
|
||||
PyObject * operator() (std::string const& s) const
|
||||
{
|
||||
PyObject *obj = Py_None;
|
||||
obj = ::PyUnicode_DecodeUTF8(s.c_str(),implicit_cast<ssize_t>(s.length()),0);
|
||||
return obj;
|
||||
}
|
||||
|
||||
PyObject * operator() (UnicodeString const& s) const
|
||||
{
|
||||
std::string buffer;
|
||||
|
@ -63,6 +71,25 @@ namespace boost { namespace python {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct mapnik_value_to_python
|
||||
{
|
||||
static PyObject* convert(mapnik::value const& v)
|
||||
{
|
||||
return boost::apply_visitor(value_converter(),v.base());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct mapnik_param_to_python
|
||||
{
|
||||
static PyObject* convert(mapnik::value_holder const& v)
|
||||
{
|
||||
return boost::apply_visitor(value_converter(),v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -253,10 +253,13 @@ int main ( int argc , char** argv)
|
|||
save_to_file<image_data_32>(buf.data(),"demo.jpg","jpeg");
|
||||
save_to_file<image_data_32>(buf.data(),"demo.png","png");
|
||||
save_to_file<image_data_32>(buf.data(),"demo256.png","png256");
|
||||
save_to_file<image_data_32>(buf.data(),"demo.tif","tiff");
|
||||
|
||||
std::cout << "Three maps have been rendered using AGG in the current directory:\n"
|
||||
"- demo.jpg\n"
|
||||
"- demo.png\n"
|
||||
"- demo256.png\n"
|
||||
"- demo.tif\n"
|
||||
"Have a look!\n";
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
|
|
|
@ -322,7 +322,7 @@ m.layers.append(popplaces_lyr)
|
|||
# Set the initial extent of the map in 'master' spherical Mercator projection
|
||||
m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855))
|
||||
|
||||
# Render two maps, two PNGs, one JPEG.
|
||||
# Render map
|
||||
im = mapnik.Image(m.width,m.height)
|
||||
mapnik.render(m, im)
|
||||
|
||||
|
@ -347,6 +347,9 @@ images_.append('demo_high.jpg')
|
|||
im.save('demo_low.jpg', 'jpeg50')
|
||||
images_.append('demo_low.jpg')
|
||||
|
||||
im.save('demo.tif', 'tiff')
|
||||
images_.append('demo.tif')
|
||||
|
||||
# Render cairo examples
|
||||
if HAS_PYCAIRO_MODULE and mapnik.has_pycairo():
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ private:
|
|||
boost::optional<box2d<double> > maximum_extent_;
|
||||
std::string base_path_;
|
||||
parameters extra_attr_;
|
||||
parameters extra_params_;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -444,14 +445,34 @@ public:
|
|||
std::string get_metawriter_property(std::string name) const;
|
||||
|
||||
/*!
|
||||
* @brief Get extra properties that can be carried on the Map
|
||||
* @brief Get extra valid attributes of the Map that are not true members
|
||||
*/
|
||||
parameters const& get_extra_attributes() const;
|
||||
|
||||
/*!
|
||||
* @brief Set extra properties that can be carried on the Map
|
||||
* @brief Get non-const extra valid attributes of the Map that are not true members
|
||||
*/
|
||||
void set_extra_attributes(parameters& params);
|
||||
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
|
||||
*/
|
||||
parameters const& get_extra_parameters() const;
|
||||
|
||||
/*!
|
||||
* @brief Get non-const extra, arbitrary Parameters attached to the Map
|
||||
*/
|
||||
parameters& get_extra_parameters();
|
||||
|
||||
/*!
|
||||
* @brief Set extra, arbitary Parameters of the Map
|
||||
*/
|
||||
void set_extra_parameters(parameters& params);
|
||||
|
||||
private:
|
||||
void fixAspectRatio();
|
||||
|
|
|
@ -23,19 +23,22 @@
|
|||
#ifndef MAPNIK_PARAMS_HPP
|
||||
#define MAPNIK_PARAMS_HPP
|
||||
|
||||
// mapnik
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/none.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/value.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
typedef boost::variant<int,double,std::string> value_holder;
|
||||
typedef boost::variant<value_null,int,double,std::string> value_holder;
|
||||
typedef std::pair<const std::string, value_holder> parameter;
|
||||
typedef std::map<const std::string, value_holder> param_map;
|
||||
|
||||
|
|
235
include/mapnik/util/geometry_to_wkb.hpp
Normal file
235
include/mapnik/util/geometry_to_wkb.hpp
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#ifndef MAPNIK_GEOMETRY_TO_WKB_HPP
|
||||
#define MAPNIK_GEOMETRY_TO_WKB_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
// boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/interprocess/streams/bufferstream.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
std::string to_hex(const char* blob, unsigned size)
|
||||
{
|
||||
std::string buf;
|
||||
buf.reserve(size*2);
|
||||
std::ostringstream s(buf);
|
||||
s.seekp(0);
|
||||
char hex[3];
|
||||
std::memset(hex,0,3);
|
||||
for ( unsigned pos=0; pos < size; ++pos)
|
||||
{
|
||||
std::sprintf (hex, "%02x", int(blob[pos]) & 0xff);
|
||||
s << hex;
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
enum wkbByteOrder {
|
||||
wkbXDR=0,
|
||||
wkbNDR=1
|
||||
};
|
||||
|
||||
|
||||
inline void reverse_bytes(char size, char *address)
|
||||
{
|
||||
char * first = address;
|
||||
char * last = first + size - 1;
|
||||
for(;first < last;++first, --last)
|
||||
{
|
||||
char x = *last;
|
||||
*last = *first;
|
||||
*first = x;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename S, typename T>
|
||||
inline void write (S & stream, T val, std::size_t size, wkbByteOrder byte_order)
|
||||
{
|
||||
#ifdef MAPNIK_BIG_ENDIAN
|
||||
bool need_swap = byte_order ? wkbNDR : wkbXDR;
|
||||
#else
|
||||
bool need_swap = byte_order ? wkbXDR : wkbNDR;
|
||||
#endif
|
||||
char* buf = reinterpret_cast<char*>(&val);
|
||||
if (need_swap)
|
||||
{
|
||||
reverse_bytes(size,buf);
|
||||
}
|
||||
stream.write(buf,size);
|
||||
}
|
||||
|
||||
struct wkb_buffer
|
||||
{
|
||||
wkb_buffer(std::size_t size)
|
||||
: size_(size),
|
||||
data_( (size_!=0) ? static_cast<char*>(::operator new (size_)):0)
|
||||
{}
|
||||
|
||||
~wkb_buffer()
|
||||
{
|
||||
::operator delete(data_);
|
||||
}
|
||||
|
||||
inline std::size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
inline char* buffer()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
std::size_t size_;
|
||||
char * data_;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<wkb_buffer> wkb_buffer_ptr;
|
||||
|
||||
wkb_buffer_ptr to_point_wkb( geometry_type const& g, wkbByteOrder byte_order)
|
||||
{
|
||||
assert(g.num_points() == 1);
|
||||
std::size_t size = 1 + 4 + 8*2 ; // byteOrder + wkbType + Point
|
||||
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
|
||||
boost::interprocess::bufferstream ss(wkb->buffer(), wkb->size(), std::ios::out | std::ios::binary);
|
||||
ss.write(reinterpret_cast<char*>(&byte_order),1);
|
||||
int type = static_cast<int>(g.type());
|
||||
write(ss,type,4,byte_order);
|
||||
double x,y;
|
||||
g.get_vertex(0,&x,&y);
|
||||
write(ss,x,8,byte_order);
|
||||
write(ss,y,8,byte_order);
|
||||
assert(ss.good());
|
||||
return wkb;
|
||||
}
|
||||
|
||||
wkb_buffer_ptr to_line_string_wkb( geometry_type const& g, wkbByteOrder byte_order)
|
||||
{
|
||||
unsigned num_points = g.num_points();
|
||||
assert(num_points > 1);
|
||||
std::size_t size = 1 + 4 + 4 + 8*2*num_points ; // byteOrder + wkbType + numPoints + Point*numPoints
|
||||
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
|
||||
boost::interprocess::bufferstream ss(wkb->buffer(), wkb->size(), std::ios::out | std::ios::binary);
|
||||
ss.write(reinterpret_cast<char*>(&byte_order),1);
|
||||
int type = static_cast<int>(g.type());
|
||||
write(ss,type,4,byte_order);
|
||||
write(ss,num_points,4,byte_order);
|
||||
double x,y;
|
||||
for (unsigned i=0; i< num_points; ++i)
|
||||
{
|
||||
g.get_vertex(i,&x,&y);
|
||||
write(ss,x,8,byte_order);
|
||||
write(ss,y,8,byte_order);
|
||||
}
|
||||
assert(ss.good());
|
||||
return wkb;
|
||||
}
|
||||
|
||||
wkb_buffer_ptr to_polygon_wkb( geometry_type const& g, wkbByteOrder byte_order)
|
||||
{
|
||||
unsigned num_points = g.num_points();
|
||||
assert(num_points > 1);
|
||||
|
||||
typedef std::pair<double,double> point_type;
|
||||
typedef std::vector<point_type> linear_ring;
|
||||
boost::ptr_vector<linear_ring> rings;
|
||||
|
||||
double x,y;
|
||||
std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
|
||||
for (unsigned i=0; i< num_points; ++i)
|
||||
{
|
||||
unsigned command = g.get_vertex(i,&x,&y);
|
||||
if (command == SEG_MOVETO)
|
||||
{
|
||||
rings.push_back(new linear_ring); // start new loop
|
||||
size += 4; // num_points
|
||||
}
|
||||
rings.back().push_back(std::make_pair(x,y));
|
||||
size += 2 * 8; // point
|
||||
}
|
||||
unsigned num_rings = rings.size();
|
||||
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
|
||||
boost::interprocess::bufferstream ss(wkb->buffer(), wkb->size(), std::ios::out | std::ios::binary);
|
||||
|
||||
ss.write(reinterpret_cast<char*>(&byte_order),1);
|
||||
int type = static_cast<int>(g.type());
|
||||
write(ss,type,4,byte_order);
|
||||
write(ss,num_rings,4,byte_order);
|
||||
|
||||
BOOST_FOREACH ( linear_ring const& ring, rings)
|
||||
{
|
||||
unsigned num_points = ring.size();
|
||||
write(ss,num_points,4,byte_order);
|
||||
BOOST_FOREACH ( point_type const& pt, ring)
|
||||
{
|
||||
double x = pt.first;
|
||||
double y = pt.second;
|
||||
write(ss,x,8,byte_order);
|
||||
write(ss,y,8,byte_order);
|
||||
}
|
||||
}
|
||||
|
||||
assert(ss.good());
|
||||
return wkb;
|
||||
}
|
||||
|
||||
wkb_buffer_ptr to_wkb(geometry_type const& g, wkbByteOrder byte_order )
|
||||
{
|
||||
wkb_buffer_ptr wkb;
|
||||
|
||||
switch (g.type())
|
||||
{
|
||||
case mapnik::Point :
|
||||
wkb = to_point_wkb(g, byte_order);
|
||||
break;
|
||||
case mapnik::LineString:
|
||||
wkb = to_line_string_wkb(g, byte_order);
|
||||
break;
|
||||
case mapnik::Polygon:
|
||||
wkb = to_polygon_wkb(g, byte_order);
|
||||
break;
|
||||
case mapnik::MultiPoint:
|
||||
case mapnik::MultiLineString:
|
||||
case mapnik::MultiPolygon:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return wkb;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif // MAPNIK_GEOMETRY_TO_WKB_HPP
|
|
@ -351,19 +351,23 @@ includes = glob.glob('../include/mapnik/*.hpp')
|
|||
svg_includes = glob.glob('../include/mapnik/svg/*.hpp')
|
||||
wkt_includes = glob.glob('../include/mapnik/wkt/*.hpp')
|
||||
grid_includes = glob.glob('../include/mapnik/grid/*.hpp')
|
||||
util_includes = glob.glob('../include/mapnik/util/*.hpp')
|
||||
|
||||
inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik')
|
||||
svg_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/svg')
|
||||
wkt_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/wkt')
|
||||
grid_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/grid')
|
||||
util_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/util')
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
env.Alias(target='install', source=env.Install(inc_target, includes))
|
||||
env.Alias(target='install', source=env.Install(svg_inc_target, svg_includes))
|
||||
env.Alias(target='install', source=env.Install(wkt_inc_target, wkt_includes))
|
||||
env.Alias(target='install', source=env.Install(grid_inc_target, grid_includes))
|
||||
env.Alias(target='install', source=env.Install(util_inc_target, util_includes))
|
||||
|
||||
env['create_uninstall_target'](env, inc_target)
|
||||
env['create_uninstall_target'](env, svg_inc_target)
|
||||
env['create_uninstall_target'](env, wkt_inc_target)
|
||||
env['create_uninstall_target'](env, grid_inc_target)
|
||||
env['create_uninstall_target'](env, util_inc_target)
|
||||
|
|
|
@ -226,6 +226,10 @@ void datasource_cache::register_datasources(const std::string& str)
|
|||
#endif
|
||||
registered_=true;
|
||||
}
|
||||
else if (!ds_name)
|
||||
{
|
||||
std::clog << "Problem loading plugin library '" << itr->path().string() << "' (plugin is lacking compatible interface)" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -255,10 +255,10 @@ void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base
|
|||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream s;
|
||||
std::ostringstream s_err;
|
||||
s << "failed to parse 'maximum-extent'";
|
||||
if ( strict_ )
|
||||
throw config_error(s.str());
|
||||
throw config_error(s_err.str());
|
||||
else
|
||||
std::clog << "### WARNING: " << s.str() << std::endl;
|
||||
}
|
||||
|
@ -311,6 +311,7 @@ void map_parser::parse_map( Map & map, ptree const & pt, std::string const& base
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
map.set_extra_attributes(extra_attr);
|
||||
}
|
||||
catch (const config_error & ex)
|
||||
|
@ -389,6 +390,32 @@ void map_parser::parse_map_include( Map & map, ptree const & include )
|
|||
}
|
||||
datasource_templates_[name] = params;
|
||||
}
|
||||
else if (v.first == "Parameters")
|
||||
{
|
||||
std::string name = get_attr(v.second, "name", std::string("Unnamed"));
|
||||
parameters & params = map.get_extra_parameters();
|
||||
ptree::const_iterator paramIter = v.second.begin();
|
||||
ptree::const_iterator endParam = v.second.end();
|
||||
for (; paramIter != endParam; ++paramIter)
|
||||
{
|
||||
ptree const& param = paramIter->second;
|
||||
|
||||
if (paramIter->first == "Parameter")
|
||||
{
|
||||
std::string name = get_attr<std::string>(param, "name");
|
||||
std::string value = get_value<std::string>( param,
|
||||
"parameter");
|
||||
params[name] = value;
|
||||
}
|
||||
else if( paramIter->first != "<xmlattr>" &&
|
||||
paramIter->first != "<xmlcomment>" )
|
||||
{
|
||||
throw config_error(std::string("Unknown child node in ") +
|
||||
"'Parameters'. Expected 'Parameter' but got '" +
|
||||
paramIter->first + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (v.first != "<xmlcomment>" &&
|
||||
v.first != "<xmlattr>")
|
||||
{
|
||||
|
@ -2185,20 +2212,12 @@ std::string map_parser::ensure_relative_to_xml( boost::optional<std::string> opt
|
|||
|
||||
void map_parser::ensure_attrs(ptree const& sym, std::string name, std::string attrs)
|
||||
{
|
||||
|
||||
typedef ptree::key_type::value_type Ch;
|
||||
//typedef boost::property_tree::xml_parser::xmlattr<Ch> x_att;
|
||||
|
||||
std::set<std::string> attr_set;
|
||||
boost::split(attr_set, attrs, boost::is_any_of(","));
|
||||
for (ptree::const_iterator itr = sym.begin(); itr != sym.end(); ++itr)
|
||||
{
|
||||
//ptree::value_type const& v = *itr;
|
||||
if (itr->first == boost::property_tree::xml_parser::xmlattr<Ch>())
|
||||
{
|
||||
optional<const ptree &> attribs = sym.get_child_optional( boost::property_tree::xml_parser::xmlattr<Ch>() );
|
||||
if (attribs)
|
||||
{
|
||||
std::set<std::string> attr_set;
|
||||
boost::split(attr_set, attrs, boost::is_any_of(","));
|
||||
std::ostringstream s("");
|
||||
s << "### " << name << " properties warning: ";
|
||||
int missing = 0;
|
||||
|
@ -2208,20 +2227,27 @@ void map_parser::ensure_attrs(ptree const& sym, std::string name, std::string at
|
|||
bool found = (attr_set.find(name) != attr_set.end());
|
||||
if (!found)
|
||||
{
|
||||
if (missing) s << ",";
|
||||
if (missing)
|
||||
{
|
||||
s << ",";
|
||||
}
|
||||
s << "'" << name << "'";
|
||||
++missing;
|
||||
}
|
||||
}
|
||||
if (missing) {
|
||||
if (missing > 1) s << " are";
|
||||
else s << " is";
|
||||
if (missing > 1)
|
||||
{
|
||||
s << " are";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << " is";
|
||||
}
|
||||
s << " invalid, acceptable values are:\n'" << attrs << "'\n";
|
||||
std::clog << s.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
||||
|
|
28
src/map.cpp
28
src/map.cpp
|
@ -92,7 +92,8 @@ 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_attr_(rhs.extra_attr_),
|
||||
extra_params_(rhs.extra_params_) {}
|
||||
|
||||
Map& Map::operator=(const Map& rhs)
|
||||
{
|
||||
|
@ -110,6 +111,7 @@ Map& Map::operator=(const Map& rhs)
|
|||
maximum_extent_=rhs.maximum_extent_;
|
||||
base_path_=rhs.base_path_;
|
||||
extra_attr_=rhs.extra_attr_;
|
||||
extra_params_=rhs.extra_params_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -677,9 +679,29 @@ parameters const& Map::get_extra_attributes() const
|
|||
return extra_attr_;
|
||||
}
|
||||
|
||||
void Map::set_extra_attributes(parameters& params)
|
||||
parameters& Map::get_extra_attributes()
|
||||
{
|
||||
extra_attr_ = params;
|
||||
return extra_attr_;
|
||||
}
|
||||
|
||||
void Map::set_extra_attributes(parameters& attr)
|
||||
{
|
||||
extra_attr_ = attr;
|
||||
}
|
||||
|
||||
parameters const& Map::get_extra_parameters() const
|
||||
{
|
||||
return extra_params_;
|
||||
}
|
||||
|
||||
parameters& Map::get_extra_parameters()
|
||||
{
|
||||
return extra_params_;
|
||||
}
|
||||
|
||||
void Map::set_extra_parameters(parameters& params)
|
||||
{
|
||||
extra_params_ = params;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -120,11 +120,9 @@ void raster_colorizer::colorize(raster_ptr const& raster,const std::map<std::str
|
|||
|
||||
const std::map<std::string,value>::const_iterator fi = Props.find("NODATA");
|
||||
if (fi != Props.end())
|
||||
//if (Props.count("NODATA")>0)
|
||||
{
|
||||
hasNoData = true;
|
||||
//noDataValue = Props.at("NODATA").to_double();
|
||||
noDataValue = fi->second.to_double();
|
||||
noDataValue = static_cast<float>(fi->second.to_double());
|
||||
}
|
||||
|
||||
for (int i=0; i<len; ++i)
|
||||
|
@ -138,9 +136,9 @@ void raster_colorizer::colorize(raster_ptr const& raster,const std::map<std::str
|
|||
}
|
||||
}
|
||||
|
||||
inline float interpolate(float start,float end, float fraction)
|
||||
inline unsigned interpolate(unsigned start, unsigned end, float fraction)
|
||||
{
|
||||
return fraction * (end - start) + start;
|
||||
return static_cast<unsigned>(fraction * (end - start) + start);
|
||||
}
|
||||
|
||||
color raster_colorizer::get_color(float value) const {
|
||||
|
@ -213,10 +211,10 @@ color raster_colorizer::get_color(float value) const {
|
|||
else {
|
||||
float fraction = (value - stopValue) / (nextStopValue - stopValue);
|
||||
|
||||
float r = interpolate(stopColor.red(), nextStopColor.red(),fraction);
|
||||
float g = interpolate(stopColor.green(), nextStopColor.green(),fraction);
|
||||
float b = interpolate(stopColor.blue(), nextStopColor.blue(),fraction);
|
||||
float a = interpolate(stopColor.alpha(), nextStopColor.alpha(),fraction);
|
||||
unsigned r = interpolate(stopColor.red(), nextStopColor.red(),fraction);
|
||||
unsigned g = interpolate(stopColor.green(), nextStopColor.green(),fraction);
|
||||
unsigned b = interpolate(stopColor.blue(), nextStopColor.blue(),fraction);
|
||||
unsigned a = interpolate(stopColor.alpha(), nextStopColor.alpha(),fraction);
|
||||
|
||||
outputColor.set_red(r);
|
||||
outputColor.set_green(g);
|
||||
|
|
|
@ -761,6 +761,24 @@ void serialize_datasource( ptree & layer_node, datasource_ptr datasource)
|
|||
}
|
||||
}
|
||||
|
||||
void serialize_parameters( ptree & map_node, mapnik::parameters const& params)
|
||||
{
|
||||
ptree & params_node = map_node.push_back(
|
||||
ptree::value_type("Parameters", ptree()))->second;
|
||||
|
||||
parameters::const_iterator it = params.begin();
|
||||
parameters::const_iterator end = params.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
boost::property_tree::ptree & param_node = params_node.push_back(
|
||||
boost::property_tree::ptree::value_type("Parameter",
|
||||
boost::property_tree::ptree()))->second;
|
||||
param_node.put("<xmlattr>.name", it->first );
|
||||
param_node.put_value( it->second );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void serialize_layer( ptree & map_node, const layer & layer, bool explicit_defaults )
|
||||
{
|
||||
ptree & layer_node = map_node.push_back(
|
||||
|
@ -901,6 +919,8 @@ void serialize_map(ptree & pt, Map const & map, bool explicit_defaults)
|
|||
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();
|
||||
Map::const_style_iterator end = map.styles().end();
|
||||
for (; it != end; ++it)
|
||||
|
|
20
tests/data/good_maps/extra_arbitary_map_parameters.xml
Normal file
20
tests/data/good_maps/extra_arbitary_map_parameters.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Map>
|
||||
|
||||
<!--
|
||||
totally arbirary Parameters can also be attached to the map
|
||||
which will be respected during serialization.
|
||||
|
||||
This makes it easier for calling applications that work with mapnik
|
||||
xml, and leverage its serialization, to pass through directives that
|
||||
the calling application needs which describe how to handle the map.
|
||||
-->
|
||||
|
||||
<Parameters>
|
||||
<Parameter name="key"><![CDATA[value]]></Parameter>
|
||||
<!-- this one will override previous key with same name -->
|
||||
<Parameter name="key"><![CDATA[value2]]></Parameter>
|
||||
<Parameter name="key3"><![CDATA[value3]]></Parameter>
|
||||
<Parameter name="unicode"><![CDATA[iván]]></Parameter>
|
||||
</Parameters>
|
||||
|
||||
</Map>
|
11
tests/data/good_maps/extra_known_map_attributes.xml
Normal file
11
tests/data/good_maps/extra_known_map_attributes.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<Map font-directory="." 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.
|
||||
|
||||
They are treated as 'extra' because they have no role during map rendering
|
||||
-->
|
||||
|
||||
</Map>
|
40
tests/python_tests/extra_map_props_test.py
Normal file
40
tests/python_tests/extra_map_props_test.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
from Queue import Queue
|
||||
import threading
|
||||
|
||||
import os, mapnik
|
||||
import sqlite3
|
||||
|
||||
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_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.params),3)
|
||||
eq_(m.params['key'],'value2')
|
||||
eq_(m.params['key3'],'value3')
|
||||
eq_(m.params['unicode'],u'iván')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import mapnik, pickle
|
||||
import mapnik
|
||||
|
||||
# Tests that exercise fonts.
|
||||
|
||||
|
|
45
tests/python_tests/geometry_wkb_test.py
Normal file
45
tests/python_tests/geometry_wkb_test.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
#encoding: utf8
|
||||
|
||||
from nose.tools import *
|
||||
import os
|
||||
from utilities import execution_path
|
||||
import mapnik
|
||||
|
||||
wkts = [
|
||||
[1,"POINT (30 10)"],
|
||||
[1,"LINESTRING (30 10, 10 30, 40 40)"],
|
||||
[1,"POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))"],
|
||||
[1,"POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))"],
|
||||
[4,"MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"],
|
||||
[2,"MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))"],
|
||||
[2,"MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"],
|
||||
[2,"MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))"]
|
||||
]
|
||||
|
||||
|
||||
def compare_wkb_from_wkt(wkt,num):
|
||||
f = mapnik.Feature(1)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
eq_(len(f.geometries()),num)
|
||||
|
||||
paths = mapnik.Path.from_wkt(wkt)
|
||||
eq_(len(paths),num)
|
||||
|
||||
eq_(f.geometries()[0].to_wkb(),paths[0].to_wkb())
|
||||
|
||||
paths2 = mapnik.Path()
|
||||
for path in paths:
|
||||
paths2.add_wkb(path.to_wkb())
|
||||
|
||||
eq_(len(paths2),num)
|
||||
eq_(f.geometries()[0].to_wkb(),paths2[0].to_wkb())
|
||||
|
||||
def test_point():
|
||||
for wkt in wkts:
|
||||
try:
|
||||
compare_wkb_from_wkt(wkt[1],wkt[0])
|
||||
except RuntimeError, e:
|
||||
raise RuntimeError('%s %s' % (e, wkt))
|
||||
|
||||
if __name__ == "__main__":
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
|
@ -5,8 +5,9 @@ import os
|
|||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
from utilities import Todo
|
||||
import tempfile
|
||||
|
||||
import mapnik, pickle
|
||||
import mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -122,17 +123,6 @@ def test_pointsymbolizer_init():
|
|||
#def test_pointsymbolizer_missing_image():
|
||||
# p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/broken.png"))
|
||||
|
||||
# PointSymbolizer pickling
|
||||
def test_pointsymbolizer_pickle():
|
||||
raise Todo("point_symbolizer pickling currently disabled")
|
||||
p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/dummy.png"))
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# image type, width, and height only used in contructor...
|
||||
eq_(p.filename, p2.filename)
|
||||
eq_(p.allow_overlap, p2.allow_overlap)
|
||||
eq_(p.opacity, p2.opacity)
|
||||
eq_(p.ignore_placement, p2.ignore_placement)
|
||||
eq_(p.placement, p2.placement)
|
||||
|
||||
# PolygonSymbolizer initialization
|
||||
def test_polygonsymbolizer_init():
|
||||
|
@ -146,17 +136,6 @@ def test_polygonsymbolizer_init():
|
|||
eq_(p.fill, mapnik.Color('blue'))
|
||||
eq_(p.fill_opacity, 1)
|
||||
|
||||
# PolygonSymbolizer pickling
|
||||
def test_polygonsymbolizer_pickle():
|
||||
p = mapnik.PolygonSymbolizer(mapnik.Color('black'))
|
||||
p.fill_opacity = .5
|
||||
# does not work for some reason...
|
||||
#eq_(pickle.loads(pickle.dumps(p)), p)
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(p.fill, p2.fill)
|
||||
eq_(p.fill_opacity, p2.fill_opacity)
|
||||
|
||||
|
||||
# Stroke initialization
|
||||
def test_stroke_init():
|
||||
s = mapnik.Stroke()
|
||||
|
@ -187,25 +166,6 @@ def test_stroke_dash_arrays():
|
|||
|
||||
eq_(s.get_dashes(), [(1,2),(3,4),(5,6)])
|
||||
|
||||
# Stroke pickling
|
||||
def test_stroke_pickle():
|
||||
s = mapnik.Stroke(mapnik.Color('black'),4.5)
|
||||
|
||||
eq_(s.width, 4.5)
|
||||
eq_(s.color, mapnik.Color('black'))
|
||||
|
||||
s.add_dash(1,2)
|
||||
s.add_dash(3,4)
|
||||
s.add_dash(5,6)
|
||||
|
||||
s2 = pickle.loads(pickle.dumps(s,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(s.color, s2.color)
|
||||
eq_(s.width, s2.width)
|
||||
eq_(s.opacity, s2.opacity)
|
||||
eq_(s.get_dashes(), s2.get_dashes())
|
||||
eq_(s.line_cap, s2.line_cap)
|
||||
eq_(s.line_join, s2.line_join)
|
||||
|
||||
|
||||
# LineSymbolizer initialization
|
||||
def test_linesymbolizer_init():
|
||||
|
@ -234,19 +194,6 @@ def test_linesymbolizer_init():
|
|||
eq_(l.stroke.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik.line_join.MITER_JOIN)
|
||||
|
||||
# LineSymbolizer pickling
|
||||
def test_linesymbolizer_pickle():
|
||||
p = mapnik.LineSymbolizer()
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# line and stroke eq fails, so we compare attributes for now..
|
||||
s,s2 = p.stroke, p2.stroke
|
||||
eq_(s.color, s2.color)
|
||||
eq_(s.opacity, s2.opacity)
|
||||
eq_(s.width, s2.width)
|
||||
eq_(s.get_dashes(), s2.get_dashes())
|
||||
eq_(s.line_cap, s2.line_cap)
|
||||
eq_(s.line_join, s2.line_join)
|
||||
|
||||
|
||||
# TextSymbolizer initialization
|
||||
def test_textsymbolizer_init():
|
||||
|
@ -258,56 +205,6 @@ def test_textsymbolizer_init():
|
|||
eq_(ts.fill, mapnik.Color('black'))
|
||||
eq_(ts.label_placement, mapnik.label_placement.POINT_PLACEMENT)
|
||||
|
||||
# TextSymbolizer pickling
|
||||
def test_textsymbolizer_pickle():
|
||||
ts = mapnik.TextSymbolizer(mapnik.Expression('[Field_Name]'), 'Font Name', 8, mapnik.Color('black'))
|
||||
|
||||
eq_(str(ts.name), str(mapnik.Expression('[Field_Name]')))
|
||||
eq_(ts.face_name, 'Font Name')
|
||||
eq_(ts.text_size, 8)
|
||||
eq_(ts.fill, mapnik.Color('black'))
|
||||
|
||||
raise Todo("text_symbolizer pickling currently disabled")
|
||||
|
||||
ts2 = pickle.loads(pickle.dumps(ts,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(ts.name, ts2.name)
|
||||
eq_(ts.face_name, ts2.face_name)
|
||||
eq_(ts.allow_overlap, ts2.allow_overlap)
|
||||
eq_(ts.displacement, ts2.displacement)
|
||||
eq_(ts.anchor, ts2.anchor)
|
||||
eq_(ts.fill, ts2.fill)
|
||||
eq_(ts.force_odd_labels, ts2.force_odd_labels)
|
||||
eq_(ts.halo_fill, ts2.halo_fill)
|
||||
eq_(ts.halo_radius, ts2.halo_radius)
|
||||
eq_(ts.label_placement, ts2.label_placement)
|
||||
eq_(ts.minimum_distance, ts2.minimum_distance)
|
||||
eq_(ts.text_ratio, ts2.text_ratio)
|
||||
eq_(ts.text_size, ts2.text_size)
|
||||
eq_(ts.wrap_width, ts2.wrap_width)
|
||||
eq_(ts.vertical_alignment, ts2.vertical_alignment)
|
||||
eq_(ts.label_spacing, ts2.label_spacing)
|
||||
eq_(ts.label_position_tolerance, ts2.label_position_tolerance)
|
||||
# 22.5 * M_PI/180.0 initialized by default
|
||||
assert_almost_equal(s.max_char_angle_delta, 0.39269908169872414)
|
||||
|
||||
eq_(ts.wrap_character, ts2.wrap_character)
|
||||
eq_(ts.text_transform, ts2.text_transform)
|
||||
eq_(ts.line_spacing, ts2.line_spacing)
|
||||
eq_(ts.character_spacing, ts2.character_spacing)
|
||||
|
||||
# r1341
|
||||
eq_(ts.wrap_before, ts2.wrap_before)
|
||||
eq_(ts.horizontal_alignment, ts2.horizontal_alignment)
|
||||
eq_(ts.justify_alignment, ts2.justify_alignment)
|
||||
eq_(ts.opacity, ts2.opacity)
|
||||
|
||||
# r2300
|
||||
eq_(s.minimum_padding, 0.0)
|
||||
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik.org/ticket/348")
|
||||
eq_(ts.fontset, ts2.fontset)
|
||||
|
||||
|
||||
# Map initialization
|
||||
def test_layer_init():
|
||||
l = mapnik.Layer('test')
|
||||
|
@ -365,11 +262,13 @@ def test_map_init_from_string():
|
|||
eq_(m.base, './')
|
||||
mapnik.load_map_from_string(m, map_string, False, "") # this "" will have no effect
|
||||
eq_(m.base, './')
|
||||
|
||||
tmp_dir = tempfile.gettempdir()
|
||||
try:
|
||||
mapnik.load_map_from_string(m, map_string, False, "/tmp")
|
||||
mapnik.load_map_from_string(m, map_string, False, tmp_dir)
|
||||
except RuntimeError:
|
||||
pass # runtime error expected because shapefile path should be wrong and datasource will throw
|
||||
eq_(m.base, '/tmp') # /tmp will be set despite the exception because load_map mostly worked
|
||||
eq_(m.base, tmp_dir) # tmp_dir will be set despite the exception because load_map mostly worked
|
||||
m.base = 'foo'
|
||||
mapnik.load_map_from_string(m, map_string, True, ".")
|
||||
eq_(m.base, '.')
|
||||
|
@ -379,19 +278,6 @@ def test_map_init_from_string():
|
|||
if not 'Could not create datasource' in str(e):
|
||||
raise RuntimeError(e)
|
||||
|
||||
# Map pickling
|
||||
def test_map_pickle():
|
||||
# Fails due to scale() not matching, possibly other things
|
||||
raise(Todo("Map does not support pickling yet (Tickets #345)."))
|
||||
|
||||
m = mapnik.Map(256, 256)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
m = mapnik.Map(256, 256, '+proj=latlong')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
# Color initialization
|
||||
|
||||
@raises(Exception) # Boost.Python.ArgumentError
|
||||
|
@ -505,20 +391,6 @@ def test_color_equality():
|
|||
eq_(c3, mapnik.Color(0,0,255,128))
|
||||
|
||||
|
||||
# Color pickling
|
||||
def test_color_pickle():
|
||||
c = mapnik.Color('blue')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik.Color(0, 64, 128)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik.Color(0, 64, 128, 192)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
# Rule initialization
|
||||
def test_rule_init():
|
||||
min_scale = 5
|
||||
|
@ -678,12 +550,6 @@ def test_envelope_static_init():
|
|||
eq_(c.x, 150)
|
||||
eq_(c.y, 150)
|
||||
|
||||
# Box2d pickling
|
||||
def test_envelope_pickle():
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(e)), e)
|
||||
|
||||
# Box2d multiplication
|
||||
def test_envelope_multiplication():
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
|
@ -716,7 +582,7 @@ def test_envelope_multiplication():
|
|||
eq_(c.y, 150)
|
||||
|
||||
# Box2d clipping
|
||||
def test_envelope_pickle():
|
||||
def test_envelope_clipping():
|
||||
e1 = mapnik.Box2d(-180,-90,180,90)
|
||||
e2 = mapnik.Box2d(-120,40,-110,48)
|
||||
e1.clip(e2)
|
||||
|
|
53
tests/python_tests/parameters_test.py
Normal file
53
tests/python_tests/parameters_test.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
|
||||
import mapnik
|
||||
import pickle
|
||||
|
||||
def setup():
|
||||
os.chdir(execution_path('.'))
|
||||
|
||||
def test_parameter():
|
||||
p = mapnik.Parameter('key','value')
|
||||
eq_(p[0],'key')
|
||||
eq_(p[1],'value')
|
||||
|
||||
p = mapnik.Parameter('int',1)
|
||||
eq_(p[0],'int')
|
||||
eq_(p[1],1)
|
||||
|
||||
p = mapnik.Parameter('float',1.0777)
|
||||
eq_(p[0],'float')
|
||||
eq_(p[1],1.0777)
|
||||
|
||||
|
||||
def test_parameters():
|
||||
params = mapnik.Parameters()
|
||||
p = mapnik.Parameter('float',1.0777)
|
||||
eq_(p[0],'float')
|
||||
eq_(p[1],1.0777)
|
||||
|
||||
params.append(p)
|
||||
|
||||
eq_(params[0][0],'float')
|
||||
eq_(params[0][1],1.0777)
|
||||
|
||||
eq_(params.get('float'),1.0777)
|
||||
|
||||
def test_parameters_pickling():
|
||||
params = mapnik.Parameters()
|
||||
params.append(mapnik.Parameter('oh',str('yeah')))
|
||||
|
||||
params2 = pickle.loads(pickle.dumps(params,pickle.HIGHEST_PROTOCOL))
|
||||
|
||||
eq_(params[0][0],params2[0][0])
|
||||
eq_(params[0][1],params2[0][1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
159
tests/python_tests/pickling_test.py
Normal file
159
tests/python_tests/pickling_test.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
from utilities import Todo
|
||||
import tempfile
|
||||
|
||||
import mapnik, pickle
|
||||
|
||||
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('.'))
|
||||
|
||||
# PointSymbolizer pickling
|
||||
def test_pointsymbolizer_pickle():
|
||||
raise Todo("point_symbolizer pickling currently disabled")
|
||||
p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/dummy.png"))
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# image type, width, and height only used in contructor...
|
||||
eq_(p.filename, p2.filename)
|
||||
eq_(p.allow_overlap, p2.allow_overlap)
|
||||
eq_(p.opacity, p2.opacity)
|
||||
eq_(p.ignore_placement, p2.ignore_placement)
|
||||
eq_(p.placement, p2.placement)
|
||||
|
||||
|
||||
# PolygonSymbolizer pickling
|
||||
def test_polygonsymbolizer_pickle():
|
||||
p = mapnik.PolygonSymbolizer(mapnik.Color('black'))
|
||||
p.fill_opacity = .5
|
||||
# does not work for some reason...
|
||||
#eq_(pickle.loads(pickle.dumps(p)), p)
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(p.fill, p2.fill)
|
||||
eq_(p.fill_opacity, p2.fill_opacity)
|
||||
|
||||
|
||||
# Stroke pickling
|
||||
def test_stroke_pickle():
|
||||
s = mapnik.Stroke(mapnik.Color('black'),4.5)
|
||||
|
||||
eq_(s.width, 4.5)
|
||||
eq_(s.color, mapnik.Color('black'))
|
||||
|
||||
s.add_dash(1,2)
|
||||
s.add_dash(3,4)
|
||||
s.add_dash(5,6)
|
||||
|
||||
s2 = pickle.loads(pickle.dumps(s,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(s.color, s2.color)
|
||||
eq_(s.width, s2.width)
|
||||
eq_(s.opacity, s2.opacity)
|
||||
eq_(s.get_dashes(), s2.get_dashes())
|
||||
eq_(s.line_cap, s2.line_cap)
|
||||
eq_(s.line_join, s2.line_join)
|
||||
|
||||
# LineSymbolizer pickling
|
||||
def test_linesymbolizer_pickle():
|
||||
p = mapnik.LineSymbolizer()
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# line and stroke eq fails, so we compare attributes for now..
|
||||
s,s2 = p.stroke, p2.stroke
|
||||
eq_(s.color, s2.color)
|
||||
eq_(s.opacity, s2.opacity)
|
||||
eq_(s.width, s2.width)
|
||||
eq_(s.get_dashes(), s2.get_dashes())
|
||||
eq_(s.line_cap, s2.line_cap)
|
||||
eq_(s.line_join, s2.line_join)
|
||||
|
||||
|
||||
|
||||
# TextSymbolizer pickling
|
||||
def test_textsymbolizer_pickle():
|
||||
ts = mapnik.TextSymbolizer(mapnik.Expression('[Field_Name]'), 'Font Name', 8, mapnik.Color('black'))
|
||||
|
||||
eq_(str(ts.name), str(mapnik.Expression('[Field_Name]')))
|
||||
eq_(ts.face_name, 'Font Name')
|
||||
eq_(ts.text_size, 8)
|
||||
eq_(ts.fill, mapnik.Color('black'))
|
||||
|
||||
raise Todo("text_symbolizer pickling currently disabled")
|
||||
|
||||
ts2 = pickle.loads(pickle.dumps(ts,pickle.HIGHEST_PROTOCOL))
|
||||
eq_(ts.name, ts2.name)
|
||||
eq_(ts.face_name, ts2.face_name)
|
||||
eq_(ts.allow_overlap, ts2.allow_overlap)
|
||||
eq_(ts.displacement, ts2.displacement)
|
||||
eq_(ts.anchor, ts2.anchor)
|
||||
eq_(ts.fill, ts2.fill)
|
||||
eq_(ts.force_odd_labels, ts2.force_odd_labels)
|
||||
eq_(ts.halo_fill, ts2.halo_fill)
|
||||
eq_(ts.halo_radius, ts2.halo_radius)
|
||||
eq_(ts.label_placement, ts2.label_placement)
|
||||
eq_(ts.minimum_distance, ts2.minimum_distance)
|
||||
eq_(ts.text_ratio, ts2.text_ratio)
|
||||
eq_(ts.text_size, ts2.text_size)
|
||||
eq_(ts.wrap_width, ts2.wrap_width)
|
||||
eq_(ts.vertical_alignment, ts2.vertical_alignment)
|
||||
eq_(ts.label_spacing, ts2.label_spacing)
|
||||
eq_(ts.label_position_tolerance, ts2.label_position_tolerance)
|
||||
# 22.5 * M_PI/180.0 initialized by default
|
||||
assert_almost_equal(s.max_char_angle_delta, 0.39269908169872414)
|
||||
|
||||
eq_(ts.wrap_character, ts2.wrap_character)
|
||||
eq_(ts.text_transform, ts2.text_transform)
|
||||
eq_(ts.line_spacing, ts2.line_spacing)
|
||||
eq_(ts.character_spacing, ts2.character_spacing)
|
||||
|
||||
# r1341
|
||||
eq_(ts.wrap_before, ts2.wrap_before)
|
||||
eq_(ts.horizontal_alignment, ts2.horizontal_alignment)
|
||||
eq_(ts.justify_alignment, ts2.justify_alignment)
|
||||
eq_(ts.opacity, ts2.opacity)
|
||||
|
||||
# r2300
|
||||
eq_(s.minimum_padding, 0.0)
|
||||
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik.org/ticket/348")
|
||||
eq_(ts.fontset, ts2.fontset)
|
||||
|
||||
|
||||
def test_map_pickle():
|
||||
# Fails due to scale() not matching, possibly other things
|
||||
raise(Todo("Map does not support pickling yet (Tickets #345)."))
|
||||
|
||||
m = mapnik.Map(256, 256)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
m = mapnik.Map(256, 256, '+proj=latlong')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
def test_color_pickle():
|
||||
c = mapnik.Color('blue')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik.Color(0, 64, 128)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik.Color(0, 64, 128, 192)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
|
||||
def test_envelope_pickle():
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(e)), e)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
|
@ -35,7 +35,7 @@ def psql_can_connect():
|
|||
call('psql %s -c "select postgis_version()"' % POSTGIS_TEMPLATE_DBNAME)
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests as basic auth is not correctly set up. Error was: %s' % e.message
|
||||
print 'Notice: skipping postgis tests (connection)'
|
||||
return False
|
||||
|
||||
def shp2pgsql_on_path():
|
||||
|
@ -47,7 +47,7 @@ def shp2pgsql_on_path():
|
|||
call('shp2pgsql')
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests because shp2pgsql not found. Error was: %s' % e.message
|
||||
print 'Notice: skipping postgis tests (shp2pgsql)'
|
||||
return False
|
||||
|
||||
def createdb_and_dropdb_on_path():
|
||||
|
@ -60,7 +60,7 @@ def createdb_and_dropdb_on_path():
|
|||
call('dropdb --help')
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests because createdb or dropdb not found. Error was: %s' % e.message
|
||||
print 'Notice: skipping postgis tests (createdb/dropdb)'
|
||||
return False
|
||||
|
||||
def postgis_setup():
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import mapnik, pickle
|
||||
import mapnik
|
||||
|
||||
# Tests that exercise map projections.
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from nose.tools import *
|
||||
|
||||
import tempfile
|
||||
import os, mapnik
|
||||
from nose.tools import *
|
||||
|
||||
from utilities import execution_path
|
||||
from utilities import Todo
|
||||
|
||||
|
@ -216,7 +215,7 @@ def test_render_points():
|
|||
p = mapnik.Projection(projs[projdescr])
|
||||
m.zoom_to_box(p.forward(mapnik.Box2d(ul_lonlat,lr_lonlat)))
|
||||
# Render to SVG so that it can be checked how many points are there with string comparison
|
||||
svg_file = '/tmp/%s.svg'
|
||||
svg_file = os.path.join(tempfile.gettempdir(),'%s.svg')
|
||||
mapnik.render_to_file(m, svg_file)
|
||||
num_points_present = len(places_ds.all_features())
|
||||
svg = open(svg_file,'r').read()
|
||||
|
|
|
@ -42,9 +42,14 @@ if 'sqlite' in mapnik.DatasourceCache.instance().plugin_names():
|
|||
eq_(os.path.exists(index),True)
|
||||
conn = sqlite3.connect(index)
|
||||
cur = conn.cursor()
|
||||
try:
|
||||
cur.execute("Select count(*) from idx_%s_GEOMETRY" % TABLE.replace("'",""))
|
||||
conn.commit()
|
||||
eq_(cur.fetchone()[0],TOTAL)
|
||||
except sqlite3.OperationalError:
|
||||
# don't worry about testing # of index records if
|
||||
# python's sqlite module does not support rtree
|
||||
pass
|
||||
cur.close()
|
||||
|
||||
ds = mapnik.SQLite(file=DB,table=TABLE)
|
||||
|
|
19
utils/geometry_to_wkb/Jamroot
Normal file
19
utils/geometry_to_wkb/Jamroot
Normal file
|
@ -0,0 +1,19 @@
|
|||
######################################################################
|
||||
|
||||
MAPNIK_INCLUDE_DIR = "/opt/mapnik/include" ;
|
||||
MAPNIK_LIB_DIR = "/opt/mapnik/lib" ;
|
||||
BOOST_INCLUDE_DIR = "/opt/boost_1_48_0/include" ;
|
||||
|
||||
|
||||
lib mapnik : : <name>mapnik <search>$(MAPNIK_LIB_DIR) ;
|
||||
lib icu : : <name>icuuc <search>/usr/local/lib ;
|
||||
|
||||
exe to_wkb :
|
||||
main.cpp
|
||||
.//mapnik
|
||||
.//icu
|
||||
:
|
||||
<include>$(MAPNIK_INCLUDE_DIR)
|
||||
<include>$(BOOST_INCLUDE_DIR)
|
||||
;
|
||||
|
109
utils/geometry_to_wkb/main.cpp
Normal file
109
utils/geometry_to_wkb/main.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/util/geometry_to_wkb.hpp>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
int main (int argc, char ** argv )
|
||||
{
|
||||
|
||||
if ( argc !=2)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <path-to-shapefile>\n";
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
std::cerr << "Geometry to WKB converter\n";
|
||||
|
||||
mapnik::datasource_cache::instance()->register_datasources("/opt/mapnik/lib/mapnik/input/");
|
||||
|
||||
std::string filename(argv[1]);
|
||||
std::cerr << filename << std::endl;
|
||||
|
||||
mapnik::parameters p;
|
||||
p["type"] = "shape";
|
||||
p["file"] = filename;
|
||||
|
||||
mapnik::datasource_ptr ds;
|
||||
|
||||
try
|
||||
{
|
||||
ds = mapnik::datasource_cache::instance()->create(p);
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << "Can't create datasource!\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (ds)
|
||||
{
|
||||
std::cerr << ds->envelope() << std::endl;
|
||||
|
||||
mapnik::query q(ds->envelope());
|
||||
mapnik::layer_descriptor layer_desc = ds->get_descriptor();
|
||||
BOOST_FOREACH ( mapnik::attribute_descriptor const& attr_desc, layer_desc.get_descriptors())
|
||||
{
|
||||
q.add_property_name(attr_desc.get_name());
|
||||
}
|
||||
|
||||
mapnik::featureset_ptr fs = ds->features(q);
|
||||
mapnik::feature_ptr f = fs->next();
|
||||
|
||||
while(f)
|
||||
{
|
||||
std::cerr << *f << std::endl;
|
||||
boost::ptr_vector<mapnik::geometry_type> & paths = f->paths();
|
||||
BOOST_FOREACH ( mapnik::geometry_type const& geom, paths)
|
||||
{
|
||||
// NDR
|
||||
{
|
||||
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::util::wkbNDR);
|
||||
std::cerr << mapnik::util::to_hex(wkb->buffer(),wkb->size()) << std::endl;
|
||||
}
|
||||
// XDR
|
||||
{
|
||||
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::util::wkbXDR);
|
||||
std::cerr << mapnik::util::to_hex(wkb->buffer(),wkb->size()) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
f = fs->next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue