Coverage Report

Created: 2026-06-10 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/noding/IteratedNoder.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2006 Refractions Research Inc.
7
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
8
 *
9
 * This is free software; you can redistribute and/or modify it under
10
 * the terms of the GNU Lesser General Licence as published
11
 * by the Free Software Foundation.
12
 * See the COPYING file for more information.
13
 *
14
 **********************************************************************
15
 *
16
 * Last port: noding/IteratedNoder.java r591 (JTS-1.12+)
17
 *
18
 **********************************************************************/
19
20
#include <sstream>
21
#include <vector>
22
23
#include <geos/profiler.h>
24
#include <geos/util/TopologyException.h>
25
#include <geos/noding/IteratedNoder.h>
26
#include <geos/noding/SegmentString.h>
27
#include <geos/noding/MCIndexNoder.h>
28
#include <geos/noding/IntersectionAdder.h>
29
30
#ifndef GEOS_DEBUG
31
#define GEOS_DEBUG 0
32
#endif
33
34
using namespace geos::geom;
35
36
namespace geos {
37
namespace noding { // geos.noding
38
39
/* private */
40
void
41
IteratedNoder::node(const std::vector<SegmentString*>& segStrings,
42
                    int& numInteriorIntersections,
43
                    CoordinateXY& intersectionPoint)
44
0
{
45
0
    IntersectionAdder si(li);
46
0
    MCIndexNoder noder;
47
0
    noder.setSegmentIntersector(&si);
48
0
    noder.computeNodes(segStrings);
49
0
    auto updatedSegStrings = noder.getNodedSubstrings();
50
0
    nodedSegStrings = std::move(updatedSegStrings);
51
0
    numInteriorIntersections = si.numInteriorIntersections;
52
53
0
    if (si.hasProperInteriorIntersection()) {
54
0
        intersectionPoint = si.getProperIntersectionPoint();
55
0
    }
56
0
}
57
58
/* public */
59
void
60
IteratedNoder::computeNodes(const std::vector<SegmentString*>& segStrings)
61
0
{
62
0
    int numInteriorIntersections;
63
0
    int nodingIterationCount = 0;
64
0
    int lastNodesCreated = -1;
65
0
    CoordinateXY intersectionPoint = CoordinateXY::getNull();
66
67
0
    bool firstPass = true;
68
0
    do  {
69
        // NOTE: will change this.nodedSegStrings
70
0
        if (firstPass) {
71
0
            node(segStrings, numInteriorIntersections, intersectionPoint);
72
0
            firstPass = false;
73
0
        } else {
74
0
            auto nodingInput = SegmentString::toRawPointerVector(nodedSegStrings);
75
0
            node(nodingInput, numInteriorIntersections, intersectionPoint);
76
0
        }
77
78
0
        nodingIterationCount++;
79
0
        int nodesCreated = numInteriorIntersections;
80
81
        /*
82
         * Fail if the number of nodes created is not declining.
83
         * However, allow a few iterations at least before doing this
84
         */
85
0
        if(lastNodesCreated > 0
86
0
                && nodesCreated >= lastNodesCreated
87
0
                && nodingIterationCount > maxIter) {
88
89
0
            std::stringstream s;
90
0
            s << "Iterated noding failed to converge after " <<
91
0
              nodingIterationCount << " iterations (near " <<
92
0
              intersectionPoint << ")";
93
0
            throw util::TopologyException(s.str());
94
0
        }
95
0
        lastNodesCreated = nodesCreated;
96
97
0
    }
98
0
    while(lastNodesCreated > 0);
99
    //cerr<<"# nodings = "<<nodingIterationCount<<endl;
100
0
}
101
102
103
} // namespace geos.noding
104
} // namespace geos
105