diff --git a/plugins/input/geojson/geojson_index_featureset.cpp b/plugins/input/geojson/geojson_index_featureset.cpp index 594fc83f5..da23aac3f 100644 --- a/plugins/input/geojson/geojson_index_featureset.cpp +++ b/plugins/input/geojson/geojson_index_featureset.cpp @@ -29,14 +29,100 @@ #include #include #include -#include +#include #include -#include +#include // stl #include #include #include + +namespace mapnik { namespace json { namespace { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::omit; +using x3::char_; + +struct feature_tag; +// generic json rule +auto const& value = generic_json_grammar(); +// import unicode string rule +auto const& geojson_string = unicode_string_grammar(); +// import positions rule +auto const& positions_rule = positions_grammar(); +// geometry types symbols +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"", mapnik::geometry::geometry_types::Point) + ("\"LineString\"", mapnik::geometry::geometry_types::LineString) + ("\"Polygon\"", mapnik::geometry::geometry_types::Polygon) + ("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint) + ("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString ) + ("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon) + ("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection) + ; + } +} geometry_type_symbols; + +auto const assign_geometry_type = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto const assign_geometry = [] (auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + mapnik::geometry::geometry geom; + auto const type = std::get<0>(_attr(ctx)); + auto const& coordinates = std::get<1>(_attr(ctx)); + mapnik::json::create_geometry(geom, type, coordinates); + feature.set_geometry(std::move(geom)); +}; + +auto const assign_positions = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto const feature_type = lit("\"type\"") > lit(':') > lit("\"Feature\""); +auto const geometry_type = x3::rule {} = + lit("\"type\"") > lit(':') > geometry_type_symbols; + +auto const coordinates = x3::rule {} = + lit("\"coordinates\"") > lit(':') > positions_rule + ; + +auto const geometry = x3::rule> {} = + (geometry_type[assign_geometry_type] + | + coordinates[assign_positions] + | + (omit[geojson_string] > lit(':') > omit[value])) % lit(',') + ; + + +auto const feature_part = x3::rule {} = + feature_type + | + (lit("\"geometry\"") > lit(':') > lit('{') > geometry[assign_geometry] > lit('}')) + | + (lit("\"properties\"") > lit(':') > omit[value]) + | + omit[geojson_string] > lit(':') > omit[value] + ; + +auto const feature = x3::rule {} = + lit('{') > feature_part % lit(',') > lit('}') + ; + +}}} + + geojson_index_featureset::geojson_index_featureset(std::string const& filename, mapnik::filter_in_box const& filter) : #if defined(MAPNIK_MEMORY_MAPPED_FILE) @@ -77,13 +163,6 @@ geojson_index_featureset::geojson_index_featureset(std::string const& filename, geojson_index_featureset::~geojson_index_featureset() {} -namespace { -using namespace boost::spirit; -//static const mapnik::json::keys_map keys = mapnik::json::get_keys(); -static const mapnik::json::grammar::geojson_grammar_type geojson_g = mapnik::json::geojson_grammar(); - -} - mapnik::feature_ptr geojson_index_featureset::next() { while( itr_ != positions_.end()) @@ -105,13 +184,14 @@ mapnik::feature_ptr geojson_index_featureset::next() using namespace boost::spirit; using space_type = mapnik::json::grammar::space_type; using mapnik::json::grammar::iterator_type; - mapnik::json::geojson_value value; - auto const grammar = x3::with(std::ref(keys_)) - [ geojson_g ]; + //mapnik::json::geojson_value value; + //auto const grammar = x3::with(std::ref(keys_)) + // [ mapnik::json::geojson_grammar() ]; + auto grammar = x3::with(std::ref(*feature)) + [ mapnik::json::feature ]; + bool result = x3::phrase_parse(start, end, grammar, space_type()); - bool result = x3::phrase_parse(start, end, grammar, space_type(), value); if (!result) throw std::runtime_error("Failed to parse GeoJSON feature"); - mapnik::json::create_feature(*feature, value, keys_, tr); // skip empty geometries if (mapnik::geometry::is_empty(feature->get_geometry())) continue; diff --git a/plugins/input/geojson/geojson_index_featureset.hpp b/plugins/input/geojson/geojson_index_featureset.hpp index 4371636b0..41e8e84ba 100644 --- a/plugins/input/geojson/geojson_index_featureset.hpp +++ b/plugins/input/geojson/geojson_index_featureset.hpp @@ -32,10 +32,6 @@ #include #include #include -#include -#include -#include -#include #pragma GCC diagnostic pop #include #endif @@ -43,35 +39,6 @@ #include #include -namespace { - -using keys_map = boost::bimap, - boost::bimaps::set_of>; - -enum well_known_names -{ - id = 1, - type, - features, - geometry, - coordinates, - properties -}; - -inline keys_map get_keys() -{ - keys_map keys = boost::assign::list_of - ("type", well_known_names::type) - ("features", well_known_names::features) - ("geometry", well_known_names::geometry) - ("coordinates", well_known_names::coordinates) - ("properties", well_known_names::properties) - ("id", well_known_names::id) - ; - return keys; -} -} - class geojson_index_featureset : public mapnik::Featureset { using value_type = std::pair; @@ -92,7 +59,6 @@ private: mapnik::context_ptr ctx_; std::vector positions_; std::vector::iterator itr_; - keys_map keys_ = get_keys(); }; #endif // GEOJSON_INDEX_FEATURESE_HPP