diff --git a/utils/mapnik-index/mapnik-index.cpp b/utils/mapnik-index/mapnik-index.cpp index a19b1f129..a8f367332 100644 --- a/utils/mapnik-index/mapnik-index.cpp +++ b/utils/mapnik-index/mapnik-index.cpp @@ -61,6 +61,7 @@ int main (int argc, char** argv) //using namespace mapnik; namespace po = boost::program_options; bool verbose = false; + bool validate_features = false; unsigned int depth = DEFAULT_DEPTH; double ratio = DEFAULT_RATIO; std::vector files; @@ -80,6 +81,7 @@ int main (int argc, char** argv) ("quote,q", po::value(), "CSV columns quote") ("manual-headers,H", po::value(), "CSV manual headers string") ("files",po::value >(),"Files to index: file1 file2 ...fileN") + ("validate-features", "Validate GeoJSON features") ; po::positional_options_description p; @@ -102,6 +104,10 @@ int main (int argc, char** argv) { verbose = true; } + if (vm.count("validate-features")) + { + validate_features = true; + } if (vm.count("depth")) { depth = vm["depth"].as(); @@ -180,7 +186,7 @@ int main (int argc, char** argv) else if (mapnik::detail::is_geojson(filename)) { std::clog << "processing '" << filename << "' as GeoJSON\n"; - auto result = mapnik::detail::process_geojson_file(boxes, filename); + auto result = mapnik::detail::process_geojson_file(boxes, filename, validate_features); if (!result.first) continue; extent = result.second; } diff --git a/utils/mapnik-index/process_geojson_file.cpp b/utils/mapnik-index/process_geojson_file.cpp index 1ca0be752..b8f30894c 100644 --- a/utils/mapnik-index/process_geojson_file.cpp +++ b/utils/mapnik-index/process_geojson_file.cpp @@ -39,16 +39,30 @@ #include #include +#include namespace { +struct feature_validate_callback +{ + feature_validate_callback() {} + + void operator() (mapnik::feature_ptr const& f) const + { + auto bbox = f->envelope(); + std::cerr << bbox << std::endl; + } +}; + using base_iterator_type = char const*; const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; +const mapnik::transcoder tr("utf8"); +const mapnik::json::feature_grammar_callback fc_grammar(tr); } namespace mapnik { namespace detail { template -std::pair> process_geojson_file(T & boxes, std::string const& filename) +std::pair> process_geojson_file(T & boxes, std::string const& filename, bool validate_features) { mapnik::box2d extent; #if defined(MAPNIK_MEMORY_MAPPED_FILE) @@ -81,9 +95,10 @@ std::pair> process_geojson_file(T & boxes, std::string const& #endif boost::spirit::standard::space_type space; + auto const* itr = start; try { - if (!boost::spirit::qi::phrase_parse(start, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) + if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) { std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl; return std::make_pair(false, extent); @@ -93,12 +108,28 @@ std::pair> process_geojson_file(T & boxes, std::string const& { std::clog << "mapnik-index (GeoJSON): " << ex.what() << std::endl; } + mapnik::context_ptr ctx = std::make_shared(); + std::size_t start_id = 1; for (auto const& item : boxes) { if (item.first.valid()) { if (!extent.valid()) extent = item.first; else extent.expand_to_include(item.first); + + if (validate_features) + { + base_iterator_type feat_itr = start + item.second.first; + base_iterator_type feat_end = feat_itr + item.second.second; + feature_validate_callback callback; + bool result = boost::spirit::qi::phrase_parse(feat_itr, feat_end, (fc_grammar) + (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), + space); + if (!result || feat_itr != feat_end) + { + return std::make_pair(false, extent); + } + } } } return std::make_pair(true, extent); @@ -107,6 +138,6 @@ std::pair> process_geojson_file(T & boxes, std::string const& using box_type = mapnik::box2d; using item_type = std::pair>; using boxes_type = std::vector; -template std::pair> process_geojson_file(boxes_type&, std::string const&); +template std::pair> process_geojson_file(boxes_type&, std::string const&, bool); }} diff --git a/utils/mapnik-index/process_geojson_file.hpp b/utils/mapnik-index/process_geojson_file.hpp index d7ccd634f..a4d468ad2 100644 --- a/utils/mapnik-index/process_geojson_file.hpp +++ b/utils/mapnik-index/process_geojson_file.hpp @@ -29,7 +29,7 @@ namespace mapnik { namespace detail { template -std::pair> process_geojson_file(T & boxes, std::string const& filename); +std::pair> process_geojson_file(T & boxes, std::string const& filename, bool validate_features); }}