ArcGIS API for Silverlight 使用GP服務實現要素裁剪功能


     昨天一QQ好友問了一個關於裁剪的問題,感覺自己也沒有幫上什么忙,之后自己做了一個裁剪的例子,不過在做這個例子的時候還遇到了不少的問題,在此和大家分享一下.

1.裁剪功能的實現過程

這里的裁剪功能很簡單,只需要一個Clip(裁剪)工具即可。

但是這里需要注意的問題是裁剪工具的參數:

裁剪工具有兩個輸入參數:

a.輸入要素:這里指的是你用什么來裁剪目標要素,也就是你用什么裁剪

b.裁剪要素:這里指的被裁剪的要素,即目標要素,也就是說你要裁剪誰。

例如,我現在有一幅中國地圖,我想根據我輸入的任意形狀,裁剪出任意形狀所包含的中國地圖部分。

如下圖所示:

中國地圖作為底圖(裁剪要素)

輸入多邊形(輸入要素),裁剪中國地圖

輸入多變行包含的中國地圖部分

以上主要是說一下裁剪工具,如果這里弄反了,則無法得到結果。

2.GP服務模型

以上說了一下裁剪工具注意的東西,以及其功能。下面給出的是GP服務的模型,比較簡單,只需要注意輸入要素和裁剪要素別弄反就行,上面已經給出,在此不再解釋。

3.發布GP服務

右鍵工具箱——發布到ArcGIS Server

輸入GP服務名稱,點擊下一步知道完成發布即可。

到此實現裁剪功能的GP服務已經發布完畢,在此推薦最好在ArcMap中驗證一下裁剪功能是否好使。

注意:

上面說到,裁剪工具需要注意輸入要素和裁剪要素別弄反。實際上,當裁剪工具的兩個要素參數弄反了之后,我們再發布實現裁剪的GP服務,同樣不會報錯,而且在ArcMap中驗證還會得到和沒有弄反時一樣的結果,也就是說如果只針對於ArcMap來講,裁剪工具的這兩個參數弄反都無所謂,即不影響最后的結果,但是當我們在Web端調用(本文只針對於Silverlight客戶端)時,就會得不到正確的結果,但是Silverlight客戶端調用GP服務的整個過程不會報錯。

關於GP服務的發布及注意事項可以參考之前的博文。

2.Silverlight客戶端代碼

(1).聲明一個Draw對象,繪制多邊形,作為裁剪要素。

 Draw myDraw = null;

(2).聲明一個地理處理服務變量,用於請求GP服務

 Geoprocessor _geoprocessor = null;

(3).聲明一個GraphicsLayer,存儲繪制的多邊形和最后裁剪的結果

GraphicsLayer graphicLayer = null;

(4).實例化上面的參數

             myDraw= new Draw(map1);
             myDraw.DrawComplete += new EventHandler<DrawEventArgs>(myDraw_DrawComplete);

             myDraw.DrawMode = DrawMode.Polygon;
             myDraw.IsEnabled = false;

             DrawButton.Click += new RoutedEventHandler(DrawButton_Click);
             ClipButton.Click += new RoutedEventHandler(ClipButton_Click);
             ClearButton.Click += new RoutedEventHandler(ClearButton_Click);

graphicLayer
= map1.Layers["ClipGraphic"] as GraphicsLayer; _geoprocessor = new Geoprocessor("http://qzj-pc/arcgis/rest/services/ClipService/GPServer/ClipTool"); _geoprocessor.JobCompleted += new EventHandler<JobInfoEventArgs>(_geoprocessor_JobCompleted); _geoprocessor.Failed += new EventHandler<TaskFailedEventArgs>(_geoprocessor_Failed);

上面聲明了實例化了Draw對象,以及Geoprocessor,並注冊相應的Button事件。


(5).首先是點擊繪制多邊形按鈕,開始繪制裁剪要素多邊形,所以在DrawButton的Click事件函數中添加如下代碼:

        private void DrawButton_Click(object sender, RoutedEventArgs e)
        {
            //設置Draw為True,開始繪制
            myDraw.IsEnabled = true;
        }

(6).然后是繪制完成,在DrawComplete事件函數中獲得繪制的多邊形,並添加到圖層中,示例代碼如下:

 private void myDraw_DrawComplete(object sender, DrawEventArgs e)
        {
            graphicLayer.Graphics.Clear();

            myDraw.IsEnabled = false;
            //因為上面指定DrawMode為Polygon所以得到的就是多邊形,如果DrawMode指定的是矩形,那么這里會出錯
            //因為矩形不是Polygon,因為只有Polygon或者Polyline以及MapPoint才能夠被指定為Graphic的Geometry
            Polygon clipPolygon = e.Geometry as Polygon;
            
            Graphic graphic = new Graphic()
            {
                Geometry=clipPolygon,
                Symbol = LayoutRoot.Resources["FillSymbol"] as SimpleFillSymbol,
            };
            graphicLayer.Graphics.Add(graphic);
        }

(7).繪制完成以后,接下來就是開始裁剪工作,在ClipButton的Click事件函數中開始Clip操作。
首先取得存儲GraphicLayer中的Graphic。在此之前需要做一個判斷,就是確認GraphicsLayer不為空。

然后由這些Graphic構成一個FeatureSet,將這個FeatureSet作為GP服務的輸入參數,

最后請求GP服務。示例代碼如下:

   private void ClipButton_Click(object sender, RoutedEventArgs e)
        {
            if (graphicLayer.Graphics.Count == 0)
            {
                MessageBox.Show("裁剪要素不能為空!");
                return;
            }
            FeatureSet featureSet= new FeatureSet();
            //遍歷Graphic,添加到FeatureSet中
            foreach (Graphic g in graphicLayer.Graphics)
            {
                featureSet.Features.Add(g);
            }
            //聲明GP服務參數
            List<GPParameter> gpparameter = new List<GPParameter>();
            //添加給名為ClipPolygon的GP服務參數名賦值
            gpparameter.Add(new GPFeatureRecordSetLayer("ClipPolygon", featureSet));
            //請求GP服務
            _geoprocessor.SubmitJobAsync(gpparameter);
        }

(8).接着我們在GP服務的JobCompleted事件中注冊GetResultDataCompleted事件,並請求GP服務的結果,示例代碼如下:

 void _geoprocessor_JobCompleted(object sender, JobInfoEventArgs e)
        {
            //如果GP服務執行成功,則獲取結果
            if (e.JobInfo.JobStatus == esriJobStatus.esriJobSucceeded)
            {
                _geoprocessor.GetResultDataCompleted += new EventHandler<GPParameterEventArgs>(_geoprocessor_GetResultDataCompleted);
                _geoprocessor.GetResultDataAsync(e.JobInfo.JobId, "ClipResult");
            }
            else if(e.JobInfo.JobStatus==esriJobStatus.esriJobFailed)
            {
                MessageBox.Show("GP服務執行失敗!");
            }
        }

(9).最后在GetResultDataCompleted事件函數中,獲得GP服務的執行結果,並將其現實在地圖上。示例代碼:

private  void _geoprocessor_GetResultDataCompleted(object sender, GPParameterEventArgs e)
        {
            graphicLayer.Graphics.Clear();
            if (e.Parameter is GPFeatureRecordSetLayer)
            {
                GPFeatureRecordSetLayer featureSetLayer = e.Parameter as GPFeatureRecordSetLayer;
                if (featureSetLayer.FeatureSet.Features.Count == 0)
                {
                    MessageBox.Show("裁剪的結果為空!");
                }
                else
                {

                    for (int i = 0; i < featureSetLayer.FeatureSet.Features.Count;i++)
                    {
                        featureSetLayer.FeatureSet.Features[i].Symbol = LayoutRoot.Resources["ResultFillSymbol"] as ESRI.ArcGIS.Client.Symbols.FillSymbol;                   
                        graphicLayer.Graphics.Add(featureSetLayer.FeatureSet.Features[i]);
                    }
                }
            }
        }

最后的示意圖:

裁剪結果:

 

(版權所有,轉載請標明出處)

 

 

 


免責聲明!

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



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