83 for(
int i=0; i<4; i++)
102 for(
int i=0; i<4; i++)
143 if( x != pLeaf->
Get_X() || y != pLeaf->
Get_Y() )
197 Create(Extent, bStatistics);
207 Create(pShapes, Attribute, bStatistics);
256 if( Attribute < 0 || !pShape->is_NoData(Attribute) )
258 double z = Attribute < 0 ? iShape : pShape->
asDouble(Attribute);
270 return( m_nPoints > 0 );
288 m_Selection.Destroy();
299 if( _Check_Root(x, y) && m_pRoot->Add_Point(x, y, z) )
321bool CSG_PRQuadTree::_Check_Root(
double x,
double y)
328 if( m_pRoot->Get_Extent().Contains(x, y) )
334 int Quadrant = y < m_pRoot->Get_yMin()
335 ? (x < m_pRoot->Get_xMin() ? 0 : 3)
336 : (x < m_pRoot->Get_xMin() ? 1 : 2);
338 TSG_Rect Extent = m_pRoot->Get_Extent();
342 case 0: Extent.
xMin -= m_pRoot->Get_Size(); Extent.
yMin -= m_pRoot->Get_Size();
break;
343 case 1: Extent.
xMin -= m_pRoot->Get_Size(); Extent.
yMax += m_pRoot->Get_Size();
break;
344 case 2: Extent.
xMax += m_pRoot->Get_Size(); Extent.
yMin -= m_pRoot->Get_Size();
break;
345 case 3: Extent.
xMax += m_pRoot->Get_Size(); Extent.
yMax += m_pRoot->Get_Size();
break;
348 CSG_PRQuadTree_Node *pRoot;
350 if( m_pRoot->has_Statistics() )
352 CSG_PRQuadTree_Node_Statistics *pNode =
new CSG_PRQuadTree_Node_Statistics(Extent);
354 pNode->
m_x = ((CSG_PRQuadTree_Node_Statistics *)m_pRoot)->m_x;
355 pNode->
m_y = ((CSG_PRQuadTree_Node_Statistics *)m_pRoot)->m_y;
356 pNode->
m_z = ((CSG_PRQuadTree_Node_Statistics *)m_pRoot)->m_z;
362 pRoot =
new CSG_PRQuadTree_Node(Extent);
369 return( _Check_Root(x, y) );
378inline bool CSG_PRQuadTree::_Quadrant_Contains(
double x,
double y,
int iQuadrant,
const TSG_Point &p)
const
382 case 0:
return( x < p.
x && y < p.
y );
383 case 1:
return( x < p.x && y >= p.
y );
384 case 2:
return( x >= p.
x && y >= p.
y );
385 case 3:
return( x >= p.
x && y < p.
y );
392inline bool CSG_PRQuadTree::_Radius_Contains(
double x,
double y,
double r,
const TSG_Point &p)
const
396 if( fabs(dx = x - p.
x) <= r && fabs(dy = y - p.
y) <= r )
398 return( dx*dx + dy*dy < r*r );
405inline bool CSG_PRQuadTree::_Radius_Contains(
double x,
double y,
double r,
int iQuadrant,
const TSG_Point &p)
const
407 return( _Quadrant_Contains(x, y, iQuadrant, p) && _Radius_Contains(x, y, r, p) );
411inline bool CSG_PRQuadTree::_Quadrant_Intersects(
double x,
double y,
int iQuadrant,
CSG_PRQuadTree_Item *pItem)
const
415 case 0:
return( x < pItem->Get_xMax() && y < pItem->Get_yMax() );
416 case 1:
return( x < pItem->Get_xMax() && y >= pItem->
Get_yMin() );
418 case 3:
return( x >= pItem->
Get_xMin() && y < pItem->Get_yMax() );
425inline bool CSG_PRQuadTree::_Radius_Intersects(
double x,
double y,
double r,
CSG_PRQuadTree_Item *pItem)
const
438 if( (pItem->
Get_xMin() <= x && x <= pItem->Get_xMax())
439 || (pItem->
Get_yMin() <= y && y <= pItem->Get_yMax()) )
457 return( _Radius_Contains(x, y, r, p) );
461inline bool CSG_PRQuadTree::_Radius_Intersects(
double x,
double y,
double r,
int iQuadrant,
CSG_PRQuadTree_Item *pItem)
const
463 return( _Quadrant_Intersects(x, y, iQuadrant, pItem) && _Radius_Intersects(x, y, r, pItem) );
479 return( _Get_Nearest_Point(m_pRoot, x, y, Distance = -1) );
496 Value = pLeaf->
Get_Z();
517 if( Distance < 0.0 || Distance > d )
531 CSG_PRQuadTree_Item *pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i);
533 if( pChild && pChild->
Contains(x, y) && (pLeaf = _Get_Nearest_Point(pChild, x, y, Distance)) != NULL )
542 CSG_PRQuadTree_Item *pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i);
544 if( pChild && pChild->
Contains(x, y) ==
false && (Distance < 0.0
545 || ( Distance > (x < pChild->Get_xCenter() ? pChild->
Get_xMin() - x : x - pChild->
Get_xMax())
546 && Distance > (y < pChild->Get_yCenter() ? pChild->
Get_yMin() - y : y - pChild->
Get_yMax()) ))
547 && (pLeaf = _Get_Nearest_Point(pChild, x, y, Distance)) != NULL )
564inline CSG_PRQuadTree::TLeaf * CSG_PRQuadTree::_Get_Selected(
const CSG_Array &Selection,
size_t i)
const
566 return( (TLeaf *)Selection.
Get_Entry(i) );
577 pL->Distance = Distance;
588 TLeaf *pL = (TLeaf *)Selection.
Get_Entry(i);
593 pL->Distance = Distance;
615 return( _Select_Nearest_Points(m_Selection, x, y, maxPoints, Radius, iQuadrant) );
619size_t CSG_PRQuadTree::_Select_Nearest_Points(
CSG_Array &Selection,
double x,
double y,
size_t maxPoints,
double Radius,
int iQuadrant)
const
636 maxPoints = m_nPoints;
641 _Select_Nearest_Points(Selection, m_pRoot, x, y, Distance = 0.0, Radius, maxPoints, iQuadrant);
645 for(iQuadrant=0; iQuadrant<4; iQuadrant++)
647 _Select_Nearest_Points(Selection, m_pRoot, x, y, Distance = 0.0, Radius, maxPoints, iQuadrant);
656void CSG_PRQuadTree::_Select_Nearest_Points(
CSG_Array &Selection,
CSG_PRQuadTree_Item *pItem,
double x,
double y,
double &Distance,
double Radius,
size_t maxPoints,
int iQuadrant)
const
661 CSG_PRQuadTree_Leaf *pLeaf = (CSG_PRQuadTree_Leaf *)pItem;
663 if( _Quadrant_Contains(x, y, iQuadrant, pLeaf->
Get_Point()) ==
false )
670 if( Radius > 0.0 && Radius < d )
683 _Add_Selected(Selection, pLeaf, d);
685 else if( d < Distance )
687 for(
size_t i=0; i<Selection.
Get_uSize(); i++)
689 if( Distance <= _Get_Selected(Selection, i)->Distance )
691 _Set_Selected(Selection, i, pLeaf, d);
699 for(
size_t i=0; i<maxPoints; i++)
701 if( Distance < _Get_Selected(Selection, i)->Distance )
703 Distance = _Get_Selected(Selection, i)->Distance;
714 CSG_PRQuadTree_Item *pChild;
718 if( (pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i)) != NULL && pChild->
Contains(x, y) ==
true )
720 _Select_Nearest_Points(Selection, pChild, x, y, Distance, Radius, maxPoints, iQuadrant);
726 if( (pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i)) != NULL && pChild->
Contains(x, y) ==
false )
728 if( _Radius_Intersects(x, y, Radius, iQuadrant, pChild) )
731 || ( Distance > (x < pChild->Get_xCenter() ? pChild->
Get_xMin() - x : x - pChild->
Get_xMax())
732 && Distance > (y < pChild->Get_yCenter() ? pChild->
Get_yMin() - y : y - pChild->
Get_yMax()) ) )
734 _Select_Nearest_Points(Selection, pChild, x, y, Distance, Radius, maxPoints, iQuadrant);
758 _Select_Nearest_Points(Selection, x, y, maxPoints, Radius, iQuadrant);
762 for(
size_t i=0; i<Selection.
Get_uSize(); i++)
bool SG_UI_Process_Set_Progress(int Position, int Range)
void * Create(const CSG_Array &Array)
bool Set_Array(sLong nValues, bool bShrink=true)
bool Inc_Array(sLong nValues=1)
size_t Get_Value_Size(void) const
sLong Get_Size(void) const
size_t Get_uSize(void) const
void * Get_Entry(sLong Index) const
Returns a pointer to the memory address of the requested variable. You have to type cast and derefere...
virtual bool is_Leaf(void) const
double Get_xMax(void) const
double Get_yMin(void) const
double Get_yMax(void) const
CSG_PRQuadTree_Item(const CSG_Rect &Extent, int Quadrant=-1)
void Set_Extent(const CSG_Rect &Extent, int Quadrant=-1)
virtual bool has_Statistics(void) const
double Get_xMin(void) const
bool Contains(const CSG_Point &p) const
int Get_Quadrant(const TSG_Point &p) const
class CSG_PRQuadTree_Node * asNode(void) const
const TSG_Point & Get_Point(void) const
CSG_Simple_Statistics m_z
CSG_Simple_Statistics m_x
CSG_Simple_Statistics m_y
CSG_PRQuadTree_Item * Get_Child(int Quadrant) const
CSG_PRQuadTree_Item * m_pChildren[4]
virtual CSG_Simple_Statistics * Get_Z(void)
virtual ~CSG_PRQuadTree_Node(void)
virtual CSG_Simple_Statistics * Get_X(void)
CSG_PRQuadTree_Node(const CSG_Rect &Extent, int Quadrant=-1)
virtual CSG_Simple_Statistics * Get_Y(void)
virtual bool is_Node(void) const
bool Add_Point(double x, double y, double z)
size_t Get_Selected_Count(void) const
virtual ~CSG_PRQuadTree(void)
bool Create(const CSG_Rect &Extent, bool bStatistics=false)
CSG_PRQuadTree_Leaf * Get_Nearest_Leaf(const TSG_Point &p, double &Distance) const
size_t Select_Nearest_Points(const TSG_Point &p, size_t maxPoints, double Radius=0., int iQuadrant=-1)
size_t Get_Nearest_Points(CSG_Points_3D &Points, const TSG_Point &p, size_t maxPoints, double Radius=0., int iQuadrant=-1) const
bool Add_Point(double x, double y, double z)
bool Get_Nearest_Point(const TSG_Point &p, TSG_Point &Point, double &Value, double &Distance) const
bool Add(double x, double y, double z)
sLong Get_Count(void) const
double Get_YRange(void) const
double Get_YCenter(void) const
double Get_XRange(void) const
double Get_XCenter(void) const
virtual int Get_Point_Count(void) const =0
virtual int Get_Part_Count(void) const =0
virtual TSG_Point Get_Point(int iPoint=0) const =0
virtual bool is_Valid(void) const
virtual const CSG_Rect & Get_Extent(void)
virtual CSG_Shape * Get_Shape(const CSG_Point &Point, double Epsilon=0.)
void Add_Value(double Value, double Weight=1.)
double asDouble(int Field) const
sLong Get_Count(void) const
double SG_Get_Distance(double ax, double ay, double bx, double by, bool bPolar)