Find a route and directions

Learn how to find a route and directions with the route service.

find a route and directions

Routing is the process of finding the path from an origin to a destination in a street network. You can use the Routing service to find routes, get driving directions, calculate drive times, and solve complicated, multiple vehicle routing problems. To create a route, you typically define a set of stops (origin and one or more destinations) and use the service to find a route with directions. You can also use a number of additional parameters such as barriers and mode of travel to refine the results.

In this tutorial, you define an origin and destination by clicking on the map. These values are used to get a route and directions from the route service. The directions are also displayed on the map.

Prerequisites

The following are required for this tutorial:

  1. An ArcGIS account to access API keys. If you don't have an account, sign up for free.
  2. Your system meets the system requirements.
  3. The ArcGIS Runtime API for Qt is installed.

Steps

Open the project in Qt Creator

  1. To start this tutorial, complete the Display a map tutorial or download and unzip the solution.

  2. Open the display_a_map project in Qt Creator.

  3. If you downloaded the Display a map solution, set your API key.

    An API Key enables access to services, web maps, and web scenes hosted in ArcGIS Online.

    1. Go to your developer dashboard to get your API key. For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.

    2. Under Projects, in the display_a_map project, double click Sources > Display_a_map.cpp to open the file.

    3. Replace the string YOUR_API_KEY with the API key from your dashboard.


      Display_a_map.cpp
      Change lineChange line
                                                                               
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      //   Copyright 2020 Esri
      //   Licensed under the Apache License, Version 2.0 (the "License");
      //   you may not use this file except in compliance with the License.
      //   You may obtain a copy of the License at
      //
      //   https://www.apache.org/licenses/LICENSE-2.0
      //
      //   Unless required by applicable law or agreed to in writing, software
      //   distributed under the License is distributed on an "AS IS" BASIS,
      //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      //   See the License for the specific language governing permissions and
      //   limitations under the License.
      
      
      #include "Display_a_map.h"
      
      #include "ArcGISRuntimeEnvironment.h"
      
      #include "Basemap.h"
      #include "Map.h"
      #include "MapQuickView.h"
      
      
      #include <QUrl>
      
      using namespace Esri::ArcGISRuntime;
      
      Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
        QObject(parent),
      
        m_map(new Map(BasemapStyle::ArcGISTopographic, this))
      
      {
      
        // Note: It is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
        const QString api_key = QStringLiteral("YOUR_API_KEY");
      
        ArcGISRuntimeEnvironment::setApiKey(api_key);
      
      }
      
      Display_a_map::~Display_a_map()
      {
      }
      
      MapQuickView* Display_a_map::mapView() const
      {
        return m_mapView;
      }
      
      void Display_a_map::setupMap()
      {
        const Point center(-118.80543, 34.02700, SpatialReference::wgs84());
        const Viewpoint viewpoint(center, 100000.0);
        m_mapView->setViewpoint(viewpoint);
      }
      
      // Set the view (created in QML)
      void Display_a_map::setMapView(MapQuickView* mapView)
      {
        if (!mapView || mapView == m_mapView)
        {
          return;
        }
      
        m_mapView = mapView;
        m_mapView->setMap(m_map);
      
        setupMap();
      
      
        emit mapViewChanged();
      }
      

Declare classes, functions, variables, enumerations and signals

  1. In the display_a_map project, double click on Headers > Display_a_map.h to open the file. Include the four classes shown.

    Display_a_map.h
    Add line.Add line.Add line.Add line.
    21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 22 23 24 25 26 27 28 28 28 28 28 27 26 25 24 23 22 21 20 19 19 19 19 19 19 19 19 18 17 17 17 17 17 17 17 17 17 16 15 15 15 15 15 15 14 13 12 11 11 11 11 10 9 8 7 6 5 4 3 2 2 2 2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H
  2. Create an enum to monitor user route selections and maintain the route builder status. This will be initialized in Display_a_map.cpp in a later step.

    Display_a_map.h
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 40 40 40 40 40 40 40 40 39 38 38 38 38 38 38 38 38 38 37 36 36 36 36 36 36 35 34 33 32 32 32 32 31 30 29 28 27 26 25 24 23 23 23 23
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H
  3. Use Q_PROPERTY to create a member variable m_directions.

    Display_a_map.h
    Add line.
    46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 47 48 49 49 49 49 49 49 49 49 49 49 48 47 47 47 47 47 47 46 45 44 43 43 43 43 42 41 40 39 38 37 36 35 34 34 34 34
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
    
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H
  4. Add the following signal declaration; this will be used to prompt updates to route directions.

    Display_a_map.h
    Add line.
    55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 56 57 58 59 59 59 59 59 59 59 58 57 56 55 55 55 55 54 53 52 51 50 49 48 47 46 46 46 46
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H
  5. Declare the following private methods.

    Display_a_map.h
    Add line.Add line.Add line.
    60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 61 62 63 64 65 66 67 68 68 68 68 68 67 66 65 64 63 62 61 60 59 59 59 59
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H
  6. Declare and initialize the following pointers, object, and enumeration. Then save and close the file.

    Display_a_map.h
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 80 80 80 80
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.i
    
    #ifndef DISPLAY_A_MAP_H
    #define DISPLAY_A_MAP_H
    
    namespace Esri
    {
    namespace ArcGISRuntime
    {
    
    class Map;
    class MapQuickView;
    
    class Graphic;
    class GraphicsOverlay;
    class PictureMarkerSymbol;
    class RouteTask;
    
    }
    }
    
    enum RouteBuilderStatus
    {
      NotStarted,
      SelectedStart,
      SelectedStartAndEnd,
    };
    
    #include "RouteParameters.h"
    
    #include <QObject>
    class Display_a_map : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
      Q_PROPERTY(QAbstractListModel* directions MEMBER m_directions NOTIFY directionsChanged)
    public:
      explicit Display_a_map(QObject* parent = nullptr);
      ~Display_a_map() override;
    
    signals:
      void mapViewChanged();
    
      void directionsChanged();
    
    private:
      Esri::ArcGISRuntime::MapQuickView* mapView() const;
      void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
      void setupMap();
    
      void setupRouteTask();
      void findRoute();
      void resetState();
    
      Esri::ArcGISRuntime::Map* m_map = nullptr;
      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
      Esri::ArcGISRuntime::RouteTask* m_routeTask = nullptr;
      Esri::ArcGISRuntime::Graphic* m_startGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_endGraphic = nullptr;
      Esri::ArcGISRuntime::Graphic* m_lineGraphic = nullptr;
      QAbstractListModel* m_directions = nullptr;
      Esri::ArcGISRuntime::RouteParameters m_routeParameters;
      RouteBuilderStatus m_currentState;
    
    };
    
    #endif // DISPLAY_A_MAP_H

Include header files to access needed classes

  1. In the display_a_map project, double click on Sources > Display_a_map.cpp to open the file. Include the six classes shown.

    Display_a_map.cpp
    Add line.Add line.Add line.Add line.Add line.Add line.
    15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 16 17 18 19 20 21 22 23 24 25 26 26 26 26 26 26 26 26 26 26 26 25 24 24 24 24 24 24 24 23 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 21 20 19 19 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -25 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -83 -83 -83 -83 -83 -83 -83 -83 -83 -83 -83 -83
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    

Update the constructor

  1. Update the constructor as shown, to use a BasemapStyle and to initialize the RouteBuilderStatus enumeration.

    Display_a_map.cpp
    Change lineAdd line.
    31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 32 33 34 35 36 37 37 37 37 37 37 37 37 36 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 34 33 32 32 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -12 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -70 -70 -70 -70 -70 -70 -70 -70 -70 -70 -70 -70
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    
  2. Call the setupRouteTask() method within the constructor. This will be populated in a later step.

    Display_a_map.cpp
    Add line.
    40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 41 42 43 44 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 44 43 42 42 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -2 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -60 -60 -60 -60 -60 -60 -60 -60 -60 -60 -60 -60
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    

Change the map's view point

  1. In setupMap() change the map's Point and Viewpoint to place the map over over downtown Los Angeles.

    Display_a_map.cpp
    Change lineChange line
    57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 58 59 60 61 62 62 62 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 18 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    

Change setupMap() to respond to mouse clicks and find the route

  1. Add a connect statement to setupMap() to detect user mouse clicks, set and display point graphics, respond to the first and second click (using the switch statement) and call findRoute on the second mouse click.

    Display_a_map.cpp
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 66 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 8 8 8 8 8 8 8 8 8 8 8 8
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    

Create route graphics

  1. Add code to setupMap() to create the route's starting point Graphic, determined by the user's first mouse click. This consists of a SimpleLineSymbol, color blue, size 2, that outlines a SimpleMarkerSymbol, diamond shaped and orange in color.

  2. Create the route's ending point Graphic, determined by the user's second mouse click. This consists of a SimpleLineSymbol, color red, size 2, that outlines a SimpleMarkersymbol, square shaped and green in color.

  3. Create a line Graphic connecting the route's starting and ending points using a SimpleLineSymbol, color blue, size 4. Then append the starting point graphic, ending point graphic, and route line graphic to a GraphicsOverlay.

    Display_a_map.cpp
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 108 108 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 50 50 50 50 50 50 50 50 50 50 50 50
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    

Create the setRouteTask() method

A task makes a request to a service and returns the results. Use the RouteTask class to access a routing service.

A routing service with global coverage is provided by the ArcGIS Platform. You can also publish custom routing services using ArcGIS Enterprise.

Create a RouteTask with a string URL to reference the ArcGIS Platform's routing service.

  1. Begin implementing the setRouteTask() method. Point the RouteTask to an online service. Then connect to createDefaultParametersCompleted and store the resulting route parameters.

    Display_a_map.cpp
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 112 113 114 115 116 117 118 119 120 121 122 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 76 76 76 76 76 76 76 76 76 76 76 76
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    #include "Display_a_map.h"
    
    #include "ArcGISRuntimeEnvironment.h"
    #include "Basemap.h"
    #include "Map.h"
    #include "MapQuickView.h"
    
    #include "Point.h"
    #include "RouteTask.h"
    #include "RouteParameters.h"
    #include "SimpleLineSymbol.h"
    #include "SimpleMarkerSymbol.h"
    #include "Stop.h"
    
    #include <QUrl>
    
    using namespace Esri::ArcGISRuntime;
    
    Display_a_map::Display_a_map(QObject* parent /* = nullptr */):
      QObject(parent),
    
      m_map(new Map(BasemapStyle::ArcGISStreets, this)),
    
      m_currentState(RouteBuilderStatus::NotStarted)
    
    {
    
      // Note: it is not best practice to store API keys in source code. The API key is referenced here for the convenience of this tutorial.
      const QString api_key = QStringLiteral("YOUR_API_KEY");
      ArcGISRuntimeEnvironment::setApiKey(api_key);
    
      setupRouteTask();
    
    }
    
    Display_a_map::~Display_a_map()
    {
    }
    
    MapQuickView* Display_a_map::mapView() const
    {
      return m_mapView;
    }
    
    void Display_a_map::setupMap()
    {
    
      const Point center(-118.24532, 34.05398, SpatialReference::wgs84());
      const Viewpoint viewpoint(center, 144447.638572);
    
      m_mapView->setViewpoint(viewpoint);
    
      connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent mouse)
      {
        const Point mapPoint = m_mapView->screenToLocation(mouse.x(), mouse.y());
    
        switch (m_currentState)
        {
          case RouteBuilderStatus::NotStarted:
            resetState();
            m_currentState = RouteBuilderStatus::SelectedStart;
            m_startGraphic->setGeometry(mapPoint);
            break;
          case RouteBuilderStatus::SelectedStart:
            m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
            m_endGraphic->setGeometry(mapPoint);
            findRoute();
            break;
    
          case RouteBuilderStatus::SelectedStartAndEnd:
            // Ignore touches while routing is in progress
            break;
        }
      });
    
      m_graphicsOverlay = new GraphicsOverlay(this);
      m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
    
      SimpleLineSymbol* startOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2/*width*/, this);
      SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12/*width*/, this);
      startSymbol->setOutline(startOutlineSymbol);
      m_startGraphic = new Graphic(this);
      m_startGraphic->setSymbol(startSymbol);
    
      SimpleLineSymbol* endOutlineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2/*width*/, this);
      SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12/*width*/, this);
      endSymbol->setOutline(endOutlineSymbol);
      m_endGraphic = new Graphic(this);
      m_endGraphic->setSymbol(endSymbol);
    
      SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4/*width*/, this);
      m_lineGraphic = new Graphic(this);
      m_lineGraphic->setSymbol(lineSymbol);
    
      m_graphicsOverlay->graphics()->append(QList<Graphic*> {m_startGraphic, m_endGraphic, m_lineGraphic});
    
    }
    
    void Display_a_map::setupRouteTask()
    {
      // create the route task pointing to an online service
      m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);
    
      // connect to createDefaultParametersCompleted signal
      connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
      {
        // Store the resulting route parameters
        m_routeParameters = routeParameters;
      });
    
      // connect to solveRouteCompleted signal
      connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
      {
        // Add the route graphic once the solve completes
        const Route generatedRoute = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(generatedRoute.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;
    
        // set the direction maneuver list model
        m_directions = generatedRoute.directionManeuvers(this);
        emit directionsChanged();
      });
    
      // create the default parameters which will load the route task implicitly
      m_routeTask->createDefaultParameters();
    }
    
    void Display_a_map::findRoute()
    {
      if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;
    
      // set parameters to return directions
      m_routeParameters.setReturnDirections(true);
    
      // clear previous stops from the parameters
      m_routeParameters.clearStops();
    
      // set the stops to the parameters
      const Stop stop1(m_startGraphic->geometry());
      const Stop stop2(m_endGraphic->geometry());
      m_routeParameters.setStops(QList<Stop> { stop1, stop2 });
    
      // solve the route with the parameters
      m_routeTask->solveRoute(m_routeParameters);
    }
    
    void Display_a_map::resetState()
    {
      m_startGraphic->setGeometry(Point());
      m_endGraphic->setGeometry(Point());
      m_lineGraphic->setGeometry(Point());
      m_directions = nullptr;
      m_currentState = RouteBuilderStatus::NotStarted;
    }
    
    // Set the view (created in QML)
    void Display_a_map::setMapView(MapQuickView* mapView)
    {
      if (!mapView || mapView == m_mapView)
      {
        return;
      }
      m_mapView = mapView;
      m_mapView->setMap(m_map);
      setupMap();
      emit mapViewChanged();
    }
    
  2. Connect to solveRouteCompleted. With the route completed, set the route graphic's Geometry and reset RouteBuilderStatus to prepare for a new route task. Then display the route directions. Outside of connect, configure the RouteTask with default parameters.

    Display_a_map.cpp
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    116 116 116 116 116 116 116 116 116 116 116 116 116 116 116