30
30
31
31
#include " qgsdatadefined.h"
32
32
33
+ #include " qgsgeometry.h"
34
+ #include " qgswkbptr.h"
35
+ #include " qgsgeometrycollectionv2.h"
36
+ #include " qgsclipper.h"
37
+
33
38
#include < QColor>
34
39
#include < QImage>
35
40
#include < QPainter>
@@ -90,19 +95,163 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, const QgsSymbolLayerV2List& layers )
90
95
{
91
96
mLayers .removeAt ( i-- );
92
97
}
93
- else if ( !isSymbolLayerCompatible ( mLayers [i]->type () ) )
98
+ else if ( !mLayers [i]->isCompatibleWithSymbol ( this ) )
94
99
{
95
100
delete mLayers [i];
96
101
mLayers .removeAt ( i-- );
97
102
}
98
103
}
99
104
}
100
105
106
+ const unsigned char * QgsSymbolV2::_getPoint ( QPointF& pt, QgsRenderContext& context, const unsigned char * wkb )
107
+ {
108
+ QgsConstWkbPtr wkbPtr ( wkb + 1 );
109
+ unsigned int wkbType;
110
+ wkbPtr >> wkbType >> pt.rx () >> pt.ry ();
111
+
112
+ if (( QgsWKBTypes::Type )wkbType == QgsWKBTypes::Point25D || ( QgsWKBTypes::Type )wkbType == QgsWKBTypes::PointZ )
113
+ wkbPtr += sizeof ( double );
114
+
115
+ if ( context.coordinateTransform () )
116
+ {
117
+ double z = 0 ; // dummy variable for coordiante transform
118
+ context.coordinateTransform ()->transformInPlace ( pt.rx (), pt.ry (), z );
119
+ }
120
+
121
+ context.mapToPixel ().transformInPlace ( pt.rx (), pt.ry () );
122
+
123
+ return wkbPtr;
124
+ }
125
+
126
+ const unsigned char * QgsSymbolV2::_getLineString ( QPolygonF& pts, QgsRenderContext& context, const unsigned char * wkb, bool clipToExtent )
127
+ {
128
+ QgsConstWkbPtr wkbPtr ( wkb + 1 );
129
+ unsigned int wkbType, nPoints;
130
+ wkbPtr >> wkbType >> nPoints;
131
+
132
+ bool hasZValue = QgsWKBTypes::hasZ (( QgsWKBTypes::Type )wkbType );
133
+ bool hasMValue = QgsWKBTypes::hasM (( QgsWKBTypes::Type )wkbType );
134
+
135
+ double x = 0.0 ;
136
+ double y = 0.0 ;
137
+ const QgsCoordinateTransform* ct = context.coordinateTransform ();
138
+ const QgsMapToPixel& mtp = context.mapToPixel ();
139
+
140
+ // apply clipping for large lines to achieve a better rendering performance
141
+ if ( clipToExtent && nPoints > 1 )
142
+ {
143
+ const QgsRectangle& e = context.extent ();
144
+ double cw = e.width () / 10 ; double ch = e.height () / 10 ;
145
+ QgsRectangle clipRect ( e.xMinimum () - cw, e.yMinimum () - ch, e.xMaximum () + cw, e.yMaximum () + ch );
146
+ wkbPtr = QgsConstWkbPtr ( QgsClipper::clippedLineWKB ( wkb, clipRect, pts ) );
147
+ }
148
+ else
149
+ {
150
+ pts.resize ( nPoints );
151
+
152
+ QPointF* ptr = pts.data ();
153
+ for ( unsigned int i = 0 ; i < nPoints; ++i, ++ptr )
154
+ {
155
+ wkbPtr >> x >> y;
156
+ if ( hasZValue )
157
+ wkbPtr += sizeof ( double );
158
+ if ( hasMValue )
159
+ wkbPtr += sizeof ( double );
160
+
161
+ *ptr = QPointF ( x, y );
162
+ }
163
+ }
164
+
165
+ // transform the QPolygonF to screen coordinates
166
+ if ( ct )
167
+ {
168
+ ct->transformPolygon ( pts );
169
+ }
170
+
171
+ QPointF* ptr = pts.data ();
172
+ for ( int i = 0 ; i < pts.size (); ++i, ++ptr )
173
+ {
174
+ mtp.transformInPlace ( ptr->rx (), ptr->ry () );
175
+ }
176
+
177
+ return wkbPtr;
178
+ }
179
+
180
+ const unsigned char * QgsSymbolV2::_getPolygon ( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char * wkb, bool clipToExtent )
181
+ {
182
+ QgsConstWkbPtr wkbPtr ( wkb + 1 );
183
+
184
+ unsigned int wkbType, numRings;
185
+ wkbPtr >> wkbType >> numRings;
186
+
187
+ if ( numRings == 0 ) // sanity check for zero rings in polygon
188
+ return wkbPtr;
189
+
190
+ bool hasZValue = QgsWKBTypes::hasZ (( QgsWKBTypes::Type )wkbType );
191
+ bool hasMValue = QgsWKBTypes::hasM (( QgsWKBTypes::Type )wkbType );
192
+
193
+ double x, y;
194
+ holes.clear ();
195
+
196
+ const QgsCoordinateTransform* ct = context.coordinateTransform ();
197
+ const QgsMapToPixel& mtp = context.mapToPixel ();
198
+ const QgsRectangle& e = context.extent ();
199
+ double cw = e.width () / 10 ; double ch = e.height () / 10 ;
200
+ QgsRectangle clipRect ( e.xMinimum () - cw, e.yMinimum () - ch, e.xMaximum () + cw, e.yMaximum () + ch );
201
+
202
+ for ( unsigned int idx = 0 ; idx < numRings; idx++ )
203
+ {
204
+ unsigned int nPoints;
205
+ wkbPtr >> nPoints;
206
+
207
+ QPolygonF poly ( nPoints );
208
+
209
+ // Extract the points from the WKB and store in a pair of vectors.
210
+ QPointF* ptr = poly.data ();
211
+ for ( unsigned int jdx = 0 ; jdx < nPoints; ++jdx, ++ptr )
212
+ {
213
+ wkbPtr >> x >> y;
214
+ if ( hasZValue )
215
+ wkbPtr += sizeof ( double );
216
+ if ( hasMValue )
217
+ wkbPtr += sizeof ( double );
218
+
219
+ *ptr = QPointF ( x, y );
220
+ }
221
+
222
+ if ( nPoints < 1 )
223
+ continue ;
224
+
225
+ // clip close to view extent, if needed
226
+ QRectF ptsRect = poly.boundingRect ();
227
+ if ( clipToExtent && !context.extent ().contains ( ptsRect ) ) QgsClipper::trimPolygon ( poly, clipRect );
228
+
229
+ // transform the QPolygonF to screen coordinates
230
+ if ( ct )
231
+ {
232
+ ct->transformPolygon ( poly );
233
+ }
234
+
235
+
236
+ ptr = poly.data ();
237
+ for ( int i = 0 ; i < poly.size (); ++i, ++ptr )
238
+ {
239
+ mtp.transformInPlace ( ptr->rx (), ptr->ry () );
240
+ }
241
+
242
+ if ( idx == 0 )
243
+ pts = poly;
244
+ else
245
+ holes.append ( poly );
246
+ }
247
+
248
+ return wkbPtr;
249
+ }
250
+
101
251
QgsSymbolV2::~QgsSymbolV2 ()
102
252
{
103
253
// delete all symbol layers (we own them, so it's okay)
104
- for ( QgsSymbolLayerV2List::iterator it = mLayers .begin (); it != mLayers .end (); ++it )
105
- delete *it;
254
+ qDeleteAll ( mLayers );
106
255
}
107
256
108
257
QgsSymbolV2::OutputUnit QgsSymbolV2::outputUnit () const
@@ -217,28 +366,25 @@ QgsSymbolV2* QgsSymbolV2::defaultSymbol( QGis::GeometryType geomType )
217
366
218
367
QgsSymbolLayerV2* QgsSymbolV2::symbolLayer ( int layer )
219
368
{
220
- if ( layer < 0 || layer >= mLayers .count () )
221
- return NULL ;
222
-
223
- return mLayers [layer];
369
+ return mLayers .value ( layer );
224
370
}
225
371
226
372
227
- bool QgsSymbolV2::isSymbolLayerCompatible ( SymbolType t )
373
+ bool QgsSymbolV2::isSymbolLayerCompatible ( SymbolType layerType )
228
374
{
229
375
// fill symbol can contain also line symbol layers for drawing of outlines
230
- if ( mType == Fill && t == Line )
376
+ if ( mType == Fill && layerType == Line )
231
377
return true ;
232
378
233
- return mType == t ;
379
+ return mType == layerType ;
234
380
}
235
381
236
382
237
383
bool QgsSymbolV2::insertSymbolLayer ( int index, QgsSymbolLayerV2* layer )
238
384
{
239
385
if ( index < 0 || index > mLayers .count () ) // can be added also after the last index
240
386
return false ;
241
- if ( layer == NULL || !isSymbolLayerCompatible ( layer->type () ) )
387
+ if ( layer == NULL || !layer->isCompatibleWithSymbol ( this ) )
242
388
return false ;
243
389
244
390
mLayers .insert ( index, layer );
@@ -248,7 +394,7 @@ bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
248
394
249
395
bool QgsSymbolV2::appendSymbolLayer ( QgsSymbolLayerV2* layer )
250
396
{
251
- if ( layer == NULL || !isSymbolLayerCompatible ( layer->type () ) )
397
+ if ( layer == NULL || !layer->isCompatibleWithSymbol ( this ) )
252
398
return false ;
253
399
254
400
mLayers .append ( layer );
@@ -280,7 +426,7 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
280
426
{
281
427
if ( index < 0 || index >= mLayers .count () )
282
428
return false ;
283
- if ( layer == NULL || !isSymbolLayerCompatible ( layer->type () ) )
429
+ if ( layer == NULL || !layer->isCompatibleWithSymbol ( this ) )
284
430
return false ;
285
431
286
432
delete mLayers [index]; // first delete the original layer
@@ -294,26 +440,26 @@ void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsFields* field
294
440
QgsSymbolV2RenderContext symbolContext ( context, outputUnit (), mAlpha , false , mRenderHints , 0 , fields, mapUnitScale () );
295
441
296
442
297
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
298
- ( *it ) ->startRender ( symbolContext );
443
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
444
+ layer ->startRender ( symbolContext );
299
445
}
300
446
301
447
void QgsSymbolV2::stopRender ( QgsRenderContext& context )
302
448
{
303
449
QgsSymbolV2RenderContext symbolContext ( context, outputUnit (), mAlpha , false , mRenderHints , 0 , 0 , mapUnitScale () );
304
450
305
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
306
- ( *it ) ->stopRender ( symbolContext );
451
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
452
+ layer ->stopRender ( symbolContext );
307
453
308
454
mLayer = NULL ;
309
455
}
310
456
311
457
void QgsSymbolV2::setColor ( const QColor& color )
312
458
{
313
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
459
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
314
460
{
315
- if ( !( *it ) ->isLocked () )
316
- ( *it ) ->setColor ( color );
461
+ if ( !layer ->isLocked () )
462
+ layer ->setColor ( color );
317
463
}
318
464
}
319
465
@@ -334,22 +480,25 @@ void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size, QgsRenderConte
334
480
context.setForceVectorOutput ( true );
335
481
QgsSymbolV2RenderContext symbolContext ( context, outputUnit (), mAlpha , false , mRenderHints , 0 , 0 , mapUnitScale () );
336
482
337
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
483
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
338
484
{
339
- if ( mType == Fill && ( *it ) ->type () == Line )
485
+ if ( mType == Fill && layer ->type () == Line )
340
486
{
341
487
// line symbol layer would normally draw just a line
342
488
// so we override this case to force it to draw a polygon outline
343
- QgsLineSymbolLayerV2* lsl = ( QgsLineSymbolLayerV2* ) * it ;
489
+ QgsLineSymbolLayerV2* lsl = dynamic_cast < QgsLineSymbolLayerV2*>( layer ) ;
344
490
345
- // from QgsFillSymbolLayerV2::drawPreviewIcon()
346
- QPolygonF poly = QRectF ( QPointF ( 0 , 0 ), QPointF ( size.width () - 1 , size.height () - 1 ) );
347
- lsl->startRender ( symbolContext );
348
- lsl->renderPolygonOutline ( poly, NULL , symbolContext );
349
- lsl->stopRender ( symbolContext );
491
+ if ( lsl )
492
+ {
493
+ // from QgsFillSymbolLayerV2::drawPreviewIcon()
494
+ QPolygonF poly = QRectF ( QPointF ( 0 , 0 ), QPointF ( size.width () - 1 , size.height () - 1 ) );
495
+ lsl->startRender ( symbolContext );
496
+ lsl->renderPolygonOutline ( poly, NULL , symbolContext );
497
+ lsl->stopRender ( symbolContext );
498
+ }
350
499
}
351
500
else
352
- ( *it ) ->drawPreviewIcon ( symbolContext, size );
501
+ layer ->drawPreviewIcon ( symbolContext, size );
353
502
}
354
503
}
355
504
@@ -476,6 +625,68 @@ QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
476
625
return lst;
477
626
}
478
627
628
+ void QgsSymbolV2::renderUsingLayer ( QgsSymbolLayerV2* layer, QgsSymbolV2RenderContext& context )
629
+ {
630
+ static QPointF nullPoint;
631
+ static QPolygonF nullLine;
632
+ static QList<QPolygonF> nullRings;
633
+
634
+
635
+ QgsPaintEffect* effect = layer->paintEffect ();
636
+ if ( effect && effect->enabled () )
637
+ {
638
+ QPainter* p = context.renderContext ().painter ();
639
+ p->save ();
640
+
641
+ effect->begin ( context.renderContext () );
642
+ switch ( layer->type () )
643
+ {
644
+ case Fill:
645
+ static_cast <QgsFillSymbolLayerV2*>( layer )->renderPolygon ( nullLine, &nullRings, context );
646
+ break ;
647
+
648
+ case Line:
649
+ static_cast <QgsLineSymbolLayerV2*>( layer )->renderPolyline ( nullLine, context );
650
+ break ;
651
+
652
+ case Marker:
653
+ static_cast <QgsMarkerSymbolLayerV2*>( layer )->renderPoint ( nullPoint, context );
654
+ break ;
655
+
656
+ case Hybrid:
657
+ Q_ASSERT ( false );
658
+ // Layers should only be registered as accepting hybrid input but always return a defined output
659
+ break ;
660
+ }
661
+
662
+ effect->end ( context.renderContext () );
663
+
664
+ p->restore ();
665
+ }
666
+ else
667
+ {
668
+ switch ( layer->type () )
669
+ {
670
+ case Fill:
671
+ static_cast <QgsFillSymbolLayerV2*>( layer )->renderPolygon ( nullLine, &nullRings, context );
672
+ break ;
673
+
674
+ case Line:
675
+ static_cast <QgsLineSymbolLayerV2*>( layer )->renderPolyline ( nullLine, context );
676
+ break ;
677
+
678
+ case Marker:
679
+ static_cast <QgsMarkerSymbolLayerV2*>( layer )->renderPoint ( nullPoint, context );
680
+ break ;
681
+
682
+ case Hybrid:
683
+ Q_ASSERT ( false );
684
+ // Layers should only be registered as accepting hybrid input but always return a defined output
685
+ break ;
686
+ }
687
+ }
688
+ }
689
+
479
690
QSet<QString> QgsSymbolV2::usedAttributes () const
480
691
{
481
692
QSet<QString> attributes;
@@ -500,13 +711,220 @@ bool QgsSymbolV2::hasDataDefinedProperties() const
500
711
return false ;
501
712
}
502
713
714
+ void QgsSymbolV2::renderFeature ( const QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker, int currentVertexMarkerType, int currentVertexMarkerSize )
715
+ {
716
+ const QgsGeometry* geom = feature.constGeometry ();
717
+ if ( !geom || !geom->geometry () )
718
+ {
719
+ return ;
720
+ }
721
+
722
+ const QgsGeometry* segmentizedGeometry = geom;
723
+ bool deleteSegmentizedGeometry = false ;
724
+ context.setGeometry ( geom->geometry () );
725
+
726
+ // convert curve types to normal point/line/polygon ones
727
+ switch ( QgsWKBTypes::flatType ( geom->geometry ()->wkbType () ) )
728
+ {
729
+ case QgsWKBTypes::CurvePolygon:
730
+ case QgsWKBTypes::CircularString:
731
+ case QgsWKBTypes::CompoundCurve:
732
+ case QgsWKBTypes::MultiSurface:
733
+ case QgsWKBTypes::MultiCurve:
734
+ {
735
+ QgsAbstractGeometryV2* g = geom->geometry ()->segmentize ();
736
+ if ( !g )
737
+ {
738
+ return ;
739
+ }
740
+ segmentizedGeometry = new QgsGeometry ( g );
741
+ deleteSegmentizedGeometry = true ;
742
+ break ;
743
+ }
744
+
745
+ default :
746
+ break ;
747
+ }
748
+
749
+ switch ( QgsWKBTypes::flatType ( segmentizedGeometry->geometry ()->wkbType () ) )
750
+ {
751
+ case QgsWKBTypes::Point:
752
+ {
753
+ QPointF pt;
754
+ if ( mType != QgsSymbolV2::Marker )
755
+ {
756
+ QgsDebugMsg ( " point can be drawn only with marker symbol!" );
757
+ break ;
758
+ }
759
+ _getPoint ( pt, context, segmentizedGeometry->asWkb () );
760
+ ( static_cast <QgsMarkerSymbolV2*>( this ) )->renderPoint ( pt, &feature, context, layer, selected );
761
+ if ( context.testFlag ( QgsRenderContext::DrawSymbolBounds ) )
762
+ {
763
+ // draw debugging rect
764
+ context.painter ()->setPen ( Qt::red );
765
+ context.painter ()->setBrush ( QColor ( 255 , 0 , 0 , 100 ) );
766
+ context.painter ()->drawRect ( static_cast <QgsMarkerSymbolV2*>( this )->bounds ( pt, context ) );
767
+ }
768
+ }
769
+ break ;
770
+ case QgsWKBTypes::LineString:
771
+ {
772
+ QPolygonF pts;
773
+ if ( mType != QgsSymbolV2::Line )
774
+ {
775
+ QgsDebugMsg ( " linestring can be drawn only with line symbol!" );
776
+ break ;
777
+ }
778
+ _getLineString ( pts, context, segmentizedGeometry->asWkb (), clipFeaturesToExtent () );
779
+ static_cast <QgsLineSymbolV2*>( this )->renderPolyline ( pts, &feature, context, layer, selected );
780
+ }
781
+ break ;
782
+ case QgsWKBTypes::Polygon:
783
+ {
784
+ QPolygonF pts;
785
+ QList<QPolygonF> holes;
786
+ if ( mType != QgsSymbolV2::Fill )
787
+ {
788
+ QgsDebugMsg ( " polygon can be drawn only with fill symbol!" );
789
+ break ;
790
+ }
791
+ _getPolygon ( pts, holes, context, segmentizedGeometry->asWkb (), clipFeaturesToExtent () );
792
+ static_cast <QgsFillSymbolV2*>( this )->renderPolygon ( pts, ( !holes.isEmpty () ? &holes : NULL ), &feature, context, layer, selected );
793
+ }
794
+ break ;
795
+
796
+ case QgsWKBTypes::MultiPoint:
797
+ {
798
+ QPointF pt;
799
+
800
+ if ( mType != QgsSymbolV2::Marker )
801
+ {
802
+ QgsDebugMsg ( " multi-point can be drawn only with marker symbol!" );
803
+ break ;
804
+ }
805
+
806
+ QgsConstWkbPtr wkbPtr ( segmentizedGeometry->asWkb () + 1 + sizeof ( int ) );
807
+ unsigned int num;
808
+ wkbPtr >> num;
809
+ const unsigned char * ptr = wkbPtr;
810
+
811
+ for ( unsigned int i = 0 ; i < num; ++i )
812
+ {
813
+ ptr = QgsConstWkbPtr ( _getPoint ( pt, context, ptr ) );
814
+ static_cast <QgsMarkerSymbolV2*>( this )->renderPoint ( pt, &feature, context, layer, selected );
815
+ }
816
+ }
817
+ break ;
818
+
819
+ case QgsWKBTypes::MultiCurve:
820
+ case QgsWKBTypes::MultiLineString:
821
+ {
822
+ QPolygonF pts;
823
+
824
+ if ( mType != QgsSymbolV2::Line )
825
+ {
826
+ QgsDebugMsg ( " multi-linestring can be drawn only with line symbol!" );
827
+ break ;
828
+ }
829
+
830
+ QgsConstWkbPtr wkbPtr ( segmentizedGeometry->asWkb () + 1 + sizeof ( int ) );
831
+ unsigned int num;
832
+ wkbPtr >> num;
833
+ const unsigned char * ptr = wkbPtr;
834
+
835
+ const QgsGeometryCollectionV2* geomCollection = dynamic_cast <const QgsGeometryCollectionV2*>( geom->geometry () );
836
+
837
+ for ( unsigned int i = 0 ; i < num; ++i )
838
+ {
839
+ if ( geomCollection )
840
+ {
841
+ context.setGeometry ( geomCollection->geometryN ( i ) );
842
+ }
843
+ ptr = QgsConstWkbPtr ( _getLineString ( pts, context, ptr, clipFeaturesToExtent () ) );
844
+ static_cast <QgsLineSymbolV2*>( this )->renderPolyline ( pts, &feature, context, layer, selected );
845
+ }
846
+ }
847
+ break ;
848
+
849
+ case QgsWKBTypes::MultiSurface:
850
+ case QgsWKBTypes::MultiPolygon:
851
+ {
852
+ if ( mType != QgsSymbolV2::Fill )
853
+ {
854
+ QgsDebugMsg ( " multi-polygon can be drawn only with fill symbol!" );
855
+ break ;
856
+ }
857
+
858
+ QgsConstWkbPtr wkbPtr ( segmentizedGeometry->asWkb () + 1 + sizeof ( int ) );
859
+ unsigned int num;
860
+ wkbPtr >> num;
861
+ const unsigned char * ptr = wkbPtr;
862
+
863
+ QPolygonF pts;
864
+ QList<QPolygonF> holes;
865
+
866
+ const QgsGeometryCollectionV2* geomCollection = dynamic_cast <const QgsGeometryCollectionV2*>( geom->geometry () );
867
+
868
+ for ( unsigned int i = 0 ; i < num; ++i )
869
+ {
870
+ if ( geomCollection )
871
+ {
872
+ context.setGeometry ( geomCollection->geometryN ( i ) );
873
+ }
874
+ ptr = _getPolygon ( pts, holes, context, ptr, clipFeaturesToExtent () );
875
+ static_cast <QgsFillSymbolV2*>( this )->renderPolygon ( pts, ( !holes.isEmpty () ? &holes : NULL ), &feature, context, layer, selected );
876
+ }
877
+ break ;
878
+ }
879
+ default :
880
+ QgsDebugMsg ( QString ( " feature %1: unsupported wkb type 0x%2 for rendering" ).arg ( feature.id () ).arg ( geom->wkbType (), 0 , 16 ) );
881
+ }
882
+
883
+ if ( drawVertexMarker )
884
+ {
885
+ const QgsCoordinateTransform* ct = context.coordinateTransform ();
886
+ const QgsMapToPixel& mtp = context.mapToPixel ();
887
+
888
+ QgsPointV2 vertexPoint;
889
+ QgsVertexId vertexId;
890
+ double x, y, z;
891
+ QPointF mapPoint;
892
+ while ( geom->geometry ()->nextVertex ( vertexId, vertexPoint ) )
893
+ {
894
+ // transform
895
+ x = vertexPoint.x (); y = vertexPoint.y (); z = vertexPoint.z ();
896
+ if ( ct )
897
+ {
898
+ ct->transformInPlace ( x, y, z );
899
+ }
900
+ mapPoint.setX ( x ); mapPoint.setY ( y );
901
+ mtp.transformInPlace ( mapPoint.rx (), mapPoint.ry () );
902
+ QgsVectorLayer::drawVertexMarker ( mapPoint.x (), mapPoint.y (), *context.painter (),
903
+ ( QgsVectorLayer::VertexMarkerType ) currentVertexMarkerType,
904
+ currentVertexMarkerSize );
905
+ }
906
+ }
907
+
908
+ if ( deleteSegmentizedGeometry )
909
+ {
910
+ delete segmentizedGeometry;
911
+ }
912
+ }
913
+
503
914
// //////////////////
504
915
505
916
506
917
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext ( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints, const QgsFeature* f, const QgsFields* fields, const QgsMapUnitScale& mapUnitScale )
507
- : mRenderContext( c ), mOutputUnit( u ), mMapUnitScale( mapUnitScale ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints ), mFeature( f ), mFields( fields )
918
+ : mRenderContext( c ),
919
+ mOutputUnit( u ),
920
+ mMapUnitScale( mapUnitScale ),
921
+ mAlpha( alpha ),
922
+ mSelected( selected ),
923
+ mRenderHints( renderHints ),
924
+ mFeature( f ),
925
+ mFields( fields ),
926
+ mExpressionContext( c.expressionContext() )
508
927
{
509
-
510
928
}
511
929
512
930
QgsSymbolV2RenderContext::~QgsSymbolV2RenderContext ()
@@ -587,10 +1005,11 @@ void QgsMarkerSymbolV2::setAngle( double ang )
587
1005
{
588
1006
double origAngle = angle ();
589
1007
double angleDiff = ang - origAngle;
590
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1008
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
591
1009
{
592
- QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
593
- layer->setAngle ( layer->angle () + angleDiff );
1010
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1011
+ if ( markerLayer )
1012
+ markerLayer->setAngle ( markerLayer->angle () + angleDiff );
594
1013
}
595
1014
}
596
1015
@@ -608,34 +1027,40 @@ double QgsMarkerSymbolV2::angle() const
608
1027
609
1028
void QgsMarkerSymbolV2::setLineAngle ( double lineAng )
610
1029
{
611
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1030
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
612
1031
{
613
- QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
614
- layer->setLineAngle ( lineAng );
1032
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1033
+
1034
+ if ( markerLayer )
1035
+ markerLayer->setLineAngle ( lineAng );
615
1036
}
616
1037
}
617
1038
618
1039
void QgsMarkerSymbolV2::setDataDefinedAngle ( const QgsDataDefined& dd )
619
1040
{
620
1041
const double symbolRotation = angle ();
621
1042
622
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1043
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
623
1044
{
624
- QgsMarkerSymbolLayerV2* layer = static_cast <QgsMarkerSymbolLayerV2 *>( *it );
625
- if ( dd.hasDefaultValues () )
626
- {
627
- layer->removeDataDefinedProperty ( " angle" );
628
- }
629
- else
1045
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1046
+
1047
+ if ( markerLayer )
630
1048
{
631
- if ( qgsDoubleNear ( layer-> angle (), symbolRotation ) )
1049
+ if ( dd. hasDefaultValues ( ) )
632
1050
{
633
- layer->setDataDefinedProperty ( " angle" , new QgsDataDefined ( dd ) );
1051
+ layer->removeDataDefinedProperty ( " angle" );
634
1052
}
635
1053
else
636
1054
{
637
- QgsDataDefined* rotatedDD = rotateWholeSymbol ( layer->angle () - symbolRotation, dd );
638
- layer->setDataDefinedProperty ( " angle" , rotatedDD );
1055
+ if ( qgsDoubleNear ( markerLayer->angle (), symbolRotation ) )
1056
+ {
1057
+ layer->setDataDefinedProperty ( " angle" , new QgsDataDefined ( dd ) );
1058
+ }
1059
+ else
1060
+ {
1061
+ QgsDataDefined* rotatedDD = rotateWholeSymbol ( markerLayer->angle () - symbolRotation, dd );
1062
+ layer->setDataDefinedProperty ( " angle" , rotatedDD );
1063
+ }
639
1064
}
640
1065
}
641
1066
}
@@ -687,20 +1112,20 @@ void QgsMarkerSymbolV2::setSize( double s )
687
1112
{
688
1113
double origSize = size ();
689
1114
690
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1115
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
691
1116
{
692
- QgsMarkerSymbolLayerV2* layer = static_cast <QgsMarkerSymbolLayerV2*>( *it );
693
- if ( layer ->size () == origSize )
694
- layer ->setSize ( s );
1117
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1118
+ if ( markerLayer ->size () == origSize )
1119
+ markerLayer ->setSize ( s );
695
1120
else if ( origSize != 0 )
696
1121
{
697
1122
// proportionally scale size
698
- layer ->setSize ( layer ->size () * s / origSize );
1123
+ markerLayer ->setSize ( markerLayer ->size () * s / origSize );
699
1124
}
700
1125
// also scale offset to maintain relative position
701
- if ( origSize != 0 && ( layer ->offset ().x () || layer ->offset ().y () ) )
702
- layer ->setOffset ( QPointF ( layer ->offset ().x () * s / origSize,
703
- layer ->offset ().y () * s / origSize ) );
1126
+ if ( origSize != 0 && ( markerLayer ->offset ().x () || markerLayer ->offset ().y () ) )
1127
+ markerLayer ->setOffset ( QPointF ( markerLayer ->offset ().x () * s / origSize,
1128
+ markerLayer ->offset ().y () * s / origSize ) );
704
1129
}
705
1130
}
706
1131
@@ -722,31 +1147,31 @@ void QgsMarkerSymbolV2::setDataDefinedSize( const QgsDataDefined &dd )
722
1147
{
723
1148
const double symbolSize = size ();
724
1149
725
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1150
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
726
1151
{
727
- QgsMarkerSymbolLayerV2* layer = static_cast <QgsMarkerSymbolLayerV2 *>( *it );
1152
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2 *>( layer );
728
1153
729
1154
if ( dd.hasDefaultValues () )
730
1155
{
731
- layer ->removeDataDefinedProperty ( " size" );
732
- layer ->removeDataDefinedProperty ( " offset" );
1156
+ markerLayer ->removeDataDefinedProperty ( " size" );
1157
+ markerLayer ->removeDataDefinedProperty ( " offset" );
733
1158
}
734
1159
else
735
1160
{
736
- if ( symbolSize == 0 || qgsDoubleNear ( layer ->size (), symbolSize ) )
1161
+ if ( symbolSize == 0 || qgsDoubleNear ( markerLayer ->size (), symbolSize ) )
737
1162
{
738
- layer ->setDataDefinedProperty ( " size" , new QgsDataDefined ( dd ) );
1163
+ markerLayer ->setDataDefinedProperty ( " size" , new QgsDataDefined ( dd ) );
739
1164
}
740
1165
else
741
1166
{
742
- layer ->setDataDefinedProperty ( " size" , scaleWholeSymbol ( layer ->size () / symbolSize, dd ) );
1167
+ markerLayer ->setDataDefinedProperty ( " size" , scaleWholeSymbol ( markerLayer ->size () / symbolSize, dd ) );
743
1168
}
744
1169
745
- if ( layer ->offset ().x () || layer ->offset ().y () )
1170
+ if ( markerLayer ->offset ().x () || markerLayer ->offset ().y () )
746
1171
{
747
- layer ->setDataDefinedProperty ( " offset" , scaleWholeSymbol (
748
- layer ->offset ().x () / symbolSize,
749
- layer ->offset ().y () / symbolSize, dd ) );
1172
+ markerLayer ->setDataDefinedProperty ( " offset" , scaleWholeSymbol (
1173
+ markerLayer ->offset ().x () / symbolSize,
1174
+ markerLayer ->offset ().y () / symbolSize, dd ) );
750
1175
}
751
1176
}
752
1177
}
@@ -805,10 +1230,11 @@ QgsDataDefined QgsMarkerSymbolV2::dataDefinedSize() const
805
1230
806
1231
void QgsMarkerSymbolV2::setScaleMethod ( QgsSymbolV2::ScaleMethod scaleMethod )
807
1232
{
808
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1233
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
809
1234
{
810
- QgsMarkerSymbolLayerV2* layer = static_cast <QgsMarkerSymbolLayerV2*>( *it );
811
- layer->setScaleMethod ( scaleMethod );
1235
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1236
+ if ( markerLayer )
1237
+ markerLayer->setScaleMethod ( scaleMethod );
812
1238
}
813
1239
}
814
1240
@@ -860,9 +1286,12 @@ void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f,
860
1286
return ;
861
1287
}
862
1288
863
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1289
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
864
1290
{
865
- renderPointUsingLayer (( QgsMarkerSymbolLayerV2* ) * it, point, symbolContext );
1291
+ QgsMarkerSymbolLayerV2* markerLayer = dynamic_cast <QgsMarkerSymbolLayerV2*>( layer );
1292
+
1293
+ if ( markerLayer )
1294
+ renderPointUsingLayer ( markerLayer, point, symbolContext );
866
1295
}
867
1296
}
868
1297
@@ -905,33 +1334,41 @@ void QgsLineSymbolV2::setWidth( double w )
905
1334
{
906
1335
double origWidth = width ();
907
1336
908
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1337
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
909
1338
{
910
- QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
911
- if ( layer->width () == origWidth )
912
- {
913
- layer->setWidth ( w );
914
- }
915
- else if ( origWidth != 0 )
1339
+ QgsLineSymbolLayerV2* lineLayer = dynamic_cast <QgsLineSymbolLayerV2*>( layer );
1340
+
1341
+ if ( lineLayer )
916
1342
{
917
- // proportionally scale the width
918
- layer->setWidth ( layer->width () * w / origWidth );
1343
+ if ( lineLayer->width () == origWidth )
1344
+ {
1345
+ lineLayer->setWidth ( w );
1346
+ }
1347
+ else if ( origWidth != 0 )
1348
+ {
1349
+ // proportionally scale the width
1350
+ lineLayer->setWidth ( lineLayer->width () * w / origWidth );
1351
+ }
1352
+ // also scale offset to maintain relative position
1353
+ if ( origWidth != 0 && lineLayer->offset () )
1354
+ lineLayer->setOffset ( lineLayer->offset () * w / origWidth );
919
1355
}
920
- // also scale offset to maintain relative position
921
- if ( origWidth != 0 && layer->offset () )
922
- layer->setOffset ( layer->offset () * w / origWidth );
923
1356
}
924
1357
}
925
1358
926
1359
double QgsLineSymbolV2::width () const
927
1360
{
928
1361
double maxWidth = 0 ;
929
- for ( QgsSymbolLayerV2List::const_iterator it = mLayers .begin (); it != mLayers .end (); ++it )
1362
+
1363
+ Q_FOREACH ( QgsSymbolLayerV2* symbolLayer, mLayers )
930
1364
{
931
- const QgsLineSymbolLayerV2* layer = ( const QgsLineSymbolLayerV2* ) * it;
932
- double width = layer->width ();
933
- if ( width > maxWidth )
934
- maxWidth = width;
1365
+ const QgsLineSymbolLayerV2* lineLayer = dynamic_cast <QgsLineSymbolLayerV2*>( symbolLayer );
1366
+ if ( lineLayer )
1367
+ {
1368
+ double width = lineLayer->width ();
1369
+ if ( width > maxWidth )
1370
+ maxWidth = width;
1371
+ }
935
1372
}
936
1373
return maxWidth;
937
1374
}
@@ -940,29 +1377,32 @@ void QgsLineSymbolV2::setDataDefinedWidth( const QgsDataDefined& dd )
940
1377
{
941
1378
const double symbolWidth = width ();
942
1379
943
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1380
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
944
1381
{
945
- QgsLineSymbolLayerV2* layer = static_cast <QgsLineSymbolLayerV2*>( *it );
1382
+ QgsLineSymbolLayerV2* lineLayer = dynamic_cast <QgsLineSymbolLayerV2*>( layer );
946
1383
947
- if ( dd.hasDefaultValues () )
948
- {
949
- layer->removeDataDefinedProperty ( " width" );
950
- layer->removeDataDefinedProperty ( " offset" );
951
- }
952
- else
1384
+ if ( lineLayer )
953
1385
{
954
- if ( symbolWidth == 0 || qgsDoubleNear ( layer-> width (), symbolWidth ) )
1386
+ if ( dd. hasDefaultValues ( ) )
955
1387
{
956
- layer->setDataDefinedProperty ( " width" , new QgsDataDefined ( dd ) );
1388
+ lineLayer->removeDataDefinedProperty ( " width" );
1389
+ lineLayer->removeDataDefinedProperty ( " offset" );
957
1390
}
958
1391
else
959
1392
{
960
- layer->setDataDefinedProperty ( " width" , scaleWholeSymbol ( layer->width () / symbolWidth, dd ) );
961
- }
962
-
963
- if ( layer->offset () )
964
- {
965
- layer->setDataDefinedProperty ( " offset" , scaleWholeSymbol ( layer->offset () / symbolWidth, dd ) );
1393
+ if ( symbolWidth == 0 || qgsDoubleNear ( lineLayer->width (), symbolWidth ) )
1394
+ {
1395
+ lineLayer->setDataDefinedProperty ( " width" , new QgsDataDefined ( dd ) );
1396
+ }
1397
+ else
1398
+ {
1399
+ lineLayer->setDataDefinedProperty ( " width" , scaleWholeSymbol ( lineLayer->width () / symbolWidth, dd ) );
1400
+ }
1401
+
1402
+ if ( lineLayer->offset () )
1403
+ {
1404
+ lineLayer->setDataDefinedProperty ( " offset" , scaleWholeSymbol ( lineLayer->offset () / symbolWidth, dd ) );
1405
+ }
966
1406
}
967
1407
}
968
1408
}
@@ -977,8 +1417,8 @@ QgsDataDefined QgsLineSymbolV2::dataDefinedWidth() const
977
1417
// find the base of the "en masse" pattern
978
1418
for ( QgsSymbolLayerV2List::const_iterator it = mLayers .begin (); it != mLayers .end (); ++it )
979
1419
{
980
- const QgsLineSymbolLayerV2* layer = static_cast <const QgsLineSymbolLayerV2*>( *it );
981
- if ( layer->width () == symbolWidth && layer->getDataDefinedProperty ( " width" ) )
1420
+ const QgsLineSymbolLayerV2* layer = dynamic_cast <const QgsLineSymbolLayerV2*>( *it );
1421
+ if ( layer && layer ->width () == symbolWidth && layer->getDataDefinedProperty ( " width" ) )
982
1422
{
983
1423
symbolDD = layer->getDataDefinedProperty ( " width" );
984
1424
break ;
@@ -1119,11 +1559,11 @@ void QgsFillSymbolV2::renderPolygonUsingLayer( QgsSymbolLayerV2* layer, const QP
1119
1559
effect->begin ( context.renderContext () );
1120
1560
if ( layertype == QgsSymbolV2::Fill )
1121
1561
{
1122
- (( QgsFillSymbolLayerV2* ) layer )->renderPolygon ( points.translated ( -bounds.topLeft () ), translatedRings, context );
1562
+ ( static_cast < QgsFillSymbolLayerV2*>( layer ) )->renderPolygon ( points.translated ( -bounds.topLeft () ), translatedRings, context );
1123
1563
}
1124
1564
else if ( layertype == QgsSymbolV2::Line )
1125
1565
{
1126
- (( QgsLineSymbolLayerV2* ) layer )->renderPolygonOutline ( points.translated ( -bounds.topLeft () ), translatedRings, context );
1566
+ ( static_cast < QgsLineSymbolLayerV2*>( layer ) )->renderPolygonOutline ( points.translated ( -bounds.topLeft () ), translatedRings, context );
1127
1567
}
1128
1568
delete translatedRings;
1129
1569
@@ -1134,11 +1574,11 @@ void QgsFillSymbolV2::renderPolygonUsingLayer( QgsSymbolLayerV2* layer, const QP
1134
1574
{
1135
1575
if ( layertype == QgsSymbolV2::Fill )
1136
1576
{
1137
- (( QgsFillSymbolLayerV2* ) layer )->renderPolygon ( points, rings, context );
1577
+ ( static_cast < QgsFillSymbolLayerV2*>( layer ) )->renderPolygon ( points, rings, context );
1138
1578
}
1139
1579
else if ( layertype == QgsSymbolV2::Line )
1140
1580
{
1141
- (( QgsLineSymbolLayerV2* ) layer )->renderPolygonOutline ( points, rings, context );
1581
+ ( static_cast < QgsLineSymbolLayerV2*>( layer ) )->renderPolygonOutline ( points, rings, context );
1142
1582
}
1143
1583
}
1144
1584
}
@@ -1182,10 +1622,12 @@ QgsFillSymbolV2* QgsFillSymbolV2::clone() const
1182
1622
1183
1623
void QgsFillSymbolV2::setAngle ( double angle )
1184
1624
{
1185
- for ( QgsSymbolLayerV2List::iterator it = mLayers . begin (); it != mLayers . end (); ++it )
1625
+ Q_FOREACH ( QgsSymbolLayerV2* layer, mLayers )
1186
1626
{
1187
- QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
1188
- layer->setAngle ( angle );
1627
+ QgsFillSymbolLayerV2* fillLayer = dynamic_cast <QgsFillSymbolLayerV2*>( layer );
1628
+
1629
+ if ( fillLayer )
1630
+ fillLayer->setAngle ( angle );
1189
1631
}
1190
1632
}
1191
1633
0 commit comments