I'm trying to read a local .tpk file on a windows 10 phone using your .NET SDK version 100. I've tried the picture library and then found on the internet this directory is not valid for this SDK. Any help would be appreciated. Thanks
Hi William -
I've dealt with this frustration too.
You can use something like a FileOpenPicker to choose a file, or programmatically access one using StorageLibrary, but you're not guaranteed to have access to the returned file through its Path property (which is what the TileCache constructor takes). If your TPK file is in the app's directory, however, it's pretty easy. Here are a couple of options:
Perhaps the easiest solution is to just package your TPK file(s) with the app. You can add them to your project (in the Assets folder, for example) and give them a Build Action of "Content" and set Copy to Output Directory to "Do not copy". In your app code, you can use an "ms-appx" URI to access things in your app's local folder, like so:
// "Topographic.tpk" is in the application's "Assets" folder: Build action = "Content", Copy = "Do not copy"
var tpkFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Assets/Topographic.tpk"));
// After opening the file from the app's Assets folder, use the path to create the tile cache
TileCache tileCache = new TileCache(tpkFile.Path);
// Load the cache using that file
// Note: this is where an exception is thrown if a file is not accessible
await tileCache.LoadAsync();
// Make a new tiled layer from the local cache
ArcGISTiledLayer localTileLayer = new ArcGISTiledLayer(tileCache);
// Add it to the map
var map = new Map();
map.Basemap.BaseLayers.Add(localTileLayer);
MyMapView.Map = map;
If you still would like your user to select a TPK from their device and add it as a tile layer, you can take the extra step of copying the selected file to the app's local storage. Once there, you can create the TileCache using its Path. Here's an example:
// Create a file picker to get a *.tpk file from the user
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".tpk");
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
// Show the picker and get the selected file
StorageFile selectedFile = await openPicker.PickSingleFileAsync();
if(selectedFile == null) { return; }
// Open the selected .tpk file for read
var stream = await selectedFile.OpenReadAsync();
// Create a local copy of the tpk file; replace if exists
StorageFolder localStorage = ApplicationData.Current.LocalFolder;
StorageFile localTpkFile = await localStorage.CreateFileAsync(selectedFile.Name, CreationCollisionOption.ReplaceExisting);
// Write the contents of the selected .tpk to the new local file
var writeStream = await localTpkFile.OpenStreamForWriteAsync();
stream.AsStreamForRead().CopyTo(writeStream);
writeStream.Flush();
// ** Important to dispose ... won't be able to access the file otherwise!
writeStream.Dispose();
// Create a new TileCache with the path to the *local storage* version of the file
TileCache tileCache = new TileCache(localTpkFile.Path);
await tileCache.LoadAsync();
// Create a new tile layer from the cache and add it to the map
ArcGISTiledLayer localTileLayer = new ArcGISTiledLayer(tileCache);
var map = new Map();
map.Basemap.BaseLayers.Add(localTileLayer);
MyMapView.Map = map;
I hope that helps!
Thad