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