Skip to content
Permalink
Browse files

After loading an ArcGIS Vector Tile Service layer, automatically load

and set the default style and labels for the layer

Also populate the layer metadata with the available content from the
service definition (e.g. layer attribution)
  • Loading branch information
nyalldawson committed Sep 8, 2020
1 parent 9114e91 commit 6901d6f68a14f64cc7cec6b413a6b2a2ecf54c2f
@@ -742,7 +742,7 @@ record in the users style table in their personal qgis.db)
.. versionadded:: 3.0
%End

QString loadDefaultMetadata( bool &resultFlag );
virtual QString loadDefaultMetadata( bool &resultFlag );
%Docstring
Retrieve the default metadata for this layer if one
exists (either as a .qmd file on disk or as a
@@ -83,18 +83,26 @@ Constructs a new vector tile layer

virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;


virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context );


virtual bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const;

virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );

virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllStyleCategories ) const;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );

virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllStyleCategories ) const;

virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext );

virtual QString loadDefaultStyle( bool &resultFlag /Out/ );

virtual QString loadDefaultMetadata( bool &resultFlag /Out/ );


virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const ${SIP_FINAL};

virtual QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const ${SIP_FINAL};
@@ -2057,6 +2057,9 @@ void QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst )
else if ( u.layerType == QLatin1String( "vector-tile" ) )
{
QgsVectorTileLayer *layer = new QgsVectorTileLayer( uri, u.name );
bool ok = false;
layer->loadDefaultStyle( ok );
layer->loadDefaultMetadata( ok );
addMapLayer( layer );
}
else if ( u.layerType == QLatin1String( "plugin" ) )
@@ -5653,6 +5656,13 @@ QgsVectorTileLayer *QgisApp::addVectorTileLayerPrivate( const QString &url, cons
// since the layer is bad, stomp on it
return nullptr;
}
bool ok = false;
QString error = layer->loadDefaultStyle( ok );
if ( !ok )
visibleMessageBar()->pushMessage( tr( "Error loading style" ), error, Qgis::Warning, messageTimeout() );
error = layer->loadDefaultMetadata( ok );
if ( !ok )
visibleMessageBar()->pushMessage( tr( "Error loading layer metadata" ), error, Qgis::Warning, messageTimeout() );

QgsProject::instance()->addMapLayer( layer.get() );
activateDeactivateLayerRelatedActions( activeLayer() );
@@ -739,7 +739,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \returns a QString with any status messages
* \since QGIS 3.0
*/
QString loadDefaultMetadata( bool &resultFlag );
virtual QString loadDefaultMetadata( bool &resultFlag );

/**
* Retrieve a named metadata for this layer from a sqlite database.
@@ -292,6 +292,94 @@ void QgsVectorTileLayer::setTransformContext( const QgsCoordinateTransformContex
Q_UNUSED( transformContext )
}

QString QgsVectorTileLayer::loadDefaultStyle( bool &resultFlag )
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( mDataSource );
if ( mSourceType == QStringLiteral( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
{
QNetworkRequest request = QNetworkRequest( QUrl( mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString()
+ '/' + mArcgisLayerConfiguration.value( QStringLiteral( "defaultStyles" ) ).toString() ) );

QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) );

QgsBlockingNetworkRequest networkRequest;
switch ( networkRequest.get( request ) )
{
case QgsBlockingNetworkRequest::NoError:
break;

case QgsBlockingNetworkRequest::NetworkError:
case QgsBlockingNetworkRequest::TimeoutError:
case QgsBlockingNetworkRequest::ServerExceptionError:
resultFlag = false;
return QObject::tr( "Error retrieving default style" );
}

const QgsNetworkReplyContent content = networkRequest.reply();
const QByteArray raw = content.content();

QgsMapBoxGlStyleConversionContext context;
// convert automatically from pixel sizes to millimeters, because pixel sizes
// are a VERY edge case in QGIS and don't play nice with hidpi map renders or print layouts
context.setTargetUnit( QgsUnitTypes::RenderMillimeters );
//assume source uses 96 dpi
context.setPixelSizeConversionFactor( 25.4 / 96.0 );

QgsMapBoxGlStyleConverter converter;
if ( converter.convert( raw, &context ) != QgsMapBoxGlStyleConverter::Success )
{
resultFlag = false;
return converter.errorMessage();
}

setRenderer( converter.renderer() );
setLabeling( converter.labeling() );
resultFlag = true;
return QString();
}
else
{
QgsMapLayer::loadDefaultStyle( resultFlag );
resultFlag = true;
return QString();
}
}

QString QgsVectorTileLayer::loadDefaultMetadata( bool &resultFlag )
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( mDataSource );
if ( mSourceType == QStringLiteral( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
{
// populate default metadata
QgsLayerMetadata metadata;
metadata.setIdentifier( mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() );
const QString parentIdentifier = mArcgisLayerConfiguration.value( QStringLiteral( "serviceItemId" ) ).toString();
if ( !parentIdentifier.isEmpty() )
{
metadata.setParentIdentifier( parentIdentifier );
}
metadata.setType( QStringLiteral( "dataset" ) );
metadata.setTitle( mArcgisLayerConfiguration.value( QStringLiteral( "name" ) ).toString() );
QString copyright = mArcgisLayerConfiguration.value( QStringLiteral( "copyrightText" ) ).toString();
if ( !copyright.isEmpty() )
metadata.setRights( QStringList() << copyright );
metadata.addLink( QgsAbstractMetadataBase::Link( tr( "Source" ), QStringLiteral( "WWW:LINK" ), mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() ) );

setMetadata( metadata );

resultFlag = true;
return QString();
}
else
{
QgsMapLayer::loadDefaultMetadata( resultFlag );
resultFlag = true;
return QString();
}
}

QString QgsVectorTileLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
@@ -93,19 +93,21 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer

QgsVectorTileLayer *clone() const override SIP_FACTORY;

virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;

virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override;
bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override;

virtual bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const override;

virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) override;
bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) override;

virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllStyleCategories ) const override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllStyleCategories ) const override;

virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) override;
QString loadDefaultMetadata( bool &resultFlag SIP_OUT ) override;

QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const FINAL;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const FINAL;

0 comments on commit 6901d6f

Please sign in to comment.
You can’t perform that action at this time.