-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1055 from CesiumGS/url-template-overlay
Add UrlTemplateRasterOverlay
- Loading branch information
Showing
8 changed files
with
442 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
CesiumRasterOverlays/include/CesiumRasterOverlays/UrlTemplateRasterOverlay.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#pragma once | ||
|
||
#include "IPrepareRasterOverlayRendererResources.h" | ||
#include "Library.h" | ||
#include "RasterOverlayTileProvider.h" | ||
|
||
#include <CesiumAsync/AsyncSystem.h> | ||
#include <CesiumAsync/Future.h> | ||
#include <CesiumAsync/IAssetAccessor.h> | ||
#include <CesiumAsync/SharedAssetDepot.h> | ||
#include <CesiumGeometry/QuadtreeTileID.h> | ||
#include <CesiumGeometry/QuadtreeTilingScheme.h> | ||
#include <CesiumRasterOverlays/RasterOverlay.h> | ||
#include <CesiumUtility/CreditSystem.h> | ||
#include <CesiumUtility/Result.h> | ||
#include <CesiumUtility/SharedAsset.h> | ||
|
||
#include <list> | ||
#include <memory> | ||
#include <optional> | ||
#include <string> | ||
|
||
namespace CesiumRasterOverlays { | ||
|
||
/** | ||
* @brief Options for URL template overlays. | ||
*/ | ||
struct UrlTemplateRasterOverlayOptions { | ||
/** | ||
* @brief A credit for the data source, which is displayed on the canvas. | ||
*/ | ||
std::optional<std::string> credit; | ||
|
||
/** | ||
* @brief The {@link CesiumGeospatial::Projection} that is used. | ||
*/ | ||
std::optional<CesiumGeospatial::Projection> projection; | ||
|
||
/** | ||
* @brief The {@link CesiumGeometry::QuadtreeTilingScheme} specifying how | ||
* the ellipsoidal surface is broken into tiles. | ||
*/ | ||
std::optional<CesiumGeometry::QuadtreeTilingScheme> tilingScheme; | ||
|
||
/** | ||
* @brief The minimum level-of-detail supported by the imagery provider. | ||
* | ||
* Take care when specifying this that the number of tiles at the minimum | ||
* level is small, such as four or less. A larger number is likely to | ||
* result in rendering problems. | ||
*/ | ||
uint32_t minimumLevel = 0; | ||
|
||
/** | ||
* @brief The maximum level-of-detail supported by the imagery provider. | ||
*/ | ||
uint32_t maximumLevel = 25; | ||
|
||
/** | ||
* @brief Pixel width of image tiles. | ||
*/ | ||
uint32_t tileWidth = 256; | ||
|
||
/** | ||
* @brief Pixel height of image tiles. | ||
*/ | ||
uint32_t tileHeight = 256; | ||
|
||
/** | ||
* @brief The {@link CesiumGeometry::Rectangle}, in radians, covered by the | ||
* image. | ||
*/ | ||
std::optional<CesiumGeometry::Rectangle> coverageRectangle; | ||
}; | ||
|
||
/** | ||
* @brief A {@link RasterOverlay} accessing images from a templated URL. | ||
*/ | ||
class CESIUMRASTEROVERLAYS_API UrlTemplateRasterOverlay final | ||
: public RasterOverlay { | ||
public: | ||
/** | ||
* @brief Creates a new instance. | ||
* | ||
* The following template parameters are supported in `url`: | ||
* - `{x}` - The tile X coordinate in the tiling scheme, where 0 is the westernmost tile. | ||
* - `{y}` - The tile Y coordinate in the tiling scheme, where 0 is the nothernmost tile. | ||
* - `{z}` - The level of the tile in the tiling scheme, where 0 is the root of the quadtree pyramid. | ||
* - `{reverseX}` - The tile X coordinate in the tiling scheme, where 0 is the easternmost tile. | ||
* - `{reverseY}` - The tile Y coordinate in the tiling scheme, where 0 is the southernmost tile. | ||
* - `{reverseZ}` - The tile Z coordinate in the tiling scheme, where 0 is equivalent to `urlTemplateOptions.maximumLevel`. | ||
* - `{westDegrees}` - The western edge of the tile in geodetic degrees. | ||
* - `{southDegrees}` - The southern edge of the tile in geodetic degrees. | ||
* - `{eastDegrees}` - The eastern edge of the tile in geodetic degrees. | ||
* - `{northDegrees}` - The northern edge of the tile in geodetic degrees. | ||
* - `{minimumX}` - The minimum X coordinate of the tile's projected coordinates. | ||
* - `{minimumY}` - The minimum Y coordinate of the tile's projected coordinates. | ||
* - `{maximumX}` - The maximum X coordinate of the tile's projected coordinates. | ||
* - `{maximumY}` - The maximum Y coordinate of the tile's projected coordinates. | ||
* - `{width}` - The width of each tile in pixels. | ||
* - `{height}` - The height of each tile in pixels. | ||
* | ||
* @param name The user-given name of this overlay layer. | ||
* @param url The URL with template parameters. | ||
* @param headers The headers. This is a list of pairs of strings of the | ||
* form (Key,Value) that will be inserted as request headers internally. | ||
* @param urlTemplateOptions The {@link UrlTemplateRasterOverlayOptions}. | ||
* @param overlayOptions The {@link RasterOverlayOptions} for this instance. | ||
*/ | ||
UrlTemplateRasterOverlay( | ||
const std::string& name, | ||
const std::string& url, | ||
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers = {}, | ||
const UrlTemplateRasterOverlayOptions& urlTemplateOptions = {}, | ||
const RasterOverlayOptions& overlayOptions = {}) | ||
: RasterOverlay(name, overlayOptions), | ||
_url(url), | ||
_headers(headers), | ||
_options(urlTemplateOptions) {} | ||
|
||
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider( | ||
const CesiumAsync::AsyncSystem& asyncSystem, | ||
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor, | ||
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem, | ||
const std::shared_ptr<IPrepareRasterOverlayRendererResources>& | ||
pPrepareRendererResources, | ||
const std::shared_ptr<spdlog::logger>& pLogger, | ||
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) | ||
const override; | ||
|
||
private: | ||
std::string _url; | ||
std::vector<CesiumAsync::IAssetAccessor::THeader> _headers; | ||
UrlTemplateRasterOverlayOptions _options; | ||
}; | ||
} // namespace CesiumRasterOverlays |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
#include <CesiumAsync/Future.h> | ||
#include <CesiumAsync/HttpHeaders.h> | ||
#include <CesiumAsync/IAssetAccessor.h> | ||
#include <CesiumGeometry/QuadtreeTileID.h> | ||
#include <CesiumGeometry/QuadtreeTilingScheme.h> | ||
#include <CesiumGeometry/Rectangle.h> | ||
#include <CesiumGeospatial/GeographicProjection.h> | ||
#include <CesiumGeospatial/GlobeRectangle.h> | ||
#include <CesiumGeospatial/Projection.h> | ||
#include <CesiumGeospatial/WebMercatorProjection.h> | ||
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h> | ||
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h> | ||
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h> | ||
#include <CesiumRasterOverlays/UrlTemplateRasterOverlay.h> | ||
#include <CesiumUtility/CreditSystem.h> | ||
#include <CesiumUtility/IntrusivePointer.h> | ||
#include <CesiumUtility/Math.h> | ||
#include <CesiumUtility/Uri.h> | ||
|
||
#include <spdlog/logger.h> | ||
|
||
#include <cstdint> | ||
#include <map> | ||
#include <memory> | ||
#include <optional> | ||
#include <string> | ||
#include <utility> | ||
#include <variant> | ||
#include <vector> | ||
|
||
using namespace CesiumAsync; | ||
using namespace CesiumGeometry; | ||
using namespace CesiumGeospatial; | ||
using namespace CesiumUtility; | ||
|
||
namespace CesiumRasterOverlays { | ||
|
||
class UrlTemplateRasterOverlayTileProvider final | ||
: public QuadtreeRasterOverlayTileProvider { | ||
public: | ||
UrlTemplateRasterOverlayTileProvider( | ||
const IntrusivePointer<const RasterOverlay>& pOwner, | ||
const CesiumAsync::AsyncSystem& asyncSystem, | ||
const std::shared_ptr<IAssetAccessor>& pAssetAccessor, | ||
std::optional<Credit> credit, | ||
const std::shared_ptr<IPrepareRasterOverlayRendererResources>& | ||
pPrepareRendererResources, | ||
const std::shared_ptr<spdlog::logger>& pLogger, | ||
const CesiumGeospatial::Projection& projection, | ||
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme, | ||
const CesiumGeometry::Rectangle& coverageRectangle, | ||
const std::string& url, | ||
const std::vector<IAssetAccessor::THeader>& headers, | ||
uint32_t width, | ||
uint32_t height, | ||
uint32_t minimumLevel, | ||
uint32_t maximumLevel) | ||
: QuadtreeRasterOverlayTileProvider( | ||
pOwner, | ||
asyncSystem, | ||
pAssetAccessor, | ||
credit, | ||
pPrepareRendererResources, | ||
pLogger, | ||
projection, | ||
tilingScheme, | ||
coverageRectangle, | ||
minimumLevel, | ||
maximumLevel, | ||
width, | ||
height), | ||
_url(url), | ||
_headers(headers) {} | ||
|
||
virtual ~UrlTemplateRasterOverlayTileProvider() = default; | ||
|
||
protected: | ||
virtual CesiumAsync::Future<LoadedRasterOverlayImage> loadQuadtreeTileImage( | ||
const CesiumGeometry::QuadtreeTileID& tileID) const override { | ||
|
||
LoadTileImageFromUrlOptions options; | ||
options.rectangle = this->getTilingScheme().tileToRectangle(tileID); | ||
options.moreDetailAvailable = tileID.level < this->getMaximumLevel(); | ||
|
||
const GlobeRectangle unprojectedRect = | ||
unprojectRectangleSimple(this->getProjection(), options.rectangle); | ||
|
||
const std::map<std::string, std::string, CaseInsensitiveCompare> | ||
placeholdersMap{ | ||
{"x", std::to_string(tileID.x)}, | ||
{"y", std::to_string(tileID.y)}, | ||
{"z", std::to_string(tileID.level)}, | ||
{"reverseX", | ||
std::to_string(tileID.computeInvertedX(this->getTilingScheme()))}, | ||
{"reverseY", | ||
std::to_string(tileID.computeInvertedY(this->getTilingScheme()))}, | ||
{"reverseZ", | ||
std::to_string(this->getMaximumLevel() - tileID.level)}, | ||
{"westDegrees", | ||
std::to_string(Math::radiansToDegrees(unprojectedRect.getWest()))}, | ||
{"southDegrees", | ||
std::to_string( | ||
Math::radiansToDegrees(unprojectedRect.getSouth()))}, | ||
{"eastDegrees", | ||
std::to_string(Math::radiansToDegrees(unprojectedRect.getEast()))}, | ||
{"northDegrees", | ||
std::to_string( | ||
Math::radiansToDegrees(unprojectedRect.getNorth()))}, | ||
{"minimumY", std::to_string(options.rectangle.minimumY)}, | ||
{"minimumX", std::to_string(options.rectangle.minimumX)}, | ||
{"maximumY", std::to_string(options.rectangle.maximumY)}, | ||
{"maximumX", std::to_string(options.rectangle.maximumX)}, | ||
{"width", std::to_string(this->getWidth())}, | ||
{"height", std::to_string(this->getHeight())}}; | ||
|
||
const std::string substitutedUrl = Uri::substituteTemplateParameters( | ||
this->_url, | ||
[&placeholdersMap](const std::string& placeholder) { | ||
auto placeholderIt = placeholdersMap.find(placeholder); | ||
if (placeholderIt != placeholdersMap.end()) { | ||
return placeholderIt->second; | ||
} | ||
return std::string("[UNKNOWN PLACEHOLDER]"); | ||
}); | ||
return this->loadTileImageFromUrl( | ||
substitutedUrl, | ||
this->_headers, | ||
std::move(options)); | ||
} | ||
|
||
private: | ||
std::string _url; | ||
std::vector<IAssetAccessor::THeader> _headers; | ||
}; | ||
|
||
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> | ||
UrlTemplateRasterOverlay::createTileProvider( | ||
const CesiumAsync::AsyncSystem& asyncSystem, | ||
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor, | ||
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem, | ||
const std::shared_ptr<IPrepareRasterOverlayRendererResources>& | ||
pPrepareRendererResources, | ||
const std::shared_ptr<spdlog::logger>& pLogger, | ||
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const { | ||
pOwner = pOwner ? pOwner : this; | ||
|
||
std::optional<Credit> credit = std::nullopt; | ||
if (pCreditSystem && this->_options.credit) { | ||
credit = pCreditSystem->createCredit( | ||
*this->_options.credit, | ||
pOwner->getOptions().showCreditsOnScreen); | ||
} | ||
|
||
CesiumGeospatial::Projection projection = _options.projection.value_or( | ||
CesiumGeospatial::WebMercatorProjection(pOwner->getOptions().ellipsoid)); | ||
CesiumGeospatial::GlobeRectangle tilingSchemeRectangle = | ||
CesiumGeospatial::WebMercatorProjection::MAXIMUM_GLOBE_RECTANGLE; | ||
|
||
uint32_t rootTilesX = 1; | ||
if (std::get_if<CesiumGeospatial::GeographicProjection>(&projection)) { | ||
tilingSchemeRectangle = | ||
CesiumGeospatial::GeographicProjection::MAXIMUM_GLOBE_RECTANGLE; | ||
rootTilesX = 2; | ||
} | ||
CesiumGeometry::Rectangle coverageRectangle = | ||
_options.coverageRectangle.value_or( | ||
projectRectangleSimple(projection, tilingSchemeRectangle)); | ||
|
||
CesiumGeometry::QuadtreeTilingScheme tilingScheme = | ||
_options.tilingScheme.value_or(CesiumGeometry::QuadtreeTilingScheme( | ||
coverageRectangle, | ||
rootTilesX, | ||
1)); | ||
|
||
return asyncSystem | ||
.createResolvedFuture<RasterOverlay::CreateTileProviderResult>( | ||
new UrlTemplateRasterOverlayTileProvider( | ||
pOwner, | ||
asyncSystem, | ||
pAssetAccessor, | ||
credit, | ||
pPrepareRendererResources, | ||
pLogger, | ||
projection, | ||
tilingScheme, | ||
coverageRectangle, | ||
_url, | ||
_headers, | ||
_options.tileWidth, | ||
_options.tileHeight, | ||
_options.minimumLevel, | ||
_options.maximumLevel)); | ||
} | ||
|
||
} // namespace CesiumRasterOverlays |
Oops, something went wrong.