diff --git a/include/mapnik/json/feature_grammar_x3_def.hpp b/include/mapnik/json/feature_grammar_x3_def.hpp index a67cffd76..e5dcf9f7c 100644 --- a/include/mapnik/json/feature_grammar_x3_def.hpp +++ b/include/mapnik/json/feature_grammar_x3_def.hpp @@ -177,14 +177,40 @@ auto const assign_geometry_type = [] (auto const& ctx) std::get<0>(_val(ctx)) = _attr(ctx); }; +auto const create_collection = [] (auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + feature.set_geometry(mapnik::geometry::geometry_collection()); +}; + auto const assign_geometry = [] (auto const& ctx) { mapnik::feature_impl & feature = x3::get(ctx); + // first check if we're not dealing with GeometryCollection + if (feature.get_geometry().is()) + { + 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 push_geometry = [] (auto const& 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)); + mapnik::feature_impl & feature = x3::get(ctx); + geometry::geometry & collection = feature.get_geometry(); + + if (collection.is>()) + { + auto & col = collection.get>(); + col.push_back(std::move(geom)); + } }; auto const assign_positions = [] (auto const& ctx) @@ -213,7 +239,7 @@ x3::rule> const property = "Property"; x3::rule const properties = "Properties"; x3::rule const feature_part = "Feature part"; - +x3::rule const geometry_collection = "GeometryCollection"; auto const feature_type_def = lit("\"type\"") > lit(':') > lit("\"Feature\""); @@ -221,10 +247,18 @@ auto const geometry_type_def = lit("\"type\"") > lit(':') > geometry_type_symbol auto const coordinates_def = lit("\"coordinates\"") > lit(':') > positions_rule; +auto const geometry_collection_def = lit("\"geometries\"")[create_collection] > lit(':') + > lit('[') + > ((lit('{') > geometry_tuple[push_geometry] > lit('}')) % lit(',')) + > lit(']'); + + auto const geometry_tuple_def = (geometry_type[assign_geometry_type] | coordinates[assign_positions] | + geometry_collection + | (omit[geojson_string] > lit(':') > omit[value])) % lit(','); @@ -258,7 +292,8 @@ BOOST_SPIRIT_DEFINE( properties, feature_part, feature_rule, - geometry_rule + geometry_rule, + geometry_collection ); #pragma GCC diagnostic pop