ArcObjects SDK開發 011 RasterLayer

mytudousi 發表於 2022-12-05

1、RasterLayer的結構

圖層的話,除了FeatureLayer外,用的最多的就是RasterLayer了。較FeatureLayer而言,RasterLayer比較簡單,這點可以從柵格圖層的屬性對話方塊中可以看出。

image1.png

其中General選項卡對應著RasterLayer繼承實現的ILayerGeneralProperties介面,Source選項卡對應IRasterLayer的Ratser屬性,Display選項卡對應著ILayerEffects介面,Symbology選項卡對應著IRasterLayer的Renderer屬性。

2、IRaster介面

IRasterLayer的Raster屬性返回的是IRaster介面型別。其指的是實際的柵格資料來源,我們一般儲存為tif或者img檔案。Raster類實現了IRaster介面,同時Raster還繼承了以下介面。

image2.png

其中透過IRaster可以分塊讀取柵格資料的像元資訊,並可以設定重取樣方式。IRaster2介面提供了一些畫素與地圖座標相互轉換的函式。IRasterBandCollection介面可以讀取柵格資料包含的波段資訊。IRasterEdit介面提供了修改柵格資料像元值的功能。IRasterProps提供了柵格資料的屬性資訊。ISaveAs介面提供了柵格資料的儲存功能。

不過我們一般很少用IRaser介面去修改柵格資料,主要還是靠呼叫ArcToolbox裡面的工具來處理。

3、IRasterRenderer介面

該介面為柵格圖層渲染介面,透過RasterLayer的Renderer可以獲取或設定。繼承該介面的類如下圖所示。

image3.png

其中我們常用的有RasterClassifyColorRampRenderer,分級別渲染,例如顯示某個區域內的人口密度資料的柵格資料檔案,就可以按照不同的顏色進行分段顯示。

RasterUniqueValueRenderer,唯一值渲染,例如土地分類資料,就可以把耕地、林地、草地、城市用地等按照不同的顏色顯示。

RasterStretchColorRampRenderer,拉伸渲染,一般我們顯示Dem資料的時候都會使用這種渲染方式。

每種渲染方式如何設定,都可以參考ArcMap中的引數設定介面以及SDK幫助。

4、開啟柵格資料

我們常用的柵格資料主要有tif和img格式。開啟柵格資料有多種方法,我習慣用RasterLayer的CreateFromFilePath函式開啟柵格資料,這這種方式比較簡單。程式碼如下。

var myRasterLayer = new RasterLayerClass();
myRasterLayer.CreateFromFilePath(this.DEMFilePath);

5、建立柵格資料檔案

我們可以使用IWorkSpace來建立柵格資料檔案。

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

我們一般建立的時候,會呼叫ArcToolbox中的工具去建立。