Skip to content

Commit

Permalink
Use scale for symbology export (if symbol measures are defined in map…
Browse files Browse the repository at this point in the history
… units)
  • Loading branch information
mhugent committed Dec 21, 2012
1 parent 3a63b7b commit 1a79041
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 126 deletions.
4 changes: 2 additions & 2 deletions python/core/symbology-ng/qgssymbollayerv2utils.sip
Expand Up @@ -168,9 +168,9 @@ class QgsSymbolLayerV2Utils
static QColor parseColor( QString colorStr );

/**Returns the line width scale factor depending on the unit and the paint device*/
static double lineWidthScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
static double lineWidthScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
/**Returns scale factor painter units -> pixel dimensions*/
static double pixelSizeScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
static double pixelSizeScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
/**Creates a render context for a pixel based device*/
static QgsRenderContext createRenderContext( QPainter* p );

Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -82,6 +82,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/../core/
${CMAKE_CURRENT_SOURCE_DIR}/../core/renderer
${CMAKE_CURRENT_SOURCE_DIR}/../core/raster
${CMAKE_CURRENT_SOURCE_DIR}/../core/symbology-ng
interpolation
${PROJ_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}
Expand Down
5 changes: 5 additions & 0 deletions src/app/ogr/qgsvectorlayersaveasdialog.cpp
Expand Up @@ -200,3 +200,8 @@ int QgsVectorLayerSaveAsDialog::symbologyExport() const
{
return mSymbologyExportComboBox->itemData( mSymbologyExportComboBox->currentIndex() ).toInt();
}

double QgsVectorLayerSaveAsDialog::scaleDenominator() const
{
return mScaleSpinBox->value();
}
1 change: 1 addition & 0 deletions src/app/ogr/qgsvectorlayersaveasdialog.h
Expand Up @@ -46,6 +46,7 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
1: Feature symbology
2: Symbol level symbology*/
int symbologyExport() const;
double scaleDenominator() const;

private slots:
void on_mFormatComboBox_currentIndexChanged( int idx );
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgisapp.cpp
Expand Up @@ -4205,7 +4205,8 @@ void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection )
datasourceOptions, dialog->layerOptions(),
dialog->skipAttributeCreation(),
&newFilename,
( QgsVectorFileWriter::SymbologyExport )( dialog->symbologyExport() ) );
( QgsVectorFileWriter::SymbologyExport )( dialog->symbologyExport() ),
dialog->scaleDenominator() );

QApplication::restoreOverrideCursor();

Expand Down
65 changes: 54 additions & 11 deletions src/core/qgsvectorfilewriter.cpp
Expand Up @@ -25,7 +25,6 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsvectorfilewriter.h"
#include "qgsrendererv2.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2.h"

#include <QFile>
Expand Down Expand Up @@ -435,7 +434,7 @@ QString QgsVectorFileWriter::errorMessage()
return mErrorMessage;
}

bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2* renderer )
bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2* renderer, QGis::UnitType outputUnit )
{
// create the feature
OGRFeatureH poFeature = createFeature( feature );
Expand All @@ -459,7 +458,8 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
{
continue;
}*/
currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle();//"@" + it.value();
double wScaleFactor = widthScaleFactor( mSymbologyScaleDenominator, ( *symbolIt )->outputUnit(), outputUnit );
currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( wScaleFactor );//"@" + it.value();

if ( mSymbologyExport == FeatureSymbology )
{
Expand Down Expand Up @@ -683,7 +683,8 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
const QStringList &layerOptions,
bool skipAttributeCreation,
QString *newFilename,
SymbologyExport symbologyExport )
SymbologyExport symbologyExport,
double symbologyScale )
{
QgsDebugMsg( "fileName = " + fileName );
const QgsCoordinateReferenceSystem* outputCRS;
Expand All @@ -709,6 +710,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
QgsVectorFileWriter* writer =
new QgsVectorFileWriter( fileName, fileEncoding, skipAttributeCreation ? QgsFieldMap() : layer->pendingFields(), layer->wkbType(),
outputCRS, driverName, datasourceOptions, layerOptions, newFilename, symbologyExport );
writer->setSymbologyScaleDenominator( symbologyScale );

if ( newFilename )
{
Expand Down Expand Up @@ -750,10 +752,10 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
}

//create symbol table if needed
/*if( writer->symbologyExport() != NoSymbology )
if ( writer->symbologyExport() != NoSymbology )
{
writer->createSymbolLayerTable( layer, writer->mDS );
}*/
//writer->createSymbolLayerTable( layer, writer->mDS );
}

if ( writer->symbologyExport() == SymbolLayerSymbology && layer->isUsingRendererV2() )
{
Expand All @@ -770,6 +772,13 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,

int n = 0, errors = 0;

//unit type
QGis::UnitType mapUnits = layer->crs().mapUnits();
if ( ct )
{
mapUnits = ct->destCRS().mapUnits();
}

// write all features
while ( layer->nextFeature( fet ) )
{
Expand Down Expand Up @@ -803,7 +812,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
{
fet.clearAttributeMap();
}
if ( !writer->addFeature( fet, layer->rendererV2() ) )
if ( !writer->addFeature( fet, layer->rendererV2(), mapUnits ) )
{
WriterError err = writer->hasError();
if ( err != NoError && errorMessage )
Expand Down Expand Up @@ -1165,7 +1174,7 @@ bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName,
return true;
}

void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSourceH ds )
void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, const QgsCoordinateTransform* ct, OGRDataSourceH ds )
{
if ( !vl || !ds )
{
Expand All @@ -1183,6 +1192,13 @@ void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSo
return;
}

//unit type
QGis::UnitType mapUnits = vl->crs().mapUnits();
if ( ct )
{
mapUnits = ct->destCRS().mapUnits();
}

mSymbolLayerTable.clear();
OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
Expand All @@ -1197,7 +1213,8 @@ void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSo
for ( int i = 0; i < nLevels; ++i )
{
mSymbolLayerTable.insert(( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(), ( *symbolIt )->ogrFeatureStyle().toLocal8Bit() );
OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( widthScaleFactor( mSymbologyScaleDenominator, ( *symbolIt )->outputUnit(), mapUnits ) ).toLocal8Bit() );
++nTotalLevels;
}
}
Expand All @@ -1217,6 +1234,13 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
}
QHash< QgsSymbolV2*, QList<QgsFeature> > features;

//unit type
QGis::UnitType mapUnits = layer->crs().mapUnits();
if ( ct )
{
mapUnits = ct->destCRS().mapUnits();
}

//fetch features
QgsFeature fet;
QgsSymbolV2* featureSymbol = 0;
Expand Down Expand Up @@ -1307,7 +1331,8 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
continue;
}

QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle();
QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( widthScaleFactor( mSymbologyScaleDenominator, levelIt.key()->outputUnit(),
mapUnits ) );
if ( !styleString.isEmpty() )
{
OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
Expand All @@ -1328,3 +1353,21 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels

return ( nErrors > 0 ) ? QgsVectorFileWriter::ErrFeatureWriteFailed : QgsVectorFileWriter::NoError;
}

double QgsVectorFileWriter::widthScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits )
{
if ( symbolUnits == QgsSymbolV2::MM )
{
return 1.0;
}
else
{
//conversion factor map units -> mm
if ( mapUnits == QGis::Meters )
{
return 1000 / scaleDenominator;
}

}
return 1.0; //todo: map units
}
15 changes: 12 additions & 3 deletions src/core/qgsvectorfilewriter.h
Expand Up @@ -21,6 +21,7 @@

#include "qgsvectorlayer.h"
#include "qgsfield.h"
#include "qgssymbolv2.h"

#include <QPair>

Expand Down Expand Up @@ -104,7 +105,8 @@ class CORE_EXPORT QgsVectorFileWriter
const QStringList &layerOptions = QStringList(), // added in 1.6
bool skipAttributeCreation = false, // added in 1.6
QString *newFilename = 0, // added in 1.9
SymbologyExport symbologyExport = NoSymbology //added in 2.0
SymbologyExport symbologyExport = NoSymbology, //added in 2.0
double symbologyScale = 1.0 // added in 2.0
);

/** create shapefile and initialize it */
Expand Down Expand Up @@ -144,7 +146,7 @@ class CORE_EXPORT QgsVectorFileWriter
QString errorMessage();

/** add feature to the currently opened shapefile */
bool addFeature( QgsFeature& feature, QgsFeatureRendererV2* renderer = 0 );
bool addFeature( QgsFeature& feature, QgsFeatureRendererV2* renderer = 0, QGis::UnitType outputUnit = QGis::Meters );

//! @note not available in python bindings
QMap<int, int> attrIdxToOgrIdx() { return mAttrIdxToOgrIdx; }
Expand All @@ -161,6 +163,9 @@ class CORE_EXPORT QgsVectorFileWriter
SymbologyExport symbologyExport() const { return mSymbologyExport; }
void setSymbologyExport( SymbologyExport symExport ) { mSymbologyExport = symExport; }

double symbologyScaleDenominator() const { return mSymbologyScaleDenominator; }
void setSymbologyScaleDenominator( double d ) { mSymbologyScaleDenominator = d; }

protected:
//! @note not available in python bindings
OGRGeometryH createEmptyGeometry( QGis::WkbType wkbType );
Expand All @@ -187,14 +192,18 @@ class CORE_EXPORT QgsVectorFileWriter

QMap< QgsSymbolLayerV2*, QString > mSymbolLayerTable;

/**Scale for symbology export (e.g. for symbols units in map units)*/
double mSymbologyScaleDenominator;

private:
static bool driverMetadata( QString driverName, QString &longName, QString &trLongName, QString &glob, QString &ext );
void createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSourceH ds );
void createSymbolLayerTable( QgsVectorLayer* vl, const QgsCoordinateTransform* ct, OGRDataSourceH ds );
OGRFeatureH createFeature( QgsFeature& feature );
bool writeFeature( OGRLayerH layer, OGRFeatureH feature );

/**Writes features considering symbol level order*/
WriterError exportFeaturesSymbolLevels( QgsVectorLayer* layer, const QgsCoordinateTransform* ct, QString* errorMessage = 0 );
double widthScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits );
};

#endif
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgslinesymbollayerv2.cpp
Expand Up @@ -195,7 +195,7 @@ void QgsSimpleLineSymbolLayerV2::toSld( QDomDocument &doc, QDomElement &element,
}
}

QString QgsSimpleLineSymbolLayerV2::ogrFeatureStyle() const
QString QgsSimpleLineSymbolLayerV2::ogrFeatureStyle( double widthScaleFactor ) const
{
QString symbolStyle;

Expand All @@ -205,7 +205,7 @@ QString QgsSimpleLineSymbolLayerV2::ogrFeatureStyle() const
symbolStyle.append( mPen.color().name() );
symbolStyle.append( ",w:" );
//dxf driver writes ground units as mm? Should probably be changed in ogr
symbolStyle.append( QString::number( mWidth ) );
symbolStyle.append( QString::number( mWidth * widthScaleFactor ) );
symbolStyle.append( "g" );
symbolStyle.append( ")" );

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgslinesymbollayerv2.h
Expand Up @@ -56,7 +56,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2

void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const;

QString ogrFeatureStyle() const;
QString ogrFeatureStyle( double widthScaleFactor ) const;

// new stuff

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -480,7 +480,7 @@ void QgsSimpleMarkerSymbolLayerV2::writeSldMarker( QDomDocument &doc, QDomElemen
QgsSymbolLayerV2Utils::createDisplacementElement( doc, graphicElem, mOffset );
}

QString QgsSimpleMarkerSymbolLayerV2::ogrFeatureStyle() const
QString QgsSimpleMarkerSymbolLayerV2::ogrFeatureStyle( double widthScaleFactor ) const
{
#if 0
QString ogrType = "3"; //default is circle
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -62,7 +62,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2

void writeSldMarker( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const;

QString ogrFeatureStyle() const;
QString ogrFeatureStyle( double widthScaleFactor ) const;

QString name() const { return mName; }
void setName( QString name ) { mName = name; }
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssymbollayerv2.h
Expand Up @@ -54,7 +54,7 @@ class CORE_EXPORT QgsSymbolLayerV2
virtual void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
{ Q_UNUSED( props ); element.appendChild( doc.createComment( QString( "SymbolLayerV2 %1 not implemented yet" ).arg( layerType() ) ) ); }

virtual QString ogrFeatureStyle() const { return QString(); }
virtual QString ogrFeatureStyle( double widthScaleFactor ) const { Q_UNUSED( widthScaleFactor ); return QString(); }

virtual QgsStringMap properties() const = 0;

Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgssymbollayerv2utils.cpp
Expand Up @@ -2455,7 +2455,7 @@ QColor QgsSymbolLayerV2Utils::parseColor( QString colorStr )
return QColor( p[0].toInt(), p[1].toInt(), p[2].toInt() );
}

double QgsSymbolLayerV2Utils::lineWidthScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
double QgsSymbolLayerV2Utils::lineWidthScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
{

if ( u == QgsSymbolV2::MM )
Expand All @@ -2476,7 +2476,7 @@ double QgsSymbolLayerV2Utils::lineWidthScaleFactor( QgsRenderContext& c, QgsSymb
}
}

double QgsSymbolLayerV2Utils::pixelSizeScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
double QgsSymbolLayerV2Utils::pixelSizeScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
{
if ( u == QgsSymbolV2::MM )
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgssymbollayerv2utils.h
Expand Up @@ -203,9 +203,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
static QColor parseColor( QString colorStr );

/**Returns the line width scale factor depending on the unit and the paint device*/
static double lineWidthScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
static double lineWidthScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
/**Returns scale factor painter units -> pixel dimensions*/
static double pixelSizeScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
static double pixelSizeScaleFactor( const QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
/**Creates a render context for a pixel based device*/
static QgsRenderContext createRenderContext( QPainter* p );

Expand Down
21 changes: 0 additions & 21 deletions src/core/symbology-ng/qgssymbolv2.cpp
Expand Up @@ -314,27 +314,6 @@ void QgsSymbolV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap p
}
}

QString QgsSymbolV2::ogrFeatureStyle() const
{
QString styleString;
QString currentStyleString;
for ( QgsSymbolLayerV2List::const_iterator it = mLayers.constBegin(); it != mLayers.constEnd(); ++it )
{
currentStyleString = ( *it )->ogrFeatureStyle();
if ( currentStyleString.isEmpty() )
{
continue;
}

if ( it != mLayers.constBegin() )
{
styleString.append( ";" );
}
styleString.append( currentStyleString );
}
return styleString;
}

QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
{
QgsSymbolLayerV2List lst;
Expand Down
3 changes: 0 additions & 3 deletions src/core/symbology-ng/qgssymbolv2.h
Expand Up @@ -113,9 +113,6 @@ class CORE_EXPORT QgsSymbolV2

void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const;

/**Returns the OGR feature style string for the symbol*/
QString ogrFeatureStyle() const;

OutputUnit outputUnit() const { return mOutputUnit; }
void setOutputUnit( OutputUnit u ) { mOutputUnit = u; }

Expand Down
1 change: 1 addition & 0 deletions src/providers/ogr/CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ QT4_WRAP_CPP(OGR_MOC_SRCS ${OGR_MOC_HDRS})
INCLUDE_DIRECTORIES(
.
../../core
${CMAKE_CURRENT_SOURCE_DIR}/../../core/symbology-ng
${GDAL_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}
)
Expand Down

0 comments on commit 1a79041

Please sign in to comment.