Add vector tiled layer from custom style

View inMAUIWPFWinUIView on GitHubSample viewer app

Load ArcGIS vector tiled layers using custom styles.

Image of offline vector tiled layer custom style

Use case

Vector tile basemaps can be created in ArcGIS Pro and published as offline packages or online services. You can create a custom style tailored to your needs and easily apply them to your map. The layer's colors, patterns, icons, and labels could be modified, for example.

How to use the sample

Pan and zoom to explore the vector tile basemap.

How it works

  1. Create a PortalItem for each vector tiled layer.
  2. Create a Map and set the default Viewpoint.
  3. Export the light and dark offline custom styles.
    i. Create a ExportVectorTilesTask using the portal item.
    ii. Get the path for where the cache is being stored locally.
    iii. Return with the cache if the path already exists.
    iv. Else, create a ExportVectorTilesJob by having the task call ExportStyleResourceCache with the path as a parameter.
    v. Start the job.
    vi. When the job completes, store the result as a ExportVectorTilesResult.
    vii. Return the result's item resource cache.
  4. Update the Basemap and Viewpoint when a new style is selected.

Relevant API

  • ExportVectorTilesJob
  • ExportVectorTilesResult
  • ExportVectorTilesTask
  • VectorTileCache
  • VectorTiledLayer
  • VectorTilesTask

Tags

tiles, vector, vector basemap, vector tiled layer, vector tiles

Sample Code

AddVectorTiledLayerFromCustomStyle.xaml.csAddVectorTiledLayerFromCustomStyle.xaml.csAddVectorTiledLayerFromCustomStyle.xaml
Use dark colors for code blocksCopy
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright 2023 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 ArcGIS.Samples.Managers;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Portal;
using Esri.ArcGISRuntime.Tasks.Offline;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ArcGIS.WPF.Samples.AddVectorTiledLayerFromCustomStyle
{
    [ArcGIS.Samples.Shared.Attributes.Sample(
        name: "Add vector tiled layer from custom style",
        category: "Layers",
        description: "Load ArcGIS vector tiled layers using custom styles.",
        instructions: "Pan and zoom to explore the vector tile basemap.",
        tags: new[] { "tiles", "vector", "vector basemap", "vector tiled layer", "vector tiles" })]
    [ArcGIS.Samples.Shared.Attributes.OfflineData("f4b742a57af344988b02227e2824ca5f")]
    public partial class AddVectorTiledLayerFromCustomStyle
    {
        // ArcGIS Online vector tile layers.
        private readonly string[] _portalItemIDs =
        {
            "1349bfa0ed08485d8a92c442a3850b06",
            "bd8ac41667014d98b933e97713ba8377",
            "02f85ec376084c508b9c8e5a311724fa",
            "1bf0cc4a4380468fbbff107e100f65a5",

            // Offline custom style vector tiled layer will be created once a VTPK is exported.
            "e01262ef2a4f4d91897d9bbd3a9b1075",
            "ce8a34e5d4ca4fa193a097511daa8855"
        };

        // Path to Dodge City vector tile package.
        private readonly string _localVectorPackagePath = DataManager.GetDataFolder("f4b742a57af344988b02227e2824ca5f", "dodge_city.vtpk");

        private List<PortalItem> _vectorTiledLayers = new List<PortalItem>();

        private readonly Viewpoint _defaultViewpoint = new Viewpoint(10, 5.5, 1e8);
        private readonly Viewpoint _dodgeCityViewpoint = new Viewpoint(37.76528, -100.01766, 4e4);

        private ItemResourceCache _lightStyleResourceCache;
        private ItemResourceCache _darkStyleResourceCache;

        public AddVectorTiledLayerFromCustomStyle()
        {
            InitializeComponent();
            _ = Initialize();
        }

        private async Task Initialize()
        {
            try
            {
                // Load the default portal.
                ArcGISPortal portal = await ArcGISPortal.CreateAsync();

                // Store a list all portal items.
                foreach (string itemID in _portalItemIDs)
                {
                    PortalItem portalItem = await PortalItem.CreateAsync(portal, itemID);
                    _vectorTiledLayers.Add(portalItem);
                }

                // Create a map using defaults.
                MyMapView.Map = new Map() { InitialViewpoint = _defaultViewpoint };

                // Populate the combo box.
                StyleChooser.ItemsSource = new string[]
                {
                    "Default",
                    "Style 1",
                    "Style 2",
                    "Style 3",
                    "Offline custom style - Light",
                    "Offline custom style - Dark"
                };

                // Select the default style.
                StyleChooser.SelectedIndex = 0;

                // Export offline custom styles.
                _lightStyleResourceCache = await ExportStyle(_vectorTiledLayers[4]);
                _darkStyleResourceCache = await ExportStyle(_vectorTiledLayers[5]);
            }
            catch (Exception ex)
            {
                // Report exceptions.
                MessageBox.Show("Error: " + ex.Message, ex.GetType().Name, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private async void StyleChooser_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                // Get the style name and index of the selected item.
                await ChangeStyleAsync(StyleChooser.SelectedIndex, StyleChooser.SelectedItem.ToString());
            }
            catch (Exception ex)
            {
                // Report exceptions.
                MessageBox.Show("Error: " + ex.Message, ex.GetType().Name, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private async Task ChangeStyleAsync(int styleIndex, string styleName)
        {
            // Check if the user selected a offline custom style.
            // Create a new basemap with the appropriate style.
            if (styleName.Contains("Offline"))
            {
                // Determine which cache to use based on if the style selected is light or dark.
                ItemResourceCache cache = styleName.Contains("Light") ? _lightStyleResourceCache : _darkStyleResourceCache;

                MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(new VectorTileCache(_localVectorPackagePath), cache));
                await MyMapView.SetViewpointAsync(_dodgeCityViewpoint);
                await cache.LoadAsync();
            }
            else
            {
                MyMapView.Map.Basemap = new Basemap(new ArcGISVectorTiledLayer(_vectorTiledLayers[styleIndex]));
                await MyMapView.SetViewpointAsync(_defaultViewpoint);
            }
        }

        private async Task<ItemResourceCache> ExportStyle(PortalItem vectorTiledLayer)
        {
            try
            {
                // Create the task.
                ExportVectorTilesTask exportTask = await ExportVectorTilesTask.CreateAsync(vectorTiledLayer.Url);

                // Get the item resource path for the basemap styling.
                string itemResourceCachePath = Path.Combine(Path.GetTempPath(), vectorTiledLayer.ItemId + "_styleItemResources");

                // If cache has been created previously, return.
                if (Directory.Exists(itemResourceCachePath) && (Directory.GetFiles(itemResourceCachePath).Length != 0))
                {
                    return new ItemResourceCache(itemResourceCachePath);
                }

                // Create the export job and start it.
                ExportVectorTilesJob job = exportTask.ExportStyleResourceCache(itemResourceCachePath);
                job.Start();

                // Wait for the job to complete.
                ExportVectorTilesResult vectorTilesResult = await job.GetResultAsync();

                return vectorTilesResult.ItemResourceCache;
            }
            catch (Exception ex)
            {
                // Report exceptions.
                MessageBox.Show("Error: " + ex.Message, ex.GetType().Name, MessageBoxButton.OK, MessageBoxImage.Error);
                return null;
            }
        }
    }
}

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