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

📄 lsdoc.cpp

📁 数据结构链表的演示程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// LSDoc.cpp : implementation of the CLSDoc class
//

#include "stdafx.h"
#include "LandSoft.h"
#include "math.h"
#include "LSDoc.h"
#include "malloc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLSDoc

IMPLEMENT_DYNCREATE(CLSDoc, CDocument)

BEGIN_MESSAGE_MAP(CLSDoc, CDocument)
	//{{AFX_MSG_MAP(CLSDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BlockIDs::BlockIDs()
{
	ID=0;
	IsBorder=FALSE;
}

BlockIDs::~BlockIDs()
{
}

/////////////////////////////////////////////////////////////////////////////
// CLSDoc construction/destruction

CLSDoc::CLSDoc()
{
	m_bEverToget=FALSE;
	m_bTogether=FALSE;
	m_bLineSpace=FALSE;
	m_bPointFromFile=FALSE;
	m_dPower=2;
	m_bRandom=FALSE;
	m_nRanBoxNum=2;
	m_nRanBoxWidth=1;
	m_nRanBoxHeight=1;
	m_bEverDefine=FALSE;
	oldDiffRange=0;
	oldDiffString="";
	TANG=tan(PI/8);
//	m_bEverAutoCorre=FALSE;
	m_bShowPoint=FALSE;
	m_bShowBox=FALSE;
	m_bEverAllSpace=FALSE;
	m_bShowLine=FALSE;
	m_bSampleMouse=FALSE;
	m_bCanExecute=TRUE;
	m_bEverName=FALSE;
	m_bDone=FALSE;
	m_bOren8=TRUE;
	m_nShow=0;
	m_nMinArea=0;
	m_bSaveTip=TRUE;
	m_bInfo=FALSE;
	m_bMouseLine=FALSE;
	m_nXBox=1;
	m_nYBox=1;
	

}

CLSDoc::~CLSDoc()
{
}

BOOL CLSDoc::OnNewDocument()
{
	return FALSE;
}



/////////////////////////////////////////////////////////////////////////////
// CLSDoc serialization

void CLSDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
	}
	else
	{
	}
}

/////////////////////////////////////////////////////////////////////////////
// CLSDoc diagnostics

#ifdef _DEBUG
void CLSDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CLSDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

CSize CLSDoc::GetSize()
{
	return m_dib.GetSize();
}

inline BYTE CLSDoc::GetValue(int x,int y)
{
	return m_Values[x+m_nWidth*y];
}

inline BYTE CLSDoc::GetNameIndex(BYTE value)
{
	for(BYTE i=0;i<m_BlockTypes.GetSize();i++)
		if(m_BlockTypes[i].Val==value)
			return i;
	return NULL;
}

void CLSDoc::ConstructValue()
{
	m_Values.SetSize(m_nWidth*m_nHeight);
	
	int datawidth;

	for(long nn=0;nn<m_nHeight;nn++)
	{
		for(long mm=0;mm<m_nWidth;mm++)
		{
			if(m_dib.m_nBitcount==1)
			{
				datawidth=m_nWidth/8+0.9;
				if(datawidth%4!=0)
				{
					datawidth=datawidth/4+1;
					datawidth=datawidth*4;
				}

				LONG oo=mm/8+(m_nHeight-nn-1)*datawidth;
				BYTE pp=7-mm%8;
				m_Values[mm+nn*m_nWidth]=((*(m_dib.GetBits()+oo))&(1<<pp))>>pp;
			}
			else if(m_dib.m_nBitcount==4)
			{
				datawidth=m_nWidth/2+0.6;
				if(datawidth%4!=0)
				{
					datawidth=datawidth/4+1;
					datawidth=datawidth*4;
				}

				LONG oo=mm/2+(m_nHeight-nn-1)*datawidth;
				if(mm%2==0)
				{
					m_Values[mm+nn*m_nWidth]=(*(m_dib.GetBits()+oo))>>4;
				}
				else
				{
					m_Values[mm+nn*m_nWidth]=(*(m_dib.GetBits()+oo))&15;
				}
			}
			else
			{
				if(m_nWidth%4==0)
				{
					datawidth=m_nWidth;
				}
				else
				{
					datawidth=m_nWidth/4+1;
					datawidth=datawidth*4;
				}

				LONG oo=mm+(m_nHeight-nn-1)*datawidth;
				m_Values[mm+nn*m_nWidth]=*(m_dib.GetBits()+oo);
			}
		}
	}
}


/////////////////////////////////////////////////////////////////////////////
// CLSDoc commands

BOOL CLSDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if(!(m_dib.Open (lpszPathName)))
		return FALSE;
	else if(m_dib.m_Colors>0&&m_dib.m_Colors<=256)		// 只处理颜色数为 0-256 的图像
	{
		m_bEverName=FALSE;
		
		m_nWidth=GetSize().cx;
		m_nHeight=GetSize().cy;

		ConstructValue();

		if(m_nWidth*m_nHeight>1000000)
		{
			int tt=AfxMessageBox("图像较大(>1000x1000),处理时间较长,是否继续?",MB_OKCANCEL,0);
			if(tt==IDCANCEL)
				return FALSE;
		}
		// 开始扫描图像得到景观类数和面积
		if(!CalcTypes())
			return FALSE;

		BYTE len=strlen(lpszPathName);

		strncpy(m_strPathName,lpszPathName,len-4);
		return TRUE;
	}
	else
	{
		m_bCanExecute=FALSE;
		CString error;
		error.Format("该图像是256色以上位图,不能进行景观分析!\n\n按[确定]继续显示,按[取消]不显示。");
		int what=AfxMessageBox(error,MB_OKCANCEL,0);
		if(what==IDOK)
			return TRUE;
		else
			return FALSE;
	}
}

BOOL CLSDoc::CalcTypes()
{
	int Width=m_nWidth;		// 宽
	int Height=m_nHeight;	// 高

	// 以下定义临时景观类型临时变量,加入第一种类型
	Types block;	
	block.Val=GetValue(0,0);
	block.Area=0;

	m_BlockTypes.Add(block);

	for (int j = 0; j < Height; j++)
	{ 
		for (int i = 0; i < Width; i++)
		{ 
			for(int index=0; index<=m_BlockTypes.GetUpperBound(); index++)
			{
				if(GetValue(i,j)==m_BlockTypes[index].Val)	//判断是否为新类型
				{					// 否则面积加一
					m_BlockTypes[index].Area++;
					break;
				}
			}

			if(index==m_BlockTypes.GetSize())		// 是新类型则加入景观类型数组
			{ 
				block.Val=GetValue(i,j);
				block.Area=1;
				m_BlockTypes.Add( block );
			} 

			if(m_BlockTypes.GetSize()>MAXTYPE)		// 判断景观类型数是否超过20种
			{ 
				m_BlockTypes.RemoveAll();
				m_bCanExecute=FALSE;
				CString error;
				error.Format("该图像产生的景观类型大于 %d 种,将不能用此图做景观分析。请分类后再做!\n\n\t\t按[确定]继续显示,按[取消]不显示。",MAXTYPE);
				int what=AfxMessageBox(error,MB_OKCANCEL,0);
				if (what==IDOK)
					return TRUE;
				else
					return FALSE;
			} 
		}
	}

	double bitnum=Width*Height;
	BYTE size=m_BlockTypes.GetSize();
	m_Coefficient.SetSize(size*4);
	m_BaseSpace.SetSize(size);
	for(BYTE i=0;i<size;i++)
	{
		m_BaseSpace[i]=bitnum/double(m_BlockTypes[i].Area);
	}

	return TRUE;
}

void CLSDoc::CalcBlocks()
{//1
	int Width=m_nWidth;		// 宽
	int Height=m_nHeight;	// 高
	int maxx=m_nWidth-1;
	int maxy=m_nHeight-1;

	long BitNum = Width*Height;		// 数据长

//	int bdleng;					// 存储一点产生的边界长
	m_BlockID.RemoveAll();		// 删除原数组值
	m_BlockID.SetSize(BitNum);	// 初始化块数据数组
	POINT *SearchPtr=(POINT *)malloc(BitNum * sizeof(POINT));		// 初始化搜索临时指针
	m_BlockNum = 0;		// 初始化块数量
	
	m_LittleBlocks.RemoveAll();		// 删除原来斑块数组

	// 把m_BlockTypes中有关斑块的数据充0
	for(int ii=0;ii<m_BlockTypes.GetSize();ii++)
	{
		m_BlockTypes[ii].Length=0;
		m_BlockTypes[ii].Number=0;
	}

	m_nMinBlockArea=BitNum;
	m_nMaxBlockArea=1;
	m_nMinBlockLeng=BitNum;
	m_nMaxBlockLeng=4;

	for (int j = 0; j < Height; j++)
	{ //2
		for (int i = 0; i < Width; i++)
		{ //3
			// 搜索新斑块
			if (m_BlockID[i+Width*j].ID==0)
			{ //4
				BYTE color=GetValue(i,j);	// 颜色值
				BYTE index=GetNameIndex(color);		// 类型索引
				m_BlockNum++;	// 块数加一
				m_BlockID[i+Width*j].ID=m_BlockNum;

				// 初始化临时块结构变量
				Block tmpBlock;
				tmpBlock.AREA=1;
				tmpBlock.TYPEINDEX=index;
				tmpBlock.LEFTX=i;
				tmpBlock.RIGHTX=i;
				tmpBlock.UPY=j;
				tmpBlock.DOWNY=j;

				LONGLONG xsum=i;		// 所有点的横坐标之和(用于计算中心点坐标)
				LONGLONG ysum=j;		// 所有点的纵坐标之和

				tmpBlock.LENG=0;
//				if(bdleng=GetBorderLength(i,j))// 是否边界
//					tmpBlock.LENG+=bdleng;	// 斑块周长增加

				// 开始计算该点产生的边界长, 并置边界标志
				//	(可变为函数,但由于频繁访问,故直接进行计算)
				//////////////////////////////////////////////////////////////////
				if(i==0) 		// 图形左边界
					tmpBlock.LENG++;

				else if( (i>0) && ( GetValue(i-1,j) != color) )  //  斑块左边界
				{
					tmpBlock.LENG++;
					m_BlockID[i+j*m_nWidth].IsBorder=TRUE;
				}
									
				if(i==maxx) 		// 图形右边界
					tmpBlock.LENG++;

				else if( (i<maxx) && ( GetValue(i+1,j)!=color))   // 斑块右边界
				{
					tmpBlock.LENG++;
					m_BlockID[i+j*m_nWidth].IsBorder=TRUE;
				}

				if(j==0) 		// 图形上边界
					tmpBlock.LENG++;

				else if( (j>0) && ( GetValue(i,j-1) != color) )	// 斑块上边界
				{
					tmpBlock.LENG++;
					m_BlockID[i+j*m_nWidth].IsBorder=TRUE;
				}

				if (j==maxy) 	// 图形下边界
					tmpBlock.LENG++;

				else if ( (j<maxy) && ( GetValue(i,j+1)!=color) )  // 斑块下边界
				{
					tmpBlock.LENG++;
					m_BlockID[i+j*m_nWidth].IsBorder=TRUE;
				}
				// 结束计算边界
				/////////////////////////////////////////////////////////////////////

				long start=0; long end =1;
				SearchPtr[0].x=i;
				SearchPtr[0].y=j;

				// 从起点出发搜索所有该斑块的点
				while(start<end)
				{//5
					int xpos=SearchPtr[start].x;
					int ypos=SearchPtr[start].y;
					start++;
					for (int i1=-1; i1<=1; i1++)
					{ //6
						for (int j1=-1; j1<=1; j1++)
						{ //7
							int xpos1=xpos+i1;
							int ypos1=ypos+j1;
							if((i1==0)&&(j1==0))	// 不搜索原来的点
								continue;
							if((m_bOren8==FALSE)&&(i1*j1!=0))	// 若为四方向,不搜索斜向
								continue;
							if ((xpos1>=0)&&(xpos1<Width)&&(ypos1>=0)&&(ypos1<Height)
								&&(m_BlockID[xpos1+Width*ypos1].ID==0)
								&&(GetValue(xpos1,ypos1)==color))
								// 如果找着新的属于该块的点
							{ // 8
								SearchPtr[end].x=xpos1;
								SearchPtr[end].y=ypos1;
								m_BlockID[xpos1+Width*ypos1].ID=m_BlockNum;	// 置该点块ID
								
								// 更新矩形 
								if(xpos1<tmpBlock.LEFTX)
									tmpBlock.LEFTX=xpos1;
								else if(xpos1>tmpBlock.RIGHTX)
									tmpBlock.RIGHTX=xpos1;
								if(ypos1<tmpBlock.UPY)
									tmpBlock.UPY=ypos1;
								else if(ypos1>tmpBlock.DOWNY)
									tmpBlock.DOWNY=ypos1;

								tmpBlock.AREA++;	// 斑块面积加一
								xsum+=xpos1;		// 加上该点横坐标
								ysum+=ypos1;		// 加上该点纵坐标
			
						// 开始计算该点产生的边界长, 并置边界标志
						//////////////////////////////////////////////////////////////////
								if(xpos1==0) 		// 图形左边界
									tmpBlock.LENG++;

								else if( (xpos1>0) && ( GetValue(xpos1-1,ypos1) != color) )  //  斑块左边界
								{
									tmpBlock.LENG++;
									m_BlockID[xpos1+ypos1*m_nWidth].IsBorder=TRUE;
								}
								
								if(xpos1==maxx) 		// 图形右边界
									tmpBlock.LENG++;

								else if( (xpos1<maxx) && ( GetValue(xpos1+1,ypos1)!=color))   // 斑块右边界
								{
									tmpBlock.LENG++;
									m_BlockID[xpos1+ypos1*m_nWidth].IsBorder=TRUE;
								}

								if(ypos1==0) 		// 图形上边界
									tmpBlock.LENG++;

								else if( (ypos1>0) && ( GetValue(xpos1,ypos1-1) != color) )	// 斑块上边界
								{
									tmpBlock.LENG++;
									m_BlockID[xpos1+ypos1*m_nWidth].IsBorder=TRUE;
								}

								if (ypos1==maxy) 	// 图形下边界
									tmpBlock.LENG++;

								else if ( (ypos1<maxy) && ( GetValue(xpos1,ypos1+1)!=color) )  // 斑块下边界
								{
									tmpBlock.LENG++;
									m_BlockID[xpos1+ypos1*m_nWidth].IsBorder=TRUE;
								}

						// 结束计算边界
						/////////////////////////////////////////////////////////////////////
						
								end++;
							} //8
						}//7
					}//6
				}//5

				// 计算中心点坐标
				tmpBlock.CX=double(xsum)/double(tmpBlock.AREA)+0.5;
				tmpBlock.CY=double(ysum)/double(tmpBlock.AREA)+0.5;
				// 加入斑块数组
				m_LittleBlocks.Add(tmpBlock);

				if(tmpBlock.AREA>m_nMaxBlockArea)
					m_nMaxBlockArea=tmpBlock.AREA;
				if(tmpBlock.AREA<m_nMinBlockArea)
					m_nMinBlockArea=tmpBlock.AREA;
				if(tmpBlock.LENG>m_nMaxBlockLeng)
					m_nMaxBlockLeng=tmpBlock.LENG;
				if(tmpBlock.LENG<m_nMinBlockLeng)
					m_nMinBlockLeng=tmpBlock.LENG;

				m_BlockTypes[index].Number++;	// 该类景观的块数加一
				m_BlockTypes[index].Length+=tmpBlock.LENG;	
					// 该类景观的周长加上这个块的周长

			}//4
		}//3
	}//2
	return;
}//1



⌨️ 快捷键说明

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