diff --git a/plugins/input/geojson/build.py b/plugins/input/geojson/build.py index a5d738f58..4bf125d67 100644 --- a/plugins/input/geojson/build.py +++ b/plugins/input/geojson/build.py @@ -44,6 +44,7 @@ else: %(PLUGIN_NAME)s_featureset.cpp %(PLUGIN_NAME)s_index_featureset.cpp %(PLUGIN_NAME)s_memory_index_featureset.cpp + ../../../utils/mapnik-index/extract_bounding_boxes_x3.cpp """ % locals() ) diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 688a691ad..2a400fdfa 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -51,11 +51,12 @@ #include #include #include -#include +//#include #include #include #include #include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #pragma GCC diagnostic push @@ -183,14 +184,14 @@ geojson_datasource::geojson_datasource(parameters const& params) } namespace { -using box_type = box2d; +using box_type = box2d; using boxes_type = std::vector>>; using base_iterator_type = char const*; const mapnik::transcoder geojson_datasource_static_tr("utf8"); const mapnik::json::feature_collection_grammar geojson_datasource_static_fc_grammar(geojson_datasource_static_tr); const mapnik::json::feature_grammar_callback geojson_datasource_static_feature_callback_grammar(geojson_datasource_static_tr); const mapnik::json::feature_grammar geojson_datasource_static_feature_grammar(geojson_datasource_static_tr); -const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; +//const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; } void geojson_datasource::initialise_descriptor(mapnik::feature_ptr const& feature) @@ -254,7 +255,39 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end) boxes_type boxes; boost::spirit::standard::space_type space; Iterator itr = start; - if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) + try + { + mapnik::json::extract_bounding_boxes(itr, end, boxes); + // bulk insert initialise r-tree + tree_ = std::make_unique(boxes); + // calculate total extent + std::size_t feature_count = 0; + mapnik::context_ptr ctx = std::make_shared(); + for (auto const& item : boxes) + { + auto const& box = std::get<0>(item); + auto const& geometry_index = std::get<1>(item); + if (!extent_.valid()) extent_.init(box.minx(), box.miny(), box.maxx(), box.maxy()); + else extent_.expand_to_include(mapnik::box2d(box.minx(), box.miny(), box.maxx(), box.maxy())); + if (feature_count++ < num_features_to_query_) + { + // parse first N features to extract attributes schema. + // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication + Iterator itr2 = start + geometry_index.first; + Iterator end2 = itr2 + geometry_index.second; + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature + if (!boost::spirit::qi::phrase_parse(itr2, end2, + (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) + || itr2 != end2) + { + throw std::runtime_error("Failed to parse geojson feature"); + } + + initialise_descriptor(feature); + } + } + } + catch(...) { cache_features_ = true; // force caching single feature itr = start; // reset iteraror @@ -289,7 +322,8 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end) { extent_.expand_to_include(box); } - values.emplace_back(box, std::make_pair(geometry_index,0)); + values.emplace_back(mapnik::box2d(box.minx(), box.miny(), box.maxx(), box.maxy()), + std::make_pair(geometry_index,0)); } if (geometry_index++ < num_features_to_query_) @@ -300,37 +334,6 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end) // packing algorithm tree_ = std::make_unique(values); } - else - { - // bulk insert initialise r-tree - tree_ = std::make_unique(boxes); - // calculate total extent - std::size_t feature_count = 0; - mapnik::context_ptr ctx = std::make_shared(); - for (auto const& item : boxes) - { - auto const& box = std::get<0>(item); - auto const& geometry_index = std::get<1>(item); - if (!extent_.valid()) extent_ = box; - else extent_.expand_to_include(box); - if (feature_count++ < num_features_to_query_) - { - // parse first N features to extract attributes schema. - // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication - Iterator itr2 = start + geometry_index.first; - Iterator end2 = itr2 + geometry_index.second; - mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature - if (!boost::spirit::qi::phrase_parse(itr2, end2, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || itr2 != end2) - { - throw std::runtime_error("Failed to parse geojson feature"); - } - - initialise_descriptor(feature); - } - } - } desc_.order_by_name(); } @@ -397,7 +400,8 @@ void geojson_datasource::parse_geojson(Iterator start, Iterator end) { extent_.expand_to_include(box); } - values.emplace_back(box, std::make_pair(geometry_index,0)); + values.emplace_back(mapnik::box2d(box.minx(), box.miny(), box.maxx(), box.maxy()), + std::make_pair(geometry_index,0)); } if (geometry_index < num_features_to_query_) { diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index e295cb1d6..be0b32053 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -74,7 +74,7 @@ struct options_type > class geojson_datasource : public mapnik::datasource { public: - using box_type = mapnik::box2d; + using box_type = mapnik::box2d; using item_type = std::pair >; using spatial_index_type = boost::geometry::index::rtree >;