AE栅格处理:读取、加载、复制、修改属性、创建栅格数据集、保存、
2019-03-25 本文已影响0人
吵吵人
从图层中读取数据
//读取指定图层,含有landuse字样
if (axMapControl1.LayerCount > 0)
for (int i = 0; i < axMapControl1.LayerCount; i++)
if (axMapControl1.get_Layer(i).Name.Contains("landuse"))
rasterLayer = (IRasterLayer)axMapControl1.Map.get_Layer(i);
IRaster raster = rasterLayer.Raster;
IRaster2 pRaster2 = raster as IRaster2; //IRaster2接口常用于处理栅格
将栅格加载至地图中
// 是否将最后的结果加载至地图
DialogResult dr = MessageBox.Show("是否将结果添加至地图?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr == DialogResult.Yes)
{
IRasterLayer pRasterLayer;
pRasterLayer = new RasterLayer();
pRasterLayer.CreateFromRaster(raster);
ILayer pLayer = pRasterLayer as ILayer;
axMapControl1.AddLayer(pLayer, 0);
axMapControl1.ActiveView.Refresh();
}
复制栅格
注意: 是rasterbandcollection.Item(0).RasterDataset;,不是简单的接口转换,否则会出现错误。
IRasterBandCollection rasterbandcollection = raster as IRasterBandCollection;
IRasterDataset rasterdataset = rasterbandcollection.Item(0).RasterDataset;
IWorkspaceFactory rWorkspaceFactory = new RasterWorkspaceFactory();
IWorkspace rasterWorkspace=rWorkspaceFactory.OpenFromFile(@"E:\GraduationProject\data\数据备份", 0);
IDataset resultDataset = rasterdataset.Copy("栖霞2005.tif", rasterWorkspace);
MessageBox.Show("栅格复制完毕!");
栅格属性
//获取栅格属性
IRasterProps rasterProps = (IRasterProps)raster; //栅格属性
int dHeight = rasterProps.Height; //当前栅格数据集的行数484
int dWidth = rasterProps.Width; //当前栅格数据集的列数894
double dX = rasterProps.MeanCellSize().X; //栅格的宽度50
double dY = rasterProps.MeanCellSize().Y; //栅格的高度50
IEnvelope extent = rasterProps.Extent; //当前栅格数据集的范围
rasterProps.PixelType = rstPixelType.PT_LONG; //设置栅格像素值类型为PT_LONG型
提取栅格数据值到二维数组
private int[,] GetPixelValueToIntArray(IRaster pRaster)
{
IRaster2 pRaster2 = pRaster as IRaster2;
IRasterProps pRasterProps = pRaster as IRasterProps;
int Height = pRasterProps.Height;
int Width = pRasterProps.Width;
int[,] PixelValue = new int[Height, Width];
IRasterCursor pRasterCursor = pRaster2.CreateCursorEx(null); //参数设为null,内部自动设置PixelBlock大小
long blockwidth = 0;
long blockheight = 0;
try
{
do
{
int left = (int)pRasterCursor.TopLeft.X;
int top = (int)pRasterCursor.TopLeft.Y;
IPixelBlock3 pPixelBlock3 = pRasterCursor.PixelBlock as IPixelBlock3;
blockheight = pPixelBlock3.Height;
blockwidth = pPixelBlock3.Width;
System.Array pixels = (System.Array)pPixelBlock3.get_PixelData(0);
for (int i = 0; i < blockheight; i++)
for (int j = 0; j < blockwidth; j++)
PixelValue[top + i, left + j] = Convert.ToInt32(pixels.GetValue(j, i));
}
while (pRasterCursor.Next() == true);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
return PixelValue;
}
修改栅格数据值
像素块移动修改像素值,可以自定义像素块的大小
public void ChangeRasterValue(IRaster pRaster, int[,] values)
{
IRaster2 pRaster2 = pRaster as IRaster2;
IRasterProps pRasterProps = pRaster as IRasterProps;
//获取图层的行列值
int Height = pRasterProps.Height;
int Width = pRasterProps.Width;
//定义并初始化数组,用于存储栅格内所有像员像素值
short[,] PixelValue = new short[Width, Height];
System.Array pixels;
//数设为null,内部自动设置PixelBlock大小
IRasterCursor pRasterCursor = pRaster2.CreateCursorEx(null);
//用于存储PixelBlock的长宽
long blockwidth = 0;
long blockheight = 0;
IPixelBlock3 pPixelBlock3;
IRasterEdit pRasterEdit = pRaster2 as IRasterEdit; //栅格状态编辑
try
{
do
{
//获取Cursor的左上角坐标
int left = (int)pRasterCursor.TopLeft.X;
int top = (int)pRasterCursor.TopLeft.Y;
pPixelBlock3 = pRasterCursor.PixelBlock as IPixelBlock3;
blockheight = pPixelBlock3.Height;
blockwidth = pPixelBlock3.Width;
//pPixelBlock3.Mask(255);
pixels = (System.Array)pPixelBlock3.get_PixelData(0);
//获取该Cursor的PixelBlock中像素的值
try
{
for (int i = 0; i < blockwidth; i++)
for (int j = 0; j < blockheight; j++)
{
//一定要注意,pixels中的数组排序为[Width,Height]
object pvalue = pixels.GetValue(i, j);
if (Convert.ToInt32(pvalue) != -9999) PixelValue.SetValue((short)1, i, j);
}
}
catch (Exception)
{
}
}
while (pRasterCursor.Next() == true);
pPixelBlock3.set_PixelData(0, PixelValue);
pRasterEdit.Write(pRasterCursor.TopLeft, (IPixelBlock)pPixelBlock3);
pRasterEdit.Refresh();
System.Runtime.InteropServices.Marshal.ReleaseComObject(pRasterEdit);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//释放资源
System.Runtime.InteropServices.Marshal.ReleaseComObject(pRasterEdit);
创建栅格数据集
之前一直不会如何创建一个栅格,只会备份了栅格数据之后,再修改栅格的值。这种办法让人觉得很不舒服。现在,可以随心所欲的创建了。其实就两步:
- CreateRasterDataset 创建一个栅格数据集
- 给栅格赋值
step1:从栅格中创建像素块
step2:修改像素块的值
step3:将像素块写入栅格
ok,大功告成!
public IRasterDataset CreateFileRasterDataset(string directoryName, string fileName,IRasterProps pros,int[,] data)
{
try
{
IRasterDataset rasterDataset = null;
IPoint originPoint = new PointClass();
originPoint.PutCoords(pros.Extent.XMin, pros.Extent.YMin);
// Create the dataset
IRasterWorkspace2 rasterWorkspace2 = null;
rasterWorkspace2 = this.CreateRasterWorkspace(directoryName);
//rasterDataset = rasterWorkspace2.CreateRasterDataset(fileName, "TIFF", originPoint, pros.Width, pros.Height, pros.MeanCellSize().X, pros.MeanCellSize().Y, 1, pros.PixelType, new UnknownCoordinateSystemClass(), true);
rasterDataset = rasterWorkspace2.CreateRasterDataset(fileName, "TIFF", originPoint, pros.Width, pros.Height, pros.MeanCellSize().X, pros.MeanCellSize().Y, 1, pros.PixelType, pros.SpatialReference, true);
IRasterBandCollection rasterBands = (IRasterBandCollection)rasterDataset;
IRasterBand rasterBand;
IRasterProps rasterProps;
rasterBand = rasterBands.Item(0);
rasterProps = (IRasterProps)rasterBand;
rasterProps.NoDataValue = this.mNoDataValue;
IRaster raster = rasterDataset.CreateDefaultRaster();
//Create a pixel block using the weight and height of the raster dataset.
//If the raster dataset is large, a smaller pixel block should be used.
//Refer to the topic "How to access pixel data using a raster cursor".
IPnt blocksize = new PntClass();
blocksize.SetCoords(pros.Width, pros.Height);
IPixelBlock3 pixelblock = raster.CreatePixelBlock(blocksize)as IPixelBlock3;
//Populate some pixel values to the pixel block.
System.Array pixels;
pixels = (System.Array)pixelblock.get_PixelData(0);
for (int i = 0; i < pros.Width; i++)
for (int j = 0; j < pros.Height; j++)
//if (i == j)
// pixels.SetValue(Convert.ToByte(255), i, j);
//else
pixels.SetValue(Convert.ToByte(data[j, i]), i, j);
////测试
////Populate some pixel values to the pixel block.
//System.Array pixels;
//pixels = (System.Array)pixelblock.get_PixelData(0);
//for (int i = 0; i < pros.Width; i++)
// for (int j = 0; j < pros.Height; j++)
// pixels.SetValue(Convert.ToByte(255), i, j);
//for (int i = 200; i < 500; i++)
// for (int j = 100; j <200; j++)
// pixels.SetValue(Convert.ToByte(5), i, j);
pixelblock.set_PixelData(0, (System.Array)pixels);
//Define the location that the upper left corner of the pixel block is to write.
IPnt upperLeft = new PntClass();
upperLeft.SetCoords(0, 0);
//Write the pixel block.
IRasterEdit rasterEdit = (IRasterEdit)raster;
rasterEdit.Write(upperLeft, (IPixelBlock)pixelblock);
//Release rasterEdit explicitly.
System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);
return rasterDataset ;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
}
public IRasterWorkspace2 CreateRasterWorkspace(string pathName)
{
// Create RasterWorkspace
IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass();
return workspaceFactory.OpenFromFile(pathName, 0) as IRasterWorkspace2;
}
如果取消掉测试的注释,黑色是其他的图,白色是修改的图
测试结果
在给很少量的点创建栅格时,可以先给栅格统一赋值成无值,再设置某些点的栅格值,否则会出现其他区域为0,而不是无值的情况。
用二维数组更新栅格数据
整体一次性更新完毕
public void ChangeRasterValue(IRaster pRaster, int[,] values)
{
IRaster2 pRaster2 = pRaster as IRaster2;
IRasterProps pRasterProps = pRaster as IRasterProps;
int Height = pRasterProps.Height;
int Width = pRasterProps.Width;
short[,] PixelValue = new short[Width, Height];
Pnt pntSize = new PntClass();
pntSize.X = pRasterProps.Width;
pntSize.Y = pRasterProps.Height;
IRasterCursor pRasterCursor = pRaster2.CreateCursorEx(pntSize);
IRasterEdit pRasterEdit = pRaster2 as IRasterEdit;
try
{
for (int i = 0; i < Width; i++)
for (int j = 0; j < Height; j++)
PixelValue.SetValue((short)values[j, i],i,j);
IPixelBlock3 pPixelBlock3 = pRasterCursor.PixelBlock as IPixelBlock3;
System.Array pixels = (System.Array)pPixelBlock3.get_PixelData(0);
pPixelBlock3.set_PixelData(0, PixelValue);
pRasterEdit.Write(pRasterCursor.TopLeft, (IPixelBlock)pPixelBlock3);
pRasterEdit.Refresh();
System.Runtime.InteropServices.Marshal.ReleaseComObject(pRasterEdit);
MessageBox.Show("完成遍历!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
保存栅格
可以用rasterBandCollection.SaveAs(fullPath, rWorkspace, "TIFF");
亦可以用pRaster2接口转换到ISaveAS接口
private void SaveRasterToFile(IRaster2 pRaster2)
{
//保存结果
SaveFileDialog sd = new SaveFileDialog();
sd.Title = "保存文件";
sd.InitialDirectory = @"E:\毕设CA项目\TEST\结果\";
sd.Filter = "栅格数据(*.tif)|(*.tif)";
try
{
if (sd.ShowDialog() == DialogResult.OK)
{
string fullPath = sd.FileName;
int index = fullPath.LastIndexOf("\\");
string direction = fullPath.Substring(0, index); //路径,没带//
string name = fullPath.Substring(index + 1); //文件名
IWorkspaceFactory rWorkspaceFactory = new RasterWorkspaceFactory();
IWorkspace rasterWorkspace = rWorkspaceFactory.OpenFromFile(direction + "\\", 0);
IRasterBandCollection rasterBandCollection = pRaster2 as IRasterBandCollection;
rasterBandCollection.SaveAs(fullPath, rasterWorkspace, "TIFF");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
结果写入txt文件
string filename = System.IO.Directory.GetCurrentDirectory() + @"文件名.txt";
System.IO.FileStream fs = System.IO.File.Create(filename);
fs.Close();
System.IO.StreamWriter sw = new System.IO.StreamWriter(filename);
for(int i=0;i<num;i++)
{
for(int j=0;j<3;j++)
{
if(j<2)
sw.Write(arr[i, j] + ", ");
else
sw.Write(arr[i, j]);
}
sw.Write("\r\n");
}
sw.Flush();
弹出窗口自定义保存路径
//自定义保存路径
SaveFileDialog sd = new SaveFileDialog();
sd.Title = "保存文件";
sd.InitialDirectory = @"E:\GraduationProject\result\";
try
{
if (sd.ShowDialog() == DialogResult.OK)
{
fullPath = sd.FileName;
//int index = fullPath.LastIndexOf("\\");
//string direction = fullPath.Substring(0, index); //路径,没带//
//string name = fullPath.Substring(index + 1); //文件名
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
计时器
//记时开始
Stopwatch timer = new Stopwatch();
timer.Start();
//记时结束
timer.Stop();
//运行时间
timer.Elapsed.ToString()
ArcObjects API Reference for .NET:http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/