Skip to content

Commit 4a34e9d

Browse files
author
marco
committed
[FEATURE]: Add point and line pattern symbol layers
2 parents a1cc666 + a5f8a82 commit 4a34e9d

8 files changed

Lines changed: 929 additions & 71 deletions

src/core/symbology-ng/qgsfillsymbollayerv2.cpp

Lines changed: 406 additions & 59 deletions
Large diffs are not rendered by default.

src/core/symbology-ng/qgsfillsymbollayerv2.h

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,29 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2
6767
QPointF mOffset;
6868
};
6969

70+
/**Base class for polygon renderers generating texture images*/
71+
class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayerV2
72+
{
73+
public:
74+
QgsImageFillSymbolLayer();
75+
virtual ~QgsImageFillSymbolLayer();
76+
void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
77+
78+
virtual QgsSymbolV2* subSymbol() { return mOutline; }
79+
virtual bool setSubSymbol( QgsSymbolV2* symbol );
80+
81+
protected:
82+
QBrush mBrush;
83+
84+
/**Outline width*/
85+
double mOutlineWidth;
86+
/**Custom outline*/
87+
QgsLineSymbolV2* mOutline;
88+
};
89+
7090
/**A class for svg fill patterns. The class automatically scales the pattern to
7191
the appropriate pixel dimensions of the output device*/
72-
class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
92+
class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
7393
{
7494
public:
7595
QgsSVGFillSymbolLayer( const QString& svgFilePath = "", double width = 20, double rotation = 0.0 );
@@ -85,8 +105,6 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
85105
void startRender( QgsSymbolV2RenderContext& context );
86106
void stopRender( QgsSymbolV2RenderContext& context );
87107

88-
void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
89-
90108
QgsStringMap properties() const;
91109

92110
QgsSymbolLayerV2* clone() const;
@@ -97,9 +115,6 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
97115
void setPatternWidth( double width ) { mPatternWidth = width;}
98116
double patternWidth() const { return mPatternWidth; }
99117

100-
QgsSymbolV2* subSymbol() { return mOutline; }
101-
bool setSubSymbol( QgsSymbolV2* symbol );
102-
103118
protected:
104119
/**Width of the pattern (in QgsSymbolV2 output units)*/
105120
double mPatternWidth;
@@ -109,19 +124,90 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
109124
QString mSvgFilePath;
110125
/**SVG view box (to keep the aspect ratio */
111126
QRectF mSvgViewBox;
112-
/**Brush that receives rendered pixel image in startRender() method*/
113-
QBrush mBrush;
114-
/**Outline width*/
115-
double mOutlineWidth;
116-
/**Custom outline*/
117-
QgsLineSymbolV2* mOutline;
118127

119128
private:
120129
/**Helper function that gets the view box from the byte array*/
121130
void storeViewBox();
122131
};
123132

133+
class CORE_EXPORT QgsLinePatternFillSymbolLayer: public QgsImageFillSymbolLayer
134+
{
135+
public:
136+
QgsLinePatternFillSymbolLayer();
137+
~QgsLinePatternFillSymbolLayer();
138+
139+
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
140+
141+
QString layerType() const;
142+
143+
void startRender( QgsSymbolV2RenderContext& context );
144+
145+
void stopRender( QgsSymbolV2RenderContext& context );
124146

147+
QgsStringMap properties() const;
148+
149+
QgsSymbolLayerV2* clone() const;
150+
151+
//getters and setters
152+
void setAngle( double a ){ mAngle = a; }
153+
double angle() const { return mAngle; }
154+
void setDistance( double d ){ mDistance = d; }
155+
double distance() const { return mDistance; }
156+
void setLineWidth( double w ){ mLineWidth = w; }
157+
double lineWidth() const { return mLineWidth; }
158+
void setColor( const QColor& c ){ mColor = c; }
159+
QColor color() const{ return mColor; }
160+
161+
protected:
162+
/**Distance (in mm or map units) between lines*/
163+
double mDistance;
164+
/**Line width (in mm or map units)*/
165+
double mLineWidth;
166+
QColor mColor;
167+
//todo: line type
168+
double mAngle;
169+
};
170+
171+
class CORE_EXPORT QgsPointPatternFillSymbolLayer: public QgsImageFillSymbolLayer
172+
{
173+
public:
174+
QgsPointPatternFillSymbolLayer();
175+
~QgsPointPatternFillSymbolLayer();
176+
177+
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
178+
QString layerType() const;
179+
180+
void startRender( QgsSymbolV2RenderContext& context );
181+
182+
void stopRender( QgsSymbolV2RenderContext& context );
183+
184+
QgsStringMap properties() const;
185+
186+
QgsSymbolLayerV2* clone() const;
187+
188+
//getters and setters
189+
double distanceX() const { return mDistanceX; }
190+
void setDistanceX( double d ) { mDistanceX = d; }
191+
192+
double distanceY() const { return mDistanceY; }
193+
void setDistanceY( double d ) { mDistanceY = d; }
194+
195+
double displacementX() const { return mDisplacementX; }
196+
void setDisplacementX( double d ){ mDisplacementX = d; }
197+
198+
double displacementY() const { return mDisplacementY; }
199+
void setDisplacementY( double d ){ mDisplacementY = d; }
200+
201+
bool setSubSymbol( QgsSymbolV2* symbol );
202+
virtual QgsSymbolV2* subSymbol() { return mMarkerSymbol; }
203+
204+
protected:
205+
QgsMarkerSymbolV2* mMarkerSymbol;
206+
double mDistanceX;
207+
double mDistanceY;
208+
double mDisplacementX;
209+
double mDisplacementY;
210+
};
125211

126212
class CORE_EXPORT QgsCentroidFillSymbolLayerV2 : public QgsFillSymbolLayerV2
127213
{

src/core/symbology-ng/qgssymbollayerv2registry.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ QgsSymbolLayerV2Registry::QgsSymbolLayerV2Registry()
3333
QgsSVGFillSymbolLayer::create ) );
3434
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "CentroidFill", QObject::tr( "Centroid fill" ), QgsSymbolV2::Fill,
3535
QgsCentroidFillSymbolLayerV2::create ) );
36+
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "LinePatternFill", QObject::tr("Line pattern fill"), QgsSymbolV2::Fill,
37+
QgsLinePatternFillSymbolLayer::create ) );
38+
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "PointPatternFill", QObject::tr("Point pattern fill"), QgsSymbolV2::Fill,
39+
QgsPointPatternFillSymbolLayer::create ) );
3640
}
3741

3842
QgsSymbolLayerV2Registry::~QgsSymbolLayerV2Registry()

src/gui/symbology-ng/qgssymbollayerv2widget.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,183 @@ void QgsSVGFillSymbolLayerWidget::updateOutlineIcon()
910910

911911
/////////////
912912

913+
QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent ):
914+
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
915+
{
916+
setupUi( this );
917+
}
918+
919+
void QgsLinePatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer)
920+
{
921+
if( layer->layerType() != "LinePatternFill" )
922+
{
923+
return;
924+
}
925+
926+
QgsLinePatternFillSymbolLayer* patternLayer = static_cast<QgsLinePatternFillSymbolLayer*>( layer );
927+
if( patternLayer )
928+
{
929+
mLayer = patternLayer;
930+
mAngleSpinBox->setValue( mLayer->angle() );
931+
mDistanceSpinBox->setValue( mLayer->distance() );
932+
mLineWidthSpinBox->setValue( mLayer->lineWidth() );
933+
}
934+
}
935+
936+
QgsSymbolLayerV2* QgsLinePatternFillSymbolLayerWidget::symbolLayer()
937+
{
938+
return mLayer;
939+
}
940+
941+
void QgsLinePatternFillSymbolLayerWidget::on_mAngleSpinBox_valueChanged( double d )
942+
{
943+
if( mLayer )
944+
{
945+
mLayer->setAngle( d );
946+
emit changed();
947+
}
948+
}
949+
950+
void QgsLinePatternFillSymbolLayerWidget::on_mDistanceSpinBox_valueChanged( double d )
951+
{
952+
if( mLayer )
953+
{
954+
mLayer->setDistance( d );
955+
emit changed();
956+
}
957+
}
958+
959+
void QgsLinePatternFillSymbolLayerWidget::on_mLineWidthSpinBox_valueChanged( double d )
960+
{
961+
if( mLayer )
962+
{
963+
mLayer->setLineWidth( d );
964+
emit changed();
965+
}
966+
}
967+
968+
void QgsLinePatternFillSymbolLayerWidget::on_mColorPushButton_clicked()
969+
{
970+
if( mLayer )
971+
{
972+
QColor c = QColorDialog::getColor( mLayer->color() );
973+
if( c.isValid() )
974+
{
975+
mLayer->setColor( c );
976+
emit changed();
977+
}
978+
}
979+
}
980+
981+
void QgsLinePatternFillSymbolLayerWidget::on_mOutlinePushButton_clicked()
982+
{
983+
if( mLayer )
984+
{
985+
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
986+
if ( dlg.exec() == QDialog::Rejected )
987+
{
988+
return;
989+
}
990+
991+
//updateOutlineIcon();
992+
emit changed();
993+
}
994+
}
995+
996+
/////////////
997+
998+
QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent ):
999+
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
1000+
{
1001+
setupUi( this );
1002+
updateMarkerIcon();
1003+
}
1004+
1005+
1006+
void QgsPointPatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer)
1007+
{
1008+
if( !layer || layer->layerType() != "PointPatternFill" )
1009+
{
1010+
return;
1011+
}
1012+
1013+
mLayer = static_cast<QgsPointPatternFillSymbolLayer*>( layer );
1014+
mHorizontalDistanceSpinBox->setValue( mLayer->distanceX() );
1015+
mVerticalDistanceSpinBox->setValue( mLayer->distanceY() );
1016+
mHorizontalDisplacementSpinBox->setValue( mLayer->displacementX() );
1017+
mVerticalDisplacementSpinBox->setValue( mLayer->displacementY() );
1018+
updateMarkerIcon();
1019+
}
1020+
1021+
QgsSymbolLayerV2* QgsPointPatternFillSymbolLayerWidget::symbolLayer()
1022+
{
1023+
return mLayer;
1024+
}
1025+
1026+
void QgsPointPatternFillSymbolLayerWidget::updateMarkerIcon()
1027+
{
1028+
if ( mLayer )
1029+
{
1030+
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), mChangeMarkerButton->iconSize() );
1031+
mChangeMarkerButton->setIcon( icon );
1032+
}
1033+
}
1034+
1035+
void QgsPointPatternFillSymbolLayerWidget::on_mHorizontalDistanceSpinBox_valueChanged ( double d )
1036+
{
1037+
if( mLayer )
1038+
{
1039+
mLayer->setDistanceX( d );
1040+
emit changed();
1041+
}
1042+
}
1043+
1044+
void QgsPointPatternFillSymbolLayerWidget::on_mVerticalDistanceSpinBox_valueChanged ( double d )
1045+
{
1046+
if( mLayer )
1047+
{
1048+
mLayer->setDistanceY( d );
1049+
emit changed();
1050+
}
1051+
}
1052+
1053+
void QgsPointPatternFillSymbolLayerWidget::on_mHorizontalDisplacementSpinBox_valueChanged ( double d )
1054+
{
1055+
if( mLayer )
1056+
{
1057+
mLayer->setDisplacementX( d );
1058+
emit changed();
1059+
}
1060+
}
1061+
1062+
void QgsPointPatternFillSymbolLayerWidget::on_mVerticalDisplacementSpinBox_valueChanged ( double d )
1063+
{
1064+
if( mLayer )
1065+
{
1066+
mLayer->setDisplacementY( d );
1067+
emit changed();
1068+
}
1069+
}
1070+
1071+
void QgsPointPatternFillSymbolLayerWidget::on_mChangeMarkerButton_clicked()
1072+
{
1073+
if( !mLayer )
1074+
{
1075+
return;
1076+
}
1077+
1078+
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
1079+
if ( dlg.exec() == QDialog::Rejected )
1080+
{
1081+
return;
1082+
}
1083+
1084+
updateMarkerIcon();
1085+
emit changed();
1086+
}
1087+
1088+
/////////////
1089+
9131090
QgsFontMarkerSymbolLayerV2Widget::QgsFontMarkerSymbolLayerV2Widget( const QgsVectorLayer* vl, QWidget* parent )
9141091
: QgsSymbolLayerV2Widget( parent, vl )
9151092
{

0 commit comments

Comments
 (0)