return actual features

This commit is contained in:
artemp 2015-01-27 16:13:12 +01:00
parent 863ae6a8b3
commit 6faf7efa36
3 changed files with 118 additions and 14 deletions

View file

@ -52,18 +52,56 @@ using mapnik::parameters;
DATASOURCE_PLUGIN(geobuf_datasource)
struct attr_value_converter
{
mapnik::eAttributeType operator() (mapnik::value_integer) const
{
return mapnik::Integer;
}
mapnik::eAttributeType operator() (double) const
{
return mapnik::Double;
}
mapnik::eAttributeType operator() (float) const
{
return mapnik::Double;
}
mapnik::eAttributeType operator() (bool) const
{
return mapnik::Boolean;
}
mapnik::eAttributeType operator() (std::string const& ) const
{
return mapnik::String;
}
mapnik::eAttributeType operator() (mapnik::value_unicode_string const&) const
{
return mapnik::String;
}
mapnik::eAttributeType operator() (mapnik::value_null const& ) const
{
return mapnik::String;
}
};
geobuf_datasource::geobuf_datasource(parameters const& params)
: datasource(params),
type_(datasource::Vector),
desc_(geobuf_datasource::name(),
*params.get<std::string>("encoding","utf-8")),
filename_(),
extent_(),
features_(),
tree_(nullptr)
: datasource(params),
type_(datasource::Vector),
desc_(geobuf_datasource::name(),
*params.get<std::string>("encoding","utf-8")),
filename_(),
extent_(),
features_(),
tree_(nullptr)
{
boost::optional<std::string> file = params.get<std::string>("file");
if (!file) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");
if (!file) throw mapnik::datasource_exception("Geobuf Plugin: missing <file> parameter");
boost::optional<std::string> base = params.get<std::string>("base");
if (base)
@ -88,6 +126,47 @@ void geobuf_datasource::parse_geobuf(std::uint8_t const* data, std::size_t size)
mapnik::util::geobuf buf(data, size);
buf.read(features_);
std::cerr << "Num of features = " << features_.size() << std::endl;
#if BOOST_VERSION >= 105600
using values_container = std::vector< std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
values_container values;
values.reserve(features_.size());
#else
tree_ = std::make_unique<spatial_index_type>(16, 4);
#endif
std::size_t geometry_index = 0;
for (mapnik::feature_ptr const& f : features_)
{
mapnik::box2d<double> box = f->envelope();
if (box.valid())
{
if (geometry_index == 0)
{
extent_ = box;
for ( auto const& kv : *f)
{
desc_.add_descriptor(mapnik::attribute_descriptor(std::get<0>(kv),
mapnik::util::apply_visitor(attr_value_converter(),
std::get<1>(kv))));
}
}
else
{
extent_.expand_to_include(box);
}
}
#if BOOST_VERSION >= 105600
values.emplace_back(box, std::make_pair(geometry_index,0));
#else
tree_->insert(box, std::make_pair(geometry_index));
#endif
++geometry_index;
}
#if BOOST_VERSION >= 105600
// packing algorithm
tree_ = std::make_unique<spatial_index_type>(values);
#endif
}
geobuf_datasource::~geobuf_datasource() {}
@ -136,6 +215,24 @@ mapnik::layer_descriptor geobuf_datasource::get_descriptor() const
mapnik::featureset_ptr geobuf_datasource::features(mapnik::query const& q) const
{
// if the query box intersects our world extent then query for features
mapnik::box2d<double> const& box = q.get_bbox();
if (extent_.intersects(box))
{
#if BOOST_VERSION >= 105600
geobuf_featureset::array_type index_array;
if (tree_)
{
tree_->query(boost::geometry::index::intersects(box),std::back_inserter(index_array));
return std::make_shared<geobuf_featureset>(features_, std::move(index_array));
}
}
#else
if (tree_)
{
return std::make_shared<geobuf_featureset>(features_, tree_->find(box));
}
#endif
return mapnik::featureset_ptr();
}

View file

@ -30,8 +30,9 @@
#include "geobuf_featureset.hpp"
geobuf_featureset::geobuf_featureset(array_type && index_array)
: index_array_(std::move(index_array)),
geobuf_featureset::geobuf_featureset(std::vector<mapnik::feature_ptr> const& features,array_type && index_array)
: features_(features),
index_array_(std::move(index_array)),
index_itr_(index_array_.begin()),
index_end_(index_array_.end()),
ctx_(std::make_shared<mapnik::context_type>()) {}
@ -44,12 +45,16 @@ mapnik::feature_ptr geobuf_featureset::next()
{
#if BOOST_VERSION >= 105600
geobuf_datasource::item_type const& item = *index_itr_++;
std::size_t file_offset = item.second.first;
std::size_t size = item.second.second;
std::size_t index = item.second.first;
//std::size_t size = item.second.second;
//std::cerr << file_offset << " (" << size << ") " << item.first << std::endl;
#else
std::size_t index = *index_itr_++;
#endif
if ( index < features_.size())
{
return features_.at(index);
}
}
return mapnik::feature_ptr();
}

View file

@ -34,11 +34,13 @@ class geobuf_featureset : public mapnik::Featureset
{
public:
typedef std::deque<geobuf_datasource::item_type> array_type;
geobuf_featureset(array_type && index_array);
geobuf_featureset(std::vector<mapnik::feature_ptr> const& features,
array_type && index_array);
virtual ~geobuf_featureset();
mapnik::feature_ptr next();
private:
std::vector<mapnik::feature_ptr> const& features_;
const array_type index_array_;
array_type::const_iterator index_itr_;
array_type::const_iterator index_end_;