Just as layers in your app can use data sourced from online services, such as ArcGIS Online, WFS, or WMS services, layers can also use data from data files stored locally on your user's device. Local data files support scenarios where your users never have a network connection.
This page describes what you can do with data files and lists supported data file formats. It also provides details on how to use a data file in your app, which are summarized in the following steps:
- Create, sideload, or download the data file onto your user's device.
- Access the data file.
- Create a layer referencing the data file.
- Apply a renderer to define symbols for features in the layer (Optional).
- Add the layer to a map or scene.
For information on mobile map packages and mobile scene packages, which are also stand-alone files, see Offline maps, scenes, and data or the ArcGIS Pro topics Share a mobile map package and Share a mobile scene package. For details on working with data from services while offline, see Work with offline data.
What you can do with data files
You can do the following types of things in your app using local data files:
- Display maps or scenes without a network connection.
- Access, display, and analyze geospatial data.
- Include data with the installation of your app.
- Collect data on devices that never have access to a network connection.
- Create new mobile geodatabases, tables, and domains.
- Share datasets between applications using peer-to-peer technology.
Supported data files
The following data files are supported:
Data file type | Data access API | Layer API | Can query? | Can edit? | License level |
---|---|---|---|---|---|
Vector tile package | VectorTileCache | ArcGISVectorTiledLayer | No | No | Lite |
Image tile package | TileCache | ArcGISTiledLayer , ArcGISTiledElevationSource | No | No | Lite |
Mobile geodatabase. You can create a geodatabase file (SQLite database) with this API, using ArcGIS Pro or ArcMap, or by downloading offline data from a feature service. | Geodatabase | FeatureLayer | Yes | Yes | Lite |
Scene layer package. For display in scenes only. | N/A. Access a Scene Layer Package (.slpk) file directly from the ArcGIS Scene Layer. | ArcGISSceneLayer | No | No | Lite |
Shapefile | ShapefileFeatureTable | FeatureLayer | Yes | Yes | Standard |
Local raster file. The following raster formats are supported: ASRP/USRP, CIB, CADRG/ECRG, DTED, GeoPackage Raster, GeoTIFF/TIFF, HFA, HRE, IMG, JPEG, JPEG2000, Mosaic Dataset in SQLite, NITF, PNG, RPF, SRTM, CRF, and MrSID. | Raster | RasterLayer | No | No | Standard |
OGC GeoPackage (feature data) | GeoPackageFeatureTable() | FeatureLayer | Yes | Yes | Standard |
OGC GeoPackage (raster data) | GeoPackageRaster | RasterLayer | No | No | Standard |
OGC KML file (.kml file or compressed .kmz file) | KmlDataset | KmlLayer | No | Yes | Standard |
Electronic Nautical Chart (S-57). For display in maps only. Not supported in scenes. | EncCell | EncLayer | No | No | Standard |
Other (e.g. GeoJSON) | FeatureCollection | FeatureCollectionLayer | Yes | Yes | Lite |
Vector tiled layer
Vector tiled layers contain vector representations of data across a range of scales. Unlike raster tiles, they can adapt to the resolution of their display device as you zoom in and out.
When you create a vector tile package, it must be in the same spatial reference as the map in which it will be displayed.
To create a vector tiled layer from the vector tile package (.vtpk
), instantiate an ArcGISVectorTiledLayer
object with the vector tile package's file URL. The default style will be loaded directly from the vector tile package.
// Create the path to the local vector tile package (.vtpk file).
const QString myDocumentsFolder = QStandardPaths::standardLocations(
QStandardPaths::DocumentsLocation).at(0);
const QString tileCachePath(QDir::toNativeSeparators(myDocumentsFolder + "/PencilMapTiles.vtpk"));
// Create a vector tile cache from the local data.
VectorTileCache* vectorTileCache = new VectorTileCache(tileCachePath, this);
// Use the tile cache to create an ArcGIS vector tiled layer.
ArcGISVectorTiledLayer* arcgisVectorTiledLayer = new ArcGISVectorTiledLayer(vectorTileCache, this);
// Create a new basemap from the ArcGIS vector tiled layer.
Basemap* basemap = new Basemap(arcgisVectorTiledLayer, this);
// Create a new map using the basemap.
Map* map = new Map(basemap, this);
// Set the map in the map view.
m_mapView->setMap(map);
Image tiled layer
Image tiled layers are typically used to display pregenerated tiled data as basemaps. A tile cache can also be used to provide offline elevation data for visualizing 3D terrain in a scene. You can take a portion of tiled data and store it within a single tile package (.tpk or .tpkx) file for completely disconnected scenarios. To store a portion of tile data as a tile package, you must specify area of interest, the tiling scheme, the levels of detail, and the tile format using one of the following approaches:
- Run the ArcGIS Pro python tool, Create Map Tile Package, to create a tile package file.
- In ArcMap, choose File > Share As > Tile Package to create a tile package file, as described in the ArcMap topic, How to create a tile package.
- In ArcMap, choose Share as > ArcGIS Runtime Content to export the map's basemap layer to a tile package file (.tpk) that is output within the ArcGIS Runtime Content folder. For details, see the ArcMap topic Creating ArcGIS Runtime content, which is available with ArcGIS 10.2.1 for Desktop or later. Also see ArcMap's tile packages.
When you create a tile package, it must have the same spatial reference as the map in which it will be displayed.
To create a tiled layer from a tile package file, instantiate an ArcGISTiledLayer
object with the path to the tile package file on the device.
// Create the path to the local package (.tpkx file).
const QString myDocumentsFolder = QStandardPaths::standardLocations(
QStandardPaths::DocumentsLocation).at(0);
const QString tileCachePath(QDir::toNativeSeparators(myDocumentsFolder + "/StreetMapTiles.tpkx"));
// Create a tile cache from the local data.
TileCache* tileCache = new TileCache(tileCachePath, this);
// Use the tile cache to create an ArcGIS tiled layer.
ArcGISTiledLayer* arcgisTiledLayer = new ArcGISTiledLayer(tileCache, this);
// Create a new basemap from the ArcGIS tiled layer.
Basemap* basemap = new Basemap(arcgisTiledLayer, this);
// Create a new map using the basemap.
Map* map = new Map(basemap, this);
// Set the map in the map view.
m_mapView->setMap(map);
To create an elevation source from a tile package file, instantiate an ArcGISTiledElevationSource
object with the path to the tile package file on the device.
// Create the path to the local tile cache file (.tpkx).
const QString myDocumentsFolder = QStandardPaths::standardLocations(
QStandardPaths::DocumentsLocation).at(0);
const QString tileCachePath(QDir::toNativeSeparators(myDocumentsFolder + "/WorldElevation3DTiles.tpkx"));
// Create a tile cache from the local data.
TileCache* tileCache = new TileCache(tileCachePath, this);
// Use the tile cache to create an ArcGIS tiled elevation source.
ArcGISTiledElevationSource* arcgisTiledElevationSource = new ArcGISTiledElevationSource(tileCache, this);
// Connect to the ArcGIS tiled elevation source's done loading event.
connect(arcgisTiledElevationSource, &ArcGISTiledElevationSource::doneLoading, this,
[this, arcgisTiledElevationSource](Error e)
{
// Test for any errors and broadcast it.
if (!e.isEmpty())
{
qDebug() << e.message() << ": " << e.additionalMessage();
}
// Create a new surface (default constructor).
Surface* surface = new Surface(this);
// Set the elevation exaggeration (2.0) on the surface.
surface->setElevationExaggeration(2.0);
// Get the elevation source list model from the surface.
ElevationSourceListModel* elevationSourceListModel = surface->elevationSources();
// Append the ArcGIS tiled elevation source to the elevation source list model.
elevationSourceListModel->append(arcgisTiledElevationSource);
// Create a new scene using the 'ArcGIS Community' base map style.
Scene* scene = new Scene(BasemapStyle::ArcGISCommunity, this);
// Set the base surface on the scene.
scene->setBaseSurface(surface);
// Set the gloabal scope scene to the scene.
m_scene = scene;
// Set the scene in the scene view.
m_sceneView->setArcGISScene(scene);
});
// Call the load event on the ArcGIS tiled elevation source.
arcgisTiledElevationSource->load();
Feature layer
Feature layers allow you to display, select, edit, and query individual features and their attributes. You can work with features offline using features stored in a data file, such as a mobile geodatabase file (.geodatabase
), a GeoPackage file (.gpkg
), or a shapefile (.shp
). You can edit feature geometry and attributes, and, when using a mobile geodatabase, can also edit attachments and related records.
Mobile geodatabase
Mobile geodatabases (.geodatabase) can be created with ArcGIS Pro (2.7 or later) or ArcMap (10.2.1 or later). At version 100.14, they can also be created in your app.
To create a mobile geodatabase that you can sideload for use in your app:
-
In ArcGIS Pro, follow the instructions in the ArcGIS Pro help topic Create a mobile geodatabase.
-
In ArcMap, follow the instructions in the ArcMap help topic Creating ArcGIS Runtime content.
To create a mobile geodatabase with this API:
- Use the static function
Geodatabase::create()
to create a new geodatabase at the provided path.
To display tables from a mobile geodatabase:
- Instantiate the
Geodatabase
object by opening an existing geodatabase or creating a new one. In either case, you need to specify a path to the.geodatabase
file. - Instantiate a
FeatureTable
from one of the mobile geodatabase's tables or create a new one using aTableDescription
and associatedFieldDescription
objects and callingGeodatabase::createTableAsync()
. - Create a new
FeatureLayer
from the feature table and add it to the map. Optionally, create a newRenderer
to symbolize features in the layer. If the layer is based on a new geodatabase table, nothing will appear in the layer until features are created.
The following code opens a geodatabase at the given path. If it doesn't exist, a new geodatabase is created at that location and a new table and domain are added. Finally, the table is displayed as a feature layer in the map.
// Get the path to a local geodatabase.
const QString myDocumentsFolder = QStandardPaths::standardLocations(QStandardPaths::TempLocation).at(0);
const QString geodatabasePath(QDir::toNativeSeparators(myDocumentsFolder + "/recreation.geodatabase"));
// Open the geodatabase if the file exists at the specified path.
if (QFile(geodatabasePath).exists())
{
// Get the geodatabase using the path.
Geodatabase* geodatabase = new Geodatabase(geodatabasePath, this);
// Connect to the geodatabase's done loading event.
connect(geodatabase, &Geodatabase::doneLoading, this, [this, geodatabase](Error loadError)
{
// Test for any errors and broadcast it.
if (!loadError.isEmpty())
{
qDebug() << "Geodatabase load error: " << loadError.message() << " : " <<
loadError.additionalMessage();
}
// Access one of the feature tables in the geodatabase using its name ("Trailheads").
GeodatabaseFeatureTable* geodatabaseFeatureTable = geodatabase->
geodatabaseFeatureTable("Trailheads");
// Create a new feature layer from the geodatabase feature table.
FeatureLayer* featureLayer = new FeatureLayer(geodatabaseFeatureTable);
// Get the layer list model from the map's operational layers.
LayerListModel* layerListModel = m_map->operationalLayers();
// Add the feature layer to the layer list model (causing the layer to display).
layerListModel->append(featureLayer);
});
// Call the geodatabase load event.
geodatabase->load();
}
else // If the geodatabase doesn't exist, create it.
{
// Execute the static geodatabase create async method using the supplied path and returning
// a new geodatabase.
Geodatabase::createAsync(geodatabasePath, this).then(this, [this](Geodatabase* geodatabase)
{
// Create a new range domain description in the geodatabase for rating values from 1-10.
RangeDomainDescription* rangeDomainDescription = new RangeDomainDescription
(
"RatingDomain", // range domain name
FieldType::Int16, // rage domain field type
QVariant(1), // minimum value - QVariant
QVariant(10), // maximum value - QVariant
this // parent
);
// Execute the geodatabase's create domain async method using the supplied
// range domain description.
geodatabase->createDomainAsync(rangeDomainDescription).then(this,
[this, geodatabase](Domain domain)
{
// Create a new table description for a "Trailheads" table that will store points.
TableDescription* tableDescription = new TableDescription
(
"Trailheads", // table name
SpatialReference::wgs84(), // table spatial reference
GeometryType::Point // table geometry type
);
// Create a new field description to define the "Name" field.
FieldDescription* fieldDescription = new FieldDescription
(
"Name", // field name
FieldType::Text, // field data type
this // parent
);
// Get the field description list model from the table description.
FieldDescriptionListModel* fieldDescriptionListModel = tableDescription->fieldDescriptions();
// Add the field description to the field description list model.
fieldDescriptionListModel->append(fieldDescription);
// Create a new field description to define the "Difficulty" field.
FieldDescription* difficultyFieldDescription = new FieldDescription
(
"Difficulty", // field name
FieldType::Int16, // field data type
this // parent
);
// Set the domain name of "RatingDomain" for the difficulty field description.
difficultyFieldDescription->setDomainName("RatingDomain");
// Add the field description to the field descripton list model.
fieldDescriptionListModel->append(difficultyFieldDescription);
// Call the geodatabase's create table async method using the supplied table description.
// The returned object is a geodatabase feature table.
geodatabase->createTableAsync(tableDescription, this).then(this, [this]
(GeodatabaseFeatureTable* geodatabaseFeatureTable)
{
// Create a new feature layer from the geodatabase feature table.
FeatureLayer* featureLayer = new FeatureLayer(geodatabaseFeatureTable);
// Get the map from the map view.
Map* map = m_mapView->map();
// Get the layer list model from the map's operational layers.
LayerListModel* layerListModel = map->operationalLayers();
// Add the feature layer to the layer list model.
layerListModel->append(featureLayer);
});
});
});
}
GeoPackage
GeoPackage is an open, standards-based, platform-independent, portable, self-describing, compact format for transferring geospatial information. It uses a single SQLite file (.gpkg
) that conforms to the OGC GeoPackage standard. You can create a GeoPackage file from your own data using the Create SQLite Database tool in ArcGIS Pro.
To display features stored in a GeoPackage file, you must do the following:
- Instantiate the
GeoPackage
with the.gpkg
file path. - Load the
GeoPackage
and then examine its list ofGeoPackageFeatureTable()
s. - Create a
FeatureLayer
from one of theGeoPackageFeatureTable()
s and add it as an operational layer to the map.
// Get the path to a local GeoPackage (.gpkg file).
const QString myDocumentsFolder = QStandardPaths::standardLocations(
QStandardPaths::DocumentsLocation).at(0);
const QString geopackagePath(QDir::toNativeSeparators(myDocumentsFolder + "/trails.gpkg"));
// Create a new geopackage by providing the path.
GeoPackage* geopackage = new GeoPackage(geopackagePath, this);
// Connect to the geodatabase's done loading event.
connect(geopackage, &GeoPackage::doneLoading, this, [this, geopackage](Error e)
{
// Get the QList of geopackage feature tables from the geopackage.
const QList<GeoPackageFeatureTable*> geoPackageFeatureTables = geopackage->geoPackageFeatureTables();
// Iterate over the geopackage feature tables in the QList.
for (GeoPackageFeatureTable* geoPackageFeatureTable : geoPackageFeatureTables)
{
// Get the name of the table in the geopackage feature table.
const QString tableName = geoPackageFeatureTable->tableName();
// Test if the table name is "trailheads".
if (tableName.toLower() == "trailheads")
{
// Create a new feature layer from the geopackage feature table.
FeatureLayer* featureLayer = new FeatureLayer(geoPackageFeatureTable, this);
// Get the map from the map view.
Map* map = m_mapView->map();
// Get the layer list model from the map's operational layers.
LayerListModel* layerListModel = map->operationalLayers();
// Add the feature layer to the layer list model.
layerListModel->append(featureLayer);
}
}
});
// Call the goepackage's load function.
geopackage->load();
Shapefiles
A shapefile is a vector data storage format that contains geometry and attribute data for geographic features. Despite the name, a shapefile dataset is composed of at least four physical files: .shp
, .dbf
, and .shx
. A shapefile may include several other files, such as projection information, spatial indices, attribute indices, and so on.
To create a feature layer from a shapefile (.shp
), do the following:
- Instantiate the
ShapefileFeatureTable
with the path to the shapefile. This path must point to the.shp
file. The.shp
file's associated files (.shx
,.dbf
, and so on) must be present at the same location. - Create a
FeatureLayer
from theShapefileFeatureTable
and add it to the map.
// Get the path to a local shapefile (.shp file).
const QString myDocumentsFolder = QStandardPaths::standardLocations(
QStandardPaths::DocumentsLocation).at(0);
const QString shapefilePath(QDir::toNativeSeparators(myDocumentsFolder + "/trails.shp"));
// Create a shapefile feature table using the path.
ShapefileFeatureTable* shapefileFeatureTable = new ShapefileFeatureTable(shapefilePath, this);
// Connect to the shapefile feature table's done loading event.
connect(shapefileFeatureTable, &ShapefileFeatureTable::doneLoading, this,
[this, shapefileFeatureTable](Error e)
{
// Test if we have any errors and broadcast it.
if (!e.isEmpty())
{
qDebug() << e.message() << ": " << e.additionalMessage();
}
// Create a feature layer from the shapefile feature table.
FeatureLayer* featureLayer = new FeatureLayer(shapefileFeatureTable);
// Get the map from the map view.
Map* map = m_mapView->map();
// Get the layer list model from the map's operational layers.
LayerListModel* layerListModel = map->operationalLayers();
// Add the feature layer to the layer list model.
layerListModel->append(featureLayer);
});
// Call the shapefile feature table load event.
shapefileFeatureTable->load();
Raster layer
Raster data consists of a matrix of cells in which each individual cell contains a value representing information. For example, satellite or aerial images and photographs for visualizing an area. You can define renderers to display the raster data. Several raster formats are supported. To work offline, copy the raster data onto your device and add the raster dataset to your app using the Raster
class. For more information and a list of supported raster formats, See Add raster data.