1
// Spatial Index Library
3
// Copyright (C) 2002 Navel Ltd.
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
namespace SpatialIndex
33
typedef Tools::PoolPointer<Node> NodePtr;
35
class Node : public SpatialIndex::INode
41
// Tools::IObject interface
43
virtual Tools::IObject* clone();
46
// Tools::ISerializable interface
48
virtual uint32_t getByteArraySize();
49
virtual void loadFromByteArray(const byte* data);
50
virtual void storeToByteArray(byte** data, uint32_t& len);
53
// SpatialIndex::IEntry interface
55
virtual id_type getIdentifier() const;
56
virtual void getShape(IShape** out) const;
59
// SpatialIndex::INode interface
61
virtual uint32_t getChildrenCount() const;
62
virtual id_type getChildIdentifier(uint32_t index) const;
63
virtual void getChildShape(uint32_t index, IShape** out) const;
64
virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
65
virtual uint32_t getLevel() const;
66
virtual bool isIndex() const;
67
virtual bool isLeaf() const;
71
Node(TPRTree* pTree, id_type id, uint32_t level, uint32_t capacity);
73
virtual Node& operator=(const Node&);
75
virtual bool insertEntry(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id);
76
virtual void deleteEntry(uint32_t index);
78
virtual bool insertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable);
79
virtual void reinsertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep);
81
virtual void rstarSplit(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
83
virtual void condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis);
85
virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
86
virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
88
virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right) = 0;
91
// Parent of all nodes.
94
// The level of the node in the tree.
95
// Leaves are always at level 0.
98
// The unique ID of this node.
101
// The number of children pointed by this node.
104
// Specifies the node capacity.
106
MovingRegion m_nodeMBR;
107
// The minimum bounding region enclosing all data contained in the node.
110
// The data stored in the node.
112
MovingRegionPtr* m_ptrMBR;
113
// The corresponding data MBRs.
115
id_type* m_pIdentifier;
116
// The corresponding data identifiers.
118
uint32_t* m_pDataLength;
120
uint32_t m_totalDataLength;
122
class RstarSplitEntry
125
MovingRegion* m_pRegion;
129
RstarSplitEntry(MovingRegion* pr, uint32_t index, uint32_t dimension)
130
: m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
132
static int compareLow(const void* pv1, const void* pv2)
134
RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
135
RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
137
if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return -1;
138
if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return 1;
142
static int compareHigh(const void* pv1, const void* pv2)
144
RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
145
RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
147
if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return -1;
148
if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return 1;
152
static int compareVLow(const void* pv1, const void* pv2)
154
RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
155
RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
157
if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] < pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return -1;
158
if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] > pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return 1;
162
static int compareVHigh(const void* pv1, const void* pv2)
164
RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
165
RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
167
if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return -1;
168
if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return 1;
171
}; // RstarSplitEntry
179
ReinsertEntry(uint32_t index, double dist) : m_index(index), m_dist(dist) {}
181
static int compareReinsertEntry(const void* pv1, const void* pv2)
183
ReinsertEntry* pe1 = * (ReinsertEntry**) pv1;
184
ReinsertEntry* pe2 = * (ReinsertEntry**) pv2;
186
if (pe1->m_dist < pe2->m_dist) return -1;
187
if (pe1->m_dist > pe2->m_dist) return 1;
192
// Needed to access protected members without having to cast from Node.
193
// It is more efficient than using member functions to access protected members.
194
friend class TPRTree;
197
friend class Tools::PointerPool<Node>;