ArcGIS 柵格函數在線調用詳解

ArcGIS 柵格函數在線調用詳解

導讀:ArcGIS從10.0版本開始引用鑲嵌數據集,並且第一次在影像中加入柵格函數(raster functions),使得影像的呈現和信息提取與GIS緊密的結合起來,簡單的影像功能都可以在ArcGIS中實現(當然了,如果是專業的影像處理,還是建議在ENVI這類專業的遙感軟件下進行)。ArcGIS軟件向來注重一體化,因此,在桌面軟件ArcMap中實現的功能都會逐漸遷移到服務器中。本文着重從桌面端功能介紹轉移到服務器端及Web開發,旨在說明ArcGIS軟件的柵格函數技術路線。 BY 李遠祥

ArcMap中的柵格函數調用

在ArcMap中可以對任何影像格式,包括柵格數據集、柵格目錄和鑲嵌數據集。在菜單欄–【窗口】–【影像分析】中可以調出影像分析面板,如下圖所示

2017-08-04-16-50-59

影像分析面板可以實現常見的圖像處理功能,如果是熟悉Photoshop等軟件,那就會發現一些非常數據的名詞,如對比度、亮度、透明度、銳化、平滑、交互式拉伸等。但其最大的特色是柵格函數,隨着每個版本的更新,柵格函數會逐漸增加。

在【影像分析】面板中選中影像數據之後,可以找到柵格函數的入口,包含了非常多的處理函數,如下圖所示

2017-08-04-16-56-36

這些函數不同於ToolBox工具,Toolbox工具的特點就是每處理完一次都會生成一個新的柵格數據作爲結果,整個過程會進行影像計算、重採樣等,並佔單獨佔用存儲,一般處理時間比較長。柵格函數的性質是動態處理,函數與柵格數據的關係是引用關係,有點類似於PS裏面的濾鏡。在引用函數調用的時候不會生成新的數據,ArcMap會根據函數的設定動態對影像進行渲染,而且性能相當高。同時函數也是可以進行相互疊加的。

例如下圖針對Landsat數據進行波段提取,提取第四波段。可以在柵格函數中直接使用【波段提取函數】,如下圖

2017-08-04-17-02-07

2017-08-04-17-02-41

將波段組合設置爲4,結果即馬上生成一個動態的渲染圖層,至顯示第四波段數據,如下圖所示

2017-08-04-17-04-03

如果是DEM數據,柵格函數還支持如坡度、坡向、山體陰影等操作。如下圖就是對DEM進行的山體陰影的操作。

2017-08-04-17-10-16

imageserver 中的影像

將影像發佈爲影像服務,同樣也支持柵格函數。影像服務發佈需要ArcGIS Server 的imageserver 授權。柵格數據集、柵格目錄和鑲嵌數據集都支持直接發佈爲影像服務。在ArcMap的目錄中右鍵選擇影像,可以將其發佈成影像服務,如下圖:

2017-08-04-17-13-52

影像服務的發佈過程與一般的地圖服務Mapservice的嚮導類似,不過在其服務設置方面有自己的特點,如下圖所示:

2017-08-04-17-15-16

通過rest地址訪問已發佈的影像服務,可以看到其影像服務的功能。其中一項就是柵格函數

2017-08-07-09-05-46

影像服務的調用與傳統的mapservice類似,不過採用的是 ArcGISImageServiceLayer 接口。調用代碼如下

        var map;
        require([
                    "esri/map",
                    "esri/layers/ArcGISImageServiceLayer",
                    "esri/layers/ImageServiceParameters",
                    "dojo/domReady!"],
                function(Map,ArcGISImageServiceLayer,ImageServiceParameters) {
                    map = new Map("mapDiv");												
                    var imgParams = new ImageServiceParameters();
                    imgParams.onData = 0;
					
                    var layerUrl = "http://localhost:6080/arcgis/rest/services/LC441821/ImageServer";
                    var imageServiceLayer = new ArcGISImageServiceLayer(layerUrl,{
                        imageServiceParameters:imgParams,
                        opacity:0.75
                    });
                    map.addLayer(imageServiceLayer);
                    map.centerAt([113.34, 23.51]);
                });

這裏除了使用接口加載影像服務之外,還使用了ImageServiceParameters 接口去設置影像服務的參數。例如上述代碼使用的 imgParams.onData = 0; 就是設置影像的onData 。

ImageServiceParameters 是非常重要的影像服務接口,它涉及到影像服務的多種設置,柵格函數的設置最終也會落在該接口對應的參數中。

ArcGIS JavaScript API 使用柵格函數

imageservice 支持直接在前端使用柵格函數來重新渲染影像服務。ArcGIS JavaScript API 中集成了柵格函數的調用接口–RasterFunction 。 RasterFunction 不能單獨使用,需要配合ArcGISImageServiceLayer和ImageServiceParameters 接口。

目前前端能支持的柵格函數類型不是特別多,從官方的在線幫助可以看到其具體能支持的類型和數量。支持的柵格函數可以訪問此處 。下圖是前端支持的柵格函數

2017-08-07-09-41-36

2017-08-07-09-47-11

ArcGIS在10.0版本之後每一個版本都加入了新的柵格函數,如上圖顯示的信息。所以在前端調用柵格函數之前,先要查詢一下當前的ArcGIS Server 版本是否支持對應的柵格函數。

筆者建議在使用 JavaScript API 調用柵格函數之前,先在ArcMap中走通其流程,並針對結果進行。例如前面所說的提取影像的第四波段。

下面例子是使用JS API 調用波段提取函數。

        var map;
        require([
                    "esri/map",
                    "esri/layers/ArcGISImageServiceLayer",
                    "esri/layers/ImageServiceParameters",
                    "dojo/domReady!"],
                function(Map,ArcGISImageServiceLayer,ImageServiceParameters) {
                    map = new Map("mapDiv");					
					var rasterFunction = new esri.layers.RasterFunction();
					rasterFunction.functionName = "ExtractBand";
					
					var functionArguments = {};
					functionArguments.BandIDs= [4]									   
					rasterFunction.functionArguments = functionArguments;				   
					rasterFunction.variableName = "Raster";	
					
                    var imgParams = new ImageServiceParameters();
                    imgParams.onData = 0;
					imgParams.renderingRule=rasterFunction;
					
                    var layerUrl = "http://localhost:6080/arcgis/rest/services/LC441821/ImageServer";
                    var imageServiceLayer = new ArcGISImageServiceLayer(layerUrl,{
                        imageServiceParameters:imgParams,
                        opacity:0.75
                    });
                    map.addLayer(imageServiceLayer);
                    map.centerAt([113.34, 23.51]);
                });

效果如下圖所示

2017-08-07-10-01-01

從代碼中可以看出,關鍵部分是使用了RasterFunction接口,要調用什麼樣的函數,需要在 functionName 中設置其柵格函數名稱。柵格函數的參數每個都不一樣,這個就必須查看在線幫助了。例如波段提取函數名稱爲 ExtractBand ,在在線幫助中點擊該名稱,則跳轉到它的參數說明和調用樣例。如下圖所示

2017-08-07-10-04-59

通過對應的參數來定義柵格函數的參數 functionArguments ,其中關鍵字部分是需要對應幫助說明的每一個參數名稱。

例如將該LandSat影像服務設置爲假彩色顯示,可以通過提取波段函數進行參數的修改,如下圖所示,將波段組合修改之後

2017-08-07-10-11-10

在頁面端可以直接調用出來,如下圖

2017-08-07-10-12-39

通過上述例子可以看出,柵格函數的使用是極其簡單的。Esri 官方幫助提供了非常詳細的接口說明。不過礙於都是英文,所以,筆者建議是先將ArcMap切換爲英文版,在英文版上進行前期的函數調用,查看結果。英文版的ArcMap中的柵格函數名稱是跟JS API 中的名稱是完全對應的。

柵格函數模版

前面的內容旨在說明柵格函數的桌面使用和Web端調用。通過ArcMap的操作,很多人可能已經看到,柵格函數是可以疊加使用的。這種疊加在前端API可以照搬。不過如果疊加的函數比較多,就需要編寫比較長的代碼。

還有一種情況,ImageServer 中提供的柵格函數前端接口沒有ArcMap的那麼多,如果需要調用一些桌面端具備的接口,而目前前端還沒提供的柵格函數,那就需要在服務器端配置柵格函數模版。

可以看看Esri官方幫助上調用的自定義的柵格函數,其渲染效果相當不錯。這種效果在前端API是無法實現的。

2017-08-07-10-23-50

柵格函數模版需要在ArcMap中進行設計,其設計到柵格函數的調用和結果的渲染。

先說說前端渲染,目前ArcGIS JavaScript API 能支持的前端渲染是colorMap方式,就是類似柵格數據分類渲染,其構建方式如下

 [[0,175,240,233],[3,175,240,222]]

這種方式構建爲數組,第一個數組值是柵格象元值,後面三個數值分別爲RGB值。定義比較麻煩,需要對所用的象元值都給頂一個RGB值才能實現前端渲染。例如下面構建一個非常龐大的 colorMap 。

var colorMap = [[0,175,240,233],[3,175,240,222],[7,177,242,212],
          [11,177,242,198],[15,176,245,183],[19,185,247,178],[23,200,247,178],
          [27,216,250,177],[31,232,252,179],[35,248,252,179],[39,238,245,162],
          [43,208,232,135],[47,172,217,111],[51,136,204,88],[55,97,189,66],
          [59,58,176,48],[63,32,161,43],[67,18,148,50],[71,5,133,58],[75,30,130,62],
          [79,62,138,59],[83,88,145,55],[87,112,153,50],[91,136,158,46],[95,162,166,41],
          [99,186,171,34],[103,212,178,25],[107,237,181,14],[111,247,174,2],
          [115,232,144,2],[119,219,118,2],[123,204,93,2],[127,191,71,2],[131,176,51,2],
          [135,163,34,2],[139,148,21,1],[143,135,8,1],[147,120,5,1],[151,117,14,2],[155,117,22,5],
          [159,115,26,6],[163,112,31,7],[167,112,36,8],[171,110,37,9],[175,107,41,11],
          [179,107,45,12],[183,105,48,14],[187,115,61,28],[191,122,72,40],[155,117,22,5],
          [159,115,26,6],[163,112,31,7],[167,112,36,8],[171,110,37,9],
          [175,107,41,11],[179,107,45,12],[183,105,48,14],[187,115,61,28],[191,122,72,40],
          [155,117,22,5],[159,115,26,6],[163,112,31,7],[167,112,36,8],[171,110,37,9],
          [175,107,41,11],[179,107,45,12],[183,105,48,14],[187,115,61,28],[191,122,72,40],
          [195,133,86,57],[199,140,99,73],[203,148,111,90],[207,153,125,109],
          [213,163,148,139],[217,168,163,160],[223,179,179,179],[227,189,189,189],
          [231,196,196,196],[235,207,204,207],[239,217,215,217],[243,224,222,224],
          [247,235,232,235],[251,245,242,245],[255,255,252,255]];				

在柵格函數設置的時候,可以指定渲染方式,例如

functionArguments.Colormap = colorMap;

這種方式構建工作量巨大,而且沒有任何的界面設計器可用。目前還沒有前端接口支持拉伸方式渲染,例如桌面端的【渲染地貌函數】採用的色帶配置。

2017-08-07-10-38-28

這些都需要在服務器端來柵格函數模版。

首選需要在ArcMap中調用【柵格函數模版編輯器】對柵格函數進行配置。在ArcMap菜單欄【窗口】–【自定義】面板中,選擇【命令】標籤,輸入關鍵字【柵格】,找到【柵格函數模版編輯器】,將其拖動到菜單的工具條任意位置即可使用

2017-08-07-10-42-10

2017-08-07-10-45-10

從圖上可以看到,其界面與【影像】面板中調用的柵格函數的方式非常類似。但它有自己非常獨特的地方,多了一個【文件】菜單,可以將設計好的影像分析流程保存下來。如下圖所示

2017-08-07-10-46-46

筆者做了一個例子,使用DEM數據進行地形渲染。【渲染地貌函數】並不在前端柵格函數的支持範圍,其顯示的渲染效果是拉伸方式,前端api同樣不支持。這個例子很好的反映出服務器中柵格函數模版的重要性。

針對dem數據在【柵格函數模版編輯器】中使用【渲染地貌函數】,並且設計好結果的渲染方式。

2017-08-07-10-50-30

設置好後,在【柵格函數模版編輯器】的【文件】菜單中【另存爲】將其保存在rft.xml 文件。例如,筆者這裏將配置好的模版另存名稱爲 customfun.rft.xml

此處一定要使用英文名稱。因爲該模版一旦被導入到imageservice中,其調用名稱與文件名稱對應。中文名稱在調用的時候rest路徑會出現一些特殊的符號,導致瀏覽器請求失敗。所以一定要使用英文。

配置柵格函數模版可以在兩種情況下進行。第一種是在影像服務發佈的時候進行導入,在服務編輯器的【函數】項中設置,如下圖所示,點擊【管理】,在管理面板中加入一個或者多個柵格函數模版。

2017-08-07-10-57-34

注意:筆者這裏使用的模版存放在計算機桌面中,可以通過截圖看清楚。在影像服務發佈的時候指定柵格函數模版,無論柵格函數模版文件放在什麼目錄下,都能識別,因爲arcgis server 最終會將這個模版文件拷貝到服務器能訪問的目錄中。

點擊【確定】併發布影像服務,柵格函數模版會隨着服務發佈註冊到對應的服務目錄中。下圖是從服務的屬性中重新查看其模版情況,可以看到這個模版已經自動被拷貝到arcgisserver註冊的目錄中

2017-08-07-11-02-30

另一種情況是向已經存在的影像服務註冊柵格函數模版,這稍微複雜一點,要先將模版文件拷貝到arcgis server 已註冊的文件目錄下,不然imageserver 無法訪問到對應的路徑,導致模版讀取失敗 ,如下圖

2017-08-07-11-04-15

然後停止對應的影像服務,在服務屬性對應的【函數】項目導入模版文件。導入後重啓對應的影像服務即可。

在瀏覽器中通過rest訪問對應的影像服務,點擊 rasterFunctionInfos 項,可以查看到對應的柵格函數模板的內容

2017-08-07-11-09-37

2017-08-07-11-12-31

從圖上可以看出,影像服務上多了一個以柵格函數模版文件名爲命名的自定義函數。這個函數名相當重要,在ArcGIS JavaScript API 的調用中需要使用到。

自定義柵格函數的調用與一般的調用方式沒有任何不一樣的地方,只需要在rasterFunction.functionName修改函數名稱即可。下面是調用自定義函數的代碼例子

        var map;
        require([
                    "esri/map",
                    "esri/layers/ArcGISImageServiceLayer",
                    "esri/layers/ImageServiceParameters",
                    "dojo/domReady!"],
                function(Map,ArcGISImageServiceLayer,ImageServiceParameters) {
                    map = new Map("mapDiv");	
					var rasterFunction = new esri.layers.RasterFunction();
					rasterFunction.functionName = "customfun";//自定義柵格函數					
					rasterFunction.variableName = "Raster";					
                    var imgParams = new ImageServiceParameters();
                    imgParams.onData = 0;
					imgParams.renderingRule=rasterFunction;
					
                    var layerUrl = "http://localhost:6080/arcgis/rest/services/dem/ImageServer";
                    var imageServiceLayer = new ArcGISImageServiceLayer(layerUrl,{
                        imageServiceParameters:imgParams,
                        opacity:0.75
                    });
                    map.addLayer(imageServiceLayer);
                    //map.centerAt([113.34, 23.51]);
                });

具體的效果如下圖所示

2017-08-07-11-18-45

利用柵格函數模版的方式可以將很多常用的柵格表達方式註冊到影像服務中,非常方便快速切換影像的顯示方式,而且柵格函數模版是可以複用的。

總結

柵格函數雖然在ArcGIS10.0之後的版本才提出來,並在每一個ArcGIS版本中逐步完善和增加功能。從技術路線上看,柵格函數模版的方式依然是主流的調用方式(儘管這種方式很早就在imageserver 中使用),但前端調用的接口也越來越完善,Esri也在進一步開放其前端功能。在當前影像數據獲取越來越便捷和廉價的情況下,影像的使用不僅僅是停留在瀏覽階段,分析功能和多種表達方式也是越來越重要了。

更多的GIS主流和非主流技術,可以持續關注CSDN的GIS製圖樂園,以及微信公衆號【GIS製圖樂園】。BY 李遠祥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章