Skip to content
Permalink
Browse files

[FEATURE][AFS] Create labels when settings provied by server

  • Loading branch information
nirvn committed Dec 10, 2018
1 parent cf0442d commit 22a66ef390cb85cef049495d4734f5053585d5de
@@ -52,6 +52,7 @@ of feature and attribute information from a spatial datasource.
WriteLayerMetadata,
CancelSupport,
CreateRenderer,
CreateLabeling,
};

typedef QFlags<QgsVectorDataProvider::Capability> Capabilities;
@@ -518,6 +519,23 @@ Only providers which report the CreateRenderer capability will return a feature
providers will return None.

.. versionadded:: 3.2
%End

virtual QgsAbstractVectorLayerLabeling *createLabeling( const QVariantMap &configuration = QVariantMap() ) const /Factory/;
%Docstring
Creates labeling settings, using provider backend specific information.

The ``configuration`` map can be used to pass provider-specific configuration maps to the provider to
allow customization of the returned labeling object. Support and format of ``configuration`` varies by provider.

When called with an empty ``configuration`` map the provider's default labeling settings will be returned.

This method returns a new labeling settings and the caller takes ownership of the returned object.

Only providers which report the CreateLabeling capability will return labeling settings. Other
providers will return None.

.. versionadded:: 3.6
%End

static QVariant convertValue( QVariant::Type type, const QString &value );
@@ -699,6 +699,11 @@ QgsFeatureRenderer *QgsVectorDataProvider::createRenderer( const QVariantMap & )
return nullptr;
}

QgsAbstractVectorLayerLabeling *QgsVectorDataProvider::createLabeling( const QVariantMap & ) const
{
return nullptr;
}

void QgsVectorDataProvider::pushError( const QString &msg ) const
{
QgsDebugMsg( msg );
@@ -41,6 +41,7 @@ class QgsFeatureIterator;
class QgsTransaction;
class QgsFeedback;
class QgsFeatureRenderer;
class QgsAbstractVectorLayerLabeling;

#include "qgsfeaturerequest.h"

@@ -93,6 +94,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
WriteLayerMetadata = 1 << 22, //!< Provider can write layer metadata to the data store. Since QGIS 3.0. See QgsDataProvider::writeLayerMetadata()
CancelSupport = 1 << 23, //!< Supports interruption of pending queries from a separated thread. Since QGIS 3.2
CreateRenderer = 1 << 24, //!< Provider can create feature renderers using backend-specific formatting information. Since QGIS 3.2. See QgsVectorDataProvider::createRenderer().
CreateLabeling = 1 << 25, //!< Provider can set labeling settings using backend-specific formatting information. Since QGIS 3.6. See QgsVectorDataProvider::createLabeling().
};

Q_DECLARE_FLAGS( Capabilities, Capability )
@@ -520,6 +522,23 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
*/
virtual QgsFeatureRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const SIP_FACTORY;

/**
* Creates labeling settings, using provider backend specific information.
*
* The \a configuration map can be used to pass provider-specific configuration maps to the provider to
* allow customization of the returned labeling object. Support and format of \a configuration varies by provider.
*
* When called with an empty \a configuration map the provider's default labeling settings will be returned.
*
* This method returns a new labeling settings and the caller takes ownership of the returned object.
*
* Only providers which report the CreateLabeling capability will return labeling settings. Other
* providers will return nullptr.
*
* \since QGIS 3.6
*/
virtual QgsAbstractVectorLayerLabeling *createLabeling( const QVariantMap &configuration = QVariantMap() ) const SIP_FACTORY;

static QVariant convertValue( QVariant::Type type, const QString &value );

/**
@@ -1531,6 +1531,16 @@ void QgsVectorLayer::setDataSource( const QString &dataSource, const QString &ba
}

setLegend( QgsMapLayerLegend::defaultVectorLegend( this ) );

if ( mDataProvider->capabilities() & QgsVectorDataProvider::CreateLabeling )
{
std::unique_ptr< QgsAbstractVectorLayerLabeling > defaultLabeling( mDataProvider->createLabeling() );
if ( defaultLabeling )
{
setLabeling( defaultLabeling.release() );
setLabelsEnabled( true );
}
}
}

emit dataSourceChanged();
@@ -222,6 +222,7 @@ QgsAfsProvider::QgsAfsProvider( const QString &uri, const ProviderOptions &optio

// renderer
mRendererDataMap = layerData.value( QStringLiteral( "drawingInfo" ) ).toMap().value( QStringLiteral( "renderer" ) ).toMap();
mLabelingDataList = layerData.value( QStringLiteral( "drawingInfo" ) ).toMap().value( QStringLiteral( "labelingInfo" ) ).toList();

mValid = true;
}
@@ -263,6 +264,10 @@ QgsVectorDataProvider::Capabilities QgsAfsProvider::capabilities() const
{
c = c | QgsVectorDataProvider::CreateRenderer;
}
if ( !mLabelingDataList.empty() )
{
c = c | QgsVectorDataProvider::CreateLabeling;
}
return c;
}

@@ -307,6 +312,10 @@ QgsFeatureRenderer *QgsAfsProvider::createRenderer( const QVariantMap & ) const
return QgsArcGisRestUtils::parseEsriRenderer( mRendererDataMap );
}

QgsAbstractVectorLayerLabeling *QgsAfsProvider::createLabeling( const QVariantMap & ) const
{
return QgsArcGisRestUtils::parseEsriLabeling( mLabelingDataList );
}

#ifdef HAVE_GUI

@@ -71,6 +71,7 @@ class QgsAfsProvider : public QgsVectorDataProvider
QString dataComment() const override;
void reloadData() override;
QgsFeatureRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const override;
QgsAbstractVectorLayerLabeling *createLabeling( const QVariantMap &configuration = QVariantMap() ) const override;

private:
bool mValid = false;
@@ -80,6 +81,7 @@ class QgsAfsProvider : public QgsVectorDataProvider
QString mLayerDescription;
QgsLayerMetadata mLayerMetadata;
QVariantMap mRendererDataMap;
QVariantList mLabelingDataList;
};

#endif // QGSAFSPROVIDER_H
@@ -28,6 +28,7 @@
#include "geometry/qgspolygon.h"
#include "geometry/qgspoint.h"
#include "qgsfeedback.h"
#include "qgspallabeling.h"
#include "qgssymbol.h"
#include "qgssymbollayer.h"
#include "qgsauthmanager.h"
@@ -36,8 +37,11 @@
#include "qgsfillsymbollayer.h"
#include "qgsmarkersymbollayer.h"
#include "qgsrenderer.h"
#include "qgsrulebasedlabeling.h"
#include "qgssinglesymbolrenderer.h"
#include "qgscategorizedsymbolrenderer.h"
#include "qgsvectorlayerlabeling.h"

#include <QEventLoop>
#include <QNetworkRequest>
#include <QNetworkReply>
@@ -765,6 +769,132 @@ std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbo
return symbol;
}

QgsAbstractVectorLayerLabeling *QgsArcGisRestUtils::parseEsriLabeling( const QVariantList &labelingData )
{
if ( labelingData.empty() )
return nullptr;

QgsRuleBasedLabeling::Rule *root = new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings(), 0, 0, QString(), QString(), false );
root->setActive( true );

int i = 1;
for ( const QVariant &lbl : labelingData )
{
const QVariantMap labeling = lbl.toMap();

QgsPalLayerSettings *settings = new QgsPalLayerSettings();
QgsTextFormat format;

const QString placement = labeling.value( QStringLiteral( "labelPlacement" ) ).toString();
if ( placement == QLatin1String( "esriServerPointLabelPlacementAboveCenter" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantAbove;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementBelowCenter" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantBelow;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementCenterCenter" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantOver;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementAboveLeft" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantAboveLeft;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementBelowLeft" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantBelowLeft;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementCenterLeft" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantLeft;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementAboveRight" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantAboveRight;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementBelowRight" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantBelowRight;
}
else if ( placement == QLatin1String( "esriServerPointLabelPlacementCenterRight" ) )
{
settings->placement = QgsPalLayerSettings::OverPoint;
settings->quadOffset = QgsPalLayerSettings::QuadrantRight;
}
else if ( placement == QLatin1String( "esriServerLinePlacementAboveAfter" ) ||
placement == QLatin1String( "esriServerLinePlacementAboveStart" ) ||
placement == QLatin1String( "esriServerLinePlacementAboveAlong" ) )
{
settings->placement = QgsPalLayerSettings::Line;
settings->placementFlags = QgsPalLayerSettings::AboveLine | QgsPalLayerSettings::MapOrientation;
}
else if ( placement == QLatin1String( "esriServerLinePlacementBelowAfter" ) ||
placement == QLatin1String( "esriServerLinePlacementBelowStart" ) ||
placement == QLatin1String( "esriServerLinePlacementBelowAlong" ) )
{
settings->placement = QgsPalLayerSettings::Line;
settings->placementFlags = QgsPalLayerSettings::BelowLine | QgsPalLayerSettings::MapOrientation;
}
else if ( placement == QLatin1String( "esriServerLinePlacementCenterAfter" ) ||
placement == QLatin1String( "esriServerLinePlacementCenterStart" ) ||
placement == QLatin1String( "esriServerLinePlacementCenterAlong" ) )
{
settings->placement = QgsPalLayerSettings::Line;
settings->placementFlags = QgsPalLayerSettings::OnLine | QgsPalLayerSettings::MapOrientation;
}
else if ( placement == QLatin1String( "esriServerPolygonPlacementAlwaysHorizontal" ) )
{
settings->placement = QgsPalLayerSettings::Horizontal;
}

const double minScale = labeling.value( QStringLiteral( "minScale" ) ).toDouble();
const double maxScale = labeling.value( QStringLiteral( "maxScale" ) ).toDouble();

QVariantMap symbol = labeling.value( QStringLiteral( "symbol" ) ).toMap();
format.setColor( parseEsriColorJson( symbol.value( QStringLiteral( "color" ) ) ) );

const QString fontFamily = symbol.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "family" ) ).toString();
const QString fontStyle = symbol.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "style" ) ).toString();
const QString fontWeight = symbol.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "weight" ) ).toString();
const int fontSize = symbol.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "size" ) ).toInt();
QFont font( fontFamily, fontSize );
font.setStyleName( fontStyle );
font.setWeight( fontWeight == QLatin1String( "bold" ) ? QFont::Bold : QFont::Normal );

format.setFont( font );
format.setSize( fontSize );
format.setSizeUnit( QgsUnitTypes::RenderPoints );

settings->setFormat( format );

QString where = labeling.value( QStringLiteral( "where" ) ).toString();
QgsExpression exp( where );
// If the where clause isn't parsed as valid, don't use its
if ( !exp.isValid() )
where.clear();

QString expression = labeling.value( QStringLiteral( "labelExpression" ) ).toString();
settings->fieldName = expression.replace( '[', '"' ).replace( ']', '"' );
settings->isExpression = true;

QgsRuleBasedLabeling::Rule *child = new QgsRuleBasedLabeling::Rule( settings, maxScale, minScale, where, QObject::tr( "ASF label %1" ).arg( i++ ), false );
child->setActive( true );
root->appendChild( child );
}

return new QgsRuleBasedLabeling( root );
}

QgsFeatureRenderer *QgsArcGisRestUtils::parseEsriRenderer( const QVariantMap &rendererData )
{
const QString type = rendererData.value( QStringLiteral( "type" ) ).toString();
@@ -24,6 +24,7 @@ class QNetworkReply;
class QgsNetworkAccessManager;
class QgsFields;
class QgsAbstractGeometry;
class QgsAbstractVectorLayerLabeling;
class QgsCoordinateReferenceSystem;
class QgsFeedback;
class QgsSymbol;
@@ -58,6 +59,7 @@ class QgsArcGisRestUtils
static std::unique_ptr< QgsMarkerSymbol > parseEsriMarkerSymbolJson( const QVariantMap &symbolData );
static std::unique_ptr< QgsMarkerSymbol > parseEsriPictureMarkerSymbolJson( const QVariantMap &symbolData );
static QgsFeatureRenderer *parseEsriRenderer( const QVariantMap &rendererData );
static QgsAbstractVectorLayerLabeling *parseEsriLabeling( const QVariantList &labelingData );

static QColor parseEsriColorJson( const QVariant &colorData );
static Qt::PenStyle parseEsriLineStyle( const QString &style );

0 comments on commit 22a66ef

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