Coverage Report

Created: 2025-08-30 06:52

/src/geos/src/operation/valid/IndexedNestedHoleTester.cpp
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2021 Paul Ramsey <pramsey@cleverelephant.ca>
7
 * Copyright (C) 2021 Martin Davis
8
 *
9
 * This is free software; you can redistribute and/or modify it under
10
 * the terms of the GNU Lesser General Public Licence as published
11
 * by the Free Software Foundation.
12
 * See the COPYING file for more information.
13
 *
14
 **********************************************************************/
15
16
#include <geos/algorithm/PointLocation.h>
17
#include <geos/geom/Coordinate.h>
18
#include <geos/geom/Envelope.h>
19
#include <geos/geom/LinearRing.h>
20
#include <geos/geom/Polygon.h>
21
#include <geos/index/strtree/TemplateSTRtree.h>
22
#include <geos/operation/valid/IndexedNestedHoleTester.h>
23
#include <geos/operation/valid/PolygonTopologyAnalyzer.h>
24
25
namespace geos {      // geos
26
namespace operation { // geos.operation
27
namespace valid {     // geos.operation.valid
28
29
using namespace geos::geom;
30
31
/* private */
32
void
33
IndexedNestedHoleTester::loadIndex()
34
0
{
35
0
    for (std::size_t i = 0; i < polygon->getNumInteriorRing(); i++) {
36
0
        const LinearRing* hole = static_cast<const LinearRing*>(polygon->getInteriorRingN(i));
37
0
        const Envelope* env = hole->getEnvelopeInternal();
38
0
        index.insert(*env, hole);
39
0
    }
40
0
}
41
42
/* public */
43
bool
44
IndexedNestedHoleTester::isNested()
45
0
{
46
0
    for (std::size_t i = 0; i < polygon->getNumInteriorRing(); i++) {
47
0
        const LinearRing* hole = static_cast<const LinearRing*>(polygon->getInteriorRingN(i));
48
49
0
        std::vector<const LinearRing*> results;
50
0
        index.query(*(hole->getEnvelopeInternal()), results);
51
52
0
        for (const LinearRing* testHole: results) {
53
0
            if (hole == testHole)
54
0
                continue;
55
56
            /**
57
             * Hole is not fully covered by test hole, so cannot be nested
58
             */
59
0
            if (! testHole->getEnvelopeInternal()->covers(hole->getEnvelopeInternal()))
60
0
                continue;
61
62
            /**
63
             * Checks nesting via a point-in-polygon test,
64
             * or if the point lies on the boundary via
65
             * the topology of the incident edges.
66
             */
67
0
            if (PolygonTopologyAnalyzer::isRingNested(hole, testHole)) {
68
0
                nestedPt = hole->getCoordinatesRO()->getAt<CoordinateXY>(0);
69
0
                return true;
70
0
            }
71
0
        }
72
0
    }
73
0
    return false;
74
0
}
75
76
77
78
} // namespace geos.operation.valid
79
} // namespace geos.operation
80
} // namespace geos