mapnik/test/unit/datasource/ds_test_util.hpp

208 lines
8.6 KiB
C++
Raw Normal View History

/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
2024-07-22 11:20:47 +02:00
* Copyright (C) 2024 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_UNIT_DATSOURCE_UTIL
#define MAPNIK_UNIT_DATSOURCE_UTIL
#include "catch.hpp"
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/geometry.hpp>
2017-03-27 17:14:51 +02:00
#include <mapnik/geometry/geometry_types.hpp>
#include <mapnik/geometry/geometry_type.hpp>
namespace {
2022-01-26 23:25:53 +01:00
template<typename T>
2015-10-29 17:48:09 +01:00
std::string vector_to_string(T const& vec)
{
std::stringstream s;
for (auto const& item : vec)
{
s << " " << item << "\n";
2015-10-29 17:48:09 +01:00
}
return s.str();
}
2022-01-26 23:25:53 +01:00
template<>
2015-10-29 17:48:09 +01:00
std::string vector_to_string(std::vector<mapnik::attribute_descriptor> const& vec)
{
std::stringstream s;
for (auto const& item : vec)
{
s << " " << item.get_name() << "\n";
2015-10-29 17:48:09 +01:00
}
return s.str();
}
2022-01-26 23:25:53 +01:00
#define REQUIRE_FIELD_NAMES(fields, names) \
INFO("fields:\n" + vector_to_string(fields) + "names:\n" + vector_to_string(names)); \
REQUIRE(fields.size() == names.size()); \
auto itr_a = fields.begin(); \
auto const end_a = fields.end(); \
auto itr_b = names.begin(); \
for (; itr_a != end_a; ++itr_a, ++itr_b) \
{ \
CHECK(itr_a->get_name() == *itr_b); \
}
inline void require_field_names(std::vector<mapnik::attribute_descriptor> const& fields,
std::initializer_list<std::string> const& names)
{
2022-01-26 23:25:53 +01:00
REQUIRE_FIELD_NAMES(fields, names);
}
2022-01-26 23:25:53 +01:00
#define REQUIRE_FIELD_TYPES(fields, types) \
REQUIRE(fields.size() == types.size()); \
auto itr_a = fields.begin(); \
auto const end_a = fields.end(); \
auto itr_b = types.begin(); \
for (; itr_a != end_a; ++itr_a, ++itr_b) \
{ \
CHECK(itr_a->get_type() == *itr_b); \
}
inline void require_field_types(std::vector<mapnik::attribute_descriptor> const& fields,
std::initializer_list<mapnik::eAttributeType> const& types)
{
REQUIRE_FIELD_TYPES(fields, types);
}
2022-01-26 23:25:53 +01:00
inline mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds)
{
auto fields = ds->get_descriptor().get_descriptors();
mapnik::query query(ds->envelope());
2022-01-26 23:25:53 +01:00
for (auto const& field : fields)
{
query.add_property_name(field.get_name());
}
return ds->features(query);
}
2022-01-26 23:25:53 +01:00
inline std::size_t count_features(mapnik::featureset_ptr features)
{
std::size_t count = 0;
2022-01-26 23:25:53 +01:00
while (features->next())
{
++count;
}
return count;
}
using attr = std::tuple<std::string, mapnik::value>;
2022-01-26 23:25:53 +01:00
#define REQUIRE_ATTRIBUTES(feature, ...) \
do \
{ \
auto const& _feat = (feature); /* evaluate feature only once */ \
REQUIRE(_feat != nullptr); \
for (auto const& kv : __VA_ARGS__) \
{ \
auto& key = std::get<0>(kv); \
auto& val = std::get<1>(kv); \
CAPTURE(key); \
CHECKED_IF(_feat->has_key(key)) \
{ \
CHECK(_feat->get(key) == val); \
CHECK(_feat->get(key).which() == val.which()); \
} \
} \
} while (0)
namespace detail {
2022-01-26 23:25:53 +01:00
template<typename T>
struct feature_count
{
2022-01-26 23:25:53 +01:00
template<typename U>
std::size_t operator()(U const& geom) const
{
return mapnik::util::apply_visitor(*this, geom);
}
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::geometry_empty const&) const { return 0; }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::point<T> const&) const { return 1; }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::line_string<T> const&) const { return 1; }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::polygon<T> const&) const { return 1; }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::multi_point<T> const& mp) const { return mp.size(); }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::multi_line_string<T> const& mls) const { return mls.size(); }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::multi_polygon<T> const& mp) const { return mp.size(); }
2022-01-26 23:25:53 +01:00
std::size_t operator()(mapnik::geometry::geometry_collection<T> const& col) const
{
std::size_t sum = 0;
2022-01-26 23:25:53 +01:00
for (auto const& geom : col)
{
sum += operator()(geom);
}
return sum;
}
};
} // namespace detail
2022-01-26 23:25:53 +01:00
template<typename T>
inline std::size_t feature_count(mapnik::geometry::geometry<T> const& g)
{
return detail::feature_count<T>()(g);
}
2022-01-26 23:25:53 +01:00
inline void require_geometry(mapnik::feature_ptr feature, std::size_t num_parts, mapnik::geometry::geometry_types type)
{
REQUIRE(bool(feature));
CHECK(mapnik::geometry::geometry_type(feature->get_geometry()) == type);
CHECK(feature_count(feature->get_geometry()) == num_parts);
}
inline int create_disk_index(std::string const& filename, bool silent = true)
{
std::string cmd;
if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
{
cmd += std::string("DYLD_LIBRARY_PATH=") + std::getenv("DYLD_LIBRARY_PATH") + " ";
}
cmd += "mapnik-index";
2021-10-21 18:22:53 +02:00
#ifdef _WIN32
cmd += ".exe";
#endif
cmd += " " + filename;
if (silent)
{
2021-10-21 18:22:53 +02:00
#ifndef _WIN32
cmd += " 2>/dev/null";
#else
cmd += " 2> nul";
#endif
}
return std::system(cmd.c_str());
}
2022-01-26 23:25:53 +01:00
} // namespace
#endif // MAPNIK_UNIT_DATSOURCE_UTIL