Skip To Content ArcGIS for Developers Sign In Dashboard

Overview

You will learn: how to load a basemap and feature layers from a mobile map package (.mmpk) file.

Offline maps allow users to load basemaps and layers when their network connectivity is poor or offline. Mobile map packages can be created in ArcGIS Pro and loaded in your app with the MobileMapPackage class.

In this tutorial you will learn how to load a mobile map package and then use it in your app.

Before you begin

You must have previously installed the ArcGIS Runtime SDK for Qt and set up the development environment for your operating system.

Open the starter app project

If you have already completed the Create a starter app tutorial, start Qt Creator and open your starter app project. Otherwise, download and unzip the starter app project solution, and then open it in Qt Creator.

Prepare your data

You will need an .mmpk file to complete this tutorial. You can how to create mobile map packages in the Prepare your data for offline use. Alternatively, download the map package we prepared, and save the file somewhere on your development machine.

Steps

Save the path of the mobile map package

  1. You will need the absolute path of the mobile map package file. The path /usr/EsriDev/ArcGIS/Runtime/Data/offline-maps-package.mmpk is used below, but you should change this to match your own file system.

Import headers and declare member variables

  1. In Projects, double click on Headers > Create_a_starter_app.h, add MobileMapPackage to the namespace along with two additional include statements.

    class MapQuickView;
    
    // *** ADD ***
    class MobileMapPackage;
    }
    
    }
    
    #include <QObject>
    
    // *** ADD ***
    #include <QTemporaryDir>
    #include <QString>
    
  2. Add the public member functions openMapPackage and createMapPackage.

    public:
      explicit Create_a_starter_app(QObject* parent = nullptr);
      ~Create_a_starter_app() override;
    
      // *** ADD ***
      void openMapPackage(const QString& dataPath);
      void createMapPackage(const QString& dataPath);
    
  3. Add the private member variables m_mmpk and m_unpackTempDir.

      Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
    
      // *** ADD ***
      Esri::ArcGISRuntime::MobileMapPackage* m_mmpk = nullptr;
      QTemporaryDir m_unpackTempDir;
    

Load the mobile map package

  1. In Projects, double click on Sources > Create_a_starter_app.cpp and update the constructor to remove m_map from the initializer list in the constructor and replace the body of the constructor with the following code.

    Create_a_starter_app::Create_a_starter_app(QObject* parent /* = nullptr */):
       // *** UPDATE ***
       // QObject(parent),
       // m_map(new Map(Basemap::topographicVector(this), this))
       QObject(parent)
    {
      // *** UPDATE ***
      // const Point center(-118.71511, 34.09042, SpatialReference::wgs84());
      // const Viewpoint viewpoint(center, 300000.0);
      const QString mmpk_path("/usr/EsriDev/ArcGIS/Runtime/Data/offline-maps-package.mmpk");
      MobileMapPackage::isDirectReadSupported(mmpk_path);
      openMapPackage(mmpk_path);
    }
    
  2. Add the public member function Create_a_starter_app::openMapPackage.

    void Create_a_starter_app::openMapPackage(const QString& dataPath)
    {
       connect(MobileMapPackage::instance(), &MobileMapPackage::isDirectReadSupportedCompleted,
         this, [this, dataPath](QUuid, bool supported)
         {
           if (supported)
           {
             createMapPackage(dataPath);
           }
           else
           {
             MobileMapPackage::unpack(dataPath, m_unpackTempDir.path());
           }
         });
    
       connect(MobileMapPackage::instance(), &MobileMapPackage::unpackCompleted,
         this, [this](QUuid, bool success)
         {
           if (success)
           {
             createMapPackage(m_unpackTempDir.path());
           }
           else
           {
             qDebug() << "Failed to unpack offline map";
           }
         });
    
       connect(MobileMapPackage::instance(), &MobileMapPackage::errorOccurred,
         [](Error e)
         {
           if (e.isEmpty())
           {
             return;
           }
           else
           {
             qDebug() << QString("Error: %1, %2").arg(e.message(), e.additionalMessage());
           }
         });
    }
    
  3. Add the public member function createMapPackage to create a new MobileMapPackage and wait until it loads to add it to the map view.

    void Create_a_starter_app::createMapPackage(const QString& dataPath)
    {
      m_mmpk = new MobileMapPackage(dataPath, this);
    
      connect(m_mmpk, &MobileMapPackage::doneLoading, this, [this](Error e)
        {
          if (!e.isEmpty())
            {
              qDebug() << QString("Error loading package: %1 %2").arg(e.message(), e.additionalMessage());
              return;
            }
    
            if (!m_mmpk || !m_mapView || m_mmpk->maps().isEmpty())
            {
              return;
            }
    
            m_mapView->setMap(m_mmpk->maps().at(0));
       });
    
       m_mmpk->load();
    }
    
  4. Run your code to load the offline map.

Congratulations, you're done!

Your map, as it was designed in ArcGIS Pro, should load and display with the view point centered on the Santa Monica Mountains. Compare your map with our completed solution project.

Challenge

Change map contents

Learn how you can change many elements of your map without writing any code. Return to ArcGIS Pro and alter your map: change the extent, add or remove layers, and change the symbols. Republish your map package and load it on your device.

Change map package

Add a map file picker to allow your user to select the map package. Try starting with QML's FileDialog.