From 153d2397906486ed01e4be16982eec80a80d2b47 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Fri, 17 Jun 2016 13:07:15 -0400 Subject: [PATCH] Catch exceptions when not able to read a GDAL dataset. --- .../tile/TileProviderManager.cpp | 14 ++++- .../tile/temporaltileprovider.cpp | 62 +++++++++++++------ modules/globebrowsing/tile/tiledataset.cpp | 5 +- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/modules/globebrowsing/tile/TileProviderManager.cpp b/modules/globebrowsing/tile/TileProviderManager.cpp index 0bfb4c77de..7608980b46 100644 --- a/modules/globebrowsing/tile/TileProviderManager.cpp +++ b/modules/globebrowsing/tile/TileProviderManager.cpp @@ -98,9 +98,14 @@ namespace openspace { texDict.getValue("FilePath", path); texDict.getValue("Enabled", enabled); - std::shared_ptr tileProvider = initProvider(path, initData); - - //bool enabled = dest.size() == 0; // Only enable first layer + std::shared_ptr tileProvider; + try { + tileProvider = initProvider(path, initData); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.message); + continue; + } dest.push_back({ name, tileProvider, enabled }); } } @@ -111,6 +116,9 @@ namespace openspace { { std::shared_ptr tileProvider; CPLXMLNode * node = CPLParseXMLFile(file.c_str()); + if (!node) { + throw ghoul::RuntimeError("Unable to parse XML:\n" + file); + } if (std::string(node->pszValue) == "OpenSpaceTemporalGDALDataset") { tileProvider = std::shared_ptr( new TemporalTileProvider(file, initData)); diff --git a/modules/globebrowsing/tile/temporaltileprovider.cpp b/modules/globebrowsing/tile/temporaltileprovider.cpp index 5eaf3701f0..5efb3bc3fe 100644 --- a/modules/globebrowsing/tile/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/temporaltileprovider.cpp @@ -79,8 +79,18 @@ namespace openspace { end.setTime(timeEnd); } - _timeQuantizer = TimeQuantizer(start, end, timeResolution); + try { + _timeQuantizer = TimeQuantizer(start, end, timeResolution); + } + catch (const ghoul::RuntimeError& e) { + throw ghoul::RuntimeError( + "Could not create time quantizer for Temporal GDAL dataset '" + + _datasetFile + "'. " + e.message); + } _timeFormat = TimeIdProviderFactory::getProvider(timeIdFormat); + if (!_timeFormat) { + throw ghoul::RuntimeError("Invalid Time Format " + timeIdFormat + " in " + _datasetFile); + } CPLXMLNode* gdalNode = CPLSearchXMLNode(node, "GDAL_WMS"); return CPLSerializeXMLTree(gdalNode); @@ -89,6 +99,10 @@ namespace openspace { std::string TemporalTileProvider::getXMLValue(CPLXMLNode* root, const std::string& key, const std::string& defaultVal) { CPLXMLNode * n = CPLSearchXMLNode(root, key.c_str()); + if (!n) { + throw ghoul::RuntimeError("Unable to parse file " + _datasetFile + ". " + key + " missing."); + } + bool hasValue = (n != nullptr && n->psChild != nullptr && n->psChild->pszValue != nullptr); return hasValue ? std::string(n->psChild->pszValue) : defaultVal; } @@ -141,7 +155,13 @@ namespace openspace { Time tCopy(t); if (_timeQuantizer.quantize(tCopy)) { TimeKey timekey = _timeFormat->stringify(tCopy); - return getTileProvider(timekey); + try { + return getTileProvider(timekey); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.message); + return nullptr; + } } return nullptr; } @@ -257,23 +277,29 @@ namespace openspace { double TimeQuantizer::parseTimeResolutionStr(const std::string& resoltutionStr) { const char unit = resoltutionStr.back(); - double value = std::stod(resoltutionStr); - - // convert value to seconds, based on unit. - // The switch statment has intentional fall throughs - switch (unit) { - case 'y': value *= 365; - case 'd': value *= 24.0; - case 'h': value *= 60.0; - case 'm': value *= 60.0; - case 's': value *= 1.0; - break; - default: - ghoul_assert(false, "Invalid unit format. Using default value 1 d"); - value = 60 * 60 * 24; + std::string numberString = resoltutionStr.substr(0, resoltutionStr.length() - 1); + + char* p; + double value = strtol(numberString.c_str(), &p, 10); + if (*p) { // not a number + throw ghoul::RuntimeError("Cannot convert " + numberString + " to number"); + } + else { + // convert value to seconds, based on unit. + // The switch statment has intentional fall throughs + switch (unit) { + case 'y': value *= 365; + case 'd': value *= 24.0; + case 'h': value *= 60.0; + case 'm': value *= 60.0; + case 's': value *= 1.0; + break; + default: + throw ghoul::RuntimeError("Invalid unit format '" + std::string(1, unit) + + "'. Expected 'y', 'd', 'h', 'm' or 's'."); + } + return value; } - - return value; } bool TimeQuantizer::quantize(Time& t) const { diff --git a/modules/globebrowsing/tile/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp index 64a2389bfb..66ef34ceb5 100644 --- a/modules/globebrowsing/tile/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -59,7 +59,10 @@ namespace openspace { } _dataset = (GDALDataset *)GDALOpen(gdalDatasetDesc.c_str(), GA_ReadOnly); - ghoul_assert(_dataset != nullptr, "Failed to load dataset:\n" << gdalDatasetDesc); + if (!_dataset) { + throw ghoul::RuntimeError("Failed to load dataset:\n" + gdalDatasetDesc); + } + //ghoul_assert(_dataset != nullptr, "Failed to load dataset:\n" << gdalDatasetDesc); _dataLayout = DataLayout(_dataset, dataType); _depthTransform = calculateTileDepthTransform();