今天实现的功能是栅格重分类和栅格复制
我写的是植被覆盖率计算,但是实际实现的方法是栅格重分类。
private void 植被覆盖率计算ToolStripMenuItem_Click(object sender, EventArgs e)
{
// 自定义的提示信息
string customMessage1 = "请输入ndvi栅格";
IRaster resultRaster = null;
// 显示自定义提示信息
MessageBox.Show(customMessage1, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
IRasterDataset rasterDataset = OpenTiffFile();
if (rasterDataset == null)
{
MessageBox.Show("未选择任何TIFF文件或者打开文件失败。");
return;
}
//调用 reclass 方法
resultRaster = reclass(rasterDataset.CreateDefaultRaster());
IRasterLayer rasterLayer = new RasterLayerClass();
rasterLayer.CreateFromRaster(resultRaster);
rasterLayer.Name = "重分类";
axMapControl2.AddLayer((ILayer)rasterLayer, 0);
axMapControl2.ActiveView.Refresh();
SaveRasterToFile(resultRaster);
}
private IRaster reclass(IRaster pRaster)
{
IRasterProps rasterProps = (IRasterProps)pRaster;
//设置栅格数据起始点
IPnt pBlockSize = new Pnt();
pBlockSize.SetCoords(rasterProps.Width, rasterProps.Height);
//选取整个范围
IPixelBlock pPixelBlock = pRaster.CreatePixelBlock(pBlockSize);
//左上点坐标
IPnt tlp = new Pnt();
tlp.SetCoords(0, 0);
//读入栅格
IRasterBandCollection pRasterBands = pRaster as IRasterBandCollection;
IRasterBand pRasterBand = pRasterBands.Item(0);
IRawPixels pRawPixels = pRasterBands.Item(0) as IRawPixels;
pRawPixels.Read(tlp, pPixelBlock);
//将PixBlock的值组成数组
System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array;
List<double> pixelValues = new List<double>();
for (int y = 0; y < rasterProps.Height; y++)
{
for (int x = 0; x < rasterProps.Width; x++)
{
double value = Convert.ToDouble(pSafeArray.GetValue(x, y));
if (value >= 0)
pixelValues.Add(value);
}
}
// 对像元值进行排序
pixelValues.Sort();
// 计算后5%和前95%处的值作为分界值
int lowerIndex = (int)Math.Floor(pixelValues.Count * 0.05);
int upperIndex = (int)Math.Floor(pixelValues.Count * 0.95);
// 添加边界条件检查
lowerIndex = Math.Max(lowerIndex, 0);
upperIndex = Math.Min(upperIndex, pixelValues.Count - 1);
double lowerValue = pixelValues[lowerIndex];
double upperValue = pixelValues[upperIndex];
MessageBox.Show(lowerValue.ToString());
MessageBox.Show(upperValue.ToString());
System.Array dataArray = pSafeArray;
for (int y = 0; y < rasterProps.Height; y++)
{
for (int x = 0; x < rasterProps.Width; x++)
{
double value = Convert.ToDouble(dataArray.GetValue(x, y));
if (value < lowerValue)
dataArray.SetValue(0.0f, x, y);
else if (value >= upperValue)
dataArray.SetValue(1.0f, x, y);
else if (value >= lowerValue && value < upperValue)
{
double normalizedValue = (value - lowerValue) / (upperValue - lowerValue);
dataArray.SetValue((float)normalizedValue, x, y);
}
else
{
dataArray.SetValue(float.NaN, x, y); // 设置为空值
}
}
}
pPixelBlock.set_SafeArray(0, pSafeArray);
//编辑raster,将更新的值写入raster中
IRasterEdit rasterEdit = pRaster as IRasterEdit;
rasterEdit.Write(tlp, pPixelBlock);
rasterEdit.Refresh();
return pRaster;
}
复制栅格,为什么要复制栅格呢?因为有一个问题我没有解决,就是重分类的时候会改变原文件的值,我为了方便,搞了复制栅格来备份。
private void 复制栅格ToolStripMenuItem_Click(object sender, EventArgs e)
{
IRasterDataset rasterDataset = OpenTiffFile();
if (rasterDataset == null)
{
MessageBox.Show("未选择任何TIFF文件或者打开文件失败。");
return;
}
IRaster raster = rasterDataset.CreateDefaultRaster();
SaveRasterToFile(raster);
}
C因子的计算比c因子计算要简单一些。但是方法都是栅格重分类。
private void c因子计算ToolStripMenuItem_Click(object sender, EventArgs e)
{
// 自定义的提示信息
string customMessage1 = "请输入植被覆盖率栅格";
IRaster resultRaster = null;
// 显示自定义提示信息
MessageBox.Show(customMessage1, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
IRasterDataset rasterDataset = OpenTiffFile();
if (rasterDataset == null)
{
MessageBox.Show("未选择任何TIFF文件或者打开文件失败。");
return;
}
//调用 reclass 方法
resultRaster = reclass1(rasterDataset.CreateDefaultRaster());
IRasterLayer rasterLayer = new RasterLayerClass();
rasterLayer.CreateFromRaster(resultRaster);
rasterLayer.Name = "重分类";
axMapControl2.AddLayer((ILayer)rasterLayer, 0);
axMapControl2.ActiveView.Refresh();
SaveRasterToFile(resultRaster);
}
private IRaster reclass1(IRaster pRaster)
{
IRasterProps rasterProps = (IRasterProps)pRaster;
//设置栅格数据起始点
IPnt pBlockSize = new Pnt();
pBlockSize.SetCoords(rasterProps.Width, rasterProps.Height);
//选取整个范围
IPixelBlock pPixelBlock = pRaster.CreatePixelBlock(pBlockSize);
//左上点坐标
IPnt tlp = new Pnt();
tlp.SetCoords(0, 0);
//读入栅格
IRasterBandCollection pRasterBands = pRaster as IRasterBandCollection;
IRasterBand pRasterBand = pRasterBands.Item(0);
IRawPixels pRawPixels = pRasterBands.Item(0) as IRawPixels;
pRawPixels.Read(tlp, pPixelBlock);
//将PixBlock的值组成数组
System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array;
List<double> pixelValues = new List<double>();
System.Array dataArray = pSafeArray;
for (int y = 0; y < rasterProps.Height; y++)
{
for (int x = 0; x < rasterProps.Width; x++)
{
double value = Convert.ToDouble(dataArray.GetValue(x, y));
if (value == 0)
dataArray.SetValue(1.0f, x, y);
else if (value >= 0.783)
dataArray.SetValue(0.0f, x, y);
else if (value > 0 && value < 0.783)
{
double normalizedValue = 0.6508 - 0.3436 * Math.Log10(value*100);
dataArray.SetValue((float)normalizedValue, x, y);
}
else
{
dataArray.SetValue(float.NaN, x, y); // 设置为空值
}
}
}
pPixelBlock.set_SafeArray(0, pSafeArray);
//编辑raster,将更新的值写入raster中
IRasterEdit rasterEdit = pRaster as IRasterEdit;
rasterEdit.Write(tlp, pPixelBlock);
rasterEdit.Refresh();
return pRaster;
}