Skip to content

Commit f9cdadd

Browse files
authored
Merge pull request #1742 from joto/geom-functions
Geom functions
2 parents 1314cbb + 7893919 commit f9cdadd

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

src/geom-functions.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -309,22 +309,28 @@ static void split_linestring(linestring_t const &line, double split_at,
309309
}
310310
}
311311

312-
geometry_t segmentize(geometry_t const &geom, double max_segment_length)
312+
void segmentize(geometry_t *output, geometry_t const &input,
313+
double max_segment_length)
313314
{
314-
geometry_t output{multilinestring_t{}, geom.srid()};
315-
auto *multilinestring = &output.get<multilinestring_t>();
315+
output->set_srid(input.srid());
316+
auto *multilinestring = &output->set<multilinestring_t>();
316317

317-
if (geom.is_linestring()) {
318-
split_linestring(geom.get<linestring_t>(), max_segment_length,
318+
if (input.is_linestring()) {
319+
split_linestring(input.get<linestring_t>(), max_segment_length,
319320
multilinestring);
320-
} else if (geom.is_multilinestring()) {
321-
for (auto const &line : geom.get<multilinestring_t>()) {
321+
} else if (input.is_multilinestring()) {
322+
for (auto const &line : input.get<multilinestring_t>()) {
322323
split_linestring(line, max_segment_length, multilinestring);
323324
}
324325
} else {
325-
output.reset();
326+
output->reset();
326327
}
328+
}
327329

330+
geometry_t segmentize(geometry_t const &input, double max_segment_length)
331+
{
332+
geometry_t output;
333+
segmentize(&output, input, max_segment_length);
328334
return output;
329335
}
330336

@@ -440,16 +446,16 @@ static void add_nodes_to_linestring(linestring_t *linestring, ITERATOR it,
440446
}
441447
}
442448

443-
geometry_t line_merge(geometry_t geom)
449+
void line_merge(geometry_t *output, geometry_t const &input)
444450
{
445-
geometry_t output{multilinestring_t{}, geom.srid()};
446-
447-
if (geom.is_null()) {
448-
output.reset();
449-
return output;
451+
if (!input.is_multilinestring()) {
452+
output->reset();
453+
return;
450454
}
451455

452-
assert(geom.is_multilinestring());
456+
output->set_srid(input.srid());
457+
458+
auto &linestrings = output->set<multilinestring_t>();
453459

454460
// Make a list of all endpoints...
455461
struct endpoint_t
@@ -484,16 +490,16 @@ geometry_t line_merge(geometry_t geom)
484490
struct connection_t
485491
{
486492
std::size_t left = NOCONN;
487-
geom::linestring_t const *ls;
493+
linestring_t const *ls;
488494
std::size_t right = NOCONN;
489495

490-
explicit connection_t(geom::linestring_t const *l) noexcept : ls(l) {}
496+
explicit connection_t(linestring_t const *l) noexcept : ls(l) {}
491497
};
492498

493499
std::vector<connection_t> conns;
494500

495501
// Initialize the two lists.
496-
for (auto const &line : geom.get<multilinestring_t>()) {
502+
for (auto const &line : input.get<multilinestring_t>()) {
497503
endpoints.emplace_back(line.front(), conns.size(), true);
498504
endpoints.emplace_back(line.back(), conns.size(), false);
499505
conns.emplace_back(&line);
@@ -519,8 +525,6 @@ geometry_t line_merge(geometry_t geom)
519525
}
520526
}
521527

522-
auto &linestrings = output.get<multilinestring_t>();
523-
524528
// First find all open ends and use them as starting points to assemble
525529
// linestrings. Mark ways as "done" as we go.
526530
std::size_t done_ways = 0;
@@ -608,9 +612,14 @@ geometry_t line_merge(geometry_t geom)
608612
}
609613

610614
if (linestrings.num_geometries() == 0) {
611-
output.reset();
615+
output->reset();
612616
}
617+
}
613618

619+
geometry_t line_merge(geometry_t const &input)
620+
{
621+
geometry_t output;
622+
line_merge(&output, input);
614623
return output;
615624
}
616625

src/geom-functions.hpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,27 @@ geometry_t transform(geometry_t const &input, reprojection const &reprojection);
115115
* Returns a modified geometry having no segment longer than the given
116116
* max_segment_length.
117117
*
118-
* \param geom The input geometry, must be a linestring or multilinestring.
118+
* \param output Pointer to output geometry. Will be a multilinestring
119+
* geometry, or nullgeom_t on error.
120+
* \param input The input geometry, must be a linestring or multilinestring.
119121
* \param max_segment_length The maximum length (using Euclidean distance
120-
* in the length unit of the srs of the geometry) of each resulting
122+
* in the length unit of the SRS of the geometry) of each resulting
123+
* linestring.
124+
*/
125+
void segmentize(geometry_t *output, geometry_t const &input,
126+
double max_segment_length);
127+
128+
/**
129+
* Returns a modified geometry having no segment longer than the given
130+
* max_segment_length.
131+
*
132+
* \param input The input geometry, must be a linestring or multilinestring.
133+
* \param max_segment_length The maximum length (using Euclidean distance
134+
* in the length unit of the SRS of the geometry) of each resulting
121135
* linestring.
122136
* \returns Resulting multilinestring geometry, nullgeom_t on error.
123137
*/
124-
geometry_t segmentize(geometry_t const &geom, double max_segment_length);
138+
geometry_t segmentize(geometry_t const &input, double max_segment_length);
125139

126140
/**
127141
* Calculate area of geometry.
@@ -149,10 +163,20 @@ std::vector<geometry_t> split_multi(geometry_t &&geom, bool split_multi = true);
149163
* returns a multilinestring unless there is an error or the input geometry
150164
* is a nullgeom_t, in which case nullgeom_t is returned.
151165
*
152-
* \param geom Input geometry.
166+
* \param output Pointer to output geometry.
167+
* \param input Input geometry.
168+
*/
169+
void line_merge(geometry_t *output, geometry_t const &input);
170+
171+
/**
172+
* Merge lines in a multilinestring end-to-end as far as possible. Always
173+
* returns a multilinestring unless there is an error or the input geometry
174+
* is a nullgeom_t, in which case nullgeom_t is returned.
175+
*
176+
* \param input Input geometry.
153177
* \returns Result multilinestring.
154178
*/
155-
geometry_t line_merge(geometry_t geom);
179+
geometry_t line_merge(geometry_t const &input);
156180

157181
/**
158182
* Calculate the centroid of a geometry.

0 commit comments

Comments
 (0)