Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Using QGIS version 1.7.

I have a plain text file that lists a set of rgb values against a code. I want to use this colour table to colour a polygon layer by mapping one of its attribute fields ('map_symb') to a code in the text file.

the colour table is very long, and looks like this:

$ head gsv1Msymbology.txt
MAPCODE RED GREEN   BLUE
Oc  143 255 255
WAT 255 255 255
Qa  244 250 202
Qdl 195 239 218
Na  248 255 238
Qd2 227 255 190
Qxw 248 255 238
Qns 255 148 83
Qn  255 202 190
.... 

So I want to match my 'map_symb' attribute to a value in MAPCODE, and use the corresponding RGB values to colour the polygons.

Is there a gui way to do this? Any way? Ben.

share|improve this question
1  
I've filed a feature request for this: hub.qgis.org/issues/4339 –  underdark Sep 30 '11 at 15:30
    
See this question & responses for solutions: gis.stackexchange.com/questions/15185/… –  a different ben Oct 3 '11 at 1:38
    
This is implemented from QGIS 2.0 onwards as data defined symbology: gis.stackexchange.com/questions/60450/… –  AndreJ Aug 8 at 15:17

2 Answers 2

up vote 5 down vote accepted

You can use Python with ElementTree module :

from string import *
from xml.etree import cElementTree as ET

class symbol:
    def __init__(self,b=[]):
            self.typec= typec
            self.b = b
            self.key = ['MAPCODE','R','G','B']
            self.data = dict(zip(self.key,self.b))
            self.symb = ET.SubElement(typec,"symbol")
            self.lower = ET.SubElement(self.symb, "lowervalue")
            self.upper = ET.SubElement(self.symb, "uppervalue")
            self.outline = ET.SubElement(self.symb,"outlinecolor")
            self.outsty = ET.SubElement(self.symb, "outlinestyle")
            self.outtail = ET.SubElement(self.symb, "outlinewidth")
            self.fillc = ET.SubElement(self.symb,"fillcolor")
            self.fillp = ET.SubElement(self.symb,"fillpattern")

    def creation(self):
            self.lower.text = self.data['MAPCODE']
            self.upper.text = self.data['MAPCODE']
            self.outsty.text="SolidLine"
            self.outtail.text="0.26"
            self.outline.set("red",str(self.data['R']))
            self.outline.set("green",str(self.data['G']))
            self.outline.set("blue",str(self.data['B']))
            self.fillc.set("red",str(self.data['R']))
            self.fillc.set("green",str(self.data['G']))
            self.fillc.set("blue",str(self.data['B']))
            self.fillp.text = "SolidPattern"

# QML file creation
intro = ET.Element("qgis")
transp = ET.SubElement(intro,"transparencyLevelInt")
transp.text = '255'
classatr = ET.SubElement(intro, "classificationattribute")
classatr.text= "MAPCODE"
typec = ET.SubElement(intro,"uniquevalue")
classif = ET.SubElement(typec,"classificationfield")
classif.text="MAPCODE"

# RGB file processing              
def main():
    file = "RGB.txt"
    f= open(file,"r")
    while 1 :
        line = f.readline()
        if not line :
            break
        elem = split(line,',') #or tab, or space, or
        symboltag = symbol(elem)
        symboltag.creation()
     result = ET.ElementTree(intro)
     result.write("RGB.qml")

if __name__ == '__main__':
    main()

The style file generated by this script is (and it works) :

  <qgis>
  <transparencyLevelInt>255</transparencyLevelInt>
   <classificationattribute>MAPCODE</classificationattribute>
   <uniquevalue>
      <classificationfield>MAPCODE</classificationfield>
         <symbol>
             <lowervalue>Oc</lowervalue>
             <uppervalue>Oc</uppervalue>
             <outlinecolor blue="143" green="255" red="255" />
             <outlinestyle>SolidLine</outlinestyle>
             <outlinewidth>0.26</outlinewidth>
             <fillcolor blue="143" green="255" red="255"/>
             <fillpattern>SolidPattern</fillpattern>
          </symbol>
          <symbol>
             <lowervalue>WAT</lowervalue>
             <uppervalue>WAT</uppervalue>
             <outlinecolor blue="255" green="255" red="255" />
             <outlinestyle>SolidLine</outlinestyle>
             <outlinewidth>0.26</outlinewidth>
             <fillcolor blue="255" green="255" red="255" /> 
             <fillpattern>SolidPattern</fillpattern>
          </symbol>
              and so...
   </uniquevalue>
</qgis>

You can also use the shapefile module ([shapefile])1 for shapefiles with RGB columns

import shapefile ....
[....]
noduplicates = []

def main():
sf = shapefile.Reader("RGBshape")
for rec in enumerate(sf.records()):
    if rec[1][0] not in noduplicates:
        noduplicates.append(rec[1][0])
        symboltag = symbol(rec[1])
        symboltag.creation()      
    else:
        continue

and so...

share|improve this answer
    
You are most awesome :) Perhaps you should submit this against the feature request made by underdark above? –  a different ben Oct 4 '11 at 1:53
    
I am no good with python script. I have a shapefile with 3 columns RGB which have the colours for each component part. How do i set the style of the layer to match the RGB> –  Gerald May 15 '13 at 11:03

So basically, you want to classify some vector data in a repeatable way? OK then, here's what you do:

  • Load your vector into QGIS.
  • Right-click on the layer in the "Layers" pane on the left side of the screen.
  • Click on "Properties" in the menu that appears.
  • Click on the "Style" tab in the window that appears.
  • There should be a drop-down list item on the screen that says "Single Symbol". Click on it, and change its value to "Categorized".
  • The interface layout will change, giving you a new option labeled "Column". Click on it and select the "map_symb" field.
  • Click the "Classify" button below the large empty field. The empty field will be populated with the contents of the "map_symb" column in your dataset.
  • Double-click on the symbols you want to change. In the window that appears, click the button labeled "Change".
  • This allows you to change the color for the given attribute value.
  • Keep doing this until you have changed colors as required.
  • When you're done, you may want to save the style by clicking the "Save Style ..." button. This will allow you to apply the same style to any other dataset, merely by clicking "Load Style ..." when in this same window. This may be what you were trying to achieve by linking the text file with the dataset, which isn't possible AFAIK. Once you have saved the style, though, you will be able to use it on any following datasets (assuming they have the same attribute values). If you open the style's save file, you'll see that it's just plain text, which you can edit if you want. It is of course possible to just write this file yourself in any text editor, but it's faster and easier doing it via GUI.
  • Click "Apply" to see your changes and "OK" to close the Layer Properties window.

You need any other pointers, just holler :)

share|improve this answer
1  
That seems like an awful lot of work when the OP already has a table of the desired colors. Is there anyway to go from the original table to what the "Save Style" format is directly? –  Andy W Sep 29 '11 at 12:13
1  
Actually it's easy. It's how you normally classify vector data in any GIS. I'm starting with a blank canvas and describing each mouse click, just to prevent confusion. You can, of course, write your color specification in the Style format from the get-go. It's simple and fairly human readable. But that's not very portable, and will not work if you make a typo. Just do it with the GUI. Once you've saved the Style file, you can modify it in a text editor and save yourself the headache of navigating a GUI. –  R Thiede Sep 29 '11 at 12:41
1  
Andy has it by the balls; there are hundreds of MAPCODEs. And yes, I know how to do it manually. –  a different ben Sep 29 '11 at 22:21
    
Ah, I see. Well, in that case, you may want to classify only a small part of your MAPCODEs, like three of them. Then save the style. Then open the style file and look at how it is formatted. Then just write a script (in, say, Python) to iterate thru your MAPCODE file line by line, and convert it into the style file's format, which you can then apply to your map. I'm not aware of an existing script that does this and unfortunately I'm in the middle of a project, so don't have time to do it myself right now. But if someone could pull it off, it'd be nice to have it posted on here as an answer :) –  R Thiede Sep 30 '11 at 7:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.