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

📄 readshapefile.cpp

📁 用于地理信息系统(GIS)行业程序。 完整的鼠标交互式地图点、线、面的绘制
💻 CPP
字号:
// ReadShapefile.cpp: implementation of the CReadShapefile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DrawShape.h"
#include "ReadShapefile.h"


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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CReadShapefile::CReadShapefile(const char* a_pFileName)
{
	m_pFileName = a_pFileName;
	
}

CReadShapefile::~CReadShapefile()
{
	if(m_fShapefile != NULL)
	{
		m_fShapefile.Close();

	}
}



bool CReadShapefile::OpenShapefile()
{
	CFileException ef;
//	CString pFileName;
	int iFileType;


//	CFileDialog file_dlg(true);

//	file_dlg.m_ofn.lpstrFilter=".shp";
//	if(file_dlg.DoModal()==IDOK)
//	{
//	 pFileName = file_dlg.GetPathName();
//	}
//	for(int i=0; i < pFileName.GetLength(); i++)
//	{
//	//	strcpy(pPathName,pFileName.GetAt(i));
//	}


//	pFileName = "D:\\work\\arcvviewData\\polygonshp.shp";


	if( !m_fShapefile.Open(m_pFileName , CFile::modeRead|CFile::typeBinary, &ef ) )
	{
		#ifdef _DEBUG
		afxDump << "文件不能打开" << ef.m_cause << "\n";
		#endif
		AfxMessageBox("文件不能打开");
		return false;
	}

	m_fShapefile.Read(&iFileType,4);
	ChangeBigInt(iFileType);
	if(iFileType!= 9994)
	{
		AfxMessageBox("打开文件不是shapefile格式,不能进行读取!");
		return false;
	}

	return true;

}


//将byte order 为Big的整数,转换为正确的值

 CReadShapefile::ChangeBigInt(int& InputVal)
{
	//取出对应的位,再合并
	//将读文件取得的数,按照无符号数来处理,这样经过移位处理后才
	//能得到正确的结果

	unsigned int temp = InputVal;
	UINT d,e,f,g;

	d = temp & 0xFF;
	d <<= 24;
	e = temp & 0xFF00;
	e <<= 8;
	f = temp & 0xFF0000;
	f >>= 8;
	g = temp & 0xFF000000;
	g >>= 24;
	InputVal = d | e| f | g;
}


int  CReadShapefile::GetShapeType()
{
		int pInt;

		//定位到文件 Shape type 处
		m_fShapefile.Seek(32,CFile::begin);
		m_fShapefile.Read(&pInt,4);
		return pInt;
}

void CReadShapefile::SetFilepath(char* a_cFileName)
{
	m_pFileName=a_cFileName;
}

void CReadShapefile::GetMapBound(double &Xmin, double &Ymin, double &Xmax, double &Ymax)
{
		double* pdDouble=new double;
			//定位到文件Map Bounds 处
		m_fShapefile.Seek(36,CFile::begin);
		m_fShapefile.Read(pdDouble,8);
		Xmin=*pdDouble;
		m_fShapefile.Read(pdDouble,8);
		Ymin=*pdDouble;
		m_fShapefile.Read(pdDouble,8);
		Xmax=*pdDouble;
		m_fShapefile.Read(pdDouble,8);
		Ymax=*pdDouble;

		delete pdDouble;

}

int CReadShapefile::GetFileLength()
{
	int iFileLength;
	UINT uiFileLength;
	m_fShapefile.Seek(24,CFile::begin);
	m_fShapefile.Read(&uiFileLength,4);
	iFileLength = uiFileLength;
	ChangeBigInt(iFileLength);
	return iFileLength;
}




/*--< 函数头     >------------------------------------------------------------*
*    函数名称	      : GetPLine
*    功能概述	      : 得到多线/多边形坐标
*    输入参数         :
*    输出参数         :
					
					  
*    返回值			  :	const   : 返回读取的数据长度(16位单位长)
*----------------------------------------------------------------------------*/



int CReadShapefile::GetPLine(PointStruct* a_stPoint, PointStruct* a_stBounds,
							 int* a_pParts,int& a_NumPoints, int& a_iRecordNO)
{
//		int iRecordNO;			//记录号
//		int 
		int iContentLen;		//内容长(不包括文件头,仅是该条记录的内容长度)
		int iShapeType;			//图形类型,该类型或与文件头中相同,或为0(NULL type)
		int iReadedLen = 0;		//已经读取的内容长度
//		int iNumPoints ;		//一条线/多边形包含点的个数
		int iNumParts ;			//一条线/多边形包含的部分个数
		int iCountParts = 0;	//part 计数
		int iCountPoints = 0;	//point 计数

//		m_fShapefile.Seek(100,CFile::begin);
		m_fShapefile.Read(&a_iRecordNO,4);
		ChangeBigInt(a_iRecordNO);	//记录号

		m_fShapefile.Read(&iContentLen,4);	//内容长度
		ChangeBigInt(iContentLen);

		m_fShapefile.Read(&iShapeType,4);	//Shape 类型
		iReadedLen += 2;	//记录上面已读过的长度,只包含Shape类型的4字节

		if (iShapeType == 3 || iShapeType == 5)	//线或多边形类型
		{
			//边界
			m_fShapefile.Read(&a_stBounds[0].x,8);
			m_fShapefile.Read(&a_stBounds[0].y,8);
			m_fShapefile.Read(&a_stBounds[1].x,8);
			m_fShapefile.Read(&a_stBounds[1].y,8);
			
			//parts and NumPoints
			m_fShapefile.Read(&iNumParts,4);
			m_fShapefile.Read(&a_NumPoints,4);
			
			//读取parts数组

			do
			{
				int iTemp;


		//		m_fShapefile.Read(a_pParts,4);		//Parts 数组值
				m_fShapefile.Read(&iTemp,4);		//Parts 数组值
				a_pParts[iCountParts] = iTemp;
//				a_pParts++;		//指针下移一位
				iReadedLen += 2;
				iCountParts++;	//计数
			}while (iCountParts < iNumParts);


			//读points数组
			do 
			{
				double Xtemp,Ytemp;	//临时读入数据
				m_fShapefile.Read(&Xtemp,8);		//Points 数组值
				a_stPoint[iCountPoints].x = (float)Xtemp;
				m_fShapefile.Read(&Ytemp,8);		//Points 数组值
				a_stPoint[iCountPoints].y = (float)Ytemp;
			//	a_stPoint++;	//指针下移一位
				iReadedLen += 8;
				iCountPoints++;
			} while(iCountPoints < a_NumPoints);

			if(iShapeType == 5)	//如果是多边形类型,要除去一多边形始末的重复顶点
			{
				a_NumPoints--;
			}

		}
		else	//NULL type,没有边界、坐标点等数据,则什么都不做
		{
		//	iReadedLen += 2;
		}
	
		return (iContentLen + 4);	//返回读取的数据长度(16位单位长)
									//记录内容 + 8字节记录头
}


 //读点数据

int CReadShapefile::GetPoint(float& a_fXcoord,float& a_fYcoord,
							 int& a_iRecordNO)
{

		int iContentLen;	//内容长(不包括文件头,仅是该条记录的内容长度)
		int iShapeType;		//图形类型,该类型或与文件头中相同,或为0(NULL type)
		int iReadedLen = 0;		//已经读取的内容长度
		int iPointNum = 0;		//一条线包含点的个数

		m_fShapefile.Read(&a_iRecordNO,4);
		ChangeBigInt(a_iRecordNO);	//记录号

		m_fShapefile.Read(&iContentLen,4);	//内容长度
		ChangeBigInt(iContentLen);

		m_fShapefile.Read(&iShapeType,4);	//Shape 类型
		iReadedLen += 2;	//记录上面已读过的长度

//		do
//		{
			if (iShapeType == 1)	//线或多边形类型
			{

				double Xtemp,Ytemp;	//临时读入数据
				m_fShapefile.Read(&Xtemp,8);		//X坐标
				m_fShapefile.Read(&Ytemp,8);		//Y坐标
				a_fXcoord =(float)Xtemp;
				a_fYcoord =(float)Ytemp;
//				iReadedLen += 8;

			}
			else	//NULL type,没有坐标点数据,则什么都不做
			{
			}

//			iPointNum++;

//		}while (iReadedLen < iContentLen);
	
		return (iContentLen + 4);	//返回读取的数据长度(16位单位长)
									//记录内容 + 8字节记录头
}






/*

int  CReadShapefile::GetPLine(PointStruct* a_stPoint ,int& a_iRecordNO)
{
		int iContentLen;	//内容长(不包括文件头,仅是该条记录的内容长度)
		int iShapeType;		//图形类型,该类型或与文件头中相同,或为0(NULL type)

		m_fShapefile.Read(&a_iRecordNO,4);
		ChangeBigInt(a_iRecordNO);	//记录号

		m_fShapefile.Read(&iContentLen,4);
		ChangeBigInt(iContentLen);

		m_fShapefile.Read(&iShapeType,4);
		if (iShapeType == 3 || iShapeType == 5)	//线类型
		{

			m_fShapefile.Read(&a_dXcoord1,8);		//起始X坐标
			m_fShapefile.Read(&a_dYcoord1,8);		//起始Y坐标
			m_fShapefile.Read(&a_dXcoord2,8);		//结束X坐标
			m_fShapefile.Read(&a_dYcoord2,8);		//结束Y坐标
			
			return 20;	//返回读取的数据长度(16位单位长)

		}
		else	//NULL type,没有坐标点数据,则什么都不做
		{
			return 6;	//返回读取的数据长度(16位单位长)
		}	
}

  */



 //从文件头开始定位
void CReadShapefile::Seek(long lPos)
{
	m_fShapefile.Seek(lPos,CFile::begin);
}

⌨️ 快捷键说明

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