Learn how to download and display an offline map
Offline maps
In this tutorial, you will download an offline map
Before starting this tutorial:
-
You need an ArcGIS Location Platform or ArcGIS Online account.
-
Ensure your development environment meets the system requirements.
Optionally, you may want to install the ArcGIS Maps SDK for .NET to get access to project templates in Visual Studio (Windows only) and offline copies of the NuGet packages.
Develop or download
You have two options for completing this tutorial:
Option 1: Develop the code
To start the tutorial, complete the Display a web map tutorial. This creates a map loaded from a portal item stored in ArcGIS Online. You can choose to implement either API key authentication or user authentication.
Open a Visual Studio solution
- Open the Visual Studio solution you created by completing the Display a web map tutorial.
- Continue with the following instructions to download and display an offline map for a user-defined geographic area of a web map.
Update the tutorial name used in the project (optional)
The Visual Studio solution, project, and the namespace for all classes currently use the name Display. Follow the steps below if you prefer the name to reflect the current tutorial. These steps are not required, your code will still work if you keep the original name.
The tutorial instructions and code use the name Display for the solution, project, and namespace. You can choose any name you like, but it should be the same for each of these.
-
Update the name for the solution and the project.
- In Visual Studio, in the Solution Explorer, right-click the solution name and choose Rename. Provide the new name for your solution.
- In the Solution Explorer, right-click the project name and choose Rename. Provide the new name for your project.
-
Rename the namespace used by classes in the project.
- In the Solution Explorer, expand the project node.
- Double-click MapViewModel.cs in the Solution Explorer to open the file.
- In the
Mapclass, double-click the namespace name (View Model Display) to select it, and then right-click and choose Rename....A Web Map - Provide the new name for the namespace.
- Hit Enter to confirm the new name. This will rename the namespace throughout your project.
-
Build the project.
- Choose Build > Build solution (or press <F6>).
Get the web map item ID
You can use ArcGIS tools
- Go to the Naperville water network
in the Map Viewer
Map Viewer is a browser-based mapping tool that can view, create, and save web maps. It can also perform mapping, visualization, and spatial analysis operations. in ArcGIS OnlineArcGIS Online is a GIS mapping, analytics, data hosting, and content management software as a service (SaaS) product. It includes applications, tools, APIs, and location services for users and developers. It is subscription-based and requires an ArcGIS Online account. . This web mapA web map is a map stored as a JSON object that defines properties such as the basemap layer, data layers, layer styles, and pop-up styles. Its JSON structure is defined by the web map specification. displays stormwater network within Naperville, IL, USA . - Make a note of the item ID
An item ID is a unique identifier representing a single item stored, managed, and accessed in a portal, such as a web map, hosted layer, or file. at the end of the browser's URL. The item ID should be:acc027394bc84c2fb04d1ed317aac674
Display the web map
You can display a web map
-
In the Visual Studio > Solution Explorer, double-click MapViewModel.cs to open the file.
The project uses the Model-View-ViewModel (MVVM) design pattern to separate the application logic (view model) from the user interface (view).
Mapcontains the view model class for the application, calledView Model.cs Map. See the Microsoft documentation for more information about the Model-View-ViewModel pattern.View Model -
Add additional required
usingstatements at the top of the class.MapViewModel.csUse dark colors for code blocks using System; using System.Collections.Generic; using System.Text; using Esri.ArcGISRuntime.Geometry; using Esri.ArcGISRuntime.Mapping; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Esri.ArcGISRuntime.Portal; using Esri.ArcGISRuntime.Symbology; using Esri.ArcGISRuntime.Tasks.Offline; using Esri.ArcGISRuntime.UI; using System.Windows; using System.Diagnostics; using System.Drawing; -
In MapViewModel.cs, modify the
Setupfunction to update the web map's item IDMap() An item ID is a unique identifier representing a single item stored, managed, and accessed in a portal, such as a web map, hosted layer, or file. to that of the Naperville water network.The existing code creates a
PortalItemusing the item IDAn item ID is a unique identifier representing a single item stored, managed, and accessed in a portal, such as a web map, hosted layer, or file. and anArcGISPortalreferencing ArcGIS OnlineArcGIS Online is a GIS mapping, analytics, data hosting, and content management software as a service (SaaS) product. It includes applications, tools, APIs, and location services for users and developers. It is subscription-based and requires an ArcGIS Online account. . It sets theMapproperty to a newView Model. Map Mapcreated using thePortalItem.MapViewModel.csUse dark colors for code blocks private async Task SetupMap() { // Create a portal pointing to ArcGIS Online. ArcGISPortal portal = await ArcGISPortal.CreateAsync(); // Create a portal item for a specific web map id. string webMapId = "acc027394bc84c2fb04d1ed317aac674"; PortalItem mapItem = await PortalItem.CreateAsync(portal, webMapId); // Create the map from the item. Map map = new Map(mapItem); // Set the view model "Map" property. this.Map = map; -
Click Debug > Start Debugging (or press <F5> on the keyboard) to run the app. If your app uses user authentication, enter your ArcGIS Online credentials when prompted.
You should see a map of the stormwater network within Naperville, IL, USA . Use the mouse to drag, scroll, and double-click the map view to explore the map.
Specify an area of the web map to take offline
You can specify an area of the web mapEnvelope or a Polygon. You can use a graphic to display the area on the map.
-
In the MapViewModel class, create a new property named
Graphics. This will be a collection ofOverlays GraphicsOverlayto display a graphicA graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. of the area to take offline.Use dark colors for code blocks private Map? _map; public Map? Map { get { return _map; } set { _map = value; OnPropertyChanged(); } } private GraphicsOverlayCollection? _graphicsOverlays; public GraphicsOverlayCollection? GraphicsOverlays { get { return _graphicsOverlays; } set { _graphicsOverlays = value; OnPropertyChanged(); } } -
Modify the
Setupfunction. Use anMap() EnvelopeBuilderto create a newEnvelopethat defines an area to take offline.MapViewModel.csUse dark colors for code blocks // Set the view model "Map" property. this.Map = map; // Define area of interest (envelope) to take offline. EnvelopeBuilder envelopeBldr = new EnvelopeBuilder(SpatialReferences.Wgs84) { XMin = -88.1526, XMax = -88.1490, YMin = 41.7694, YMax = 41.7714 }; Envelope offlineArea = envelopeBldr.ToGeometry(); -
Display a graphic of the area to take offline.
Use a
SimpleLineSymboland aSimpleFillSymbolto display a newGraphicof theofflinewith a red outline. Add the graphic to a newArea GraphicsOverlayand set theMapproperty to display it in the map view.View Model. Graphics Overlays MapViewModel.csUse dark colors for code blocks Envelope offlineArea = envelopeBldr.ToGeometry(); // Create a graphic to display the area to take offline. SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Red, 2); SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Solid, Color.Transparent, lineSymbol); Graphic offlineAreaGraphic = new Graphic(offlineArea, fillSymbol); // Create a graphics overlay and add the graphic. GraphicsOverlay areaOverlay = new GraphicsOverlay(); areaOverlay.Graphics.Add(offlineAreaGraphic); // Add the overlay to a new graphics overlay collection. GraphicsOverlayCollection overlays = new GraphicsOverlayCollection { areaOverlay }; // Set the view model's "GraphicsOverlays" property (will be consumed by the map view). this.GraphicsOverlays = overlays; -
In the Visual Studio > Solution Explorer, double-click MainWindow.xaml to open the file.
-
Use data binding to bind the
Graphicsproperty of theOverlays Mapto theView Model MapViewcontrol.Data binding and the Model-View-ViewModel (MVVM) design pattern allow you to separate the logic in your app (the view model) from the presentation layer (the view).
Use dark colors for code blocks <esri:MapView x:Name="MyMapView" Map="{Binding Map, Source={StaticResource MapViewModel}}" GraphicsOverlays="{Binding GraphicsOverlays, Source={StaticResource MapViewModel}}" /> -
Click Debug > Start Debugging (or press <F5> on the keyboard) to run the app. If your app uses user authentication, enter your ArcGIS Online credentials when prompted.
You should see a red outline on the stormwater network within Naperville, IL, USA . This indicates the area of the web map that you are going to take offline.
Download and display the offline map
You can generate and download an offline map
-
Return to the MapViewModel.cs file and add code to the
Setupfunction to create anMap OfflineMapTaskthat references the online map by calling the staticOfflineMapTask.CreateAsyncmethod.MapViewModel.csUse dark colors for code blocks // Set the view model's "GraphicsOverlays" property (will be consumed by the map view). this.GraphicsOverlays = overlays; // Create an offline map task using the current map. OfflineMapTask offlineMapTask = await OfflineMapTask.CreateAsync(map); -
Get default parameters to generate and download the offline map
An offline map is a map area and its data content downloaded from an offline-enabled web map for use in offline applications built with ArcGIS Maps SDKs for Native Apps. . Modify them to download a read-only offline map.This tutorial does not involve editing and updating the contents of the offline map. When an offline map is editable, metadata is stored in ArcGIS to track and synchronize edits. Setting the
GenerateOfflineMapUpdateModetoNoavoids the overhead of maintaining this metadata in ArcGIS.Updates MapViewModel.csUse dark colors for code blocks // Create an offline map task using the current map. OfflineMapTask offlineMapTask = await OfflineMapTask.CreateAsync(map); // Create a default set of parameters for generating the offline map from the area of interest. GenerateOfflineMapParameters parameters = await offlineMapTask.CreateDefaultGenerateOfflineMapParametersAsync(offlineArea); parameters.UpdateMode = GenerateOfflineMapUpdateMode.NoUpdates; -
Set a download location for the offline map
An offline map is a map area and its data content downloaded from an offline-enabled web map for use in offline applications built with ArcGIS Maps SDKs for Native Apps. .MapViewModel.csUse dark colors for code blocks // Create a default set of parameters for generating the offline map from the area of interest. GenerateOfflineMapParameters parameters = await offlineMapTask.CreateDefaultGenerateOfflineMapParametersAsync(offlineArea); parameters.UpdateMode = GenerateOfflineMapUpdateMode.NoUpdates; // Build a folder path named with today's date/time in the "My Documents" folder. string documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string downloadDirectory = System.IO.Path.Combine(documentsFolder, "OfflineMap_" + DateTime.Now.ToFileTime().ToString());This tutorial code creates a new unique folder in the documents folder using the current date and time.
-
Create a new
GenerateOfflineMapJobusing theparametersanddownload.Directory MapViewModel.csUse dark colors for code blocks // Build a folder path named with today's date/time in the "My Documents" folder. string documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string downloadDirectory = System.IO.Path.Combine(documentsFolder, "OfflineMap_" + DateTime.Now.ToFileTime().ToString()); GenerateOfflineMapJob generateJob = offlineMapTask.GenerateOfflineMap(parameters, downloadDirectory); -
Create a function called
Generate. This function will respond when the job completes or fails and will track the precent complete as the job runs. Add aJob _Progress Changed try/catchblock to handle exceptions and start by getting a reference to theGenerateOfflineMapJob, passed in as thesenderargument.MapViewModel.csUse dark colors for code blocks // Build a folder path named with today's date/time in the "My Documents" folder. string documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string downloadDirectory = System.IO.Path.Combine(documentsFolder, "OfflineMap_" + DateTime.Now.ToFileTime().ToString()); GenerateOfflineMapJob generateJob = offlineMapTask.GenerateOfflineMap(parameters, downloadDirectory); } private async void GenerateJob_ProgressChanged(object? sender, EventArgs e) { try { var generateJob = sender as GenerateOfflineMapJob; if(generateJob == null) { return; } } catch (Exception ex) { MessageBox.Show($"Error generating offline map: {ex.Message}"); } } -
If the job succeeds, set the
Mapproperty with the offline map result. If it fails, notify the user. If the job is running, write the percent complete to the console.View Model. Map MapViewModel.csUse dark colors for code blocks try { var generateJob = sender as GenerateOfflineMapJob; if(generateJob == null) { return; } // If the job succeeds, show the offline map in the map view. if (generateJob.Status == Esri.ArcGISRuntime.Tasks.JobStatus.Succeeded) { var result = await generateJob.GetResultAsync(); this.Map = result.OfflineMap; Debug.WriteLine("Generate offline map: Complete"); } // If the job fails, notify the user. else if (generateJob.Status == Esri.ArcGISRuntime.Tasks.JobStatus.Failed) { MessageBox.Show($"Unable to generate a map for that area: {generateJob?.Error?.Message}"); } else { int percentComplete = generateJob.Progress; Debug.WriteLine($"Generate offline map: {percentComplete}%"); } } catch (Exception ex) { MessageBox.Show($"Error generating offline map: {ex.Message}"); } -
Return to your code in
Setupand assign theMap Generatefunction to handle theJob _Progress Changed Job.ProgressChanged()event.MapViewModel.csUse dark colors for code blocks GenerateOfflineMapJob generateJob = offlineMapTask.GenerateOfflineMap(parameters, downloadDirectory); generateJob.ProgressChanged += GenerateJob_ProgressChanged; -
Start the
generateby calling itsJob Job.Start()method.MapViewModel.csUse dark colors for code blocks GenerateOfflineMapJob generateJob = offlineMapTask.GenerateOfflineMap(parameters, downloadDirectory); generateJob.ProgressChanged += GenerateJob_ProgressChanged; generateJob.Start(); } -
Click Debug > Start Debugging (or press <F5> on the keyboard) to run the app. If your app uses user authentication, enter your ArcGIS Online credentials when prompted.
You should see an offline map
Alternatively, you can download the tutorial solution, as follows.
Option 2: Download the solution
-
Click the Download solution link in the right-hand panel of the page.
-
Unzip the file to a location on your machine.
-
Open the
.slnfile in Visual Studio.
Since the downloaded solution does not contain authentication credentials, you must first set up authentication to create credentials, and then add the developer credentials to the solution.
Set up authentication
To access the secure ArcGIS location services
You can implement API key authentication or user authentication in this tutorial. Compare the differences below:
API key authentication
- Users are not required to sign in.
- Requires creating an API key credential
API key credentials are an item that contains the parameters used to create and manage long-lived access tokens for API key authentication. They are a type of developer credential. with the correct privileges. - API keys
An API key is a long-lived access token created using API key credentials. They are valid for up to one year and are typically embedded directly into client applications. are long-lived access tokens. - Service usage is billed to the API key owner/developer.
- Simplest authentication method to implement.
- Recommended approach for new ArcGIS developers.
Learn more in API key authentication.
User authentication
- Users are required to sign in with an ArcGIS account
An ArcGIS account is an identity with a user type and set of privileges that can access specific ArcGIS products, tools, APIs, services, and resources. The main account types that can be used for development are an ArcGIS Location Platform account, ArcGIS Online account, and ArcGIS Enterprise account. ArcGIS Location Platform and ArcGIS Online accounts are also associated with a subscription. . - User accounts must have privilege
Privileges are a set of permissions assigned to ArcGIS accounts, developer credentials, and applications that grant access to secure resources and functionality in ArcGIS. to access the ArcGIS servicesA service, also known as an ArcGIS service, is software that supports an ArcGIS REST API and provides geospatial functionality or data. A service can be hosted by Esri or in ArcGIS Enterprise. used in application. - Requires creating OAuth credentials
OAuth credentials are an item that contains parameters required to implement user authentication or app authentication, including a .client_id,client_secret, and redirect URIs. They are a type of developer credential. - Application uses a redirect URL and client ID.
- Service usage is billed to the organization of the user signed into the application.
Learn more in User authentication.
To complete this tutorial, click on the tab in the switcher below for your authentication type of choice, either API key authentication or User authentication.
Create a new API key access token
-
Complete the Create an API key tutorial and create an API key with the following privilege(s)
Privileges are a set of permissions assigned to ArcGIS accounts, developer credentials, and applications that grant access to secure resources and functionality in ArcGIS. :- Privileges
- Location services > Basemaps
- Privileges
-
Copy and paste the API key access token into a safe location. It will be used in a later step.
Set developer credentials in the solution
To allow your app users to access ArcGIS location services
-
In Visual Studio, in the Solution Explorer, click App.xaml.cs to open the file.
-
Set the
ArcGISproperty with your API key access token.Environment. Api Key App.xaml.csUse dark colors for code blocks protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // Set the access token for ArcGIS Maps SDK for .NET. Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_ACCESS_TOKEN"; // Call a function to set up the AuthenticationManager for OAuth. UserAuth.ArcGISLoginPrompt.RegisterOAuthConfig(); } -
Remove the code that sets up user authentication.
App.xaml.csUse dark colors for code blocks protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // Set the access token for ArcGIS Maps SDK for .NET. Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_ACCESS_TOKEN"; // Call a function to set up the AuthenticationManager for OAuth. UserAuth.ArcGISLoginPrompt.RegisterOAuthConfig(); }
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
Click Debug > Start Debugging (or press <F5> on the keyboard) to run the app. If your app uses user authentication, enter your ArcGIS Online credentials when prompted.
You should see an offline map
What's next?
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: