Coverage Report

Created: 2025-10-12 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/index/quadtree/Node.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 Public Licence as published
11
 * by the Free Software Foundation.
12
 * See the COPYING file for more information.
13
 *
14
 **********************************************************************
15
 *
16
 * Last port: index/quadtree/Node.java rev 1.8 (JTS-1.10)
17
 *
18
 **********************************************************************/
19
20
#include <geos/index/quadtree/Node.h>
21
#include <geos/index/quadtree/Key.h>
22
#include <geos/geom/Envelope.h>
23
24
#include <string>
25
#include <sstream>
26
#include <cassert>
27
#include <memory>
28
29
#ifndef GEOS_DEBUG
30
#define GEOS_DEBUG 0
31
#endif
32
33
#if GEOS_DEBUG
34
#include <iostream>
35
#endif
36
37
38
using namespace geos::geom;
39
40
namespace geos {
41
namespace index { // geos.index
42
namespace quadtree { // geos.index.quadtree
43
44
/* public static */
45
std::unique_ptr<Node>
46
Node::createNode(const Envelope& env)
47
0
{
48
0
    Key key(env);
49
0
    std::unique_ptr<Envelope> envelope(new Envelope(key.getEnvelope()));
50
0
    std::unique_ptr<Node> node(
51
0
        new Node(std::move(envelope), key.getLevel())
52
0
    );
53
0
    return node;
54
0
}
55
56
/* static public */
57
std::unique_ptr<Node>
58
Node::createExpanded(std::unique_ptr<Node> node, const Envelope& addEnv)
59
0
{
60
0
    Envelope expandEnv(addEnv);
61
0
    if(node.get()) {  // should this be asserted ?
62
0
        expandEnv.expandToInclude(node->getEnvelope());
63
0
    }
64
65
#if GEOS_DEBUG
66
    std::cerr << "Node::createExpanded computed " << expandEnv.toString() << std::endl;
67
#endif
68
69
0
    std::unique_ptr<Node> largerNode = createNode(expandEnv);
70
0
    if(node.get()) {  // should this be asserted ?
71
0
        largerNode->insertNode(std::move(node));
72
0
    }
73
74
0
    return largerNode;
75
0
}
76
77
/*public*/
78
Node*
79
Node::getNode(const Envelope* searchEnv)
80
0
{
81
0
    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
82
    // if subquadIndex is -1 searchEnv is not contained in a subquad
83
0
    if(subnodeIndex != -1) {
84
        // create the quad if it does not exist
85
0
        Node* node = getSubnode(subnodeIndex);
86
        // recursively search the found/created quad
87
0
        return node->getNode(searchEnv);
88
0
    }
89
0
    else {
90
0
        return this;
91
0
    }
92
0
}
93
94
/*public*/
95
NodeBase*
96
Node::find(const Envelope* searchEnv)
97
0
{
98
0
    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
99
0
    if(subnodeIndex == -1) {
100
0
        return this;
101
0
    }
102
0
    if(subnodes[static_cast<std::size_t>(subnodeIndex)] != nullptr) {
103
        // query lies in subquad, so search it
104
0
        Node* node = subnodes[static_cast<std::size_t>(subnodeIndex)];
105
0
        return node->find(searchEnv);
106
0
    }
107
    // no existing subquad, so return this one anyway
108
0
    return this;
109
0
}
110
111
void
112
Node::insertNode(std::unique_ptr<Node> node)
113
0
{
114
0
    assert(env->contains(node->getEnvelope()));
115
116
0
    int index = getSubnodeIndex(node->getEnvelope(), centre);
117
0
    assert(index >= 0);
118
119
0
    if(node->level == level - 1) {
120
        // We take ownership of node
121
0
        delete subnodes[static_cast<std::size_t>(index)];
122
0
        subnodes[static_cast<std::size_t>(index)] = node.release();
123
124
        //System.out.println("inserted");
125
0
    }
126
0
    else {
127
        // the quad is not a direct child, so make a new child
128
        // quad to contain it and recursively insert the quad
129
0
        std::unique_ptr<Node> childNode(createSubnode(index));
130
131
        // childNode takes ownership of node
132
0
        childNode->insertNode(std::move(node));
133
134
        // We take ownership of childNode
135
0
        delete subnodes[static_cast<std::size_t>(index)];
136
0
        subnodes[static_cast<std::size_t>(index)] = childNode.release();
137
0
    }
138
0
}
139
140
Node*
141
Node::getSubnode(int index)
142
0
{
143
0
    assert(index >= 0 && index < 4);
144
0
    if(subnodes[static_cast<std::size_t>(index)] == nullptr) {
145
0
        subnodes[static_cast<std::size_t>(index)] = createSubnode(index).release();
146
0
    }
147
0
    return subnodes[static_cast<std::size_t>(index)];
148
0
}
149
150
std::unique_ptr<Node>
151
Node::createSubnode(int index)
152
0
{
153
    // create a new subquad in the appropriate quadrant
154
0
    double minx = 0.0;
155
0
    double maxx = 0.0;
156
0
    double miny = 0.0;
157
0
    double maxy = 0.0;
158
159
0
    switch(index) {
160
0
    case 0:
161
0
        minx = env->getMinX();
162
0
        maxx = centre.x;
163
0
        miny = env->getMinY();
164
0
        maxy = centre.y;
165
0
        break;
166
0
    case 1:
167
0
        minx = centre.x;
168
0
        maxx = env->getMaxX();
169
0
        miny = env->getMinY();
170
0
        maxy = centre.y;
171
0
        break;
172
0
    case 2:
173
0
        minx = env->getMinX();
174
0
        maxx = centre.x;
175
0
        miny = centre.y;
176
0
        maxy = env->getMaxY();
177
0
        break;
178
0
    case 3:
179
0
        minx = centre.x;
180
0
        maxx = env->getMaxX();
181
0
        miny = centre.y;
182
0
        maxy = env->getMaxY();
183
0
        break;
184
0
    }
185
0
    std::unique_ptr<Envelope> sqEnv(new Envelope(minx, maxx, miny, maxy));
186
0
    std::unique_ptr<Node> node(new Node(std::move(sqEnv), level - 1));
187
0
    return node;
188
0
}
189
190
std::string
191
Node::toString() const
192
0
{
193
0
    std::ostringstream os;
194
0
    os << "L" << level << " " << env->toString() << " Ctr[" << centre.toString() << "]";
195
0
    os << " " << NodeBase::toString();
196
0
    return os.str();
197
0
}
198
199
200
} // namespace geos.index.quadtree
201
} // namespace geos.index
202
} // namespace geos