天天看點

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】

簡單介紹RouteTask的使用,分析結果是最短路徑分析結果。

要說網頁端最經典的GIS應用,非網絡分析莫屬了。

什麼?你沒用過?百度高德谷歌地圖的路線分析就是活生生的例子啊!隻不過它們是根據大實際背景優化了結果顯示而已。

這個例子使用RouteTask進行網絡分析,我會先講講什麼是RouteTask,再講講這個例子是怎麼用的,這個例子代碼量不多。

在官方的例子中,标題為:SimpleRouting - RouteTask

看看結果

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】

點選兩個點,安靜等待十秒左右就會出現這個紫色的路線了。當然右鍵點選也是一樣的。反應比較慢。

RouteTask類

這個例子用到了這個類,務必先介紹一下,因為在上一章中已經介紹了三個用于查詢的Task類了。

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】

介紹上說,RouteTask允許使用者在AJS中友善地在給定的點上進行最短路徑查詢,RouteTask使用ArcGIS Server釋出的網絡分析服務(NAServer)。

有關ArcGIS Server如何釋出NAServer,我會在我另一個系列中寫一寫。

這就說明了RouteTask是使用Server的REST URL進行執行個體化的。

它最常用的是solve()方法。(與AO二次開發類似)

同樣的,它也有對應的RouteParameters和RouteResult類。

RouteParameters和RouteResult類

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】

這個參數類擁有網絡分析特有的屬性:如途徑點、障礙點、阻抗屬性等,見桌面GIS網絡分析的文檔。

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】

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對象。

最後給出完整代碼:

ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】
ArcGIS API for JavaScript 4.2學習筆記[27] 網絡分析之最短路徑分析【RouteTask類】
<!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>      

完整HTML代碼

繼續閱讀