Generate offline map

View inQMLC++
View on GitHub
Sample viewer app

Take a web map offline.

screenshot

Use case

Taking a web map offline allows users continued productivity when their network connectivity is poor or nonexistent. For example, by taking a map offline, a field worker inspecting utility lines in remote areas could still access a feature's location and attribute information.

How to use the sample

When the app starts, you will be prompted to sign in using an ArcGIS Online account. Once the map loads, zoom to the extent you want to take offline. The red border shows the extent that will be downloaded. Click the "Take Map Offline" button to start the offline map job. The progress bar will show the job's progress. When complete, the offline map will replace the online map in the map view.

How it works

  1. Create a Map with a Portal item pointing to the web map.
  2. Create GenerateOfflineMapParameters specifying the download area geometry, minimum scale, and maximum scale.
  3. Create an OfflineMapTask with the map.
  4. Create the OfflineMapJob with OfflineMapTask::generateOfflineMap(params, downloadDirectoryPath) and start it with OfflineMapJob::start().
  5. When the job is done, get the offline map with OfflineMapJob::result()::offlineMap().

Relevant API

  • GenerateOfflineMapJob
  • GenerateOfflineMapParameters
  • GenerateOfflineMapResult
  • OfflineMapTask
  • Portal

About the data

The map used in this sample shows the stormwater network within Naperville, IL, USA, with cartography designed for web and mobile devices with offline support.

Additional information

The creation of the offline map can be fine-tuned using parameter overrides for feature layers, or by using local basemaps. For examples on these, please consult the samples, "Generate Offline Map (Overrides)" and "Generate offline map with local basemap".

Tags

download, offline, save, web map

Sample Code

GenerateOfflineMap.qmlDownloadButton.qmlGenerateOfflineMap.cppGenerateOfflineMap.hGenerateWindow.qml
                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// [WriteFile Name=GenerateOfflineMap, Category=Maps]
// [Legal]
// Copyright 2017 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.
// [Legal]

import QtQuick 2.6
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Esri.Samples 1.0
import Esri.ArcGISRuntime.Toolkit 100.11

GenerateOfflineMapSample {
    id: offlineMapSample
    clip: true
    width: 800
    height: 600

    onUpdateStatus: generateWindow.statusText = status;
    onUpdateProgress: generateWindow.progressText = progress;
    onHideWindow: {
        generateWindow.hideWindow(time);

        if (success) {
            extentRectangle.visible = false;
            downloadButton.visible = false;
        }
    }

    onShowLayerErrors: {
        msgDialog.detailedText = error;
        msgDialog.open();
    }

    // add a mapView component
    MapView {
        id: mapView
        anchors.fill: parent
        objectName: "mapView"

        // Create a button and anchor it to the attribution top
        DownloadButton {
            id: downloadButton
            anchors {
                horizontalCenter: parent.horizontalCenter
                bottom: mapView.attributionTop
                margins: 5
            }
            visible: mapLoaded

            onButtonClicked: {
                generateMapByExtent(extentRectangle.x, extentRectangle.y, (extentRectangle.x + extentRectangle.width), (extentRectangle.y + extentRectangle.height));
                generateWindow.visible = true;
            }
        }
    }

    // Create an extent rectangle for selecting the offline area
    Rectangle {
        id: extentRectangle
        anchors.centerIn: parent
        width: parent.width - 50
        height: parent.height - 125
        color: "transparent"
        visible: mapLoaded
        border {
            color: "red"
            width: 3
        }
    }

    GenerateWindow {
        id: generateWindow
        anchors.fill: parent
    }

    Dialog {
        id: msgDialog
        modal: true
        x: Math.round(parent.width - width) / 2
        y: Math.round(parent.height - height) / 2
        standardButtons: Dialog.Ok
        title: "Layer Errors"
        property alias text : textLabel.text
        property alias detailedText : detailsLabel.text
        ColumnLayout {
            Text {
                id: textLabel
                text: "Some layers could not be taken offline."
            }
            Text {
                id: detailsLabel
            }
        }
    }

    /* Uncomment this section when running as standalone application
    AuthenticationView {
        anchors.fill: parent
    }
    */
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.