QuadTree内存索引
来源:互联网 发布:成睿进销存软件 编辑:程序博客网 时间:2024/06/05 10:03
#ifndef SHAPEFILE_H_INCLUDED
#define SHAPEFILE_H_INCLUDED
#include <stdio.h>
typedef LONG OBJTYPE;
/* this can be two or four for binary or quad tree */
#define MAX_SUBNODE 4
/* upper limit of tree levels for automatic estimation */
#define MAX_DEFAULT_TREE_DEPTH 12
typedef struct qtree_box
{
double minx;
double maxx;
double miny;
double maxy;
} QTreeBox;
typedef struct sdx_tree_node
{
QTreeBox box;
LONG nShapeCapacity;
LONG nShapeCount;
OBJTYPE *pShapes;
int nSubNodes;
struct sdx_tree_node *pSubNodes[MAX_SUBNODE];
} SDXTreeNode;
typedef struct
{
int nMaxDepth;
int nDimension;
int nTotalCount;
SDXTreeNode *psRoot;
} SDXTree;
SDXTree * SDX_CreateTree( QTreeBox *box, int nDimension, int nMaxDepth );
void SDX_DestroyTree( SDXTree * hTree );
int SDX_TreeAddShape( SDXTree * hTree, OBJTYPE obj);
int SDX_TreeRemoveShape( SDXTree * hTree, OBJTYPE obj );
void SDX_TreeTrimExtraNodes( SDXTree * hTree );
OBJTYPE *SDX_TreeFindLikelyShapes( SDXTree * hTree, QTreeBox *box, OBJTYPE * );
int SDX_CheckBoundsOverlap( QTreeBox &src, QTreeBox *dest, OBJTYPE );
#endif /* ndef SHAPEFILE_H_INCLUDED */
#include "stdafx.h"
#include "quadtree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef TRUE
# define TRUE 1
# define FALSE 0
#endif
static int bBigEndian = 0;
/* -------------------------------------------------------------------- */
/* If the following is 0.5, nodes will be split in half. If it */
/* is 0.6 then each subnode will contain 60% of the parent */
/* node, with 20% representing overlap. This can be help to */
/* prevent small objects on a boundary from shifting too high */
/* up the tree. */
/* -------------------------------------------------------------------- */
#define SHP_SPLIT_RATIO 0.55
static void * SDX_SfRealloc( void * pMem, int nNewSize )
{
if( pMem == NULL )
return( (void *) malloc(nNewSize) );
else
return( (void *) realloc(pMem,nNewSize) );
}
// If no max depth was defined, try to select a reasonable one
// that implies approximately 8 shapes per node.
int SDX_GetDefaultDepth(int count)
{
int nMaxNodeCount = 1;
int nMaxDepth = 0;
while( nMaxNodeCount*4 < count )
{
nMaxDepth += 1;
nMaxNodeCount = nMaxNodeCount * 2;
}
return nMaxDepth;
}
static SDXTreeNode *SDX_TreeNodeCreate( QTreeBox *box )
{
if (NULL==box)
return NULL;
SDXTreeNode *pTreeNode;
pTreeNode = (SDXTreeNode *) malloc(sizeof(SDXTreeNode));
if( NULL == pTreeNode )
{
return NULL;
}
pTreeNode->box = *box;
pTreeNode->nShapeCount = 0;
pTreeNode->nShapeCapacity= 0;
pTreeNode->pShapes = NULL;
pTreeNode->nSubNodes = 0;
return pTreeNode;
}
SDXTree * SDX_CreateTree( QTreeBox *box, int nDimension, int nMaxDepth )
{
SDXTree *psTree;
psTree = (SDXTree *) malloc(sizeof(SDXTree));
if( NULL == psTree )
{
return NULL;
}
psTree->nMaxDepth = nMaxDepth;
psTree->nDimension = nDimension;
psTree->nTotalCount = 0;
if( psTree->nMaxDepth > MAX_DEFAULT_TREE_DEPTH || psTree->nMaxDepth==0)
{
psTree->nMaxDepth = MAX_DEFAULT_TREE_DEPTH;
}
psTree->psRoot = SDX_TreeNodeCreate( box );
if( NULL == psTree->psRoot )
{
return NULL;
}
return psTree;
}
static void SDX_DestroyTreeNode( SDXTreeNode * pTreeNode )
{
if ( NULL == pTreeNode )
return;
int i;
for( i = 0; i < pTreeNode->nSubNodes; i++ )
{
if( pTreeNode->pSubNodes[i] != NULL )
SDX_DestroyTreeNode( pTreeNode->pSubNodes[i] );
}
if( pTreeNode->pShapes != NULL )
free( pTreeNode->pShapes );
free( pTreeNode );
}
void SHPDestroyTree( SDXTree * psTree )
{
SDX_DestroyTreeNode( psTree->psRoot );
free( psTree );
}
int SHPCheckBoundsOverlap( QTreeBox *src, QTreeBox *dest, int nDimension )
{
if (2==nDimension)
{
if (src->minx>dest->maxy || src->maxx<dest->minx
|| src->miny>dest->maxy || src->maxy<dest->miny)
return FALSE;
else
return TRUE;
}
return FALSE;
}
// src contains dest ?
static BOOL SHPCheckContained( QTreeBox *src, QTreeBox *dest, int nDimension )
{
if( dest->minx< src->minx || dest->maxx>src->maxx
|| dest->miny< src->miny || dest->maxy>src->maxy )
return FALSE;
return TRUE;
}
// Split a region into two subregion evenly, cutting along the longest dimension. */
void SHPTreeSplitBounds( QTreeBox *src, QTreeBox *dest)
{
if (NULL==dest || NULL==src)
return;
memcpy( dest, src, sizeof(QTreeBox) );
memcpy( dest+1, src, sizeof(QTreeBox) );
// Split in X direction.
double xDelta = src->maxx-src->minx;
double yDelta = src->maxy-src->miny;
if( xDelta > yDelta )
{
dest[0].maxx = src->minx + xDelta * SHP_SPLIT_RATIO;
dest[1].minx = src->maxx - xDelta * SHP_SPLIT_RATIO;
}
// Split in X direction.
else
{
dest[0].maxy = src->miny + yDelta * SHP_SPLIT_RATIO;
dest[1].miny = src->maxy - yDelta * SHP_SPLIT_RATIO;
}
}
static int SDX_TreeNodeAddShape( SDXTreeNode * pTreeNode, QTreeBox *box, OBJTYPE obj,
int nMaxDepth, int nDimension )
{
int i;
// If there are subnodes, then consider wether this object will fit in them.
if( nMaxDepth > 1 && pTreeNode->nSubNodes > 0 )
{
for( i = 0; i < pTreeNode->nSubNodes; i++ )
{
if( SHPCheckContained( &(pTreeNode->pSubNodes[i]->box), box, nDimension) )
{
return SDX_TreeNodeAddShape( pTreeNode->pSubNodes[i], box, obj, nMaxDepth-1, nDimension );
}
}
}
else if( nMaxDepth > 1 && pTreeNode->nSubNodes == 0 )
{
QTreeBox boxH[2];
QTreeBox box1[2];
QTreeBox box2[2];
SHPTreeSplitBounds( &(pTreeNode->box), boxH);
SHPTreeSplitBounds( &(boxH[0]), box1 );
SHPTreeSplitBounds( &(boxH[1]), box2 );
if( SHPCheckContained( &(box1[0]), box, nDimension )
|| SHPCheckContained( &(box1[1]), box, nDimension)
|| SHPCheckContained( &(box2[0]), box, nDimension )
|| SHPCheckContained( &(box2[1]), box, nDimension ) )
{
pTreeNode->nSubNodes = 4;
pTreeNode->pSubNodes[0] = SDX_TreeNodeCreate( &(box1[0]) );
pTreeNode->pSubNodes[1] = SDX_TreeNodeCreate( &(box1[1]) );
pTreeNode->pSubNodes[2] = SDX_TreeNodeCreate( &(box2[0]) );
pTreeNode->pSubNodes[3] = SDX_TreeNodeCreate( &(box2[1]) );
/* recurse back on this node now that it has subnodes */
return( SDX_TreeNodeAddShape( pTreeNode, box, obj, nMaxDepth, nDimension ) );
}
}
// If none of that worked, just add it to this nodes list.
pTreeNode->nShapeCount++;
if ( pTreeNode->nShapeCapacity < pTreeNode->nShapeCount )
{
pTreeNode->pShapes = (LONG *) SDX_SfRealloc( pTreeNode->pShapes, sizeof(OBJTYPE) * (pTreeNode->nShapeCapacity+16) );
pTreeNode->pShapes[pTreeNode->nShapeCount-1] = obj;
}
return TRUE;
}
// Work function implementing SDX_TreeFindLikelyShapes() on a tree node by tree node basis
void SDX_TreeCollectShapes( SDXTree *hTree, SDXTreeNode * pTreeNode,
QTreeBox *box,
int * pnShapeCount, int * pnMaxShapes,
OBJTYPE ** ppanShapeList )
{
int i;
// Does this node overlap the area of interest at all? If not,
// return without adding to the list at all.
if( !SHPCheckBoundsOverlap( &(pTreeNode->box), box, hTree->nDimension ) )
return;
// Grow the list to hold the shapes on this node
if( *pnShapeCount + pTreeNode->nShapeCount > *pnMaxShapes )
{
*pnMaxShapes = (*pnShapeCount + pTreeNode->nShapeCount) * 2 + 20;
*ppanShapeList = (OBJTYPE *)
SDX_SfRealloc(*ppanShapeList,sizeof(OBJTYPE) * *pnMaxShapes);
}
// Add the local nodes shapeids to the list
for( i = 0; i < pTreeNode->nShapeCount; i++ )
{
(*ppanShapeList)[(*pnShapeCount)++] = pTreeNode->pShapes[i];
}
// Recurse to subnodes if they exist
for( i = 0; i < pTreeNode->nSubNodes; i++ )
{
if( pTreeNode->pSubNodes[i] != NULL )
SDX_TreeCollectShapes( hTree, pTreeNode->pSubNodes[i],
box,
pnShapeCount, pnMaxShapes,
ppanShapeList );
}
}
/************************************************************************/
/* SDX_TreeFindLikelyShapes() */
/* */
/* Find all shapes within tree nodes for which the tree node */
/* bounding box overlaps the search box. The return value is */
/* an array of shapeids terminated by a -1. The shapeids will */
/* be in order, as hopefully this will result in faster (more */
/* sequential) reading from the file. */
/************************************************************************/
/* helper for qsort */
static int
compare_ints( const void * a, const void * b)
{
return (*(int*)a) - (*(int*)b);
}
OBJTYPE * SDX_TreeFindLikelyShapes( SDXTree * hTree,
QTreeBox *box, int * pnShapeCount )
{
OBJTYPE *panShapeList=NULL;
int nMaxShapes = 0;
*pnShapeCount = 0;
SDX_TreeCollectShapes( hTree, hTree->psRoot,
box,
pnShapeCount, &nMaxShapes,
&panShapeList );
return panShapeList;
}
// This is the recurve version of SDX_TreeTrimExtraNodes() that walks the tree cleaning it up.
static int SDX_TreeNodeTrim( SDXTreeNode * pTreeNode )
{
int i;
/* -------------------------------------------------------------------- */
/* Trim subtrees, and free subnodes that come back empty. */
/* -------------------------------------------------------------------- */
for( i = 0; i < pTreeNode->nSubNodes; i++ )
{
if( SDX_TreeNodeTrim( pTreeNode->pSubNodes[i] ) )
{
SDX_DestroyTreeNode( pTreeNode->pSubNodes[i] );
pTreeNode->pSubNodes[i] =
pTreeNode->pSubNodes[pTreeNode->nSubNodes-1];
pTreeNode->nSubNodes--;
i--; /* process the new occupant of this subnode entry */
}
}
return( pTreeNode->nSubNodes == 0 && pTreeNode->nShapeCount == 0 );
}
// Trim empty nodes from the tree. Note that we never trim an empty root node
void SDX_TreeTrimExtraNodes( SDXTree * hTree )
{
SDX_TreeNodeTrim( hTree->psRoot );
}
/************************************************************************/
/* SwapWord() */
/* */
/* Swap a 2, 4 or 8 byte word. */
/************************************************************************/
static void SwapWord( int length, void * wordP )
{
int i;
unsigned char temp;
for( i=0; i < length/2; i++ )
{
temp = ((unsigned char *) wordP)[i];
((unsigned char *)wordP)[i] = ((unsigned char *) wordP)[length-i-1];
((unsigned char *) wordP)[length-i-1] = temp;
}
}
- QuadTree内存索引
- zoj1955-Quadtree
- zoj1959-Quadtree II
- QuadTree c++实验结果
- d3,四叉树,quadtree
- Quadtree - ZOJ 1955 四分树
- 四叉树QuadTree源码
- Terrain LOD ---QuadTree
- lucene-内存索引、内存索引保存在硬盘、索引优化
- Lucene_demo05_内存索引和文件索引
- Lucene的内存索引和磁盘索引
- 内存数据库T-tree索引
- lucene 中文分词 内存索引
- 内存数据库T-tree索引
- 内存数据库T-tree索引
- 内存数据库中的索引技术
- 内存数据库中的索引技术
- 内存数据库中的索引技术
- #define用法
- struts的上传、下载
- vs2010 vc6 编译体积优化
- 我的新空间是mader2028-----csdn.net
- C++实现队列进栈、出栈、打印数据
- QuadTree内存索引
- 页面表格被全角字符撑变形
- Qt中进度条的颜色设置
- 用qmake快速生成makefile
- turine
- MySQL ADO.NET接口程序测试
- Qt4中的模态与非模态对话框用法总结
- Web错误代码详解
- 不断完善,要有个较完善的项目