diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 16f7f9de3..d90daabd1 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -323,7 +323,7 @@ void csv_datasource::parse_csv(T & stream) { auto values = csv_utils::parse_line(csv_line, separator_, quote_); unsigned num_fields = values.size(); - if (num_fields > num_headers) + if (num_fields > num_headers || num_fields < num_headers) { std::ostringstream s; s << "CSV Plugin: # of columns(" @@ -331,14 +331,6 @@ void csv_datasource::parse_csv(T & stream) << num_headers << ") parsed for row " << line_number << "\n"; throw mapnik::datasource_exception(s.str()); } - else if (num_fields < num_headers) - { - std::ostringstream s; - s << "CSV Plugin: # of headers(" - << num_headers << ") > # of columns(" - << num_fields << ") parsed for row " << line_number << "\n"; - throw mapnik::datasource_exception(s.str()); - } auto geom = detail::extract_geometry(values, locator_); if (!geom.is()) @@ -497,40 +489,88 @@ template boost::optional csv_datasource::get_geometry_type_impl(T & stream) const { boost::optional result; - int multi_type = 0; - auto itr = tree_->qbegin(boost::geometry::index::intersects(extent_)); - auto end = tree_->qend(); - for (std::size_t count = 0; itr !=end && count < 5; ++itr, ++count) + if (tree_) { - csv_datasource::item_type const& item = *itr; - std::size_t file_offset = item.second.first; - std::size_t size = item.second.second; - stream.seekg(file_offset); - std::vector record; - record.resize(size); - stream.read(record.data(), size); - std::string str(record.begin(), record.end()); - try + int multi_type = 0; + auto itr = tree_->qbegin(boost::geometry::index::intersects(extent_)); + auto end = tree_->qend(); + for (std::size_t count = 0; itr !=end && count < 5; ++itr, ++count) { - auto values = csv_utils::parse_line(str, separator_, quote_); - auto geom = detail::extract_geometry(values, locator_); - result = mapnik::util::to_ds_type(geom); - if (result) + csv_datasource::item_type const& item = *itr; + std::size_t file_offset = item.second.first; + std::size_t size = item.second.second; + stream.seekg(file_offset); + std::vector record; + record.resize(size); + stream.read(record.data(), size); + std::string str(record.begin(), record.end()); + try { - int type = static_cast(*result); - if (multi_type > 0 && multi_type != type) + auto values = csv_utils::parse_line(str, separator_, quote_); + auto geom = detail::extract_geometry(values, locator_); + result = mapnik::util::to_ds_type(geom); + if (result) { - result.reset(mapnik::datasource_geometry_t::Collection); - return result; + int type = static_cast(*result); + if (multi_type > 0 && multi_type != type) + { + result.reset(mapnik::datasource_geometry_t::Collection); + return result; + } + multi_type = type; } - multi_type = type; + } + catch (std::exception const& ex) + { + if (strict_) throw ex; + else MAPNIK_LOG_ERROR(csv) << ex.what(); } } - catch (std::exception const& ex) + } + else + { + // try reading *.index + using value_type = std::pair; + std::ifstream index(filename_ + ".index", std::ios::binary); + if (!index) throw mapnik::datasource_exception("CSV Plugin: could not open: '" + filename_ + ".index'"); + + mapnik::filter_in_box filter(extent_); + std::vector positions; + mapnik::util::spatial_index::query_first_n(filter, index, positions, 5); + int multi_type = 0; + for (auto const& val : positions) { - if (strict_) throw ex; - else MAPNIK_LOG_ERROR(csv) << ex.what(); + std::cerr << val.first << ":" << val.second << std::endl; + stream.seekg(val.first); + std::vector record; + record.resize(val.second); + stream.read(record.data(), val.second); + std::string str(record.begin(), record.end()); + try + { + auto values = csv_utils::parse_line(str, separator_, quote_); + auto geom = detail::extract_geometry(values, locator_); + result = mapnik::util::to_ds_type(geom); + if (result) + { + int type = static_cast(*result); + if (multi_type > 0 && multi_type != type) + { + result.reset(mapnik::datasource_geometry_t::Collection); + return result; + } + multi_type = type; + } + } + catch (std::exception const& ex) + { + if (strict_) throw ex; + else MAPNIK_LOG_ERROR(csv) << ex.what(); + } } + } return result; }