-
Notifications
You must be signed in to change notification settings - Fork 370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement local caching for WMTS requests #2316
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable. There is a lot of duplicated code here between this and the other cache PR, so I am curious if there would be a good way to consolidate some of it into helper functions or class to be shared somehow. That can be a follow-up PR as well though if you don't want to expand the scope here.
Thanks for your feedback. Working on implementing these suggestions! |
@dnowacki-usgs , sorry for losing track of this one. Were you still making updates to it or is it ready for review now? It looks like at a minimum it would be good to add a test for the caching. Could you rebase on the latest main branch updates to get all the checks passing again? |
Hi Greg--I did make some progress as I recall but it's been a few months. I will look back into how far I got and update the PR. |
After merging the updated main branch and adding a missing import the PR is running again, but the cache is wonky--only some of the tiles are being saved and/or loaded with gaps. This wasn't the case when I was working on this months ago, so this will take a deeper dive. |
More testing and I can't reproduce the gaps I was experiencing the other day. As far as I can tell, this PR is working. Multiple requests do not result in re-downloading of the tiles, and the .npy files are successfully being saved in the cache directory. The following test code, adapted from the initial issue, is working for me with
I think this is ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Thanks for looking into all of this! Overall looks good to me, just some minor nits. Could you also add a similar test to the GoogleImageTiles one for this new addition too?
cartopy/lib/cartopy/tests/test_img_tiles.py
Line 333 in 0d4e39f
def test_cache(cache_dir, tmp_path): |
lib/cartopy/io/ogc_clients.py
Outdated
if self._default_cache: | ||
warnings.warn( | ||
'Cartopy created the following directory to cache ' | ||
'WMTSRasterSource tiles: {}'.format(cache_dir)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'WMTSRasterSource tiles: {}'.format(cache_dir)) | |
f'WMTSRasterSource tiles: {cache_dir}') |
lib/cartopy/io/ogc_clients.py
Outdated
warnings.warn( | ||
'Cartopy created the following directory to cache ' | ||
'WMTSRasterSource tiles: {}'.format(cache_dir)) | ||
self.cache = self.cache.union(set(os.listdir(cache_dir))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.cache = self.cache.union(set(os.listdir(cache_dir))) | |
self.cache = self.cache.union(set(cache_dir.iterdir())) |
lib/cartopy/io/ogc_clients.py
Outdated
cached_file = os.path.join( | ||
self._cache_dir, | ||
filename | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cached_file = os.path.join( | |
self._cache_dir, | |
filename | |
) | |
cached_file = self._cache_dir / filename |
lib/cartopy/io/ogc_clients.py
Outdated
filename = None | ||
cached_file = None | ||
|
||
if filename in self.cache: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is some bouncing back and forth between pathlib and str-like paths. So if you change the previous around, I think this would also need to be the Path version.
if filename in self.cache: | |
if cached_file in self.cache: |
@dnowacki-usgs thank you very much for this PR, it really solved slowness and dropout issues for me. For anyone interested, this is a code snippet to create N figures using the cache for bluemarble: import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import owslib.wmts
# caching the WMTS
cache_dir = "~/.cartopy"
cartopy.config.update({"cache_dir": cache_dir})
url = 'https://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'
layer = 'BlueMarble_NextGeneration'
wmts = owslib.wmts.WebMapTileService(url)
# loop over all the first 10 frames
for kt in range(0, 10):
subplot_kws={'projection': ccrs.NearsidePerspective()}
ax = plt.axes(**subplot_kws)
ax.add_wmts(wmts, layer, cache=cache_dir)
plt.close("all") I really hope this PR will be merged soon as it is solving quite a big problem for WMTS users. |
This is an in-progress PR to implement local caching of WMTS image tiles. It is based heavily on the caching approach and code implemented in #1533. No tests added yet; this is really a working proof of concept.
Rationale
The rationale is described in #2314.
Briefly, this PR implements local caching of image tiles so repeated WMTSRasterSource calls do not incur additional network traffic.
Implications