Skip to content

Commit ee6b86f

Browse files
committed
CoverageSimplify: add progress callback and add GEOSCoverageSimplifyVWWithProgress_r()
1 parent cd8275e commit ee6b86f

File tree

11 files changed

+231
-43
lines changed

11 files changed

+231
-43
lines changed

capi/geos_c.h.in

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,23 @@ typedef void (*GEOSMessageHandler)(GEOS_PRINTF_FORMAT const char *fmt, ...)
117117
*/
118118
typedef void (*GEOSMessageHandler_r)(const char *message, void *userdata);
119119

120+
121+
/**
122+
* A GEOS progression and cancel function.
123+
*
124+
* Such function takes a progression ratio, and an optional
125+
* message, and returns true if computation must continue, or false if it
126+
* must be interrupted.
127+
*
128+
* \param progressRatio Progression ratio (between 0 and 1)
129+
* \param message Information message (can be NULL)
130+
* \param userdata the user data pointer that was passed to GEOS together with
131+
* this callback.
132+
* \return TRUE if processing must continue, or FALSE to interrupt it.
133+
*/
134+
typedef int (*GEOSProgressCallback_r)(double progressRatio, const char* message, void* userdata);
135+
136+
120137
/*
121138
* When we're included by geos_c.cpp, these types are #defined to the
122139
* C++ definitions via preprocessor. We don't touch them to allow the
@@ -886,6 +903,16 @@ GEOSCoverageSimplifyVW_r(
886903
double tolerance,
887904
int preserveBoundary);
888905

906+
/** \see GEOSCoverageSimplifyVW */
907+
extern GEOSGeometry GEOS_DLL *
908+
GEOSCoverageSimplifyVWWithProgress_r(
909+
GEOSContextHandle_t extHandle,
910+
const GEOSGeometry* input,
911+
double tolerance,
912+
int preserveBoundary,
913+
GEOSProgressCallback_r progressFunc,
914+
void* progressUserData);
915+
889916
/** \see GEOSCoverageCleanParams_create */
890917
extern GEOSCoverageCleanParams GEOS_DLL *
891918
GEOSCoverageCleanParams_create_r(
@@ -5328,7 +5355,7 @@ extern char GEOS_DLL GEOSIntersects(const GEOSGeometry* g1, const GEOSGeometry*
53285355
extern char GEOS_DLL GEOSCrosses(const GEOSGeometry* g1, const GEOSGeometry* g2);
53295356

53305357
/**
5331-
* Tests if geometry g1 is completely within g2,
5358+
* Tests if geometry g1 is completely within g2,
53325359
* but not wholly contained in the boundary of g2.
53335360
* \param g1 Input geometry
53345361
* \param g2 Input geometry

capi/geos_ts_c.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
#include <geos/util/Interrupt.h>
115115
#include <geos/util/UniqueCoordinateArrayFilter.h>
116116
#include <geos/util/Machine.h>
117+
#include <geos/util/Progress.h>
117118
#include <geos/version.h>
118119

119120
// This should go away
@@ -4522,6 +4523,25 @@ extern "C" {
45224523
double tolerance,
45234524
int preserveBoundary)
45244525
{
4526+
return GEOSCoverageSimplifyVWWithProgress_r(extHandle, input, tolerance,
4527+
preserveBoundary,
4528+
nullptr, nullptr);
4529+
}
4530+
4531+
Geometry*
4532+
GEOSCoverageSimplifyVWWithProgress_r(GEOSContextHandle_t extHandle,
4533+
const Geometry* input,
4534+
double tolerance,
4535+
int preserveBoundary,
4536+
GEOSProgressCallback_r progressFunc,
4537+
void* progressUserData)
4538+
{
4539+
geos::util::ProgressFunction progressFunction =
4540+
[progressFunc, progressUserData](double progress, const char* message)
4541+
{
4542+
return progressFunc(progress, message, progressUserData);
4543+
};
4544+
45254545
using geos::coverage::CoverageSimplifier;
45264546

45274547
return execute(extHandle, [&]() -> Geometry* {
@@ -4536,10 +4556,10 @@ extern "C" {
45364556
CoverageSimplifier cov(coverage);
45374557
std::vector<std::unique_ptr<Geometry>> simple;
45384558
if (preserveBoundary == 1) {
4539-
simple = cov.simplifyInner(tolerance);
4559+
simple = cov.simplifyInner(tolerance, progressFunc ? &progressFunction : nullptr);
45404560
}
45414561
else if (preserveBoundary == 0) {
4542-
simple = cov.simplify(tolerance);
4562+
simple = cov.simplify(tolerance, progressFunc ? &progressFunction : nullptr);
45434563
}
45444564
else return nullptr;
45454565

include/geos/coverage/CoverageSimplifier.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020
#include <memory>
2121
#include <geos/export.h>
22+
#include <geos/util/Progress.h>
2223

2324

2425
namespace geos {
@@ -87,15 +88,18 @@ class GEOS_DLL CoverageSimplifier {
8788
*
8889
* @param coverage a set of polygonal geometries forming a coverage
8990
* @param tolerance the simplification tolerance
91+
* @param progressFunction Progress function, or nullptr.
9092
* @return the simplified polygons
9193
*/
9294
static std::vector<std::unique_ptr<Geometry>> simplify(
9395
std::vector<const Geometry*>& coverage,
94-
double tolerance);
96+
double tolerance,
97+
geos::util::ProgressFunction* progressFunction);
9598

9699
static std::vector<std::unique_ptr<Geometry>> simplify(
97100
const std::vector<std::unique_ptr<Geometry>>& coverage,
98-
double tolerance);
101+
double tolerance,
102+
geos::util::ProgressFunction* progressFunction);
99103

100104
/**
101105
* Simplifies the inner boundaries of a set of polygonal geometries forming a coverage,
@@ -104,35 +108,40 @@ class GEOS_DLL CoverageSimplifier {
104108
*
105109
* @param coverage a set of polygonal geometries forming a coverage
106110
* @param tolerance the simplification tolerance
111+
* @param progressFunction Progress function, or nullptr.
107112
* @return the simplified polygons
108113
*/
109114
static std::vector<std::unique_ptr<Geometry>> simplifyInner(
110115
std::vector<const Geometry*>& coverage,
111-
double tolerance);
116+
double tolerance,
117+
geos::util::ProgressFunction* progressFunction);
112118

113119
static std::vector<std::unique_ptr<Geometry>> simplifyInner(
114120
const std::vector<std::unique_ptr<Geometry>>& coverage,
115-
double tolerance);
121+
double tolerance,
122+
geos::util::ProgressFunction* progressFunction);
116123

117124
/**
118125
* Computes the simplified coverage, preserving the coverage topology.
119126
*
120127
* @param tolerance the simplification tolerance
128+
* @param progressFunction Progress function, or nullptr.
121129
* @return the simplified polygons
122130
*/
123131
std::vector<std::unique_ptr<Geometry>> simplify(
124-
double tolerance);
132+
double tolerance, geos::util::ProgressFunction* progressFunction);
125133

126134
/**
127135
* Computes the inner-boundary simplified coverage,
128136
* preserving the coverage topology,
129137
* and leaving outer boundary edges unchanged.
130138
*
131139
* @param tolerance the simplification tolerance
140+
* @param progressFunction Progress function, or nullptr.
132141
* @return the simplified polygons
133142
*/
134143
std::vector<std::unique_ptr<Geometry>> simplifyInner(
135-
double tolerance);
144+
double tolerance, geos::util::ProgressFunction* progressFunction);
136145

137146

138147
private:
@@ -145,7 +154,8 @@ class GEOS_DLL CoverageSimplifier {
145154
void simplifyEdges(
146155
std::vector<CoverageEdge*> edges,
147156
const MultiLineString* constraints,
148-
double tolerance);
157+
double tolerance,
158+
geos::util::ProgressFunction* progressFunction);
149159

150160
void setCoordinates(
151161
std::vector<CoverageEdge*>& edges,

include/geos/coverage/TPVWSimplifier.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <geos/simplify/LinkedLine.h>
2222
#include <geos/coverage/Corner.h>
2323
#include <geos/export.h>
24+
#include <geos/util/Progress.h>
2425

2526

2627
namespace geos {
@@ -164,11 +165,13 @@ class GEOS_DLL TPVWSimplifier
164165
*
165166
* @param lines the lines to simplify
166167
* @param distanceTolerance the simplification tolerance
168+
* @param progressFunction Progress function, or nullptr.
167169
* @return the simplified lines
168170
*/
169171
static std::unique_ptr<MultiLineString> simplify(
170172
const MultiLineString* lines,
171-
double distanceTolerance);
173+
double distanceTolerance,
174+
geos::util::ProgressFunction* progressFunction);
172175

173176
/**
174177
* Simplifies a set of lines, preserving the topology of the lines between
@@ -181,13 +184,15 @@ class GEOS_DLL TPVWSimplifier
181184
* @param freeRings flags indicating which ring edges do not have node endpoints
182185
* @param constraintLines the linear constraints
183186
* @param distanceTolerance the simplification tolerance
187+
* @param progressFunction Progress function, or nullptr.
184188
* @return the simplified lines
185189
*/
186190
static std::unique_ptr<MultiLineString> simplify(
187191
const MultiLineString* lines,
188192
std::vector<bool>& freeRings,
189193
const MultiLineString* constraintLines,
190-
double distanceTolerance);
194+
double distanceTolerance,
195+
geos::util::ProgressFunction* progressFunction);
191196

192197
// Constructor
193198
TPVWSimplifier(const MultiLineString* lines,
@@ -209,7 +214,7 @@ class GEOS_DLL TPVWSimplifier
209214

210215
void setConstraints(const MultiLineString* constraints);
211216

212-
std::unique_ptr<MultiLineString> simplify();
217+
std::unique_ptr<MultiLineString> simplify(geos::util::ProgressFunction* progressFunction);
213218

214219
std::vector<Edge> createEdges(
215220
const MultiLineString* lines,

include/geos/util/Progress.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**********************************************************************
2+
*
3+
* GEOS - Geometry Engine Open Source
4+
* http://geos.osgeo.org
5+
*
6+
* Copyright (C) 2025 Even Rouault <[email protected]>
7+
*
8+
* This is free software; you can redistribute and/or modify it under
9+
* the terms of the GNU Lesser General Public Licence as published
10+
* by the Free Software Foundation.
11+
* See the COPYING file for more information.
12+
*
13+
**********************************************************************/
14+
15+
#pragma once
16+
17+
#include <functional>
18+
19+
#include <geos/export.h>
20+
21+
namespace geos {
22+
namespace util { // geos::util
23+
24+
/** Signature of a progression and cancel function.
25+
*
26+
* Such function takes a progression ratio (between 0 and 1), and an optional
27+
* message, and returns true if computation must continue, or false if it
28+
* must be interrupted.
29+
*/
30+
typedef std::function<bool(double, const char*)> ProgressFunction;
31+
32+
/** Do progress function related processing for an iteration loop of iterCount iterations.
33+
*
34+
* This function will invoke (*progressFunction) every notificationInterval
35+
*iteration.
36+
*
37+
* This function will return, or throw a geos::util::InterruptedException.
38+
*
39+
* A typical use is:
40+
* \code
41+
* const size_t notificationInterval = std::max<size_t>(1, iterCount / 100);
42+
* for (size_t i = 0, iNotify = 0; i < iterCount; ++i) {
43+
* // do something useful
44+
* if (progressFunction) {
45+
* geos::util::ProgressFunctionIteration(*progressFunction, i, iterCount, iNotify, notificationInterval);
46+
* }
47+
* }
48+
* if (progressFunction) {
49+
* (*progressFunction)(1.0, nullptr);
50+
* }
51+
* \endcode
52+
*
53+
* @param progressFunction Progress function
54+
* @param i Current index of loop iteration.
55+
* @param iterCount Total number of loop iteration.
56+
* @param iNotify Notification counter, updated by this function. Must be set by the caller (before the loop) to 0.
57+
* @param notificationInterval Notification interval (e.g. iterCount / 100).
58+
*/
59+
void ProgressFunctionIteration(ProgressFunction& progressFunction, size_t i, size_t iterCount, size_t& iNotify, size_t notificationInterval);
60+
61+
} // namespace geos::util
62+
} // namespace geos
63+

0 commit comments

Comments
 (0)