[FEATURE]: merge dxf_export branch

This commit is contained in:
Marco Hugentobler 2013-12-06 17:46:47 +01:00
commit 561f01c0c2
24 changed files with 3013 additions and 14 deletions

View File

@ -38,6 +38,7 @@ INCLUDE_DIRECTORIES(
../src/core/pal
../src/core/composer
../src/core/diagram
../src/core/dxf
../src/core/gps
../src/core/raster
../src/core/symbology-ng

View File

@ -27,6 +27,7 @@
%Include qgsdatasourceuri.sip
%Include qgsdbfilterproxymodel.sip
%Include qgsdistancearea.sip
%Include qgsdxfexport.sip
%Include qgseditorwidgetconfig.sip
%Include qgserror.sip
%Include qgsexpression.sip

View File

@ -0,0 +1,29 @@
/***************************************************************************
qgsdxfexport.sip
----------------
begin : September 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
class QgsDxfExport
{
%TypeHeaderCode
#include <qgsdxfexport.h>
%End
public:
QgsDxfExport();
~QgsDxfExport();
void addLayers( QList< QgsMapLayer* >& layers );
int writeToFile( QIODevice* d );
};

View File

@ -157,7 +157,7 @@ class QgsMarkerSymbolLayerV2 : QgsSymbolLayerV2
protected:
QgsMarkerSymbolLayerV2( bool locked = false );
void markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY );
void markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;
static QPointF _rotatedOffset( const QPointF& offset, double angle );
};

View File

@ -27,6 +27,7 @@ SET(QGIS_APP_SRCS
qgsdecorationscalebardialog.cpp
qgsdecorationgrid.cpp
qgsdecorationgriddialog.cpp
qgsdxfexportdialog.cpp
qgsformannotationdialog.cpp
qgshtmlannotationdialog.cpp
qgsdelattrdialog.cpp
@ -190,6 +191,7 @@ SET (QGIS_APP_MOC_HDRS
qgsdelattrdialog.h
qgsdiagramproperties.h
qgsdisplayangle.h
qgsdxfexportdialog.h
qgsfeatureaction.h
qgsfieldcalculator.h
qgsfieldsproperties.h
@ -423,7 +425,7 @@ INCLUDE_DIRECTORIES(
../analysis/raster ../analysis/openstreetmap
../core
../core/gps
../core/composer ../core/raster ../core/symbology-ng
../core/composer ../core/dxf ../core/raster ../core/symbology-ng
../gui ../gui/symbology-ng ../gui/attributetable ../gui/raster ../gui/editorwidgets ../gui/editorwidgets/core
../plugins
../python

View File

@ -116,6 +116,8 @@
#include "qgscustomprojectiondialog.h"
#include "qgsdatasourceuri.h"
#include "qgsdatumtransformdialog.h"
#include "qgsdxfexport.h"
#include "qgsdxfexportdialog.h"
#include "qgsdecorationcopyright.h"
#include "qgsdecorationnortharrow.h"
#include "qgsdecorationscalebar.h"
@ -958,6 +960,7 @@ void QgisApp::createActions()
connect( mActionNewPrintComposer, SIGNAL( triggered() ), this, SLOT( newPrintComposer() ) );
connect( mActionShowComposerManager, SIGNAL( triggered() ), this, SLOT( showComposerManager() ) );
connect( mActionExit, SIGNAL( triggered() ), this, SLOT( fileExit() ) );
connect( mActionDxfExport, SIGNAL( triggered() ), this, SLOT( dxfExport() ) );
// Edit Menu Items
@ -3808,6 +3811,54 @@ void QgisApp::fileSaveAs()
}
} // QgisApp::fileSaveAs
void QgisApp::dxfExport()
{
QgsLegend* mapLegend = legend();
if ( !mapLegend )
{
return;
}
QgsDxfExportDialog d( mapLegend->layers() );
if ( d.exec() == QDialog::Accepted )
{
QgsDxfExport dxfExport;
QList<QgsMapLayer*> layerList;
QList<QString> layerIdList = d.layers();
QList<QString>::const_iterator layerIt = layerIdList.constBegin();
for ( ; layerIt != layerIdList.constEnd(); ++layerIt )
{
QgsMapLayer* l = QgsMapLayerRegistry::instance()->mapLayer( *layerIt );
if ( l )
{
layerList.append( l );
}
}
dxfExport.addLayers( layerList );
dxfExport.setSymbologyScaleDenominator( d.symbologyScale() );
dxfExport.setSymbologyExport( d.symbologyMode() );
if ( mapCanvas() )
{
QgsMapRenderer* r = mapCanvas()->mapRenderer();
if ( r )
{
dxfExport.setMapUnits( r->mapUnits() );
}
}
QFile dxfFile( d.saveFile() );
if ( dxfExport.writeToFile( &dxfFile ) == 0 )
{
messageBar()->pushMessage( tr( "DXF export completed" ), QgsMessageBar::INFO, 4 );
}
else
{
messageBar()->pushMessage( tr( "DXF export failed" ), QgsMessageBar::CRITICAL, 4 );
}
}
}
// Open the project file corresponding to the
// path at the given index in mRecentProjectPaths
void QgisApp::openProject( QAction *action )
@ -7430,7 +7481,7 @@ QMenu* QgisApp::getPluginMenu( QString menuName )
}
// It doesn't exist, so create
QMenu *menu = new QMenu( menuName, this );
menu->setObjectName( menuName.normalized(QString::NormalizationForm_KD).remove(QRegExp("[^a-zA-Z]")) );
menu->setObjectName( menuName.normalized( QString::NormalizationForm_KD ).remove( QRegExp( "[^a-zA-Z]" ) ) );
// Where to put it? - we worked that out above...
mPluginMenu->insertMenu( before, menu );

View File

@ -838,6 +838,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
bool fileSave();
//! Save project as
void fileSaveAs();
//! Export project in dxf format
void dxfExport();
//! Open the project file corresponding to the
//! text)= of the given action.
void openProject( QAction *action );

View File

@ -0,0 +1,119 @@
#include "qgsdxfexportdialog.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
#include "qgis.h"
#include <QFileDialog>
#include <QPushButton>
#include <QSettings>
QgsDxfExportDialog::QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
{
setupUi( this );
connect( mFileLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( setOkEnabled() ) );
connect( this, SIGNAL( accepted() ), this, SLOT( saveSettings() ) );
QList<QgsMapLayer*>::const_iterator layerIt = layerKeys.constBegin();
for ( ; layerIt != layerKeys.constEnd(); ++layerIt )
{
QgsMapLayer* layer = *layerIt;
if ( layer )
{
if ( layer->type() == QgsMapLayer::VectorLayer )
{
QListWidgetItem* layerItem = new QListWidgetItem( layer->name() );
layerItem->setData( Qt::UserRole, layer->id() );
layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
layerItem->setCheckState( Qt::Checked );
mLayersListWidget->addItem( layerItem );
}
}
}
//last dxf symbology mode
QSettings s;
mSymbologyModeComboBox->setCurrentIndex( s.value( "qgis/lastDxfSymbologyMode", "2" ).toInt() );
//last symbol scale
mSymbologyScaleLineEdit->setText( s.value( "qgis/lastSymbologyExportScale", "50000" ).toString() );
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
}
QgsDxfExportDialog::~QgsDxfExportDialog()
{
}
QList<QString> QgsDxfExportDialog::layers() const
{
QList<QString> layerKeyList;
int nItems = mLayersListWidget->count();
for ( int i = 0; i < nItems; ++i )
{
QListWidgetItem* currentItem = mLayersListWidget->item( i );
if ( currentItem->checkState() == Qt::Checked )
{
layerKeyList.prepend( currentItem->data( Qt::UserRole ).toString() );
}
}
return layerKeyList;
}
double QgsDxfExportDialog::symbologyScale() const
{
double scale = mSymbologyScaleLineEdit->text().toDouble();
if ( qgsDoubleNear( scale, 0.0 ) )
{
return 1.0;
}
return scale;
}
QString QgsDxfExportDialog::saveFile() const
{
return mFileLineEdit->text();
}
QgsDxfExport::SymbologyExport QgsDxfExportDialog::symbologyMode() const
{
return ( QgsDxfExport::SymbologyExport )mSymbologyModeComboBox->currentIndex();
}
void QgsDxfExportDialog::on_mFileSelectionButton_clicked()
{
//get last dxf save directory
QSettings s;
QString lastSavePath = s.value( "qgis/lastDxfDir" ).toString();
QString filePath = QFileDialog::getSaveFileName( 0, tr( "Export as DXF" ), lastSavePath, tr( "DXF files *.dxf *.DXF" ) );
if ( !filePath.isEmpty() )
{
mFileLineEdit->setText( filePath );
}
}
void QgsDxfExportDialog::setOkEnabled()
{
QPushButton* btn = buttonBox->button( QDialogButtonBox::Ok );
QString filePath = mFileLineEdit->text();
if ( filePath.isEmpty() )
{
btn->setEnabled( false );
}
QFileInfo fi( filePath );
btn->setEnabled( fi.absoluteDir().exists() );
}
void QgsDxfExportDialog::saveSettings()
{
QSettings s;
//last dxf dir
QFileInfo dxfFileInfo( mFileLineEdit->text() );
s.setValue( "qgis/lastDxfDir", dxfFileInfo.absolutePath() );
//last dxf symbology mode
s.setValue( "qgis/lastDxfSymbologyMode", mSymbologyModeComboBox->currentIndex() );
s.setValue( "qgis/lastSymbologyExportScale", mSymbologyScaleLineEdit->text() );
}

View File

@ -0,0 +1,25 @@
#ifndef QGSDXFEXPORTDIALOG_H
#define QGSDXFEXPORTDIALOG_H
#include "ui_qgsdxfexportdialogbase.h"
#include "qgsdxfexport.h"
class QgsDxfExportDialog: public QDialog, private Ui::QgsDxfExportDialogBase
{
Q_OBJECT
public:
QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsDxfExportDialog();
QList<QString> layers() const;
double symbologyScale() const;
QgsDxfExport::SymbologyExport symbologyMode() const;
QString saveFile() const;
private slots:
void on_mFileSelectionButton_clicked();
void setOkEnabled();
void saveSettings();
};
#endif // QGSDXFEXPORTDIALOG_H

View File

@ -162,6 +162,10 @@ SET(QGIS_CORE_SRCS
composer/qgscomposerhtml.cpp
composer/qgscomposermultiframe.cpp
composer/qgscomposition.cpp
dxf/qgsdxfexport.cpp
dxf/qgsdxfpaintdevice.cpp
dxf/qgsdxfpaintengine.cpp
pal/costcalculator.cpp
pal/feature.cpp
@ -556,6 +560,7 @@ ENDIF (QT_MOBILITY_LOCATION_FOUND)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
composer
dxf
pal
raster
renderer

File diff suppressed because it is too large Load Diff

160
src/core/dxf/qgsdxfexport.h Normal file
View File

@ -0,0 +1,160 @@
/***************************************************************************
qgsdxfexport.h
--------------
begin : September 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDXFEXPORT_H
#define QGSDXFEXPORT_H
#include "qgsgeometry.h"
#include "qgssymbolv2.h"
#include <QColor>
#include <QList>
#include <QTextStream>
class QgsMapLayer;
class QgsPoint;
class QgsSymbolLayerV2;
class QIODevice;
class CORE_EXPORT QgsDxfExport
{
public:
enum SymbologyExport
{
NoSymbology = 0, //export only data
FeatureSymbology, //Keeps the number of features and export symbology per feature (using the first symbol level)
SymbolLayerSymbology //Exports one feature per symbol layer (considering symbol levels)
};
QgsDxfExport();
QgsDxfExport( const QgsDxfExport& dxfExport );
~QgsDxfExport();
QgsDxfExport& operator=( const QgsDxfExport& dxfExport );
void addLayers( QList< QgsMapLayer* >& layers ) { mLayers = layers; }
int writeToFile( QIODevice* d ); //maybe add progress dialog? //other parameters (e.g. scale, dpi)?
void setSymbologyScaleDenominator( double d ) { mSymbologyScaleDenominator = d; }
double symbologyScaleDenominator() const { return mSymbologyScaleDenominator; }
void setMapUnits( QGis::UnitType u ) { mMapUnits = u; }
QGis::UnitType mapUnits() const { return mMapUnits; }
void setSymbologyExport( SymbologyExport e ) { mSymbologyExport = e; }
SymbologyExport symbologyExport() const { return mSymbologyExport; }
//get closest entry in dxf palette
static int closestColorMatch( QRgb pixel );
void writeGroup( int code, int i );
void writeGroup( int code, double d );
void writeGroup( int code, const QString& s );
void writeGroupCode( int code );
void writeInt( int i );
void writeDouble( double d );
void writeString( const QString& s );
//draw dxf primitives
void writePolyline( const QgsPolyline& line, const QString& layer, const QString& lineStyleName, int color,
double width = -1, bool polygon = false );
void writeSolid( const QString& layer, int color, const QgsPoint& pt1, const QgsPoint& pt2, const QgsPoint& pt3, const QgsPoint& pt4 );
//write line (as a polyline)
void writeLine( const QgsPoint& pt1, const QgsPoint& pt2, const QString& layer, const QString& lineStyleName, int color, double width = -1 );
void writePoint( const QString& layer, int color, const QgsPoint& pt );
void writeCircle( const QString& layer, int color, const QgsPoint& pt, double radius );
private:
QList< QgsMapLayer* > mLayers;
/**Scale for symbology export (used if symbols units are mm)*/
double mSymbologyScaleDenominator;
SymbologyExport mSymbologyExport;
QGis::UnitType mMapUnits;
QTextStream mTextStream;
static double mDxfColors[][3];
int mSymbolLayerCounter; //internal counter
int mNextHandleId;
int mBlockCounter;
QHash< const QgsSymbolLayerV2*, QString > mLineStyles; //symbol layer name types
QHash< const QgsSymbolLayerV2*, QString > mPointSymbolBlocks; //reference to point symbol blocks
//AC1009
void writeHeader();
void writeTables();
void writeBlocks();
void writeEntities();
void writeEntitiesSymbolLevels( QgsVectorLayer* layer );
void writeEndFile();
void startSection();
void endSection();
void writePoint( const QgsPoint& pt, const QString& layer, int color, const QgsFeature* f, const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2* symbol );
void writeVertex( const QgsPoint& pt, const QString& layer );
void writeDefaultLinestyles();
void writeSymbolLayerLinestyle( const QgsSymbolLayerV2* symbolLayer );
void writeLinestyle( const QString& styleName, const QVector<qreal>& pattern, QgsSymbolV2::OutputUnit u );
//AC1018
void writeHeaderAC1018( QTextStream& stream );
void writeTablesAC1018( QTextStream& stream );
void writeEntitiesAC1018( QTextStream& stream );
void writeEntitiesSymbolLevelsAC1018( QTextStream& stream, QgsVectorLayer* layer );
void writeSymbolLayerLinestyleAC1018( QTextStream& stream, const QgsSymbolLayerV2* symbolLayer );
void writeLinestyleAC1018( QTextStream& stream, const QString& styleName, const QVector<qreal>& pattern, QgsSymbolV2::OutputUnit u );
void writeVertexAC1018( QTextStream& stream, const QgsPoint& pt );
void writePolylineAC1018( QTextStream& stream, const QgsPolyline& line, const QString& layer, const QString& lineStyleName, int color,
double width = -1, bool polygon = false );
QgsRectangle dxfExtent() const;
void addFeature( const QgsFeature& fet, const QString& layer, const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2* symbol );
double scaleToMapUnits( double value, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits ) const;
//returns dxf palette index from symbol layer color
static int colorFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer );
double widthFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer ) const;
QString lineStyleFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer );
//functions for dxf palette
static int color_distance( QRgb p1, int index );
static QRgb createRgbEntry( qreal r, qreal g, qreal b );
//helper functions for symbology export
QgsRenderContext renderContext() const;
void startRender( QgsVectorLayer* vl ) const;
void stopRender( QgsVectorLayer* vl ) const;
static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits );
QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > > symbolLayers();
static int nLineTypes( const QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2*> >& symbolLayers );
static bool hasDataDefinedProperties( const QgsSymbolLayerV2* sl, const QgsSymbolV2* symbol );
double dashSize() const;
double dotSize() const;
double dashSeparatorSize() const;
double sizeToMapUnits( double s ) const;
static QString lineNameFromPenStyle( Qt::PenStyle style );
};
#endif // QGSDXFEXPORT_H

View File

@ -0,0 +1,100 @@
/***************************************************************************
qgsdxpaintdevice.cpp
--------------------
begin : November 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdxfpaintdevice.h"
QgsDxfPaintDevice::QgsDxfPaintDevice( QgsDxfExport* dxf ): QPaintDevice(), mPaintEngine( 0 )
{
mPaintEngine = new QgsDxfPaintEngine( this, dxf );
}
QgsDxfPaintDevice::~QgsDxfPaintDevice()
{
delete mPaintEngine;
}
QPaintEngine* QgsDxfPaintDevice::paintEngine() const
{
return mPaintEngine;
}
int QgsDxfPaintDevice::metric( PaintDeviceMetric metric ) const
{
switch ( metric )
{
case QPaintDevice::PdmWidth:
return mDrawingSize.width();
case QPaintDevice::PdmHeight:
return mDrawingSize.height();
case QPaintDevice::PdmWidthMM:
return mDrawingSize.width();
case QPaintDevice::PdmHeightMM:
return mDrawingSize.height();
case QPaintDevice::PdmNumColors:
return INT_MAX;
case QPaintDevice::PdmDepth:
return 32;
case QPaintDevice::PdmDpiX:
case QPaintDevice::PdmDpiY:
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmPhysicalDpiY:
return 96;
}
return 0;
}
double QgsDxfPaintDevice::widthScaleFactor() const
{
if ( !mDrawingSize.isValid() || mRectangle.isEmpty() )
{
return 1.0;
}
double widthFactor = mRectangle.width() / mDrawingSize.width();
double heightFactor = mRectangle.height() / mDrawingSize.height();
return ( widthFactor + heightFactor ) / 2.0;
}
QPointF QgsDxfPaintDevice::dxfCoordinates( const QPointF& pt ) const
{
if ( !mDrawingSize.isValid() || mRectangle.isEmpty() )
{
return QPointF( pt.x(), pt.y() );
}
double x = mRectangle.left() + pt.x() * ( mRectangle.width() / mDrawingSize.width() );
double y = mRectangle.bottom() - pt.y() * ( mRectangle.height() / mDrawingSize.height() );
return QPointF( x, y );
}
void QgsDxfPaintDevice::setLayer( const QString& layer )
{
if ( mPaintEngine )
{
mPaintEngine->setLayer( layer );
}
}
void QgsDxfPaintDevice::setShift( const QPointF& shift )
{
if ( mPaintEngine )
{
mPaintEngine->setShift( shift );
}
}

View File

@ -0,0 +1,63 @@
/***************************************************************************
qgsdxpaintdevice.h
------------------
begin : November 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDXFPAINTDEVICE_H
#define QGSDXFPAINTDEVICE_H
#include <QPaintDevice>
#include "qgsdxfpaintengine.h"
class QgsDxfExport;
class QPaintEngine;
/**A paint device for drawing into dxf files*/
class CORE_EXPORT QgsDxfPaintDevice: public QPaintDevice
{
public:
QgsDxfPaintDevice( QgsDxfExport* dxf );
~QgsDxfPaintDevice();
QPaintEngine* paintEngine() const;
void setDrawingSize( const QSizeF& size ) { mDrawingSize = size; }
void setOutputSize( const QRectF& r ) { mRectangle = r; }
/**Returns scale factor for line width*/
double widthScaleFactor() const;
/**Converts a point from device coordinates to dxf coordinates*/
QPointF dxfCoordinates( const QPointF& pt ) const;
/*int height() const { return mDrawingSize.height(); }
int width() const { return mDrawingSize.width(); }*/
int metric( PaintDeviceMetric metric ) const;
void setLayer( const QString& layer );
void setShift( const QPointF& shift );
private:
QgsDxfPaintEngine* mPaintEngine;
QSizeF mDrawingSize; //size (in source coordinates)
QRectF mRectangle; //size (in dxf coordinates)
};
#endif // QGSDXFPAINTDEVICE_H

View File

@ -0,0 +1,171 @@
/***************************************************************************
qgsdxpaintengine.cpp
--------------------
begin : November 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdxfpaintengine.h"
#include "qgsdxfexport.h"
#include "qgsdxfpaintdevice.h"
#include "qgslogger.h"
QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxfExport* dxf ): QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
, mPaintDevice( dxfDevice ), mDxf( dxf )
{
}
QgsDxfPaintEngine::~QgsDxfPaintEngine()
{
}
bool QgsDxfPaintEngine::begin( QPaintDevice* pdev )
{
Q_UNUSED( pdev );
return true;
}
bool QgsDxfPaintEngine::end()
{
return true;
}
QPaintEngine::Type QgsDxfPaintEngine::type() const
{
return QPaintEngine::User;
}
void QgsDxfPaintEngine::drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr )
{
Q_UNUSED( r ); Q_UNUSED( pm ); Q_UNUSED( sr );
}
void QgsDxfPaintEngine::updateState( const QPaintEngineState& state )
{
if ( state.state() & QPaintEngine::DirtyTransform )
{
mTransform = state.transform();
}
if ( state.state() & QPaintEngine::DirtyPen )
{
mPen = state.pen();
}
}
void QgsDxfPaintEngine::drawPolygon( const QPointF* points, int pointCount, PolygonDrawMode mode )
{
if ( !mDxf || !mPaintDevice )
{
return;
}
QgsPolyline polyline( pointCount );
for ( int i = 0; i < pointCount; ++i )
{
polyline[i] = toDxfCoordinates( points[i] );
}
mDxf->writePolyline( polyline, mLayer, "CONTINUOUS", currentPenColor(), currentWidth(), mode != QPaintEngine::PolylineMode );
}
void QgsDxfPaintEngine::drawRects( const QRectF* rects, int rectCount )
{
if ( !mDxf || !mPaintDevice || !rects )
{
return;
}
for ( int i = 0; i < rectCount; ++i )
{
double left = rects[i].left();
double right = rects[i].right();
double top = rects[i].top();
double bottom = rects[i].bottom();
QgsPoint pt1 = toDxfCoordinates( QPointF( left, bottom ) );
QgsPoint pt2 = toDxfCoordinates( QPointF( right, bottom ) );
QgsPoint pt3 = toDxfCoordinates( QPointF( left, top ) );
QgsPoint pt4 = toDxfCoordinates( QPointF( right, top ) );
mDxf->writeSolid( mLayer, currentPenColor(), pt1, pt2, pt3, pt4 );
}
}
void QgsDxfPaintEngine::drawEllipse( const QRectF& rect )
{
QPoint midPoint(( rect.left() + rect.right() ) / 2.0, ( rect.top() + rect.bottom() ) / 2.0 );
//a circle
if ( qgsDoubleNear( rect.width(), rect.height() ) )
{
mDxf->writeCircle( mLayer, currentPenColor(), toDxfCoordinates( midPoint ), rect.width() / 2.0 );
}
//todo: create polyline for real ellises
}
void QgsDxfPaintEngine::drawPath( const QPainterPath& path )
{
QList<QPolygonF> polygonList = path.toFillPolygons();
QList<QPolygonF>::const_iterator pIt = polygonList.constBegin();
for ( ; pIt != polygonList.constEnd(); ++pIt )
{
drawPolygon( pIt->constData(), pIt->size(), pIt->isClosed() ? QPaintEngine::OddEvenMode : QPaintEngine::PolylineMode );
}
}
void QgsDxfPaintEngine::drawLines( const QLineF* lines, int lineCount )
{
if ( !mDxf || !mPaintDevice || !lines )
{
return;
}
for ( int i = 0; i < lineCount; ++i )
{
QgsPoint pt1 = toDxfCoordinates( lines[i].p1() );
QgsPoint pt2 = toDxfCoordinates( lines[i].p2() );
mDxf->writeLine( pt1, pt2, mLayer, "CONTINUOUS", currentPenColor(), currentWidth() );
}
}
QgsPoint QgsDxfPaintEngine::toDxfCoordinates( const QPointF& pt ) const
{
if ( !mPaintDevice || !mDxf )
{
return QgsPoint( pt.x(), pt.y() );
}
QPointF dxfPt = mPaintDevice->dxfCoordinates( mTransform.map( pt ) ) + mShift;
return QgsPoint( dxfPt.x(), dxfPt.y() );
}
int QgsDxfPaintEngine::currentPenColor() const
{
if ( !mDxf )
{
return 0;
}
return mDxf->closestColorMatch( mPen.color().rgb() );
}
double QgsDxfPaintEngine::currentWidth() const
{
if ( !mPaintDevice )
{
return 1;
}
return mPen.widthF() * mPaintDevice->widthScaleFactor();
}

View File

@ -0,0 +1,66 @@
/***************************************************************************
qgsdxpaintengine.h
------------------
begin : November 2013
copyright : (C) 2013 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDXFPAINTENGINE_H
#define QGSDXFPAINTENGINE_H
#include <QPaintEngine>
class QgsDxfExport;
class QgsDxfPaintDevice;
class QgsPoint;
class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
{
public:
QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxfExport* dxf );
~QgsDxfPaintEngine();
bool begin( QPaintDevice* pdev );
bool end();
QPaintEngine::Type type() const;
void updateState( const QPaintEngineState& state );
void drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr );
void drawPolygon( const QPointF * points, int pointCount, PolygonDrawMode mode );
void drawRects( const QRectF * rects, int rectCount );
void drawEllipse( const QRectF& rect );
void drawPath( const QPainterPath& path );
void drawLines( const QLineF* lines, int lineCount );
void setLayer( const QString& layer ) { mLayer = layer; }
QString layer() const { return mLayer; }
void setShift( const QPointF& shift ) { mShift = shift; }
private:
const QgsDxfPaintDevice* mPaintDevice;
QgsDxfExport* mDxf;
//painter state information
QTransform mTransform;
QPen mPen;
QString mLayer;
QPointF mShift;
QgsPoint toDxfCoordinates( const QPointF& pt ) const;
int currentPenColor() const;
double currentWidth() const;
};
#endif // QGSDXFPAINTENGINE_H

View File

@ -13,6 +13,7 @@
* *
***************************************************************************/
#include "qgsellipsesymbollayerv2.h"
#include "qgsdxfexport.h"
#include "qgsexpression.h"
#include "qgsfeature.h"
#include "qgsrendercontext.h"
@ -492,3 +493,139 @@ QgsSymbolV2::OutputUnit QgsEllipseSymbolLayerV2::outputUnit() const
}
return unit;
}
bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift ) const
{
//width
double symbolWidth = mSymbolWidth;
QgsExpression* widthExpression = expression( "width" );
if ( widthExpression ) //1. priority: data defined setting on symbol layer level
{
symbolWidth = widthExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
}
else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
{
symbolWidth = mSize;
}
if ( mSymbolWidthUnit == QgsSymbolV2::MM )
{
symbolWidth *= mmMapUnitScaleFactor;
}
//height
double symbolHeight = mSymbolHeight;
QgsExpression* heightExpression = expression( "height" );
if ( heightExpression ) //1. priority: data defined setting on symbol layer level
{
symbolHeight = heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
}
else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
{
symbolHeight = mSize;
}
if ( mSymbolHeightUnit == QgsSymbolV2::MM )
{
symbolHeight *= mmMapUnitScaleFactor;
}
//outline width
double outlineWidth = mOutlineWidth;
QgsExpression* outlineWidthExpression = expression( "outline_width" );
if ( outlineWidthExpression )
{
outlineWidth = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble();
}
if ( mOutlineWidthUnit == QgsSymbolV2::MM )
{
outlineWidth *= outlineWidth;
}
//color
QColor c = mFillColor;
QgsExpression* fillColorExpression = expression( "fill_color" );
if ( fillColorExpression )
{
c = QColor( fillColorExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toString() );
}
int colorIndex = e.closestColorMatch( c.rgb() );
//symbol name
QString symbolName = mSymbolName;
QgsExpression* symbolNameExpression = expression( "symbol_name" );
if ( symbolNameExpression )
{
QgsExpression* symbolNameExpression = expression( "symbol_name" );
symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toString();
}
//offset
double offsetX = 0;
double offsetY = 0;
markerOffset( *context, offsetX, offsetY );
QPointF off( offsetX, offsetY );
//priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
double rotation = 0.0;
QgsExpression* rotationExpression = expression( "rotation" );
if ( rotationExpression )
{
rotation = rotationExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble();
}
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
{
rotation = mAngle;
}
rotation = -rotation; //rotation in Qt is counterclockwise
if ( rotation )
off = _rotatedOffset( off, rotation );
QTransform t;
t.translate( shift.x() + offsetX, shift.y() + offsetY );
if ( rotation != 0 )
t.rotate( rotation );
double halfWidth = symbolWidth / 2.0;
double halfHeight = symbolHeight / 2.0;
if ( symbolName == "circle" )
{
//soon...
}
else if ( symbolName == "rectangle" )
{
QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
QPointF pt3( t.map( QPointF( -halfWidth, halfHeight ) ) );
QPointF pt4( t.map( QPointF( halfWidth, halfHeight ) ) );
e.writeSolid( layerName, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
return true;
}
else if ( symbolName == "cross" )
{
QgsPolyline line1( 2 );
QPointF pt1( t.map( QPointF( -halfWidth, 0 ) ) );
QPointF pt2( t.map( QPointF( halfWidth, 0 ) ) );
line1[0] = QgsPoint( pt1.x(), pt1.y() );
line1[1] = QgsPoint( pt2.x(), pt2.y() );
e.writePolyline( line1, layerName, "CONTINUOUS", colorIndex, outlineWidth, false );
QgsPolyline line2( 2 );
QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
QPointF pt4( t.map( QPointF( 0, -halfHeight ) ) );
line2[0] = QgsPoint( pt3.x(), pt3.y() );
line2[1] = QgsPoint( pt3.x(), pt3.y() );
e.writePolyline( line2, layerName, "CONTINUOUS", colorIndex, outlineWidth, false );
return true;
}
else if ( symbolName == "triangle" )
{
QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
QPointF pt4( t.map( QPointF( 0, halfHeight ) ) );
e.writeSolid( layerName, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
return true;
}
return false; //soon...
}

View File

@ -40,6 +40,8 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const;
void writeSldMarker( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const;
bool writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const;
void setSymbolName( const QString& name ) { mSymbolName = name; }
QString symbolName() const { return mSymbolName; }

View File

@ -16,6 +16,8 @@
#include "qgsmarkersymbollayerv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsdxfexport.h"
#include "qgsdxfpaintdevice.h"
#include "qgsexpression.h"
#include "qgsrendercontext.h"
#include "qgslogger.h"
@ -721,6 +723,116 @@ void QgsSimpleMarkerSymbolLayerV2::drawMarker( QPainter* p, QgsSymbolV2RenderCon
}
}
bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift ) const
{
//data defined size?
double size = mSize;
QgsExpression *sizeExpression = expression( "size" );
bool hasDataDefinedSize = false;
if ( context )
{
hasDataDefinedSize = context->renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;
}
//data defined size
if ( hasDataDefinedSize )
{
if ( sizeExpression )
{
size = sizeExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble();
}
size *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context->renderContext(), mSizeUnit );
switch ( mScaleMethod )
{
case QgsSymbolV2::ScaleArea:
size = sqrt( size );
break;
case QgsSymbolV2::ScaleDiameter:
break;
}
}
if ( mSizeUnit == QgsSymbolV2::MM )
{
size *= mmMapUnitScaleFactor;
}
double halfSize = size / 2.0;
QColor c = mBrush.color();
QgsExpression* colorExpression = expression( "color" );
if ( colorExpression )
{
c = QgsSymbolLayerV2Utils::decodeColor( colorExpression->evaluate( *f ).toString() );
}
int colorIndex = QgsDxfExport::closestColorMatch( c.rgb() );
//offset
double offsetX = 0;
double offsetY = 0;
markerOffset( *context, offsetX, offsetY );
QPointF off( offsetX, offsetY );
//angle
double angle = mAngle;
QgsExpression* angleExpression = expression( "angle" );
if ( angleExpression )
{
angle = angleExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble();
}
angle = -angle; //rotation in Qt is counterclockwise
if ( angle )
off = _rotatedOffset( off, angle );
if ( mSizeUnit == QgsSymbolV2::MM )
{
off *= mmMapUnitScaleFactor;
}
QTransform t;
t.translate( shift.x() + offsetX, shift.y() + offsetY );
if ( angle != 0 )
t.rotate( angle );
//data defined symbol name
if ( mName == "circle" )
{
e.writeGroup( 0, "CIRCLE" );
e.writeGroup( 8, layerName );
e.writeGroup( 62, colorIndex );
e.writeGroup( 10, halfSize + shift.x() );
e.writeGroup( 20, halfSize + shift.y() );
e.writeGroup( 30, 0.0 );
e.writeGroup( 40, halfSize );
}
else if ( mName == "square" || mName == "rectangle" )
{
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, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
}
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, colorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) );
}
else
{
return false;
}
return true;
}
//////////
@ -1143,6 +1255,93 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::createFromSld( QDomElement &element
return m;
}
bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f,
const QPointF& shift ) const
{
Q_UNUSED( layerName );
Q_UNUSED( shift ); //todo...
QSvgRenderer r( mPath );
if ( !r.isValid() )
{
return false;
}
QgsDxfPaintDevice pd( &e );
pd.setDrawingSize( QSizeF( r.defaultSize() ) );
//size
double size = mSize;
QgsExpression* sizeExpression = expression( "size" );
bool hasDataDefinedSize = context->renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression;
if ( sizeExpression )
{
size = sizeExpression->evaluate( *f ).toDouble();
}
if ( mSizeUnit == QgsSymbolV2::MM )
{
size *= mmMapUnitScaleFactor;
}
if ( hasDataDefinedSize )
{
switch ( mScaleMethod )
{
case QgsSymbolV2::ScaleArea:
size = sqrt( size );
break;
case QgsSymbolV2::ScaleDiameter:
break;
}
}
double halfSize = size / 2.0;
//offset, angle
QPointF offset = mOffset;
QgsExpression* offsetExpression = expression( "offset" );
if ( offsetExpression )
{
QString offsetString = offsetExpression->evaluate( *f ).toString();
offset = QgsSymbolLayerV2Utils::decodePoint( offsetString );
}
double offsetX = offset.x();
double offsetY = offset.y();
if ( mSizeUnit == QgsSymbolV2::MM )
{
offsetX *= mmMapUnitScaleFactor;
offsetY *= mmMapUnitScaleFactor;
}
QPointF outputOffset( offsetX, offsetY );
double angle = mAngle;
QgsExpression* angleExpression = expression( "angle" );
if ( angleExpression )
{
angle = angleExpression->evaluate( *f ).toDouble();
}
//angle = -angle; //rotation in Qt is counterclockwise
if ( angle )
outputOffset = _rotatedOffset( outputOffset, angle );
QPainter p;
p.begin( &pd );
if ( !qgsDoubleNear( angle, 0.0 ) )
{
p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
p.rotate( angle );
p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
}
pd.setShift( shift );
pd.setOutputSize( QRectF( -halfSize, -halfSize, size, size ) );
pd.setLayer( layerName );
r.render( &p );
p.end();
return true;
}
//////////
QgsFontMarkerSymbolLayerV2::QgsFontMarkerSymbolLayerV2( QString fontFamily, QChar chr, double pointSize, QColor color, double angle )

View File

@ -76,6 +76,8 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QgsSymbolV2::OutputUnit outlineWidthUnit() const { return mOutlineWidthUnit; }
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u ) { mOutlineWidthUnit = u; }
bool writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const;
protected:
void drawMarker( QPainter* p, QgsSymbolV2RenderContext& context );
@ -157,6 +159,8 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;
bool writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const;
protected:
QString mPath;

View File

@ -34,10 +34,10 @@ const QgsExpression* QgsSymbolLayerV2::dataDefinedProperty( const QString& prope
return 0;
}
QgsExpression* QgsSymbolLayerV2::expression( const QString& property )
QgsExpression* QgsSymbolLayerV2::expression( const QString& property ) const
{
QMap< QString, QgsExpression* >::iterator it = mDataDefinedProperties.find( property );
if ( it != mDataDefinedProperties.end() )
QMap< QString, QgsExpression* >::const_iterator it = mDataDefinedProperties.find( property );
if ( it != mDataDefinedProperties.constEnd() )
{
return it.value();
}
@ -180,14 +180,14 @@ void QgsMarkerSymbolLayerV2::setOutputUnit( QgsSymbolV2::OutputUnit unit )
mOffsetUnit = unit;
}
void QgsMarkerSymbolLayerV2::markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY )
void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const
{
markerOffset( context, mSize, mSize, mSizeUnit, mSizeUnit, offsetX, offsetY );
}
void QgsMarkerSymbolLayerV2::markerOffset( QgsSymbolV2RenderContext& context, double width, double height,
void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double width, double height,
QgsSymbolV2::OutputUnit widthUnit, QgsSymbolV2::OutputUnit heightUnit,
double& offsetX, double& offsetY )
double& offsetX, double& offsetY ) const
{
offsetX = mOffset.x();
offsetY = mOffset.y();

View File

@ -38,6 +38,7 @@ class QPainter;
class QSize;
class QPolygonF;
class QgsDxfExport;
class QgsExpression;
class QgsRenderContext;
@ -91,6 +92,10 @@ class CORE_EXPORT QgsSymbolLayerV2
virtual void setDataDefinedProperty( const QString& property, const QString& expressionString );
virtual void removeDataDefinedProperty( const QString& property );
virtual void removeDataDefinedProperties();
bool hasDataDefinedProperties() const { return mDataDefinedProperties.size() > 0; }
virtual bool writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift = QPointF( 0.0, 0.0 ) ) const
{ Q_UNUSED( e ); Q_UNUSED( mmMapUnitScaleFactor ); Q_UNUSED( layerName ); Q_UNUSED( context ); Q_UNUSED( f ); Q_UNUSED( shift ); return false; }
protected:
QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false )
@ -109,7 +114,8 @@ class CORE_EXPORT QgsSymbolLayerV2
static const bool selectFillStyle = false; // Fill symbol uses symbol layer style..
virtual void prepareExpressions( const QgsVectorLayer* vl, double scale = -1 );
virtual QgsExpression* expression( const QString& property );
virtual QgsExpression* expression( const QString& property ) const;
/**Saves data defined properties to string map*/
void saveDataDefinedProperties( QgsStringMap& stringMap ) const;
/**Copies data defined properties of this layer to another symbol layer*/
@ -174,11 +180,13 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
protected:
QgsMarkerSymbolLayerV2( bool locked = false );
//handles marker offset and anchor point shift together
void markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY );
void markerOffset( QgsSymbolV2RenderContext& context, double width, double height,
void markerOffset( const QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;
void markerOffset( const QgsSymbolV2RenderContext& context, double width, double height,
QgsSymbolV2::OutputUnit widthUnit, QgsSymbolV2::OutputUnit heightUnit,
double& offsetX, double& offsetY );
double& offsetX, double& offsetY ) const;
static QPointF _rotatedOffset( const QPointF& offset, double angle );
double mAngle;

View File

@ -17,7 +17,7 @@
<x>0</x>
<y>0</y>
<width>1050</width>
<height>31</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="mProjectMenu">
@ -47,6 +47,7 @@
<addaction name="mActionSaveProject"/>
<addaction name="mActionSaveProjectAs"/>
<addaction name="mActionSaveMapAsImage"/>
<addaction name="mActionDxfExport"/>
<addaction name="separator"/>
<addaction name="mActionNewPrintComposer"/>
<addaction name="mActionShowComposerManager"/>
@ -2136,6 +2137,11 @@ Acts on currently active editable layer</string>
<string>Paste features in clipboard into a new memory vector layer.</string>
</property>
</action>
<action name="mActionDxfExport">
<property name="text">
<string>DXF Export...</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsDxfExportDialogBase</class>
<widget class="QDialog" name="QgsDxfExportDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>377</width>
<height>292</height>
</rect>
</property>
<property name="windowTitle">
<string>DXF export</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QLineEdit" name="mFileLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mSymbologyModeLabel">
<property name="text">
<string>Symbology mode</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mSymbologyScaleLabel">
<property name="text">
<string>Symbology scale</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mSaveAsLabel">
<property name="text">
<string>Save as</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="mFileSelectionButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="mSymbologyModeComboBox">
<item>
<property name="text">
<string>No symbology</string>
</property>
</item>
<item>
<property name="text">
<string>Feature symbology</string>
</property>
</item>
<item>
<property name="text">
<string>Symbol layer symbology</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="mSymbologyScaleLineEdit"/>
</item>
<item row="3" column="0" colspan="3">
<widget class="QListWidget" name="mLayersListWidget"/>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsDxfExportDialogBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsDxfExportDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>