Coverage Report

Created: 2025-12-18 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/include/geos/index/quadtree/Quadtree.h
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
 *
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
 * Last port: index/quadtree/Quadtree.java rev. 1.16 (JTS-1.10)
16
 *
17
 **********************************************************************/
18
19
#pragma once
20
21
#include <geos/export.h>
22
#include <geos/geom/Envelope.h>
23
#include <geos/index/SpatialIndex.h> // for inheritance
24
#include <geos/index/quadtree/Root.h> // for composition
25
26
#include <memory>
27
#include <vector>
28
#include <string>
29
30
#ifdef _MSC_VER
31
#pragma warning(push)
32
#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
33
#endif
34
35
// Forward declarations
36
namespace geos {
37
namespace index {
38
namespace quadtree {
39
// class Root;
40
}
41
}
42
}
43
44
namespace geos {
45
namespace index { // geos::index
46
namespace quadtree { // geos::index::quadtree
47
48
/**
49
 * \brief
50
 * A Quadtree is a spatial index structure for efficient querying
51
 * of 2D rectangles.  If other kinds of spatial objects
52
 * need to be indexed they can be represented by their
53
 * envelopes
54
 *
55
 * The quadtree structure is used to provide a primary filter
56
 * for range rectangle queries.  The query() method returns a list of
57
 * all objects which <i>may</i> intersect the query rectangle.  Note that
58
 * it may return objects which do not in fact intersect.
59
 * A secondary filter is required to test for exact intersection.
60
 * Of course, this secondary filter may consist of other tests besides
61
 * intersection, such as testing other kinds of spatial relationships.
62
 *
63
 * This implementation does not require specifying the extent of the inserted
64
 * items beforehand.  It will automatically expand to accommodate any extent
65
 * of dataset.
66
 *
67
 * This data structure is also known as an <i>MX-CIF quadtree</i>
68
 * following the usage of Samet and others.
69
 */
70
class GEOS_DLL Quadtree: public SpatialIndex {
71
72
private:
73
74
    std::vector<std::unique_ptr<geom::Envelope>> newEnvelopes;
75
76
    void collectStats(const geom::Envelope& itemEnv);
77
78
    Root root;
79
80
    /**
81
     *  Statistics
82
     *
83
     * minExtent is the minimum envelope extent of all items
84
     * inserted into the tree so far. It is used as a heuristic value
85
     * to construct non-zero envelopes for features with zero X and/or
86
     * Y extent.
87
     * Start with a non-zero extent, in case the first feature inserted has
88
     * a zero extent in both directions.  This value may be non-optimal, but
89
     * only one feature will be inserted with this value.
90
     */
91
    double minExtent;
92
93
public:
94
    /**
95
     * \brief
96
     * Ensure that the envelope for the inserted item has non-zero extents.
97
     *
98
     * Use the current minExtent to pad the envelope, if necessary.
99
     * Can return a new Envelope or the given one (casted to non-const).
100
     */
101
    static geom::Envelope* ensureExtent(const geom::Envelope* itemEnv,
102
                                        double minExtent);
103
104
    /**
105
     * \brief
106
     * Constructs a Quadtree with zero items.
107
     */
108
    Quadtree()
109
        :
110
0
        root(),
111
0
        minExtent(1.0)
112
0
    {}
113
114
0
    ~Quadtree() override = default;
115
116
    /// Returns the number of levels in the tree.
117
    std::size_t depth();
118
119
    /// Returns the number of items in the tree.
120
    std::size_t size();
121
122
    void insert(const geom::Envelope* itemEnv, void* item) override;
123
124
    /** \brief
125
     * Queries the tree and returns items which may lie
126
     * in the given search envelope.
127
     *
128
     * Precisely, the items that are returned are all items in the tree
129
     * whose envelope <b>may</b> intersect the search Envelope.
130
     * Note that some items with non-intersecting envelopes may be
131
     * returned as well;
132
     * the client is responsible for filtering these out.
133
     * In most situations there will be many items in the tree which do not
134
     * intersect the search envelope and which are not returned - thus
135
     * providing improved performance over a simple linear scan.
136
     *
137
     * @param searchEnv the envelope of the desired query area.
138
     * @param ret a vector where items which may intersect the
139
     *        search envelope are pushed
140
     */
141
    void query(const geom::Envelope* searchEnv, std::vector<void*>& ret) override;
142
143
144
    /** \brief
145
     * Queries the tree and visits items which may lie in
146
     * the given search envelope.
147
     *
148
     * Precisely, the items that are visited are all items in the tree
149
     * whose envelope <b>may</b> intersect the search Envelope.
150
     * Note that some items with non-intersecting envelopes may be
151
     * visited as well;
152
     * the client is responsible for filtering these out.
153
     * In most situations there will be many items in the tree which do not
154
     * intersect the search envelope and which are not visited - thus
155
     * providing improved performance over a simple linear scan.
156
     *
157
     * @param searchEnv the envelope of the desired query area.
158
     * @param visitor a visitor object which is passed the visited items
159
     */
160
    void
161
    query(const geom::Envelope* searchEnv, ItemVisitor& visitor) override
162
0
    {
163
        /*
164
         * the items that are matched are the items in quads which
165
         * overlap the search envelope
166
         */
167
0
        root.visit(searchEnv, visitor);
168
0
    }
169
170
    /**
171
     * Removes a single item from the tree.
172
     *
173
     * @param itemEnv the Envelope of the item to be removed
174
     * @param item the item to remove
175
     * @return <code>true</code> if the item was found (and thus removed)
176
     */
177
    bool remove(const geom::Envelope* itemEnv, void* item) override;
178
179
    /// Return a list of all items in the Quadtree
180
    std::vector<void*>* queryAll();
181
182
    std::string toString() const;
183
184
    /**
185
     * Disable copy construction and assignment. Apparently needed to make this
186
     * class compile under MSVC. (See https://stackoverflow.com/q/29565299)
187
     */
188
    Quadtree(const Quadtree&) = delete;
189
    Quadtree& operator=(const Quadtree&) = delete;
190
191
192
    // Move constructor
193
    Quadtree(Quadtree&& other) noexcept :
194
        newEnvelopes(std::move(other.newEnvelopes)),
195
        root(other.root),
196
        minExtent(other.minExtent)
197
0
    {
198
0
        // The contents of 'other' are moved to 'this'
199
0
        // 'other' will be empty after the move
200
0
    };
201
202
    // Move assignment operator
203
    Quadtree& operator=(Quadtree&& other) noexcept
204
0
    {
205
0
        if (this != &other) {
206
0
            // Move the vector from 'other' to 'this'
207
0
            // 'newEnvelopes.data' will be empty after this operation
208
0
            newEnvelopes.clear();
209
0
            newEnvelopes = std::move(other.newEnvelopes);
210
0
            minExtent = other.minExtent;
211
0
            root = other.root;
212
0
        }
213
0
        return *this;
214
0
    };
215
216
};
217
218
} // namespace geos::index::quadtree
219
} // namespace geos::index
220
} // namespace geos
221
222
#ifdef _MSC_VER
223
#pragma warning(pop)
224
#endif
225