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

📄 grid_memory.cpp

📁 这是一个GPS相关的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//           Application Programming Interface           //
//                                                       //
//                  Library: SAGA_API                    //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                   grid_memory.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 <memory.h>

#include "grid.h"
#include "parameters.h"


///////////////////////////////////////////////////////////
//														 //
//					Caching Options						 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
static CSG_String	gSG_Grid_Cache_Directory;

const SG_Char *		SG_Grid_Cache_Get_Directory(void)
{
	return( gSG_Grid_Cache_Directory );
}

void				SG_Grid_Cache_Set_Directory(const SG_Char *Directory)
{
	if( SG_Dir_Exists(Directory) )
	{
		gSG_Grid_Cache_Directory.Printf(Directory);
	}
}

//---------------------------------------------------------
static bool			gSG_Grid_Cache_bAutomatic	= false;

void				SG_Grid_Cache_Set_Automatic(bool bOn)
{
	gSG_Grid_Cache_bAutomatic	= bOn;
}

bool				SG_Grid_Cache_Get_Automatic(void)
{
	return( gSG_Grid_Cache_bAutomatic );
}

//---------------------------------------------------------
static int			gSG_Grid_Cache_Confirm		= 1;

void				SG_Grid_Cache_Set_Confirm(int Confirm)
{
	gSG_Grid_Cache_Confirm		= Confirm;
}

int					SG_Grid_Cache_Get_Confirm(void)
{
	return( gSG_Grid_Cache_Confirm );
}

//---------------------------------------------------------
static int			gSG_Grid_Cache_Threshold	= 40 * N_MEGABYTE_BYTES;

void				SG_Grid_Cache_Set_Threshold(int nBytes)
{
	if( nBytes >= 0 )
	{
		gSG_Grid_Cache_Threshold	= nBytes;
	}
}

void				SG_Grid_Cache_Set_Threshold_MB(double nMegabytes)
{
	SG_Grid_Cache_Set_Threshold((int)(nMegabytes * N_MEGABYTE_BYTES));
}

int					SG_Grid_Cache_Get_Threshold(void)
{
	return( gSG_Grid_Cache_Threshold );
}

double				SG_Grid_Cache_Get_Threshold_MB(void)
{
	return( (double)gSG_Grid_Cache_Threshold / (double)N_MEGABYTE_BYTES );
}


///////////////////////////////////////////////////////////
//														 //
//						Memory							 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::_Memory_Create(TSG_Grid_Memory_Type Memory_Type)
{
	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count )
	{
		_Memory_Destroy();

		Set_Buffer_Size(gSG_Grid_Cache_Threshold);

		if(	Memory_Type != GRID_MEMORY_Cache && gSG_Grid_Cache_bAutomatic && Get_NCells() * Get_nValueBytes() > gSG_Grid_Cache_Threshold )
		{
			switch( gSG_Grid_Cache_Confirm )
			{
			default:
				Memory_Type	= GRID_MEMORY_Cache;
				break;

			case 1:
				{
					CSG_String	s;

					s.Printf(SG_T("%s\n%s\n%s: %.2fMB"),
						LNG("Shall I activate file caching for new grid."),
						m_System.Get_Name(),
						LNG("Total memory size"),
						(Get_NCells() * Get_nValueBytes()) / (double)N_MEGABYTE_BYTES
					);

					if( SG_UI_Dlg_Continue(s, LNG("Activate Grid File Cache?")) )
					{
						Memory_Type	= GRID_MEMORY_Cache;
					}
				}
				break;

			case 2:
				{
					CSG_Parameters	p(NULL, LNG("Activate Grid File Cache?"), SG_T(""));

					p.Add_Value(
						NULL	, SG_T("BUFFERSIZE")	, LNG("Buffer Size [MB]"),
						SG_T(""),
						PARAMETER_TYPE_Double, SG_Grid_Cache_Get_Threshold_MB(), 0.0, true
					);

					if( SG_UI_Dlg_Parameters(&p, LNG("Activate Grid File Cache?")) )
					{
						Memory_Type	= GRID_MEMORY_Cache;

						Set_Buffer_Size((int)(p(SG_T("BUFFERSIZE"))->asDouble() * N_MEGABYTE_BYTES));
					}
				}
				break;
			}
		}

		//-------------------------------------------------
		switch( Memory_Type )
		{
		case GRID_MEMORY_Normal:
			return( _Array_Create() );

		case GRID_MEMORY_Cache:
			return( _Cache_Create() );

		case GRID_MEMORY_Compression:
			return( _Compr_Create() );
		}
	}

	return( false );
}

//---------------------------------------------------------
void CSG_Grid::_Memory_Destroy(void)
{
	Sort_Discard();

	switch( m_Memory_Type )
	{
	case GRID_MEMORY_Normal:		_Array_Destroy();		break;
	case GRID_MEMORY_Cache:			_Cache_Destroy(false);	break;
	case GRID_MEMORY_Compression:	_Compr_Destroy(false);	break;
	}

	_LineBuffer_Destroy();

	m_Memory_Type	= GRID_MEMORY_Normal;
}


///////////////////////////////////////////////////////////
//														 //
//						LineBuffer						 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CSG_Grid::_LineBuffer_Create(void)
{
	_LineBuffer_Destroy();

	LineBuffer			= (TSG_Grid_Line *)SG_Malloc(LineBuffer_Count * sizeof(TSG_Grid_Line));

	for(int i=0; i<LineBuffer_Count; i++)
	{
		LineBuffer[i].Data		= (char *)SG_Malloc(_LineBuffer_Get_nBytes());
		LineBuffer[i].y			= -1;
		LineBuffer[i].bModified	= false;
	}
}

//---------------------------------------------------------
void CSG_Grid::_LineBuffer_Destroy(void)
{
	if( LineBuffer )
	{
		for(int i=0; i<LineBuffer_Count; i++)
		{
			if( LineBuffer[i].Data )
			{
				SG_Free(LineBuffer[i].Data);
			}
		}

		SG_Free(LineBuffer);

		LineBuffer	= NULL;
	}
}

//---------------------------------------------------------
bool CSG_Grid::Set_Buffer_Size(int Size)
{
	int		i;

	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count )
	{
		Size	/= _LineBuffer_Get_nBytes();

		if( Size < 1 )
		{
			Size	= 1;
		}
		else if( Size >= Get_NY() )
		{
			Size	= Get_NY() - 1;
		}

		if( Size != LineBuffer_Count )
		{
			if( LineBuffer )
			{
				if( Size > LineBuffer_Count )
				{
					LineBuffer			= (TSG_Grid_Line *)SG_Realloc(LineBuffer, Size * sizeof(TSG_Grid_Line));

					for(i=LineBuffer_Count; i<Size; i++)
					{
						LineBuffer[i].Data		= (char *)SG_Malloc(_LineBuffer_Get_nBytes());
						LineBuffer[i].y			= -1;
						LineBuffer[i].bModified	= false;
					}
				}
				else
				{
					for(i=Size; i<LineBuffer_Count; i++)
					{
						if( LineBuffer[i].Data )
						{
							SG_Free(LineBuffer[i].Data);
						}
					}

					LineBuffer			= (TSG_Grid_Line *)SG_Realloc(LineBuffer, Size * sizeof(TSG_Grid_Line));
				}
			}

			LineBuffer_Count	= Size;
		}

		return( true );
	}

	return( false );
}

//---------------------------------------------------------
void CSG_Grid::_LineBuffer_Flush(void)
{
	if( LineBuffer )
	{
		for(int i=0; i<LineBuffer_Count; i++)
		{
			switch( m_Memory_Type )
			{
		    default:
		        break;

			case GRID_MEMORY_Cache:
				_Cache_LineBuffer_Save(LineBuffer + i);
				break;

			case GRID_MEMORY_Compression:
				_Compr_LineBuffer_Save(LineBuffer + i);
				break;
			}
		}
	}
}

//---------------------------------------------------------
CSG_Grid::TSG_Grid_Line * CSG_Grid::_LineBuffer_Get_Line(int y) const
{
	int				i, iLine;
	TSG_Grid_Line	tmp_Line;

	if( LineBuffer && y >= 0 && y < Get_NY() )
	{
		//-------------------------------------------------
		if( y != LineBuffer[0].y )
		{
			for(i=1, iLine=0; i<LineBuffer_Count && !iLine; i++)
			{
				if( y == LineBuffer[i].y )
				{
					iLine	= i;
				}
			}

			//---------------------------------------------
			if( !iLine )
			{
				iLine	= LineBuffer_Count - 1;

				switch( m_Memory_Type )
				{
				default:
					break;

				case GRID_MEMORY_Cache:
					_Cache_LineBuffer_Save(LineBuffer + iLine);
					_Cache_LineBuffer_Load(LineBuffer + iLine, y);
					break;

				case GRID_MEMORY_Compression:
					_Compr_LineBuffer_Save(LineBuffer + iLine);
					_Compr_LineBuffer_Load(LineBuffer + iLine, y);
					break;
				}
			}

			//---------------------------------------------
			tmp_Line		= LineBuffer[iLine];

			for(i=iLine; i>0; i--)
			{
				LineBuffer[i]	= LineBuffer[i - 1];
			}	// memmove(LineBuffer + 1, LineBuffer, (iLine - 1) * sizeof(TSG_Grid_Line));

			LineBuffer[0]	= tmp_Line;
		}

		//-------------------------------------------------
		return( LineBuffer );
	}

	return( NULL );
}

//---------------------------------------------------------
void CSG_Grid::_LineBuffer_Set_Value(int x, int y, double Value)
{
	TSG_Grid_Line	*pLine;

	if( (pLine = _LineBuffer_Get_Line(y)) != NULL )
	{
		switch( m_Type )
		{
		default:
			break;

		case GRID_TYPE_Byte:
			((BYTE   *)pLine->Data)[x]	= (BYTE  )Value;
			break;

		case GRID_TYPE_Char:
			((char   *)pLine->Data)[x]	= (char  )Value;
			break;

		case GRID_TYPE_Word:
			((WORD   *)pLine->Data)[x]	= (WORD  )Value;
			break;

		case GRID_TYPE_Short:
			((short  *)pLine->Data)[x]	= (short )Value;
			break;

		case GRID_TYPE_DWord:
			((DWORD  *)pLine->Data)[x]	= (DWORD )Value;
			break;

		case GRID_TYPE_Int:
			((int    *)pLine->Data)[x]	= (int   )Value;
			break;

		case GRID_TYPE_Float:
			((float  *)pLine->Data)[x]	= (float )Value;
			break;

		case GRID_TYPE_Double:
			((double *)pLine->Data)[x]	= (double)Value;
			break;
		}

		pLine->bModified	= true;
	}
}

//---------------------------------------------------------
double CSG_Grid::_LineBuffer_Get_Value(int x, int y) const
{
	TSG_Grid_Line	*pLine;

	if( (pLine = _LineBuffer_Get_Line(y)) != NULL )
	{
		switch( m_Type )
		{
		default:
			break;

		case GRID_TYPE_Byte:
			return( ((BYTE   *)pLine->Data)[x] );

		case GRID_TYPE_Char:
			return( ((char   *)pLine->Data)[x] );

		case GRID_TYPE_Word:
			return( ((WORD   *)pLine->Data)[x] );

		case GRID_TYPE_Short:
			return( ((short  *)pLine->Data)[x] );

		case GRID_TYPE_DWord:
			return( ((DWORD  *)pLine->Data)[x] );

		case GRID_TYPE_Int:
			return( ((int    *)pLine->Data)[x] );

		case GRID_TYPE_Float:
			return( ((float  *)pLine->Data)[x] );

		case GRID_TYPE_Double:
			return( ((double *)pLine->Data)[x] );
		}
	}

	return( 0.0 );
}


///////////////////////////////////////////////////////////
//														 //
//						Array							 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::_Array_Create(void)
{
	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count )
	{
		_Array_Destroy();

		m_Values	= (void **)SG_Malloc(Get_NY() * sizeof(void *));

		for(int y=0; y<Get_NY(); y++)
		{
			m_Values[y]	= (void *)SG_Calloc(1, _Get_nLineBytes());
		}

		return( true );
	}

	return( false );
}

//---------------------------------------------------------
void CSG_Grid::_Array_Destroy(void)
{
	if( m_Values )
	{
		for(int y=0; y<Get_NY(); y++)
		{
			if( m_Values[y] )
			{
				SG_Free(m_Values[y]);
			}

⌨️ 快捷键说明

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