gradsymbol_ramps_20071028.diff

same thing as previous attachment but uses a combo box UI - perrygeo -, 2007-11-21 09:56 AM

Download (12.3 KB)

View differences:

src/app/qgsgraduatedsymboldialog.h (working copy)
22 22
#include "ui_qgsgraduatedsymboldialogbase.h"
23 23
#include "qgssinglesymboldialog.h"
24 24
#include <map>
25
#include <string>
26
#include <vector>
27
#include <QString>
25 28

  
26 29
class QgsVectorLayer;
27 30

  
31
    struct SColor 
32
    {
33
    int Red;
34
    int Green;
35
    int Blue;
36
    };
28 37

  
38
    struct SRampSegment 
39
    {
40
    float BeginVal;
41
    float EndVal;
42
    SColor BeginColor;
43
    SColor EndColor;
44
    };
45

  
46

  
29 47
class QgsGraduatedSymbolDialog: public QDialog, private Ui::QgsGraduatedSymbolDialogBase
30 48
{
31 49
    Q_OBJECT
......
39 57
 protected slots:
40 58
     /**Changes only the number of classes*/
41 59
     void adjustNumberOfClasses();
60
     /** Get a color ramp from cpt file **/
61
     std::vector<SRampSegment*> readColorRamp(QString rampFile);
62
     /**Gets the color value along a specified ramp **/
63
     QColor getColorFromRamp( std::vector<SRampSegment*> ramp, float value);
42 64
     /**Sets a new classification field and a new classification mode*/
43 65
     void adjustClassification();
44 66
     /**Changes the display of the single symbol dialog*/
src/app/qgsgraduatedsymboldialog.cpp (working copy)
25 25
#include "qgsvectorlayer.h"
26 26
#include <algorithm>
27 27
#include <cmath>
28
/* added by mp for the color ramp business */
29
#include <iostream>
30
#include <stdlib.h>
31
#include <fstream>
32
#include <list>
33
#include <string> 
34
#include <vector>
35
#include "qgsapplication.h"
36
#include <QDir>
28 37

  
29

  
30 38
QgsGraduatedSymbolDialog::QgsGraduatedSymbolDialog(QgsVectorLayer * layer): QDialog(), mVectorLayer(layer), sydialog(layer)
31 39
{
32 40
    setupUi(this);
......
102 110
	}
103 111
	
104 112
    }
113

  
114
    // add the color ramps
115
    QDir rampList(QgsApplication::pkgDataPath() + "/ramps/", "*.cpt", QDir::Name | QDir::IgnoreCase);
116
    for (uint i = 0; i < rampList.count(); i++)
117
    {
118
      QString packageName = rampList[i];
119
      rampComboBox->insertItem(packageName);   
120
    }    
105 121
    
106 122
    //do the necessary signal/slot connections
107 123
    QObject::connect(mClassifyButton, SIGNAL(clicked()), this, SLOT(adjustClassification()));
......
224 240
	mVectorLayer->setRenderer(renderer);
225 241
}
226 242

  
243
std::vector<SRampSegment*> QgsGraduatedSymbolDialog::readColorRamp(QString RampName)
244
{
245
  std::ifstream ScaleFile;
246
  std::string Buffer;
247
  std::vector<SRampSegment*> colorRamp;
248
  SRampSegment* TempColorPoint;
249
  char * pch;
250
  char * temp;
251
  int i;
252
  QString RampDirectory;
253
  QString filename;
254

  
255
  // Read the named color ramp from the system color ramp directory
256
  // todo: get this from QgsApplication
257
  RampDirectory = QgsApplication::pkgDataPath() + "/ramps/";
258
  filename = RampDirectory + RampName;
259
  ScaleFile.open(filename.toAscii(), std::ios::in);
260

  
261
  if (!ScaleFile.is_open())
262
  {
263
      // todo: give a proper error message to the user - this color ramp not found at ...
264
      return colorRamp;
265
  }
266

  
267
  while (!ScaleFile.eof())
268
  {
269
      getline(ScaleFile, Buffer);
270

  
271
      // If not a blank line or a commented line or a non-value line
272
      if ((Buffer != "") && (Buffer[0] != '#') && 
273
	  (Buffer[0] != 'B') && (Buffer[0] != 'F') && (Buffer[0] != 'N') )
274
      {
275
	  TempColorPoint = new SRampSegment;
276
 
277
          /* 
278
             Parse the line into the eight 
279
             components of a .cpt color ramp segment: 
280
             begining value, r, g, b, ending value, r, g, b 
281
	  */
282
	  temp = (char *)Buffer.c_str();
283
	  pch = strtok(temp," \t");
284
	  i = 0;
285
	  while (pch != NULL)
286
	  {
287
	      switch (i) 
288
              {
289
		case 0:
290
		  TempColorPoint->BeginVal = atof(pch);
291
		case 1:
292
		  TempColorPoint->BeginColor.Red = atoi(pch);
293
		case 2:
294
		  TempColorPoint->BeginColor.Green = atoi(pch);
295
		case 3:
296
		  TempColorPoint->BeginColor.Blue = atoi(pch);
297
		case 4:
298
		  TempColorPoint->EndVal = atof(pch);
299
		case 5:
300
		  TempColorPoint->EndColor.Red = atoi(pch);
301
		case 6:
302
		  TempColorPoint->EndColor.Green = atoi(pch);
303
		case 7:
304
		  TempColorPoint->EndColor.Blue = atoi(pch);
305
              }
306
	      pch = strtok (NULL, " \t");
307
	      i++;
308
	  }
309

  
310
	  colorRamp.push_back(TempColorPoint);
311
	}
312
    }
313

  
314
  ScaleFile.close();
315
  return colorRamp;
316
}
317

  
318

  
319
QColor QgsGraduatedSymbolDialog::getColorFromRamp(std::vector<SRampSegment*> colorRamp, float value)
320
{
321
  QColor color = QColor(0,0,0);
322
  SRampSegment* seg;
323
  float diffFactor;
324

  
325
  if ((value<0)||(value>1)) 
326
  {
327
    // this shouldn't happen but, if so, return default color (black)
328
    return color;
329
  }
330

  
331
  // Find min and max of this color ramp and
332
  // scale the given value from 0->1 to min->max of color ramp
333
  seg = colorRamp[0];
334
  float minv = seg->BeginVal;
335
  float maxv = seg->EndVal; 
336
  for (unsigned int i = 1; i < colorRamp.size(); i++)
337
  {
338
      seg = colorRamp[i];
339

  
340
      if (seg->BeginVal < minv)
341
	minv = seg->BeginVal;
342
    
343
      if (seg->EndVal > maxv)
344
	maxv = seg->EndVal;    
345
  }
346
  value = ((maxv-minv)*value)+minv;
347

  
348
  // Loop through color ramp segments and determine the color via linear interp. in RGB space
349
  for (unsigned int i = 0; i < colorRamp.size(); i++)
350
  {
351
      seg = colorRamp[i];
352

  
353
      // find the matching ramp segment
354
      if ((value <= seg->EndVal) && (value >= seg->BeginVal))
355
      {     
356
	diffFactor = (value - seg->BeginVal) / (seg->EndVal - seg->BeginVal);
357

  
358
        // interpolate a color along the ramp segment
359
	color = QColor( (int)((seg->EndColor.Red - seg->BeginColor.Red) * diffFactor) + seg->BeginColor.Red, 
360
	                (int)((seg->EndColor.Green - seg->BeginColor.Green) * diffFactor) + seg->BeginColor.Green,
361
			(int)((seg->EndColor.Blue - seg->BeginColor.Blue) * diffFactor) + seg->BeginColor.Blue );
362
      }
363
  }
364

  
365
  return color;
366
}
367

  
227 368
void QgsGraduatedSymbolDialog::adjustClassification()
228 369
{
229 370
    mClassListWidget->clear();
......
231 372
    QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider());
232 373
    double minimum = 0;
233 374
    double maximum = 0;
375
    float scaledval;
234 376
    
235 377
    //delete all previous entries
236 378
    for(std::map<QString, QgsSymbol*>::iterator it=mEntries.begin();it!=mEntries.end();++it)
......
266 408
	}
267 409
    }
268 410

  
269
    //todo: setup a data structure which holds the symbols
411
    // Obtain the color ramp
412
    QString rampName = rampComboBox->currentText(); 
413
    std::vector<SRampSegment*> ramp;
414
    ramp = readColorRamp(rampName);
415

  
416

  
270 417
    std::list<QgsSymbol*> symbolList;
271 418
    for(int i = 0; i < numberofclassesspinbox->value(); ++i)
272 419
      {
......
274 421
	symbol->setLabel("");
275 422
	QPen pen;
276 423
	QBrush brush;
424
        
425
        // Calculate the step along the classification ramp; scaled from 0 to 1 
426
        scaledval = ( (float)i + 0.5) / (float) numberofclassesspinbox->value();
277 427

  
278
	// todo: These color ramps should come from a dropdown list  
279
        QString ramp; 
280
        ramp = "red_to_green"; 
281
        if (m_type == QGis::Line) 
282
        { 
283
          pen.setColor(getColorFromRamp(ramp,i, numberofclassesspinbox->value())); 
284
        }  
285
        else //point or polygon 
286
        { 
287
          brush.setColor(getColorFromRamp(ramp,i, numberofclassesspinbox->value())); 
288
          pen.setColor(Qt::black); 
289
        } 
290

  
428
        if (m_type == QGis::Line)
429
	{
430
	  pen.setColor(getColorFromRamp(ramp,scaledval));
431
	} 
432
	else //point or polygon
433
	{
434
	  brush.setColor(getColorFromRamp(ramp,scaledval));
435
	  pen.setColor(Qt::black);
436
	}
437
	
291 438
	pen.setWidth(1);
292 439
	brush.setStyle(Qt::SolidPattern);
293 440
	symbol->setPen(pen);
......
507 654
}
508 655

  
509 656

  
510
QColor QgsGraduatedSymbolDialog::getColorFromRamp(QString ramp, int step, int totalSteps) 
511
{ 
512
  QColor color; 
513
  /* To do: 
514
     Grab the ramp by name from a file or ramp registry 
515
       and apply determine the color for the given step. 
516
     Ideally there would be two types of ramps: 
517
       - discrete colors: the number of steps would have to match totalSteps 
518
       - continuous colors: (eg grass or gmt ramps) would need to code a method 
519
          for determining an RGB color for any point along the continuum 
520
     Color ramps should be plugin-able; should be defined in a simple text file format 
521
       and read from a directory where users can add their own ramps.  
522
  */ 
523
  if (step == 0) 
524
  { 
525
    color = QColor(0,255,0); 
526
  }  
527
  else 
528
  { 
529
    color = QColor(0,255-((255/totalSteps)*step+1),((255/totalSteps)*step+1));     
530
  }  
531
  return color; 
532
} 
657

  
src/ui/qgsgraduatedsymboldialogbase.ui (working copy)
25 25
   <string>graduated Symbol</string>
26 26
  </property>
27 27
  <layout class="QGridLayout" >
28
   <property name="margin" >
28
   <property name="leftMargin" >
29 29
    <number>9</number>
30 30
   </property>
31
   <property name="spacing" >
31
   <property name="topMargin" >
32
    <number>9</number>
33
   </property>
34
   <property name="rightMargin" >
35
    <number>9</number>
36
   </property>
37
   <property name="bottomMargin" >
38
    <number>9</number>
39
   </property>
40
   <property name="horizontalSpacing" >
32 41
    <number>6</number>
33 42
   </property>
43
   <property name="verticalSpacing" >
44
    <number>6</number>
45
   </property>
34 46
   <item rowspan="2" row="1" column="0" >
35 47
    <widget class="QStackedWidget" name="mSymbolWidgetStack" >
36 48
     <widget class="QWidget" name="page" />
......
39 51
   </item>
40 52
   <item row="0" column="0" colspan="3" >
41 53
    <layout class="QHBoxLayout" >
42
     <property name="margin" >
43
      <number>0</number>
44
     </property>
45 54
     <property name="spacing" >
46 55
      <number>6</number>
47 56
     </property>
57
     <property name="leftMargin" >
58
      <number>0</number>
59
     </property>
60
     <property name="topMargin" >
61
      <number>0</number>
62
     </property>
63
     <property name="rightMargin" >
64
      <number>0</number>
65
     </property>
66
     <property name="bottomMargin" >
67
      <number>0</number>
68
     </property>
48 69
     <item>
49 70
      <layout class="QVBoxLayout" >
50
       <property name="margin" >
51
        <number>0</number>
52
       </property>
53 71
       <property name="spacing" >
54 72
        <number>6</number>
55 73
       </property>
74
       <property name="leftMargin" >
75
        <number>0</number>
76
       </property>
77
       <property name="topMargin" >
78
        <number>0</number>
79
       </property>
80
       <property name="rightMargin" >
81
        <number>0</number>
82
       </property>
83
       <property name="bottomMargin" >
84
        <number>0</number>
85
       </property>
56 86
       <item>
57 87
        <widget class="QLabel" name="classvarlabel" >
58 88
         <property name="sizePolicy" >
59
          <sizepolicy>
60
           <hsizetype>5</hsizetype>
61
           <vsizetype>5</vsizetype>
89
          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
62 90
           <horstretch>0</horstretch>
63 91
           <verstretch>0</verstretch>
64 92
          </sizepolicy>
......
109 137
         </property>
110 138
        </widget>
111 139
       </item>
140
       <item>
141
        <widget class="QLabel" name="colorramplabel" >
142
         <property name="text" >
143
          <string>Color Ramp:</string>
144
         </property>
145
         <property name="alignment" >
146
          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
147
         </property>
148
        </widget>
149
       </item>
112 150
      </layout>
113 151
     </item>
114 152
     <item>
115 153
      <layout class="QVBoxLayout" >
116
       <property name="margin" >
154
       <property name="spacing" >
155
        <number>5</number>
156
       </property>
157
       <property name="leftMargin" >
117 158
        <number>0</number>
118 159
       </property>
119
       <property name="spacing" >
120
        <number>6</number>
160
       <property name="topMargin" >
161
        <number>0</number>
121 162
       </property>
163
       <property name="rightMargin" >
164
        <number>0</number>
165
       </property>
166
       <property name="bottomMargin" >
167
        <number>0</number>
168
       </property>
122 169
       <item>
123 170
        <widget class="QComboBox" name="classificationComboBox" >
124 171
         <property name="minimumSize" >
......
149 196
         </property>
150 197
        </widget>
151 198
       </item>
199
       <item>
200
        <widget class="QComboBox" name="rampComboBox" />
201
       </item>
152 202
      </layout>
153 203
     </item>
154 204
    </layout>