QGIS API Documentation
qgsvectorcolorrampv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorcolorrampv2.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsvectorcolorrampv2.h"
17 #include "qgscolorbrewerpalette.h"
18 #include "qgscptcityarchive.h"
19 
20 #include "qgssymbollayerv2utils.h"
21 #include "qgsapplication.h"
22 #include "qgslogger.h"
23 
24 #include <stdlib.h> // for random()
25 #include <algorithm>
26 
27 #include <QTime>
28 
30 
31 static QColor _interpolate( const QColor& c1, const QColor& c2, const double value )
32 {
33  if ( qIsNaN( value ) ) return c2;
34 
35  qreal r = ( c1.redF() + value * ( c2.redF() - c1.redF() ) );
36  qreal g = ( c1.greenF() + value * ( c2.greenF() - c1.greenF() ) );
37  qreal b = ( c1.blueF() + value * ( c2.blueF() - c1.blueF() ) );
38  qreal a = ( c1.alphaF() + value * ( c2.alphaF() - c1.alphaF() ) );
39 
40  return QColor::fromRgbF( r, g, b, a );
41 }
42 
44 
46  bool discrete, const QgsGradientStopsList& stops )
47  : mColor1( color1 )
48  , mColor2( color2 )
49  , mDiscrete( discrete )
50  , mStops( stops )
51 {
52 }
53 
55 {
56  // color1 and color2
59  if ( props.contains( "color1" ) )
60  color1 = QgsSymbolLayerV2Utils::decodeColor( props["color1"] );
61  if ( props.contains( "color2" ) )
62  color2 = QgsSymbolLayerV2Utils::decodeColor( props["color2"] );
63 
64  //stops
66  if ( props.contains( "stops" ) )
67  {
68  Q_FOREACH ( const QString& stop, props["stops"].split( ':' ) )
69  {
70  int i = stop.indexOf( ';' );
71  if ( i == -1 )
72  continue;
73 
74  QColor c = QgsSymbolLayerV2Utils::decodeColor( stop.mid( i + 1 ) );
75  stops.append( QgsGradientStop( stop.left( i ).toDouble(), c ) );
76  }
77  }
78 
79  // discrete vs. continuous
80  bool discrete = false;
81  if ( props.contains( "discrete" ) )
82  {
83  if ( props["discrete"] == "1" )
84  discrete = true;
85  }
86 
87  // search for information keys starting with "info_"
89  for ( QgsStringMap::const_iterator it = props.constBegin();
90  it != props.constEnd(); ++it )
91  {
92  if ( it.key().startsWith( "info_" ) )
93  info[ it.key().mid( 5 )] = it.value();
94  }
95 
96  QgsVectorGradientColorRampV2* r = new QgsVectorGradientColorRampV2( color1, color2, discrete, stops );
97  r->setInfo( info );
98  return r;
99 }
100 
102 {
103  if ( index <= 0 )
104  {
105  return 0;
106  }
107  else if ( index >= mStops.size() + 1 )
108  {
109  return 1;
110  }
111  else
112  {
113  return mStops[index-1].offset;
114  }
115 }
116 
118 {
119  if ( qgsDoubleNear( value, 0.0 ) || value < 0.0 )
120  {
121  return mColor1;
122  }
123  else if ( qgsDoubleNear( value, 1.0 ) || value > 1.0 )
124  {
125  return mColor2;
126  }
127  else if ( mStops.isEmpty() )
128  {
129  if ( mDiscrete )
130  return mColor1;
131 
132  return _interpolate( mColor1, mColor2, value );
133  }
134  else
135  {
136  double lower = 0, upper = 0;
137  QColor c1 = mColor1, c2;
138  for ( QgsGradientStopsList::const_iterator it = mStops.begin(); it != mStops.end(); ++it )
139  {
140  if ( it->offset > value )
141  {
142  if ( mDiscrete )
143  return c1;
144 
145  upper = it->offset;
146  c2 = it->color;
147 
148  return qgsDoubleNear( upper, lower ) ? c1 : _interpolate( c1, c2, ( value - lower ) / ( upper - lower ) );
149  }
150  lower = it->offset;
151  c1 = it->color;
152  }
153 
154  if ( mDiscrete )
155  return c1;
156 
157  upper = 1;
158  c2 = mColor2;
159  return qgsDoubleNear( upper, lower ) ? c1 : _interpolate( c1, c2, ( value - lower ) / ( upper - lower ) );
160  }
161 }
162 
164 {
166  mDiscrete, mStops );
167  r->setInfo( mInfo );
168  return r;
169 }
170 
172 {
173  QgsStringMap map;
174  map["color1"] = QgsSymbolLayerV2Utils::encodeColor( mColor1 );
175  map["color2"] = QgsSymbolLayerV2Utils::encodeColor( mColor2 );
176  if ( !mStops.isEmpty() )
177  {
178  QStringList lst;
179  for ( QgsGradientStopsList::const_iterator it = mStops.begin(); it != mStops.end(); ++it )
180  {
181  lst.append( QString( "%1;%2" ).arg( it->offset ).arg( QgsSymbolLayerV2Utils::encodeColor( it->color ) ) );
182  }
183  map["stops"] = lst.join( ":" );
184  }
185 
186  map["discrete"] = mDiscrete ? "1" : "0";
187 
189  it != mInfo.constEnd(); ++it )
190  {
191  map["info_" + it.key()] = it.value();
192  }
193 
194  return map;
195 }
197 {
198  if ( discrete == mDiscrete )
199  return;
200 
201  // if going to/from Discrete, re-arrange stops
202  // this will only work when stops are equally-spaced
203  QgsGradientStopsList newStops;
204  if ( discrete )
205  {
206  // re-arrange stops offset
207  int numStops = mStops.count() + 2;
208  int i = 1;
209  for ( QgsGradientStopsList::const_iterator it = mStops.constBegin();
210  it != mStops.constEnd(); ++it )
211  {
212  newStops.append( QgsGradientStop( static_cast< double >( i ) / numStops, it->color ) );
213  if ( i == numStops - 1 )
214  break;
215  i++;
216  }
217  // replicate last color
218  newStops.append( QgsGradientStop( static_cast< double >( i ) / numStops, mColor2 ) );
219  }
220  else
221  {
222  // re-arrange stops offset, remove duplicate last color
223  int numStops = mStops.count() + 2;
224  int i = 1;
225  for ( QgsGradientStopsList::const_iterator it = mStops.constBegin();
226  it != mStops.constEnd(); ++it )
227  {
228  newStops.append( QgsGradientStop( static_cast< double >( i ) / ( numStops - 2 ), it->color ) );
229  if ( i == numStops - 3 )
230  break;
231  i++;
232  }
233  }
234  mStops = newStops;
235  mDiscrete = discrete;
236 }
237 
239 {
240  //copy color ramp stops to a QGradient
243  if ( alpha < 1 )
244  {
245  color1.setAlpha( color1.alpha() * alpha );
246  color2.setAlpha( color2.alpha() * alpha );
247  }
248  gradient->setColorAt( 0, color1 );
249  gradient->setColorAt( 1, color2 );
250 
251  for ( QgsGradientStopsList::const_iterator it = mStops.constBegin();
252  it != mStops.constEnd(); ++it )
253  {
254  QColor rampColor = it->color;
255  if ( alpha < 1 )
256  {
257  rampColor.setAlpha( rampColor.alpha() * alpha );
258  }
259  gradient->setColorAt( it->offset, rampColor );
260  }
261 }
262 
263 
265 
266 
268  int satMin, int satMax, int valMin, int valMax )
269  : mCount( count )
270  , mHueMin( hueMin ), mHueMax( hueMax )
271  , mSatMin( satMin ), mSatMax( satMax )
272  , mValMin( valMin ), mValMax( valMax )
273 {
274  updateColors();
275 }
276 
278 {
283 
284  if ( props.contains( "count" ) ) count = props["count"].toInt();
285  if ( props.contains( "hueMin" ) ) hueMin = props["hueMin"].toInt();
286  if ( props.contains( "hueMax" ) ) hueMax = props["hueMax"].toInt();
287  if ( props.contains( "satMin" ) ) satMin = props["satMin"].toInt();
288  if ( props.contains( "satMax" ) ) satMax = props["satMax"].toInt();
289  if ( props.contains( "valMin" ) ) valMin = props["valMin"].toInt();
290  if ( props.contains( "valMax" ) ) valMax = props["valMax"].toInt();
291 
292  return new QgsVectorRandomColorRampV2( count, hueMin, hueMax, satMin, satMax, valMin, valMax );
293 }
294 
296 {
297  if ( mColors.size() < 1 ) return 0;
298  return static_cast< double >( index ) / ( mColors.size() - 1 );
299 }
300 
302 {
303  int colorCnt = mColors.count();
304  int colorIdx = static_cast< int >( value * ( colorCnt - 1 ) );
305 
306  if ( colorIdx >= 0 && colorIdx < colorCnt )
307  return mColors.at( colorIdx );
308 
309  return QColor();
310 }
311 
313 {
315 }
316 
318 {
319  QgsStringMap map;
320  map["count"] = QString::number( mCount );
321  map["hueMin"] = QString::number( mHueMin );
322  map["hueMax"] = QString::number( mHueMax );
323  map["satMin"] = QString::number( mSatMin );
324  map["satMax"] = QString::number( mSatMax );
325  map["valMin"] = QString::number( mValMin );
326  map["valMax"] = QString::number( mValMax );
327  return map;
328 }
329 
331  int hueMax, int hueMin, int satMax, int satMin, int valMax, int valMin )
332 {
333  int h, s, v;
334  QList<QColor> colors;
335 
336  //normalize values
337  int safeHueMax = qMax( hueMin, hueMax );
338  int safeHueMin = qMin( hueMin, hueMax );
339  int safeSatMax = qMax( satMin, satMax );
340  int safeSatMin = qMin( satMin, satMax );
341  int safeValMax = qMax( valMin, valMax );
342  int safeValMin = qMin( valMin, valMax );
343 
344  //start hue at random angle
345  double currentHueAngle = 360.0 * static_cast< double >( qrand() ) / RAND_MAX;
346 
347  colors.reserve( count );
348  for ( int i = 0; i < count; ++i )
349  {
350  //increment hue by golden ratio (approx 137.507 degrees)
351  //as this minimises hue nearness as count increases
352  //see http://basecase.org/env/on-rainbows for more details
353  currentHueAngle += 137.50776;
354  //scale hue to between hueMax and hueMin
355  h = qBound( 0, qRound(( fmod( currentHueAngle, 360.0 ) / 360.0 ) * ( safeHueMax - safeHueMin ) + safeHueMin ), 359 );
356  s = qBound( 0, ( qrand() % ( safeSatMax - safeSatMin + 1 ) ) + safeSatMin, 255 );
357  v = qBound( 0, ( qrand() % ( safeValMax - safeValMin + 1 ) ) + safeValMin, 255 );
358  colors.append( QColor::fromHsv( h, s, v ) );
359  }
360  return colors;
361 }
362 
364 {
366 }
367 
369 
371  : mTotalColorCount( 0 )
372 {
373 }
374 
376 {
377 
378 }
379 
381 {
382  return -1;
383 }
384 
385 double QgsRandomColorsV2::value( int index ) const
386 {
387  Q_UNUSED( index );
388  return 0.0;
389 }
390 
392 {
393  int minVal = 130;
394  int maxVal = 255;
395 
396  //if value is nan, then use last precalculated color
397  int colorIndex = ( !qIsNaN( value ) ? value : 1 ) * ( mTotalColorCount - 1 );
398  if ( mTotalColorCount >= 1 && mPrecalculatedColors.length() > colorIndex )
399  {
400  //use precalculated hue
401  return mPrecalculatedColors.at( colorIndex );
402  }
403 
404  //can't use precalculated hues, use a totally random hue
405  int h = static_cast< int >( 360.0 * qrand() / ( RAND_MAX + 1.0 ) );
406  int s = ( qrand() % ( DEFAULT_RANDOM_SAT_MAX - DEFAULT_RANDOM_SAT_MIN + 1 ) ) + DEFAULT_RANDOM_SAT_MIN;
407  int v = ( qrand() % ( maxVal - minVal + 1 ) ) + minVal;
408  return QColor::fromHsv( h, s, v );
409 }
410 
411 void QgsRandomColorsV2::setTotalColorCount( const int colorCount )
412 {
413  //calculate colors in advance, so that we can ensure they are more visually distinct than pure random colors
415  mTotalColorCount = colorCount;
416 
417  //This works ok for low color counts, but for > 10 or so colors there's still a good chance of
418  //similar colors being picked. TODO - investigate alternative "n-visually distinct color" routines
419 
420  //random offsets
421  double hueOffset = ( 360.0 * qrand() / ( RAND_MAX + 1.0 ) );
422 
423  //try to maximise difference between hues. this is not an ideal implementation, as constant steps
424  //through the hue wheel are not visually perceived as constant changes in hue
425  //(for instance, we are much more likely to get green hues than yellow hues)
426  double hueStep = 359.0 / colorCount;
427  double currentHue = hueOffset;
428 
429  //build up a list of colors
430  for ( int idx = 0; idx < colorCount; ++ idx )
431  {
432  int h = qRound( currentHue ) % 360;
433  int s = ( qrand() % ( DEFAULT_RANDOM_SAT_MAX - DEFAULT_RANDOM_SAT_MIN + 1 ) ) + DEFAULT_RANDOM_SAT_MIN;
434  int v = ( qrand() % ( DEFAULT_RANDOM_VAL_MAX - DEFAULT_RANDOM_VAL_MIN + 1 ) ) + DEFAULT_RANDOM_VAL_MIN;
436  currentHue += hueStep;
437  }
438 
439  //lastly, shuffle color list
440  std::random_shuffle( mPrecalculatedColors.begin(), mPrecalculatedColors.end() );
441 }
442 
444 {
445  return "randomcolors";
446 }
447 
449 {
450  return new QgsRandomColorsV2();
451 }
452 
454 {
455  return QgsStringMap();
456 }
457 
459 
461  : mSchemeName( schemeName ), mColors( colors )
462 {
463  loadPalette();
464 }
465 
467 {
470 
471  if ( props.contains( "schemeName" ) )
472  schemeName = props["schemeName"];
473  if ( props.contains( "colors" ) )
474  colors = props["colors"].toInt();
475 
476  return new QgsVectorColorBrewerColorRampV2( schemeName, colors );
477 }
478 
480 {
482 }
483 
485 {
487 }
488 
490 {
491  return QgsColorBrewerPalette::listSchemeVariants( schemeName );
492 }
493 
495 {
496  if ( mPalette.size() < 1 ) return 0;
497  return static_cast< double >( index ) / ( mPalette.size() - 1 );
498 }
499 
501 {
502  if ( mPalette.isEmpty() || value < 0 || value > 1 )
503  return QColor();
504 
505  int paletteEntry = static_cast< int >( value * mPalette.count() );
506  if ( paletteEntry >= mPalette.count() )
507  paletteEntry = mPalette.count() - 1;
508  return mPalette.at( paletteEntry );
509 }
510 
512 {
514 }
515 
517 {
518  QgsStringMap map;
519  map["schemeName"] = mSchemeName;
520  map["colors"] = QString::number( mColors );
521  return map;
522 }
523 
524 
526 
527 
529  bool doLoadFile )
531  , mSchemeName( schemeName ), mVariantName( variantName )
532  , mVariantList( QStringList() ), mFileLoaded( false ), mMultiStops( false )
533 {
534  // TODO replace this with hard-coded data in the default case
535  // don't load file if variant is missing
536  if ( doLoadFile && ( variantName != QString() || mVariantList.isEmpty() ) )
537  loadFile();
538 }
539 
541  const QString& variantName, bool doLoadFile )
543  , mSchemeName( schemeName ), mVariantName( variantName )
544  , mVariantList( variantList ), mFileLoaded( false ), mMultiStops( false )
545 {
547 
548  // TODO replace this with hard-coded data in the default case
549  // don't load file if variant is missing
550  if ( doLoadFile && ( variantName != QString() || mVariantList.isEmpty() ) )
551  loadFile();
552 }
553 
555 {
558 
559  if ( props.contains( "schemeName" ) )
560  schemeName = props["schemeName"];
561  if ( props.contains( "variantName" ) )
562  variantName = props["variantName"];
563 
564  return new QgsCptCityColorRampV2( schemeName, variantName );
565 }
566 
568 {
569  QgsCptCityColorRampV2* ramp = new QgsCptCityColorRampV2( "", "", false );
570  ramp->copy( this );
571  return ramp;
572 }
573 
575 {
576  if ( ! other )
577  return;
578  mColor1 = other->color1();
579  mColor2 = other->color2();
580  mDiscrete = other->isDiscrete();
581  mStops = other->stops();
582  mSchemeName = other->mSchemeName;
583  mVariantName = other->mVariantName;
584  mVariantList = other->mVariantList;
585  mFileLoaded = other->mFileLoaded;
586 }
587 
589 {
592  // add author and copyright information
593  // TODO also add COPYING.xml file/link?
595  info["cpt-city-gradient"] = "<cpt-city>/" + mSchemeName + mVariantName + ".svg";
596  QString copyingFilename = copyingFileName();
597  copyingFilename.remove( QgsCptCityArchive::defaultBaseDir() );
598  info["cpt-city-license"] = "<cpt-city>" + copyingFilename;
599  ramp->setInfo( info );
600  return ramp;
601 }
602 
603 
605 {
606  QgsStringMap map;
607  map["schemeName"] = mSchemeName;
608  map["variantName"] = mVariantName;
609  return map;
610 }
611 
612 
614 {
615  if ( mSchemeName == "" )
616  return QString();
617  else
618  {
620  }
621 }
622 
624 {
625  return QgsCptCityArchive::findFileName( "COPYING.xml", QFileInfo( fileName() ).dir().path(),
627 }
628 
630 {
631  return QgsCptCityArchive::findFileName( "DESC.xml", QFileInfo( fileName() ).dir().path(),
633 }
634 
636 {
638 }
639 
641 {
642  if ( mFileLoaded )
643  {
644  QgsDebugMsg( "File already loaded for " + mSchemeName + mVariantName );
645  return true;
646  }
647 
648  // get filename
649  QString filename = fileName();
650  if ( filename.isNull() )
651  {
652  QgsDebugMsg( "Couldn't get fileName() for " + mSchemeName + mVariantName );
653  return false;
654  }
655 
656  QgsDebugMsg( QString( "filename= %1 loaded=%2" ).arg( filename ).arg( mFileLoaded ) );
657 
658  // get color ramp from svg file
661 
662  // add colors to palette
663  mFileLoaded = false;
664  mStops.clear();
665  QMap<double, QPair<QColor, QColor> >::const_iterator it, prev;
666  // first detect if file is gradient is continuous or dicrete
667  // discrete: stop contains 2 colors and first color is identical to previous second
668  // multi: stop contains 2 colors and no relation with previous stop
669  mDiscrete = false;
670  mMultiStops = false;
671  it = prev = colorMap.constBegin();
672  while ( it != colorMap.constEnd() )
673  {
674  // look for stops that contain multiple values
675  if ( it != colorMap.constBegin() && ( it.value().first != it.value().second ) )
676  {
677  if ( it.value().first == prev.value().second )
678  {
679  mDiscrete = true;
680  break;
681  }
682  else
683  {
684  mMultiStops = true;
685  break;
686  }
687  }
688  prev = it;
689  ++it;
690  }
691 
692  // fill all stops
693  it = prev = colorMap.constBegin();
694  while ( it != colorMap.constEnd() )
695  {
696  if ( mDiscrete )
697  {
698  // mPalette << qMakePair( it.key(), it.value().second );
699  mStops.append( QgsGradientStop( it.key(), it.value().second ) );
700  }
701  else
702  {
703  // mPalette << qMakePair( it.key(), it.value().first );
704  mStops.append( QgsGradientStop( it.key(), it.value().first ) );
705  if (( mMultiStops ) &&
706  ( it.key() != 0.0 && it.key() != 1.0 ) )
707  {
708  mStops.append( QgsGradientStop( it.key(), it.value().second ) );
709  }
710  }
711  prev = it;
712  ++it;
713  }
714 
715  // remove first and last items (mColor1 and mColor2)
716  if ( ! mStops.isEmpty() && mStops.at( 0 ).offset == 0.0 )
717  mColor1 = mStops.takeFirst().color;
718  if ( ! mStops.isEmpty() && mStops.last().offset == 1.0 )
719  mColor2 = mStops.takeLast().color;
720 
721  mFileLoaded = true;
722  return true;
723 }
static QgsVectorColorRampV2 * create(const QgsStringMap &properties=QgsStringMap())
static QgsVectorColorRampV2 * create(const QgsStringMap &properties=QgsStringMap())
virtual QColor color(double value) const override
Returns the color corresponding to a specified value.
void clear()
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
static unsigned index
int count() const override
Returns number of defined colors, or -1 if undefined.
QgsRandomColorsV2 * clone() const override
Creates a clone of the color ramp.
bool contains(const Key &key) const
#define DEFAULT_CPTCITY_VARIANTNAME
virtual QgsVectorRandomColorRampV2 * clone() const override
Creates a clone of the color ramp.
Represents a color stop within a gradient color ramp.
qreal alphaF() const
qreal redF() const
void copy(const QgsCptCityColorRampV2 *other)
int length() const
int count() const override
Returns number of defined colors, or -1 if undefined.
virtual QgsVectorColorBrewerColorRampV2 * clone() const override
Creates a clone of the color ramp.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void setColorAt(qreal position, const QColor &color)
void reserve(int alloc)
static QString defaultBaseDir()
static QString encodeColor(const QColor &color)
#define DEFAULT_COLORBREWER_SCHEMENAME
#define DEFAULT_RANDOM_HUE_MIN
qreal blueF() const
const_iterator constBegin() const
const T & at(int i) const
void setInfo(const QgsStringMap &info)
Sets additional info to attach to the gradient ramp (eg authorship notes)
virtual QgsVectorGradientColorRampV2 * clone() const override
Creates a clone of the color ramp.
virtual QgsCptCityColorRampV2 * clone() const override
Creates a clone of the color ramp.
void setAlpha(int alpha)
virtual void setTotalColorCount(const int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
QString join(const QString &separator) const
QString & remove(int position, int n)
#define DEFAULT_CPTCITY_SCHEMENAME
double toDouble(bool *ok) const
static QList< QColor > listSchemeColors(const QString &schemeName, int colors)
QChar separator()
QMap< QString, QString > QgsStringMap
Definition: qgis.h:451
#define DEFAULT_RANDOM_SAT_MAX
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:348
int size() const
QgsStringMap info() const
Returns any additional info attached to the gradient ramp (eg authorship notes)
bool isNull() const
QgsCptCityColorRampV2(const QString &schemeName=DEFAULT_CPTCITY_SCHEMENAME, const QString &variantName=DEFAULT_CPTCITY_VARIANTNAME, bool doLoadFile=true)
QColor fromHsv(int h, int s, int v, int a)
static QList< int > listSchemeVariants(const QString &schemeName)
virtual QgsStringMap properties() const override
Returns a string map containing all the color ramp&#39;s properties.
virtual int count() const override
Returns number of defined colors, or -1 if undefined.
QString variantName() const
QString number(int n, int base)
int count(const T &value) const
void append(const T &value)
QStringList variantList() const
#define DEFAULT_GRADIENT_COLOR2
virtual QgsStringMap properties() const override
Returns a string map containing all the color ramp&#39;s properties.
QgsVectorRandomColorRampV2(int count=DEFAULT_RANDOM_COUNT, int hueMin=DEFAULT_RANDOM_HUE_MIN, int hueMax=DEFAULT_RANDOM_HUE_MAX, int satMin=DEFAULT_RANDOM_SAT_MIN, int satMax=DEFAULT_RANDOM_SAT_MAX, int valMin=DEFAULT_RANDOM_VAL_MIN, int valMax=DEFAULT_RANDOM_VAL_MAX)
virtual QColor color(double value) const override
Returns the color corresponding to a specified value.
static QColor _interpolate(const QColor &c1, const QColor &c2, const double value)
bool isEmpty() const
#define DEFAULT_GRADIENT_COLOR1
const_iterator constEnd() const
qreal greenF() const
#define DEFAULT_RANDOM_VAL_MAX
QgsStringMap copyingInfo() const
virtual QgsStringMap properties() const override
Returns a string map containing all the color ramp&#39;s properties.
static QMap< QString, QString > copyingInfo(const QString &fileName)
static QList< QColor > randomColors(int count, int hueMax=DEFAULT_RANDOM_HUE_MAX, int hueMin=DEFAULT_RANDOM_HUE_MIN, int satMax=DEFAULT_RANDOM_SAT_MAX, int satMin=DEFAULT_RANDOM_SAT_MIN, int valMax=DEFAULT_RANDOM_VAL_MAX, int valMin=DEFAULT_RANDOM_VAL_MIN)
Get a list of random colors.
QgsVectorGradientColorRampV2(const QColor &color1=DEFAULT_GRADIENT_COLOR1, const QColor &color2=DEFAULT_GRADIENT_COLOR2, bool discrete=false, const QgsGradientStopsList &stops=QgsGradientStopsList())
Constructor for QgsVectorGradientColorRampV2.
virtual QgsStringMap properties() const override
Returns a string map containing all the color ramp&#39;s properties.
QString type() const override
Returns a string representing the color ramp type.
void convertToDiscrete(bool discrete)
Converts a gradient with existing color stops to or from discrete interpolation.
int alpha() const
iterator end()
QColor fromRgbF(qreal r, qreal g, qreal b, qreal a)
#define DEFAULT_RANDOM_SAT_MIN
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
virtual double value(int index) const override
Returns relative value between [0,1] of color at specified index.
static QgsVectorColorRampV2 * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsVectorColorRampV2 from a map of properties.
QgsStringMap properties() const override
Returns a string map containing all the color ramp&#39;s properties.
virtual QColor color(double value) const override
Returns the color corresponding to a specified value.
const Key key(const T &value) const
QgsVectorGradientColorRampV2 * cloneGradientRamp() const
Random color ramp, which returns random colors based on preset parameters.
int ANALYSIS_EXPORT lower(int n, int i)
Lower function.
T takeLast()
QString mid(int position, int n) const
virtual double value(int index) const override
Returns relative value between [0,1] of color at specified index.
T takeFirst()
#define DEFAULT_COLORBREWER_COLORS
static QStringList listSchemes()
QColor color(double value) const override
Returns the color corresponding to a specified value.
T & last()
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
static QgsVectorColorRampV2 * create(const QgsStringMap &properties=QgsStringMap())
QList< QColor > mPrecalculatedColors
#define DEFAULT_RANDOM_HUE_MAX
QString left(int n) const
QgsVectorColorBrewerColorRampV2(const QString &schemeName=DEFAULT_COLORBREWER_SCHEMENAME, int colors=DEFAULT_COLORBREWER_COLORS)
static QColor decodeColor(const QString &str)
static QList< int > listSchemeVariants(const QString &schemeName)
virtual double value(int index) const override
Returns relative value between [0,1] of color at specified index.
static QMap< double, QPair< QColor, QColor > > gradientColorMap(const QString &fileName)
const_iterator constEnd() const
const_iterator constBegin() const
#define DEFAULT_RANDOM_VAL_MIN
void addStopsToGradient(QGradient *gradient, double alpha=1)
Copy color ramp stops to a QGradient.
Abstract base class for color ramps.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
QColor color2() const
Returns the gradient end color.
QColor color1() const
Returns the gradient start color.
iterator begin()
QString copyingFileName() const
#define DEFAULT_RANDOM_COUNT
static QString findFileName(const QString &target, const QString &startDir, const QString &baseDir)
const T value(const Key &key) const