Quantum GIS API Documentation  1.8
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   appendText( symbol, document, name, vl.pendingFields().contains( idx ) ? vl.pendingFields()[idx].name() : "" );
00479 }
00480 
00481 void QgsSymbol::appendText( QDomElement &symbol, QDomDocument &document, QString name, QString value ) const
00482 {
00483   QDomElement node = document.createElement( name );
00484   QDomText txt = document.createTextNode( value );
00485   if ( value.isNull() )
00486   {
00487     node.setAttribute( "null", "1" );
00488   }
00489   symbol.appendChild( node );
00490   node.appendChild( txt );
00491 }
00492 
00493 bool QgsSymbol::writeXML( QDomNode & item, QDomDocument & document, const QgsVectorLayer *vl ) const
00494 {
00495   bool returnval = false;
00496   returnval = true; // no error checking yet
00497   QDomElement symbol = document.createElement( "symbol" );
00498   item.appendChild( symbol );
00499 
00500   appendText( symbol, document, "lowervalue", mLowerValue );
00501   appendText( symbol, document, "uppervalue", mUpperValue );
00502   appendText( symbol, document, "label", mLabel );
00503 
00504   QString name = pointSymbolName();
00505   if ( name.startsWith( "svg:" ) )
00506   {
00507     name = name.mid( 4 );
00508 
00509     QFileInfo fi( name );
00510     if ( fi.exists() )
00511     {
00512       name = fi.canonicalFilePath();
00513 
00514       QStringList svgPaths = QgsApplication::svgPaths();
00515 
00516       for ( int i = 0; i < svgPaths.size(); i++ )
00517       {
00518         QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
00519 
00520         if ( !dir.isEmpty() && name.startsWith( dir ) )
00521         {
00522           name = name.mid( dir.size() );
00523           break;
00524         }
00525       }
00526     }
00527 
00528     name = "svg:" + name;
00529   }
00530 
00531   appendText( symbol, document, "pointsymbol", name );
00532   appendText( symbol, document, "pointsize", QString::number( pointSize() ) );
00533   appendText( symbol, document, "pointsizeunits", pointSizeUnits() ? "mapunits" : "pixels" );
00534 
00535   if ( vl )
00536   {
00537     appendField( symbol, document, *vl, "rotationclassificationfieldname", mRotationClassificationField );
00538     appendField( symbol, document, *vl, "scaleclassificationfieldname", mScaleClassificationField );
00539     appendField( symbol, document, *vl, "symbolfieldname", mSymbolField );
00540   }
00541 
00542   QDomElement outlinecolor = document.createElement( "outlinecolor" );
00543   outlinecolor.setAttribute( "red", QString::number( mPen.color().red() ) );
00544   outlinecolor.setAttribute( "green", QString::number( mPen.color().green() ) );
00545   outlinecolor.setAttribute( "blue", QString::number( mPen.color().blue() ) );
00546   symbol.appendChild( outlinecolor );
00547 
00548   appendText( symbol, document, "outlinestyle", QgsSymbologyUtils::penStyle2QString( mPen.style() ) );
00549   appendText( symbol, document, "outlinewidth", QString::number( mPen.widthF() ) );
00550 
00551   QDomElement fillcolor = document.createElement( "fillcolor" );
00552   fillcolor.setAttribute( "red", QString::number( mBrush.color().red() ) );
00553   fillcolor.setAttribute( "green", QString::number( mBrush.color().green() ) );
00554   fillcolor.setAttribute( "blue", QString::number( mBrush.color().blue() ) );
00555   symbol.appendChild( fillcolor );
00556 
00557   appendText( symbol, document, "fillpattern", QgsSymbologyUtils::brushStyle2QString( mBrush.style() ) );
00558   appendText( symbol, document, "texturepath", QgsProject::instance()->writePath( mTextureFilePath ) );
00559 
00560   return returnval;
00561 }
00562 
00563 int QgsSymbol::readFieldName( QDomNode &synode, QString name, const QgsVectorLayer &vl )
00564 {
00565   QDomNode node = synode.namedItem( name + "name" );
00566 
00567   if ( !node.isNull() )
00568   {
00569     const QgsFieldMap &fields = vl.pendingFields();
00570     QString name = node.toElement().text();
00571 
00572     for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ )
00573       if ( it->name() == name )
00574         return it.key();
00575 
00576     return -1;
00577   }
00578 
00579   node = synode.namedItem( name );
00580 
00581   return node.isNull() ? -1 : node.toElement().text().toInt();
00582 }
00583 
00584 bool QgsSymbol::readXML( QDomNode &synode, const QgsVectorLayer *vl )
00585 {
00586   // Legacy project file formats didn't have support for pointsymbol nor
00587   // pointsize Dom elements.  Therefore we should check whether these
00588   // actually exist.
00589 
00590   QDomNode lvalnode = synode.namedItem( "lowervalue" );
00591   if ( ! lvalnode.isNull() )
00592   {
00593     QDomElement lvalelement = lvalnode.toElement();
00594     if ( lvalelement.attribute( "null" ).toInt() == 1 )
00595     {
00596       mLowerValue = QString::null;
00597     }
00598     else
00599     {
00600       mLowerValue = lvalelement.text();
00601     }
00602   }
00603 
00604   QDomNode uvalnode = synode.namedItem( "uppervalue" );
00605   if ( ! uvalnode.isNull() )
00606   {
00607     QDomElement uvalelement = uvalnode.toElement();
00608     mUpperValue = uvalelement.text();
00609   }
00610 
00611   QDomNode labelnode = synode.namedItem( "label" );
00612   if ( ! labelnode.isNull() )
00613   {
00614     QDomElement labelelement = labelnode.toElement();
00615     mLabel = labelelement.text();
00616   }
00617 
00618   QDomNode psymbnode = synode.namedItem( "pointsymbol" );
00619 
00620   if ( ! psymbnode.isNull() )
00621   {
00622     QDomElement psymbelement = psymbnode.toElement();
00623     setNamedPointSymbol( psymbelement.text() );
00624   }
00625 
00626   QDomNode psizenode = synode.namedItem( "pointsize" );
00627 
00628   if ( ! psizenode.isNull() )
00629   {
00630     QDomElement psizeelement = psizenode.toElement();
00631     setPointSize( psizeelement.text().toFloat() );
00632   }
00633 
00634   QDomNode psizeunitnodes = synode.namedItem( "pointsizeunits" );
00635   if ( ! psizeunitnodes.isNull() )
00636   {
00637     QDomElement psizeunitelement = psizeunitnodes.toElement();
00638     QgsDebugMsg( QString( "psizeunitelement:%1" ).arg( psizeunitelement.text() ) );
00639     setPointSizeUnits( psizeunitelement.text().compare( "mapunits", Qt::CaseInsensitive ) == 0 );
00640   }
00641 
00642   if ( vl )
00643   {
00644     mRotationClassificationField = readFieldName( synode, "rotationclassificationfield", *vl );
00645     mScaleClassificationField = readFieldName( synode, "scaleclassificationfield", *vl );
00646     mSymbolField = readFieldName( synode, "symbolfield", *vl );
00647   }
00648   else
00649   {
00650     mRotationClassificationField = -1;
00651     mScaleClassificationField = -1;
00652   }
00653 
00654   QDomNode outlcnode = synode.namedItem( "outlinecolor" );
00655   QDomElement oulcelement = outlcnode.toElement();
00656   int red = oulcelement.attribute( "red" ).toInt();
00657   int green = oulcelement.attribute( "green" ).toInt();
00658   int blue = oulcelement.attribute( "blue" ).toInt();
00659   setColor( QColor( red, green, blue ) );
00660 
00661   QDomNode outlstnode = synode.namedItem( "outlinestyle" );
00662   QDomElement outlstelement = outlstnode.toElement();
00663   setLineStyle( QgsSymbologyUtils::qString2PenStyle( outlstelement.text() ) );
00664 
00665   QDomNode outlwnode = synode.namedItem( "outlinewidth" );
00666   QDomElement outlwelement = outlwnode.toElement();
00667   setLineWidth( outlwelement.text().toDouble() );
00668 
00669   QDomNode fillcnode = synode.namedItem( "fillcolor" );
00670   QDomElement fillcelement = fillcnode.toElement();
00671   red = fillcelement.attribute( "red" ).toInt();
00672   green = fillcelement.attribute( "green" ).toInt();
00673   blue = fillcelement.attribute( "blue" ).toInt();
00674   setFillColor( QColor( red, green, blue ) );
00675 
00676   QDomNode texturepathnode = synode.namedItem( "texturepath" );
00677   QDomElement texturepathelement = texturepathnode.toElement();
00678   setCustomTexture( QgsProject::instance()->readPath( texturepathelement.text() ) );
00679 
00680   //run this after setting the custom texture path, so we override the brush if it isn't the custom pattern brush.
00681   QDomNode fillpnode = synode.namedItem( "fillpattern" );
00682   QDomElement fillpelement = fillpnode.toElement();
00683   setFillStyle( QgsSymbologyUtils::qString2BrushStyle( fillpelement.text() ) );
00684 
00685   return true;
00686 }
00687 
00688 int QgsSymbol::rotationClassificationField() const
00689 {
00690   return mRotationClassificationField;
00691 }
00692 
00693 void QgsSymbol::setRotationClassificationField( int field )
00694 {
00695   mRotationClassificationField = field;
00696 }
00697 
00698 int QgsSymbol::scaleClassificationField() const
00699 {
00700   return mScaleClassificationField;
00701 }
00702 
00703 void QgsSymbol::setScaleClassificationField( int field )
00704 {
00705   mScaleClassificationField = field;
00706 }
00707 
00708 int QgsSymbol::symbolField() const
00709 {
00710   return mSymbolField;
00711 }
00712 
00713 void QgsSymbol::setSymbolField( int field )
00714 {
00715   mSymbolField = field;
00716 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines