mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	[FEATURE]: merge dxf_export branch
This commit is contained in:
		
						commit
						561f01c0c2
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								python/core/qgsdxfexport.sip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								python/core/qgsdxfexport.sip
									
									
									
									
									
										Normal 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 );
 | 
			
		||||
};
 | 
			
		||||
@ -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 );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 );
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								src/app/qgsdxfexportdialog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/app/qgsdxfexportdialog.cpp
									
									
									
									
									
										Normal 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() );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								src/app/qgsdxfexportdialog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/app/qgsdxfexportdialog.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1724
									
								
								src/core/dxf/qgsdxfexport.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1724
									
								
								src/core/dxf/qgsdxfexport.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										160
									
								
								src/core/dxf/qgsdxfexport.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/core/dxf/qgsdxfexport.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
							
								
								
									
										100
									
								
								src/core/dxf/qgsdxfpaintdevice.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/core/dxf/qgsdxfpaintdevice.cpp
									
									
									
									
									
										Normal 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 );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										63
									
								
								src/core/dxf/qgsdxfpaintdevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/core/dxf/qgsdxfpaintdevice.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
							
								
								
									
										171
									
								
								src/core/dxf/qgsdxfpaintengine.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/core/dxf/qgsdxfpaintengine.cpp
									
									
									
									
									
										Normal 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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/core/dxf/qgsdxfpaintengine.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/core/dxf/qgsdxfpaintengine.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -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...
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 )
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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"/>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								src/ui/qgsdxfexportdialogbase.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/ui/qgsdxfexportdialogbase.ui
									
									
									
									
									
										Normal 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>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user