1 2 /////////////////////////////////////////////////////////// 3 // // 4 // SAGA // 5 // // 6 // System for Automated Geoscientific Analyses // 7 // // 8 // User Interface // 9 // // 10 // Program: SAGA // 11 // // 12 //-------------------------------------------------------// 13 // // 14 // WKSP_Layer_Classify.h // 15 // // 16 // Copyright (C) 2005 by Olaf Conrad // 17 // // 18 //-------------------------------------------------------// 19 // // 20 // This file is part of 'SAGA - System for Automated // 21 // Geoscientific Analyses'. SAGA is free software; you // 22 // can redistribute it and/or modify it under the terms // 23 // of the GNU General Public License as published by the // 24 // Free Software Foundation, either version 2 of the // 25 // License, or (at your option) any later version. // 26 // // 27 // SAGA is distributed in the hope that it will be // 28 // useful, but WITHOUT ANY WARRANTY; without even the // 29 // implied warranty of MERCHANTABILITY or FITNESS FOR A // 30 // PARTICULAR PURPOSE. See the GNU General Public // 31 // License for more details. // 32 // // 33 // You should have received a copy of the GNU General // 34 // Public License along with this program; if not, see // 35 // <http://www.gnu.org/licenses/>. // 36 // // 37 //-------------------------------------------------------// 38 // // 39 // contact: Olaf Conrad // 40 // Institute of Geography // 41 // University of Goettingen // 42 // Goldschmidtstr. 5 // 43 // 37077 Goettingen // 44 // Germany // 45 // // 46 // e-mail: oconrad@saga-gis.org // 47 // // 48 /////////////////////////////////////////////////////////// 49 50 //--------------------------------------------------------- 51 #ifndef _HEADER_INCLUDED__SAGA_GUI__WKSP_Layer_Classify_H 52 #define _HEADER_INCLUDED__SAGA_GUI__WKSP_Layer_Classify_H 53 54 55 /////////////////////////////////////////////////////////// 56 // // 57 // // 58 // // 59 /////////////////////////////////////////////////////////// 60 61 //--------------------------------------------------------- 62 #include <wx/string.h> 63 64 #include <saga_api/saga_api.h> 65 66 67 /////////////////////////////////////////////////////////// 68 // // 69 // // 70 // // 71 /////////////////////////////////////////////////////////// 72 73 //--------------------------------------------------------- 74 enum 75 { 76 CLASSIFY_SINGLE = 0, 77 CLASSIFY_LUT, 78 CLASSIFY_DISCRETE, 79 CLASSIFY_GRADUATED, 80 CLASSIFY_OVERLAY, 81 CLASSIFY_RGB, 82 CLASSIFY_SHADE 83 }; 84 85 //--------------------------------------------------------- 86 enum 87 { 88 LUT_COLOR = 0, 89 LUT_TITLE, 90 LUT_DESCRIPTION, 91 LUT_MIN, 92 LUT_MAX 93 }; 94 95 //--------------------------------------------------------- 96 enum 97 { 98 METRIC_MODE_NORMAL = 0, 99 METRIC_MODE_LOGUP, 100 METRIC_MODE_LOGDOWN 101 }; 102 103 //--------------------------------------------------------- 104 enum 105 { 106 SHADE_MODE_DSC_GREY = 0, 107 SHADE_MODE_ASC_GREY, 108 SHADE_MODE_DSC_CYAN, 109 SHADE_MODE_ASC_CYAN, 110 SHADE_MODE_DSC_MAGENTA, 111 SHADE_MODE_ASC_MAGENTA, 112 SHADE_MODE_DSC_YELLOW, 113 SHADE_MODE_ASC_YELLOW 114 }; 115 116 117 /////////////////////////////////////////////////////////// 118 // // 119 // // 120 // // 121 /////////////////////////////////////////////////////////// 122 123 //--------------------------------------------------------- 124 class CSG_Scaler 125 { 126 public: 127 typedef enum EInterval 128 { 129 LINEAR = 0, INCREASING, DECREASING 130 } 131 TInterval; 132 133 //----------------------------------------------------- 134 CSG_Scaler(void); 135 136 CSG_Scaler (double Minimum, double Maximum, double Interval = 0.); 137 bool Create (double Minimum, double Maximum, double Interval = 0.); 138 139 //----------------------------------------------------- 140 bool Set_Linear (CSG_Table *pTable, int Field, double Interval, double Minimum, double Maximum); 141 bool Set_StdDev (CSG_Table *pTable, int Field, double Interval, double StdDev, bool bKeepInRange); 142 bool Set_Percentile (CSG_Table *pTable, int Field, double Interval, double Minimum, double Maximum); 143 144 bool Set_Linear (CSG_Grid *pGrid , double Interval, double Minimum, double Maximum); 145 bool Set_StdDev (CSG_Grid *pGrid , double Interval, double StdDev, bool bKeepInRange); 146 bool Set_Percentile (CSG_Grid *pGrid , double Interval, double Minimum, double Maximum); 147 148 bool Set_Linear (CSG_Grids *pGrids , double Interval, double Minimum, double Maximum); 149 bool Set_StdDev (CSG_Grids *pGrids , double Interval, double StdDev, bool bKeepInRange); 150 bool Set_Percentile (CSG_Grids *pGrids , double Interval, double Minimum, double Maximum); 151 152 //----------------------------------------------------- Get_Minimum(void)153 double Get_Minimum (void) const { return( m_Minimum ); } Get_Maximum(void)154 double Get_Maximum (void) const { return( m_Minimum + m_Range ); } Get_Range(void)155 double Get_Range (void) const { return( m_Range ); } 156 bool Set_Range (double Minimum, double Maximum); 157 Get_Interval_Mode(void)158 TInterval Get_Interval_Mode (void) const { return( m_Interval ); } Get_Interval(void)159 double Get_Interval (void) const { return( m_LogRange ); } 160 bool Set_Interval (double Interval); 161 162 //----------------------------------------------------- to_Relative(double Value)163 double to_Relative (double Value) const 164 { 165 if( m_Range > 0. ) 166 { 167 Value = (Value - m_Minimum) / m_Range; 168 169 switch( m_Interval ) 170 { 171 default: 172 return( Value ); 173 174 case INCREASING: 175 return( Value <= 0. ? 0. : (log(1. + m_LogRange * ( Value)) / log(1. + m_LogRange)) ); 176 177 case DECREASING: 178 return( Value >= 1. ? 1. : 1. - (log(1. + m_LogRange * (1. - Value)) / log(1. + m_LogRange)) ); 179 } 180 } 181 182 return( 0. ); 183 } 184 185 //----------------------------------------------------- from_Relative(double Value)186 double from_Relative (double Value) const 187 { 188 if( m_Range > 0. ) 189 { 190 switch( m_Interval ) 191 { 192 default: 193 break; 194 195 case INCREASING: 196 Value = ((exp(log(1. + m_LogRange) * ( Value)) - 1.) / m_LogRange); 197 break; 198 199 case DECREASING: 200 Value = 1. - ((exp(log(1. + m_LogRange) * (1. - Value)) - 1.) / m_LogRange); 201 break; 202 } 203 204 return( m_Minimum + (m_Range * Value) ); 205 } 206 207 return( m_Minimum ); 208 } 209 210 211 protected: 212 213 TInterval m_Interval; 214 215 double m_Minimum, m_Range, m_LogRange; 216 217 }; 218 219 220 /////////////////////////////////////////////////////////// 221 // // 222 // // 223 // // 224 /////////////////////////////////////////////////////////// 225 226 //--------------------------------------------------------- 227 class CWKSP_Layer_Classify 228 { 229 public: /////////////////////////////////////////////////// 230 CWKSP_Layer_Classify(void); 231 virtual ~CWKSP_Layer_Classify(void); 232 233 bool Initialise (class CWKSP_Layer *pLayer, CSG_Table *pLUT, CSG_Colors *pColors); 234 Set_Mode(int Mode)235 void Set_Mode (int Mode) { m_Mode = Mode; } Get_Mode(void)236 int Get_Mode (void) { return( m_Mode ); } 237 Set_Shade_Mode(int Mode)238 void Set_Shade_Mode (int Mode) { m_Shade_Mode = Mode; } Get_Shade_Mode(void)239 int Get_Shade_Mode (void) { return( m_Shade_Mode ); } 240 241 void Set_Unique_Color (int Color); Get_Unique_Color(void)242 int Get_Unique_Color (void) { return( m_UNI_Color ); } 243 244 245 /////////////////////////////////////////////////////// 246 247 //----------------------------------------------------- 248 bool Set_Class_Count (int Count); 249 Get_Class_Count(void)250 int Get_Class_Count (void) 251 { 252 switch( m_Mode ) 253 { 254 case CLASSIFY_SINGLE : default: 255 return( 1 ); 256 257 case CLASSIFY_LUT : 258 return( m_pLUT->Get_Record_Count() ); 259 260 case CLASSIFY_GRADUATED: 261 case CLASSIFY_SHADE : 262 case CLASSIFY_OVERLAY : 263 return( m_Count ); 264 265 case CLASSIFY_DISCRETE : 266 return( m_pColors->Get_Count() ); 267 } 268 } 269 270 //----------------------------------------------------- Get_Class(double Value)271 int Get_Class (double Value) 272 { 273 switch( m_Mode ) 274 { 275 case CLASSIFY_SINGLE : default: 276 return( 0 ); 277 278 case CLASSIFY_LUT : 279 return( _LUT_Get_Class(Value) ); 280 281 case CLASSIFY_GRADUATED: 282 case CLASSIFY_DISCRETE : 283 case CLASSIFY_SHADE : 284 case CLASSIFY_OVERLAY : 285 return( _METRIC_Get_Class(Value) ); 286 } 287 } 288 Get_Class(const CSG_String & Value)289 int Get_Class (const CSG_String &Value) 290 { 291 if( m_Mode == CLASSIFY_LUT ) 292 { 293 return( _LUT_Get_Class(Value) ); 294 } 295 296 return( Get_Class(Value.asDouble()) ); 297 } 298 299 //----------------------------------------------------- 300 double Get_Class_Value_Minimum (int iClass); 301 double Get_Class_Value_Center (int iClass); 302 double Get_Class_Value_Maximum (int iClass); 303 wxString Get_Class_Name (int iClass); 304 wxString Get_Class_Name_byValue (double Value); 305 wxString Get_Class_Name_byValue (const wxString &Value); 306 307 308 /////////////////////////////////////////////////////// 309 310 //----------------------------------------------------- Get_Class_Color(int iClass,int & Color)311 bool Get_Class_Color (int iClass, int &Color) 312 { 313 switch( m_Mode ) 314 { 315 case CLASSIFY_SINGLE : default: 316 Color = m_UNI_Color; 317 break; 318 319 case CLASSIFY_LUT : 320 if( iClass < 0 || iClass >= m_pLUT->Get_Record_Count() ) 321 { 322 Color = m_UNI_Color; 323 324 return( false ); 325 } 326 327 Color = m_pLUT->Get_Record(iClass)->asInt(LUT_COLOR); 328 break; 329 330 331 case CLASSIFY_DISCRETE : 332 Color = m_pColors->Get_Color(iClass < 0 ? 0 : iClass >= m_pColors->Get_Count() ? m_pColors->Get_Count() - 1 : iClass); 333 break; 334 335 case CLASSIFY_GRADUATED: 336 case CLASSIFY_SHADE : 337 case CLASSIFY_OVERLAY : 338 Get_Class_Color_byValue(Get_RelativeToMetric(iClass / (double)m_Count), Color); 339 break; 340 } 341 342 return( true ); 343 } 344 345 //----------------------------------------------------- Get_Class_Color(int iClass)346 int Get_Class_Color (int iClass) 347 { 348 int Color; 349 350 return( Get_Class_Color(iClass, Color) ? Color : 0 ); 351 } 352 353 //----------------------------------------------------- Get_Class_Color_byValue(double Value,int & Color)354 bool Get_Class_Color_byValue (double Value, int &Color) 355 { 356 switch( m_Mode ) 357 { 358 case CLASSIFY_SINGLE : default: 359 { 360 return( Get_Class_Color(0, Color) ); 361 } 362 363 case CLASSIFY_LUT : 364 { 365 return( Get_Class_Color(_LUT_Get_Class(Value), Color) ); 366 } 367 368 case CLASSIFY_DISCRETE : 369 { 370 return( Get_Class_Color(_METRIC_Get_Class(Value), Color) ); 371 } 372 373 case CLASSIFY_GRADUATED: 374 { 375 double iClass = Get_MetricToRelative(Value) * (m_pColors->Get_Count() - 1); 376 377 if( iClass < 0 ) 378 { 379 Color = m_pColors->Get_Color(0); 380 } 381 else if( iClass >= m_pColors->Get_Count() - 1 ) 382 { 383 Color = m_pColors->Get_Color(m_pColors->Get_Count() - 1); 384 } 385 else 386 { 387 int a = m_pColors->Get_Color( (int)iClass); 388 int b = m_pColors->Get_Color(1 + (int)iClass); 389 double d = iClass - (int)iClass; 390 391 Color = SG_GET_RGB( 392 SG_GET_R(a) + d * (SG_GET_R(b) - SG_GET_R(a)), 393 SG_GET_G(a) + d * (SG_GET_G(b) - SG_GET_G(a)), 394 SG_GET_B(a) + d * (SG_GET_B(b) - SG_GET_B(a)) 395 ); 396 } 397 398 return( true ); 399 } 400 401 case CLASSIFY_SHADE : 402 { 403 int iClass = (int)(255.0 * Get_MetricToRelative(Value)); 404 405 if( iClass < 0 ) iClass = 0; else if( iClass > 255 ) iClass = 255; 406 407 switch( m_Shade_Mode ) 408 { 409 default: 410 case SHADE_MODE_DSC_GREY : Color = SG_GET_RGB(255 - iClass, 255 - iClass, 255 - iClass); break; 411 case SHADE_MODE_DSC_CYAN : Color = SG_GET_RGB(255 - iClass, 255 , 255 ); break; 412 case SHADE_MODE_DSC_MAGENTA: Color = SG_GET_RGB(255 , 255 - iClass, 255 ); break; 413 case SHADE_MODE_DSC_YELLOW : Color = SG_GET_RGB(255 , 255 , 255 - iClass); break; 414 case SHADE_MODE_ASC_GREY : Color = SG_GET_RGB( iClass, iClass, iClass); break; 415 case SHADE_MODE_ASC_CYAN : Color = SG_GET_RGB( iClass, 255 , 255 ); break; 416 case SHADE_MODE_ASC_MAGENTA: Color = SG_GET_RGB(255 , iClass, 255 ); break; 417 case SHADE_MODE_ASC_YELLOW : Color = SG_GET_RGB(255 , 255 , iClass); break; 418 } 419 420 return( true ); 421 } 422 423 case CLASSIFY_OVERLAY : 424 { 425 int iClass = (int)(255.0 * Get_MetricToRelative(Value)); 426 427 if( iClass < 0 ) iClass = 0; else if( iClass > 255 ) iClass = 255; 428 429 Color = SG_GET_RGB(iClass, iClass, iClass); 430 431 return( true ); 432 } 433 434 case CLASSIFY_RGB : 435 { 436 Color = (int)Value; 437 438 return( true ); 439 } 440 } 441 } 442 Get_Class_Color_byValue(const CSG_String & Value,int & Color)443 bool Get_Class_Color_byValue (const CSG_String &Value, int &Color) 444 { 445 if( m_Mode == CLASSIFY_LUT ) 446 { 447 return( Get_Class_Color(_LUT_Get_Class(Value), Color) ); 448 } 449 450 return( Get_Class_Color(Value.asDouble(), Color) ); 451 } 452 453 //----------------------------------------------------- Get_Class_Color_byValue(double Value)454 int Get_Class_Color_byValue (double Value) 455 { 456 int Color; 457 458 return( Get_Class_Color_byValue(Value, Color) ? Color : 0 ); 459 } 460 Get_Class_Color_byValue(const CSG_String & Value)461 int Get_Class_Color_byValue (const CSG_String &Value) 462 { 463 int Color; 464 465 return( Get_Class_Color_byValue(Value, Color) ? Color : 0 ); 466 } 467 468 469 /////////////////////////////////////////////////////// 470 471 //----------------------------------------------------- 472 void Set_Metric (int Mode, double LogFactor, double zMin, double zMax); Get_Metric_Mode(void)473 int Get_Metric_Mode (void) { return( m_zMode ); } Get_Metric_Colors(void)474 CSG_Colors * Get_Metric_Colors (void) { return( m_pColors ); } Get_Metric_Minimum(void)475 double Get_Metric_Minimum (void) const { return( m_zMin ); } Get_Metric_Maximum(void)476 double Get_Metric_Maximum (void) const { return( m_zMin + m_zRange ); } Get_Metric_Range(void)477 double Get_Metric_Range (void) const { return( m_zRange ); } Get_Metric_LogFactor(void)478 double Get_Metric_LogFactor (void) const { return( m_zLogRange ); } 479 480 void Metric2EqualElements (void); 481 482 //----------------------------------------------------- Get_MetricToRelative(double Value)483 double Get_MetricToRelative (double Value) 484 { 485 if( m_zRange > 0.0 ) 486 { 487 Value = (Value - m_zMin) / m_zRange; 488 489 switch( m_zMode ) 490 { 491 default: 492 return( Value ); 493 494 case METRIC_MODE_LOGUP: 495 return( Value > 0.0 ? (log(1.0 + m_zLogRange * ( Value)) / m_zLogMax) : 0.0 ); 496 497 case METRIC_MODE_LOGDOWN: 498 return( Value < 1.0 ? 1.0 - (log(1.0 + m_zLogRange * (1.0 - Value)) / m_zLogMax) : 1.0 ); 499 } 500 } 501 502 return( 0.0 ); 503 } 504 505 //----------------------------------------------------- Get_RelativeToMetric(double Value)506 double Get_RelativeToMetric (double Value) 507 { 508 switch( m_zMode ) 509 { 510 case METRIC_MODE_LOGUP: 511 Value = ((exp(m_zLogMax * ( Value)) - 1.0) / m_zLogRange); 512 break; 513 514 case METRIC_MODE_LOGDOWN: 515 Value = 1.0 - ((exp(m_zLogMax * (1.0 - Value)) - 1.0) / m_zLogRange); 516 break; 517 } 518 519 return( m_zMin + (m_zRange * Value) ); 520 } 521 522 523 /////////////////////////////////////////////////////// 524 525 //----------------------------------------------------- 526 bool Histogram_Update (void); 527 Histogram_Get(void)528 const CSG_Histogram & Histogram_Get (void) const { return( m_Histogram ); } 529 Statistics_Get(void)530 const CSG_Simple_Statistics & Statistics_Get (void) const { return( m_Statistics ); } 531 532 533 protected: //////////////////////////////////////////////// 534 535 int m_Mode, m_zMode, m_Shade_Mode, m_Count, m_UNI_Color; 536 537 double m_zMin, m_zRange, m_zLogRange, m_zLogMax; 538 539 CSG_Histogram m_Histogram; 540 541 CSG_Simple_Statistics m_Statistics; 542 543 CSG_Colors *m_pColors; 544 545 CSG_Table *m_pLUT; 546 547 class CWKSP_Layer *m_pLayer; 548 549 550 //----------------------------------------------------- 551 int _LUT_Cmp_Class (double Value, int iClass); 552 int _LUT_Get_Class (double Value); 553 554 int _LUT_Cmp_Class (const CSG_String &Value, int iClass); 555 int _LUT_Get_Class (const CSG_String &Value); 556 _METRIC_Get_Class(double Value)557 int _METRIC_Get_Class (double Value) 558 { 559 if( Value < m_zMin ) 560 { 561 return( -1 ); 562 } 563 564 if( Value > m_zMin + m_zRange ) 565 { 566 return( Get_Class_Count() ); 567 } 568 569 int Class = (int)(Get_MetricToRelative(Value) * Get_Class_Count()); 570 571 return( Class < 0 ? 0 : Class < Get_Class_Count() ? Class : Get_Class_Count() - 1 ); 572 } 573 574 575 //----------------------------------------------------- 576 bool _Histogram_Update (CSG_Grid *pGrid ); 577 bool _Histogram_Update (CSG_Grids *pGrids); 578 bool _Histogram_Update (CSG_Shapes *pShapes, int Attribute, int Normalize = -1, double Scale = 1.); 579 580 }; 581 582 583 /////////////////////////////////////////////////////////// 584 // // 585 // // 586 // // 587 /////////////////////////////////////////////////////////// 588 589 //--------------------------------------------------------- 590 #endif // #ifndef _HEADER_INCLUDED__SAGA_GUI__WKSP_Layer_Classify_H 591