diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa20.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa20.asset new file mode 100644 index 0000000000..c948982e52 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa20.asset @@ -0,0 +1,33 @@ +local Layer = { + Identifier = "Temporal_NOAA20_VIIRS", + Name = "Temporal NOAA20 VIIRS", + Type = "TemporalTileProvider", + Mode = "Prototyped", + Prototyped = { + Time = { + Start = "2018-01-05", + End = "Today" + }, + TemporalResolution = "1d", + TimeFormat = "YYYY-MM-DD", + Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( + "VIIRS_NOAA20_CorrectedReflectance_TrueColor", + "250m", + "jpg" + ) + }, + PadTiles = false +} + + +asset.export("Layer", Layer) + + + +asset.meta = { + Name = "NOAA 20", + Description = [[A layer that sources its images from the NOAA-20 satellite that is part of the Joint Polar Satellite System.]], + Author = "OpenSpace Team", + URL = "http://www.openspaceproject.com", + License = "MIT License" +} diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa21.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa21.asset new file mode 100644 index 0000000000..200649673e --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/noaa21.asset @@ -0,0 +1,33 @@ +local Layer = { + Identifier = "Temporal_NOAA21_VIIRS", + Name = "Temporal NOAA21 VIIRS", + Type = "TemporalTileProvider", + Mode = "Prototyped", + Prototyped = { + Time = { + Start = "2024-04-19", + End = "Today" + }, + TemporalResolution = "1d", + TimeFormat = "YYYY-MM-DD", + Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( + "VIIRS_NOAA21_CorrectedReflectance_TrueColor", + "250m", + "jpg" + ) + }, + PadTiles = false +} + + +asset.export("Layer", Layer) + + + +asset.meta = { + Name = "NOAA 20", + Description = [[A layer that sources its images from the NOAA-21 satellite that is part of the Joint Polar Satellite System.]], + Author = "OpenSpace Team", + URL = "http://www.openspaceproject.com", + License = "MIT License" +} diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/snpp.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/snpp.asset new file mode 100644 index 0000000000..50b9648d00 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/definitions/snpp.asset @@ -0,0 +1,33 @@ +local Layer = { + Identifier = "Temporal_SNPP_VIIRS", + Name = "Temporal SNPP VIIRS", + Type = "TemporalTileProvider", + Mode = "Prototyped", + Prototyped = { + Time = { + Start = "2015-11-24", + End = "Today" + }, + TemporalResolution = "1d", + TimeFormat = "YYYY-MM-DD", + Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( + "VIIRS_SNPP_CorrectedReflectance_TrueColor", + "250m", + "jpg" + ) + }, + PadTiles = false +} + + +asset.export("Layer", Layer) + + + +asset.meta = { + Name = "NOAA 20", + Description = [[A layer that sources its images from the Suomi NPP satellite that is part of the Joint Polar Satellite System.]], + Author = "OpenSpace Team", + URL = "http://www.openspaceproject.com", + License = "MIT License" +} diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa20_combo.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa20_combo.asset index ae680ca127..19466f157a 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa20_combo.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa20_combo.asset @@ -1,4 +1,5 @@ local globe = asset.require("../../earth") +local noaa20 = asset.require("./definitions/noaa20") @@ -11,26 +12,7 @@ local Layer = { LevelTileProviders = { { MaxLevel = 4, - TileProvider = { - Identifier = "Temporal_VIIRS_NOAA20", - Name = "Temporal VIIRS NOAA20", - Type = "TemporalTileProvider", - Mode = "Prototyped", - Prototyped = { - Time = { - Start = "2020-04-25", - End = "Today" - }, - TemporalResolution = "1d", - TimeFormat = "YYYY-MM-DD", - Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( - "VIIRS_NOAA20_CorrectedReflectance_TrueColor", - "250m", - "jpg" - ) - }, - PadTiles = false - } + TileProvider = noaa20.Layer }, { MaxLevel = 22, diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa21_combo.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa21_combo.asset index 504ca739eb..06b44c5325 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa21_combo.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_noaa21_combo.asset @@ -1,4 +1,5 @@ local globe = asset.require("../../earth") +local noaa21 = asset.require("./definitions/noaa21") @@ -11,26 +12,7 @@ local Layer = { LevelTileProviders = { { MaxLevel = 4, - TileProvider = { - Identifier = "Temporal_VIIRS_NOAA21", - Name = "Temporal VIIRS NOAA21", - Type = "TemporalTileProvider", - Mode = "Prototyped", - Prototyped = { - Time = { - Start = "2024-04-19", - End = "Today" - }, - TemporalResolution = "1d", - TimeFormat = "YYYY-MM-DD", - Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( - "VIIRS_NOAA21_CorrectedReflectance_TrueColor", - "250m", - "jpg" - ) - }, - PadTiles = false - } + TileProvider = noaa21.Layer }, { MaxLevel = 22, diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_snpp_combo.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_snpp_combo.asset new file mode 100644 index 0000000000..2ee2480dc3 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_snpp_combo.asset @@ -0,0 +1,52 @@ +local globe = asset.require("../../earth") +local snpp = asset.require("./definitions/snpp") + + + +local Layer = { + Identifier = "ESRI_VIIRS_Combo", + Name = "ESRI VIIRS Combo", + Enabled = asset.enabled, + ZIndex = 20, + Type = "TileProviderByLevel", + LevelTileProviders = { + { + MaxLevel = 4, + TileProvider = snpp.Layer + }, + { + MaxLevel = 22, + TileProvider = { + Identifier = "ESRI_World_Imagery", + Name = "ESRI World Imagery", + FilePath = asset.resource("esri_world_imagery.wms"), + PadTiles = false + } + } + }, + PadTiles = false, + Description = [[Level based layer combining "VIIRS SNPP (Temporal)" and ESRI World + Imagery. "VIIRS SNPP (Temporal)" is faded out at tile level 4]] +} + + +asset.onInitialize(function() + openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", Layer) +end) + +asset.onDeinitialize(function() + openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", Layer) +end) + +asset.export("layer", Layer) + + + +asset.meta = { + Name = "ESRI VIIRS Combo", + Description = [[Level based layer combining "VIIRS SNPP (Temporal)" and ESRI World + Imagery. "VIIRS SNPP (Temporal)" is faded out at tile level 4]], + Author = "OpenSpace Tem", + URL = "http://www.openspaceproject.com", + License = "MIT License" +} diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_viirs_combo.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_viirs_combo.asset index a8a1ca1b74..4c3e24bd9c 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_viirs_combo.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/esri_viirs_combo.asset @@ -1,4 +1,7 @@ local globe = asset.require("../../earth") +local snpp = asset.require("./definitions/snpp") +local noaa20 = asset.require("./definitions/noaa20") +local noaa21 = asset.require("./definitions/noaa21") @@ -12,24 +15,14 @@ local Layer = { { MaxLevel = 4, TileProvider = { - Identifier = "Temporal_VIIRS_SNPP", - Name = "Temporal VIIRS SNPP", - Type = "TemporalTileProvider", - Mode = "Prototyped", - Prototyped = { - Time = { - Start = "2015-11-24", - End = "2024-05-27" - }, - TemporalResolution = "1d", - TimeFormat = "YYYY-MM-DD", - Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( - "VIIRS_SNPP_CorrectedReflectance_TrueColor", - "250m", - "jpg" - ) - }, - PadTiles = false + Identifier = "VIIRS_Joint_Layer", + Name = "VIIRS Joint Layer", + Type = "TileProviderByDate", + Providers = { + ["2015-11-24"] = snpp.Layer, + ["2018-01-05"] = noaa20.Layer, + ["2024-04-19"] = noaa21.Layer + } } }, { @@ -43,8 +36,8 @@ local Layer = { } }, PadTiles = false, - Description = [[Level based layer combining "VIIRS SNPP (Temporal)" and ESRI World - Imagery. "VIIRS SNPP (Temporal)" is faded out at tile level 4]] + Description = [[Level based layer combining different VIIRS layers and ESRI World + Imagery. VIIRS is faded out at tile level 4]] } diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa20_temporal.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa20_temporal.asset index 4f75667c4d..4380875f21 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa20_temporal.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa20_temporal.asset @@ -1,42 +1,16 @@ local globe = asset.require("../../earth") +local noaa20 = asset.require("./definitions/noaa20") -local Layer = { - Identifier = "VIIRS_NOAA20_Temporal", - Name = "VIIRS NOAA20 (Temporal)", - Enabled = asset.enabled, - ZIndex = 30, - Type = "TemporalTileProvider", - Mode = "Prototyped", - Prototyped = { - Time = { - Start = "2020-04-25", - End = "Yesterday" - }, - TemporalResolution = "1d", - TimeFormat = "YYYY-MM-DD", - Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( - "VIIRS_NOAA20_CorrectedReflectance_TrueColor", - "250m", - "jpg" - ) - }, - Description = [[Temporal coverage: 11 November 2015 - Present. The imagery resolution - is 0.25 km, and the temporal resolution is daily]] -} - - asset.onInitialize(function() - openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", Layer) + openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", noaa20.Layer) end) asset.onDeinitialize(function() - openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", Layer) + openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", noaa20.Layer) end) -asset.export("layer", Layer) - asset.meta = { diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa21_temporal.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa21_temporal.asset new file mode 100644 index 0000000000..e74851f857 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_noaa21_temporal.asset @@ -0,0 +1,23 @@ +local globe = asset.require("../../earth") +local noaa21 = asset.require("./definitions/noaa21") + + + +asset.onInitialize(function() + openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", noaa21.Layer) +end) + +asset.onDeinitialize(function() + openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", noaa21.Layer) +end) + + + +asset.meta = { + Name = "VIIRS NOAA21 (Temporal)", + Description = "This layer has the best daily Earth Image", + Author = "NASA EOSDIS Global Imagery Browse Services", + URL = + "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs", + License = "NASA" +} diff --git a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_snpp_temporal.asset b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_snpp_temporal.asset index e9888466e6..bf07ec7483 100644 --- a/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_snpp_temporal.asset +++ b/data/assets/scene/solarsystem/planets/earth/layers/colorlayers/viirs_snpp_temporal.asset @@ -1,42 +1,16 @@ local globe = asset.require("../../earth") +local snpp = asset.require("./definitions/snpp") -local Layer = { - Identifier = "VIIRS_SNPP_Temporal", - Name = "VIIRS SNPP (Temporal)", - Enabled = asset.enabled, - ZIndex = 30, - Type = "TemporalTileProvider", - Mode = "Prototyped", - Prototyped = { - Time = { - Start = "2015-11-24", - End = "Today" - }, - TemporalResolution = "1d", - TimeFormat = "YYYY-MM-DD", - Prototype = openspace.globebrowsing.createTemporalGibsGdalXml( - "VIIRS_SNPP_CorrectedReflectance_TrueColor", - "250m", - "jpg" - ) - }, - Description = [[Temporal coverage: 11 November 2015 - Present. The imagery resolution - is 0.25 km, and the temporal resolution is daily]] -} - - asset.onInitialize(function() - openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", Layer) + openspace.globebrowsing.addLayer(globe.Earth.Identifier, "ColorLayers", snpp.Layer) end) asset.onDeinitialize(function() - openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", Layer) + openspace.globebrowsing.deleteLayer(globe.Earth.Identifier, "ColorLayers", snpp.Layer) end) -asset.export("layer", Layer) - asset.meta = { diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 75ec1e9e24..bb1e85d6b6 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -74,6 +74,7 @@ set(HEADER_FILES src/tileprovider/texttileprovider.h src/tileprovider/tileindextileprovider.h src/tileprovider/tileprovider.h + src/tileprovider/tileproviderbydate.h src/tileprovider/tileproviderbyindex.h src/tileprovider/tileproviderbylevel.h ) @@ -120,6 +121,7 @@ set(SOURCE_FILES src/tileprovider/texttileprovider.cpp src/tileprovider/tileindextileprovider.cpp src/tileprovider/tileprovider.cpp + src/tileprovider/tileproviderbydate.cpp src/tileprovider/tileproviderbyindex.cpp src/tileprovider/tileproviderbylevel.cpp ) diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index c6c4ffa7f4..6a9eafccb9 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -310,6 +311,7 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) { fTileProvider->registerClass("TemporalTileProvider"); fTileProvider->registerClass("TileIndexTileProvider"); fTileProvider->registerClass("SizeReferenceTileProvider"); + fTileProvider->registerClass("TileProviderByDate"); fTileProvider->registerClass("TileProviderByLevel"); fTileProvider->registerClass("TileProviderByIndex"); @@ -338,6 +340,7 @@ std::vector GlobeBrowsingModule::documentations() globebrowsing::SizeReferenceTileProvider::Documentation(), globebrowsing::TemporalTileProvider::Documentation(), globebrowsing::TileIndexTileProvider::Documentation(), + globebrowsing::TileProviderByDate::Documentation(), globebrowsing::TileProviderByIndex::Documentation(), globebrowsing::TileProviderByLevel::Documentation(), globebrowsing::GeoJsonManager::Documentation(), diff --git a/modules/globebrowsing/shaders/texturetilemapping.glsl b/modules/globebrowsing/shaders/texturetilemapping.glsl index 9ede2085c0..5ae7ae60c0 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.glsl +++ b/modules/globebrowsing/shaders/texturetilemapping.glsl @@ -151,15 +151,17 @@ vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights, c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); #elif (#{#{layerGroup}#{i}LayerType} == 5) // TileIndexTileProvider c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); -#elif (#{#{layerGroup}#{i}LayerType} == 6) // TileProviderByIndex +#elif (#{#{layerGroup}#{i}LayerType} == 6) // TileProviderByDate c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); -#elif (#{#{layerGroup}#{i}LayerType} == 7) // TileProviderByLevel +#elif (#{#{layerGroup}#{i}LayerType} == 7) // TileProviderByIndex c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); -#elif (#{#{layerGroup}#{i}LayerType} == 8) // SolidColor +#elif (#{#{layerGroup}#{i}LayerType} == 8) // TileProviderByLevel + c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); +#elif (#{#{layerGroup}#{i}LayerType} == 9) // SolidColor c.rgb = #{layerGroup}[#{i}].color; -#elif (#{#{layerGroup}#{i}LayerType} == 9) // SpoutImageProvider +#elif (#{#{layerGroup}#{i}LayerType} == 10) // SpoutImageProvider c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); -#elif (#{#{layerGroup}#{i}LayerType} == 10) // VideoTileProvider +#elif (#{#{layerGroup}#{i}LayerType} == 11) // VideoTileProvider c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv); #endif diff --git a/modules/globebrowsing/src/gpulayergroup.cpp b/modules/globebrowsing/src/gpulayergroup.cpp index 319ae6ea7c..fff16af0e9 100644 --- a/modules/globebrowsing/src/gpulayergroup.cpp +++ b/modules/globebrowsing/src/gpulayergroup.cpp @@ -74,6 +74,7 @@ void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program, case layers::Layer::ID::SizeReferenceTileProvider: case layers::Layer::ID::TemporalTileProvider: case layers::Layer::ID::TileIndexTileProvider: + case layers::Layer::ID::TileProviderByDate: case layers::Layer::ID::TileProviderByIndex: case layers::Layer::ID::TileProviderByLevel: { const ChunkTilePile& ctp = al.chunkTilePile( @@ -146,6 +147,7 @@ void GPULayerGroup::bind(ghoul::opengl::ProgramObject& p, const LayerGroup& laye case layers::Layer::ID::SizeReferenceTileProvider: case layers::Layer::ID::TemporalTileProvider: case layers::Layer::ID::TileIndexTileProvider: + case layers::Layer::ID::TileProviderByDate: case layers::Layer::ID::TileProviderByIndex: case layers::Layer::ID::TileProviderByLevel: { gal.gpuChunkTiles.resize(pileSize); diff --git a/modules/globebrowsing/src/layer.cpp b/modules/globebrowsing/src/layer.cpp index cd73fa70e3..7c30f94048 100644 --- a/modules/globebrowsing/src/layer.cpp +++ b/modules/globebrowsing/src/layer.cpp @@ -130,8 +130,8 @@ namespace { std::optional type [[codegen::inlist("DefaultTileProvider", "SingleImageProvider", "ImageSequenceTileProvider", "SizeReferenceTileProvider", "TemporalTileProvider", "TileIndexTileProvider", - "TileProviderByIndex", "TileProviderByLevel", "SolidColor", - "SpoutImageProvider", "VideoTileProvider")]]; + "TileProviderByDate", "TileProviderByIndex", "TileProviderByLevel", + "SolidColor", "SpoutImageProvider", "VideoTileProvider")]]; // Determine whether the layer is enabled or not. If this value is not specified, // the layer is disabled @@ -342,6 +342,7 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou case layers::Layer::ID::SizeReferenceTileProvider: case layers::Layer::ID::TemporalTileProvider: case layers::Layer::ID::TileIndexTileProvider: + case layers::Layer::ID::TileProviderByDate: case layers::Layer::ID::TileProviderByIndex: case layers::Layer::ID::TileProviderByLevel: case layers::Layer::ID::VideoTileProvider: @@ -513,6 +514,7 @@ void Layer::initializeBasedOnType(layers::Layer::ID id, ghoul::Dictionary initDi case layers::Layer::ID::SizeReferenceTileProvider: case layers::Layer::ID::TemporalTileProvider: case layers::Layer::ID::TileIndexTileProvider: + case layers::Layer::ID::TileProviderByDate: case layers::Layer::ID::TileProviderByIndex: case layers::Layer::ID::TileProviderByLevel: case layers::Layer::ID::VideoTileProvider: @@ -546,6 +548,7 @@ void Layer::addVisibleProperties() { case layers::Layer::ID::SizeReferenceTileProvider: case layers::Layer::ID::TemporalTileProvider: case layers::Layer::ID::TileIndexTileProvider: + case layers::Layer::ID::TileProviderByDate: case layers::Layer::ID::TileProviderByIndex: case layers::Layer::ID::TileProviderByLevel: case layers::Layer::ID::VideoTileProvider: diff --git a/modules/globebrowsing/src/layergroupid.h b/modules/globebrowsing/src/layergroupid.h index a1d5f159fd..c11fbacc7b 100644 --- a/modules/globebrowsing/src/layergroupid.h +++ b/modules/globebrowsing/src/layergroupid.h @@ -84,6 +84,7 @@ struct Layer { SizeReferenceTileProvider, TemporalTileProvider, TileIndexTileProvider, + TileProviderByDate, TileProviderByIndex, TileProviderByLevel, SolidColor, @@ -95,7 +96,7 @@ struct Layer { std::string_view identifier; }; -constexpr std::array Layers = { +constexpr std::array Layers = { Layer { .id = Layer::ID::DefaultTileProvider, .identifier = "DefaultTileProvider" @@ -120,6 +121,10 @@ constexpr std::array Layers = { .id = Layer::ID::TileIndexTileProvider, .identifier = "TileIndexTileProvider" }, + Layer { + .id = Layer::ID::TileProviderByDate, + .identifier = "TileProviderByDate" + }, Layer { .id = Layer::ID::TileProviderByIndex, .identifier = "TileProviderByIndex" diff --git a/modules/globebrowsing/src/tileprovider/tileproviderbydate.cpp b/modules/globebrowsing/src/tileprovider/tileproviderbydate.cpp new file mode 100644 index 0000000000..968f51bb1f --- /dev/null +++ b/modules/globebrowsing/src/tileprovider/tileproviderbydate.cpp @@ -0,0 +1,190 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2024 * + * * + * 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 + +#include +#include +#include +#include +#include + +namespace { + struct [[codegen::Dictionary(TileProviderByDate)]] Parameters { + // Specifies the list of tile providers and for which times they are used for. The + // tile provider with the earliest time will be used for all dates prior to that + // date and the provider with the latest time will be used for all dates + // afterwards. In between, a provider is used from the specified time until the + // time of the next provider + std::map providers; + }; +#include "tileproviderbydate_codegen.cpp" +} // namespace + +namespace openspace::globebrowsing { + +documentation::Documentation TileProviderByDate::Documentation() { + return codegen::doc("globebrowsing_tileproviderbydate"); +} + +TileProviderByDate::TileProviderByDate(const ghoul::Dictionary& dictionary) { + ZoneScoped; + + Parameters p = codegen::bake(dictionary); + + // For now we need to inject the LayerGroupID this way. We don't want it to be part of + // the parameters struct as that would mean it would be visible to the end user, which + // we don't want since this value just comes from whoever creates it, not the user + ghoul_assert(dictionary.hasValue("LayerGroupID"), "No Layer Group ID provided"); + const layers::Group::ID group = static_cast( + dictionary.value("LayerGroupID") + ); + + for (std::pair& prov : p.providers) { + prov.second.setValue("LayerGroupID", static_cast(group)); + + // Pass down the caching information from the enclosing dictionary + if (dictionary.hasValue("GlobeName")) { + prov.second.setValue("GlobeName", dictionary.value("GlobeName")); + } + layers::Layer::ID typeID = layers::Layer::ID::DefaultTileProvider; + + if (prov.second.hasValue("Type")) { + const std::string type = prov.second.value("Type"); + typeID = ghoul::from_string(type); + } + + std::unique_ptr tp = createFromDictionary(typeID, prov.second); + const std::string provId = prov.second.value("Identifier"); + tp->setIdentifier(provId); + const std::string providerName = prov.second.value("Name"); + tp->setGuiName(providerName); + addPropertySubOwner(tp.get()); + + const double time = SpiceManager::ref().ephemerisTimeFromDate(prov.first); + _tileProviders.emplace_back(time, std::move(tp)); + } + + // After we added all tile providers, we need to sort them as they might have been + // given in an arbitrary order + std::sort( + _tileProviders.begin(), + _tileProviders.end(), + [](const Provider& lhs, const Provider& rhs) { + return lhs.startTime < rhs.startTime; + } + ); +} + +void TileProviderByDate::internalInitialize() { + for (const Provider& p : _tileProviders) { + p.tileProvider->initialize(); + } +} + +void TileProviderByDate::internalDeinitialize() { + for (const Provider& p : _tileProviders) { + p.tileProvider->deinitialize(); + } +} + +Tile TileProviderByDate::tile(const TileIndex& tileIndex) { + ZoneScoped; + + return _currentTileProvider ? _currentTileProvider->tile(tileIndex) : Tile(); +} + +Tile::Status TileProviderByDate::tileStatus(const TileIndex& index) { + return + _currentTileProvider ? + _currentTileProvider->tileStatus(index) : + Tile::Status::Unavailable; +} + + +TileDepthTransform TileProviderByDate::depthTransform() { + return _currentTileProvider ? + _currentTileProvider->depthTransform() : + TileDepthTransform(0.f, 1.f); +} + +void TileProviderByDate::update() { + if (_tileProviders.empty()) { + // If there are no tile providers, then there is no work to be done + _currentTileProvider = nullptr; + return; + } + + // First update all tile providers + for (const Provider& p : _tileProviders) { + p.tileProvider->update(); + } + + // Then check update our current tile provider pointer + const double time = global::timeManager->time().j2000Seconds(); + ghoul_assert(!_tileProviders.empty(), "There should be tile providers at this point"); + + // We use the first tileprovider for all times before the beginning start + if (time < _tileProviders.begin()->startTime) { + _currentTileProvider = _tileProviders.begin()->tileProvider.get(); + return; + } + + // And the last tileprovider for all times after the end + if (time > _tileProviders.back().startTime) { + _currentTileProvider = _tileProviders.back().tileProvider.get(); + return; + } + + _currentTileProvider = _tileProviders.begin()->tileProvider.get(); + for (const Provider& p : _tileProviders) { + if (p.startTime > time) { + // We have found the first entry that is larger than the current time, which + // means that we are done + return; + } + + _currentTileProvider = p.tileProvider.get(); + } +} + +void TileProviderByDate::reset() { + for (const Provider& p : _tileProviders) { + p.tileProvider->reset(); + } +} + +int TileProviderByDate::minLevel() { + return _currentTileProvider ? _currentTileProvider->minLevel() : 1; +} + +int TileProviderByDate::maxLevel() { + return _currentTileProvider ? _currentTileProvider->maxLevel() : 1; +} + +float TileProviderByDate::noDataValueAsFloat() { + return _currentTileProvider ? _currentTileProvider->noDataValueAsFloat() : 1; +} + +} // namespace openspace::globebrowsing diff --git a/modules/globebrowsing/src/tileprovider/tileproviderbydate.h b/modules/globebrowsing/src/tileprovider/tileproviderbydate.h new file mode 100644 index 0000000000..9c2f29179b --- /dev/null +++ b/modules/globebrowsing/src/tileprovider/tileproviderbydate.h @@ -0,0 +1,65 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2024 * + * * + * 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__TILEPROVIDERBYDATE___H__ +#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYDATE___H__ + +#include + +#include + +namespace openspace::globebrowsing { + +class TileProviderByDate : public TileProvider { +public: + TileProviderByDate(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 minLevel() override final; + int maxLevel() override final; + float noDataValueAsFloat() override final; + + static documentation::Documentation Documentation(); + +private: + struct Provider { + // The time at which this provider becomes valid + double startTime = 0.0; + std::unique_ptr tileProvider; + }; + + std::vector _tileProviders; + TileProvider* _currentTileProvider = nullptr; + + void internalInitialize() override final; + void internalDeinitialize() override final; +}; + +} // namespace openspace::globebrowsing + +#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYDATE___H__