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