要說網頁端最經典的GIS應用,非網絡分析莫屬了。
什么?你沒用過?百度高德谷歌地圖的路線分析就是活生生的例子啊!只不過它們是根據大實際背景優化了結果顯示而已。
這個例子使用RouteTask進行網絡分析,我會先講講什么是RouteTask,再講講這個例子是怎么用的,這個例子代碼量不多。
在官方的例子中,標題為:SimpleRouting - RouteTask
看看結果
點擊兩個點,安靜等待十秒左右就會出現這個紫色的路線了。當然右鍵點擊也是一樣的。反應比較慢。
RouteTask類
這個例子用到了這個類,務必先介紹一下,因為在上一章中已經介紹了三個用於查詢的Task類了。
介紹上說,RouteTask允許用戶在AJS中方便地在給定的點上進行最短路徑查詢,RouteTask使用ArcGIS Server發布的網絡分析服務(NAServer)。
有關ArcGIS Server如何發布NAServer,我會在我另一個系列中寫一寫。
這就說明了RouteTask是使用Server的REST URL進行實例化的。
它最常用的是solve()方法。(與AO二次開發類似)
同樣的,它也有對應的RouteParameters和RouteResult類。
RouteParameters和RouteResult類
這個參數類擁有網絡分析特有的屬性:如途徑點、障礙點、阻抗屬性等,見桌面GIS網絡分析的文檔。
RouteTask的返回結果。取決於RouteParameters的參數設置。
好,咱們正式開始吧。
給出引用
require([ "esri/Map", "esri/views/MapView", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/tasks/RouteTask", "esri/tasks/support/RouteParameters", "esri/tasks/support/FeatureSet", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/Color", "esri/core/urlUtils", "dojo/on", "dojo/domReady!" ], function(Map, MapView, Graphic, GraphicsLayer, RouteTask, RouteParameters, FeatureSet, SimpleMarkerSymbol, SimpleLineSymbol, Color, urlUtils, on) { ... } );
用到的模塊很多。
函數骨架
function(...){ urlUtils.addProxyRule({...}); var routeTask = new RouteTask({ url: "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World" }); var routeLyr = new GraphicsLayer(); var routeParams = new RouteParameters({...}); var stopSymbol = new SimpleMarkerSymbol({...}); var routeSymbol = new SimpleLineSymbol({...}); var map = new Map({...}); var view = new MapView({...}); on(view, "click", addStop); function addStop(event){...}; function showRoute(event){...}; )
重點應該是routeTask、routeParams這兩個變量,和view的click事件、addStop()方法、showRoute()方法。
兩個變量用於執行網絡分析中的最短路徑分析,而事件和方法就進行對分析結果的處理和顯示。
routeTask使用了NAServer,這是一個ArcGIS Server的服務,參考Server的文檔即可。
urlUtils類和addProxyRule是什么?查詢API得知:這是個對url進行管理設置的一個類,addProxyRule好像是添加一條代理設置。//有待考究,刪除是否可以執行網絡分析。
兩個符號:stopSymbol和routeSymbol是點擊出現的十字點符號和路徑分析結果的紫色線。
所以重點就放在了routeParams、view的click事件和兩個方法體上:
routeParams對象
var routeParams = new RouteParameters({ stops: new FeatureSet(), outSpatialReference: { wkid: 3857 } });
stops是RouteParameters類的一個屬性,其類型為DataLayer或者FeatureSet。
意義是:進行網絡分析時所需要的途徑點集合。
在這里,直接實例化了一個FeatureSet對象,不過是空對象。
click事件和2個方法體
on(view, "click", addStop); function addStop(event) { var stop = new Graphic({ geometry: event.mapPoint, symbol: stopSymbol }); routeLyr.add(stop); routeParams.stops.features.push(stop); if (routeParams.stops.features.length >= 2) { routeTask.solve(routeParams).then(showRoute); } } function showRoute(data) { var routeResult = data.routeResults[0].route; routeResult.symbol = routeSymbol; routeLyr.add(routeResult); }
視圖的點擊事件,即addStop方法。
首先會產生一個新的圖形對象,其geometry屬性賦值為了:點擊的點位置對應的Point對象(在事件流中)。
符號則用上方定義的點符號/
然后把這個圖形對象stop添加到routeLyr這個圖形圖層中。
緊接着,把這個圖形對象傳遞給routeParams。它最終傳遞到了哪里?
剛剛說了,stops給了一個FeatureSet對象,FeatureSet對象則擁有一個features屬性(類型為Graphic[]),將剛剛實例化的stop對象push進去。
這樣,RouteTask所需的RouteParameters中就多了一個需要停靠的點的信息。
然后,判斷停靠點的數量是否大於等於2(兩點才能始終嘛)
如果>=2,那么執行routeTask的solve方法,接着一個異步操作,回調函數為showRoute()。
showRoute()方法的作用是獲取傳入參數data的routeResults屬性(其為routeResults[]類型)的第一個元素,即RouteResult對象。//data類型未知,查不到,應該是solve的回傳。但是官方寫着solve的返回值是RouteResult的實例...
然后把這個RouteResult對象的route屬性獲取,並設置其符號為上方實例化的線符號,加入到routeLyr圖形圖層中。
——————
總結一下
符號、圖層、地圖、場景都是老生常談了。
最重要的部分即view的click事件,所觸發的所有信息,包括RouteParameters對象的屬性設置、RouteTask對象的solve方法的使用及RouteResult對象的數據處理。
點擊視圖——獲取點位——設置RouteParameters對象——執行RouteTask.solve()——處理RouteResult對象。
最后給出完整代碼:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> <title>Simple Routing - RouteTask - 4.2</title> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } #paneDiv { position: absolute; top: 10px; left: 62px; padding: 0 12px 0 12px; background-color: rgba(0, 0, 0, 0.5); color: white; } </style> <link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css"> <script src="https://js.arcgis.com/4.2/"></script> <script> require([ "esri/Map", "esri/views/MapView", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/tasks/RouteTask", "esri/tasks/support/RouteParameters", "esri/tasks/support/FeatureSet", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/Color", "esri/core/urlUtils", "dojo/on", "dojo/domReady!" ], function( Map, MapView, Graphic, GraphicsLayer, RouteTask, RouteParameters, FeatureSet, SimpleMarkerSymbol, SimpleLineSymbol, Color, urlUtils, on ) { // proxy the route requests to avoid prompt for log in urlUtils.addProxyRule({ urlPrefix: "route.arcgis.com", proxyUrl: "/sproxy/" }); // Point the URL to a valid route service var routeTask = new RouteTask({ url: "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World" }); // The stops and route result will be stored in this layer var routeLyr = new GraphicsLayer(); // Setup the route parameters var routeParams = new RouteParameters({ stops: new FeatureSet(), outSpatialReference: { // autocasts as new SpatialReference() wkid: 3857 } }); // Define the symbology used to display the stops var stopSymbol = new SimpleMarkerSymbol({ style: "cross", size: 15, outline: { // autocasts as new SimpleLineSymbol() width: 4 } }); // Define the symbology used to display the route var routeSymbol = new SimpleLineSymbol({ color: [0, 0, 255, 0.5], width: 5 }); var map = new Map({ basemap: "streets", layers: [routeLyr] // Add the route layer to the map }); var view = new MapView({ container: "viewDiv", // Reference to the scene div created in step 5 map: map, // Reference to the map object created before the scene center: [-117.195, 34.057], zoom: 14 }); // Adds a graphic when the user clicks the map. If 2 or more points exist, route is solved. on(view, "click", addStop); function addStop(event) { // Add a point at the location of the map click var stop = new Graphic({ geometry: event.mapPoint, symbol: stopSymbol }); routeLyr.add(stop); // Execute the route task if 2 or more stops are input routeParams.stops.features.push(stop); if (routeParams.stops.features.length >= 2) { routeTask.solve(routeParams).then(showRoute); } } // Adds the solved route to the map as a graphic function showRoute(data) { var routeResult = data.routeResults[0].route; routeResult.symbol = routeSymbol; routeLyr.add(routeResult); } }); </script> </head> <body> <div id="viewDiv"></div> <div id="paneDiv"> <div> <p>Click on the map to add stops to the route. The route from the last stop to the newly added stop is calculated. If a stop is not reachable, it is removed and the last valid point is set as the starting point.</p> </div> </div> </body> </html>