Learn how to calculate the length and area of geometries.

find length and area

You can calculate the length of a line and determine the area of a polygon using the GeometryEngine. The best measurement method depends on the geometry’s spatial reference, the size of the area or distance being measured, and the accuracy required. Geodesic measurements account for the curvature of the Earth and are generally the best choice when using a geographic coordinate system. For projected coordinate systems, geodesic measurements can be used for measurements of any size and are especially useful for large distances or areas, or when the projection significantly distorts distance or area. Planar measurements can be appropriate for smaller distances or areas when using a projected coordinate system that is designed to preserve the property being measured, such as an equidistant or equal-area projection.

In this tutorial, you will use the geometry editor tool named VertexTool to draw graphics on the view. You will then use the geometry engine to calculate geodesic and planar lengths and areas for Web Mercator geometries to see the difference between the two measurements.

Prerequisites

Before starting this tutorial:

  1. You need an ArcGIS Location Platform or ArcGIS Online account.

  2. Your system meets the system requirements.

  3. The ArcGIS Maps SDK for Qt, version 300.1.0 or later is installed.

  4. The Qt 6.8.2 software development framework or later is installed.

Develop or Download

You have two options for completing this tutorial:

  1. Option 1: Develop the code or
  2. Option 2: Download the completed solution

Option 1: Develop the code

To start the tutorial, complete the Display a map tutorial. This creates a map to display the Santa Monica Mountains in California using the topographic basemap from the ArcGIS Basemap Styles service The ArcGIS Basemap Styles service, also referred to as the Basemap Styles service, is a location service that provides basemap styles and data for the world. It returns styles as Mapbox styles and web maps, and data as vector tiles and/or map tiles. It supports all of the styles in the ArcGIS Basemap style and Open Basemap style family. An ArcGIS Location Platform or ArcGIS Online account is required to use the service. Learn more .

Open a Qt Creator project

  1. Open the project you created by completing the Display a map tutorial.

  2. Continue with the following instructions to make modifications for this, the find length and area, tutorial.

Update the location

The first thing you will do is update the center point location to be over the general area of England and zoom out quite a bit to see the entire country and part of Europe.

  1. Open the Display_a_map.cpp file, in the setupViewpoint() function, update the center and viewpoint variables to display the map over England:

    Display_a_map.cpp
    void Display_a_map::setupViewpoint()
    {
    const Point center(-1.398323, 53.402541, SpatialReference::wgs84());
    const Viewpoint viewpoint(center, 10000000.0);
    m_mapView->setViewpointAsync(viewpoint);
    }

Set up the geometry editor and vertex tool

In order to calculate length and area measurements we need a mechanism to draw graphics on the map. These graphics can be created by using the GeometryEditor via the VertexTool.

  1. In Projects, double-click Headers > Display_a_map.h to open the file.

  2. Add a class declaration for the GeometryEditor.

    Display_a_map.h
    namespace Esri::ArcGISRuntime{
    class Map;
    class MapQuickView;
    class GeometryEditor;
    }
  3. Now add a private member m_geometryEditor variable for the geometry editor. Then save the file.

    Display_a_map.h
    private:
    Esri::ArcGISRuntime::MapQuickView* mapView() const;
    void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
    void setupViewpoint();
    Esri::ArcGISRuntime::GeometryEditor* m_geometryEditor = nullptr;
  4. In Projects, double-click Sources > Display_a_map.cpp to open the file.

  5. Include the following classes as shown in the next code block.

    Display_a_map.cpp
    #include "Display_a_map.h"
    #include "Map.h"
    #include "MapTypes.h"
    #include "MapQuickView.h"
    #include "Point.h"
    #include "Viewpoint.h"
    #include "SpatialReference.h"
    #include <QFuture>
    #include "GeometryEditor.h"
    #include "VertexTool.h"
  6. In the existing setMapView(MapQuickView* mapView) function, add code to create a GeometryEditor, set the VertexTool, and then assign geometry editor to the map view. Then save the file.

    Display_a_map.cpp
    // 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);
    m_geometryEditor = new GeometryEditor(this);
    m_geometryEditor->setTool(new VertexTool(this));
    m_mapView->setGeometryEditor(m_geometryEditor);
    setupViewpoint();
    emit mapViewChanged();
    }

Add UI buttons and add back-end logic for drawing

Now that we have the geometry editor with a vertex tool available, we need to add some UI buttons for drawing a Polyline and Polygon. We will also need a UI button to Delete geometries when you are finished sketching them on the map. Additionally, we need to code the back-end logic to have the buttons do something on the map. This means the ability to start and stop drawing a polyline and polygon.

  1. In Projects, double-click Resources > qml\qml.qrc/qml/Display_a_mapForm.qml to open the file.

  2. Add UI buttons to perform the polyline and polygon drawing. Also, add the delete button. Of course we will also need to wrap these controls in a nice visual container (Rectangle) and do some alignment formatting (Column) so things appear nicely on the screen. Then save the file.

    Display_a_mapForm.qml
    // Declare the C++ instance that creates the map etc., and supply the view.
    Display_a_map {
    id: model
    mapView: view
    }
    Rectangle {
    width: 300
    height: panelContent.implicitHeight + 20
    color: "#ffffff"
    opacity: 0.92
    radius: 6
    anchors {
    left: parent.left
    top: parent.top
    margins: 15
    }
    Column {
    id: panelContent
    anchors.fill: parent
    anchors.margins: 10
    spacing: 8
    Label {
    text: "Find length and area"
    font.pixelSize: 18
    font.bold: true
    }
    Row {
    spacing: 6
    Button {
    text: "Polyline"
    onClicked: model.startPolyline()
    }
    Button {
    text: "Polygon"
    onClicked: model.startPolygon()
    }
    Button {
    text: "Delete"
    onClicked: model.deleteGeometry()
    }
    }
    }
    }
  3. In Projects, double-click Headers > Display_a_map.h to open the file.

  4. Now add some Q_INVOKABLE variables to control the geometry-editing actions that are used by QML UI controls. Then save the file.

    Display_a_map.h
    public:
    explicit Display_a_map(QObject* parent = nullptr);
    ~Display_a_map() override;
    Q_INVOKABLE void startPolyline();
    Q_INVOKABLE void startPolygon();
    Q_INVOKABLE void deleteGeometry();
  5. In the Display_a_map.cpp file, add back-end business logic methods to start a polyline editor, start a polygon editor, and deleting the current editing geometry.

    Display_a_map.cpp
    // 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);
    m_geometryEditor = new GeometryEditor(this);
    m_geometryEditor->setTool(new VertexTool(this));
    m_mapView->setGeometryEditor(m_geometryEditor);
    setupViewpoint();
    emit mapViewChanged();
    }
    void Display_a_map::startPolyline()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    m_geometryEditor->start(GeometryType::Polyline);
    }
    void Display_a_map::startPolygon()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    m_geometryEditor->start(GeometryType::Polygon);
    }
    void Display_a_map::deleteGeometry()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    }

Add UI labels and add back-end logic for measurements

We are now nearing the completion steps to have a fully functional app. We will add UI labels for the display of the geodetic and planar measurements for the polyline and polygon as you add each vertex of the graphics. We will also add the functions to calculate the measurements using some static methods via the GeometryEngine API> Code will also be added to reset the label values when switching between the drawing of a polyline and polygon.

  1. In Projects, double-click Resources > qml\qml.qrc/qml/Display_a_mapForm.qml to open the file. Then save the file.

  2. Add UI labels to display the geodetic and planar values.

    Display_a_mapForm.qml
    Rectangle {
    width: 300
    height: panelContent.implicitHeight + 20
    color: "#ffffff"
    opacity: 0.92
    radius: 6
    anchors {
    left: parent.left
    top: parent.top
    margins: 15
    }
    Column {
    id: panelContent
    anchors.fill: parent
    anchors.margins: 10
    spacing: 8
    Label {
    text: "Find length and area"
    font.pixelSize: 18
    font.bold: true
    }
    Row {
    spacing: 6
    Button {
    text: "Polyline"
    onClicked: model.startPolyline()
    }
    Button {
    text: "Polygon"
    onClicked: model.startPolygon()
    }
    Button {
    text: "Delete"
    onClicked: model.deleteGeometry()
    }
    }
    Label {
    text: "Measurement type: " + model.measurementType
    }
    Label {
    text: "Geodetic: " + model.geodeticMeasurement + " " + model.displayUnits
    }
    Label {
    text: "Planar: " + model.planarMeasurement + " " + model.displayUnits
    }
    }
    }
  3. In Projects, double-click Headers > Display_a_map.h to open the file.

  4. Now add some Q_PROPERTY variables used when a measurementsChanged notification has occurred to update the GUI labels.

    Display_a_map.h
    Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
    Q_PROPERTY(QString measurementType MEMBER m_measurementType NOTIFY measurementsChanged)
    Q_PROPERTY(QString geodeticMeasurement MEMBER m_geodeticMeasurement NOTIFY measurementsChanged)
    Q_PROPERTY(QString planarMeasurement MEMBER m_planarMeasurement NOTIFY measurementsChanged)
    Q_PROPERTY(QString displayUnits MEMBER m_displayUnits NOTIFY measurementsChanged)
  5. Add the measurementsChanged signal to detect when the measurement has changed.

    Display_a_map.h
    signals:
    void mapViewChanged();
    void measurementsChanged();
  6. Add the private helper resetMeasurements and updateMeasurements functions, and member variables to store and update measurement calculations. Then save the file.

    Display_a_map.h
    private:
    Esri::ArcGISRuntime::MapQuickView* mapView() const;
    void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
    void setupViewpoint();
    Esri::ArcGISRuntime::GeometryEditor* m_geometryEditor = nullptr;
    void resetMeasurements(const QString& measurementType, const QString& unitText);
    void updateMeasurements();
    QString m_measurementType = "measurement";
    QString m_geodeticMeasurement = "0";
    QString m_planarMeasurement = "0";
    QString m_displayUnits = "km";
  7. In Projects, double-click Sources > Display_a_map.cpp to open the file.

  8. Include the following #include preprocessor directives as shown in the next code block.

    Display_a_map.cpp
    #include "Display_a_map.h"
    #include "Map.h"
    #include "MapTypes.h"
    #include "MapQuickView.h"
    #include "Point.h"
    #include "Viewpoint.h"
    #include "SpatialReference.h"
    #include <QFuture>
    #include "GeometryEditor.h"
    #include "VertexTool.h"
    #include "AreaUnit.h"
    #include "Geometry.h"
    #include "GeometryEngine.h"
    #include "GeometryTypes.h"
    #include "LinearUnit.h"
  9. Add two new functions: the resetMeasurements function which resets the measurement operations to their initial state and the updateMeasurements function which reads the current geometry from the GeometryEngine and calculates geodetic and planar measurements for display in the GUI.

    Display_a_map.cpp
    void Display_a_map::setupViewpoint()
    {
    const Point center(-1.398323, 53.402541, SpatialReference::wgs84());
    const Viewpoint viewpoint(center, 10000000.0);
    m_mapView->setViewpointAsync(viewpoint);
    }
    void Display_a_map::resetMeasurements(const QString& measurementType, const QString& unitText)
    {
    m_measurementType = measurementType;
    m_displayUnits = unitText;
    m_geodeticMeasurement = "0";
    m_planarMeasurement = "0";
    emit measurementsChanged();
    }
    void Display_a_map::updateMeasurements()
    {
    if (!m_geometryEditor)
    return;
    const Geometry geometry = m_geometryEditor->geometry();
    if (geometry.isEmpty())
    {
    resetMeasurements(m_measurementType, m_displayUnits);
    return;
    }
    if (geometry.geometryType() == GeometryType::Polyline)
    {
    m_measurementType = "length";
    m_displayUnits = "km";
    const double geodeticLengthKm = GeometryEngine::lengthGeodetic(
    geometry,
    LinearUnit::kilometers(),
    GeodeticCurveType::Geodesic);
    const double planarLengthKm = GeometryEngine::length(geometry) / 1000.0;
    m_geodeticMeasurement = QString::number(geodeticLengthKm, 'f', 2);
    m_planarMeasurement = QString::number(planarLengthKm, 'f', 2);
    emit measurementsChanged();
    return;
    }
    if (geometry.geometryType() == GeometryType::Polygon)
    {
    m_measurementType = "area";
    m_displayUnits = "km²";
    const double geodeticAreaKm2 = qAbs(GeometryEngine::areaGeodetic(
    geometry,
    AreaUnit::squareKilometers(),
    GeodeticCurveType::Geodesic));
    const double planarAreaKm2 = qAbs(GeometryEngine::area(geometry) / 1000000.0);
    m_geodeticMeasurement = QString::number(geodeticAreaKm2, 'f', 2);
    m_planarMeasurement = QString::number(planarAreaKm2, 'f', 2);
    emit measurementsChanged();
    }
    }
  10. Now add the connect for the geometry editor’s geometry changed event that performs the updateMeasurements.

    Display_a_map.cpp
    // 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);
    m_geometryEditor = new GeometryEditor(this);
    m_geometryEditor->setTool(new VertexTool(this));
    m_mapView->setGeometryEditor(m_geometryEditor);
    connect(m_geometryEditor, &GeometryEditor::geometryChanged, this, &Display_a_map::updateMeasurements);
    setupViewpoint();
    emit mapViewChanged();
    }
  11. The final step we need to perform is to add calls to the resetMeasurements function from within the prior added functions: startPolyline, startPolygon, and deleteGeometry. Then save the file.

    Display_a_map.cpp
    void Display_a_map::startPolyline()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    m_geometryEditor->start(GeometryType::Polyline);
    resetMeasurements("length", "km");
    }
    void Display_a_map::startPolygon()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    m_geometryEditor->start(GeometryType::Polygon);
    resetMeasurements("area", "km²");
    }
    void Display_a_map::deleteGeometry()
    {
    if (!m_geometryEditor)
    return;
    m_geometryEditor->stop();
    resetMeasurements("measurement", "km");
    }

Set developer credentials

For the final steps of this tutorial, click the tab below that corresponds to the authentication type (API key authentication or User authentication) that you chose when you completed the Display a map tutorial.

Be sure to also provide the same authentication (API key or user authentication Client ID/Redirect URL) that you used for the Display a map tutorial.

Set the API Key

  1. In the project Sources folder of Qt Creator, open the main.cpp file.

  2. Modify the code to set the accessToken using your API key access token (highlighted in yellow).

    main.cpp
    // The following methods grant an access token:
    // 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account.
    // To generate a token, a user logs in to the app with an ArcGIS account that is part of an
    // organization in ArcGIS Online or ArcGIS Enterprise.
    // 2. API key authentication: Get a long-lived access token that gives your application access to
    // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key.
    // Copy the API Key access token.
    const QString accessToken = QString("");
    if (accessToken.isEmpty())
    {
    qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" <<
    "you to authenticate with an ArcGIS account or set the API Key property.";
    }
    else
    {
    ArcGISRuntimeEnvironment::setApiKey(accessToken);
    }
  3. Save the main.cpp file.

Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

Press Ctrl + R to run the app.

You should see a map centered on England with two buttons at the bottom of the screen. Click the Polyline button, and tap at least two points. The geodetic and planar length of the polyline should display below the map. Then click the Delete button to end the editing with the geometry editor control. Now click the Polygon button, and tap at least three points. The geodetic and planar area of the polygon should display. Then click the Delete button to end the editing with the geometry editor control.

Alternatively, you can download the tutorial solution, as follows.

Option 2: Download the solution

  1. Click the Download solution link under Solution and unzip the file to a location on your machine.

  2. Open the .pro project file in Qt Creator.

Since the downloaded solution does not contain authentication credentials, you must set up authentication to create the developer credentials and add them to the project.

For the final steps of this tutorial, click the tab below that corresponds to the authentication type (API key authentication or User authentication) that you chose when you completed the Display a map tutorial.

Be sure to also provide the same authentication (API key or user authentication Client ID/Redirect URL) that you used for the Display a map tutorial.

Set developer credentials in the solution

Set the API Key

  1. In the project Sources folder of Qt Creator, open the main.cpp file.

  2. Modify the code to set the accessToken using your API key access token (highlighted in yellow).

    main.cpp
    // The following methods grant an access token:
    // 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account.
    // To generate a token, a user logs in to the app with an ArcGIS account that is part of an
    // organization in ArcGIS Online or ArcGIS Enterprise.
    // 2. API key authentication: Get a long-lived access token that gives your application access to
    // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key.
    // Copy the API Key access token.
    const QString accessToken = QString("");
    if (accessToken.isEmpty())
    {
    qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" <<
    "you to authenticate with an ArcGIS account or set the API Key property.";
    }
    else
    {
    ArcGISRuntimeEnvironment::setApiKey(accessToken);
    }
  3. Save the main.cpp file.

Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

Run the solution

Press Ctrl + R to run the app.

You should see a map centered on England with two buttons at the bottom of the screen. Click the Polyline button, and tap at least two points. The geodetic and planar length of the polyline should display below the map. Then click the Delete button to end the editing with the geometry editor control. Now click the Polygon button, and tap at least three points. The geodetic and planar area of the polygon should display. Then click the Delete button to end the editing with the geometry editor control.

What’s next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: