From 3715321e6aeb76d7e6186042ff5e868c7f39f610 Mon Sep 17 00:00:00 2001 From: Paul Norman Date: Wed, 10 Dec 2014 11:50:32 -0800 Subject: [PATCH 1/2] Use arrays for center and bounds in tilejson Fixes #4 This does not validate that the parameter in the Mapnik XML is valid, but if it is valid, it will result in a valid TileJSON. --- src/tilejson.cpp | 6 +++++- test/tilejson.cpp | 16 ++++++++++++++++ test/tilejson_params.xml | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/tilejson.cpp b/src/tilejson.cpp index e3ce50d..6ecc6d8 100644 --- a/src/tilejson.cpp +++ b/src/tilejson.cpp @@ -216,7 +216,11 @@ std::string make_tilejson(const mapnik::Map &map, for (auto const &row : params) { out << "\"" << row.first << "\":"; - mapnik::util::apply_visitor(json_converter(out), row.second); + if (row.first == "center" || row.first == "bounds") { + out << "[" << row.second << "]"; + } else { + mapnik::util::apply_visitor(json_converter(out), row.second); + } out << ","; } diff --git a/test/tilejson.cpp b/test/tilejson.cpp index 64223a8..0bd3641 100644 --- a/test/tilejson.cpp +++ b/test/tilejson.cpp @@ -92,6 +92,22 @@ void test_tilejson_generate_numeric() { } } + // Some params need to be arrays of integers + for (auto ¶m : {"center", "bounds"}) { + // The same check as above for presense + sregex is_present = as_xpr('"') >> param >> '"' >> *space >> as_xpr(':'); + if (regex_search(json.begin(), json.end(), is_present)) { + sregex is_array = as_xpr('"') >> param >> '"' >> *space >> as_xpr(':') + >> *space >> as_xpr('['); + + if (!regex_search(json.begin(), json.end(), is_array)) { + throw std::runtime_error( + (boost::format("Parameter \"%1%\" should be an array of numbers, but is not " + "in TileJSON: %2%") % param % json).str()); + } + } + } + } catch (const std::exception &e) { std::throw_with_nested( std::runtime_error( diff --git a/test/tilejson_params.xml b/test/tilejson_params.xml index a77a255..b758087 100644 --- a/test/tilejson_params.xml +++ b/test/tilejson_params.xml @@ -2,7 +2,8 @@ srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over"> 1 - -75.6038,40.0799,11 + -75,40,11 + -180,-85,180,85 16 0 From 6bdb3f748bcab0b1a560aed8ad89501d133c1143 Mon Sep 17 00:00:00 2001 From: Paul Norman Date: Wed, 10 Dec 2014 16:45:49 -0800 Subject: [PATCH 2/2] Check for membership in an unorrdered set instead of hard-coded or --- src/tilejson.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tilejson.cpp b/src/tilejson.cpp index 6ecc6d8..6a8940d 100644 --- a/src/tilejson.cpp +++ b/src/tilejson.cpp @@ -13,6 +13,8 @@ #include #include +#include + namespace bpt = boost::property_tree; namespace bal = boost::algorithm; @@ -177,6 +179,7 @@ mapnik::parameters make_default_parameters() { std::string make_tilejson(const mapnik::Map &map, const std::string &base_url) { static const mapnik::parameters defaults = make_default_parameters(); + static const std::unordered_set array_keys = {"center", "bounds"}; // TODO: remove super-hacky hard-coded 'JSON' serialiser and use // a proper one. @@ -216,7 +219,7 @@ std::string make_tilejson(const mapnik::Map &map, for (auto const &row : params) { out << "\"" << row.first << "\":"; - if (row.first == "center" || row.first == "bounds") { + if (array_keys.count(row.first) > 0) { out << "[" << row.second << "]"; } else { mapnik::util::apply_visitor(json_converter(out), row.second);