Skip to content

Commit

Permalink
dxf export: improve marker symbol export
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Jan 14, 2015
1 parent 5996014 commit 0ba232d
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 64 deletions.
6 changes: 4 additions & 2 deletions python/core/dxf/qgsdxfexport.sip
Expand Up @@ -61,7 +61,7 @@ class QgsDxfExport
void writeDouble( double d );
void writeString( const QString& s );
void writeGroup( int code, const QgsPoint &p, double z = 0.0, bool skipz = false ) /PyName=writeGroupPoint/;
void writeGroup( QColor color, int exactMatch = 62, int rgb = 420 );
void writeGroup( QColor color, int exactMatch = 62, int rgbCode = 420, int transparencyCode = 440 );

int writeHandle( int code = 5, int handle = 0 );

Expand All @@ -78,7 +78,9 @@ class QgsDxfExport

void writePoint( const QString& layer, QColor color, const QgsPoint& pt );

void writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius );
void writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius );

void writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius, const QString &lineStyleName, double width );

void writeText( const QString& layer, const QString& text, const QgsPoint& pt, double size, double angle, QColor color );

Expand Down
85 changes: 53 additions & 32 deletions src/core/dxf/qgsdxfexport.cpp
Expand Up @@ -3327,45 +3327,66 @@ void QgsDxfExport::writePoint( const QString& layer, QColor color, const QgsPoin
writeGroup( 0, pt );
}

void QgsDxfExport::writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius )
void QgsDxfExport::writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius )
{
writeGroup( 0, "CIRCLE" );
writeGroup( 0, "HATCH" ); // Entity type
writeHandle();
writeGroup( 330, mModelSpaceBR );
writeGroup( 100, "AcDbEntity" );
writeGroup( 100, "AcDbCircle" );
writeGroup( 8, layer );
writeGroup( color );
writeGroup( 0, pt );
writeGroup( 40, radius );
writeGroup( 100, "AcDbHatch" );

#if 0
writeGroup( 0, "HATCH" );
writeGroup( 8, layer ); // Layer name
writeGroup( 0, QgsPoint( 0, 0 ), 0.0 ); // Elevation point (in OCS)
writeGroup( 200, QgsPoint( 0, 0 ), 1.0 );

writeGroup( 2, "SOLID" ); // Hatch pattern name
writeGroup( 70, 1 ); // Solid fill flag (solid fill = 1; pattern fill = 0)
writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)

writeGroup( color ); // Color (0 by block, 256 by layer)

writeGroup( 91, 1 ); // Number of boundary paths (loops)

writeGroup( 92, 7 ); // Boundary path type flag (bit coded): 0 = Default; 1 = External; 2 = Polyline 4 = Derived; 8 = Textbox; 16 = Outermost
writeGroup( 72, 2 );
writeGroup( 73, 1 ); // Is closed flag
writeGroup( 93, 2 ); // Number of polyline vertices

writeGroup( 0, QgsPoint( pt.x() - radius, pt.y() ) );
writeGroup( 42, 1.0 );

writeGroup( 0, QgsPoint( pt.x() + radius, pt.y() ) );
writeGroup( 42, 1.0 );

writeGroup( 97, 0 ); // Number of source boundary objects

writeGroup( 75, 1 ); // Hatch style: 0 = Hatch "odd parity" area (Normal style), 1 = Hatch outermost area only (Outer style), 2 = Hatch through entire area (Ignore style)
writeGroup( 76, 1 ); // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
writeGroup( 47, 0.0059696789328105 ); // Pixel size

writeGroup( 98, 0 ); // Number of seed points
}

void QgsDxfExport::writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius, const QString &lineStyleName, double width )
{
writeGroup( 0, "LWPOLYLINE" );
writeHandle();
writeGroup( 330, mModelSpaceBR );
writeGroup( 100, "AcDbEntity" );
writeGroup( 100, "AcDbHatch" );
writeGroup( 8, layer );
writeGroup( 100, "AcDbEntity" );
writeGroup( 100, "AcDbPolyline" );
writeGroup( 6, lineStyleName );
writeGroup( color );
writeGroup( 0, QgsPoint( 0.0, 0.0 ) ); // elevation point
writeGroup( 200, QgsPoint( 0, 0 ), 1.0 ); // Extrusion direction
writeGroup( 2, "SOLID" ); // hatch pattern
writeGroup( 70, 1 ); // solid fill flag
writeGroup( 71, 0 ); // non-associative
writeGroup( 91, 1 ); // 1 loop
writeGroup( 92, 0 ); // Default edge type
writeGroup( 72, 2 ); // Edge type Arc
writeGroup( 93, 1 ); // Is closed

writeGroup( 0, QgsPoint( pt.x(), pt.y() ), 0.0, false ); // center point
writeGroup( 40, radius ); // radius
writeGroup( 50, 0.0 ); // start angle
writeGroup( 51, 2*M_PI ); // end angle

writeGroup( 97, 0 ); // # of source boundary objects
writeGroup( 75, 1 ); // odd parity hatch style
writeGroup( 76, 1 ); // predefined hatch pattern
writeGroup( 98, 0 ); // # of seed points
#endif

writeGroup( 90, 2 );

writeGroup( 70, 1 );
writeGroup( 43, width );

writeGroup( 0, QgsPoint( pt.x() - radius, pt.y() ) );
writeGroup( 42, 1.0 );
writeGroup( 0, QgsPoint( pt.x() + radius, pt.y() ) );
writeGroup( 42, 1.0 );
}

void QgsDxfExport::writeText( const QString& layer, const QString& text, const QgsPoint& pt, double size, double angle, QColor color )
Expand Down Expand Up @@ -3403,7 +3424,7 @@ void QgsDxfExport::writeMText( const QString& layer, const QString& text, const
writeGroup( 1, text );

writeGroup( 50, angle ); // Rotation angle in radians
writeGroup( 41, width ); // Reference rectangle width
writeGroup( 41, width * 1.1 ); // Reference rectangle width

// Attachment point:
// 1 2 3
Expand Down
6 changes: 4 additions & 2 deletions src/core/dxf/qgsdxfexport.h
Expand Up @@ -74,7 +74,7 @@ class CORE_EXPORT QgsDxfExport
void writeDouble( double d );
void writeString( const QString& s );
void writeGroup( int code, const QgsPoint &p, double z = 0.0, bool skipz = false );
void writeGroup( QColor color, int exactMatch = 62, int rgbCode = 420, int tranparencyCode = 440 );
void writeGroup( QColor color, int exactMatch = 62, int rgbCode = 420, int transparencyCode = 440 );

int writeHandle( int code = 5, int handle = 0 );

Expand All @@ -91,7 +91,9 @@ class CORE_EXPORT QgsDxfExport

void writePoint( const QString& layer, QColor color, const QgsPoint& pt );

void writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius );
void writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius );

void writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius, const QString &lineStyleName, double width );

void writeText( const QString& layer, const QString& text, const QgsPoint& pt, double size, double angle, QColor color );

Expand Down
14 changes: 8 additions & 6 deletions src/core/dxf/qgsdxfpaintengine.cpp
Expand Up @@ -20,7 +20,8 @@
#include "qgsdxfpaintdevice.h"
#include "qgslogger.h"

QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxfExport* dxf ): QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxfExport* dxf )
: QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
, mPaintDevice( dxfDevice ), mDxf( dxf )
{

Expand Down Expand Up @@ -76,14 +77,16 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF* points, int pointCount, Poly
return;
}

QgsPolyline polyline( pointCount );
QgsPolygon polygon( 1 );
polygon[0].resize( pointCount );

QgsPolyline &polyline = polygon[0];
for ( int i = 0; i < pointCount; ++i )
{
polyline[i] = toDxfCoordinates( points[i] );
}

bool closed = ( pointCount > 3 && points[0] == points[pointCount - 1] );
mDxf->writePolyline( polyline, mLayer, "CONTINUOUS", currentColor(), currentWidth(), closed );
mDxf->writePolygon( polygon, mLayer, "SOLID", currentColor() );
}

void QgsDxfPaintEngine::drawRects( const QRectF* rects, int rectCount )
Expand Down Expand Up @@ -297,7 +300,6 @@ double QgsDxfPaintEngine::power( double a, int b )
double tmp = a;
for ( int i = 2; i <= qAbs(( double )b ); i++ )
{

a *= tmp;
}
if ( b > 0 )
Expand All @@ -306,7 +308,7 @@ double QgsDxfPaintEngine::power( double a, int b )
}
else
{
return ( 1.0 / a );
return 1.0 / a;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
Expand Up @@ -696,7 +696,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
if ( qgsDoubleNear( halfWidth, halfHeight ) )
{
QPointF pt( t.map( QPointF( 0, 0 ) ) );
e.writeCircle( layerName, oc, QgsPoint( pt.x(), pt.y() ), halfWidth );
e.writeFilledCircle( layerName, oc, QgsPoint( pt.x(), pt.y() ), halfWidth );
}
else
{
Expand Down
101 changes: 80 additions & 21 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -841,15 +841,19 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
}

//color
QColor c = mPen.color();
if ( mPen.style() == Qt::NoPen )
{
c = mBrush.color();
}
QColor pc = mPen.color();
QColor bc = mBrush.color();

QgsExpression* colorExpression = expression( "color" );
if ( colorExpression )
{
c = QgsSymbolLayerV2Utils::decodeColor( colorExpression->evaluate( *f ).toString() );
bc = QgsSymbolLayerV2Utils::decodeColor( colorExpression->evaluate( *f ).toString() );
}

QgsExpression* outlinecolorExpression = expression( "outline_color" );
if ( outlinecolorExpression )
{
pc = QgsSymbolLayerV2Utils::decodeColor( outlinecolorExpression->evaluate( *f ).toString() );
}

//offset
Expand Down Expand Up @@ -884,78 +888,133 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc

if ( mName == "circle" )
{
e.writeCircle( layerName, c, QgsPoint( shift.x(), shift.y() ), halfSize );
if ( mBrush.style() != Qt::NoBrush )
e.writeFilledCircle( layerName, bc, QgsPoint( shift.x(), shift.y() ), halfSize );
if ( mPen.style() != Qt::NoPen )
e.writeCircle( layerName, pc, QgsPoint( shift.x(), shift.y() ), halfSize, "CONTINUOUS", outlineWidth );
}
else if ( mName == "square" || mName == "rectangle" )
{
// pt1 pt2
// pt3 pt4
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
QPointF pt2 = t.map( QPointF( halfSize, -halfSize ) );
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
QPointF pt4 = t.map( QPointF( halfSize, halfSize ) );
e.writeSolid( layerName, c, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );

if ( mBrush.style() != Qt::NoBrush )
e.writeSolid( layerName, bc, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt2, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt4, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt3, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
}
}
else if ( mName == "diamond" )
{
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
QPointF pt2 = t.map( QPointF( 0, -halfSize ) );
QPointF pt3 = t.map( QPointF( 0, halfSize ) );
QPointF pt4 = t.map( QPointF( halfSize, 0 ) );
e.writeSolid( layerName, c, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );

if ( mBrush.style() != Qt::NoBrush )
e.writeSolid( layerName, bc, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt2, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt3, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt4, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
}
}
else if ( mName == "triangle" )
{
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
QPointF pt2 = t.map( QPointF( halfSize, -halfSize ) );
QPointF pt3 = t.map( QPointF( 0, halfSize ) );
e.writeSolid( layerName, c, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt3.x(), pt3.y() ) );

if ( mBrush.style() != Qt::NoBrush )
e.writeSolid( layerName, bc, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt3.x(), pt3.y() ) );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt2, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( pt3, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
}
}
/*else if( mName == "equilateral_triangle" )
#if 0
else if ( mName == "equilateral_triangle" )
{

}*/
}
#endif
else if ( mName == "line" )
{
QPointF pt1 = t.map( QPointF( 0, halfSize ) );
QPointF pt2 = t.map( QPointF( 0, -halfSize ) );
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", c, outlineWidth );

if ( mPen.style() != Qt::NoPen )
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
}
else if ( mName == "coss" )
else if ( mName == "cross" )
{
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
QPointF pt4 = t.map( QPointF( 0, halfSize ) );
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", c, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ), layerName, "CONTINUOUS", c, outlineWidth );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
}
}
else if ( mName == "x" || mName == "cross2" )
{
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
QPointF pt4 = t.map( QPointF( halfSize, -halfSize ) );
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", c, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ), layerName, "CONTINUOUS", c, outlineWidth );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
}
}
else if ( mName == "arrowhead" )
{
QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
QPointF pt2 = t.map( QPointF( 0, 0 ) );
QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", c, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", c, outlineWidth );

if ( mPen.style() != Qt::NoPen )
{
e.writeLine( QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
e.writeLine( QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt2.x(), pt2.y() ), layerName, "CONTINUOUS", pc, outlineWidth );
}
}
else if ( mName == "filled_arrowhead" )
{
QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
QPointF pt2 = t.map( QPointF( 0, 0 ) );
QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
e.writeSolid( layerName, c, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt3.x(), pt3.y() ) );

if ( mBrush.style() != Qt::NoBrush )
{
e.writeSolid( layerName, bc, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt3.x(), pt3.y() ) );
}
}
else
{
return false;
}

return true;
}

Expand Down

0 comments on commit 0ba232d

Please sign in to comment.