From 0db98afe6e5c5996b7398394240a845ff6dcdba8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 17 Apr 2017 18:38:36 -0400 Subject: [PATCH] - Enable caching of TileProviders at startup time - Enable path tokens in filename for temporal tile providers - Add support for relative paths in temporal tile providers - Set the GDAL temp dir to the BASE_PATH - --- .../gdalrawtiledatareader.cpp | 12 +++-- .../rawtiledatareader/gdalrawtiledatareader.h | 4 +- .../tile/rawtiledatareader/gdalwrapper.cpp | 4 ++ .../tile/tileprovider/cachingtileprovider.cpp | 19 ++++++- .../tileprovider/temporaltileprovider.cpp | 49 +++++++++++++++++++ .../tile/tileprovider/temporaltileprovider.h | 9 ++++ 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp index ca1876576f..35a05f9f73 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp +++ b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp @@ -54,13 +54,16 @@ std::ostream& operator<<(std::ostream& os, const PixelRegion& pr) { ", " << pr.numPixels.y; } -GdalRawTileDataReader::GdalRawTileDataReader( - const std::string& filePath, const Configuration& config) +GdalRawTileDataReader::GdalRawTileDataReader(const std::string& filePath, + const Configuration& config, + const std::string& baseDirectory) : RawTileDataReader(config) , _dataset(nullptr) { - _initData = { "", filePath, config.tilePixelSize, config.dataType }; - _initData.initDirectory = CPLGetCurrentDir(); + + std::string initDir = baseDirectory.empty() ? CPLGetCurrentDir() : baseDirectory; + + _initData = { initDir, filePath, config.tilePixelSize, config.dataType }; ensureInitialized(); } @@ -303,6 +306,7 @@ GDALDataset* GdalRawTileDataReader::openGdalDataset(const std::string& filePath) std::string correctedPath = FileSystem::ref().pathByAppendingComponent( _initData.initDirectory, filePath ); + dataset = (GDALDataset *)GDALOpen(correctedPath.c_str(), GA_ReadOnly); if (!dataset) { throw ghoul::RuntimeError("Failed to load dataset:\n" + filePath); diff --git a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h index f44f410c79..338f3f5a90 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h +++ b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h @@ -60,8 +60,10 @@ public: * * \param filePath, a path to a specific file GDAL can read * \param config, Configuration used for initialization + * \param baseDirectory, the base directory to use in future loading operations */ - GdalRawTileDataReader(const std::string& filePath, const Configuration& config); + GdalRawTileDataReader(const std::string& filePath, const Configuration& config, + const std::string& baseDirectory = ""); virtual ~GdalRawTileDataReader() override; diff --git a/modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.cpp b/modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.cpp index 570307eb8a..952dbb93f8 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.cpp +++ b/modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.cpp @@ -105,6 +105,10 @@ GdalWrapper::GdalWrapper(size_t maximumCacheSize, "GDAL_DATA", absPath("${MODULE_GLOBEBROWSING}/gdal_data").c_str() ); + CPLSetConfigOption( + "CPL_TMPDIR", + absPath("${BASE_PATH}").c_str() + ); setGdalProxyConfiguration(); CPLSetErrorHandler(gdalErrorHandler); diff --git a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp index 11a9709c23..89638470ac 100644 --- a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp @@ -40,7 +40,9 @@ namespace { const char* KeyDoPreProcessing = "DoPreProcessing"; const char* KeyTilePixelSize = "TilePixelSize"; const char* KeyFilePath = "FilePath"; + const char* KeyBasePath = "BasePath"; const char* KeyFlushInterval = "FlushInterval"; + const char* KeyPreCacheLevel = "PreCacheLevel"; } namespace openspace { @@ -84,9 +86,12 @@ CachingTileProvider::CachingTileProvider(const ghoul::Dictionary& dictionary) framesUntilRequestFlush); } + std::string basePath; + dictionary.getValue(KeyBasePath, basePath); + // Initialize instance variables #ifdef GLOBEBROWSING_USE_GDAL - auto tileDataset = std::make_shared(filePath, config); + auto tileDataset = std::make_shared(filePath, config, basePath); #else // GLOBEBROWSING_USE_GDAL auto tileDataset = std::make_shared(filePath, config); #endif // GLOBEBROWSING_USE_GDAL @@ -99,6 +104,18 @@ CachingTileProvider::CachingTileProvider(const ghoul::Dictionary& dictionary) _asyncTextureDataProvider = std::make_shared( tileDataset, threadPool); _framesUntilRequestFlush = framesUntilRequestFlush; + + if (dictionary.hasKeyAndValue(KeyPreCacheLevel)) { + int preCacheLevel = static_cast(dictionary.value(KeyPreCacheLevel)); + LDEBUG("Precaching '" << filePath << "' with level '" << preCacheLevel << "'"); + for (int level = 0; level <= preCacheLevel; ++level) { + for (int x = 0; x <= level * 2; ++x) { + for (int y = 0; y <= level; ++y) { + _asyncTextureDataProvider->enqueueTileIO({ x, y, level }); + } + } + } + } } CachingTileProvider::CachingTileProvider( diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp index dcd6893a82..4e8fbb2d28 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp @@ -41,8 +41,11 @@ namespace { const char* KeyDoPreProcessing = "DoPreProcessing"; const char* KeyMinimumPixelSize = "MinimumPixelSize"; const char* KeyFilePath = "FilePath"; + const char* KeyBasePath = "BasePath"; const char* KeyCacheSize = "CacheSize"; const char* KeyFlushInterval = "FlushInterval"; + const char* KeyPreCacheStartTime = "PreCacheStartTime"; + const char* KeyPreCacheEndTime = "PreCacheEndTime"; } namespace openspace { @@ -64,6 +67,8 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) throw std::runtime_error(std::string("Must define key '") + KeyFilePath + "'"); } + _datasetFile = absPath(_datasetFile); + std::ifstream in(_datasetFile.c_str()); if (!in.is_open()) { throw ghoul::FileNotFoundError(_datasetFile); @@ -74,7 +79,29 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) std::istreambuf_iterator(in), (std::istreambuf_iterator()) ); + + _initDict.setValue( + KeyBasePath, + ghoul::filesystem::File(_datasetFile).directoryName() + ); + _gdalXmlTemplate = consumeTemporalMetaData(xml); + + const bool hasStart = dictionary.hasKeyAndValue(KeyPreCacheStartTime); + const bool hasEnd = dictionary.hasKeyAndValue(KeyPreCacheEndTime); + if (hasStart && hasEnd) { + const std::string start = dictionary.value(KeyPreCacheStartTime); + const std::string end = dictionary.value(KeyPreCacheEndTime); + std::vector