00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define DOUBLE_DIFF_THRESHOLD 0.0000001
00021
00022 #include "qgslogger.h"
00023
00024 #include "qgscolorrampshader.h"
00025
00026 #include <math.h>
00027
00028 QgsColorRampShader::QgsColorRampShader( double theMinimumValue, double theMaximumValue ) : QgsRasterShaderFunction( theMinimumValue, theMaximumValue )
00029 {
00030 QgsDebugMsg( "called." );
00031 mMaximumColorCacheSize = 1024;
00032 mCurrentColorRampItemIndex = 0;
00033 }
00034
00035 QString QgsColorRampShader::colorRampTypeAsQString()
00036 {
00037 switch ( mColorRampType )
00038 {
00039 case INTERPOLATED:
00040 return QString( "INTERPOLATED" );
00041 break;
00042 case DISCRETE:
00043 return QString( "DISCRETE" );
00044 break;
00045 case EXACT:
00046 return QString( "EXACT" );
00047 break;
00048 }
00049 return QString( "Unknown" );
00050 }
00051
00052 bool QgsColorRampShader::discreteColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
00053 {
00054 int myColorRampItemCount = mColorRampItemList.count();
00055 if ( myColorRampItemCount <= 0 )
00056 {
00057 return false;
00058 }
00059
00060 double myTinyDiff = 0.0;
00061 QgsColorRampShader::ColorRampItem myColorRampItem;
00062 while ( mCurrentColorRampItemIndex >= 0 && mCurrentColorRampItemIndex < myColorRampItemCount )
00063 {
00064
00065 myColorRampItem = mColorRampItemList.value( mCurrentColorRampItemIndex );
00066 myTinyDiff = fabs( theValue - myColorRampItem.value );
00067
00068 if ( mCurrentColorRampItemIndex != 0 && theValue <= mColorRampItemList.at( mCurrentColorRampItemIndex - 1 ).value )
00069 {
00070 mCurrentColorRampItemIndex--;
00071 }
00072 else if ( theValue <= myColorRampItem.value || myTinyDiff <= DOUBLE_DIFF_THRESHOLD )
00073 {
00074 *theReturnRedValue = myColorRampItem.color.red();
00075 *theReturnGreenValue = myColorRampItem.color.green();
00076 *theReturnBlueValue = myColorRampItem.color.blue();
00077
00078 if ( mMaximumColorCacheSize >= mColorCache.size() )
00079 {
00080 mColorCache.insert( theValue, myColorRampItem.color );
00081 }
00082 return true;
00083 }
00084
00085 else
00086 {
00087 mCurrentColorRampItemIndex++;
00088 }
00089 }
00090
00091 return false;
00092 }
00093
00094 bool QgsColorRampShader::exactColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
00095 {
00096 int myColorRampItemCount = mColorRampItemList.count();
00097 if ( myColorRampItemCount <= 0 )
00098 {
00099 return false;
00100 }
00101
00102 double myTinyDiff = 0.0;
00103 QgsColorRampShader::ColorRampItem myColorRampItem;
00104 while ( mCurrentColorRampItemIndex >= 0 && mCurrentColorRampItemIndex < myColorRampItemCount )
00105 {
00106
00107 myColorRampItem = mColorRampItemList.value( mCurrentColorRampItemIndex );
00108 myTinyDiff = fabs( theValue - myColorRampItem.value );
00109 if ( theValue == myColorRampItem.value || myTinyDiff <= DOUBLE_DIFF_THRESHOLD )
00110 {
00111 *theReturnRedValue = myColorRampItem.color.red();
00112 *theReturnGreenValue = myColorRampItem.color.green();
00113 *theReturnBlueValue = myColorRampItem.color.blue();
00114
00115 if ( mMaximumColorCacheSize >= mColorCache.size() )
00116 {
00117 mColorCache.insert( theValue, myColorRampItem.color );
00118 }
00119 return true;
00120 }
00121
00122 else if ( mCurrentColorRampItemIndex != myColorRampItemCount - 1 && theValue > myColorRampItem.value && theValue < mColorRampItemList.at( mCurrentColorRampItemIndex + 1 ).value )
00123 {
00124 return false;
00125 }
00126
00127 else if ( theValue > myColorRampItem.value )
00128 {
00129 mCurrentColorRampItemIndex++;
00130 }
00131
00132 else
00133 {
00134 mCurrentColorRampItemIndex--;
00135 }
00136 }
00137
00138 return false;
00139 }
00140
00141 bool QgsColorRampShader::interpolatedColor( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
00142 {
00143 int myColorRampItemCount = mColorRampItemList.count();
00144 if ( myColorRampItemCount <= 0 )
00145 {
00146 return false;
00147 }
00148
00149 double myTinyDiff = 0.0;
00150 double myCurrentRampRange;
00151 double myOffsetInRange;
00152 QgsColorRampShader::ColorRampItem myColorRampItem;
00153 while ( mCurrentColorRampItemIndex >= 0 && mCurrentColorRampItemIndex < myColorRampItemCount )
00154 {
00155
00156 myColorRampItem = mColorRampItemList.value( mCurrentColorRampItemIndex );
00157 myTinyDiff = fabs( theValue - myColorRampItem.value );
00158
00159 if ( mCurrentColorRampItemIndex != 0 && theValue <= mColorRampItemList.at( mCurrentColorRampItemIndex - 1 ).value )
00160 {
00161 mCurrentColorRampItemIndex--;
00162 }
00163 else if ( mCurrentColorRampItemIndex != 0 && ( theValue <= myColorRampItem.value || myTinyDiff <= DOUBLE_DIFF_THRESHOLD ) )
00164 {
00165 QgsColorRampShader::ColorRampItem myPreviousColorRampItem = mColorRampItemList.value( mCurrentColorRampItemIndex - 1 );
00166 myCurrentRampRange = myColorRampItem.value - myPreviousColorRampItem.value;
00167 myOffsetInRange = theValue - myPreviousColorRampItem.value;
00168
00169 *theReturnRedValue = ( int )(( double ) myPreviousColorRampItem.color.red() + ((( double )( myColorRampItem.color.red() - myPreviousColorRampItem.color.red() ) / myCurrentRampRange ) * myOffsetInRange ) );
00170 *theReturnGreenValue = ( int )(( double ) myPreviousColorRampItem.color.green() + ((( double )( myColorRampItem.color.green() - myPreviousColorRampItem.color.green() ) / myCurrentRampRange ) * myOffsetInRange ) );
00171 *theReturnBlueValue = ( int )(( double ) myPreviousColorRampItem.color.blue() + ((( double )( myColorRampItem.color.blue() - myPreviousColorRampItem.color.blue() ) / myCurrentRampRange ) * myOffsetInRange ) );
00172 if ( mMaximumColorCacheSize >= mColorCache.size() )
00173 {
00174 QColor myNewColor( *theReturnRedValue, *theReturnGreenValue, *theReturnBlueValue );
00175 mColorCache.insert( theValue, myNewColor );
00176 }
00177 return true;
00178 }
00179 else if ( mCurrentColorRampItemIndex == 0 && theValue <= myColorRampItem.value )
00180 {
00181 QgsColorRampShader::ColorRampItem myPreviousColorRampItem = mColorRampItemList.value( mCurrentColorRampItemIndex - 1 );
00182 myCurrentRampRange = myColorRampItem.value - myPreviousColorRampItem.value;
00183 myOffsetInRange = theValue - myPreviousColorRampItem.value;
00184
00185 *theReturnRedValue = myColorRampItem.color.red();
00186 *theReturnGreenValue = myColorRampItem.color.green();
00187 *theReturnBlueValue = myColorRampItem.color.blue();
00188 if ( mMaximumColorCacheSize >= mColorCache.size() )
00189 {
00190 QColor myNewColor( *theReturnRedValue, *theReturnGreenValue, *theReturnBlueValue );
00191 mColorCache.insert( theValue, myNewColor );
00192 }
00193 return true;
00194 }
00195
00196 else if ( theValue > myColorRampItem.value )
00197 {
00198 mCurrentColorRampItemIndex++;
00199 }
00200 else
00201 {
00202 return false;
00203 }
00204 }
00205
00206 return false;
00207 }
00208
00209 void QgsColorRampShader::setColorRampItemList( const QList<QgsColorRampShader::ColorRampItem>& theList )
00210 {
00211 mColorRampItemList = theList;
00212
00213 mColorCache.clear();
00214 }
00215
00216 void QgsColorRampShader::setColorRampType( QgsColorRampShader::ColorRamp_TYPE theColorRampType )
00217 {
00218
00219 mColorCache.clear();
00220 mColorRampType = theColorRampType;
00221 }
00222
00223 void QgsColorRampShader::setColorRampType( QString theType )
00224 {
00225
00226 mColorCache.clear();
00227 if ( theType == "INTERPOLATED" )
00228 {
00229 mColorRampType = INTERPOLATED;
00230 }
00231 else if ( theType == "DISCRETE" )
00232 {
00233 mColorRampType = DISCRETE;
00234 }
00235 else
00236 {
00237 mColorRampType = EXACT;
00238 }
00239 }
00240
00241 bool QgsColorRampShader::shade( double theValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
00242 {
00243
00244
00245 QColor myColor = mColorCache.value( theValue );
00246 if ( myColor.isValid() )
00247 {
00248 *theReturnRedValue = myColor.red();
00249 *theReturnGreenValue = myColor.green();
00250 *theReturnBlueValue = myColor.blue();
00251 return true;
00252 }
00253
00254
00255
00256
00257 if ( mCurrentColorRampItemIndex < 0 )
00258 {
00259 mCurrentColorRampItemIndex = 0;
00260 }
00261 else if ( mCurrentColorRampItemIndex >= mColorRampItemList.size() )
00262 {
00263 mCurrentColorRampItemIndex = mColorRampItemList.size() - 1;
00264 }
00265
00266 if ( QgsColorRampShader::EXACT == mColorRampType )
00267 {
00268 return exactColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
00269 }
00270 else if ( QgsColorRampShader::INTERPOLATED == mColorRampType )
00271 {
00272 return interpolatedColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
00273 }
00274
00275 return discreteColor( theValue, theReturnRedValue, theReturnGreenValue, theReturnBlueValue );
00276 }
00277
00278 bool QgsColorRampShader::shade( double theRedValue, double theGreenValue, double theBlueValue, int* theReturnRedValue, int* theReturnGreenValue, int* theReturnBlueValue )
00279 {
00280 *theReturnRedValue = 0;
00281 *theReturnGreenValue = 0;
00282 *theReturnBlueValue = 0;
00283
00284 return false;
00285 }