00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qgis.h"
00020 #include "qgssinglesymbolrenderer.h"
00021
00022 #include "qgsfeature.h"
00023 #include "qgslogger.h"
00024 #include "qgssymbol.h"
00025 #include "qgssymbologyutils.h"
00026 #include "qgsvectorlayer.h"
00027 #include "qgsrendercontext.h"
00028
00029 #include <QDomNode>
00030 #include <QImage>
00031 #include <QPainter>
00032 #include <QString>
00033 #include <math.h>
00034
00035 QgsSingleSymbolRenderer::QgsSingleSymbolRenderer( QGis::GeometryType type )
00036 {
00037 mGeometryType = type;
00038
00039
00040 QgsSymbol* sy = new QgsSymbol( mGeometryType );
00041
00042
00043 int red = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
00044 int green = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
00045 int blue = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
00046
00047 if ( type == QGis::Line )
00048 {
00049 sy->setColor( QColor( red, green, blue ) );
00050 }
00051 else
00052 {
00053 sy->setFillColor( QColor( red, green, blue ) );
00054 sy->setFillStyle( Qt::SolidPattern );
00055 sy->setColor( QColor( 0, 0, 0 ) );
00056 }
00057 mSymbol0 = sy;
00058 mSymbols[ QString()] = sy;
00059 updateSymbolAttributes();
00060 }
00061
00062 QgsSingleSymbolRenderer::QgsSingleSymbolRenderer( const QgsSingleSymbolRenderer& other )
00063 {
00064 *this = other;
00065 }
00066
00067 QgsSingleSymbolRenderer& QgsSingleSymbolRenderer::operator=( const QgsSingleSymbolRenderer & other )
00068 {
00069 if ( this != &other )
00070 {
00071 mGeometryType = other.mGeometryType;
00072
00073 for ( QMap<QString, QgsSymbol *>::const_iterator it = other.mSymbols.begin(); it != other.mSymbols.end(); it++ )
00074 mSymbols[ it.key()] = new QgsSymbol( *it.value() );
00075
00076 if ( mSymbols.size() > 0 )
00077 {
00078 mSymbol0 = mSymbols[0];
00079 }
00080 else
00081 {
00082 mSymbol0 = 0;
00083 }
00084 }
00085 updateSymbolAttributes();
00086 return *this;
00087 }
00088
00089 QgsSingleSymbolRenderer::~QgsSingleSymbolRenderer()
00090 {
00091 for ( QMap<QString, QgsSymbol *>::iterator it = mSymbols.begin(); it != mSymbols.end(); it++ )
00092 delete it.value();
00093 }
00094
00095 void QgsSingleSymbolRenderer::addSymbol( QgsSymbol *sy )
00096 {
00097 for ( QMap<QString, QgsSymbol *>::iterator it = mSymbols.begin(); it != mSymbols.end(); it++ )
00098 delete it.value();
00099
00100 mSymbol0 = sy;
00101 mSymbols[ QString()] = sy;
00102
00103 updateSymbolAttributes();
00104 }
00105
00106 void QgsSingleSymbolRenderer::renderFeature( QgsRenderContext &renderContext, QgsFeature & f, QImage* img, bool selected, double opacity )
00107 {
00108 QPainter *p = renderContext.painter();
00109
00110
00111 if ( img && mGeometryType == QGis::Point )
00112 {
00113
00114
00115 double fieldScale = 1.0;
00116 double rotation = 0.0;
00117 QgsSymbol *sy = mSymbol0;
00118
00119 if ( mSymbol0->symbolField() >= 0 )
00120 {
00121 const QgsAttributeMap& attrs = f.attributeMap();
00122 QString name = attrs[ mSymbol0->symbolField()].toString();
00123 QgsDebugMsgLevel( QString( "Feature has name %1" ).arg( name ), 3 );
00124
00125 if ( !mSymbols.contains( name ) )
00126 {
00127 sy = new QgsSymbol( mGeometryType );
00128 sy->setNamedPointSymbol( name );
00129 mSymbols[ name ] = sy;
00130 }
00131 else
00132 {
00133 sy = mSymbols[ name ];
00134 }
00135
00136 sy->setPointSize( mSymbol0->pointSize() );
00137 sy->setPointSizeUnits( mSymbol0->pointSizeUnits() );
00138 }
00139
00140 if ( mSymbol0->scaleClassificationField() >= 0 )
00141 {
00142
00143 const QgsAttributeMap& attrs = f.attributeMap();
00144 fieldScale = sqrt( fabs( attrs[ mSymbol0->scaleClassificationField()].toDouble() ) );
00145 QgsDebugMsgLevel( QString( "Feature has field scale factor %1" ).arg( fieldScale ), 3 );
00146 }
00147 if ( mSymbol0->rotationClassificationField() >= 0 )
00148 {
00149 const QgsAttributeMap& attrs = f.attributeMap();
00150 rotation = attrs[ mSymbol0->rotationClassificationField()].toDouble();
00151 QgsDebugMsgLevel( QString( "Feature has rotation factor %1" ).arg( rotation ), 3 );
00152 }
00153
00154 double scale = renderContext.scaleFactor();
00155
00156 if ( sy->pointSizeUnits() )
00157 {
00158 scale = 1.0 / renderContext.mapToPixel().mapUnitsPerPixel();
00159 }
00160
00161 *img = sy->getPointSymbolAsImage( scale, selected, mSelectionColor, fieldScale, rotation, renderContext.rasterScaleFactor(), opacity );
00162 }
00163
00164
00165 if ( mGeometryType != QGis::Point )
00166 {
00167 if ( !selected )
00168 {
00169 QPen pen = mSymbol0->pen();
00170 pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
00171 p->setPen( pen );
00172
00173 if ( mGeometryType == QGis::Polygon )
00174 {
00175 QBrush brush = mSymbol0->brush();
00176 scaleBrush( brush, renderContext.rasterScaleFactor() );
00177 p->setBrush( brush );
00178 }
00179 }
00180 else
00181 {
00182 QPen pen = mSymbol0->pen();
00183 pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
00184 if ( mGeometryType == QGis::Polygon )
00185 {
00186 QBrush brush = mSymbol0->brush();
00187 scaleBrush( brush, renderContext.rasterScaleFactor() );
00188 brush.setColor( mSelectionColor );
00189 p->setBrush( brush );
00190 }
00191 else
00192 {
00193
00194
00195 pen.setColor( mSelectionColor );
00196 }
00197 p->setPen( pen );
00198 }
00199 }
00200 }
00201
00202 int QgsSingleSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
00203 {
00204 mGeometryType = vl.geometryType();
00205 QgsSymbol* sy = new QgsSymbol( mGeometryType );
00206
00207 QDomNode synode = rnode.namedItem( "symbol" );
00208
00209 if ( synode.isNull() )
00210 {
00211 QgsDebugMsg( "No symbol node in project file's renderitem Dom" );
00212
00213 }
00214 else
00215 {
00216 sy->readXML( synode, &vl );
00217 }
00218 updateSymbolAttributes();
00219
00220
00221 addSymbol( sy );
00222 vl.setRenderer( this );
00223 return 0;
00224 }
00225
00226 bool QgsSingleSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const
00227 {
00228 bool returnval = false;
00229 QDomElement singlesymbol = document.createElement( "singlesymbol" );
00230 layer_node.appendChild( singlesymbol );
00231
00232 if ( mSymbol0 )
00233 {
00234 returnval = mSymbol0->writeXML( singlesymbol, document, &vl );
00235 }
00236 return returnval;
00237 }
00238
00239
00240 QgsAttributeList QgsSingleSymbolRenderer::classificationAttributes() const
00241 {
00242 return mSymbolAttributes;
00243 }
00244
00245 void QgsSingleSymbolRenderer::updateSymbolAttributes()
00246 {
00247
00248
00249
00250 mSymbolAttributes.clear();
00251 int rotationField = mSymbol0->rotationClassificationField();
00252 if ( rotationField >= 0 && !( mSymbolAttributes.contains( rotationField ) ) )
00253 {
00254 mSymbolAttributes.append( rotationField );
00255 }
00256 int scaleField = mSymbol0->scaleClassificationField();
00257 if ( scaleField >= 0 && !( mSymbolAttributes.contains( scaleField ) ) )
00258 {
00259 mSymbolAttributes.append( scaleField );
00260 }
00261 int symbolField = mSymbol0->symbolField();
00262 if ( symbolField >= 0 && !( mSymbolAttributes.contains( symbolField ) ) )
00263 {
00264 mSymbolAttributes.append( symbolField );
00265 }
00266 }
00267
00268 QString QgsSingleSymbolRenderer::name() const
00269 {
00270 return "Single Symbol";
00271 }
00272
00273 const QList<QgsSymbol*> QgsSingleSymbolRenderer::symbols() const
00274 {
00275 return mSymbols.values();
00276 }
00277
00278 QgsRenderer* QgsSingleSymbolRenderer::clone() const
00279 {
00280 QgsSingleSymbolRenderer* r = new QgsSingleSymbolRenderer( *this );
00281 return r;
00282 }