C++读取ArcGis数据.shp格式

#include "shpopen.h"
#include "dbfopen.h"

bool UnicodeToAnsi(const WCHAR* pSrc, char* pDes) 
{ 
	char defaultChar[100]; 
	BOOL bUseDefaultChar; 
	WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDes, 1024, defaultChar, &bUseDefaultChar); 

	return true; 
}

static unsigned utf8decode(const char* p, const char* end, int* len)
{
	unsigned char c = *(unsigned char*)p;
	if (c < 0x80) {
		*len = 1;
		return c;
#if ERRORS_TO_CP1252
	} else if (c < 0xa0) {
		*len = 1;
		return cp1252[c-0x80];
#endif
	} else if (c < 0xc2) {
		goto FAIL;
	}
	if (p+1 >= end || (p[1]&0xc0) != 0x80) goto FAIL;
	if (c < 0xe0) {
		*len = 2;
		return
			((p[0] & 0x1f) << 6) +
			((p[1] & 0x3f));
	} else if (c == 0xe0) {
		if (((unsigned char*)p)[1] < 0xa0) goto FAIL;
		goto UTF8_3;
#if STRICT_RFC3629
	} else if (c == 0xed) {
		// RFC 3629 says surrogate chars are illegal.
		if (((unsigned char*)p)[1] >= 0xa0) goto FAIL;
		goto UTF8_3;
	} else if (c == 0xef) {
		// 0xfffe and 0xffff are also illegal characters
		if (((unsigned char*)p)[1]==0xbf &&
			((unsigned char*)p)[2]>=0xbe) goto FAIL;
		goto UTF8_3;
#endif
	} else if (c < 0xf0) {
UTF8_3:
		if (p+2 >= end || (p[2]&0xc0) != 0x80) goto FAIL;
		*len = 3;
		return
			((p[0] & 0x0f) << 12) +
			((p[1] & 0x3f) << 6) +
			((p[2] & 0x3f));
	} else if (c == 0xf0) {
		if (((unsigned char*)p)[1] < 0x90) goto FAIL;
		goto UTF8_4;
	} else if (c < 0xf4) {
UTF8_4:
		if (p+3 >= end || (p[2]&0xc0) != 0x80 || (p[3]&0xc0) != 0x80) goto FAIL;
		*len = 4;
#if STRICT_RFC3629
		// RFC 3629 says all codes ending in fffe or ffff are illegal:
		if ((p[1]&0xf)==0xf &&
			((unsigned char*)p)[2] == 0xbf &&
			((unsigned char*)p)[3] >= 0xbe) goto FAIL;
#endif
		return
			((p[0] & 0x07) << 18) +
			((p[1] & 0x3f) << 12) +
			((p[2] & 0x3f) << 6) +
			((p[3] & 0x3f));
	} else if (c == 0xf4) {
		if (((unsigned char*)p)[1] > 0x8f) goto FAIL; // after 0x10ffff
		goto UTF8_4;
	} else {
FAIL:
		*len = 1;
#if ERRORS_TO_ISO8859_1
		return c;
#else
		return 0xfffd; // Unicode REPLACEMENT CHARACTER
#endif
	}
}

static unsigned utf8towc(const char* src, unsigned srclen,
	wchar_t* dst, unsigned dstlen)
{
	const char* p = src;
	const char* e = src+srclen;
	unsigned count = 0;
	if (dstlen) for (;;) {
		if (p >= e) {dst[count] = 0; return count;}
		if (!(*p & 0x80)) { // ascii
			dst[count] = *p++;
		} else {
			int len = 0;
			unsigned ucs = utf8decode(p,e,&len);
			p += len;
#ifdef _WIN32
			if (ucs < 0x10000) {
				dst[count] = (wchar_t)ucs;
			} else {
				// make a surrogate pair:
				if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;}
				dst[count] = (wchar_t)((((ucs-0x10000u)>>10)&0x3ff) | 0xd800);
				dst[++count] = (wchar_t)((ucs&0x3ff) | 0xdc00);
			}
#else
			dst[count] = (wchar_t)ucs;
#endif
		}
		if (++count == dstlen) {dst[count-1] = 0; break;}
	}
	// we filled dst, measure the rest:
	while (p < e) {
		if (!(*p & 0x80)) p++;
		else {
#ifdef _WIN32
			int len = 0;
			unsigned ucs = utf8decode(p,e,&len);
			p += len;
			if (ucs >= 0x10000) ++count;
#else
			int len = 0;
			utf8decode(p,e,&len);
			p += len;
#endif
		}
		++count;
	}
	return count;
}

CString UTF8ToString(const char* pszUTF8Src)
{
	CString sResult = _T("");
	if (pszUTF8Src == NULL)
	{
		return sResult;
	}

	int nSrcLen = static_cast<int>(strlen(pszUTF8Src));
	wchar_t *pwszResult = new wchar_t[nSrcLen+1];
	utf8towc( pszUTF8Src, nSrcLen, pwszResult, nSrcLen+1 );
	sResult = pwszResult;
	delete pwszResult;
	pwszResult = NULL;

	return sResult;
}

、、、、、、、、、、、、、、

if( !IsValidShpFile(m_strPipeFilePath) )
	{
		CString sTmp;
		sTmp.Format(_T("文件 %s 格式错误或缺乏匹配的文件!\n"),m_strPipeFilePath);
		MessageBox(sTmp);
		return false;
	}

bool IsValidShpFile(CString sFileName)
{
	CString sName = sFileName;
	int nFind = sName.ReverseFind( '.');
	if( nFind >0 )
	{
		sName = sName.Left(nFind);
	}

	CString sShp = sName + _T(".shp");
	CString sDbf = sName + _T(".dbf");
	CString sShx = sName + _T(".shx");
	if( !PathFileExists(sShp) || 
		!PathFileExists(sDbf) || 
		!PathFileExists(sShx)   )
	{
		return false;
	}

	return true;
}

CString GetFileFolderPath(const CString& sFileName)
{
	int nFind = sFileName.ReverseFind( '.');
	if ( nFind > 0 )
	{
		CString sFilePath = sFileName.Left(nFind);
		return sFilePath;
	}

	return _T("");
}


// 读数据
	{
		CString strFolderPath = GetFileFolderPath(m_strNodeShpFilePath);
		char pShpFile[512];
		char pDbfFile[512];
		ZeroMemory(pShpFile, 512);
		ZeroMemory(pDbfFile, 512);

		CString strPathTemp = strFolderPath;
		USES_CONVERSION;
		WCHAR * pFolderPath1=T2W((strPathTemp));
		WCHAR * pFolderPath2=T2W((strPathTemp));
		wchar_t a[8] = L".shp";
		wchar_t b[8] = L".dbf";
		wcscat(pFolderPath1, a);
		wcscat(pFolderPath2, b);
		UnicodeToAnsi(pFolderPath1,pShpFile);
		UnicodeToAnsi(pFolderPath2,pDbfFile);

		// 列
		DBFHandle hDBF = DBFOpen( pDbfFile, "rb");
		if ( hDBF == NULL )
		{
			return false;
		}

		typedef std::map<CString, int> mapPipeInfoToCol;	
		mapPipeInfoToCol mapPipeSheet;
		const int nFieldCount = DBFGetFieldCount( hDBF);
		char szFieldName[64];
		for (int iFieldIndex=0; iFieldIndex<nFieldCount; iFieldIndex++)
		{
			DBFFieldType ft = DBFGetFieldInfo(hDBF, iFieldIndex, szFieldName, NULL, NULL);
			if ( (ft == FTInvalid) )
			{
				continue;
			}

			const CString sFieldName = szFieldName;
			mapPipeSheet.insert(std::make_pair(sFieldName, iFieldIndex));
		}

	int nBigEndian = 1;
		SHPHandle hSHP = SHPOpen(pShpFile, "rb", &nBigEndian);
		int nObjCount = 0;
		int nShpType = SHPT_ARC;
		SHPGetInfo(hSHP, &nObjCount, &nShpType, NULL, NULL);
		short int nScale = 1;
		if (nObjCount < nValidRow)
		{
			AfxMessageBox(_T("shp管点表格数据起始行不符要求!"));
			return false;
		}

		if (nObjCount > SHRT_MAX)
		{
			nScale = nObjCount/SHRT_MAX+1;
		}
	
		for (int i = 0; i < nObjCount; i++)
		{
			NODE_PARAMS_DOUBLE nodeParams;

			// 节点参数
			{
				char* pNodeType = DBFReadStringAttribute( hDBF, i, nNodeTypeTemp);
				if (m_nCodeType == 0)
				{
					nodeParams.strNodeType = pNodeType;
				}
				else
				{
					nodeParams.strNodeType = UTF8ToString(pNodeType);
				}
				delete pNodeType;
				pNodeType = NULL;

				if (nodeParams.strNodeType.IsEmpty())
				{
					CString strTip;
					strTip.Format(_T("管点表第%d行节点类型丢失!"), nObjCount);
					m_aryWaringTips.Add(strTip);
				}

				char* pCodeNum = DBFReadStringAttribute( hDBF, i, nCodeNumTemp);
				if (m_nCodeType == 0)
				{
					nodeParams.strCodeNum = pCodeNum;
				}
				else
				{
					nodeParams.strCodeNum = UTF8ToString(pCodeNum);
				}
				delete pCodeNum;
				pCodeNum = NULL;

				if (nodeParams.strCodeNum.IsEmpty())
				{
					CString strTip;
					strTip.Format(_T("管点表第%d行节点编号丢失!"), nObjCount);
					m_aryErrorTips.Add(strTip);
				}

				double dGElev = DBFReadDoubleAttribute( hDBF, i, nGElevenTemp);
				nodeParams.dGroundElev = dGElev;
			}

			// 平面数据
			{
				CString strSX;
				CString strSY;

				if (nHorizType == 1)
				{
					CString strMark = m_curPipePlan->stuPipeData.sHorizFields.strDivMark;
					char* pNodePos = DBFReadStringAttribute( hDBF, i, nPos);
					CString strNodePos = pNodePos;
					if (m_nCodeType != 0)
					{
						strNodePos = UTF8ToString(pNodePos);
					}
					delete pNodePos;
					pNodePos = NULL;

					if (strNodePos.Find(strMark) == -1)
					{
						CString strTip;
						strTip.Format(_T("第%d行起终点数据解析出错"), i);
						MessageBox(strTip);
					}
					else
					{
						strSX = strPos.Left(strNodePos.Find(strMark));
						strSY = strPos.Mid(strNodePos.Find(strMark) + 1);
					}

					nodeParams.ptPos.x = _tstof(strSX);
					nodeParams.ptPos.y = _tstof(strSY);
				}
				else
				{
					nodeParams.ptPos.x = DBFReadDoubleAttribute( hDBF, i, nPosX);
					nodeParams.ptPos.y = DBFReadDoubleAttribute( hDBF, i, nPosY);
				}
			}

			// 竖向数据
			{
				if (nVerticalType == 1)
				{
					double dElev = DBFReadDoubleAttribute( hDBF, i, nElev);
					nodeParams.ptPos.z = dElev;
				}
				else
				{
					double dDeepth = DBFReadDoubleAttribute( hDBF, i, nDeepth);
					double dElev = nodeParams.dGroundElev - dDeepth;
					nodeParams.ptPos.z = dElev;
				}
			}

			vecNodeDData.push_back(nodeParams);
		}
		//progress.Close();
		SHPClose(hSHP, nBigEndian);
		DBFClose(hDBF);
}

猜你喜欢

转载自blog.csdn.net/m0_37251750/article/details/88525180