Skip to content

Commit ef001fd

Browse files
committed
read labeling from SLD
1 parent 0536cfa commit ef001fd

File tree

4 files changed

+285
-0
lines changed

4 files changed

+285
-0
lines changed

src/core/qgsogcutils.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "qgsexpression.h"
44
#include "qgsgeometry.h"
55

6+
#include <QColor>
67
#include <QStringList>
78
#include <QTextStream>
89

@@ -1411,6 +1412,44 @@ QDomElement QgsOgcUtils::createGMLPositions( const QgsPolyline &points, QDomDocu
14111412

14121413
// -----------------------------------------
14131414

1415+
QColor QgsOgcUtils::colorFromOgcFill( const QDomElement& fillElement )
1416+
{
1417+
if ( fillElement.isNull() || !fillElement.hasChildNodes() )
1418+
{
1419+
return QColor();
1420+
}
1421+
1422+
QString cssName;
1423+
QString elemText;
1424+
QColor color;
1425+
QDomElement cssElem = fillElement.firstChildElement( "CssParameter" );
1426+
while ( !cssElem.isNull() )
1427+
{
1428+
cssName = cssElem.attribute( "name", "not_found" );
1429+
if ( cssName != "not_found" )
1430+
{
1431+
elemText = cssElem.text();
1432+
if ( cssName == "fill" )
1433+
{
1434+
color.setNamedColor( elemText );
1435+
}
1436+
else if ( cssName == "fill-opacity" )
1437+
{
1438+
bool ok;
1439+
double opacity = elemText.toDouble( &ok );
1440+
if ( ok )
1441+
{
1442+
color.setAlphaF( opacity );
1443+
}
1444+
}
1445+
}
1446+
1447+
cssElem = cssElem.nextSiblingElement( "CssParameter" );
1448+
}
1449+
1450+
return color;
1451+
}
1452+
14141453

14151454
QgsExpression* QgsOgcUtils::expressionFromOgcFilter( const QDomElement& element )
14161455
{

src/core/qgsogcutils.h

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef QGSOGCUTILS_H
22
#define QGSOGCUTILS_H
33

4+
class QColor;
45
class QDomNode;
56
class QDomElement;
67
class QDomDocument;
@@ -68,6 +69,9 @@ class CORE_EXPORT QgsOgcUtils
6869
static QDomElement rectangleToGMLEnvelope( QgsRectangle* env, QDomDocument& doc );
6970

7071

72+
/** Parse XML with OGC fill into QColor */
73+
static QColor colorFromOgcFill( const QDomElement& fillElement );
74+
7175
/** Parse XML with OGC filter into QGIS expression */
7276
static QgsExpression* expressionFromOgcFilter( const QDomElement& element );
7377

src/core/qgsvectorlayer.cpp

+239
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "qgslogger.h"
5050
#include "qgsmessagelog.h"
5151
#include "qgsmaptopixel.h"
52+
#include "qgsogcutils.h"
5253
#include "qgspoint.h"
5354
#include "qgsproviderregistry.h"
5455
#include "qgsrectangle.h"
@@ -2504,6 +2505,9 @@ bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
25042505
return false;
25052506

25062507
setRendererV2( r );
2508+
2509+
// labeling
2510+
readSldLabeling( node );
25072511
}
25082512
return true;
25092513
}
@@ -3691,6 +3695,241 @@ void QgsVectorLayer::prepareLabelingAndDiagrams( QgsRenderContext& rendererConte
36913695
}
36923696
}
36933697

3698+
void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3699+
{
3700+
QDomElement element = node.toElement();
3701+
if ( element.isNull() )
3702+
return;
3703+
3704+
QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3705+
if ( userStyleElem.isNull() )
3706+
{
3707+
QgsDebugMsg( "Info: UserStyle element not found.");
3708+
return;
3709+
}
3710+
3711+
QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3712+
if ( featureTypeStyleElem.isNull() )
3713+
{
3714+
QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3715+
return;
3716+
}
3717+
3718+
// use last rule
3719+
QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3720+
if ( ruleElem.isNull() )
3721+
{
3722+
QgsDebugMsg( "Info: Rule element not found." );
3723+
return;
3724+
}
3725+
3726+
// use last text symbolizer
3727+
QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3728+
if ( textSymbolizerElem.isNull() )
3729+
{
3730+
QgsDebugMsg( "Info: TextSymbolizer element not found." );
3731+
return;
3732+
}
3733+
3734+
// Label
3735+
setCustomProperty( "labeling/enabled", false );
3736+
QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3737+
if ( !labelElem.isNull() )
3738+
{
3739+
QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3740+
if ( !propertyNameElem.isNull() )
3741+
{
3742+
// enable labeling
3743+
setCustomProperty( "labeling", "pal" );
3744+
setCustomProperty( "labeling/enabled", true );
3745+
3746+
// set labeling defaults
3747+
setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3748+
setCustomProperty( "labeling/fontItalic", false );
3749+
setCustomProperty( "labeling/fontSize", 10 );
3750+
setCustomProperty( "labeling/fontSizeInMapUnits", false );
3751+
setCustomProperty( "labeling/fontBold", false );
3752+
setCustomProperty( "labeling/fontUnderline", false );
3753+
setCustomProperty( "labeling/textColorR", 0 );
3754+
setCustomProperty( "labeling/textColorG", 0 );
3755+
setCustomProperty( "labeling/textColorB", 0 );
3756+
setCustomProperty( "labeling/textTransp", 0 );
3757+
setCustomProperty( "labeling/bufferDraw", false );
3758+
setCustomProperty( "labeling/bufferSize", 1 );
3759+
setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3760+
setCustomProperty( "labeling/bufferColorR", 255 );
3761+
setCustomProperty( "labeling/bufferColorG", 255 );
3762+
setCustomProperty( "labeling/bufferColorB", 255 );
3763+
setCustomProperty( "labeling/bufferTransp", 0 );
3764+
setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3765+
setCustomProperty( "labeling/xOffset", 0 );
3766+
setCustomProperty( "labeling/yOffset", 0 );
3767+
setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3768+
setCustomProperty( "labeling/angleOffset", 0 );
3769+
3770+
// label attribute
3771+
QString labelAttribute = propertyNameElem.text();
3772+
setCustomProperty( "labeling/fieldName", labelAttribute );
3773+
setCustomProperty( "labeling/isExpression", false );
3774+
3775+
int fieldIndex = fieldNameIndex( labelAttribute );
3776+
if ( fieldIndex == -1 )
3777+
{
3778+
// label attribute is not in columns, check if it is an expression
3779+
QgsExpression exp( labelAttribute );
3780+
if ( !exp.hasEvalError() )
3781+
{
3782+
setCustomProperty( "labeling/isExpression", true );
3783+
}
3784+
else
3785+
{
3786+
QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3787+
}
3788+
}
3789+
}
3790+
else
3791+
{
3792+
QgsDebugMsg( "Info: PropertyName element not found." );
3793+
return;
3794+
}
3795+
}
3796+
else
3797+
{
3798+
QgsDebugMsg( "Info: Label element not found." );
3799+
return;
3800+
}
3801+
3802+
// Font
3803+
QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3804+
if ( !fontElem.isNull() )
3805+
{
3806+
QString cssName;
3807+
QString elemText;
3808+
QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3809+
while ( !cssElem.isNull() )
3810+
{
3811+
cssName = cssElem.attribute( "name", "not_found" );
3812+
if ( cssName != "not_found" )
3813+
{
3814+
elemText = cssElem.text();
3815+
if ( cssName == "font-family" )
3816+
{
3817+
setCustomProperty( "labeling/fontFamily", elemText );
3818+
}
3819+
else if ( cssName == "font-style" )
3820+
{
3821+
setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3822+
}
3823+
else if ( cssName == "font-size" )
3824+
{
3825+
bool ok;
3826+
int fontSize = elemText.toInt( &ok );
3827+
if ( ok )
3828+
{
3829+
setCustomProperty( "labeling/fontSize", fontSize );
3830+
}
3831+
}
3832+
else if ( cssName == "font-weight" )
3833+
{
3834+
setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3835+
}
3836+
else if ( cssName == "font-underline" )
3837+
{
3838+
setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3839+
}
3840+
}
3841+
3842+
cssElem = cssElem.nextSiblingElement( "CssParameter" );
3843+
}
3844+
}
3845+
3846+
// Fill
3847+
QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3848+
if ( textColor.isValid() )
3849+
{
3850+
setCustomProperty( "labeling/textColorR", textColor.red() );
3851+
setCustomProperty( "labeling/textColorG", textColor.green() );
3852+
setCustomProperty( "labeling/textColorB", textColor.blue() );
3853+
setCustomProperty( "labeling/textTransp", 100 - ( int )( 100 * textColor.alphaF() ) );
3854+
}
3855+
3856+
// Halo
3857+
QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3858+
if ( !haloElem.isNull() )
3859+
{
3860+
setCustomProperty( "labeling/bufferDraw", true );
3861+
setCustomProperty( "labeling/bufferSize", 1 );
3862+
3863+
QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3864+
if ( !radiusElem.isNull() )
3865+
{
3866+
bool ok;
3867+
double bufferSize = radiusElem.text().toDouble( &ok );
3868+
if ( ok )
3869+
{
3870+
setCustomProperty( "labeling/bufferSize", bufferSize );
3871+
}
3872+
}
3873+
3874+
QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3875+
if ( bufferColor.isValid() )
3876+
{
3877+
setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3878+
setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3879+
setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3880+
setCustomProperty( "labeling/bufferTransp", 100 - ( int )( 100 * bufferColor.alphaF() ) );
3881+
}
3882+
}
3883+
3884+
// LabelPlacement
3885+
QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3886+
if ( !labelPlacementElem.isNull() )
3887+
{
3888+
// PointPlacement
3889+
QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3890+
if ( !pointPlacementElem.isNull() )
3891+
{
3892+
setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3893+
3894+
QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3895+
if ( !displacementElem.isNull() )
3896+
{
3897+
QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3898+
if ( !displacementXElem.isNull() )
3899+
{
3900+
bool ok;
3901+
double xOffset = displacementXElem.text().toDouble( &ok );
3902+
if ( ok )
3903+
{
3904+
setCustomProperty( "labeling/xOffset", xOffset );
3905+
}
3906+
}
3907+
QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3908+
if ( !displacementYElem.isNull() )
3909+
{
3910+
bool ok;
3911+
double yOffset = displacementYElem.text().toDouble( &ok );
3912+
if ( ok )
3913+
{
3914+
setCustomProperty( "labeling/yOffset", yOffset );
3915+
}
3916+
}
3917+
}
3918+
3919+
QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3920+
if ( !rotationElem.isNull() )
3921+
{
3922+
bool ok;
3923+
double rotation = rotationElem.text().toDouble( &ok );
3924+
if ( ok )
3925+
{
3926+
setCustomProperty( "labeling/angleOffset", rotation );
3927+
}
3928+
}
3929+
}
3930+
}
3931+
}
3932+
36943933
void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings& s )
36953934
{
36963935
if ( !mDiagramLayerSettings )

src/core/qgsvectorlayer.h

+3
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
15961596
@param labeling out: true if there will be labeling (ng) for this layer*/
15971597
void prepareLabelingAndDiagrams( QgsRenderContext& rendererContext, QgsAttributeList& attributes, bool& labeling );
15981598

1599+
/** Read labeling from SLD */
1600+
void readSldLabeling( const QDomNode& node );
1601+
15991602
private: // Private attributes
16001603

16011604
/** Update threshold for drawing features as they are read. A value of zero indicates

0 commit comments

Comments
 (0)