Skip to content

Commit

Permalink
Export map level scale based dependencies in most vector symbology
Browse files Browse the repository at this point in the history
  • Loading branch information
aaime authored and rldhont committed Oct 1, 2016
1 parent 760036a commit 5297df7
Show file tree
Hide file tree
Showing 25 changed files with 2,910 additions and 67 deletions.
11 changes: 9 additions & 2 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -733,7 +733,15 @@ class QgsVectorLayer : QgsMapLayer
*/
bool writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const;

bool writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const;
/** Write just the style information for the layer into the document
* @param node the node that will have the style element added to it.
* @param doc the document that will have the QDomNode added.
* @param errorMessage reference to string that will be updated with any error messages
* @return true in case of success.
*/
bool writeStyle( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const;

bool writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage, QgsStringMap& props ) const;
bool readSld( const QDomNode& node, QString& errorMessage );

/**
Expand Down Expand Up @@ -1820,4 +1828,3 @@ class QgsVectorLayer : QgsMapLayer


};

31 changes: 31 additions & 0 deletions python/core/symbology-ng/qgssymbollayerv2utils.sip
Expand Up @@ -204,6 +204,7 @@ class QgsSymbolLayerV2Utils
static void createGeometryElement( QDomDocument &doc, QDomElement &element, const QString& geomFunc );
static bool geometryFromSldElement( QDomElement &element, QString &geomFunc );

static bool createExpressionElement( QDomDocument &doc, QDomElement &element, const QString& function );
static bool createFunctionElement( QDomDocument &doc, QDomElement &element, const QString& function );
static bool functionFromSldElement( QDomElement &element, QString &function );

Expand Down Expand Up @@ -412,4 +413,34 @@ class QgsSymbolLayerV2Utils
*/
static QList<double> prettyBreaks( double minimum, double maximum, int classes );

/** Rescales the given size based on the uomScale found in the props, if any is found, otherwise
* returns the value un-modified
* @note added in 3.0
*/
static double rescaleUom( double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap& props );

/** Rescales the given point based on the uomScale found in the props, if any is found, otherwise
* returns a copy of the original point
* @note added in 3.0
*/
static QPointF rescaleUom( const QPointF& point, QgsUnitTypes::RenderUnit unit, const QgsStringMap& props ) /PyName=rescalePointUom/;

/** Rescales the given array based on the uomScale found in the props, if any is found, otherwise
* returns a copy of the original point
* @note added in 3.0
*/
static QVector<qreal> rescaleUom( const QVector<qreal>& array, QgsUnitTypes::RenderUnit unit, const QgsStringMap& props ) /PyName=rescaleArrayUom/;

/**
* Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into the SE Rule element
* @note added in 3.0
*/
static void applyScaleDependency( QDomDocument& doc, QDomElement& ruleElem, QgsStringMap& props );

/**
* Merges the local scale limits, if any, with the ones already in the map, if any
* @note added in 3.0
*/
static void mergeScaleDependencies( int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap& props );

};
8 changes: 7 additions & 1 deletion src/core/qgsmaplayer.cpp
Expand Up @@ -1471,7 +1471,13 @@ void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg )
return;
}

if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg ) )
QgsStringMap props;
if ( hasScaleBasedVisibility() )
{
props[ "scaleMinDenom" ] = QString::number( mMinScale );
props[ "scaleMaxDenom" ] = QString::number( mMaxScale );
}
if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg, props ) )
{
errorMsg = tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
return;
Expand Down
14 changes: 12 additions & 2 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2107,8 +2107,12 @@ bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
return true;
}


bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
{
return writeSld( node, doc, errorMessage, QgsStringMap() );
}

bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage, QgsStringMap props ) const
{
Q_UNUSED( errorMessage );

Expand All @@ -2117,9 +2121,15 @@ bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& error
nameNode.appendChild( doc.createTextNode( name() ) );
node.appendChild( nameNode );

QgsStringMap localProps = QgsStringMap( props );
if ( hasScaleBasedVisibility() )
{
QgsSymbolLayerUtils::mergeScaleDependencies( minimumScale(), maximumScale(), localProps );
}

if ( hasGeometryType() )
{
node.appendChild( mRendererV2->writeSld( doc, name() ) );
node.appendChild( mRendererV2->writeSld( doc, name(), localProps ) );
}
return true;
}
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -841,6 +841,17 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
bool writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const override;

bool writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const;

/**
* Writes the symbology of the layer into the document provided in SLD 1.1 format
* @param node the node that will have the style element added to it.
* @param doc the document that will have the QDomNode added.
* @param errorMessage reference to string that will be updated with any error messages
* @param props a open ended set of properties that can drive/inform the SLD encoding
* @return true in case of success
*/
bool writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage, QgsStringMap props = QgsStringMap() ) const;

bool readSld( const QDomNode& node, QString& errorMessage ) override;

/**
Expand Down
6 changes: 4 additions & 2 deletions src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
Expand Up @@ -141,6 +141,9 @@ void QgsRendererCategoryV2::toSld( QDomDocument &doc, QDomElement &element, QgsS
mValue.toString().replace( '\'', "''" ) );
QgsSymbolLayerV2Utils::createFunctionElement( doc, ruleElem, filterFunc );

// add the mix/max scale denoms if we got any from the callers
QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElem, props );

mSymbol->toSld( doc, ruleElem, props );
}

Expand Down Expand Up @@ -528,9 +531,8 @@ QgsCategorizedSymbolRendererV2* QgsCategorizedSymbolRendererV2::clone() const
return r;
}

void QgsCategorizedSymbolRendererV2::toSld( QDomDocument &doc, QDomElement &element ) const
void QgsCategorizedSymbolRendererV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
{
QgsStringMap props;
props[ "attribute" ] = mAttrName;
if ( mRotation.data() )
props[ "angle" ] = mRotation->expression();
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
Expand Up @@ -94,7 +94,7 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsCategorizedSymbolRendererV2* clone() const override;

virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;

//! returns bitwise OR-ed capabilities of the renderer
virtual int capabilities() override { return SymbolLevels | RotationField | Filter; }
Expand Down
3 changes: 1 addition & 2 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Expand Up @@ -559,9 +559,8 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::clone() const
return r;
}

void QgsGraduatedSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &element ) const
void QgsGraduatedSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const
{
QgsStringMap props;
props[ "attribute" ] = mAttrName;
props[ "method" ] = graduatedMethodStr( mGraduatedMethod );
if ( mRotation.data() )
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
Expand Up @@ -143,7 +143,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsGraduatedSymbolRendererV2* clone() const override;

virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;

//! returns bitwise OR-ed capabilities of the renderer
virtual int capabilities() override { return SymbolLevels | RotationField | Filter; }
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgslinesymbollayerv2.cpp
Expand Up @@ -1446,7 +1446,7 @@ void QgsMarkerLineSymbolLayerV2::toSld( QDomDocument &doc, QDomElement &element,
if ( !gap.isEmpty() )
{
QDomElement gapElem = doc.createElement( "se:Gap" );
QgsSymbolLayerV2Utils::createFunctionElement( doc, gapElem, gap );
QgsSymbolLayerV2Utils::createExpressionElement( doc, gapElem, gap );
graphicStrokeElem.appendChild( gapElem );
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgspointdisplacementrenderer.cpp
Expand Up @@ -86,9 +86,9 @@ QgsPointDisplacementRenderer* QgsPointDisplacementRenderer::clone() const
return r;
}

void QgsPointDisplacementRenderer::toSld( QDomDocument& doc, QDomElement &element ) const
void QgsPointDisplacementRenderer::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const
{
mRenderer->toSld( doc, element );
mRenderer->toSld( doc, element, props );
}


Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgspointdisplacementrenderer.h
Expand Up @@ -45,7 +45,7 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2

QgsPointDisplacementRenderer* clone() const override;

virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;

/** Reimplemented from QgsFeatureRendererV2*/
bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false ) override;
Expand Down
7 changes: 4 additions & 3 deletions src/core/symbology-ng/qgsrendererv2.cpp
Expand Up @@ -335,10 +335,11 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::loadSld( const QDomNode &node, QGis:

QDomElement QgsFeatureRendererV2::writeSld( QDomDocument& doc, const QgsVectorLayer &layer ) const
{
return writeSld( doc, layer.name() );
QgsStringMap props;
return writeSld( doc, layer.name(), props );
}

QDomElement QgsFeatureRendererV2::writeSld( QDomDocument& doc, const QString& styleName ) const
QDomElement QgsFeatureRendererV2::writeSld( QDomDocument& doc, const QString& styleName, QgsStringMap props ) const
{
QDomElement userStyleElem = doc.createElement( "UserStyle" );

Expand All @@ -347,7 +348,7 @@ QDomElement QgsFeatureRendererV2::writeSld( QDomDocument& doc, const QString& st
userStyleElem.appendChild( nameElem );

QDomElement featureTypeStyleElem = doc.createElement( "se:FeatureTypeStyle" );
toSld( doc, featureTypeStyleElem );
toSld( doc, featureTypeStyleElem, props );
userStyleElem.appendChild( featureTypeStyleElem );

return userStyleElem;
Expand Down
9 changes: 6 additions & 3 deletions src/core/symbology-ng/qgsrendererv2.h
Expand Up @@ -224,7 +224,7 @@ class CORE_EXPORT QgsFeatureRendererV2
Q_DECL_DEPRECATED virtual QDomElement writeSld( QDomDocument& doc, const QgsVectorLayer &layer ) const;
//! create the SLD UserStyle element following the SLD v1.1 specs with the given name
//! @note added in 2.8
virtual QDomElement writeSld( QDomDocument& doc, const QString& styleName ) const;
virtual QDomElement writeSld( QDomDocument& doc, const QString& styleName, QgsStringMap props = QgsStringMap() ) const;

/** Create a new renderer according to the information contained in
* the UserStyle element of a SLD style document
Expand All @@ -239,8 +239,11 @@ class CORE_EXPORT QgsFeatureRendererV2
static QgsFeatureRendererV2* loadSld( const QDomNode &node, QGis::GeometryType geomType, QString &errorMessage );

//! used from subclasses to create SLD Rule elements following SLD v1.1 specs
virtual void toSld( QDomDocument& doc, QDomElement &element ) const
{ element.appendChild( doc.createComment( QString( "FeatureRendererV2 %1 not implemented yet" ).arg( type() ) ) ); }
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const
{
element.appendChild( doc.createComment( QString( "FeatureRendererV2 %1 not implemented yet" ).arg( type() ) ) );
( void ) props; // warning avoidance
}

//! return a list of symbology items for the legend
virtual QgsLegendSymbologyList legendSymbologyItems( QSize iconSize );
Expand Down
40 changes: 7 additions & 33 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Expand Up @@ -334,25 +334,7 @@ void QgsRuleBasedRendererV2::Rule::toSld( QDomDocument& doc, QDomElement &elemen
props[ "filter" ] += mFilterExp;
}

if ( mScaleMinDenom != 0 )
{
bool ok;
int parentScaleMinDenom = props.value( "scaleMinDenom", "0" ).toInt( &ok );
if ( !ok || parentScaleMinDenom <= 0 )
props[ "scaleMinDenom" ] = QString::number( mScaleMinDenom );
else
props[ "scaleMinDenom" ] = QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
}

if ( mScaleMaxDenom != 0 )
{
bool ok;
int parentScaleMaxDenom = props.value( "scaleMaxDenom", "0" ).toInt( &ok );
if ( !ok || parentScaleMaxDenom <= 0 )
props[ "scaleMaxDenom" ] = QString::number( mScaleMaxDenom );
else
props[ "scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
}
QgsSymbolLayerUtils::mergeScaleDependencies( mScaleMinDenom, mScaleMaxDenom, props );

if ( mSymbol )
{
Expand Down Expand Up @@ -388,19 +370,7 @@ void QgsRuleBasedRendererV2::Rule::toSld( QDomDocument& doc, QDomElement &elemen
QgsSymbolLayerV2Utils::createFunctionElement( doc, ruleElem, props.value( "filter", "" ) );
}

if ( !props.value( "scaleMinDenom", "" ).isEmpty() )
{
QDomElement scaleMinDenomElem = doc.createElement( "se:MinScaleDenominator" );
scaleMinDenomElem.appendChild( doc.createTextNode( props.value( "scaleMinDenom", "" ) ) );
ruleElem.appendChild( scaleMinDenomElem );
}

if ( !props.value( "scaleMaxDenom", "" ).isEmpty() )
{
QDomElement scaleMaxDenomElem = doc.createElement( "se:MaxScaleDenominator" );
scaleMaxDenomElem.appendChild( doc.createTextNode( props.value( "scaleMaxDenom", "" ) ) );
ruleElem.appendChild( scaleMaxDenomElem );
}
QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElem, props );

mSymbol->toSld( doc, ruleElem, props );
}
Expand Down Expand Up @@ -957,9 +927,13 @@ QgsRuleBasedRendererV2* QgsRuleBasedRendererV2::clone() const
return r;
}

<<<<<<< HEAD:src/core/symbology-ng/qgsrulebasedrendererv2.cpp
void QgsRuleBasedRendererV2::toSld( QDomDocument& doc, QDomElement &element ) const
=======
void QgsRuleBasedRenderer::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const
>>>>>>> a25b025... Export map level scale based dependencies in most vector symbology:src/core/symbology-ng/qgsrulebasedrenderer.cpp
{
mRootRule->toSld( doc, element, QgsStringMap() );
mRootRule->toSld( doc, element, props );
}

// TODO: ideally this function should be removed in favor of legendSymbol(ogy)Items
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsrulebasedrendererv2.h
Expand Up @@ -424,7 +424,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2

virtual QgsRuleBasedRendererV2* clone() const override;

virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;

static QgsFeatureRendererV2* createFromSld( QDomElement& element, QGis::GeometryType geomType );

Expand Down
6 changes: 3 additions & 3 deletions src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
Expand Up @@ -205,10 +205,8 @@ QgsSingleSymbolRendererV2* QgsSingleSymbolRendererV2::clone() const
return r;
}

void QgsSingleSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &element ) const
void QgsSingleSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const
{
QgsStringMap props;
QString errorMsg;
if ( mRotation.data() )
props[ "angle" ] = mRotation->expression();
if ( mSizeScale.data() )
Expand All @@ -221,6 +219,8 @@ void QgsSingleSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &element )
nameElem.appendChild( doc.createTextNode( "Single symbol" ) );
ruleElem.appendChild( nameElem );

QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElem, props );

if ( mSymbol.data() ) mSymbol->toSld( doc, ruleElem, props );
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssinglesymbolrendererv2.h
Expand Up @@ -58,7 +58,7 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsSingleSymbolRendererV2* clone() const override;

virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;
virtual void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props = QgsStringMap() ) const override;
static QgsFeatureRendererV2* createFromSld( QDomElement& element, QGis::GeometryType geomType );

//! returns bitwise OR-ed capabilities of the renderer
Expand Down

0 comments on commit 5297df7

Please sign in to comment.