From 34470af474e0e1e7dae66c4f6207d3d0bd6ff0b3 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Tue, 12 Jun 2012 13:55:15 +0100 Subject: [PATCH 1/4] + allow empty arrays in "coordinates" property --- include/mapnik/json/feature_grammar.hpp | 53 ++++++++++++------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp index 20b13f9b1..b756daead 100644 --- a/include/mapnik/json/feature_grammar.hpp +++ b/include/mapnik/json/feature_grammar.hpp @@ -162,7 +162,7 @@ struct feature_grammar : using qi::_pass; using qi::eps; using qi::raw; - + using phoenix::new_; using phoenix::push_back; using phoenix::construct; @@ -197,7 +197,7 @@ struct feature_grammar : unesc_char.add ("\\\"", '\"') // quotation mark ("\\\\", '\\') // reverse solidus - ("\\/", '/') // solidus + ("\\/", '/') // solidus ("\\b", '\b') // backspace ("\\f", '\f') // formfeed ("\\n", '\n') // newline @@ -207,7 +207,7 @@ struct feature_grammar : string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"') ; - + // geojson types feature_type = lit("\"type\"") @@ -244,17 +244,17 @@ struct feature_grammar : // ; ////////////////////////////////////////////////////////////////// - geometry = (lit('{')[_a = 0 ] + geometry = (lit('{')[_a = 0 ] >> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick! - >> lit(',') + >> lit(',') >> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a) - | - lit("\"geometries\"") > lit(':') + | + lit("\"geometries\"") > lit(':') >> lit('[') >> geometry_collection(_r1) >> lit(']')) >> lit('}')) | lit("null") ; - + geometry_dispatch.add ("\"Point\"",1) ("\"LineString\"",2) @@ -265,7 +265,7 @@ struct feature_grammar : ("\"GeometryCollection\"",7) // ; - + coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1))) | (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1))) | (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1))) @@ -273,46 +273,45 @@ struct feature_grammar : | (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1))) | (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1))) ; - + point_coordinates = eps[ _a = new_(Point) ] > ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] ) ; linestring_coordinates = eps[ _a = new_(LineString)] - > (points(_a) [push_back(_r1,_a)] + > -(points(_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false]) ; polygon_coordinates = eps[ _a = new_(Polygon) ] > ((lit('[') - > points(_a) % lit(',') + > -(points(_a) % lit(',')) > lit(']')) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false]) ; - - multipoint_coordinates = lit('[') - > (point_coordinates(_r1) % lit(',')) + + multipoint_coordinates = lit('[') + > -(point_coordinates(_r1) % lit(',')) > lit(']') ; - - multilinestring_coordinates = lit('[') - > (linestring_coordinates(_r1) % lit(',')) + + multilinestring_coordinates = lit('[') + > -(linestring_coordinates(_r1) % lit(',')) > lit(']') ; - - multipolygon_coordinates = lit('[') - > (polygon_coordinates(_r1) % lit(',')) + + multipolygon_coordinates = lit('[') + > -(polygon_coordinates(_r1) % lit(',')) > lit(']') ; geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1)) ; - - // point - point = (lit('[') > double_ > lit(',') > double_ > lit(']')) [push_vertex_(_r1,_r2,_1,_2)]; - // points - points = lit('[')[_a = SEG_MOVETO] > point (_a,_r1) % lit(',') [_a = SEG_LINETO] > lit(']'); + // point + point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']'); + // points + points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']'); on_error ( feature @@ -362,7 +361,7 @@ struct feature_grammar : qi::rule, void(boost::ptr_vector& ),space_type> linestring_coordinates; qi::rule, - void(boost::ptr_vector& ),space_type> polygon_coordinates; + void(boost::ptr_vector& ),space_type> polygon_coordinates; qi::rule& ),space_type> multipoint_coordinates; qi::rule& ),space_type> multilinestring_coordinates; From 689e8ec96dc87ed9cbdc04e2ecb72f706f5dbe4a Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 14 Jun 2012 11:49:47 +0100 Subject: [PATCH 2/4] + make feature's optional: -(feature % lit(',')) --- include/mapnik/json/feature_collection_grammar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/json/feature_collection_grammar.hpp b/include/mapnik/json/feature_collection_grammar.hpp index 9117b14a7..54c749dd4 100644 --- a/include/mapnik/json/feature_collection_grammar.hpp +++ b/include/mapnik/json/feature_collection_grammar.hpp @@ -87,7 +87,7 @@ struct feature_collection_grammar : features = lit("\"features\"") > lit(":") > lit('[') - > feature(_val) % lit(',') + > -(feature(_val) % lit(',')) > lit(']') ; From ddfe15025bd2369f9c5f0ec17cf9b3dde5f4f4dc Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 14 Jun 2012 12:16:25 +0100 Subject: [PATCH 3/4] + use rtree index --- plugins/input/geojson/geojson_datasource.cpp | 11 ++++---- plugins/input/geojson/geojson_datasource.hpp | 1 + plugins/input/geojson/geojson_featureset.cpp | 27 ++++++++++---------- plugins/input/geojson/geojson_featureset.hpp | 12 ++++++--- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 7c1fc978f..69c3ba230 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -25,7 +25,6 @@ #include #include - // boost #include #include @@ -129,11 +128,9 @@ std::map geojson_datasource::get_statistics() c return statistics_; } -// FIXME: implement mapnik::box2d geojson_datasource::envelope() const { if (!is_bound_) bind(); - return extent_; } @@ -149,9 +146,13 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons if (!is_bound_) bind(); // if the query box intersects our world extent then query for features - if (extent_.intersects(q.get_bbox())) + mapnik::box2d const& b = q.get_bbox(); + if (extent_.intersects(b)) { - return boost::make_shared(features_,tree_); + box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy())); + index_array_ = tree_.find(box); + std::cout << "QUERY SIZE=" << index_array_.size() << std::endl; + return boost::make_shared(features_, index_array_.begin(), index_array_.end()); } // otherwise return an empty featureset pointer return mapnik::featureset_ptr(); diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index 829a30f5f..079cb7e3c 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -62,6 +62,7 @@ private: boost::shared_ptr tr_; mutable std::vector features_; mutable spatial_index_type tree_; + mutable std::deque index_array_; }; diff --git a/plugins/input/geojson/geojson_featureset.cpp b/plugins/input/geojson/geojson_featureset.cpp index bf5cb7878..f6d45a9d1 100644 --- a/plugins/input/geojson/geojson_featureset.cpp +++ b/plugins/input/geojson/geojson_featureset.cpp @@ -29,23 +29,24 @@ #include "geojson_featureset.hpp" -geojson_featureset::geojson_featureset(std::vector const& features, - geojson_datasource::spatial_index_type const& tree) - : feature_id_(1), - features_(features), - tree_(tree) {} +geojson_featureset::geojson_featureset(std::vector const& features, + std::deque::const_iterator index_itr, + std::deque::const_iterator index_end) + : features_(features), + index_itr_(index_itr), + index_end_(index_end) {} geojson_featureset::~geojson_featureset() {} mapnik::feature_ptr geojson_featureset::next() { - feature_id_++; - if (feature_id_ <= features_.size()) + if (index_itr_ != index_end_) { - return features_.at(feature_id_ - 1); - } - else - { - return mapnik::feature_ptr(); - } + std::size_t index = *index_itr_++; + if ( index < features_.size()) + { + return features_.at(index); + } + } + return mapnik::feature_ptr(); } diff --git a/plugins/input/geojson/geojson_featureset.hpp b/plugins/input/geojson/geojson_featureset.hpp index 6a463f66e..d10919ef8 100644 --- a/plugins/input/geojson/geojson_featureset.hpp +++ b/plugins/input/geojson/geojson_featureset.hpp @@ -2,22 +2,26 @@ #define GEOJSON_FEATURESET_HPP #include -#include #include "geojson_datasource.hpp" +#include +#include + + class geojson_featureset : public mapnik::Featureset { public: geojson_featureset(std::vector const& features, - geojson_datasource::spatial_index_type const& tree); + std::deque::const_iterator index_itr, + std::deque::const_iterator index_end); virtual ~geojson_featureset(); mapnik::feature_ptr next(); private: mapnik::box2d box_; - unsigned int feature_id_; std::vector const& features_; - geojson_datasource::spatial_index_type const& tree_; + std::deque::const_iterator index_itr_; + std::deque::const_iterator index_end_; }; #endif // GEOJSON_FEATURESET_HPP From 8d4534de781796d4c663261ea9856c4c7d254860 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 14 Jun 2012 15:10:32 +0100 Subject: [PATCH 4/4] + remove debug print --- plugins/input/geojson/geojson_datasource.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 69c3ba230..068bf4c1f 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -151,7 +151,6 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons { box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy())); index_array_ = tree_.find(box); - std::cout << "QUERY SIZE=" << index_array_.size() << std::endl; return boost::make_shared(features_, index_array_.begin(), index_array_.end()); } // otherwise return an empty featureset pointer