ArcObjects中IMapAlgebraOp的使用体会

本文提供使用IMapAlgebraOp接口实现大部分栅格计算的简单方法。

1.首先,ArcObjects提供了很多关于栅格计算的方法,有条件运算、逻辑运算及数学表达式,如下:

ArcObjects中IMapAlgebraOp的使用体会_第1张图片   ArcObjects中IMapAlgebraOp的使用体会_第2张图片   ArcObjects中IMapAlgebraOp的使用体会_第3张图片      等等....

 

开发的过程中如果为每个计算都写一个方法,那实在是太累了,而且还不如手动在ArcMap里面点击工具,说到工具,想起ArcToolbox的Map Algebra/Raster Calculator可以实现大部分栅格相关的运算。

Raster Calculator工具界面

ArcObjects中IMapAlgebraOp的使用体会_第4张图片

 

 通过界面发现,不仅有简单的+ - * /、逻辑后面的框里面还有大量函数,功能很强大。那就看看ArcObjects提供的相应接口吧 !

 

找到IMapAlgebraOp Interface,

ArcObjects中IMapAlgebraOp的使用体会_第5张图片

 可怜的三个方法,能支持大部分运算吗?

阅读一下方法说明,

BindRaster,两个参数IGeoDataset geoDataset,String symbol,把geoDataset绑定到symbol,即给栅格数据起别名,方便使用

UnbindRaster,取消绑定

Execute,只有一个string类型参数,但这个参数可以是任意符合Map Algebra的表达式!也就是可以执行很多上面的运算。

强大的东西有种简洁的美。

2.牛刀小试

创建一个MapAlgebra方法,接收三个参数:一个IGeoDataset栅格数据pGeoDataset,一个string的别名symbol,一个string的表达式expression;

功能:把pGeoDataset绑定到symbol,执行expression,取消绑定,返回执行结果。

 1 public static IGeoDataset MapAlgebra(IGeoDataset pGeoDataset, string symbol, string expression)
 2         {
 3             try
 4             {
 5                 IMapAlgebraOp pMapAlgebraOp = new RasterMapAlgebraOp() as IMapAlgebraOp;
 6                 pMapAlgebraOp.BindRaster(pGeoDataset, symbol);
 7                 IGeoDataset resDataset = pMapAlgebraOp.Execute(expression);
 8                 pMapAlgebraOp.UnbindRaster(symbol);
 9                 return resDataset;
10             }
11             catch (Exception e)
12             {
13                 throw e;
14             }
15         }

调用,对一个栅格数据执行Int运算:

1 IGeoDataset pGeoDatasetInt = GeoAnalyst.MapAlgebra(pGeoDataset, "inRaster", "Int([inRaster])");

说明:表达中需要用" [ ] " 把symbol括起来。

再试一个 “ * ” 乘法运算:

1 IGeoDataset pGeoDatasetTimes = GeoAnalyst.MapAlgebra(pGeoDatasetTimes, "inRaster", "[inRaster]*100");

运行,报错  ERROR 010316: Unable to open the input raster

 查找既没发现文件占用,也没发现表达式有问题,在ArcMap里面同样的计算也能执行,最后经多方查找发现操作符前后需要留有空格,也即是如下:

1 IGeoDataset pGeoDatasetTimes = GeoAnalyst.MapAlgebra(pGeoDatasetTimes, "inRaster", "[inRaster] * 100");

至此,完美解决。

等等,如果有多个栅格输入呢,总不能一直增加参数个数吧。其实,栅格增加一个,symbol增加一个,expression的数量还是一个,

可以构建一个实体,包含栅格和symbol两个属性,把他们放入一个列表中,这样就可以应对多个栅格数据的情况了。

修改MapAlgebra方法如下:

 1 public static IGeoDataset MapAlgebra(List pDatasetWithSymbolList, string expression)
 2         {
 3             try
 4             {
 5                 IMapAlgebraOp pMapAlgebraOp = new RasterMapAlgebraOp() as IMapAlgebraOp;
 6 
 7                 foreach (DatasetWithSymbol item in pDatasetWithSymbolList)
 8                 {
 9                     pMapAlgebraOp.BindRaster(item.PGeoDataset, item.Symbol);
10                 }
11                 IGeoDataset resDataset = pMapAlgebraOp.Execute(expression);
12                 foreach (DatasetWithSymbol item in pDatasetWithSymbolList)
13                 {
14                     pMapAlgebraOp.UnbindRaster(item.Symbol);
15                 }
16                 return resDataset;
17             }
18             catch (Exception e)
19             {
20                 throw e;
21             }
22         }

它接收一个包含栅格和symbol两个属性的实体列表,循环做BindRaster,执行后再UnbindRaster。

实体如下:

 1 public class DatasetWithSymbol
 2     {
 3         public DatasetWithSymbol(IGeoDataset pGeoDataset, string symbol)
 4         {
 5             this.pGeoDataset = pGeoDataset;
 6             this.symbol = symbol;
 7         }
 8 
 9         IGeoDataset pGeoDataset;
10         string symbol;
11 
12         public IGeoDataset PGeoDataset
13         {
14             get
15             {
16                 return pGeoDataset;
17             }
18 
19             set
20             {
21                 pGeoDataset = value;
22             }
23         }
24 
25         public string Symbol
26         {
27             get
28             {
29                 return symbol;
30             }
31 
32             set
33             {
34                 symbol = value;
35             }
36         }
37     }

使用方法如下:

1 DatasetWithSymbol pDatasetWithSymbol = new DatasetWithSymbol(pRasterDataset as IGeoDataset, "inRaster");
2 List pDatasetWithSymbolList = new List();
3 pDatasetWithSymbolList.Add(pDatasetWithSymbol);
4 IGeoDataset pGeoDatasetTimes = GeoAnalyst.MapAlgebra(pDatasetWithSymbolList, "[inRaster] * 100");

这样只要表达式配合好,添加多个栅格都不成问题。

 

结束,欢迎留言交流~  

 

你可能感兴趣的:(ArcObjects中IMapAlgebraOp的使用体会)