QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgscolorrampimpl.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscolorrampimpl.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 "qgscolorrampimpl.h"
17 #include "qgscolorbrewerpalette.h"
18 #include "qgscptcityarchive.h"
19 
20 #include "qgssymbollayerutils.h"
21 #include "qgsapplication.h"
22 #include "qgslogger.h"
23 
24 #include <algorithm>
25 #include <random>
26 
27 #include <QTime>
28 #include <QDir>
29 #include <QFileInfo>
30 
32 
33 
34 static QColor _interpolateRgb( const QColor &c1, const QColor &c2, const double value, const Qgis::AngularDirection )
35 {
36  if ( std::isnan( value ) )
37  return c2;
38 
39  const qreal red1 = c1.redF();
40  const qreal red2 = c2.redF();
41  const qreal red = ( red1 + value * ( red2 - red1 ) );
42 
43  const qreal green1 = c1.greenF();
44  const qreal green2 = c2.greenF();
45  const qreal green = ( green1 + value * ( green2 - green1 ) );
46 
47  const qreal blue1 = c1.blueF();
48  const qreal blue2 = c2.blueF();
49  const qreal blue = ( blue1 + value * ( blue2 - blue1 ) );
50 
51  const qreal alpha1 = c1.alphaF();
52  const qreal alpha2 = c2.alphaF();
53  const qreal alpha = ( alpha1 + value * ( alpha2 - alpha1 ) );
54 
55  return QColor::fromRgbF( red, green, blue, alpha );
56 }
57 
58 static QColor _interpolateHsv( const QColor &c1, const QColor &c2, const double value, const Qgis::AngularDirection direction )
59 {
60  if ( std::isnan( value ) )
61  return c2;
62 
63  qreal hue1 = c1.hsvHueF();
64  qreal hue2 = c2.hsvHueF();
65  qreal hue = 0;
66  if ( hue1 == -1 )
67  hue = hue2;
68  else if ( hue2 == -1 )
69  hue = hue1;
70  else
71  {
72  switch ( direction )
73  {
75  {
76  if ( hue1 < hue2 )
77  hue1 += 1;
78 
79  hue = hue1 - value * ( hue1 - hue2 );
80  if ( hue < 0 )
81  hue += 1;
82  if ( hue > 1 )
83  hue -= 1;
84  break;
85  }
86 
88  {
89  if ( hue2 < hue1 )
90  hue2 += 1;
91 
92  hue = hue1 + value * ( hue2 - hue1 );
93  if ( hue > 1 )
94  hue -= 1;
95  break;
96  }
97  }
98  }
99 
100  const qreal saturation1 = c1.hsvSaturationF();
101  const qreal saturation2 = c2.hsvSaturationF();
102  const qreal saturation = ( saturation1 + value * ( saturation2 - saturation1 ) );
103 
104  const qreal value1 = c1.valueF();
105  const qreal value2 = c2.valueF();
106  const qreal valueOut = ( value1 + value * ( value2 - value1 ) );
107 
108  const qreal alpha1 = c1.alphaF();
109  const qreal alpha2 = c2.alphaF();
110  const qreal alpha = ( alpha1 + value * ( alpha2 - alpha1 ) );
111 
112  return QColor::fromHsvF( hue > 1 ? hue - 1 : hue, saturation, valueOut, alpha );
113 }
114 
115 static QColor _interpolateHsl( const QColor &c1, const QColor &c2, const double value, const Qgis::AngularDirection direction )
116 {
117  if ( std::isnan( value ) )
118  return c2;
119 
120  qreal hue1 = c1.hslHueF();
121  qreal hue2 = c2.hslHueF();
122  qreal hue = 0;
123  if ( hue1 == -1 )
124  hue = hue2;
125  else if ( hue2 == -1 )
126  hue = hue1;
127  else
128  {
129  switch ( direction )
130  {
132  {
133  if ( hue1 < hue2 )
134  hue1 += 1;
135 
136  hue = hue1 - value * ( hue1 - hue2 );
137  if ( hue < 0 )
138  hue += 1;
139  if ( hue > 1 )
140  hue -= 1;
141  break;
142  }
143 
145  {
146  if ( hue2 < hue1 )
147  hue2 += 1;
148 
149  hue = hue1 + value * ( hue2 - hue1 );
150  if ( hue > 1 )
151  hue -= 1;
152  break;
153  }
154  }
155  }
156 
157  const qreal saturation1 = c1.hslSaturationF();
158  const qreal saturation2 = c2.hslSaturationF();
159  const qreal saturation = ( saturation1 + value * ( saturation2 - saturation1 ) );
160 
161  const qreal lightness1 = c1.lightnessF();
162  const qreal lightness2 = c2.lightnessF();
163  const qreal lightness = ( lightness1 + value * ( lightness2 - lightness1 ) );
164 
165  const qreal alpha1 = c1.alphaF();
166  const qreal alpha2 = c2.alphaF();
167  const qreal alpha = ( alpha1 + value * ( alpha2 - alpha1 ) );
168 
169  return QColor::fromHslF( hue > 1 ? hue - 1 : hue, saturation, lightness, alpha );
170 }
171 
173 
174 
175 QgsGradientStop::QgsGradientStop( double offset, const QColor &color )
176  : offset( offset )
177  , color( color )
178  , mFunc( _interpolateRgb )
179 {
180 
181 }
182 
183 void QgsGradientStop::setColorSpec( QColor::Spec spec )
184 {
185  mColorSpec = spec;
186 
187  switch ( mColorSpec )
188  {
189  case QColor::Rgb:
190  case QColor::Invalid:
191 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
192  case QColor::ExtendedRgb:
193 #endif
194  case QColor::Cmyk:
195  mFunc = _interpolateRgb;
196  break;
197  case QColor::Hsv:
198  mFunc = _interpolateHsv;
199  break;
200  case QColor::Hsl:
201  mFunc = _interpolateHsl;
202  break;
203  }
204 }
205 
206 QgsGradientColorRamp::QgsGradientColorRamp( const QColor &color1, const QColor &color2,
207  bool discrete, const QgsGradientStopsList &stops )
208  : mColor1( color1 )
209  , mColor2( color2 )
210  , mDiscrete( discrete )
211  , mStops( stops )
212  , mFunc( _interpolateRgb )
213 {
214 }
215 
216 QgsColorRamp *QgsGradientColorRamp::create( const QVariantMap &props )
217 {
218  // color1 and color2
221  if ( props.contains( QStringLiteral( "color1" ) ) )
222  color1 = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "color1" )].toString() );
223  if ( props.contains( QStringLiteral( "color2" ) ) )
224  color2 = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "color2" )].toString() );
225 
226  //stops
228  if ( props.contains( QStringLiteral( "stops" ) ) )
229  {
230  const auto constSplit = props[QStringLiteral( "stops" )].toString().split( ':' );
231  for ( const QString &stop : constSplit )
232  {
233  const QStringList parts = stop.split( ';' );
234  if ( parts.size() != 2 && parts.size() != 4 )
235  continue;
236 
237  QColor c = QgsSymbolLayerUtils::decodeColor( parts.at( 1 ) );
238  stops.append( QgsGradientStop( parts.at( 0 ).toDouble(), c ) );
239 
240  if ( parts.size() == 4 )
241  {
242  if ( parts.at( 2 ).compare( QLatin1String( "rgb" ) ) == 0 )
243  stops.last().setColorSpec( QColor::Spec::Rgb );
244  else if ( parts.at( 2 ).compare( QLatin1String( "hsv" ) ) == 0 )
245  stops.last().setColorSpec( QColor::Spec::Hsv );
246  else if ( parts.at( 2 ).compare( QLatin1String( "hsl" ) ) == 0 )
247  stops.last().setColorSpec( QColor::Spec::Hsl );
248 
249  if ( parts.at( 3 ).compare( QLatin1String( "cw" ) ) == 0 )
250  stops.last().setDirection( Qgis::AngularDirection::Clockwise );
251  else if ( parts.at( 3 ).compare( QLatin1String( "ccw" ) ) == 0 )
252  stops.last().setDirection( Qgis::AngularDirection::CounterClockwise );
253  }
254  }
255  }
256 
257  // discrete vs. continuous
258  bool discrete = false;
259  if ( props.contains( QStringLiteral( "discrete" ) ) )
260  {
261  if ( props[QStringLiteral( "discrete" )] == QLatin1String( "1" ) )
262  discrete = true;
263  }
264 
265  // search for information keys starting with "info_"
267  for ( QVariantMap::const_iterator it = props.constBegin();
268  it != props.constEnd(); ++it )
269  {
270  if ( it.key().startsWith( QLatin1String( "info_" ) ) )
271  info[ it.key().mid( 5 )] = it.value().toString();
272  }
273 
275  r->setInfo( info );
276 
277  if ( props.contains( QStringLiteral( "spec" ) ) )
278  {
279  const QString spec = props.value( QStringLiteral( "spec" ) ).toString().trimmed();
280  if ( spec.compare( QLatin1String( "rgb" ) ) == 0 )
281  r->setColorSpec( QColor::Spec::Rgb );
282  else if ( spec.compare( QLatin1String( "hsv" ) ) == 0 )
283  r->setColorSpec( QColor::Spec::Hsv );
284  else if ( spec.compare( QLatin1String( "hsl" ) ) == 0 )
285  r->setColorSpec( QColor::Spec::Hsl );
286  }
287 
288  if ( props.contains( QStringLiteral( "direction" ) ) )
289  {
290  const QString direction = props.value( QStringLiteral( "direction" ) ).toString().trimmed();
291  if ( direction.compare( QLatin1String( "ccw" ) ) == 0 )
293  else if ( direction.compare( QLatin1String( "cw" ) ) == 0 )
295  }
296 
297  return r;
298 }
299 
300 double QgsGradientColorRamp::value( int index ) const
301 {
302  if ( index <= 0 )
303  {
304  return 0;
305  }
306  else if ( index >= mStops.size() + 1 )
307  {
308  return 1;
309  }
310  else
311  {
312  return mStops[index - 1].offset;
313  }
314 }
315 
316 QColor QgsGradientColorRamp::color( double value ) const
317 {
318  if ( qgsDoubleNear( value, 0.0 ) || value < 0.0 )
319  {
320  return mColor1;
321  }
322  else if ( qgsDoubleNear( value, 1.0 ) || value > 1.0 )
323  {
324  return mColor2;
325  }
326  else if ( mStops.isEmpty() )
327  {
328  if ( mDiscrete )
329  return mColor1;
330 
331  return mFunc( mColor1, mColor2, value, mDirection );
332  }
333  else
334  {
335  double lower = 0, upper = 0;
336  QColor c1 = mColor1, c2;
337  for ( QgsGradientStopsList::const_iterator it = mStops.begin(); it != mStops.end(); ++it )
338  {
339  if ( it->offset > value )
340  {
341  if ( mDiscrete )
342  return c1;
343 
344  upper = it->offset;
345  c2 = it->color;
346 
347  return qgsDoubleNear( upper, lower ) ? c1 : it->mFunc( c1, c2, ( value - lower ) / ( upper - lower ), it->mDirection );
348  }
349  lower = it->offset;
350  c1 = it->color;
351  }
352 
353  if ( mDiscrete )
354  return c1;
355 
356  upper = 1;
357  c2 = mColor2;
358  return qgsDoubleNear( upper, lower ) ? c1 : mFunc( c1, c2, ( value - lower ) / ( upper - lower ), mDirection );
359  }
360 }
361 
363 {
365 }
366 
368 {
369  QgsGradientStopsList newStops;
370  newStops.reserve( mStops.size() );
371 
372  if ( mDiscrete )
373  {
374  mColor2 = mColor1;
375  mColor1 = mStops.at( mStops.size() - 1 ).color;
376  for ( int k = mStops.size() - 1; k >= 1; k-- )
377  {
378  newStops << QgsGradientStop( 1 - mStops.at( k ).offset, mStops.at( k - 1 ).color );
379  }
380  newStops << QgsGradientStop( 1 - mStops.at( 0 ).offset, mColor2 );
381  }
382  else
383  {
384  QColor tmpColor = mColor2;
385  mColor2 = mColor1;
386  mColor1 = tmpColor;
387  for ( int k = mStops.size() - 1; k >= 0; k-- )
388  {
389  newStops << QgsGradientStop( 1 - mStops.at( k ).offset, mStops.at( k ).color );
390  }
391  }
392 
393  // transfer color spec, invert directions
394  if ( mStops.empty() )
395  {
396  // reverse direction
398  }
399  else
400  {
401  newStops[0].setColorSpec( mColorSpec );
403  for ( int i = 1, j = mStops.size() - 1; i < mStops.size(); ++i, --j )
404  {
405  newStops[i].setColorSpec( mStops.at( j ).colorSpec() );
407  }
408  mColorSpec = mStops.at( 0 ).colorSpec();
410  }
411 
412  mStops = newStops;
413 }
414 
416 {
418  mDiscrete, mStops );
419  r->setInfo( mInfo );
420  r->setColorSpec( mColorSpec );
421  r->setDirection( mDirection );
422  return r;
423 }
424 
426 {
427  QVariantMap map;
428  map[QStringLiteral( "color1" )] = QgsSymbolLayerUtils::encodeColor( mColor1 );
429  map[QStringLiteral( "color2" )] = QgsSymbolLayerUtils::encodeColor( mColor2 );
430  if ( !mStops.isEmpty() )
431  {
432  QStringList lst;
433  lst.reserve( mStops.size() );
434  for ( const QgsGradientStop &stop : mStops )
435  {
436  lst.append( QStringLiteral( "%1;%2;%3;%4" ).arg( stop.offset ).arg( QgsSymbolLayerUtils::encodeColor( stop.color ),
437  stop.colorSpec() == QColor::Rgb ? QStringLiteral( "rgb" )
438  : stop.colorSpec() == QColor::Hsv ? QStringLiteral( "hsv" )
439  : stop.colorSpec() == QColor::Hsl ? QStringLiteral( "hsl" ) : QString(),
440  stop.direction() == Qgis::AngularDirection::CounterClockwise ? QStringLiteral( "ccw" ) : QStringLiteral( "cw" ) ) );
441  }
442  map[QStringLiteral( "stops" )] = lst.join( QLatin1Char( ':' ) );
443  }
444 
445  map[QStringLiteral( "discrete" )] = mDiscrete ? "1" : "0";
446 
447  for ( QgsStringMap::const_iterator it = mInfo.constBegin();
448  it != mInfo.constEnd(); ++it )
449  {
450  map["info_" + it.key()] = it.value();
451  }
452 
453  switch ( mColorSpec )
454  {
455  case QColor::Rgb:
456  map[QStringLiteral( "spec" ) ] = QStringLiteral( "rgb" );
457  break;
458  case QColor::Hsv:
459  map[QStringLiteral( "spec" ) ] = QStringLiteral( "hsv" );
460  break;
461  case QColor::Hsl:
462  map[QStringLiteral( "spec" ) ] = QStringLiteral( "hsl" );
463  break;
464  case QColor::Cmyk:
465  case QColor::Invalid:
466 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
467  case QColor::ExtendedRgb:
468 #endif
469  break;
470  }
471 
472  switch ( mDirection )
473  {
475  map[QStringLiteral( "direction" ) ] = QStringLiteral( "cw" );
476  break;
478  map[QStringLiteral( "direction" ) ] = QStringLiteral( "ccw" );
479  break;
480  }
481 
482  map[QStringLiteral( "rampType" )] = type();
483  return map;
484 }
486 {
487  if ( discrete == mDiscrete )
488  return;
489 
490  // if going to/from Discrete, re-arrange stops
491  // this will only work when stops are equally-spaced
492  QgsGradientStopsList newStops;
493  if ( discrete )
494  {
495  // re-arrange stops offset
496  int numStops = mStops.count() + 2;
497  int i = 1;
498  for ( QgsGradientStopsList::const_iterator it = mStops.constBegin();
499  it != mStops.constEnd(); ++it )
500  {
501  newStops.append( QgsGradientStop( static_cast< double >( i ) / numStops, it->color ) );
502  if ( i == numStops - 1 )
503  break;
504  i++;
505  }
506  // replicate last color
507  newStops.append( QgsGradientStop( static_cast< double >( i ) / numStops, mColor2 ) );
508  }
509  else
510  {
511  // re-arrange stops offset, remove duplicate last color
512  int numStops = mStops.count() + 2;
513  int i = 1;
514  for ( QgsGradientStopsList::const_iterator it = mStops.constBegin();
515  it != mStops.constEnd(); ++it )
516  {
517  newStops.append( QgsGradientStop( static_cast< double >( i ) / ( numStops - 2 ), it->color ) );
518  if ( i == numStops - 3 )
519  break;
520  i++;
521  }
522  }
523  mStops = newStops;
524  mDiscrete = discrete;
525 }
526 
527 bool stopLessThan( const QgsGradientStop &s1, const QgsGradientStop &s2 )
528 {
529  return s1.offset < s2.offset;
530 }
531 
533 {
534  mStops = stops;
535 
536  //sort stops by offset
537  std::sort( mStops.begin(), mStops.end(), stopLessThan );
538 }
539 
540 void QgsGradientColorRamp::addStopsToGradient( QGradient *gradient, double opacity ) const
541 {
542  //copy color ramp stops to a QGradient
543  QColor color1 = mColor1;
544  QColor color2 = mColor2;
545  if ( opacity < 1 )
546  {
547  color1.setAlpha( color1.alpha() * opacity );
548  color2.setAlpha( color2.alpha() * opacity );
549  }
550  gradient->setColorAt( 0, color1 );
551  gradient->setColorAt( 1, color2 );
552 
553  double lastOffset = 0;
554  for ( const QgsGradientStop &stop : mStops )
555  {
556 
557  QColor rampColor = stop.color;
558  if ( opacity < 1 )
559  {
560  rampColor.setAlpha( rampColor.alpha() * opacity );
561  }
562  gradient->setColorAt( stop.offset, rampColor );
563 
564  if ( stop.colorSpec() != QColor::Rgb )
565  {
566  // QGradient only supports RGB interpolation. For other color specs we have
567  // to "fake" things by populating the gradient with additional stops
568  for ( double offset = lastOffset + 0.05; offset < stop.offset; offset += 0.05 )
569  {
570  QColor midColor = color( offset );
571  if ( opacity < 1 )
572  {
573  midColor.setAlpha( midColor.alpha() * opacity );
574  }
575  gradient->setColorAt( offset, midColor );
576  }
577  }
578  lastOffset = stop.offset;
579  }
580 
581  if ( mColorSpec != QColor::Rgb )
582  {
583  for ( double offset = lastOffset + 0.05; offset < 1; offset += 0.05 )
584  {
585  QColor midColor = color( offset );
586  if ( opacity < 1 )
587  {
588  midColor.setAlpha( midColor.alpha() * opacity );
589  }
590  gradient->setColorAt( offset, midColor );
591  }
592  }
593 }
594 
595 void QgsGradientColorRamp::setColorSpec( QColor::Spec spec )
596 {
597  mColorSpec = spec;
598  switch ( mColorSpec )
599  {
600  case QColor::Rgb:
601  case QColor::Invalid:
602 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
603  case QColor::ExtendedRgb:
604 #endif
605  case QColor::Cmyk:
606  mFunc = _interpolateRgb;
607  break;
608  case QColor::Hsv:
609  mFunc = _interpolateHsv;
610  break;
611  case QColor::Hsl:
612  mFunc = _interpolateHsl;
613  break;
614  }
615 }
616 
617 
619 
620 
621 QgsLimitedRandomColorRamp::QgsLimitedRandomColorRamp( int count, int hueMin, int hueMax,
622  int satMin, int satMax, int valMin, int valMax )
623  : mCount( count )
624  , mHueMin( hueMin ), mHueMax( hueMax )
625  , mSatMin( satMin ), mSatMax( satMax )
626  , mValMin( valMin ), mValMax( valMax )
627 {
628  updateColors();
629 }
630 
632 {
637 
638  if ( props.contains( QStringLiteral( "count" ) ) ) count = props[QStringLiteral( "count" )].toInt();
639  if ( props.contains( QStringLiteral( "hueMin" ) ) ) hueMin = props[QStringLiteral( "hueMin" )].toInt();
640  if ( props.contains( QStringLiteral( "hueMax" ) ) ) hueMax = props[QStringLiteral( "hueMax" )].toInt();
641  if ( props.contains( QStringLiteral( "satMin" ) ) ) satMin = props[QStringLiteral( "satMin" )].toInt();
642  if ( props.contains( QStringLiteral( "satMax" ) ) ) satMax = props[QStringLiteral( "satMax" )].toInt();
643  if ( props.contains( QStringLiteral( "valMin" ) ) ) valMin = props[QStringLiteral( "valMin" )].toInt();
644  if ( props.contains( QStringLiteral( "valMax" ) ) ) valMax = props[QStringLiteral( "valMax" )].toInt();
645 
647 }
648 
649 double QgsLimitedRandomColorRamp::value( int index ) const
650 {
651  if ( mColors.empty() )
652  return 0;
653  return static_cast< double >( index ) / ( mColors.size() - 1 );
654 }
655 
656 QColor QgsLimitedRandomColorRamp::color( double value ) const
657 {
658  if ( value < 0 || value > 1 )
659  return QColor();
660 
661  int colorCnt = mColors.count();
662  int colorIdx = std::min( static_cast< int >( value * colorCnt ), colorCnt - 1 );
663 
664  if ( colorIdx >= 0 && colorIdx < colorCnt )
665  return mColors.at( colorIdx );
666 
667  return QColor();
668 }
669 
671 {
673 }
674 
676 {
678 }
679 
681 {
682  QVariantMap map;
683  map[QStringLiteral( "count" )] = QString::number( mCount );
684  map[QStringLiteral( "hueMin" )] = QString::number( mHueMin );
685  map[QStringLiteral( "hueMax" )] = QString::number( mHueMax );
686  map[QStringLiteral( "satMin" )] = QString::number( mSatMin );
687  map[QStringLiteral( "satMax" )] = QString::number( mSatMax );
688  map[QStringLiteral( "valMin" )] = QString::number( mValMin );
689  map[QStringLiteral( "valMax" )] = QString::number( mValMax );
690  map[QStringLiteral( "rampType" )] = type();
691  return map;
692 }
693 
695  int hueMax, int hueMin, int satMax, int satMin, int valMax, int valMin )
696 {
697  int h, s, v;
698  QList<QColor> colors;
699 
700  //normalize values
701  int safeHueMax = std::max( hueMin, hueMax );
702  int safeHueMin = std::min( hueMin, hueMax );
703  int safeSatMax = std::max( satMin, satMax );
704  int safeSatMin = std::min( satMin, satMax );
705  int safeValMax = std::max( valMin, valMax );
706  int safeValMin = std::min( valMin, valMax );
707 
708  //start hue at random angle
709  double currentHueAngle = 360.0 * static_cast< double >( std::rand() ) / RAND_MAX;
710 
711  colors.reserve( count );
712  for ( int i = 0; i < count; ++i )
713  {
714  //increment hue by golden ratio (approx 137.507 degrees)
715  //as this minimizes hue nearness as count increases
716  //see http://basecase.org/env/on-rainbows for more details
717  currentHueAngle += 137.50776;
718  //scale hue to between hueMax and hueMin
719  h = std::clamp( std::round( ( std::fmod( currentHueAngle, 360.0 ) / 360.0 ) * ( safeHueMax - safeHueMin ) + safeHueMin ), 0.0, 359.0 );
720  s = std::clamp( ( static_cast<int>( std::rand() ) % ( safeSatMax - safeSatMin + 1 ) ) + safeSatMin, 0, 255 );
721  v = std::clamp( ( static_cast<int>( std::rand() ) % ( safeValMax - safeValMin + 1 ) ) + safeValMin, 0, 255 );
722  colors.append( QColor::fromHsv( h, s, v ) );
723  }
724  return colors;
725 }
726 
728 {
730 }
731 
733 
735 {
736  return -1;
737 }
738 
739 double QgsRandomColorRamp::value( int index ) const
740 {
741  Q_UNUSED( index )
742  return 0.0;
743 }
744 
745 QColor QgsRandomColorRamp::color( double value ) const
746 {
747  int minVal = 130;
748  int maxVal = 255;
749 
750  //if value is nan, then use last precalculated color
751  if ( std::isnan( value ) )
752  {
753  value = 1.0;
754  }
755  // Caller has converted an index into a value in [0.0, 1.0]
756  // by doing "index / (mTotalColorCount - 1)"; retrieve the original index.
757  int colorIndex = std::round( value * ( mTotalColorCount - 1 ) );
758  if ( mTotalColorCount >= 1 && mPrecalculatedColors.length() > colorIndex )
759  {
760  //use precalculated hue
761  return mPrecalculatedColors.at( colorIndex );
762  }
763 
764  //can't use precalculated hues, use a totally random hue
765  int h = static_cast< int >( 360.0 * std::rand() / ( RAND_MAX + 1.0 ) );
766  int s = ( std::rand() % ( DEFAULT_RANDOM_SAT_MAX - DEFAULT_RANDOM_SAT_MIN + 1 ) ) + DEFAULT_RANDOM_SAT_MIN;
767  int v = ( std::rand() % ( maxVal - minVal + 1 ) ) + minVal;
768  return QColor::fromHsv( h, s, v );
769 }
770 
771 void QgsRandomColorRamp::setTotalColorCount( const int colorCount )
772 {
773  //calculate colors in advance, so that we can ensure they are more visually distinct than pure random colors
774  mPrecalculatedColors.clear();
775  mTotalColorCount = colorCount;
776 
777  //This works OK for low color counts, but for > 10 or so colors there's still a good chance of
778  //similar colors being picked. TODO - investigate alternative "n-visually distinct color" routines
779 
780  //random offsets
781  double hueOffset = ( 360.0 * std::rand() / ( RAND_MAX + 1.0 ) );
782 
783  //try to maximise difference between hues. this is not an ideal implementation, as constant steps
784  //through the hue wheel are not visually perceived as constant changes in hue
785  //(for instance, we are much more likely to get green hues than yellow hues)
786  double hueStep = 359.0 / colorCount;
787  double currentHue = hueOffset;
788 
789  //build up a list of colors
790  for ( int idx = 0; idx < colorCount; ++ idx )
791  {
792  int h = static_cast< int >( std::round( currentHue ) ) % 360;
793  int s = ( std::rand() % ( DEFAULT_RANDOM_SAT_MAX - DEFAULT_RANDOM_SAT_MIN + 1 ) ) + DEFAULT_RANDOM_SAT_MIN;
794  int v = ( std::rand() % ( DEFAULT_RANDOM_VAL_MAX - DEFAULT_RANDOM_VAL_MIN + 1 ) ) + DEFAULT_RANDOM_VAL_MIN;
795  mPrecalculatedColors << QColor::fromHsv( h, s, v );
796  currentHue += hueStep;
797  }
798 
799  //lastly, shuffle color list
800  std::random_device rd;
801  std::mt19937 g( rd() );
802  std::shuffle( mPrecalculatedColors.begin(), mPrecalculatedColors.end(), g );
803 }
804 
806 {
808 }
809 
811 {
812  return new QgsRandomColorRamp();
813 }
814 
816 {
817  return QVariantMap();
818 }
819 
821 
822 QgsColorBrewerColorRamp::QgsColorBrewerColorRamp( const QString &schemeName, int colors, bool inverted )
823  : mSchemeName( schemeName )
824  , mColors( colors )
825  , mInverted( inverted )
826 {
827  loadPalette();
828 }
829 
830 QgsColorRamp *QgsColorBrewerColorRamp::create( const QVariantMap &props )
831 {
834  bool inverted = false;
835 
836  if ( props.contains( QStringLiteral( "schemeName" ) ) )
837  schemeName = props[QStringLiteral( "schemeName" )].toString();
838  if ( props.contains( QStringLiteral( "colors" ) ) )
839  colors = props[QStringLiteral( "colors" )].toInt();
840  if ( props.contains( QStringLiteral( "inverted" ) ) )
841  inverted = props[QStringLiteral( "inverted" )].toInt();
842 
843  return new QgsColorBrewerColorRamp( schemeName, colors, inverted );
844 }
845 
847 {
849 
850  if ( mInverted )
851  {
852  QList<QColor> tmpPalette;
853 
854  for ( int k = mPalette.size() - 1; k >= 0; k-- )
855  {
856  tmpPalette << mPalette.at( k );
857  }
858  mPalette = tmpPalette;
859  }
860 }
861 
863 {
865 }
866 
867 QList<int> QgsColorBrewerColorRamp::listSchemeVariants( const QString &schemeName )
868 {
870 }
871 
872 double QgsColorBrewerColorRamp::value( int index ) const
873 {
874  if ( mPalette.empty() )
875  return 0;
876  return static_cast< double >( index ) / ( mPalette.size() - 1 );
877 }
878 
879 QColor QgsColorBrewerColorRamp::color( double value ) const
880 {
881  if ( mPalette.isEmpty() || value < 0 || value > 1 || std::isnan( value ) )
882  return QColor();
883 
884  int paletteEntry = static_cast< int >( value * mPalette.count() );
885  if ( paletteEntry >= mPalette.count() )
886  paletteEntry = mPalette.count() - 1;
887  return mPalette.at( paletteEntry );
888 }
889 
891 {
892  mInverted = !mInverted;
893  loadPalette();
894 }
895 
897 {
899 }
900 
902 {
903  QVariantMap map;
904  map[QStringLiteral( "schemeName" )] = mSchemeName;
905  map[QStringLiteral( "colors" )] = QString::number( mColors );
906  map[QStringLiteral( "inverted" )] = QString::number( mInverted );
907  map[QStringLiteral( "rampType" )] = type();
908  return map;
909 }
910 
911 
913 
914 
915 QgsCptCityColorRamp::QgsCptCityColorRamp( const QString &schemeName, const QString &variantName,
916  bool inverted, bool doLoadFile )
918  , mSchemeName( schemeName )
919  , mVariantName( variantName )
920  , mInverted( inverted )
921 {
922  // TODO replace this with hard-coded data in the default case
923  // don't load file if variant is missing
924  if ( doLoadFile && ( variantName != QString() || mVariantList.isEmpty() ) )
925  loadFile();
926 }
927 
928 QgsCptCityColorRamp::QgsCptCityColorRamp( const QString &schemeName, const QStringList &variantList,
929  const QString &variantName, bool inverted, bool doLoadFile )
931  , mSchemeName( schemeName )
932  , mVariantName( variantName )
933  , mVariantList( variantList )
934  , mInverted( inverted )
935 {
937 
938  // TODO replace this with hard-coded data in the default case
939  // don't load file if variant is missing
940  if ( doLoadFile && ( variantName != QString() || mVariantList.isEmpty() ) )
941  loadFile();
942 }
943 
944 QgsColorRamp *QgsCptCityColorRamp::create( const QVariantMap &props )
945 {
948  bool inverted = false;
949 
950  if ( props.contains( QStringLiteral( "schemeName" ) ) )
951  schemeName = props[QStringLiteral( "schemeName" )].toString();
952  if ( props.contains( QStringLiteral( "variantName" ) ) )
953  variantName = props[QStringLiteral( "variantName" )].toString();
954  if ( props.contains( QStringLiteral( "inverted" ) ) )
955  inverted = props[QStringLiteral( "inverted" )].toInt();
956 
957  return new QgsCptCityColorRamp( schemeName, variantName, inverted );
958 }
959 
961 {
963 }
964 
966 {
967  mInverted = !mInverted;
969 }
970 
972 {
973  QgsCptCityColorRamp *ramp = new QgsCptCityColorRamp( QString(), QString(), mInverted, false );
974  ramp->copy( this );
975  return ramp;
976 }
977 
979 {
980  if ( ! other )
981  return;
982  mColor1 = other->color1();
983  mColor2 = other->color2();
984  mDiscrete = other->isDiscrete();
985  mStops = other->stops();
986  mSchemeName = other->mSchemeName;
987  mVariantName = other->mVariantName;
988  mVariantList = other->mVariantList;
989  mFileLoaded = other->mFileLoaded;
990  mInverted = other->mInverted;
991 }
992 
994 {
995  QgsGradientColorRamp *ramp =
997  // add author and copyright information
998  // TODO also add COPYING.xml file/link?
1000  info[QStringLiteral( "cpt-city-gradient" )] = "<cpt-city>/" + mSchemeName + mVariantName + ".svg";
1001  QString copyingFilename = copyingFileName();
1002  copyingFilename.remove( QgsCptCityArchive::defaultBaseDir() );
1003  info[QStringLiteral( "cpt-city-license" )] = "<cpt-city>" + copyingFilename;
1004  ramp->setInfo( info );
1005  return ramp;
1006 }
1007 
1008 
1010 {
1011  QVariantMap map;
1012  map[QStringLiteral( "schemeName" )] = mSchemeName;
1013  map[QStringLiteral( "variantName" )] = mVariantName;
1014  map[QStringLiteral( "inverted" )] = QString::number( mInverted );
1015  map[QStringLiteral( "rampType" )] = type();
1016  return map;
1017 }
1018 
1019 QString QgsCptCityColorRamp::fileNameForVariant( const QString &schema, const QString &variant )
1020 {
1021  return QgsCptCityArchive::defaultBaseDir() + QDir::separator() + schema + variant + ".svg";
1022 }
1023 
1025 {
1026  if ( mSchemeName.isEmpty() )
1027  return QString();
1028  else
1029  {
1030  return QgsCptCityArchive::defaultBaseDir() + QDir::separator() + mSchemeName + mVariantName + ".svg";
1031  }
1032 }
1033 
1035 {
1036  return QgsCptCityArchive::findFileName( QStringLiteral( "COPYING.xml" ), QFileInfo( fileName() ).dir().path(),
1038 }
1039 
1041 {
1042  return QgsCptCityArchive::findFileName( QStringLiteral( "DESC.xml" ), QFileInfo( fileName() ).dir().path(),
1044 }
1045 
1047 {
1049 }
1050 
1052 {
1053  if ( mFileLoaded )
1054  {
1055  QgsDebugMsgLevel( "File already loaded for " + mSchemeName + mVariantName, 2 );
1056  return true;
1057  }
1058 
1059  // get filename
1060  QString filename = fileName();
1061  if ( filename.isNull() )
1062  {
1063  return false;
1064  }
1065 
1066  QgsDebugMsgLevel( QStringLiteral( "filename= %1 loaded=%2" ).arg( filename ).arg( mFileLoaded ), 2 );
1067 
1068  // get color ramp from svg file
1069  QMap< double, QPair<QColor, QColor> > colorMap =
1071 
1072  // add colors to palette
1073  mFileLoaded = false;
1074  mStops.clear();
1075  QMap<double, QPair<QColor, QColor> >::const_iterator it, prev;
1076  // first detect if file is gradient is continuous or discrete
1077  // discrete: stop contains 2 colors and first color is identical to previous second
1078  // multi: stop contains 2 colors and no relation with previous stop
1079  mDiscrete = false;
1080  mMultiStops = false;
1081  it = prev = colorMap.constBegin();
1082  while ( it != colorMap.constEnd() )
1083  {
1084  // look for stops that contain multiple values
1085  if ( it != colorMap.constBegin() && ( it.value().first != it.value().second ) )
1086  {
1087  if ( it.value().first == prev.value().second )
1088  {
1089  mDiscrete = true;
1090  break;
1091  }
1092  else
1093  {
1094  mMultiStops = true;
1095  break;
1096  }
1097  }
1098  prev = it;
1099  ++it;
1100  }
1101 
1102  // fill all stops
1103  it = prev = colorMap.constBegin();
1104  while ( it != colorMap.constEnd() )
1105  {
1106  if ( mDiscrete )
1107  {
1108  // mPalette << qMakePair( it.key(), it.value().second );
1109  mStops.append( QgsGradientStop( it.key(), it.value().second ) );
1110  }
1111  else
1112  {
1113  // mPalette << qMakePair( it.key(), it.value().first );
1114  mStops.append( QgsGradientStop( it.key(), it.value().first ) );
1115  if ( ( mMultiStops ) &&
1116  ( it.key() != 0.0 && it.key() != 1.0 ) )
1117  {
1118  mStops.append( QgsGradientStop( it.key(), it.value().second ) );
1119  }
1120  }
1121  prev = it;
1122  ++it;
1123  }
1124 
1125  // remove first and last items (mColor1 and mColor2)
1126  if ( ! mStops.isEmpty() && mStops.at( 0 ).offset == 0.0 )
1127  mColor1 = mStops.takeFirst().color;
1128  if ( ! mStops.isEmpty() && mStops.last().offset == 1.0 )
1129  mColor2 = mStops.takeLast().color;
1130 
1131  if ( mInverted )
1132  {
1134  }
1135 
1136  mFileLoaded = true;
1137  return true;
1138 }
1139 
1140 
1141 //
1142 // QgsPresetColorRamp
1143 //
1144 
1146 {
1147  const auto constColors = colors;
1148  for ( const QColor &color : constColors )
1149  {
1150  mColors << qMakePair( color, color.name() );
1151  }
1152  // need at least one color
1153  if ( mColors.isEmpty() )
1154  mColors << qMakePair( QColor( 250, 75, 60 ), QStringLiteral( "#fa4b3c" ) );
1155 }
1156 
1158  : mColors( colors )
1159 {
1160  // need at least one color
1161  if ( mColors.isEmpty() )
1162  mColors << qMakePair( QColor( 250, 75, 60 ), QStringLiteral( "#fa4b3c" ) );
1163 }
1164 
1165 QgsColorRamp *QgsPresetSchemeColorRamp::create( const QVariantMap &properties )
1166 {
1168 
1169  int i = 0;
1170  QString colorString = properties.value( QStringLiteral( "preset_color_%1" ).arg( i ), QString() ).toString();
1171  QString colorName = properties.value( QStringLiteral( "preset_color_name_%1" ).arg( i ), QString() ).toString();
1172  while ( !colorString.isEmpty() )
1173  {
1174  colors << qMakePair( QgsSymbolLayerUtils::decodeColor( colorString ), colorName );
1175  i++;
1176  colorString = properties.value( QStringLiteral( "preset_color_%1" ).arg( i ), QString() ).toString();
1177  colorName = properties.value( QStringLiteral( "preset_color_name_%1" ).arg( i ), QString() ).toString();
1178  }
1179 
1180  return new QgsPresetSchemeColorRamp( colors );
1181 }
1182 
1184 {
1185  QList< QColor > l;
1186  l.reserve( mColors.count() );
1187  for ( int i = 0; i < mColors.count(); ++i )
1188  {
1189  l << mColors.at( i ).first;
1190  }
1191  return l;
1192 }
1193 
1194 double QgsPresetSchemeColorRamp::value( int index ) const
1195 {
1196  if ( mColors.empty() )
1197  return 0;
1198  return static_cast< double >( index ) / ( mColors.size() - 1 );
1199 }
1200 
1201 QColor QgsPresetSchemeColorRamp::color( double value ) const
1202 {
1203  if ( value < 0 || value > 1 )
1204  return QColor();
1205 
1206  int colorCnt = mColors.count();
1207  int colorIdx = std::min( static_cast< int >( value * colorCnt ), colorCnt - 1 );
1208 
1209  if ( colorIdx >= 0 && colorIdx < colorCnt )
1210  return mColors.at( colorIdx ).first;
1211 
1212  return QColor();
1213 }
1214 
1216 {
1218 }
1219 
1221 {
1222  QgsNamedColorList tmpColors;
1223 
1224  for ( int k = mColors.size() - 1; k >= 0; k-- )
1225  {
1226  tmpColors << mColors.at( k );
1227  }
1228  mColors = tmpColors;
1229 }
1230 
1232 {
1233  return new QgsPresetSchemeColorRamp( *this );
1234 }
1235 
1237 {
1238  QVariantMap props;
1239  for ( int i = 0; i < mColors.count(); ++i )
1240  {
1241  props.insert( QStringLiteral( "preset_color_%1" ).arg( i ), QgsSymbolLayerUtils::encodeColor( mColors.at( i ).first ) );
1242  props.insert( QStringLiteral( "preset_color_name_%1" ).arg( i ), mColors.at( i ).second );
1243  }
1244  props[QStringLiteral( "rampType" )] = type();
1245  return props;
1246 }
1247 
1249 {
1250  return mColors.count();
1251 }
1252 
1254 {
1255  return mColors;
1256 }
DEFAULT_COLORBREWER_SCHEMENAME
#define DEFAULT_COLORBREWER_SCHEMENAME
Definition: qgscolorrampimpl.h:606
QgsGradientStop::QgsGradientStop
QgsGradientStop(double offset, const QColor &color)
Constructor for QgsGradientStop.
Definition: qgscolorrampimpl.cpp:175
QgsColorBrewerColorRamp::listSchemeVariants
static QList< int > listSchemeVariants(const QString &schemeName)
Returns a list of the valid variants (numbers of colors) for a specified color brewer scheme name.
Definition: qgscolorrampimpl.cpp:867
QgsColorRamp
Abstract base class for color ramps.
Definition: qgscolorramp.h:29
QgsColorBrewerColorRamp::value
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
Definition: qgscolorrampimpl.cpp:872
qgscolorrampimpl.h
QgsRandomColorRamp::mPrecalculatedColors
QList< QColor > mPrecalculatedColors
Definition: qgscolorrampimpl.h:532
QgsPresetSchemeColorRamp::clone
QgsPresetSchemeColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:1231
QgsGradientColorRamp::color1
QColor color1() const
Returns the gradient start color.
Definition: qgscolorrampimpl.h:177
QgsColorBrewerPalette::listSchemeVariants
static QList< int > listSchemeVariants(const QString &schemeName)
Definition: qgscolorbrewerpalette.cpp:331
QgsSymbolLayerUtils::encodeColor
static QString encodeColor(const QColor &color)
Definition: qgssymbollayerutils.cpp:64
QgsCptCityColorRamp::mInverted
bool mInverted
Definition: qgscolorrampimpl.h:798
QgsGradientColorRamp
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Definition: qgscolorrampimpl.h:136
QgsColorBrewerColorRamp::clone
QgsColorBrewerColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:896
QgsLimitedRandomColorRamp::mSatMax
int mSatMax
Definition: qgscolorrampimpl.h:479
QgsGradientColorRamp::value
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
Definition: qgscolorrampimpl.cpp:300
QgsCptCityColorRamp::QgsCptCityColorRamp
QgsCptCityColorRamp(const QString &schemeName=DEFAULT_CPTCITY_SCHEMENAME, const QString &variantName=DEFAULT_CPTCITY_VARIANTNAME, bool inverted=false, bool doLoadFile=true)
Constructor for QgsCptCityColorRamp.
Definition: qgscolorrampimpl.cpp:915
QgsLimitedRandomColorRamp::hueMin
int hueMin() const
Returns the minimum hue for generated colors.
Definition: qgscolorrampimpl.h:401
QgsCptCityColorRamp::copyingFileName
QString copyingFileName() const
Definition: qgscolorrampimpl.cpp:1034
QgsCptCityArchive::findFileName
static QString findFileName(const QString &target, const QString &startDir, const QString &baseDir)
Definition: qgscptcityarchive.cpp:146
QgsRandomColorRamp::color
QColor color(double value) const override
Returns the color corresponding to a specified value.
Definition: qgscolorrampimpl.cpp:745
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
DEFAULT_GRADIENT_COLOR2
#define DEFAULT_GRADIENT_COLOR2
Definition: qgscolorrampimpl.h:127
QgsPresetSchemeColorRamp::count
int count() const override
Returns number of defined colors, or -1 if undefined.
Definition: qgscolorrampimpl.cpp:1248
QgsLimitedRandomColorRamp::mCount
int mCount
Definition: qgscolorrampimpl.h:475
QgsLimitedRandomColorRamp::mSatMin
int mSatMin
Definition: qgscolorrampimpl.h:478
QgsGradientColorRamp::setInfo
void setInfo(const QgsStringMap &info)
Sets additional info to attach to the gradient ramp (e.g., authorship notes)
Definition: qgscolorrampimpl.h:253
QgsPresetSchemeColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.cpp:1215
DEFAULT_RANDOM_VAL_MAX
#define DEFAULT_RANDOM_VAL_MAX
Definition: qgscolorrampimpl.h:330
QgsPresetSchemeColorRamp
A scheme based color ramp consisting of a list of predefined colors.
Definition: qgscolorrampimpl.h:543
qgssymbollayerutils.h
QgsPresetSchemeColorRamp::fetchColors
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
Definition: qgscolorrampimpl.cpp:1253
QgsNamedColorList
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
Definition: qgscolorscheme.h:34
QgsRandomColorRamp::count
int count() const override
Returns number of defined colors, or -1 if undefined.
Definition: qgscolorrampimpl.cpp:734
QgsGradientColorRamp::clone
QgsGradientColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:415
QgsColorBrewerColorRamp::mInverted
bool mInverted
Definition: qgscolorrampimpl.h:703
QgsCptCityArchive::defaultBaseDir
static QString defaultBaseDir()
Definition: qgscptcityarchive.cpp:131
QgsGradientColorRamp::setStops
void setStops(const QgsGradientStopsList &stops)
Sets the list of intermediate gradient stops for the ramp.
Definition: qgscolorrampimpl.cpp:532
QgsLimitedRandomColorRamp::create
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Returns a new QgsLimitedRandomColorRamp color ramp created using the properties encoded in a string m...
Definition: qgscolorrampimpl.cpp:631
QgsCptCityColorRamp::variantName
QString variantName() const
Definition: qgscolorrampimpl.h:763
QgsCptCityColorRamp::variantList
QStringList variantList() const
Definition: qgscolorrampimpl.h:764
MathUtils::lower
int ANALYSIS_EXPORT lower(int n, int i)
Lower function.
Definition: MathUtils.cpp:407
QgsCptCityColorRamp::mMultiStops
bool mMultiStops
Definition: qgscolorrampimpl.h:797
QgsRandomColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:815
QgsCptCityColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:1009
qgscptcityarchive.h
QgsGradientColorRamp::invert
void invert() override
Inverts the ordering of the color ramp.
Definition: qgscolorrampimpl.cpp:367
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:69
QgsRandomColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.cpp:805
DEFAULT_COLORBREWER_COLORS
#define DEFAULT_COLORBREWER_COLORS
Definition: qgscolorrampimpl.h:607
QgsPresetSchemeColorRamp::invert
void invert() override
Inverts the ordering of the color ramp.
Definition: qgscolorrampimpl.cpp:1220
QgsLimitedRandomColorRamp
Constrained random color ramp, which returns random colors based on preset parameters.
Definition: qgscolorrampimpl.h:340
QgsLimitedRandomColorRamp::satMax
int satMax() const
Returns the maximum saturation for generated colors.
Definition: qgscolorrampimpl.h:419
QgsLimitedRandomColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:680
QgsColorBrewerColorRamp
Color ramp utilising "Color Brewer" preset color schemes.
Definition: qgscolorrampimpl.h:615
DEFAULT_GRADIENT_COLOR1
#define DEFAULT_GRADIENT_COLOR1
Definition: qgscolorrampimpl.h:126
QgsCptCityColorRamp::cloneGradientRamp
QgsGradientColorRamp * cloneGradientRamp() const
Definition: qgscolorrampimpl.cpp:993
QgsGradientColorRamp::mColor2
QColor mColor2
Definition: qgscolorrampimpl.h:314
QgsPresetSchemeColorRamp::color
QColor color(double value) const override
Returns the color corresponding to a specified value.
Definition: qgscolorrampimpl.cpp:1201
QgsGradientColorRamp::convertToDiscrete
void convertToDiscrete(bool discrete)
Converts a gradient with existing color stops to or from discrete interpolation.
Definition: qgscolorrampimpl.cpp:485
DEFAULT_RANDOM_SAT_MIN
#define DEFAULT_RANDOM_SAT_MIN
Definition: qgscolorrampimpl.h:331
QgsRandomColorRamp
Totally random color ramp. Returns colors generated at random, but constrained to some hardcoded satu...
Definition: qgscolorrampimpl.h:492
QgsGradientColorRamp::stops
QgsGradientStopsList stops() const
Returns the list of intermediate gradient stops for the ramp.
Definition: qgscolorrampimpl.h:240
qgsapplication.h
QgsCptCityColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
Definition: qgscolorrampimpl.h:750
QgsLimitedRandomColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.cpp:670
QgsGradientColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
Definition: qgscolorrampimpl.h:165
QgsCptCityColorRamp::mSchemeName
QString mSchemeName
Definition: qgscolorrampimpl.h:793
QgsPresetSchemeColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsPresetSchemeColorRamp.
Definition: qgscolorrampimpl.h:588
QgsLimitedRandomColorRamp::updateColors
void updateColors()
Must be called after changing the properties of the color ramp to regenerate the list of random color...
Definition: qgscolorrampimpl.cpp:727
QgsCptCityColorRamp::invert
void invert() override
Inverts the ordering of the color ramp.
Definition: qgscolorrampimpl.cpp:965
QgsPresetSchemeColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:1236
QgsLimitedRandomColorRamp::clone
QgsLimitedRandomColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:675
QgsCptCityColorRamp::copyingInfo
QgsStringMap copyingInfo() const
Definition: qgscolorrampimpl.cpp:1046
DEFAULT_CPTCITY_SCHEMENAME
#define DEFAULT_CPTCITY_SCHEMENAME
Definition: qgscolorrampimpl.h:707
qgscolorbrewerpalette.h
QgsLimitedRandomColorRamp::valMax
int valMax() const
Returns the maximum value for generated colors.
Definition: qgscolorrampimpl.h:431
QgsGradientColorRamp::mFunc
InterpolateColorFunc mFunc
Definition: qgscolorrampimpl.h:321
QgsGradientColorRamp::create
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
Definition: qgscolorrampimpl.cpp:216
QgsGradientColorRamp::color2
QColor color2() const
Returns the gradient end color.
Definition: qgscolorrampimpl.h:184
QgsGradientColorRamp::setColorSpec
void setColorSpec(QColor::Spec spec)
Sets the color specification in which the color component interpolation will occur.
Definition: qgscolorrampimpl.cpp:595
QgsLimitedRandomColorRamp::satMin
int satMin() const
Returns the minimum saturation for generated colors.
Definition: qgscolorrampimpl.h:413
QgsRandomColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsRandomColorRamp.
Definition: qgscolorrampimpl.h:521
QgsColorBrewerColorRamp::colors
int colors() const
Returns the number of colors in the ramp.
Definition: qgscolorrampimpl.h:663
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsRandomColorRamp::setTotalColorCount
virtual void setTotalColorCount(int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
Definition: qgscolorrampimpl.cpp:771
QgsCptCityColorRamp::schemeName
QString schemeName() const
Definition: qgscolorrampimpl.h:762
stopLessThan
bool stopLessThan(const QgsGradientStop &s1, const QgsGradientStop &s2)
Definition: qgscolorrampimpl.cpp:527
QgsCptCityColorRamp::fileNameForVariant
static QString fileNameForVariant(const QString &schema, const QString &variant)
Returns the source file name for a CPT schema and variant.
Definition: qgscolorrampimpl.cpp:1019
QgsCptCityColorRamp::clone
QgsCptCityColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:971
QgsGradientColorRamp::mColor1
QColor mColor1
Definition: qgscolorrampimpl.h:313
QgsPresetSchemeColorRamp::create
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Returns a new QgsPresetSchemeColorRamp color ramp created using the properties encoded in a string ma...
Definition: qgscolorrampimpl.cpp:1165
QgsColorBrewerColorRamp::schemeName
QString schemeName() const
Returns the name of the color brewer color scheme.
Definition: qgscolorrampimpl.h:657
QgsColorBrewerColorRamp::mSchemeName
QString mSchemeName
Definition: qgscolorrampimpl.h:700
QgsGradientColorRamp::direction
Qgis::AngularDirection direction() const
Returns the direction to traverse the color wheel using when interpolating hue-based color specificat...
Definition: qgscolorrampimpl.h:298
QgsGradientColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.cpp:362
QgsCptCityColorRamp::mFileLoaded
bool mFileLoaded
Definition: qgscolorrampimpl.h:796
Qgis::AngularDirection::CounterClockwise
@ CounterClockwise
Counter-clockwise direction.
QgsGradientColorRamp::QgsGradientColorRamp
QgsGradientColorRamp(const QColor &color1=DEFAULT_GRADIENT_COLOR1, const QColor &color2=DEFAULT_GRADIENT_COLOR2, bool discrete=false, const QgsGradientStopsList &stops=QgsGradientStopsList())
Constructor for QgsGradientColorRamp.
Definition: qgscolorrampimpl.cpp:206
QgsGradientColorRamp::mColorSpec
QColor::Spec mColorSpec
Definition: qgscolorrampimpl.h:318
QgsRandomColorRamp::clone
QgsRandomColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorrampimpl.cpp:810
QgsColorBrewerColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.h:647
QgsCptCityColorRamp::descFileName
QString descFileName() const
Definition: qgscolorrampimpl.cpp:1040
QgsCptCityArchive::copyingInfo
static QMap< QString, QString > copyingInfo(const QString &fileName)
Definition: qgscptcityarchive.cpp:179
QgsLimitedRandomColorRamp::randomColors
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)
Gets a list of random colors.
Definition: qgscolorrampimpl.cpp:694
QgsGradientColorRamp::mDirection
Qgis::AngularDirection mDirection
Definition: qgscolorrampimpl.h:319
QgsColorBrewerColorRamp::invert
void invert() override
Inverts the ordering of the color ramp.
Definition: qgscolorrampimpl.cpp:890
QgsLimitedRandomColorRamp::value
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
Definition: qgscolorrampimpl.cpp:649
QgsGradientStop::setColorSpec
void setColorSpec(QColor::Spec spec)
Sets the color specification in which the color component interpolation will occur.
Definition: qgscolorrampimpl.cpp:183
QgsCptCityColorRamp::create
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
Definition: qgscolorrampimpl.cpp:944
DEFAULT_CPTCITY_VARIANTNAME
#define DEFAULT_CPTCITY_VARIANTNAME
Definition: qgscolorrampimpl.h:708
QgsGradientColorRamp::setDirection
void setDirection(Qgis::AngularDirection direction)
Sets the direction to traverse the color wheel using when interpolating hue-based color specification...
Definition: qgscolorrampimpl.h:310
DEFAULT_RANDOM_SAT_MAX
#define DEFAULT_RANDOM_SAT_MAX
Definition: qgscolorrampimpl.h:332
QgsLimitedRandomColorRamp::mColors
QList< QColor > mColors
Definition: qgscolorrampimpl.h:482
QgsColorBrewerColorRamp::listSchemeNames
static QStringList listSchemeNames()
Returns a list of all valid color brewer scheme names.
Definition: qgscolorrampimpl.cpp:862
QgsGradientStopsList
QList< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
Definition: qgscolorrampimpl.h:122
Qgis::AngularDirection::Clockwise
@ Clockwise
Clockwise direction.
QgsCptCityColorRamp::type
QString type() const override
Returns a string representing the color ramp type.
Definition: qgscolorrampimpl.cpp:960
QgsColorBrewerColorRamp::mPalette
QList< QColor > mPalette
Definition: qgscolorrampimpl.h:702
QgsRandomColorRamp::QgsRandomColorRamp
QgsRandomColorRamp()=default
Constructor for QgsRandomColorRamp.
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:2781
QgsGradientColorRamp::addStopsToGradient
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
Definition: qgscolorrampimpl.cpp:540
QgsRandomColorRamp::mTotalColorCount
int mTotalColorCount
Definition: qgscolorrampimpl.h:531
QgsCptCityColorRamp::copy
void copy(const QgsCptCityColorRamp *other)
Definition: qgscolorrampimpl.cpp:978
QgsCptCityColorRamp::mVariantName
QString mVariantName
Definition: qgscolorrampimpl.h:794
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsColorBrewerPalette::listSchemeColors
static QList< QColor > listSchemeColors(const QString &schemeName, int colors)
Definition: qgscolorbrewerpalette.cpp:295
QgsLimitedRandomColorRamp::hueMax
int hueMax() const
Returns the maximum hue for generated colors.
Definition: qgscolorrampimpl.h:407
QgsLimitedRandomColorRamp::mHueMin
int mHueMin
Definition: qgscolorrampimpl.h:476
QgsGradientColorRamp::color
QColor color(double value) const override
Returns the color corresponding to a specified value.
Definition: qgscolorrampimpl.cpp:316
QgsGradientColorRamp::mInfo
QgsStringMap mInfo
Definition: qgscolorrampimpl.h:317
QgsLimitedRandomColorRamp::mValMin
int mValMin
Definition: qgscolorrampimpl.h:480
DEFAULT_RANDOM_HUE_MAX
#define DEFAULT_RANDOM_HUE_MAX
Definition: qgscolorrampimpl.h:328
QgsRandomColorRamp::value
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
Definition: qgscolorrampimpl.cpp:739
QgsGradientColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:425
QgsCptCityColorRamp::mVariantList
QStringList mVariantList
Definition: qgscolorrampimpl.h:795
QgsGradientColorRamp::mDiscrete
bool mDiscrete
Definition: qgscolorrampimpl.h:315
QgsColorBrewerColorRamp::QgsColorBrewerColorRamp
QgsColorBrewerColorRamp(const QString &schemeName=DEFAULT_COLORBREWER_SCHEMENAME, int colors=DEFAULT_COLORBREWER_COLORS, bool inverted=false)
Constructor for QgsColorBrewerColorRamp.
Definition: qgscolorrampimpl.cpp:822
DEFAULT_RANDOM_VAL_MIN
#define DEFAULT_RANDOM_VAL_MIN
Definition: qgscolorrampimpl.h:329
DEFAULT_RANDOM_COUNT
#define DEFAULT_RANDOM_COUNT
Definition: qgscolorrampimpl.h:326
QgsCptCityColorRamp
Definition: qgscolorrampimpl.h:714
QgsGradientColorRamp::mStops
QgsGradientStopsList mStops
Definition: qgscolorrampimpl.h:316
qgslogger.h
QgsColorBrewerPalette::listSchemes
static QStringList listSchemes()
Definition: qgscolorbrewerpalette.cpp:314
QgsColorBrewerColorRamp::create
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Returns a new QgsColorBrewerColorRamp color ramp created using the properties encoded in a string map...
Definition: qgscolorrampimpl.cpp:830
DEFAULT_RANDOM_HUE_MIN
#define DEFAULT_RANDOM_HUE_MIN
Definition: qgscolorrampimpl.h:327
QgsCptCityArchive::gradientColorMap
static QMap< double, QPair< QColor, QColor > > gradientColorMap(const QString &fileName)
Definition: qgscptcityarchive.cpp:329
QgsColorBrewerColorRamp::properties
QVariantMap properties() const override
Returns a string map containing all the color ramp's properties.
Definition: qgscolorrampimpl.cpp:901
QgsPresetSchemeColorRamp::QgsPresetSchemeColorRamp
QgsPresetSchemeColorRamp(const QList< QColor > &colors=QList< QColor >())
Constructor for QgsPresetSchemeColorRamp.
Definition: qgscolorrampimpl.cpp:1145
QgsPresetSchemeColorRamp::colors
QList< QColor > colors() const
Returns the list of colors used by the ramp.
Definition: qgscolorrampimpl.cpp:1183
QgsColorBrewerColorRamp::loadPalette
void loadPalette()
Generates the scheme using the current name and number of colors.
Definition: qgscolorrampimpl.cpp:846
QgsColorBrewerColorRamp::mColors
int mColors
Definition: qgscolorrampimpl.h:701
QgsLimitedRandomColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsLimitedRandomColorRamp.
Definition: qgscolorrampimpl.h:375
QgsGradientStop
Represents a color stop within a QgsGradientColorRamp color ramp.
Definition: qgscolorrampimpl.h:38
QgsGradientColorRamp::isDiscrete
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
Definition: qgscolorrampimpl.h:207
QgsLimitedRandomColorRamp::valMin
int valMin() const
Returns the minimum value for generated colors.
Definition: qgscolorrampimpl.h:425
QgsGradientStop::offset
double offset
Relative positional offset, between 0 and 1.
Definition: qgscolorrampimpl.h:50
QgsGradientColorRamp::info
QgsStringMap info() const
Returns any additional info attached to the gradient ramp (e.g., authorship notes)
Definition: qgscolorrampimpl.h:246
QgsLimitedRandomColorRamp::mHueMax
int mHueMax
Definition: qgscolorrampimpl.h:477
QgsLimitedRandomColorRamp::color
QColor color(double value) const override
Returns the color corresponding to a specified value.
Definition: qgscolorrampimpl.cpp:656
QgsCptCityColorRamp::loadFile
bool loadFile()
Definition: qgscolorrampimpl.cpp:1051
Qgis::AngularDirection
AngularDirection
Angular directions.
Definition: qgis.h:1635
QgsLimitedRandomColorRamp::mValMax
int mValMax
Definition: qgscolorrampimpl.h:481
QgsLimitedRandomColorRamp::count
int count() const override
Returns number of defined colors, or -1 if undefined.
Definition: qgscolorrampimpl.h:380
QgsColorBrewerColorRamp::color
QColor color(double value) const override
Returns the color corresponding to a specified value.
Definition: qgscolorrampimpl.cpp:879
QgsCptCityColorRamp::fileName
QString fileName() const
Definition: qgscolorrampimpl.cpp:1024
QgsPresetSchemeColorRamp::value
double value(int index) const override
Returns relative value between [0,1] of color at specified index.
Definition: qgscolorrampimpl.cpp:1194
QgsLimitedRandomColorRamp::QgsLimitedRandomColorRamp
QgsLimitedRandomColorRamp(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)
Constructor for QgsLimitedRandomColorRamp.
Definition: qgscolorrampimpl.cpp:621