Complete Note#1 in the http://wiki.osgeo.org/wiki/GEOS_Provenance_Review to get out...
[geos.git] / include / geos / index / strtree / AbstractSTRtree.h
blob910528ad5c9d9dbe4e5d67aa0d756f8b760258e6
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
22 #include <vector>
23 #include <list>
24 #include <memory> // for auto_ptr
25 #include <cassert> // for inlines
26 #include <algorithm>
28 // Forward declarations
29 namespace geos {
30 namespace index {
31 class ItemVisitor;
32 namespace strtree {
33 class Boundable;
34 class AbstractNode;
39 namespace geos {
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.
49 class ItemsList;
51 class ItemsListItem
53 public:
54 enum type {
55 item_is_geometry,
56 item_is_list
59 ItemsListItem(void *item_)
60 : t(item_is_geometry)
62 item.g = item_;
64 ItemsListItem(ItemsList* item_)
65 : t(item_is_list)
67 item.l = item_;
70 type get_type() const { return t; }
72 void* get_geometry() const
74 assert(t == item_is_geometry);
75 return item.g;
77 ItemsList* get_itemslist() const
79 assert(t == item_is_list);
80 return item.l;
83 type t;
84 union {
85 void* g;
86 ItemsList* l;
87 } item;
90 class ItemsList : public std::vector<ItemsListItem>
92 private:
93 typedef std::vector<ItemsListItem> base_type;
95 static void delete_item(ItemsListItem& item)
97 if (ItemsListItem::item_is_list == item.t)
98 delete item.item.l;
101 public:
102 ~ItemsList()
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));
120 /** \brief
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 {
134 private:
135 bool built;
136 BoundableList* itemBoundables;
139 * Creates the levels higher than the given level
141 * @param boundablesOfALevel
142 * the level to build on
143 * @param level
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,
150 int level);
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);
159 protected:
161 /** \brief
162 * A test for intersection between two bounds, necessary because
163 * subclasses of AbstractSTRtree have different implementations of
164 * bounds.
166 class GEOS_DLL IntersectsOp {
167 public:
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() {}
182 AbstractNode *root;
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* nodes)
198 assert(!nodes->empty());
199 // Cast from Boundable to AbstractNode
200 return static_cast<AbstractNode*>( nodes->back() );
203 virtual AbstractNode* getRoot() {
204 assert(built);
205 return root;
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);
214 #if 0
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);
219 return matches;
221 #endif
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.
239 * @see IntersectsOp
241 virtual IntersectsOp *getIntersectsOp()=0;
244 public:
247 * Constructs an AbstractSTRtree with the specified maximum number of child
248 * nodes that a node may have
250 AbstractSTRtree(std::size_t newNodeCapacity)
252 built(false),
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) {
261 // NOTE - strk:
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
287 * the tree.
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.
301 * <p>
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.
305 * <p>
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
318 } // namespace geos
320 #endif // GEOS_INDEX_STRTREE_ABSTRACTSTRTREE_H
322 /**********************************************************************
323 * $Log$
324 * Revision 1.3 2006/06/12 10:49:43 strk
325 * unsigned int => size_t
327 * Revision 1.2 2006/06/08 11:20:24 strk
328 * Added missing virtual destructor to abstract classes.
330 * Revision 1.1 2006/03/21 10:47:34 strk
331 * indexStrtree.h split
333 **********************************************************************/