ArcEngine 栅格数据 总结

本文大部分内容参考AO帮助文档和ArcMap帮助文档,大家实际使用中遇到的问题也可以在本帖下方留言交流,谢谢!
欢迎浏览,拒绝转载!

基础知识

栅格数据基础知识:传送门
栅格数据相关博文:栅格那点儿事儿

栅格数据是由一系列等间距的格网矩阵组成,用来表达完整的主题、光谱、图像信息。
栅格数据模型分为栅格数据集(Raster dataset)、栅格目录(Raster catalog)、镶嵌数据集(Mosaic dataset)。他们以文件系统、个人地理数据库、文件地理数据库、企业地理数据库为数据源进行存储。

栅格数据集也就是我们经常所得的jpg、tif文件等, ArcGIS 将这些栅格数据抽象为 RasterDataset,栅格数据集就代表了磁盘中的一个文件,它由一个或多个波段组成。在使用栅格数据集的时候,栅格数据会被转换成 IMG 文件存储在数据库中。我们可以对栅格数据集进行一些操作,如改变空间参考,建立影像金字塔等。

栅格目录,正如其名字一样是一个目录,跟书的目录相似,它记录了一个或者多个栅格数据集,每一个栅格数据集都作为一条记录存储在栅格目录中。栅格目录对栅格数据集的管理有两种方式,托管和非托管。托管方式的时候,栅格数据是存储在数据库中, 非托管的时候,栅格目录记录了栅格数据集的路径,也就是栅格数据并没有存储在数据库中。当我们删除一条记录的时候,对我们的栅格数据没有任何影响。

镶嵌数据集可以说是栅格数据集和栅格目录的混合技术,它的存储方式和栅格目录类似,但是在使用的时候和普通的栅格数据集是一样的,镶嵌数据集用于管理和发布海量多分辨率,多传感器影像,对栅格数据提供了动态镶嵌和实时处理的功能。
对文件地理数据库、个人地理数据库和 ArcSDE 地理数据库中的栅格存储加以比较:
ArcEngine 栅格数据 总结_第1张图片

类图

在线地址:传送门
本地路径:本地路径:如 C:\Program Files (x86)\ArcGIS\DeveloperKit10.2\Diagrams\DataSourcesRasterObjectModel.pdf
##和栅格数据集有关的GP工具
ArcEngine 栅格数据 总结_第2张图片

栅格数据接口使用示例

ArcEngine 栅格数据 总结_第3张图片

打开栅格数据工作空间

//Open a file geodatabase workspace as RasterWorkspace.
static IRasterWorkspaceEx OpenFGDB(string FGDBPath)
{
    //FGDBPath string example: c:\data\raster.gdb.
    IWorkspaceFactory2 workspaceFactory = new FileGDBWorkspaceFactoryClass();
    return (IRasterWorkspaceEx)workspaceFactory.OpenFromFile(FGDBPath, 0);
}

//Open an ArcSDE workspace as RasterWorkspace.
static IRasterWorkspaceEx OpenSDE(string conString)
{
    //conString example: SERVER=ais;INSTANCE=9200;VERSION=sde.DEFAULT;USER=raster;PASSWORD=raster.
    IWorkspaceFactory2 workspaceFactory = new SdeWorkspaceFactoryClass();
    return (IRasterWorkspaceEx)workspaceFactory.OpenFromString(conString, 0);
}

//Open an accessed workspace as RasterWorkspace.
static IRasterWorkspaceEx OpenAccess(string PGDBPath)
{
    //FGDBPath string example: c:\data\rasters.mdb.
    IWorkspaceFactory2 workspaceFactory = new AccessWorkspaceFactoryClass();
    return (IRasterWorkspaceEx)workspaceFactory.OpenFromFile(PGDBPath, 0);
}

//Open a file workspace as RasterWorkspace.
static IRasterWorkspace OpenFileWorkspace(string wsPath)
{
    //wsPath example: c:\data\rasters.
    IWorkspaceFactory workspaceFact = new RasterWorkspaceFactoryClass();
    return (IRasterWorkspace)workspaceFact.OpenFromFile(wsPath, 0);
}

打开栅格数据集

IRasterDataset rasterDataset = rasterWorkspace.OpenRasterDataset(datasetName);
IRasterDataset rasterDataset = rasterWorkspaceEx.OpenRasterDataset(datasetName);

创建栅格数据集

  1. Creating a raster dataset(创建以文件存储的栅格数据集,如TIFF)
    1)Create a workspace.创建工作空间
    2)Create a TIFF file with specified width, height, pixel type, cell size, and other necessary dimensions.创建一个TIFF文件,并指定它的宽度,高度,像素类型、像元大小和其他必要的维度。
    3)Use the IPixelBlock and IRasterEdit interfaces to edit the pixel values.使用IPixelBlock 和 IRasterEdit 接口来编辑像元的值。
public static IRasterDataset CreateRasterDataset(string Path, string FileName)
{
    try
    {
        IRasterWorkspace2 rasterWs = OpenRasterWorkspace(Path);
        //Define the spatial reference of the raster dataset.
        ISpatialReference sr = new UnknownCoordinateSystemClass();
        //Define the origin for the raster dataset, which is the lower left corner of the raster.
        IPoint origin = new PointClass();
        origin.PutCoords(15.0, 15.0);
        //Define the dimensions of the raster dataset.
        int width = 100; //This is the width of the raster dataset.
        int height = 100; //This is the height of the raster dataset.
        double xCell = 30; //This is the cell size in x direction.
        double yCell = 30; //This is the cell size in y direction.
        int NumBand = 1; // This is the number of bands the raster dataset contains.
        //Create a raster dataset in TIFF format.
        IRasterDataset rasterDataset = rasterWs.CreateRasterDataset(FileName, "TIFF", 
			origin, width, height, xCell, yCell, NumBand, rstPixelType.PT_UCHAR, sr,
            true);

        //If you need to set NoData for some of the pixels, you need to set it on band 
        //to get the raster band.
        IRasterBandCollection rasterBands = (IRasterBandCollection)rasterDataset;
        IRasterBand rasterBand;
        IRasterProps rasterProps;
        rasterBand = rasterBands.Item(0);
        rasterProps = (IRasterProps)rasterBand;
        //Set NoData if necessary. For a multiband image, a NoData value needs to be set for each band.
        rasterProps.NoDataValue = 255;
        //Create a raster from the dataset.
        IRaster raster = rasterDataset.CreateFullRaster();

        //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(width, 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 < width; i++)
            for (int j = 0; j < height; j++)
                if (i == j)
                    pixels.SetValue(Convert.ToByte(255), i, j);
                else
                    pixels.SetValue(Convert.ToByte((i * j) / 255), 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 static IRasterWorkspace2 OpenRasterWorkspace(string PathName)
{
    //This function opens a raster workspace.
    try
    {
        IWorkspaceFactory workspaceFact = new RasterWorkspaceFactoryClass();
        return workspaceFact.OpenFromFile(PathName, 0)as IRasterWorkspace2;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
        return null;
    }
}
  1. Creating a raster dataset in a geodatabase(创建以GDB存储的栅格数据集,如GRID)
    1)Create a file geodatabase workspace factory.创建哥FGDB的工作工厂对象。
    2)Create a raster workspace and query IRasterWorkspaceEx.创建一个栅格工作空间对象并且转换到IRasterWorkspaceEx对象上
    3)Define the storage and raster properties using the RasterStorageDef and RasterDef classes. 利用RasterStorageDef 和RasterDef 类定义栅格数据集的存储和栅格属性。
    4)Create the dataset using the CreateRasterDataset method.利用CreateRasterDataset方法创建栅格数据集。
IWorkspaceFactory wsf = new FileGDBWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)wsf.OpenFromFile(@"c:\temp\fgdb.gdb", 0);

//Define the raster storage.
IRasterStorageDef storage = new RasterStorageDefClass();
storage.Tiled = true;
storage.TileHeight = 128;
storage.TileWidth = 128;

//Define the spatial reference.
IRasterDef rasterDef = new RasterDefClass();
rasterDef.SpatialReference = new UnknownCoordinateSystemClass();

//Create data.
IRasterDataset rasterDs = ws.CreateRasterDataset("newraster", 3,
rstPixelType.PT_SHORT, storage, "sde.DEFAULT", rasterDef, null);

访问HDF和NIFF数据的子集

一些栅格格式,如分层数据格式(HDF),可以在单个文件中包含多个subdatasets。访问HDF subdatasets使用IRasterDatasetJukebox接口,请参见下面的代码示例:

IWorkspaceFactory wsf = new FileGDBWorkspaceFactoryClass();
IRasterWorkspaceEx ws = (IRasterWorkspaceEx)wsf.OpenFromFile(@"c:\temp\fgdb.gdb", 0);

//Define the raster storage.
IRasterStorageDef storage = new RasterStorageDefClass();
storage.Tiled = true;
storage.TileHeight = 128;
storage.TileWidth = 128;

//Define the spatial reference.
IRasterDef rasterDef = new RasterDefClass();
rasterDef.SpatialReference = new UnknownCoordinateSystemClass();

//Create data.
IRasterDataset rasterDs = ws.CreateRasterDataset("newraster", 3,
rstPixelType.PT_SHORT, storage, "sde.DEFAULT", rasterDef, null);

读取JPEG EXIF扩展标记信息

public static void JPEG_EXIFtag(IRasterDataset exifDataset)
{
    //exifDataset represents a raster dataset opened from a JPEG file that has EXIF tags.
    IDataset dataset = (IDataset)exifDataset;
    //Get the EXIF tags and the associated values.
    IPropertySet propertySet = dataset.PropertySet;    
	System.Object tag_names;
    System.Object tag_values;
    propertySet.GetAllProperties(out tag_names, out tag_values);
    string[] stringNames = (string[])tag_names;
    object[] stringValues = (object[])tag_values;
    for (int i = 0; i < stringNames.Length - 1; i++)    
	{
		System.Console.WriteLine(stringNames[i]);
		System.Console.WriteLine(stringValues[i]);    
	}
}

读取像素数据

  • 使用光栅游标访问像素数据,参考博文:传送门
public static void UsingRasterCursorWithPixelBlock(IRasterDataset2 rasterDs)
{
    try
    {
        //Create a raster. 
        IRaster2 raster2 = rasterDs.CreateFullRaster()as IRaster2;
        //Create a raster cursor with a system-optimized pixel block size by passing a null.
        IRasterCursor rasterCursor = raster2.CreateCursorEx(null);
        //Use the IRasterEdit interface.
        IRasterEdit rasterEdit = raster2 as IRasterEdit;
        //Loop through each band and pixel block.
        IRasterBandCollection bands = rasterDs as IRasterBandCollection;
        IPixelBlock3 pixelblock3 = null;
        long blockwidth = 0;
        long blockheight = 0;
        System.Array pixels;
        IPnt tlc = null;
        object v;
        long bandCount = bands.Count;
        do
        {
            pixelblock3 = rasterCursor.PixelBlock as IPixelBlock3;
            blockwidth = pixelblock3.Width;
            blockheight = pixelblock3.Height;
            pixelblock3.Mask(255);
            for (int k = 0; k < bandCount; k++)
            {
                //Get the pixel array.
                pixels = (System.Array)pixelblock3.get_PixelData(k);
                for (long i = 0; i < blockwidth; i++)
                {
                    for (long j = 0; j < blockheight; j++)
                    {
                        //Get the pixel value.
                        v = pixels.GetValue(i, j);
                        //Do something with the value.
                    }
                }
                //Set the pixel array to the pixel block.
                pixelblock3.set_PixelData(k, pixels);
            }
            //Write back to the raster.
            tlc = rasterCursor.TopLeft;
            rasterEdit.Write(tlc, (IPixelBlock)pixelblock3);
        }
        while (rasterCursor.Next() == true);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }
}

  • 使用RawBlocks 对象访问像素数据
    Raster pixels can be accessed through the IRasterEdit and IPixelBlock3 interfaces. These interfaces read and edit pixels on raster objects. The RawBlocks object, new at ArcGIS 10, works with pixels on a raster band. It reads pixels using an internal tiling structure and loops through the pixel blocks without resampling.
    This topic shows how to use the RawBlocks object to manipulate raster data at a pixel level.
    概要翻译:可以通过IRasterEdit 和 IPixelBlock3 接口访问栅格像素,这两个接口会在栅格对象本身读去和编辑栅格像素。在ArcGIS10版本以后,提供了使用RawBlocks 对象,它在栅格波段上操作像素,它使用一个内部瓦片结构和循环遍历像素块(没有重采样)读取像素。这一主题展示了如何使用RawBlocks对象在一个像素水平操纵栅格数据。
public static void ReadWriteRawBlocks(IRasterDataset rasDs)
{
    IRasterBandCollection rasBandCol = (IRasterBandCollection)rasDs;
    IRawBlocks rawBlocks;
    IRasterInfo rasInfo;
    IPixelBlock pb;

    // Iterate through each band of the dataset.
    for (int m = 0; m <= rasBandCol.Count - 1; m++)
    {
        // QI to IRawBlocks from IRasterBandCollection.
        rawBlocks = (IRawBlocks)rasBandCol.Item(m);
        rasInfo = rawBlocks.RasterInfo;
        // Create the pixel block.
        pb = rawBlocks.CreatePixelBlock();

        // Determine the tiling scheme for the raster dataset.

        int bStartX = (int)Math.Floor((rasInfo.Extent.Envelope.XMin -
            rasInfo.Origin.X) / (rasInfo.BlockWidth * rasInfo.CellSize.X));
        int bEndX = (int)Math.Ceiling((rasInfo.Extent.Envelope.XMax -
            rasInfo.Origin.X) / (rasInfo.BlockWidth * rasInfo.CellSize.X));
        int bStartY = (int)Math.Floor((rasInfo.Origin.Y -
            rasInfo.Extent.Envelope.YMax) / (rasInfo.BlockHeight *
            rasInfo.CellSize.Y));
        int bEndY = (int)Math.Ceiling((rasInfo.Origin.Y -
            rasInfo.Extent.Envelope.YMin) / (rasInfo.BlockHeight *
            rasInfo.CellSize.Y));

        // Iterate through the pixel blocks.
        for (int pbYcursor = startY; pbYcursor < endY; pbYcursor++)
        {
            for (int pbXcursor = startX; pbXcursor < endX; pbXcursor++)
            {
                // Get the pixel block.
                rawBlocks.ReadBlock(pbXcursor, pbYcursor, 0, pb);
                System.Array safeArray;
                // Put the pixel block into a SafeArray for manipulation.
                safeArray = (System.Array)pb.get_SafeArray(0);

                // Iterate through the pixels in the pixel block.
                for (int safeArrayHeight = 0; safeArrayHeight < pb.Height;
                    safeArrayHeight++)
                {
                    for (int safeArrayWidth = 0; safeArrayWidth < pb.Width;
                        safeArrayWidth++)
                    {
                        // Use System.Array.SetValue to write the new pixel value back into the SafeArray.
                        safeArray.SetValue(Convert.ToByte(128), safeArrayWidth,
                            safeArrayHeight);
                    }
                }
                // Set the SafeArray back to the pixel block.
                pb.set_SafeArray(0, safeArray);

                // Write the pixel block back to the dataset.
                rawBlocks.WriteBlock(pbXcursor, pbYcursor, 0, pb);
            }
        }
    }
}

创建栅格属性表

static void BuildRasterAttributeTable(IRasterDataset rasterDataset, ITable table)
{
    //Cast to IRasterDatasetEdit2 to build a raster attribute table.
    IRasterDatasetEdit2 rasterDatasetEdit = (IRasterDatasetEdit2)rasterDataset;

    //Build a default raster attribute table with VALUE and COUNT fields.
    if (table == null)
    {
        rasterDatasetEdit.BuildAttributeTable();
    }
    else
    {
        //Assign the given table as the raster attribute table.
        rasterDatasetEdit.AlterAttributeTable(table);
    }
}

读取栅格数据属性(官方文档)

ArcEngine 栅格数据 总结_第4张图片

主要用到的接口:

  1. IRasterProps
  2. IRasterBandCollection
  3. IRasterDataset
  4. IRasterPyramid3
  5. IRasterBand
    栅格属性列表:
    列数和行数(Columns and Rows):通过IRasterProps的Width和Height属性获取
    波段数量(Number of Bands):通过IRasterBandCollection接口获取(可以由IRaster对象跳转接口到此接口)
    像元大小(CellSize(X,Y)):通过IRasterProps的MeanCellSize
    格式(Format):通过IRasterDataset的Format属性获取
    源类型(Source Type):可以通过GP工具SetRasterProperties来设置。
    像素类型(Pixel Type):通过IRasterProps接口的PixelType 属性获取
    像素位深(Pixel Depth):根据像素类型来判断像素位深
    无数据值(NoData Value):通过IRasterProps 的NoDataValue属性获取
    颜色表/色带(Colormap):通过IRaster2接口的Colormap属性获取色带
    金字塔(Pyramids):通过IRasterPyramid3接口来创建、获取、删除金字塔(PS:用IRasterDataset接口跳转到IRasterPyramid3接口)
    压缩(Compression):通过IRasterDataset的CompressionType属性获取压缩类型
    范围(Extent):将IRasterDataset接口对象转换成IGeoDataset对象来范围信息
    空间参考(Spatial Reference):1)将IRasterDataset接口对象转换成IGeoDataset对象来获取空间参考信息 2)通过IRasterProps 的属性SpatialReference获取 3)其它方法
    统计(Statistics):通过IRasterBand接口的Statistics属性获取波段的统计信息
    波段集合:通过IRasterBandCollection 接口来添加、删除、获取波段。

构建金字塔

构建金字塔有两种方式:1)利用IRasterPyramid3接口来创建金字塔 2)利用GP工具创建金字塔
示例代码:
1)

IRasterPyramid3 pRasterPyramid = rasterDataset as IRasterPyramid3;
if (pRasterPyramid != null && !pRasterPyramid.Present)
{
	//-1代表创建全部级别的金字塔,0代表删除金字塔,其它代表创建对应级别的金字塔
	pRasterPyramid.BuildPyramid(-1, rstResamplingTypes.RSP_NearestNeighbor);
}

2)
ArcEngine 栅格数据 总结_第5张图片

//如何监听GP消息请参考文章《ArcEngine GP笔记(持续补充中......)》
ESRI.ArcGIS.DataManagementTools.BuildPyramids buildPyramids = new ESRI.ArcGIS.DataManagementTools.BuildPyramids();
buildPyramids.in_raster_dataset = sRasterFile; //栅格数据源
buildPyramids.resample_technique = cmbEditResample.Text; //重分类方法
buildPyramids.compression_type = cmbEditCompressType.Text; //压缩类型
buildPyramids.compression_quality = Convert.ToInt32(txtCompressQuality.Text); //压缩质量
IGeoProcessorResult gpResult = m_geoProcesser.Execute(buildPyramids, null);
if (gpResult.Status == ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded)
{
	//do something 
}

个人经验:遇到数据量大的数据创建金字塔比较耗时,建议使用第二种方式GP工具创建金字塔,可以对GP工具进行监听,实时输出动态消息;数据量小的时候可以使用接口,简单快捷。个人经验仅供参考,如有意见,请留言!

栅格数据另存

栅格数据另存有两种方式:①利用ISaveAs和ISaveAs2接口 ②利用GP工具另存
示例代码:
1)ISaveAs2接口另存图片

//去黑边
IRasterProps pRasterProps=pRaster as IRasterProps;
pRasterProps.NoDataValue=255;
//另存输出
ISaveAs2 pSaveAs = pRaster as ISaveAs2;
if (!pSaveAs.CanSaveAs(sFormat))
{
	XtraMessageBox.Show("不支持指定像素类型或文件格式的输出", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
	return ;
}
IWorkspaceFactory worksapceFactory = new RasterWorkspaceFactoryClass();
workspace = worksapceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(m_sOutputPath), 0);
IDataset dataset = pSaveAs.SaveAs(System.IO.Path.GetFileName(m_sOutputPath), workspace, sFormat);

个人经验: ISaveAs 保存Grid格式数据技巧
2)可以利用CopyRaster工具拷贝一份栅格数据实现栅格数据的另存。

栅格数据裁切

栅格数据裁切有两种方式:①利用接口进行裁切 ②利用GP工具进行裁切
1)利用接口进行裁切
①基于IEnvelope对象裁切,主要用到的接口:IRasterGeometryProc

IRasterGeometryProc pRasterGeometryProc = new RasterGeometryProcClass();
pRasterGeometryProc.Clip(pClipEnvelope,pInputRaster)

②利用 IExtractionOp2接口进行裁切,然后用ISaveAs2接口保存裁切后的结果。代码链接:传送门(这种方法不支持含孔洞的面作为裁切范围)
③调用IClipFilter裁切,参考链接
④调用IRasterFunction裁切,参考链接

// Create the Function Arguments object.
IClipFunctionArguments rasterFunctionArguments = (IClipFunctionArguments)new
    ClipFunctionArguments();
// The input data can be of type IRasterDataset, IRasterBand, or IRaster.
rasterFunctionArguments.Raster = inputData;
// Set the parameters for the function:
// Set the clipping type (clip outside leaves the area inside the envelope untouched)
rasterFunctionArguments.ClippingType =
    esriRasterClippingType.esriRasterClippingOutside;
// Set the extents to clip to by providing a raster envelope object.
rasterFunctionArguments.ClippingGeometry = rasterEnvelope;

// Create the Raster Function object.
IRasterFunction rasterFunction = new ClipFunction();
// Create the Function Raster Dataset object.
IFunctionRasterDataset functionRasterDataset = new FunctionRasterDataset();
// Create a name object for the Function Raster Dataset.
IFunctionRasterDatasetName functionRasterDatasetName = (IFunctionRasterDatasetName)
    new FunctionRasterDatasetName();
// Specify the output file name for the new dataset (including the .afr extension at the end).
functionRasterDatasetName.FullName = @"c:\temp\Clip.afr";
functionRasterDataset.FullName = (IName)functionRasterDatasetName;
// Initialize the new Function Raster Dataset with the Raster Function and its arguments.
functionRasterDataset.Init(rasterFunction, rasterFunctionArguments);

2)调用Clip工具进行裁切,代码略(这块我做过基于范围、文件、ROI绘制图形的裁切,不会的可以留言,我可以把示例代码发过去)。
这块有几个注意事项:
① 注意输入数据和裁切范围要有坐标系
② 注意被裁切的数据和裁切范围是否可以叠加上
③ 注意将裁切范围转换到输入数据的坐标系上去
④ 如果基于栅格文件裁切,clipping_geometry设置为 “NONE”;如果基于矢量文件裁切,clipping_geometry设置为 “ClippingGeometry”;
⑤ 如果基于四角坐标裁切,注意rectangle参数格式;如果in_template_dataset不为空字符串或空对象,设置rectangle参数为“#”即可。

in_rectangle = string.Format("{0} {1} {2} {3}", pEnvelope.XMin, pEnvelope.YMin, pEnvelope.XMax, pEnvelope.YMax);

栅格数据可视化

1.栅格数据渲染包括一下几种:

  • Raster Unique value Renderer 唯一值渲染
  • Raster Classify Renderer 分类渲染
  • Raster Stretch Renderer 色带拉伸渲染
  • RGB渲染,必须为多波段影像
    主要用到的接口:
  1. IRasterLayer
  2. IRasterRenderer

ArcEngine 栅格数据 总结_第6张图片
示例代码暂时略,有问题的同学可以留言。这块想着以后有时间的话以新帖子总结,顺便将色带总结了。

2.栅格图层的显示效果
栅格图层的显示效果受亮度、对比度、透明度等因素的影响。
用到的接口:
1)ILayerEffects
2)IRasterDisplayProps

栅格数据分析

分享几个我项目中用到的栅格分析功能的例子:
1)坡度分析

private IRaster ProduceSlopeData(DirectoryInfo demFile, string outputFolder,
  string strOutputMeasurement, double zFactor, IGeoDataset inputGeoDataset, IWorkspace pWorkspace)
{
	IRaster solpeRaster = null;
	ISurfaceOp pSurface = new RasterSurfaceOpClass();
	esriGeoAnalysisSlopeEnum enumSlope = (strOutputMeasurement == "DEGREE") ? esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopeDegrees :
		esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopePercentrise;
	IGeoDataset outSlopeDataset = pSurface.Slope(inputGeoDataset, enumSlope, zFactor);
	//输出坡度数据
	ISaveAs pSlopeSaveAs = outSlopeDataset as ISaveAs;
	string outputSlopeName = demFile.Parent.Name.ToUpper() +"SLP";
	//string outputSlopeName = demFile.Parent.Name + "SLP.tif";

	if (System.IO.File.Exists(System.IO.Path.Combine(outputFolder, outputSlopeName)))
	{
		IRasterDataset oldRasterDataset = (pWorkspace as IRasterWorkspace).OpenRasterDataset(outputSlopeName);
		(oldRasterDataset as IDataset).Delete();
	}
	IDataset solpeDataset = pSlopeSaveAs.SaveAs(outputSlopeName, pWorkspace, "GRID");
	//IDataset solpeDataset = pSlopeSaveAs.SaveAs(outputSlopeName, pWorkspace, "TIFF");
	IRasterDataset solpeRasterDataset = solpeDataset as IRasterDataset;
	if (solpeRasterDataset != null)
	{
		solpeRaster = solpeRasterDataset.CreateDefaultRaster();
	}

	System.Runtime.InteropServices.Marshal.ReleaseComObject(outSlopeDataset);
	System.Runtime.InteropServices.Marshal.ReleaseComObject(solpeRasterDataset);
	return solpeRaster;
}


2)坡向分析

private void ProduceAspectData(DirectoryInfo demFile, string outputFolder, IGeoDataset inputGeoDataset, IWorkspace pWorkspace)
{
	ISurfaceOp pSurface = new RasterSurfaceOpClass();
	IGeoDataset outAspectDataset = pSurface.Aspect(inputGeoDataset);
	ISaveAs pAspectSaveAs = outAspectDataset as ISaveAs;
	
	string outputAspectName = demFile.Parent.Name.ToUpper() + "SPD";
	//string outputAspectName = demFile.Parent.Name + "SPD.tif";
	string outputAspectFilePath = System.IO.Path.Combine(outputFolder, outputAspectName);
	if (System.IO.File.Exists(outputAspectFilePath))
	{
		IRasterDataset oldRasterDataset = (pWorkspace as IRasterWorkspace).OpenRasterDataset(outputAspectName);
		(oldRasterDataset as IDataset).Delete();
	}
	IDataset aspectDataset = pAspectSaveAs.SaveAs(outputAspectName, pWorkspace, "GRID");
	//IDataset aspectDataset = pAspectSaveAs.SaveAs(outputAspectName, pWorkspace, "TIFF");
	
	System.Runtime.InteropServices.Marshal.ReleaseComObject(outAspectDataset);
	System.Runtime.InteropServices.Marshal.ReleaseComObject(aspectDataset);
}

3)重分类

private IRasterDataset ProduceSlopeZone(DirectoryInfo demFile, string outputFolder,
	IWorkspace pWorkspace, IRaster pInRaster)
{
	if (pInRaster == null)
	{
		m_richTxtBoxLog.SelectionColor = System.Drawing.Color.Red;
		m_richTxtBoxLog.AppendText("生成高程带数据失败!\r\n");
		return null;
	}
	IReclassOp pReclassOp = new RasterReclassOpClass();
	IGeoDataset pGeodataset = pInRaster as IGeoDataset;
	INumberRemap pNumRemap = new NumberRemapClass();
	IRasterStatistics pRasterStatistic = GetRasterStatistics(pInRaster);
	pNumRemap.MapRange(0, 2, 0);
	pNumRemap.MapRange(2, 3, 2);
	pNumRemap.MapRange(3, 5, 3);
	pNumRemap.MapRange(5, 6, 5);
	pNumRemap.MapRange(6, 8, 6);
	pNumRemap.MapRange(8, 10, 8);
	pNumRemap.MapRange(10, 15, 10);
	pNumRemap.MapRange(15, 25, 15);
	pNumRemap.MapRange(25, 35, 25);
	pNumRemap.MapRange(35, 45, 35);
	if (pRasterStatistic.Maximum > 45)
	{
		pNumRemap.MapRange(45, 90, 45);
	}
	IRemap pRemap = pNumRemap as IRemap;
	IRaster2 pOutRaster = pReclassOp.ReclassByRemap(pGeodataset, pRemap, false) as IRaster2;
	//保存
	ISaveAs pAspectSaveAs = pOutRaster as ISaveAs;
	string outputAspectName = demFile.Parent.Name.ToUpper() + "SPZA.tif";
	if (System.IO.File.Exists(System.IO.Path.Combine(outputFolder, outputAspectName)))
	{
		IRasterDataset oldRasterDataset = (pWorkspace as IRasterWorkspace).OpenRasterDataset(outputAspectName);
		(oldRasterDataset as IDataset).Delete();
	}
	IDataset aspectDataset = pAspectSaveAs.SaveAs(outputAspectName, pWorkspace, "TIFF");
	System.Runtime.InteropServices.Marshal.ReleaseComObject(pInRaster);
	return (aspectDataset as IRasterDataset);        
}

/// 
/// 获取栅格统计
/// 
/// 
/// 
private IRasterStatistics GetRasterStatistics(IRaster pRaster)
{
	if (null == pRaster)
		return null;

	IRasterBandCollection pRBandCol = pRaster as IRasterBandCollection;
	IRasterBand pRBand = pRBandCol.Item(0);
	if (pRBand.Statistics == null)
	{
		pRBand.ComputeStatsAndHist();
	}
	return pRBand.Statistics;
}

和栅格数据相关的GP工具箱

和栅格数据有关的工具箱:3D Analyst Tools 、Data Management Tools、Spatial Analyst Tools 等工具箱。

具体内容不在此赘述,有问题的可以留言。

如何去除栅格影像的黑边

参考博客:http://zhihu.esrichina.com.cn/?/question/6725

对于三波段进行RDB渲染的影像可以使用下面代码:

IRasterRenderer RR = RL.Renderer; 
IRasterRGBRenderer rasterRGBRenderer = null; 
if (RR is IRasterRGBRenderer) 
rasterRGBRenderer = RR as IRasterRGBRenderer; 
RR.Update(); 
rasterRGBRenderer.RedBandIndex = 0; 
rasterRGBRenderer.GreenBandIndex = 1; 
rasterRGBRenderer.BlueBandIndex = 2; 
IRgbColor rgb = new RgbColorClass(); 
rgb.NullColor = true; 
IRasterStretch2 RS = rasterRGBRenderer as IRasterStretch2; // IRasterStretch无法设置数组,需用2 
double background = 
{ 
0, 0, 0 
}; 
RS.Background = true; 
RS.BackgroundValue = background as object; 
RS.BackgroundColor = rgb as IColor; 
axMapControl1.Refresh();

对于单波段

IRasterRenderer RR = RL.Renderer;
IRasterStretchColorRampRenderer RSC = null;
if (RR is IRasterStretchColorRampRenderer)
RSC = RR as IRasterStretchColorRampRenderer;
RR.Update();
RSC.BandIndex = 0;
IRgbColor rgb = new RgbColorClass(); 
rgb.NullColor = true; 
IRasterStretch RS = RSC as IRasterStretch;
RS.Background = true;
RS.set_BackgroundValues(0);
RS.BackgroundColor = rgb as IColor;
axMapControl1.Refresh();

栅格函数的使用(待补充)

问题记录

  1. ArcGIS栅格裁剪-----裁剪前后的栅格颜色如何保持一致

本文书写参考内容:
1)官方帮助文档
2)个人项目经验
3)参考博客:arcengine栅格数据使用总结
4)相关文档资料:CSDN下载-》ArcEngine 栅格数据总结.ppt

你可能感兴趣的:(ArcEngine,ArcEngine那些事)