Quantum GIS API Documentation  1.7.4
src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
Go to the documentation of this file.
00001 
00002 #include "qgssinglesymbolrendererv2.h"
00003 
00004 #include "qgssymbolv2.h"
00005 #include "qgssymbollayerv2utils.h"
00006 
00007 #include "qgslogger.h"
00008 #include "qgsfeature.h"
00009 #include "qgsvectorlayer.h"
00010 
00011 #include <QDomDocument>
00012 #include <QDomElement>
00013 
00014 QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2( QgsSymbolV2* symbol )
00015     : QgsFeatureRendererV2( "singleSymbol" ), mRotationFieldIdx( -1 ), mSizeScaleFieldIdx( -1 ), mTempSymbol( NULL )
00016 {
00017   Q_ASSERT( symbol );
00018   mSymbol = symbol;
00019 }
00020 
00021 QgsSingleSymbolRendererV2::~QgsSingleSymbolRendererV2()
00022 {
00023   delete mSymbol;
00024 }
00025 
00026 QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature( QgsFeature& feature )
00027 {
00028   if ( mRotationFieldIdx == -1 && mSizeScaleFieldIdx == -1 )
00029     return mSymbol;
00030 
00031   double rotation = 0;
00032   double sizeScale = 1;
00033   if ( mRotationFieldIdx != -1 )
00034   {
00035     rotation = feature.attributeMap()[mRotationFieldIdx].toDouble();
00036   }
00037   if ( mSizeScaleFieldIdx != -1 )
00038   {
00039     sizeScale = feature.attributeMap()[mSizeScaleFieldIdx].toDouble();
00040   }
00041 
00042   if ( mTempSymbol->type() == QgsSymbolV2::Marker )
00043   {
00044     QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mTempSymbol );
00045     if ( mRotationFieldIdx != -1 )
00046       markerSymbol->setAngle( rotation );
00047     if ( mSizeScaleFieldIdx != -1 )
00048       markerSymbol->setSize( sizeScale * mOrigSize );
00049   }
00050   else if ( mTempSymbol->type() == QgsSymbolV2::Line )
00051   {
00052     QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mTempSymbol );
00053     if ( mSizeScaleFieldIdx != -1 )
00054       lineSymbol->setWidth( sizeScale * mOrigSize );
00055   }
00056   else if ( mTempSymbol->type() == QgsSymbolV2::Fill )
00057   {
00058     QgsFillSymbolV2* fillSymbol = static_cast<QgsFillSymbolV2*>( mTempSymbol );
00059     if ( mRotationFieldIdx != -1 )
00060       fillSymbol->setAngle( rotation );
00061   }
00062 
00063   return mTempSymbol;
00064 }
00065 
00066 void QgsSingleSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
00067 {
00068   if ( !mSymbol )
00069   {
00070     return;
00071   }
00072   mRotationFieldIdx  = mRotationField.isEmpty()  ? -1 : vlayer->fieldNameIndex( mRotationField );
00073   mSizeScaleFieldIdx = mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField );
00074 
00075   mSymbol->startRender( context );
00076 
00077   if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
00078   {
00079     // we are going to need a temporary symbol
00080     mTempSymbol = mSymbol->clone();
00081 
00082     int hints = 0;
00083     if ( mRotationFieldIdx != -1 ) hints |= QgsSymbolV2::DataDefinedRotation;
00084     if ( mSizeScaleFieldIdx != -1 ) hints |= QgsSymbolV2::DataDefinedSizeScale;
00085     mTempSymbol->setRenderHints( hints );
00086 
00087     mTempSymbol->startRender( context );
00088 
00089     if ( mSymbol->type() == QgsSymbolV2::Marker )
00090     {
00091       mOrigSize = static_cast<QgsMarkerSymbolV2*>( mSymbol )->size();
00092     }
00093     else if ( mSymbol->type() == QgsSymbolV2::Line )
00094     {
00095       mOrigSize = static_cast<QgsLineSymbolV2*>( mSymbol )->width();
00096     }
00097     else
00098     {
00099       mOrigSize = 0;
00100     }
00101   }
00102 }
00103 
00104 void QgsSingleSymbolRendererV2::stopRender( QgsRenderContext& context )
00105 {
00106   if ( !mSymbol )
00107   {
00108     return;
00109   }
00110   mSymbol->stopRender( context );
00111 
00112   if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
00113   {
00114     // we are going to need a temporary symbol
00115     mTempSymbol->stopRender( context );
00116     delete mTempSymbol;
00117     mTempSymbol = NULL;
00118   }
00119 }
00120 
00121 QList<QString> QgsSingleSymbolRendererV2::usedAttributes()
00122 {
00123   QList<QString> lst;
00124   if ( !mRotationField.isEmpty() )
00125     lst.append( mRotationField );
00126   if ( !mSizeScaleField.isEmpty() )
00127     lst.append( mSizeScaleField );
00128   return lst;
00129 }
00130 
00131 QgsSymbolV2* QgsSingleSymbolRendererV2::symbol() const
00132 {
00133   return mSymbol;
00134 }
00135 
00136 void QgsSingleSymbolRendererV2::setSymbol( QgsSymbolV2* s )
00137 {
00138   Q_ASSERT( s );
00139   delete mSymbol;
00140   mSymbol = s;
00141 }
00142 
00143 QString QgsSingleSymbolRendererV2::dump()
00144 {
00145   if ( mSymbol )
00146   {
00147     return QString( "SINGLE: %1" ).arg( mSymbol->dump() );
00148   }
00149   else
00150   {
00151     return "";
00152   }
00153 }
00154 
00155 QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
00156 {
00157   QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
00158   r->setUsingSymbolLevels( usingSymbolLevels() );
00159   r->setRotationField( rotationField() );
00160   r->setSizeScaleField( sizeScaleField() );
00161   return r;
00162 }
00163 
00164 QgsSymbolV2List QgsSingleSymbolRendererV2::symbols()
00165 {
00166   QgsSymbolV2List lst;
00167   lst.append( mSymbol );
00168   return lst;
00169 }
00170 
00171 QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create( QDomElement& element )
00172 {
00173   QDomElement symbolsElem = element.firstChildElement( "symbols" );
00174   if ( symbolsElem.isNull() )
00175     return NULL;
00176 
00177   QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
00178 
00179   if ( !symbolMap.contains( "0" ) )
00180     return NULL;
00181 
00182   QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( symbolMap.take( "0" ) );
00183 
00184   // delete symbols if there are any more
00185   QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
00186 
00187   QDomElement rotationElem = element.firstChildElement( "rotation" );
00188   if ( !rotationElem.isNull() )
00189     r->setRotationField( rotationElem.attribute( "field" ) );
00190 
00191   QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
00192   if ( !sizeScaleElem.isNull() )
00193     r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
00194 
00195   // TODO: symbol levels
00196   return r;
00197 }
00198 
00199 QDomElement QgsSingleSymbolRendererV2::save( QDomDocument& doc )
00200 {
00201   QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
00202   rendererElem.setAttribute( "type", "singleSymbol" );
00203   rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
00204 
00205   QgsSymbolV2Map symbols;
00206   symbols["0"] = mSymbol;
00207   QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
00208   rendererElem.appendChild( symbolsElem );
00209 
00210   QDomElement rotationElem = doc.createElement( "rotation" );
00211   rotationElem.setAttribute( "field", mRotationField );
00212   rendererElem.appendChild( rotationElem );
00213 
00214   QDomElement sizeScaleElem = doc.createElement( "sizescale" );
00215   sizeScaleElem.setAttribute( "field", mSizeScaleField );
00216   rendererElem.appendChild( sizeScaleElem );
00217 
00218   return rendererElem;
00219 }
00220 
00221 QgsLegendSymbologyList QgsSingleSymbolRendererV2::legendSymbologyItems( QSize iconSize )
00222 {
00223   QgsLegendSymbologyList lst;
00224   if ( mSymbol )
00225   {
00226     QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( mSymbol, iconSize );
00227     lst << qMakePair( QString(), pix );
00228   }
00229   return lst;
00230 }
00231 
00232 QgsLegendSymbolList QgsSingleSymbolRendererV2::legendSymbolItems()
00233 {
00234   QgsLegendSymbolList lst;
00235   lst << qMakePair( QString(), mSymbol );
00236   return lst;
00237 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines