3

I have downloaded a shapefile of bedrock geology. I need it to be displayed as it should be with the style applied. The supplier will no give me a qml. but i have noticed in the .dbf file the Cyan Magenta yellow and black numbers are stated.

There are hundreds of entries and i dont have the time or patience to go through each one individually.

Is there a way i can apply the colours onto the shapefile (which is polygons and the extracted csv file creates points which have no xy).

QGIS1.8.0 on windows 7.

1
  • You have another issue to address first; QGIS uses RGB as its colour schema. You will need to convert the CMYK colours to RGB first. Commented May 11, 2013 at 16:08

3 Answers 3

6

The solution to create a qml file from RGB field values was presented in Python in How to use a field-to-RGB mapping for symbology in QGIS?

but, as pointed out by Ryan Garnett, the problem is to convert the CMYK colour to RGB because:

"it seems that there is the notion out there that conversion from CMYK to RGB is easy. Newsflash: It’s not. As every graphic designer knows, the CMYK color gamut is smaller than the the RGB color gamut (even the sRGB color gamut). You can’t take a CMYK color and convert it to an out-of-CMYK-gamut RGB color! That’s nonsense! And it’s precisely what most conversion algorithms and color pickers out there do! Even Adobe Kuler!!! Since yesterday, I’ve studied dozens of algorithms and color pickers that claim to do CMYK -> RGB conversion, and every single one of them is wrong."

and

So basically, these algorithms convert a CMYK color to an RGB color that is outside of the CMYK color gamut! A color that cannot be represented with CMYK is supposed to be the result of a CMYK->RGB conversion?

from Lea Verou in 100% Cyan in CMYK is NOT rgb(0,255,255)!!, because the correct conversion of a CMYK value to RGB would depend on the source CMYK space (?) and the destination RGB space (QGIS).

But you can always try with one of these algorithms as an approximation (from an old avenue script cmykrgb.ave at CMYK to RGB and RGB to CMYK algorithms):

  1. create new R, G, B fields
  2. use the field calculator to convert the C,M,Y,K values (in the range 0-100) to R,G,B values (range 0-255 in QGIS) with the formulas:

R = (1 - ((C + K)/100)) * 255
G = (1 - ((M + K)/100)) * 255
B = (1 - ((Y + K)/100)) * 255

But if all are the algorithms are wrong, good luck.

1
  • Most nicely done so far. But i am having major issues with the gis.stackexchange.com/questions/15135/…. I have now got a shapefile with it in RGB but there should be an ability to set style from attribute allowing you to click r g b.
    – Ger
    Commented May 15, 2013 at 10:51
6

Thanks to Chris and Nyall and the work done to add data defined symbols there is now functions in QGIS to be able colour a symbol on the fly based on a column or expression.

(Note: You need to be running the dev build of QGIS)

data defined symbols

You will have to break the parts into different columns, or you can do it on the fly using the string functions in the expression engine, but that should do what you need.

4
  • I know it's not a 1.8 answer but it's still an answer for anyone else, or if you want to run 1.9 - 2.0
    – Nathan W
    Commented May 11, 2013 at 22:56
  • Were can i download 1.9 or 2.0
    – Ger
    Commented May 15, 2013 at 10:54
  • You can use the OSGeo4W installer
    – Nathan W
    Commented May 15, 2013 at 11:17
  • Where is this in 3+?
    – user15741
    Commented Nov 8, 2018 at 5:23
0

BGS use the BGSref column(s) in the attribute table to hold a Yellow (Y), Cyan (C), Magenta (M) value (in that order). The following python code can be used as part of a data defined properties, expression to obtain the RGB value.

# Python Function to be used within QGIS and called as part of data defined properties
# 
# Takes BGSREF attribute value, which is in Yellow (Y), Cyan (C), Magenta (M) order 
# and converts to Red (R), Green (G), Blue (B) order
#       
# OUTPUT of the function is typically an RGB string in the style 255,148,0
# OUTPUT may occasionally be an RGB + alpha channel string 255,255,255,255
#
# EXAMPLE take a BGSREF (YCM) value of 608 and converts it into a RGB value of 255,51,117
# EXAMPLE take a BGSREF (YCM) value of 20 and converts it as 020 into a RGB value of 219,255,255
# 
# EXPRESSION should look like: BGSrefToQGIScolorRGB( "BGSREF" )
#
# Technically RGB colours are calculated with colour + Black (K) as
# R = 255 * (1-C) * (1-K)
# G = 255 * (1-M) * (1-K)
# B = 255 * (1-Y) * (1-K)

from qgis.utils import qgsfunction
from qgis.core import QGis
import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
#logger.info("Attempting to log some debug information")

aColourAdjust = [0,7,14,21,31,42,54,67,80,100]

@qgsfunction(1, "Python")
def BGSrefToQGIScolorRGB(values, feature, parent):
    """
       Converts BGSref colour (attribution) from YCM to RGB values.
       Output as integers in the range 0 - 255, in the style:
       rrr,ggg,bbb(,aaa)
    """
    rgbValue = "255,255,255"
    isTransparent = False

    #logger.info("+++++ Debug for attribute table row starts here +++++")
    #logger.debug("Default rgbvalue is " + rgbValue)

    bgsref2Convert = str(values[0])

    # Test the length of the input value and pad with zeros if applicable.
    if len(bgsref2Convert) == 1:
        bgsref2Convert = "00" + bgsref2Convert
    elif len(bgsref2Convert) == 2:
        bgsref2Convert = "0" + bgsref2Convert
    elif len(bgsref2Convert) == 3:
        #logger.debug("bgsref2Convert value not changed")
        pass
    else:
        #logger.debug("bgsref2Convert value is taken to be white transparent")
        rgbValue = "255,255,255,255"
        isTransparent = True

    #logger.debug("bgsref2Convert value is: " + bgsref2Convert)

    # Now we can calculate the RGB values...  
    if isTransparent == False:
        try:
            yellow = aColourAdjust[int(bgsref2Convert[:1])]
        except TypeError:
            yellow = aColourAdjust[int(str(bgsref2Convert)[:1])]
        except Exception as e:
            yellow = 0

        try:
            cyan = aColourAdjust[int(bgsref2Convert[1:2])]
        except TypeError:
            cyan = aColourAdjust[int(str(bgsref2Convert)[-1:])]
        except Exception as e:
            cyan = 0

        try:
            magenta = aColourAdjust[int(bgsref2Convert[-1:])]
        except TypeError:
            magenta = aColourAdjust[int(str(bgsref2Convert)[-1:])]
        except Exception as e:
            magenta = 0

        # Python syntax: 100.0 is deliberate to get a floating point result, otherwise the result of division will always be zero. 
        #logger.debug("Y is: " + str(yellow) + " C is: " + str(cyan) + " M is: " + str(magenta))

        red = int(255-((cyan/100.0)*255))
        green = int(255-((magenta/100.0)*255))
        blue = int(255-((yellow/100.0)*255))

        # Now just output the expected QGIS format for the colour output...
        rgbValue = str(red) + "," + str(green) + "," + str(blue)

    #logger.debug("Output rgbvalue is " + rgbValue)
    #logger.info("----- Debug for attrubute table row ends here -----")

    return rgbValue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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