天天看點

C#+AE分區統計像元數量

因為近期需要進行對某一區域内進行像元數量的統計,而Arcgis内置的分區統計功能輸出的又是一個栅格資料感覺不是我想要的,是以就自己編了這樣一個小功能。話不多說,開始進入正題。

一、設計思路

按照老習慣,每次要編代碼之前先梳理一下思路:

1、擷取栅格資料和矢量資料(栅格資料是要統計的對象,矢量資料是統計的區域)

2、擷取矢量資料中要素的包絡範圍(IEnvelope)并以此建立像素塊(IPixelBlock)用來存儲包絡範圍内栅格資料的像元值

3、周遊矢量資料中的要素根據判斷條件來統計像元個數

4、顯示輸出結果

二、功能的實作

1、定義全局變量

long pixCount = 0;   //記錄像元的個數
double xmin, ymin, xmax, ymax;  //記錄地理坐标範圍
int RowMin, ColumnMin, RowMax, ColumnMax;    //記錄像元坐标範圍
double GeoX, GeoY;   //地理坐标
int red,green,blue;
           

2、擷取輸入資料

//擷取栅格圖層
IRasterLayer rasterLayer = GetLayer(comboBox1_StaticFile.Text) as IRasterLayer;
IRaster raster = rasterLayer.Raster;
IRaster2 raster2 = raster as IRaster2;//建立栅格資料
           
//擷取矢量圖層
IFeatureLayer featureLayer = GetLayer(comboBox2_StaticZone.Text) as IFeatureLayer;
IFeatureCursor cursor = featureLayer.Search(null, false);   //矢量遊标
IFeature feature = cursor.NextFeature();
IPoint point = new PointClass();
           

3、周遊矢量資料中的要素,并統計各個要素内滿足條件的像元個數

while (feature != null)
{
     IPolygon polygon = feature.Shape as IPolygon;

     //擷取目前矢量範圍IEnvelope行列号範圍,ColMin,ColMin,ColMax,RowMax
     IEnvelope envelope = feature.Extent;
     envelope.QueryCoords(out xmin, out ymin, out xmax, out ymax);
     raster2.MapToPixel(xmin, ymin, out ColumnMin,out RowMax);
     raster2.MapToPixel(xmax, ymax, out ColumnMax,out RowMin);

     //定義像素塊的尺寸
     IPnt size = new PntClass();
     size.X = Math.Abs(ColumnMax - ColumnMin);       //像素塊中的每一個像元都對應着栅格圖中的一個點
     size.Y = Math.Abs(RowMax - RowMin);             //像素塊隻需要足夠大就可以達到目的

     //建立像素塊
     IPixelBlock pb = raster.CreatePixelBlock(size);

     //定義像素塊起始位置坐标
     IPnt orginPoint = new PntClass();
     orginPoint.SetCoords(ColumnMin, RowMin);

     //讀取資料到像素塊中
     raster.Read(orginPoint, pb);
     IPixelBlock3 pb3 = pb as IPixelBlock3;

     //判斷點與面之間的關系器
     IRelationalOperator pRelOpt = polygon as IRelationalOperator;

     //周遊每一個像元
     for (int i = ColumnMin; i < ColumnMax; i++)
     {
         for (int j = RowMin; j < RowMax; j++)
         {
             raster2.PixelToMap(i, j, out GeoX, out GeoY);
             point.PutCoords(GeoX, GeoY);
             //擷取像元值
             red = Convert.ToInt32(pb3.GetVal(0,i-ColumnMin,j-RowMin));
             green = Convert.ToInt32(pb3.GetVal(1, i - ColumnMin, j - RowMin));
             blue = Convert.ToInt32(pb3.GetVal(2, i - ColumnMin, j - RowMin));

             if (pRelOpt.Contains(point) && green > 50) //判斷條件
             {
                 pixCount++;
             }
         }
     }

     MessageBox.Show("像元個數:" + pixCount.ToString());
     pixCount = 0;
     feature = cursor.NextFeature();
 }
           

三、實驗的效果和小結

C#+AE分區統計像元數量

小結:既然經曆了這個過程,就要總結一下在這中間所遇到的問題,要不然就白痛苦了哈哈。

1、IPixelBlock的建立是通過栅格資料的CreatePixelBlock函數來建立的,像素塊的尺寸通過IPnt來确定

2、在将資料讀取到像素塊中起始的坐标也是通過IPnt來确定

3、判斷點線面的關系可以使用IRelationalOperator接口