Switching day/night mode styling for vector tile layer

654
3
Jump to solution
05-03-2022 03:16 AM
JohnFannon
Occasional Contributor III

I have a requirement to have separate basemap styling for day and night mode and are using a local vector tile package for basemaps as part of an MMPK. In theory this should be possible with vector tiles, but I can't find any samples or documentation on how this can be acheived in the runtime SDK.

The ArcGISVectorTiledLayer class constructor seems to have the option of specifying an ItemResourceCache, which appears to offer a way to override styling, but it can't find much in the way of documentation on what the ItemResourceCache format should be or how to create it.

https://developers.arcgis.com/net/api-reference/api/netwin/Esri.ArcGISRuntime/Esri.ArcGISRuntime.Map...

Does anyone know what the format/structure of ItemResourceCache should be or how to create it?

If anyone else has tackled this, I'd be grateful for any insight.

John

0 Kudos
1 Solution

Accepted Solutions
JohnFannon
Occasional Contributor III

After some further investigation and experimentation, I've managed to get this working as follows:

1) Create two VTPKs in Pro for day/night mode with the same data/layers but different styling using Create Vector Tile Package.

2) Extract (unzip) the "resources" folder from each VTPK into it's own directory.

3) Zip the contents of the resulting "resources" folder(s) in uncompressed format (e.g. 7zip "store" option) into a file called resources.zip. Note don't include the "resources" folder itself, just the child folders.

4) Place the VTPK and resources.zip files in a structure similar to below:

  • Root
    • basemap.vtpk
    • style
      • day
        • resources.zip
      • night
        • resources.zip

5) Use code similar to below to:

  • Load a VectorTileCache from the vtpk.
  • Load an ItemResourceCache from the required resources.zip.
  • Create a new ArcGISVectorTiledLayer using the above VectorTileCache and ItemResourceCache.
  • Set the map basemap as the new ArcGISVectorTiledLayer.
public async void SetBasemap(Boolean toggle)
{
	// load tile cache from vtpk
	String localVTPKPath = Path.Combine(_localFolder.Path, "basemap.vtpk");
	VectorTileCache vectorTileCache = new VectorTileCache(localVTPKPath);
	await vectorTileCache.LoadAsync();

	// load resource cache from folder path (should contain an uncompressed zip file called resources.zip containing the vector tile resource cache directory structure
	String resourceCachePath = Path.Combine(_localFolder.Path, @"style\day");
	if (toggle)
	{
		if (_currentBasemapMode == "day")
		{
			resourceCachePath = Path.Combine(_localFolder.Path, @"style\night");
			_currentBasemapMode = "night";
		}
		else
		{
			resourceCachePath = Path.Combine(_localFolder.Path, @"style\day");
			_currentBasemapMode = "day";
		}
	} 

	ItemResourceCache resourceCache = new ItemResourceCache(resourceCachePath);
	await resourceCache.LoadAsync();

	// create new vector tiled layer and set as basemap
	ArcGISVectorTiledLayer vectorTiledLayer = new ArcGISVectorTiledLayer(vectorTileCache, resourceCache);
	_map.Basemap = new Basemap(vectorTiledLayer);

}

 

It's worth noting that VTPKs and the styles (ItemResourceCaches) can also be downloaded from ArcGIS Online/Enterprise using the SDK (see ExportVectorTilesTask). In this case we wanted to avoid using Online/Enterprise, hence the above approach.

View solution in original post

0 Kudos
3 Replies
JohnFannon
Occasional Contributor III

After some further investigation and experimentation, I've managed to get this working as follows:

1) Create two VTPKs in Pro for day/night mode with the same data/layers but different styling using Create Vector Tile Package.

2) Extract (unzip) the "resources" folder from each VTPK into it's own directory.

3) Zip the contents of the resulting "resources" folder(s) in uncompressed format (e.g. 7zip "store" option) into a file called resources.zip. Note don't include the "resources" folder itself, just the child folders.

4) Place the VTPK and resources.zip files in a structure similar to below:

  • Root
    • basemap.vtpk
    • style
      • day
        • resources.zip
      • night
        • resources.zip

5) Use code similar to below to:

  • Load a VectorTileCache from the vtpk.
  • Load an ItemResourceCache from the required resources.zip.
  • Create a new ArcGISVectorTiledLayer using the above VectorTileCache and ItemResourceCache.
  • Set the map basemap as the new ArcGISVectorTiledLayer.
public async void SetBasemap(Boolean toggle)
{
	// load tile cache from vtpk
	String localVTPKPath = Path.Combine(_localFolder.Path, "basemap.vtpk");
	VectorTileCache vectorTileCache = new VectorTileCache(localVTPKPath);
	await vectorTileCache.LoadAsync();

	// load resource cache from folder path (should contain an uncompressed zip file called resources.zip containing the vector tile resource cache directory structure
	String resourceCachePath = Path.Combine(_localFolder.Path, @"style\day");
	if (toggle)
	{
		if (_currentBasemapMode == "day")
		{
			resourceCachePath = Path.Combine(_localFolder.Path, @"style\night");
			_currentBasemapMode = "night";
		}
		else
		{
			resourceCachePath = Path.Combine(_localFolder.Path, @"style\day");
			_currentBasemapMode = "day";
		}
	} 

	ItemResourceCache resourceCache = new ItemResourceCache(resourceCachePath);
	await resourceCache.LoadAsync();

	// create new vector tiled layer and set as basemap
	ArcGISVectorTiledLayer vectorTiledLayer = new ArcGISVectorTiledLayer(vectorTileCache, resourceCache);
	_map.Basemap = new Basemap(vectorTiledLayer);

}

 

It's worth noting that VTPKs and the styles (ItemResourceCaches) can also be downloaded from ArcGIS Online/Enterprise using the SDK (see ExportVectorTilesTask). In this case we wanted to avoid using Online/Enterprise, hence the above approach.

0 Kudos
Daniel_l
New Contributor II

Hi John!

Very interesting solution, but one thing I don´t get is how to "repack" the mmpk after organizing the folders and resources.zip´s?

Best regrds

Daniel

0 Kudos
JohnFannon
Occasional Contributor III

@Daniel_l- I ended up not using an mmpk and so the solution relies on a vtpk being stored somewhere on the file system of the device along with the resources.zip files containing the different styles.