mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-24 21:18:32 -05:00
Splitting tile providers back into individual files
This commit is contained in:
@@ -286,13 +286,13 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
|
||||
|
||||
_reset.onChange([&]() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::reset(*_tileProvider);
|
||||
_tileProvider->reset();
|
||||
}
|
||||
});
|
||||
|
||||
_remove.onChange([&]() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::reset(*_tileProvider);
|
||||
_tileProvider->reset();
|
||||
_parent.deleteLayer(identifier());
|
||||
}
|
||||
});
|
||||
@@ -360,13 +360,13 @@ void Layer::initialize() {
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
tileprovider::initialize(*_tileProvider);
|
||||
_tileProvider->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::deinitialize() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::deinitialize(*_tileProvider);
|
||||
_tileProvider->deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) con
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
return tileprovider::chunkTilePile(*_tileProvider, tileIndex, pileSize);
|
||||
return _tileProvider->chunkTilePile(tileIndex, pileSize);
|
||||
}
|
||||
else {
|
||||
ChunkTilePile chunkTilePile;
|
||||
@@ -390,7 +390,7 @@ ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) con
|
||||
|
||||
Tile::Status Layer::tileStatus(const TileIndex& index) const {
|
||||
return _tileProvider ?
|
||||
tileprovider::tileStatus(*_tileProvider, index) :
|
||||
_tileProvider->tileStatus(index) :
|
||||
Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ layergroupid::BlendModeID Layer::blendMode() const {
|
||||
|
||||
TileDepthTransform Layer::depthTransform() const {
|
||||
return _tileProvider ?
|
||||
tileprovider::depthTransform(*_tileProvider) :
|
||||
_tileProvider->depthTransform() :
|
||||
TileDepthTransform{ 1.f, 0.f };
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ bool Layer::enabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
tileprovider::TileProvider* Layer::tileProvider() const {
|
||||
TileProvider* Layer::tileProvider() const {
|
||||
return _tileProvider.get();
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ void Layer::update() {
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
tileprovider::update(*_tileProvider);
|
||||
_tileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ void Layer::initializeBasedOnType(layergroupid::TypeID id, ghoul::Dictionary ini
|
||||
std::string name = initDict.value<std::string>(KeyName);
|
||||
LDEBUG("Initializing tile provider for layer: '" + name + "'");
|
||||
}
|
||||
_tileProvider = tileprovider::createFromDictionary(id, std::move(initDict));
|
||||
_tileProvider = TileProvider::createFromDictionary(id, std::move(initDict));
|
||||
break;
|
||||
}
|
||||
case layergroupid::TypeID::SolidColor: {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/layeradjustment.h>
|
||||
#include <modules/globebrowsing/src/layerrendersettings.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace openspace::globebrowsing {
|
||||
|
||||
struct LayerGroup;
|
||||
struct TileIndex;
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
struct TileProvider;
|
||||
|
||||
class Layer : public properties::PropertyOwner {
|
||||
public:
|
||||
@@ -59,7 +58,7 @@ public:
|
||||
TileDepthTransform depthTransform() const;
|
||||
void setEnabled(bool enabled);
|
||||
bool enabled() const;
|
||||
tileprovider::TileProvider* tileProvider() const;
|
||||
TileProvider* tileProvider() const;
|
||||
glm::vec3 solidColor() const;
|
||||
const LayerRenderSettings& renderSettings() const;
|
||||
const LayerAdjustment& layerAdjustment() const;
|
||||
@@ -89,7 +88,7 @@ private:
|
||||
properties::StringProperty _guiDescription;
|
||||
|
||||
layergroupid::TypeID _type;
|
||||
std::unique_ptr<tileprovider::TileProvider> _tileProvider;
|
||||
std::unique_ptr<TileProvider> _tileProvider;
|
||||
properties::Vec3Property _solidColor;
|
||||
LayerRenderSettings _renderSettings;
|
||||
LayerAdjustment _layerAdjustment;
|
||||
|
||||
@@ -36,8 +36,6 @@ namespace openspace::documentation { struct Documentation; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
|
||||
class LayerAdjustment : public properties::PropertyOwner {
|
||||
public:
|
||||
LayerAdjustment();
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class Layer;
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
struct TileProvider;
|
||||
|
||||
/**
|
||||
* Convenience class for dealing with multiple <code>Layer</code>s.
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
@@ -155,7 +155,7 @@ void LayerManager::reset(bool includeDisabled) {
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
for (Layer* layer : layerGroup->layers()) {
|
||||
if ((layer->enabled() || includeDisabled) && layer->tileProvider()) {
|
||||
tileprovider::reset(*layer->tileProvider());
|
||||
layer->tileProvider()->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
@@ -322,7 +322,7 @@ ChunkTileVector tilesAndSettingsUnsorted(const LayerGroup& layerGroup,
|
||||
for (Layer* layer : layerGroup.activeLayers()) {
|
||||
if (layer->tileProvider()) {
|
||||
tilesAndSettings.emplace_back(
|
||||
tileprovider::chunkTile(*layer->tileProvider(), tileIndex),
|
||||
layer->tileProvider()->chunkTile(tileIndex),
|
||||
&layer->renderSettings()
|
||||
);
|
||||
}
|
||||
@@ -403,7 +403,7 @@ bool colorAvailableForChunk(const Chunk& chunk, const LayerManager& lm) {
|
||||
|
||||
for (Layer* lyr : colorLayers.activeLayers()) {
|
||||
if (lyr->tileProvider()) {
|
||||
ChunkTile t = tileprovider::chunkTile(*lyr->tileProvider(), chunk.tileIndex);
|
||||
ChunkTile t = lyr->tileProvider()->chunkTile(chunk.tileIndex);
|
||||
if (t.tile.status == Tile::Status::Unavailable) {
|
||||
return false;
|
||||
}
|
||||
@@ -1886,16 +1886,15 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
_layerManager.layerGroup(layergroupid::GroupID::HeightLayers).activeLayers();
|
||||
|
||||
for (Layer* layer : heightMapLayers) {
|
||||
tileprovider::TileProvider* tileProvider = layer->tileProvider();
|
||||
TileProvider* tileProvider = layer->tileProvider();
|
||||
if (!tileProvider) {
|
||||
continue;
|
||||
}
|
||||
// Transform the uv coordinates to the current tile texture
|
||||
const ChunkTile chunkTile = tileprovider::chunkTile(*tileProvider, tileIndex);
|
||||
const ChunkTile chunkTile = tileProvider->chunkTile(tileIndex);
|
||||
const Tile& tile = chunkTile.tile;
|
||||
const TileUvTransform& uvTransform = chunkTile.uvTransform;
|
||||
const TileDepthTransform& depthTransform =
|
||||
tileprovider::depthTransform(*tileProvider);
|
||||
const TileDepthTransform& depthTransform = tileProvider->depthTransform();
|
||||
if (tile.status != Tile::Status::OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1953,10 +1952,10 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
std::isnan(sample11);
|
||||
|
||||
const bool anySampleIsNoData =
|
||||
sample00 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample01 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample10 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample11 == tileprovider::noDataValueAsFloat(*tileProvider);
|
||||
sample00 == tileProvider->noDataValueAsFloat() ||
|
||||
sample01 == tileProvider->noDataValueAsFloat() ||
|
||||
sample10 == tileProvider->noDataValueAsFloat() ||
|
||||
sample11 == tileProvider->noDataValueAsFloat();
|
||||
|
||||
if (anySampleIsNaN || anySampleIsNoData) {
|
||||
continue;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,292 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/ellipsoid.h>
|
||||
#include <modules/globebrowsing/src/layergroupid.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/timequantizer.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <unordered_map>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
struct CPLXMLNode;
|
||||
|
||||
namespace ghoul::fontrendering {
|
||||
class Font;
|
||||
class FontRenderer;
|
||||
} // namespace ghoul::fontrendering
|
||||
|
||||
namespace openspace { class PixelBuffer; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
class AsyncTileDataProvider;
|
||||
struct RawTile;
|
||||
struct TileIndex;
|
||||
namespace cache { class MemoryAwareTileCache; }
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
namespace openspace::globebrowsing::tileprovider {
|
||||
|
||||
enum class Type {
|
||||
DefaultTileProvider = 0,
|
||||
SingleImageTileProvider,
|
||||
ImageSequenceTileProvider,
|
||||
SizeReferenceTileProvider,
|
||||
TemporalTileProvider,
|
||||
TileIndexTileProvider,
|
||||
ByIndexTileProvider,
|
||||
ByLevelTileProvider,
|
||||
InterpolateTileProvider
|
||||
};
|
||||
|
||||
|
||||
struct TileProvider : public properties::PropertyOwner {
|
||||
static unsigned int NumTileProviders;
|
||||
|
||||
Type type;
|
||||
|
||||
TileProvider();
|
||||
virtual ~TileProvider() = default;
|
||||
|
||||
std::string name;
|
||||
|
||||
uint16_t uniqueIdentifier = 0;
|
||||
bool isInitialized = false;
|
||||
};
|
||||
|
||||
struct DefaultTileProvider : public TileProvider {
|
||||
DefaultTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<AsyncTileDataProvider> asyncTextureDataProvider;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
properties::IntProperty tilePixelSize;
|
||||
layergroupid::GroupID layerGroupID = layergroupid::GroupID::Unknown;
|
||||
bool performPreProcessing = false;
|
||||
bool padTiles = true;
|
||||
};
|
||||
|
||||
struct SingleImageProvider : public TileProvider {
|
||||
SingleImageProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> tileTexture;
|
||||
Tile tile;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
};
|
||||
|
||||
struct InterpolateTileProvider : public TileProvider {
|
||||
InterpolateTileProvider(const ghoul::Dictionary&);
|
||||
virtual ~InterpolateTileProvider();
|
||||
|
||||
Tile calculateTile(const TileIndex&);
|
||||
TileProvider* before = nullptr;
|
||||
TileProvider* t1 = nullptr;
|
||||
TileProvider* t2 = nullptr;
|
||||
TileProvider* future = nullptr;
|
||||
float factor = 1.f;
|
||||
GLuint vaoQuad = 0;
|
||||
GLuint vboQuad = 0;
|
||||
GLuint fbo = 0;
|
||||
std::string colormap;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> shaderProgram;
|
||||
std::unique_ptr<SingleImageProvider> singleImageProvider;
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
};
|
||||
|
||||
struct TextTileProvider : public TileProvider {
|
||||
TextTileProvider(TileTextureInitData initData, size_t fontSize = 48);
|
||||
|
||||
const TileTextureInitData initData;
|
||||
|
||||
std::unique_ptr<ghoul::fontrendering::FontRenderer> fontRenderer;
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font;
|
||||
size_t fontSize = 0;
|
||||
|
||||
std::string text;
|
||||
glm::vec2 textPosition = glm::vec2(0.f);
|
||||
glm::vec4 textColor = glm::vec4(0.f);
|
||||
|
||||
GLuint fbo = 0;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache;
|
||||
};
|
||||
|
||||
struct SizeReferenceTileProvider : public TextTileProvider {
|
||||
SizeReferenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Ellipsoid ellipsoid;
|
||||
};
|
||||
|
||||
struct TileIndexTileProvider : public TextTileProvider {
|
||||
TileIndexTileProvider(const ghoul::Dictionary& dictionary);
|
||||
};
|
||||
|
||||
struct TileProviderByIndex : public TileProvider {
|
||||
TileProviderByIndex(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unordered_map<
|
||||
TileIndex::TileHashKey, std::unique_ptr<TileProvider>
|
||||
> tileProviderMap;
|
||||
std::unique_ptr<TileProvider> defaultTileProvider;
|
||||
};
|
||||
|
||||
struct TileProviderByLevel : public TileProvider {
|
||||
TileProviderByLevel(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::vector<int> providerIndices;
|
||||
std::vector<std::unique_ptr<TileProvider>> levelTileProviders;
|
||||
};
|
||||
|
||||
|
||||
struct ImageSequenceTileProvider : public TileProvider {
|
||||
ImageSequenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<DefaultTileProvider> currentTileProvider = nullptr;
|
||||
|
||||
properties::IntProperty index;
|
||||
properties::StringProperty currentImage;
|
||||
properties::StringProperty folderPath;
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
bool isImageDirty = true;
|
||||
std::vector<std::filesystem::path> imagePaths;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide <code>Tile</code>s from web map services that have temporal resolution.
|
||||
*
|
||||
* TemporalTileProviders are instantiated using a ghoul::Dictionary,
|
||||
* and must define a filepath to a Openspace Temporal dataset description file.
|
||||
* This is an xml-file that defines the same meta data as the GDAL wms description
|
||||
* (http://www.gdal.org/frmt_wms.html), but augmented with some
|
||||
* extra tags describing the temporal properties of the dataset. See
|
||||
* <code>TemporalTileProvider::TemporalXMLTags</code>
|
||||
*
|
||||
*/
|
||||
struct TemporalTileProvider : public TileProvider {
|
||||
enum class TimeFormatType {
|
||||
YYYY_MM_DD = 0,
|
||||
YYYYMMDD_hhmmss,
|
||||
YYYYMMDD_hhmm,
|
||||
YYYY_MM_DDThhColonmmColonssZ,
|
||||
YYYY_MM_DDThh_mm_ssZ
|
||||
};
|
||||
|
||||
using TimeKey = std::string;
|
||||
|
||||
TemporalTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
properties::StringProperty filePath;
|
||||
properties::BoolProperty useFixedTime;
|
||||
properties::StringProperty fixedTime;
|
||||
std::string gdalXmlTemplate;
|
||||
|
||||
std::unordered_map<TimeKey, std::unique_ptr<TileProvider>> tileProviderMap;
|
||||
|
||||
bool interpolation = false;
|
||||
|
||||
TileProvider* currentTileProvider = nullptr;
|
||||
double startTimeJ2000;
|
||||
double endTimeJ2000;
|
||||
TimeFormatType timeFormat;
|
||||
TimeQuantizer timeQuantizer;
|
||||
std::string colormap;
|
||||
|
||||
std::string myResolution;
|
||||
std::unique_ptr<InterpolateTileProvider> interpolateTileProvider;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void initializeDefaultTile();
|
||||
void deinitializeDefaultTile();
|
||||
|
||||
std::unique_ptr<TileProvider> createFromDictionary(layergroupid::TypeID layerTypeID,
|
||||
const ghoul::Dictionary& dictionary);
|
||||
|
||||
bool initialize(TileProvider& tp);
|
||||
bool deinitialize(TileProvider& tp);
|
||||
|
||||
Tile tile(TileProvider& tp, const TileIndex& tileIndex);
|
||||
|
||||
ChunkTile chunkTile(TileProvider& tp, TileIndex tileIndex, int parents = 0,
|
||||
int maxParents = 1337);
|
||||
|
||||
ChunkTilePile chunkTilePile(TileProvider& tp, TileIndex tileIndex, int pileSize);
|
||||
|
||||
/**
|
||||
* Returns the status of a <code>Tile</code>. The <code>Tile::Status</code>
|
||||
* corresponds the <code>Tile</code> that would be returned
|
||||
* if the function <code>tile</code> would be invoked with the same
|
||||
* <code>TileIndex</code> argument at this point in time.
|
||||
*/
|
||||
Tile::Status tileStatus(TileProvider& tp, const TileIndex& index);
|
||||
|
||||
/**
|
||||
* Get the associated depth transform for this TileProvider.
|
||||
* This is necessary for TileProviders serving height map
|
||||
* data, in order to correcly map pixel values to meters.
|
||||
*/
|
||||
TileDepthTransform depthTransform(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* This method should be called once per frame. Here, TileProviders
|
||||
* are given the opportunity to update their internal state.
|
||||
*/
|
||||
void update(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* Provides a uniform way of all TileProviders to reload or
|
||||
* restore all of its internal state. This is mainly useful
|
||||
* for debugging purposes.
|
||||
*/
|
||||
void reset(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* \returns The maximum level as defined by <code>TileIndex</code>
|
||||
* that this TileProvider is able provide.
|
||||
*/
|
||||
int maxLevel(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* \returns the no data value for the dataset. Default is the minimum float avalue.
|
||||
*/
|
||||
float noDataValueAsFloat(TileProvider& tp);
|
||||
|
||||
} // namespace openspace::globebrowsing::tileprovider
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
@@ -0,0 +1,221 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/asynctiledataprovider.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
constexpr const char* KeyPerformPreProcessing = "PerformPreProcessing";
|
||||
constexpr const char* KeyTilePixelSize = "TilePixelSize";
|
||||
constexpr const char* KeyPadTiles = "PadTiles";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"The path of the GDAL file or the image file that is to be used in this tile "
|
||||
"provider."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TilePixelSizeInfo = {
|
||||
"TilePixelSize",
|
||||
"Tile Pixel Size",
|
||||
"This value is the preferred size (in pixels) for each tile. Choosing the right "
|
||||
"value is a tradeoff between more efficiency (larger images) and better quality "
|
||||
"(smaller images). The tile pixel size has to be smaller than the size of the "
|
||||
"complete image if a single image is used."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: filePath(FilePathInfo, "")
|
||||
, tilePixelSize(TilePixelSizeInfo, 32, 32, 2048)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
tileCache = global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
name = "Name unspecified";
|
||||
if (dictionary.hasValue<std::string>("Name")) {
|
||||
name = dictionary.value<std::string>("Name");
|
||||
}
|
||||
std::string _loggerCat = "DefaultTileProvider (" + name + ")";
|
||||
|
||||
// 1. Get required Keys
|
||||
filePath = dictionary.value<std::string>(KeyFilePath);
|
||||
layerGroupID =
|
||||
static_cast<layergroupid::GroupID>(dictionary.value<int>("LayerGroupID"));
|
||||
|
||||
// 2. Initialize default values for any optional Keys
|
||||
// getValue does not work for integers
|
||||
int pixelSize = 0;
|
||||
if (dictionary.hasValue<double>(KeyTilePixelSize)) {
|
||||
pixelSize = static_cast<int>(dictionary.value<double>(KeyTilePixelSize));
|
||||
LDEBUG(fmt::format("Default pixel size overridden: {}", pixelSize));
|
||||
}
|
||||
|
||||
if (dictionary.hasValue<bool>(KeyPadTiles)) {
|
||||
padTiles = dictionary.value<bool>(KeyPadTiles);
|
||||
}
|
||||
|
||||
TileTextureInitData initData(
|
||||
tileTextureInitData(layerGroupID, padTiles, pixelSize)
|
||||
);
|
||||
tilePixelSize = initData.dimensions.x;
|
||||
|
||||
|
||||
// Only preprocess height layers by default
|
||||
switch (layerGroupID) {
|
||||
case layergroupid::GroupID::HeightLayers: performPreProcessing = true; break;
|
||||
default: performPreProcessing = false; break;
|
||||
}
|
||||
|
||||
if (dictionary.hasValue<bool>(KeyPerformPreProcessing)) {
|
||||
performPreProcessing = dictionary.value<bool>(KeyPerformPreProcessing);
|
||||
LDEBUG(fmt::format(
|
||||
"Default PerformPreProcessing overridden: {}", performPreProcessing
|
||||
));
|
||||
}
|
||||
|
||||
initAsyncTileDataReader(initData);
|
||||
|
||||
addProperty(filePath);
|
||||
addProperty(tilePixelSize);
|
||||
}
|
||||
|
||||
void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData) {
|
||||
ZoneScoped
|
||||
|
||||
asyncTextureDataProvider = std::make_unique<AsyncTileDataProvider>(
|
||||
name,
|
||||
std::make_unique<RawTileDataReader>(
|
||||
filePath,
|
||||
initData,
|
||||
RawTileDataReader::PerformPreprocessing(performPreProcessing)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Tile DefaultTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
if (asyncTextureDataProvider) {
|
||||
if (tileIndex.level > maxLevel()) {
|
||||
return Tile{ nullptr, std::nullopt, Tile::Status::OutOfRange };
|
||||
}
|
||||
const cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
Tile tile = tileCache->get(key);
|
||||
if (!tile.texture) {
|
||||
//TracyMessage("Enqueuing tile", 32);
|
||||
asyncTextureDataProvider->enqueueTileIO(tileIndex);
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
else {
|
||||
return Tile{ nullptr, std::nullopt, Tile::Status::Unavailable };
|
||||
}
|
||||
}
|
||||
|
||||
Tile::Status DefaultTileProvider::tileStatus(const TileIndex& index) {
|
||||
if (asyncTextureDataProvider) {
|
||||
const RawTileDataReader& reader = asyncTextureDataProvider->rawTileDataReader();
|
||||
|
||||
if (index.level > reader.maxChunkLevel()) {
|
||||
return Tile::Status::OutOfRange;
|
||||
}
|
||||
|
||||
const cache::ProviderTileKey key = { index, uniqueIdentifier };
|
||||
return tileCache->get(key).status;
|
||||
}
|
||||
else {
|
||||
return Tile::Status::Unavailable;
|
||||
}
|
||||
}
|
||||
|
||||
TileDepthTransform DefaultTileProvider::depthTransform() {
|
||||
if (asyncTextureDataProvider) {
|
||||
return asyncTextureDataProvider->rawTileDataReader().depthTransform();
|
||||
}
|
||||
else {
|
||||
return { 1.f, 0.f };
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultTileProvider::update() {
|
||||
if (!asyncTextureDataProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
asyncTextureDataProvider->update();
|
||||
|
||||
std::optional<RawTile> tile = asyncTextureDataProvider->popFinishedRawTile();
|
||||
if (tile) {
|
||||
const cache::ProviderTileKey key = { tile->tileIndex, uniqueIdentifier };
|
||||
ghoul_assert(!tileCache->exist(key), "Tile must not be existing in cache");
|
||||
tileCache->createTileAndPut(key, std::move(*tile));
|
||||
}
|
||||
|
||||
|
||||
if (asyncTextureDataProvider->shouldBeDeleted()) {
|
||||
asyncTextureDataProvider = nullptr;
|
||||
initAsyncTileDataReader(
|
||||
tileTextureInitData(layerGroupID, padTiles, tilePixelSize)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultTileProvider::reset() {
|
||||
tileCache->clear();
|
||||
if (asyncTextureDataProvider) {
|
||||
asyncTextureDataProvider->prepareToBeDeleted();
|
||||
}
|
||||
else {
|
||||
initAsyncTileDataReader(
|
||||
tileTextureInitData(layerGroupID, padTiles, tilePixelSize)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int DefaultTileProvider::maxLevel() {
|
||||
// 22 is the current theoretical maximum based on the number of hashes that are
|
||||
// possible to uniquely identify a tile. See ProviderTileHasher in
|
||||
// memoryawaretilecache.h
|
||||
return asyncTextureDataProvider ?
|
||||
asyncTextureDataProvider->rawTileDataReader().maxChunkLevel() :
|
||||
22;
|
||||
}
|
||||
|
||||
float DefaultTileProvider::noDataValueAsFloat() {
|
||||
return asyncTextureDataProvider ?
|
||||
asyncTextureDataProvider->noDataValueAsFloat() :
|
||||
std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,59 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct DefaultTileProvider : public TileProvider {
|
||||
DefaultTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
std::unique_ptr<AsyncTileDataProvider> asyncTextureDataProvider;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
properties::IntProperty tilePixelSize;
|
||||
layergroupid::GroupID layerGroupID = layergroupid::GroupID::Unknown;
|
||||
bool performPreProcessing = false;
|
||||
bool padTiles = true;
|
||||
|
||||
private:
|
||||
void initAsyncTileDataReader(TileTextureInitData initData);
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
@@ -0,0 +1,159 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IndexInfo = {
|
||||
"Index",
|
||||
"Index",
|
||||
"The index into the list of images that is used to pick the currently displayed "
|
||||
"image"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CurrentImageInfo = {
|
||||
"CurrentImage",
|
||||
"Current Image",
|
||||
"The read-only value of the currently selected image"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FolderPathInfo = {
|
||||
"FolderPath",
|
||||
"Folder Path",
|
||||
"The path that is used to look for images for this image provider. The path must "
|
||||
"point to an existing folder that contains images"
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
ImageSequenceTileProvider::ImageSequenceTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: index(IndexInfo, 0)
|
||||
, currentImage(CurrentImageInfo)
|
||||
, folderPath(FolderPathInfo)
|
||||
, initDict(dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
if (dictionary.hasValue<int>(IndexInfo.identifier)) {
|
||||
index = dictionary.value<int>(IndexInfo.identifier);
|
||||
}
|
||||
index.setMinValue(0);
|
||||
index.onChange([this]() { isImageDirty = true; });
|
||||
addProperty(index);
|
||||
|
||||
folderPath.setReadOnly(true);
|
||||
addProperty(folderPath);
|
||||
|
||||
folderPath = dictionary.value<std::string>(FolderPathInfo.identifier);
|
||||
addProperty(folderPath);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
Tile ImageSequenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
if (currentTileProvider) {
|
||||
return currentTileProvider->tile(tileIndex);
|
||||
}
|
||||
else {
|
||||
return Tile();
|
||||
}
|
||||
}
|
||||
|
||||
Tile::Status ImageSequenceTileProvider::tileStatus(const TileIndex& index) {
|
||||
if (currentTileProvider) {
|
||||
return currentTileProvider->tileStatus(index);
|
||||
}
|
||||
else {
|
||||
return Tile::Status::Unavailable;
|
||||
}
|
||||
}
|
||||
|
||||
TileDepthTransform ImageSequenceTileProvider::depthTransform() {
|
||||
if (currentTileProvider) {
|
||||
return currentTileProvider->depthTransform();
|
||||
}
|
||||
else {
|
||||
return { 1.f, 0.f };
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSequenceTileProvider::update() {
|
||||
if (isImageDirty && !imagePaths.empty() &&
|
||||
index >= 0 && index < imagePaths.size())
|
||||
{
|
||||
if (currentTileProvider) {
|
||||
currentTileProvider->deinitialize();
|
||||
}
|
||||
|
||||
std::string p = imagePaths[index].string();
|
||||
currentImage = p;
|
||||
initDict.setValue(KeyFilePath, p);
|
||||
currentTileProvider = std::make_unique<DefaultTileProvider>(initDict);
|
||||
currentTileProvider->initialize();
|
||||
isImageDirty = false;
|
||||
}
|
||||
|
||||
if (currentTileProvider) {
|
||||
currentTileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSequenceTileProvider::reset() {
|
||||
namespace fs = std::filesystem;
|
||||
std::string path = folderPath;
|
||||
imagePaths.clear();
|
||||
for (const fs::directory_entry& p : fs::directory_iterator(path)) {
|
||||
if (p.is_regular_file()) {
|
||||
imagePaths.push_back(p.path());
|
||||
}
|
||||
}
|
||||
|
||||
index = 0;
|
||||
index.setMaxValue(static_cast<int>(imagePaths.size() - 1));
|
||||
|
||||
if (currentTileProvider) {
|
||||
currentTileProvider->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int ImageSequenceTileProvider::maxLevel() {
|
||||
return currentTileProvider ? currentTileProvider->maxLevel() : 0;
|
||||
}
|
||||
|
||||
float ImageSequenceTileProvider::noDataValueAsFloat() {
|
||||
if (currentTileProvider) {
|
||||
return currentTileProvider->noDataValueAsFloat();
|
||||
}
|
||||
else {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct ImageSequenceTileProvider : public TileProvider {
|
||||
ImageSequenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
std::unique_ptr<DefaultTileProvider> currentTileProvider = nullptr;
|
||||
|
||||
properties::IntProperty index;
|
||||
properties::StringProperty currentImage;
|
||||
properties::StringProperty folderPath;
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
bool isImageDirty = true;
|
||||
std::vector<std::filesystem::path> imagePaths;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
@@ -0,0 +1,241 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/interpolatetileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
InterpolateTileProvider::InterpolateTileProvider(const ghoul::Dictionary&) {
|
||||
ZoneScoped
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glGenVertexArrays(1, &vaoQuad);
|
||||
glGenBuffers(1, &vboQuad);
|
||||
glBindVertexArray(vaoQuad);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vboQuad);
|
||||
tileCache = global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
// Quad for fullscreen with vertex (xy) and texture coordinates (uv)
|
||||
const GLfloat vertexData[] = {
|
||||
// x y u v
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 0.f, 1.f,
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f
|
||||
};
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
|
||||
// vertex coordinates at location 0
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
|
||||
glEnableVertexAttribArray(0);
|
||||
// texture coords at location 1
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
4 * sizeof(GLfloat),
|
||||
reinterpret_cast<void*>(sizeof(GLfloat) * 2)
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
shaderProgram = global::renderEngine->buildRenderProgram(
|
||||
"InterpolatingProgram",
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/interpolate_vs.glsl"),
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/interpolate_fs.glsl")
|
||||
);
|
||||
}
|
||||
|
||||
InterpolateTileProvider::~InterpolateTileProvider() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteBuffers(1, &vboQuad);
|
||||
glDeleteVertexArrays(1, &vaoQuad);
|
||||
}
|
||||
|
||||
Tile InterpolateTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
TracyGpuZone("tile");
|
||||
|
||||
// prev and next are the two tiles to interpolate between
|
||||
Tile prev = t1->tile(tileIndex);
|
||||
Tile next = t2->tile(tileIndex);
|
||||
// the tile before and the tile after the interpolation interval are loaded so the
|
||||
// interpolation goes smoother
|
||||
Tile prevprev = before->tile(tileIndex);
|
||||
Tile nextnext = future->tile(tileIndex);
|
||||
cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
|
||||
if (!prev.texture || !next.texture) {
|
||||
return Tile{ nullptr, std::nullopt, Tile::Status::Unavailable };
|
||||
}
|
||||
|
||||
// There is a previous and next texture to interpolate between so do the interpolation
|
||||
|
||||
// The texture that will give the color for the interpolated texture
|
||||
ghoul::opengl::Texture* colormapTexture = singleImageProvider->ttile.texture;
|
||||
long long hkey = cache::ProviderTileHasher()(key);
|
||||
// The data for initializing the texture
|
||||
TileTextureInitData initData(
|
||||
prev.texture->dimensions().x,
|
||||
prev.texture->dimensions().y,
|
||||
prev.texture->dataType(),
|
||||
prev.texture->format(),
|
||||
TileTextureInitData::PadTiles::No,
|
||||
TileTextureInitData::ShouldAllocateDataOnCPU::No
|
||||
);
|
||||
|
||||
// Check if a tile exists for the given key in the tileCache
|
||||
// Initializing the tile that will contian the interpolated texture
|
||||
Tile ourTile;
|
||||
// The texture that will contain the interpolated image
|
||||
ghoul::opengl::Texture* writeTexture;
|
||||
if (tileCache->exist(key)) {
|
||||
// Get the tile from the tilecache
|
||||
ourTile = tileCache->get(key);
|
||||
// Use the texture from the tileCache
|
||||
writeTexture = ourTile.texture;
|
||||
}
|
||||
else {
|
||||
// Create a texture with the initialization data
|
||||
writeTexture = tileCache->texture(initData);
|
||||
// Create a tile with the texture
|
||||
ourTile = Tile{ writeTexture, std::nullopt, Tile::Status::OK };
|
||||
// Add it to the tilecache
|
||||
tileCache->put(key, initData.hashKey, ourTile);
|
||||
}
|
||||
|
||||
// Saves current state
|
||||
GLint currentFBO;
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFBO);
|
||||
global::renderEngine->openglStateCache().viewport(viewport);
|
||||
// Bind render texture to FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
*writeTexture,
|
||||
0
|
||||
);
|
||||
glDisable(GL_BLEND);
|
||||
GLenum textureBuffers[1] = { GL_COLOR_ATTACHMENT0 };
|
||||
glDrawBuffers(1, textureBuffers);
|
||||
// Check that our framebuffer is ok
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERRORC("TileProvider", "Incomplete framebuffer");
|
||||
}
|
||||
// Setup our own viewport settings
|
||||
GLsizei w = static_cast<GLsizei>(writeTexture->width());
|
||||
GLsizei h = static_cast<GLsizei>(writeTexture->height());
|
||||
glViewport(0, 0, w, h);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLint id;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &id);
|
||||
// Activate shader and bind uniforms
|
||||
shaderProgram->activate();
|
||||
shaderProgram->setUniform("blendFactor", factor);
|
||||
|
||||
ghoul::opengl::TextureUnit colormapUnit;
|
||||
colormapUnit.activate();
|
||||
colormapTexture->bind();
|
||||
shaderProgram->setUniform("colormapTexture", colormapUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit prevUnit;
|
||||
prevUnit.activate();
|
||||
prev.texture->bind();
|
||||
shaderProgram->setUniform("prevTexture", prevUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit nextUnit;
|
||||
nextUnit.activate();
|
||||
next.texture->bind();
|
||||
shaderProgram->setUniform("nextTexture", nextUnit);
|
||||
|
||||
// Render to the texture
|
||||
glBindVertexArray(vaoQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6); // 2 triangles
|
||||
// Deactivate shader program (when rendering is completed)
|
||||
shaderProgram->deactivate();
|
||||
glUseProgram(id);
|
||||
// Restores system state
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, currentFBO);
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
// Restores OpenGL Rendering State
|
||||
global::renderEngine->openglStateCache().resetColorState();
|
||||
global::renderEngine->openglStateCache().resetBlendState();
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
global::renderEngine->openglStateCache().resetPolygonAndClippingState();
|
||||
global::renderEngine->openglStateCache().resetViewportState();
|
||||
|
||||
return ourTile;
|
||||
}
|
||||
|
||||
Tile::Status InterpolateTileProvider::tileStatus(const TileIndex& index) {
|
||||
Tile::Status t1Stat = t1->tileStatus(index);
|
||||
Tile::Status t2Stat = t2->tileStatus(index);
|
||||
if (t1Stat <= t2Stat) {
|
||||
return t1Stat;
|
||||
}
|
||||
else {
|
||||
return t2Stat;
|
||||
}
|
||||
}
|
||||
|
||||
TileDepthTransform InterpolateTileProvider::depthTransform() {
|
||||
return t1->depthTransform();
|
||||
}
|
||||
|
||||
void InterpolateTileProvider::update() {
|
||||
t1->update();
|
||||
t2->update();
|
||||
before->update();
|
||||
future->update();
|
||||
}
|
||||
|
||||
void InterpolateTileProvider::reset() {
|
||||
t1->reset();
|
||||
t2->reset();
|
||||
before->reset();
|
||||
future->reset();
|
||||
}
|
||||
|
||||
int InterpolateTileProvider::maxLevel() {
|
||||
return glm::min(t1->maxLevel(), t2->maxLevel());
|
||||
}
|
||||
|
||||
float InterpolateTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,62 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__INTERPOLATEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__INTERPOLATEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct InterpolateTileProvider : public TileProvider {
|
||||
InterpolateTileProvider(const ghoul::Dictionary&);
|
||||
virtual ~InterpolateTileProvider();
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
TileProvider* before = nullptr;
|
||||
TileProvider* t1 = nullptr;
|
||||
TileProvider* t2 = nullptr;
|
||||
TileProvider* future = nullptr;
|
||||
float factor = 1.f;
|
||||
GLuint vaoQuad = 0;
|
||||
GLuint vboQuad = 0;
|
||||
GLuint fbo = 0;
|
||||
std::string colormap;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> shaderProgram;
|
||||
std::unique_ptr<SingleImageProvider> singleImageProvider;
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__INTERPOLATEPROVIDER___H__
|
||||
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"The file path that is used for this image provider. The file must point to an "
|
||||
"image that is then loaded and used for all tiles."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary)
|
||||
: filePath(FilePathInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
filePath = dictionary.value<std::string>(KeyFilePath);
|
||||
addProperty(filePath);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
Tile SingleImageProvider::tile(const TileIndex&) {
|
||||
ZoneScoped
|
||||
return ttile;
|
||||
}
|
||||
|
||||
Tile::Status SingleImageProvider::tileStatus(const TileIndex&) {
|
||||
return ttile.status;
|
||||
}
|
||||
|
||||
TileDepthTransform SingleImageProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void SingleImageProvider::update() {}
|
||||
|
||||
void SingleImageProvider::reset() {
|
||||
if (filePath.value().empty()) {
|
||||
return;
|
||||
}
|
||||
tileTexture = ghoul::io::TextureReader::ref().loadTexture(filePath, 2);
|
||||
if (!tileTexture) {
|
||||
throw ghoul::RuntimeError(
|
||||
fmt::format("Unable to load texture '{}'", filePath.value())
|
||||
);
|
||||
}
|
||||
Tile::Status tileStatus = Tile::Status::OK;
|
||||
|
||||
tileTexture->uploadTexture();
|
||||
tileTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
ttile = Tile{ tileTexture.get(), std::nullopt, tileStatus };
|
||||
}
|
||||
|
||||
int SingleImageProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float SingleImageProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,52 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct SingleImageProvider : public TileProvider {
|
||||
SingleImageProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> tileTexture;
|
||||
Tile ttile;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
@@ -0,0 +1,112 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/sizereferencetileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/geodeticpatch.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyRadii = "Radii";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: TextTileProvider(tileTextureInitData(layergroupid::GroupID::ColorLayers, false))
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
font = global::fontManager->font("Mono", static_cast<float>(fontSize));
|
||||
|
||||
if (dictionary.hasValue<glm::dvec3>(KeyRadii)) {
|
||||
ellipsoid = dictionary.value<glm::dvec3>(KeyRadii);
|
||||
}
|
||||
else if (dictionary.hasValue<double>(KeyRadii)) {
|
||||
const double r = dictionary.value<double>(KeyRadii);
|
||||
ellipsoid = glm::dvec3(r, r, r);
|
||||
}
|
||||
}
|
||||
|
||||
Tile SizeReferenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
const GeodeticPatch patch(tileIndex);
|
||||
const bool aboveEquator = patch.isNorthern();
|
||||
const double lat = aboveEquator ? patch.minLat() : patch.maxLat();
|
||||
const double lon1 = patch.minLon();
|
||||
const double lon2 = patch.maxLon();
|
||||
int l = static_cast<int>(ellipsoid.longitudalDistance(lat, lon1, lon2));
|
||||
|
||||
const bool useKm = l > 9999;
|
||||
if (useKm) {
|
||||
l /= 1000;
|
||||
}
|
||||
l = static_cast<int>(std::round(l));
|
||||
if (useKm) {
|
||||
l *= 1000;
|
||||
}
|
||||
double tileLongitudalLength = l;
|
||||
|
||||
const char* unit;
|
||||
if (tileLongitudalLength > 9999) {
|
||||
tileLongitudalLength *= 0.001;
|
||||
unit = "km";
|
||||
}
|
||||
else {
|
||||
unit = "m";
|
||||
}
|
||||
|
||||
text = fmt::format(" {:.0f} {:s}", tileLongitudalLength, unit);
|
||||
textPosition = {
|
||||
0.f,
|
||||
aboveEquator ?
|
||||
fontSize / 2.f :
|
||||
initData.dimensions.y - 3.f * fontSize / 2.f
|
||||
};
|
||||
textColor = glm::vec4(1.f);
|
||||
|
||||
return TextTileProvider::tile(tileIndex);
|
||||
}
|
||||
|
||||
Tile::Status SizeReferenceTileProvider::tileStatus(const TileIndex& index) {
|
||||
return Tile::Status::OK;
|
||||
}
|
||||
|
||||
TileDepthTransform SizeReferenceTileProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void SizeReferenceTileProvider::update() {}
|
||||
|
||||
int SizeReferenceTileProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float SizeReferenceTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct SizeReferenceTileProvider : public TextTileProvider {
|
||||
SizeReferenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
Ellipsoid ellipsoid;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
@@ -0,0 +1,527 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/temporaltileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include "cpl_minixml.h"
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyBasePath = "BasePath";
|
||||
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
constexpr const char* UrlTimePlaceholder = "${OpenSpaceTimeId}";
|
||||
constexpr const char* TimeStart = "OpenSpaceTimeStart";
|
||||
constexpr const char* TimeEnd = "OpenSpaceTimeEnd";
|
||||
constexpr const char* TimeResolution = "OpenSpaceTimeResolution";
|
||||
constexpr const char* TimeFormat = "OpenSpaceTimeIdFormat";
|
||||
constexpr const char* TimeInterpolation = "OpenSpaceTimeInterpolation";
|
||||
constexpr const char* TransferFunction = "OpenSpaceTransferFunction";
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"This is the path to the XML configuration file that describes the temporal tile "
|
||||
"information."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo UseFixedTimeInfo = {
|
||||
"UseFixedTime",
|
||||
"Use Fixed Time",
|
||||
"If this value is enabled, the time-varying timevarying dataset will always use "
|
||||
"the time that is specified in the 'FixedTime' property, rather than using the "
|
||||
"actual time from OpenSpace"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FixedTimeInfo = {
|
||||
"FixedTime",
|
||||
"Fixed Time",
|
||||
"If the 'UseFixedTime' is enabled, this time will be used instead of the actual "
|
||||
"time taken from OpenSpace for the displayed tiles."
|
||||
};
|
||||
|
||||
|
||||
std::string xmlValue(openspace::globebrowsing::TemporalTileProvider& t,
|
||||
CPLXMLNode* node, const std::string& key,
|
||||
const std::string& defaultVal, bool isOptional = false)
|
||||
{
|
||||
CPLXMLNode* n = CPLSearchXMLNode(node, key.c_str());
|
||||
if (!n && !isOptional) {
|
||||
throw ghoul::RuntimeError(
|
||||
fmt::format("Unable to parse file {}. {} missing", t.filePath.value(), key)
|
||||
);
|
||||
}
|
||||
|
||||
const bool hasValue = n && n->psChild && n->psChild->pszValue;
|
||||
return hasValue ? n->psChild->pszValue : defaultVal;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace ghoul {
|
||||
template <>
|
||||
constexpr openspace::globebrowsing::TemporalTileProvider::TimeFormatType
|
||||
from_string(std::string_view string)
|
||||
{
|
||||
using namespace openspace::globebrowsing;
|
||||
if (string == "YYYY-MM-DD") {
|
||||
return TemporalTileProvider::TimeFormatType::YYYY_MM_DD;
|
||||
}
|
||||
else if (string == "YYYY-MM-DDThh:mm:ssZ") {
|
||||
return TemporalTileProvider::TimeFormatType::YYYY_MM_DDThhColonmmColonssZ;
|
||||
}
|
||||
else if (string == "YYYY-MM-DDThh_mm_ssZ") {
|
||||
return TemporalTileProvider::TimeFormatType::YYYY_MM_DDThh_mm_ssZ;
|
||||
}
|
||||
else if (string == "YYYYMMDD_hhmmss") {
|
||||
return TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmmss;
|
||||
}
|
||||
else if (string == "YYYYMMDD_hhmm") {
|
||||
return TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmm;
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError("Unknown timeformat '" + std::string(string) + "'");
|
||||
}
|
||||
}
|
||||
} // namespace ghoul
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: initDict(dictionary)
|
||||
, filePath(FilePathInfo)
|
||||
, useFixedTime(UseFixedTimeInfo, false)
|
||||
, fixedTime(FixedTimeInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
filePath = dictionary.value<std::string>(KeyFilePath);
|
||||
addProperty(filePath);
|
||||
|
||||
if (dictionary.hasValue<bool>(UseFixedTimeInfo.identifier)) {
|
||||
useFixedTime = dictionary.value<bool>(UseFixedTimeInfo.identifier);
|
||||
}
|
||||
addProperty(useFixedTime);
|
||||
|
||||
if (dictionary.hasValue<std::string>(FixedTimeInfo.identifier)) {
|
||||
fixedTime = dictionary.value<std::string>(FixedTimeInfo.identifier);
|
||||
}
|
||||
addProperty(fixedTime);
|
||||
|
||||
readFilePath();
|
||||
|
||||
if (interpolation) {
|
||||
interpolateTileProvider = std::make_unique<InterpolateTileProvider>(dictionary);
|
||||
interpolateTileProvider->colormap = colormap;
|
||||
interpolateTileProvider->initialize();
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("FilePath", colormap);
|
||||
interpolateTileProvider->singleImageProvider =
|
||||
std::make_unique<SingleImageProvider>(dict);
|
||||
}
|
||||
}
|
||||
|
||||
void TemporalTileProvider::readFilePath() {
|
||||
ZoneScoped
|
||||
|
||||
std::ifstream in(filePath.value());
|
||||
std::string xml;
|
||||
if (in.is_open()) {
|
||||
// read file
|
||||
xml = std::string(
|
||||
std::istreambuf_iterator<char>(in),
|
||||
(std::istreambuf_iterator<char>())
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Assume that it is already an xml
|
||||
xml = filePath;
|
||||
}
|
||||
|
||||
// File path was not a path to a file but a GDAL config or empty
|
||||
std::filesystem::path f(filePath.value());
|
||||
if (std::filesystem::is_regular_file(f)) {
|
||||
initDict.setValue(KeyBasePath, f.parent_path().string());
|
||||
}
|
||||
|
||||
gdalXmlTemplate = consumeTemporalMetaData(xml);
|
||||
}
|
||||
|
||||
std::string TemporalTileProvider::consumeTemporalMetaData(const std::string& xml) {
|
||||
ZoneScoped
|
||||
|
||||
CPLXMLNode* node = CPLParseXMLString(xml.c_str());
|
||||
|
||||
std::string timeStart = xmlValue(*this, node, TimeStart, "2000 Jan 1");
|
||||
std::string timeResolution = xmlValue(*this, node, TimeResolution, "2d");
|
||||
std::string timeEnd = xmlValue(*this, node, TimeEnd, "Today");
|
||||
std::string timeIdFormat = xmlValue(
|
||||
*this,
|
||||
node,
|
||||
TimeFormat,
|
||||
"YYYY-MM-DDThh:mm:ssZ"
|
||||
);
|
||||
std::string timeInterpolation = xmlValue(
|
||||
*this,
|
||||
node,
|
||||
TimeInterpolation,
|
||||
"none",
|
||||
true
|
||||
);
|
||||
colormap = xmlValue(*this, node, TransferFunction, "none", true);
|
||||
|
||||
Time start = Time(timeStart);
|
||||
Time end = Time::now();
|
||||
Time endOfInterval = Time(timeEnd);
|
||||
startTimeJ2000 = start.j2000Seconds();
|
||||
endTimeJ2000 = endOfInterval.j2000Seconds();
|
||||
if (timeEnd == "Yesterday") {
|
||||
end.advanceTime(-60.0 * 60.0 * 24.0); // Go back one day
|
||||
}
|
||||
else if (timeEnd != "Today") {
|
||||
end.setTime(std::move(timeEnd));
|
||||
}
|
||||
|
||||
try {
|
||||
timeQuantizer.setStartEndRange(
|
||||
std::string(start.ISO8601()),
|
||||
std::string(end.ISO8601())
|
||||
);
|
||||
timeQuantizer.setResolution(timeResolution);
|
||||
myResolution = timeResolution;
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Could not create time quantizer for Temporal GDAL dataset '{}'. {}",
|
||||
filePath.value(), e.message
|
||||
));
|
||||
}
|
||||
timeFormat = ghoul::from_string<TemporalTileProvider::TimeFormatType>(timeIdFormat);
|
||||
interpolation = (timeInterpolation == "linear");
|
||||
|
||||
CPLXMLNode* gdalNode = CPLSearchXMLNode(node, "GDAL_WMS");
|
||||
if (gdalNode) {
|
||||
std::string gdalDescription = CPLSerializeXMLTree(gdalNode);
|
||||
return gdalDescription;
|
||||
}
|
||||
else {
|
||||
gdalNode = CPLSearchXMLNode(node, "FilePath");
|
||||
if (gdalNode) {
|
||||
std::string gdalDescription = std::string(gdalNode->psChild->pszValue);
|
||||
return gdalDescription;
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TemporalTileProvider::ensureUpdated() {
|
||||
ZoneScoped
|
||||
|
||||
if (!currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
Tile TemporalTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ensureUpdated();
|
||||
return currentTileProvider->tile(tileIndex);
|
||||
}
|
||||
|
||||
Tile::Status TemporalTileProvider::tileStatus(const TileIndex& index) {
|
||||
ensureUpdated();
|
||||
return currentTileProvider->tileStatus(index);
|
||||
}
|
||||
|
||||
TileDepthTransform TemporalTileProvider::depthTransform() {
|
||||
ensureUpdated();
|
||||
return currentTileProvider->depthTransform();
|
||||
}
|
||||
|
||||
void TemporalTileProvider::update() {
|
||||
TileProvider* newCurr = getTileProvider(global::timeManager->time());
|
||||
if (newCurr) {
|
||||
currentTileProvider = newCurr;
|
||||
}
|
||||
if (currentTileProvider) {
|
||||
currentTileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TemporalTileProvider::reset() {
|
||||
using K = TemporalTileProvider::TimeKey;
|
||||
using V = std::unique_ptr<TileProvider>;
|
||||
for (std::pair<const K, V>& it : tileProviderMap) {
|
||||
it.second->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int TemporalTileProvider::maxLevel() {
|
||||
ensureUpdated();
|
||||
return currentTileProvider->maxLevel();
|
||||
}
|
||||
|
||||
float TemporalTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
// Buffer needs at least 22 characters space
|
||||
std::string_view TemporalTileProvider::timeStringify(TemporalTileProvider::TimeFormatType type, const Time& t) {
|
||||
ZoneScoped
|
||||
|
||||
char* buffer = reinterpret_cast<char*>(
|
||||
global::memoryManager->TemporaryMemory.allocate(22)
|
||||
);
|
||||
|
||||
std::memset(buffer, 0, 22);
|
||||
const double time = t.j2000Seconds();
|
||||
|
||||
switch (type) {
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DD:
|
||||
{
|
||||
constexpr const char Format[] = "YYYY-MM-DD";
|
||||
constexpr const int Size = sizeof(Format);
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
|
||||
return std::string_view(buffer, Size - 1);
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmmss: {
|
||||
constexpr const char Format[] = "YYYYMMDD_HRMNSC";
|
||||
constexpr const int Size = sizeof(Format);
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
|
||||
return std::string_view(buffer, Size - 1);
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmm: {
|
||||
constexpr const char Format[] = "YYYYMMDD_HRMN";
|
||||
constexpr const int Size = sizeof(Format);
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
|
||||
return std::string_view(buffer, Size - 1);
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThhColonmmColonssZ:
|
||||
{
|
||||
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SCZ";
|
||||
constexpr const int Size = sizeof(Format);
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
|
||||
return std::string_view(buffer, Size - 1);
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThh_mm_ssZ: {
|
||||
constexpr const char Format[] = "YYYY-MM-DDTHR_MN_SCZ";
|
||||
constexpr const int Size = sizeof(Format);
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
|
||||
return std::string_view(buffer, Size - 1);
|
||||
}
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TileProvider> TemporalTileProvider::initTileProvider(
|
||||
std::string_view timekey)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
static const std::vector<std::string> IgnoredTokens = {
|
||||
// From: http://www.gdal.org/frmt_wms.html
|
||||
"${x}",
|
||||
"${y}",
|
||||
"${z}",
|
||||
"${version}",
|
||||
"${format}",
|
||||
"${layer}"
|
||||
};
|
||||
|
||||
|
||||
std::string xmlTemplate(gdalXmlTemplate);
|
||||
const size_t pos = xmlTemplate.find(UrlTimePlaceholder);
|
||||
const size_t numChars = strlen(UrlTimePlaceholder);
|
||||
// @FRAGILE: This will only find the first instance. Dangerous if that instance is
|
||||
// commented out ---abock
|
||||
std::string xml = xmlTemplate.replace(pos, numChars, timekey);
|
||||
|
||||
xml = FileSys.expandPathTokens(std::move(xml), IgnoredTokens).string();
|
||||
|
||||
initDict.setValue(KeyFilePath, xml);
|
||||
return std::make_unique<DefaultTileProvider>(initDict);
|
||||
}
|
||||
|
||||
TileProvider* TemporalTileProvider::getTileProvider(std::string_view timekey) {
|
||||
ZoneScoped
|
||||
|
||||
// @TODO (abock, 2020-08-20) This std::string creation can be removed once we switch
|
||||
// to C++20 thanks to P0919R2
|
||||
const auto it = tileProviderMap.find(std::string(timekey));
|
||||
if (it != tileProviderMap.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
else {
|
||||
std::unique_ptr<TileProvider> tileProvider = initTileProvider(timekey);
|
||||
tileProvider->initialize();
|
||||
|
||||
TileProvider* res = tileProvider.get();
|
||||
tileProviderMap[std::string(timekey)] = std::move(tileProvider);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
TileProvider* TemporalTileProvider::getTileProvider(const Time& time) {
|
||||
ZoneScoped
|
||||
|
||||
if (!interpolation) {
|
||||
if (useFixedTime && !fixedTime.value().empty()) {
|
||||
try {
|
||||
return getTileProvider(fixedTime.value());
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Time tCopy(time);
|
||||
if (timeQuantizer.quantize(tCopy, true)) {
|
||||
std::string_view timeStr = timeStringify(timeFormat, tCopy);
|
||||
try {
|
||||
return getTileProvider(timeStr);
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Time tCopy(time);
|
||||
if (!timeQuantizer.quantize(tCopy, true)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Time simulationTime(time);
|
||||
Time nextTile;
|
||||
Time nextNextTile;
|
||||
Time prevTile;
|
||||
Time secondToLast;
|
||||
Time secondToFirst;
|
||||
|
||||
std::string_view tCopyStr = timeStringify(timeFormat, tCopy);
|
||||
try {
|
||||
interpolateTileProvider->t1 = getTileProvider(tCopyStr);
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
// if the images are for each hour
|
||||
if (myResolution == "1h") {
|
||||
// the second tile to interpolate between
|
||||
nextTile.setTime(tCopy.j2000Seconds() + 60 * 60);
|
||||
// the tile after the second tile
|
||||
nextNextTile.setTime(tCopy.j2000Seconds() + 120 * 60);
|
||||
// the tile before the first tile
|
||||
prevTile.setTime(tCopy.j2000Seconds() - 60 * 60 + 1);
|
||||
// to make sure that an image outside the dataset is not searched for both ends of
|
||||
// the dataset are calculated
|
||||
secondToLast.setTime(endTimeJ2000 - 60 * 60);
|
||||
secondToFirst.setTime(startTimeJ2000 + 60 * 60);
|
||||
}
|
||||
// if the images are for each month
|
||||
if (myResolution == "1M") {
|
||||
// the second tile to interpolate between
|
||||
nextTile.setTime(tCopy.j2000Seconds() + 32 * 60 * 60 * 24);
|
||||
// the tile after the second tile
|
||||
nextNextTile.setTime(tCopy.j2000Seconds() + 64 * 60 * 60 * 24);
|
||||
// the tile before the first tile
|
||||
prevTile.setTime(tCopy.j2000Seconds() - 2 * 60 * 60 * 24);
|
||||
// to make sure that an image outside the dataset is not searched for both ends of
|
||||
// the dataset are calculated
|
||||
secondToLast.setTime(endTimeJ2000 - 2 * 60 * 60 * 24);
|
||||
secondToFirst.setTime(startTimeJ2000 + 32 * 60 * 60 * 24);
|
||||
|
||||
// since months vary in length the time strings are set to the first of each month
|
||||
auto setToFirstOfMonth = [](Time& time) {
|
||||
std::string timeString = std::string(time.ISO8601());
|
||||
timeString[8] = '0';
|
||||
timeString[9] = '1';
|
||||
time.setTime(timeString);
|
||||
};
|
||||
|
||||
setToFirstOfMonth(nextTile);
|
||||
setToFirstOfMonth(nextNextTile);
|
||||
setToFirstOfMonth(prevTile);
|
||||
setToFirstOfMonth(secondToLast);
|
||||
setToFirstOfMonth(secondToFirst);
|
||||
}
|
||||
|
||||
std::string_view nextTileStr = timeStringify(timeFormat, nextTile);
|
||||
std::string_view nextNextTileStr = timeStringify(timeFormat, nextNextTile);
|
||||
std::string_view prevTileStr = timeStringify(timeFormat, prevTile);
|
||||
try {
|
||||
// the necessary tile providers are loaded if they exist within the
|
||||
// dataset's timespan
|
||||
if (secondToLast.j2000Seconds() > simulationTime.j2000Seconds() &&
|
||||
secondToFirst.j2000Seconds() < simulationTime.j2000Seconds())
|
||||
{
|
||||
interpolateTileProvider->t2 = getTileProvider(nextTileStr);
|
||||
interpolateTileProvider->future = getTileProvider(nextNextTileStr);
|
||||
interpolateTileProvider->before = getTileProvider(prevTileStr);
|
||||
}
|
||||
else if (secondToLast.j2000Seconds() < simulationTime.j2000Seconds() &&
|
||||
endTimeJ2000 > simulationTime.j2000Seconds())
|
||||
{
|
||||
interpolateTileProvider->t2 = getTileProvider(nextTileStr);
|
||||
interpolateTileProvider->future = getTileProvider(tCopyStr);
|
||||
interpolateTileProvider->before = getTileProvider(prevTileStr);
|
||||
}
|
||||
else if (secondToFirst.j2000Seconds() > simulationTime.j2000Seconds() &&
|
||||
startTimeJ2000 < simulationTime.j2000Seconds())
|
||||
{
|
||||
interpolateTileProvider->t2 = getTileProvider(nextTileStr);
|
||||
interpolateTileProvider->future = getTileProvider(nextNextTileStr);
|
||||
interpolateTileProvider->before = getTileProvider(tCopyStr);
|
||||
}
|
||||
else {
|
||||
interpolateTileProvider->t2 = getTileProvider(tCopyStr);
|
||||
interpolateTileProvider->future = getTileProvider(tCopyStr);
|
||||
interpolateTileProvider->before = getTileProvider(tCopyStr);
|
||||
}
|
||||
interpolateTileProvider->factor =
|
||||
(simulationTime.j2000Seconds() - tCopy.j2000Seconds()) /
|
||||
(nextTile.j2000Seconds() - tCopy.j2000Seconds());
|
||||
|
||||
if (interpolateTileProvider->factor > 1) {
|
||||
interpolateTileProvider->factor = 1;
|
||||
}
|
||||
return interpolateTileProvider.get();
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,99 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/interpolatetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Provide <code>Tile</code>s from web map services that have temporal resolution.
|
||||
*
|
||||
* TemporalTileProviders are instantiated using a ghoul::Dictionary, and must define a
|
||||
* filepath to a Openspace Temporal dataset description file. This is an xml-file that
|
||||
* defines the same meta data as the GDAL wms description
|
||||
* (http://www.gdal.org/frmt_wms.html), but augmented with some extra tags describing the
|
||||
* temporal properties of the dataset. See
|
||||
* <code>TemporalTileProvider::TemporalXMLTags</code>
|
||||
*/
|
||||
struct TemporalTileProvider : public TileProvider {
|
||||
enum class TimeFormatType {
|
||||
YYYY_MM_DD = 0,
|
||||
YYYYMMDD_hhmmss,
|
||||
YYYYMMDD_hhmm,
|
||||
YYYY_MM_DDThhColonmmColonssZ,
|
||||
YYYY_MM_DDThh_mm_ssZ
|
||||
};
|
||||
|
||||
using TimeKey = std::string;
|
||||
|
||||
TemporalTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
properties::StringProperty filePath;
|
||||
properties::BoolProperty useFixedTime;
|
||||
properties::StringProperty fixedTime;
|
||||
std::string gdalXmlTemplate;
|
||||
|
||||
std::unordered_map<TimeKey, std::unique_ptr<TileProvider>> tileProviderMap;
|
||||
|
||||
bool interpolation = false;
|
||||
|
||||
TileProvider* currentTileProvider = nullptr;
|
||||
double startTimeJ2000;
|
||||
double endTimeJ2000;
|
||||
TimeFormatType timeFormat;
|
||||
TimeQuantizer timeQuantizer;
|
||||
std::string colormap;
|
||||
|
||||
std::string myResolution;
|
||||
std::unique_ptr<InterpolateTileProvider> interpolateTileProvider;
|
||||
|
||||
private:
|
||||
void readFilePath();
|
||||
std::string consumeTemporalMetaData(const std::string& xml);
|
||||
void ensureUpdated();
|
||||
std::string_view timeStringify(TimeFormatType type, const Time& t);
|
||||
std::unique_ptr<TileProvider> initTileProvider(std::string_view timekey);
|
||||
TileProvider* getTileProvider(std::string_view timekey);
|
||||
TileProvider* getTileProvider(const Time& time);
|
||||
};
|
||||
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
@@ -0,0 +1,108 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TextTileProvider::TextTileProvider(TileTextureInitData initData_, size_t fontSize_)
|
||||
: initData(std::move(initData_))
|
||||
, fontSize(fontSize_)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
tileCache = global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
}
|
||||
|
||||
TextTileProvider::~TextTileProvider() {}
|
||||
|
||||
void TextTileProvider::internalInitialize() {
|
||||
ZoneScoped
|
||||
|
||||
font = global::fontManager->font("Mono", static_cast<float>(fontSize));
|
||||
fontRenderer = ghoul::fontrendering::FontRenderer::createDefault();
|
||||
fontRenderer->setFramebufferSize(glm::vec2(initData.dimensions));
|
||||
glGenFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
void TextTileProvider::internalDeinitialize() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
Tile TextTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
TracyGpuZone("tile")
|
||||
|
||||
cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
Tile tile = tileCache->get(key);
|
||||
if (!tile.texture) {
|
||||
ghoul::opengl::Texture* texture = tileCache->texture(initData);
|
||||
|
||||
// Keep track of defaultFBO and viewport to be able to reset state when done
|
||||
GLint defaultFBO;
|
||||
defaultFBO = global::renderEngine->openglStateCache().defaultFramebuffer();
|
||||
|
||||
// Render to texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
*texture,
|
||||
0
|
||||
);
|
||||
|
||||
GLsizei w = static_cast<GLsizei>(texture->width());
|
||||
GLsizei h = static_cast<GLsizei>(texture->height());
|
||||
glViewport(0, 0, w, h);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
fontRenderer->render(*font, textPosition, text, textColor);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
global::renderEngine->openglStateCache().resetViewportState();
|
||||
|
||||
tile = Tile{ texture, std::nullopt, Tile::Status::OK };
|
||||
tileCache->put(key, initData.hashKey, tile);
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
void TextTileProvider::reset() {
|
||||
ZoneScoped
|
||||
|
||||
tileCache->clear();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,61 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TextTileProvider : public TileProvider {
|
||||
TextTileProvider(TileTextureInitData initData, size_t fontSize = 48);
|
||||
virtual ~TextTileProvider();
|
||||
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override;
|
||||
void reset() override;
|
||||
|
||||
const TileTextureInitData initData;
|
||||
|
||||
std::unique_ptr<ghoul::fontrendering::FontRenderer> fontRenderer;
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font;
|
||||
size_t fontSize = 0;
|
||||
|
||||
std::string text;
|
||||
glm::vec2 textPosition = glm::vec2(0.f);
|
||||
glm::vec4 textColor = glm::vec4(0.f);
|
||||
|
||||
GLuint fbo = 0;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache;
|
||||
|
||||
private:
|
||||
void internalInitialize() override final;
|
||||
void internalDeinitialize() override final;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
@@ -0,0 +1,66 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileindextileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileIndexTileProvider::TileIndexTileProvider(const ghoul::Dictionary&)
|
||||
: TextTileProvider(tileTextureInitData(layergroupid::GroupID::ColorLayers, false))
|
||||
{}
|
||||
|
||||
Tile TileIndexTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
text = fmt::format(
|
||||
"level: {}\nx: {}\ny: {}", tileIndex.level, tileIndex.x, tileIndex.y
|
||||
);
|
||||
textPosition = glm::vec2(
|
||||
initData.dimensions.x / 4 -
|
||||
(initData.dimensions.x / 32) * log10(1 << tileIndex.level),
|
||||
initData.dimensions.y / 2 + fontSize
|
||||
);
|
||||
textColor = glm::vec4(1.f);
|
||||
|
||||
return TextTileProvider::tile(tileIndex);
|
||||
}
|
||||
|
||||
Tile::Status TileIndexTileProvider::tileStatus(const TileIndex&) {
|
||||
return Tile::Status::OK;
|
||||
}
|
||||
|
||||
TileDepthTransform TileIndexTileProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void TileIndexTileProvider::update() {}
|
||||
|
||||
int TileIndexTileProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float TileIndexTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileIndexTileProvider : public TextTileProvider {
|
||||
TileIndexTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
@@ -0,0 +1,213 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/asynctiledataprovider.h>
|
||||
#include <modules/globebrowsing/src/geodeticpatch.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/rawtiledatareader.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/interpolatetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/sizereferencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/temporaltileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileindextileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include "cpl_minixml.h"
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> DefaultTileTexture;
|
||||
Tile DefaultTile = Tile { nullptr, std::nullopt, Tile::Status::Unavailable };
|
||||
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
|
||||
void reset(TextTileProvider& t) {
|
||||
ZoneScoped
|
||||
|
||||
t.tileCache->clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
unsigned int TileProvider::NumTileProviders = 0;
|
||||
|
||||
|
||||
std::unique_ptr<TileProvider> TileProvider::createFromDictionary(
|
||||
layergroupid::TypeID layerTypeID,
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const char* type = layergroupid::LAYER_TYPE_NAMES[static_cast<int>(layerTypeID)];
|
||||
auto factory = FactoryManager::ref().factory<TileProvider>();
|
||||
TileProvider* result = factory->create(type, dictionary);
|
||||
return std::unique_ptr<TileProvider>(result);
|
||||
}
|
||||
|
||||
TileProvider::TileProvider() : properties::PropertyOwner({ "tileProvider" }) {}
|
||||
|
||||
void TileProvider::initialize() {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(!isInitialized, "TileProvider can only be initialized once.");
|
||||
|
||||
if (TileProvider::NumTileProviders >
|
||||
static_cast<unsigned int>(std::numeric_limits<uint16_t>::max()) - 1)
|
||||
{
|
||||
LERRORC(
|
||||
"TileProvider",
|
||||
"Number of tile providers exceeds 65535. Something will break soon"
|
||||
);
|
||||
TileProvider::NumTileProviders = 0;
|
||||
}
|
||||
uniqueIdentifier = static_cast<uint16_t>(TileProvider::NumTileProviders++);
|
||||
if (TileProvider::NumTileProviders == std::numeric_limits<unsigned int>::max()) {
|
||||
--TileProvider::NumTileProviders;
|
||||
return;
|
||||
}
|
||||
|
||||
internalInitialize();
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
void TileProvider::deinitialize() {
|
||||
ZoneScoped
|
||||
|
||||
internalDeinitialize();
|
||||
}
|
||||
|
||||
void TileProvider::internalInitialize() {}
|
||||
void TileProvider::internalDeinitialize() {}
|
||||
|
||||
ChunkTile TileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParents) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized.");
|
||||
|
||||
auto ascendToParent = [](TileIndex& ti, TileUvTransform& uv) {
|
||||
uv.uvOffset *= 0.5;
|
||||
uv.uvScale *= 0.5;
|
||||
|
||||
uv.uvOffset += ti.positionRelativeParent();
|
||||
|
||||
ti.x /= 2;
|
||||
ti.y /= 2;
|
||||
ti.level--;
|
||||
};
|
||||
|
||||
TileUvTransform uvTransform = { glm::vec2(0.f, 0.f), glm::vec2(1.f, 1.f) };
|
||||
|
||||
// Step 1. Traverse 0 or more parents up the chunkTree as requested by the caller
|
||||
for (int i = 0; i < parents && tileIndex.level > 1; i++) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
maxParents -= parents;
|
||||
|
||||
// Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside
|
||||
// the range of defined data.
|
||||
int maximumLevel = maxLevel();
|
||||
while (tileIndex.level > maximumLevel) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
maxParents--;
|
||||
}
|
||||
if (maxParents < 0) {
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
|
||||
// Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that
|
||||
// has a loaded tile ready to use.
|
||||
while (tileIndex.level > 1) {
|
||||
Tile t = tile(tileIndex);
|
||||
if (t.status != Tile::Status::OK) {
|
||||
if (--maxParents < 0) {
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
else {
|
||||
return ChunkTile { std::move(t), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
}
|
||||
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
|
||||
ChunkTilePile TileProvider::chunkTilePile(TileIndex tileIndex, int pileSize) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized.");
|
||||
ghoul_assert(pileSize >= 0, "pileSize must be positive");
|
||||
|
||||
ChunkTilePile chunkTilePile;
|
||||
std::fill(chunkTilePile.begin(), chunkTilePile.end(), std::nullopt);
|
||||
for (int i = 0; i < pileSize; ++i) {
|
||||
chunkTilePile[i] = chunkTile(tileIndex, i);
|
||||
if (chunkTilePile[i]->tile.status == Tile::Status::Unavailable) {
|
||||
if (i == 0) {
|
||||
// First iteration
|
||||
chunkTilePile[i]->tile = DefaultTile;
|
||||
chunkTilePile[i]->uvTransform.uvOffset = { 0.f, 0.f };
|
||||
chunkTilePile[i]->uvTransform.uvScale = { 1.f, 1.f };
|
||||
}
|
||||
else {
|
||||
// We are iterating through the array one-by-one, so we are guaranteed
|
||||
// that for tile 'i', tile 'i-1' already was initializated
|
||||
chunkTilePile[i]->tile = chunkTilePile[i - 1]->tile;
|
||||
chunkTilePile[i]->uvTransform.uvOffset =
|
||||
chunkTilePile[i - 1]->uvTransform.uvOffset;
|
||||
chunkTilePile[i]->uvTransform.uvScale =
|
||||
chunkTilePile[i - 1]->uvTransform.uvScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunkTilePile;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,142 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/ellipsoid.h>
|
||||
#include <modules/globebrowsing/src/layergroupid.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/timequantizer.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <unordered_map>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
struct CPLXMLNode;
|
||||
|
||||
namespace ghoul::fontrendering {
|
||||
class Font;
|
||||
class FontRenderer;
|
||||
} // namespace ghoul::fontrendering
|
||||
|
||||
namespace openspace { class PixelBuffer; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
class AsyncTileDataProvider;
|
||||
struct RawTile;
|
||||
struct TileIndex;
|
||||
namespace cache { class MemoryAwareTileCache; }
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
enum class Type {
|
||||
DefaultTileProvider = 0,
|
||||
SingleImageTileProvider,
|
||||
ImageSequenceTileProvider,
|
||||
SizeReferenceTileProvider,
|
||||
TemporalTileProvider,
|
||||
TileIndexTileProvider,
|
||||
ByIndexTileProvider,
|
||||
ByLevelTileProvider,
|
||||
InterpolateTileProvider
|
||||
};
|
||||
|
||||
|
||||
struct TileProvider : public properties::PropertyOwner {
|
||||
static unsigned int NumTileProviders;
|
||||
|
||||
static std::unique_ptr<TileProvider> createFromDictionary(
|
||||
layergroupid::TypeID layerTypeID, const ghoul::Dictionary& dictionary);
|
||||
|
||||
TileProvider();
|
||||
virtual ~TileProvider() = default;
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
virtual Tile tile(const TileIndex& tileIndex) = 0;
|
||||
|
||||
/**
|
||||
* Returns the status of a <code>Tile</code>. The <code>Tile::Status</code>
|
||||
* corresponds the <code>Tile</code> that would be returned if the function
|
||||
* <code>tile</code> would be invoked with the same <code>TileIndex</code> argument at
|
||||
* this point in time.
|
||||
*/
|
||||
virtual Tile::Status tileStatus(const TileIndex& index) = 0;
|
||||
|
||||
/**
|
||||
* Get the associated depth transform for this TileProvider. This is necessary for
|
||||
* TileProviders serving height map data, in order to correcly map pixel values to
|
||||
* meters.
|
||||
*/
|
||||
virtual TileDepthTransform depthTransform() = 0;
|
||||
|
||||
/**
|
||||
* This method should be called once per frame. Here, TileProviders are given the
|
||||
* opportunity to update their internal state.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/**
|
||||
* Provides a uniform way of all TileProviders to reload or restore all of its
|
||||
* internal state. This is mainly useful for debugging purposes.
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
/**
|
||||
* \return The maximum level as defined by <code>TileIndex</code> that this
|
||||
* TileProvider is able provide.
|
||||
*/
|
||||
virtual int maxLevel() = 0;
|
||||
|
||||
/**
|
||||
* \return the no data value for the dataset. Default is the minimum float value.
|
||||
*/
|
||||
virtual float noDataValueAsFloat() = 0;
|
||||
|
||||
|
||||
ChunkTile chunkTile(TileIndex tileIndex, int parents = 0, int maxParents = 1337);
|
||||
ChunkTilePile chunkTilePile(TileIndex tileIndex, int pileSize);
|
||||
|
||||
|
||||
std::string name;
|
||||
|
||||
uint16_t uniqueIdentifier = 0;
|
||||
bool isInitialized = false;
|
||||
|
||||
private:
|
||||
virtual void internalInitialize();
|
||||
virtual void internalDeinitialize();
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
@@ -0,0 +1,145 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyDefaultProvider = "DefaultProvider";
|
||||
constexpr const char* KeyProviders = "IndexTileProviders";
|
||||
constexpr const char* KeyTileIndex = "TileIndex";
|
||||
constexpr const char* KeyTileProvider = "TileProvider";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileProviderByIndex::TileProviderByIndex(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
|
||||
const ghoul::Dictionary& defaultProviderDict = dictionary.value<ghoul::Dictionary>(
|
||||
KeyDefaultProvider
|
||||
);
|
||||
|
||||
layergroupid::TypeID typeID;
|
||||
if (defaultProviderDict.hasValue<std::string>("Type")) {
|
||||
const std::string& t = defaultProviderDict.value<std::string>("Type");
|
||||
typeID = ghoul::from_string<layergroupid::TypeID>(t);
|
||||
|
||||
if (typeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + t);
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
}
|
||||
|
||||
defaultTileProvider = createFromDictionary(typeID, defaultProviderDict);
|
||||
|
||||
const ghoul::Dictionary& indexProvidersDict = dictionary.value<ghoul::Dictionary>(
|
||||
KeyProviders
|
||||
);
|
||||
for (size_t i = 1; i <= indexProvidersDict.size(); i++) {
|
||||
ghoul::Dictionary indexProviderDict = indexProvidersDict.value<ghoul::Dictionary>(
|
||||
std::to_string(i)
|
||||
);
|
||||
ghoul::Dictionary tileIndexDict = indexProviderDict.value<ghoul::Dictionary>(
|
||||
KeyTileIndex
|
||||
);
|
||||
ghoul::Dictionary providerDict = indexProviderDict.value<ghoul::Dictionary>(
|
||||
KeyTileProvider
|
||||
);
|
||||
|
||||
constexpr const char* KeyLevel = "Level";
|
||||
constexpr const char* KeyX = "X";
|
||||
constexpr const char* KeyY = "Y";
|
||||
|
||||
int level = static_cast<int>(tileIndexDict.value<double>(KeyLevel));
|
||||
ghoul_assert(level < std::numeric_limits<uint8_t>::max(), "Level too large");
|
||||
int x = static_cast<int>(tileIndexDict.value<double>(KeyX));
|
||||
int y = static_cast<int>(tileIndexDict.value<double>(KeyY));
|
||||
|
||||
const TileIndex tileIndex(x, y, static_cast<uint8_t>(level));
|
||||
|
||||
layergroupid::TypeID providerTypeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
if (defaultProviderDict.hasValue<std::string>("Type")) {
|
||||
const std::string& t = defaultProviderDict.value<std::string>("Type");
|
||||
providerTypeID = ghoul::from_string<layergroupid::TypeID>(t);
|
||||
|
||||
if (providerTypeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TileProvider> stp = createFromDictionary(
|
||||
providerTypeID,
|
||||
providerDict
|
||||
);
|
||||
TileIndex::TileHashKey key = tileIndex.hashKey();
|
||||
tileProviderMap.insert(std::make_pair(key, std::move(stp)));
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByIndex::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
const auto it = tileProviderMap.find(tileIndex.hashKey());
|
||||
const bool hasProvider = it != tileProviderMap.end();
|
||||
return hasProvider ? it->second->tile(tileIndex) : Tile();
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByIndex::tileStatus(const TileIndex& index) {
|
||||
const auto it = tileProviderMap.find(index.hashKey());
|
||||
const bool hasProvider = it != tileProviderMap.end();
|
||||
return hasProvider ? it->second->tileStatus(index) : Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByIndex::depthTransform() {
|
||||
return defaultTileProvider->depthTransform();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::update() {
|
||||
using K = TileIndex::TileHashKey;
|
||||
using V = std::unique_ptr<TileProvider>;
|
||||
for (std::pair<const K, V>& it : tileProviderMap) {
|
||||
it.second->update();
|
||||
}
|
||||
defaultTileProvider->update();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::reset() {
|
||||
using K = TileIndex::TileHashKey;
|
||||
using V = std::unique_ptr<TileProvider>;
|
||||
for (std::pair<const K, V>& it : tileProviderMap) {
|
||||
it.second->reset();
|
||||
}
|
||||
defaultTileProvider->reset();
|
||||
}
|
||||
|
||||
int TileProviderByIndex::maxLevel() {
|
||||
return defaultTileProvider->maxLevel();
|
||||
}
|
||||
|
||||
float TileProviderByIndex::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,52 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileProviderByIndex : public TileProvider {
|
||||
TileProviderByIndex(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
|
||||
std::unordered_map<
|
||||
TileIndex::TileHashKey, std::unique_ptr<TileProvider>
|
||||
> tileProviderMap;
|
||||
std::unique_ptr<TileProvider> defaultTileProvider;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
@@ -0,0 +1,169 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyProviders = "LevelTileProviders";
|
||||
constexpr const char* KeyMaxLevel = "MaxLevel";
|
||||
constexpr const char* KeyTileProvider = "TileProvider";
|
||||
constexpr const char* KeyLayerGroupID = "LayerGroupID";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
|
||||
layergroupid::GroupID layerGroupID = static_cast<layergroupid::GroupID>(
|
||||
dictionary.value<int>(KeyLayerGroupID)
|
||||
);
|
||||
|
||||
if (dictionary.hasValue<ghoul::Dictionary>(KeyProviders)) {
|
||||
ghoul::Dictionary providers = dictionary.value<ghoul::Dictionary>(KeyProviders);
|
||||
|
||||
for (size_t i = 1; i <= providers.size(); i++) {
|
||||
ghoul::Dictionary levelProviderDict = providers.value<ghoul::Dictionary>(
|
||||
std::to_string(i)
|
||||
);
|
||||
double floatMaxLevel = levelProviderDict.value<double>(KeyMaxLevel);
|
||||
int maxLevel = static_cast<int>(std::round(floatMaxLevel));
|
||||
|
||||
ghoul::Dictionary providerDict = levelProviderDict.value<ghoul::Dictionary>(
|
||||
KeyTileProvider
|
||||
);
|
||||
providerDict.setValue(KeyLayerGroupID, static_cast<int>(layerGroupID));
|
||||
|
||||
layergroupid::TypeID typeID;
|
||||
if (providerDict.hasValue<std::string>("Type")) {
|
||||
const std::string& typeString = providerDict.value<std::string>("Type");
|
||||
typeID = ghoul::from_string<layergroupid::TypeID>(typeString);
|
||||
|
||||
if (typeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + typeString);
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
}
|
||||
|
||||
std::unique_ptr<TileProvider> tp = createFromDictionary(typeID, providerDict);
|
||||
|
||||
std::string provId = providerDict.value<std::string>("Identifier");
|
||||
tp->setIdentifier(provId);
|
||||
std::string providerName = providerDict.value<std::string>("Name");
|
||||
tp->setGuiName(providerName);
|
||||
addPropertySubOwner(tp.get());
|
||||
|
||||
levelTileProviders.push_back(std::move(tp));
|
||||
|
||||
// Ensure we can represent the max level
|
||||
if (static_cast<int>(providerIndices.size()) < maxLevel) {
|
||||
providerIndices.resize(maxLevel + 1, -1);
|
||||
}
|
||||
|
||||
// map this level to the tile provider index
|
||||
providerIndices[maxLevel] = static_cast<int>(levelTileProviders.size()) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the gaps (value -1 ) in provider indices, from back to end
|
||||
for (int i = static_cast<int>(providerIndices.size()) - 2; i >= 0; --i) {
|
||||
if (providerIndices[i] == -1) {
|
||||
providerIndices[i] = providerIndices[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::internalInitialize() {
|
||||
for (const std::unique_ptr<TileProvider>& prov : levelTileProviders) {
|
||||
prov->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::internalDeinitialize() {
|
||||
for (const std::unique_ptr<TileProvider>& prov : levelTileProviders) {
|
||||
prov->deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByLevel::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
TileProvider* provider = levelProvider(tileIndex.level);
|
||||
if (provider) {
|
||||
return provider->tile(tileIndex);
|
||||
}
|
||||
else {
|
||||
return Tile();
|
||||
}
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByLevel::tileStatus(const TileIndex& index) {
|
||||
TileProvider* provider = levelProvider(index.level);
|
||||
return provider ? provider->tileStatus(index) : Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileProvider* TileProviderByLevel::levelProvider(int level) const {
|
||||
ZoneScoped
|
||||
|
||||
if (!levelTileProviders.empty()) {
|
||||
int clampedLevel = glm::clamp(
|
||||
level,
|
||||
0,
|
||||
static_cast<int>(providerIndices.size() - 1)
|
||||
);
|
||||
int idx = providerIndices[clampedLevel];
|
||||
return levelTileProviders[idx].get();
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByLevel::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void TileProviderByLevel::update() {
|
||||
for (const std::unique_ptr<TileProvider>& provider : levelTileProviders) {
|
||||
provider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::reset() {
|
||||
for (const std::unique_ptr<TileProvider>& provider : levelTileProviders) {
|
||||
provider->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int TileProviderByLevel::maxLevel() {
|
||||
return static_cast<int>(providerIndices.size() - 1);
|
||||
}
|
||||
|
||||
float TileProviderByLevel::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,54 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileProviderByLevel : public TileProvider {
|
||||
TileProviderByLevel(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
std::vector<int> providerIndices;
|
||||
std::vector<std::unique_ptr<TileProvider>> levelTileProviders;
|
||||
|
||||
private:
|
||||
void internalInitialize() override final;
|
||||
void internalDeinitialize() override final;
|
||||
TileProvider* levelProvider(int level) const;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
Reference in New Issue
Block a user