1
/**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2006 Refractions Research Inc.
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.
13 **********************************************************************/
15 #ifndef GEOS_INDEX_STRTREE_ABSTRACTSTRTREE_H
16 #define GEOS_INDEX_STRTREE_ABSTRACTSTRTREE_H
18 #include <geos/export.h>
20 #include <geos/index/strtree/AbstractNode.h> // for inlines
24 #include <memory> // for auto_ptr
25 #include <cassert> // for inlines
28 // Forward declarations
40 namespace index
{ // geos::index
41 namespace strtree
{ // geos::index::strtree
43 /// A list of boundables. TODO: use a list
44 typedef std::vector
<Boundable
*> BoundableList
;
45 //typedef std::list<Boundable*> BoundableList;
47 /// list contains boundables or lists of boundables. The lists are owned by
48 /// this class, the plain boundables are held by reference only.
59 ItemsListItem(void *item_
)
64 ItemsListItem(ItemsList
* item_
)
70 type
get_type() const { return t
; }
72 void* get_geometry() const
74 assert(t
== item_is_geometry
);
77 ItemsList
* get_itemslist() const
79 assert(t
== item_is_list
);
90 class ItemsList
: public std::vector
<ItemsListItem
>
93 typedef std::vector
<ItemsListItem
> base_type
;
95 static void delete_item(ItemsListItem
& item
)
97 if (ItemsListItem::item_is_list
== item
.t
)
104 std::for_each(begin(), end(), &ItemsList::delete_item
);
107 // lists of items need to be deleted in the end
108 void push_back(void* item
)
110 this->base_type::push_back(ItemsListItem(item
));
113 // lists of items need to be deleted in the end
114 void push_back_owned(ItemsList
* itemList
)
116 this->base_type::push_back(ItemsListItem(itemList
));
121 * Base class for STRtree and SIRtree.
123 * STR-packed R-trees are described in:
124 * P. Rigaux, Michel Scholl and Agnes Voisard. Spatial Databases With
125 * Application To GIS. Morgan Kaufmann, San Francisco, 2002.
127 * This implementation is based on Boundables rather than just AbstractNodes,
128 * because the STR algorithm operates on both nodes and
129 * data, both of which are treated here as Boundables.
132 class GEOS_DLL AbstractSTRtree
{
136 BoundableList
* itemBoundables
;
139 * Creates the levels higher than the given level
141 * @param boundablesOfALevel
142 * the level to build on
144 * the level of the Boundables, or -1 if the boundables are item
145 * boundables (that is, below level 0)
146 * @return the root, which may be a ParentNode or a LeafNode
148 virtual AbstractNode
* createHigherLevels(
149 BoundableList
* boundablesOfALevel
,
152 virtual std::auto_ptr
<BoundableList
> sortBoundables(const BoundableList
* input
)=0;
154 bool remove(const void* searchBounds
, AbstractNode
& node
, void* item
);
155 bool removeItem(AbstractNode
& node
, void* item
);
157 ItemsList
* itemsTree(AbstractNode
* node
);
162 * A test for intersection between two bounds, necessary because
163 * subclasses of AbstractSTRtree have different implementations of
166 class GEOS_DLL IntersectsOp
{
169 * For STRtrees, the bounds will be Envelopes; for
170 * SIRtrees, Intervals; for other subclasses of
171 * AbstractSTRtree, some other class.
172 * @param aBounds the bounds of one spatial object
173 * @param bBounds the bounds of another spatial object
174 * @return whether the two bounds intersect
176 virtual bool intersects(const void* aBounds
,
177 const void* bBounds
)=0;
179 virtual ~IntersectsOp() {}
184 std::vector
<AbstractNode
*> *nodes
;
186 // Ownership to caller (TODO: return by auto_ptr)
187 virtual AbstractNode
* createNode(int level
)=0;
190 * Sorts the childBoundables then divides them into groups of size M, where
191 * M is the node capacity.
193 virtual std::auto_ptr
<BoundableList
> createParentBoundables(
194 BoundableList
* childBoundables
, int newLevel
);
196 virtual AbstractNode
* lastNode(BoundableList
* nodeList
)
198 assert(!nodeList
->empty());
199 // Cast from Boundable to AbstractNode
200 return static_cast<AbstractNode
*>(nodeList
->back() );
203 virtual AbstractNode
* getRoot() {
208 /// Also builds the tree, if necessary.
209 virtual void insert(const void* bounds
,void* item
);
211 /// Also builds the tree, if necessary.
212 void query(const void* searchBounds
, std::vector
<void*>& foundItems
);
215 /// Also builds the tree, if necessary.
216 std::vector
<void*>* query(const void* searchBounds
) {
217 vector
<void*>* matches
= new vector
<void*>();
218 query(searchBounds
, *matches
);
222 /// Also builds the tree, if necessary.
223 void query(const void* searchBounds
, ItemVisitor
& visitor
);
225 void query(const void* searchBounds
, const AbstractNode
& node
, ItemVisitor
& visitor
);
227 /// Also builds the tree, if necessary.
228 bool remove(const void* itemEnv
, void* item
);
230 std::auto_ptr
<BoundableList
> boundablesAtLevel(int level
);
232 // @@ should be size_t, probably
233 std::size_t nodeCapacity
;
236 * @return a test for intersection between two bounds,
237 * necessary because subclasses
238 * of AbstractSTRtree have different implementations of bounds.
241 virtual IntersectsOp
*getIntersectsOp()=0;
247 * Constructs an AbstractSTRtree with the specified maximum number of child
248 * nodes that a node may have
250 AbstractSTRtree(std::size_t newNodeCapacity
)
253 itemBoundables(new BoundableList()),
254 nodes(new std::vector
<AbstractNode
*>()),
255 nodeCapacity(newNodeCapacity
)
257 assert(newNodeCapacity
>1);
260 static bool compareDoubles(double a
, double b
) {
262 // Ternary operation is a workaround for
263 // a probable MingW bug, see
264 // http://trac.osgeo.org/geos/ticket/293
265 return ( a
< b
) ? true : false;
268 virtual ~AbstractSTRtree();
271 * Creates parent nodes, grandparent nodes, and so forth up to the root
272 * node, for the data that has been inserted into the tree. Can only be
273 * called once, and thus can be called only after all of the data has been
274 * inserted into the tree.
276 virtual void build();
279 * Returns the maximum number of child nodes that a node may have
281 virtual std::size_t getNodeCapacity() { return nodeCapacity
; }
283 virtual void query(const void* searchBounds
, const AbstractNode
* node
, std::vector
<void*>* matches
);
286 * Iterate over all items added thus far. Explicitly does not build
289 void iterate(ItemVisitor
& visitor
);
293 * @param level -1 to get items
295 virtual void boundablesAtLevel(int level
, AbstractNode
* top
,
296 BoundableList
* boundables
);
299 * Gets a tree structure (as a nested list)
300 * corresponding to the structure of the items and nodes in this tree.
302 * The returned {@link List}s contain either {@link Object} items,
303 * or Lists which correspond to subtrees of the tree
304 * Subtrees which do not contain any items are not included.
306 * Builds the tree if necessary.
308 * @note The caller is responsible for releasing the list
310 * @return a List of items and/or Lists
312 ItemsList
* itemsTree();
316 } // namespace geos::index::strtree
317 } // namespace geos::index
320 #endif // GEOS_INDEX_STRTREE_ABSTRACTSTRTREE_H