From 6faf7efa369354c50dce83797384220bad4a6b59 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 27 Jan 2015 16:13:12 +0100 Subject: [PATCH] return actual features --- plugins/input/geobuf/geobuf_datasource.cpp | 115 +++++++++++++++++++-- plugins/input/geobuf/geobuf_featureset.cpp | 13 ++- plugins/input/geobuf/geobuf_featureset.hpp | 4 +- 3 files changed, 118 insertions(+), 14 deletions(-) diff --git a/plugins/input/geobuf/geobuf_datasource.cpp b/plugins/input/geobuf/geobuf_datasource.cpp index f172ad5de..4341408a8 100644 --- a/plugins/input/geobuf/geobuf_datasource.cpp +++ b/plugins/input/geobuf/geobuf_datasource.cpp @@ -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("encoding","utf-8")), - filename_(), - extent_(), - features_(), - tree_(nullptr) + : datasource(params), + type_(datasource::Vector), + desc_(geobuf_datasource::name(), + *params.get("encoding","utf-8")), + filename_(), + extent_(), + features_(), + tree_(nullptr) { boost::optional file = params.get("file"); - if (!file) throw mapnik::datasource_exception("GeoJSON Plugin: missing parameter"); + if (!file) throw mapnik::datasource_exception("Geobuf Plugin: missing parameter"); boost::optional base = params.get("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>>; + values_container values; + values.reserve(features_.size()); +#else + tree_ = std::make_unique(16, 4); +#endif + + std::size_t geometry_index = 0; + for (mapnik::feature_ptr const& f : features_) + { + mapnik::box2d 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(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 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(features_, std::move(index_array)); + } + } +#else + if (tree_) + { + return std::make_shared(features_, tree_->find(box)); + } +#endif return mapnik::featureset_ptr(); } diff --git a/plugins/input/geobuf/geobuf_featureset.cpp b/plugins/input/geobuf/geobuf_featureset.cpp index 70ec4c298..ed0543381 100644 --- a/plugins/input/geobuf/geobuf_featureset.cpp +++ b/plugins/input/geobuf/geobuf_featureset.cpp @@ -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 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()) {} @@ -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(); } diff --git a/plugins/input/geobuf/geobuf_featureset.hpp b/plugins/input/geobuf/geobuf_featureset.hpp index 1c8f9407e..a1a0668aa 100644 --- a/plugins/input/geobuf/geobuf_featureset.hpp +++ b/plugins/input/geobuf/geobuf_featureset.hpp @@ -34,11 +34,13 @@ class geobuf_featureset : public mapnik::Featureset { public: typedef std::deque array_type; - geobuf_featureset(array_type && index_array); + geobuf_featureset(std::vector const& features, + array_type && index_array); virtual ~geobuf_featureset(); mapnik::feature_ptr next(); private: + std::vector const& features_; const array_type index_array_; array_type::const_iterator index_itr_; array_type::const_iterator index_end_;