Quantum GIS API Documentation  master-2bfffaa
src/core/symbology/qgssymbol.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           QgsSymbol.cpp  -  description
00003                              -------------------
00004     begin                : Sun Aug 11 2002
00005     copyright            : (C) 2002 by Gary E.Sherman
00006     email                : sherman at mrcc dot com
00007        Romans 3:23=>Romans 6:23=>Romans 5:8=>Romans 10:9,10=>Romans 12
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 #include <cmath>
00019 
00020 #include "qgis.h"
00021 #include "qgssymbol.h"
00022 #include "qgslogger.h"
00023 #include "qgssymbologyutils.h"
00024 #include "qgsmarkercatalogue.h"
00025 #include "qgsapplication.h"
00026 #include "qgsvectorlayer.h"
00027 #include "qgsproject.h"
00028 
00029 #include <QPainter>
00030 #include <QDomNode>
00031 #include <QDomDocument>
00032 #include <QImage>
00033 #include <QDir>
00034 #include <QFileInfo>
00035 //#include <QString>
00036 //do we have to include qstring?
00037 
00038 QgsSymbol::QgsSymbol( QGis::GeometryType t, QString lvalue, QString uvalue, QString label ) :
00039     mLowerValue( lvalue ),
00040     mUpperValue( uvalue ),
00041     mLabel( label ),
00042     mType( t ),
00043     mPointSymbolName( "hard:circle" ),
00044     mSize( DEFAULT_POINT_SIZE ),
00045     mSizeInMapUnits( false ),
00046     mPointSymbolImage( 1, 1, QImage::Format_ARGB32_Premultiplied ),
00047     mWidthScale( -1.0 ),
00048     mCacheUpToDate( false ),
00049     mCacheUpToDate2( false ),
00050     mRotationClassificationField( -1 ),
00051     mScaleClassificationField( -1 ),
00052     mSymbolField( -1 )
00053 {
00054   mPen.setWidthF( DEFAULT_LINE_WIDTH );
00055 }
00056 
00057 
00058 QgsSymbol::QgsSymbol( QGis::GeometryType t, QString lvalue, QString uvalue, QString label, QColor c ) :
00059     mLowerValue( lvalue ),
00060     mUpperValue( uvalue ),
00061     mLabel( label ),
00062     mType( t ),
00063     mPen( c ),
00064     mBrush( c ),
00065     mPointSymbolName( "hard:circle" ),
00066     mSize( DEFAULT_POINT_SIZE ),
00067     mSizeInMapUnits( false ),
00068     mPointSymbolImage( 1, 1, QImage::Format_ARGB32_Premultiplied ),
00069     mWidthScale( -1.0 ),
00070     mCacheUpToDate( false ),
00071     mCacheUpToDate2( false ),
00072     mRotationClassificationField( -1 ),
00073     mScaleClassificationField( -1 ),
00074     mSymbolField( -1 )
00075 {
00076   mPen.setWidthF( DEFAULT_LINE_WIDTH );
00077 }
00078 
00079 QgsSymbol::QgsSymbol()
00080     : mPointSymbolName( "hard:circle" ),
00081     mSize( DEFAULT_POINT_SIZE ),
00082     mSizeInMapUnits( false ),
00083     mPointSymbolImage( 1, 1, QImage::Format_ARGB32_Premultiplied ),
00084     mWidthScale( -1.0 ),
00085     mCacheUpToDate( false ),
00086     mCacheUpToDate2( false ),
00087     mRotationClassificationField( -1 ),
00088     mScaleClassificationField( -1 ),
00089     mSymbolField( -1 )
00090 {
00091   mPen.setWidthF( DEFAULT_LINE_WIDTH );
00092 }
00093 
00094 
00095 QgsSymbol::QgsSymbol( QColor c )
00096     : mPen( c ),
00097     mBrush( c ),
00098     mPointSymbolName( "hard:circle" ),
00099     mSize( DEFAULT_POINT_SIZE ),
00100     mSizeInMapUnits( false ),
00101     mPointSymbolImage( 1, 1, QImage::Format_ARGB32_Premultiplied ),
00102     mWidthScale( -1.0 ),
00103     mCacheUpToDate( false ),
00104     mCacheUpToDate2( false ),
00105     mRotationClassificationField( -1 ),
00106     mScaleClassificationField( -1 ),
00107     mSymbolField( -1 )
00108 {
00109   mPen.setWidthF( DEFAULT_LINE_WIDTH );
00110 }
00111 
00112 QgsSymbol::QgsSymbol( const QgsSymbol& s )
00113 {
00114   if ( this != &s )
00115   {
00116     mLowerValue = s.mLowerValue;
00117     mUpperValue = s.mUpperValue;
00118     mLabel = s.mLabel;
00119     mType = s.mType;
00120     mPen = s.mPen;
00121     mBrush = s.mBrush;
00122     mTextureFilePath = s.mTextureFilePath;
00123     mPointSymbolName = s.mPointSymbolName;
00124     mSize = s.mSize;
00125     mSizeInMapUnits = s.mSizeInMapUnits;
00126     mPointSymbolImage = s.mPointSymbolImage;
00127     mPointSymbolImageSelected = s.mPointSymbolImageSelected;
00128     mWidthScale = s.mWidthScale;
00129     mPointSymbolImage2 = s.mPointSymbolImage2;
00130     mPointSymbolImageSelected2 = s.mPointSymbolImageSelected2;
00131     mCacheUpToDate = s.mCacheUpToDate;
00132     mCacheUpToDate2 = s.mCacheUpToDate2;
00133     mSelectionColor = s.mSelectionColor;
00134     mSelectionColor2 = s.mSelectionColor2;
00135     mRotationClassificationField = s.mRotationClassificationField;
00136     mScaleClassificationField = s.mScaleClassificationField;
00137     mSymbolField = s.mSymbolField;
00138   }
00139 }
00140 
00141 QgsSymbol::~QgsSymbol()
00142 {
00143 }
00144 
00145 
00146 QColor QgsSymbol::color() const
00147 {
00148   return mPen.color();
00149 }
00150 
00151 void QgsSymbol::setColor( QColor c )
00152 {
00153   mPen.setColor( c );
00154   mCacheUpToDate = mCacheUpToDate2 = false;
00155 }
00156 
00157 QColor QgsSymbol::fillColor() const
00158 {
00159   return mBrush.color();
00160 }
00161 
00162 void QgsSymbol::setFillColor( QColor c )
00163 {
00164   mBrush.setColor( c );
00165   mCacheUpToDate = mCacheUpToDate2 = false;
00166 }
00167 
00168 double QgsSymbol::lineWidth() const
00169 {
00170   return mPen.widthF();
00171 }
00172 
00173 void QgsSymbol::setLineWidth( double w )
00174 {
00175   mPen.setWidthF( w );
00176   mCacheUpToDate = mCacheUpToDate2 = false;
00177 }
00178 
00179 void QgsSymbol::setLineStyle( Qt::PenStyle s )
00180 {
00181   mPen.setStyle( s );
00182   mCacheUpToDate = mCacheUpToDate2 = false;
00183 }
00184 
00185 void QgsSymbol::setFillStyle( Qt::BrushStyle s )
00186 {
00187   mBrush.setStyle( s );
00188   mCacheUpToDate = mCacheUpToDate2 = false;
00189 }
00190 
00191 QString QgsSymbol::customTexture() const
00192 {
00193   return mTextureFilePath;
00194 }
00195 
00196 void QgsSymbol::setCustomTexture( QString path )
00197 {
00198   mTextureFilePath = path;
00199   mBrush.setTextureImage( QImage( path ) );
00200   mCacheUpToDate = mCacheUpToDate2 = false;
00201 }
00202 
00203 //should we set the path independently of setting the texture?
00204 
00205 void QgsSymbol::setNamedPointSymbol( QString name )
00206 {
00207   if ( name.startsWith( "svg:" ) )
00208   {
00209     // do some sanity checking for svgs...
00210     QString myTempName = name;
00211     myTempName.replace( "svg:", "" );
00212     QFile myFile( myTempName );
00213     if ( !myFile.exists() )
00214     {
00215       QgsDebugMsg( "\n\n\n *** Svg Symbol not found on fs ***" );
00216       QgsDebugMsg( "Name: " + name );
00217       //see if we can resolve the problem...
00218       //
00219 
00220       QStringList svgPaths = QgsApplication::svgPaths();
00221       for ( int i = 0; i < svgPaths.size(); i++ )
00222       {
00223         QgsDebugMsg( "SvgPath: " + svgPaths[i] );
00224         QFileInfo myInfo( myTempName );
00225         QString myFileName = myInfo.fileName(); // foo.svg
00226         QString myLowestDir = myInfo.dir().dirName();
00227         QString myLocalPath = svgPaths[i] + "/" + myLowestDir + "/" + myFileName;
00228 
00229         QgsDebugMsg( "Alternative svg path: " + myLocalPath );
00230         if ( QFile( myLocalPath ).exists() )
00231         {
00232           name = "svg:" + myLocalPath;
00233           QgsDebugMsg( "Svg found in alternative path" );
00234         }
00235         else if ( myInfo.isRelative() )
00236         {
00237           QFileInfo pfi( QgsProject::instance()->fileName() );
00238           if ( pfi.exists() && QFile( pfi.canonicalPath() + QDir::separator() + myTempName ).exists() )
00239           {
00240             name = "svg:" + pfi.canonicalPath() + QDir::separator() + myTempName;
00241             QgsDebugMsg( "Svg found in alternative path" );
00242             break;
00243           }
00244           else
00245           {
00246             QgsDebugMsg( "Svg not found in project path" );
00247           }
00248         }
00249         else
00250         {
00251           //couldnt find the file, no happy ending :-(
00252           QgsDebugMsg( "Computed alternate path but no svg there either" );
00253         }
00254       }
00255     }
00256   }
00257   mPointSymbolName = name;
00258   mCacheUpToDate = mCacheUpToDate2 = false;
00259 }
00260 
00261 QString QgsSymbol::pointSymbolName() const
00262 {
00263   return mPointSymbolName;
00264 }
00265 
00266 void QgsSymbol::setPointSizeUnits( bool sizeInMapUnits )
00267 {
00268   mSizeInMapUnits = sizeInMapUnits;
00269 }
00270 
00271 bool QgsSymbol::pointSizeUnits() const
00272 {
00273   return mSizeInMapUnits;
00274 }
00275 
00276 void QgsSymbol::setPointSize( double s )
00277 {
00278   if ( mSizeInMapUnits )
00279   {
00280     mSize = s;
00281   }
00282   else if ( s < MINIMUM_POINT_SIZE )
00283     mSize = MINIMUM_POINT_SIZE;
00284   else
00285     mSize = s;
00286 
00287   mCacheUpToDate = mCacheUpToDate2 = false;
00288 }
00289 
00290 double QgsSymbol::pointSize() const
00291 {
00292   return mSize;
00293 }
00294 
00295 QImage QgsSymbol::getLineSymbolAsImage()
00296 {
00297   //Note by Tim: don't use premultiplied - it causes
00298   //artifacts on the output icon!
00299   QImage img( 15, 15, QImage::Format_ARGB32 );//QImage::Format_ARGB32_Premultiplied);
00300   //0 = fully transparent
00301   img.fill( QColor( 255, 255, 255, 0 ).rgba() );
00302   QPainter p( &img );
00303   p.setRenderHints( QPainter::Antialiasing );
00304   p.setPen( mPen );
00305 
00306 
00307   QPainterPath myPath;
00308   myPath.moveTo( 0, 0 );
00309   myPath.cubicTo( 15, 0, 5, 7, 15, 15 );
00310   p.drawPath( myPath );
00311   //p.drawLine(0, 0, 15, 15);
00312   return img; //this is ok because of qts sharing mechanism
00313 }
00314 
00315 QImage QgsSymbol::getPolygonSymbolAsImage()
00316 {
00317   //Note by Tim: don't use premultiplied - it causes
00318   //artifacts on the output icon!
00319   QImage img( 15, 15, QImage::Format_ARGB32 ); //, QImage::Format_ARGB32_Premultiplied);
00320   //0 = fully transparent
00321   img.fill( QColor( 255, 255, 255, 0 ).rgba() );
00322   QPainter p( &img );
00323   p.setRenderHints( QPainter::Antialiasing );
00324   p.setPen( mPen );
00325   p.setBrush( mBrush );
00326   QPolygon myPolygon;
00327   //leave a little white space around so
00328   //don't draw at 0,0,15,15
00329   myPolygon << QPoint( 2, 2 )
00330   << QPoint( 1, 5 )
00331   << QPoint( 1, 10 )
00332   << QPoint( 2, 12 )
00333   << QPoint( 5, 13 )
00334   << QPoint( 6, 13 )
00335   << QPoint( 8, 12 )
00336   << QPoint( 8, 12 )
00337   << QPoint( 10, 12 )
00338   << QPoint( 12, 13 )
00339   << QPoint( 13, 11 )
00340   << QPoint( 12, 8 )
00341   << QPoint( 11, 6 )
00342   << QPoint( 12, 5 )
00343   << QPoint( 13, 2 )
00344   << QPoint( 11, 1 )
00345   << QPoint( 10, 1 )
00346   << QPoint( 8, 2 )
00347   << QPoint( 6, 4 )
00348   << QPoint( 4, 2 )
00349   ;
00350   p.drawPolygon( myPolygon );
00351   //p.drawRect(1, 1, 14, 14);
00352   return img; //this is ok because of qts sharing mechanism
00353 }
00354 
00355 QImage QgsSymbol::getCachedPointSymbolAsImage( double widthScale, bool selected, QColor selectionColor, double opacity )
00356 {
00357   if ( !mCacheUpToDate2
00358        || ( selected && mSelectionColor != selectionColor ) || ( opacity != mOpacity ) )
00359   {
00360     if ( selected )
00361     {
00362       cache2( widthScale, selectionColor, opacity );
00363     }
00364     else
00365     {
00366 
00367       cache2( widthScale, mSelectionColor, opacity );
00368     }
00369   }
00370 
00371   if ( selected )
00372   {
00373     return mPointSymbolImageSelected2;
00374   }
00375   else
00376   {
00377     return mPointSymbolImage2;
00378   }
00379 }
00380 
00381 QImage QgsSymbol::getPointSymbolAsImage( double widthScale, bool selected, QColor selectionColor, double scale,
00382     double rotation, double rasterScaleFactor, double opacity )
00383 {
00384   double scaleProduct = scale * rasterScaleFactor;
00385 
00386   //on systems where dpi in x- and y-direction are not the same, the scaleProduct may differ from 1.0 by a very small number
00387   if ( scaleProduct > 0.9 && scaleProduct < 1.1 && 0 == rotation )
00388   {
00389     if ( mWidthScale < 0 || widthScale == mWidthScale )
00390     {
00391       // If scale is 1.0, rotation 0.0  use cached image.
00392       return getCachedPointSymbolAsImage( widthScale, selected, selectionColor, opacity );
00393     }
00394   }
00395 
00396   QImage preRotateImage;
00397   QPen pen = mPen;
00398   double newWidth = mPen.widthF() * widthScale * rasterScaleFactor;
00399   pen.setWidthF( newWidth );
00400 
00401   if ( selected )
00402   {
00403     pen.setColor( selectionColor );
00404     QBrush brush = mBrush;
00405     preRotateImage = QgsMarkerCatalogue::instance()->imageMarker(
00406                        mPointSymbolName,
00407                        ( float )( mSize * scale * widthScale * rasterScaleFactor ),
00408                        pen, mBrush, opacity );
00409   }
00410   else
00411   {
00412     QgsDebugMsgLevel( QString( "marker:%1 mPointSize:%2 mPointSizeUnits:%3 scale:%4 widthScale:%5 rasterScaleFactor:%6 opacity:%7" )
00413                       .arg( mPointSymbolName ).arg( mSize ).arg( mSizeInMapUnits ? "true" : "false" )
00414                       .arg( scale ).arg( widthScale ).arg( rasterScaleFactor ).arg( opacity ), 3 );
00415 
00416 
00417     preRotateImage = QgsMarkerCatalogue::instance()->imageMarker(
00418                        mPointSymbolName,
00419                        ( float )( mSize * scale * widthScale * rasterScaleFactor ),
00420                        pen, mBrush, opacity );
00421   }
00422 
00423   QMatrix rotationMatrix;
00424   rotationMatrix = rotationMatrix.rotate( rotation );
00425 
00426   return preRotateImage.transformed( rotationMatrix, Qt::SmoothTransformation );
00427 }
00428 
00429 
00430 void QgsSymbol::cache( QColor selectionColor )
00431 {
00432   QPen pen = mPen;
00433   pen.setColor( selectionColor );
00434   QBrush brush = mBrush;
00435   // For symbols that have a different colored border, the line
00436   // below causes the fill color to be wrong for the print
00437   // composer. Not sure why...
00438   // brush.setColor ( selectionColor );
00439 
00440   mPointSymbolImage = QgsMarkerCatalogue::instance()->imageMarker( mPointSymbolName, mSize,
00441                       mPen, mBrush );
00442 
00443   mPointSymbolImageSelected = QgsMarkerCatalogue::instance()->imageMarker(
00444                                 mPointSymbolName, mSize, pen, brush );
00445 
00446   mSelectionColor = selectionColor;
00447   mCacheUpToDate = true;
00448 }
00449 
00450 void QgsSymbol::cache2( double widthScale, QColor selectionColor, double opacity )
00451 {
00452 // QgsDebugMsg(QString("widthScale = %1").arg(widthScale));
00453 
00454   QPen pen = mPen;
00455   pen.setWidthF( widthScale * pen.widthF() );
00456 
00457   mPointSymbolImage2 = QgsMarkerCatalogue::instance()->imageMarker( mPointSymbolName, mSize * widthScale,
00458                        pen, mBrush, opacity );
00459 
00460   QBrush brush = mBrush;
00461   brush.setColor( selectionColor );
00462   pen.setColor( selectionColor );
00463 
00464   mPointSymbolImageSelected2 = QgsMarkerCatalogue::instance()->imageMarker(
00465                                  mPointSymbolName, mSize * widthScale, pen, brush, opacity );
00466 
00467   mSelectionColor2 = selectionColor;
00468 
00469   mWidthScale = widthScale;
00470 
00471   mOpacity = opacity;
00472 
00473   mCacheUpToDate2 = true;
00474 }
00475 
00476 void QgsSymbol::appendField( QDomElement &symbol, QDomDocument &document, const QgsVectorLayer &vl, QString name, int idx ) const
00477 {
00478   const QgsFields& fields = vl.pendingFields();
00479   QString txt = ( idx >= 0 && idx < fields.count() ? fields[idx].name() : QString() );
00480   appendText( symbol, document, name, txt );
00481 }
00482 
00483 void QgsSymbol::appendText( QDomElement &symbol, QDomDocument &document, QString name, QString value ) const
00484 {
00485   QDomElement node = document.createElement( name );
00486   QDomText txt = document.createTextNode( value );
00487   if ( value.isNull() )
00488   {
00489     node.setAttribute( "null", "1" );
00490   }
00491   symbol.appendChild( node );
00492   node.appendChild( txt );
00493 }
00494 
00495 bool QgsSymbol::writeXML( QDomNode & item, QDomDocument & document, const QgsVectorLayer *vl ) const
00496 {
00497   bool returnval = false;
00498   returnval = true; // no error checking yet
00499   QDomElement symbol = document.createElement( "symbol" );
00500   item.appendChild( symbol );
00501 
00502   appendText( symbol, document, "lowervalue", mLowerValue );
00503   appendText( symbol, document, "uppervalue", mUpperValue );
00504   appendText( symbol, document, "label", mLabel );
00505 
00506   QString name = pointSymbolName();
00507   if ( name.startsWith( "svg:" ) )
00508   {
00509     name = name.mid( 4 );
00510 
00511     QFileInfo fi( name );
00512     if ( fi.exists() )
00513     {
00514       name = fi.canonicalFilePath();
00515 
00516       QStringList svgPaths = QgsApplication::svgPaths();
00517 
00518       for ( int i = 0; i < svgPaths.size(); i++ )
00519       {
00520         QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
00521 
00522         if ( !dir.isEmpty() && name.startsWith( dir ) )
00523         {
00524           name = name.mid( dir.size() );
00525           break;
00526         }
00527       }
00528     }
00529 
00530     name = "svg:" + name;
00531   }
00532 
00533   appendText( symbol, document, "pointsymbol", name );
00534   appendText( symbol, document, "pointsize", QString::number( pointSize() ) );
00535   appendText( symbol, document, "pointsizeunits", pointSizeUnits() ? "mapunits" : "pixels" );
00536 
00537   if ( vl )
00538   {
00539     appendField( symbol, document, *vl, "rotationclassificationfieldname", mRotationClassificationField );
00540     appendField( symbol, document, *vl, "scaleclassificationfieldname", mScaleClassificationField );
00541     appendField( symbol, document, *vl, "symbolfieldname", mSymbolField );
00542   }
00543 
00544   QDomElement outlinecolor = document.createElement( "outlinecolor" );
00545   outlinecolor.setAttribute( "red", QString::number( mPen.color().red() ) );
00546   outlinecolor.setAttribute( "green", QString::number( mPen.color().green() ) );
00547   outlinecolor.setAttribute( "blue", QString::number( mPen.color().blue() ) );
00548   symbol.appendChild( outlinecolor );
00549 
00550   appendText( symbol, document, "outlinestyle", QgsSymbologyUtils::penStyle2QString( mPen.style() ) );
00551   appendText( symbol, document, "outlinewidth", QString::number( mPen.widthF() ) );
00552 
00553   QDomElement fillcolor = document.createElement( "fillcolor" );
00554   fillcolor.setAttribute( "red", QString::number( mBrush.color().red() ) );
00555   fillcolor.setAttribute( "green", QString::number( mBrush.color().green() ) );
00556   fillcolor.setAttribute( "blue", QString::number( mBrush.color().blue() ) );
00557   symbol.appendChild( fillcolor );
00558 
00559   appendText( symbol, document, "fillpattern", QgsSymbologyUtils::brushStyle2QString( mBrush.style() ) );
00560   appendText( symbol, document, "texturepath", QgsProject::instance()->writePath( mTextureFilePath ) );
00561 
00562   return returnval;
00563 }
00564 
00565 int QgsSymbol::readFieldName( QDomNode &synode, QString name, const QgsVectorLayer &vl )
00566 {
00567   QDomNode node = synode.namedItem( name + "name" );
00568 
00569   if ( !node.isNull() )
00570   {
00571     const QgsFields &fields = vl.pendingFields();
00572     QString name = node.toElement().text();
00573 
00574     for ( int idx = 0; idx < fields.count(); ++idx )
00575       if ( fields[idx].name() == name )
00576         return idx;
00577 
00578     return -1;
00579   }
00580 
00581   node = synode.namedItem( name );
00582 
00583   return node.isNull() ? -1 : node.toElement().text().toInt();
00584 }
00585 
00586 bool QgsSymbol::readXML( QDomNode &synode, const QgsVectorLayer *vl )
00587 {
00588   // Legacy project file formats didn't have support for pointsymbol nor
00589   // pointsize Dom elements.  Therefore we should check whether these
00590   // actually exist.
00591 
00592   QDomNode lvalnode = synode.namedItem( "lowervalue" );
00593   if ( ! lvalnode.isNull() )
00594   {
00595     QDomElement lvalelement = lvalnode.toElement();
00596     if ( lvalelement.attribute( "null" ).toInt() == 1 )
00597     {
00598       mLowerValue = QString::null;
00599     }
00600     else
00601     {
00602       mLowerValue = lvalelement.text();
00603     }
00604   }
00605 
00606   QDomNode uvalnode = synode.namedItem( "uppervalue" );
00607   if ( ! uvalnode.isNull() )
00608   {
00609     QDomElement uvalelement = uvalnode.toElement();
00610     mUpperValue = uvalelement.text();
00611   }
00612 
00613   QDomNode labelnode = synode.namedItem( "label" );
00614   if ( ! labelnode.isNull() )
00615   {
00616     QDomElement labelelement = labelnode.toElement();
00617     mLabel = labelelement.text();
00618   }
00619 
00620   QDomNode psymbnode = synode.namedItem( "pointsymbol" );
00621 
00622   if ( ! psymbnode.isNull() )
00623   {
00624     QDomElement psymbelement = psymbnode.toElement();
00625     setNamedPointSymbol( psymbelement.text() );
00626   }
00627 
00628   QDomNode psizenode = synode.namedItem( "pointsize" );
00629 
00630   if ( ! psizenode.isNull() )
00631   {
00632     QDomElement psizeelement = psizenode.toElement();
00633     setPointSize( psizeelement.text().toFloat() );
00634   }
00635 
00636   QDomNode psizeunitnodes = synode.namedItem( "pointsizeunits" );
00637   if ( ! psizeunitnodes.isNull() )
00638   {
00639     QDomElement psizeunitelement = psizeunitnodes.toElement();
00640     QgsDebugMsg( QString( "psizeunitelement:%1" ).arg( psizeunitelement.text() ) );
00641     setPointSizeUnits( psizeunitelement.text().compare( "mapunits", Qt::CaseInsensitive ) == 0 );
00642   }
00643 
00644   if ( vl )
00645   {
00646     mRotationClassificationField = readFieldName( synode, "rotationclassificationfield", *vl );
00647     mScaleClassificationField = readFieldName( synode, "scaleclassificationfield", *vl );
00648     mSymbolField = readFieldName( synode, "symbolfield", *vl );
00649   }
00650   else
00651   {
00652     mRotationClassificationField = -1;
00653     mScaleClassificationField = -1;
00654   }
00655 
00656   QDomNode outlcnode = synode.namedItem( "outlinecolor" );
00657   QDomElement oulcelement = outlcnode.toElement();
00658   int red = oulcelement.attribute( "red" ).toInt();
00659   int green = oulcelement.attribute( "green" ).toInt();
00660   int blue = oulcelement.attribute( "blue" ).toInt();
00661   setColor( QColor( red, green, blue ) );
00662 
00663   QDomNode outlstnode = synode.namedItem( "outlinestyle" );
00664   QDomElement outlstelement = outlstnode.toElement();
00665   setLineStyle( QgsSymbologyUtils::qString2PenStyle( outlstelement.text() ) );
00666 
00667   QDomNode outlwnode = synode.namedItem( "outlinewidth" );
00668   QDomElement outlwelement = outlwnode.toElement();
00669   setLineWidth( outlwelement.text().toDouble() );
00670 
00671   QDomNode fillcnode = synode.namedItem( "fillcolor" );
00672   QDomElement fillcelement = fillcnode.toElement();
00673   red = fillcelement.attribute( "red" ).toInt();
00674   green = fillcelement.attribute( "green" ).toInt();
00675   blue = fillcelement.attribute( "blue" ).toInt();
00676   setFillColor( QColor( red, green, blue ) );
00677 
00678   QDomNode texturepathnode = synode.namedItem( "texturepath" );
00679   QDomElement texturepathelement = texturepathnode.toElement();
00680   setCustomTexture( QgsProject::instance()->readPath( texturepathelement.text() ) );
00681 
00682   //run this after setting the custom texture path, so we override the brush if it isn't the custom pattern brush.
00683   QDomNode fillpnode = synode.namedItem( "fillpattern" );
00684   QDomElement fillpelement = fillpnode.toElement();
00685   setFillStyle( QgsSymbologyUtils::qString2BrushStyle( fillpelement.text() ) );
00686 
00687   return true;
00688 }
00689 
00690 int QgsSymbol::rotationClassificationField() const
00691 {
00692   return mRotationClassificationField;
00693 }
00694 
00695 void QgsSymbol::setRotationClassificationField( int field )
00696 {
00697   mRotationClassificationField = field;
00698 }
00699 
00700 int QgsSymbol::scaleClassificationField() const
00701 {
00702   return mScaleClassificationField;
00703 }
00704 
00705 void QgsSymbol::setScaleClassificationField( int field )
00706 {
00707   mScaleClassificationField = field;
00708 }
00709 
00710 int QgsSymbol::symbolField() const
00711 {
00712   return mSymbolField;
00713 }
00714 
00715 void QgsSymbol::setSymbolField( int field )
00716 {
00717   mSymbolField = field;
00718 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines