Skip to content

Commit 6901d6f

Browse files
committedSep 8, 2020
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)
1 parent 9114e91 commit 6901d6f

File tree

6 files changed

+122
-14
lines changed

6 files changed

+122
-14
lines changed
 

‎python/core/auto_generated/qgsmaplayer.sip.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ record in the users style table in their personal qgis.db)
742742
.. versionadded:: 3.0
743743
%End
744744

745-
QString loadDefaultMetadata( bool &resultFlag );
745+
virtual QString loadDefaultMetadata( bool &resultFlag );
746746
%Docstring
747747
Retrieve the default metadata for this layer if one
748748
exists (either as a .qmd file on disk or as a

‎python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,26 @@ Constructs a new vector tile layer
8383

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

86+
8687
virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context );
8788

89+
8890
virtual bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const;
8991

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

93-
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
94-
StyleCategories categories = AllStyleCategories ) const;
93+
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
94+
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );
95+
96+
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
97+
StyleCategories categories = AllStyleCategories ) const;
9598

9699
virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext );
97100

101+
virtual QString loadDefaultStyle( bool &resultFlag /Out/ );
102+
103+
virtual QString loadDefaultMetadata( bool &resultFlag /Out/ );
104+
105+
98106
virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const ${SIP_FINAL};
99107

100108
virtual QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const ${SIP_FINAL};

‎src/app/qgisapp.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,9 @@ void QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst )
20572057
else if ( u.layerType == QLatin1String( "vector-tile" ) )
20582058
{
20592059
QgsVectorTileLayer *layer = new QgsVectorTileLayer( uri, u.name );
2060+
bool ok = false;
2061+
layer->loadDefaultStyle( ok );
2062+
layer->loadDefaultMetadata( ok );
20602063
addMapLayer( layer );
20612064
}
20622065
else if ( u.layerType == QLatin1String( "plugin" ) )
@@ -5653,6 +5656,13 @@ QgsVectorTileLayer *QgisApp::addVectorTileLayerPrivate( const QString &url, cons
56535656
// since the layer is bad, stomp on it
56545657
return nullptr;
56555658
}
5659+
bool ok = false;
5660+
QString error = layer->loadDefaultStyle( ok );
5661+
if ( !ok )
5662+
visibleMessageBar()->pushMessage( tr( "Error loading style" ), error, Qgis::Warning, messageTimeout() );
5663+
error = layer->loadDefaultMetadata( ok );
5664+
if ( !ok )
5665+
visibleMessageBar()->pushMessage( tr( "Error loading layer metadata" ), error, Qgis::Warning, messageTimeout() );
56565666

56575667
QgsProject::instance()->addMapLayer( layer.get() );
56585668
activateDeactivateLayerRelatedActions( activeLayer() );

‎src/core/qgsmaplayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
739739
* \returns a QString with any status messages
740740
* \since QGIS 3.0
741741
*/
742-
QString loadDefaultMetadata( bool &resultFlag );
742+
virtual QString loadDefaultMetadata( bool &resultFlag );
743743

744744
/**
745745
* Retrieve a named metadata for this layer from a sqlite database.

‎src/core/vectortile/qgsvectortilelayer.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,94 @@ void QgsVectorTileLayer::setTransformContext( const QgsCoordinateTransformContex
292292
Q_UNUSED( transformContext )
293293
}
294294

295+
QString QgsVectorTileLayer::loadDefaultStyle( bool &resultFlag )
296+
{
297+
QgsDataSourceUri dsUri;
298+
dsUri.setEncodedUri( mDataSource );
299+
if ( mSourceType == QStringLiteral( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
300+
{
301+
QNetworkRequest request = QNetworkRequest( QUrl( mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString()
302+
+ '/' + mArcgisLayerConfiguration.value( QStringLiteral( "defaultStyles" ) ).toString() ) );
303+
304+
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) );
305+
306+
QgsBlockingNetworkRequest networkRequest;
307+
switch ( networkRequest.get( request ) )
308+
{
309+
case QgsBlockingNetworkRequest::NoError:
310+
break;
311+
312+
case QgsBlockingNetworkRequest::NetworkError:
313+
case QgsBlockingNetworkRequest::TimeoutError:
314+
case QgsBlockingNetworkRequest::ServerExceptionError:
315+
resultFlag = false;
316+
return QObject::tr( "Error retrieving default style" );
317+
}
318+
319+
const QgsNetworkReplyContent content = networkRequest.reply();
320+
const QByteArray raw = content.content();
321+
322+
QgsMapBoxGlStyleConversionContext context;
323+
// convert automatically from pixel sizes to millimeters, because pixel sizes
324+
// are a VERY edge case in QGIS and don't play nice with hidpi map renders or print layouts
325+
context.setTargetUnit( QgsUnitTypes::RenderMillimeters );
326+
//assume source uses 96 dpi
327+
context.setPixelSizeConversionFactor( 25.4 / 96.0 );
328+
329+
QgsMapBoxGlStyleConverter converter;
330+
if ( converter.convert( raw, &context ) != QgsMapBoxGlStyleConverter::Success )
331+
{
332+
resultFlag = false;
333+
return converter.errorMessage();
334+
}
335+
336+
setRenderer( converter.renderer() );
337+
setLabeling( converter.labeling() );
338+
resultFlag = true;
339+
return QString();
340+
}
341+
else
342+
{
343+
QgsMapLayer::loadDefaultStyle( resultFlag );
344+
resultFlag = true;
345+
return QString();
346+
}
347+
}
348+
349+
QString QgsVectorTileLayer::loadDefaultMetadata( bool &resultFlag )
350+
{
351+
QgsDataSourceUri dsUri;
352+
dsUri.setEncodedUri( mDataSource );
353+
if ( mSourceType == QStringLiteral( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
354+
{
355+
// populate default metadata
356+
QgsLayerMetadata metadata;
357+
metadata.setIdentifier( mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() );
358+
const QString parentIdentifier = mArcgisLayerConfiguration.value( QStringLiteral( "serviceItemId" ) ).toString();
359+
if ( !parentIdentifier.isEmpty() )
360+
{
361+
metadata.setParentIdentifier( parentIdentifier );
362+
}
363+
metadata.setType( QStringLiteral( "dataset" ) );
364+
metadata.setTitle( mArcgisLayerConfiguration.value( QStringLiteral( "name" ) ).toString() );
365+
QString copyright = mArcgisLayerConfiguration.value( QStringLiteral( "copyrightText" ) ).toString();
366+
if ( !copyright.isEmpty() )
367+
metadata.setRights( QStringList() << copyright );
368+
metadata.addLink( QgsAbstractMetadataBase::Link( tr( "Source" ), QStringLiteral( "WWW:LINK" ), mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() ) );
369+
370+
setMetadata( metadata );
371+
372+
resultFlag = true;
373+
return QString();
374+
}
375+
else
376+
{
377+
QgsMapLayer::loadDefaultMetadata( resultFlag );
378+
resultFlag = true;
379+
return QString();
380+
}
381+
}
382+
295383
QString QgsVectorTileLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const
296384
{
297385
QgsDataSourceUri dsUri;

‎src/core/vectortile/qgsvectortilelayer.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,21 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer
9393

9494
QgsVectorTileLayer *clone() const override SIP_FACTORY;
9595

96-
virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
96+
QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
9797

98-
virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override;
98+
bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override;
9999

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

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

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

108-
virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
108+
void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
109+
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) override;
110+
QString loadDefaultMetadata( bool &resultFlag SIP_OUT ) override;
109111

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

0 commit comments

Comments
 (0)
Please sign in to comment.