Create and share a mobile geodatabase.
Use case
A mobile geodatabase is a collection of various types of GIS datasets contained in a single file (.geodatabase
) on disk that can store, query, and manage spatial and nonspatial data. Mobile geodatabases are stored in a SQLite database and can contain up to 2 TB of portable data. Users can create, edit and share mobile geodatabases across ArcGIS Pro, ArcGIS Maps SDK for Native Apps, or any SQL software. These mobile geodatabases support both viewing and editing and enable new offline editing workflows that don't require a feature service.
For example, a user would like to track the location of their device at various intervals to generate a heat map of the most visited locations. The user can add each location as a feature to a table and generate a mobile geodatabase. The user can then instantly share the mobile geodatabase to ArcGIS Pro to generate a heat map using the recorded locations stored as a geodatabase feature table.
How to use the sample
Tap on the map to add a feature symbolizing the user's location. Tap "View table" to view the contents of the geodatabase feature table. Once you have added the location points to the map, tap the "Close" button to retrieve the .geodatabase
file which can then be imported into ArcGIS Pro or opened in an ArcGIS application. Tap the "Create" button to make another geodatabase.
How it works
- Create the
Geodatabase
from the mobile geodatabase location on file. - Create a new
TableDescription
and add theFieldDescription
s to the table description. - Create a
GeodatabaseFeatureTable
in the geodatabase from theTableDescription
usingGeodatabase.CreateTableAsync()
. - Create a feature on the selected map point using
GeodatabaseFeatureTable.CreateFeature(featureAttributes, mapPoint)
. - Add the feature to the table using
GeodatabaseFeatureTable.AddFeatureAsync(feature)
. - Each feature added to the
GeodatabaseFeatureTable
is committed to the mobile geodatabase file. - Close the mobile geodatabase to safely share the ".geodatabase" file using
Geodatabase.close()
Relevant API
- ArcGISFeature
- FeatureLayer
- FeatureTable
- FieldDescription
- Geodatabase
- GeodatabaseFeatureTable
- TableDescription
Additional information
Learn more about mobile geodatabases and how to utilize them on the ArcGIS Pro documentation page. The following mobile geodatabase behaviors are supported in ArcGIS Maps SDK for .NET: annotation, attachments, attribute rules, contingent values, dimensions, domains, feature-linked annotation, subtypes, utility network and relationship classes.
Learn more about the types of fields supported with mobile geodatabases on the ArcGIS Pro documentation page.
Tags
arcgis pro, database, feature, feature table, geodatabase, mobile geodatabase, sqlite
Sample Code
// Copyright 2022 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: http://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.
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Mapping;
using Map = Esri.ArcGISRuntime.Mapping.Map;
namespace ArcGIS.Samples.CreateMobileGeodatabase
{
[ArcGIS.Samples.Shared.Attributes.Sample(
name: "Create mobile geodatabase",
category: "Data",
description: "Create and share a mobile geodatabase.",
instructions: "Tap on the map to add a feature symbolizing the user's location. Tap \"View table\" to view the contents of the geodatabase feature table. Once you have added the location points to the map, tap the \"Close\" button to retrieve the `.geodatabase` file which can then be imported into ArcGIS Pro or opened in an ArcGIS application. Tap the \"Create\" button to make another geodatabase.",
tags: new[] { "arcgis pro", "database", "feature", "feature table", "geodatabase", "mobile geodatabase", "sqlite" })]
public partial class CreateMobileGeodatabase : ContentPage, IDisposable
{
private GeodatabaseFeatureTable _featureTable;
private Geodatabase _geodatabase;
private string _gdbPath;
private string _directoryPath;
public CreateMobileGeodatabase()
{
InitializeComponent();
_ = Initialize();
}
private async Task Initialize()
{
// Create a map.
MyMapView.Map = new Map(BasemapStyle.ArcGISTopographic);
MyMapView.SetViewpoint(new Viewpoint(39.323845, -77.733201, 10000.0));
await CreateGeodatabase();
}
private async Task CreateGeodatabase()
{
try
{
// Create a new randomly named directory for the geodatabase.
#if WINUI
_directoryPath = Path.Combine(Environment.ExpandEnvironmentVariables("%TEMP%"), "CreateMobileGeodatabase", Guid.NewGuid().ToString());
#else
_directoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "CreateMobileGeodatabase", Guid.NewGuid().ToString());
#endif
if (!Directory.Exists(_directoryPath))
{
Directory.CreateDirectory(_directoryPath);
}
// Create the geodatabase file.
_gdbPath = Path.Combine(_directoryPath, "LocationHistory.geodatabase");
// Delete existing file if present from previous sample run.
if (File.Exists(_gdbPath))
{
File.Delete(_gdbPath);
}
_geodatabase = await Geodatabase.CreateAsync(_gdbPath);
// Construct a table description which stores features as points on a map.
var tableDescription = new TableDescription("LocationHistory", SpatialReferences.Wgs84, GeometryType.Point)
{
HasAttachments = false,
HasM = false,
HasZ = false
};
// Set up the fields for the table:
// FieldType.OID is the primary key of the SQLite table.
// FieldType.Date is a date column used to store a Calendar date.
// FieldDescriptions can be a SHORT, INTEGER, GUID, FLOAT, DOUBLE, DATE, TEXT, OID, GLOBALID, BLOB, GEOMETRY, RASTER, or XML.
tableDescription.FieldDescriptions.Add(new FieldDescription("oid", FieldType.OID));
tableDescription.FieldDescriptions.Add(new FieldDescription("collection_timestamp", FieldType.Date));
// Add a new table to the geodatabase by creating one from the table description.
_featureTable = await _geodatabase.CreateTableAsync(tableDescription);
// Refresh the UI for the new empty table.
await UpdateTable();
// Create a feature layer for the map.
FeatureLayer featureLayer = new FeatureLayer(_featureTable);
MyMapView.Map.OperationalLayers.Add(featureLayer);
// Add an event handler for new feature taps.
MyMapView.GeoViewTapped += MyMapView_GeoViewTapped;
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert(ex.GetType().Name, ex.Message, "OK");
}
}
private void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.Maui.GeoViewInputEventArgs e)
{
_ = AddFeature(e.Location);
}
private async Task AddFeature(MapPoint location)
{
// Create an attributes dictionary for the feature.
var attributes = new Dictionary<string, object>();
// Add a timestamp of when the feature was created.
attributes["collection_timestamp"] = DateTime.Now;
// Create the feature.
Feature feature = _featureTable.CreateFeature(attributes, location);
try
{
// Add the feature to the feature table.
await _featureTable.AddFeatureAsync(feature);
// Update the UI.
await UpdateTable();
FeaturesLabel.Text = $"Number of features added: {_featureTable.NumberOfFeatures}";
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert(ex.GetType().Name, ex.Message, "OK");
}
}
private async Task UpdateTable()
{
// Query all of the features in the feature table.
FeatureQueryResult queryFeatureResult = await _featureTable.QueryFeaturesAsync(new QueryParameters());
// Set the items source for the data grid with the updated query result.
FeatureListView.ItemsSource = queryFeatureResult;
}
private void ViewTable(object sender, EventArgs e)
{
TableFrame.IsVisible = true;
}
private void CloseTable(object sender, EventArgs e)
{
TableFrame.IsVisible = false;
}
private void CloseGeodatabaseClick(object sender, EventArgs e)
{
try
{
// Clear the UI.
MyMapView.GeoViewTapped -= MyMapView_GeoViewTapped;
CloseGdbButton.IsEnabled = false;
CreateGdbButton.IsEnabled = true;
MyMapView.Map.OperationalLayers.Clear();
FeatureListView.ItemsSource = null;
FeaturesLabel.Text = $"Number of features added:";
// Close the geodatabase.
_geodatabase.Close();
#if WINDOWS
// Instead of using the Windows share feature, this call opens the folder containing the geodatabase file with the file explorer.
_ = Windows.System.Launcher.LaunchFolderPathAsync(_directoryPath);
#else
_ = ShareFile();
#endif
}
catch (Exception ex)
{
Application.Current.MainPage.DisplayAlert(ex.GetType().Name, ex.Message, "OK");
}
}
private async Task ShareFile()
{
try
{
// Share the file using the Microsoft.Maui share feature.
await Share.RequestAsync(new ShareFileRequest
{
Title = "Share geodatabase",
File = new ShareFile(_gdbPath)
});
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert(ex.GetType().Name, ex.Message, "OK");
}
}
private void CreateGdbButton_Click(object sender, EventArgs e)
{
_ = CreateGeodatabase();
CloseGdbButton.IsEnabled = true;
CreateGdbButton.IsEnabled = false;
}
public void Dispose()
{
// Close the geodatabase.
_geodatabase?.Close();
}
}
}