Generalize tile fetching to consider datasets without overviews.

This commit is contained in:
Kalle Bladin
2016-06-27 16:17:10 -04:00
parent ad79831014
commit 627f00faba
4 changed files with 83 additions and 33 deletions
+6 -6
View File
@@ -28,8 +28,8 @@ return {
Type = "RenderableGlobe",
Frame = "IAU_EARTH",
Body = "EARTH",
Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii
--Radii = {3396190.0, 3396190.0, 3396190.0}, -- Mars as a spheroid
--Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii
Radii = {3396190.0, 3396190.0, 3376200.0}, -- Mars' radii
SegmentsPerPatch = 64,
TextureInitData = {
ColorTextureMinimumSize = 1024,
@@ -56,14 +56,14 @@ return {
{
Name = "ESRI Imagery World 2D",
FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms",
Enabled = true,
Enabled = false,
},
},
GrayScaleOverlays = {
{
Name = "CTX Mosaic",
FilePath = "map_service_configs/CTX_Mosaic.xml",
Enabled = false,
Enabled = true,
},
},
NightTextures = {
@@ -77,12 +77,12 @@ return {
{
Name = "Terrain tileset",
FilePath = "map_service_configs/TERRAIN.wms",
Enabled = true,
Enabled = false,
},
{
Name = "Mola Elevation",
FilePath = "map_service_configs/Mola_Elevation.xml",
Enabled = false,
Enabled = true,
},
},
WaterMasks = {
@@ -118,22 +118,30 @@ namespace openspace {
const TileProviderInitData& initData)
{
std::shared_ptr<TileProvider> 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::make_shared<TemporalTileProvider>(file, initData);
try
{ // First try reading normally
auto tileDataset = std::make_shared<TileDataset>(file, initData.minimumPixelSize, initData.preprocessTiles);
auto threadPool = std::make_shared<ThreadPool>(1);
auto tileReader = std::make_shared<AsyncTileDataProvider>(tileDataset, threadPool);
auto tileCache = std::make_shared<TileCache>(initData.cacheSize);
tileProvider = std::make_shared<CachingTileProvider>(tileReader, tileCache, initData.framesUntilRequestQueueFlush);
return tileProvider;
}
auto tileDataset = std::make_shared<TileDataset>(file, initData.minimumPixelSize, initData.preprocessTiles);
auto threadPool = std::make_shared<ThreadPool>(1);
auto tileReader = std::make_shared<AsyncTileDataProvider>(tileDataset, threadPool);
auto tileCache = std::make_shared<TileCache>(initData.cacheSize);
tileProvider = std::make_shared<CachingTileProvider>(tileReader, tileCache, initData.framesUntilRequestQueueFlush);
return tileProvider;
catch (const ghoul::RuntimeError& e)
{ // Then try to see if it is a temporal dataset.
CPLXMLNode * node = CPLParseXMLFile(file.c_str());
if (!node) {
throw ghoul::RuntimeError("Unable to parse file:\n" + file);
}
if (std::string(node->pszValue) == "OpenSpaceTemporalGDALDataset") {
tileProvider = std::make_shared<TemporalTileProvider>(file, initData);
return tileProvider;
}
// If still not able to read, throw the error.
throw ghoul::RuntimeError(e.message);
}
}
TileProviderManager::LayerCategory& TileProviderManager::getLayerCategory(LayeredTextures::TextureCategory category)
+54 -12
View File
@@ -23,6 +23,7 @@
****************************************************************************************/
#include <ogr_featurestyle.h>
#include <ogr_spatialref.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // abspath
@@ -177,15 +178,27 @@ namespace openspace {
int TileDataset::calculateTileLevelDifference(GDALDataset* dataset, int minimumPixelSize) {
GDALRasterBand* firstBand = dataset->GetRasterBand(1);
GDALRasterBand* maxOverview;
int numOverviews = firstBand->GetOverviewCount();
int sizeLevel0 = firstBand->GetOverview(numOverviews - 1)->GetXSize();
int sizeLevel0;
if (numOverviews <= 0) { // No overviews. Use first band.
maxOverview = firstBand;
}
else { // Pick the highest overview.
maxOverview = firstBand->GetOverview(numOverviews - 1);
}
sizeLevel0 = maxOverview->GetXSize();
return log2(minimumPixelSize) - log2(sizeLevel0);
}
int TileDataset::calculateMaxLevel(int calculateMaxLevel) {
const int TileDataset::calculateMaxLevel(int tileLevelDifference) {
int numOverviews = _dataset->GetRasterBand(1)->GetOverviewCount();
_maxLevel = numOverviews - 1 - _tileLevelDifference;
return _maxLevel;
if (numOverviews <= 0) { // No overviews.
return - tileLevelDifference;
}
else { // Use the overview to get the maximum level.
return numOverviews - 1 - tileLevelDifference;
}
}
TileDepthTransform TileDataset::calculateTileDepthTransform() {
@@ -221,14 +234,29 @@ namespace openspace {
// Read the data (each rasterband is a separate channel)
for (size_t i = 0; i < _dataLayout.numRasters; i++) {
GDALRasterBand* rasterBand = _dataset->GetRasterBand(i + 1)->GetOverview(region.overview);
GDALRasterBand* rasterBand;
int pixelSourceScale = 1;
if (_dataset->GetRasterBand(i + 1)->GetOverviewCount() <= 0){
rasterBand = _dataset->GetRasterBand(i + 1);
pixelSourceScale = pow(2, region.overview + 1);
}
else {
rasterBand = _dataset->GetRasterBand(i + 1)->GetOverview(region.overview);
pixelSourceScale = 1;
}
char* dataDestination = imageData + (i * _dataLayout.bytesPerDatum);
int pixelStartX = region.pixelStart.x;// glm::max(int(region.pixelStart.x) - 1, 0);
int pixelStartY = region.pixelStart.y;// glm::max(int(region.pixelStart.y) - 1, 0);
int pixelWidthX = region.numPixels.x;// glm::min(pixelStartX + int(region.numPixels.x) + 2, rasterBand->GetXSize()) - pixelStartX;
int pixelWidthY = region.numPixels.y;// glm::min(pixelStartY + int(region.numPixels.y) + 2, rasterBand->GetYSize()) - pixelStartY;
int pixelStartX = region.pixelStart.x * pixelSourceScale;
int pixelStartY = region.pixelStart.y * pixelSourceScale;
int pixelWidthX = region.numPixels.x * pixelSourceScale;
int pixelWidthY = region.numPixels.y * pixelSourceScale;
// Clamp to be inside dataset
pixelStartX = glm::max(pixelStartX, 0);
pixelStartY = glm::max(pixelStartY, 0);
pixelWidthX = glm::min(pixelStartX + pixelWidthX, rasterBand->GetXSize()) - pixelStartX;
pixelWidthY = glm::min(pixelStartY + pixelWidthY, rasterBand->GetYSize()) - pixelStartY;
CPLErr err = rasterBand->RasterIO(
GF_Read,
@@ -413,6 +441,7 @@ namespace openspace {
glm::uvec2 TileDataset::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
double padfTransform[6];
CPLErr err = dataSet->GetGeoTransform(padfTransform);
@@ -420,7 +449,7 @@ namespace openspace {
Scalar Y = Angle<Scalar>::fromRadians(geo.lat).asDegrees();
Scalar X = Angle<Scalar>::fromRadians(geo.lon).asDegrees();
// convert from pixel and line to geodetic coordinates
// Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
// Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
@@ -576,9 +605,22 @@ namespace openspace {
// Calculate a suitable overview to choose from the GDAL dataset
int minNumPixels0 = glm::min(numPixels0.x, numPixels0.y);
int sizeLevel0 = firstBand->GetOverview(numOverviews - 1)->GetXSize();
GDALRasterBand* maxOverview;
if (numOverviews <= 0) {
maxOverview = firstBand;
}
else {
maxOverview = firstBand->GetOverview(numOverviews - 1);
}
int sizeLevel0 = maxOverview->GetXSize();
// The dataset itself may not have overviews but even if it does not, an overview
// for the data region can be calculated and possibly be used to sample greater
// Regions of the original dataset.
int ov = std::log2(minNumPixels0) - std::log2(sizeLevel0 + 1) - tileLevelDifference;
ov = glm::clamp(ov, 0, numOverviews - 1);
if (numOverviews > 0) {
ov = glm::clamp(ov, 0, numOverviews - 1);
}
// Convert the interval [pixelStart0, pixelEnd0] to pixel space at
// the calculated suitable overview, ov. using a >> b = a / 2^b
+1 -1
View File
@@ -158,7 +158,7 @@ namespace openspace {
// HELPER FUNCTIONS //
//////////////////////////////////////////////////////////////////////////////////
int calculateMaxLevel(int calculateMaxLevel);
const int calculateMaxLevel(int tileLevelDifference);
TileDepthTransform calculateTileDepthTransform();