[QGIS Commit] r12563 - in trunk/qgis: python/core src/app src/core src/core/symbology-ng

svn_qgis at osgeo.org svn_qgis at osgeo.org
Mon Dec 21 10:13:02 EST 2009


Author: wonder
Date: 2009-12-21 10:13:01 -0500 (Mon, 21 Dec 2009)
New Revision: 12563

Added:
   trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.cpp
   trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.h
Modified:
   trunk/qgis/python/core/symbology-ng-core.sip
   trunk/qgis/src/app/qgsvectorlayerproperties.cpp
   trunk/qgis/src/core/CMakeLists.txt
Log:
Preserve as many settings as possible when converting between new and old symbology.


Modified: trunk/qgis/python/core/symbology-ng-core.sip
===================================================================
--- trunk/qgis/python/core/symbology-ng-core.sip	2009-12-21 09:34:21 UTC (rev 12562)
+++ trunk/qgis/python/core/symbology-ng-core.sip	2009-12-21 15:13:01 UTC (rev 12563)
@@ -724,3 +724,31 @@
   virtual QgsStringMap properties() const = 0;
 
 };
+
+//////////
+
+class QgsSymbologyV2Conversion
+{
+%TypeHeaderCode
+#include <qgssymbologyv2conversion.h>
+%End
+
+public:
+
+  //! return a symbol in new symbology as close as possible to old symbol
+  //! @note not all properties will be preserved
+  static QgsSymbolV2* symbolV1toV2(const QgsSymbol* s) /Factory/;
+
+  //! return a symbol in old symbology as close as possible to new symbol
+  //! @note not all properties will be preserved
+  static QgsSymbol* symbolV2toV1(QgsSymbolV2* s) /Factory/;
+
+  //! convert layer from old symbology to new symbology
+  //! @note not all properties will be preserved
+  static void rendererV1toV2(QgsVectorLayer* layer);
+
+  //! convert layer from new symbology to old symbology
+  //! @note not all properties will be preserved
+  static void rendererV2toV1(QgsVectorLayer* layer);
+
+};

Modified: trunk/qgis/src/app/qgsvectorlayerproperties.cpp
===================================================================
--- trunk/qgis/src/app/qgsvectorlayerproperties.cpp	2009-12-21 09:34:21 UTC (rev 12562)
+++ trunk/qgis/src/app/qgsvectorlayerproperties.cpp	2009-12-21 15:13:01 UTC (rev 12563)
@@ -56,8 +56,7 @@
 
 #include "qgsrendererv2propertiesdialog.h"
 #include "qgsstylev2.h"
-#include "qgssinglesymbolrenderer.h"
-#include "qgssinglesymbolrendererv2.h"
+#include "qgssymbologyv2conversion.h"
 
 #if QT_VERSION < 0x040300
 #define toPlainText() text()
@@ -1108,15 +1107,11 @@
 {
   if ( useNewSymbology )
   {
-    layer->setUsingRendererV2( true );
-    layer->setRendererV2( QgsFeatureRendererV2::defaultRenderer( layer->geometryType() ) );
-    layer->setRenderer( NULL );
+    QgsSymbologyV2Conversion::rendererV1toV2( layer );
   }
   else
   {
-    layer->setUsingRendererV2( false );
-    layer->setRendererV2( NULL );
-    layer->setRenderer( new QgsSingleSymbolRenderer( layer->geometryType() ) );
+    QgsSymbologyV2Conversion::rendererV2toV1( layer );
   }
 
   // update GUI!

Modified: trunk/qgis/src/core/CMakeLists.txt
===================================================================
--- trunk/qgis/src/core/CMakeLists.txt	2009-12-21 09:34:21 UTC (rev 12562)
+++ trunk/qgis/src/core/CMakeLists.txt	2009-12-21 15:13:01 UTC (rev 12563)
@@ -19,6 +19,7 @@
   symbology-ng/qgsgraduatedsymbolrendererv2.cpp
   symbology-ng/qgsvectorcolorrampv2.cpp
   symbology-ng/qgsstylev2.cpp
+  symbology-ng/qgssymbologyv2conversion.cpp
 
   qgis.cpp
   qgsapplication.cpp

Added: trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.cpp	                        (rev 0)
+++ trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.cpp	2009-12-21 15:13:01 UTC (rev 12563)
@@ -0,0 +1,328 @@
+#include "qgssymbologyv2conversion.h"
+
+#include "qgssinglesymbolrenderer.h"
+#include "qgsgraduatedsymbolrenderer.h"
+#include "qgsuniquevaluerenderer.h"
+#include "qgssymbol.h"
+#include "qgsvectorlayer.h"
+
+#include "qgslogger.h"
+
+#include "qgsmarkersymbollayerv2.h"
+#include "qgslinesymbollayerv2.h"
+#include "qgsfillsymbollayerv2.h"
+#include "qgssinglesymbolrendererv2.h"
+#include "qgsgraduatedsymbolrendererv2.h"
+#include "qgscategorizedsymbolrendererv2.h"
+
+// some ad-hoc conversions
+#define MM2PIXELS(x) ((x)/0.26)
+#define PIXELS2MM(x) ((x)*0.26)
+
+
+QgsSymbolV2* QgsSymbologyV2Conversion::symbolV1toV2( const QgsSymbol* s )
+{
+  switch ( s->type() )
+  {
+    case QGis::Point:
+    {
+      QgsMarkerSymbolLayerV2* sl = NULL;
+      double size = MM2PIXELS( s->pointSize() );
+      double angle = 0; // rotation only from classification field
+      QString symbolName = s->pointSymbolName();
+      if ( symbolName.startsWith( "hard:" ) )
+      {
+        // simple symbol marker
+        QColor color = s->fillColor();
+        QColor borderColor = s->color();
+        QString name = symbolName.mid( 5 );
+        sl = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle );
+      }
+      else
+      {
+        // svg symbol marker
+        QString name = symbolName.mid( 4 );
+        sl = new QgsSvgMarkerSymbolLayerV2( name, size, angle );
+      }
+      QgsSymbolLayerV2List layers;
+      layers.append( sl );
+      return new QgsMarkerSymbolV2( layers );
+    }
+
+    case QGis::Line:
+    {
+      QColor color = s->color();
+      double width = MM2PIXELS( s->lineWidth() );
+      Qt::PenStyle penStyle = s->pen().style();
+      QgsLineSymbolLayerV2* sl = new QgsSimpleLineSymbolLayerV2( color, width, penStyle );
+
+      QgsSymbolLayerV2List layers;
+      layers.append( sl );
+      return new QgsLineSymbolV2( layers );
+    }
+
+    case QGis::Polygon:
+    {
+      QColor color = s->fillColor();
+      QColor borderColor = s->color();
+      Qt::BrushStyle brushStyle = s->brush().style();
+      Qt::PenStyle borderStyle = s->pen().style();
+      double borderWidth = MM2PIXELS( s->lineWidth() );
+      QgsFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, brushStyle, borderColor, borderStyle, borderWidth );
+
+      QgsSymbolLayerV2List layers;
+      layers.append( sl );
+      return new QgsFillSymbolV2( layers );
+    }
+
+    default:
+      return NULL;
+  }
+}
+
+QgsSymbol* QgsSymbologyV2Conversion::symbolV2toV1( QgsSymbolV2* s )
+{
+  if ( s == NULL || s->symbolLayerCount() == 0 )
+    return NULL;
+
+  // we will use only the first symbol layer
+  QgsSymbolLayerV2* sl = s->symbolLayer( 0 );
+
+  switch ( sl->type() )
+  {
+    case QgsSymbolV2::Marker:
+    {
+      QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( sl );
+      QgsSymbol* sOld = new QgsSymbol( QGis::Point );
+      sOld->setFillColor( sl->color() );
+      sOld->setFillStyle( Qt::SolidPattern );
+      sOld->setPointSize( PIXELS2MM( msl->size() ) );
+      if ( sl->layerType() == "SimpleMarker" )
+      {
+        QgsSimpleMarkerSymbolLayerV2* smsl = static_cast<QgsSimpleMarkerSymbolLayerV2*>( sl );
+        sOld->setColor( smsl->borderColor() );
+        sOld->setNamedPointSymbol( "hard:" + smsl->name() );
+      }
+      else if ( sl->layerType() == "SvgMarker" )
+      {
+        QgsSvgMarkerSymbolLayerV2* smsl = static_cast<QgsSvgMarkerSymbolLayerV2*>( sl );
+        sOld->setNamedPointSymbol( "svg:" + smsl->path() );
+      }
+      return sOld;
+    }
+    break;
+
+    case QgsSymbolV2::Line:
+    {
+      QgsLineSymbolLayerV2* lsl = static_cast<QgsLineSymbolLayerV2*>( sl );
+      QgsSymbol* sOld = new QgsSymbol( QGis::Line );
+      sOld->setColor( sl->color() );
+      sOld->setLineWidth( PIXELS2MM( lsl->width() ) );
+      if ( sl->layerType() == "SimpleLine" )
+      {
+        // add specific settings
+        QgsSimpleLineSymbolLayerV2* slsl = static_cast<QgsSimpleLineSymbolLayerV2*>( sl );
+        sOld->setLineStyle( slsl->penStyle() );
+      }
+      return sOld;
+    }
+
+    case QgsSymbolV2::Fill:
+    {
+      QgsSymbol* sOld = new QgsSymbol( QGis::Polygon );
+      sOld->setFillColor( sl->color() );
+      if ( sl->layerType() == "SimpleFill" )
+      {
+        // add specifc settings
+        QgsSimpleFillSymbolLayerV2* sfsl = static_cast<QgsSimpleFillSymbolLayerV2*>( sl );
+        sOld->setColor( sfsl->borderColor() );
+        sOld->setLineWidth( PIXELS2MM( sfsl->borderWidth() ) );
+        sOld->setLineStyle( sfsl->borderStyle() );
+        sOld->setFillStyle( sfsl->brushStyle() );
+      }
+      return sOld;
+    }
+  }
+
+  return NULL; // should never get here
+}
+
+void QgsSymbologyV2Conversion::rendererV1toV2( QgsVectorLayer* layer )
+{
+  if ( layer->isUsingRendererV2() )
+    return;
+
+  const QgsRenderer* r = layer->renderer();
+  if ( r == NULL )
+    return;
+
+  QgsFeatureRendererV2* r2final = NULL;
+
+  QString rtype = r->name();
+  if ( rtype == "Single Symbol" )
+  {
+    const QgsSingleSymbolRenderer* ssr = dynamic_cast<const QgsSingleSymbolRenderer*>( r );
+    if ( ssr == NULL )
+      return;
+    QgsSymbolV2* symbol = symbolV1toV2( ssr->symbol() );
+    QgsSingleSymbolRendererV2* r2 = new QgsSingleSymbolRendererV2( symbol );
+    r2final = r2;
+  }
+  else if ( rtype == "Graduated Symbol" )
+  {
+    const QgsGraduatedSymbolRenderer* gsr = dynamic_cast<const QgsGraduatedSymbolRenderer*>( r );
+    if ( gsr == NULL )
+      return;
+
+    QString attrName;
+    if ( layer->pendingFields().contains( gsr->classificationField() ) )
+    {
+      attrName = layer->pendingFields()[ gsr->classificationField()].name();
+    }
+
+    QgsRangeList ranges;
+    foreach( const QgsSymbol* sym, gsr->symbols() )
+    {
+      double lowerValue = sym->lowerValue().toDouble();
+      double upperValue = sym->upperValue().toDouble();
+      QString label = sym->label();
+      if ( label.isEmpty() )
+        label = QString( "%1 - %2" ).arg( lowerValue, -1, 'f', 3 ).arg( upperValue, -1, 'f', 3 );
+      QgsSymbolV2* symbolv2 = symbolV1toV2( sym );
+      ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbolv2, label ) );
+    }
+
+    QgsGraduatedSymbolRendererV2* r2 = new QgsGraduatedSymbolRendererV2( attrName, ranges );
+
+    // find out mode
+    QgsGraduatedSymbolRendererV2::Mode m = QgsGraduatedSymbolRendererV2::Custom;
+    switch ( gsr->mode() )
+    {
+      case QgsGraduatedSymbolRenderer::EqualInterval: m = QgsGraduatedSymbolRendererV2::EqualInterval; break;
+      case QgsGraduatedSymbolRenderer::Quantile: m = QgsGraduatedSymbolRendererV2::Quantile; break;
+      case QgsGraduatedSymbolRenderer::Empty: m = QgsGraduatedSymbolRendererV2::Custom; break;
+    }
+    r2->setMode( m );
+    // source symbol, color ramp not set (unknown)
+    r2final = r2;
+  }
+  else if ( rtype == "Continuous Color" )
+  {
+    // TODO
+  }
+  else if ( rtype == "Unique Value" )
+  {
+    const QgsUniqueValueRenderer* uvr = dynamic_cast<const QgsUniqueValueRenderer*>( r );
+    if ( uvr == NULL )
+      return;
+
+    QString attrName;
+    if ( layer->pendingFields().contains( uvr->classificationField() ) )
+    {
+      attrName = layer->pendingFields()[ uvr->classificationField()].name();
+    }
+
+    QgsCategoryList cats;
+    foreach( QgsSymbol* sym, uvr->symbols() )
+    {
+      QVariant value = QVariant( sym->lowerValue() );
+      QString label = sym->label();
+      if ( label.isEmpty() )
+        label = value.toString();
+      QgsSymbolV2* symbolv2 = symbolV1toV2( sym );
+      cats.append( QgsRendererCategoryV2( value, symbolv2, label ) );
+    }
+
+    QgsCategorizedSymbolRendererV2* r2 = new QgsCategorizedSymbolRendererV2( attrName, cats );
+    // source symbol and color ramp are not set (unknown)
+    r2final = r2;
+  }
+
+  if ( r2final == NULL )
+  {
+    r2final = QgsFeatureRendererV2::defaultRenderer( layer->geometryType() );
+  }
+
+  // change of renderers
+  layer->setUsingRendererV2( true );
+  layer->setRendererV2( r2final );
+  layer->setRenderer( NULL );
+}
+
+void QgsSymbologyV2Conversion::rendererV2toV1( QgsVectorLayer* layer )
+{
+  if ( !layer->isUsingRendererV2() )
+    return;
+
+  QgsFeatureRendererV2* r2 = layer->rendererV2();
+  if ( r2 == NULL )
+    return;
+
+  QgsRenderer* rfinal = NULL;
+
+  QString r2type = r2->type();
+  if ( r2type == "singleSymbol" )
+  {
+    QgsSingleSymbolRendererV2* ssr2 = static_cast<QgsSingleSymbolRendererV2*>( r2 );
+
+    QgsSingleSymbolRenderer* r = new QgsSingleSymbolRenderer( layer->geometryType() );
+    r->addSymbol( symbolV2toV1( ssr2->symbol() ) );
+    rfinal = r;
+  }
+  else if ( r2type == "graduatedSymbol" )
+  {
+    QgsGraduatedSymbolRendererV2* gsr2 = static_cast<QgsGraduatedSymbolRendererV2*>( r2 );
+
+    QgsGraduatedSymbolRenderer::Mode m;
+    switch ( gsr2->mode() )
+    {
+      case QgsGraduatedSymbolRendererV2::EqualInterval: m = QgsGraduatedSymbolRenderer::EqualInterval; break;
+      case QgsGraduatedSymbolRendererV2::Quantile: m = QgsGraduatedSymbolRenderer::Quantile; break;
+      default: m = QgsGraduatedSymbolRenderer::Empty; break;
+    }
+
+    QgsGraduatedSymbolRenderer* r = new QgsGraduatedSymbolRenderer( layer->geometryType(), m );
+
+    r->setClassificationField( layer->fieldNameIndex( gsr2->classAttribute() ) );
+
+    foreach( QgsRendererRangeV2 range, gsr2->ranges() )
+    {
+      QgsSymbol* s = symbolV2toV1( range.symbol() );
+      s->setLowerValue( QString::number( range.lowerValue(), 'f', 5 ) );
+      s->setUpperValue( QString::number( range.upperValue(), 'f', 5 ) );
+      s->setLabel( range.label() );
+      r->addSymbol( s );
+    }
+
+    rfinal = r;
+  }
+  else if ( r2type == "categorizedSymbol" )
+  {
+    QgsCategorizedSymbolRendererV2* csr2 = static_cast<QgsCategorizedSymbolRendererV2*>( r2 );
+
+    QgsUniqueValueRenderer* r = new QgsUniqueValueRenderer( layer->geometryType() );
+
+    r->setClassificationField( layer->fieldNameIndex( csr2->classAttribute() ) );
+
+    foreach( QgsRendererCategoryV2 cat, csr2->categories() )
+    {
+      QgsSymbol* s = symbolV2toV1( cat.symbol() );
+      QString val = cat.value().toString();
+      s->setLowerValue( val );
+      s->setUpperValue( val );
+      r->insertValue( val, s );
+    }
+
+    rfinal = r;
+  }
+
+
+  if ( rfinal == NULL )
+  {
+    rfinal = new QgsSingleSymbolRenderer( layer->geometryType() );
+  }
+
+  layer->setUsingRendererV2( false );
+  layer->setRendererV2( NULL );
+  layer->setRenderer( rfinal );
+}

Added: trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.h
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.h	                        (rev 0)
+++ trunk/qgis/src/core/symbology-ng/qgssymbologyv2conversion.h	2009-12-21 15:13:01 UTC (rev 12563)
@@ -0,0 +1,30 @@
+#ifndef QGSSYMBOLOGYV2CONVERSION_H
+#define QGSSYMBOLOGYV2CONVERSION_H
+
+class QgsSymbol;
+class QgsSymbolV2;
+class QgsVectorLayer;
+
+class CORE_EXPORT QgsSymbologyV2Conversion
+{
+  public:
+
+    //! return a symbol in new symbology as close as possible to old symbol
+    //! @note not all properties will be preserved
+    static QgsSymbolV2* symbolV1toV2( const QgsSymbol* s );
+
+    //! return a symbol in old symbology as close as possible to new symbol
+    //! @note not all properties will be preserved
+    static QgsSymbol* symbolV2toV1( QgsSymbolV2* s );
+
+    //! convert layer from old symbology to new symbology
+    //! @note not all properties will be preserved
+    static void rendererV1toV2( QgsVectorLayer* layer );
+
+    //! convert layer from new symbology to old symbology
+    //! @note not all properties will be preserved
+    static void rendererV2toV1( QgsVectorLayer* layer );
+
+};
+
+#endif // QGSSYMBOLOGYV2CONVERSION_H



More information about the QGIS-commit mailing list