00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qgsuniquevaluerenderer.h"
00020 #include "qgsfeature.h"
00021 #include "qgsvectordataprovider.h"
00022 #include "qgsvectorlayer.h"
00023 #include "qgssymbol.h"
00024 #include "qgssymbologyutils.h"
00025 #include "qgslogger.h"
00026 #include <math.h>
00027 #include <QDomNode>
00028 #include <QPainter>
00029 #include <QImage>
00030 #include <vector>
00031
00032 QgsUniqueValueRenderer::QgsUniqueValueRenderer( QGis::GeometryType type ): mClassificationField( 0 )
00033 {
00034 mGeometryType = type;
00035 mSymbolAttributesDirty = false;
00036 }
00037
00038 QgsUniqueValueRenderer::QgsUniqueValueRenderer( const QgsUniqueValueRenderer& other )
00039 {
00040 mGeometryType = other.mGeometryType;
00041 mClassificationField = other.mClassificationField;
00042 QMap<QString, QgsSymbol*> s = other.mSymbols;
00043 for ( QMap<QString, QgsSymbol*>::iterator it = s.begin(); it != s.end(); ++it )
00044 {
00045 QgsSymbol* s = new QgsSymbol( * it.value() );
00046 insertValue( it.key(), s );
00047 }
00048 updateSymbolAttributes();
00049 }
00050
00051 QgsUniqueValueRenderer& QgsUniqueValueRenderer::operator=( const QgsUniqueValueRenderer & other )
00052 {
00053 if ( this != &other )
00054 {
00055 mGeometryType = other.mGeometryType;
00056 mClassificationField = other.mClassificationField;
00057 clearValues();
00058 for ( QMap<QString, QgsSymbol*>::iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )
00059 {
00060 QgsSymbol* s = new QgsSymbol( *it.value() );
00061 insertValue( it.key(), s );
00062 }
00063 updateSymbolAttributes();
00064 }
00065 return *this;
00066 }
00067
00068 QgsUniqueValueRenderer::~QgsUniqueValueRenderer()
00069 {
00070 for ( QMap<QString, QgsSymbol*>::iterator it = mSymbols.begin();it != mSymbols.end();++it )
00071 {
00072 delete it.value();
00073 }
00074 }
00075
00076 const QList<QgsSymbol*> QgsUniqueValueRenderer::symbols() const
00077 {
00078 QList <QgsSymbol*> symbollist;
00079 for ( QMap<QString, QgsSymbol*>::const_iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )
00080 {
00081 symbollist.append( it.value() );
00082 }
00083 return symbollist;
00084 }
00085
00086 void QgsUniqueValueRenderer::insertValue( QString name, QgsSymbol* symbol )
00087 {
00088 mSymbols.insert( name, symbol );
00089 mSymbolAttributesDirty = true;
00090 }
00091
00092 void QgsUniqueValueRenderer::setClassificationField( int field )
00093 {
00094 mClassificationField = field;
00095 }
00096
00097 int QgsUniqueValueRenderer::classificationField() const
00098 {
00099 return mClassificationField;
00100 }
00101
00102 bool QgsUniqueValueRenderer::willRenderFeature( QgsFeature *f )
00103 {
00104 return ( symbolForFeature( f ) != 0 );
00105 }
00106
00107 void QgsUniqueValueRenderer::renderFeature( QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale, double rasterScaleFactor )
00108 {
00109 QgsSymbol* symbol = symbolForFeature( &f );
00110 if ( !symbol )
00111 {
00112 if ( img && mGeometryType == QGis::Point )
00113 {
00114 img->fill( 0 );
00115 }
00116 else if ( mGeometryType != QGis::Point )
00117 {
00118 p->setPen( Qt::NoPen );
00119 p->setBrush( Qt::NoBrush );
00120 }
00121 return;
00122 }
00123
00124
00125 if ( img && mGeometryType == QGis::Point )
00126 {
00127 double fieldScale = 1.0;
00128 double rotation = 0.0;
00129
00130 if ( symbol->scaleClassificationField() >= 0 )
00131 {
00132
00133 const QgsAttributeMap& attrs = f.attributeMap();
00134 fieldScale = sqrt( fabs( attrs[symbol->scaleClassificationField()].toDouble() ) );
00135 }
00136 if ( symbol->rotationClassificationField() >= 0 )
00137 {
00138 const QgsAttributeMap& attrs = f.attributeMap();
00139 rotation = attrs[symbol->rotationClassificationField()].toDouble();
00140 }
00141 *img = symbol->getPointSymbolAsImage( widthScale, selected, mSelectionColor,
00142 fieldScale, rotation, rasterScaleFactor );
00143 }
00144
00145 else if ( mGeometryType != QGis::Point )
00146 {
00147 if ( !selected )
00148 {
00149 QPen pen = symbol->pen();
00150 pen.setWidthF( widthScale * pen.widthF() );
00151 p->setPen( pen );
00152 if ( mGeometryType == QGis::Polygon )
00153 {
00154 QBrush brush = symbol->brush();
00155 scaleBrush( brush, rasterScaleFactor );
00156 p->setBrush( brush );
00157 }
00158 }
00159 else
00160 {
00161 QPen pen = symbol->pen();
00162 pen.setWidthF( widthScale * pen.widthF() );
00163 if ( mGeometryType == QGis::Polygon )
00164 {
00165 QBrush brush = symbol->brush();
00166 scaleBrush( brush, rasterScaleFactor );
00167 brush.setColor( mSelectionColor );
00168 p->setBrush( brush );
00169 }
00170 else
00171 {
00172 pen.setColor( mSelectionColor );
00173 }
00174 p->setPen( pen );
00175 }
00176 }
00177 }
00178
00179 QgsSymbol *QgsUniqueValueRenderer::symbolForFeature( const QgsFeature *f )
00180 {
00181
00182 const QgsAttributeMap& attrs = f->attributeMap();
00183 QString value = attrs[mClassificationField].toString();
00184
00185 QMap<QString, QgsSymbol*>::iterator it = mSymbols.find( value );
00186 if ( it == mSymbols.end() )
00187 {
00188 return 0;
00189 }
00190 else
00191 {
00192 return it.value();
00193 }
00194 }
00195
00196 int QgsUniqueValueRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
00197 {
00198 mGeometryType = vl.geometryType();
00199 QDomNode classnode = rnode.namedItem( "classificationfield" );
00200 QString classificationField = classnode.toElement().text();
00201
00202 QgsVectorDataProvider* theProvider = vl.dataProvider();
00203 if ( !theProvider )
00204 {
00205 return 1;
00206 }
00207
00208 int classificationId = theProvider->fieldNameIndex( classificationField );
00209 if ( classificationId == -1 )
00210 {
00211 return 2;
00212 }
00213 setClassificationField( classificationId );
00214
00215 QDomNode symbolnode = rnode.namedItem( "symbol" );
00216 while ( !symbolnode.isNull() )
00217 {
00218 QgsSymbol* msy = new QgsSymbol( mGeometryType );
00219 msy->readXML( symbolnode, &vl );
00220 insertValue( msy->lowerValue(), msy );
00221 symbolnode = symbolnode.nextSibling();
00222 }
00223 updateSymbolAttributes();
00224 vl.setRenderer( this );
00225 return 0;
00226 }
00227
00228 void QgsUniqueValueRenderer::clearValues()
00229 {
00230 for ( QMap<QString, QgsSymbol*>::iterator it = mSymbols.begin();it != mSymbols.end();++it )
00231 {
00232 delete it.value();
00233 }
00234 mSymbols.clear();
00235 updateSymbolAttributes();
00236 }
00237
00238 void QgsUniqueValueRenderer::updateSymbolAttributes()
00239 {
00240 mSymbolAttributesDirty = false;
00241
00242 mSymbolAttributes.clear();
00243
00244 QMap<QString, QgsSymbol*>::iterator it;
00245 for ( it = mSymbols.begin(); it != mSymbols.end(); ++it )
00246 {
00247 int rotationField = ( *it )->rotationClassificationField();
00248 if ( rotationField >= 0 && !( mSymbolAttributes.contains( rotationField ) ) )
00249 {
00250 mSymbolAttributes.append( rotationField );
00251 }
00252 int scaleField = ( *it )->scaleClassificationField();
00253 if ( scaleField >= 0 && !( mSymbolAttributes.contains( scaleField ) ) )
00254 {
00255 mSymbolAttributes.append( scaleField );
00256 }
00257 }
00258 }
00259
00260 QString QgsUniqueValueRenderer::name() const
00261 {
00262 return "Unique Value";
00263 }
00264
00265 QgsAttributeList QgsUniqueValueRenderer::classificationAttributes() const
00266 {
00267 QgsAttributeList list( mSymbolAttributes );
00268 if ( ! list.contains( mClassificationField ) )
00269 {
00270 list.append( mClassificationField );
00271 }
00272 return list;
00273 }
00274
00275 bool QgsUniqueValueRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const
00276 {
00277 const QgsVectorDataProvider* theProvider = vl.dataProvider();
00278 if ( !theProvider )
00279 {
00280 return false;
00281 }
00282
00283 QString classificationFieldName;
00284 QgsFieldMap::const_iterator field_it = theProvider->fields().find( mClassificationField );
00285 if ( field_it != theProvider->fields().constEnd() )
00286 {
00287 classificationFieldName = field_it.value().name();
00288 }
00289
00290 bool returnval = true;
00291 QDomElement uniquevalue = document.createElement( "uniquevalue" );
00292 layer_node.appendChild( uniquevalue );
00293 QDomElement classificationfield = document.createElement( "classificationfield" );
00294 QDomText classificationfieldtxt = document.createTextNode( classificationFieldName );
00295 classificationfield.appendChild( classificationfieldtxt );
00296 uniquevalue.appendChild( classificationfield );
00297 for ( QMap<QString, QgsSymbol*>::const_iterator it = mSymbols.begin();it != mSymbols.end();++it )
00298 {
00299 if ( !( it.value()->writeXML( uniquevalue, document, &vl ) ) )
00300 {
00301 returnval = false;
00302 }
00303 }
00304 return returnval;
00305 }
00306
00307 QgsRenderer* QgsUniqueValueRenderer::clone() const
00308 {
00309 QgsUniqueValueRenderer* r = new QgsUniqueValueRenderer( *this );
00310 return r;
00311 }