00001
00002 #include "qgsrenderer.h"
00003 #include "qgssymbolv2.h"
00004 #include "qgssymbollayerv2.h"
00005
00006 #include "qgslinesymbollayerv2.h"
00007 #include "qgsmarkersymbollayerv2.h"
00008 #include "qgsfillsymbollayerv2.h"
00009
00010 #include "qgslogger.h"
00011 #include "qgsrendercontext.h"
00012
00013 #include <QColor>
00014 #include <QImage>
00015 #include <QPainter>
00016 #include <QSize>
00017
00018 #include <cmath>
00019
00020 QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
00021 : mType( type ), mLayers( layers ), mOutputUnit( MM ), mAlpha( 1.0 ), mRenderHints( 0 )
00022 {
00023
00024
00025 for ( int i = 0; i < mLayers.count(); i++ )
00026 {
00027 if ( mLayers[i] == NULL )
00028 {
00029 mLayers.removeAt( i-- );
00030 }
00031 else if ( mLayers[i]->type() != mType )
00032 {
00033 delete mLayers[i];
00034 mLayers.removeAt( i-- );
00035 }
00036 }
00037
00038 }
00039
00040 QgsSymbolV2::~QgsSymbolV2()
00041 {
00042
00043 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00044 delete *it;
00045 }
00046
00047 QgsSymbolV2* QgsSymbolV2::defaultSymbol( QGis::GeometryType geomType )
00048 {
00049 QgsSymbolV2* s;
00050 switch ( geomType )
00051 {
00052 case QGis::Point: s = new QgsMarkerSymbolV2(); break;
00053 case QGis::Line: s = new QgsLineSymbolV2(); break;
00054 case QGis::Polygon: s = new QgsFillSymbolV2(); break;
00055 default: QgsDebugMsg( "unknown layer's geometry type" ); return NULL;
00056 }
00057
00058 s->setColor( QColor::fromHsv( rand() % 360, 64 + rand() % 192, 128 + rand() % 128 ) );
00059 return s;
00060 }
00061
00062
00063 QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
00064 {
00065 if ( layer < 0 || layer >= mLayers.count() )
00066 return NULL;
00067
00068 return mLayers[layer];
00069 }
00070
00071
00072
00073 bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
00074 {
00075 if ( index < 0 || index > mLayers.count() )
00076 return false;
00077 if ( layer == NULL || layer->type() != mType )
00078 return false;
00079
00080 mLayers.insert( index, layer );
00081 return true;
00082 }
00083
00084
00085 bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
00086 {
00087 if ( layer == NULL || layer->type() != mType )
00088 return false;
00089
00090 mLayers.append( layer );
00091 return true;
00092 }
00093
00094
00095 bool QgsSymbolV2::deleteSymbolLayer( int index )
00096 {
00097 if ( index < 0 || index >= mLayers.count() )
00098 return false;
00099
00100 delete mLayers[index];
00101 mLayers.removeAt( index );
00102 return true;
00103 }
00104
00105
00106 QgsSymbolLayerV2* QgsSymbolV2::takeSymbolLayer( int index )
00107 {
00108 if ( index < 0 || index >= mLayers.count() )
00109 return NULL;
00110
00111 return mLayers.takeAt( index );
00112 }
00113
00114
00115 bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
00116 {
00117 if ( index < 0 || index >= mLayers.count() )
00118 return false;
00119 if ( layer == NULL || layer->type() != mType )
00120 return false;
00121
00122 delete mLayers[index];
00123 mLayers[index] = layer;
00124 return true;
00125 }
00126
00127
00128 void QgsSymbolV2::startRender( QgsRenderContext& context )
00129 {
00130 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
00131 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00132 ( *it )->startRender( symbolContext );
00133 }
00134
00135 void QgsSymbolV2::stopRender( QgsRenderContext& context )
00136 {
00137 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
00138 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00139 ( *it )->stopRender( symbolContext );
00140 }
00141
00142 void QgsSymbolV2::setColor( const QColor& color )
00143 {
00144 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00145 {
00146 if ( !( *it )->isLocked() )
00147 ( *it )->setColor( color );
00148 }
00149 }
00150
00151 QColor QgsSymbolV2::color()
00152 {
00153 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00154 {
00155
00156 if ( !( *it )->isLocked() )
00157 return ( *it )->color();
00158 }
00159 return QColor( 0, 0, 0 );
00160 }
00161
00162 void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
00163 {
00164 QgsRenderContext context = QgsSymbolLayerV2Utils::createRenderContext( painter );
00165 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
00166 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00167 {
00168 ( *it )->drawPreviewIcon( symbolContext, size );
00169 }
00170 }
00171
00172
00173 QImage QgsSymbolV2::bigSymbolPreviewImage()
00174 {
00175 QImage preview( QSize( 100, 100 ), QImage::Format_ARGB32_Premultiplied );
00176 preview.fill( 0 );
00177
00178 QPainter p( &preview );
00179 p.setRenderHint( QPainter::Antialiasing );
00180 p.translate( 0.5, 0.5 );
00181
00182 if ( mType == QgsSymbolV2::Marker )
00183 {
00184 p.setPen( QPen( Qt::gray ) );
00185 p.drawLine( 0, 50, 100, 50 );
00186 p.drawLine( 50, 0, 50, 100 );
00187 }
00188
00189 QgsRenderContext context = QgsSymbolLayerV2Utils::createRenderContext( &p );
00190 startRender( context );
00191
00192 if ( mType == QgsSymbolV2::Line )
00193 {
00194 QPolygonF poly;
00195 poly << QPointF( 0, 50 ) << QPointF( 99, 50 );
00196 static_cast<QgsLineSymbolV2*>( this )->renderPolyline( poly, context );
00197 }
00198 else if ( mType == QgsSymbolV2::Fill )
00199 {
00200 QPolygonF polygon;
00201 polygon << QPointF( 20, 20 ) << QPointF( 80, 20 ) << QPointF( 80, 80 ) << QPointF( 20, 80 ) << QPointF( 20, 20 );
00202 static_cast<QgsFillSymbolV2*>( this )->renderPolygon( polygon, NULL, context );
00203 }
00204 else
00205 {
00206 static_cast<QgsMarkerSymbolV2*>( this )->renderPoint( QPointF( 50, 50 ), context );
00207 }
00208
00209 stopRender( context );
00210 return preview;
00211 }
00212
00213
00214 QString QgsSymbolV2::dump()
00215 {
00216 QString t;
00217 switch ( type() )
00218 {
00219 case QgsSymbolV2::Marker: t = "MARKER"; break;
00220 case QgsSymbolV2::Line: t = "LINE"; break;
00221 case QgsSymbolV2::Fill: t = "FILL"; break;
00222 default: Q_ASSERT( 0 && "unknown symbol type" );
00223 }
00224 QString s = QString( "%1 SYMBOL (%2 layers) color %3" ).arg( t ).arg( mLayers.count() ).arg( QgsSymbolLayerV2Utils::encodeColor( color() ) );
00225
00226 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00227 {
00228
00229 }
00230 return s;
00231 }
00232
00233 QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
00234 {
00235 QgsSymbolLayerV2List lst;
00236 for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00237 {
00238 QgsSymbolLayerV2* layer = ( *it )->clone();
00239 layer->setLocked(( *it )->isLocked() );
00240 layer->setRenderingPass(( *it )->renderingPass() );
00241 lst.append( layer );
00242 }
00243 return lst;
00244 }
00245
00247
00248 QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints )
00249 : mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints )
00250 {
00251
00252 }
00253
00254 QgsSymbolV2RenderContext::~QgsSymbolV2RenderContext()
00255 {
00256
00257 }
00258
00259 QColor QgsSymbolV2RenderContext::selectionColor()
00260 {
00261 return QgsRenderer::selectionColor();
00262 }
00263
00264
00265 double QgsSymbolV2RenderContext::outputLineWidth( double width ) const
00266 {
00267 return width * QgsSymbolLayerV2Utils::lineWidthScaleFactor( mRenderContext, mOutputUnit );
00268 }
00269
00270 double QgsSymbolV2RenderContext::outputPixelSize( double size ) const
00271 {
00272 return size * QgsSymbolLayerV2Utils::pixelSizeScaleFactor( mRenderContext, mOutputUnit );
00273 }
00274
00275 QgsSymbolV2RenderContext& QgsSymbolV2RenderContext::operator=( const QgsSymbolV2RenderContext& )
00276 {
00277
00278
00279
00280
00281 Q_ASSERT( false );
00282 return *this;
00283 }
00284
00286
00287
00288 QgsMarkerSymbolV2::QgsMarkerSymbolV2( QgsSymbolLayerV2List layers )
00289 : QgsSymbolV2( Marker, layers )
00290 {
00291 if ( mLayers.count() == 0 )
00292 mLayers.append( new QgsSimpleMarkerSymbolLayerV2() );
00293 }
00294
00295 void QgsMarkerSymbolV2::setAngle( double angle )
00296 {
00297 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00298 {
00299 QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
00300 layer->setAngle( angle );
00301 }
00302 }
00303
00304 double QgsMarkerSymbolV2::angle()
00305 {
00306 QgsSymbolLayerV2List::const_iterator it = mLayers.begin();
00307
00308 if ( it == mLayers.end() )
00309 return 0;
00310
00311
00312 const QgsMarkerSymbolLayerV2 *layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
00313 return layer->angle();
00314 }
00315
00316 void QgsMarkerSymbolV2::setSize( double s )
00317 {
00318 double origSize = size();
00319
00320 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00321 {
00322 QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
00323 if ( layer->size() == origSize )
00324 layer->setSize( s );
00325 else
00326 {
00327
00328 if ( origSize != 0 )
00329 layer->setSize( layer->size() * s / origSize );
00330 }
00331 }
00332 }
00333
00334 double QgsMarkerSymbolV2::size()
00335 {
00336
00337 double maxSize = 0;
00338 for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00339 {
00340 const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
00341 double lsize = layer->size();
00342 if ( lsize > maxSize )
00343 maxSize = lsize;
00344 }
00345 return maxSize;
00346 }
00347
00348 void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer, bool selected )
00349 {
00350 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
00351 if ( layer != -1 )
00352 {
00353 if ( layer >= 0 && layer < mLayers.count() )
00354 (( QgsMarkerSymbolLayerV2* ) mLayers[layer] )->renderPoint( point, symbolContext );
00355 return;
00356 }
00357
00358 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00359 {
00360 QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
00361 layer->renderPoint( point, symbolContext );
00362 }
00363 }
00364
00365 QgsSymbolV2* QgsMarkerSymbolV2::clone() const
00366 {
00367 QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() );
00368 cloneSymbol->setOutputUnit( mOutputUnit );
00369 cloneSymbol->setAlpha( mAlpha );
00370 return cloneSymbol;
00371 }
00372
00373
00375
00376
00377 QgsLineSymbolV2::QgsLineSymbolV2( QgsSymbolLayerV2List layers )
00378 : QgsSymbolV2( Line, layers )
00379 {
00380 if ( mLayers.count() == 0 )
00381 mLayers.append( new QgsSimpleLineSymbolLayerV2() );
00382 }
00383
00384 void QgsLineSymbolV2::setWidth( double w )
00385 {
00386 double origWidth = width();
00387
00388 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00389 {
00390 QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
00391 if ( layer->width() == origWidth )
00392 {
00393 layer->setWidth( w );
00394 }
00395 else
00396 {
00397
00398 if ( origWidth != 0 )
00399 layer->setWidth( layer->width() * w / origWidth );
00400 }
00401 }
00402 }
00403
00404 double QgsLineSymbolV2::width()
00405 {
00406 double maxWidth = 0;
00407 for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00408 {
00409 const QgsLineSymbolLayerV2* layer = ( const QgsLineSymbolLayerV2* ) * it;
00410 double width = layer->width();
00411 if ( width > maxWidth )
00412 maxWidth = width;
00413 }
00414 return maxWidth;
00415 }
00416
00417 void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer, bool selected )
00418 {
00419 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
00420 if ( layer != -1 )
00421 {
00422 if ( layer >= 0 && layer < mLayers.count() )
00423 (( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolyline( points, symbolContext );
00424 return;
00425 }
00426
00427 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00428 {
00429 QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
00430 layer->renderPolyline( points, symbolContext );
00431 }
00432 }
00433
00434
00435 QgsSymbolV2* QgsLineSymbolV2::clone() const
00436 {
00437 QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() );
00438 cloneSymbol->setOutputUnit( mOutputUnit );
00439 cloneSymbol->setAlpha( mAlpha );
00440 return cloneSymbol;
00441 }
00442
00444
00445
00446 QgsFillSymbolV2::QgsFillSymbolV2( QgsSymbolLayerV2List layers )
00447 : QgsSymbolV2( Fill, layers )
00448 {
00449 if ( mLayers.count() == 0 )
00450 mLayers.append( new QgsSimpleFillSymbolLayerV2() );
00451 }
00452
00453 void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer, bool selected )
00454 {
00455 QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints );
00456 if ( layer != -1 )
00457 {
00458 if ( layer >= 0 && layer < mLayers.count() )
00459 (( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
00460 return;
00461 }
00462
00463 for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00464 {
00465 QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
00466 layer->renderPolygon( points, rings, symbolContext );
00467 }
00468 }
00469
00470
00471 QgsSymbolV2* QgsFillSymbolV2::clone() const
00472 {
00473 QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() );
00474 cloneSymbol->setOutputUnit( mOutputUnit );
00475 cloneSymbol->setAlpha( mAlpha );
00476 return cloneSymbol;
00477 }