diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bdf0e468..165d2b4a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Released ... Summary: TODO +- CSV Plugin: added the ability to pass an `extent` in options + - Fixed crash when rendering to cairo context from python (#2031) - Moved `label-position-tolerance` from unsigned type to double diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index e1478cd36..c55318b2d 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -73,7 +73,8 @@ csv_datasource::csv_datasource(parameters const& params) manual_headers_(mapnik::util::trim_copy(*params.get("headers", ""))), strict_(*params.get("strict", false)), filesize_max_(*params.get("filesize_max", 20.0)), // MB - ctx_(boost::make_shared()) + ctx_(boost::make_shared()), + extent_initialized_(false) { /* TODO: general: @@ -97,6 +98,12 @@ csv_datasource::csv_datasource(parameters const& params) http://boost-spirit.com/home/articles/qi-example/tracking-the-input-position-while-parsing/ */ + boost::optional ext = params.get("extent"); + if (ext && !ext->empty()) + { + extent_initialized_ = extent_.from_string(*ext); + } + boost::optional inline_string = params.get("inline"); if (inline_string) { @@ -407,7 +414,8 @@ void csv_datasource::parse_csv(T & stream, } mapnik::value_integer feature_count(0); - bool extent_initialized = false; + bool extent_started = false; + std::size_t num_headers = headers_.size(); for (std::size_t i = 0; i < headers_.size(); ++i) @@ -740,14 +748,17 @@ void csv_datasource::parse_csv(T & stream, { if (parsed_wkt || parsed_json) { - if (!extent_initialized) + if (!extent_initialized_) { - extent_initialized = true; - extent_ = feature->envelope(); - } - else - { - extent_.expand_to_include(feature->envelope()); + if (!extent_started) + { + extent_started = true; + extent_ = feature->envelope(); + } + else + { + extent_.expand_to_include(feature->envelope()); + } } features_.push_back(feature); null_geom = false; @@ -778,14 +789,17 @@ void csv_datasource::parse_csv(T & stream, feature->add_geometry(pt); features_.push_back(feature); null_geom = false; - if (!extent_initialized) + if (!extent_initialized_) { - extent_initialized = true; - extent_ = feature->envelope(); - } - else - { - extent_.expand_to_include(feature->envelope()); + if (!extent_started) + { + extent_started = true; + extent_ = feature->envelope(); + } + else + { + extent_.expand_to_include(feature->envelope()); + } } } else if (parsed_x || parsed_y) diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp index 0d9e28b34..b5b695b29 100644 --- a/plugins/input/csv/csv_datasource.hpp +++ b/plugins/input/csv/csv_datasource.hpp @@ -76,6 +76,7 @@ private: bool strict_; double filesize_max_; mapnik::context_ptr ctx_; + bool extent_initialized_; }; #endif // MAPNIK_CSV_DATASOURCE_HPP diff --git a/tests/python_tests/csv_test.py b/tests/python_tests/csv_test.py index 75cce7df8..644b9ef5e 100644 --- a/tests/python_tests/csv_test.py +++ b/tests/python_tests/csv_test.py @@ -570,6 +570,17 @@ if 'csv' in mapnik.DatasourceCache.plugin_names(): eq_(desc['geometry_type'],mapnik.DataGeometryType.Point) eq_(len(ds.all_features()),8) + def test_manually_supplied_extent(**kwargs): + csv_string = ''' + wkt,Name + ''' + ds = mapnik.Datasource(**{"type":"csv","extent":"-180,-90,180,90","inline":csv_string}) + b = ds.envelope() + eq_(b.minx,-180) + eq_(b.miny,-90) + eq_(b.maxx,180) + eq_(b.maxy,90) + if __name__ == "__main__": setup() [eval(run)(visual=True) for run in dir() if 'test_' in run]