Skip to content

Commit bcad16d

Browse files
committed
Data defined size / color / rotation for marker export
1 parent fa509b8 commit bcad16d

9 files changed

+150
-37
lines changed

src/core/dxf/qgsdxfexport.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,19 @@ void QgsDxfExport::writeBlocks()
481481
QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > >::const_iterator slIt = slList.constBegin();
482482
for ( ; slIt != slList.constEnd(); ++slIt )
483483
{
484-
//if point symbol layer and no data defined properties: write block
485484
QgsMarkerSymbolLayerV2* ml = dynamic_cast< QgsMarkerSymbolLayerV2*>( slIt->first );
486485
if ( ml )
487486
{
487+
//if point symbol layer and no data defined properties: write block
488+
QgsRenderContext ct;
489+
QgsSymbolV2RenderContext ctx( ct, QgsSymbolV2::MapUnit, slIt->second->alpha(), false, slIt->second->renderHints(), 0 );
490+
ml->startRender( ctx );
491+
488492
//markers with data defined properties are inserted inline
489493
if ( hasDataDefinedProperties( ml, slIt->second ) )
490494
{
491495
continue;
496+
ml->stopRender( ctx );
492497
}
493498
writeGroup( 0, "BLOCK" );
494499
writeGroup( 8, 0 );
@@ -500,17 +505,18 @@ void QgsDxfExport::writeBlocks()
500505
//todo: consider anchor point
501506
double size = ml->size();
502507
size *= mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits );
503-
writeGroup( 10, size / 2.0 );
504-
writeGroup( 20, size / 2.0 );
508+
writeGroup( 10, 0 );
509+
writeGroup( 20, 0 );
505510
writeGroup( 30, 0 );
506511
writeGroup( 3, blockName );
507512

508-
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits ), "0", 0, 0 ); //maplayer 0 -> block receives layer from INSERT statement
513+
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits ), "0", &ctx, 0 ); //maplayer 0 -> block receives layer from INSERT statement
509514

510515
writeGroup( 0, "ENDBLK" );
511516
writeGroup( 8, 0 );
512517

513518
mPointSymbolBlocks.insert( ml, blockName );
519+
ml->stopRender( ctx );
514520
}
515521
}
516522
endSection();
@@ -531,17 +537,22 @@ void QgsDxfExport::writeEntities()
531537
continue;
532538
}
533539

540+
QgsRenderContext ctx;
534541
QgsFeatureRendererV2* renderer = vl->rendererV2();
542+
renderer->startRender( ctx, vl );
543+
535544
if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology && renderer->usingSymbolLevels() )
536545
{
537546
writeEntitiesSymbolLevels( vl );
547+
renderer->stopRender( ctx );
538548
continue;
539549
}
540550

541551
QgsVectorDataProvider* dp = vl->dataProvider();
542552
if ( !dp )
543553
{
544554
continue;
555+
renderer->stopRender( ctx );
545556
}
546557

547558

@@ -575,6 +586,7 @@ void QgsDxfExport::writeEntities()
575586
addFeature( fet, vl->name(), s->symbolLayer( 0 ), s );
576587
}
577588
}
589+
renderer->stopRender( ctx );
578590
}
579591

580592
endSection();
@@ -1134,8 +1146,8 @@ bool QgsDxfExport::hasDataDefinedProperties( const QgsSymbolLayerV2* sl, const Q
11341146
return false;
11351147
}
11361148

1137-
if ( symbol->renderHints() | QgsSymbolV2::DataDefinedSizeScale ||
1138-
symbol->renderHints() | QgsSymbolV2::DataDefinedRotation )
1149+
if ( symbol->renderHints() & QgsSymbolV2::DataDefinedSizeScale ||
1150+
symbol->renderHints() & QgsSymbolV2::DataDefinedRotation )
11391151
{
11401152
return true;
11411153
}

src/core/dxf/qgsdxfpaintdevice.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,12 @@ void QgsDxfPaintDevice::setLayer( const QString& layer )
8989
}
9090
}
9191

92+
void QgsDxfPaintDevice::setShift( const QPointF& shift )
93+
{
94+
if ( mPaintEngine )
95+
{
96+
mPaintEngine->setShift( shift );
97+
}
98+
}
99+
92100

src/core/dxf/qgsdxfpaintdevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class QgsDxfPaintDevice: public QPaintDevice
5050

5151
void setLayer( const QString& layer );
5252

53+
void setShift( const QPointF& shift );
54+
5355

5456
private:
5557
QgsDxfPaintEngine* mPaintEngine;

src/core/dxf/qgsdxfpaintengine.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ void QgsDxfPaintEngine::drawPixmap( const QRectF& r, const QPixmap& pm, const QR
5454

5555
void QgsDxfPaintEngine::updateState( const QPaintEngineState& state )
5656
{
57-
if ( state.state() | QPaintEngine::DirtyTransform )
57+
if ( state.state() & QPaintEngine::DirtyTransform )
5858
{
5959
mTransform = state.transform();
6060
}
61-
if ( state.state() | QPaintEngine::DirtyPen )
61+
if ( state.state() & QPaintEngine::DirtyPen )
6262
{
6363
mPen = state.pen();
6464
}
@@ -140,7 +140,7 @@ QgsPoint QgsDxfPaintEngine::toDxfCoordinates( const QPointF& pt ) const
140140
return QgsPoint( pt.x(), pt.y() );
141141
}
142142

143-
QPointF dxfPt = mPaintDevice->dxfCoordinates( mTransform.map( pt ) );
143+
QPointF dxfPt = mPaintDevice->dxfCoordinates( mTransform.map( pt ) ) + mShift;
144144
return QgsPoint( dxfPt.x(), dxfPt.y() );
145145
}
146146

src/core/dxf/qgsdxfpaintengine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class QgsDxfPaintEngine: public QPaintEngine
4646
void setLayer( const QString& layer ) { mLayer = layer; }
4747
QString layer() const { return mLayer; }
4848

49+
void setShift( const QPointF& shift ) { mShift = shift; }
50+
4951
private:
5052
const QgsDxfPaintDevice* mPaintDevice;
5153
QgsDxfExport* mDxf;
@@ -54,6 +56,7 @@ class QgsDxfPaintEngine: public QPaintEngine
5456
QTransform mTransform;
5557
QPen mPen;
5658
QString mLayer;
59+
QPointF mShift;
5760

5861
QgsPoint toDxfCoordinates( const QPointF& pt ) const;
5962
int currentPenColor() const;

src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

Lines changed: 110 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ void QgsSimpleMarkerSymbolLayerV2::drawMarker( QPainter* p, QgsSymbolV2RenderCon
702702
}
703703
}
704704

705-
void QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& offset ) const
705+
void QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift ) const
706706
{
707707
//data defined size?
708708
double size = mSize;
@@ -738,41 +738,72 @@ void QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
738738
size *= mmMapUnitScaleFactor;
739739
}
740740
double halfSize = size / 2.0;
741-
int colorIndex = QgsDxfExport::closestColorMatch( mBrush.color().rgb() );
742741

743-
//data defined size
744742

743+
QColor c = mBrush.color();
744+
QgsExpression* colorExpression = expression( "color" );
745+
if ( colorExpression )
746+
{
747+
c = QgsSymbolLayerV2Utils::decodeColor( colorExpression->evaluate( *f ).toString() );
748+
}
749+
int colorIndex = QgsDxfExport::closestColorMatch( c.rgb() );
750+
751+
//offset
752+
double offsetX = 0;
753+
double offsetY = 0;
754+
markerOffset( *context, offsetX, offsetY );
755+
QPointF off( offsetX, offsetY );
756+
757+
//angle
758+
double angle = mAngle;
759+
QgsExpression* angleExpression = expression( "angle" );
760+
if ( angleExpression )
761+
{
762+
angle = angleExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble();
763+
}
764+
angle = -angle; //rotation in Qt is counterclockwise
765+
if ( angle )
766+
off = _rotatedOffset( off, angle );
767+
768+
if ( mSizeUnit == QgsSymbolV2::MM )
769+
{
770+
off *= mmMapUnitScaleFactor;
771+
}
745772

746-
//data defined color, rotation, offset
773+
QTransform t;
774+
t.translate( shift.x() + offsetX, shift.y() + offsetY );
747775

776+
if ( angle != 0 )
777+
t.rotate( angle );
748778

779+
//data defined symbol name
749780

750781
if ( mName == "circle" )
751782
{
752783
e.writeGroup( 0, "CIRCLE" );
753784
e.writeGroup( 8, layerName );
754785

755786
e.writeGroup( 62, colorIndex );
756-
e.writeGroup( 10, halfSize + offset.x() );
757-
e.writeGroup( 20, halfSize + offset.y() );
787+
e.writeGroup( 10, halfSize + shift.x() );
788+
e.writeGroup( 20, halfSize + shift.y() );
758789
e.writeGroup( 30, 0.0 );
759790
e.writeGroup( 40, halfSize );
760791
}
761792
else if ( mName == "square" || mName == "rectangle" )
762793
{
763-
QgsPoint pt1( 0.0 + offset.x(), 0.0 + offset.y() );
764-
QgsPoint pt2( size + offset.x(), 0.0 + offset.y() );
765-
QgsPoint pt3( 0.0 + offset.x(), size + offset.y() );
766-
QgsPoint pt4( size + offset.x(), size + offset.y() );
767-
e.writeSolid( layerName, colorIndex, pt1, pt2, pt3, pt4 );
794+
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
795+
QPointF pt2 = t.map( QPointF( halfSize, -halfSize ) );
796+
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
797+
QPointF pt4 = t.map( QPointF( halfSize, halfSize ) );
798+
e.writeSolid( layerName, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
768799
}
769800
else if ( mName == "diamond" )
770801
{
771-
QgsPoint pt1( 0.0 + offset.x(), halfSize + offset.y() );
772-
QgsPoint pt2( halfSize + offset.x(), 0.0 + offset.y() );
773-
QgsPoint pt3( halfSize + offset.x(), size + offset.y() );
774-
QgsPoint pt4( size + offset.x(), halfSize + offset.y() );
775-
e.writeSolid( layerName, colorIndex, pt1, pt2, pt3, pt4 );
802+
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
803+
QPointF pt2 = t.map( QPointF( 0, -halfSize ) );
804+
QPointF pt3 = t.map( QPointF( 0, halfSize ) );
805+
QPointF pt4 = t.map( QPointF( halfSize, 0 ) );
806+
e.writeSolid( layerName, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
776807
}
777808
}
778809

@@ -1182,10 +1213,10 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::createFromSld( QDomElement &element
11821213
}
11831214

11841215
void QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f,
1185-
const QPointF& offset ) const
1216+
const QPointF& shift ) const
11861217
{
11871218
Q_UNUSED( layerName );
1188-
Q_UNUSED( offset ); //todo...
1219+
Q_UNUSED( shift ); //todo...
11891220

11901221
QSvgRenderer r( mPath );
11911222
if ( !r.isValid() )
@@ -1195,12 +1226,69 @@ void QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
11951226

11961227
QgsDxfPaintDevice pd( &e );
11971228
pd.setDrawingSize( QSizeF( r.defaultSize() ) );
1198-
double size = mSize * mmMapUnitScaleFactor ;
1199-
pd.setOutputSize( QRectF( 0, 0, size, size ) );
1200-
pd.setLayer( layerName );
1201-
QPainter p;
12021229

1230+
//size
1231+
double size = mSize;
1232+
QgsExpression* sizeExpression = expression( "size" );
1233+
bool hasDataDefinedSize = context->renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;
1234+
1235+
if ( sizeExpression )
1236+
{
1237+
size = sizeExpression->evaluate( *f ).toDouble();
1238+
}
1239+
if ( mSizeUnit == QgsSymbolV2::MM )
1240+
{
1241+
size *= mmMapUnitScaleFactor;
1242+
}
1243+
1244+
if ( hasDataDefinedSize )
1245+
{
1246+
switch ( mScaleMethod )
1247+
{
1248+
case QgsSymbolV2::ScaleArea:
1249+
size = sqrt( size );
1250+
break;
1251+
case QgsSymbolV2::ScaleDiameter:
1252+
break;
1253+
}
1254+
}
1255+
1256+
double halfSize = size / 2.0;
1257+
1258+
//offset, angle
1259+
QPointF offset = mOffset;
1260+
QgsExpression* offsetExpression = expression( "offset" );
1261+
if ( offsetExpression )
1262+
{
1263+
QString offsetString = offsetExpression->evaluate( *f ).toString();
1264+
offset = QgsSymbolLayerV2Utils::decodePoint( offsetString );
1265+
}
1266+
double offsetX = offset.x();
1267+
double offsetY = offset.y();
1268+
if ( mSizeUnit == QgsSymbolV2::MM )
1269+
{
1270+
offsetX *= mmMapUnitScaleFactor;
1271+
offsetY *= mmMapUnitScaleFactor;
1272+
}
1273+
1274+
QPointF outputOffset( offsetX, offsetY );
1275+
1276+
double angle = mAngle;
1277+
QgsExpression* angleExpression = expression( "angle" );
1278+
if ( angleExpression )
1279+
{
1280+
angle = angleExpression->evaluate( *f ).toDouble();
1281+
}
1282+
//angle = -angle; //rotation in Qt is counterclockwise
1283+
if ( angle )
1284+
outputOffset = _rotatedOffset( outputOffset, angle );
1285+
1286+
QPainter p;
12031287
p.begin( &pd );
1288+
p.rotate( angle );
1289+
pd.setShift( shift - QPointF( halfSize, halfSize ) );
1290+
pd.setOutputSize( QRectF( 0, 0, size, size ) );
1291+
pd.setLayer( layerName );
12041292
r.render( &p );
12051293
p.end();
12061294
}

src/core/symbology-ng/qgsmarkersymbollayerv2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
7676
QgsSymbolV2::OutputUnit outlineWidthUnit() const { return mOutlineWidthUnit; }
7777
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u ) { mOutlineWidthUnit = u; }
7878

79-
void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& offset = QPointF( 0.0, 0.0 ) ) const;
79+
void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const;
8080

8181
protected:
8282

@@ -159,7 +159,7 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
159159
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
160160
QgsSymbolV2::OutputUnit outputUnit() const;
161161

162-
void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& offset = QPointF( 0.0, 0.0 ) ) const;
162+
void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const;
163163

164164
protected:
165165
QString mPath;

src/core/symbology-ng/qgssymbollayerv2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void QgsMarkerSymbolLayerV2::setOutputUnit( QgsSymbolV2::OutputUnit unit )
175175
mOffsetUnit = unit;
176176
}
177177

178-
void QgsMarkerSymbolLayerV2::markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY )
178+
void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const
179179
{
180180
offsetX = mOffset.x();
181181
offsetY = mOffset.y();

src/core/symbology-ng/qgssymbollayerv2.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ class CORE_EXPORT QgsSymbolLayerV2
9494
virtual void removeDataDefinedProperties();
9595
bool hasDataDefinedProperties() const { return mDataDefinedProperties.size() > 0; }
9696

97-
virtual void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& offset = QPointF( 0.0, 0.0 ) ) const
98-
{ Q_UNUSED( e ); Q_UNUSED( mmMapUnitScaleFactor ); Q_UNUSED( layerName ); Q_UNUSED( context ); Q_UNUSED( f ); Q_UNUSED( offset ); }
97+
virtual void writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const
98+
{ Q_UNUSED( e ); Q_UNUSED( mmMapUnitScaleFactor ); Q_UNUSED( layerName ); Q_UNUSED( context ); Q_UNUSED( f ); Q_UNUSED( shift ); }
9999

100100
protected:
101101
QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false )
@@ -158,7 +158,7 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
158158

159159
protected:
160160
QgsMarkerSymbolLayerV2( bool locked = false );
161-
void markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY );
161+
void markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;
162162
static QPointF _rotatedOffset( const QPointF& offset, double angle );
163163

164164
double mAngle;

0 commit comments

Comments
 (0)