全国高分辨率土地利用数据服务 土地利用数据服务 土地覆盖数据服务 坡度数据服务 土壤侵蚀数据服务 全国各省市DEM数据服务 耕地资源空间分布数据服务 草地资源空间分布数据服务 林地资源空间分布数据服务 水域资源空间分布数据服务 建设用地空间分布数据服务 地形、地貌、土壤数据服务 分坡度耕地数据服务 全国大宗农作物种植范围空间分布数据服务
多种卫星遥感数据反演植被覆盖度数据服务 地表反照率数据服务 比辐射率数据服务 地表温度数据服务 地表蒸腾与蒸散数据服务 归一化植被指数数据服务 叶面积指数数据服务 净初级生产力数据服务 净生态系统生产力数据服务 生态系统总初级生产力数据服务 生态系统类型分布数据服务 土壤类型质地养分数据服务 生态系统空间分布数据服务 增强型植被指数数据服务
多年平均气温空间分布数据服务 多年平均降水量空间分布数据服务 湿润指数数据服务 大于0℃积温空间分布数据服务 光合有效辐射分量数据服务 显热/潜热信息数据服务 波文比信息数据服务 地表净辐射通量数据服务 光合有效辐射数据服务 温度带分区数据服务 山区小气候因子精细数据服务
全国夜间灯光指数数据服务 全国GDP公里格网数据服务 全国建筑物总面积公里格网数据服务 全国人口密度数据服务 全国县级医院分布数据服务 人口调查空间分布数据服务 收入统计空间分布数据服务 矿山面积统计及分布数据服务 载畜量及空间分布数据服务 农作物种植面积统计数据服务 农田分类面积统计数据服务 农作物长势遥感监测数据服务 医疗资源统计数据服务 教育资源统计数据服务 行政辖区信息数据服务
Landsat 8 高分二号 高分一号 SPOT-6卫星影像 法国Pleiades高分卫星 资源三号卫星 风云3号 中巴资源卫星 NOAA/AVHRR MODIS Landsat TM 环境小卫星 Landsat MSS 天绘一号卫星影像
开门见山,先把这个函数拿出来,看函数实现之前,我想先说一说各参数。
1,szPath是生成的栅格的路径
2,szFile是生成的栅格的文件名
3,rstInfo是RasterInfo结构体变量,是生成栅格的一些参数信息
struct RasterInfo {
IPointPtr ipOrigin; //栅格原点坐标
long lColCount; //栅格列数
long lRowCount; //栅格行数
double dCellSizeX; //栅格X分辨率,X方向每像素大小
double dCellSizeY; //栅格Y分辨率,Y方向每像素大小
long lNumbands; //波段数
ISpatialReferencePtr ipSpaRef; //空间参考
rstPixelType rstTy; //数据类型,具体为:
Constant Value Description
PT_U1 0 Pixel values are 1 bit.
PT_U2 1 Pixel values are 2 bits.
PT_U4 2 Pixel values are 4 bits.
PT_UCHAR 3 Pixel values are unsigned 8 bit integers.
PT_CHAR 4 Pixel values are 8 bit integers.
PT_USHORT 5 Pixel values are unsigned 16 bit integers.
PT_SHORT 6 Pixel values are 16 bit integers.
PT_ULONG 7 Pixel values are unsigned 32 bit integers.
PT_LONG 8 Pixel values are 32 bit integers.
PT_FLOAT 9 Pixel values are single precision floating point.
PT_DOUBLE 10 Pixel values are double precision floating point.
PT_COMPLEX 11 Pixel values are complex.
PT_DCOMPLEX 12 Pixel values are double precision complex.
//为了方便赋值,做了结构体的构造函数
RasterFormat(IPointPtr ipOrg, long lColC, long lRowC, double dCSX, double dCSY, long lNumBDS, rstPixelType ty, ISpatialReferencePtr ipSF)
{
ipOrigin = ipOrg;
lColCount = lColC;
lRowCount = lRowC;
dCellSizeX = dCSX;
dCellSizeY = dCSY;
lNumbands = lNumBDS;
rstTy = ty;
ipSpaRef = ipSF;
};
//为了能从栅格属性接口中得到栅格信息赋值,做了下面这个函数,目的还是方便给结构体赋值。
FromRasProps(IRasterPropsPtr ipRasProps, double dCSX, double dCSY, long lNumBDS,rstPixelType ty= PT_UCHAR, ISpatialReferencePtr ipSF = NULL){
IEnvelopePtr ipEnv;
ipRasProps->get_Extent(&ipEnv);
double x, y;
ipEnv->get_XMin(&x);
ipEnv->get_YMin(&y);
IPointPtr ipPt(CLSID_Point);
ipPt->PutCoords(x,y);
ipOrigin = ipPt;
ipRasProps->get_Width(&lColCount);
ipRasProps->get_Height(&lRowCount);
dCellSizeX = dCSX;
dCellSizeY = dCSY;
lNumbands = lNumBDS;
rstTy = ty;
ipSpaRef = ipSF;
};
};
4,pData是一个BYTE**(LPBYTE)类型的数组,
5,szRasFormat是栅格类型枚举,其定义为
enum RasterFormat
{
IMAGINE_Image,
TIFF,
GRID
};
6,bNoDataValue是透明灰度值,不过现在我还没有研究明白,实现不了效果,哪们朋友研究清楚了,可以指点一下。
//下面才是真正的函数开始了。
//生成ArcGIS支持的栅格数据
void CWzjAoRasterOp::WriteRaster(CString szPath, CString szFile, RasterInfo rstInfo, LPBYTE pData, CString szRasFormat /*= "IMAGINE Image"*/, BYTE bNoDataValue /*= 256*/)
{
IWorkspacePtr ipWS;
IWorkspaceFactoryPtr ipWSF(CLSID_RasterWorkspaceFactory);
//If Not pWSF.IsWorkspace(sPath) Then Exit Sub
ipWSF->OpenFromFile(CComBSTR(szPath), 0, &ipWS);
IRasterWorkspace2Ptr ipRWS(ipWS);
IRasterDatasetPtr ipRasterDS;//szRasFormat),
ipRWS->CreateRasterDataset(CComBSTR(szFile), CComBSTR(szRasFormat), rstInfo.ipOrigin, rstInfo.lColCount,
rstInfo.lRowCount, rstInfo.dCellSizeX, rstInfo.dCellSizeY, rstInfo.lNumbands, rstInfo.rstTy, rstInfo.ipSpaRef, TRUE, &ipRasterDS);
IRasterPtr ipRaster;
ipRasterDS->CreateDefaultRaster(&ipRaster);
IRasterPropsPtr ipRasProps = ipRaster;
// Get RasterBand from the raster
IRasterBandPtr ipBand;
IRasterBandCollectionPtr ipBandCol(ipRaster);
ipBandCol->Item(0, &ipBand);
//目前这个设置透明色值不管用,不知道正确的方法是怎么样
/*if (bNoDataValue > 0 || bNoDataValue < 256) {
VARIANT vVal;
vVal.vt = VT_UI1;
vVal.cVal = bNoDataValue;
// ipRasProps->put_NoDataValue(vVal);
ipRasProps->put_NoDataValue(CComVariant(bNoDataValue));
}
*/// QI RawPixel interface
IRawPixelsPtr ipRawPixel(ipBand);
ipRasProps = ipRaster;
// Create a DblPnt to hold the PixelBlock size
IPntPtr ipSize(CLSID_DblPnt);
long lWidth, lHeight;
ipRasProps->get_Width(&lWidth);
ipRasProps->get_Height(&lHeight);
ipSize->SetCoords(lWidth, lHeight);
// Create PixelBlock with defined size
IPntPtr ipPnt(CLSID_DblPnt);
ipPnt->SetCoords(0,0);
IPixelBlockPtr ipBlock;
ipRawPixel->CreatePixelBlock(ipSize, &ipBlock);
VARIANT varChunk;
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[2];
rgsabound[0].cElements = lWidth;
rgsabound[0].lLbound = 0;
rgsabound[1].cElements = lHeight;
rgsabound[1].lLbound = 0;
psa = SafeArrayCreate(VT_UI1,2,rgsabound);
LPBYTE pD;
SafeArrayAccessData(psa, (void**)&pD);
// pD = pData; 事实证明,直接这样不行,必须要经过下面赋值过程
long index;
CProDlg* pProDlg = new CProDlg();
pProDlg->Create(IDD_DLG_PRO);
pProDlg->SetWindowText("正在生成图像文件");
pProDlg->ShowWindow(SW_SHOW);
pProDlg->m_pro.SetRange(0, lWidth * lHeight-1);
for(long i=0;i {
for (long j = 0; j < lHeight; j++)
{
index = i*lHeight + j;
pD[index] =pData[index];//i+j;
}
pProDlg->m_pro.SetPos(i*lHeight+j);
}
delete pProDlg;
pProDlg = NULL;
varChunk.vt = VT_ARRAY|VT_UI1;
varChunk.parray = psa;
SafeArrayUnaccessData(psa);
ipBlock->put_SafeArray(0, varChunk);
ipPnt->SetCoords(0,0);
// Write the PixelBlock to raster band
ipRawPixel->Write(ipPnt, ipBlock);
}
小结一下,实现的过程中难点在于SAFEARRAY类型数据的使用,如果在VB或C#中不存在这个难点问题,很简单了,如果有什么问题的话,大家可以查一查SAFEARRAY它的用法或跟wzj23020723联系。