Compare commits
40 commits
Author | SHA1 | Date | |
---|---|---|---|
|
89238f9559 | ||
|
7902591ac0 | ||
|
7f506ff5cf | ||
|
e0616bd5ab | ||
|
0639d54db4 | ||
|
1b9ba41f96 | ||
|
d8fd967c99 | ||
|
1ffa0f2b94 | ||
|
6a3b0634fe | ||
|
29b717f9f6 | ||
|
8c4a5d53d3 | ||
|
9c947232e9 | ||
|
5dd79e88c0 | ||
|
08f651289d | ||
|
3fc6e1282f | ||
|
9e03ace209 | ||
|
ec089dcaea | ||
|
f0821d897f | ||
|
f68291c5b4 | ||
|
d269ce3bb3 | ||
|
8e8794790a | ||
|
189d86ddd7 | ||
|
e3a456f846 | ||
|
c32b9b6788 | ||
|
44ef0324f0 | ||
|
d4662005fe | ||
|
5be238b2cd | ||
|
2b2aead8b3 | ||
|
5edc39555d | ||
|
449e83fbf2 | ||
|
482c4eb215 | ||
|
a295eea843 | ||
|
f9a09be2b1 | ||
|
09c919b3bd | ||
|
fe06c959c6 | ||
|
b821c67cc5 | ||
|
4b988a2c20 | ||
|
cde04dba4a | ||
|
dc7b943873 | ||
|
ec2f03a6e0 |
46 changed files with 643 additions and 179 deletions
53
.travis.yml
53
.travis.yml
|
@ -1,21 +1,44 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
compiler: clang
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- XMLPARSER="libxml2" DEBUG=False
|
||||||
|
- XMLPARSER="libxml2" DEBUG=True
|
||||||
|
- XMLPARSER="ptree" DEBUG=True
|
||||||
|
|
||||||
|
# travis + ubuntugis with gdal and postggis leads to many potential dead-end conflicts
|
||||||
|
# the below is thanks to https://github.com/CartoDB/Windshaft/blob/d82fe08b32fc7907bbe907ab290f8a082215ae26/.travis.yml#L1
|
||||||
before_install:
|
before_install:
|
||||||
- echo 'yes' | sudo add-apt-repository ppa:mapnik/boost
|
- export PGUSER=postgres
|
||||||
- sudo apt-get update -qq
|
- sudo mv /etc/apt/sources.list.d/pgdg-source.list* /tmp
|
||||||
- sudo apt-get install -qq libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-system-dev libboost-thread-dev python-nose libicu-dev libpng-dev libjpeg-dev libtiff-dev libz-dev libfreetype6-dev libxml2-dev libproj-dev
|
- sudo apt-get -qq purge postgis* postgresql*
|
||||||
|
- sudo apt-add-repository -y ppa:cartodb/postgresql-9.3
|
||||||
|
- sudo apt-add-repository -y ppa:cartodb/gis
|
||||||
|
- sudo rm -Rf /var/lib/postgresql /etc/postgresql
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get install -q libharfbuzz-dev postgresql-9.3-postgis-2.1 postgresql-contrib-9.3 gdal-bin libgdal-dev
|
||||||
|
- echo -e "local\tall\tall\ttrust\nhost\tall\tall\t127.0.0.1/32\ttrust\nhost\tall\tall\t::1/128\ttrust" |sudo tee /etc/postgresql/9.3/main/pg_hba.conf
|
||||||
|
- sudo service postgresql restart
|
||||||
|
|
||||||
|
install:
|
||||||
|
- sudo apt-get install -y libboost-python1.48-dev libboost-thread1.48-dev libboost-filesystem1.48-dev libboost-regex1.48-dev libboost-program-options1.48-dev
|
||||||
|
- sudo apt-get install -y make valgrind python-nose libicu-dev libproj-dev libcairo-dev python-cairo-dev libcairo-dev python-cairo-dev libpng-dev libjpeg-dev libtiff-dev libwebp-dev libz-dev libfreetype6-dev libxml2-dev libsqlite3-dev
|
||||||
|
# multi-face ttc font: https://github.com/mapnik/mapnik/issues/2274
|
||||||
|
- sudo apt-get install ttf-wqy-microhei
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- psql -U postgres -c 'create database template_postgis'
|
||||||
|
- psql -U postgres -c 'create extension postgis' -d template_postgis
|
||||||
|
- if [[ "${CXX}" == 'g++' ]]; then export JOBS=2; fi;
|
||||||
|
- if [[ "${CXX}" == 'clang++' ]]; then export JOBS=4; fi;
|
||||||
|
- if [[ "${DEBUG}" == True ]]; then export JOBS=$((JOBS/2)); fi;
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./configure DEMO=False BINDINGS='python' CPP_TESTS=False CAIRO=False INPUT_PLUGINS='' OPTIMIZATION=1 FAST=True && JOBS=2 make
|
- ./configure CXX=${CXX} CC=${CC} XML_PARSER=$XML_PARSER DEBUG=${DEBUG} DEMO=True BENCHMARK=False BINDINGS='python' CPP_TESTS=True CAIRO=True FAST=True
|
||||||
|
- make
|
||||||
branches:
|
- make test-local
|
||||||
only:
|
- source localize.sh && make grind
|
||||||
- master
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- "irc.freenode.org#mapnik"
|
|
||||||
use_notice: true
|
|
||||||
|
|
15
SConstruct
15
SConstruct
|
@ -610,6 +610,10 @@ def get_pkg_lib(context, config, lib):
|
||||||
if ret:
|
if ret:
|
||||||
try:
|
try:
|
||||||
value = call(cmd,silent=True)
|
value = call(cmd,silent=True)
|
||||||
|
if ' ' in value:
|
||||||
|
parts = value.split(' ')
|
||||||
|
if len(parts) > 1:
|
||||||
|
value = parts[1]
|
||||||
libnames = re.findall(libpattern,value)
|
libnames = re.findall(libpattern,value)
|
||||||
if libnames:
|
if libnames:
|
||||||
libname = libnames[0]
|
libname = libnames[0]
|
||||||
|
@ -1427,7 +1431,7 @@ if not preconfigured:
|
||||||
env["CAIRO_ALL_LIBS"] = ['cairo']
|
env["CAIRO_ALL_LIBS"] = ['cairo']
|
||||||
if env['RUNTIME_LINK'] == 'static':
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
env["CAIRO_ALL_LIBS"].extend(
|
env["CAIRO_ALL_LIBS"].extend(
|
||||||
['pixman-1','expat','fontconfig','iconv']
|
['pixman-1','expat','iconv']
|
||||||
)
|
)
|
||||||
# todo - run actual checkLib?
|
# todo - run actual checkLib?
|
||||||
env['HAS_CAIRO'] = True
|
env['HAS_CAIRO'] = True
|
||||||
|
@ -1619,6 +1623,15 @@ if not preconfigured:
|
||||||
debug_defines = ['-DDEBUG', '-DMAPNIK_DEBUG']
|
debug_defines = ['-DDEBUG', '-DMAPNIK_DEBUG']
|
||||||
ndebug_defines = ['-DNDEBUG']
|
ndebug_defines = ['-DNDEBUG']
|
||||||
|
|
||||||
|
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||||
|
if boost_version_from_header > 53 or 'c++11' in env['CUSTOM_CXXFLAGS']:
|
||||||
|
env.Append(CPPDEFINES = '-DBOOST_SPIRIT_USE_PHOENIX_V3=1')
|
||||||
|
# - workaround boost gil channel_algorithm.hpp narrowing error
|
||||||
|
# TODO - remove when building against >= 1.55
|
||||||
|
# https://github.com/mapnik/mapnik/issues/1970
|
||||||
|
if 'clang++' in env['CXX']:
|
||||||
|
env.Append(CXXFLAGS = '-Wno-c++11-narrowing')
|
||||||
|
|
||||||
# Enable logging in debug mode (always) and release mode (when specified)
|
# Enable logging in debug mode (always) and release mode (when specified)
|
||||||
if env['DEFAULT_LOG_SEVERITY']:
|
if env['DEFAULT_LOG_SEVERITY']:
|
||||||
if env['DEFAULT_LOG_SEVERITY'] not in severities:
|
if env['DEFAULT_LOG_SEVERITY'] not in severities:
|
||||||
|
|
|
@ -194,7 +194,11 @@ struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
|
||||||
ListNodeWrap(object l) : formatting::list_node(), wrapper<formatting::list_node>()
|
ListNodeWrap(object l) : formatting::list_node(), wrapper<formatting::list_node>()
|
||||||
{
|
{
|
||||||
stl_input_iterator<formatting::node_ptr> begin(l), end;
|
stl_input_iterator<formatting::node_ptr> begin(l), end;
|
||||||
children_.insert(children_.end(), begin, end);
|
while (begin != end)
|
||||||
|
{
|
||||||
|
children_.push_back(*begin);
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add constructor taking variable number of arguments.
|
/* TODO: Add constructor taking variable number of arguments.
|
||||||
|
|
|
@ -199,6 +199,11 @@ struct symbolizer_attributes : public boost::static_visitor<>
|
||||||
{
|
{
|
||||||
boost::apply_visitor(f_attr,*width_expr);
|
boost::apply_visitor(f_attr,*width_expr);
|
||||||
}
|
}
|
||||||
|
path_expression_ptr const& filename_expr = sym.get_filename();
|
||||||
|
if (filename_expr)
|
||||||
|
{
|
||||||
|
path_processor_type::collect_attributes(*filename_expr,names_);
|
||||||
|
}
|
||||||
collect_transform(sym.get_image_transform());
|
collect_transform(sym.get_image_transform());
|
||||||
collect_transform(sym.get_transform());
|
collect_transform(sym.get_transform());
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,11 @@ struct alpha_conv_impl
|
||||||
|
|
||||||
struct hsl_conv_impl
|
struct hsl_conv_impl
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template<typename T>
|
||||||
|
#else
|
||||||
template<typename T0,typename T1, typename T2, typename T3>
|
template<typename T0,typename T1, typename T2, typename T3>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -413,7 +417,11 @@ struct alpha_conv_impl
|
||||||
|
|
||||||
struct hsl_conv_impl
|
struct hsl_conv_impl
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template<typename T>
|
||||||
|
#else
|
||||||
template<typename T0,typename T1, typename T2, typename T3>
|
template<typename T0,typename T1, typename T2, typename T3>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
|
|
@ -65,7 +65,11 @@ struct unicode_impl
|
||||||
|
|
||||||
struct regex_match_impl
|
struct regex_match_impl
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef expr_node type;
|
typedef expr_node type;
|
||||||
|
@ -82,7 +86,11 @@ struct regex_match_impl
|
||||||
|
|
||||||
struct regex_replace_impl
|
struct regex_replace_impl
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef expr_node type;
|
typedef expr_node type;
|
||||||
|
|
|
@ -145,7 +145,7 @@ expression_grammar<Iterator>::expression_grammar(mapnik::transcoder const& tr)
|
||||||
multiplicative_expr = unary_expr [_val = _1]
|
multiplicative_expr = unary_expr [_val = _1]
|
||||||
>> *( '*' >> unary_expr [_val *= _1]
|
>> *( '*' >> unary_expr [_val *= _1]
|
||||||
| '/' >> unary_expr [_val /= _1]
|
| '/' >> unary_expr [_val /= _1]
|
||||||
| '%' >> unary_expr [_val %= _1]
|
| '%' >> unary_expr [_val %= construct<mapnik::expr_node>(_1)] //needed by clang++ with -std=c++11
|
||||||
| regex_match_expr[_val = regex_match_(_val, _1)]
|
| regex_match_expr[_val = regex_match_(_val, _1)]
|
||||||
| regex_replace_expr(_val) [_val = _1]
|
| regex_replace_expr(_val) [_val = _1]
|
||||||
)
|
)
|
||||||
|
|
|
@ -232,6 +232,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
||||||
int buffer_size,
|
int buffer_size,
|
||||||
std::set<std::string>& names)
|
std::set<std::string>& names)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
std::vector<std::string> const& style_names = lay.styles();
|
std::vector<std::string> const& style_names = lay.styles();
|
||||||
|
|
||||||
unsigned int num_styles = style_names.size();
|
unsigned int num_styles = style_names.size();
|
||||||
|
@ -548,6 +549,13 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p.end_layer_processing(lay);
|
p.end_layer_processing(lay);
|
||||||
|
|
||||||
|
} catch (std::exception const& e) {
|
||||||
|
std::ostringstream m;
|
||||||
|
m << lay.name() << ": " << e.what();
|
||||||
|
throw std::runtime_error(m.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,30 @@ public:
|
||||||
mapnik::transcoder const& tr_;
|
mapnik::transcoder const& tr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
struct put_property
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
explicit put_property(mapnik::transcoder const& tr)
|
||||||
|
: tr_(tr) {}
|
||||||
|
template <typename T0,typename T1, typename T2>
|
||||||
|
result_type operator() (T0 & feature, T1 const& key, T2 const& val) const
|
||||||
|
{
|
||||||
|
feature.put_new(key, boost::apply_visitor(attribute_value_visitor(tr_),val));
|
||||||
|
}
|
||||||
|
mapnik::transcoder const& tr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct extract_geometry
|
||||||
|
{
|
||||||
|
typedef boost::ptr_vector<mapnik::geometry_type>& result_type;
|
||||||
|
template <typename T>
|
||||||
|
result_type operator() (T & feature) const
|
||||||
|
{
|
||||||
|
return feature.paths();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct put_property
|
struct put_property
|
||||||
{
|
{
|
||||||
template <typename T0,typename T1, typename T2>
|
template <typename T0,typename T1, typename T2>
|
||||||
|
@ -100,6 +124,7 @@ struct extract_geometry
|
||||||
return feature.paths();
|
return feature.paths();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename Iterator, typename FeatureType>
|
template <typename Iterator, typename FeatureType>
|
||||||
struct feature_grammar :
|
struct feature_grammar :
|
||||||
|
|
|
@ -38,11 +38,8 @@
|
||||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||||
#include <boost/spirit/include/phoenix_function.hpp>
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
#include <boost/spirit/include/phoenix_statement.hpp>
|
#include <boost/spirit/include/phoenix_statement.hpp>
|
||||||
#include <boost/fusion/include/boost_tuple.hpp>
|
#include <boost/fusion/adapted/boost_tuple.hpp>
|
||||||
#include <boost/math/special_functions/trunc.hpp> // trunc to avoid needing C++11
|
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunct
|
||||||
|
|
||||||
|
|
||||||
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
|
||||||
|
|
||||||
namespace boost { namespace spirit { namespace traits {
|
namespace boost { namespace spirit { namespace traits {
|
||||||
|
|
||||||
|
@ -61,6 +58,68 @@ namespace phoenix = boost::phoenix;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
struct get_type
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
result_type operator() (geometry_type const& geom) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(geom.type());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct get_first
|
||||||
|
{
|
||||||
|
typedef geometry_type::value_type const result_type;
|
||||||
|
result_type operator() (geometry_type const& geom) const
|
||||||
|
{
|
||||||
|
geometry_type::value_type coord;
|
||||||
|
boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord));
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct multi_geometry_type
|
||||||
|
{
|
||||||
|
typedef boost::tuple<unsigned,bool> result_type;
|
||||||
|
result_type operator() (geometry_container const& geom) const
|
||||||
|
{
|
||||||
|
unsigned type = 0u;
|
||||||
|
bool collection = false;
|
||||||
|
|
||||||
|
geometry_container::const_iterator itr = geom.begin();
|
||||||
|
geometry_container::const_iterator end = geom.end();
|
||||||
|
|
||||||
|
for ( ; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (type != 0u && itr->type() != type)
|
||||||
|
{
|
||||||
|
collection = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
type = itr->type();
|
||||||
|
}
|
||||||
|
if (geom.size() > 1) type +=3;
|
||||||
|
return boost::tuple<unsigned,bool>(type, collection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct not_empty
|
||||||
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
result_type operator() (geometry_container const& cont) const
|
||||||
|
{
|
||||||
|
geometry_container::const_iterator itr = cont.begin();
|
||||||
|
geometry_container::const_iterator end = cont.end();
|
||||||
|
for ( ; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (itr->size() > 0) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
struct get_type
|
struct get_type
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -100,7 +159,7 @@ struct multi_geometry_type
|
||||||
|
|
||||||
for ( ; itr != end; ++itr)
|
for ( ; itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if (type != 0u && itr->type() != type)
|
if (type != 0u && static_cast<unsigned>(itr->type()) != type)
|
||||||
{
|
{
|
||||||
collection = true;
|
collection = true;
|
||||||
break;
|
break;
|
||||||
|
@ -113,6 +172,28 @@ struct multi_geometry_type
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct not_empty
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct result { typedef bool type; };
|
||||||
|
|
||||||
|
bool operator() (geometry_container const& cont) const
|
||||||
|
{
|
||||||
|
geometry_container::const_iterator itr = cont.begin();
|
||||||
|
geometry_container::const_iterator end = cont.end();
|
||||||
|
|
||||||
|
for (; itr!=end; ++itr)
|
||||||
|
{
|
||||||
|
if (itr->size() > 0) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct json_coordinate_policy : karma::real_policies<T>
|
struct json_coordinate_policy : karma::real_policies<T>
|
||||||
{
|
{
|
||||||
|
@ -123,7 +204,7 @@ struct json_coordinate_policy : karma::real_policies<T>
|
||||||
{
|
{
|
||||||
if (n == 0.0) return 0;
|
if (n == 0.0) return 0;
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
return static_cast<unsigned>(15 - boost::math::trunc(log10(traits::get_absolute_value(n))));
|
return static_cast<unsigned>(14 - boost::math::trunc(log10(traits::get_absolute_value(n))));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
|
@ -135,7 +216,7 @@ struct json_coordinate_policy : karma::real_policies<T>
|
||||||
|
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
static bool fraction_part(OutputIterator& sink, T n
|
static bool fraction_part(OutputIterator& sink, T n
|
||||||
, unsigned adjprec, unsigned precision)
|
, unsigned adjprec, unsigned precision)
|
||||||
{
|
{
|
||||||
if (n == 0) return true;
|
if (n == 0) return true;
|
||||||
return base_type::fraction_part(sink, n, adjprec, precision);
|
return base_type::fraction_part(sink, n, adjprec, precision);
|
||||||
|
@ -153,6 +234,7 @@ struct geometry_generator_grammar :
|
||||||
: geometry_generator_grammar::base_type(coordinates)
|
: geometry_generator_grammar::base_type(coordinates)
|
||||||
{
|
{
|
||||||
using boost::spirit::karma::uint_;
|
using boost::spirit::karma::uint_;
|
||||||
|
using boost::spirit::bool_;
|
||||||
using boost::spirit::karma::_val;
|
using boost::spirit::karma::_val;
|
||||||
using boost::spirit::karma::_1;
|
using boost::spirit::karma::_1;
|
||||||
using boost::spirit::karma::lit;
|
using boost::spirit::karma::lit;
|
||||||
|
@ -182,15 +264,15 @@ struct geometry_generator_grammar :
|
||||||
point_coord = &uint_
|
point_coord = &uint_
|
||||||
<< lit('[')
|
<< lit('[')
|
||||||
<< coord_type << lit(',') << coord_type
|
<< coord_type << lit(',') << coord_type
|
||||||
<< lit("]")
|
<< lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
|
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
|
||||||
<< karma::string[ if_ (_r1 > 1) [_1 = "],["]
|
<< karma::string[ if_ (_r1 > 1u) [_1 = "],["]
|
||||||
.else_[_1 = '[' ]] | &uint_ << lit(','))
|
.else_[_1 = '[' ]]
|
||||||
<< lit('[') << coord_type
|
|
|
||||||
<< lit(',')
|
&uint_(mapnik::SEG_LINETO)
|
||||||
<< coord_type << lit(']')
|
<< lit(',')) << lit('[') << coord_type << lit(',') << coord_type << lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
coords2 %= *polygon_coord(_a)
|
coords2 %= *polygon_coord(_a)
|
||||||
|
@ -205,7 +287,6 @@ struct geometry_generator_grammar :
|
||||||
karma::rule<OutputIterator, geometry_type const& ()> point;
|
karma::rule<OutputIterator, geometry_type const& ()> point;
|
||||||
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
||||||
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
||||||
|
|
||||||
karma::rule<OutputIterator, geometry_type const& ()> coords;
|
karma::rule<OutputIterator, geometry_type const& ()> coords;
|
||||||
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
|
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
|
||||||
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
|
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
|
||||||
|
@ -235,6 +316,7 @@ struct multi_geometry_generator_grammar :
|
||||||
using boost::spirit::karma::_1;
|
using boost::spirit::karma::_1;
|
||||||
using boost::spirit::karma::_a;
|
using boost::spirit::karma::_a;
|
||||||
using boost::spirit::karma::_r1;
|
using boost::spirit::karma::_r1;
|
||||||
|
using boost::spirit::bool_;
|
||||||
|
|
||||||
geometry_types.add
|
geometry_types.add
|
||||||
(mapnik::Point,"\"Point\"")
|
(mapnik::Point,"\"Point\"")
|
||||||
|
@ -245,7 +327,7 @@ struct multi_geometry_generator_grammar :
|
||||||
(mapnik::Polygon + 3,"\"MultiPolygon\"")
|
(mapnik::Polygon + 3,"\"MultiPolygon\"")
|
||||||
;
|
;
|
||||||
|
|
||||||
start %= ( eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)]
|
start %= ( eps(phoenix::at_c<1>(_a))[_a = multi_type_(_val)]
|
||||||
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[")
|
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[")
|
||||||
<< geometry_collection << lit("]}")
|
<< geometry_collection << lit("]}")
|
||||||
|
|
|
|
||||||
|
@ -255,13 +337,13 @@ struct multi_geometry_generator_grammar :
|
||||||
geometry_collection = -(geometry2 % lit(','))
|
geometry_collection = -(geometry2 % lit(','))
|
||||||
;
|
;
|
||||||
|
|
||||||
geometry = (lit("{\"type\":")
|
geometry = ( &bool_(true)[_1 = not_empty_(_val)] << lit("{\"type\":")
|
||||||
<< geometry_types[_1 = phoenix::at_c<0>(_a)][_a = _multi_type(_val)]
|
<< geometry_types[_1 = phoenix::at_c<0>(_a)][_a = multi_type_(_val)]
|
||||||
<< lit(",\"coordinates\":")
|
<< lit(",\"coordinates\":")
|
||||||
<< karma::string[ if_ (phoenix::at_c<0>(_a) > 3) [_1 = '[']]
|
<< karma::string[ phoenix::if_ (phoenix::at_c<0>(_a) > 3u) [_1 = '['].else_[_1 = ""]]
|
||||||
<< coordinates
|
<< coordinates
|
||||||
<< karma::string[ if_ (phoenix::at_c<0>(_a) > 3) [_1 = ']']]
|
<< karma::string[ phoenix::if_ (phoenix::at_c<0>(_a) > 3u) [_1 = ']'].else_[_1 = ""]]
|
||||||
<< lit('}')) | lit("null")
|
<< lit('}')) | lit("null")
|
||||||
;
|
;
|
||||||
|
|
||||||
geometry2 = lit("{\"type\":")
|
geometry2 = lit("{\"type\":")
|
||||||
|
@ -287,8 +369,9 @@ struct multi_geometry_generator_grammar :
|
||||||
karma::rule<OutputIterator, geometry_container const&()> coordinates;
|
karma::rule<OutputIterator, geometry_container const&()> coordinates;
|
||||||
geometry_generator_grammar<OutputIterator> path;
|
geometry_generator_grammar<OutputIterator> path;
|
||||||
// phoenix
|
// phoenix
|
||||||
phoenix::function<multi_geometry_type> _multi_type;
|
phoenix::function<multi_geometry_type> multi_type_;
|
||||||
phoenix::function<get_type > type_;
|
phoenix::function<get_type > type_;
|
||||||
|
phoenix::function<not_empty> not_empty_;
|
||||||
// symbols table
|
// symbols table
|
||||||
karma::symbols<unsigned, char const*> geometry_types;
|
karma::symbols<unsigned, char const*> geometry_types;
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,58 @@ namespace qi = boost::spirit::qi;
|
||||||
namespace standard_wide = boost::spirit::standard_wide;
|
namespace standard_wide = boost::spirit::standard_wide;
|
||||||
using standard_wide::space_type;
|
using standard_wide::space_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
struct push_vertex
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
|
||||||
|
template <typename T0,typename T1, typename T2, typename T3>
|
||||||
|
result_type operator() (T0 c, T1 path, T2 x, T3 y) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( path!=0 );
|
||||||
|
path->push_vertex(x,y,c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct close_path
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
result_type operator() (T path) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( path!=0 );
|
||||||
|
if (path->size() > 2u) // to form a polygon ring we need at least 3 vertices
|
||||||
|
{
|
||||||
|
path->close_path();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cleanup
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
template <typename T0>
|
||||||
|
void operator() (T0 & path) const
|
||||||
|
{
|
||||||
|
if (path) delete path, path=0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct where_message
|
||||||
|
{
|
||||||
|
typedef std::string result_type;
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
std::string operator() (Iterator first, Iterator last, std::size_t size) const
|
||||||
|
{
|
||||||
|
std::string str(first, last);
|
||||||
|
if (str.length() > size)
|
||||||
|
return str.substr(0, size) + "..." ;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct push_vertex
|
struct push_vertex
|
||||||
{
|
{
|
||||||
template <typename T0,typename T1, typename T2, typename T3>
|
template <typename T0,typename T1, typename T2, typename T3>
|
||||||
|
@ -65,8 +117,11 @@ struct close_path
|
||||||
void operator() (T path) const
|
void operator() (T path) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( path!=0 );
|
BOOST_ASSERT( path!=0 );
|
||||||
path->close_path();
|
if (path->size() > 2u) // to form a polygon ring we need at least 3 vertices
|
||||||
}
|
{
|
||||||
|
path->close_path();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cleanup
|
struct cleanup
|
||||||
|
@ -101,12 +156,13 @@ struct where_message
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
struct geometry_grammar :
|
struct geometry_grammar :
|
||||||
qi::grammar<Iterator,qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& )
|
qi::grammar<Iterator,qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& )
|
||||||
, space_type>
|
, space_type>
|
||||||
{
|
{
|
||||||
geometry_grammar();
|
geometry_grammar();
|
||||||
qi::rule<Iterator, qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> geometry;
|
qi::rule<Iterator, qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> geometry;
|
||||||
|
|
|
@ -124,12 +124,12 @@ public:
|
||||||
|
|
||||||
inline bool is_bitmap() const
|
inline bool is_bitmap() const
|
||||||
{
|
{
|
||||||
return bitmap_data_;
|
return bitmap_data_ ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_vector() const
|
inline bool is_vector() const
|
||||||
{
|
{
|
||||||
return vector_data_;
|
return vector_data_ ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<mapnik::image_ptr> get_bitmap_data() const
|
boost::optional<mapnik::image_ptr> get_bitmap_data() const
|
||||||
|
|
|
@ -45,7 +45,12 @@ inline double deg2rad(double deg)
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct move_to
|
struct move_to
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -66,7 +71,11 @@ struct move_to
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct hline_to
|
struct hline_to
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -88,7 +97,11 @@ struct hline_to
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct vline_to
|
struct vline_to
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -109,7 +122,11 @@ struct vline_to
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct line_to
|
struct line_to
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -131,7 +148,11 @@ struct line_to
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct curve4
|
struct curve4
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2, typename T3>
|
template <typename T0, typename T1, typename T2, typename T3>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -156,7 +177,11 @@ struct curve4
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct curve4_smooth
|
struct curve4_smooth
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -178,7 +203,11 @@ struct curve4_smooth
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct curve3
|
struct curve3
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -201,7 +230,11 @@ struct curve3
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct curve3_smooth
|
struct curve3_smooth
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -223,7 +256,11 @@ struct curve3_smooth
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
struct arc_to
|
struct arc_to
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
|
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
|
|
@ -50,7 +50,11 @@ namespace mapnik { namespace svg {
|
||||||
template <typename TransformType>
|
template <typename TransformType>
|
||||||
struct process_matrix
|
struct process_matrix
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
|
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -70,7 +74,11 @@ namespace mapnik { namespace svg {
|
||||||
template <typename TransformType>
|
template <typename TransformType>
|
||||||
struct process_rotate
|
struct process_rotate
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -101,7 +109,11 @@ namespace mapnik { namespace svg {
|
||||||
template <typename TransformType>
|
template <typename TransformType>
|
||||||
struct process_translate
|
struct process_translate
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -123,7 +135,11 @@ namespace mapnik { namespace svg {
|
||||||
template <typename TransformType>
|
template <typename TransformType>
|
||||||
struct process_scale
|
struct process_scale
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
@ -146,7 +162,11 @@ namespace mapnik { namespace svg {
|
||||||
template <typename TransformType>
|
template <typename TransformType>
|
||||||
struct process_skew
|
struct process_skew
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T0>
|
||||||
|
#else
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
|
#ifndef MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
|
||||||
#define MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
|
#define MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
|
||||||
|
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/geometry.hpp> // for container stuff
|
#include <mapnik/geometry.hpp> // for container stuff
|
||||||
|
@ -41,13 +42,11 @@
|
||||||
#include <boost/fusion/include/boost_tuple.hpp>
|
#include <boost/fusion/include/boost_tuple.hpp>
|
||||||
#include <boost/type_traits/remove_pointer.hpp>
|
#include <boost/type_traits/remove_pointer.hpp>
|
||||||
|
|
||||||
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
|
||||||
|
|
||||||
/*!
|
// adapted to conform to the concepts
|
||||||
* adapted to conform to the concepts
|
// required by Karma to be recognized as a container of
|
||||||
* required by Karma to be recognized as a container of
|
// attributes for output generation.
|
||||||
* attributes for output generation.
|
|
||||||
*/
|
|
||||||
namespace boost { namespace spirit { namespace traits {
|
namespace boost { namespace spirit { namespace traits {
|
||||||
|
|
||||||
// TODO - this needs to be made generic to any path type
|
// TODO - this needs to be made generic to any path type
|
||||||
|
@ -76,7 +75,7 @@ template <>
|
||||||
struct end_container<path_type const>
|
struct end_container<path_type const>
|
||||||
{
|
{
|
||||||
static mapnik::util::path_iterator<path_type>
|
static mapnik::util::path_iterator<path_type>
|
||||||
call (path_type const& g)
|
call (path_type const& /*g*/)
|
||||||
{
|
{
|
||||||
return mapnik::util::path_iterator<path_type>();
|
return mapnik::util::path_iterator<path_type>();
|
||||||
}
|
}
|
||||||
|
@ -92,6 +91,31 @@ namespace mapnik { namespace util {
|
||||||
|
|
||||||
namespace svg_detail {
|
namespace svg_detail {
|
||||||
|
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename Geometry>
|
||||||
|
struct get_type
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
result_type operator() (Geometry const& geom) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(geom.type());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct get_first
|
||||||
|
{
|
||||||
|
typedef T geometry_type;
|
||||||
|
typedef typename geometry_type::value_type const result_type;
|
||||||
|
result_type operator() (geometry_type const& geom) const
|
||||||
|
{
|
||||||
|
typename geometry_type::value_type coord;
|
||||||
|
geom.rewind(0);
|
||||||
|
boost::get<0>(coord) = geom.vertex(&boost::get<1>(coord),&boost::get<2>(coord));
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
template <typename Geometry>
|
template <typename Geometry>
|
||||||
struct get_type
|
struct get_type
|
||||||
{
|
{
|
||||||
|
@ -112,7 +136,7 @@ namespace mapnik { namespace util {
|
||||||
template <typename U>
|
template <typename U>
|
||||||
struct result { typedef typename geometry_type::value_type const type; };
|
struct result { typedef typename geometry_type::value_type const type; };
|
||||||
|
|
||||||
typename geometry_type::value_type const operator() (geometry_type const& geom) const
|
typename geometry_type::value_type operator() (geometry_type const& geom) const
|
||||||
{
|
{
|
||||||
typename geometry_type::value_type coord;
|
typename geometry_type::value_type coord;
|
||||||
geom.rewind(0);
|
geom.rewind(0);
|
||||||
|
@ -121,12 +145,13 @@ namespace mapnik { namespace util {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct coordinate_policy : karma::real_policies<T>
|
struct coordinate_policy : karma::real_policies<T>
|
||||||
{
|
{
|
||||||
typedef boost::spirit::karma::real_policies<T> base_type;
|
typedef boost::spirit::karma::real_policies<T> base_type;
|
||||||
static int floatfield(T n) { return base_type::fmtflags::fixed; }
|
static int floatfield(T n) { return base_type::fmtflags::fixed; }
|
||||||
static unsigned precision(T n) { return 6u ;}
|
static unsigned precision(T n) { return 4u ;}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,15 +186,15 @@ namespace mapnik { namespace util {
|
||||||
;
|
;
|
||||||
|
|
||||||
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)]
|
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)]
|
||||||
<< svg_path << lit('\"')
|
<< lit("d=\"") << svg_path << lit("\"")
|
||||||
;
|
;
|
||||||
|
|
||||||
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
|
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
|
||||||
<< svg_path << lit('\"')
|
<< lit("d=\"") << svg_path << lit("\"")
|
||||||
;
|
;
|
||||||
|
|
||||||
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit("d=\"") << lit('M')
|
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit('M')
|
||||||
| &uint_(mapnik::SEG_LINETO) [_a +=1] << karma::string [if_(_a == 1) [_1 = "L" ] ])
|
| &uint_(mapnik::SEG_LINETO) [_a +=1] << karma::string [if_(_a == 1u) [_1 = "L" ].else_[_1 =""]])
|
||||||
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
|
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <boost/type_traits/remove_pointer.hpp>
|
#include <boost/type_traits/remove_pointer.hpp>
|
||||||
|
|
||||||
#include <boost/math/special_functions/trunc.hpp> // trunc to avoid needing C++11
|
#include <boost/math/special_functions/trunc.hpp> // trunc to avoid needing C++11
|
||||||
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
|
||||||
|
|
||||||
namespace boost { namespace spirit { namespace traits {
|
namespace boost { namespace spirit { namespace traits {
|
||||||
|
|
||||||
|
@ -205,8 +204,7 @@ template <typename OutputIterator, typename GeometryContainer>
|
||||||
struct wkt_multi_generator :
|
struct wkt_multi_generator :
|
||||||
karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, GeometryContainer const& ()>
|
karma::grammar<OutputIterator, karma::locals< boost::tuple<unsigned,bool> >, GeometryContainer const& ()>
|
||||||
{
|
{
|
||||||
typedef GeometryContainer geometry_contaner;
|
typedef typename boost::remove_pointer<typename GeometryContainer::value_type>::type geometry_type;
|
||||||
typedef boost::remove_pointer<typename geometry_container::value_type>::type geometry_type;
|
|
||||||
|
|
||||||
wkt_multi_generator();
|
wkt_multi_generator();
|
||||||
// rules
|
// rules
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#ifndef MAPNIK_VERSION_HPP
|
#ifndef MAPNIK_VERSION_HPP
|
||||||
#define MAPNIK_VERSION_HPP
|
#define MAPNIK_VERSION_HPP
|
||||||
|
|
||||||
#define MAPNIK_VERSION_IS_RELEASE 1
|
#define MAPNIK_VERSION_IS_RELEASE 0
|
||||||
|
|
||||||
#define MAPNIK_MAJOR_VERSION 2
|
#define MAPNIK_MAJOR_VERSION 2
|
||||||
#define MAPNIK_MINOR_VERSION 2
|
#define MAPNIK_MINOR_VERSION 2
|
||||||
|
|
|
@ -40,12 +40,15 @@
|
||||||
namespace mapnik { namespace wkt {
|
namespace mapnik { namespace wkt {
|
||||||
|
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
using namespace boost::fusion;
|
|
||||||
using namespace boost::phoenix;
|
using namespace boost::phoenix;
|
||||||
|
|
||||||
struct push_vertex
|
struct push_vertex
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
|
template <typename T>
|
||||||
|
#else
|
||||||
template <typename T0,typename T1, typename T2, typename T3>
|
template <typename T0,typename T1, typename T2, typename T3>
|
||||||
|
#endif
|
||||||
struct result
|
struct result
|
||||||
{
|
{
|
||||||
typedef void type;
|
typedef void type;
|
||||||
|
|
13
localize.sh
Executable file
13
localize.sh
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
UNAME=$(uname -s)
|
||||||
|
export CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
if [ ${UNAME} = 'Darwin' ]; then
|
||||||
|
export DYLD_LIBRARY_PATH="${CURRENT_DIR}/src/"
|
||||||
|
else
|
||||||
|
export LD_LIBRARY_PATH="${CURRENT_DIR}/src/"
|
||||||
|
fi
|
||||||
|
export PYTHONPATH="${CURRENT_DIR}/bindings/python/":${PYTHONPATH}
|
||||||
|
export MAPNIK_FONT_DIRECTORY="${CURRENT_DIR}/fonts/dejavu-fonts-ttf-2.33/ttf/"
|
||||||
|
export MAPNIK_INPUT_PLUGINS_DIRECTORY="${CURRENT_DIR}/plugins/input/"
|
||||||
|
export PATH="${CURRENT_DIR}/utils/mapnik-config/":${PATH}
|
||||||
|
export PATH="${CURRENT_DIR}/utils/nik2img":${PATH}
|
|
@ -32,10 +32,6 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/spirit/include/support_multi_pass.hpp>
|
#include <boost/spirit/include/support_multi_pass.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/geometry/geometries/box.hpp>
|
|
||||||
#include <boost/geometry/geometries/geometries.hpp>
|
|
||||||
#include <boost/geometry.hpp>
|
|
||||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
|
@ -101,7 +97,11 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
||||||
extent_(),
|
extent_(),
|
||||||
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
|
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
|
||||||
features_(),
|
features_(),
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
tree_()
|
||||||
|
#else
|
||||||
tree_(16,1)
|
tree_(16,1)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");
|
if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");
|
||||||
|
|
||||||
|
@ -137,15 +137,13 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
||||||
throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");
|
throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool first = true;
|
std::size_t geometry_index = 0;
|
||||||
std::size_t count=0;
|
BOOST_FOREACH (mapnik::feature_ptr const& f, features_)
|
||||||
BOOST_FOREACH (mapnik::feature_ptr f, features_)
|
|
||||||
{
|
{
|
||||||
mapnik::box2d<double> const& box = f->envelope();
|
mapnik::box2d<double> box = f->envelope();
|
||||||
if (first)
|
if (geometry_index == 0)
|
||||||
{
|
{
|
||||||
extent_ = box;
|
extent_ = box;
|
||||||
first = false;
|
|
||||||
mapnik::feature_kv_iterator f_itr = f->begin();
|
mapnik::feature_kv_iterator f_itr = f->begin();
|
||||||
mapnik::feature_kv_iterator f_end = f->end();
|
mapnik::feature_kv_iterator f_end = f->end();
|
||||||
for ( ;f_itr!=f_end; ++f_itr)
|
for ( ;f_itr!=f_end; ++f_itr)
|
||||||
|
@ -158,7 +156,12 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
||||||
{
|
{
|
||||||
extent_.expand_to_include(box);
|
extent_.expand_to_include(box);
|
||||||
}
|
}
|
||||||
tree_.insert(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())), count++);
|
#if BOOST_VERSION >= 105600
|
||||||
|
tree_.insert(std::make_pair(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())),geometry_index));
|
||||||
|
#else
|
||||||
|
tree_.insert(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())),geometry_index);
|
||||||
|
#endif
|
||||||
|
++geometry_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +216,11 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons
|
||||||
if (extent_.intersects(b))
|
if (extent_.intersects(b))
|
||||||
{
|
{
|
||||||
box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy()));
|
box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy()));
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
tree_.query(boost::geometry::index::intersects(box),std::back_inserter(index_array_));
|
||||||
|
#else
|
||||||
index_array_ = tree_.find(box);
|
index_array_ = tree_.find(box);
|
||||||
|
#endif
|
||||||
return boost::make_shared<geojson_featureset>(features_, index_array_.begin(), index_array_.end());
|
return boost::make_shared<geojson_featureset>(features_, index_array_.begin(), index_array_.end());
|
||||||
}
|
}
|
||||||
// otherwise return an empty featureset pointer
|
// otherwise return an empty featureset pointer
|
||||||
|
|
|
@ -36,11 +36,16 @@
|
||||||
// boost
|
// boost
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/geometry/geometries/box.hpp>
|
|
||||||
#include <boost/geometry/geometries/point_xy.hpp>
|
#include <boost/geometry/geometries/point_xy.hpp>
|
||||||
#include <boost/geometry/algorithms/area.hpp>
|
#include <boost/geometry/geometries/box.hpp>
|
||||||
#include <boost/geometry/geometries/geometries.hpp>
|
#include <boost/geometry/geometries/geometries.hpp>
|
||||||
|
#include <boost/geometry.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
#include <boost/geometry/index/rtree.hpp>
|
||||||
|
#else
|
||||||
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -53,7 +58,14 @@ class geojson_datasource : public mapnik::datasource
|
||||||
public:
|
public:
|
||||||
typedef boost::geometry::model::d2::point_xy<double> point_type;
|
typedef boost::geometry::model::d2::point_xy<double> point_type;
|
||||||
typedef boost::geometry::model::box<point_type> box_type;
|
typedef boost::geometry::model::box<point_type> box_type;
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
typedef std::pair<box_type,std::size_t> item_type;
|
||||||
|
typedef boost::geometry::index::linear<16,1> linear_type;
|
||||||
|
typedef boost::geometry::index::rtree<item_type,linear_type> spatial_index_type;
|
||||||
|
#else
|
||||||
|
typedef std::size_t item_type;
|
||||||
typedef boost::geometry::index::rtree<box_type,std::size_t> spatial_index_type;
|
typedef boost::geometry::index::rtree<box_type,std::size_t> spatial_index_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
geojson_datasource(mapnik::parameters const& params);
|
geojson_datasource(mapnik::parameters const& params);
|
||||||
|
@ -74,7 +86,7 @@ private:
|
||||||
boost::shared_ptr<mapnik::transcoder> tr_;
|
boost::shared_ptr<mapnik::transcoder> tr_;
|
||||||
std::vector<mapnik::feature_ptr> features_;
|
std::vector<mapnik::feature_ptr> features_;
|
||||||
spatial_index_type tree_;
|
spatial_index_type tree_;
|
||||||
mutable std::deque<std::size_t> index_array_;
|
mutable std::deque<item_type> index_array_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
#include "geojson_featureset.hpp"
|
#include "geojson_featureset.hpp"
|
||||||
|
|
||||||
geojson_featureset::geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
geojson_featureset::geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
||||||
std::deque<std::size_t>::const_iterator index_itr,
|
array_type::const_iterator index_itr,
|
||||||
std::deque<std::size_t>::const_iterator index_end)
|
array_type::const_iterator index_end)
|
||||||
: features_(features),
|
: features_(features),
|
||||||
index_itr_(index_itr),
|
index_itr_(index_itr),
|
||||||
index_end_(index_end) {}
|
index_end_(index_end) {}
|
||||||
|
@ -42,7 +42,12 @@ mapnik::feature_ptr geojson_featureset::next()
|
||||||
{
|
{
|
||||||
if (index_itr_ != index_end_)
|
if (index_itr_ != index_end_)
|
||||||
{
|
{
|
||||||
std::size_t index = *index_itr_++;
|
#if BOOST_VERSION >= 105600
|
||||||
|
geojson_datasource::item_type const& item = *index_itr_++;
|
||||||
|
std::size_t index = item.second;
|
||||||
|
#else
|
||||||
|
std::size_t index = *index_itr_++;
|
||||||
|
#endif
|
||||||
if ( index < features_.size())
|
if ( index < features_.size())
|
||||||
{
|
{
|
||||||
return features_.at(index);
|
return features_.at(index);
|
||||||
|
|
|
@ -11,17 +11,18 @@
|
||||||
class geojson_featureset : public mapnik::Featureset
|
class geojson_featureset : public mapnik::Featureset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::deque<geojson_datasource::item_type> array_type;
|
||||||
geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
||||||
std::deque<std::size_t>::const_iterator index_itr,
|
array_type::const_iterator index_itr,
|
||||||
std::deque<std::size_t>::const_iterator index_end);
|
array_type::const_iterator index_end);
|
||||||
virtual ~geojson_featureset();
|
virtual ~geojson_featureset();
|
||||||
mapnik::feature_ptr next();
|
mapnik::feature_ptr next();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mapnik::box2d<double> box_;
|
mapnik::box2d<double> box_;
|
||||||
std::vector<mapnik::feature_ptr> const& features_;
|
std::vector<mapnik::feature_ptr> const& features_;
|
||||||
std::deque<std::size_t>::const_iterator index_itr_;
|
array_type::const_iterator index_itr_;
|
||||||
std::deque<std::size_t>::const_iterator index_end_;
|
array_type::const_iterator index_end_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GEOJSON_FEATURESET_HPP
|
#endif // GEOJSON_FEATURESET_HPP
|
||||||
|
|
|
@ -72,7 +72,11 @@ ogr_datasource::~ogr_datasource()
|
||||||
{
|
{
|
||||||
// free layer before destroying the datasource
|
// free layer before destroying the datasource
|
||||||
layer_.free_layer();
|
layer_.free_layer();
|
||||||
|
#if GDAL_VERSION_MAJOR >= 2
|
||||||
|
GDALClose(( GDALDatasetH) dataset_);
|
||||||
|
#else
|
||||||
OGRDataSource::DestroyDataSource (dataset_);
|
OGRDataSource::DestroyDataSource (dataset_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogr_datasource::init(mapnik::parameters const& params)
|
void ogr_datasource::init(mapnik::parameters const& params)
|
||||||
|
@ -82,6 +86,7 @@ void ogr_datasource::init(mapnik::parameters const& params)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// initialize ogr formats
|
// initialize ogr formats
|
||||||
|
// NOTE: in GDAL >= 2.0 this is the same as GDALAllRegister()
|
||||||
OGRRegisterAll();
|
OGRRegisterAll();
|
||||||
|
|
||||||
boost::optional<std::string> file = params.get<std::string>("file");
|
boost::optional<std::string> file = params.get<std::string>("file");
|
||||||
|
@ -112,17 +117,26 @@ void ogr_datasource::init(mapnik::parameters const& params)
|
||||||
|
|
||||||
if (! driver.empty())
|
if (! driver.empty())
|
||||||
{
|
{
|
||||||
|
#if GDAL_VERSION_MAJOR >= 2
|
||||||
|
unsigned int nOpenFlags = GDAL_OF_READONLY | GDAL_OF_VECTOR;
|
||||||
|
const char* papszAllowedDrivers[] = { driver.c_str(), NULL };
|
||||||
|
dataset_ = static_cast<gdal_dataset_type>(GDALOpenEx(dataset_name_.c_str(),nOpenFlags,papszAllowedDrivers,NULL,NULL));
|
||||||
|
#else
|
||||||
OGRSFDriver * ogr_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver.c_str());
|
OGRSFDriver * ogr_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver.c_str());
|
||||||
if (ogr_driver && ogr_driver != NULL)
|
if (ogr_driver && ogr_driver != NULL)
|
||||||
{
|
{
|
||||||
dataset_ = ogr_driver->Open((dataset_name_).c_str(), FALSE);
|
dataset_ = ogr_driver->Open((dataset_name_).c_str(), FALSE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// open ogr driver
|
// open ogr driver
|
||||||
dataset_ = OGRSFDriverRegistrar::Open((dataset_name_).c_str(), FALSE);
|
#if GDAL_VERSION_MAJOR >= 2
|
||||||
|
dataset_ = static_cast<gdal_dataset_type>(OGROpen(dataset_name_.c_str(), FALSE, NULL));
|
||||||
|
#else
|
||||||
|
dataset_ = OGRSFDriverRegistrar::Open(dataset_name_.c_str(), FALSE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! dataset_)
|
if (! dataset_)
|
||||||
|
|
|
@ -63,7 +63,7 @@ private:
|
||||||
mapnik::datasource::datasource_t type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
std::string dataset_name_;
|
std::string dataset_name_;
|
||||||
std::string index_name_;
|
std::string index_name_;
|
||||||
OGRDataSource* dataset_;
|
gdal_dataset_type dataset_;
|
||||||
ogr_layer_ptr layer_;
|
ogr_layer_ptr layer_;
|
||||||
std::string layer_name_;
|
std::string layer_name_;
|
||||||
mapnik::layer_descriptor desc_;
|
mapnik::layer_descriptor desc_;
|
||||||
|
|
|
@ -29,9 +29,16 @@
|
||||||
// stl
|
// stl
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
// ogr
|
// gdal
|
||||||
|
#include <gdal_version.h>
|
||||||
#include <ogrsf_frmts.h>
|
#include <ogrsf_frmts.h>
|
||||||
|
|
||||||
|
#if GDAL_VERSION_MAJOR >= 2
|
||||||
|
typedef GDALDataset* gdal_dataset_type;
|
||||||
|
#else
|
||||||
|
typedef OGRDataSource* gdal_dataset_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
class ogr_layer_ptr
|
class ogr_layer_ptr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -62,7 +69,7 @@ public:
|
||||||
is_valid_ = false;
|
is_valid_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer_by_name(OGRDataSource* const datasource,
|
void layer_by_name(gdal_dataset_type const datasource,
|
||||||
std::string const& layer_name)
|
std::string const& layer_name)
|
||||||
{
|
{
|
||||||
free_layer();
|
free_layer();
|
||||||
|
@ -84,7 +91,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer_by_index(OGRDataSource* const datasource,
|
void layer_by_index(gdal_dataset_type const datasource,
|
||||||
int layer_index)
|
int layer_index)
|
||||||
{
|
{
|
||||||
free_layer();
|
free_layer();
|
||||||
|
@ -110,7 +117,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer_by_sql(OGRDataSource* const datasource,
|
void layer_by_sql(gdal_dataset_type const datasource,
|
||||||
std::string const& layer_sql)
|
std::string const& layer_sql)
|
||||||
{
|
{
|
||||||
free_layer();
|
free_layer();
|
||||||
|
@ -179,7 +186,7 @@ private:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OGRDataSource* datasource_;
|
gdal_dataset_type datasource_;
|
||||||
OGRLayer* layer_;
|
OGRLayer* layer_;
|
||||||
std::string layer_name_;
|
std::string layer_name_;
|
||||||
bool owns_layer_;
|
bool owns_layer_;
|
||||||
|
|
|
@ -38,8 +38,22 @@ plugin_sources = Split(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Link Library to Dependencies
|
# Link Library to Dependencies
|
||||||
libraries = [ 'xml2' ]
|
plugin_env['LIBS'] = []
|
||||||
libraries.append('curl')
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
|
# pkg-config is more reliable than pg_config across platforms
|
||||||
|
cmd = 'pkg-config libcurl --libs --static'
|
||||||
|
try:
|
||||||
|
plugin_env.ParseConfig(cmd)
|
||||||
|
except OSError, e:
|
||||||
|
# if this fails likely only system curl is available
|
||||||
|
# on OS X at least the system curl lacks a pkg-config file
|
||||||
|
# so static linking is not viable anyway
|
||||||
|
plugin_env.Append(LIBS='curl')
|
||||||
|
else:
|
||||||
|
plugin_env.Append(LIBS='curl')
|
||||||
|
|
||||||
|
libraries = plugin_env['LIBS']
|
||||||
|
libraries.append('xml2')
|
||||||
libraries.append(env['ICU_LIB_NAME'])
|
libraries.append(env['ICU_LIB_NAME'])
|
||||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ public:
|
||||||
|
|
||||||
PGresult *result = PQexec(conn_, sql.c_str());
|
PGresult *result = PQexec(conn_, sql.c_str());
|
||||||
bool ok = (result && (PQresultStatus(result) == PGRES_COMMAND_OK));
|
bool ok = (result && (PQresultStatus(result) == PGRES_COMMAND_OK));
|
||||||
PQclear(result);
|
if ( result ) PQclear(result);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,8 @@ public:
|
||||||
|
|
||||||
if (! result || (PQresultStatus(result) != PGRES_TUPLES_OK))
|
if (! result || (PQresultStatus(result) != PGRES_TUPLES_OK))
|
||||||
{
|
{
|
||||||
std::string err_msg = status();
|
std::string err_msg = "Postgis Plugin: ";
|
||||||
|
err_msg += status();
|
||||||
err_msg += "\nFull sql was: '";
|
err_msg += "\nFull sql was: '";
|
||||||
err_msg += sql;
|
err_msg += sql;
|
||||||
err_msg += "'\n";
|
err_msg += "'\n";
|
||||||
|
@ -127,7 +128,8 @@ public:
|
||||||
std::string status;
|
std::string status;
|
||||||
if (conn_)
|
if (conn_)
|
||||||
{
|
{
|
||||||
status = PQerrorMessage(conn_);
|
if ( isOK() ) return PQerrorMessage(conn_);
|
||||||
|
else return "Bad connection";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
DATASOURCE_PLUGIN(postgis_datasource)
|
DATASOURCE_PLUGIN(postgis_datasource)
|
||||||
|
|
||||||
const double postgis_datasource::FMAX = std::numeric_limits<double>::max();
|
const double postgis_datasource::FMAX = std::numeric_limits<float>::max();
|
||||||
const std::string postgis_datasource::GEOMETRY_COLUMNS = "geometry_columns";
|
const std::string postgis_datasource::GEOMETRY_COLUMNS = "geometry_columns";
|
||||||
const std::string postgis_datasource::SPATIAL_REF_SYS = "spatial_ref_system";
|
const std::string postgis_datasource::SPATIAL_REF_SYS = "spatial_ref_system";
|
||||||
|
|
||||||
|
@ -424,10 +424,19 @@ postgis_datasource::~postgis_datasource()
|
||||||
shared_ptr< Pool<Connection,ConnectionCreator> > pool = ConnectionManager::instance().getPool(creator_.id());
|
shared_ptr< Pool<Connection,ConnectionCreator> > pool = ConnectionManager::instance().getPool(creator_.id());
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
shared_ptr<Connection> conn = pool->borrowObject();
|
try {
|
||||||
if (conn)
|
shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
{
|
if (conn)
|
||||||
conn->close();
|
{
|
||||||
|
conn->close();
|
||||||
|
}
|
||||||
|
} catch (mapnik::datasource_exception const& ex) {
|
||||||
|
// happens when borrowObject tries to
|
||||||
|
// create a new connection and fails.
|
||||||
|
// In turn, new connection would be needed
|
||||||
|
// when our broke and was thus no good to
|
||||||
|
// be borrowed
|
||||||
|
// See https://github.com/mapnik/mapnik/issues/2191
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import copy
|
||||||
Import ('plugin_base')
|
Import ('plugin_base')
|
||||||
Import ('env')
|
Import ('env')
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ libraries.append(env['BOOST_PYTHON_LIB'])
|
||||||
libraries.append(env['ICU_LIB_NAME'])
|
libraries.append(env['ICU_LIB_NAME'])
|
||||||
|
|
||||||
python_cpppath = env['PYTHON_INCLUDES']
|
python_cpppath = env['PYTHON_INCLUDES']
|
||||||
allcpp_paths = env['CPPPATH']
|
allcpp_paths = copy.copy(env['CPPPATH'])
|
||||||
allcpp_paths.extend(python_cpppath)
|
allcpp_paths.extend(python_cpppath)
|
||||||
# NOTE: explicit linking to libpython is uneeded on most linux version if the
|
# NOTE: explicit linking to libpython is uneeded on most linux version if the
|
||||||
# python plugin is used by a app in python using mapnik's python bindings
|
# python plugin is used by a app in python using mapnik's python bindings
|
||||||
|
|
|
@ -8,7 +8,7 @@ failures=$((failures+$?))
|
||||||
|
|
||||||
echo "*** Running C++ tests..."
|
echo "*** Running C++ tests..."
|
||||||
for FILE in tests/cpp_tests/*-bin; do
|
for FILE in tests/cpp_tests/*-bin; do
|
||||||
${FILE} -q -d .;
|
${FILE} -q -d .;
|
||||||
failures=$((failures+$?))
|
failures=$((failures+$?))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ void jpeg_reader<T>::skip(j_decompress_ptr cinfo, long count)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wrap->stream->seekg(count, std::ios_base::cur);
|
wrap->stream->seekg(count - wrap->manager.bytes_in_buffer, std::ios_base::cur);
|
||||||
// trigger buffer fill
|
// trigger buffer fill
|
||||||
wrap->manager.next_input_byte = 0;
|
wrap->manager.next_input_byte = 0;
|
||||||
wrap->manager.bytes_in_buffer = 0; //bytes_in_buffer may be zero on return.
|
wrap->manager.bytes_in_buffer = 0; //bytes_in_buffer may be zero on return.
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
// TODO https://github.com/mapnik/mapnik/issues/1658
|
// TODO https://github.com/mapnik/mapnik/issues/1658
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#if BOOST_VERSION >= 105200
|
#if BOOST_VERSION >= 105200
|
||||||
|
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
#define BOOST_SPIRIT_USE_PHOENIX_V3
|
#define BOOST_SPIRIT_USE_PHOENIX_V3
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/json/feature_collection_parser.hpp>
|
#include <mapnik/json/feature_collection_parser.hpp>
|
||||||
|
|
|
@ -108,7 +108,10 @@ void projection::init_proj4() const
|
||||||
proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str());
|
proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str());
|
||||||
if (!proj_)
|
if (!proj_)
|
||||||
{
|
{
|
||||||
if (proj_ctx_) pj_ctx_free(proj_ctx_);
|
if (proj_ctx_) {
|
||||||
|
pj_ctx_free(proj_ctx_);
|
||||||
|
proj_ctx_ = 0;
|
||||||
|
}
|
||||||
throw proj_init_error(params_);
|
throw proj_init_error(params_);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
// Parse using appropriate flags
|
// Parse using appropriate flags
|
||||||
// https://github.com/mapnik/mapnik/issues/1856
|
// https://github.com/mapnik/mapnik/issues/1856
|
||||||
// const int f_tws = rapidxml::parse_normalize_whitespace;
|
// const int f_tws = rapidxml::parse_normalize_whitespace;
|
||||||
const int f_tws = rapidxml::parse_trim_whitespace;
|
const int f_tws = rapidxml::parse_trim_whitespace | rapidxml::parse_validate_closing_tags;
|
||||||
rapidxml::xml_document<> doc;
|
rapidxml::xml_document<> doc;
|
||||||
doc.parse<f_tws>(&v.front());
|
doc.parse<f_tws>(&v.front());
|
||||||
|
|
||||||
|
@ -143,7 +143,10 @@ private:
|
||||||
case rapidxml::node_data:
|
case rapidxml::node_data:
|
||||||
case rapidxml::node_cdata:
|
case rapidxml::node_cdata:
|
||||||
{
|
{
|
||||||
node.add_child(cur_node->value(), 0, true);
|
if (cur_node->value_size() > 0) // Don't add empty text nodes
|
||||||
|
{
|
||||||
|
node.add_child(cur_node->value(), 0, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
// boost
|
// boost
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/xml_parser.hpp>
|
#include <boost/property_tree/xml_parser.hpp>
|
||||||
|
|
||||||
|
@ -869,7 +870,11 @@ void save_map(Map const & map, std::string const& filename, bool explicit_defaul
|
||||||
{
|
{
|
||||||
ptree pt;
|
ptree pt;
|
||||||
serialize_map(pt,map,explicit_defaults);
|
serialize_map(pt,map,explicit_defaults);
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
write_xml(filename,pt,std::locale(),boost::property_tree::xml_writer_make_settings<ptree::key_type>(' ',4));
|
||||||
|
#else
|
||||||
write_xml(filename,pt,std::locale(),boost::property_tree::xml_writer_make_settings(' ',4));
|
write_xml(filename,pt,std::locale(),boost::property_tree::xml_writer_make_settings(' ',4));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string save_map_to_string(Map const & map, bool explicit_defaults)
|
std::string save_map_to_string(Map const & map, bool explicit_defaults)
|
||||||
|
@ -877,7 +882,11 @@ std::string save_map_to_string(Map const & map, bool explicit_defaults)
|
||||||
ptree pt;
|
ptree pt;
|
||||||
serialize_map(pt,map,explicit_defaults);
|
serialize_map(pt,map,explicit_defaults);
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
|
#if BOOST_VERSION >= 105600
|
||||||
|
write_xml(ss,pt,boost::property_tree::xml_writer_make_settings<ptree::key_type>(' ',4));
|
||||||
|
#else
|
||||||
write_xml(ss,pt,boost::property_tree::xml_writer_make_settings(' ',4));
|
write_xml(ss,pt,boost::property_tree::xml_writer_make_settings(' ',4));
|
||||||
|
#endif
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char** argv)
|
||||||
// NOTE: this is a valid font, but will fail because none are registered
|
// NOTE: this is a valid font, but will fail because none are registered
|
||||||
fontset.add_face_name("DejaVu Sans Book");
|
fontset.add_face_name("DejaVu Sans Book");
|
||||||
m.insert_fontset("fontset", fontset);
|
m.insert_fontset("fontset", fontset);
|
||||||
mapnik::layer lyr("layer");
|
mapnik::layer lyr("myLayerName");
|
||||||
lyr.set_datasource(memory_ds);
|
lyr.set_datasource(memory_ds);
|
||||||
lyr.add_style("style");
|
lyr.add_style("style");
|
||||||
m.addLayer(lyr);
|
m.addLayer(lyr);
|
||||||
|
@ -70,7 +70,7 @@ int main(int argc, char** argv)
|
||||||
mapnik::agg_renderer<mapnik::image_32> ren(m,buf);
|
mapnik::agg_renderer<mapnik::image_32> ren(m,buf);
|
||||||
ren.apply();
|
ren.apply();
|
||||||
} catch (std::exception const& ex) {
|
} catch (std::exception const& ex) {
|
||||||
BOOST_TEST_EQ(std::string(ex.what()),std::string("No valid font face could be loaded for font set: 'fontset'"));
|
BOOST_TEST_EQ(std::string(ex.what()),std::string("myLayerName: No valid font face could be loaded for font set: 'fontset'"));
|
||||||
}
|
}
|
||||||
if (!::boost::detail::test_errors()) {
|
if (!::boost::detail::test_errors()) {
|
||||||
if (quiet) std::clog << "\x1b[1;32m.\x1b[0m";
|
if (quiet) std::clog << "\x1b[1;32m.\x1b[0m";
|
||||||
|
|
15
tests/data/good_maps/empty_text_symbolizer.xml
Normal file
15
tests/data/good_maps/empty_text_symbolizer.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" background-color="steelblue" minimum-version="0.7.2">
|
||||||
|
|
||||||
|
<Style name="labels">
|
||||||
|
<Rule>
|
||||||
|
<TextSymbolizer face-name="DejaVu Sans Book"></TextSymbolizer>
|
||||||
|
<TextSymbolizer face-name="DejaVu Sans Book">''</TextSymbolizer>
|
||||||
|
<TextSymbolizer face-name="DejaVu Sans Book"><![CDATA[]]></TextSymbolizer>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Layer name="point" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||||
|
<StyleName>labels</StyleName>
|
||||||
|
</Layer>
|
||||||
|
|
||||||
|
</Map>
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from nose.tools import *
|
from nose.tools import *
|
||||||
from utilities import execution_path, run_all
|
from utilities import execution_path, run_all, datasources_available
|
||||||
import os, mapnik
|
import os, mapnik
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
|
@ -99,9 +99,10 @@ def test_hit_grid():
|
||||||
""" encode a list of strings with run-length compression """
|
""" encode a list of strings with run-length compression """
|
||||||
return ["%d:%s" % (len(list(group)), name) for name, group in groupby(l)]
|
return ["%d:%s" % (len(list(group)), name) for name, group in groupby(l)]
|
||||||
|
|
||||||
m = mapnik.Map(256,256);
|
xmlfile = '../data/good_maps/agg_poly_gamma_map.xml'
|
||||||
try:
|
if datasources_available(xmlfile):
|
||||||
mapnik.load_map(m,'../data/good_maps/agg_poly_gamma_map.xml');
|
m = mapnik.Map(256, 256)
|
||||||
|
mapnik.load_map(m, xmlfile)
|
||||||
m.zoom_all()
|
m.zoom_all()
|
||||||
join_field = 'NAME'
|
join_field = 'NAME'
|
||||||
fg = [] # feature grid
|
fg = [] # feature grid
|
||||||
|
@ -117,10 +118,6 @@ def test_hit_grid():
|
||||||
hit_list = '|'.join(rle_encode(fg))
|
hit_list = '|'.join(rle_encode(fg))
|
||||||
eq_(hit_list[:16],'730:|2:Greenland')
|
eq_(hit_list[:16],'730:|2:Greenland')
|
||||||
eq_(hit_list[-12:],'1:Chile|812:')
|
eq_(hit_list[-12:],'1:Chile|812:')
|
||||||
except RuntimeError, e:
|
|
||||||
# only test datasources that we have installed
|
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
raise RuntimeError(str(e))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -28,9 +28,9 @@ def test_adding_datasource_to_layer():
|
||||||
|
|
||||||
</Map>
|
</Map>
|
||||||
'''
|
'''
|
||||||
m = mapnik.Map(256, 256)
|
if 'shape' in mapnik.DatasourceCache.plugin_names():
|
||||||
|
m = mapnik.Map(256, 256)
|
||||||
|
|
||||||
try:
|
|
||||||
mapnik.load_map_from_string(m, map_string)
|
mapnik.load_map_from_string(m, map_string)
|
||||||
|
|
||||||
# validate it loaded fine
|
# validate it loaded fine
|
||||||
|
@ -65,10 +65,6 @@ def test_adding_datasource_to_layer():
|
||||||
# test that assignment
|
# test that assignment
|
||||||
eq_(m.layers[0].srs,'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs')
|
eq_(m.layers[0].srs,'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs')
|
||||||
eq_(lyr.srs,'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs')
|
eq_(lyr.srs,'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs')
|
||||||
except RuntimeError, e:
|
|
||||||
# only test datasources that we have installed
|
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
raise RuntimeError(e)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup()
|
setup()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from nose.tools import *
|
from nose.tools import *
|
||||||
from utilities import execution_path, run_all
|
from utilities import execution_path, run_all, datasources_available
|
||||||
|
|
||||||
import os, sys, glob, mapnik
|
import os, sys, glob, mapnik
|
||||||
|
|
||||||
|
@ -30,20 +30,27 @@ def test_broken_files():
|
||||||
mapnik.logger.set_severity(default_logging_severity)
|
mapnik.logger.set_severity(default_logging_severity)
|
||||||
|
|
||||||
def test_good_files():
|
def test_good_files():
|
||||||
good_files = glob.glob("../data/good_maps/*.xml")
|
all_files = glob.glob("../data/good_maps/*.xml")
|
||||||
|
|
||||||
failures = [];
|
good_files = list()
|
||||||
|
for xmlfile in all_files:
|
||||||
|
missing_plugins = set()
|
||||||
|
have_inputs = datasources_available(xmlfile, missing_plugins)
|
||||||
|
if have_inputs:
|
||||||
|
good_files.append(xmlfile)
|
||||||
|
else:
|
||||||
|
print 'Notice: skipping load_map_test for %s due to unavailable input plugins: %s' % (os.path.basename(xmlfile), list(missing_plugins))
|
||||||
|
|
||||||
|
failures = []
|
||||||
|
strict = True
|
||||||
for filename in good_files:
|
for filename in good_files:
|
||||||
try:
|
try:
|
||||||
m = mapnik.Map(512, 512)
|
m = mapnik.Map(512, 512)
|
||||||
strict = True
|
|
||||||
mapnik.load_map(m, filename, strict)
|
mapnik.load_map(m, filename, strict)
|
||||||
base_path = os.path.dirname(filename)
|
base_path = os.path.dirname(filename)
|
||||||
mapnik.load_map_from_string(m,open(filename,'rb').read(),strict,base_path)
|
mapnik.load_map_from_string(m, open(filename, 'rb').read(), strict, base_path)
|
||||||
except RuntimeError, e:
|
except RuntimeError, e:
|
||||||
# only test datasources that we have installed
|
failures.append('Failed to load valid map %s (%s)!' % (filename, str(e)))
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
failures.append('Failed to load valid map (%s)!' % filename)
|
|
||||||
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
eq_(len(failures),0,'\n'+'\n'.join(failures))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -69,8 +69,8 @@ def test_line_symbolizer():
|
||||||
def test_line_symbolizer_stroke_reference():
|
def test_line_symbolizer_stroke_reference():
|
||||||
l = mapnik.LineSymbolizer(mapnik.Color('green'),0.1)
|
l = mapnik.LineSymbolizer(mapnik.Color('green'),0.1)
|
||||||
l.stroke.add_dash(.1,.1)
|
l.stroke.add_dash(.1,.1)
|
||||||
l.stroke.add_dash(.1,.1)
|
l.stroke.add_dash(4,4)
|
||||||
eq_(l.stroke.get_dashes(), [(.1,.1),(.1,.1)])
|
eq_(l.stroke.get_dashes(), [(.1,.1),(4,4)])
|
||||||
eq_(l.stroke.color,mapnik.Color('green'))
|
eq_(l.stroke.color,mapnik.Color('green'))
|
||||||
eq_(l.stroke.opacity,1.0)
|
eq_(l.stroke.opacity,1.0)
|
||||||
assert_almost_equal(l.stroke.width,0.1)
|
assert_almost_equal(l.stroke.width,0.1)
|
||||||
|
@ -88,6 +88,9 @@ def test_stroke_dash_api():
|
||||||
|
|
||||||
def test_text_symbolizer():
|
def test_text_symbolizer():
|
||||||
s = mapnik.TextSymbolizer()
|
s = mapnik.TextSymbolizer()
|
||||||
|
eq_(s.orientation,None)
|
||||||
|
s.orientation = mapnik.Expression('45');
|
||||||
|
eq_(str(s.orientation),str(mapnik.Expression('45')))
|
||||||
eq_(s.comp_op,mapnik.CompositeOp.src_over)
|
eq_(s.comp_op,mapnik.CompositeOp.src_over)
|
||||||
eq_(s.clip,True)
|
eq_(s.clip,True)
|
||||||
eq_(s.halo_rasterizer,mapnik.halo_rasterizer.FULL)
|
eq_(s.halo_rasterizer,mapnik.halo_rasterizer.FULL)
|
||||||
|
@ -375,9 +378,9 @@ def test_map_init_from_string():
|
||||||
</Layer>
|
</Layer>
|
||||||
</Map>'''
|
</Map>'''
|
||||||
|
|
||||||
m = mapnik.Map(600, 300)
|
if 'shape' in mapnik.DatasourceCache.plugin_names():
|
||||||
eq_(m.base, '')
|
m = mapnik.Map(600, 300)
|
||||||
try:
|
eq_(m.base, '')
|
||||||
mapnik.load_map_from_string(m, map_string)
|
mapnik.load_map_from_string(m, map_string)
|
||||||
eq_(m.base, './')
|
eq_(m.base, './')
|
||||||
mapnik.load_map_from_string(m, map_string, False, "") # this "" will have no effect
|
mapnik.load_map_from_string(m, map_string, False, "") # this "" will have no effect
|
||||||
|
@ -392,10 +395,6 @@ def test_map_init_from_string():
|
||||||
m.base = 'foo'
|
m.base = 'foo'
|
||||||
mapnik.load_map_from_string(m, map_string, True, ".")
|
mapnik.load_map_from_string(m, map_string, True, ".")
|
||||||
eq_(m.base, '.')
|
eq_(m.base, '.')
|
||||||
except RuntimeError, e:
|
|
||||||
# only test datasources that we have installed
|
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
raise RuntimeError(e)
|
|
||||||
|
|
||||||
# Color initialization
|
# Color initialization
|
||||||
@raises(Exception) # Boost.Python.ArgumentError
|
@raises(Exception) # Boost.Python.ArgumentError
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from nose.tools import *
|
from nose.tools import *
|
||||||
from utilities import execution_path, run_all, contains_word, get_unique_colors
|
from utilities import execution_path, run_all, contains_word, get_unique_colors,\
|
||||||
|
datasources_available
|
||||||
|
|
||||||
import os, mapnik
|
import os, mapnik
|
||||||
|
|
||||||
|
@ -89,27 +90,22 @@ def test_dataraster_query_point():
|
||||||
assert len(features) == 0
|
assert len(features) == 0
|
||||||
|
|
||||||
def test_load_save_map():
|
def test_load_save_map():
|
||||||
map = mapnik.Map(256,256)
|
m = mapnik.Map(256,256)
|
||||||
in_map = "../data/good_maps/raster_symbolizer.xml"
|
in_map = "../data/good_maps/raster_symbolizer.xml"
|
||||||
try:
|
if datasources_available(in_map):
|
||||||
mapnik.load_map(map, in_map)
|
mapnik.load_map(m, in_map)
|
||||||
|
out_map = mapnik.save_map_to_string(m)
|
||||||
out_map = mapnik.save_map_to_string(map)
|
|
||||||
assert 'RasterSymbolizer' in out_map
|
assert 'RasterSymbolizer' in out_map
|
||||||
assert 'RasterColorizer' in out_map
|
assert 'RasterColorizer' in out_map
|
||||||
assert 'stop' in out_map
|
assert 'stop' in out_map
|
||||||
except RuntimeError, e:
|
|
||||||
# only test datasources that we have installed
|
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
raise RuntimeError(str(e))
|
|
||||||
|
|
||||||
def test_raster_with_alpha_blends_correctly_with_background():
|
def test_raster_with_alpha_blends_correctly_with_background():
|
||||||
WIDTH = 500
|
WIDTH = 500
|
||||||
HEIGHT = 500
|
HEIGHT = 500
|
||||||
|
|
||||||
map = mapnik.Map(WIDTH, HEIGHT)
|
m = mapnik.Map(WIDTH, HEIGHT)
|
||||||
WHITE = mapnik.Color(255, 255, 255)
|
WHITE = mapnik.Color(255, 255, 255)
|
||||||
map.background = WHITE
|
m.background = WHITE
|
||||||
|
|
||||||
style = mapnik.Style()
|
style = mapnik.Style()
|
||||||
rule = mapnik.Rule()
|
rule = mapnik.Rule()
|
||||||
|
@ -119,20 +115,20 @@ def test_raster_with_alpha_blends_correctly_with_background():
|
||||||
rule.symbols.append(symbolizer)
|
rule.symbols.append(symbolizer)
|
||||||
style.rules.append(rule)
|
style.rules.append(rule)
|
||||||
|
|
||||||
map.append_style('raster_style', style)
|
m.append_style('raster_style', style)
|
||||||
|
|
||||||
map_layer = mapnik.Layer('test_layer')
|
map_layer = mapnik.Layer('test_layer')
|
||||||
filepath = '../data/raster/white-alpha.png'
|
filepath = '../data/raster/white-alpha.png'
|
||||||
if 'gdal' in mapnik.DatasourceCache.plugin_names():
|
if 'gdal' in mapnik.DatasourceCache.plugin_names():
|
||||||
map_layer.datasource = mapnik.Gdal(file=filepath)
|
map_layer.datasource = mapnik.Gdal(file=filepath)
|
||||||
map_layer.styles.append('raster_style')
|
map_layer.styles.append('raster_style')
|
||||||
map.layers.append(map_layer)
|
m.layers.append(map_layer)
|
||||||
|
|
||||||
map.zoom_all()
|
m.zoom_all()
|
||||||
|
|
||||||
mim = mapnik.Image(WIDTH, HEIGHT)
|
mim = mapnik.Image(WIDTH, HEIGHT)
|
||||||
|
|
||||||
mapnik.render(map, mim)
|
mapnik.render(m, mim)
|
||||||
imdata = mim.tostring()
|
imdata = mim.tostring()
|
||||||
# All white is expected
|
# All white is expected
|
||||||
eq_(get_unique_colors(mim),['rgba(254,254,254,255)'])
|
eq_(get_unique_colors(mim),['rgba(254,254,254,255)'])
|
||||||
|
|
|
@ -5,7 +5,7 @@ from nose.tools import *
|
||||||
import tempfile
|
import tempfile
|
||||||
import os, mapnik
|
import os, mapnik
|
||||||
from nose.tools import *
|
from nose.tools import *
|
||||||
from utilities import execution_path, run_all
|
from utilities import execution_path, run_all, datasources_available
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
# All of the paths used are relative, if we run the tests
|
# All of the paths used are relative, if we run the tests
|
||||||
|
@ -104,16 +104,15 @@ def get_paired_images(w,h,mapfile):
|
||||||
return im,im2
|
return im,im2
|
||||||
|
|
||||||
def test_render_from_serialization():
|
def test_render_from_serialization():
|
||||||
try:
|
xmlfile = '../data/good_maps/building_symbolizer.xml'
|
||||||
im,im2 = get_paired_images(100,100,'../data/good_maps/building_symbolizer.xml')
|
if datasources_available(xmlfile):
|
||||||
eq_(im.tostring(),im2.tostring())
|
im, im2 = get_paired_images(100, 100, xmlfile)
|
||||||
|
eq_(im.tostring(), im2.tostring())
|
||||||
|
|
||||||
im,im2 = get_paired_images(100,100,'../data/good_maps/polygon_symbolizer.xml')
|
xmlfile = '../data/good_maps/polygon_symbolizer.xml'
|
||||||
eq_(im.tostring(),im2.tostring())
|
if datasources_available(xmlfile):
|
||||||
except RuntimeError, e:
|
im, im2 = get_paired_images(100, 100, xmlfile)
|
||||||
# only test datasources that we have installed
|
eq_(im.tostring(), im2.tostring())
|
||||||
if not 'Could not create datasource' in str(e):
|
|
||||||
raise RuntimeError(e)
|
|
||||||
|
|
||||||
def test_render_points():
|
def test_render_points():
|
||||||
if not mapnik.has_cairo(): return
|
if not mapnik.has_cairo(): return
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from nose.tools import *
|
from nose.tools import *
|
||||||
from utilities import execution_path, run_all
|
from utilities import execution_path, run_all, datasources_available
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
import os, sys, glob, mapnik
|
import os, sys, glob, mapnik
|
||||||
|
@ -11,10 +11,16 @@ def setup():
|
||||||
# from another directory we need to chdir()
|
# from another directory we need to chdir()
|
||||||
os.chdir(execution_path('.'))
|
os.chdir(execution_path('.'))
|
||||||
|
|
||||||
def compare_map(xml):
|
def compare_map(xmlfile):
|
||||||
|
missing_plugins = set()
|
||||||
|
have_inputs = datasources_available(xmlfile, missing_plugins)
|
||||||
|
if not have_inputs:
|
||||||
|
print 'Notice: skipping map comparison for %s due to unavailable input plugins: %s' % (os.path.basename(xmlfile), list(missing_plugins))
|
||||||
|
return False
|
||||||
|
|
||||||
m = mapnik.Map(256, 256)
|
m = mapnik.Map(256, 256)
|
||||||
absolute_base = os.path.abspath(os.path.dirname(xml))
|
absolute_base = os.path.abspath(os.path.dirname(xmlfile))
|
||||||
mapnik.load_map(m, xml, False, absolute_base)
|
mapnik.load_map(m, xmlfile, False, absolute_base)
|
||||||
(handle, test_map) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map1-')
|
(handle, test_map) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map1-')
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
(handle, test_map2) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map2-')
|
(handle, test_map2) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map2-')
|
||||||
|
@ -23,13 +29,13 @@ def compare_map(xml):
|
||||||
os.remove(test_map)
|
os.remove(test_map)
|
||||||
mapnik.save_map(m, test_map)
|
mapnik.save_map(m, test_map)
|
||||||
new_map = mapnik.Map(256, 256)
|
new_map = mapnik.Map(256, 256)
|
||||||
mapnik.load_map(new_map, test_map,False,absolute_base)
|
mapnik.load_map(new_map, test_map, False, absolute_base)
|
||||||
open(test_map2,'w').write(mapnik.save_map_to_string(new_map))
|
open(test_map2, 'w').write(mapnik.save_map_to_string(new_map))
|
||||||
diff = ' diff %s %s' % (os.path.abspath(test_map),os.path.abspath(test_map2))
|
diff = ' diff %s %s' % (os.path.abspath(test_map), os.path.abspath(test_map2))
|
||||||
try:
|
try:
|
||||||
eq_(open(test_map).read(),open(test_map2).read())
|
eq_(open(test_map).read(), open(test_map2).read())
|
||||||
except AssertionError, e:
|
except AssertionError, e:
|
||||||
raise AssertionError('serialized map "%s" not the same after being reloaded, \ncompare with command:\n\n$%s' % (xml,diff))
|
raise AssertionError('serialized map "%s" not the same after being reloaded, \ncompare with command:\n\n$%s' % (xmlfile, diff))
|
||||||
|
|
||||||
if os.path.exists(test_map):
|
if os.path.exists(test_map):
|
||||||
os.remove(test_map)
|
os.remove(test_map)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
|
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
|
||||||
|
|
||||||
import os, sys, inspect, traceback
|
import os, sys, inspect, traceback
|
||||||
|
from xml.etree import ElementTree
|
||||||
import mapnik
|
import mapnik
|
||||||
|
|
||||||
def execution_path(filename):
|
def execution_path(filename):
|
||||||
|
@ -54,7 +55,7 @@ def get_unique_colors(im):
|
||||||
for y in range(im.height()):
|
for y in range(im.height()):
|
||||||
pixel = im.get_pixel(x,y)
|
pixel = im.get_pixel(x,y)
|
||||||
if pixel not in pixels:
|
if pixel not in pixels:
|
||||||
pixels.append(pixel)
|
pixels.append(pixel)
|
||||||
pixels = sorted(pixels)
|
pixels = sorted(pixels)
|
||||||
return map(pixel2rgba,pixels)
|
return map(pixel2rgba,pixels)
|
||||||
|
|
||||||
|
@ -86,3 +87,33 @@ def side_by_side_image(left_im, right_im):
|
||||||
im.blend(0, 0, left_im, 1.0)
|
im.blend(0, 0, left_im, 1.0)
|
||||||
im.blend(left_im.width() + 1, 0, right_im, 1.0)
|
im.blend(left_im.width() + 1, 0, right_im, 1.0)
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
def datasources_available(map_file, missing_datasources=None):
|
||||||
|
'''
|
||||||
|
datasources_available
|
||||||
|
|
||||||
|
Determine whether the map file contains only available data source types.
|
||||||
|
|
||||||
|
@param map_file: path of XML map file
|
||||||
|
@type map_file: string
|
||||||
|
|
||||||
|
@param missing_datasources: set of data source type names. if there
|
||||||
|
are unavailable data sources, and a collection
|
||||||
|
reference is provided, it will be populated with
|
||||||
|
the names of the unavailable data sources
|
||||||
|
@type missing_datasources: set
|
||||||
|
|
||||||
|
@return: True if all referenced data source types are available,
|
||||||
|
otherwise False
|
||||||
|
'''
|
||||||
|
have_inputs = True
|
||||||
|
map_xml = ElementTree.parse(map_file)
|
||||||
|
data_source_type_params = map_xml.findall(".//Datasource/Parameter[@name=\"type\"]")
|
||||||
|
if data_source_type_params is not None and len(data_source_type_params) > 0:
|
||||||
|
for p in data_source_type_params:
|
||||||
|
dstype = p.text
|
||||||
|
if dstype not in mapnik.DatasourceCache.plugin_names():
|
||||||
|
have_inputs = False
|
||||||
|
if missing_datasources is not None:
|
||||||
|
missing_datasources.add(dstype)
|
||||||
|
return have_inputs
|
||||||
|
|
Loading…
Reference in a new issue