Skip to content

Commit d4ab41c

Browse files
committed
Refactor split_multi() so it doesn't copy
Also removes an unneccessary cast from int to uint32_t and back.
1 parent 0a3936a commit d4ab41c

File tree

5 files changed

+22
-13
lines changed

5 files changed

+22
-13
lines changed

src/geom-functions.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,43 +322,43 @@ namespace {
322322
class split_visitor
323323
{
324324
public:
325-
split_visitor(std::vector<geometry_t> *output, uint32_t srid) noexcept
325+
split_visitor(std::vector<geometry_t> *output, int srid) noexcept
326326
: m_output(output), m_srid(srid)
327327
{}
328328

329329
template <typename T>
330330
void operator()(T) const
331331
{}
332332

333-
void operator()(geom::collection_t const &geom) const
333+
void operator()(geom::collection_t &&geom) const
334334
{
335-
for (auto sgeom : geom) {
335+
for (auto &&sgeom : geom) {
336336
m_output->push_back(std::move(sgeom));
337337
}
338338
}
339339

340340
template <typename T>
341-
void operator()(geom::multigeometry_t<T> const &geom) const
341+
void operator()(geom::multigeometry_t<T> &&geom) const
342342
{
343-
for (auto sgeom : geom) {
343+
for (auto &&sgeom : geom) {
344344
m_output->emplace_back(std::move(sgeom), m_srid);
345345
}
346346
}
347347

348348
private:
349349
std::vector<geometry_t> *m_output;
350-
uint32_t m_srid;
350+
int m_srid;
351351

352352
}; // class split_visitor
353353

354354
} // anonymous namespace
355355

356-
std::vector<geometry_t> split_multi(geometry_t geom, bool split_multi)
356+
std::vector<geometry_t> split_multi(geometry_t&& geom, bool split_multi)
357357
{
358358
std::vector<geometry_t> output;
359359

360360
if (split_multi && geom.is_multi()) {
361-
geom.visit(split_visitor{&output, static_cast<uint32_t>(geom.srid())});
361+
visit(split_visitor{&output, geom.srid()}, std::move(geom));
362362
} else if (!geom.is_null()) {
363363
output.push_back(std::move(geom));
364364
}

src/geom-functions.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ double area(geometry_t const &geom);
114114
* alone and will end up as the only geometry in the result vector. If the
115115
* input geometry is a nullgeom_t, the result vector will be empty.
116116
*
117-
* \param geom Input geometry.
117+
* \param geom Input geometry (will be moved from).
118118
* \param split_multi Only split of this is set to true.
119119
* \returns Vector of result geometries.
120120
*/
121-
std::vector<geometry_t> split_multi(geometry_t geom, bool split_multi = true);
121+
std::vector<geometry_t> split_multi(geometry_t &&geom, bool split_multi = true);
122122

123123
/**
124124
* Merge lines in a multilinestring end-to-end as far as possible. Always

src/geom.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,15 @@ class geometry_t
333333
return std::visit(std::forward<V>(visitor), m_geom);
334334
}
335335

336+
// This is non-member function visit(), different than the member
337+
// function above, because we need to move the geometry into the function
338+
// which we can't do for a member function.
339+
template <typename V>
340+
friend auto visit(V &&visitor, geometry_t &&geom)
341+
{
342+
return std::visit(std::forward<V>(visitor), std::move(geom.m_geom));
343+
}
344+
336345
[[nodiscard]] friend bool operator==(geometry_t const &a,
337346
geometry_t const &b) noexcept
338347
{

src/output-flex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ void output_flex_t::add_row(table_connection_t *table_connection,
13561356
// The geometry returned by run_transform() is in 4326 if it is a
13571357
// (multi)polygon. If it is a point or linestring, it is already in the
13581358
// target geometry.
1359-
auto const geom = run_transform(proj, transform, object);
1359+
auto geom = run_transform(proj, transform, object);
13601360

13611361
// We need to split a multi geometry into its parts if the geometry
13621362
// column can only take non-multi geometries or if the transform
@@ -1366,7 +1366,7 @@ void output_flex_t::add_row(table_connection_t *table_connection,
13661366
type == table_column_type::polygon ||
13671367
transform->split();
13681368

1369-
auto const geoms = geom::split_multi(geom, split_multi);
1369+
auto const geoms = geom::split_multi(std::move(geom), split_multi);
13701370
for (auto const &sgeom : geoms) {
13711371
m_expire.from_geometry(sgeom, id);
13721372
write_row(table_connection, object.type(), id, sgeom,

src/output-pgsql.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ void output_pgsql_t::pgsql_process_relation(osmium::Relation const &rel)
268268
if (!projected_geom.is_null() && split_at > 0.0) {
269269
projected_geom = geom::segmentize(projected_geom, split_at);
270270
}
271-
auto const geoms = geom::split_multi(projected_geom);
271+
auto const geoms = geom::split_multi(std::move(projected_geom));
272272
for (auto const &sgeom : geoms) {
273273
m_expire.from_geometry(sgeom, -rel.id());
274274
auto const wkb = geom_to_ewkb(sgeom);

0 commit comments

Comments
 (0)