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);

创建栅格数据集

之前一直不会如何创建一个栅格,只会备份了栅格数据之后,再修改栅格的值。这种办法让人觉得很不舒服。现在,可以随心所欲的创建了。其实就两步:

  1. CreateRasterDataset 创建一个栅格数据集
  2. 给栅格赋值
    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/

上一篇下一篇

猜你喜欢

热点阅读