使用ArcGIS API for Silverlight實現地形坡度在線分析


          苦逼的研究生課程終於在今天結束了,也許從今以后再也不會坐在大學的課堂上正式的聽老師講課了,接下來的時間就得開始找工作了.....前段時間一直比較忙,上課,考試,論文,以及聯系實習單位...現在就差實習還沒有着落了。

          前些天幫一網友做了個在線坡度分析的例子,大概的功能就是勾選任意的地形區域,然后實現Web端的地形坡度分析和可視化顯示,效果圖如下:

 

 實現的基本思路大致分為以下三部分:

1.在ArcMap中建立坡度求解模型和坡度統計分析模型

2.發布模型為結果地圖服務,並在客戶端調用

3.根據將結果添加地形渲染的分級視圖。

 

一、建立坡度分析和統計分析模型

打開ArcMap,使用ModelBuilder建立如下所示的模型:

 

這里需要注意兩個地方:

1.SlopeData我們發現是中間數據,中間數據是模型創建的數據,但不是模型的輸出,如果這里沒有設置為模型參數,那么任務創建的中間數據將會被 ArcGIS Server 自動刪除。

在 10.1 版本之前,必須在模型構建器中明確設置中間數據變量,並且強烈推薦使用輸出路徑下的 %scratchworkspace% 約定將所有輸出寫入地理處理 scratchworkspace 環境。在10.1中不必使用此約定。

2.該模型具有兩個輸出模型參數:SlopeData,表示坡度的柵格數據,和ZonalTable,表示對坡度柵格數據統計的結果(如:坡度的最大值,最小值,平均值等)。

在模型建好以后,需要將該模型發布為結果地圖服務,關於10.1中結果地圖服務的發布可參考之前的博文。

 

二、Silverlight客戶端調用結果地圖服務,獲得坡度分析結果和統計結果(坡度最大值,最小值,平均值等)。

Web端調用的過程和調用GP服務的過程一致,大致如下:

1.聲明地理處理變量:

 Geoprocessor _geoprocessor;

2.實例化地理處理服務變量,並注冊相應事件:

 _geoprocessor = new Geoprocessor("http://localhost:6080/arcgis/rest/services/MyGPService/SlopeAnalysis/GPServer/SlopeTool");
            _geoprocessor.JobCompleted += new EventHandler<JobInfoEventArgs>(_geoprocessor_JobCompleted);
            _geoprocessor.GetResultDataCompleted += new EventHandler<GPParameterEventArgs>(_geoprocessor_GetResultDataCompleted);
            _geoprocessor.GetResultImageLayerCompleted += new EventHandler<GetResultImageLayerEventArgs>(_geoprocessor_GetResultImageLayerCompleted);
            _geoprocessor.Failed += new EventHandler<TaskFailedEventArgs>(_geoprocessor_Failed);

3.輸入GP服務相關參數,請求GP服務

從以上建立的模型可知:

輸入的模型參數有:

polygon:表示勾選的區域,也就是執行坡度分析的地形區域

輸出測量單位:表示坡度分析的結果如何表示,有兩種選擇,Degree:坡度以角度表示,值得范圍在0-90度之間,PERCENT_RISE:表示以高程的百分比表示,默認為DEGREE.

Z 因子:一個Z單位與x,y方向單位的比值,這里

后台輸入GP服務參數,調用服務代碼:

            //e.Geometry為繪制的多邊形
            FeatureSet featureSet = new FeatureSet(e.Geometry);
            List<GPParameter> parameter = new List<GPParameter>();
            parameter.Add(new GPFeatureRecordSetLayer("polygon", featureSet));
            parameter.Add(new GPString("輸出測量單位", "DEGREE"));
            //x,y方向單位是經緯度表示,高程值用米表示
            //經緯度與米的轉化公式:degree = meter / (2 * Math.PI * 6378137.0) * 360;
            parameter.Add(new GPDouble("Z_因子", 8.98315E-6));
            _geoprocessor.SubmitJobAsync(parameter);

請求GP服務之后接下來就是獲取GP服務的結果,這里我們需要取得兩個結果,一是坡度分析結果(柵格數據,對應的格式是:GPResultImageLayer),一是坡度統計結果(表格,對應的數據格式:GPRecordSet)
這里我們先來獲取坡度分析結果,即柵格數據。

獲取柵格數據可以通過地理處理服務的GetResultImageLayerCompleted事件來獲得結果,但是我們需要在地理處理服務的Completed事件中進行請求,Completed事件表示本次地理處理任務已經完成,接下來才能獲取地理處理服務的結果。示例代碼:

在開始部分我們已經注冊地理處理服務的JobCompleted,GetResultDataCompleted和GetResultImageLayerCompleted事件,接下來在相應部分完成相應的代碼,

其中JobCompleted是獲取結果的前提,所有的獲取地理處理結果的請求,都要等地理處理服務完成(及JobCompleted),同時請求結果的時候不能同時請求兩個結果,如獲取柵格數據的代碼如下:

  private void _geoprocessor_JobCompleted(object sender, JobInfoEventArgs e)
        {
            if (e.JobInfo.JobStatus == esriJobStatus.esriJobSucceeded)
            {
                jobID = e.JobInfo.JobId;
                HttpWebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
                _geoprocessor.GetResultImageLayerAsync(e.JobInfo.JobId, "SlopeData");
                //注意不能同時請求GP服務的結果,如果在此添加下面的額代碼會出錯
                //_geoprocessor.GetResultDataAsync(jobID, "ZonalTable");
            }
            else
            {
                MessageBox.Show("請求GP服務失敗" + e.JobInfo.Messages.ToString());
            }
        }

接下來就是獲得坡度的柵格數據,然后在地圖上顯示,並同時發送獲取統計表格的請求:

   private void _geoprocessor_GetResultImageLayerCompleted(object sender, GetResultImageLayerEventArgs e)
        {
            //返回的結果實際上是一張圖片
            GPResultImageLayer imagelayer = e.GPResultImageLayer;
            //定義圖層的ID
            imagelayer.ID = "InterpolationLayer";
            //設置透明度
            imagelayer.Opacity = 0.7;
            imagelayer.DisplayName = "坡度圖層";
            //清空原有的結果
            if (map1.Layers["InterpolationLayer"] != null)
            {
                map1.Layers.Remove(map1.Layers["Interpolation"]);
            }
            //添加當前結果到圖層中
            map1.Layers.Add(imagelayer);
            //獲取坡度統計表格數據
            _geoprocessor.GetResultDataAsync(jobID, "ZonalTable");

        }

獲取坡度統計表格的數據,表格在Web客戶端傳輸的的格式是GPRecordSet,直接遍歷即可,這里因為執行一次坡度分析,所以表格中只有一條記錄,示例代碼如下:

private void _geoprocessor_GetResultDataCompleted(object sender, GPParameterEventArgs e)
        {
            GPRecordSet gpr = e.Parameter as GPRecordSet;
            if (gpr.FeatureSet != null)
            {
                double slope_MaxValue = Convert.ToDouble(gpr.FeatureSet.Features[0].Attributes["MAX"]);
                double slope_MinValue = Convert.ToDouble(gpr.FeatureSet.Features[0].Attributes["MIN"]);
                double slope_MeanValue = Convert.ToDouble(gpr.FeatureSet.Features[0].Attributes["MEAN"]);
                MEANSlopeValue.Text = slope_MeanValue.ToString("0.000");
                List<SolidColorBrush> RenderColors = new List<SolidColorBrush>();

                //默認設定10等分,顏色由綠到紅
                RenderColors = CreateColors.CreateColorList(10);
                //間隔值
                double stepValue = (slope_MaxValue - slope_MinValue) / RenderColors.Count;
                //構造不同等級的顏色和描述
                List<RenderModel> RenderModels = new List<RenderModel>();
                for (int i = 0; i < RenderColors.Count; i++)
                {
                    RenderModels.Add(new RenderModel()
                    {
                        EndValue = (i + 1) * stepValue,
                        StartValue = i * stepValue,
                        RenderColor = RenderColors[i]
                    });
                }
                //綁定到渲染等級顯示的ListBox中
                RenderColorListBox.ItemsSource = RenderModels;
                RenderColorBorder.Visibility = Visibility.Visible;
            }
        }

以上代碼包含了柵格數據渲染的顏色等級顯示圖例,其中用到了一個方法:CreateColorList,該方法用來構造由綠到黃再到紅的不同的漸變顏色。

       public static List<SolidColorBrush> CreateColorList(int _classCount)
        {
            List<SolidColorBrush> ColorList=new List<SolidColorBrush> ();
            double step=255/_classCount;
            for (int i = 0; i <= _classCount/2; i++)
            {
                ColorList.Add(new SolidColorBrush(Color.FromArgb(255, (byte)(i*step*2), 255, 0)));
            }
            for (int i = _classCount / 2 + 1; i <= _classCount; i++)
            {
                ColorList.Add(new SolidColorBrush(Color.FromArgb(255, 255,(byte)((_classCount-i)*step*2) , 0)));
            }
            return ColorList;
        }

以及RenderModel,該類代碼如下:

  public class RenderModel
    {
        public SolidColorBrush RenderColor { get; set; }
        public double StartValue { get; set; }
        public double EndValue { get; set; }
        public string Description
        {
            get { return string.Format("{0}-{1}", StartValue.ToString("#0.00"), EndValue.ToString("#0.00")); }
        }
    }

這樣便完成了坡度分析和顏色等級圖例。

 最后再來幾張效果圖吧!

初始界面:

 

勾選地形區域進行坡度分析:

正在進行坡度分析:

 

 坡度分析結果顯示:

 

PS:蛋疼的博客園,為了寫這篇日志耗了我一個晚上,上傳圖片一直失敗,失敗后直接刷新,之前寫的沒有保存,直接沒有了,代碼弄了好久也還是沒有成功,所以需要代碼的請留下您的郵箱,我會在第一時間將代碼發送到您的郵箱。

最后感謝您能認真的看完我的文章,感謝您的支持!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM