下面要講的種重分類方法,網上很多。但是好像 System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array;這一句一直報下面的錯誤。我還沒有解決。
不過還是將這種方法整理一下,轉載自此。
作者本人的初步的解決方法為:
將 pSafeArray.GetValue(x, y) 替換為 pPixelBlock.GetVal(0, c_x, r_y)。 同時避免了“System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array”的異常問題。該問題很有可能為內部調用 MemoryStream 的 set_Capacity 時,在申請新內存時失敗,可能是需要存儲到ViewState中的內容太過龐大,或者可用內存太少。導致嘗試將數據序列化寫入ViewState時內存溢出。
下面為正文
--------------------------
柵格重分類方法很多,在AE中有多種方式可以實現,使用地圖代數(在RasterModel中實現),或者IReclassOp,或者Geoprocessor的方式都可以,甚至可以遍歷柵格來實現,這是最原始的方式,不過也可能是最實用的。這里使用的是最原始的遍歷柵格的方式。
private void reclass(IRaster pRaster, float weight) { IRasterProps rasterProps = (IRasterProps)pRaster; //設置柵格數據起始點 IPnt pBlockSize = new Pnt(); pBlockSize.SetCoords(rasterProps.Width, rasterProps.Height); //選取整個范圍 IPixelBlock pPixelBlock = pRaster.CreatePixelBlock(pBlockSize); //左上點坐標 IPnt tlp = new Pnt(); tlp.SetCoords(0, 0); //讀入柵格 IRasterBandCollection pRasterBands = pRaster as IRasterBandCollection; IRasterBand pRasterBand = pRasterBands.Item(0); IRawPixels pRawRixels = pRasterBands.Item(0) as IRawPixels; pRawRixels.Read(tlp, pPixelBlock); //將PixBlock的值組成數組 System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array; for (int y = 0; y < rasterProps.Height; y++) { for (int x = 0; x < rasterProps.Width; x++) { //int value = Convert.ToInt32(pSafeArray.GetValue(x, y)); Byte value = Convert.ToByte(pSafeArray.GetValue(x, y)); if (value != 0) pSafeArray.SetValue((Byte)(value * weight), x, y); } } pPixelBlock.set_SafeArray(0, pSafeArray); //編輯raster,將更新的值寫入raster中 IRasterEdit rasterEdit = pRaster as IRasterEdit; rasterEdit.Write(tlp, pPixelBlock); rasterEdit.Refresh(); }
改變RasterLayer中DEM的值

public void ChangePixelValue(double xMax, double xMin, double yMax, double yMin,double[,] PixelChanged) { IRaster pRaster = thisRasterLayer.Raster; IRaster2 pRaster2 = pRaster as IRaster2; //地圖坐標轉換為圖中行列值 rowMax = pRaster2.ToPixelRow(yMin); rowMin = pRaster2.ToPixelRow(yMax); columnMin = pRaster2.ToPixelColumn(xMin); columnMax = pRaster2.ToPixelColumn(xMax); int Height = rowMax - rowMin + 1; int Width = columnMax - columnMin + 1; //按照需要的大小建立一個空的PixelBlock3 IPnt blocksize = new PntClass(); blocksize.SetCoords(Width, Height); IPixelBlock3 pPixelBlock3 = pRaster.CreatePixelBlock(blocksize) as IPixelBlock3; System.Array pixels = (System.Array)pPixelBlock3.get_PixelData(0); //為新建的PixelBlock賦值 try { for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { pixels.SetValue(Convert.ToByte(PixelChanged[i,j]), j, i); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } //把像素值賦予新建的PixelBlock3 pPixelBlock3.set_PixelData(0, pixels); //PixelBlock3應在的位置 blocksize.SetCoords(columnMin, rowMin); //改變的像素值寫入圖層 IRasterEdit pRasterEdit = pRaster as IRasterEdit; pRasterEdit.Write(blocksize, (IPixelBlock)pPixelBlock3); pRasterEdit.Refresh(); System.Runtime.InteropServices.Marshal.ReleaseComObject(pRasterEdit); }
及將IRasterLayer存儲起來的方法
public static void SaveRasterLayerTofile(IRasterLayer pRasterLayer, string fileName, string strFileExtension="TIFF") { IRaster pRaster = pRasterLayer.Raster; IRaster2 pRaster2 = pRaster as IRaster2; ISaveAs pSaveAs = pRaster2 as ISaveAs; pSaveAs.SaveAs(fileName, null, strFileExtension); }
參考文章: