196 lines
7.0 KiB
C
196 lines
7.0 KiB
C
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "IPrepareRasterOverlayRendererResources.h"
|
||
|
|
#include "Library.h"
|
||
|
|
#include "RasterOverlayTileProvider.h"
|
||
|
|
|
||
|
|
#include <CesiumAsync/AsyncSystem.h>
|
||
|
|
#include <CesiumAsync/IAssetAccessor.h>
|
||
|
|
#include <CesiumAsync/SharedAssetDepot.h>
|
||
|
|
#include <CesiumGeometry/QuadtreeTileID.h>
|
||
|
|
#include <CesiumGeometry/QuadtreeTilingScheme.h>
|
||
|
|
#include <CesiumUtility/CreditSystem.h>
|
||
|
|
#include <CesiumUtility/Result.h>
|
||
|
|
#include <CesiumUtility/SharedAsset.h>
|
||
|
|
|
||
|
|
#include <list>
|
||
|
|
#include <memory>
|
||
|
|
#include <optional>
|
||
|
|
|
||
|
|
namespace CesiumRasterOverlays {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief A base class used for raster overlay providers that use a
|
||
|
|
* quadtree-based tiling scheme. This includes \ref TileMapServiceRasterOverlay,
|
||
|
|
* \ref BingMapsRasterOverlay, and \ref WebMapServiceRasterOverlay.
|
||
|
|
*
|
||
|
|
* To implement a new raster overlay provider based on
|
||
|
|
* QuadtreeRasterOverlayTileProvider, use this as the base class and override
|
||
|
|
* \ref QuadtreeRasterOverlayTileProvider::loadQuadtreeTileImage
|
||
|
|
* "loadQuadtreeTileImage" with code that makes requests to your service.
|
||
|
|
*/
|
||
|
|
class CESIUMRASTEROVERLAYS_API QuadtreeRasterOverlayTileProvider
|
||
|
|
: public RasterOverlayTileProvider {
|
||
|
|
|
||
|
|
public:
|
||
|
|
/**
|
||
|
|
* @brief Creates a new instance.
|
||
|
|
*
|
||
|
|
* @param pOwner The raster overlay that created this tile provider.
|
||
|
|
* @param asyncSystem The async system used to do work in threads.
|
||
|
|
* @param pAssetAccessor The interface used to obtain assets (tiles, etc.) for
|
||
|
|
* this raster overlay.
|
||
|
|
* @param credit The {@link CesiumUtility::Credit} for this tile provider, if it exists.
|
||
|
|
* @param pPrepareRendererResources The interface used to prepare raster
|
||
|
|
* images for rendering.
|
||
|
|
* @param pLogger The logger to which to send messages about the tile provider
|
||
|
|
* and tiles.
|
||
|
|
* @param projection The {@link CesiumGeospatial::Projection}.
|
||
|
|
* @param tilingScheme The tiling scheme to be used by this {@link QuadtreeRasterOverlayTileProvider}.
|
||
|
|
* @param coverageRectangle The {@link CesiumGeometry::Rectangle}.
|
||
|
|
* @param minimumLevel The minimum quadtree tile level.
|
||
|
|
* @param maximumLevel The maximum quadtree tile level.
|
||
|
|
* @param imageWidth The image width.
|
||
|
|
* @param imageHeight The image height.
|
||
|
|
*/
|
||
|
|
QuadtreeRasterOverlayTileProvider(
|
||
|
|
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
|
||
|
|
const CesiumAsync::AsyncSystem& asyncSystem,
|
||
|
|
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
|
||
|
|
std::optional<CesiumUtility::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,
|
||
|
|
uint32_t minimumLevel,
|
||
|
|
uint32_t maximumLevel,
|
||
|
|
uint32_t imageWidth,
|
||
|
|
uint32_t imageHeight) noexcept;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Returns the minimum tile level of this instance.
|
||
|
|
*/
|
||
|
|
uint32_t getMinimumLevel() const noexcept { return this->_minimumLevel; }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Returns the maximum tile level of this instance.
|
||
|
|
*/
|
||
|
|
uint32_t getMaximumLevel() const noexcept { return this->_maximumLevel; }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Returns the image width of this instance, in pixels.
|
||
|
|
*/
|
||
|
|
uint32_t getWidth() const noexcept { return this->_imageWidth; }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Returns the image height of this instance, in pixels.
|
||
|
|
*/
|
||
|
|
uint32_t getHeight() const noexcept { return this->_imageHeight; }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Returns the {@link CesiumGeometry::QuadtreeTilingScheme} of this
|
||
|
|
* instance.
|
||
|
|
*/
|
||
|
|
const CesiumGeometry::QuadtreeTilingScheme& getTilingScheme() const noexcept {
|
||
|
|
return this->_tilingScheme;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Computes the best quadtree level to use for an image intended to
|
||
|
|
* cover a given projected rectangle when it is a given size on the screen.
|
||
|
|
*
|
||
|
|
* @param rectangle The range of projected coordinates to cover.
|
||
|
|
* @param screenPixels The number of screen pixels to be covered by the
|
||
|
|
* rectangle.
|
||
|
|
* @return The level.
|
||
|
|
*/
|
||
|
|
uint32_t computeLevelFromTargetScreenPixels(
|
||
|
|
const CesiumGeometry::Rectangle& rectangle,
|
||
|
|
const glm::dvec2& screenPixels);
|
||
|
|
|
||
|
|
protected:
|
||
|
|
/**
|
||
|
|
* @brief Asynchronously loads a tile in the quadtree.
|
||
|
|
*
|
||
|
|
* @param tileID The ID of the quadtree tile to load.
|
||
|
|
* @return A Future that resolves to the loaded image data or error
|
||
|
|
* information.
|
||
|
|
*/
|
||
|
|
virtual CesiumAsync::Future<LoadedRasterOverlayImage>
|
||
|
|
loadQuadtreeTileImage(const CesiumGeometry::QuadtreeTileID& tileID) const = 0;
|
||
|
|
|
||
|
|
private:
|
||
|
|
virtual CesiumAsync::Future<LoadedRasterOverlayImage>
|
||
|
|
loadTileImage(RasterOverlayTile& overlayTile) override final;
|
||
|
|
|
||
|
|
struct LoadedQuadtreeImage
|
||
|
|
: public CesiumUtility::SharedAsset<LoadedQuadtreeImage> {
|
||
|
|
LoadedQuadtreeImage(
|
||
|
|
const std::shared_ptr<LoadedRasterOverlayImage>& pLoaded_,
|
||
|
|
const std::optional<CesiumGeometry::Rectangle>& subset_)
|
||
|
|
: pLoaded(pLoaded_), subset(subset_) {}
|
||
|
|
std::shared_ptr<LoadedRasterOverlayImage> pLoaded = nullptr;
|
||
|
|
std::optional<CesiumGeometry::Rectangle> subset = std::nullopt;
|
||
|
|
|
||
|
|
int64_t getSizeBytes() const {
|
||
|
|
int64_t accum = 0;
|
||
|
|
accum += int64_t(sizeof(LoadedQuadtreeImage));
|
||
|
|
if (pLoaded) {
|
||
|
|
accum += pLoaded->getSizeBytes();
|
||
|
|
}
|
||
|
|
return accum;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
CesiumAsync::SharedFuture<CesiumUtility::ResultPointer<LoadedQuadtreeImage>>
|
||
|
|
getQuadtreeTile(const CesiumGeometry::QuadtreeTileID& tileID);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Map raster tiles to geometry tile.
|
||
|
|
*
|
||
|
|
* @param geometryRectangle The rectangle for which to load tiles.
|
||
|
|
* @param targetGeometricError The geometric error controlling which quadtree
|
||
|
|
* level to use to cover the rectangle.
|
||
|
|
* @return A vector of shared futures, each of which will resolve to image
|
||
|
|
* data that is required to cover the rectangle with the given geometric
|
||
|
|
* error.
|
||
|
|
*/
|
||
|
|
std::vector<CesiumAsync::SharedFuture<
|
||
|
|
CesiumUtility::ResultPointer<LoadedQuadtreeImage>>>
|
||
|
|
mapRasterTilesToGeometryTile(
|
||
|
|
const CesiumGeometry::Rectangle& geometryRectangle,
|
||
|
|
const glm::dvec2 targetScreenPixels);
|
||
|
|
|
||
|
|
struct CombinedImageMeasurements {
|
||
|
|
CesiumGeometry::Rectangle rectangle;
|
||
|
|
int32_t widthPixels;
|
||
|
|
int32_t heightPixels;
|
||
|
|
int32_t channels;
|
||
|
|
int32_t bytesPerChannel;
|
||
|
|
};
|
||
|
|
|
||
|
|
static CombinedImageMeasurements measureCombinedImage(
|
||
|
|
const CesiumGeometry::Rectangle& targetRectangle,
|
||
|
|
const std::vector<CesiumUtility::ResultPointer<LoadedQuadtreeImage>>&
|
||
|
|
images);
|
||
|
|
|
||
|
|
static LoadedRasterOverlayImage combineImages(
|
||
|
|
const CesiumGeometry::Rectangle& targetRectangle,
|
||
|
|
const CesiumGeospatial::Projection& projection,
|
||
|
|
std::vector<CesiumUtility::ResultPointer<LoadedQuadtreeImage>>&& images);
|
||
|
|
|
||
|
|
uint32_t _minimumLevel;
|
||
|
|
uint32_t _maximumLevel;
|
||
|
|
uint32_t _imageWidth;
|
||
|
|
uint32_t _imageHeight;
|
||
|
|
CesiumGeometry::QuadtreeTilingScheme _tilingScheme;
|
||
|
|
|
||
|
|
CesiumUtility::IntrusivePointer<CesiumAsync::SharedAssetDepot<
|
||
|
|
LoadedQuadtreeImage,
|
||
|
|
CesiumGeometry::QuadtreeTileID>>
|
||
|
|
_pTileDepot;
|
||
|
|
};
|
||
|
|
} // namespace CesiumRasterOverlays
|