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

📄 lsdoc.cpp

📁 数据结构链表的演示程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void CLSDoc::CalcBlockBorders()
{//1
	LONG curpos=0;
	m_BlockBorders.RemoveAll();
	LONG index;
	BlockBorder tmpBorder;
	long tmpID;

	for(long ID=1;ID<=m_BlockNum;ID++)
	{//2
		Block curblock=m_LittleBlocks[ID-1];	// 当前斑块
		curpos=m_BlockBorders.GetSize();	// 该斑块的邻居在数组中的起始位置

		// 搜索该斑块的矩形
		for(long y=curblock.UPY;y<=curblock.DOWNY;y++)
		{//3
			for(long x=curblock.LEFTX;x<=curblock.RIGHTX;x++)
			{//4
				// 找着边界点
				if((m_BlockID[x+y*m_nWidth].IsBorder)&&
					(m_BlockID[x+y*m_nWidth].ID==ID))
				{//5
					// 斑块上边界且未被计入
					if((y>0)&&((tmpID=m_BlockID[x+(y-1)*m_nWidth].ID)>ID))
					{//6
						// 检查是否为新类型
						for(index=m_BlockBorders.GetUpperBound();
							index>=curpos;index--)
						{//7
							if(m_BlockBorders[index].ID2>tmpID)
								continue;
							else if(m_BlockBorders[index].ID2==tmpID)  // 不是新类型
							{
								m_BlockBorders[index].Leng++;  // 该类型长度加一
								break;
							}
							else	// 是新类型,插在ID比他大的前面
							{
								tmpBorder.ID1=ID;
								tmpBorder.ID2=tmpID;
								tmpBorder.Leng=1;
								m_BlockBorders.InsertAt(index+1,tmpBorder,1);
								break;
							}
						}//7

						if(index<curpos)	// 如果比数组中所有类型的ID都比他大,插在最前面
						{
							tmpBorder.ID1=ID;
							tmpBorder.ID2=tmpID;
							tmpBorder.Leng=1;
							m_BlockBorders.InsertAt(index+1,tmpBorder,1);
						}
					}//6

					// 斑块左边界且未被计入
					if((x>0)&&((tmpID=m_BlockID[x-1+y*m_nWidth].ID)>ID))
					{//6
						for(index=m_BlockBorders.GetUpperBound();
							index>=curpos;index--)
						{//7
							if(m_BlockBorders[index].ID2>tmpID)
								continue;
							else if(m_BlockBorders[index].ID2==tmpID)
							{
								m_BlockBorders[index].Leng++;
								break;
							}
							else
							{
								tmpBorder.ID1=ID;
								tmpBorder.ID2=tmpID;
								tmpBorder.Leng=1;
								m_BlockBorders.InsertAt(index+1,tmpBorder,1);
								break;
							}
						}//7

						if(index<curpos)
						{
							tmpBorder.ID1=ID;
							tmpBorder.ID2=tmpID;
							tmpBorder.Leng=1;
							m_BlockBorders.InsertAt(index+1,tmpBorder,1);
						}
					}//6

					// 斑块右边界且未被计入
					if((x<(m_nWidth-1))&&((tmpID=m_BlockID[x+1+y*m_nWidth].ID)>ID))
					{//6
						for(index=m_BlockBorders.GetUpperBound();
							index>=curpos;index--)
						{//7
							if(m_BlockBorders[index].ID2>tmpID)
								continue;
							else if(m_BlockBorders[index].ID2==tmpID)
							{
								m_BlockBorders[index].Leng++;
								break;
							}
							else
							{
								tmpBorder.ID1=ID;
								tmpBorder.ID2=tmpID;
								tmpBorder.Leng=1;
								m_BlockBorders.InsertAt(index+1,tmpBorder,1);
								break;
							}
						}//7

						if(index<curpos)
						{
							tmpBorder.ID1=ID;
							tmpBorder.ID2=tmpID;
							tmpBorder.Leng=1;
							m_BlockBorders.InsertAt(index+1,tmpBorder,1);
						}
					}

					// 斑块下边界且未被计入
					if((y<(m_nHeight-1))&&((tmpID=m_BlockID[x+(y+1)*m_nWidth].ID)>ID))
					{//6
						for(index=m_BlockBorders.GetUpperBound();
							index>=curpos;index--)
						{//7
							if(m_BlockBorders[index].ID2>tmpID)
								continue;
							else if(m_BlockBorders[index].ID2==tmpID)
							{
								m_BlockBorders[index].Leng++;
								break;
							}
							else
							{
								tmpBorder.ID1=ID;
								tmpBorder.ID2=tmpID;
								tmpBorder.Leng=1;
								m_BlockBorders.InsertAt(index+1,tmpBorder,1);
								break;
							}
						}//7

						if(index<curpos)
						{//7
							tmpBorder.ID1=ID;
							tmpBorder.ID2=tmpID;
							tmpBorder.Leng=1;
							m_BlockBorders.InsertAt(index+1,tmpBorder,1);
						}//7
					}//6
				}//5
			}//4
		}//3
	}//2
}//1


BOOL CLSDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	if(!m_bCanExecute)
	{
		AfxMessageBox("该图像不能用于景观分析,没有结果可以保存!",MB_OK,0);
		return FALSE;
	}

	if(!m_bDone)
	{
		CString error;
		error.Format("尚未命名和计算,没有结果可保存,请先选择菜单:\t\n\n[景观属性]-->[命名和计算], 然后再选择此菜单!");
		AfxMessageBox(error,MB_OK,0);
		return FALSE;
	}

	CFile file;
	CString path,string;
	long id;

	CFileDialog FileDialogBox
		(FALSE,"txt","*.txt",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
		"Text file(*.txt)|*.TXT|",NULL);		
	if(FileDialogBox.DoModal()==IDOK)
	{
		CString Eo=FileDialogBox.GetFileExt();
		Eo.MakeUpper();
		if(Eo=="TXT")
		{
			path=FileDialogBox.GetPathName();
			LPCTSTR nName=LPCTSTR(path);
			file.Open(path,CFile::modeCreate|CFile::modeWrite);
			
			switch(m_nShow)
			{
			case 0:
				string.Format("序号\t景观名\t颜色\t块数(不过滤)\t总面积\t总周长\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockTypes.GetSize();id++)
				{
					Types tmpType=m_BlockTypes[id-1];
					string.Format("%2d\t%s\t%3d\t%10ld\t%ld\t%ld\r\n",
						id,tmpType.Name,tmpType.Val,tmpType.Number,
						tmpType.Area,tmpType.Length);
					file.Write(LPCTSTR(string),string.GetLength());
				}

				break;
			case 1:
				string.Format("块ID\t景观名\t颜色\t块面积\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockNum;id++)
				{
					Block tmpBlock=m_LittleBlocks[id-1];
					if(tmpBlock.AREA<=m_nMinArea)
						continue;
					Types tmpType=m_BlockTypes[tmpBlock.TYPEINDEX];
					
					string.Format("%ld\t%s\t%3d\t%ld\r\n",
						id,tmpType.Name,tmpType.Val,tmpBlock.AREA);

					file.Write(LPCTSTR(string),string.GetLength());
				}

				break;
			case 2:
				string.Format("块ID\t景观名\t颜色\t块周长\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockNum;id++)
				{
					Block tmpBlock=m_LittleBlocks[id-1];
					if(tmpBlock.AREA<=m_nMinArea)
						continue;
					Types tmpType=m_BlockTypes[tmpBlock.TYPEINDEX];
					
					string.Format("%ld\t%s\t%3d\t%ld\r\n",
						id,tmpType.Name,tmpType.Val,tmpBlock.LENG);

					file.Write(LPCTSTR(string),string.GetLength());
				}

				break;

			case 3:
				string.Format("Id①\t景观①\t颜色①\tId②\t景观②\t颜色②\t交界长\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockBorders.GetSize();id++)
				{
					BlockBorder tmpBorder=m_BlockBorders[id-1];
					long id1=tmpBorder.ID1;
					long id2=tmpBorder.ID2;
					Block tmpBlock1=m_LittleBlocks[id1-1];
					Block tmpBlock2=m_LittleBlocks[id2-1];
					if((tmpBlock1.AREA<=m_nMinArea)||(tmpBlock2.AREA<=m_nMinArea))
						continue;
					Types tmpType1=m_BlockTypes[tmpBlock1.TYPEINDEX];
					Types tmpType2=m_BlockTypes[tmpBlock2.TYPEINDEX];
					string.Format("%ld\t%s\t%3d\t%ld\t%s\t%3d\t%ld\r\n",
						id1,tmpType1.Name,tmpType1.Val,
						id2,tmpType2.Name,tmpType2.Val,tmpBorder.Leng);
					file.Write(LPCTSTR(string),string.GetLength());
				}

				break;
			case 4:
				string.Format("块ID\t景观名\t颜色\t中心点横坐标\t中心点纵坐标\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockNum;id++)
				{
					Block tmpBlock=m_LittleBlocks[id-1];
					if(tmpBlock.AREA<=m_nMinArea)
						continue;
					Types tmpType=m_BlockTypes[tmpBlock.TYPEINDEX];
					
					string.Format("%ld\t%s\t%3d\t%10.4f\t%10.4f\r\n",
						id,tmpType.Name,tmpType.Val,
						tmpBlock.CX,tmpBlock.CY);

					file.Write(LPCTSTR(string),string.GetLength());
				}				
				break;
			case 5:
				string.Format("块ID\t景观名\t颜色\t块面积\t块周长\t中心点横坐标\t中心点纵坐标\r\n");
				file.Write(LPCTSTR(string),string.GetLength());
				for(id=1;id<=m_BlockNum;id++)
				{
					Block tmpBlock=m_LittleBlocks[id-1];
					if(tmpBlock.AREA<=m_nMinArea)
						continue;
					Types tmpType=m_BlockTypes[tmpBlock.TYPEINDEX];
					
					string.Format("%ld\t%s\t%3d\t%ld\t%ld\t%10.4f\t%10.4f\r\n",
						id,tmpType.Name,tmpType.Val,tmpBlock.AREA,tmpBlock.LENG,
						tmpBlock.CX,tmpBlock.CY);

					file.Write(LPCTSTR(string),string.GetLength());
				}
				break;
			}
			file.Close();
			return TRUE;
		}
		else
		{
			AfxMessageBox("请确认文件名扩展名是否为 .TXT !",MB_OK,0);
			return FALSE;
		}
	}
	return FALSE;
}


void CLSDoc::IndexCalc()
{
	// 定义公用变量
	int type=m_BlockTypes.GetSize();
	double Area=m_nWidth*m_nHeight;

	// 初始化形状类指数数组
	m_Results.Split.SetSize(type);
	m_Results.Shape.SetSize(type);
	m_Results.TypeChip.SetSize(type);
	m_Results.TypeChip2.SetSize(type);
	
	// H 为多样性指数,Hm 为最大多样性指数
	double Pi=0,Hm,EPk=0;	

	double AllMPS=double(Area)/double(m_BlockNum);

	for(int i=0;i<type;i++)
	{
		double MPS=double(m_BlockTypes[i].Area/m_BlockTypes[i].Number);
		double TypeArea=m_BlockTypes[i].Area;

		// 多样性类指数计算
		Pi=TypeArea/Area;
		
		EPk=EPk+Pi*log(Pi);
	
		// 形状类指数计算
		
		double Ed=0,Es2=0;		// D 为分维指数, S2 为形状指数
		double blocknum=m_BlockTypes[i].Number;
		for(int j=0;j<m_BlockNum;j++)
		{
			if(m_LittleBlocks[j].TYPEINDEX==i)
			{
				double blockarea=m_LittleBlocks[j].AREA;
				double blockleng=m_LittleBlocks[j].LENG;
				if(blockleng>4)
					Ed=Ed+double(log10(blockarea))/double(log10(blockleng/4));
				Es2=Es2+blockleng/(4*sqrt(blockarea));
			}
		}

		m_Results.Split[i]=Ed/blocknum;		// 分维指数
		m_Results.Shape[i]=Es2/blocknum;	// 形状指数

		m_Results.TypeChip[i]=MPS*(blocknum-1)/Area;	// 各类型碎裂化程度
		m_Results.TypeChip2[i]=(blocknum-1)/MPS;
	}

	Hm=log(type);
	
	EPk=-EPk;
	m_Results.TrueDiversity=EPk;		// 多样性指数
	m_Results.MaxDiversity=Hm;		// 最大多样性指数

	if(Hm==0)
	{
		m_Results.Blance=0;
	}
	else
	{
		m_Results.Blance=EPk/Hm;			// 均匀度指数
	}

	m_Results.Vantage=Hm-EPk;		// 优势度指数

	m_Results.AllChip=(m_BlockNum-1)/double(Area);		// 整体碎裂化程度	

	m_Results.AllChip2=(m_BlockNum-1)/AllMPS;

	CalcRolloverIndex();
	CalcContagion();
}


void CLSDoc::CalcRolloverIndex()			// 计算连结度指数
{
	BYTE typenum=m_BlockTypes.GetSize();

	double *Ds=(double *)malloc(sizeof(double)*typenum);
	double *Rs=(double *)malloc(sizeof(double)*typenum);

	ZeroMemory(Ds,sizeof(double)*typenum);
	ZeroMemory(Rs,sizeof(double)*typenum);

	long i,j;
	double maxdist=m_nHeight*m_nHeight+m_nWidth*m_nWidth+1;

	for(i=0;i<m_BlockNum;i++)
	{
		BYTE type=m_LittleBlocks[i].TYPEINDEX;
		double thex=m_LittleBlocks[i].CX;
		double they=m_LittleBlocks[i].CY;
		double dist=maxdist;
		long area1=m_LittleBlocks[i].AREA;
		long area2;
		long id2;

		for(j=0;j<m_BlockNum;j++)
		{
			if(j==i)
				continue;

			if(m_LittleBlocks[j].TYPEINDEX==type)
			{
				double xx=m_LittleBlocks[j].CX-thex;
				double yy=m_LittleBlocks[j].CY-they;
				double thedist=xx*xx+yy*yy;
				if(thedist<dist)
				{
					dist=thedist;
					id2=j;
				}
			}
		}

		area2=m_LittleBlocks[id2].AREA;

		Ds[type]=Ds[type]+sqrt(dist);
		Rs[type]=Rs[type]+sqrt(area1*area2)/dist                                            ;
	}

	m_Results.MinDistance.SetSize(typenum);
	m_Results.Neighbour.SetSize(typenum);
	m_Results.Interaction.SetSize(typenum);
	for(BYTE k=0;k<typenum;k++)
	{
		long N=m_BlockTypes[k].Number;
		m_Results.MinDistance[k]=Ds[k]/N;
		m_Results.Neighbour[k]=2*sqrt(double(N)/double(m_nWidth*m_nHeight))*m_Results.MinDistance[k];
		m_Results.Interaction[k]=Rs[k]/m_BlockTypes[k].Number;
	}
	return;
}


void CLSDoc::CalcContagion()
{
	BYTE typenum=m_BlockTypes.GetSize();
	double * Eqlog=(double *)malloc(sizeof(double)*typenum);
	long * Eq=(long *)malloc(sizeof(long)*typenum);
	ZeroMemory(Eqlog,sizeof(double)*typenum);
	ZeroMemory(Eq,sizeof(long)*typenum);

	for(long i=0;i<m_BlockBorders.GetSize();i++)
	{
		long leng=m_BlockBorders[i].Leng;
		long id1=m_BlockBorders[i].ID1-1;
		long id2=m_BlockBorders[i].ID2-1;
		BYTE type1=m_LittleBlocks[id1].TYPEINDEX;
		BYTE type2=m_LittleBlocks[id2].TYPEINDEX;
		Eqlog[type1]=Eqlog[type1]+leng*log10(leng);
		Eqlog[type2]=Eqlog[type2]+leng*log10(leng);
		Eq[type1]=Eq[type1]+leng;
		Eq[type2]=Eq[type2]+leng;
	}

	double contagion=2*typenum*log10(typenum);
	for(BYTE j=0;j<typenum;j++)
	{
		double Ej=Eqlog[j]/Eq[j]-log10(Eq[j]);
		contagion=contagion+Ej;
	}

	m_Results.Contagion=contagion;

	return;
}


void CLSDoc::Calc4Index()
{
	double city=0;
	double jamming=0;
	double plant=0;
	double risk=0;

	for(int i=0;i<m_BlockTypes.GetSize();i++)
	{
		city+=m_BlockTypes[i].Area*m_Coefficient[4*i];
		jamming+=m_BlockTypes[i].Area*m_Coefficient[4*i+1];
		plant+=m_BlockTypes[i].Area*m_Coefficient[4*i+2];
		risk+=m_BlockTypes[i].Area*m_Coefficient[4*i+3];
	}

	double allarea=m_nHeight*m_nWidth;

	m_Results.City=city/allarea;
	m_Results.Jamming=jamming/allarea;
	m_Results.Plant=plant/allarea;
	m_Results.Risk=risk/allarea;

	return;
}


long * CLSDoc::CalcFloc(UINT slipnum, long * slips, BYTE type)
{
	slips[slipnum-1]=m_nHeight*m_nWidth;

	BYTE line=(m_BlockTypes.GetSize()+1)*2;

	long * retarray=(long *)malloc(sizeof(long)*line*slipnum);

⌨️ 快捷键说明

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