最近常常碰到用戶諮詢如何在ArcGIS Server 10.1中對圖層進行渲染的問題!html
通常如下兩個情形我會推薦用戶在發佈服務時,啓用動態圖層。前端
業務需求1:web
在服務器端有圖層,想對這個圖層進行渲染,可是圖層的要素個數不少,若是經過web api 的形式,將圖層在前端以graphic的形式進行渲染的話,會很是慢!json
業務需求2:api
想對已經發布的地圖服務中添加圖層,新添加的圖層能以服務的形式對外暴露,能夠在客戶端像已經發布的服務同樣能夠有效的無級縮放!服務器
本文采用動態圖層對上面的兩個業務需求,進行實現!向已經發布的地圖服務中添加圖層,並對該圖層進行渲染實現!採用的環境爲ArcGIS Desktop 10.1和ArcGIS Server 10.1。ide
什麼是動態圖層測試
關於動態圖層(DynamicLayers)官方幫助中是如此介紹,地圖服務發佈到 ArcGIS Server 站點後,可根據須要選擇是否容許服務器的客戶端(如 ArcGIS web API)動態更改地圖服務中的圖層外觀和行爲。要肯定哪些圖層顯示在地圖中、圖層符號系統、圖層順序和位置以及標註等,可經過使用動態圖層在服務器端實現。這種方式下,動態圖層可有效增長用戶與地圖的交互。url
動態圖層實現步驟spa
STEP1:
在計算機目錄下面E:\data\vector的目錄下有個Coasts.shp 圖層(圖層ArcMap中打開如圖所示),將該圖層發佈爲服務,並將該圖層所在的該路徑註冊爲動態空間
圖1 發佈地圖服務目錄數據
圖2 發佈地圖服務的數據ArcMap中展現
STEP2:發佈服務,啓用動態圖層,註冊動態空間!如圖紅色方框中所示。
圖3 發佈服務啓用動態圖層選項
圖4 註冊動態空間
STEP4:添加圖層,向註冊的空間中添加圖層,並將添加的圖層,進行渲染在客戶端進行渲染顯示返回前端!
圖5 註冊的動態空間中添加文件
STEP5:測試Dynamic圖層是否發佈成服務成功。打開Coast.shp 發佈的地圖服務的Rest url,出現下圖的地圖服務信息,點擊Dynamic Layers,在對話框中輸入json串,字符串以下所示,dataSourceName中輸入剛添加到註冊空間中圖層Links,能夠得到圖層信息,如圖所示,這代表,新添加的圖層也發佈成服務了。
{ "source": { "type": "dataLayer", "dataSource": { "dataSourceName": "Links.shp", "workspaceId": "myDynamic", "type": "table" } }, "id": 9999 }
圖6 rest中獲取新添加的動態圖層 圖7 獲取的動態圖層的結果
經過上面的這些測試是能夠驗證新添加的圖層能夠對外暴露服務!
STEP6:在服務器段對動態圖層進行渲染,並將渲染結果返回到前端!
注意:目前動態圖層支持的渲染方式有限,只支持三種渲染 :Simple Render(簡單渲染);Unique Value Render(惟一值渲染);Class Breaks Render(分級渲染)
對發佈的地圖服務export map
圖8 請求導出圖片
在rest目錄下,有個dynamic layers輸入相關的渲染方案,json字符串的形式
圖 9 導出圖片時對動態圖層的渲染
{ "type": "simple", "symbol": { "type": "esriSMS", "style": "esriSMSCircle", "color": [255,0,0,255], "size": 5, "angle": 0, "xoffset": 0, "yoffset": 0, "outline": { "color": [0,0,0,255], "width": 1 } }, "label": "", "description": "" }
採用上面的簡單渲染方案,能夠出圖,這個圖片就是地圖服務返回前端去的圖片
圖10 簡單渲染方式在服務器段渲染完的結果
對dynamic layers參數設置不一樣的渲染方式的字符串能夠進行不一樣方式的渲染,下面爲分級渲染的json,根據圖層id分級渲染
[{ "id": 9997, "source": { "type": "dataLayer", "dataSource": { "type": "table", "workspaceId": "china400FileGDB", "dataSourceName": "province_poly" } }, "drawingInfo": { "renderer": { "type": "classBreaks", "field": "AREA", "minValue": 0, "classBreakInfos": [{ "symbol": { "type": "esriSFS", "color": [51, 102, 0, 255], "style": "esriSFSSolid", "outline": { "type": "esriSLS", "color": [28, 39, 44, 26], "width": 0.75, "style": "esriSLSSolid" } }, "label": "0 to 500", "classMaxValue": 9.9 }, { "symbol": { "type": "esriSFS", "color": [0, 153, 51, 255], "style": "esriSFSSolid", "outline": { "type": "esriSLS", "color": [28, 39, 44, 26], "width": 0.75, "style": "esriSLSSolid" } }, "label": "501 to 10,000", "classMinValue": 10, "classMaxValue": 16 }, { "symbol": { "type": "esriSFS", "color": [0, 204, 51, 255], "style": "esriSFSSolid", "outline": { "type": "esriSLS", "color": [28, 39, 44, 26], "width": 0.75, "style": "esriSLSSolid" } }, "label": "10,001 to 30,000", "classMinValue": 17, "classMaxValue": 40 }, { "symbol": { "type": "esriSFS", "color": [102, 255, 102, 255], "style": "esriSFSSolid", "outline": { "type": "esriSLS", "color": [28, 39, 44, 26], "width": 0.75, "style": "esriSLSSolid" } }, "label": "30,001 to 90,000", "classMinValue": 41, "classMaxValue": 100 }, { "symbol": { "type": "esriSFS", "color": [204, 255, 102, 255], "style": "esriSFSSolid", "outline": { "type": "esriSLS", "color": [28, 39, 44, 26], "width": 0.75, "style": "esriSLSSolid" } }, "label": "90,001 to 10,000,000", "classMinValue": 101, "classMaxValue": 200 }] } } }]
圖 12 分級渲染結果
總結:
本文對使用動態圖層在服務器端進行渲染作了簡單的示例,下面將會使用相關的web api進行實現上面的流程。
參考:
ArcGIS Server rest api:http://resources.arcgis.com/en/help/rest/apiref/
林lin博客:http://www.cnblogs.com/dubaokun/archive/2012/12/17/2822522.html
~update20150924
在上面的文章,只對動態添加矢量圖層,準確的說table。動態圖層除了這幾種形式,還有其餘三種形式,分別爲query data soure,raster data source和Join Data source,從字面意義上也能夠看出三種所針對的形式。
這三種動態圖層的使用方式和上面的table的方式同樣,不一樣的data source object的內容不一樣,
要理解動態圖層須要,理解動態圖層的結構:
Layer Source Object | | | |----Map Layer | | | |----type | | | |----map layer id | | | Data Layer | | | |-----type | | | |-----data source | | | |----type | | | |-----data Source name | | | |----work space id | | ID
source 對象包括:map layer和data layer兩種。兩種的區別是來源,若是是對服務中已有的圖層進行動態修改,則該圖層爲map layer;若是是從動態工做空間中疊加一個服務自己沒有的圖層,則爲data layer
+ map layer 須要指定該圖層在服務圖層中的id
+ data layer 須要指定data source。data source 的類型是table,raster仍是join,和query data source。動態工做空間的id,以及圖層名字
1. raster data source 以下
{ "source" : { "type" : "dataLayer", "dataSource" : { "type" : "raster", "dataSourceName" : "090161.tif", "workspaceId" : "MyRasterWorkspaceID" } }, "id" : 9999 }
~update:20151014
動態圖層在前端api都有相關的對象進行實現,下面已silvlight api爲例子:
ESRI.ArcGIS.Client.RasterDataSource myRasterDataSource = new ESRI.ArcGIS.Client.RasterDataSource(); myRasterDataSource.WorkspaceID = "MyRasterWorkspaceID"; myRasterDataSource.DataSourceName = "090161.tif"; ESRI.ArcGIS.Client.LayerDataSource myLayerDataSource = new ESRI.ArcGIS.Client.LayerDataSource(); myLayerDataSource.DataSource = myRasterDataSource; ESRI.ArcGIS.Client.DynamicLayerInfo myLayerInfo = new ESRI.ArcGIS.Client.DynamicLayerInfo(); myLayerInfo.Source = myLayerDataSource; myLayerInfo.ID = 999; ESRI.ArcGIS.Client.DynamicLayerInfoCollection myDynamicLayerInfoCollection = new ESRI.ArcGIS.Client.DynamicLayerInfoCollection(); myDynamicLayerInfoCollection.Add(myLayerInfo); ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer myLayer = myMap.Layers["myLayer"] as ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer; myLayer.DynamicLayerInfos = myDynamicLayerInfoCollection;
~update:20160420 因爲有用戶詢問怎麼使用js api實現這個功能,今天有寫了個js的實現,核心代碼以下:
1 function (DynamicLayerInfo, QueryDataSource, LayerDataSource, RasterDataSource,ArcGISDynamicMapServiceLayer,Map) { 2 var url="http://localhost:6080/arcgis/rest/services/test/rasterDataSetTest/MapServer"; 3 var dynamicData=new ArcGISDynamicMapServiceLayer(url); 4 var map=Map("map"); 5 map.addLayer(dynamicData) 6 7 document.getElementById('addLayer').onclick = function () { 8 9 var dynamicLayerInfos = []; 10 var dynamicLayerInfo = new DynamicLayerInfo(); 11 dynamicLayerInfo.id = 1; 12 var dataSource = new RasterDataSource(); 13 dataSource.workspaceId = "MyRasterWorkspaceID"; 14 dataSource.dataSourceName = "090161.tif"; 15 16 var layerSource = new LayerDataSource(); 17 layerSource.dataSource = dataSource; 18 dynamicLayerInfo.source = layerSource; 19 dynamicLayerInfos.push(dynamicLayerInfo); 20 21 dynamicData.setDynamicLayerInfos(dynamicLayerInfos); 22 23 }; 24 25 26 }