ArcGIS Runtime SDK for Java

Take a map offline - preplanned

The preplanned workflow allows an organization to prepare offline maps so that they can be taken into the field, as required. The map author creates a map area defined by a specific geographical area of work. This process generates the associated map, tile package and geodatabase files and stores them in a mobile map package. The offline map resides in this mobile map package, in ArcGIS Online or ArcGIS Enterprise, until the field worker downloads it. As soon as the mobile map package is downloaded the field worker can disconnect their device and work with the map offline.

The main advantages of this workflow are:

  • The map author can organise and define very specific map areas for the field workers.
  • The user can obtain the preplanned map area more quickly because the mobile map package has been generated, in advance, by the author. In contrast, during the on-demand workflow the user has to both generate and download the mobile map package to their device.
  • Many users can download exactly the same mobile map package.

The preplanned workflow is outlined in the following steps:

  1. Enable services for offline use
  2. Create preplanned map areas
  3. Identify a map area
  4. Download the map area
  5. Open the offline map

Enable services for offline use (ArcGIS Online/Enterprise)

The author of the web map must ensure that all services contained in the web map can be taken offline. The author can set these options when publishing, or later using any of the service management tools.

Raster and vector tiled services

You can allow tiled services data to be downloaded and used offline by following the instructions here:

Tiled and vector tiled services must have the exportTiles capability enabled.

Feature services

You can allow feature service data to be downloaded, edited, and changes synchronized by following the instructions here:

Feature services must be sync enabled.

The map author must confirm that ArcGIS Online can access these tiled and feature services.

Create preplanned map areas

The preplanned workflow allows you to create a mobile map, in advance, so that it can be downloaded by any field workers when they need it. To do this you need to specify an area of interest, create a map area within a web map, and generate the data packages associated with this map area.

You can do this manually using the ArcGIS Online or ArcGIS Enterprise user interface. Or you can automate these steps using either Python scripts or the ArcGIS REST API.

ArcGIS Online or ArcGIS Enterprise

Manually create, edit, and manage map areas as follows:

Python scripts

Use the ArcGIS API for Python to write python scripts to create map areas and generate their associated data packages. This is detailed in the managing map areas Python topic along with other useful map area management functions such as:

  • Update a map area and any of its packages that have been deleted or contain newer data.
  • Delete an individual data package.
  • Delete a map area along with its associated packages.
  • Inspect any of the map area's packages.
  • List the web map's current map areas.

ArcGIS Rest API

Use the ArcGIS REST API if you need even more control when creating your preplanned map areas. There are two stages to this process:

  • To create a map area you must run the Create Map Area task providing a bookmark or geographical extent as the area of interest. Upon completion the task will generate a new portal item of type MapArea. This task requires that the web map is enabled for offline use. It is only available to the owner of the web map and organization administrators.
  • To create the data defined by the map area you must run the Setup Map Area task providing the map area portal item ID. This will create a set of data files such as tile packages, vector tile packages and SQLite geodatabases. For good data management, we strongly recommend that you also provide a folder to organize these files. This task is only available to the map area portal item owner and organization administrators.

Note:
The map's author can create up to 16 individual map areas per web map.

Once you have created the preplanned map areas, and their related data, they will be ready to download to your device. The following sections describe how you build a Runtime app to download the mobile map package.

Identify a map area

As discussed above, each web map can contain one or more preplanned map areas. Your app needs to determine which map area should be downloaded. You can do this by allowing the field worker to select a map area from a map view or from a list of map areas. Alternatively, the app logic could select a map area for the field worker.

Follow these steps to retrieve all of the map areas:

  1. Instantiate the offline map task by passing either a map (created from a web map) or a web map's portal item to the OfflineMapTask constructor.

    //Create a task from a map
    offlineMapTask = new OfflineMapTask(map);
    
    //or from an online map's portal item
    offlineMapTask = new OfflineMapTask(portalItem);

  2. Retrieve a list of the preplanned map areas from the web map using the getPreplannedMapAreas method on the OfflineMapTask.
  3. Load the preplanned map area; PreplannedMapArea.
  4. Display the map area titles and thumbnails in a list, or show the map area extents or just select a map area by name.

//get all of the preplanned map areas in the web map
ListenableFuture<List<PreplannedMapArea>> mapAreasFuture = offlineMapTask.getPreplannedMapAreasAsync();
mapAreasFuture.addDoneListener(() -> {
  try {
    // get the list of areas
    mapAreas = mapAreasFuture.get();
         // loop through the map areas
    for (PreplannedMapArea mapArea : mapAreas) {
      // load each map area 
      mapArea.loadAsync();
      mapArea.addDoneLoadingListener(() -> {
        // get the map area geometry so it can be used to display a graphic on the map
        Geometry areaGeometry = mapArea.getAreaOfInterest();

        // get the area title so it can be used in a UI component
        String areaTitle = mapArea.getPortalItem().getTitle();
                 // UI code for showing map areas goes here:
      });
    }
  } catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
  }
});

Download the map area

Download the map area as a mobile map package onto your device as follows:

  1. Create download preplanned map parameters
  2. Create a job to download the map area
  3. Run the job

Create download preplanned map parameters

To take a map offline you can provide a set of DownloadPreplannedOfflineMapParameters. To obtain a set of default parameters pass in the map area to the createDefaultDownloadPreplannedOfflineMapParametersAsync method on the OfflineMapTask. The value of these default parameters will match the advanced offline settings configured by the web map author.

Once you have obtained these default parameters you may customize them as required. For example:

  • Continue if a table or layer fails?

    The DownloadPreplannedOfflineMapJob takes a map's tables and layers offline. By default this job will continue to do this even if one table of layer has failed. Failures could be due to an intermittent network connection, loss of the service or an unsupported layer type. The approach ensures that you can take a map offline but you may have some data missing.

    To ensure that the offline map contains all of its layers and tables you can request that the job is stopped if any layer or table fails to download. To do this set the ContinueOnErrors property to false.

  • Which basemap should the map use?

    The author of the web map can define whether the map uses:

    • the basemap defined by the web map

      This is the default situation and ensures that a tile package is downloaded as part of the mobile map package.

    • a tile package that is already on the device

      The tile package must be downloaded or side loaded onto the device and can be located using an actual file path on the device or a path that is relative to the mobile map package. You must ensure that the tile package covers the areas required by your map area. The benefits of this option are that the mobile map package file will be smaller, the download time may be faster, and you can use the tile package in many different maps and apps.

      To use the tile package on your device you must set the referenceBasemapDirectory to the directory which contains the tile package. We recommend that you confirm that the tile package file, referenceBasemapFilename, exists on the device before running the AGSDownloadPreplannedOfflineMapJob. This job will add the tile package, as a basemap, to the offline map.

      Note:

      If this tile package has a different spatial reference to your online map then the offline map will use the spatial of the tile package.

    • No basemap

      If you only want to take the operational layers offline you can programmatically exclude the basemap. To do this set the includeBasemap property to false. In this case the DownloadPreplannedOfflineMapJob will not download layers included as part of the map's basemap. This task will not use the local tile package, even if you have specified one.

Note:

Instead of obtaining the default set of DownloadPreplannedOfflineMapParameters you could construct them manually. The author of the web map can recommended how data is downloaded to offline devices, and subsequently synchronized, by adjusting the map's advanced offline settings. You can access these advanced settings from the map's OfflineSettings. They include:

  • working with feature attachments
  • synchronizing edits
  • downloading a basemap or using one which is already on the device

Create a job to download the map area

Create the download preplanned map area job by calling the downloadPreplannedOfflineMapJob method on the OfflineMapTask. Pass in the PreplannedMapArea and a download directory on the device. If this download directory already exists it must be empty. If the directory doesn't exist, it will be created by the job.

// construct the download preplanned offline map job
downloadPreplannedOfflineMapJob = offlineMapTask.downloadPreplannedOfflineMap(mapArea, downloadDirectory);

If, however, you have created parameters to control the map content you must create the DownloadPreplannedOfflineMapJob using the downloadPreplannedOfflineMapJob method on the OfflineMapTask and provide both the DownloadPreplannedOfflineMapParameters and the download directory.

// construct the download preplanned offline map job with parameters
downloadPreplannedOfflineMapJob =
  offlineMapTask.downloadPreplannedOfflineMap(downloadPreplannedOfflineMapParameters, downloadDirectory);

Run the job

To download the preplanned map area to your device start the DownloadPreplannedOfflineMapJob. Upon completion the job will return an instance of the DownloadPreplannedOfflineMapResult. If at least one table or layer failed to be taken offline the hasErrors property will be true. In this case you should examine the layerErrors and tableErrors dictionaries to identify the problem.

Remember that if the job's ContinueOnErrors parameter has been set to false then the job will be terminated immediately if a single layer or table fails to be taken offline.

If you want to display the map immediately then use the DownloadPreplannedOfflineMapResult.offlineMap.

//start the job
downloadPreplannedOfflineMapJob.start();

// listen for job completion
downloadPreplannedOfflineMapJob.addJobDoneListener(()-> {

  // get the download result
  DownloadPreplannedOfflineMapResult downloadResult = downloadPreplannedOfflineMapJob.getResult();

  // check for errors
  if (downloadResult.hasErrors()) {
    // code here to examine errors:
    Map<Layer, ArcGISRuntimeException> layerErrors = downloadResult.getLayerErrors();
    Map<FeatureTable, ArcGISRuntimeException> tableErrors = downloadResult.getTableErrors();
  } else {
    // no errors so use the map straight away
    map = downloadResult.getOfflineMap();
  }
});

Note:
Note that the job will behave the same whether it was created with or without the DownloadPreplannedOfflineMapParameters.

For more details on how to work with jobs, see the Tasks and jobs topic.

Open the offline map

Offline maps created by the preplanned workflow are stored in an unpacked mobile map package. When your app goes into the field you will need to open the map directly from the mobile map package directory stored on your device. To create the mobile map package object, pass the mobile map package directory path to the MobileMapPackage constructor.

// Create a MobileMapPackage from the offline map directory path
final MobileMapPackage offlineMapPackage = new MobileMapPackage(mMobileMapPackage);
offlineMapPackage.loadAsync();
offlineMapPackage.addDoneLoadingListener(new Runnable() {
  @Override
  public void run() {
    // Get the title from the package metadata
    System.out.println("Title: " + offlineMapPackage.getItem().getTitle());

    // Get the map from the package and set it to the MapView
    mMapView.setMap(offlineMapPackage.getMaps().get(0));
  }
});

Upon loading the offline map, its metadata is accessible using the ArcGISMap.item property. In some situations, you may want to access the metadata from the mobile map package without loading the map itself. You can access this from the MobileMapPackage.item property.

See Display a map for more details on how to access and display maps stored in mobile map packages.