Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### ? - ?

##### Breaking Changes :mega:

- Renamed `CesiumITwinClient::Connection::getAccessToken` to `CesiumITwinClient::Connection::getAuthenticationToken`.
- Renamed `CesiumITwinClient::Connection::setAccessToken` to `CesiumITwinClient::Connection::setAuthenticationToken`.

Expand All @@ -13,6 +14,7 @@
- Added support for the [iTwin Geospatial Features API](https://developer.bentley.com/apis/geospatial-features/overview/).
- Added `CesiumITwinClient::Connection::geospatialFeatureCollections` to query for all feature collections within an iTwin.
- Added `CesiumITwinClient::Connection::geospatialFeatures` to query features within a feature collection.
- Added `CesiumITwinClient::ITwinGeospatialFeaturesRasterOverlay` for displaying Geospatial Features loaded from iTwin as a raster overlay.

##### Fixes :wrench:

Expand Down
1 change: 1 addition & 0 deletions CesiumITwinClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ target_link_libraries(CesiumITwinClient
CesiumClientCommon
CesiumGeometry
CesiumGeospatial
CesiumRasterOverlays
CesiumVectorData
PRIVATE
modp_b64::modp_b64
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once

#include <CesiumAsync/AsyncSystem.h>
#include <CesiumGeospatial/CartographicPolygon.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumITwinClient/Connection.h>
#include <CesiumITwinClient/Library.h>
#include <CesiumRasterOverlays/GeoJsonDocumentRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/Color.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumVectorData/GeoJsonDocument.h>
#include <CesiumVectorData/VectorStyle.h>

#include <spdlog/fwd.h>

#include <memory>
#include <string>

namespace CesiumITwinClient {

/**
* @brief A raster overlay made from rasterizing a \ref
* CesiumVectorData::GeoJsonDocument.
*/
class CESIUMITWINCLIENT_API ITwinGeospatialFeaturesRasterOverlay final
: public CesiumRasterOverlays::RasterOverlay {

public:
/**
* @brief Creates a new ITwinGeospatialFeaturesRasterOverlay.
*
* @param name The user-given name of this polygon layer.
* @param iTwinId The ID of the iTwin to obtain the features from.
* @param collectionId The ID of the Geospatial Features Collection to obtain
* the features from.
* @param pConnection The connection to the iTwin API to use.
* @param geoJsonOptions Options to configure the GeoJSON overlay.
* @param overlayOptions Options to use for this RasterOverlay.
*/
ITwinGeospatialFeaturesRasterOverlay(
const std::string& name,
const std::string& iTwinId,
const std::string& collectionId,
const CesiumUtility::IntrusivePointer<Connection>& pConnection,
const CesiumRasterOverlays::GeoJsonDocumentRasterOverlayOptions&
geoJsonOptions,
const CesiumRasterOverlays::RasterOverlayOptions& overlayOptions = {});
virtual ~ITwinGeospatialFeaturesRasterOverlay() override;

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<
CesiumRasterOverlays::IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const override;

private:
std::string _iTwinId;
std::string _collectionId;
CesiumUtility::IntrusivePointer<Connection> _pConnection;
CesiumRasterOverlays::GeoJsonDocumentRasterOverlayOptions _options;
};
} // namespace CesiumITwinClient
42 changes: 42 additions & 0 deletions CesiumITwinClient/include/CesiumITwinClient/PagedList.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,49 @@ template <typename T> class PagedList {
return _operation(connection, *this->_prevUrl);
}

/**
* @brief Returns all items in this page as well as all subsequent pages.
*
* This does not return items on previous pages, so call this on the first
* page if you want all results.
*
* @param asyncSystem The `AsyncSystem` to use.
* @param pConnection The `Connection` to use to fetch the next pages of
* results, if any.
*/
CesiumAsync::Future<CesiumUtility::Result<std::vector<T>>> allAfter(
const CesiumAsync::AsyncSystem& asyncSystem,
CesiumUtility::IntrusivePointer<Connection>& pConnection) {
return this->allAfter(asyncSystem, pConnection, std::vector<T>());
}

private:
CesiumAsync::Future<CesiumUtility::Result<std::vector<T>>> allAfter(
const CesiumAsync::AsyncSystem& asyncSystem,
CesiumUtility::IntrusivePointer<Connection>& pConnection,
std::vector<T>&& results) {
results.insert(results.end(), this->_items.begin(), this->_items.end());
if (!this->_nextUrl) {
return asyncSystem.createResolvedFuture(
CesiumUtility::Result<std::vector<T>>(std::move(results)));
}

return this->_operation(pConnection, *this->_nextUrl)
.thenImmediately(
[asyncSystem, pConnection, results = std::move(results)](
CesiumUtility::Result<PagedList<T>>&& result) mutable {
if (!result.value) {
return asyncSystem.createResolvedFuture(
CesiumUtility::Result<std::vector<T>>(result.errors));
}

return result.value->allAfter(
asyncSystem,
pConnection,
std::move(results));
});
}

PageOperation _operation;
std::vector<T> _items;
std::optional<std::string> _selfUrl = std::nullopt;
Expand Down
140 changes: 140 additions & 0 deletions CesiumITwinClient/src/ITwinGeospatialFeaturesRasterOverlay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/SharedAssetDepot.h>
#include <CesiumGeospatial/BoundingRegionBuilder.h>
#include <CesiumGeospatial/Cartographic.h>
#include <CesiumGeospatial/GeographicProjection.h>
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGltf/ImageAsset.h>
#include <CesiumITwinClient/ITwinGeospatialFeaturesRasterOverlay.h>
#include <CesiumRasterOverlays/GeoJsonDocumentRasterOverlay.h>
#include <CesiumRasterOverlays/Library.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/Color.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumVectorData/GeoJsonDocument.h>
#include <CesiumVectorData/GeoJsonObject.h>
#include <CesiumVectorData/VectorRasterizer.h>
#include <CesiumVectorData/VectorStyle.h>

#include <glm/common.hpp>
#include <glm/ext/vector_int2.hpp>
#include <nonstd/expected.hpp>
#include <spdlog/logger.h>

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

using namespace CesiumGeometry;
using namespace CesiumGeospatial;
using namespace CesiumRasterOverlays;
using namespace CesiumUtility;
using namespace CesiumVectorData;

namespace CesiumITwinClient {

ITwinGeospatialFeaturesRasterOverlay::ITwinGeospatialFeaturesRasterOverlay(
const std::string& name,
const std::string& iTwinId,
const std::string& collectionId,
const CesiumUtility::IntrusivePointer<Connection>& pConnection,
const CesiumRasterOverlays::GeoJsonDocumentRasterOverlayOptions&
geoJsonOptions,
const CesiumRasterOverlays::RasterOverlayOptions& overlayOptions)
: RasterOverlay(name, overlayOptions),
_iTwinId(iTwinId),
_collectionId(collectionId),
_pConnection(pConnection),
_options(geoJsonOptions) {}

ITwinGeospatialFeaturesRasterOverlay::~ITwinGeospatialFeaturesRasterOverlay() =
default;

CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
ITwinGeospatialFeaturesRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<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;

return this->_pConnection
->geospatialFeatures(this->_iTwinId, this->_collectionId)
.thenInWorkerThread(
[asyncSystem, pConnection = this->_pConnection](
Result<PagedList<GeoJsonFeature>>&& result) mutable {
if (!result.value) {
return asyncSystem.createResolvedFuture(
Result<std::vector<GeoJsonFeature>>(result.errors));
}

return result.value->allAfter(asyncSystem, pConnection);
})
.thenInWorkerThread(
[asyncSystem,
name = this->getName(),
vectorOptions = this->_options,
options = this->getOptions(),
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
pOwner](Result<std::vector<GeoJsonFeature>>&& result)
-> CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> {
if (!result.value) {
return asyncSystem.createResolvedFuture<
RasterOverlay::CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::CesiumIon,
nullptr,
fmt::format(
"Errors while loading geospatial features: {}",
CesiumUtility::joinToString(
result.errors.errors,
", "))}));
}

std::vector<GeoJsonObject> objects;
objects.reserve(result.value->size());

for (GeoJsonFeature& feature : *result.value) {
objects.emplace_back(std::move(feature));
}

std::shared_ptr<GeoJsonDocument> pDocument =
std::make_shared<GeoJsonDocument>(
GeoJsonObject{GeoJsonFeatureCollection{
std::move(objects),
std::nullopt,
{},
std::nullopt}},
std::vector<VectorDocumentAttribution>{});
GeoJsonDocumentRasterOverlay geoJsonOverlay(
name,
std::move(pDocument),
vectorOptions,
options);

return geoJsonOverlay.createTileProvider(
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
pOwner);
});
}

} // namespace CesiumITwinClient
Loading