mapnik-index - refactor to use box2d<float> and reduce memory requirement during index creations
This commit is contained in:
parent
450533ebc6
commit
7cd5301cbe
8 changed files with 45 additions and 34 deletions
|
@ -238,8 +238,12 @@ void csv_file_parser::add_feature(mapnik::value_integer, mapnik::csv_line const
|
|||
// no-op by default
|
||||
}
|
||||
|
||||
void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, boxes_type & boxes)
|
||||
template <typename T>
|
||||
void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes)
|
||||
{
|
||||
using boxes_type = T;
|
||||
using box_type = typename boxes_type::value_type::first_type;
|
||||
|
||||
auto file_length = detail::file_length(csv_file);
|
||||
// set back to start
|
||||
csv_file.seekg(0, std::ios::beg);
|
||||
|
@ -412,7 +416,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, boxes_type &
|
|||
else
|
||||
extent_ = box;
|
||||
}
|
||||
boxes.emplace_back(box, make_pair(record_offset, record_size));
|
||||
boxes.emplace_back(box_type(box), make_pair(record_offset, record_size));
|
||||
add_feature(++feature_count, values);
|
||||
}
|
||||
else
|
||||
|
@ -496,4 +500,8 @@ mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> con
|
|||
return geom;
|
||||
}
|
||||
|
||||
template void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, std::vector<std::pair<mapnik::box2d<double>, std::pair<std::size_t, std::size_t>>> & boxes);
|
||||
|
||||
template void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, std::vector<std::pair<mapnik::box2d<float>, std::pair<std::size_t, std::size_t>>> & boxes);
|
||||
|
||||
} // namespace csv_utils
|
||||
|
|
|
@ -130,11 +130,8 @@ void process_properties(Feature & feature, Headers const& headers, Values const&
|
|||
|
||||
struct csv_file_parser
|
||||
{
|
||||
using box_type = mapnik::box2d<double>;
|
||||
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
|
||||
using boxes_type = std::vector<item_type>;
|
||||
|
||||
void parse_csv_and_boxes(std::istream & csv_file, boxes_type & boxes);
|
||||
template <typename T>
|
||||
void parse_csv_and_boxes(std::istream & csv_file, T & boxes);
|
||||
|
||||
virtual void add_feature(mapnik::value_integer index, mapnik::csv_line const & values);
|
||||
|
||||
|
|
|
@ -192,12 +192,14 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
|||
}
|
||||
|
||||
namespace {
|
||||
using box_type = box2d<double>;
|
||||
using boxes_type = std::vector<std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
|
||||
using base_iterator_type = char const*;
|
||||
const mapnik::transcoder geojson_datasource_static_tr("utf8");
|
||||
const mapnik::json::feature_collection_grammar<base_iterator_type,mapnik::feature_impl> geojson_datasource_static_fc_grammar(geojson_datasource_static_tr);
|
||||
const mapnik::json::feature_grammar_callback<base_iterator_type,mapnik::feature_impl> geojson_datasource_static_feature_callback_grammar(geojson_datasource_static_tr);
|
||||
const mapnik::json::feature_grammar<base_iterator_type, mapnik::feature_impl> geojson_datasource_static_feature_grammar(geojson_datasource_static_tr);
|
||||
const mapnik::json::extract_bounding_box_grammar<base_iterator_type> geojson_datasource_static_bbox_grammar;
|
||||
const mapnik::json::extract_bounding_box_grammar<base_iterator_type, boxes_type> geojson_datasource_static_bbox_grammar;
|
||||
}
|
||||
|
||||
void geojson_datasource::initialise_descriptor(mapnik::feature_ptr const& feature)
|
||||
|
@ -257,7 +259,7 @@ void geojson_datasource::initialise_disk_index(std::string const& filename)
|
|||
template <typename Iterator>
|
||||
void geojson_datasource::initialise_index(Iterator start, Iterator end)
|
||||
{
|
||||
mapnik::json::boxes_type boxes;
|
||||
boxes_type boxes;
|
||||
boost::spirit::standard::space_type space;
|
||||
Iterator itr = start;
|
||||
if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space))
|
||||
|
|
|
@ -163,7 +163,7 @@ int main (int argc, char** argv)
|
|||
std::clog << "max tree depth:" << depth << std::endl;
|
||||
std::clog << "split ratio:" << ratio << std::endl;
|
||||
|
||||
using box_type = mapnik::box2d<double>;
|
||||
using box_type = mapnik::box2d<float>;
|
||||
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
|
||||
|
||||
for (auto const& filename : files_to_process)
|
||||
|
@ -175,7 +175,7 @@ int main (int argc, char** argv)
|
|||
}
|
||||
|
||||
std::vector<item_type> boxes;
|
||||
mapnik::box2d<double> extent;
|
||||
box_type extent;
|
||||
if (mapnik::detail::is_csv(filename))
|
||||
{
|
||||
std::clog << "processing '" << filename << "' as CSV\n";
|
||||
|
@ -198,10 +198,12 @@ int main (int argc, char** argv)
|
|||
if (extent.valid())
|
||||
{
|
||||
std::clog << extent << std::endl;
|
||||
mapnik::quad_tree<std::pair<std::size_t, std::size_t>> tree(extent, depth, ratio);
|
||||
mapnik::box2d<double> extent_d(extent.minx(), extent.miny(), extent.maxx(), extent.maxy());
|
||||
mapnik::quad_tree<std::pair<std::size_t, std::size_t>> tree(extent_d, depth, ratio);
|
||||
for (auto const& item : boxes)
|
||||
{
|
||||
tree.insert(std::get<1>(item), std::get<0>(item));
|
||||
auto ext_f = std::get<0>(item);
|
||||
tree.insert(std::get<1>(item), mapnik::box2d<double>(ext_f.minx(), ext_f.miny(), ext_f.maxx(), ext_f.maxy()));
|
||||
}
|
||||
|
||||
std::fstream file((filename + ".index").c_str(),
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
namespace mapnik { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
|
||||
std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
|
||||
{
|
||||
csv_utils::csv_file_parser p;
|
||||
p.manual_headers_ = manual_headers;
|
||||
|
@ -65,7 +65,7 @@ std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& fil
|
|||
else
|
||||
{
|
||||
std::clog << "Error : cannot mmap " << filename << std::endl;
|
||||
return std::make_pair(false, p.extent_);
|
||||
return std::make_pair(false, box2d<float>(p.extent_));
|
||||
}
|
||||
#else
|
||||
#if defined(_WINDOWS)
|
||||
|
@ -76,24 +76,24 @@ std::pair<bool,box2d<double>> process_csv_file(T & boxes, std::string const& fil
|
|||
if (!csv_file.is_open())
|
||||
{
|
||||
std::clog << "Error : cannot open " << filename << std::endl;
|
||||
return std::make_pair(false, p.extent_);
|
||||
return std::make_pair(false, box2d<float>(p.extent_));
|
||||
}
|
||||
#endif
|
||||
try
|
||||
{
|
||||
p.parse_csv_and_boxes(csv_file, boxes);
|
||||
return std::make_pair(true, p.extent_);
|
||||
return std::make_pair(true, box2d<float>(p.extent_));
|
||||
}
|
||||
catch (std::exception const& ex)
|
||||
{
|
||||
std::clog << ex.what() << std::endl;
|
||||
return std::make_pair(false, p.extent_);
|
||||
return std::make_pair(false, box2d<float>(p.extent_));
|
||||
}
|
||||
}
|
||||
|
||||
using box_type = mapnik::box2d<double>;
|
||||
using box_type = mapnik::box2d<float>;
|
||||
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
|
||||
using boxes_type = std::vector<item_type>;
|
||||
template std::pair<bool,box2d<double>> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
|
||||
template std::pair<bool,box_type> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
|
||||
|
||||
}}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
namespace mapnik { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool, box2d<double>> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote);
|
||||
std::pair<bool, typename T::value_type::first_type> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote);
|
||||
|
||||
}}
|
||||
|
||||
|
|
|
@ -38,33 +38,38 @@
|
|||
#include <mapnik/json/feature_collection_grammar_impl.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct feature_validate_callback
|
||||
{
|
||||
feature_validate_callback(mapnik::box2d<double> const& box)
|
||||
feature_validate_callback(mapnik::box2d<T> const& box)
|
||||
: box_(box) {}
|
||||
|
||||
void operator() (mapnik::feature_ptr const& f) const
|
||||
{
|
||||
if (box_ != f->envelope())
|
||||
if (box_ != box_)
|
||||
{
|
||||
throw std::runtime_error("Bounding boxes mismatch validation feature");
|
||||
}
|
||||
}
|
||||
mapnik::box2d<double> const& box_;
|
||||
mapnik::box2d<T> const& box_;
|
||||
};
|
||||
|
||||
using box_type = mapnik::box2d<float>;
|
||||
using boxes_type = std::vector<std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
|
||||
using base_iterator_type = char const*;
|
||||
const mapnik::json::extract_bounding_box_grammar<base_iterator_type> geojson_datasource_static_bbox_grammar;
|
||||
const mapnik::json::extract_bounding_box_grammar<base_iterator_type, boxes_type> geojson_datasource_static_bbox_grammar;
|
||||
const mapnik::transcoder tr("utf8");
|
||||
const mapnik::json::feature_grammar_callback<base_iterator_type, mapnik::feature_impl, feature_validate_callback> fc_grammar(tr);
|
||||
const mapnik::json::feature_grammar_callback<base_iterator_type, mapnik::feature_impl, feature_validate_callback<float>> fc_grammar(tr);
|
||||
}
|
||||
|
||||
namespace mapnik { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose)
|
||||
std::pair<bool,typename T::value_type::first_type> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose)
|
||||
{
|
||||
mapnik::box2d<double> extent;
|
||||
using box_type = typename T::value_type::first_type;
|
||||
box_type extent;
|
||||
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
||||
mapnik::mapped_region_ptr mapped_region;
|
||||
boost::optional<mapnik::mapped_region_ptr> memory =
|
||||
|
@ -121,7 +126,7 @@ std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const&
|
|||
{
|
||||
base_iterator_type feat_itr = start + item.second.first;
|
||||
base_iterator_type feat_end = feat_itr + item.second.second;
|
||||
feature_validate_callback callback(item.first);
|
||||
feature_validate_callback<float> callback(item.first);
|
||||
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);
|
||||
|
@ -136,9 +141,6 @@ std::pair<bool,box2d<double>> process_geojson_file(T & boxes, std::string const&
|
|||
return std::make_pair(true, extent);
|
||||
}
|
||||
|
||||
using box_type = mapnik::box2d<double>;
|
||||
using item_type = std::pair<box_type, std::pair<std::size_t, std::size_t>>;
|
||||
using boxes_type = std::vector<item_type>;
|
||||
template std::pair<bool,box2d<double>> process_geojson_file(boxes_type&, std::string const&, bool, bool);
|
||||
template std::pair<bool,box_type> process_geojson_file(boxes_type&, std::string const&, bool, bool);
|
||||
|
||||
}}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
namespace mapnik { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool, box2d<double>> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose);
|
||||
std::pair<bool, typename T::value_type::first_type> process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose);
|
||||
|
||||
}}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue