@@ -61,15 +61,47 @@ CoverageRingEdges::selectEdges(std::size_t ringCount) const
6161
6262/* private */
6363void
64- CoverageRingEdges::build ()
64+ CoverageRingEdges::build (geos::util::ProgressFunction* progressFunction )
6565{
66- Coordinate::UnorderedSet nodes = findMultiRingNodes (m_coverage);
67- LineSegment::UnorderedSet boundarySegs = CoverageBoundarySegmentFinder::findBoundarySegments (m_coverage);
68- Coordinate::UnorderedSet boundaryNodes = findBoundaryNodes (boundarySegs);
66+ constexpr double RATIO_FIRST_PASS = 0.1 ;
67+ constexpr double RATIO_SECOND_PASS = 0.2 ;
68+ constexpr double RATIO_THIRD_PASS = 0.9 ;
69+ constexpr double RATIO_FOURTH_PASS = 1.0 ;
70+ geos::util::ProgressFunction subProgress;
71+ if (progressFunction)
72+ {
73+ subProgress = geos::util::CreateScaledProgressFunction (
74+ 0 , RATIO_FIRST_PASS, *progressFunction);
75+ }
76+ Coordinate::UnorderedSet nodes = findMultiRingNodes (m_coverage, progressFunction ? &subProgress : nullptr );
77+
78+ if (progressFunction)
79+ {
80+ subProgress = geos::util::CreateScaledProgressFunction (
81+ RATIO_FIRST_PASS, RATIO_SECOND_PASS, *progressFunction);
82+ }
83+ LineSegment::UnorderedSet boundarySegs = CoverageBoundarySegmentFinder::findBoundarySegments (
84+ m_coverage, progressFunction ? &subProgress : nullptr );
85+
86+ if (progressFunction)
87+ {
88+ subProgress = geos::util::CreateScaledProgressFunction (
89+ RATIO_SECOND_PASS, RATIO_THIRD_PASS, *progressFunction);
90+ }
91+ Coordinate::UnorderedSet boundaryNodes = findBoundaryNodes (
92+ boundarySegs, progressFunction ? &subProgress : nullptr );
6993 nodes.insert (boundaryNodes.begin (), boundaryNodes.end ());
7094
95+ if (progressFunction)
96+ {
97+ subProgress = geos::util::CreateScaledProgressFunction (
98+ RATIO_THIRD_PASS, RATIO_FOURTH_PASS, *progressFunction);
99+ }
71100 std::map<LineSegment, CoverageEdge*> uniqueEdgeMap;
72- for (const Geometry* geom : m_coverage) {
101+ const size_t iterCount = m_coverage.size ();
102+ const size_t notificationInterval = std::max<size_t >(1 , iterCount / 100 );
103+ for (size_t i = 0 , iNotify = 0 ; i < iterCount; ++i) {
104+ const Geometry* geom = m_coverage[i];
73105 for (std::size_t ipoly = 0 ; ipoly < geom->getNumGeometries (); ipoly++) {
74106 util::ensureNoCurvedComponents (geom->getGeometryN (ipoly));
75107
@@ -91,6 +123,13 @@ CoverageRingEdges::build()
91123 addRingEdges (hole, nodes, boundarySegs, uniqueEdgeMap);
92124 }
93125 }
126+
127+ if (progressFunction) {
128+ geos::util::ProgressFunctionIteration (subProgress, i, iterCount, iNotify, notificationInterval);
129+ }
130+ }
131+ if (progressFunction) {
132+ (*progressFunction)(1.0 , nullptr );
94133 }
95134}
96135
@@ -254,54 +293,117 @@ CoverageRingEdges::next(std::size_t index, const CoordinateSequence& ring)
254293
255294/* private */
256295Coordinate::UnorderedSet
257- CoverageRingEdges::findMultiRingNodes (const std::vector<const Geometry*>& coverage)
296+ CoverageRingEdges::findMultiRingNodes (const std::vector<const Geometry*>& coverage,
297+ geos::util::ProgressFunction* progressFunction)
258298{
259299 std::map<Coordinate, std::size_t > vertexRingCount;
260- VertexRingCounter::count (coverage, vertexRingCount);
300+ geos::util::ProgressFunction subProgress;
301+ if (progressFunction)
302+ {
303+ subProgress = geos::util::CreateScaledProgressFunction (
304+ 0 , 0.5 , *progressFunction);
305+ }
306+
307+ VertexRingCounter::count (coverage, vertexRingCount, progressFunction ? &subProgress : nullptr );
261308 Coordinate::UnorderedSet nodes;
262309 // for (Coordinate v : vertexCount.keySet()) {
263310 // if (vertexCount.get(v) > 2) {
264311 // nodes.add(v);
265312 // }
266313 // }
314+ const size_t iterCount = vertexRingCount.size ();
315+ const size_t notificationInterval = std::max<size_t >(1 , iterCount / 100 );
316+ size_t i = 0 , iNotify = 0 ;
317+ if (progressFunction)
318+ {
319+ subProgress = geos::util::CreateScaledProgressFunction (
320+ 0.5 , 1.0 , *progressFunction);
321+ }
267322 for (const auto &mapPair : vertexRingCount) {
268323 const Coordinate& v = mapPair.first ;
269324 std::size_t count = mapPair.second ;
270325 if (count > 2 )
271326 nodes.insert (v);
327+ if (progressFunction) {
328+ geos::util::ProgressFunctionIteration (subProgress, i, iterCount, iNotify, notificationInterval);
329+ }
330+ ++i;
331+ }
332+ if (progressFunction) {
333+ (*progressFunction)(1.0 , nullptr );
272334 }
273335 return nodes;
274336}
275337
276338
277339/* private */
278340Coordinate::UnorderedSet
279- CoverageRingEdges::findBoundaryNodes (LineSegment::UnorderedSet& boundarySegments)
341+ CoverageRingEdges::findBoundaryNodes (LineSegment::UnorderedSet& boundarySegments,
342+ geos::util::ProgressFunction* progressFunction)
280343{
281344 std::unordered_map<Coordinate, std::size_t , Coordinate::HashCode> counter;
282- for (const LineSegment& seg : boundarySegments) {
283- counter[seg.p0 ] += 1 ;
284- counter[seg.p1 ] += 1 ;
345+ geos::util::ProgressFunction subProgress;
346+ if (progressFunction)
347+ {
348+ subProgress = geos::util::CreateScaledProgressFunction (
349+ 0 , 0.5 , *progressFunction);
350+ }
351+ {
352+ const size_t iterCount = boundarySegments.size ();
353+ const size_t notificationInterval = std::max<size_t >(1 , iterCount / 100 );
354+ size_t i = 0 , iNotify = 0 ;
355+ for (const LineSegment& seg : boundarySegments) {
356+ counter[seg.p0 ] += 1 ;
357+ counter[seg.p1 ] += 1 ;
358+ if (progressFunction) {
359+ geos::util::ProgressFunctionIteration (subProgress, i, iterCount, iNotify, notificationInterval);
360+ }
361+ ++i;
362+ }
285363 }
286364
365+ if (progressFunction)
366+ {
367+ subProgress = geos::util::CreateScaledProgressFunction (
368+ 0.5 , 1.0 , *progressFunction);
369+ }
287370 Coordinate::UnorderedSet nodes;
371+ const size_t iterCount = counter.size ();
372+ const size_t notificationInterval = std::max<size_t >(1 , iterCount / 100 );
373+ size_t i = 0 , iNotify = 0 ;
288374 for (const auto & c : counter) {
289375 const Coordinate& v = c.first ;
290376 std::size_t count = c.second ;
291377 if (count > 2 )
292378 nodes.insert (v);
379+ if (progressFunction) {
380+ geos::util::ProgressFunctionIteration (subProgress, i, iterCount, iNotify, notificationInterval);
381+ }
382+ ++i;
383+ }
384+ if (progressFunction) {
385+ (*progressFunction)(1.0 , nullptr );
293386 }
294387 return nodes;
295388}
296389
297390
298391/* public */
299392std::vector<std::unique_ptr<Geometry>>
300- CoverageRingEdges::buildCoverage () const
393+ CoverageRingEdges::buildCoverage (geos::util::ProgressFunction* progressFunction ) const
301394{
302395 std::vector<std::unique_ptr<Geometry>> result;
303- for (const Geometry* geom : m_coverage) {
396+ const size_t iterCount = m_coverage.size ();
397+ const size_t notificationInterval = std::max<size_t >(1 , iterCount / 100 );
398+ for (size_t i = 0 , iNotify = 0 ; i < iterCount; ++i) {
399+ const Geometry* geom = m_coverage[i];
304400 result.push_back (buildPolygonal (geom));
401+ if (progressFunction) {
402+ geos::util::ProgressFunctionIteration (*progressFunction, i, iterCount, iNotify, notificationInterval);
403+ }
404+ }
405+ if (progressFunction) {
406+ (*progressFunction)(1.0 , nullptr );
305407 }
306408 return result;
307409}
0 commit comments