From 56174edaa824369211f222a5c42f1f1d381ab9de Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 3 Oct 2013 17:12:33 +0100 Subject: [PATCH] == topjson == + extract and transcode property values --- .../input/topojson/topojson_datasource.cpp | 3 +- .../input/topojson/topojson_featureset.cpp | 102 +++++++++++++++--- .../input/topojson/topojson_featureset.hpp | 6 +- 3 files changed, 93 insertions(+), 18 deletions(-) diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp index 0fee1110a..c4919f6b0 100644 --- a/plugins/input/topojson/topojson_datasource.cpp +++ b/plugins/input/topojson/topojson_datasource.cpp @@ -108,7 +108,6 @@ topojson_datasource::topojson_datasource(parameters const& params) tree_.insert(box_type(point_type(bbox.minx(),bbox.miny()),point_type(bbox.maxx(),bbox.maxy())), count++); } } - std::cerr << extent_ << std::endl; } topojson_datasource::~topojson_datasource() { } @@ -147,7 +146,7 @@ mapnik::featureset_ptr topojson_datasource::features(mapnik::query const& q) con { box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy())); index_array_ = tree_.find(box); - return std::make_shared(topo_, index_array_.begin(), index_array_.end()); + return std::make_shared(topo_, *tr_, index_array_.begin(), index_array_.end()); } // otherwise return an empty featureset pointer return mapnik::featureset_ptr(); diff --git a/plugins/input/topojson/topojson_featureset.cpp b/plugins/input/topojson/topojson_featureset.cpp index 383064722..bd90c711b 100644 --- a/plugins/input/topojson/topojson_featureset.cpp +++ b/plugins/input/topojson/topojson_featureset.cpp @@ -36,22 +36,99 @@ namespace mapnik { namespace topojson { +struct attribute_value_visitor + : boost::static_visitor +{ +public: + attribute_value_visitor(mapnik::transcoder const& tr) + : tr_(tr) {} + + mapnik::value operator()(std::string const& val) const + { + return mapnik::value(tr_.transcode(val.c_str())); + } + + template + mapnik::value operator()(T const& val) const + { + return mapnik::value(val); + } + + mapnik::transcoder const& tr_; +}; + +template +void assign_properties(mapnik::feature_impl & feature, T const& geom, mapnik::transcoder const& tr) +{ + if ( geom.props) + { + for (auto const& p : *geom.props) + { + //mapnik::value v = boost::apply_visitor(attribute_value_visitor(tr),std::get<1>(p)); + feature.put_new(std::get<0>(p), boost::apply_visitor(attribute_value_visitor(tr),std::get<1>(p))); + } + } +} + template struct feature_generator : public boost::static_visitor { - feature_generator(Context & ctx, topology const& topo, std::size_t feature_id) + feature_generator(Context & ctx, mapnik::transcoder const& tr, topology const& topo, std::size_t feature_id) : ctx_(ctx), + tr_(tr), topo_(topo), feature_id_(feature_id) {} feature_ptr operator() (point const& pt) const { - return feature_ptr(); + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_)); + std::unique_ptr point_ptr(new geometry_type(geometry_type::types::Point)); + + double x = pt.coord.x; + double y = pt.coord.y; + if (topo_.tr) + { + x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x; + y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y; + } + + point_ptr->move_to(x,y); + feature->paths().push_back(point_ptr.release()); + assign_properties(*feature, pt, tr_); + return feature; } feature_ptr operator() (linestring const& line) const { - return feature_ptr(); + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_,feature_id_)); + std::unique_ptr line_ptr(new geometry_type(geometry_type::types::LineString)); + + double px = 0, py = 0; + index_type arc_index = line.ring; + bool first = true; + for (auto pt : topo_.arcs[arc_index].coordinates) + { + double x = pt.x; + double y = pt.y; + if (topo_.tr) + { + x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x; + y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y; + } + if (first) + { + first = false; + line_ptr->move_to(x,y); + } + else + { + line_ptr->line_to(x,y); + } + } + + feature->paths().push_back(line_ptr.release()); + assign_properties(*feature, line, tr_); + return feature; } feature_ptr operator() (polygon const& poly) const @@ -97,15 +174,9 @@ struct feature_generator : public boost::static_visitor } poly_ptr->close_path(); } - feature->paths().push_back(poly_ptr.release()); - if (poly.props) - { - for (auto const& p : *poly.props) - { - feature->put_new(std::get<0>(p), mapnik::value(1LL)/*std::get<1>(p)*/); // TODO - } - } + feature->paths().push_back(poly_ptr.release()); + assign_properties(*feature, poly, tr_); return feature; } @@ -116,6 +187,7 @@ struct feature_generator : public boost::static_visitor } Context & ctx_; + mapnik::transcoder const& tr_; topology const& topo_; std::size_t feature_id_; }; @@ -123,10 +195,12 @@ struct feature_generator : public boost::static_visitor }} topojson_featureset::topojson_featureset(mapnik::topojson::topology const& topo, - std::deque::const_iterator index_itr, - std::deque::const_iterator index_end) + mapnik::transcoder const& tr, + std::deque::const_iterator index_itr, + std::deque::const_iterator index_end) : ctx_(std::make_shared()), topo_(topo), + tr_(tr), index_itr_(index_itr), index_end_(index_end), feature_id_ (0) {} @@ -142,7 +216,7 @@ mapnik::feature_ptr topojson_featureset::next() { mapnik::topojson::geometry const& geom = topo_.geometries[index]; mapnik::feature_ptr feature = boost::apply_visitor( - mapnik::topojson::feature_generator(ctx_, topo_, feature_id_++), + mapnik::topojson::feature_generator(ctx_, tr_, topo_, feature_id_++), geom); return feature; } diff --git a/plugins/input/topojson/topojson_featureset.hpp b/plugins/input/topojson/topojson_featureset.hpp index 9ecc186bc..cd81179dc 100644 --- a/plugins/input/topojson/topojson_featureset.hpp +++ b/plugins/input/topojson/topojson_featureset.hpp @@ -33,8 +33,9 @@ class topojson_featureset : public mapnik::Featureset { public: topojson_featureset(mapnik::topojson::topology const& topo, - std::deque::const_iterator index_itr, - std::deque::const_iterator index_end); + mapnik::transcoder const& tr, + std::deque::const_iterator index_itr, + std::deque::const_iterator index_end); virtual ~topojson_featureset(); mapnik::feature_ptr next(); @@ -42,6 +43,7 @@ private: mapnik::context_ptr ctx_; mapnik::box2d box_; mapnik::topojson::topology const& topo_; + mapnik::transcoder const& tr_; std::deque::const_iterator index_itr_; std::deque::const_iterator index_end_; std::size_t feature_id_;