服務區分析實現的主要功能是判斷在一定時間內所能夠到達的區域,例如,從某一點出發,我們想知道在30分鍾之內能夠達到的范圍有多大,那么我們就可以借助服務區分析來實現。一下是本文最后實現的效果圖:
下面就來說一下具體的實現過程。
服務區分析算是在Web端實現網絡分析的最后一個部分,之前已經講解了關於網絡數據集的制作,網絡分析服務的發布,以及最近路徑,最近設施點查詢,今天來講述最后一個部分,服務區分析。
如果您已經學完了最短路徑以及最近設施點的分析,那么對於服務區分析,肯定也是小菜一碟了。這里也沒有什么新內容,實現的過程依然和之前的路徑分析以及設施點分析類似,不同的依然是參數不同,同時這里我們同樣需要發布一個服務區分析圖層。
假設我們已經構建好了網絡分析服務(具體的發布網絡分析服務的過程在之前的博文有詳細的介紹,在此不再說明),打開我們的網絡分析服務的地址,地址格式還是和之前的一樣。例如本文的地址為:
http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/ServiceArea
之前說服務區的參數和之前的其他分析不同,那么服務區的參數又有那些呢?
在 ArcGIS Silverlight 中,最近設施分析使用RouteServiceAreaParameters作為參數,RouteServiceAreaParameters的重要屬性如下:
參數名稱 | 參數含義 |
Facilities | 表示設施點,即出發點 |
DefaultBreaks | 表示默認中斷值,string字符串,注意用逗號分割,例如"10,20,30"(假如時間是min)則表示搜索10分鍾20分鍾30分鍾之內分別能夠達到的區域 |
ExcludeSourcesFromPolygons | 由逗號分割的字符串名稱,表示分析要排除的源要素類 |
TrimPolygonDistance | 表示修剪多邊形的容差距離。 |
TrimPolygonDistanceUnits | 表示修剪多邊形的容差距離單位。 |
SplitPolygonsAtBreaks | 表示從中斷處(不同區域等級)拆分多邊形,這樣可得到不同時間內到達的區域多邊形 |
SplitLineAtBreaks | 表示從中斷處(不同區域等級)拆分線。 |
OverlapLines | 表示多個設施點生成的線是否相互覆蓋 |
OverlapPolygons | 表示多個設施點生成的多邊形是否相互覆蓋 |
ReturnFacilities | 表示是否返回設施點 |
MergeSimilarPolygonRanges | 表示是否合幵相似中斷值(等級)的多邊形范圍 |
OutputPolygons | 表示生成的多邊形類型,默認由網絡圖層指定 |
TravelDirection | 表示路徑方向,例如以設施為起點或終點為起點 |
以上為RouteServiceAreaParameters參數的一些重要屬性。下面看看代碼的聲明:
RouteServiceAreaParameters serviceAreaParameter = new RouteServiceAreaParameters() { //獲得設施點,即出發點 Facilities = stopsGraphicsLayer.Graphics, //設置終端值,breakString為聲明的字符串變量 DefaultBreaks = breakString, //設置容差 TrimPolygonDistance = 10000, //是否返回設施點(出發點) ReturnFacilities = true, SplitPolygonsAtBreaks = true, SplitLineAtBreaks = false, OverlapLines = false, OverlapPolygons = true, MergeSimilarPolygonRanges = true, OutSpatialReference = MyMap.SpatialReference, };
以上的示例代碼聲明了一個RouteServiceAreaParameters變量。breakString為文本框的值,其中時間單位有小時和分鍾,因此在此需要判斷用戶選擇的時間單位是小時還是分鍾(默認設置和網絡分析圖層一致,本文是小時)。
因此這里需要做相應的轉換,比如用戶輸入的是30分鍾,那么需要將其轉換為0.5小時,因此我們定義了一個breakString。示例代碼如下:
string breakString = ""; if (TimeUnitcomboBox.SelectedIndex == 0) { breakString = ServiceAreaBreakTextBox.Text; } else if(TimeUnitcomboBox.SelectedIndex==1) { string[] TimeString = ServiceAreaBreakTextBox.Text.Split(','); for (int i = 0; i < TimeString.Length-1;i++ ) { breakString += (Convert.ToDouble(TimeString[i]) / 60).ToString(); breakString += ","; } breakString += (Convert.ToDouble(TimeString[TimeString.Length - 1]) / 60).ToString(); }
在完成參數的定義之后,下面我們就可以開始進行網絡分析服務的查詢了。當然,首先我們需要定義一個RouteTask,以及查詢成功和失敗的事件相應函數。這和最近設施點分析以及路徑分析也是一樣的:
定義RouteTask,將url指向服務區網絡分析圖層:
RouteTask ServiceAreaTask = new RouteTask("http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/ServiceArea");//服務區Task
注冊事件的響應函數:
ServiceAreaTask.SolveServiceAreaCompleted += new EventHandler<RouteEventArgs>(ServiceAreaTask_SolveServiceAreaCompleted); ServiceAreaTask.Failed += new EventHandler<TaskFailedEventArgs>(Task_Failed);
private void ServiceAreaTask_SolveServiceAreaCompleted(object sender, RouteEventArgs e) { } private void Task_Failed(object sender, TaskFailedEventArgs e) { MessageBox.Show("求解失敗" + e.Error.ToString()); }
基本的准備工作都已完畢,接下來就可以通過該RouteTask來查詢服務區了。
if (ServiceAreaTask.IsBusy) ServiceAreaTask.CancelAsync(); ServiceAreaTask.SolveServiceAreaAsync(serviceAreaParameter);
到這里你應該也會想到,下一步就是獲取查詢的結果了,如果你細心,你會發現這和之其他的分析實現過程基本一致。
那么服務區分析的結果是什么呢?
我們知道服務區是一個面,那么肯定得到的結果是面要素。但是不同的是服務區分析的結果不再是RouteResult了,直接通過事件參數e的ServiceAreaPolygons屬性即可得到服務區面要素。下面來看一下代碼的實現獲取結果的過程:
private void ServiceAreaTask_SolveServiceAreaCompleted(object sender, RouteEventArgs e) { int i = 1; foreach (Graphic g in e.ServiceAreaPolygons) { //這里我們輸入的中斷值一般是3個,所以結果會有三個面要素,分別表示不同時間內能夠達到的區域 switch (i) { case 1: g.Symbol = LayoutRoot.Resources["MyServiceArea1"] as SimpleFillSymbol; break; case 2: g.Symbol = LayoutRoot.Resources["MyServiceArea2"] as SimpleFillSymbol; break; case 3: g.Symbol = LayoutRoot.Resources["MyServiceArea3"] as SimpleFillSymbol; break; } i++; serviceAreaLayer.Graphics.Add(g); } }
這里的MyServiceArea1,MyServiceArea2,MyServiceArea3為在XAML中定義的面要素資源樣式,參考示例代碼:
<esri:SimpleFillSymbol x:Name="MyServiceArea1" Fill="Red" BorderBrush="Yellow" BorderThickness="3"/> <esri:SimpleFillSymbol x:Name="MyServiceArea2" Fill="Yellow" BorderBrush="Green" BorderThickness="3"/> <esri:SimpleFillSymbol x:Name="MyServiceArea3" Fill="Green" BorderBrush="Blue" BorderThickness="3"/>
到此,所有的工作算是結束了,如果一切順利,那么你也會得到和本文開始給出的那張照片。
Web端的網絡分析的全部功能算是講解結束了,歡迎大家相互交流!
網絡分析系列的源程序以及網絡分析數據下載地址:
(版權所有,轉載請標明出處)