Quantum GIS API Documentation
1.7.4
|
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 }