Select to view content in your preferred language

Cannot delete vtpk file after basemap layer has been removed and deleted

185
5
3 weeks ago
Labels (3)
LeeCarter
Emerging Contributor

I'm using Qt6.5.2 with ArcGIS Maps SDK for Qt 200.2.0 with an offline application that displays 2D maps.

Two basemaps (one .tpk and one .vtpk) plus operational layers (tpk's) are being loaded and can be made visible/not visible as required with no issues at all.

I want to be able to unload and delete individual base maps or operational layers so that the offline file associated can be deleted (and possibly another file copied to the same location/name to replace it and then be loaded and displayed).  The reason for this is the base map .vtpk file is over 50GB in size so I don't want unused files of that size hanging around.

The .tpk base map is loaded first and appended to the collection of base map base layers, so it will have an index of zero in the LayerListModel. The .vtpk base map is loaded second so will have an index of 1.

An illustration of the code to load the .vtpk base map within a class derived from Esri::ArcGISRuntime::MapGraphicsView is shown here:

 

ArcGISVectorTiledLayer* basemapLayer_p = new ArcGISVectorTiledLayer(new VectorTileCache(basemapFilename, this), this);
basemapLayer_p->setName(basemapFilename);
basemapLayer_p->setMaxScale(MapScaleFromZoomLevel(MaximumZoomLevel));
basemapLayer_p->setMinScale(MapScaleFromZoomLevel(MinimumZoomLevel));

connect(basemapLayer_p, &Layer::doneLoading, this, &MyMapView::layerFinishedLoading,  Qt::QueuedConnection);
basemapLayer_p->load();

basemapLayer_p->setVisible(true);

map()->basemap()->baseLayers()->append(basemapLayer_p);

 

 

Code for the .tpk base map and operational layers are similar (but using different ArcGIS classes for the TiledLayer and TilesCache). All works fine and the application is notified when the loading of each of the layers is completed.

Later when the user selects a file to use in place of an existing base map or operational layer, everything seems to work OK for the .tpk base map and operational layers but there is a problem with the .vtpk base map.

An illustration of the code to remove and delete the layer (and cache) and then the disk file is shown below:

 

ArcGISVectorTiledLayer* basemapLayerToDelete_p = map()->basemap()->baseLayers()->at(1);
map()->basemap()->baseLayers()->removeAt(1);

VectorTileCache* cache_p = basemapLayerToDelete_p->vectorTileCache();

delete basemapLayerToDelete_p;
delete cache_p;

if (!QFile::remove(basemapFilename))
{
    // remove fails and other investigations shows it is a 
    // "The process cannot access the file because it is being used by another process"
    // type of error situation
}

 

As indicated by the comment towards the end of the code fragment, the operation to remove the file fails and when using std C++ rather than Qt methods to try and remove it the error information available indicated that the file was still being used.

Initially, I tried just removing and deleting the base map layer but thinking that the VectorTileCache might not be being deleted by the ArcGISVectorTiledLayer I am now getting the pointer for the cache and deleting that too - with no different result.

I cannot see the internals of the ArcGIS Maps SDK for Qt so I do not know when/what opens the .vtpk file and when it is closed.  I don't see any methods/signals related to unloading a layer of any type.

I've looked for other inspiration on how to fix this and the closest thing I found was a post in the .NET area from over 4 years ago (https://community.esri.com/t5/net-maps-sdk-questions/can-t-delete-vtpk-file-after-loading/m-p/195154...) but that did not have anyone reporting a successful fix.

Am I missing something? I would be grateful if someone is able to advise how to make a (large) .vtpk file close and know when it has been closed so the physical file can be deleted from the disk.

0 Kudos
5 Replies
GuillaumeBelz
Esri Contributor

Hello LeeCarter

Sorry for the delay to reply. We will look at this internally and get back to you quickly to give a more precise answer.

Thank you

Guillaume

0 Kudos
bnoble0110
Esri Contributor

Hello LeeCarter,

At the moment, I'm unable to reproduce the behavior you're seeing. I've attached a small project that contains the code snippets you've provided. Your second block of logic (removing the file) is attached to the "Click me" button press event.

The project is set up to work with a local copy of this Arcgis VTPK, but you can swap in your vtpk file. I noticed your vtpk file was 50GB, so I tried a larger U.S. Forestry Service VTPK at 12GB but was still unable to see the issue you're facing.

Can you tell us if you can reproduce the issue with our attached project? If you can't, can you provide us with a simple reproducer or share more information about your workflow?

0 Kudos
bnoble0110
Esri Contributor

Hello LeeCarter,

My original testing was on macOS. I've switched over to Windows and I see the behavior you're describing, apologies for the initial confusion. We are investigating this further. 

0 Kudos
LeeCarter
Emerging Contributor

Thank you for the update - I was just coming to download the project you attached to try but I guess I can hold off on that now.  Apologies that I did not specify which OS I was working with - it is Windows 10 and 11.  Also, the compiler toolset being used is provided with VS 2019 but it is QtCreator that is being used as the IDE.

0 Kudos
bnoble0110
Esri Contributor

Hello LeeCarter

At the moment I have found a work around that, while not ideal, will allow you to delete the file.

 

ArcGISVectorTiledLayer* basemapLayerToDelete_p = map()->basemap()->baseLayers()->at(1);
map()->basemap()->baseLayers()->removeAt(1);

VectorTileCache* cache_p = basemapLayerToDelete_p->vectorTileCache();

// Clone the old map after the VTPK layer is removed
Map* old_map = m_map;
Map* new_map = dynamic_cast<Map*>(old_map->clone(this));

// Set the m_mapView's map to the new cloned map
m_map = new_map;
m_mapView->setMap(m_map);

// Delete the old map as well.
delete basemapLayerToDelete_p;
delete cache_p;
delete old_map;

if (!QFile::remove(basemapFilename))
{
   ...
}

 

 

When I test this locally this does allow for the VTPK file to be removed, while also preserving any other layers you may have had on the map. We are continuing to investigate this internally, but hopefully this can get you around your issue for the time being.

If this doesn't work, please let me know and we'll see if we can find another solution. 

 

0 Kudos