-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Support Zarr as a STAC cloud-optimised media type (#62838) #63358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Support Zarr as a STAC cloud-optimised media type (#62838) #63358
Conversation
Layout issues addressed |
🪟 Windows Qt6 buildsDownload Windows Qt6 builds of this PR for testing. 🍎 MacOS Qt6 buildsDownload MacOS Qt6 builds of this PR for testing. |
9a713a7
to
8c623f4
Compare
Returns a uri for the asset if it is a cloud optimized file like COG or | ||
COPC, empty auth configuration | ||
|
||
.. versionadded:: 3.42 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@m-kuhn I believe 3.42
is the correct version here. This .sip.in change resulted from pre-commit hooks executing on my change, though my change did not modify this function. The commit that added this function (here) did not update .sip.in files, and my change was the first time these files were updated for this behaviour. Presumably the previous author did not execute pre-commit hooks.
However - the following function, an overload of this function that accepts a QString
parameter, is new and should reference 4.0. I will make this change shortly.
QString html = QStringLiteral( "<html><head></head>\n<body>\n" ); | ||
|
||
html += QStringLiteral( "<h1>%1</h1>\n<hr>\n" ).arg( QLatin1String( "Item" ) ); | ||
QString html = QStringLiteral( "<h1>%1</h1>\n<hr>\n" ).arg( QLatin1String( "Item" ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should Item
be translated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@m-kuhn this is a good question. The previous implementation did not translate the string, and also "Item" is a specific term in the STAC specification and I am not sure if STAC intends for it to be translated.
As the string was not previously translated, and other STAC terms such as "Collection" and "Links" are not translated, my preference would be to address this question in a separate issue if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to not translate stac entity names, at least not yet.
ad157e1
to
f6de369
Compare
Co-authored-by: Matthias Kuhn <matthias@opengis.ch>
Co-authored-by: Matthias Kuhn <matthias@opengis.ch>
f6de369
to
1e7e899
Compare
@m-kuhn thanks for your input. I've made requested changes and responded where I wasn't sure a change was necessary. |
|
||
private: | ||
QString mAuthcfg; | ||
void setContent( QString bodyHtml, QString thumbnailHtml ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void setContent( QString bodyHtml, QString thumbnailHtml ); | |
void setContent( const QString &bodyHtml, const QString &thumbnailHtml ); |
#include "qgsstacasset.h" | ||
#include "qgsstacobject.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's forward-declare both QgsStacAsset
and QgsStacObject
instead of including
QString thumbnailHtml; | ||
if ( isThumbnailAsset( stacAsset ) ) | ||
{ | ||
thumbnailHtml = thumbnailHtmlContent( stacAsset ); | ||
} | ||
QString bodyHtml = stacAsset->toHtml( assetId ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QString thumbnailHtml; | |
if ( isThumbnailAsset( stacAsset ) ) | |
{ | |
thumbnailHtml = thumbnailHtmlContent( stacAsset ); | |
} | |
QString bodyHtml = stacAsset->toHtml( assetId ); | |
const QString thumbnailHtml = isThumbnailAsset( stacAsset ) ? thumbnailHtmlContent( stacAsset ) : QString(); | |
const QString bodyHtml = stacAsset->toHtml( assetId ); |
QString thumbnailHtml = thumbnails.join( QString() ); | ||
QString bodyHtml = stacObject->toHtml(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QString thumbnailHtml = thumbnails.join( QString() ); | |
QString bodyHtml = stacObject->toHtml(); | |
const QString thumbnailHtml = thumbnails.join( QString() ); | |
const QString bodyHtml = stacObject->toHtml(); |
QAction *actionDownload = new QAction( tr( "Download Assets…" ), menu ); | ||
connect( actionDownload, &QAction::triggered, this, [itemItem, context] { downloadAssets( itemItem, context ); } ); | ||
menu->addAction( actionDownload ); | ||
int downloadableAssets = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can replace the int
with a bool hasDownloadableAssets
and break the iteration at first downloadable asset occurrance
QString html = QStringLiteral( "<html><head></head>\n<body>\n" ); | ||
|
||
html += QStringLiteral( "<h1>%1</h1>\n<hr>\n" ).arg( QLatin1String( "Item" ) ); | ||
QString html = QStringLiteral( "<h1>%1</h1>\n<hr>\n" ).arg( QLatin1String( "Item" ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to not translate stac entity names, at least not yet.
mStacAsset( asset ), | ||
mName( name ) | ||
{ | ||
mIconName = QStringLiteral( "mActionPropertiesWidget.svg" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need a separate icon for assets
// create any assets beneath the item, so that they can be individually drag-dropped as layers if compatible | ||
i->populate( true ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why pre populate all assets for all items?
Should we not wait for the user to expand the Item?
bool hasDragEnabled() const override; | ||
QgsMimeDataUtils::UriList mimeUris() const override; | ||
bool equal( const QgsDataItem *other ) override; | ||
QVariant sortKey() const override { return QStringLiteral( "4 %1" ).arg( mName ); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if 4
might cause some unexpected sorting as the QgsStacFetchMoreItem
which should always be last, has 3
as a sort key.
/** | ||
* Returns a uri for the asset if it is a cloud optimized file like COG or COPC | ||
* \since QGIS 4.0 | ||
*/ | ||
QgsMimeDataUtils::Uri uri( const QString &authcfg ) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think QgsStacAsset
should have such method. This class should just be a container class for the stac asset properties.
It would be the caller's responsibility to add the authcfg
to the URI based on the provider (the current approach of just appending authcfg=...
is a bit naive).
Maybe something like:
QgsProviderMetadata *md = QgsProviderRegistry::instance()->providerMetadata( uri.providerKey );
QVariantMap map = md->decodeUri( uri.uri );
map[ QStringLiteral( "authcfg" ) ] = authcfg;
uri.uri = md.encodeUri( map );
??
Maybe it could be a void QgsMimeDataUtils::Uri::setAuthCfg( const QString &authcfg );
?
What do you think?
Description
Closes #62838
Incorporates the following changes.
sip
Updated sip.in files by running
sipify_all.sh
script (which generates some changes not directly triggered by this change).Cloud-Optimised
Recognised Zarr as a cloud-optimised media type in QgsStacAsset logic and added Zarr handling logic in the
uri
function to correctly prefix STAC Assethref
s withZARR:/vsicurl/
so that Zarr STAC Assets can be added as layers.Assets in Browser Pane
Added a further nesting beneath STAC Items in the Browser pane showing assets. This allows individual cloud-optimised STAC Assets to be drag-dropped into the Layers pane. Previously only STAC Items could be drag-dropped into the Layers pane if they contained at least one cloud-optimised STAC Asset, at which point all of the STAC Item's cloud-optimised STAC Assets were added to the Layers pane. This change adds greater flexibility and better supports STAC Items with many cloud-optimised STAC Assets.
Note
As part of this change logic to generate HTML representations of STAC Assets for STAC Items' Details modal was extracted to a separate function so that individual STAC Assets can have their own Details modal.
Downloadable Assets
Added
QgsStacAsset::isDownloadable
to determine if assets should provide a download option. Zarr assets should not be offered for download as the STAC Asset'shref
points to a directory rather than a data file or archive. Zarr download attempts in QGIS will either fail with 4xx or download a directory listing response.DRY
Removed duplication in STAC Asset handling logic.
Note
Prior to this change logic in the QgsStacAsset class was duplicated in QgsStacItemItem and this change includes a DRY consolidation. The QgsStacAsset class's
formatName
function anduri
function were effecitvely duplicated in the QgsStacItemItem class'smimeUris
function. The QgsStacItemItem has been changed to reference the consolidated logic. Commit fa4192dbe9bda7c4aa721500ca9f8ca0523abaa6 added auth handling toQgsStacItemItem::mimeUris
but not toQgsStacAsset::uri
. This DRY consolidation implements the same auth handling inQgsStacAsset::uri
, which is why the PR shows that function being edited.