You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
4.9 KiB
C++

2 years ago
#include "StdAfx.h"
#include "GetElevation.h"
// tiff<66>ļ<EFBFBD><C4BC><EFBFBD>ȡ
#include "gdal_priv.h"
#include "cpl_conv.h" //for CPLMalloc()
// boost-1.56:׼C++<2B><>׼<EFBFBD><D7BC>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <vector>
using namespace std;
// <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><E1B9B9>
#pragma pack(1)
struct struDemPic
{
struDemPic()
{
pDEMData = NULL;
};
virtual ~struDemPic()
{
if (pDEMData != NULL)
{
delete[] pDEMData;
pDEMData = NULL;
}
}
signed short int *pDEMData;
string strDemName;
double adfGeoTransform[6];
int iXSize;
int iYSize;
};
#pragma pack()
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD> DEM_PIC_LIST
typedef vector<struDemPic*> DEM_PIC_LIST;
// ȫ<>ֱ<EFBFBD><D6B1><EFBFBD>
DEM_PIC_LIST g_DemPicList;
// <20><><EFBFBD>ھ<EFBFBD>γ<EFBFBD><CEB3> <20><><EFBFBD><EFBFBD>tif<69>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
string GetDemName( const float fLonDeg, const float fLatDeg )
{
string sLatLon; // <20><><EFBFBD><EFBFBD>
int iLon = (int) fLonDeg;
int iLat = (int) fLatDeg;
//<2F>жϾ<D0B6>γ<EFBFBD><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ֮<CEA7><D6AE>
if ((fLonDeg < -180) || (fLonDeg > 180))
{
return "";
}
if ((fLatDeg < -90) || (fLatDeg > 90))
{
return "";
}
string sLat, sLon;
// γ<><CEB3> <20>ϱ<EFBFBD>γ <20><><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>
boost::format fmt("S%02d");
if (fLatDeg <= 0)
{
fmt % ((-iLat) + 1);
sLat = fmt.str();
}
else
{
fmt = boost::format("N%02d");
fmt % iLat;
sLat = fmt.str();
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>
if (fLonDeg <= 0)
{
fmt = boost::format("W%03d");
fmt % ((-iLon) + 1);
sLon = fmt.str();
}
else
{
fmt = boost::format("E%03d");
fmt % iLon;
sLon = fmt.str();
}
sLatLon = "ASTGTM_" + sLat + sLon + "_dem.tif";
return sLatLon;
}
// <20><>Ѱ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD>Ƿ<EFBFBD><C7B7>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
int FindDemDataSet( const string strDemName )
{
for ( unsigned int i = 0; i < g_DemPicList.size(); i++ )
{
if ( g_DemPicList[i]->strDemName == strDemName )
{
return i;
}
}
return -1;
}
bool GetDem( float& fElevator, const float fLonDeg, const float fLatDeg, struDemPic* pDemPic )
{
// <20><>ֵ<EFBFBD>ж<EFBFBD>
if (pDemPic == NULL)
{
return false;
}
// <20>ֱ<EFBFBD><D6B1><EFBFBD> <20>ж<EFBFBD>
if (pDemPic->adfGeoTransform[1] <= 0 || pDemPic->adfGeoTransform[5] >= 0)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float px = float(( fLonDeg - pDemPic->adfGeoTransform[0] ) / pDemPic->adfGeoTransform[1]);
float py = float(( pDemPic->adfGeoTransform[3] - fLatDeg ) / fabs(pDemPic->adfGeoTransform[5]));
//<2F><>ֹԽ<D6B9><D4BD>
if ((px < 0) || (px > pDemPic->iXSize - 1) ||
(py < 0) || ( py > pDemPic->iYSize - 1))
{
return false;
}
// <20><><EFBFBD><EFBFBD><><CBAB><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ֵ
int yt = 0, yb = 0; // y <20><><EFBFBD><EFBFBD>
int xl = 0, xr = 0; // x <20><><EFBFBD><EFBFBD>
yt = int(py);
yb = yt + 1;
xl = int(px);
xr = xl + 1;
if ((xl < 0) || (xl > pDemPic->iXSize - 1) ||
(xr < 0) || (xr > pDemPic->iYSize - 1))
{
return false;
}
if ((yt < 0) || (yt > pDemPic->iXSize - 1) ||
(yb < 0) || (yb > pDemPic->iYSize - 1))
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>ص<EFBFBD>ֵ
signed short int DNlt = *(pDemPic->pDEMData + yt * pDemPic->iXSize + xl);
signed short int DNrt = *(pDemPic->pDEMData + yt * pDemPic->iXSize + xr);
signed short int DNlb = *(pDemPic->pDEMData + yb * pDemPic->iXSize + xl);
signed short int DNrb = *(pDemPic->pDEMData + yb * pDemPic->iXSize + xr);
// <20><><EFBFBD><EFBFBD>
float h, v;
h = py - yt;
v = px - xl;
fElevator = DNlt * (1 - h) * (1 - v) + DNlb * h * (1 - v)+ DNrt * (1 - h) * v + DNrb * h * v;
return true;
}
// <20><>ȡ<EFBFBD>߳<EFBFBD>
bool GetDem( float& fElevator, float fLonDeg, float fLatDeg, string sDir)
{
// tif<69>ļ<EFBFBD> <20><><EFBFBD><EFBFBD>
string strName = GetDemName(fLonDeg, fLatDeg);
if (strName == "")
{
return false;
}
// tif<69>ļ<EFBFBD> ·<><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
string strPathName;
if (sDir != "")
{
strPathName = sDir + "\\" + strName;
}
else
{
return false;
}
// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڼ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ҵ<EFBFBD>
int idx = FindDemDataSet(strPathName);
if (idx >= 0)
{
return GetDem(fElevator, fLonDeg, fLatDeg, g_DemPicList[idx]);;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD> <20><>ȡ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>ݼ<EFBFBD>
// ע<><D7A2>
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
GDALDataset* tempdata = NULL;
tempdata = (GDALDataset*) GDALOpen(strPathName.c_str(), GA_ReadOnly);
if ( tempdata != NULL )
{
GDALDataType dataType = tempdata->GetRasterBand(1)->GetRasterDataType();
int iXSzie = tempdata->GetRasterBand(1)->GetXSize();
int iYSzie = tempdata->GetRasterBand(1)->GetYSize();
struDemPic* temp = new struDemPic;
temp->iXSize = iXSzie;
temp->iYSize = iYSzie;
tempdata->GetGeoTransform(temp->adfGeoTransform);
temp->pDEMData = new signed short int[iXSzie * iYSzie];
memset((void*) temp->pDEMData, 0, iXSzie * iYSzie * sizeof(signed short int));
tempdata->GetRasterBand(1)->RasterIO( GF_Read, 0, 0, iXSzie, iYSzie, temp->pDEMData, iXSzie, iYSzie, GDT_Int16, 0, 0 );
GDALClose(tempdata);
// <20><><EFBFBD><EFBFBD> <20>
temp->strDemName = strPathName;
g_DemPicList.push_back(temp);
return GetDem(fElevator, fLonDeg, fLatDeg, g_DemPicList[g_DemPicList.size() - 1]);;
}
return false;
}
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3>ͷ<EFBFBD><CDB7><EFBFBD>Դ
void ReleaseDemMemory()
{
// <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
for (unsigned int i = 0; i < g_DemPicList.size(); i++ )
{
if ( g_DemPicList[i] != NULL )
{
delete g_DemPicList[i];
}
}
g_DemPicList.clear();
}