arcengine-栅格数据详解

打开栅格数据工作空间

//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);
创建栅格数据集
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;
    }
}

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

读取栅格数据属性(官方文档)
主要用到的接口:
IRasterProps
IRasterBandCollection
IRasterDataset
IRasterPyramid3
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);
}

//如何监听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渲染,必须为多波段影像
主要用到的接口:
IRasterLayer
IRasterRenderer
示例代码暂时略,有问题的同学可以留言。这块想着以后有时间的话以新帖子总结,顺便将色带总结了。
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);        
}

/// <summary>
/// 获取栅格统计
/// </summary>
/// <param name="pRaster"></param>
/// <returns></returns>
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();
ArcGIS Engine栅格数据使用总结 ArcOjects 3D开发方法简介 作者:佚名 文章来源:GIS论坛 点击数:861 更新时间:2009-8-6 一、ArcOjects 3D开发方法简介 众所周知,在ArcGIS 3D分析扩展模块中提供了丰富的三维可视化和分析功能:你可以通过不同的视角查看表面数据,对表面数据进行查询,以及对表面数据进行坡度、坡向、视域分析等操作,进行三维动画模拟等等。其中所涉及的3D对象都是ArcObjects的一部分,针对3D的开发,实际上是ArcObjects的开发,所以具体的开发方法有: 基于ArcScene中内嵌的VBA开发; 通过VB、VC++等兼容COM的开发语言进行开发新的3D组件和功能。 二、基本的3D对象模型 在3D开发中,我们可以用ArcMap对应ArcScene,其中MxDocument对象对应SxDocument对象,Map对象对应着Scene对象,而相对于Display显示对象,在ArcScene中有SceneGraph对象。在对象模型图的顶部是Application对象,从它我们可以执行和应用相关的任务,比如打开文档或者访问和应用相关的其它对象。在VBA中,我们可以直接获得Application对象: Dim pApp as IApplicaiton Set pApp = Application 如果你在VB DLL中实现命令和工具,那么在具体实例化这个类时你可以获得和Application对象挂接的钩子(hook): Implements ICommand Private m_pApp as esriCore.Iapplication Private Sub ICommand_OnCreate(ByVal Hook As Object) Set m_pApp = Hook … End Sub 有了Application对象,你就可以访问它所包含的其它所有对象了。比如可以获得SxDocument对象,而它包含一个Scene对象,Scene对应的SceneGraph对象包含了一个或多个SceneViewer对象,每个SceneViewer对象中有一个Camera对象,它代表了观察点的特性。在Scene对象中可以访问Layer对象和GraphicsLayer3D对象,这两个对象都包含着一个3DProperties对象,用来控制图层中有关三维方面的特性。具体有关对象的特性可以参考联机帮助中对象上提供的接口所属的方法和属性。 三、3D几何模型和定制对象介绍 3D模型可以包括两种:矢量模型和表面模型,表面模型包括TIN和Raster,有关表面模型的创建、数据结构访问和分析在本文中不做介绍。在此只介绍三维矢量模型的生成和访问等。3D矢量模型包括所有含有Z值的几何对象:点、线、面,以及MultiPatch(多片)。其中多片又可以分为:三角条带(Triangle Strip)、三角扇(Triangle Fan)和环(Ring)。 在ArcScene中可以通过二维的点、线、面数据来构建三维模型,通过ArcScene中提供的拉伸功能可以将点要素构建成垂直的线,线要素构建成墙,而多边形要素构建成块,拉伸的值的大小可以是一定常数,也可以是通过要素属性字段中的值计算得出,或者通过数据自身记录的Z值。在ArcObjects中可以通过在Geometry几何对象构建过程中,任意点除了X、Y坐标值,指定坐标Z值来构建三维点、线和面对象;对于多片,则通过构建相应的Multipatch对象,并指定每一个顶点的X、Y和Z值。下面的代码描述了如何由多片来构建一个房子对象,它的房顶由三角扇构建,没有窗户的墙由三角条带构建,带窗户的墙由环构建。 Dim pMultiPatch As esriCore.IMultiPatch Set pMultiPatch = New MultiPatch Dim pGeoCol As esriCore.IGeometryCollection Set pGeoCol = pMultiPatch Dim pPoints As esriCore.IPointCollection Dim pPoint As IPoint ‘创建屋顶 Set pPoints = New esriCore.TriangleFan Set pPoint = New Point pPoint.PutCoords 5, 4 pPoint.Z = 10 pPoints.AddPoint pPoint Set pPoint = New Point pPoint.PutCoords 0, 0 pPoint.Z = 5 pPoints.AddPoint pPoint ‘屋顶的其它顶点: . . . (10, 0, 5); (10, 8, 5); ( 0, 8, 5); ( 0, 0, 5) ‘将扇加到MultiPatch pGeoCol.AddGeometry pPoints ‘为没有窗户的墙创建条带 Set pPoints = New esriCore.TriangleStrip ‘添加条带顶点: . . . (10, 0, 5); (10, 0, 0); (10, 8, 5) . . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0) . . . ( 0, 0, 5); ( 0, 0, 0) ‘将条带添加到MultiPatch pGeoCol.AddGeometry pPoints ‘为前面的墙创建外环 Set pPoints = New esriCore.Ring ‘添加外环顶点: . . . (10, 0, 5); (10, 0, 0); (10, 8, 5) . . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0) . . . ( 0, 0, 5); ( 0, 0, 0) ‘将外环添加到MultiPatch pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchOuterRing ‘为前面的墙创建内环 Set pPoints = New esriCore.Ring ‘添加内环顶点: . . .(1, 0, 2);(3, 0, 2);(3, 0, 4);(1, 0, 4);(1, 0, 2) pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing Set pPoints = New esriCore.Ring ‘添加内环顶点: . . .(7, 0, 2);(9, 0, 2);(9, 0, 4);(7, 0, 4);(7, 0, 2) pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing ‘设置Z和M坐标awareness Dim pZAware As esriCore.IZAware Set pZAware = pMultiPatch pZAware.ZAware = True Dim pMAware As esriCore.IMAware Set pMAware = pMultiPatch pMAware.MAware = False 通常,多片是用来描述阴影平面集合,并且可以在其上粘贴影像,也就是贴图。为了粘贴影像,需要在Multipatch的每一个定点上记录纹理坐标。纹理坐标记录为s和t,值为0到1,表示了从x到y方向影像的起点到终点。在ArcObjects中将s和t编码存储在定点的M值中。另外,如果要用Multipatch表达复杂连续的几何对象,比如球体,为了平滑阴影平面之间的转折,需要在Multipatch的每一个顶点上记录它的法向量,同样法向量也是编码后存储在定点的M值中。如下面的代码: Dim pNormal As esriCore.IVector3D Dim pVertex As esriCore.Ipoint Dim m As Double m = 0 . . . Dim pEncoder As IEncode3DProperties Set pEncoder = New GeometryEnvironment pEncoder.PackNormal vNormal, m pEncoder.PackTexture2D s, t, m pVertex.M = m 四、3D渲染和动画功能定制简介
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值