One, what is Rtree
"R-Tree is another form of B-tree development to multidimensional space, it divides the space objects by scope, each node corresponds to a region and a disk page, a non-leaf node's disk page stores all of its child nodes, and the region of all the nodes of the Non-leaf node falls within its range. The disk page of a leaf node stores an external rectangle for all space objects within its range. Each node can have the number of sub nodes have upper and lower limit, guarantee the effective use of disk space, the upper limit to ensure that each node corresponds to a disk page, when the insertion of a new node caused a node required more space than a disk page, the node in Split. The R-Tree is a dynamic index structure, that is, its query can take place at the same time as inserts or deletes, and does not require regular tree structure restructuring. When a relationship is updated and a scan is being done on this relationship, if the update affects any page of the scan, we need to check the scan and fix it. ”
In fact, you do not have to do more research. Understanding Rtree is a range tree, suitable for doing spatial indexing (quick lookup). More about Rtree I have no time to write here, I only know the principle, and then provide the following code (after I modified, look more pleasing to the eye). Be sure to use it. Thanks to the original author of the algorithm and the person who invented the algorithm. "The establishment of the Empire State Building, more people in capital" Ah!
Second, the implementation of Rtree code
The code of this article originates from grass, I have made the appropriate modification according to own custom, has synthesized the original multiple files 2 files (rtree.h and rtree.c). This article provides a complete Rtree implementation code and a simple test code (TEST.C). If you find any problems, please submit the comments in time to facilitate the correction.
RTree.h file:
/****************************************************************************
* RTree.H
*
* Module:r-tree Library
*
* AUTHOR (S): Antonin guttman-original Code
* Daniel Green (green@superliminal.com)-Major clean-up
* and implementation of bounding spheres
*
* Purpose:multi dimensional Index
*
* COPYRIGHT: (C) 2001 by the GRASS Development team
*
* This are free software under the GNU general public
* License (>=V2). Read the file copying that comes with GRASS
* For details.
*
* Last Modify:zhangliang (cheungmine@gmail.com)-2007-11
*****************************************************************************/
#ifndef rtree_h_included
#define Rtree_h_included
/* Page_size is normally the natural PAGE SIZE of the machine * *
#define PAGE_SIZE 512
#define DIMS_NUMB 3/* Number of dimensions * *
#define SIDES_NUMB 2*dims_numb
/* typedef float REALTYPE; */
typedef double REALTYPE;
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
typedef struct _RTREEMBR
{
RealType Bound[sides_numb]; /* Xmin,ymin,..., xmax,ymax,... * *
}RTREEMBR;
typedef struct _RTREEBRANCH
{
RTREEMBR MBR;
struct _rtreenode *child; /* MBR ID * *
}rtreebranch;
/* Max branching factor of a node */
#define Maxcard (int) (page_size-(2*sizeof (int))/sizeof (Rtreebranch))
typedef struct _RTREENODE
{
int count;
int level; /* 0 is leaf, others positive * *
Rtreebranch Branch[maxcard];
}rtreenode;
typedef struct _RTREELISTNODE
{
struct _rtreelistnode *next;
Rtreenode *node;
}rtreelistnode;
/*
* If passed to a tree search, this callback function would be called
* With the ID of each data mbr, that overlaps the search MBR
* Plus whatever user specific pointer is passed to the search.
* It can terminate the search early by returning 0 in which case
* The search would return the number of hits found of the.
*/
typedef int (*pfnsearchhitcallback) (int id, void* pfnparam);
int Rtreesetnodemax (int new_max);
int Rtreesetleafmax (int new_max);
int Rtreegetnodemax (void);
int Rtreegetleafmax (void);
/**
* Initialize a rectangle to have all 0 coordinates.
*/
void Rtreeinitrect (Rtreembr *rc);
/**
* Return a MBR whose the side is higher than its opposite side-
* Interpreted as an undefined mbr.
*/
RTREEMBR rtreenullrect (void);
/**
* Print out of the data for a rectangle.
*/
void Rtreeprintrect (rtreembr *rc, int depth);
/**
* Calculate the 2-dimensional area of a rectangle
*/
RealType Rtreerectarea (rtreembr *RC);
/**
* Calculate the n-dimensional volume of a rectangle
*/
RealType Rtreerectvolume (rtreembr *RC);
/**
* Calculate the n-dimensional volume of the bounding sphere of a rectangle
* The exact volume of the bounding sphere for the given rtreembr.
*/
RealType Rtreerectsphericalvolume (rtreembr *RC);
/**
* Calculate the n-dimensional surface area of a rectangle
*/
RealType Rtreerectsurfacearea (rtreembr *RC);
/**
* Combine two rectangles, make one of that includes both.
*/
Rtreembr Rtreecombinerect (rtreembr *rc1, rtreembr *rc2);
/**
* Decide whether two rectangles overlap.
*/
int Rtreeoverlap (rtreembr *rc1, rtreembr *rc2);
/**
* Decide whether rectangle R is contained in rectangle S.
*/
int rtreecontained (rtreembr *r, rtreembr *s);
/**
* Split a node.
* Divides the nodes branches and the extra one between two.
* Old node are one of the new ones, and one really new one is created.
* Tries more than one method for choosing a partition, uses best result.
*/
void Rtreesplitnode (Rtreenode *node, Rtreebranch *br, Rtreenode **new_node);
/**
* Initialize a RTREENODE structure.
*/
void Rtreeinitnode (Rtreenode *node);
/**
* Make a new node and initialize to have all branch cells empty.
*/
Rtreenode *rtreenewnode (void);
void Rtreefreenode (Rtreenode *node);
/**
* Print out of the data in a node.
*/
void Rtreeprintnode (Rtreenode *node, int depth);
/**
* Find the smallest rectangle this includes all rectangles in branches of a node.
*/
Rtreembr rtreenodecover (Rtreenode *node);
/**
* Pick a branch. Pick the one that would need the smallest increase
* in area to accomodate the new rectangle. This is the
* Least total area for the covering rectangles at the current node.
* In case of a tie, pick the one which is smaller before, to get
* The best resolution when searching.
*/
int Rtreepickbranch (rtreembr *rc, Rtreenode *node);
/**
* ADD a branch to a node. Split the node if necessary.
* Returns 0 if node not split. Old node updated.
* Returns 1 if node split, sets *new_node to address of new node.
* Old node updated, becomes one of two.
*/
int Rtreeaddbranch (Rtreebranch *br, Rtreenode *node, Rtreenode **new_node);
/**
* Disconnect a dependent node.
*/
void Rtreedisconnectbranch (Rtreenode *node, int i);
/**
* Destroy (free) node recursively.
*/
void Rtreedestroynode (Rtreenode *node);
/**
* Create A new rtree index, empty. Consists of a single node.
*/
Rtreenode * rtreecreate (void);
/**
* Destroy A rtree root must is a root of rtree. Free all memory.
*/
void Rtreedestroy (Rtreenode *root);
/**
* Search in a index tree or subtree to all data rectangles that overlap the argument rectangle.
* Return the number of qualifying data rects.
*/
int Rtreesearch (Rtreenode *node, rtreembr *rc, Pfnsearchhitcallback PFNSHCB, void* pfnparam);
/**
* Insert a data rectangle into a index structure.
* Rtreeinsertrect provides for splitting the root;
* Returns 1 if Root was split, 0 if it is not.
* The level argument specifies the number of steps up from the leaf
* Level to insert; e.g. a data rectangle goes in the level = 0.
* _rtreeinsertrect does the recursion.
*/
int Rtreeinsertrect (rtreembr *rc, int tid, rtreenode **root, int level);
/**
* Delete a data rectangle from a index structure.
* Pass in a pointer to a RTREEMBR, the Tid's, ptr to ptr to root node.
* Returns 1 if record is not found, 0 if success.
* Rtreedeleterect provides for eliminating the root.
*/
int Rtreedeleterect (rtreembr *rc, int tid, Rtreenode **root);
#endif/* rtree_h_included * *