DemReader
/* ******* DemReader.h ********** ********* DemReader常用操作函数声明 ********** */ /* author: autumoon */ #pragma once #include "StrDirFileU.h" #include "gdalUser.h" #include <atlimage.h> #define NoData -99999 typedef struct tagDEMHEADERINFO { int nType;//类型 给0 double lfStartX;//起点 double lfStartY;// double lfDx;//采样间隔 double lfDy;// int nRow;//行 int nColumn;//列 double lfKapa;//旋转角,给0 int nProjection;//投影,给0 double lfHeight;//平均高度? double lfNoData;//无效数 int nScale;//缩放比 int nDot;//小数点位数 int nPixelSize;//占用的字节数 }DEMHEADERINFO, *PDEMHEADERINFO; class CDemReader { public: // 在文件头后面开始真实的高程值,浮点形式。 //写入的顺序和文本格式的相同。 CDemReader(const CString& strDem); ~CDemReader(); private: const CString m_strDemPath; CStrDirFile sdf; public: char* m_DataMark; float m_Version; char* m_Unit; double m_Alfa; double m_Beta; double m_lfStartX; double m_lfStartY; double m_lfDx; double m_lfDy; int m_nRow; int m_nColumn; int m_nScale; double** m_pHeight; public: inline bool CheckData(const double& dData); int ChangeAreaHeight(const int& nXoffset, const int& nYOffset, const int& nWidth, const int& nHeight, const double& dNewHeight); int CreateBmpByDem(const CString& strDemPath, const CString& strBmpPath); int CreateDemByPic(const CString& strPicPath); int CreateNewDem(const CString& strDemPath, const double& m_lfStartX, const double& m_lfStartY, const int& nRow, const int& nColumn, const int& nScale = 1000, const double& m_lfDx = 5.0, const double& m_lfDy = 5.0, const CString& strDataMark = _T("NSDTF-DEM"), const float& fVersion = 1.0, const CString& strUnit = _T("M"), const float& fAlfa = 0.000, const float& fBeta = 0.0000); int ReadDemData(); int SaveDemData(const CString& strDem); };
/* ******* DemReader.cpp ********** ********* DemReader常用操作函数实现 ********** */ /* author: autumoon */ #include "DemReader.h" template <class T> bool FindMaxMin(std::list<T>& lTs, T& Tmax, T& Tmin); CDemReader::CDemReader(const CString& strDem) :m_strDemPath(strDem) { m_DataMark = new char[100]; m_Unit = new char[100]; } CDemReader::~CDemReader() { if (m_DataMark) { delete[]m_DataMark; } if (m_Unit) { delete[]m_Unit; } } bool CDemReader::CheckData(const double& dData) { return fabs(dData - NoData) > 0.001; } int CDemReader::ReadDemData() { FILE *fp; const char* lpszFileName = sdf.CString2Char(m_strDemPath); fopen_s(&fp, lpszFileName, "rt"); if (fp == NULL) { MessageBox(NULL, _T("文件无法打开!"), _T("提示"), MB_ICONERROR); return FALSE; } fscanf_s(fp, "%s", m_DataMark); //保存到数组当中 if (strcmp(m_DataMark, "NSDTF-DEM") != 0) { MessageBox(NULL, _T("文件错误!"), _T("提示"), MB_ICONERROR); return FALSE; } //AfxMessageBox(m_DataMark); fscanf_s(fp, "%f", &m_Version);//版本号 fscanf_s(fp, "%s", m_Unit);//单位(米) fscanf_s(fp, "%lf", &m_Alfa);//α fscanf_s(fp, "%lf", &m_Beta);//β fscanf_s(fp, "%lf", &m_lfStartX); fscanf_s(fp, "%lf", &m_lfStartY); fscanf_s(fp, "%lf", &m_lfDx); fscanf_s(fp, "%lf", &m_lfDy); fscanf_s(fp, "%d", &m_nRow); fscanf_s(fp, "%d", &m_nColumn); fscanf_s(fp, "%d", &m_nScale); int j; m_pHeight = new double*[m_nRow]; for (j = 0; j < m_nRow; j++) { m_pHeight[j] = new double[m_nColumn]; } long x; for (int i = 0; i < m_nRow; i++) { for (int j = 0; j < m_nColumn; j++) { fscanf_s(fp, "%ld", &x); m_pHeight[i][j] = x; if (x == -99999) { m_pHeight[i][j] = (long)NoData; } else m_pHeight[i][j] = (double)x / m_nScale; } } fclose(fp); return 0; } int CDemReader::SaveDemData(const CString& strDem) { std::list<CString> lOutput; lOutput.push_back(CString(m_DataMark) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_Version, 1) + '\n'); lOutput.push_back(CString(m_Unit) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_Alfa, 4) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_Beta, 4) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_lfStartX) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_lfStartY) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_lfDx) + '\n'); lOutput.push_back(sdf.Float2Cstring(m_lfDy) + '\n'); lOutput.push_back(sdf.Int2Cstring(m_nRow) + '\n'); lOutput.push_back(sdf.Int2Cstring(m_nColumn) + '\n'); lOutput.push_back(sdf.Int2Cstring(m_nScale)); CString strLine; for (int i = 0; i < m_nRow; i++) { for (int j = 0; j < m_nColumn; j++) { if (j % 10 == 0) { strLine += '\n'; lOutput.push_back(strLine); strLine = ""; } if (CheckData(m_pHeight[i][j])) { strLine += sdf.Int2Cstring(m_pHeight[i][j] * m_nScale) + _T(" "); } else strLine += sdf.Int2Cstring(m_pHeight[i][j]) + _T(" "); } } //增加最后一行 strLine += '\n'; lOutput.push_back(strLine); strLine = ""; sdf.SaveTXTFile(strDem, lOutput); return 0; } int CDemReader::CreateNewDem(const CString& strDemPath, const double& dStartX, const double& dStartY, const int& nRow, const int& nColumn, const int& nScale /* = 1000*/, const double& dDx /*= 5.0*/, const double& dDy /*= 5.0*/, const CString& strDataMark /*= _T("NSDTF-DEM")*/, const float& fVersion /*= 1.0*/, const CString& strUnit /*= _T("M")*/, const float& fAlfa /*= 0.000*/, const float& fBeta /*= 0.0000*/) { std::list<CString> lOutput; lOutput.push_back(CString(strDataMark) + '\n'); lOutput.push_back(sdf.Float2Cstring(fVersion, 1) + '\n'); lOutput.push_back(CString(m_Unit) + '\n'); lOutput.push_back(sdf.Float2Cstring(fAlfa, 4) + '\n'); lOutput.push_back(sdf.Float2Cstring(fBeta, 4) + '\n'); lOutput.push_back(sdf.Float2Cstring(dStartX) + '\n'); lOutput.push_back(sdf.Float2Cstring(dStartY) + '\n'); lOutput.push_back(sdf.Float2Cstring(dDx) + '\n'); lOutput.push_back(sdf.Float2Cstring(dDy) + '\n'); lOutput.push_back(sdf.Int2Cstring(nRow) + '\n'); lOutput.push_back(sdf.Int2Cstring(nColumn) + '\n'); lOutput.push_back(sdf.Int2Cstring(nScale)); CString strLine; for (int i = 0; i < m_nRow; i++) { for (int j = 0; j < m_nColumn; j++) { if (j % 10 == 0) { strLine += '\n'; lOutput.push_back(strLine); strLine = ""; } strLine += sdf.Int2Cstring(NoData) + _T(" "); } } //增加最后一行 strLine += '\n'; lOutput.push_back(strLine); strLine = ""; sdf.SaveTXTFile(strDemPath, lOutput); return 0; } int CDemReader::CreateDemByPic(const CString& strPicPath) { CGdalUser gu(strPicPath); //gu.Initialnize(); double dStartX = 0; double dStartY = 0; //在每个像素之间的距离代表1m的时候,不需要通过tfw文件更新参数 m_nRow = gu.m_nRasterYSize / 5; m_nColumn = gu.m_nRasterXSize / 5; CString strTfwPath = sdf.GetDirOfFile(strPicPath) + "\\" + sdf.GetNameOfFile(strPicPath, false) + _T(".tfw"); CString strDemPath = sdf.GetDirOfFile(strPicPath) + "\\" + sdf.GetNameOfFile(strPicPath, false) + _T(".dem"); if (sdf.IfExistFile(strTfwPath)) { //存在tfw文件的时候,需要更新参数 } CreateNewDem(strDemPath, dStartX, dStartY, m_nRow, m_nColumn); return 0; } int CDemReader::ChangeAreaHeight(const int& nXoffset, const int& nYOffset, const int& nWidth, const int& nHeight, const double& dNewHeight) { for (int i = 0; i < m_nRow; i++) { for (int j = 0; j < m_nColumn; j++) { if ( j >= nXoffset && j <= nXoffset + nWidth && i >= nYOffset && i <= nYOffset + nHeight) { m_pHeight[i][j] = dNewHeight; } } } return 0; } int CDemReader::CreateBmpByDem(const CString& strDemPath, const CString& strBmpPath) { ReadDemData(); int nWidth = m_nColumn; int nHeight = m_nRow; std::list<double> ldArray; for (int i = 0; i < m_nRow; i++) { for (int j = 0; j < m_nColumn; j++) { if (CheckData(m_pHeight[i][j])) { ldArray.push_back(m_pHeight[i][j]); } } } double dMaxHeight; double dMinHeight; FindMaxMin(ldArray, dMaxHeight, dMinHeight); CImage *image = new CImage(); image->Create(nWidth, nHeight, 32); CDC *pDC = CDC::FromHandle(image->GetDC()); pDC->FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255)); for (int i = 0; i < nWidth; i++) { for (int j = 0; j < nHeight; j++) { //设置每个像素点的RGB if (CheckData(m_pHeight[j][i])) { double dGray = (m_pHeight[j][i] - dMinHeight) / (dMaxHeight - dMinHeight) * 255; image->SetPixelRGB(i, j, dGray, dGray, dGray); } else { image->SetPixelRGB(i, j, 0, 0, 0); } } } image->Save(strBmpPath); return 0; } template <class T> bool FindMaxMin(std::list<T>& lTs, T& Tmax, T& Tmin) { std::list<T>::iterator it = lTs.begin(); Tmax = Tmin = *it; for (; it != lTs.end(); ++it) { if (*it > Tmax) { Tmax = *it; } else if (*it < Tmin) { Tmin = *it; } } return Tmax == Tmin; }