create shape_io object per featureset to allow datasource sharing

This commit is contained in:
artemp 2014-05-30 15:37:44 +01:00
parent 1cb03bac2f
commit 22aa3f4aef
6 changed files with 43 additions and 50 deletions

View File

@ -31,6 +31,7 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/std.hpp>
#include <mapnik/util/fs.hpp>
#include <mapnik/global.hpp>
#include <mapnik/utils.hpp>
@ -95,7 +96,7 @@ shape_datasource::shape_datasource(parameters const& params)
mapnik::progress_timer __stats2__(std::clog, "shape_datasource::init(get_column_description)");
#endif
std::shared_ptr<shape_io> shape_ref = std::make_shared<shape_io>(shape_name_);
std::unique_ptr<shape_io> shape_ref = std::make_unique<shape_io>(shape_name_);
init(*shape_ref);
for (int i=0;i<shape_ref->dbf().num_fields();++i)
{
@ -136,11 +137,6 @@ shape_datasource::shape_datasource(parameters const& params)
break;
}
}
// for indexed shapefiles we keep open the file descriptor for fast reads
if (indexed_) {
shape_ = shape_ref;
}
}
catch (datasource_exception const& ex)
{
@ -198,8 +194,6 @@ void shape_datasource::init(shape_io& shape)
MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Z min/max=" << zmin << "," << zmax;
MAPNIK_LOG_DEBUG(shape) << "shape_datasource: M min/max=" << mmin << "," << mmax;
#else
shape.shp().skip(4*8);
#endif
// check if we have an index file around
@ -226,7 +220,7 @@ layer_descriptor shape_datasource::get_descriptor() const
return desc_;
}
featureset_ptr shape_datasource::features(const query& q) const
featureset_ptr shape_datasource::features(query const& q) const
{
#ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "shape_datasource::features");
@ -235,11 +229,10 @@ featureset_ptr shape_datasource::features(const query& q) const
filter_in_box filter(q.get_bbox());
if (indexed_)
{
shape_->shp().seek(0);
// TODO - use std::make_shared - #760
std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
return featureset_ptr
(new shape_index_featureset<filter_in_box>(filter,
*shape_,
std::move(shape_ptr),
q.property_names(),
desc_.get_encoding(),
shape_name_,
@ -248,11 +241,11 @@ featureset_ptr shape_datasource::features(const query& q) const
else
{
return std::make_shared<shape_featureset<filter_in_box> >(filter,
shape_name_,
q.property_names(),
desc_.get_encoding(),
file_length_,
row_limit_);
shape_name_,
q.property_names(),
desc_.get_encoding(),
file_length_,
row_limit_);
}
}
@ -277,11 +270,10 @@ featureset_ptr shape_datasource::features_at_point(coord2d const& pt, double tol
if (indexed_)
{
shape_->shp().seek(0);
// TODO - use std::make_shared - #760
std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
return featureset_ptr
(new shape_index_featureset<filter_at_point>(filter,
*shape_,
std::move(shape_ptr),
names,
desc_.get_encoding(),
shape_name_,
@ -290,11 +282,11 @@ featureset_ptr shape_datasource::features_at_point(coord2d const& pt, double tol
else
{
return std::make_shared<shape_featureset<filter_at_point> >(filter,
shape_name_,
names,
desc_.get_encoding(),
file_length_,
row_limit_);
shape_name_,
names,
desc_.get_encoding(),
file_length_,
row_limit_);
}
}

View File

@ -53,11 +53,11 @@ using mapnik::coord2d;
class shape_datasource : public datasource
{
public:
shape_datasource(const parameters &params);
shape_datasource(parameters const& params);
virtual ~shape_datasource();
datasource::datasource_t type() const;
static const char * name();
featureset_ptr features(const query& q) const;
featureset_ptr features(query const& q) const;
featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
box2d<double> envelope() const;
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
@ -68,7 +68,6 @@ private:
datasource::datasource_t type_;
std::string shape_name_;
std::shared_ptr<shape_io> shape_;
shape_io::shapeType shape_type_;
long file_length_;
box2d<double> extent_;

View File

@ -42,23 +42,23 @@ using mapnik::geometry_type;
template <typename filterT>
shape_index_featureset<filterT>::shape_index_featureset(filterT const& filter,
shape_io& shape,
std::unique_ptr<shape_io> && shape_ptr,
std::set<std::string> const& attribute_names,
std::string const& encoding,
std::string const& shape_name,
int row_limit)
: filter_(filter),
ctx_(std::make_shared<mapnik::context_type>()),
shape_(shape),
tr_(new mapnik::transcoder(encoding)),
row_limit_(row_limit),
count_(0),
feature_bbox_()
shape_ptr_(std::move(shape_ptr)),
tr_(new mapnik::transcoder(encoding)),
row_limit_(row_limit),
count_(0),
feature_bbox_()
{
shape_.shp().skip(100);
setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_);
shape_ptr_->shp().skip(100);
setup_attributes(ctx_, attribute_names, shape_name, *shape_ptr_,attr_ids_);
std::shared_ptr<shape_file> index = shape_.index();
auto index = shape_ptr_->index();
if (index)
{
#ifdef SHAPE_MEMORY_MAPPED_FILE
@ -86,11 +86,11 @@ feature_ptr shape_index_featureset<filterT>::next()
while ( itr_ != offsets_.end())
{
shape_.move_to(*itr_++);
shape_file::record_type record(shape_.reclength_ * 2);
shape_.shp().read_record(record);
shape_ptr_->move_to(*itr_++);
shape_file::record_type record(shape_ptr_->reclength_ * 2);
shape_ptr_->shp().read_record(record);
int type = record.read_ndr_integer();
feature_ptr feature(feature_factory::create(ctx_,shape_.id_));
feature_ptr feature(feature_factory::create(ctx_,shape_ptr_->id_));
switch (type)
{
@ -146,17 +146,17 @@ feature_ptr shape_index_featureset<filterT>::next()
}
// FIXME: https://github.com/mapnik/mapnik/issues/1020
feature->set_id(shape_.id_);
feature->set_id(shape_ptr_->id_);
if (attr_ids_.size())
{
shape_.dbf().move_to(shape_.id_);
shape_ptr_->dbf().move_to(shape_ptr_->id_);
std::vector<int>::const_iterator itr = attr_ids_.begin();
std::vector<int>::const_iterator end = attr_ids_.end();
try
{
for (; itr!=end; ++itr)
{
shape_.dbf().add_attribute(*itr, *tr_, *feature);
shape_ptr_->dbf().add_attribute(*itr, *tr_, *feature);
}
}
catch (...)

View File

@ -50,7 +50,7 @@ class shape_index_featureset : public Featureset
{
public:
shape_index_featureset(filterT const& filter,
shape_io & shape,
std::unique_ptr<shape_io> && shape_ptr,
std::set<std::string> const& attribute_names,
std::string const& encoding,
std::string const& shape_name,
@ -61,7 +61,7 @@ public:
private:
filterT filter_;
context_ptr ctx_;
shape_io & shape_;
std::unique_ptr<shape_io> shape_ptr_;
const std::unique_ptr<mapnik::transcoder> tr_;
std::vector<std::streampos> offsets_;
std::vector<std::streampos>::iterator itr_;

View File

@ -24,6 +24,7 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/std.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/geom_util.hpp>
@ -53,7 +54,7 @@ shape_io::shape_io(std::string const& shape_name, bool open_index)
{
try
{
index_= std::make_shared<shape_file>(shape_name + INDEX);
index_ = std::make_unique<shape_file>(shape_name + INDEX);
}
catch (...)
{

View File

@ -61,9 +61,10 @@ public:
shape_file& shp();
dbf_file& dbf();
inline std::shared_ptr<shape_file>& index()
inline boost::optional<shape_file&> index()
{
return index_;
if (index_) return boost::optional<shape_file&>(*index_);
return boost::optional<shape_file&>();
}
inline bool has_index() const
@ -79,7 +80,7 @@ public:
shapeType type_;
shape_file shp_;
dbf_file dbf_;
std::shared_ptr<shape_file> index_;
std::unique_ptr<shape_file> index_;
unsigned reclength_;
unsigned id_;
box2d<double> cur_extent_;