ensure tests pass with no plugins built
This commit is contained in:
parent
a4753f4c87
commit
1eea7294ae
3 changed files with 550 additions and 534 deletions
|
@ -10,7 +10,7 @@
|
|||
#include <mapnik/expression.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
|
||||
#include <mapnik/util/fs.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
@ -157,519 +157,525 @@ void require_geometry(mapnik::feature_ptr feature,
|
|||
}
|
||||
} // anonymous namespace
|
||||
|
||||
const bool registered = mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
||||
|
||||
TEST_CASE("csv") {
|
||||
REQUIRE(registered);
|
||||
|
||||
// make the tests silent since we intentially test error conditions that are noisy
|
||||
auto const severity = mapnik::logger::instance().get_severity();
|
||||
mapnik::logger::instance().set_severity(mapnik::logger::none);
|
||||
std::string csv_plugin("./plugins/input/csv.input");
|
||||
if (mapnik::util::exists(csv_plugin))
|
||||
{
|
||||
|
||||
// check the CSV datasource is loaded
|
||||
const std::vector<std::string> plugin_names =
|
||||
mapnik::datasource_cache::instance().plugin_names();
|
||||
const bool have_csv_plugin =
|
||||
std::find(plugin_names.begin(), plugin_names.end(), "csv") != plugin_names.end();
|
||||
const bool registered = mapnik::datasource_cache::instance().register_datasources(csv_plugin);
|
||||
|
||||
SECTION("broken files") {
|
||||
if (have_csv_plugin) {
|
||||
std::vector<bfs::path> broken;
|
||||
add_csv_files("test/data/csv/fails", broken);
|
||||
add_csv_files("test/data/csv/warns", broken);
|
||||
broken.emplace_back("test/data/csv/fails/does_not_exist.csv");
|
||||
REQUIRE(registered);
|
||||
|
||||
for (auto const &path : broken) {
|
||||
REQUIRE_THROWS(get_csv_ds(path.native()));
|
||||
}
|
||||
}
|
||||
} // END SECTION
|
||||
// make the tests silent since we intentially test error conditions that are noisy
|
||||
auto const severity = mapnik::logger::instance().get_severity();
|
||||
mapnik::logger::instance().set_severity(mapnik::logger::none);
|
||||
|
||||
SECTION("good files") {
|
||||
if (have_csv_plugin) {
|
||||
std::vector<bfs::path> good;
|
||||
add_csv_files("test/data/csv", good);
|
||||
add_csv_files("test/data/csv/warns", good);
|
||||
// check the CSV datasource is loaded
|
||||
const std::vector<std::string> plugin_names =
|
||||
mapnik::datasource_cache::instance().plugin_names();
|
||||
const bool have_csv_plugin =
|
||||
std::find(plugin_names.begin(), plugin_names.end(), "csv") != plugin_names.end();
|
||||
|
||||
for (auto const &path : good) {
|
||||
auto ds = get_csv_ds(path.native(), false);
|
||||
// require a non-null pointer returned
|
||||
REQUIRE(bool(ds));
|
||||
}
|
||||
}
|
||||
} // END SECTION
|
||||
SECTION("broken files") {
|
||||
if (have_csv_plugin) {
|
||||
std::vector<bfs::path> broken;
|
||||
add_csv_files("test/data/csv/fails", broken);
|
||||
add_csv_files("test/data/csv/warns", broken);
|
||||
broken.emplace_back("test/data/csv/fails/does_not_exist.csv");
|
||||
|
||||
SECTION("lon/lat detection") {
|
||||
for (auto const &lon_name : {std::string("lon"), std::string("lng")}) {
|
||||
auto ds = get_csv_ds((boost::format("test/data/csv/%1%_lat.csv") % lon_name).str());
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {lon_name, "lat"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer});
|
||||
for (auto const &path : broken) {
|
||||
REQUIRE_THROWS(get_csv_ds(path.native()));
|
||||
}
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
SECTION("good files") {
|
||||
if (have_csv_plugin) {
|
||||
std::vector<bfs::path> good;
|
||||
add_csv_files("test/data/csv", good);
|
||||
add_csv_files("test/data/csv/warns", good);
|
||||
|
||||
mapnik::query query(ds->envelope());
|
||||
for (auto const &field : fields) {
|
||||
query.add_property_name(field.get_name());
|
||||
}
|
||||
auto features = ds->features(query);
|
||||
auto feature = features->next();
|
||||
for (auto const &path : good) {
|
||||
auto ds = get_csv_ds(path.native(), false);
|
||||
// require a non-null pointer returned
|
||||
REQUIRE(bool(ds));
|
||||
}
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
require_attributes(feature, {
|
||||
attr { lon_name, mapnik::value_integer(0) },
|
||||
attr { "lat", mapnik::value_integer(0) }
|
||||
});
|
||||
}
|
||||
} // END SECTION
|
||||
SECTION("lon/lat detection") {
|
||||
for (auto const &lon_name : {std::string("lon"), std::string("lng")}) {
|
||||
auto ds = get_csv_ds((boost::format("test/data/csv/%1%_lat.csv") % lon_name).str());
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {lon_name, "lat"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer});
|
||||
|
||||
SECTION("type detection") {
|
||||
auto ds = get_csv_ds("test/data/csv/nypd.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"});
|
||||
require_field_types(fields, {mapnik::String, mapnik::String, mapnik::String, mapnik::String, mapnik::Double, mapnik::Double, mapnik::String});
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 2);
|
||||
mapnik::query query(ds->envelope());
|
||||
for (auto const &field : fields) {
|
||||
query.add_property_name(field.get_name());
|
||||
}
|
||||
auto features = ds->features(query);
|
||||
auto feature = features->next();
|
||||
|
||||
auto feature = all_features(ds)->next();
|
||||
require_attributes(feature, {
|
||||
attr { "City", mapnik::value_unicode_string("New York, NY") }
|
||||
, attr { "geo_accuracy", mapnik::value_unicode_string("house") }
|
||||
, attr { "Phone", mapnik::value_unicode_string("(212) 334-0711") }
|
||||
, attr { "Address", mapnik::value_unicode_string("19 Elizabeth Street") }
|
||||
, attr { "Precinct", mapnik::value_unicode_string("5th Precinct") }
|
||||
, attr { "geo_longitude", mapnik::value_integer(-70) }
|
||||
, attr { "geo_latitude", mapnik::value_integer(40) }
|
||||
});
|
||||
} // END SECTION
|
||||
require_attributes(feature, {
|
||||
attr { lon_name, mapnik::value_integer(0) },
|
||||
attr { "lat", mapnik::value_integer(0) }
|
||||
});
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("skipping blank rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/blank_rows.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
SECTION("type detection") {
|
||||
auto ds = get_csv_ds("test/data/csv/nypd.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"Precinct", "Phone", "Address", "City", "geo_longitude", "geo_latitude", "geo_accuracy"});
|
||||
require_field_types(fields, {mapnik::String, mapnik::String, mapnik::String, mapnik::String, mapnik::Double, mapnik::Double, mapnik::String});
|
||||
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 2);
|
||||
} // END SECTION
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 2);
|
||||
|
||||
SECTION("empty rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/empty_rows.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "text", "date", "integer", "boolean", "float", "time", "datetime", "empty_column"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Integer, mapnik::Boolean, mapnik::Double, mapnik::String, mapnik::String, mapnik::String});
|
||||
auto feature = all_features(ds)->next();
|
||||
require_attributes(feature, {
|
||||
attr { "City", mapnik::value_unicode_string("New York, NY") }
|
||||
, attr { "geo_accuracy", mapnik::value_unicode_string("house") }
|
||||
, attr { "Phone", mapnik::value_unicode_string("(212) 334-0711") }
|
||||
, attr { "Address", mapnik::value_unicode_string("19 Elizabeth Street") }
|
||||
, attr { "Precinct", mapnik::value_unicode_string("5th Precinct") }
|
||||
, attr { "geo_longitude", mapnik::value_integer(-70) }
|
||||
, attr { "geo_latitude", mapnik::value_integer(40) }
|
||||
});
|
||||
} // END SECTION
|
||||
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 4);
|
||||
SECTION("skipping blank rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/blank_rows.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
auto feature = featureset->next();
|
||||
require_attributes(feature, {
|
||||
attr { "x", mapnik::value_integer(0) }
|
||||
, attr { "empty_column", mapnik::value_unicode_string("") }
|
||||
, attr { "text", mapnik::value_unicode_string("a b") }
|
||||
, attr { "float", mapnik::value_double(1.0) }
|
||||
, attr { "datetime", mapnik::value_unicode_string("1971-01-01T04:14:00") }
|
||||
, attr { "y", mapnik::value_integer(0) }
|
||||
, attr { "boolean", mapnik::value_bool(true) }
|
||||
, attr { "time", mapnik::value_unicode_string("04:14:00") }
|
||||
, attr { "date", mapnik::value_unicode_string("1971-01-01") }
|
||||
, attr { "integer", mapnik::value_integer(40) }
|
||||
});
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 2);
|
||||
} // END SECTION
|
||||
|
||||
while (bool(feature = featureset->next())) {
|
||||
CHECK(feature->size() == 10);
|
||||
CHECK(feature->get("empty_column") == mapnik::value_unicode_string(""));
|
||||
}
|
||||
} // END SECTION
|
||||
SECTION("empty rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/empty_rows.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "text", "date", "integer", "boolean", "float", "time", "datetime", "empty_column"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::Integer, mapnik::Boolean, mapnik::Double, mapnik::String, mapnik::String, mapnik::String});
|
||||
|
||||
SECTION("slashes") {
|
||||
auto ds = get_csv_ds("test/data/csv/has_attributes_with_slashes.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
// NOTE: y column is integer, even though a double value is used below in the test?
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
|
||||
CHECK(count_features(all_features(ds)) == 4);
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}
|
||||
, attr{"y", 0}
|
||||
, attr{"name", mapnik::value_unicode_string("a/a") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 1}
|
||||
, attr{"y", 4}
|
||||
, attr{"name", mapnik::value_unicode_string("b/b") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 10}
|
||||
, attr{"y", 2.5}
|
||||
, attr{"name", mapnik::value_unicode_string("c/c") } });
|
||||
} // END SECTION
|
||||
auto featureset = all_features(ds);
|
||||
auto feature = featureset->next();
|
||||
require_attributes(feature, {
|
||||
attr { "x", mapnik::value_integer(0) }
|
||||
, attr { "empty_column", mapnik::value_unicode_string("") }
|
||||
, attr { "text", mapnik::value_unicode_string("a b") }
|
||||
, attr { "float", mapnik::value_double(1.0) }
|
||||
, attr { "datetime", mapnik::value_unicode_string("1971-01-01T04:14:00") }
|
||||
, attr { "y", mapnik::value_integer(0) }
|
||||
, attr { "boolean", mapnik::value_bool(true) }
|
||||
, attr { "time", mapnik::value_unicode_string("04:14:00") }
|
||||
, attr { "date", mapnik::value_unicode_string("1971-01-01") }
|
||||
, attr { "integer", mapnik::value_integer(40) }
|
||||
});
|
||||
|
||||
SECTION("wkt field") {
|
||||
using mapnik::geometry::geometry_types;
|
||||
while (bool(feature = featureset->next())) {
|
||||
CHECK(feature->size() == 10);
|
||||
CHECK(feature->get("empty_column") == mapnik::value_unicode_string(""));
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/wkt.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"type"});
|
||||
require_field_types(fields, {mapnik::String});
|
||||
SECTION("slashes") {
|
||||
auto ds = get_csv_ds("test/data/csv/has_attributes_with_slashes.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
// NOTE: y column is integer, even though a double value is used below in the test?
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Point);
|
||||
require_geometry(featureset->next(), 1, geometry_types::LineString);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 4, geometry_types::MultiPoint);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiLineString);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
} // END SECTION
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}
|
||||
, attr{"y", 0}
|
||||
, attr{"name", mapnik::value_unicode_string("a/a") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 1}
|
||||
, attr{"y", 4}
|
||||
, attr{"name", mapnik::value_unicode_string("b/b") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 10}
|
||||
, attr{"y", 2.5}
|
||||
, attr{"name", mapnik::value_unicode_string("c/c") } });
|
||||
} // END SECTION
|
||||
|
||||
SECTION("handling of missing header") {
|
||||
// TODO: does this mean 'missing_header.csv' should be in the warnings
|
||||
// subdirectory, since it doesn't work in strict mode?
|
||||
auto ds = get_csv_ds("test/data/csv/missing_header.csv", false);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"one", "two", "x", "y", "_4", "aftermissing"});
|
||||
auto feature = all_features(ds)->next();
|
||||
REQUIRE(feature);
|
||||
REQUIRE(feature->has_key("_4"));
|
||||
CHECK(feature->get("_4") == mapnik::value_unicode_string("missing"));
|
||||
} // END SECTION
|
||||
SECTION("wkt field") {
|
||||
using mapnik::geometry::geometry_types;
|
||||
|
||||
SECTION("handling of headers that are numbers") {
|
||||
auto ds = get_csv_ds("test/data/csv/numbers_for_headers.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "1990", "1991", "1992"});
|
||||
auto feature = all_features(ds)->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}
|
||||
, attr{"y", 0}
|
||||
, attr{"1990", 1}
|
||||
, attr{"1991", 2}
|
||||
, attr{"1992", 3}
|
||||
});
|
||||
auto expression = mapnik::parse_expression("[1991]=2");
|
||||
REQUIRE(bool(expression));
|
||||
auto value = mapnik::util::apply_visitor(
|
||||
mapnik::evaluate<mapnik::feature_impl, mapnik::value_type, mapnik::attributes>(
|
||||
*feature, mapnik::attributes()), *expression);
|
||||
CHECK(value == true);
|
||||
} // END SECTION
|
||||
auto ds = get_csv_ds("test/data/csv/wkt.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"type"});
|
||||
require_field_types(fields, {mapnik::String});
|
||||
|
||||
SECTION("quoted numbers") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
auto featureset = all_features(ds);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Point);
|
||||
require_geometry(featureset->next(), 1, geometry_types::LineString);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 4, geometry_types::MultiPoint);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiLineString);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
} // END SECTION
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/quoted_numbers.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "label"});
|
||||
auto featureset = all_features(ds);
|
||||
SECTION("handling of missing header") {
|
||||
// TODO: does this mean 'missing_header.csv' should be in the warnings
|
||||
// subdirectory, since it doesn't work in strict mode?
|
||||
auto ds = get_csv_ds("test/data/csv/missing_header.csv", false);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"one", "two", "x", "y", "_4", "aftermissing"});
|
||||
auto feature = all_features(ds)->next();
|
||||
REQUIRE(feature);
|
||||
REQUIRE(feature->has_key("_4"));
|
||||
CHECK(feature->get("_4") == mapnik::value_unicode_string("missing"));
|
||||
} // END SECTION
|
||||
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"label", ustring("0,0") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 5}, attr{"y", 5}, attr{"label", ustring("5,5") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 5}, attr{"label", ustring("0,5") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 5}, attr{"y", 0}, attr{"label", ustring("5,0") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 2.5}, attr{"y", 2.5}, attr{"label", ustring("2.5,2.5") } });
|
||||
SECTION("handling of headers that are numbers") {
|
||||
auto ds = get_csv_ds("test/data/csv/numbers_for_headers.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "1990", "1991", "1992"});
|
||||
auto feature = all_features(ds)->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}
|
||||
, attr{"y", 0}
|
||||
, attr{"1990", 1}
|
||||
, attr{"1991", 2}
|
||||
, attr{"1992", 3}
|
||||
});
|
||||
auto expression = mapnik::parse_expression("[1991]=2");
|
||||
REQUIRE(bool(expression));
|
||||
auto value = mapnik::util::apply_visitor(
|
||||
mapnik::evaluate<mapnik::feature_impl, mapnik::value_type, mapnik::attributes>(
|
||||
*feature, mapnik::attributes()), *expression);
|
||||
CHECK(value == true);
|
||||
} // END SECTION
|
||||
|
||||
} // END SECTION
|
||||
SECTION("quoted numbers") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
SECTION("reading newlines") {
|
||||
for (auto const &platform : {std::string("windows"), std::string("mac")}) {
|
||||
std::string file_name = (boost::format("test/data/csv/%1%_newlines.csv") % platform).str();
|
||||
auto ds = get_csv_ds(file_name);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 1}, attr{"y", 10}, attr{"z", 9999.9999} });
|
||||
}
|
||||
} // END SECTION
|
||||
auto ds = get_csv_ds("test/data/csv/quoted_numbers.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "label"});
|
||||
auto featureset = all_features(ds);
|
||||
|
||||
SECTION("mixed newlines") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"label", ustring("0,0") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 5}, attr{"y", 5}, attr{"label", ustring("5,5") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 5}, attr{"label", ustring("0,5") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 5}, attr{"y", 0}, attr{"label", ustring("5,0") } });
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 2.5}, attr{"y", 2.5}, attr{"label", ustring("2.5,2.5") } });
|
||||
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/mac_newlines_with_unix_inline.csv")
|
||||
, std::string("test/data/csv/mac_newlines_with_unix_inline_escaped.csv")
|
||||
, std::string("test/data/csv/windows_newlines_with_unix_inline.csv")
|
||||
, std::string("test/data/csv/windows_newlines_with_unix_inline_escaped.csv")
|
||||
} // END SECTION
|
||||
|
||||
SECTION("reading newlines") {
|
||||
for (auto const &platform : {std::string("windows"), std::string("mac")}) {
|
||||
std::string file_name = (boost::format("test/data/csv/%1%_newlines.csv") % platform).str();
|
||||
auto ds = get_csv_ds(file_name);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 1}, attr{"y", 10}, attr{"z", 9999.9999} });
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("mixed newlines") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/mac_newlines_with_unix_inline.csv")
|
||||
, std::string("test/data/csv/mac_newlines_with_unix_inline_escaped.csv")
|
||||
, std::string("test/data/csv/windows_newlines_with_unix_inline.csv")
|
||||
, std::string("test/data/csv/windows_newlines_with_unix_inline_escaped.csv")
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "line"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}
|
||||
, attr{"line", ustring("many\n lines\n of text\n with unix newlines")} });
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("tabs") {
|
||||
auto ds = get_csv_ds("test/data/csv/tabs_in_csv.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", -122}, attr{"y", 48}, attr{"z", 0} });
|
||||
} // END SECTION
|
||||
|
||||
SECTION("separators") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/pipe_delimiters.csv")
|
||||
, std::string("test/data/csv/semicolon_delimiters.csv")
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"z", ustring("hello")} });
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("null and bool keywords are empty strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/nulls_and_booleans_as_strings.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "null", "boolean"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::Boolean});
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("null")}, attr{"boolean", true}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("")}, attr{"boolean", false}});
|
||||
} // END SECTION
|
||||
|
||||
SECTION("nonexistent query fields throw") {
|
||||
auto ds = get_csv_ds("test/data/csv/lon_lat.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"lon", "lat"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer});
|
||||
|
||||
mapnik::query query(ds->envelope());
|
||||
for (auto const &field : fields) {
|
||||
query.add_property_name(field.get_name());
|
||||
}
|
||||
// also add an invalid one, triggering throw
|
||||
query.add_property_name("bogus");
|
||||
|
||||
REQUIRE_THROWS(ds->features(query));
|
||||
} // END SECTION
|
||||
|
||||
SECTION("leading zeros mean strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/leading_zeros.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "fips"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("001")}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("003")}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("005")}});
|
||||
} // END SECTION
|
||||
|
||||
SECTION("advanced geometry detection") {
|
||||
using row = std::pair<std::string, mapnik::datasource_geometry_t>;
|
||||
|
||||
for (row r : {
|
||||
row{"point", mapnik::datasource_geometry_t::Point}
|
||||
, row{"poly", mapnik::datasource_geometry_t::Polygon}
|
||||
, row{"multi_poly", mapnik::datasource_geometry_t::Polygon}
|
||||
, row{"line", mapnik::datasource_geometry_t::LineString}
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "line"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}
|
||||
, attr{"line", ustring("many\n lines\n of text\n with unix newlines")} });
|
||||
}
|
||||
} // END SECTION
|
||||
std::string file_name = (boost::format("test/data/csv/%1%_wkt.csv") % r.first).str();
|
||||
auto ds = get_csv_ds(file_name);
|
||||
CHECK(ds->get_geometry_type() == r.second);
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("tabs") {
|
||||
auto ds = get_csv_ds("test/data/csv/tabs_in_csv.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", -122}, attr{"y", 48}, attr{"z", 0} });
|
||||
} // END SECTION
|
||||
SECTION("creation of CSV from in-memory strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
SECTION("separators") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
for (auto const &name : {std::string("Winthrop, WA"), std::string(u8"Qu\u00e9bec")}) {
|
||||
std::string csv_string =
|
||||
(boost::format(
|
||||
"wkt,Name\n"
|
||||
"\"POINT (120.15 48.47)\",\"%1%\"\n"
|
||||
) % name).str();
|
||||
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/pipe_delimiters.csv")
|
||||
, std::string("test/data/csv/semicolon_delimiters.csv")
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "z"});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"z", ustring("hello")} });
|
||||
}
|
||||
} // END SECTION
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
SECTION("null and bool keywords are empty strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
auto feature = all_features(ds)->next();
|
||||
REQUIRE(bool(feature));
|
||||
REQUIRE(feature->has_key("Name"));
|
||||
CHECK(feature->get("Name") == ustring(name.c_str()));
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/nulls_and_booleans_as_strings.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "null", "boolean"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::Boolean});
|
||||
SECTION("geojson quoting") {
|
||||
using mapnik::geometry::geometry_types;
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("null")}, attr{"boolean", true}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"null", ustring("")}, attr{"boolean", false}});
|
||||
} // END SECTION
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/geojson_double_quote_escape.csv")
|
||||
, std::string("test/data/csv/geojson_single_quote.csv")
|
||||
, std::string("test/data/csv/geojson_2x_double_quote_filebakery_style.csv")
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"type"});
|
||||
require_field_types(fields, {mapnik::String});
|
||||
|
||||
SECTION("nonexistent query fields throw") {
|
||||
auto ds = get_csv_ds("test/data/csv/lon_lat.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"lon", "lat"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer});
|
||||
auto featureset = all_features(ds);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Point);
|
||||
require_geometry(featureset->next(), 1, geometry_types::LineString);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 4, geometry_types::MultiPoint);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiLineString);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
mapnik::query query(ds->envelope());
|
||||
for (auto const &field : fields) {
|
||||
query.add_property_name(field.get_name());
|
||||
}
|
||||
// also add an invalid one, triggering throw
|
||||
query.add_property_name("bogus");
|
||||
SECTION("blank undelimited rows are still parsed") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
|
||||
REQUIRE_THROWS(ds->features(query));
|
||||
} // END SECTION
|
||||
// TODO: does this mean this CSV file should be in the warnings
|
||||
// subdirectory, since it doesn't work in strict mode?
|
||||
auto ds = get_csv_ds("test/data/csv/more_headers_than_column_values.csv", false);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "one", "two", "three"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::String});
|
||||
|
||||
SECTION("leading zeros mean strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"one", ustring("")}, attr{"two", ustring("")}, attr{"three", ustring("")} });
|
||||
} // END SECTION
|
||||
|
||||
auto ds = get_csv_ds("test/data/csv/leading_zeros.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "fips"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
SECTION("fewer headers than rows throws") {
|
||||
REQUIRE_THROWS(get_csv_ds("test/data/csv/more_column_values_than_headers.csv"));
|
||||
} // END SECTION
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("001")}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("003")}});
|
||||
require_attributes(featureset->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"fips", ustring("005")}});
|
||||
} // END SECTION
|
||||
SECTION("feature ID only incremented for valid rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/warns/feature_id_counting.csv", false);
|
||||
auto fs = all_features(ds);
|
||||
|
||||
SECTION("advanced geometry detection") {
|
||||
using row = std::pair<std::string, mapnik::datasource_geometry_t>;
|
||||
// first
|
||||
auto feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->id() == 1);
|
||||
|
||||
for (row r : {
|
||||
row{"point", mapnik::datasource_geometry_t::Point}
|
||||
, row{"poly", mapnik::datasource_geometry_t::Polygon}
|
||||
, row{"multi_poly", mapnik::datasource_geometry_t::Polygon}
|
||||
, row{"line", mapnik::datasource_geometry_t::LineString}
|
||||
}) {
|
||||
std::string file_name = (boost::format("test/data/csv/%1%_wkt.csv") % r.first).str();
|
||||
auto ds = get_csv_ds(file_name);
|
||||
CHECK(ds->get_geometry_type() == r.second);
|
||||
}
|
||||
} // END SECTION
|
||||
// second, should have skipped bogus one
|
||||
feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->id() == 2);
|
||||
|
||||
SECTION("creation of CSV from in-memory strings") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
feature = fs->next();
|
||||
CHECK(!feature);
|
||||
} // END SECTION
|
||||
|
||||
for (auto const &name : {std::string("Winthrop, WA"), std::string(u8"Qu\u00e9bec")}) {
|
||||
std::string csv_string =
|
||||
(boost::format(
|
||||
"wkt,Name\n"
|
||||
"\"POINT (120.15 48.47)\",\"%1%\"\n"
|
||||
) % name).str();
|
||||
SECTION("dynamically defining headers") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
using row = std::pair<std::string, std::size_t>;
|
||||
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
for (auto const &r : {
|
||||
row{"test/data/csv/fails/needs_headers_two_lines.csv", 2}
|
||||
, row{"test/data/csv/fails/needs_headers_one_line.csv", 1}
|
||||
, row{"test/data/csv/fails/needs_headers_one_line_no_newline.csv", 1}
|
||||
}) {
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["file"] = r.first;
|
||||
params["headers"] = "x,y,name";
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
auto feature = all_features(ds)->next();
|
||||
REQUIRE(bool(feature));
|
||||
REQUIRE(feature->has_key("Name"));
|
||||
CHECK(feature->get("Name") == ustring(name.c_str()));
|
||||
}
|
||||
} // END SECTION
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"name", ustring("data_name")} });
|
||||
REQUIRE(count_features(all_features(ds)) == r.second);
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("geojson quoting") {
|
||||
using mapnik::geometry::geometry_types;
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wlong-long"
|
||||
SECTION("64bit int fields work") {
|
||||
auto ds = get_csv_ds("test/data/csv/64bit_int.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "bigint"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Integer});
|
||||
|
||||
for (auto const &file : {
|
||||
std::string("test/data/csv/geojson_double_quote_escape.csv")
|
||||
, std::string("test/data/csv/geojson_single_quote.csv")
|
||||
, std::string("test/data/csv/geojson_2x_double_quote_filebakery_style.csv")
|
||||
}) {
|
||||
auto ds = get_csv_ds(file);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"type"});
|
||||
require_field_types(fields, {mapnik::String});
|
||||
auto fs = all_features(ds);
|
||||
auto feature = fs->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 2147483648} });
|
||||
|
||||
auto featureset = all_features(ds);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Point);
|
||||
require_geometry(featureset->next(), 1, geometry_types::LineString);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 1, geometry_types::Polygon);
|
||||
require_geometry(featureset->next(), 4, geometry_types::MultiPoint);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiLineString);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
require_geometry(featureset->next(), 2, geometry_types::MultiPolygon);
|
||||
}
|
||||
} // END SECTION
|
||||
feature = fs->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 9223372036854775807ll} });
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 0x7FFFFFFFFFFFFFFFll} });
|
||||
} // END SECTION
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
SECTION("blank undelimited rows are still parsed") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
SECTION("various number types") {
|
||||
auto ds = get_csv_ds("test/data/csv/number_types.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "floats"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Double});
|
||||
|
||||
// TODO: does this mean this CSV file should be in the warnings
|
||||
// subdirectory, since it doesn't work in strict mode?
|
||||
auto ds = get_csv_ds("test/data/csv/more_headers_than_column_values.csv", false);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "one", "two", "three"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String, mapnik::String, mapnik::String});
|
||||
auto fs = all_features(ds);
|
||||
for (double d : { .0, +.0, 1e-06, -1e-06, 0.000001, 1.234e+16, 1.234e+16 }) {
|
||||
auto feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->get("floats").get<mapnik::value_double>() == Approx(d));
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"one", ustring("")}, attr{"two", ustring("")}, attr{"three", ustring("")} });
|
||||
} // END SECTION
|
||||
SECTION("manually supplied extent") {
|
||||
std::string csv_string("wkt,Name\n");
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
params["extent"] = "-180,-90,180,90";
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
SECTION("fewer headers than rows throws") {
|
||||
REQUIRE_THROWS(get_csv_ds("test/data/csv/more_column_values_than_headers.csv"));
|
||||
} // END SECTION
|
||||
auto box = ds->envelope();
|
||||
CHECK(box.minx() == -180);
|
||||
CHECK(box.miny() == -90);
|
||||
CHECK(box.maxx() == 180);
|
||||
CHECK(box.maxy() == 90);
|
||||
} // END SECTION
|
||||
|
||||
SECTION("feature ID only incremented for valid rows") {
|
||||
auto ds = get_csv_ds("test/data/csv/warns/feature_id_counting.csv", false);
|
||||
auto fs = all_features(ds);
|
||||
SECTION("inline geojson") {
|
||||
std::string csv_string = "geojson\n'{\"coordinates\":[-92.22568,38.59553],\"type\":\"Point\"}'";
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
// first
|
||||
auto feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->id() == 1);
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {});
|
||||
|
||||
// second, should have skipped bogus one
|
||||
feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->id() == 2);
|
||||
// TODO: this originally had the following comment:
|
||||
// - re-enable after https://github.com/mapnik/mapnik/issues/2319 is fixed
|
||||
// but that seems to have been merged and tested separately?
|
||||
auto fs = all_features(ds);
|
||||
auto feat = fs->next();
|
||||
CHECK(feature_count(feat->get_geometry()) == 1);
|
||||
} // END SECTION
|
||||
|
||||
feature = fs->next();
|
||||
CHECK(!feature);
|
||||
} // END SECTION
|
||||
|
||||
SECTION("dynamically defining headers") {
|
||||
using ustring = mapnik::value_unicode_string;
|
||||
using row = std::pair<std::string, std::size_t>;
|
||||
|
||||
for (auto const &r : {
|
||||
row{"test/data/csv/fails/needs_headers_two_lines.csv", 2}
|
||||
, row{"test/data/csv/fails/needs_headers_one_line.csv", 1}
|
||||
, row{"test/data/csv/fails/needs_headers_one_line_no_newline.csv", 1}
|
||||
}) {
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["file"] = r.first;
|
||||
params["headers"] = "x,y,name";
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "name"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::String});
|
||||
require_attributes(all_features(ds)->next(), {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"name", ustring("data_name")} });
|
||||
REQUIRE(count_features(all_features(ds)) == r.second);
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wlong-long"
|
||||
SECTION("64bit int fields work") {
|
||||
auto ds = get_csv_ds("test/data/csv/64bit_int.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "bigint"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Integer});
|
||||
|
||||
auto fs = all_features(ds);
|
||||
auto feature = fs->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 2147483648} });
|
||||
|
||||
feature = fs->next();
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 9223372036854775807ll} });
|
||||
require_attributes(feature, {
|
||||
attr{"x", 0}, attr{"y", 0}, attr{"bigint", 0x7FFFFFFFFFFFFFFFll} });
|
||||
} // END SECTION
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
SECTION("various number types") {
|
||||
auto ds = get_csv_ds("test/data/csv/number_types.csv");
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {"x", "y", "floats"});
|
||||
require_field_types(fields, {mapnik::Integer, mapnik::Integer, mapnik::Double});
|
||||
|
||||
auto fs = all_features(ds);
|
||||
for (double d : { .0, +.0, 1e-06, -1e-06, 0.000001, 1.234e+16, 1.234e+16 }) {
|
||||
auto feature = fs->next();
|
||||
REQUIRE(bool(feature));
|
||||
CHECK(feature->get("floats").get<mapnik::value_double>() == Approx(d));
|
||||
}
|
||||
} // END SECTION
|
||||
|
||||
SECTION("manually supplied extent") {
|
||||
std::string csv_string("wkt,Name\n");
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
params["extent"] = "-180,-90,180,90";
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
auto box = ds->envelope();
|
||||
CHECK(box.minx() == -180);
|
||||
CHECK(box.miny() == -90);
|
||||
CHECK(box.maxx() == 180);
|
||||
CHECK(box.maxy() == 90);
|
||||
} // END SECTION
|
||||
|
||||
SECTION("inline geojson") {
|
||||
std::string csv_string = "geojson\n'{\"coordinates\":[-92.22568,38.59553],\"type\":\"Point\"}'";
|
||||
mapnik::parameters params;
|
||||
params["type"] = std::string("csv");
|
||||
params["inline"] = csv_string;
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
require_field_names(fields, {});
|
||||
|
||||
// TODO: this originally had the following comment:
|
||||
// - re-enable after https://github.com/mapnik/mapnik/issues/2319 is fixed
|
||||
// but that seems to have been merged and tested separately?
|
||||
auto fs = all_features(ds);
|
||||
auto feat = fs->next();
|
||||
CHECK(feature_count(feat->get_geometry()) == 1);
|
||||
} // END SECTION
|
||||
|
||||
mapnik::logger::instance().set_severity(severity);
|
||||
mapnik::logger::instance().set_severity(severity);
|
||||
}
|
||||
} // END TEST CASE
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/util/fs.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
@ -19,55 +20,59 @@ SECTION("layers") {
|
|||
{
|
||||
mapnik::Map m0(100,100);
|
||||
mapnik::Map m2(200,100);
|
||||
mapnik::datasource_cache::instance().register_datasources("plugins/input/shape.input");
|
||||
mapnik::parameters p;
|
||||
p["type"]="shape";
|
||||
p["file"]="demo/data/boundaries";
|
||||
p["encoding"]="latin1";
|
||||
auto ds0 = mapnik::datasource_cache::instance().create(p);
|
||||
std::string shape_plugin("./plugins/input/shape.input");
|
||||
if (mapnik::util::exists(shape_plugin))
|
||||
{
|
||||
mapnik::datasource_cache::instance().register_datasources("plugins/input/shape.input");
|
||||
mapnik::parameters p;
|
||||
p["type"]="shape";
|
||||
p["file"]="demo/data/boundaries";
|
||||
p["encoding"]="latin1";
|
||||
auto ds0 = mapnik::datasource_cache::instance().create(p);
|
||||
|
||||
auto ds1 = ds0; // shared ptr copy
|
||||
REQUIRE( (ds1 == ds0) );
|
||||
REQUIRE( !(*ds1 != *ds0) );
|
||||
REQUIRE( (ds1.get() == ds0.get()) );
|
||||
ds1 = mapnik::datasource_cache::instance().create(p); // new with the same parameters
|
||||
REQUIRE( (ds1 != ds0) );
|
||||
REQUIRE( (*ds1 == *ds0) );
|
||||
auto ds2 = std::move(ds1);
|
||||
REQUIRE( (ds2 != ds0) );
|
||||
REQUIRE( (*ds2 == *ds0) );
|
||||
auto ds1 = ds0; // shared ptr copy
|
||||
REQUIRE( (ds1 == ds0) );
|
||||
REQUIRE( !(*ds1 != *ds0) );
|
||||
REQUIRE( (ds1.get() == ds0.get()) );
|
||||
ds1 = mapnik::datasource_cache::instance().create(p); // new with the same parameters
|
||||
REQUIRE( (ds1 != ds0) );
|
||||
REQUIRE( (*ds1 == *ds0) );
|
||||
auto ds2 = std::move(ds1);
|
||||
REQUIRE( (ds2 != ds0) );
|
||||
REQUIRE( (*ds2 == *ds0) );
|
||||
|
||||
// mapnik::layer
|
||||
mapnik::layer l0("test-layer");
|
||||
l0.set_datasource(ds0);
|
||||
// mapnik::layer
|
||||
mapnik::layer l0("test-layer");
|
||||
l0.set_datasource(ds0);
|
||||
|
||||
mapnik::layer l1 = l0; // copy assignment
|
||||
REQUIRE( (l1 == l0) );
|
||||
mapnik::layer l2(l0); // copy ctor
|
||||
REQUIRE( (l2 == l0) );
|
||||
mapnik::layer l3(mapnik::layer("test-layer")); // move ctor
|
||||
l3.set_datasource(ds2);
|
||||
mapnik::layer l1 = l0; // copy assignment
|
||||
REQUIRE( (l1 == l0) );
|
||||
mapnik::layer l2(l0); // copy ctor
|
||||
REQUIRE( (l2 == l0) );
|
||||
mapnik::layer l3(mapnik::layer("test-layer")); // move ctor
|
||||
l3.set_datasource(ds2);
|
||||
|
||||
REQUIRE( (l3 == l0) );
|
||||
mapnik::layer l4 = std::move(l3);
|
||||
REQUIRE( (l4 == l0) ); // move assignment
|
||||
REQUIRE( (l3 == l0) );
|
||||
mapnik::layer l4 = std::move(l3);
|
||||
REQUIRE( (l4 == l0) ); // move assignment
|
||||
|
||||
m0.add_layer(l4);
|
||||
m0.set_background(mapnik::color("skyblue"));
|
||||
m2.set_background(mapnik::color("skyblue"));
|
||||
m0.add_layer(l4);
|
||||
m0.set_background(mapnik::color("skyblue"));
|
||||
m2.set_background(mapnik::color("skyblue"));
|
||||
|
||||
auto m1 = m0; //copy
|
||||
auto m1 = m0; //copy
|
||||
|
||||
REQUIRE( (m0 == m1) );
|
||||
REQUIRE( (m0 != m2) );
|
||||
REQUIRE( (m0 == m1) );
|
||||
REQUIRE( (m0 != m2) );
|
||||
|
||||
m2 = m1; // copy
|
||||
REQUIRE( (m2 == m1) );
|
||||
m2 = std::move(m1);
|
||||
REQUIRE( (m2 == m0) );
|
||||
REQUIRE( (m1 != m0) );
|
||||
m2 = m1; // copy
|
||||
REQUIRE( (m2 == m1) );
|
||||
m2 = std::move(m1);
|
||||
REQUIRE( (m2 == m0) );
|
||||
REQUIRE( (m1 != m0) );
|
||||
|
||||
REQUIRE( (m0 == m2) );
|
||||
REQUIRE( (m0 == m2) );
|
||||
}
|
||||
}
|
||||
catch (std::exception const & ex)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/expression.hpp>
|
||||
#include <mapnik/util/fs.hpp>
|
||||
|
||||
TEST_CASE("image") {
|
||||
|
||||
|
@ -17,47 +18,51 @@ SECTION("painting") {
|
|||
|
||||
try
|
||||
{
|
||||
datasource_cache::instance().register_datasources("plugins/input/csv.input");
|
||||
|
||||
Map m(256, 256);
|
||||
|
||||
feature_type_style lines_style;
|
||||
std::string csv_plugin("./plugins/input/csv.input");
|
||||
if (mapnik::util::exists(csv_plugin))
|
||||
{
|
||||
rule r;
|
||||
line_symbolizer line_sym;
|
||||
r.append(std::move(line_sym));
|
||||
lines_style.add_rule(std::move(r));
|
||||
datasource_cache::instance().register_datasources(csv_plugin);
|
||||
|
||||
Map m(256, 256);
|
||||
|
||||
feature_type_style lines_style;
|
||||
{
|
||||
rule r;
|
||||
line_symbolizer line_sym;
|
||||
r.append(std::move(line_sym));
|
||||
lines_style.add_rule(std::move(r));
|
||||
}
|
||||
m.insert_style("lines", std::move(lines_style));
|
||||
|
||||
feature_type_style markers_style;
|
||||
{
|
||||
rule r;
|
||||
r.set_filter(parse_expression("False"));
|
||||
markers_symbolizer mark_sym;
|
||||
r.append(std::move(mark_sym));
|
||||
markers_style.add_rule(std::move(r));
|
||||
}
|
||||
m.insert_style("markers", std::move(markers_style));
|
||||
|
||||
parameters p;
|
||||
p["type"] = "csv";
|
||||
p["separator"] = "|";
|
||||
p["inline"] = "wkt\nLINESTRING(-10 0, 0 20, 10 0, 15 5)";
|
||||
|
||||
layer lyr("layer");
|
||||
lyr.set_datasource(datasource_cache::instance().create(p));
|
||||
lyr.add_style("lines");
|
||||
lyr.add_style("markers");
|
||||
m.add_layer(lyr);
|
||||
|
||||
m.zoom_all();
|
||||
|
||||
image_rgba8 image(m.width(), m.height());
|
||||
agg_renderer<image_rgba8> ren(m, image);
|
||||
ren.apply();
|
||||
|
||||
REQUIRE(image.painted() == true);
|
||||
}
|
||||
m.insert_style("lines", std::move(lines_style));
|
||||
|
||||
feature_type_style markers_style;
|
||||
{
|
||||
rule r;
|
||||
r.set_filter(parse_expression("False"));
|
||||
markers_symbolizer mark_sym;
|
||||
r.append(std::move(mark_sym));
|
||||
markers_style.add_rule(std::move(r));
|
||||
}
|
||||
m.insert_style("markers", std::move(markers_style));
|
||||
|
||||
parameters p;
|
||||
p["type"] = "csv";
|
||||
p["separator"] = "|";
|
||||
p["inline"] = "wkt\nLINESTRING(-10 0, 0 20, 10 0, 15 5)";
|
||||
|
||||
layer lyr("layer");
|
||||
lyr.set_datasource(datasource_cache::instance().create(p));
|
||||
lyr.add_style("lines");
|
||||
lyr.add_style("markers");
|
||||
m.add_layer(lyr);
|
||||
|
||||
m.zoom_all();
|
||||
|
||||
image_rgba8 image(m.width(), m.height());
|
||||
agg_renderer<image_rgba8> ren(m, image);
|
||||
ren.apply();
|
||||
|
||||
REQUIRE(image.painted() == true);
|
||||
}
|
||||
catch (std::exception const & ex)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue