mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-19 00:04:52 -04:00
[25d] Improve convertability to other layers
* Move height and angle expressions for 2.5D renderer to layer * Apply color based on main symbol color This makes the transition to other renderers easy. Fixes #14132
This commit is contained in:
parent
aca49992a9
commit
8d72f13a57
@ -391,6 +391,8 @@ class QgsExpressionContext
|
|||||||
static const QString EXPR_FIELDS;
|
static const QString EXPR_FIELDS;
|
||||||
static const QString EXPR_FEATURE;
|
static const QString EXPR_FEATURE;
|
||||||
static const QString EXPR_ORIGINAL_VALUE;
|
static const QString EXPR_ORIGINAL_VALUE;
|
||||||
|
static const QString EXPR_SYMBOL_COLOR;
|
||||||
|
static const QString EXPR_SYMBOL_ANGLE;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \ingroup core
|
/** \ingroup core
|
||||||
@ -488,6 +490,16 @@ class QgsExpressionContextUtils
|
|||||||
*/
|
*/
|
||||||
static QgsExpressionContextScope* mapSettingsScope( const QgsMapSettings &mapSettings ) /Factory/;
|
static QgsExpressionContextScope* mapSettingsScope( const QgsMapSettings &mapSettings ) /Factory/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a symbol scope related to a QgsSymbolV2 to an expression context. If there is no existing scope
|
||||||
|
* provided, a new one will be generated and returned.
|
||||||
|
* @param symbol symbol to extract properties from
|
||||||
|
* @param symbolScope optional pointer to an existing scope to update
|
||||||
|
* @note added in QGIS 2.14
|
||||||
|
*/
|
||||||
|
static QgsExpressionContextScope* updateSymbolScope( const QgsSymbolV2* symbol, QgsExpressionContextScope* symbolScope = nullptr ) /Factory/;
|
||||||
|
|
||||||
|
|
||||||
/** Creates a new scope which contains variables and functions relating to a QgsComposition.
|
/** Creates a new scope which contains variables and functions relating to a QgsComposition.
|
||||||
* For instance, number of pages and page sizes.
|
* For instance, number of pages and page sizes.
|
||||||
* @param composition source composition
|
* @param composition source composition
|
||||||
|
@ -39,24 +39,6 @@ class Qgs25DRenderer : QgsFeatureRendererV2
|
|||||||
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );
|
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );
|
||||||
virtual QgsSymbolV2List symbols( QgsRenderContext& context );
|
virtual QgsSymbolV2List symbols( QgsRenderContext& context );
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the field or expression used to determine the height of extrusion
|
|
||||||
*/
|
|
||||||
QgsDataDefined height() const;
|
|
||||||
/**
|
|
||||||
* Set the field or expression used to determine the height of extrusion
|
|
||||||
*/
|
|
||||||
void setHeight( const QgsDataDefined& height );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the angle for the extrusion effect
|
|
||||||
*/
|
|
||||||
int angle() const;
|
|
||||||
/**
|
|
||||||
* Set the angle for the extrusion effect
|
|
||||||
*/
|
|
||||||
void setAngle( int angle );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the roof color
|
* Get the roof color
|
||||||
*/
|
*/
|
||||||
@ -77,6 +59,16 @@ class Qgs25DRenderer : QgsFeatureRendererV2
|
|||||||
*/
|
*/
|
||||||
void setWallColor( const QColor& wallColor );
|
void setWallColor( const QColor& wallColor );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set wall shading enabled
|
||||||
|
*/
|
||||||
|
void setWallShadingEnabled( bool enabled );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get wall shading enabled
|
||||||
|
*/
|
||||||
|
bool wallShadingEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shadow's color
|
* Get the shadow's color
|
||||||
*/
|
*/
|
||||||
|
@ -35,4 +35,8 @@ class Qgs25DRendererWidget : QgsRendererV2Widget
|
|||||||
Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer );
|
Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer );
|
||||||
|
|
||||||
QgsFeatureRendererV2* renderer();
|
QgsFeatureRendererV2* renderer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void apply();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,14 @@ class QgsRendererV2PropertiesDialog : QDialog
|
|||||||
*/
|
*/
|
||||||
void setMapCanvas( QgsMapCanvas* canvas );
|
void setMapCanvas( QgsMapCanvas* canvas );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* Emitted when expression context variables on the associated
|
||||||
|
* vector layers have been changed. Will request the parent dialog
|
||||||
|
* to re-synchronize with the variables.
|
||||||
|
*/
|
||||||
|
void layerVariablesChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! called when user changes renderer type
|
//! called when user changes renderer type
|
||||||
void rendererChanged();
|
void rendererChanged();
|
||||||
|
@ -34,6 +34,19 @@ class QgsRendererV2Widget : QWidget
|
|||||||
*/
|
*/
|
||||||
const QgsVectorLayer* vectorLayer() const;
|
const QgsVectorLayer* vectorLayer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should be called whenever the renderer is actually set on the layer.
|
||||||
|
*/
|
||||||
|
void applyChanges();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* Emitted when expression context variables on the associated
|
||||||
|
* vector layers have been changed. Will request the parent dialog
|
||||||
|
* to re-synchronize with the variables.
|
||||||
|
*/
|
||||||
|
void layerVariablesChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Subclasses may provide the capability of changing multiple symbols at once by implementing the following two methods
|
/** Subclasses may provide the capability of changing multiple symbols at once by implementing the following two methods
|
||||||
and by connecting the slot contextMenuViewCategories(const QPoint&)*/
|
and by connecting the slot contextMenuViewCategories(const QPoint&)*/
|
||||||
@ -58,6 +71,13 @@ class QgsRendererV2Widget : QWidget
|
|||||||
virtual void copy();
|
virtual void copy();
|
||||||
virtual void paste();
|
virtual void paste();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* This will be called whenever the renderer is set on a layer.
|
||||||
|
* This can be overwritten in subclasses.
|
||||||
|
*/
|
||||||
|
virtual void apply();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,9 +50,11 @@ static QgsExpressionContext _getExpressionContext( const void* context )
|
|||||||
if ( layer )
|
if ( layer )
|
||||||
expContext << QgsExpressionContextUtils::layerScope( layer );
|
expContext << QgsExpressionContextUtils::layerScope( layer );
|
||||||
|
|
||||||
|
expContext << QgsExpressionContextUtils::updateSymbolScope( nullptr );
|
||||||
|
|
||||||
//TODO - show actual value
|
//TODO - show actual value
|
||||||
expContext.setOriginalValueVariable( QVariant() );
|
expContext.setOriginalValueVariable( QVariant() );
|
||||||
expContext.setHighlightedVariables( QStringList() << QgsExpressionContext::EXPR_ORIGINAL_VALUE );
|
expContext.setHighlightedVariables( QStringList() << QgsExpressionContext::EXPR_ORIGINAL_VALUE << QgsExpressionContext::EXPR_SYMBOL_COLOR );
|
||||||
|
|
||||||
return expContext;
|
return expContext;
|
||||||
}
|
}
|
||||||
|
@ -1263,10 +1263,12 @@ void QgsVectorLayerProperties::updateSymbologyPage()
|
|||||||
mRendererDialog = new QgsRendererV2PropertiesDialog( layer, QgsStyleV2::defaultStyle(), true );
|
mRendererDialog = new QgsRendererV2PropertiesDialog( layer, QgsStyleV2::defaultStyle(), true );
|
||||||
mRendererDialog->setMapCanvas( QgisApp::instance()->mapCanvas() );
|
mRendererDialog->setMapCanvas( QgisApp::instance()->mapCanvas() );
|
||||||
|
|
||||||
|
connect( mRendererDialog, SIGNAL( layerVariablesChanged() ), this, SLOT( updateVariableEditor() ) );
|
||||||
|
|
||||||
// display the menu to choose the output format (fix #5136)
|
// display the menu to choose the output format (fix #5136)
|
||||||
mActionSaveStyleAs->setText( tr( "Save Style" ) );
|
mActionSaveStyleAs->setText( tr( "Save Style" ) );
|
||||||
mActionSaveStyleAs->setMenu( mSaveAsMenu );
|
mActionSaveStyleAs->setMenu( mSaveAsMenu );
|
||||||
QObject::disconnect( mActionSaveStyleAs, SIGNAL( triggered() ), this, SLOT( saveStyleAs_clicked() ) );
|
disconnect( mActionSaveStyleAs, SIGNAL( triggered() ), this, SLOT( saveStyleAs_clicked() ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4546,6 +4546,9 @@ void QgsExpression::initVariableHelp()
|
|||||||
//symbol variables
|
//symbol variables
|
||||||
gVariableHelpTexts.insert( "geometry_part_count", QCoreApplication::translate( "variable_help", "Number of parts in rendered feature's geometry." ) );
|
gVariableHelpTexts.insert( "geometry_part_count", QCoreApplication::translate( "variable_help", "Number of parts in rendered feature's geometry." ) );
|
||||||
gVariableHelpTexts.insert( "geometry_part_num", QCoreApplication::translate( "variable_help", "Current geometry part number for feature being rendered." ) );
|
gVariableHelpTexts.insert( "geometry_part_num", QCoreApplication::translate( "variable_help", "Current geometry part number for feature being rendered." ) );
|
||||||
|
|
||||||
|
gVariableHelpTexts.insert( "symbol_color", QCoreApplication::translate( "symbol_color", "Color of symbol used to render the feature." ) );
|
||||||
|
gVariableHelpTexts.insert( "symbol_angle", QCoreApplication::translate( "symbol_angle", "Angle of symbol used to render the feature (valid for marker symbols only)." ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsExpression::variableHelpText( const QString &variableName, bool showValue, const QVariant &value )
|
QString QgsExpression::variableHelpText( const QString &variableName, bool showValue, const QVariant &value )
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
const QString QgsExpressionContext::EXPR_FIELDS( "_fields_" );
|
const QString QgsExpressionContext::EXPR_FIELDS( "_fields_" );
|
||||||
const QString QgsExpressionContext::EXPR_FEATURE( "_feature_" );
|
const QString QgsExpressionContext::EXPR_FEATURE( "_feature_" );
|
||||||
const QString QgsExpressionContext::EXPR_ORIGINAL_VALUE( "value" );
|
const QString QgsExpressionContext::EXPR_ORIGINAL_VALUE( "value" );
|
||||||
|
const QString QgsExpressionContext::EXPR_SYMBOL_COLOR( "symbol_color" );
|
||||||
|
const QString QgsExpressionContext::EXPR_SYMBOL_ANGLE( "symbol_angle" );
|
||||||
|
|
||||||
//
|
//
|
||||||
// QgsExpressionContextScope
|
// QgsExpressionContextScope
|
||||||
@ -716,6 +718,24 @@ QgsExpressionContextScope* QgsExpressionContextUtils::mapSettingsScope( const Qg
|
|||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsExpressionContextScope* QgsExpressionContextUtils::updateSymbolScope( const QgsSymbolV2* symbol, QgsExpressionContextScope* symbolScope )
|
||||||
|
{
|
||||||
|
if ( !symbolScope )
|
||||||
|
symbolScope = new QgsExpressionContextScope( QObject::tr( "Symbol Scope" ) );
|
||||||
|
|
||||||
|
symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
|
||||||
|
|
||||||
|
double angle = 0.0;
|
||||||
|
const QgsMarkerSymbolV2* markerSymbol = dynamic_cast< const QgsMarkerSymbolV2* >( symbol );
|
||||||
|
if ( markerSymbol )
|
||||||
|
{
|
||||||
|
angle = markerSymbol->angle();
|
||||||
|
}
|
||||||
|
symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_ANGLE, angle, true ) );
|
||||||
|
|
||||||
|
return symbolScope;
|
||||||
|
}
|
||||||
|
|
||||||
QgsExpressionContextScope *QgsExpressionContextUtils::compositionScope( const QgsComposition *composition )
|
QgsExpressionContextScope *QgsExpressionContextUtils::compositionScope( const QgsComposition *composition )
|
||||||
{
|
{
|
||||||
QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Composition" ) );
|
QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Composition" ) );
|
||||||
|
@ -28,6 +28,7 @@ class QgsComposition;
|
|||||||
class QgsComposerItem;
|
class QgsComposerItem;
|
||||||
class QgsAtlasComposition;
|
class QgsAtlasComposition;
|
||||||
class QgsMapSettings;
|
class QgsMapSettings;
|
||||||
|
class QgsSymbolV2;
|
||||||
|
|
||||||
/** \ingroup core
|
/** \ingroup core
|
||||||
* \class QgsScopedExpressionFunction
|
* \class QgsScopedExpressionFunction
|
||||||
@ -425,6 +426,8 @@ class CORE_EXPORT QgsExpressionContext
|
|||||||
static const QString EXPR_FIELDS;
|
static const QString EXPR_FIELDS;
|
||||||
static const QString EXPR_FEATURE;
|
static const QString EXPR_FEATURE;
|
||||||
static const QString EXPR_ORIGINAL_VALUE;
|
static const QString EXPR_ORIGINAL_VALUE;
|
||||||
|
static const QString EXPR_SYMBOL_COLOR;
|
||||||
|
static const QString EXPR_SYMBOL_ANGLE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -519,6 +522,16 @@ class CORE_EXPORT QgsExpressionContextUtils
|
|||||||
*/
|
*/
|
||||||
static QgsExpressionContextScope* mapSettingsScope( const QgsMapSettings &mapSettings );
|
static QgsExpressionContextScope* mapSettingsScope( const QgsMapSettings &mapSettings );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a symbol scope related to a QgsSymbolV2 to an expression context. If there is no existing scope
|
||||||
|
* provided, a new one will be generated and returned.
|
||||||
|
* @param symbol symbol to extract properties from
|
||||||
|
* @param symbolScope optional pointer to an existing scope to update
|
||||||
|
* @note added in QGIS 2.14
|
||||||
|
*/
|
||||||
|
static QgsExpressionContextScope* updateSymbolScope( const QgsSymbolV2* symbol, QgsExpressionContextScope* symbolScope = nullptr );
|
||||||
|
|
||||||
|
|
||||||
/** Creates a new scope which contains variables and functions relating to a QgsComposition.
|
/** Creates a new scope which contains variables and functions relating to a QgsComposition.
|
||||||
* For instance, number of pages and page sizes.
|
* For instance, number of pages and page sizes.
|
||||||
* @param composition source composition
|
* @param composition source composition
|
||||||
|
@ -281,19 +281,33 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
|
|||||||
request.setSubsetOfAttributes( attrNames, mFields );
|
request.setSubsetOfAttributes( attrNames, mFields );
|
||||||
QgsFeatureIterator fit = mSource->getFeatures( request );
|
QgsFeatureIterator fit = mSource->getFeatures( request );
|
||||||
|
|
||||||
|
QgsExpressionContextScope* symbolScope = nullptr;
|
||||||
QgsFeature fet;
|
QgsFeature fet;
|
||||||
while ( fit.nextFeature( fet ) )
|
while ( fit.nextFeature( fet ) )
|
||||||
{
|
{
|
||||||
QScopedPointer<QgsGeometry> obstacleGeometry;
|
QScopedPointer<QgsGeometry> obstacleGeometry;
|
||||||
if ( fet.constGeometry()->type() == QGis::Point )
|
if ( mRenderer )
|
||||||
{
|
{
|
||||||
//point feature, use symbol bounds as obstacle
|
QgsSymbolV2List symbols = mRenderer->originalSymbolsForFeature( fet, ctx );
|
||||||
obstacleGeometry.reset( getPointObstacleGeometry( fet, ctx, mRenderer ) );
|
if ( !symbols.isEmpty() && fet.constGeometry()->type() == QGis::Point )
|
||||||
|
{
|
||||||
|
//point feature, use symbol bounds as obstacle
|
||||||
|
obstacleGeometry.reset( QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, ctx, symbols ) );
|
||||||
|
}
|
||||||
|
if ( !symbols.isEmpty() )
|
||||||
|
{
|
||||||
|
symbolScope = QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
|
||||||
|
if ( !ctx.expressionContext().scopes().contains( symbolScope ) )
|
||||||
|
ctx.expressionContext().appendScope( symbolScope );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.expressionContext().setFeature( fet );
|
ctx.expressionContext().setFeature( fet );
|
||||||
registerFeature( fet, ctx, obstacleGeometry.data() );
|
registerFeature( fet, ctx, obstacleGeometry.data() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ctx.expressionContext().lastScope() == symbolScope )
|
||||||
|
ctx.expressionContext().popScope();
|
||||||
|
|
||||||
if ( mRenderer )
|
if ( mRenderer )
|
||||||
mRenderer->stopRender( ctx );
|
mRenderer->stopRender( ctx );
|
||||||
|
|
||||||
@ -308,14 +322,11 @@ void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRende
|
|||||||
mLabels << label;
|
mLabels << label;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsGeometry* QgsVectorLayerLabelProvider::getPointObstacleGeometry( QgsFeature& fet, QgsRenderContext& context, QgsFeatureRendererV2* renderer )
|
QgsGeometry* QgsVectorLayerLabelProvider::getPointObstacleGeometry( QgsFeature& fet, QgsRenderContext& context, const QgsSymbolV2List& symbols )
|
||||||
{
|
{
|
||||||
if ( !fet.constGeometry() || fet.constGeometry()->isEmpty() || fet.constGeometry()->type() != QGis::Point || !renderer )
|
if ( !fet.constGeometry() || fet.constGeometry()->isEmpty() || fet.constGeometry()->type() != QGis::Point )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
//calculate bounds for symbols for feature
|
|
||||||
QgsSymbolV2List symbols = renderer->originalSymbolsForFeature( fet, context );
|
|
||||||
|
|
||||||
bool isMultiPoint = fet.constGeometry()->geometry()->nCoordinates() > 1;
|
bool isMultiPoint = fet.constGeometry()->geometry()->nCoordinates() > 1;
|
||||||
QgsAbstractGeometryV2* obstacleGeom = nullptr;
|
QgsAbstractGeometryV2* obstacleGeom = nullptr;
|
||||||
if ( isMultiPoint )
|
if ( isMultiPoint )
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
#define QGSVECTORLAYERLABELPROVIDER_H
|
#define QGSVECTORLAYERLABELPROVIDER_H
|
||||||
|
|
||||||
#include "qgslabelingenginev2.h"
|
#include "qgslabelingenginev2.h"
|
||||||
|
#include "qgsrendererv2.h"
|
||||||
|
|
||||||
class QgsAbstractFeatureSource;
|
class QgsAbstractFeatureSource;
|
||||||
class QgsFeatureRendererV2;
|
class QgsFeatureRendererV2;
|
||||||
|
class QgsSymbolV2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The QgsVectorLayerLabelProvider class implements a label provider
|
* @brief The QgsVectorLayerLabelProvider class implements a label provider
|
||||||
@ -80,10 +82,10 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
|
|||||||
* point, and ensures that labels will not overlap large or offset points.
|
* point, and ensures that labels will not overlap large or offset points.
|
||||||
* @param fet point feature
|
* @param fet point feature
|
||||||
* @param context render context
|
* @param context render context
|
||||||
* @param renderer renderer used for layer, required to determine symbols rendered for point feature
|
* @param symbols symbols rendered for point feature
|
||||||
* @note added in QGIS 2.14
|
* @note added in QGIS 2.14
|
||||||
*/
|
*/
|
||||||
static QgsGeometry* getPointObstacleGeometry( QgsFeature& fet, QgsRenderContext& context, QgsFeatureRendererV2* renderer );
|
static QgsGeometry* getPointObstacleGeometry( QgsFeature& fet, QgsRenderContext& context, const QgsSymbolV2List& symbols );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! initialization method - called from constructors
|
//! initialization method - called from constructors
|
||||||
|
@ -286,6 +286,9 @@ void QgsVectorLayerRenderer::setGeometryCachePointer( QgsGeometryCache* cache )
|
|||||||
|
|
||||||
void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
|
void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
|
||||||
{
|
{
|
||||||
|
QgsExpressionContextScope* symbolScope = QgsExpressionContextUtils::updateSymbolScope( nullptr );
|
||||||
|
mContext.expressionContext().appendScope( symbolScope );
|
||||||
|
|
||||||
QgsFeature fet;
|
QgsFeature fet;
|
||||||
while ( fit.nextFeature( fet ) )
|
while ( fit.nextFeature( fet ) )
|
||||||
{
|
{
|
||||||
@ -332,10 +335,18 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
|
|||||||
if ( mContext.labelingEngineV2() )
|
if ( mContext.labelingEngineV2() )
|
||||||
{
|
{
|
||||||
QScopedPointer<QgsGeometry> obstacleGeometry;
|
QScopedPointer<QgsGeometry> obstacleGeometry;
|
||||||
if ( fet.constGeometry()->type() == QGis::Point )
|
QgsSymbolV2List symbols = mRendererV2->originalSymbolsForFeature( fet, mContext );
|
||||||
|
|
||||||
|
if ( !symbols.isEmpty() && fet.constGeometry()->type() == QGis::Point )
|
||||||
{
|
{
|
||||||
obstacleGeometry.reset( QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, mContext, mRendererV2 ) );
|
obstacleGeometry.reset( QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, mContext, symbols ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !symbols.isEmpty() )
|
||||||
|
{
|
||||||
|
QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
|
||||||
|
}
|
||||||
|
|
||||||
if ( mLabelProvider )
|
if ( mLabelProvider )
|
||||||
{
|
{
|
||||||
mLabelProvider->registerFeature( fet, mContext, obstacleGeometry.data() );
|
mLabelProvider->registerFeature( fet, mContext, obstacleGeometry.data() );
|
||||||
@ -355,6 +366,8 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mContext.expressionContext().popScope();
|
||||||
|
|
||||||
stopRendererV2( nullptr );
|
stopRendererV2( nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,6 +384,9 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit )
|
|||||||
selRenderer->startRender( mContext, mFields );
|
selRenderer->startRender( mContext, mFields );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsExpressionContextScope* symbolScope = QgsExpressionContextUtils::updateSymbolScope( nullptr );
|
||||||
|
mContext.expressionContext().appendScope( symbolScope );
|
||||||
|
|
||||||
// 1. fetch features
|
// 1. fetch features
|
||||||
QgsFeature fet;
|
QgsFeature fet;
|
||||||
while ( fit.nextFeature( fet ) )
|
while ( fit.nextFeature( fet ) )
|
||||||
@ -382,6 +398,7 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit )
|
|||||||
{
|
{
|
||||||
qDebug( "rendering stop!" );
|
qDebug( "rendering stop!" );
|
||||||
stopRendererV2( selRenderer );
|
stopRendererV2( selRenderer );
|
||||||
|
mContext.expressionContext().popScope();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,10 +437,18 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit )
|
|||||||
if ( mContext.labelingEngineV2() )
|
if ( mContext.labelingEngineV2() )
|
||||||
{
|
{
|
||||||
QScopedPointer<QgsGeometry> obstacleGeometry;
|
QScopedPointer<QgsGeometry> obstacleGeometry;
|
||||||
if ( fet.constGeometry()->type() == QGis::Point )
|
QgsSymbolV2List symbols = mRendererV2->originalSymbolsForFeature( fet, mContext );
|
||||||
|
|
||||||
|
if ( !symbols.isEmpty() && fet.constGeometry()->type() == QGis::Point )
|
||||||
{
|
{
|
||||||
obstacleGeometry.reset( QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, mContext, mRendererV2 ) );
|
obstacleGeometry.reset( QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, mContext, symbols ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !symbols.isEmpty() )
|
||||||
|
{
|
||||||
|
QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
|
||||||
|
}
|
||||||
|
|
||||||
if ( mLabelProvider )
|
if ( mLabelProvider )
|
||||||
{
|
{
|
||||||
mLabelProvider->registerFeature( fet, mContext, obstacleGeometry.data() );
|
mLabelProvider->registerFeature( fet, mContext, obstacleGeometry.data() );
|
||||||
@ -435,6 +460,8 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mContext.expressionContext().popScope();
|
||||||
|
|
||||||
// find out the order
|
// find out the order
|
||||||
QgsSymbolV2LevelOrder levels;
|
QgsSymbolV2LevelOrder levels;
|
||||||
QgsSymbolV2List symbols = mRendererV2->symbols( mContext );
|
QgsSymbolV2List symbols = mRendererV2->symbols( mContext );
|
||||||
|
@ -48,6 +48,16 @@
|
|||||||
" )" \
|
" )" \
|
||||||
")"
|
")"
|
||||||
|
|
||||||
|
#define WALL_SHADING_EXPRESSION \
|
||||||
|
"set_color_part( " \
|
||||||
|
" @symbol_color," \
|
||||||
|
" 'value'," \
|
||||||
|
" 40 + 20 * abs( $pi - azimuth( " \
|
||||||
|
" point_n( geometry_n($geometry, @geometry_part_num) , 1 ), " \
|
||||||
|
" point_n( geometry_n($geometry, @geometry_part_num) , 2 )" \
|
||||||
|
" ) ) " \
|
||||||
|
")"
|
||||||
|
|
||||||
Qgs25DRenderer::Qgs25DRenderer()
|
Qgs25DRenderer::Qgs25DRenderer()
|
||||||
: QgsFeatureRendererV2( "25dRenderer" )
|
: QgsFeatureRendererV2( "25dRenderer" )
|
||||||
{
|
{
|
||||||
@ -67,6 +77,8 @@ Qgs25DRenderer::Qgs25DRenderer()
|
|||||||
roofProperties.insert( "symbolType", "Fill" );
|
roofProperties.insert( "symbolType", "Fill" );
|
||||||
QgsSymbolLayerV2* roof = QgsGeometryGeneratorSymbolLayerV2::create( roofProperties );
|
QgsSymbolLayerV2* roof = QgsGeometryGeneratorSymbolLayerV2::create( roofProperties );
|
||||||
|
|
||||||
|
floor->setLocked( true );
|
||||||
|
|
||||||
mSymbol->appendSymbolLayer( floor );
|
mSymbol->appendSymbolLayer( floor );
|
||||||
mSymbol->appendSymbolLayer( walls );
|
mSymbol->appendSymbolLayer( walls );
|
||||||
mSymbol->appendSymbolLayer( roof );
|
mSymbol->appendSymbolLayer( roof );
|
||||||
@ -81,12 +93,11 @@ Qgs25DRenderer::Qgs25DRenderer()
|
|||||||
setRoofColor( QColor( "#fdbf6f" ) );
|
setRoofColor( QColor( "#fdbf6f" ) );
|
||||||
setWallColor( QColor( "#777777" ) );
|
setWallColor( QColor( "#777777" ) );
|
||||||
|
|
||||||
|
wallLayer()->setDataDefinedProperty( "color", new QgsDataDefined( QString( WALL_SHADING_EXPRESSION ) ) );
|
||||||
|
|
||||||
setShadowSpread( 4 );
|
setShadowSpread( 4 );
|
||||||
setShadowColor( QColor( "#1111111" ) );
|
setShadowColor( QColor( "#1111111" ) );
|
||||||
|
|
||||||
setHeight( QString( "20" ) );
|
|
||||||
setAngle( 40 );
|
|
||||||
|
|
||||||
QgsFeatureRequest::OrderBy orderBy;
|
QgsFeatureRequest::OrderBy orderBy;
|
||||||
orderBy << QgsFeatureRequest::OrderByClause(
|
orderBy << QgsFeatureRequest::OrderByClause(
|
||||||
ORDER_BY_EXPRESSION,
|
ORDER_BY_EXPRESSION,
|
||||||
@ -100,8 +111,6 @@ QDomElement Qgs25DRenderer::save( QDomDocument& doc )
|
|||||||
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
|
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
|
||||||
|
|
||||||
rendererElem.setAttribute( "type", "25dRenderer" );
|
rendererElem.setAttribute( "type", "25dRenderer" );
|
||||||
rendererElem.setAttribute( "height", mHeight.expressionOrField() );
|
|
||||||
rendererElem.setAttribute( "angle", mAngle );
|
|
||||||
|
|
||||||
QDomElement symbolElem = QgsSymbolLayerV2Utils::saveSymbol( "symbol", mSymbol.data(), doc );
|
QDomElement symbolElem = QgsSymbolLayerV2Utils::saveSymbol( "symbol", mSymbol.data(), doc );
|
||||||
|
|
||||||
@ -112,19 +121,14 @@ QDomElement Qgs25DRenderer::save( QDomDocument& doc )
|
|||||||
|
|
||||||
QgsFeatureRendererV2* Qgs25DRenderer::create( QDomElement& element )
|
QgsFeatureRendererV2* Qgs25DRenderer::create( QDomElement& element )
|
||||||
{
|
{
|
||||||
|
Q_UNUSED( element )
|
||||||
Qgs25DRenderer* renderer = new Qgs25DRenderer();
|
Qgs25DRenderer* renderer = new Qgs25DRenderer();
|
||||||
renderer->mHeight.setField( element.attribute( "height" ) );
|
|
||||||
renderer->mAngle = element.attribute( "angle", "45" ).toInt();
|
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qgs25DRenderer::startRender( QgsRenderContext& context, const QgsFields& fields )
|
void Qgs25DRenderer::startRender( QgsRenderContext& context, const QgsFields& fields )
|
||||||
{
|
{
|
||||||
QgsExpressionContextScope* scope = new QgsExpressionContextScope( "2.5D Renderer" );
|
|
||||||
scope->setVariable( "qgis_25d_height", mHeight.expressionOrField() );
|
|
||||||
scope->setVariable( "qgis_25d_angle", mAngle );
|
|
||||||
context.expressionContext().appendScope( scope );
|
|
||||||
mSymbol->startRender( context, &fields );
|
mSymbol->startRender( context, &fields );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +146,6 @@ QgsFeatureRendererV2* Qgs25DRenderer::clone() const
|
|||||||
{
|
{
|
||||||
Qgs25DRenderer* c = new Qgs25DRenderer();
|
Qgs25DRenderer* c = new Qgs25DRenderer();
|
||||||
c->mSymbol.reset( mSymbol->clone() );
|
c->mSymbol.reset( mSymbol->clone() );
|
||||||
c->mAngle = mAngle;
|
|
||||||
c->mHeight = mHeight;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,26 +164,6 @@ QgsSymbolV2List Qgs25DRenderer::symbols( QgsRenderContext& context )
|
|||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsDataDefined Qgs25DRenderer::height() const
|
|
||||||
{
|
|
||||||
return mHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qgs25DRenderer::setHeight( const QgsDataDefined& height )
|
|
||||||
{
|
|
||||||
mHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Qgs25DRenderer::angle() const
|
|
||||||
{
|
|
||||||
return mAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qgs25DRenderer::setAngle( int angle )
|
|
||||||
{
|
|
||||||
mAngle = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsFillSymbolLayerV2* Qgs25DRenderer::roofLayer() const
|
QgsFillSymbolLayerV2* Qgs25DRenderer::roofLayer() const
|
||||||
{
|
{
|
||||||
return static_cast<QgsFillSymbolLayerV2*>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
|
return static_cast<QgsFillSymbolLayerV2*>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
|
||||||
@ -238,6 +220,16 @@ void Qgs25DRenderer::setWallColor( const QColor& wallColor )
|
|||||||
wallLayer()->setOutlineColor( wallColor );
|
wallLayer()->setOutlineColor( wallColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qgs25DRenderer::setWallShadingEnabled( bool enabled )
|
||||||
|
{
|
||||||
|
wallLayer()->getDataDefinedProperty( "color" )->setActive( enabled );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qgs25DRenderer::wallShadingEnabled()
|
||||||
|
{
|
||||||
|
return wallLayer()->getDataDefinedProperty( "color" )->isActive();
|
||||||
|
}
|
||||||
|
|
||||||
QColor Qgs25DRenderer::roofColor() const
|
QColor Qgs25DRenderer::roofColor() const
|
||||||
{
|
{
|
||||||
return roofLayer()->fillColor();
|
return roofLayer()->fillColor();
|
||||||
|
@ -43,24 +43,6 @@ class CORE_EXPORT Qgs25DRenderer : public QgsFeatureRendererV2
|
|||||||
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
|
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
|
||||||
virtual QgsSymbolV2List symbols( QgsRenderContext& context ) override;
|
virtual QgsSymbolV2List symbols( QgsRenderContext& context ) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the field or expression used to determine the height of extrusion
|
|
||||||
*/
|
|
||||||
QgsDataDefined height() const;
|
|
||||||
/**
|
|
||||||
* Set the field or expression used to determine the height of extrusion
|
|
||||||
*/
|
|
||||||
void setHeight( const QgsDataDefined& height );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the angle for the extrusion effect
|
|
||||||
*/
|
|
||||||
int angle() const;
|
|
||||||
/**
|
|
||||||
* Set the angle for the extrusion effect
|
|
||||||
*/
|
|
||||||
void setAngle( int angle );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the roof color
|
* Get the roof color
|
||||||
*/
|
*/
|
||||||
@ -81,6 +63,16 @@ class CORE_EXPORT Qgs25DRenderer : public QgsFeatureRendererV2
|
|||||||
*/
|
*/
|
||||||
void setWallColor( const QColor& wallColor );
|
void setWallColor( const QColor& wallColor );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set wall shading enabled
|
||||||
|
*/
|
||||||
|
void setWallShadingEnabled( bool enabled );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get wall shading enabled
|
||||||
|
*/
|
||||||
|
bool wallShadingEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shadow's color
|
* Get the shadow's color
|
||||||
*/
|
*/
|
||||||
@ -123,9 +115,6 @@ class CORE_EXPORT Qgs25DRenderer : public QgsFeatureRendererV2
|
|||||||
QgsOuterGlowEffect* glowEffect() const;
|
QgsOuterGlowEffect* glowEffect() const;
|
||||||
|
|
||||||
QScopedPointer<QgsSymbolV2> mSymbol;
|
QScopedPointer<QgsSymbolV2> mSymbol;
|
||||||
|
|
||||||
QgsDataDefined mHeight;
|
|
||||||
int mAngle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGS25DRENDERER_H
|
#endif // QGS25DRENDERER_H
|
||||||
|
@ -441,7 +441,7 @@ void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsFields* field
|
|||||||
|
|
||||||
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, nullptr, fields, mapUnitScale() );
|
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, nullptr, fields, mapUnitScale() );
|
||||||
|
|
||||||
QgsExpressionContextScope* scope = new QgsExpressionContextScope( QApplication::translate( "QgsSymbolV2", "Symbol Scope" ) );
|
QgsExpressionContextScope* scope = QgsExpressionContextUtils::updateSymbolScope( this );
|
||||||
|
|
||||||
mSymbolRenderContext->setExpressionContextScope( scope );
|
mSymbolRenderContext->setExpressionContextScope( scope );
|
||||||
|
|
||||||
@ -714,6 +714,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() );
|
context.expressionContext().appendScope( mSymbolRenderContext->expressionContextScope() );
|
||||||
|
QgsExpressionContextUtils::updateSymbolScope( this, mSymbolRenderContext->expressionContextScope() );
|
||||||
mSymbolRenderContext->expressionContextScope()->setVariable( "geometry_part_count", segmentizedGeometry->geometry()->partCount() );
|
mSymbolRenderContext->expressionContextScope()->setVariable( "geometry_part_count", segmentizedGeometry->geometry()->partCount() );
|
||||||
mSymbolRenderContext->expressionContextScope()->setVariable( "geometry_part_num", 1 );
|
mSymbolRenderContext->expressionContextScope()->setVariable( "geometry_part_num", 1 );
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "qgs25drendererwidget.h"
|
#include "qgs25drendererwidget.h"
|
||||||
|
|
||||||
|
#include "qgsmaplayerstylemanager.h"
|
||||||
|
|
||||||
Qgs25DRendererWidget::Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
Qgs25DRendererWidget::Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
||||||
: QgsRendererV2Widget( layer, style )
|
: QgsRendererV2Widget( layer, style )
|
||||||
, mRenderer( nullptr )
|
, mRenderer( nullptr )
|
||||||
@ -42,13 +44,19 @@ Qgs25DRendererWidget::Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* s
|
|||||||
}
|
}
|
||||||
|
|
||||||
mHeightWidget->setLayer( layer );
|
mHeightWidget->setLayer( layer );
|
||||||
mHeightWidget->setField( mRenderer->height().expressionOrField() );
|
|
||||||
mAngleWidget->setValue( mRenderer->angle() );
|
QgsExpressionContextScope* scope = QgsExpressionContextUtils::layerScope( mLayer );
|
||||||
|
QVariant height = scope->variable( "qgis_25d_height" );
|
||||||
|
QVariant angle = scope->variable( "qgis_25d_angle" );
|
||||||
|
|
||||||
|
mHeightWidget->setField( height.isNull() ? "10" : height.toString() );
|
||||||
|
mAngleWidget->setValue( angle.isNull() ? 70 : angle.toDouble() );
|
||||||
mWallColorButton->setColor( mRenderer->wallColor() );
|
mWallColorButton->setColor( mRenderer->wallColor() );
|
||||||
mRoofColorButton->setColor( mRenderer->roofColor() );
|
mRoofColorButton->setColor( mRenderer->roofColor() );
|
||||||
mShadowColorButton->setColor( mRenderer->shadowColor() );
|
mShadowColorButton->setColor( mRenderer->shadowColor() );
|
||||||
mShadowEnabledWidget->setEnabled( mRenderer->shadowEnabled() );
|
mShadowEnabledWidget->setEnabled( mRenderer->shadowEnabled() );
|
||||||
mShadowSizeWidget->setValue( mRenderer->shadowSpread() );
|
mShadowSizeWidget->setValue( mRenderer->shadowSpread() );
|
||||||
|
mWallExpositionShading->setChecked( mRenderer->wallShadingEnabled() );
|
||||||
|
|
||||||
connect( mAngleWidget, SIGNAL( valueChanged( int ) ), this, SLOT( updateRenderer() ) );
|
connect( mAngleWidget, SIGNAL( valueChanged( int ) ), this, SLOT( updateRenderer() ) );
|
||||||
connect( mHeightWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( updateRenderer() ) );
|
connect( mHeightWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( updateRenderer() ) );
|
||||||
@ -57,6 +65,7 @@ Qgs25DRendererWidget::Qgs25DRendererWidget( QgsVectorLayer* layer, QgsStyleV2* s
|
|||||||
connect( mShadowColorButton, SIGNAL( colorChanged( QColor ) ), this, SLOT( updateRenderer() ) );
|
connect( mShadowColorButton, SIGNAL( colorChanged( QColor ) ), this, SLOT( updateRenderer() ) );
|
||||||
connect( mShadowEnabledWidget, SIGNAL( toggled( bool ) ), this, SLOT( updateRenderer() ) );
|
connect( mShadowEnabledWidget, SIGNAL( toggled( bool ) ), this, SLOT( updateRenderer() ) );
|
||||||
connect( mShadowSizeWidget, SIGNAL( valueChanged( double ) ), this, SLOT( updateRenderer() ) );
|
connect( mShadowSizeWidget, SIGNAL( valueChanged( double ) ), this, SLOT( updateRenderer() ) );
|
||||||
|
connect( mWallExpositionShading, SIGNAL( toggled( bool ) ), this, SLOT( updateRenderer() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsFeatureRendererV2* Qgs25DRendererWidget::renderer()
|
QgsFeatureRendererV2* Qgs25DRendererWidget::renderer()
|
||||||
@ -66,13 +75,20 @@ QgsFeatureRendererV2* Qgs25DRendererWidget::renderer()
|
|||||||
|
|
||||||
void Qgs25DRendererWidget::updateRenderer()
|
void Qgs25DRendererWidget::updateRenderer()
|
||||||
{
|
{
|
||||||
mRenderer->setHeight( QgsDataDefined( mHeightWidget->currentText() ) );
|
|
||||||
mRenderer->setAngle( mAngleWidget->value() );
|
|
||||||
mRenderer->setRoofColor( mRoofColorButton->color() );
|
mRenderer->setRoofColor( mRoofColorButton->color() );
|
||||||
mRenderer->setWallColor( mWallColorButton->color() );
|
mRenderer->setWallColor( mWallColorButton->color() );
|
||||||
mRenderer->setShadowColor( mShadowColorButton->color() );
|
mRenderer->setShadowColor( mShadowColorButton->color() );
|
||||||
mRenderer->setShadowEnabled( mShadowEnabledWidget->isChecked() );
|
mRenderer->setShadowEnabled( mShadowEnabledWidget->isChecked() );
|
||||||
mRenderer->setShadowSpread( mShadowSizeWidget->value() );
|
mRenderer->setShadowSpread( mShadowSizeWidget->value() );
|
||||||
|
mRenderer->setWallShadingEnabled( mWallExpositionShading->isChecked() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qgs25DRendererWidget::apply()
|
||||||
|
{
|
||||||
|
QgsExpressionContextUtils::setLayerVariable( mLayer, "qgis_25d_height", mHeightWidget->currentText() );
|
||||||
|
QgsExpressionContextUtils::setLayerVariable( mLayer, "qgis_25d_angle", mAngleWidget->value() );
|
||||||
|
|
||||||
|
emit layerVariablesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRendererV2Widget* Qgs25DRendererWidget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
QgsRendererV2Widget* Qgs25DRendererWidget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
||||||
|
@ -45,6 +45,8 @@ class GUI_EXPORT Qgs25DRendererWidget : public QgsRendererV2Widget, Ui::Qgs25DRe
|
|||||||
void updateRenderer();
|
void updateRenderer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void apply() override;
|
||||||
|
|
||||||
Qgs25DRenderer* mRenderer;
|
Qgs25DRenderer* mRenderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,6 +223,7 @@ void QgsRendererV2PropertiesDialog::rendererChanged()
|
|||||||
if ( mMapCanvas )
|
if ( mMapCanvas )
|
||||||
mActiveWidget->setMapCanvas( mMapCanvas );
|
mActiveWidget->setMapCanvas( mMapCanvas );
|
||||||
changeOrderBy( mActiveWidget->renderer()->orderBy() );
|
changeOrderBy( mActiveWidget->renderer()->orderBy() );
|
||||||
|
connect( mActiveWidget, SIGNAL( layerVariablesChanged() ), this, SIGNAL( layerVariablesChanged() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -239,6 +240,8 @@ void QgsRendererV2PropertiesDialog::apply()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mActiveWidget->applyChanges();
|
||||||
|
|
||||||
QgsFeatureRendererV2* renderer = mActiveWidget->renderer();
|
QgsFeatureRendererV2* renderer = mActiveWidget->renderer();
|
||||||
if ( renderer )
|
if ( renderer )
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,14 @@ class GUI_EXPORT QgsRendererV2PropertiesDialog : public QDialog, private Ui::Qgs
|
|||||||
*/
|
*/
|
||||||
void setMapCanvas( QgsMapCanvas* canvas );
|
void setMapCanvas( QgsMapCanvas* canvas );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* Emitted when expression context variables on the associated
|
||||||
|
* vector layers have been changed. Will request the parent dialog
|
||||||
|
* to re-synchronize with the variables.
|
||||||
|
*/
|
||||||
|
void layerVariablesChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
//! called when user changes renderer type
|
//! called when user changes renderer type
|
||||||
void rendererChanged();
|
void rendererChanged();
|
||||||
|
@ -261,11 +261,16 @@ void QgsRendererV2Widget::setMapCanvas( QgsMapCanvas *canvas )
|
|||||||
mMapCanvas = canvas;
|
mMapCanvas = canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QgsMapCanvas*QgsRendererV2Widget::mapCanvas() const
|
const QgsMapCanvas* QgsRendererV2Widget::mapCanvas() const
|
||||||
{
|
{
|
||||||
return mMapCanvas;
|
return mMapCanvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsRendererV2Widget::applyChanges()
|
||||||
|
{
|
||||||
|
apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
@ -580,3 +585,8 @@ void QgsDataDefinedWidthDialog::setDataDefined( QgsSymbolV2 *symbol, const QgsDa
|
|||||||
{
|
{
|
||||||
static_cast<QgsLineSymbolV2*>( symbol )->setDataDefinedWidth( dd );
|
static_cast<QgsLineSymbolV2*>( symbol )->setDataDefinedWidth( dd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsRendererV2Widget::apply()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -69,6 +69,19 @@ class GUI_EXPORT QgsRendererV2Widget : public QWidget
|
|||||||
*/
|
*/
|
||||||
const QgsVectorLayer* vectorLayer() const { return mLayer; }
|
const QgsVectorLayer* vectorLayer() const { return mLayer; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should be called whenever the renderer is actually set on the layer.
|
||||||
|
*/
|
||||||
|
void applyChanges();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* Emitted when expression context variables on the associated
|
||||||
|
* vector layers have been changed. Will request the parent dialog
|
||||||
|
* to re-synchronize with the variables.
|
||||||
|
*/
|
||||||
|
void layerVariablesChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QgsVectorLayer* mLayer;
|
QgsVectorLayer* mLayer;
|
||||||
QgsStyleV2* mStyle;
|
QgsStyleV2* mStyle;
|
||||||
@ -100,6 +113,13 @@ class GUI_EXPORT QgsRendererV2Widget : public QWidget
|
|||||||
virtual void copy() {}
|
virtual void copy() {}
|
||||||
virtual void paste() {}
|
virtual void paste() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* This will be called whenever the renderer is set on a layer.
|
||||||
|
* This can be overwritten in subclasses.
|
||||||
|
*/
|
||||||
|
virtual void apply();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>602</width>
|
<width>657</width>
|
||||||
<height>395</height>
|
<height>587</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -62,7 +62,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="2">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="mShadowEnabledWidget">
|
<widget class="QGroupBox" name="mShadowEnabledWidget">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Shadow</string>
|
<string>Shadow</string>
|
||||||
@ -98,6 +98,13 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="mWallExpositionShading">
|
||||||
|
<property name="text">
|
||||||
|
<string>Shade walls based on exposition</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -114,6 +121,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-weight:600;">Advanced Styling</span><br/>This page helps to configure the 2.5D effect as easily as possible with some basic parameters.</p><p>Once you have finished the basic styling, you can can convert this to another renderer (single, categorized, graduated) and fine-tune the appearance to your liking.</p><p><span style=" font-weight:600;">Overlay problems</span></p><p>Features are rendered based on their distance to the camera. It is sometimes possible that parts of a feature are in front of another feature by mistake. This happens if any part of the overlapped feature is closer to the camera than the overlapping feature.</p><p>In such cases you can avoid rendering problems by cutting the feature in front into smaller pieces.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -101,5 +101,21 @@ class TestQgsSymbolExpressionVariables(TestCase):
|
|||||||
|
|
||||||
self.assertTrue(result)
|
self.assertTrue(result)
|
||||||
|
|
||||||
|
def testSymbolColor(self):
|
||||||
|
# Create rulebased style
|
||||||
|
sym1 = QgsFillSymbolV2.createSimple({'color': '#ff0000'})
|
||||||
|
|
||||||
|
renderer = QgsSingleSymbolRendererV2(sym1)
|
||||||
|
renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty('color', 'set_color_part( @symbol_color, \'value\', "Value" * 4)')
|
||||||
|
self.layer.setRendererV2(renderer)
|
||||||
|
|
||||||
|
# Setup rendering check
|
||||||
|
renderchecker = QgsMultiRenderChecker()
|
||||||
|
renderchecker.setMapSettings(self.mapsettings)
|
||||||
|
renderchecker.setControlName('expected_symbol_color_variable')
|
||||||
|
result = renderchecker.runTest('symbol_color_variable')
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
BIN
tests/testdata/control_images/expected_symbol_color_variable/expected_symbol_color_variable.png
vendored
Normal file
BIN
tests/testdata/control_images/expected_symbol_color_variable/expected_symbol_color_variable.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 MiB |
Loading…
x
Reference in New Issue
Block a user