Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
85e00d6596
26 changed files with 270 additions and 234 deletions
|
@ -8,6 +8,8 @@ For a complete change history, see the git log.
|
|||
|
||||
## Future
|
||||
|
||||
- Added serialization of `line-offset` to save_map (#1562)
|
||||
|
||||
- Enabled default input plugin directory and fonts path to be set inherited from environment settings in
|
||||
python bindings to make it easier to run tests locally (#1594). New environment settings are:
|
||||
- MAPNIK_INPUT_PLUGINS_DIRECTORY
|
||||
|
|
2
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
2
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
|
@ -29,6 +29,7 @@ namespace agg
|
|||
|
||||
void rewind(unsigned) {}
|
||||
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
||||
unsigned type() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,6 +65,7 @@ namespace agg
|
|||
}
|
||||
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
private:
|
||||
// Prohibit copying
|
||||
|
|
1
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
1
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
|
@ -33,6 +33,7 @@ namespace agg
|
|||
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned type() const { return m_source->type(); }
|
||||
|
||||
private:
|
||||
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
|
||||
|
|
1
deps/agg/include/agg_conv_clip_polygon.h
vendored
1
deps/agg/include/agg_conv_clip_polygon.h
vendored
|
@ -51,6 +51,7 @@ namespace agg
|
|||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
|
||||
private:
|
||||
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
||||
|
|
1
deps/agg/include/agg_conv_clip_polyline.h
vendored
1
deps/agg/include/agg_conv_clip_polyline.h
vendored
|
@ -51,6 +51,7 @@ namespace agg
|
|||
double y1() const { return base_type::vpgen().y1(); }
|
||||
double x2() const { return base_type::vpgen().x2(); }
|
||||
double y2() const { return base_type::vpgen().y2(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
|
||||
private:
|
||||
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
||||
|
|
2
deps/agg/include/agg_conv_smooth_poly1.h
vendored
2
deps/agg/include/agg_conv_smooth_poly1.h
vendored
|
@ -42,6 +42,7 @@ namespace agg
|
|||
|
||||
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
||||
double smooth_value() const { return base_type::generator().smooth_value(); }
|
||||
unsigned type() const { return base_type::type(); }
|
||||
|
||||
private:
|
||||
conv_smooth_poly1(const conv_smooth_poly1<VertexSource>&);
|
||||
|
@ -64,6 +65,7 @@ namespace agg
|
|||
|
||||
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
||||
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
||||
unsigned type() const { return m_smooth.type(); }
|
||||
|
||||
private:
|
||||
conv_smooth_poly1_curve(const conv_smooth_poly1_curve<VertexSource>&);
|
||||
|
|
|
@ -6,8 +6,8 @@ Import('env')
|
|||
base = './mapnik/'
|
||||
subdirs = ['','svg','wkt','grid','json','util','text_placements','formatting']
|
||||
|
||||
#if env['SVG_RENDERER']:
|
||||
# subdirs.append('svg/output')
|
||||
if env['SVG_RENDERER']:
|
||||
subdirs.append('svg/output')
|
||||
|
||||
if 'install' in COMMAND_LINE_TARGETS:
|
||||
for subdir in subdirs:
|
||||
|
|
|
@ -100,6 +100,11 @@ struct MAPNIK_DECL coord_transform
|
|||
geom_.rewind(pos);
|
||||
}
|
||||
|
||||
unsigned type() const
|
||||
{
|
||||
return static_cast<unsigned>(geom_.type());
|
||||
}
|
||||
|
||||
Geometry const& geom() const
|
||||
{
|
||||
return geom_;
|
||||
|
|
|
@ -427,7 +427,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
featureset_ptr features = ds->features(q);
|
||||
if (features) {
|
||||
// Cache all features into the memory_datasource before rendering.
|
||||
memory_datasource cache;
|
||||
memory_datasource cache(ds->type(),false);
|
||||
feature_ptr feature, prev;
|
||||
|
||||
while ((feature = features->next()))
|
||||
|
@ -458,7 +458,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
}
|
||||
else if (cache_features)
|
||||
{
|
||||
memory_datasource cache(ds->type());
|
||||
memory_datasource cache(ds->type(),false);
|
||||
featureset_ptr features = ds->features(q);
|
||||
if (features) {
|
||||
// Cache all features into the memory_datasource before rendering.
|
||||
|
|
|
@ -91,7 +91,12 @@ struct vector_markers_rasterizer_dispatch
|
|||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
if (path.type() == LineString)
|
||||
{
|
||||
if (!label::middle_point(path, x, y))
|
||||
return;
|
||||
}
|
||||
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
{
|
||||
if (!label::interior_position(path, x, y))
|
||||
return;
|
||||
|
@ -187,7 +192,12 @@ struct raster_markers_rasterizer_dispatch
|
|||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
if (path.type() == LineString)
|
||||
{
|
||||
if (!label::middle_point(path, x, y))
|
||||
return;
|
||||
}
|
||||
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
{
|
||||
if (!label::interior_position(path, x, y))
|
||||
return;
|
||||
|
|
|
@ -36,7 +36,7 @@ class MAPNIK_DECL memory_datasource : public datasource
|
|||
{
|
||||
friend class memory_featureset;
|
||||
public:
|
||||
memory_datasource(datasource::datasource_t type=datasource::Vector);
|
||||
memory_datasource(datasource::datasource_t type=datasource::Vector, bool bbox_check=true);
|
||||
virtual ~memory_datasource();
|
||||
void push(feature_ptr feature);
|
||||
datasource::datasource_t type() const;
|
||||
|
@ -51,6 +51,7 @@ private:
|
|||
std::vector<feature_ptr> features_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
datasource::datasource_t type_;
|
||||
bool bbox_check_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -34,18 +34,20 @@ namespace mapnik {
|
|||
class memory_featureset : public Featureset
|
||||
{
|
||||
public:
|
||||
memory_featureset(box2d<double> const& bbox, memory_datasource const& ds)
|
||||
memory_featureset(box2d<double> const& bbox, memory_datasource const& ds, bool bbox_check = true)
|
||||
: bbox_(bbox),
|
||||
pos_(ds.features_.begin()),
|
||||
end_(ds.features_.end()),
|
||||
type_(ds.type())
|
||||
type_(ds.type()),
|
||||
bbox_check_(bbox_check)
|
||||
{}
|
||||
|
||||
memory_featureset(box2d<double> const& bbox, std::vector<feature_ptr> const& features)
|
||||
memory_featureset(box2d<double> const& bbox, std::vector<feature_ptr> const& features, bool bbox_check = true)
|
||||
: bbox_(bbox),
|
||||
pos_(features.begin()),
|
||||
end_(features.end()),
|
||||
type_(datasource::Vector)
|
||||
type_(datasource::Vector),
|
||||
bbox_check_(bbox_check)
|
||||
{}
|
||||
|
||||
virtual ~memory_featureset() {}
|
||||
|
@ -54,22 +56,33 @@ public:
|
|||
{
|
||||
while (pos_ != end_)
|
||||
{
|
||||
if (type_ == datasource::Raster)
|
||||
if (!bbox_check_)
|
||||
{
|
||||
return *pos_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i=0; i<(*pos_)->num_geometries();++i)
|
||||
if (type_ == datasource::Raster)
|
||||
{
|
||||
geometry_type & geom = (*pos_)->get_geometry(i);
|
||||
if (bbox_.intersects(geom.envelope()))
|
||||
raster_ptr const& source = (*pos_)->get_raster();
|
||||
if (source && bbox_.intersects(source->ext_))
|
||||
{
|
||||
return *pos_++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned i=0; i<(*pos_)->num_geometries();++i)
|
||||
{
|
||||
geometry_type & geom = (*pos_)->get_geometry(i);
|
||||
if (bbox_.intersects(geom.envelope()))
|
||||
{
|
||||
return *pos_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
++pos_;
|
||||
}
|
||||
++pos_;
|
||||
}
|
||||
return feature_ptr();
|
||||
}
|
||||
|
@ -79,6 +92,7 @@ private:
|
|||
std::vector<feature_ptr>::const_iterator pos_;
|
||||
std::vector<feature_ptr>::const_iterator end_;
|
||||
datasource::datasource_t type_;
|
||||
bool bbox_check_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/util/geometry_svg_generator.hpp>
|
||||
#include <mapnik/svg/output/svg_output_grammars.hpp>
|
||||
#include <mapnik/svg/output/svg_output_attributes.hpp>
|
||||
|
||||
|
@ -44,11 +45,8 @@ namespace mapnik { namespace svg {
|
|||
template <typename OutputIterator>
|
||||
class svg_generator : private boost::noncopyable
|
||||
{
|
||||
typedef coord_transform<CoordTransform, geometry_type> path_type;
|
||||
|
||||
typedef svg::svg_root_attributes_grammar<OutputIterator> root_attributes_grammar;
|
||||
typedef svg::svg_rect_attributes_grammar<OutputIterator> rect_attributes_grammar;
|
||||
//typedef svg::svg_path_data_grammar<OutputIterator, path_type> path_data_grammar;
|
||||
typedef svg::svg_path_attributes_grammar<OutputIterator> path_attributes_grammar;
|
||||
typedef svg::svg_path_dash_array_grammar<OutputIterator> path_dash_array_grammar;
|
||||
|
||||
|
@ -60,7 +58,16 @@ namespace mapnik { namespace svg {
|
|||
void generate_opening_root(root_output_attributes const& root_attributes);
|
||||
void generate_closing_root();
|
||||
void generate_rect(rect_output_attributes const& rect_attributes);
|
||||
//void generate_path(path_type const& path, path_output_attributes const& path_attributes);
|
||||
template <typename PathType>
|
||||
void generate_path(PathType const& path, path_output_attributes const& path_attributes)
|
||||
{
|
||||
util::svg_generator<OutputIterator,PathType> svg_path_grammer;
|
||||
karma::generate(output_iterator_, lit("<path ") << svg_path_grammer, path);
|
||||
path_attributes_grammar attributes_grammar;
|
||||
path_dash_array_grammar dash_array_grammar;
|
||||
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
|
||||
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
|
||||
}
|
||||
|
||||
private:
|
||||
OutputIterator& output_iterator_;
|
||||
|
|
|
@ -87,88 +87,11 @@ BOOST_FUSION_ADAPT_STRUCT(
|
|||
(std::string, svg_namespace_url_)
|
||||
)
|
||||
|
||||
/*!
|
||||
* mapnik::geometry_type is adapted to conform to the concepts
|
||||
* required by Karma to be recognized as a container of
|
||||
* attributes for output generation.
|
||||
*/
|
||||
/*
|
||||
namespace boost { namespace spirit { namespace traits {
|
||||
|
||||
typedef mapnik::coord_transform<mapnik::CoordTransform, mapnik::geometry_type> path_type;
|
||||
|
||||
template <>
|
||||
struct is_container<path_type const>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct container_iterator<path_type const>
|
||||
{
|
||||
typedef mapnik::svg::path_iterator_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_container<path_type const>
|
||||
{
|
||||
static mapnik::svg::path_iterator_type
|
||||
call(path_type const& path)
|
||||
{
|
||||
return mapnik::svg::path_iterator_type(0, path);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_container<path_type const>
|
||||
{
|
||||
static mapnik::svg::path_iterator_type
|
||||
call(path_type const& path)
|
||||
{
|
||||
return mapnik::svg::path_iterator_type(path);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
*/
|
||||
|
||||
namespace mapnik { namespace svg {
|
||||
|
||||
using namespace boost::spirit;
|
||||
using namespace boost::phoenix;
|
||||
|
||||
/*
|
||||
template <typename OutputIterator, typename PathType>
|
||||
struct svg_path_data_grammar : karma::grammar<OutputIterator, PathType&()>
|
||||
{
|
||||
typedef path_iterator_type::value_type vertex_type;
|
||||
|
||||
explicit svg_path_data_grammar(PathType const& path_type)
|
||||
: svg_path_data_grammar::base_type(svg_path),
|
||||
path_type_(path_type)
|
||||
{
|
||||
using karma::int_;
|
||||
using karma::double_;
|
||||
using repository::confix;
|
||||
|
||||
svg_path =
|
||||
lit("d=")
|
||||
<< confix('"', '"')[
|
||||
-(path_vertex % lit(' '))];
|
||||
|
||||
path_vertex =
|
||||
path_vertex_command
|
||||
<< double_
|
||||
<< lit(' ')
|
||||
<< double_;
|
||||
|
||||
path_vertex_command = &int_(1) << lit('M') | lit('L');
|
||||
}
|
||||
|
||||
karma::rule<OutputIterator, PathType&()> svg_path;
|
||||
karma::rule<OutputIterator, vertex_type()> path_vertex;
|
||||
karma::rule<OutputIterator, int()> path_vertex_command;
|
||||
|
||||
PathType const& path_type_;
|
||||
};
|
||||
*/
|
||||
|
||||
template <typename OutputIterator>
|
||||
struct svg_path_attributes_grammar : karma::grammar<OutputIterator, mapnik::svg::path_output_attributes()>
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry.hpp> // for container stuff
|
||||
#include <mapnik/ctrans.hpp> // for container stuff
|
||||
#include <mapnik/util/path_iterator.hpp>
|
||||
#include <mapnik/util/container_adapter.hpp>
|
||||
|
||||
|
@ -38,35 +39,84 @@
|
|||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#include <boost/spirit/home/phoenix/statement/if.hpp>
|
||||
#include <boost/fusion/include/boost_tuple.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
|
||||
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
||||
|
||||
/*!
|
||||
* adapted to conform to the concepts
|
||||
* required by Karma to be recognized as a container of
|
||||
* attributes for output generation.
|
||||
*/
|
||||
namespace boost { namespace spirit { namespace traits {
|
||||
|
||||
// TODO - this needs to be made generic to any path type
|
||||
typedef mapnik::coord_transform<mapnik::CoordTransform, mapnik::geometry_type> path_type;
|
||||
|
||||
template <>
|
||||
struct is_container<path_type const> : mpl::true_ {} ;
|
||||
|
||||
template <>
|
||||
struct container_iterator<path_type const>
|
||||
{
|
||||
typedef mapnik::util::path_iterator<path_type> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_container<path_type const>
|
||||
{
|
||||
static mapnik::util::path_iterator<path_type>
|
||||
call (path_type const& g)
|
||||
{
|
||||
return mapnik::util::path_iterator<path_type>(g);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_container<path_type const>
|
||||
{
|
||||
static mapnik::util::path_iterator<path_type>
|
||||
call (path_type const& g)
|
||||
{
|
||||
return mapnik::util::path_iterator<path_type>();
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
namespace karma = boost::spirit::karma;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
namespace svg_detail {
|
||||
|
||||
template <typename Geometry>
|
||||
struct get_type
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef int type; };
|
||||
|
||||
int operator() (geometry_type const& geom) const
|
||||
int operator() (Geometry const& geom) const
|
||||
{
|
||||
return (int)geom.type();
|
||||
return static_cast<int>(geom.type());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_first
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef geometry_type::value_type const type; };
|
||||
typedef T geometry_type;
|
||||
|
||||
geometry_type::value_type const operator() (geometry_type const& geom) const
|
||||
template <typename U>
|
||||
struct result { typedef typename geometry_type::value_type const type; };
|
||||
|
||||
typename geometry_type::value_type const 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));
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
@ -80,11 +130,14 @@ namespace mapnik { namespace util {
|
|||
};
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
template <typename OutputIterator, typename Geometry>
|
||||
struct svg_generator :
|
||||
karma::grammar<OutputIterator, geometry_type const& ()>
|
||||
karma::grammar<OutputIterator, Geometry const& ()>
|
||||
{
|
||||
|
||||
typedef Geometry geometry_type;
|
||||
typedef typename boost::remove_pointer<typename geometry_type::value_type>::type coord_type;
|
||||
|
||||
svg_generator()
|
||||
: svg_generator::base_type(svg)
|
||||
{
|
||||
|
@ -102,22 +155,22 @@ namespace mapnik { namespace util {
|
|||
;
|
||||
|
||||
svg_point = &uint_
|
||||
<< lit("cx=\"") << coord_type
|
||||
<< lit("\" cy=\"") << coord_type
|
||||
<< lit("cx=\"") << coordinate
|
||||
<< lit("\" cy=\"") << coordinate
|
||||
<< lit('\"')
|
||||
;
|
||||
|
||||
linestring = &uint_(mapnik::LineString)[_1 = _type(_val)]
|
||||
<< svg_path
|
||||
<< svg_path << lit('\"')
|
||||
;
|
||||
|
||||
polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)]
|
||||
<< svg_path
|
||||
<< svg_path << lit('\"')
|
||||
;
|
||||
|
||||
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit('M')
|
||||
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit("d=\"") << lit('M')
|
||||
| &uint_(mapnik::SEG_LINETO) [_a +=1] << karma::string [if_(_a == 1) [_1 = "L" ] ])
|
||||
<< lit(' ') << coord_type << lit(' ') << coord_type) % lit(' ')
|
||||
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
|
||||
;
|
||||
|
||||
|
||||
|
@ -129,14 +182,14 @@ namespace mapnik { namespace util {
|
|||
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
||||
|
||||
karma::rule<OutputIterator, geometry_type::value_type ()> svg_point;
|
||||
karma::rule<OutputIterator, coord_type ()> svg_point;
|
||||
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> svg_path;
|
||||
|
||||
// phoenix functions
|
||||
phoenix::function<svg_detail::get_type > _type;
|
||||
phoenix::function<svg_detail::get_first> _first;
|
||||
phoenix::function<svg_detail::get_type<geometry_type> > _type;
|
||||
phoenix::function<svg_detail::get_first<geometry_type> > _first;
|
||||
//
|
||||
karma::real_generator<double, svg_detail::coordinate_policy<double> > coord_type;
|
||||
karma::real_generator<double, svg_detail::coordinate_policy<double> > coordinate;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ bool to_svg(std::string & svg, mapnik::geometry_type const& geom)
|
|||
{
|
||||
typedef std::back_insert_iterator<std::string> sink_type;
|
||||
sink_type sink(svg);
|
||||
svg_generator<sink_type> generator;
|
||||
svg_generator<sink_type, mapnik::geometry_type> generator;
|
||||
bool result = karma::generate(sink, generator, geom);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
#include <boost/thread/mutex.hpp>
|
||||
//using boost::mutex;
|
||||
#endif
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
@ -115,9 +111,6 @@ public:
|
|||
|
||||
bool registerPool(const ConnectionCreator<Connection>& creator,unsigned initialSize,unsigned maxSize)
|
||||
{
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
//mutex::scoped_lock lock(mutex_);
|
||||
#endif
|
||||
ContType::const_iterator itr = pools_.find(creator.id());
|
||||
|
||||
if (itr != pools_.end())
|
||||
|
@ -137,9 +130,6 @@ public:
|
|||
|
||||
boost::shared_ptr<PoolType> getPool(std::string const& key)
|
||||
{
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
//mutex::scoped_lock lock(mutex_);
|
||||
#endif
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
if (itr!=pools_.end())
|
||||
{
|
||||
|
@ -149,19 +139,6 @@ public:
|
|||
return emptyPool;
|
||||
}
|
||||
|
||||
HolderType get(std::string const& key)
|
||||
{
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
//mutex::scoped_lock lock(mutex_);
|
||||
#endif
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
if (itr!=pools_.end())
|
||||
{
|
||||
boost::shared_ptr<PoolType> pool=itr->second;
|
||||
return pool->borrowObject();
|
||||
}
|
||||
return HolderType();
|
||||
}
|
||||
ConnectionManager() {}
|
||||
private:
|
||||
ConnectionManager(const ConnectionManager&);
|
||||
|
|
|
@ -160,46 +160,49 @@ void postgis_datasource::bind() const
|
|||
#ifdef MAPNIK_STATS
|
||||
mapnik::progress_timer __stats2__(std::clog, "postgis_datasource::bind(get_srid_and_geometry_column)");
|
||||
#endif
|
||||
|
||||
std::ostringstream s;
|
||||
s << "SELECT f_geometry_column, srid FROM "
|
||||
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||
<< "'";
|
||||
|
||||
if (! schema_.empty())
|
||||
try
|
||||
{
|
||||
s << " AND f_table_schema='"
|
||||
<< mapnik::sql_utils::unquote_double(schema_)
|
||||
s << "SELECT f_geometry_column, srid FROM "
|
||||
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||
<< "'";
|
||||
}
|
||||
|
||||
if (! geometry_field_.empty())
|
||||
{
|
||||
s << " AND f_geometry_column='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||
<< "'";
|
||||
}
|
||||
|
||||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
geometryColumn_ = rs->getValue("f_geometry_column");
|
||||
|
||||
if (srid_ == 0)
|
||||
if (! schema_.empty())
|
||||
{
|
||||
const char* srid_c = rs->getValue("srid");
|
||||
if (srid_c != NULL)
|
||||
s << " AND f_table_schema='"
|
||||
<< mapnik::sql_utils::unquote_double(schema_)
|
||||
<< "'";
|
||||
}
|
||||
if (! geometry_field_.empty())
|
||||
{
|
||||
s << " AND f_geometry_column='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||
<< "'";
|
||||
}
|
||||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
geometryColumn_ = rs->getValue("f_geometry_column");
|
||||
if (srid_ == 0)
|
||||
{
|
||||
int result = 0;
|
||||
if (mapnik::util::string2int(srid_c, result))
|
||||
const char* srid_c = rs->getValue("srid");
|
||||
if (srid_c != NULL)
|
||||
{
|
||||
srid_ = result;
|
||||
int result = 0;
|
||||
if (mapnik::util::string2int(srid_c, result))
|
||||
{
|
||||
srid_ = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rs->close();
|
||||
}
|
||||
catch (mapnik::datasource_exception const& ex) {
|
||||
// let this pass on query error and use the fallback below
|
||||
MAPNIK_LOG_WARN(postgis) << "postgis_datasource: metadata query failed: " << ex.what();
|
||||
}
|
||||
rs->close();
|
||||
|
||||
// If we still do not know the srid then we can try to fetch
|
||||
// it from the 'table_' parameter, which should work even if it is
|
||||
|
@ -711,7 +714,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
}
|
||||
else
|
||||
{
|
||||
err_msg += "Null connection";
|
||||
err_msg += " Null connection";
|
||||
}
|
||||
throw mapnik::datasource_exception(err_msg);
|
||||
}
|
||||
|
@ -929,50 +932,53 @@ boost::optional<mapnik::datasource::geometry_t> postgis_datasource::get_geometry
|
|||
|
||||
std::ostringstream s;
|
||||
std::string g_type;
|
||||
|
||||
s << "SELECT lower(type) as type FROM "
|
||||
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||
<< "'";
|
||||
|
||||
if (! schema_.empty())
|
||||
try
|
||||
{
|
||||
s << " AND f_table_schema='"
|
||||
<< mapnik::sql_utils::unquote_double(schema_)
|
||||
s << "SELECT lower(type) as type FROM "
|
||||
<< GEOMETRY_COLUMNS <<" WHERE f_table_name='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_table_)
|
||||
<< "'";
|
||||
if (! schema_.empty())
|
||||
{
|
||||
s << " AND f_table_schema='"
|
||||
<< mapnik::sql_utils::unquote_double(schema_)
|
||||
<< "'";
|
||||
}
|
||||
if (! geometry_field_.empty())
|
||||
{
|
||||
s << " AND f_geometry_column='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||
<< "'";
|
||||
}
|
||||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
g_type = rs->getValue("type");
|
||||
if (boost::algorithm::contains(g_type, "line"))
|
||||
{
|
||||
result.reset(mapnik::datasource::LineString);
|
||||
return result;
|
||||
}
|
||||
else if (boost::algorithm::contains(g_type, "point"))
|
||||
{
|
||||
result.reset(mapnik::datasource::Point);
|
||||
return result;
|
||||
}
|
||||
else if (boost::algorithm::contains(g_type, "polygon"))
|
||||
{
|
||||
result.reset(mapnik::datasource::Polygon);
|
||||
return result;
|
||||
}
|
||||
else // geometry
|
||||
{
|
||||
result.reset(mapnik::datasource::Collection);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! geometry_field_.empty())
|
||||
{
|
||||
s << " AND f_geometry_column='"
|
||||
<< mapnik::sql_utils::unquote_double(geometry_field_)
|
||||
<< "'";
|
||||
}
|
||||
|
||||
shared_ptr<ResultSet> rs = conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
g_type = rs->getValue("type");
|
||||
if (boost::algorithm::contains(g_type, "line"))
|
||||
{
|
||||
result.reset(mapnik::datasource::LineString);
|
||||
return result;
|
||||
}
|
||||
else if (boost::algorithm::contains(g_type, "point"))
|
||||
{
|
||||
result.reset(mapnik::datasource::Point);
|
||||
return result;
|
||||
}
|
||||
else if (boost::algorithm::contains(g_type, "polygon"))
|
||||
{
|
||||
result.reset(mapnik::datasource::Polygon);
|
||||
return result;
|
||||
}
|
||||
else // geometry
|
||||
{
|
||||
result.reset(mapnik::datasource::Collection);
|
||||
return result;
|
||||
}
|
||||
catch (mapnik::datasource_exception const& ex) {
|
||||
// let this pass on query error and use the fallback below
|
||||
MAPNIK_LOG_WARN(postgis) << "postgis_datasource: metadata query failed: " << ex.what();
|
||||
}
|
||||
|
||||
// fallback to querying first several features
|
||||
|
|
|
@ -57,7 +57,7 @@ shape_featureset<filterT>::shape_featureset(filterT const& filter,
|
|||
template <typename filterT>
|
||||
feature_ptr shape_featureset<filterT>::next()
|
||||
{
|
||||
if (row_limit_ && count_ > row_limit_)
|
||||
if (row_limit_ && count_ >= row_limit_)
|
||||
{
|
||||
return feature_ptr();
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
|
|||
template <typename filterT>
|
||||
feature_ptr shape_index_featureset<filterT>::next()
|
||||
{
|
||||
if (row_limit_ && count_ > row_limit_)
|
||||
if (row_limit_ && count_ >= row_limit_)
|
||||
{
|
||||
return feature_ptr();
|
||||
}
|
||||
|
|
|
@ -62,10 +62,11 @@ struct accumulate_extent
|
|||
bool first_;
|
||||
};
|
||||
|
||||
memory_datasource::memory_datasource(datasource::datasource_t type)
|
||||
memory_datasource::memory_datasource(datasource::datasource_t type, bool bbox_check)
|
||||
: datasource(parameters()),
|
||||
desc_("in-memory datasource","utf-8"),
|
||||
type_(type) {}
|
||||
type_(type),
|
||||
bbox_check_(bbox_check) {}
|
||||
|
||||
memory_datasource::~memory_datasource() {}
|
||||
|
||||
|
@ -83,7 +84,7 @@ datasource::datasource_t memory_datasource::type() const
|
|||
|
||||
featureset_ptr memory_datasource::features(const query& q) const
|
||||
{
|
||||
return boost::make_shared<memory_featureset>(q.get_bbox(),*this);
|
||||
return boost::make_shared<memory_featureset>(q.get_bbox(),*this,bbox_check_);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -98,6 +98,10 @@ public:
|
|||
{
|
||||
set_attr( sym_node, "rasterizer", sym.get_rasterizer() );
|
||||
}
|
||||
if ( sym.offset() != dfl.offset() || explicit_defaults_ )
|
||||
{
|
||||
set_attr( sym_node, "offset", sym.offset() );
|
||||
}
|
||||
serialize_symbolizer_base(sym_node, sym);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
|
|||
// generate path output for each geometry of the current feature.
|
||||
for(unsigned i=0; i<feature.num_geometries(); ++i)
|
||||
{
|
||||
geometry_type const& geom = feature.get_geometry(i);
|
||||
if(geom.size() > 1)
|
||||
geometry_type & geom = feature.get_geometry(i);
|
||||
if(geom.size() > 0)
|
||||
{
|
||||
//path_type path(t_, geom, prj_trans);
|
||||
//generator_.generate_path(path, path_attributes_);
|
||||
path_type path(t_, geom, prj_trans);
|
||||
generator_.generate_path(path, path_attributes_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,17 +65,5 @@ namespace mapnik { namespace svg {
|
|||
karma::generate(output_iterator_, lit("<rect ") << attributes_grammar << lit("/>\n"), rect_attributes);
|
||||
}
|
||||
|
||||
/*template <typename OutputIterator>
|
||||
void svg_generator<OutputIterator>::generate_path(path_type const& path, path_output_attributes const& path_attributes)
|
||||
{
|
||||
path_data_grammar data_grammar(path);
|
||||
path_attributes_grammar attributes_grammar;
|
||||
path_dash_array_grammar dash_array_grammar;
|
||||
|
||||
karma::generate(output_iterator_, lit("<path ") << data_grammar, path);
|
||||
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
|
||||
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
|
||||
}*/
|
||||
|
||||
template class svg_generator<std::ostream_iterator<char> >;
|
||||
}}
|
||||
|
|
|
@ -89,9 +89,13 @@ transform_type const& symbolizer_base::get_transform() const
|
|||
std::string symbolizer_base::get_transform_string() const
|
||||
{
|
||||
if (affine_transform_)
|
||||
{
|
||||
return transform_processor_type::to_string(*affine_transform_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void symbolizer_base::set_clip(bool clip)
|
||||
|
@ -189,9 +193,13 @@ transform_type const& symbolizer_with_image::get_image_transform() const
|
|||
std::string symbolizer_with_image::get_image_transform_string() const
|
||||
{
|
||||
if (image_transform_)
|
||||
{
|
||||
return transform_processor_type::to_string(*image_transform_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace mapnik
|
||||
|
|
|
@ -6,6 +6,9 @@ import time
|
|||
from utilities import execution_path
|
||||
from subprocess import Popen, PIPE
|
||||
import os, mapnik
|
||||
from Queue import Queue
|
||||
import threading
|
||||
|
||||
|
||||
MAPNIK_TEST_DBNAME = 'mapnik-tmp-postgis-test-db'
|
||||
POSTGIS_TEMPLATE_DBNAME = 'template_postgis'
|
||||
|
@ -443,9 +446,36 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
|
|||
fs = ds.featureset()
|
||||
eq_(fs.next()['gid'],1)
|
||||
|
||||
def create_ds():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,
|
||||
table='test',
|
||||
max_size=20)
|
||||
fs = ds.all_features()
|
||||
|
||||
def test_threaded_create(NUM_THREADS=100):
|
||||
for i in range(NUM_THREADS):
|
||||
t = threading.Thread(target=create_ds)
|
||||
t.start()
|
||||
t.join()
|
||||
|
||||
def create_ds_and_error():
|
||||
try:
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,
|
||||
table='asdfasdfasdfasdfasdf',
|
||||
max_size=20)
|
||||
fs = ds.all_features()
|
||||
except: pass
|
||||
|
||||
def test_threaded_create2(NUM_THREADS=10):
|
||||
for i in range(NUM_THREADS):
|
||||
t = threading.Thread(target=create_ds_and_error)
|
||||
t.start()
|
||||
t.join()
|
||||
|
||||
|
||||
|
||||
atexit.register(postgis_takedown)
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
#test_auto_detection_and_subquery()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
||||
|
|
Loading…
Add table
Reference in a new issue