GeoJSON - allow empty arrays in "coordinates" element for Multi* geometries (ref #4431)

This commit is contained in:
Artem Pavlenko 2024-02-26 14:01:09 +00:00
parent cc1c990a2a
commit 995d3044a4
3 changed files with 48 additions and 8 deletions

View file

@ -64,6 +64,10 @@ struct create_linestring
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
std::size_t size = points.size(); std::size_t size = points.size();
//if (size < 2)
//{
// throw std::runtime_error("RFC 7946: For type \"LineString\", the \"coordinates\" member is an array of two or more positions.");
//}
line.reserve(size); line.reserve(size);
for (auto&& pt : points) for (auto&& pt : points)
{ {
@ -108,6 +112,12 @@ struct create_polygon
mapnik::geometry::correct(geom_); mapnik::geometry::correct(geom_);
} }
void operator()(ring const& points) const
{
//POLYGON EMPTY
geom_ = std::move(mapnik::geometry::polygon<double>{});
}
template<typename T> template<typename T>
void operator()(T const&) const void operator()(T const&) const
{ {
@ -170,6 +180,12 @@ struct create_multilinestring
geom_ = std::move(multi_line); geom_ = std::move(multi_line);
} }
void operator()(ring const& points) const
{
//MULTILINESTRING EMPTY
geom_ = std::move(mapnik::geometry::multi_line_string<double>{});
}
template<typename T> template<typename T>
void operator()(T const&) const void operator()(T const&) const
{ {
@ -213,6 +229,26 @@ struct create_multipolygon
mapnik::geometry::correct(geom_); mapnik::geometry::correct(geom_);
} }
void operator()(rings const& rngs) const
{
//MULTIPOLYGON
mapnik::geometry::multi_polygon<double> multi_poly;
mapnik::geometry::polygon<double> poly;
std::size_t num_rings = rngs.size();
for (std::size_t i = 0; i < num_rings; ++i)
{
// POLYGON EMPTY
multi_poly.emplace_back(mapnik::geometry::polygon<double>{});
}
geom_ = std::move(multi_poly);
}
void operator()(ring const& points) const
{
//MULTIPOLYGON EMPTY
geom_ = std::move(mapnik::geometry::multi_polygon<double>{});
}
template<typename T> template<typename T>
void operator()(T const&) const void operator()(T const&) const
{ {

View file

@ -83,16 +83,16 @@ geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar
linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias() linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias()
; ;
polygon_coord = lit('[') << linear_ring_coord % lit(',') << lit(']') polygon_coord = lit('[') << -(linear_ring_coord % lit(',')) << lit(']')
; ;
multi_point_coord = lit('[') << -(point_coord % lit(',')) << lit(']');//linestring_coord.alias() multi_point_coord = lit('[') << -(point_coord % lit(',')) << lit(']');//linestring_coord.alias()
; ;
multi_linestring_coord = lit('[') << linestring_coord % lit(',') << lit(']') multi_linestring_coord = lit('[') << -(linestring_coord % lit(',')) << lit(']')
; ;
multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]") multi_polygon_coord = lit('[') << -(polygon_coord % lit(',')) << lit("]")
; ;
geometries = geometry % lit(',') geometries = geometry % lit(',')

View file

@ -125,11 +125,15 @@ TEST_CASE("geojson")
SECTION("GeoJSON empty Geometries handling") SECTION("GeoJSON empty Geometries handling")
{ {
auto valid_empty_geometries = {"null", // Point can't be empty auto valid_empty_geometries = {"null", // Point can't be empty
"{ \"type\": \"LineString\", \"coordinates\": [] }", "{ \"type\": \"LineString\", \"coordinates\":[]}",
"{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ", "{ \"type\": \"Polygon\", \"coordinates\":[]} ",
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }", "{ \"type\": \"Polygon\", \"coordinates\":[[]]} ",
"{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }", "{ \"type\": \"MultiPoint\", \"coordinates\":[]}",
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }"}; "{ \"type\": \"MultiLineString\", \"coordinates\":[]}",
"{ \"type\": \"MultiLineString\", \"coordinates\":[[]]}",
"{ \"type\": \"MultiPolygon\", \"coordinates\":[]}",
"{ \"type\": \"MultiPolygon\", \"coordinates\":[[]]}",
"{ \"type\": \"MultiPolygon\", \"coordinates\": [[[]]] }"};
for (auto const& in : valid_empty_geometries) for (auto const& in : valid_empty_geometries)
{ {