Quantum GIS API Documentation  master-693a1fe
src/core/symbology-ng/qgssymbologyv2conversion.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgssymbologyv2conversion.cpp
00003     ---------------------
00004     begin                : December 2009
00005     copyright            : (C) 2009 by Martin Dobias
00006     email                : wonder dot sk at gmail dot com
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 #include "qgssymbologyv2conversion.h"
00016 
00017 #include "qgslogger.h"
00018 
00019 #include "qgsmarkersymbollayerv2.h"
00020 #include "qgslinesymbollayerv2.h"
00021 #include "qgsfillsymbollayerv2.h"
00022 #include "qgssinglesymbolrendererv2.h"
00023 #include "qgsgraduatedsymbolrendererv2.h"
00024 #include "qgscategorizedsymbolrendererv2.h"
00025 
00026 
00027 
00028 struct QgsOldSymbolMeta
00029 {
00030   QString lowerValue;
00031   QString upperValue;
00032   QString label;
00033 };
00034 
00035 
00036 static QgsOldSymbolMeta readSymbolMeta( const QDomNode& synode )
00037 {
00038   QgsOldSymbolMeta meta;
00039 
00040   QDomNode lvalnode = synode.namedItem( "lowervalue" );
00041   if ( ! lvalnode.isNull() )
00042   {
00043     QDomElement lvalelement = lvalnode.toElement();
00044     if ( lvalelement.attribute( "null" ).toInt() == 1 )
00045     {
00046       meta.lowerValue = QString::null;
00047     }
00048     else
00049     {
00050       meta.lowerValue = lvalelement.text();
00051     }
00052   }
00053 
00054   QDomNode uvalnode = synode.namedItem( "uppervalue" );
00055   if ( ! uvalnode.isNull() )
00056   {
00057     QDomElement uvalelement = uvalnode.toElement();
00058     meta.upperValue = uvalelement.text();
00059   }
00060 
00061   QDomNode labelnode = synode.namedItem( "label" );
00062   if ( ! labelnode.isNull() )
00063   {
00064     QDomElement labelelement = labelnode.toElement();
00065     meta.label = labelelement.text();
00066   }
00067 
00068   return meta;
00069 }
00070 
00071 
00072 static QColor readSymbolColor( const QDomNode& synode, bool fillColor )
00073 {
00074   QDomNode cnode = synode.namedItem( fillColor ? "fillcolor" : "outlinecolor" );
00075   QDomElement celement = cnode.toElement();
00076   int red = celement.attribute( "red" ).toInt();
00077   int green = celement.attribute( "green" ).toInt();
00078   int blue = celement.attribute( "blue" ).toInt();
00079   return QColor( red, green, blue );
00080 }
00081 
00082 static double readOutlineWidth( const QDomNode& synode )
00083 {
00084   QDomNode outlwnode = synode.namedItem( "outlinewidth" );
00085   QDomElement outlwelement = outlwnode.toElement();
00086   return outlwelement.text().toDouble();
00087 }
00088 
00089 
00090 static Qt::PenStyle readOutlineStyle( const QDomNode& synode )
00091 {
00092   QDomNode outlstnode = synode.namedItem( "outlinestyle" );
00093   QDomElement outlstelement = outlstnode.toElement();
00094   return QgsSymbologyV2Conversion::qString2PenStyle( outlstelement.text() );
00095 }
00096 
00097 static Qt::BrushStyle readBrushStyle( const QDomNode& synode )
00098 {
00099   QDomNode fillpnode = synode.namedItem( "fillpattern" );
00100   QDomElement fillpelement = fillpnode.toElement();
00101   return QgsSymbologyV2Conversion::qString2BrushStyle( fillpelement.text() );
00102 }
00103 
00104 static QString readMarkerSymbolName( const QDomNode& synode )
00105 {
00106   QDomNode psymbnode = synode.namedItem( "pointsymbol" );
00107   if ( ! psymbnode.isNull() )
00108   {
00109     QDomElement psymbelement = psymbnode.toElement();
00110     return psymbelement.text();
00111   }
00112   return QString( "hard:circle" );
00113 }
00114 
00115 static float readMarkerSymbolSize( const QDomNode& synode )
00116 {
00117   QDomNode psizenode = synode.namedItem( "pointsize" );
00118   if ( ! psizenode.isNull() )
00119   {
00120     QDomElement psizeelement = psizenode.toElement();
00121     return psizeelement.text().toFloat();
00122   }
00123   return DEFAULT_POINT_SIZE;
00124 }
00125 
00126 
00127 
00128 static QgsSymbolV2* readOldSymbol( const QDomNode& synode, QGis::GeometryType geomType )
00129 {
00130   switch ( geomType )
00131   {
00132     case QGis::Point:
00133     {
00134       QgsMarkerSymbolLayerV2* sl = NULL;
00135       double size = readMarkerSymbolSize( synode );
00136       double angle = 0; // rotation only from classification field
00137       QString symbolName = readMarkerSymbolName( synode );
00138       if ( symbolName.startsWith( "hard:" ) )
00139       {
00140         // simple symbol marker
00141         QColor color = readSymbolColor( synode, true );
00142         QColor borderColor = readSymbolColor( synode, false );
00143         QString name = symbolName.mid( 5 );
00144         sl = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle );
00145       }
00146       else
00147       {
00148         // svg symbol marker
00149         QString name = symbolName.mid( 4 );
00150         sl = new QgsSvgMarkerSymbolLayerV2( name, size, angle );
00151       }
00152       QgsSymbolLayerV2List layers;
00153       layers.append( sl );
00154       return new QgsMarkerSymbolV2( layers );
00155     }
00156 
00157     case QGis::Line:
00158     {
00159       QColor color = readSymbolColor( synode, false );
00160       double width = readOutlineWidth( synode );
00161       Qt::PenStyle penStyle = readOutlineStyle( synode );
00162       QgsLineSymbolLayerV2* sl = new QgsSimpleLineSymbolLayerV2( color, width, penStyle );
00163 
00164       QgsSymbolLayerV2List layers;
00165       layers.append( sl );
00166       return new QgsLineSymbolV2( layers );
00167     }
00168 
00169     case QGis::Polygon:
00170     {
00171       QColor color = readSymbolColor( synode, true );
00172       QColor borderColor = readSymbolColor( synode, false );
00173       Qt::BrushStyle brushStyle = readBrushStyle( synode );
00174       Qt::PenStyle borderStyle = readOutlineStyle( synode );
00175       double borderWidth = readOutlineWidth( synode );
00176       QgsFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, brushStyle, borderColor, borderStyle, borderWidth );
00177 
00178       QgsSymbolLayerV2List layers;
00179       layers.append( sl );
00180       return new QgsFillSymbolV2( layers );
00181     }
00182 
00183     default:
00184       return NULL;
00185   }
00186 }
00187 
00188 
00189 
00190 static QgsFeatureRendererV2* readOldSingleSymbolRenderer( const QDomNode& rnode, QGis::GeometryType geomType )
00191 {
00192   QDomNode synode = rnode.namedItem( "symbol" );
00193   if ( synode.isNull() )
00194     return 0;
00195 
00196   QgsSymbolV2* sy2 = readOldSymbol( synode, geomType );
00197   QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( sy2 );
00198   return r;
00199 }
00200 
00201 
00202 static QgsFeatureRendererV2* readOldGraduatedSymbolRenderer( const QDomNode& rnode, QGis::GeometryType geomType )
00203 {
00204   QDomNode modeNode = rnode.namedItem( "mode" );
00205   QString modeValue = modeNode.toElement().text();
00206   QDomNode classnode = rnode.namedItem( "classificationfield" );
00207   QString classificationField = classnode.toElement().text();
00208 
00209   QgsGraduatedSymbolRendererV2::Mode m = QgsGraduatedSymbolRendererV2::Custom;
00210   if ( modeValue == "Empty" )
00211   {
00212     m = QgsGraduatedSymbolRendererV2::Custom;
00213   }
00214   else if ( modeValue == "Quantile" )
00215   {
00216     m = QgsGraduatedSymbolRendererV2::Quantile;
00217   }
00218   else //default
00219   {
00220     m = QgsGraduatedSymbolRendererV2::EqualInterval;
00221   }
00222 
00223   // load ranges and symbols
00224   QgsRangeList ranges;
00225   QDomNode symbolnode = rnode.namedItem( "symbol" );
00226   while ( !symbolnode.isNull() )
00227   {
00228     QgsSymbolV2* symbolv2 = readOldSymbol( symbolnode, geomType );
00229     if ( symbolv2 )
00230     {
00231       QgsOldSymbolMeta meta = readSymbolMeta( symbolnode );
00232       double lowerValue = meta.lowerValue.toDouble();
00233       double upperValue = meta.upperValue.toDouble();
00234       QString label = meta.label;
00235       if ( label.isEmpty() )
00236         label = QString( "%1 - %2" ).arg( lowerValue, -1, 'f', 3 ).arg( upperValue, -1, 'f', 3 );
00237       ranges.append( QgsRendererRangeV2( lowerValue, upperValue, symbolv2, label ) );
00238     }
00239 
00240     symbolnode = symbolnode.nextSibling();
00241   }
00242 
00243   // create renderer
00244   QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( classificationField, ranges );
00245   r->setMode( m );
00246   return r;
00247 }
00248 
00249 
00250 
00251 static QgsFeatureRendererV2* readOldUniqueValueRenderer( const QDomNode& rnode, QGis::GeometryType geomType )
00252 {
00253   QDomNode classnode = rnode.namedItem( "classificationfield" );
00254   QString classificationField = classnode.toElement().text();
00255 
00256   // read categories and symbols
00257   QgsCategoryList cats;
00258   QDomNode symbolnode = rnode.namedItem( "symbol" );
00259   while ( !symbolnode.isNull() )
00260   {
00261     QgsSymbolV2* symbolv2 = readOldSymbol( symbolnode, geomType );
00262     if ( symbolv2 )
00263     {
00264       QgsOldSymbolMeta meta = readSymbolMeta( symbolnode );
00265       QVariant value = QVariant( meta.lowerValue );
00266       QString label = meta.label;
00267       if ( label.isEmpty() )
00268         label = value.toString();
00269       cats.append( QgsRendererCategoryV2( value, symbolv2, label ) );
00270     }
00271 
00272     symbolnode = symbolnode.nextSibling();
00273   }
00274 
00275   QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( classificationField, cats );
00276   // source symbol and color ramp are not set (unknown)
00277   return r;
00278 }
00279 
00280 
00281 
00282 
00283 QgsFeatureRendererV2* QgsSymbologyV2Conversion::readOldRenderer( const QDomNode& layerNode, QGis::GeometryType geomType )
00284 {
00285   QDomNode singlenode = layerNode.namedItem( "singlesymbol" );
00286   QDomNode graduatednode = layerNode.namedItem( "graduatedsymbol" );
00287   QDomNode continuousnode = layerNode.namedItem( "continuoussymbol" );
00288   QDomNode uniquevaluenode = layerNode.namedItem( "uniquevalue" );
00289 
00290   if ( !singlenode.isNull() )
00291   {
00292     return readOldSingleSymbolRenderer( singlenode, geomType );
00293   }
00294   else if ( !graduatednode.isNull() )
00295   {
00296     return readOldGraduatedSymbolRenderer( graduatednode, geomType );
00297   }
00298   else if ( !continuousnode.isNull() )
00299   {
00300     return 0;
00301   }
00302   else if ( !uniquevaluenode.isNull() )
00303   {
00304     return readOldUniqueValueRenderer( uniquevaluenode, geomType );
00305   }
00306 
00307   return 0;
00308 }
00309 
00310 
00311 /*
00312 UNSUPPORTED RENDERER: continuous color
00313 
00314   QDomNode classnode = rnode.namedItem( "classificationfield" );
00315   QDomNode polyoutlinenode = rnode.namedItem( "polygonoutline" );
00316   QString polyoutline = polyoutlinenode.toElement().text();
00317   if ( polyoutline == "0" )
00318     drawPolygonOutline = false;
00319   else if ( polyoutline == "1" )
00320     drawPolygonOutline = true;
00321   QDomNode lowernode = rnode.namedItem( "lowestsymbol" );
00322   lowSymbol = readOldSymbol( lowernode.namedItem( "symbol" ), geomType );
00323   QDomNode uppernode = rnode.namedItem( "highestsymbol" );
00324   highSymbol = readOldSymbol( uppernode.namedItem( "symbol" ), geomType );
00325 
00326 UNSUPPORTED SYMBOL PROPERTY: point size units
00327 
00328   QDomNode psizeunitnodes = synode.namedItem( "pointsizeunits" );
00329   if ( ! psizeunitnodes.isNull() )
00330   {
00331     QDomElement psizeunitelement = psizeunitnodes.toElement();
00332     QgsDebugMsg( QString( "psizeunitelement:%1" ).arg( psizeunitelement.text() ) );
00333     setPointSizeUnits( psizeunitelement.text().compare( "mapunits", Qt::CaseInsensitive ) == 0 );
00334   }
00335 
00336 UNSUPPORTED SYMBOL PROPERTY: data-defined rotation / scale / symbol name
00337 
00338   rotationClassificationFieldName = synode.namedItem( "rotationclassificationfieldname" ).toElement().text();
00339   scaleClassificationFieldName = synode.namedItem( "scaleclassificationfield" ).toElement().text();
00340   symbolFieldName = synode.namedItem( "symbolfieldname" ).toElement().text();
00341 
00342 UNSUPPORTED SYMBOL PROPERTY: texture
00343 
00344   QDomNode texturepathnode = synode.namedItem( "texturepath" );
00345   QDomElement texturepathelement = texturepathnode.toElement();
00346   setCustomTexture( QgsProject::instance()->readPath( texturepathelement.text() ) );
00347 */
00348 
00349 
00350 
00351 
00352 
00353 QString QgsSymbologyV2Conversion::penStyle2QString( Qt::PenStyle penstyle )
00354 {
00355   if ( penstyle == Qt::NoPen )
00356   {
00357     return "NoPen";
00358   }
00359   else if ( penstyle == Qt::SolidLine )
00360   {
00361     return "SolidLine";
00362   }
00363   else if ( penstyle == Qt::DashLine )
00364   {
00365     return "DashLine";
00366   }
00367   else if ( penstyle == Qt::DotLine )
00368   {
00369     return "DotLine";
00370   }
00371   else if ( penstyle == Qt::DashDotLine )
00372   {
00373     return "DashDotLine";
00374   }
00375   else if ( penstyle == Qt::DashDotDotLine )
00376   {
00377     return "DashDotDotLine";
00378   }
00379   else if ( penstyle == Qt::MPenStyle )
00380   {
00381     return "MPenStyle";
00382   }
00383   else                        //return a null string
00384   {
00385     return QString();
00386   }
00387 }
00388 
00389 Qt::PenStyle QgsSymbologyV2Conversion::qString2PenStyle( QString penString )
00390 {
00391   if ( penString == "NoPen" )
00392   {
00393     return Qt::NoPen;
00394   }
00395   else if ( penString == "SolidLine" )
00396   {
00397     return Qt::SolidLine;
00398   }
00399   else if ( penString == "DashLine" )
00400   {
00401     return Qt::DashLine;
00402   }
00403   else if ( penString == "DotLine" )
00404   {
00405     return Qt::DotLine;
00406   }
00407   else if ( penString == "DashDotLine" )
00408   {
00409     return Qt::DashDotLine;
00410   }
00411   else if ( penString == "DashDotDotLine" )
00412   {
00413     return Qt::DashDotDotLine;
00414   }
00415   else if ( penString == "MPenStyle" )
00416   {
00417     return Qt::MPenStyle;
00418   }
00419   else
00420   {
00421     return Qt::NoPen;
00422   }
00423 }
00424 
00425 QString QgsSymbologyV2Conversion::brushStyle2QString( Qt::BrushStyle brushstyle )
00426 {
00427   if ( brushstyle == Qt::NoBrush )
00428   {
00429     return "NoBrush";
00430   }
00431   else if ( brushstyle == Qt::SolidPattern )
00432   {
00433     return "SolidPattern";
00434   }
00435   else if ( brushstyle == Qt::Dense1Pattern )
00436   {
00437     return "Dense1Pattern";
00438   }
00439   else if ( brushstyle == Qt::Dense2Pattern )
00440   {
00441     return "Dense2Pattern";
00442   }
00443   else if ( brushstyle == Qt::Dense3Pattern )
00444   {
00445     return "Dense3Pattern";
00446   }
00447   else if ( brushstyle == Qt::Dense4Pattern )
00448   {
00449     return "Dense4Pattern";
00450   }
00451   else if ( brushstyle == Qt::Dense5Pattern )
00452   {
00453     return "Dense5Pattern";
00454   }
00455   else if ( brushstyle == Qt::Dense6Pattern )
00456   {
00457     return "Dense6Pattern";
00458   }
00459   else if ( brushstyle == Qt::Dense7Pattern )
00460   {
00461     return "Dense7Pattern";
00462   }
00463   else if ( brushstyle == Qt::HorPattern )
00464   {
00465     return "HorPattern";
00466   }
00467   else if ( brushstyle == Qt::VerPattern )
00468   {
00469     return "VerPattern";
00470   }
00471   else if ( brushstyle == Qt::CrossPattern )
00472   {
00473     return "CrossPattern";
00474   }
00475   else if ( brushstyle == Qt::BDiagPattern )
00476   {
00477     return "BDiagPattern";
00478   }
00479   else if ( brushstyle == Qt::FDiagPattern )
00480   {
00481     return "FDiagPattern";
00482   }
00483   else if ( brushstyle == Qt::DiagCrossPattern )
00484   {
00485     return "DiagCrossPattern";
00486   }
00487   else if ( brushstyle == Qt::TexturePattern )
00488   {
00489     return "TexturePattern";
00490   }
00491   else                        //return a null string
00492   {
00493     QgsDebugMsg( "no matching pattern found" );
00494     return " ";
00495   }
00496 }
00497 
00498 Qt::BrushStyle QgsSymbologyV2Conversion::qString2BrushStyle( QString brushString )
00499 {
00500   if ( brushString == "NoBrush" )
00501   {
00502     return Qt::NoBrush;
00503   }
00504   else if ( brushString == "SolidPattern" )
00505   {
00506     return Qt::SolidPattern;
00507   }
00508   else if ( brushString == "Dense1Pattern" )
00509   {
00510     return Qt::Dense1Pattern;
00511   }
00512   else if ( brushString == "Dense2Pattern" )
00513   {
00514     return Qt::Dense2Pattern;
00515   }
00516   else if ( brushString == "Dense3Pattern" )
00517   {
00518     return Qt::Dense3Pattern;
00519   }
00520   else if ( brushString == "Dense4Pattern" )
00521   {
00522     return Qt::Dense4Pattern;
00523   }
00524   else if ( brushString == "Dense5Pattern" )
00525   {
00526     return Qt::Dense5Pattern;
00527   }
00528   else if ( brushString == "Dense6Pattern" )
00529   {
00530     return Qt::Dense6Pattern;
00531   }
00532   else if ( brushString == "Dense7Pattern" )
00533   {
00534     return Qt::Dense7Pattern;
00535   }
00536   else if ( brushString == "HorPattern" )
00537   {
00538     return Qt::HorPattern;
00539   }
00540   else if ( brushString == "VerPattern" )
00541   {
00542     return Qt::VerPattern;
00543   }
00544   else if ( brushString == "CrossPattern" )
00545   {
00546     return Qt::CrossPattern;
00547   }
00548   else if ( brushString == "BDiagPattern" )
00549   {
00550     return Qt::BDiagPattern;
00551   }
00552   else if ( brushString == "FDiagPattern" )
00553   {
00554     return Qt::FDiagPattern;
00555   }
00556   else if ( brushString == "DiagCrossPattern" )
00557   {
00558     return Qt::DiagCrossPattern;
00559   }
00560   else if ( brushString == "TexturePattern" )
00561   {
00562     return Qt::TexturePattern;
00563   }
00564   else                        //return a null string
00565   {
00566     QgsDebugMsg( QString( "Brush style \"%1\" not found" ).arg( brushString ) );
00567     return Qt::NoBrush;
00568   }
00569 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines