I have developed an app for iOS using the Swift language. The app uses online map services, including WMTS, WMS, TMS, XYZ and makes heavy use of OpenLayers to display these. I would like to be display some of these maps offline and therefore need to be able to cache selected portions of them locally (ie, selected extent and selected range of zoom levels).
(Don't need to remind me about copyright or licensing issues - I have my own Geoserver service so it's fine for those maps at least, and the app will have warning to users of other map services.)
I can cache a portion of a TMS map service, and it works fine offline displayed from the cache. I essentially calculate which tiles are required, download them, and store them on the file system in the same heirarchy as they are in their online URLs. Then they can simply be called by substituting the "http://servername/.../" with "file:///.../" in the base service URL.
WMTS is Complicated
However, I'm having trouble doing the same thing for WMTS, which has a much more complicated Capabilities.xml. Additionally, WMTS GetTile URLs are not well suited to offline caching as some of them could result in a flat directory structure and some of them can include characters that are inappropriate for filenames. So if I attempted to replicate a similar method to what I'm doing with TMS, all the tiles would end up in the same directory, making for very slow file system traversal and therefore inefficient reading of the tiles, plus I would have to work out some scheme for translating the file paths AND the Capabilities to avoid certain characters that don't play well with file names (eg, ":" is often used in WMTS tile paths, but is forbidden in iOS file names - if you see it in a file name, it is actually using a different character in the real file name, behind the scenes).
Proposed WMTS Work-Around
In order to work around these issues, I'm attempting to produce an offline TMS cache for the online WMTS service. This enables me to work with simple file names and a directory tree that doesn't result in excessive numbers of files in any one directory. I should then be able to feed the TMS cache to OpenLayers in the same way that I already do for my cached TMS services.
This is almost working. It downloads all of the right tiles, but the row numbers, column numbers, extent and origin are all different to what I get when I download from the equivalent TMS service from the same Geoserver, and the cached map doesn't display in OpenLayers.
Can anybody provide advice on how to convert online WMTS to an offline cache that I can feed into OpenLayers?
As an example, just one of the issues I'm struggling with is... how to convert WMTS' array of DIFFERENT origins ("TopLeftCorner") into a single TMS origin? (The origin-X-coordinate seems to be same as for TMS, but none of the WMTS origin Y-coordinates are anywhere near the TMS origin-Y coordinate for the same Geoserver map layer!)
I'd like to provide some code to show what I'm trying so far, but the nature of the beast is so complicated that it would require a prohibitively large base of code to be posted (and how many GIS people know Swift anyhow?).