⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shapes_search.cpp

📁 这是一个GPS相关的程序
💻 CPP
字号:

///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//           Application Programming Interface           //
//                                                       //
//                  Library: SAGA_API                    //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                  shapes_search.cpp                    //
//                                                       //
//          Copyright (C) 2005 by Olaf Conrad            //
//                                                       //
//-------------------------------------------------------//
//                                                       //
// This file is part of 'SAGA - System for Automated     //
// Geoscientific Analyses'.                              //
//                                                       //
// This library is free software; you can redistribute   //
// it and/or modify it under the terms of the GNU Lesser //
// General Public License as published by the Free       //
// Software Foundation, version 2.1 of the License.      //
//                                                       //
// This library is distributed in the hope that it will  //
// be useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A  //
// PARTICULAR PURPOSE. See the GNU Lesser General Public //
// License for more details.                             //
//                                                       //
// You should have received a copy of the GNU Lesser     //
// General Public License along with this program; if    //
// not, write to the Free Software Foundation, Inc.,     //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307,   //
// USA.                                                  //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//    contact:    Olaf Conrad                            //
//                Institute of Geography                 //
//                University of Goettingen               //
//                Goldschmidtstr. 5                      //
//                37077 Goettingen                       //
//                Germany                                //
//                                                       //
//    e-mail:     oconrad@saga-gis.org                   //
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
#include "shapes.h"


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CSG_Shapes_Search::CSG_Shapes_Search(void)
{
	_On_Construction();
}

//---------------------------------------------------------
CSG_Shapes_Search::CSG_Shapes_Search(CSG_Shapes *pPoints)
{
	_On_Construction();

	Create(pPoints);
}

//---------------------------------------------------------
void CSG_Shapes_Search::_On_Construction(void)
{
	m_pPoints		= NULL;
	m_nPoints		= 0;
	m_bDestroy		= false;

	m_nSelected		= 0;
	m_Selected		= NULL;
	m_Selected_Dst	= NULL;
	m_Selected_Buf	= 0;

	m_Pos			= NULL;
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CSG_Shapes_Search::~CSG_Shapes_Search(void)
{
	Destroy();
}

//---------------------------------------------------------
void CSG_Shapes_Search::Destroy(void)
{
	if( m_nPoints > 0 )
	{
		SG_Free(m_Pos);
	}

	m_Pos			= NULL;
	m_Idx			.Destroy();

	//-----------------------------------------------------
	if( m_bDestroy && m_pPoints )
	{
		delete(m_pPoints);
	}

	m_pPoints		= NULL;
	m_nPoints		= 0;
	m_bDestroy		= false;

	//-----------------------------------------------------
	if( m_Selected )
	{
		SG_Free(m_Selected);
		SG_Free(m_Selected_Dst);
	}

	m_Selected		= NULL;
	m_Selected_Dst	= NULL;
	m_nSelected		= 0;
	m_Selected_Buf	= 0;

	m_Selected_Idx	.Destroy();
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Shapes_Search::Create(CSG_Shapes *pShapes)
{
	int		iShape, iPart, iPoint;
	CSG_Shape	*pShape, *pPoint;
	double	*Value;

	Destroy();

	//-----------------------------------------------------
	if( pShapes && pShapes->is_Valid() )
	{
		if( pShapes->Get_Type() == SHAPE_TYPE_Point )
		{
			m_bDestroy	= false;
			m_pPoints	= pShapes;
		}
		else
		{
			m_bDestroy	= true;
			m_pPoints	= SG_Create_Shapes(SHAPE_TYPE_Point, NULL, &pShapes->Get_Table());

			for(iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++)
			{
				pShape	= pShapes->Get_Shape(iShape);

				for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
				{
					for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
					{
						pPoint	= m_pPoints->Add_Shape(pShape->Get_Record());
						pPoint->Add_Point(pShape->Get_Point(iPoint, iPart));
					}
				}
			}
		}

		//-------------------------------------------------
		if( m_pPoints->Get_Count() > 1 )
		{
			m_nPoints	= m_pPoints->Get_Count();

			Value		= (double    *)SG_Malloc(m_nPoints * sizeof(double));
			m_Pos		= (TSG_Point *)SG_Malloc(m_nPoints * sizeof(TSG_Point));

			for(iPoint=0; iPoint<m_nPoints; iPoint++)
			{
				Value[iPoint]	= m_pPoints->Get_Shape(iPoint)->Get_Point(0).x;
			}

			m_Idx.Create(m_nPoints, Value, true);

			for(iPoint=0; iPoint<m_nPoints; iPoint++)
			{
				m_Pos[iPoint]	= m_pPoints->Get_Shape(m_Idx[iPoint])->Get_Point(0);
			}

			SG_Free(Value);

			return( true );
		}
	}

	//-----------------------------------------------------
	Destroy();

	return( false );
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
int CSG_Shapes_Search::_Get_Index_Next(double Position)
{
	int		i, iLo, iHi;

	if( m_Pos[0].x > Position )
	{
		return( 0 );
	}
	else if( m_Pos[m_nPoints - 1].x < Position )
	{
		return( m_nPoints - 1 );
	}

	for(iLo=0, iHi=m_nPoints-1; iHi-iLo>1; )
	{
		i	= iLo + (iHi - iLo) / 2;

		if( m_Pos[i].x <= Position )
		{
			iLo	= i;
		}
		else
		{
			iHi	= i;
		}
	}

	return( Position - m_Pos[iLo].x < m_Pos[iHi].x - Position ? iLo : iHi );
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CSG_Shape * CSG_Shapes_Search::Get_Point_Nearest(double x, double y)
{
	int			ax, ix, iPoint_Min;
	double		dx, dy, Dist, Dist_Min;

	//-----------------------------------------------------
	iPoint_Min	= -1;
	ax			= _Get_Index_Next(x);

	//-----------------------------------------------------
	for(ix=ax, Dist_Min=-1.0; ix<m_nPoints; ix++)
	{
		dy		= m_Pos[ix].y - y;
		dx		= m_Pos[ix].x - x;

		if( iPoint_Min >= 0 && Dist_Min < dx )
		{
			break;
		}
		else
		{
			Dist	= sqrt(dx*dx + dy*dy);

			if( iPoint_Min < 0 || Dist < Dist_Min )
			{
				iPoint_Min	= m_Idx[ix];
				Dist_Min	= Dist;
			}
		}
	}

	//-----------------------------------------------------
	for(ix=ax-1; ix>=0; ix--)
	{
		dy		= m_Pos[ix].y - y;
		dx		= m_Pos[ix].x - x;

		if( iPoint_Min >= 0 && Dist_Min < dx )
		{
			break;
		}
		else
		{
			Dist	= sqrt(dx*dx + dy*dy);

			if( iPoint_Min < 0 || Dist < Dist_Min )
			{
				iPoint_Min	= m_Idx[ix];
				Dist_Min	= Dist;
			}
		}
	}

	return( iPoint_Min < 0 ? NULL : m_pPoints->Get_Shape(iPoint_Min) );
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CSG_Shape * CSG_Shapes_Search::Get_Point_Nearest(double x, double y, int Quadrant)
{
	int		iPoint;

	iPoint	= _Get_Point_Nearest(x, y, Quadrant);

	return( iPoint >= 0 && iPoint < m_nPoints ? m_pPoints->Get_Shape(iPoint) : NULL );
}

//---------------------------------------------------------
int CSG_Shapes_Search::_Get_Point_Nearest(double x, double y, int Quadrant)
{
	int		ax, ix, iPoint_Min;
	double	dx, dy, Dist, Dist_Min;

	//-----------------------------------------------------
	Dist_Min	= -1.0;
	iPoint_Min	= -1;
	ax			= _Get_Index_Next(x);

	switch( Quadrant )
	{
	//-----------------------------------------------------
	case 0:	// +x +y
		if( m_Pos[ax].x < x )
		{
			ax++;
		}

		for(ix=ax; ix<m_nPoints; ix++)
		{
			if( (dy = m_Pos[ix].y - y) >= 0.0 )
			{
				dx		= m_Pos[ix].x - x;

				if( iPoint_Min >= 0 && Dist_Min < dx )
				{
					return( iPoint_Min );
				}

				Dist	= sqrt(dx*dx + dy*dy);

				if( iPoint_Min < 0 || Dist < Dist_Min )
				{
					iPoint_Min	= m_Idx[ix];
					Dist_Min	= Dist;
				}
			}
		}
		break;

	//-----------------------------------------------------
	case 1:	// +x -y
		if( m_Pos[ax].x < x )
		{
			ax++;
		}

		for(ix=ax; ix<m_nPoints; ix++)
		{
			if( (dy = m_Pos[ix].y - y) <= 0.0 )
			{
				dx		= m_Pos[ix].x - x;

				if( iPoint_Min >= 0 && Dist_Min < dx )
				{
					return( iPoint_Min );
				}

				Dist	= sqrt(dx*dx + dy*dy);

				if( iPoint_Min < 0 || Dist < Dist_Min )
				{
					iPoint_Min	= m_Idx[ix];
					Dist_Min	= Dist;
				}
			}
		}
		break;

	//-----------------------------------------------------
	case 2:	// -x -y
		if( m_Pos[ax].x > x )
		{
			ax--;
		}

		for(ix=ax; ix>=0; ix--)
		{
			if( (dy = m_Pos[ix].y - y) <= 0.0 )
			{
				dx		= m_Pos[ix].x - x;

				if( iPoint_Min >= 0 && Dist_Min < dx )
				{
					return( iPoint_Min );
				}

				Dist	= sqrt(dx*dx + dy*dy);

				if( iPoint_Min < 0 || Dist < Dist_Min )
				{
					iPoint_Min	= m_Idx[ix];
					Dist_Min	= Dist;
				}
			}
		}
		break;

	//-----------------------------------------------------
	case 3:	// -x +y
		if( m_Pos[ax].x > x )
		{
			ax--;
		}

		for(ix=ax; ix>=0; ix--)
		{
			if( (dy = m_Pos[ix].y - y) >= 0.0 )
			{
				dx		= m_Pos[ix].x - x;

				if( iPoint_Min >= 0 && Dist_Min < dx )
				{
					return( iPoint_Min );
				}

				Dist	= sqrt(dx*dx + dy*dy);

				if( iPoint_Min < 0 || Dist < Dist_Min )
				{
					iPoint_Min	= m_Idx[ix];
					Dist_Min	= Dist;
				}
			}
		}
		break;
	}

	//-----------------------------------------------------
	return( iPoint_Min );
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CSG_Shapes_Search::_Select_Add(CSG_Shape *pPoint, double Distance)
{
	if( m_nSelected >= m_Selected_Buf )
	{
		m_Selected_Buf	+= 8;

		m_Selected		= (CSG_Shape **)SG_Realloc(m_Selected    , m_Selected_Buf * sizeof(CSG_Shape *));
		m_Selected_Dst	= (double  *)SG_Realloc(m_Selected_Dst, m_Selected_Buf * sizeof(double  ));
	}

	m_Selected    [m_nSelected]	= pPoint;
	m_Selected_Dst[m_nSelected]	= Distance;
	m_nSelected++;
}

//---------------------------------------------------------
int CSG_Shapes_Search::Select_Radius(double x, double y, double Radius, bool bSort, int MaxPoints)
{
	int			ix, xLeft, xRight;
	double		d, dx, Radius_2;

	m_nSelected	= 0;

	Radius_2	= Radius * Radius;

	xLeft		= _Get_Index_Next(x - Radius);
	xRight		= _Get_Index_Next(x + Radius);

	for(ix=xLeft; ix<=xRight; ix++)
	{
		d		= m_Pos[ix].y - y;

		if( d >= -Radius && d <= Radius )
		{
			dx	= m_Pos[ix].x - x;
			d	= dx*dx + d*d;

			if( d <= Radius_2 )
			{
				_Select_Add(m_pPoints->Get_Shape(m_Idx[ix]), d);
			}
		}
	}

	if( bSort || (MaxPoints > 0 && MaxPoints < m_nSelected) )
	{
		m_Selected_Idx.Create(m_nSelected, m_Selected_Dst, true);
	}

	return( MaxPoints <= 0 || MaxPoints > m_nSelected ? m_nSelected : MaxPoints );
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -