Hello everyone,
I've developed an application in Qt using the ArcGIS Runtime SDK. While the application functions well in online mode, I now require it to operate offline.
After conducting some research on offline mapping, I began constructing the application using the guidance provided in this reference: https://developers.arcgis.com/qt/cpp/sample-code/generate-offline-map/ .
I have successfully executed the application and observed several files generated in the designated location. However, I am uncertain whether these files are the correct ones for offline map functionality (please see the attached screenshot of the folder contents).
I have included my code for your review. Kindly advise on any mistakes I may have made.
Additionally, the sample code appears to only support creating offline maps for specific geometries (extents). Is it feasible to display/load maps offline based on regions or to encompass entire countries, incorporating both raster and vector files?
I am working with ArcGIS Free Developer License. Will offline mode works with ArcGIS Free License?
Thank you!
// H FILES
#ifndef OFFLINE_MAP_GENERATION_H
#define OFFLINE_MAP_GENERATION_H
#include <QWidget>
#include <QTemporaryDir>
#define DELHI_LAT 28.7041
#define DELHI_LON 77.1025
#define BENGALURU_LAT 12.9716
#define BENGALURU_LON 77.5946
#define CHENNAI_LAT 13.0843
#define CHENNAI_LON 80.2705
namespace Esri::ArcGISRuntime
{
class Map;
class MapGraphicsView;
class Portal;
class PortalItem;
class OfflineMapTask;
class Basemap;
class PortalItem;
class Portal;
class Error;
class GenerateOfflineMapJob;
class GenerateOfflineMapParameters;
class Envelope;
class Viewpoint;
class SpatialReference;
class Point;
class GeometryEngine;
} // namespace Esri::ArcGISRuntime
namespace Ui {
class offline_map_generation;
}
class offline_map_generation : public QWidget
{
Q_OBJECT
public:
explicit offline_map_generation(QWidget *parent = nullptr);
~offline_map_generation();
private slots:
void slot_portal_error(const Esri::ArcGISRuntime::Error& error);
void slot_portal_item_error(const Esri::ArcGISRuntime::Error& error);
void onGenerateOfflineMapParametersCompleted(const QUuid& taskId, const Esri::ArcGISRuntime::GenerateOfflineMapParameters& parameters);
void slot_map_offline_generator_job_has_error(const Esri::ArcGISRuntime::Error& error);
void slot_offline_map_generator_error_occured(const Esri::ArcGISRuntime::Error& error);
void on_pushButton_offlinemap_clicked();
private:
Ui::offline_map_generation *ui;
QString m_WebMapID;
Esri::ArcGISRuntime::Map *m_map = nullptr;
Esri::ArcGISRuntime::MapGraphicsView *m_mapView = nullptr;
Esri::ArcGISRuntime::OfflineMapTask *m_OfflineMapTask;
Esri::ArcGISRuntime::PortalItem *m_PortalItem;
Esri::ArcGISRuntime::Portal *m_Portal;
Esri::ArcGISRuntime::GenerateOfflineMapJob *m_offline_generator_job;
QTemporaryDir m_tempPath;
void generate_offline_map();
};
#endif // OFFLINE_MAP_GENERATION_H
// CPP
#include "offline_map_generation.h"
#include "ui_offline_map_generation.h"
#include "Map.h"
#include "MapGraphicsView.h"
#include "PortalItem.h"
#include "Portal.h"
#include "OfflineMapTask.h"
#include "Error.h"
#include "GenerateOfflineMapJob.h"
#include "GenerateOfflineMapParameters.h"
#include "Viewpoint.h"
#include "TaskWatcher.h"
#include "SpatialReference.h"
#include "Point.h"
#include "Envelope.h"
#include "GeometryEngine.h"
using namespace Esri::ArcGISRuntime;
offline_map_generation::offline_map_generation(QWidget *parent)
: QWidget(parent)
, ui(new Ui::offline_map_generation)
{
ui->setupUi(this);
m_WebMapID = "0807d723aa8e41428319524e75148522";
bool loginRequired = false;
m_Portal = new Portal(loginRequired, this);
m_Portal->load();
m_PortalItem = new PortalItem(m_Portal, m_WebMapID, this);
connect(m_Portal, &Esri::ArcGISRuntime::Portal::errorOccurred, this, &offline_map_generation::slot_portal_error);
connect(m_PortalItem, &Esri::ArcGISRuntime::PortalItem::errorOccurred, this, &offline_map_generation::slot_portal_item_error);
m_map = new Map(m_PortalItem, this);
m_mapView = new MapGraphicsView();
m_mapView->setMap(m_map);
m_OfflineMapTask = new OfflineMapTask(m_map, this);
ui->widget->layout()->addWidget(m_mapView);
}
offline_map_generation::~offline_map_generation()
{
delete ui;
}
void offline_map_generation::slot_portal_error(const Esri::ArcGISRuntime::Error& error)
{
qDebug()<<"Portal Error";
qDebug()<<"Error Type"<<error.errorType();
qDebug()<<error.message();
qDebug()<<error.additionalMessage();
}
void offline_map_generation::slot_portal_item_error(const Esri::ArcGISRuntime::Error &error)
{
qDebug()<<"Portal Item Error";
qDebug()<<"Error Type"<<error.errorType();
qDebug()<<error.message();
qDebug()<<error.additionalMessage();
}
void offline_map_generation::onGenerateOfflineMapParametersCompleted(const QUuid& taskId, const Esri::ArcGISRuntime::GenerateOfflineMapParameters& parameters)
{
QString Path = "D:/offline_map";
GenerateOfflineMapJob *generateJob = NULL;
// Adjust as needed based on your map's scale
generateJob = m_OfflineMapTask->generateOfflineMap(parameters, Path);
if(generateJob == NULL)
{
qDebug()<<"Offline Map is not generated";
}
else
{
generateJob->start();
qDebug()<<"Map generated in path"<<Path;
connect(generateJob, &GenerateOfflineMapJob::errorOccurred, this, &offline_map_generation::slot_map_offline_generator_job_has_error);
}
}
void offline_map_generation::generate_offline_map()
{
Point corner1 = {CHENNAI_LON, CHENNAI_LAT, SpatialReference::wgs84()};
Point corner2 = {DELHI_LAT, DELHI_LON, SpatialReference::wgs84()};
const Envelope extent = Envelope(corner1, corner2);
const Envelope mapExtent = geometry_cast<Envelope>(GeometryEngine::project(extent, SpatialReference::wgs84()));
connect(m_OfflineMapTask, &Esri::ArcGISRuntime::OfflineMapTask::createDefaultGenerateOfflineMapParametersCompleted, this, &offline_map_generation::onGenerateOfflineMapParametersCompleted);
connect(m_OfflineMapTask, &Esri::ArcGISRuntime::OfflineMapTask::errorOccurred, this, &offline_map_generation::slot_offline_map_generator_error_occured);
m_OfflineMapTask->createDefaultGenerateOfflineMapParameters(mapExtent);
}
void offline_map_generation::on_pushButton_offlinemap_clicked()
{
generate_offline_map();
}
void offline_map_generation::slot_map_offline_generator_job_has_error(const Esri::ArcGISRuntime::Error &error)
{
qDebug()<<"Error in Job";
qDebug()<<"Error Type"<<error.errorType();
qDebug()<<error.message();
qDebug()<<error.additionalMessage();
}
void offline_map_generation::slot_offline_map_generator_error_occured(const Esri::ArcGISRuntime::Error &error)
{
qDebug()<<"Error in Map Generation";
qDebug()<<"Error Type"<<error.errorType();
qDebug()<<error.message();
qDebug()<<error.additionalMessage();
}