diff --git a/db/detail/meta_ops.hpp b/db/detail/meta_ops.hpp index 4893ed5..967e151 100644 --- a/db/detail/meta_ops.hpp +++ b/db/detail/meta_ops.hpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -39,26 +38,23 @@ template bool indexed(Indexes&& indexes, ColumnNames&& col_nms) { return boost::algorithm::any_of(indexes, [&](auto& idx) { - return boost::range::search(idx.columns, - col_nms, - unicode::case_insensitive_equal_to{}) == + return boost::range::search(idx.columns, col_nms) == idx.columns.begin(); }); } -template -auto find(Rng&& rng, std::string_view name) +template +auto find(Columns&& cols, std::string_view col_nm) { - return boost::range::find_if(rng, [&](auto& item) { - return unicode::case_insensitive_equal_to{}(name, item.name); - }); + return boost::range::find_if(cols, + [=](auto& col) { return col_nm == col.name; }); } -template -auto names(Rng&& rng) +template +auto names(Columns&& cols) { - return as>(rng, - [&](auto& item) { return item.name; }); + return as>(cols, + [&](auto& col) { return col.name; }); } inline geometry::box_rtree make_tiles(size_t count, geometry::box ext) diff --git a/db/detail/postgres_dialect.hpp b/db/detail/postgres_dialect.hpp index 773895a..e84f347 100644 --- a/db/detail/postgres_dialect.hpp +++ b/db/detail/postgres_dialect.hpp @@ -25,12 +25,13 @@ struct postgres_dialect : dialect { void columns_sql(sql_builder& bld, const qualified_name& tbl_nm) override { + auto& tbl = tbl_nm.back(); auto& scm = tbl_nm.at(-2); bld << "SELECT column_name, LOWER(CASE data_type WHEN " << param{"USER-DEFINED"} << " THEN udt_name ELSE data_type END), numeric_scale FROM " "information_schema.columns WHERE table_schema = " - << param{scm} << " AND table_name = " << param{tbl_nm.back()} + << param{scm} << " AND table_name = " << param{tbl} << " ORDER BY ordinal_position"; } diff --git a/db/detail/table_guide.hpp b/db/detail/table_guide.hpp index bbc109c..8bacf9f 100644 --- a/db/detail/table_guide.hpp +++ b/db/detail/table_guide.hpp @@ -68,8 +68,7 @@ class table_guide { tbl.columns.push_back(col); } if (tbl.columns.empty()) - throw std::runtime_error( - "no columns: " + boost::lexical_cast(tbl.name)); + throw std::runtime_error(concat("no columns: ", tbl.name)); } void load_indexes(meta::table& tbl) diff --git a/db/meta.hpp b/db/meta.hpp index 2b42998..0051064 100644 --- a/db/meta.hpp +++ b/db/meta.hpp @@ -58,9 +58,8 @@ inline std::ostream& operator<<(std::ostream& os, const column& col) if (!col.projection.empty()) opts.push_back(proj::abbreviation(col.projection)); if (!col.tiles.empty()) - opts.push_back("BOX" + - boost::lexical_cast( - boost::geometry::dsv(bounds(col.tiles)))); + opts.push_back( + concat("BOX", boost::geometry::dsv(bounds(col.tiles)))); if (!opts.empty()) os << " (" << list{opts, ", "} << ")"; } diff --git a/db/mysql/command.hpp b/db/mysql/command.hpp index 400fa9a..09c6fc6 100644 --- a/db/mysql/command.hpp +++ b/db/mysql/command.hpp @@ -109,7 +109,7 @@ class command : public db::command, private transaction { : nullptr}; unsigned cols = res ? mysql_num_fields(res.get()) : 0; - std::vector names(cols); + auto names = std::vector(cols); binds_.resize(cols); memset(binds_.data(), 0, binds_.size() * sizeof(MYSQL_BIND)); cols_.resize(cols); diff --git a/db/provider.hpp b/db/provider.hpp index ea4ec2f..9f307a6 100644 --- a/db/provider.hpp +++ b/db/provider.hpp @@ -35,7 +35,7 @@ struct provider { /// Returns a balanced data grid. - /// @param layer is a data set; + /// @param layer is a data set identifier; /// @param extent is a spatial filter; /// @param pixel selects the level of the raster pyramid. virtual geometry::multi_box tile_coverage(const qualified_name& layer, @@ -45,7 +45,7 @@ struct provider { /// Returns @ref rowset with spatial data set. /// Columns @code GEOMETRY[,IMAGE][,ATTRIBUTES...] @endcode - /// @param layer is a data set; + /// @param layer is a data set identifier; /// @param extent is a spatial filter; /// @param pixel selects the level of the raster pyramid. virtual rowset spatial_objects(const qualified_name& layer, @@ -147,6 +147,13 @@ sql_builder insert_sql(provider& pvd, return res; }; +inline sql_builder insert_sql(provider& pvd, + const qualified_name& tbl_nm, + const rowset& rows) +{ + return insert_sql(pvd, tbl_nm, rows.columns, select(rows)); +} + inline sql_builder drop_sql(provider& pvd, const qualified_name& tbl_nm) { auto res = builder(pvd); diff --git a/db/rowset.hpp b/db/rowset.hpp index cd9493d..696b97c 100644 --- a/db/rowset.hpp +++ b/db/rowset.hpp @@ -28,19 +28,16 @@ inline auto select(const rowset& from) /// Returns tuples of @ref variant_t template -auto select(const Columns& columns, const rowset& from) +auto select(const Columns& cols, const rowset& from) { - auto cols = as>( - columns, [](const auto& col) { return unicode::to_lower(col); }); - - auto idxs = as>(from.columns, [&](const auto& col) { - auto it = std::find(cols.begin(), cols.end(), unicode::to_lower(col)); - return std::distance(cols.begin(), it); + auto idxs = as>(from.columns, [&](auto&& col) { + auto it = std::find(std::begin(cols), std::end(cols), col); + return std::distance(std::begin(cols), it); }); auto res = std::vector>{}; for (auto is = variant_istream{from.data}; !is.data.empty();) { - auto& row = res.emplace_back(cols.size()); + auto& row = res.emplace_back(idxs.size()); for (size_t idx : idxs) if (idx < row.size()) is >> row[idx]; diff --git a/detail/lru_cache.hpp b/detail/lru_cache.hpp index 15dd523..4ab5891 100644 --- a/detail/lru_cache.hpp +++ b/detail/lru_cache.hpp @@ -44,7 +44,7 @@ class lru_cache { auto res = mapped_type::result_of(std::forward(f), std::forward(args)...); insert({scoped_key, res}); - return res.get(); + return std::move(res).get(); } template diff --git a/detail/unicode.hpp b/detail/unicode.hpp index ff1e14d..167e2f8 100644 --- a/detail/unicode.hpp +++ b/detail/unicode.hpp @@ -79,14 +79,6 @@ auto to_upper(const Str& str) return unicode::to_string>(wstr); } -struct case_insensitive_equal_to { - template - bool operator()(const Lhs& lhs, const Rhs& rhs) const - { - return to_lower(lhs) == to_lower(rhs); - } -}; - } // namespace bark::unicode #endif // BARK_UNICODE_HPP diff --git a/detail/utility.hpp b/detail/utility.hpp index 7974cb2..7ec70cb 100644 --- a/detail/utility.hpp +++ b/detail/utility.hpp @@ -133,32 +133,31 @@ constexpr size_t variant_index() /// expected is either a T or the exception preventing its creation. template class expected { + std::variant val_; + public: template static expected result_of(F&& f, Args&&... args) noexcept { expected res; try { - res.state_ = + res.val_ = std::invoke(std::forward(f), std::forward(args)...); } - catch (const std::exception&) { - res.state_ = std::current_exception(); + catch (...) { + res.val_ = std::current_exception(); } return res; } - T get() + T get() && { - return std::visit(overloaded{[](T& val) -> T { return std::move(val); }, - [](std::exception_ptr& e) -> T { - std::rethrow_exception(std::move(e)); - }}, - state_); + return std::visit( + overloaded{ + [](std::exception_ptr e) -> T { std::rethrow_exception(e); }, + [](T&& val) -> T { return std::move(val); }}, + std::move(val_)); } - -private: - std::variant state_; }; /// Joins 'items' by adding user defined separator. @@ -240,6 +239,11 @@ streamable(T) -> streamable; /// @see https://en.cppreference.com/w/cpp/named_req/TimedLockable template , class Equal = std::equal_to> class timed_lockable { + T val_; + inline static std::mutex guard_; + inline static std::condition_variable notifier_; + inline static std::unordered_set locked_; + public: explicit timed_lockable(const T& val) : val_{val} {} @@ -260,12 +264,6 @@ class timed_lockable { } notifier_.notify_all(); } - -private: - T val_; - inline static std::mutex guard_; - inline static std::condition_variable notifier_; - inline static std::unordered_set locked_; }; } // namespace bark diff --git a/test/db.hpp b/test/db.hpp index 97bc05e..bf5b3b2 100644 --- a/test/db.hpp +++ b/test/db.hpp @@ -3,42 +3,43 @@ #ifndef BARK_TEST_DB_HPP #define BARK_TEST_DB_HPP -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include #include -#include #include namespace bark::db { +inline void simplify_geometry_column(const rowset& rows, std::string_view col) +{ + auto it = std::find(rows.columns.begin(), rows.columns.end(), col); + auto offset = std::distance(rows.columns.begin(), it); + for_each_blob(select(rows), offset, simplify_geometry{}); +} + inline bool operator==(const rowset& lhs, const rowset& rhs) { - return std::make_tuple(lhs.columns.size(), - static_cast(lhs.data)) == - std::make_tuple(rhs.columns.size(), - static_cast(rhs.data)); + return std::is_permutation(lhs.columns.begin(), + lhs.columns.end(), + rhs.columns.begin(), + rhs.columns.end()) && + select(lhs) == select(lhs.columns, rhs); } namespace meta { inline bool operator==(const column& lhs, const column& rhs) { - return unicode::case_insensitive_equal_to{}(lhs.name, rhs.name) && - lhs.type == rhs.type && lhs.projection == rhs.projection; + return std::tie(lhs.name, lhs.type, lhs.projection) == + std::tie(rhs.name, rhs.type, rhs.projection); } inline bool operator==(const index& lhs, const index& rhs) { return lhs.type == rhs.type && - boost::range::equal( - lhs.columns, rhs.columns, unicode::case_insensitive_equal_to{}); + boost::range::equal(lhs.columns, rhs.columns); } inline bool operator==(const table& lhs, const table& rhs) @@ -58,120 +59,39 @@ inline bool operator==(const table& lhs, const table& rhs) } // namespace bark::db -inline auto random_name() -{ - return bark::db::id(bark::concat("drop_me_", bark::random_index{10000}())); -} - -inline const auto& odbc_driver(std::initializer_list tokens) +TEST_CASE("db_insert") { using namespace bark; - static const auto Drivers = db::odbc::drivers(); - auto it = boost::range::find_if(Drivers, [tokens](const auto& drv) { - return all_of(tokens, within(drv)); - }); - if (it == std::end(Drivers)) - throw std::runtime_error( - concat("ODBC driver not found: ", list{tokens, ", "})); - return *it; -} - -#if defined(BARK_TEST_DATABASE_SERVER) -#define BARK_TEST_MYSQL_SERVER BARK_TEST_DATABASE_SERVER -#define BARK_TEST_ODBC_DB2_SERVER BARK_TEST_DATABASE_SERVER -#define BARK_TEST_ODBC_MSSQL_SERVER BARK_TEST_DATABASE_SERVER -#define BARK_TEST_ODBC_MYSQL_SERVER BARK_TEST_DATABASE_SERVER -#define BARK_TEST_ODBC_POSTGRES_SERVER BARK_TEST_DATABASE_SERVER -#define BARK_TEST_POSTGRES_SERVER BARK_TEST_DATABASE_SERVER -#endif - -inline std::vector make_write_providers() -{ using namespace bark::db; - return - { -#if defined(BARK_TEST_MYSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared(BOOST_PP_STRINGIZE(BARK_TEST_MYSQL_SERVER), 3306, "mysql", "root", BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD)), -#endif -#if defined(BARK_TEST_ODBC_DB2_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared("DRIVER=" + odbc_driver({"IBM"}) + ";UID=DB2INST1;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=SAMPLE;HOSTNAME=" BOOST_PP_STRINGIZE(BARK_TEST_ODBC_DB2_SERVER)), -#endif -#if defined(BARK_TEST_ODBC_MSSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared("DRIVER=" + odbc_driver({"SQL", "Server"}) + ";UID=sa;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=master;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_ODBC_MSSQL_SERVER)), -#endif -#if defined(BARK_TEST_ODBC_MYSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared("DRIVER=" + odbc_driver({"MySQL", "Unicode"}) + ";UID=root;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=mysql;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_MYSQL_SERVER) ";MULTI_STATEMENTS=1;SSLMODE=disabled"), -#endif -#if defined(BARK_TEST_ODBC_POSTGRES_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared("DRIVER=" + odbc_driver({"PostgreSQL", "Unicode"}) + ";UID=postgres;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=postgres;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_POSTGRES_SERVER)), -#endif -#if defined(BARK_TEST_POSTGRES_SERVER) && defined(BARK_TEST_DATABASE_PWD) - std::make_shared(BOOST_PP_STRINGIZE(BARK_TEST_POSTGRES_SERVER), 5432, "postgres", "postgres", BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD)), -#endif - std::make_shared(R"(./drop_me.sqlite)") - }; -} - -TEST_CASE("db_geometry") -{ - using namespace bark::db; - static constexpr size_t Limit = 10; - - boost::io::ios_flags_saver ifs(std::cout); - gdal::provider pvd_from("./data/mexico.sqlite"); - auto lr_from = pvd_from.dir().begin()->first; - auto tbl_from = pvd_from.table(qualifier(lr_from)); - std::cout << tbl_from << std::endl; - REQUIRE(!tbl_from.columns.empty()); - REQUIRE(!tbl_from.indexes.empty()); - auto cols = names(tbl_from.columns); - auto col = std::distance(tbl_from.columns.begin(), - find(tbl_from.columns, lr_from.back())); - auto rowset_from = - fetch_all(pvd_from, select_sql(pvd_from, tbl_from.name, 1, Limit)); - std::cout << rowset_from << std::endl; - REQUIRE(!rowset_from.data.empty()); - auto rows_from = select(cols, rowset_from); - bark::db::for_each_blob(rows_from, col, wkb_unifier{}); - for (auto& pvd_to : make_write_providers()) { - auto [name, sql] = - pvd_to->ddl({random_name(), tbl_from.columns, tbl_from.indexes}); - REQUIRE_THROWS(pvd_to->table(name)); - exec(*pvd_to, sql); - pvd_to->refresh(); - auto tbl_to = pvd_to->table(name); - REQUIRE(tbl_from == tbl_to); - - auto cmd = pvd_to->make_command(); - cmd->set_autocommit(false); - cmd->exec(insert_sql(*pvd_to, tbl_to.name, cols, rows_from)); - cmd->commit(); - pvd_to->refresh(); - auto rowset_to = - fetch_all(*pvd_to, select_sql(*pvd_to, tbl_to.name, 0, Limit)); - auto rows_to = select(cols, rowset_to); - bark::db::for_each_blob(rows_to, col, wkb_unifier{}); - REQUIRE(rows_from == rows_to); - - cmd->exec(drop_sql(*pvd_to, tbl_to.name)); - cmd->commit(); - pvd_to->refresh(); - REQUIRE_THROWS(pvd_to->table(tbl_to.name)); + auto ifs = boost::io::ios_flags_saver{std::cout}; + auto pvd_src = gdal::provider{"./data/mexico.sqlite"}; + auto lr_src = pvd_src.dir().begin()->first; + auto tbl_src = pvd_src.table(qualifier(lr_src)); + std::cout << tbl_src << std::endl; + REQUIRE(!tbl_src.columns.empty()); + REQUIRE(!tbl_src.indexes.empty()); + auto rows_src = fetch_all(pvd_src, select_sql(pvd_src, tbl_src.name, 3, 5)); + std::cout << rows_src << std::endl; + REQUIRE(!rows_src.data.empty()); + simplify_geometry_column(rows_src, lr_src.back()); + for (auto& pvd : make_providers()) { + auto [tbl_nm, ddl] = + pvd->ddl({id(concat("drop_me_", random_index{10000}())), + tbl_src.columns, + tbl_src.indexes}); + REQUIRE_THROWS(pvd->table(tbl_nm)); + exec(*pvd, ddl); + pvd->refresh(); + REQUIRE(tbl_src == pvd->table(tbl_nm)); + exec(*pvd, insert_sql(*pvd, tbl_nm, rows_src)); + pvd->refresh(); + auto rows = fetch_all(*pvd, select_sql(*pvd, tbl_nm, 0, 100500)); + simplify_geometry_column(rows, lr_src.back()); + REQUIRE(rows_src == rows); + exec(*pvd, drop_sql(*pvd, tbl_nm)); + pvd->refresh(); + REQUIRE_THROWS(pvd->table(tbl_nm)); } } -TEST_CASE("gdal_raster") -{ - using namespace bark; - using namespace bark::db; - - gdal::provider pvd(R"(./data/albers27.tif)"); - auto reg = pvd.dir(); - REQUIRE(!reg.empty()); - auto layer = reg.begin()->first; - std::cout << layer << '\n' - << proj::abbreviation(pvd.projection(layer)) << '\n' - << geometry::wkt{pvd.extent(layer)} << std::endl; -} - #endif // BARK_TEST_DB_HPP diff --git a/test/main.cpp b/test/main.cpp index e6a449f..fd7096f 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/test/providers.hpp b/test/providers.hpp new file mode 100644 index 0000000..2904487 --- /dev/null +++ b/test/providers.hpp @@ -0,0 +1,63 @@ +// Andrew Naplavkov + +#ifndef BARK_TEST_PROVIDERS_HPP +#define BARK_TEST_PROVIDERS_HPP + +#include +#include +#include +#include +#include +#include +#include + +inline const auto& odbc_driver(std::initializer_list tokens) +{ + using namespace bark; + static const auto Drivers = db::odbc::drivers(); + auto it = boost::range::find_if(Drivers, [tokens](const auto& drv) { + return all_of(tokens, within(drv)); + }); + if (it == std::end(Drivers)) + throw std::runtime_error( + concat("ODBC driver not found: ", list{tokens, ", "})); + return *it; +} + +#if defined(BARK_TEST_DATABASE_SERVER) +#define BARK_TEST_MYSQL_SERVER BARK_TEST_DATABASE_SERVER +#define BARK_TEST_ODBC_DB2_SERVER BARK_TEST_DATABASE_SERVER +#define BARK_TEST_ODBC_MSSQL_SERVER BARK_TEST_DATABASE_SERVER +#define BARK_TEST_ODBC_MYSQL_SERVER BARK_TEST_DATABASE_SERVER +#define BARK_TEST_ODBC_POSTGRES_SERVER BARK_TEST_DATABASE_SERVER +#define BARK_TEST_POSTGRES_SERVER BARK_TEST_DATABASE_SERVER +#endif + +inline std::vector make_providers() +{ + using namespace bark::db; + return + { +#if defined(BARK_TEST_MYSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared(BOOST_PP_STRINGIZE(BARK_TEST_MYSQL_SERVER), 3306, "mysql", "root", BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD)), +#endif +#if defined(BARK_TEST_ODBC_DB2_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared("DRIVER=" + odbc_driver({"IBM"}) + ";UID=DB2INST1;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=SAMPLE;HOSTNAME=" BOOST_PP_STRINGIZE(BARK_TEST_ODBC_DB2_SERVER)), +#endif +#if defined(BARK_TEST_ODBC_MSSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared("DRIVER=" + odbc_driver({"SQL", "Server"}) + ";UID=sa;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=master;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_ODBC_MSSQL_SERVER)), +#endif +#if defined(BARK_TEST_ODBC_MYSQL_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared("DRIVER=" + odbc_driver({"MySQL", "Unicode"}) + ";UID=root;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=mysql;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_MYSQL_SERVER) ";MULTI_STATEMENTS=1;SSLMODE=disabled"), +#endif +#if defined(BARK_TEST_ODBC_POSTGRES_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared("DRIVER=" + odbc_driver({"PostgreSQL", "Unicode"}) + ";UID=postgres;PWD=" BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD) ";DATABASE=postgres;SERVER=" BOOST_PP_STRINGIZE(BARK_TEST_POSTGRES_SERVER)), +#endif +#if defined(BARK_TEST_POSTGRES_SERVER) && defined(BARK_TEST_DATABASE_PWD) + std::make_shared(BOOST_PP_STRINGIZE(BARK_TEST_POSTGRES_SERVER), 5432, "postgres", "postgres", BOOST_PP_STRINGIZE(BARK_TEST_DATABASE_PWD)), +#endif + std::make_shared(R"(./drop_me.sqlite)") + }; +} + +#endif // BARK_TEST_PROVIDERS_HPP diff --git a/test/raster.hpp b/test/raster.hpp new file mode 100644 index 0000000..b238bab --- /dev/null +++ b/test/raster.hpp @@ -0,0 +1,24 @@ +// Andrew Naplavkov + +#ifndef BARK_TEST_RASTER_HPP +#define BARK_TEST_RASTER_HPP + +#include +#include + +TEST_CASE("gdal_raster") +{ + using namespace bark; + using namespace bark::db; + + gdal::provider pvd(R"(./data/albers27.tif)"); + auto reg = pvd.dir(); + REQUIRE(!reg.empty()); + auto [layer, type] = *reg.begin(); + REQUIRE(type == bark::db::meta::layer_type::Raster); + std::cout << layer << "\n" + << pvd.projection(layer) << "\nBOX" + << boost::geometry::dsv(pvd.extent(layer)) << std::endl; +} + +#endif // BARK_TEST_RASTER_HPP diff --git a/test/wkb_unifier.hpp b/test/simplify_geometry.hpp similarity index 83% rename from test/wkb_unifier.hpp rename to test/simplify_geometry.hpp index bb7e863..8ecad00 100644 --- a/test/wkb_unifier.hpp +++ b/test/simplify_geometry.hpp @@ -1,13 +1,13 @@ // Andrew Naplavkov -#ifndef BARK_TEST_WKB_UNIFIER_HPP -#define BARK_TEST_WKB_UNIFIER_HPP +#ifndef BARK_TEST_SIMPLIFY_GEOMETRY_HPP +#define BARK_TEST_SIMPLIFY_GEOMETRY_HPP #include #include /// WKB visitor -class wkb_unifier { +class simplify_geometry { public: void operator()(bark::blob_view data) { @@ -16,6 +16,7 @@ class wkb_unifier { bark::wkb::geometry::accept(is, *this); } + /// reduce precision boost::none_t operator()(double x, double y) { *this << (double)(float)x << (double)(float)y; @@ -50,7 +51,7 @@ class wkb_unifier { bark::blob_view data_; template - wkb_unifier& operator<<(T val) + simplify_geometry& operator<<(T val) { *(T*)data_.data() = val; data_.remove_prefix(sizeof(T)); @@ -58,4 +59,4 @@ class wkb_unifier { } }; -#endif // BARK_TEST_WKB_UNIFIER_HPP +#endif // BARK_TEST_SIMPLIFY_GEOMETRY_HPP