Merge pull request #3971 from lightmare/fix-topojson-empty
Accept TopoJSON with no objects
This commit is contained in:
commit
9275ca9373
2 changed files with 70 additions and 5 deletions
|
@ -276,7 +276,7 @@ using x3::lit;
|
|||
using x3::double_;
|
||||
using x3::int_;
|
||||
using x3::omit;
|
||||
using x3::char_;
|
||||
|
||||
namespace
|
||||
{
|
||||
// import unicode string rule
|
||||
|
@ -360,9 +360,13 @@ auto const bbox_def = lit("\"bbox\"") > lit(':')
|
|||
;
|
||||
|
||||
|
||||
// A topology must have an “objects” member whose value is an object.
|
||||
// This object may have any number of members, whose value must be a geometry object.
|
||||
auto const objects_def = lit("\"objects\"") > lit(':')
|
||||
> lit('{')
|
||||
> ((omit[*~char_(':')] > lit(':') > ((geometry_collection[push_collection] | geometry[push_geometry]))) % lit(','))
|
||||
> -((omit[json_string] > ':' > ( geometry_collection[push_collection]
|
||||
| geometry[push_geometry]
|
||||
)) % ',')
|
||||
> lit('}')
|
||||
;
|
||||
|
||||
|
@ -375,7 +379,7 @@ auto const geometry_tuple_def =
|
|||
|
|
||||
properties[assign_properties]
|
||||
|
|
||||
omit[json_string] > lit(':') > omit[json_value]) % lit(',')
|
||||
(omit[json_string] > lit(':') > omit[json_value])) % lit(',')
|
||||
;
|
||||
|
||||
auto const geometry_def = lit("{") > geometry_tuple[create_geometry] > lit("}");
|
||||
|
|
|
@ -29,8 +29,12 @@
|
|||
#include <mapnik/json/topojson_grammar_x3.hpp>
|
||||
#include <mapnik/json/topojson_utils.hpp>
|
||||
|
||||
#define HEREDOC(...) #__VA_ARGS__
|
||||
|
||||
namespace {
|
||||
|
||||
bool parse_topology_string(std::string const& buffer, mapnik::topojson::topology & topo);
|
||||
|
||||
bool parse_topology(std::string const& filename, mapnik::topojson::topology & topo)
|
||||
{
|
||||
mapnik::util::file file(filename);
|
||||
|
@ -38,6 +42,17 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to
|
|||
buffer.resize(file.size());
|
||||
std::fread(&buffer[0], buffer.size(), 1, file.get());
|
||||
if (!file) return false;
|
||||
return parse_topology_string(buffer, topo);
|
||||
}
|
||||
|
||||
bool parse_topology_string(std::string const& buffer)
|
||||
{
|
||||
mapnik::topojson::topology topo;
|
||||
return parse_topology_string(buffer, topo);
|
||||
}
|
||||
|
||||
bool parse_topology_string(std::string const& buffer, mapnik::topojson::topology & topo)
|
||||
{
|
||||
using space_type = boost::spirit::x3::standard::space_type;
|
||||
char const* itr = buffer.c_str();
|
||||
char const* end = itr + buffer.length();
|
||||
|
@ -50,7 +65,17 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to
|
|||
std::cerr << "failed to parse TopoJSON..." << std::endl;
|
||||
std::cerr << ex.what() << std::endl;
|
||||
std::cerr << "Expected: " << ex.which();
|
||||
std::cerr << " Got: \"" << std::string(ex.where(), ex.where() + 200) << "...\"" << std::endl;
|
||||
std::cerr << "\nGot: \"";
|
||||
auto ctx = ex.where();
|
||||
std::streamsize len = 0;
|
||||
// stop before NUL terminator or after 200 bytes, whichever comes first
|
||||
for (; ctx[len] && len < 200; ++len)
|
||||
;
|
||||
// extend to UTF-8 character boundary or 210 bytes, whichever comes first
|
||||
for (; len < 210 && ((unsigned char)ctx[len] & 0xC0) == 0x80; ++len)
|
||||
;
|
||||
std::cerr.write(ctx, len);
|
||||
std::cerr << (ctx[len] ? "..." : "") << '"' << std::endl;
|
||||
return false;
|
||||
}
|
||||
return (itr == end);
|
||||
|
@ -58,8 +83,44 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to
|
|||
|
||||
}
|
||||
|
||||
TEST_CASE("topojson")
|
||||
TEST_CASE("TopoJSON")
|
||||
{
|
||||
SECTION("Minimal Topology")
|
||||
{
|
||||
// + A topology must have a member with the name “objects” whose value is another object.
|
||||
// + A topology must have a member with the name “arcs” whose value is an array of arcs.
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"type": "Topology", "objects": {}, "arcs": []
|
||||
}
|
||||
)));
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"type": "Topology", "arcs": [], "objects": {}
|
||||
}
|
||||
)));
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"objects": {}, "type": "Topology", "arcs": []
|
||||
}
|
||||
)));
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"objects": {}, "arcs": [], "type": "Topology"
|
||||
}
|
||||
)));
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"arcs": [], "type": "Topology", "objects": {}
|
||||
}
|
||||
)));
|
||||
CHECK(parse_topology_string(HEREDOC(
|
||||
{
|
||||
"arcs": [], "objects": {}, "type": "Topology"
|
||||
}
|
||||
)));
|
||||
}
|
||||
|
||||
SECTION("geometry parsing")
|
||||
{
|
||||
mapnik::value_integer feature_id = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue