zoukankan      html  css  js  c++  java
  • ArcGIS API for JavaScript 4.2学习笔记[27] 网络分析之最短路径分析【RouteTask类】

    要说网页端最经典的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()
               4
            }
          });
    
          // Define the symbology used to display the route
          var routeSymbol = new SimpleLineSymbol({
            color: [0, 0, 255, 0.5],
             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代码
  • 相关阅读:
    更换pip下载源
    django同步数据库时出现错误
    Django Debug Toolbar
    使用Django-environ区分环境
    CDOJ 1591 An easy problem A(ST表)
    for循环06(打印正三角形)
    了解 label 标签 与 goto (不建议使用)
    continue01
    break01
    break 与 continue
  • 原文地址:https://www.cnblogs.com/onsummer/p/6421540.html
Copyright © 2011-2022 走看看