Quantum GIS API Documentation  1.8
src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsfillsymbollayerv2.cpp
00003     ---------------------
00004     begin                : November 2009
00005     copyright            : (C) 2009 by Martin Dobias
00006     email                : wonder.sk at gmail.com
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 #include "qgsfillsymbollayerv2.h"
00016 #include "qgsmarkersymbollayerv2.h"
00017 #include "qgssymbollayerv2utils.h"
00018 
00019 #include "qgsrendercontext.h"
00020 #include "qgsproject.h"
00021 #include "qgssvgcache.h"
00022 #include "qgslogger.h"
00023 
00024 #include <QPainter>
00025 #include <QFile>
00026 #include <QSvgRenderer>
00027 #include <QDomDocument>
00028 #include <QDomElement>
00029 
00030 QgsSimpleFillSymbolLayerV2::QgsSimpleFillSymbolLayerV2( QColor color, Qt::BrushStyle style, QColor borderColor, Qt::PenStyle borderStyle, double borderWidth )
00031     : mBrushStyle( style ), mBorderColor( borderColor ), mBorderStyle( borderStyle ), mBorderWidth( borderWidth )
00032 {
00033   mColor = color;
00034 }
00035 
00036 
00037 QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::create( const QgsStringMap& props )
00038 {
00039   QColor color = DEFAULT_SIMPLEFILL_COLOR;
00040   Qt::BrushStyle style = DEFAULT_SIMPLEFILL_STYLE;
00041   QColor borderColor = DEFAULT_SIMPLEFILL_BORDERCOLOR;
00042   Qt::PenStyle borderStyle = DEFAULT_SIMPLEFILL_BORDERSTYLE;
00043   double borderWidth = DEFAULT_SIMPLEFILL_BORDERWIDTH;
00044   QPointF offset;
00045 
00046   if ( props.contains( "color" ) )
00047     color = QgsSymbolLayerV2Utils::decodeColor( props["color"] );
00048   if ( props.contains( "style" ) )
00049     style = QgsSymbolLayerV2Utils::decodeBrushStyle( props["style"] );
00050   if ( props.contains( "color_border" ) )
00051     borderColor = QgsSymbolLayerV2Utils::decodeColor( props["color_border"] );
00052   if ( props.contains( "style_border" ) )
00053     borderStyle = QgsSymbolLayerV2Utils::decodePenStyle( props["style_border"] );
00054   if ( props.contains( "width_border" ) )
00055     borderWidth = props["width_border"].toDouble();
00056   if ( props.contains( "offset" ) )
00057     offset = QgsSymbolLayerV2Utils::decodePoint( props["offset"] );
00058 
00059   QgsSimpleFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, style, borderColor, borderStyle, borderWidth );
00060   sl->setOffset( offset );
00061   return sl;
00062 }
00063 
00064 
00065 QString QgsSimpleFillSymbolLayerV2::layerType() const
00066 {
00067   return "SimpleFill";
00068 }
00069 
00070 void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
00071 {
00072   mColor.setAlphaF( context.alpha() );
00073   mBrush = QBrush( mColor, mBrushStyle );
00074 
00075   // scale brush content for printout
00076   double rasterScaleFactor = context.renderContext().rasterScaleFactor();
00077   if ( rasterScaleFactor != 1.0 )
00078   {
00079     mBrush.setMatrix( QMatrix().scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ) );
00080   }
00081 
00082   QColor selColor = context.selectionColor();
00083   // selColor.setAlphaF( context.alpha() );
00084   mSelBrush = QBrush( selColor );
00085   if ( selectFillStyle )
00086     mSelBrush.setStyle( mBrushStyle );
00087   mBorderColor.setAlphaF( context.alpha() );
00088   mPen = QPen( mBorderColor );
00089   mPen.setStyle( mBorderStyle );
00090   mPen.setWidthF( context.outputLineWidth( mBorderWidth ) );
00091 }
00092 
00093 void QgsSimpleFillSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
00094 {
00095   Q_UNUSED( context );
00096 }
00097 
00098 void QgsSimpleFillSymbolLayerV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
00099 {
00100   QPainter* p = context.renderContext().painter();
00101   if ( !p )
00102   {
00103     return;
00104   }
00105 
00106   p->setBrush( context.selected() ? mSelBrush : mBrush );
00107   p->setPen( mPen );
00108 
00109   if ( !mOffset.isNull() )
00110     p->translate( mOffset );
00111 
00112   _renderPolygon( p, points, rings );
00113 
00114   if ( !mOffset.isNull() )
00115     p->translate( -mOffset );
00116 }
00117 
00118 QgsStringMap QgsSimpleFillSymbolLayerV2::properties() const
00119 {
00120   QgsStringMap map;
00121   map["color"] = QgsSymbolLayerV2Utils::encodeColor( mColor );
00122   map["style"] = QgsSymbolLayerV2Utils::encodeBrushStyle( mBrushStyle );
00123   map["color_border"] = QgsSymbolLayerV2Utils::encodeColor( mBorderColor );
00124   map["style_border"] = QgsSymbolLayerV2Utils::encodePenStyle( mBorderStyle );
00125   map["width_border"] = QString::number( mBorderWidth );
00126   map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
00127   return map;
00128 }
00129 
00130 QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::clone() const
00131 {
00132   QgsSimpleFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( mColor, mBrushStyle, mBorderColor, mBorderStyle, mBorderWidth );
00133   sl->setOffset( mOffset );
00134   return sl;
00135 }
00136 
00137 void QgsSimpleFillSymbolLayerV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
00138 {
00139   if ( mBrushStyle == Qt::NoBrush && mBorderStyle == Qt::NoPen )
00140     return;
00141 
00142   QDomElement symbolizerElem = doc.createElement( "se:PolygonSymbolizer" );
00143   if ( !props.value( "uom", "" ).isEmpty() )
00144     symbolizerElem.setAttribute( "uom", props.value( "uom", "" ) );
00145   element.appendChild( symbolizerElem );
00146 
00147   // <Geometry>
00148   QgsSymbolLayerV2Utils::createGeometryElement( doc, symbolizerElem, props.value( "geom", "" ) );
00149 
00150   if ( mBrushStyle != Qt::NoBrush )
00151   {
00152     // <Fill>
00153     QDomElement fillElem = doc.createElement( "se:Fill" );
00154     symbolizerElem.appendChild( fillElem );
00155     QgsSymbolLayerV2Utils::fillToSld( doc, fillElem, mBrushStyle, mColor );
00156   }
00157 
00158   if ( mBorderStyle != Qt::NoPen )
00159   {
00160     // <Stroke>
00161     QDomElement strokeElem = doc.createElement( "se:Stroke" );
00162     symbolizerElem.appendChild( strokeElem );
00163     QgsSymbolLayerV2Utils::lineToSld( doc, strokeElem, mBorderStyle, mBorderColor, mBorderWidth );
00164   }
00165 
00166   // <se:Displacement>
00167   QgsSymbolLayerV2Utils::createDisplacementElement( doc, symbolizerElem, mOffset );
00168 }
00169 
00170 QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::createFromSld( QDomElement &element )
00171 {
00172   QgsDebugMsg( "Entered." );
00173 
00174   QColor color, borderColor;
00175   Qt::BrushStyle fillStyle;
00176   Qt::PenStyle borderStyle;
00177   double borderWidth;
00178 
00179   QDomElement fillElem = element.firstChildElement( "Fill" );
00180   QgsSymbolLayerV2Utils::fillFromSld( fillElem, fillStyle, color );
00181 
00182   QDomElement strokeElem = element.firstChildElement( "Stroke" );
00183   QgsSymbolLayerV2Utils::lineFromSld( strokeElem, borderStyle, borderColor, borderWidth );
00184 
00185   QPointF offset;
00186   QgsSymbolLayerV2Utils::displacementFromSldElement( element, offset );
00187 
00188   QgsSimpleFillSymbolLayerV2* sl = new QgsSimpleFillSymbolLayerV2( color, fillStyle, borderColor, borderStyle, borderWidth );
00189   sl->setOffset( offset );
00190   return sl;
00191 }
00192 
00193 
00194 //QgsImageFillSymbolLayer
00195 
00196 QgsImageFillSymbolLayer::QgsImageFillSymbolLayer(): mOutlineWidth( 0.0 ), mOutline( 0 )
00197 {
00198   setSubSymbol( new QgsLineSymbolV2() );
00199 }
00200 
00201 QgsImageFillSymbolLayer::~QgsImageFillSymbolLayer()
00202 {
00203 }
00204 
00205 void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
00206 {
00207   QPainter* p = context.renderContext().painter();
00208   if ( !p )
00209   {
00210     return;
00211   }
00212   p->setPen( QPen( Qt::NoPen ) );
00213   if ( context.selected() )
00214   {
00215     QColor selColor = context.selectionColor();
00216     if ( ! selectionIsOpaque )
00217       selColor.setAlphaF( context.alpha() );
00218     p->setBrush( QBrush( selColor ) );
00219     _renderPolygon( p, points, rings );
00220   }
00221 
00222   if ( doubleNear( mAngle, 0.0 ) )
00223   {
00224     p->setBrush( mBrush );
00225   }
00226   else
00227   {
00228     QTransform t = mBrush.transform();
00229     t.rotate( mAngle );
00230     QBrush rotatedBrush = mBrush;
00231     rotatedBrush.setTransform( t );
00232     p->setBrush( rotatedBrush );
00233   }
00234   _renderPolygon( p, points, rings );
00235   if ( mOutline )
00236   {
00237     mOutline->renderPolyline( points, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() );
00238     if ( rings )
00239     {
00240       QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
00241       for ( ; ringIt != rings->constEnd(); ++ringIt )
00242       {
00243         mOutline->renderPolyline( *ringIt, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() );
00244       }
00245     }
00246   }
00247 }
00248 
00249 bool QgsImageFillSymbolLayer::setSubSymbol( QgsSymbolV2* symbol )
00250 {
00251   if ( !symbol ) //unset current outline
00252   {
00253     delete mOutline;
00254     mOutline = 0;
00255     return true;
00256   }
00257 
00258   if ( symbol->type() != QgsSymbolV2::Line )
00259   {
00260     delete symbol;
00261     return false;
00262   }
00263 
00264   QgsLineSymbolV2* lineSymbol = dynamic_cast<QgsLineSymbolV2*>( symbol );
00265   if ( lineSymbol )
00266   {
00267     delete mOutline;
00268     mOutline = lineSymbol;
00269     return true;
00270   }
00271 
00272   delete symbol;
00273   return false;
00274 }
00275 
00276 //QgsSVGFillSymbolLayer
00277 
00278 QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QString& svgFilePath, double width, double angle ): QgsImageFillSymbolLayer(), mPatternWidth( width )
00279 {
00280   setSvgFilePath( svgFilePath );
00281   mOutlineWidth = 0.3;
00282   mAngle = angle;
00283   setDefaultSvgParams();
00284 }
00285 
00286 QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QByteArray& svgData, double width, double angle ): QgsImageFillSymbolLayer(), mPatternWidth( width ),
00287     mSvgData( svgData )
00288 {
00289   storeViewBox();
00290   mOutlineWidth = 0.3;
00291   mAngle = angle;
00292   setSubSymbol( new QgsLineSymbolV2() );
00293   setDefaultSvgParams();
00294 }
00295 
00296 QgsSVGFillSymbolLayer::~QgsSVGFillSymbolLayer()
00297 {
00298   delete mOutline;
00299 }
00300 
00301 void QgsSVGFillSymbolLayer::setSvgFilePath( const QString& svgPath )
00302 {
00303   QFile svgFile( svgPath );
00304   if ( svgFile.open( QFile::ReadOnly ) )
00305   {
00306     mSvgData = svgFile.readAll();
00307 
00308     storeViewBox();
00309   }
00310   mSvgFilePath = svgPath;
00311   setDefaultSvgParams();
00312 }
00313 
00314 QgsSymbolLayerV2* QgsSVGFillSymbolLayer::create( const QgsStringMap& properties )
00315 {
00316   QByteArray data;
00317   double width = 20;
00318   QString svgFilePath;
00319   double angle = 0.0;
00320 
00321   if ( properties.contains( "width" ) )
00322   {
00323     width = properties["width"].toDouble();
00324   }
00325   if ( properties.contains( "svgFile" ) )
00326   {
00327     QString svgName = properties["svgFile"];
00328     QString savePath = QgsSvgMarkerSymbolLayerV2::symbolNameToPath( svgName );
00329     svgFilePath = ( savePath.isEmpty() ? svgName : savePath );
00330   }
00331   if ( properties.contains( "angle" ) )
00332   {
00333     angle = properties["angle"].toDouble();
00334   }
00335 
00336   QgsSVGFillSymbolLayer* symbolLayer = 0;
00337   if ( !svgFilePath.isEmpty() )
00338   {
00339     symbolLayer = new QgsSVGFillSymbolLayer( svgFilePath, width, angle );
00340   }
00341   else
00342   {
00343     if ( properties.contains( "data" ) )
00344     {
00345       data = QByteArray::fromHex( properties["data"].toLocal8Bit() );
00346     }
00347     symbolLayer = new QgsSVGFillSymbolLayer( data, width, angle );
00348   }
00349 
00350   //svg parameters
00351   if ( properties.contains( "svgFillColor" ) )
00352   {
00353     symbolLayer->setSvgFillColor( QColor( properties["svgFillColor"] ) );
00354   }
00355   if ( properties.contains( "svgOutlineColor" ) )
00356   {
00357     symbolLayer->setSvgOutlineColor( QColor( properties["svgOutlineColor"] ) );
00358   }
00359   if ( properties.contains( "svgOutlineWidth" ) )
00360   {
00361     symbolLayer->setSvgOutlineWidth( properties["svgOutlineWidth"].toDouble() );
00362   }
00363 
00364 
00365   return symbolLayer;
00366 }
00367 
00368 QString QgsSVGFillSymbolLayer::layerType() const
00369 {
00370   return "SVGFill";
00371 }
00372 
00373 void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
00374 {
00375   if ( mSvgViewBox.isNull() )
00376   {
00377     return;
00378   }
00379 
00380   int size = context.outputPixelSize( mPatternWidth );
00381   const QImage& patternImage = QgsSvgCache::instance()->svgAsImage( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth,
00382                                context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor() );
00383   QTransform brushTransform;
00384   brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
00385   if ( !doubleNear( context.alpha(), 1.0 ) )
00386   {
00387     QImage transparentImage = patternImage.copy();
00388     QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() );
00389     mBrush.setTextureImage( transparentImage );
00390   }
00391   else
00392   {
00393     mBrush.setTextureImage( patternImage );
00394   }
00395   mBrush.setTransform( brushTransform );
00396 
00397   if ( mOutline )
00398   {
00399     mOutline->startRender( context.renderContext() );
00400   }
00401 }
00402 
00403 void QgsSVGFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
00404 {
00405   if ( mOutline )
00406   {
00407     mOutline->stopRender( context.renderContext() );
00408   }
00409 }
00410 
00411 QgsStringMap QgsSVGFillSymbolLayer::properties() const
00412 {
00413   QgsStringMap map;
00414   if ( !mSvgFilePath.isEmpty() )
00415   {
00416     map.insert( "svgFile", QgsSvgMarkerSymbolLayerV2::symbolPathToName( mSvgFilePath ) );
00417   }
00418   else
00419   {
00420     map.insert( "data", QString( mSvgData.toHex() ) );
00421   }
00422 
00423   map.insert( "width", QString::number( mPatternWidth ) );
00424   map.insert( "angle", QString::number( mAngle ) );
00425 
00426   //svg parameters
00427   map.insert( "svgFillColor", mSvgFillColor.name() );
00428   map.insert( "svgOutlineColor", mSvgOutlineColor.name() );
00429   map.insert( "svgOutlineWidth", QString::number( mSvgOutlineWidth ) );
00430 
00431   return map;
00432 }
00433 
00434 QgsSymbolLayerV2* QgsSVGFillSymbolLayer::clone() const
00435 {
00436   QgsSymbolLayerV2* clonedLayer = 0;
00437   if ( !mSvgFilePath.isEmpty() )
00438   {
00439     clonedLayer = new QgsSVGFillSymbolLayer( mSvgFilePath, mPatternWidth, mAngle );
00440     QgsSVGFillSymbolLayer* sl = static_cast<QgsSVGFillSymbolLayer*>( clonedLayer );
00441     sl->setSvgFillColor( mSvgFillColor );
00442     sl->setSvgOutlineColor( mSvgOutlineColor );
00443     sl->setSvgOutlineWidth( mSvgOutlineWidth );
00444   }
00445   else
00446   {
00447     clonedLayer = new QgsSVGFillSymbolLayer( mSvgData, mPatternWidth, mAngle );
00448   }
00449 
00450   if ( mOutline )
00451   {
00452     clonedLayer->setSubSymbol( mOutline->clone() );
00453   }
00454   return clonedLayer;
00455 }
00456 
00457 void QgsSVGFillSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
00458 {
00459   QDomElement symbolizerElem = doc.createElement( "se:PolygonSymbolizer" );
00460   if ( !props.value( "uom", "" ).isEmpty() )
00461     symbolizerElem.setAttribute( "uom", props.value( "uom", "" ) );
00462   element.appendChild( symbolizerElem );
00463 
00464   QgsSymbolLayerV2Utils::createGeometryElement( doc, symbolizerElem, props.value( "geom", "" ) );
00465 
00466   QDomElement fillElem = doc.createElement( "se:Fill" );
00467   symbolizerElem.appendChild( fillElem );
00468 
00469   QDomElement graphicFillElem = doc.createElement( "se:GraphicFill" );
00470   fillElem.appendChild( graphicFillElem );
00471 
00472   QDomElement graphicElem = doc.createElement( "se:Graphic" );
00473   graphicFillElem.appendChild( graphicElem );
00474 
00475   if ( !mSvgFilePath.isEmpty() )
00476   {
00477     QgsSymbolLayerV2Utils::externalGraphicToSld( doc, graphicElem, mSvgFilePath, "image/svg+xml", mSvgFillColor, mPatternWidth );
00478   }
00479   else
00480   {
00481     // TODO: create svg from data
00482     // <se:InlineContent>
00483     symbolizerElem.appendChild( doc.createComment( "SVG from data not implemented yet" ) );
00484   }
00485 
00486   if ( mSvgOutlineColor.isValid() || mSvgOutlineWidth >= 0 )
00487   {
00488     QgsSymbolLayerV2Utils::lineToSld( doc, graphicElem, Qt::SolidLine, mSvgOutlineColor, mSvgOutlineWidth );
00489   }
00490 
00491   // <Rotation>
00492   QString angleFunc;
00493   bool ok;
00494   double angle = props.value( "angle", "0" ).toDouble( &ok );
00495   if ( !ok )
00496   {
00497     angleFunc = QString( "%1 + %2" ).arg( props.value( "angle", "0" ) ).arg( mAngle );
00498   }
00499   else if ( angle + mAngle != 0 )
00500   {
00501     angleFunc = QString::number( angle + mAngle );
00502   }
00503   QgsSymbolLayerV2Utils::createRotationElement( doc, graphicElem, angleFunc );
00504 
00505   if ( mOutline )
00506   {
00507     // the outline sub symbol should be stored within the Stroke element,
00508     // but it will be stored in a separated LineSymbolizer because it could
00509     // have more than one layer
00510     mOutline->toSld( doc, element, props );
00511   }
00512 }
00513 
00514 QgsSymbolLayerV2* QgsSVGFillSymbolLayer::createFromSld( QDomElement &element )
00515 {
00516   QgsDebugMsg( "Entered." );
00517 
00518   QString path, mimeType;
00519   QColor fillColor, borderColor;
00520   Qt::PenStyle penStyle;
00521   double size, borderWidth;
00522 
00523   QDomElement fillElem = element.firstChildElement( "Fill" );
00524   if ( fillElem.isNull() )
00525     return NULL;
00526 
00527   QDomElement graphicFillElem = fillElem.firstChildElement( "GraphicFill" );
00528   if ( graphicFillElem.isNull() )
00529     return NULL;
00530 
00531   QDomElement graphicElem = graphicFillElem.firstChildElement( "Graphic" );
00532   if ( graphicElem.isNull() )
00533     return NULL;
00534 
00535   if ( !QgsSymbolLayerV2Utils::externalGraphicFromSld( graphicElem, path, mimeType, fillColor, size ) )
00536     return NULL;
00537 
00538   if ( mimeType != "image/svg+xml" )
00539     return NULL;
00540 
00541   QgsSymbolLayerV2Utils::lineFromSld( graphicElem, penStyle, borderColor, borderWidth );
00542 
00543   double angle = 0.0;
00544   QString angleFunc;
00545   if ( QgsSymbolLayerV2Utils::rotationFromSldElement( graphicElem, angleFunc ) )
00546   {
00547     bool ok;
00548     double d = angleFunc.toDouble( &ok );
00549     if ( ok )
00550       angle = d;
00551   }
00552 
00553   QgsSVGFillSymbolLayer* sl = new QgsSVGFillSymbolLayer( path, size, angle );
00554   sl->setSvgFillColor( fillColor );
00555   sl->setSvgOutlineColor( borderColor );
00556   sl->setSvgOutlineWidth( borderWidth );
00557 
00558   // try to get the outline
00559   QDomElement strokeElem = element.firstChildElement( "Stroke" );
00560   if ( !strokeElem.isNull() )
00561   {
00562     QgsSymbolLayerV2 *l = QgsSymbolLayerV2Utils::createLineLayerFromSld( strokeElem );
00563     if ( l )
00564     {
00565       QgsSymbolLayerV2List layers;
00566       layers.append( l );
00567       sl->setSubSymbol( new QgsLineSymbolV2( layers ) );
00568     }
00569   }
00570 
00571   return sl;
00572 }
00573 
00574 void QgsSVGFillSymbolLayer::storeViewBox()
00575 {
00576   if ( !mSvgData.isEmpty() )
00577   {
00578     QSvgRenderer r( mSvgData );
00579     if ( r.isValid() )
00580     {
00581       mSvgViewBox = r.viewBoxF();
00582       return;
00583     }
00584   }
00585 
00586   mSvgViewBox = QRectF();
00587   return;
00588 }
00589 
00590 void QgsSVGFillSymbolLayer::setDefaultSvgParams()
00591 {
00592   //default values
00593   mSvgFillColor = QColor( 0, 0, 0 );
00594   mSvgOutlineColor = QColor( 0, 0, 0 );
00595   mSvgOutlineWidth = 0.3;
00596 
00597   if ( mSvgFilePath.isEmpty() )
00598   {
00599     return;
00600   }
00601 
00602   bool hasFillParam, hasOutlineParam, hasOutlineWidthParam;
00603   QColor defaultFillColor, defaultOutlineColor;
00604   double defaultOutlineWidth;
00605   QgsSvgCache::instance()->containsParams( mSvgFilePath, hasFillParam, defaultFillColor, hasOutlineParam, defaultOutlineColor, hasOutlineWidthParam,
00606       defaultOutlineWidth );
00607 
00608   if ( hasFillParam )
00609   {
00610     mSvgFillColor = defaultFillColor;
00611   }
00612   if ( hasOutlineParam )
00613   {
00614     mSvgOutlineColor = defaultOutlineColor;
00615   }
00616   if ( hasOutlineWidthParam )
00617   {
00618     mSvgOutlineWidth = defaultOutlineWidth;
00619   }
00620 }
00621 
00622 QgsLinePatternFillSymbolLayer::QgsLinePatternFillSymbolLayer(): QgsImageFillSymbolLayer()
00623 {
00624 }
00625 
00626 QgsLinePatternFillSymbolLayer::~QgsLinePatternFillSymbolLayer()
00627 {
00628 }
00629 
00630 QgsSymbolLayerV2* QgsLinePatternFillSymbolLayer::create( const QgsStringMap& properties )
00631 {
00632   QgsLinePatternFillSymbolLayer* patternLayer = new QgsLinePatternFillSymbolLayer();
00633 
00634   //default values
00635   double lineAngle = 45;
00636   double distance = 5;
00637   double lineWidth = 0.5;
00638   QColor color( Qt::black );
00639   double offset = 0.0;
00640 
00641   if ( properties.contains( "lineangle" ) )
00642   {
00643     lineAngle = properties["lineangle"].toDouble();
00644   }
00645   patternLayer->setLineAngle( lineAngle );
00646 
00647   if ( properties.contains( "distance" ) )
00648   {
00649     distance = properties["distance"].toDouble();
00650   }
00651   patternLayer->setDistance( distance );
00652 
00653   if ( properties.contains( "linewidth" ) )
00654   {
00655     lineWidth = properties["linewidth"].toDouble();
00656   }
00657   patternLayer->setLineWidth( lineWidth );
00658 
00659   if ( properties.contains( "color" ) )
00660   {
00661     color = QgsSymbolLayerV2Utils::decodeColor( properties["color"] );
00662   }
00663   patternLayer->setColor( color );
00664 
00665   if ( properties.contains( "offset" ) )
00666   {
00667     offset = properties["offset"].toDouble();
00668   }
00669   patternLayer->setOffset( offset );
00670   return patternLayer;
00671 }
00672 
00673 QString QgsLinePatternFillSymbolLayer::layerType() const
00674 {
00675   return "LinePatternFill";
00676 }
00677 
00678 void QgsLinePatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
00679 {
00680   double outlinePixelWidth = context.outputPixelSize( mLineWidth );
00681   double outputPixelDist = context.outputPixelSize( mDistance );
00682   double outputPixelOffset = context.outputPixelSize( mOffset );
00683 
00684   //create image
00685   int height, width;
00686   if ( doubleNear( mLineAngle, 0 ) || doubleNear( mLineAngle, 360 ) || doubleNear( mLineAngle, 90 ) || doubleNear( mLineAngle, 180 ) || doubleNear( mLineAngle, 270 ) )
00687   {
00688     height = outputPixelDist;
00689     width = height; //width can be set to arbitrary value
00690   }
00691   else
00692   {
00693     height = qAbs( outputPixelDist / cos( mLineAngle * M_PI / 180 ) ); //keep perpendicular distance between lines constant
00694     width = qAbs( height / tan( mLineAngle * M_PI / 180 ) );
00695   }
00696 
00697   //depending on the angle, we might need to render into a larger image and use a subset of it
00698   int dx = 0;
00699   int dy = 0;
00700 
00701   QImage patternImage( width, height, QImage::Format_ARGB32 );
00702   patternImage.fill( 0 );
00703   QPainter p( &patternImage );
00704 
00705   p.setRenderHint( QPainter::Antialiasing, true );
00706   QPen pen( mColor );
00707   pen.setWidthF( outlinePixelWidth );
00708   pen.setCapStyle( Qt::FlatCap );
00709   p.setPen( pen );
00710 
00711   QPoint p1, p2, p3, p4, p5, p6;
00712   if ( doubleNear( mLineAngle, 0.0 ) || doubleNear( mLineAngle, 360.0 ) || doubleNear( mLineAngle, 180.0 ) )
00713   {
00714     p1 = QPoint( 0, height );
00715     p2 = QPoint( width, height );
00716     p3 = QPoint( 0, 0 );
00717     p4 = QPoint( width, 0 );
00718     p5 = QPoint( 0, 2 * height );
00719     p6 = QPoint( width, 2 * height );
00720   }
00721   else if ( doubleNear( mLineAngle, 90.0 ) || doubleNear( mLineAngle, 270.0 ) )
00722   {
00723     p1 = QPoint( 0, height );
00724     p2 = QPoint( 0, 0 );
00725     p3 = QPoint( width, height );
00726     p4 = QPoint( width, 0 );
00727     p5 = QPoint( -width, height );
00728     p6 = QPoint( -width, 0 );
00729   }
00730   else if (( mLineAngle > 0 && mLineAngle < 90 ) || ( mLineAngle > 180 && mLineAngle < 270 ) )
00731   {
00732     dx = outputPixelDist * cos(( 90 - mLineAngle ) * M_PI / 180.0 );
00733     dy = outputPixelDist * sin(( 90 - mLineAngle ) * M_PI / 180.0 );
00734     p1 = QPoint( 0, height );
00735     p2 = QPoint( width, 0 );
00736     p3 = QPoint( -dx, height - dy );
00737     p4 = QPoint( width - dx, -dy ); //p4 = QPoint( p3.x() + width, p3.y() - height );
00738     p5 = QPoint( dx, height + dy );
00739     p6 = QPoint( width + dx, dy ); //p6 = QPoint( p5.x() + width, p5.y() - height );
00740   }
00741   else if (( mLineAngle < 180 ) || ( mLineAngle > 270 && mLineAngle < 360 ) )
00742   {
00743     dy = outputPixelDist * cos(( 180 - mLineAngle ) * M_PI / 180 );
00744     dx = outputPixelDist * sin(( 180 - mLineAngle ) * M_PI / 180 );
00745     p1 = QPoint( width, height );
00746     p2 = QPoint( 0, 0 );
00747     p5 = QPoint( width + dx, height - dy );
00748     p6 = QPoint( p5.x() - width, p5.y() - height ); //p6 = QPoint( dx, -dy );
00749     p3 = QPoint( width - dx, height + dy );
00750     p4 = QPoint( p3.x() - width, p3.y() - height ); //p4 = QPoint( -dx, dy );
00751   }
00752 
00753   if ( !doubleNear( mOffset, 0.0 ) ) //shift everything
00754   {
00755     QPointF tempPt;
00756     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p3, outputPixelDist + outputPixelOffset );
00757     p3 = QPoint( tempPt.x(), tempPt.y() );
00758     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p4, outputPixelDist + outputPixelOffset );
00759     p4 = QPoint( tempPt.x(), tempPt.y() );
00760     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p5, outputPixelDist - outputPixelOffset );
00761     p5 = QPoint( tempPt.x(), tempPt.y() );
00762     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p6, outputPixelDist - outputPixelOffset );
00763     p6 = QPoint( tempPt.x(), tempPt.y() );
00764 
00765     //update p1, p2 last
00766     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p3, outputPixelOffset ).toPoint();
00767     p1 = QPoint( tempPt.x(), tempPt.y() );
00768     tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p4, outputPixelOffset ).toPoint();
00769     p2 = QPoint( tempPt.x(), tempPt.y() );;
00770   }
00771 
00772   p.drawLine( p1, p2 );
00773   p.drawLine( p3, p4 );
00774   p.drawLine( p5, p6 );
00775   p.end();
00776 
00777   //set image to mBrush
00778   if ( !doubleNear( context.alpha(), 1.0 ) )
00779   {
00780     QImage transparentImage = patternImage.copy();
00781     QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() );
00782     mBrush.setTextureImage( transparentImage );
00783   }
00784   else
00785   {
00786     mBrush.setTextureImage( patternImage );
00787   }
00788 
00789   QTransform brushTransform;
00790   brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
00791   mBrush.setTransform( brushTransform );
00792 
00793   if ( mOutline )
00794   {
00795     mOutline->startRender( context.renderContext() );
00796   }
00797 }
00798 
00799 void QgsLinePatternFillSymbolLayer::stopRender( QgsSymbolV2RenderContext & )
00800 {
00801 }
00802 
00803 QgsStringMap QgsLinePatternFillSymbolLayer::properties() const
00804 {
00805   QgsStringMap map;
00806   map.insert( "lineangle", QString::number( mLineAngle ) );
00807   map.insert( "distance", QString::number( mDistance ) );
00808   map.insert( "linewidth", QString::number( mLineWidth ) );
00809   map.insert( "color", QgsSymbolLayerV2Utils::encodeColor( mColor ) );
00810   map.insert( "offset", QString::number( mOffset ) );
00811   return map;
00812 }
00813 
00814 QgsSymbolLayerV2* QgsLinePatternFillSymbolLayer::clone() const
00815 {
00816   QgsSymbolLayerV2* clonedLayer = QgsLinePatternFillSymbolLayer::create( properties() );
00817   if ( mOutline )
00818   {
00819     clonedLayer->setSubSymbol( mOutline->clone() );
00820   }
00821   return clonedLayer;
00822 }
00823 
00824 void QgsLinePatternFillSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
00825 {
00826   QDomElement symbolizerElem = doc.createElement( "se:PolygonSymbolizer" );
00827   if ( !props.value( "uom", "" ).isEmpty() )
00828     symbolizerElem.setAttribute( "uom", props.value( "uom", "" ) );
00829   element.appendChild( symbolizerElem );
00830 
00831   // <Geometry>
00832   QgsSymbolLayerV2Utils::createGeometryElement( doc, symbolizerElem, props.value( "geom", "" ) );
00833 
00834   QDomElement fillElem = doc.createElement( "se:Fill" );
00835   symbolizerElem.appendChild( fillElem );
00836 
00837   QDomElement graphicFillElem = doc.createElement( "se:GraphicFill" );
00838   fillElem.appendChild( graphicFillElem );
00839 
00840   QDomElement graphicElem = doc.createElement( "se:Graphic" );
00841   graphicFillElem.appendChild( graphicElem );
00842 
00843   QgsSymbolLayerV2Utils::wellKnownMarkerToSld( doc, graphicElem, "horline", QColor(), mColor, mLineWidth, mDistance );
00844 
00845   // <Rotation>
00846   QString angleFunc;
00847   bool ok;
00848   double angle = props.value( "angle", "0" ).toDouble( &ok );
00849   if ( !ok )
00850   {
00851     angleFunc = QString( "%1 + %2" ).arg( props.value( "angle", "0" ) ).arg( mLineAngle );
00852   }
00853   else if ( angle + mLineAngle != 0 )
00854   {
00855     angleFunc = QString::number( angle + mLineAngle );
00856   }
00857   QgsSymbolLayerV2Utils::createRotationElement( doc, graphicElem, angleFunc );
00858 
00859   // <se:Displacement>
00860   QPointF lineOffset( qSin( mLineAngle ) * mOffset, qCos( mLineAngle ) * mOffset );
00861   QgsSymbolLayerV2Utils::createDisplacementElement( doc, graphicElem, lineOffset );
00862 }
00863 
00864 QgsSymbolLayerV2* QgsLinePatternFillSymbolLayer::createFromSld( QDomElement &element )
00865 {
00866   Q_UNUSED( element );
00867   return NULL;
00868 }
00869 
00871 
00872 QgsPointPatternFillSymbolLayer::QgsPointPatternFillSymbolLayer(): QgsImageFillSymbolLayer(), mMarkerSymbol( 0 ), mDistanceX( 15 ),
00873     mDistanceY( 15 ), mDisplacementX( 0 ), mDisplacementY( 0 )
00874 {
00875   mDistanceX = 15;
00876   mDistanceY = 15;
00877   mDisplacementX = 0;
00878   mDisplacementY = 0;
00879   setSubSymbol( new QgsMarkerSymbolV2() );
00880   QgsImageFillSymbolLayer::setSubSymbol( 0 ); //no outline
00881 }
00882 
00883 QgsPointPatternFillSymbolLayer::~QgsPointPatternFillSymbolLayer()
00884 {
00885 }
00886 
00887 QgsSymbolLayerV2* QgsPointPatternFillSymbolLayer::create( const QgsStringMap& properties )
00888 {
00889   QgsPointPatternFillSymbolLayer* layer = new QgsPointPatternFillSymbolLayer();
00890   if ( properties.contains( "distance_x" ) )
00891   {
00892     layer->setDistanceX( properties["distance_x"].toDouble() );
00893   }
00894   if ( properties.contains( "distance_y" ) )
00895   {
00896     layer->setDistanceY( properties["distance_y"].toDouble() );
00897   }
00898   if ( properties.contains( "displacement_x" ) )
00899   {
00900     layer->setDisplacementX( properties["displacement_x"].toDouble() );
00901   }
00902   if ( properties.contains( "displacement_y" ) )
00903   {
00904     layer->setDisplacementY( properties["displacement_y"].toDouble() );
00905   }
00906   return layer;
00907 }
00908 
00909 QString QgsPointPatternFillSymbolLayer::layerType() const
00910 {
00911   return "PointPatternFill";
00912 }
00913 
00914 void QgsPointPatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
00915 {
00916   //render 3 rows and columns in one go to easily incorporate displacement
00917   double width = context.outputPixelSize( mDistanceX ) * 2.0;
00918   double height = context.outputPixelSize( mDistanceY ) * 2.0;
00919 
00920   QImage patternImage( width, height, QImage::Format_ARGB32 );
00921   patternImage.fill( 0 );
00922 
00923   if ( mMarkerSymbol )
00924   {
00925     QPainter p( &patternImage );
00926 
00927     //marker rendering needs context for drawing on patternImage
00928     QgsRenderContext pointRenderContext;
00929     pointRenderContext.setPainter( &p );
00930     pointRenderContext.setRasterScaleFactor( 1.0 );
00931     pointRenderContext.setScaleFactor( context.renderContext().scaleFactor() * context.renderContext().rasterScaleFactor() );
00932     QgsMapToPixel mtp( context.renderContext().mapToPixel().mapUnitsPerPixel() / context.renderContext().rasterScaleFactor() );
00933     pointRenderContext.setMapToPixel( mtp );
00934     pointRenderContext.setForceVectorOutput( false );
00935 
00936     mMarkerSymbol->setOutputUnit( context.outputUnit() );
00937     mMarkerSymbol->startRender( pointRenderContext );
00938 
00939     //render corner points
00940     mMarkerSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), pointRenderContext );
00941     mMarkerSymbol->renderPoint( QPointF( width, 0 ), context.feature(), pointRenderContext );
00942     mMarkerSymbol->renderPoint( QPointF( 0, height ), context.feature(), pointRenderContext );
00943     mMarkerSymbol->renderPoint( QPointF( width, height ), context.feature(), pointRenderContext );
00944 
00945     //render displaced points
00946     double displacementPixelX = context.outputPixelSize( mDisplacementX );
00947     double displacementPixelY = context.outputPixelSize( mDisplacementY );
00948     mMarkerSymbol->renderPoint( QPointF( width / 2.0, -displacementPixelY ), context.feature(), pointRenderContext );
00949     mMarkerSymbol->renderPoint( QPointF( displacementPixelX, height / 2.0 ), context.feature(), pointRenderContext );
00950     mMarkerSymbol->renderPoint( QPointF( width / 2.0 + displacementPixelX, height / 2.0 - displacementPixelY ), context.feature(), pointRenderContext );
00951     mMarkerSymbol->renderPoint( QPointF( width + displacementPixelX, height / 2.0 ), context.feature(), pointRenderContext );
00952     mMarkerSymbol->renderPoint( QPointF( width / 2.0, height - displacementPixelY ), context.feature(), pointRenderContext );
00953 
00954     mMarkerSymbol->stopRender( pointRenderContext );
00955   }
00956 
00957   if ( !doubleNear( context.alpha(), 1.0 ) )
00958   {
00959     QImage transparentImage = patternImage.copy();
00960     QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() );
00961     mBrush.setTextureImage( transparentImage );
00962   }
00963   else
00964   {
00965     mBrush.setTextureImage( patternImage );
00966   }
00967   QTransform brushTransform;
00968   brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
00969   mBrush.setTransform( brushTransform );
00970 
00971   if ( mOutline )
00972   {
00973     mOutline->startRender( context.renderContext() );
00974   }
00975 }
00976 
00977 void QgsPointPatternFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
00978 {
00979   if ( mOutline )
00980   {
00981     mOutline->stopRender( context.renderContext() );
00982   }
00983 }
00984 
00985 QgsStringMap QgsPointPatternFillSymbolLayer::properties() const
00986 {
00987   QgsStringMap propertyMap;
00988   propertyMap["distance_x"] = QString::number( mDistanceX );
00989   propertyMap["distance_y"] = QString::number( mDistanceY );
00990   propertyMap["displacement_x"] = QString::number( mDisplacementX );
00991   propertyMap["displacement_y"] = QString::number( mDisplacementY );
00992   return propertyMap;
00993 }
00994 
00995 QgsSymbolLayerV2* QgsPointPatternFillSymbolLayer::clone() const
00996 {
00997   QgsSymbolLayerV2* clonedLayer = QgsPointPatternFillSymbolLayer::create( properties() );
00998   if ( mMarkerSymbol )
00999   {
01000     clonedLayer->setSubSymbol( mMarkerSymbol->clone() );
01001   }
01002   return clonedLayer;
01003 }
01004 
01005 void QgsPointPatternFillSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
01006 {
01007   for ( int i = 0; i < mMarkerSymbol->symbolLayerCount(); i++ )
01008   {
01009     QDomElement symbolizerElem = doc.createElement( "se:PolygonSymbolizer" );
01010     if ( !props.value( "uom", "" ).isEmpty() )
01011       symbolizerElem.setAttribute( "uom", props.value( "uom", "" ) );
01012     element.appendChild( symbolizerElem );
01013 
01014     // <Geometry>
01015     QgsSymbolLayerV2Utils::createGeometryElement( doc, symbolizerElem, props.value( "geom", "" ) );
01016 
01017     QDomElement fillElem = doc.createElement( "se:Fill" );
01018     symbolizerElem.appendChild( fillElem );
01019 
01020     QDomElement graphicFillElem = doc.createElement( "se:GraphicFill" );
01021     fillElem.appendChild( graphicFillElem );
01022 
01023     // store distanceX, distanceY, displacementX, displacementY in a <VendorOption>
01024     QString dist =  QgsSymbolLayerV2Utils::encodePoint( QPointF( mDistanceX, mDistanceY ) );
01025     QDomElement distanceElem = QgsSymbolLayerV2Utils::createVendorOptionElement( doc, "distance", dist );
01026     symbolizerElem.appendChild( distanceElem );
01027 
01028     QgsSymbolLayerV2 *layer = mMarkerSymbol->symbolLayer( i );
01029     QgsMarkerSymbolLayerV2 *markerLayer = static_cast<QgsMarkerSymbolLayerV2 *>( layer );
01030     if ( !markerLayer )
01031     {
01032       QString errorMsg = QString( "MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->layerType() );
01033       graphicFillElem.appendChild( doc.createComment( errorMsg ) );
01034     }
01035     else
01036     {
01037       markerLayer->writeSldMarker( doc, graphicFillElem, props );
01038     }
01039   }
01040 }
01041 
01042 QgsSymbolLayerV2* QgsPointPatternFillSymbolLayer::createFromSld( QDomElement &element )
01043 {
01044   Q_UNUSED( element );
01045   return NULL;
01046 }
01047 
01048 bool QgsPointPatternFillSymbolLayer::setSubSymbol( QgsSymbolV2* symbol )
01049 {
01050   if ( !symbol )
01051   {
01052     return false;
01053   }
01054 
01055   if ( symbol->type() == QgsSymbolV2::Marker )
01056   {
01057     QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( symbol );
01058     delete mMarkerSymbol;
01059     mMarkerSymbol = markerSymbol;
01060   }
01061   return true;
01062 }
01063 
01065 
01066 
01067 QgsCentroidFillSymbolLayerV2::QgsCentroidFillSymbolLayerV2()
01068 {
01069   mMarker = NULL;
01070   setSubSymbol( new QgsMarkerSymbolV2() );
01071 }
01072 
01073 QgsCentroidFillSymbolLayerV2::~QgsCentroidFillSymbolLayerV2()
01074 {
01075   delete mMarker;
01076 }
01077 
01078 QgsSymbolLayerV2* QgsCentroidFillSymbolLayerV2::create( const QgsStringMap& /*properties*/ )
01079 {
01080   return new QgsCentroidFillSymbolLayerV2();
01081 }
01082 
01083 QString QgsCentroidFillSymbolLayerV2::layerType() const
01084 {
01085   return "CentroidFill";
01086 }
01087 
01088 void QgsCentroidFillSymbolLayerV2::setColor( const QColor& color )
01089 {
01090   mMarker->setColor( color );
01091   mColor = color;
01092 }
01093 
01094 void QgsCentroidFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
01095 {
01096   mMarker->setAlpha( context.alpha() );
01097   mMarker->setOutputUnit( context.outputUnit() );
01098 
01099   mMarker->startRender( context.renderContext() );
01100 }
01101 
01102 void QgsCentroidFillSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
01103 {
01104   mMarker->stopRender( context.renderContext() );
01105 }
01106 
01107 void QgsCentroidFillSymbolLayerV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
01108 {
01109   Q_UNUSED( rings );
01110 
01111   // calculate centroid
01112   double cx = 0, cy = 0;
01113   double area, sum = 0;
01114   for ( int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
01115   {
01116     const QPointF& p1 = points[i];
01117     const QPointF& p2 = points[j];
01118     area = p1.x() * p2.y() - p1.y() * p2.x();
01119     sum += area;
01120     cx += ( p1.x() + p2.x() ) * area;
01121     cy += ( p1.y() + p2.y() ) * area;
01122   }
01123   sum *= 3.0;
01124   cx /= sum;
01125   cy /= sum;
01126 
01127   mMarker->renderPoint( QPointF( cx, cy ), context.feature(), context.renderContext(), -1, context.selected() );
01128 }
01129 
01130 QgsStringMap QgsCentroidFillSymbolLayerV2::properties() const
01131 {
01132   return QgsStringMap();
01133 }
01134 
01135 QgsSymbolLayerV2* QgsCentroidFillSymbolLayerV2::clone() const
01136 {
01137   QgsCentroidFillSymbolLayerV2* x = new QgsCentroidFillSymbolLayerV2();
01138   x->setSubSymbol( mMarker->clone() );
01139   return x;
01140 }
01141 
01142 void QgsCentroidFillSymbolLayerV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
01143 {
01144   // SLD 1.0 specs says: "if a line, polygon, or raster geometry is
01145   // used with PointSymbolizer, then the semantic is to use the centroid
01146   // of the geometry, or any similar representative point.
01147   mMarker->toSld( doc, element, props );
01148 }
01149 
01150 QgsSymbolLayerV2* QgsCentroidFillSymbolLayerV2::createFromSld( QDomElement &element )
01151 {
01152   QgsDebugMsg( "Entered." );
01153 
01154   QgsSymbolLayerV2 *l = QgsSymbolLayerV2Utils::createMarkerLayerFromSld( element );
01155   if ( !l )
01156     return NULL;
01157 
01158   QgsSymbolLayerV2List layers;
01159   layers.append( l );
01160   QgsMarkerSymbolV2 *marker = new QgsMarkerSymbolV2( layers );
01161 
01162   QgsCentroidFillSymbolLayerV2* x = new QgsCentroidFillSymbolLayerV2();
01163   x->setSubSymbol( marker );
01164   return x;
01165 }
01166 
01167 
01168 QgsSymbolV2* QgsCentroidFillSymbolLayerV2::subSymbol()
01169 {
01170   return mMarker;
01171 }
01172 
01173 bool QgsCentroidFillSymbolLayerV2::setSubSymbol( QgsSymbolV2* symbol )
01174 {
01175   if ( symbol == NULL || symbol->type() != QgsSymbolV2::Marker )
01176   {
01177     delete symbol;
01178     return false;
01179   }
01180 
01181   delete mMarker;
01182   mMarker = static_cast<QgsMarkerSymbolV2*>( symbol );
01183   mColor = mMarker->color();
01184   return true;
01185 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines