📄 readshapefile.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 + -