00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qgscontinuouscolorrenderer.h"
00020 #include "qgsmarkercatalogue.h"
00021 #include "qgssymbol.h"
00022 #include "qgssymbologyutils.h"
00023 #include "qgsvectordataprovider.h"
00024 #include "qgsvectorlayer.h"
00025 #include "qgsrendercontext.h"
00026
00027 #include <cfloat>
00028 #include <QDomElement>
00029 #include <QPainter>
00030 #include <QImage>
00031
00032 QgsContinuousColorRenderer::QgsContinuousColorRenderer( QGis::GeometryType type ): mMinimumSymbol( 0 ), mMaximumSymbol( 0 )
00033 {
00034 mGeometryType = type;
00035 }
00036
00037 QgsContinuousColorRenderer::QgsContinuousColorRenderer( const QgsContinuousColorRenderer& other )
00038 {
00039 mGeometryType = other.mGeometryType;
00040 mClassificationField = other.mClassificationField;
00041 mMinimumSymbol = new QgsSymbol( *other.mMinimumSymbol );
00042 mMaximumSymbol = new QgsSymbol( *other.mMaximumSymbol );
00043 }
00044
00045 QgsContinuousColorRenderer& QgsContinuousColorRenderer::operator=( const QgsContinuousColorRenderer & other )
00046 {
00047 if ( this != &other )
00048 {
00049 mGeometryType = other.mGeometryType;
00050 mClassificationField = other.mClassificationField;
00051 delete mMinimumSymbol;
00052 delete mMaximumSymbol;
00053 mMinimumSymbol = new QgsSymbol( *other.mMinimumSymbol );
00054 mMaximumSymbol = new QgsSymbol( *other.mMaximumSymbol );
00055 }
00056 return *this;
00057 }
00058
00059 QgsContinuousColorRenderer::~QgsContinuousColorRenderer()
00060 {
00061 delete mMinimumSymbol;
00062 delete mMaximumSymbol;
00063 }
00064
00065 void QgsContinuousColorRenderer::setMinimumSymbol( QgsSymbol* sy )
00066 {
00067 delete mMinimumSymbol;
00068 mMinimumSymbol = sy;
00069 }
00070
00071 void QgsContinuousColorRenderer::setMaximumSymbol( QgsSymbol* sy )
00072 {
00073 delete mMaximumSymbol;
00074 mMaximumSymbol = sy;
00075 }
00076
00077 void QgsContinuousColorRenderer::renderFeature( QgsRenderContext &renderContext, QgsFeature & f, QImage* img, bool selected, double opacity )
00078 {
00079 QPainter *p = renderContext.painter();
00080
00081 if (( mMinimumSymbol && mMaximumSymbol ) )
00082 {
00083
00084 const QgsAttributeMap& attrs = f.attributeMap();
00085 if ( attrs[mClassificationField].isNull() )
00086 {
00087 if ( img )
00088 *img = QImage();
00089 }
00090 double fvalue = attrs[mClassificationField].toDouble();
00091
00092
00093 double minvalue = mMinimumSymbol->lowerValue().toDouble();
00094 double maxvalue = mMaximumSymbol->lowerValue().toDouble();
00095
00096 QColor mincolor, maxcolor;
00097
00098 if ( mGeometryType == QGis::Line || mGeometryType == QGis::Point )
00099 {
00100 mincolor = mMinimumSymbol->pen().color();
00101 maxcolor = mMaximumSymbol->pen().color();
00102 }
00103 else
00104 {
00105 p->setPen( mMinimumSymbol->pen() );
00106 mincolor = mMinimumSymbol->fillColor();
00107 maxcolor = mMaximumSymbol->fillColor();
00108 }
00109
00110 int red, green, blue;
00111
00112 if (( maxvalue - minvalue ) != 0 )
00113 {
00114 red = int ( maxcolor.red() * ( fvalue - minvalue ) / ( maxvalue - minvalue ) + mincolor.red() * ( maxvalue - fvalue ) / ( maxvalue - minvalue ) );
00115 green = int ( maxcolor.green() * ( fvalue - minvalue ) / ( maxvalue - minvalue ) + mincolor.green() * ( maxvalue - fvalue ) / ( maxvalue - minvalue ) );
00116 blue = int ( maxcolor.blue() * ( fvalue - minvalue ) / ( maxvalue - minvalue ) + mincolor.blue() * ( maxvalue - fvalue ) / ( maxvalue - minvalue ) );
00117 }
00118 else
00119 {
00120 red = int ( mincolor.red() );
00121 green = int ( mincolor.green() );
00122 blue = int ( mincolor.blue() );
00123 }
00124
00125 if ( mGeometryType == QGis::Point && img )
00126 {
00127
00128
00129
00130
00131
00132
00133 QPen pen = mMinimumSymbol->pen();
00134 pen.setColor( QColor( red, green, blue ) );
00135 pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
00136
00137 QBrush brush = mMinimumSymbol->brush();
00138
00139 if ( selected )
00140 {
00141 pen.setColor( mSelectionColor );
00142 brush.setColor( mSelectionColor );
00143 }
00144 else
00145 {
00146 brush.setColor( QColor( red, green, blue ) );
00147 }
00148 brush.setStyle( Qt::SolidPattern );
00149
00150 *img = QgsMarkerCatalogue::instance()->imageMarker( mMinimumSymbol->pointSymbolName(),
00151 mMinimumSymbol->pointSize() * renderContext.scaleFactor() * renderContext.rasterScaleFactor(),
00152 pen, brush, opacity );
00153
00154 }
00155 else if ( mGeometryType == QGis::Line )
00156 {
00157 QPen linePen;
00158 linePen.setColor( QColor( red, green, blue ) );
00159 linePen.setWidthF( renderContext.scaleFactor()*mMinimumSymbol->pen().widthF() );
00160 p->setPen( linePen );
00161 }
00162 else
00163 {
00164 p->setBrush( QColor( red, green, blue ) );
00165 if ( mDrawPolygonOutline )
00166 {
00167 QPen pen;
00168 pen.setColor( QColor( 0, 0, 0 ) );
00169 pen.setWidthF( renderContext.scaleFactor()*mMinimumSymbol->pen().widthF() );
00170 p->setPen( pen );
00171 }
00172 else
00173 {
00174 p->setPen( Qt::NoPen );
00175 }
00176 }
00177 if ( selected )
00178 {
00179
00180
00181 if ( mGeometryType != QGis::Polygon )
00182 {
00183 QPen pen = mMinimumSymbol->pen();
00184 pen.setColor( mSelectionColor );
00185 p->setPen( pen );
00186 }
00187 QBrush brush = mMinimumSymbol->brush();
00188 brush.setColor( mSelectionColor );
00189 p->setBrush( brush );
00190 }
00191 }
00192 }
00193
00194 int QgsContinuousColorRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
00195 {
00196 mGeometryType = vl.geometryType();
00197 QDomNode classnode = rnode.namedItem( "classificationfield" );
00198 QString classificationField = classnode.toElement().text();
00199
00200 QgsVectorDataProvider* theProvider = vl.dataProvider();
00201 if ( !theProvider )
00202 {
00203 return 1;
00204 }
00205 int classificationId = theProvider->fieldNameIndex( classificationField );
00206 if ( classificationId == -1 )
00207 {
00208 return 2;
00209 }
00210 setClassificationField( classificationId );
00211
00212
00213 QDomNode polyoutlinenode = rnode.namedItem( "polygonoutline" );
00214 QString polyoutline = polyoutlinenode.toElement().text();
00215 if ( polyoutline == "0" )
00216 {
00217 mDrawPolygonOutline = false;
00218 }
00219 else if ( polyoutline == "1" )
00220 {
00221 mDrawPolygonOutline = true;
00222 }
00223
00224
00225 QDomNode lowernode = rnode.namedItem( "lowestsymbol" );
00226 QDomNode lsymbolnode = lowernode.namedItem( "symbol" );
00227 if ( ! lsymbolnode.isNull() )
00228 {
00229 QgsSymbol* lsy = new QgsSymbol( mGeometryType );
00230 lsy->readXML( lsymbolnode, &vl );
00231 setMinimumSymbol( lsy );
00232 }
00233 QDomNode uppernode = rnode.namedItem( "highestsymbol" );
00234 QDomNode usymbolnode = uppernode.namedItem( "symbol" );
00235 if ( ! usymbolnode.isNull() )
00236 {
00237 QgsSymbol* usy = new QgsSymbol( mGeometryType );
00238 usy->readXML( usymbolnode, &vl );
00239 setMaximumSymbol( usy );
00240 }
00241 vl.setRenderer( this );
00242 return 0;
00243 }
00244
00245 QgsAttributeList QgsContinuousColorRenderer::classificationAttributes() const
00246 {
00247 QgsAttributeList list;
00248 list.append( mClassificationField );
00249 return list;
00250 }
00251
00252 QString QgsContinuousColorRenderer::name() const
00253 {
00254 return "Continuous Color";
00255 }
00256
00257 bool QgsContinuousColorRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const
00258 {
00259 const QgsVectorDataProvider* theProvider = vl.dataProvider();
00260 if ( !theProvider )
00261 {
00262 return false;
00263 }
00264
00265 QString classificationFieldName;
00266 QgsFieldMap::const_iterator field_it = theProvider->fields().find( mClassificationField );
00267 if ( field_it != theProvider->fields().constEnd() )
00268 {
00269 classificationFieldName = field_it.value().name();
00270 }
00271 bool returnval = true;
00272
00273 QDomElement continuoussymbol = document.createElement( "continuoussymbol" );
00274 layer_node.appendChild( continuoussymbol );
00275 QDomElement classificationfield = document.createElement( "classificationfield" );
00276 QDomText classificationfieldtxt = document.createTextNode( classificationFieldName );
00277 classificationfield.appendChild( classificationfieldtxt );
00278 continuoussymbol.appendChild( classificationfield );
00279
00280
00281 QDomElement drawPolygonOutlines = document.createElement( "polygonoutline" );
00282 int drawPolyInt = mDrawPolygonOutline ? 1 : 0;
00283 QDomText drawPolygonText = document.createTextNode( QString::number( drawPolyInt ) );
00284 drawPolygonOutlines.appendChild( drawPolygonText );
00285 continuoussymbol.appendChild( drawPolygonOutlines );
00286
00287 QDomElement lowestsymbol = document.createElement( "lowestsymbol" );
00288 continuoussymbol.appendChild( lowestsymbol );
00289 if ( mMinimumSymbol )
00290 {
00291 mMinimumSymbol->writeXML( lowestsymbol, document, &vl );
00292 }
00293 QDomElement highestsymbol = document.createElement( "highestsymbol" );
00294 continuoussymbol.appendChild( highestsymbol );
00295 if ( mMaximumSymbol )
00296 {
00297 mMaximumSymbol->writeXML( highestsymbol, document, &vl );
00298 }
00299
00300 return returnval;
00301 }
00302
00303 const QList<QgsSymbol*> QgsContinuousColorRenderer::symbols() const
00304 {
00305 QList<QgsSymbol*> list;
00306 list.append( mMinimumSymbol );
00307 list.append( mMaximumSymbol );
00308 return list;
00309 }
00310
00311 QgsRenderer* QgsContinuousColorRenderer::clone() const
00312 {
00313 QgsContinuousColorRenderer* r = new QgsContinuousColorRenderer( *this );
00314 return r;
00315 }