Skip to main content

It would seem that Tiles can be made of complete RGB-data (FMERGB24Tile for instance), but the getTile() method seems to be available from FMEBand only, which in turn will only contain a single color channel, as generated from FMERaster.getBand(). Is there some elegant way to generate an FMERGB24Tile from an input raster?

That's a good one! Didn't dive that deep into the raster API yet, but you're right, it only seems possible to create a FMERGB24Tile from scratch, but you can't obtain one from a raster just like that.

 

The FMEBandTilePopulator might have something to do with what you want to achieve, but I get the feeling that it's not fully implemented yet... Might ask @support for more info! And do post the response here, because I'm also curious 🙂

 

 

/edit]You probably want to do some advanced raster calculations with Python, but just in case you were looking for ways to simply tile rasters in FME, the most elegant way would be to use a RasterTiler (or WebMapTiler). That will keep the interpretation in tact.[/edit]

Hi @steinarvatne, in my understanding, an instance of FMERGB24Tile class is used as a container of the values of an RGB24 palette, and it can be generated from an RGB24 palette instance. See this script example.

# PythonCaller Script Example
# The input feature should have a raster whose first band has RGB24 palette.
def processFeature(feature):
    raster = feature.getGeometry()
    band = raster.getBand(0) # get the first band
    palette = band.getPalette(0) # get the first palette
    
    # Generate a Tile instance containing key values of the palette.
    # number of rows = 1
    # number of columns = number of keys
    keyTile = palette.getKeyTile()
    keys = keyTile.getData() #  nK0,K1,K2,...]]
    
    # Generate an FMERGB24Tile instance containing RGB values of the palette.
    # number of rows = 1
    # number of columns = number of keys (each column has 3 (R,G,B) values)
    rgbTile = palette.getValueTile()
    rgbs = rgbTile.getData() # brR0,G0,B0,R1,G1,B1,R2,G2,B2,...]]
    
    # Create formatted palette definition.
    # See the help on the RasterPaletteExtractor to learn about the syntax.
    rows = ["RGB24"]
    for i, key in enumerate(keys 0]):
        n = i * 3
        rows.append("%d %d,%d,%d" %
            (key, rgbsÂ0]an], rgbst0]En+1], rgbst0] n+2]))
    feature.setAttribute('_palette', "\n".join(rows))

OK, but isn't the use of the FMERGB24Tile class somewhat incidental in this case? I mean, it's used in this case simply because the data it is meant to hold fits the data in a palette? The way I read things, this is not the sole purpose of the FMERGB24Tile class, which seem designed to hold regular 24-bit RGB data as you would find in typical input rasters? If my interpretation is correct, then there really should be a method or function for generating such tiles from RGB-rasters?


I think that the major (maybe only) purpose of the FMERGB24Tile class is to contain the values of an RGB24 palette, at least in the current Python FME Objects API implementation. Hope someone from Safe elaborates about the design concept.

Anyway, if you need to retrieve R, G, B values of the cells in an RGB24 raster, you will have to collect them for each band. However, it's not so complicated.

# PythonCaller Script Example
# The input feature should have an RGB24 raster consisting of 3 bands (R, G, B).
import fmeobjects
class FeatureProcessor(object):
    def __init__(self):
        self.rgb24TileClasses = t
            fmeobjects.FMERed8Tile,
            fmeobjects.FMEGreen8Tile,
            fmeobjects.FMEBlue8Tile,
        ]
        
    def input(self, feature):
        raster = feature.getGeometry()
        rproperties = raster.getProperties()
        numRows = rproperties.getNumRows()
        numCols = rproperties.getNumCols()
        
        # Collect cell values.
        cellValues = p]
        for i, tileClass in enumerate(self.rgb24TileClasses):
            band = raster.getBand(i)
            tile = band.getTile(0, 0, tileClass(numRows, numCols))
            cellValues.append(tile.getData())
            
        # Do something with the cellValues.
        # Just an example, save all the cell values as a JSON array.
        import json
        feature.setAttribute('_cellValues', json.dumps(cellValues))
        
        self.pyoutput(feature)

I think that the major (maybe only) purpose of the FMERGB24Tile class is to contain the values of an RGB24 palette, at least in the current Python FME Objects API implementation. Hope someone from Safe elaborates about the design concept.

Anyway, if you need to retrieve R, G, B values of the cells in an RGB24 raster, you will have to collect them for each band. However, it's not so complicated.

# PythonCaller Script Example
# The input feature should have an RGB24 raster consisting of 3 bands (R, G, B).
import fmeobjects
class FeatureProcessor(object):
    def __init__(self):
        self.rgb24TileClasses = t
            fmeobjects.FMERed8Tile,
            fmeobjects.FMEGreen8Tile,
            fmeobjects.FMEBlue8Tile,
        ]
        
    def input(self, feature):
        raster = feature.getGeometry()
        rproperties = raster.getProperties()
        numRows = rproperties.getNumRows()
        numCols = rproperties.getNumCols()
        
        # Collect cell values.
        cellValues = p]
        for i, tileClass in enumerate(self.rgb24TileClasses):
            band = raster.getBand(i)
            tile = band.getTile(0, 0, tileClass(numRows, numCols))
            cellValues.append(tile.getData())
            
        # Do something with the cellValues.
        # Just an example, save all the cell values as a JSON array.
        import json
        feature.setAttribute('_cellValues', json.dumps(cellValues))
        
        self.pyoutput(feature)
If by "purpose" you mean what it can actually be used for, you would appear to be partially correct, although it is probably possible to construct new raster tiles containing RGB information. This is not at all clear from the documentation, though. The definitions of all the ...Tile classes are almost identical, makes no mention of palettes, and most of them are perhaps not suited to hold palette data (like the Red/Green/Blue tiles). Based on the documentation, I would maintain my view that the purpose of the FMERGB24Tile class APPEARS to be to hold general RGB raster data. It seems this potential has not been developed in the current API though, and I can't find any complementary method for going the other way either, from an RGB tile to a raster.

 

 

However, it should be possible to do what I want with bands and the classes you mention above, although I'd have to reassemble the data into a list of nR,G,B] manually.

 

 

 


If by "purpose" you mean what it can actually be used for, you would appear to be partially correct, although it is probably possible to construct new raster tiles containing RGB information. This is not at all clear from the documentation, though. The definitions of all the ...Tile classes are almost identical, makes no mention of palettes, and most of them are perhaps not suited to hold palette data (like the Red/Green/Blue tiles). Based on the documentation, I would maintain my view that the purpose of the FMERGB24Tile class APPEARS to be to hold general RGB raster data. It seems this potential has not been developed in the current API though, and I can't find any complementary method for going the other way either, from an RGB tile to a raster.

 

 

However, it should be possible to do what I want with bands and the classes you mention above, although I'd have to reassemble the data into a list of fR,G,B] manually.

 

 

 

It seems this potential has not been developed in the current API though, and I can't find any complementary method for going the other way either, from an RGB tile to a raster. Yes, that's exactly what I meant in my comment. I don't think the API is finished yet either!

 

@daleatsafe: do you know what's the status of the current raster classes and methods?

Thank you all for the discussion. In speaking to the lead raster developer at Safe, he confirms that the FMERGB*Tile objects are used solely for the purpose of palettes.

The confusion here may stem from the doc string for FMEBandProperties.getInterpretation() and FMEBandProperties.setInterpretation(). Both methods state that a band interpretation can possibly be FME_INTERPRETATION_RGB*, where in actuality they can only be single component interpretations like FME_INTERPRETATION_RED (We will correct the doc string to remove them). This basically means bands are retrieved from a raster and each band represents a single component that is retrieved as tiles. We have plans to improve our Python FME Objects API doc and hope to roll that out for users.

For palette values, the possible interpretations are FME_INTERPRETATION_RGB24, FME_INTERPRETATION_RGBA32, FME_INTERPRETATION_RGB48, FME_INTERPRETATION_RGBA64, FME_INTERPRETATION_GRAY8, FME_INTERPRETATION_GRAY16, FME_INTERPRETATION_STRING, FME_INTERPRETATION_NULL. There isn't a direct method on the API to get a palette value's interpretation, so the way to do it is FMEPalette.getValueTile().getInterpretation().

 


The raster API in its current state is up to date and closely matches the C++ raster API.


Thank you all for the discussion. In speaking to the lead raster developer at Safe, he confirms that the FMERGB*Tile objects are used solely for the purpose of palettes.

The confusion here may stem from the doc string for FMEBandProperties.getInterpretation() and FMEBandProperties.setInterpretation(). Both methods state that a band interpretation can possibly be FME_INTERPRETATION_RGB*, where in actuality they can only be single component interpretations like FME_INTERPRETATION_RED (We will correct the doc string to remove them). This basically means bands are retrieved from a raster and each band represents a single component that is retrieved as tiles. We have plans to improve our Python FME Objects API doc and hope to roll that out for users.

For palette values, the possible interpretations are FME_INTERPRETATION_RGB24, FME_INTERPRETATION_RGBA32, FME_INTERPRETATION_RGB48, FME_INTERPRETATION_RGBA64, FME_INTERPRETATION_GRAY8, FME_INTERPRETATION_GRAY16, FME_INTERPRETATION_STRING, FME_INTERPRETATION_NULL. There isn't a direct method on the API to get a palette value's interpretation, so the way to do it is FMEPalette.getValueTile().getInterpretation().

 


The raster API in its current state is up to date and closely matches the C++ raster API.

Thank you for the answer. The cause of confusion is probably my own expectations combined with a very limited knowledge of the API. Even so, I'd maintain that a mechanism for getting and setting RGB (or any number/type of channels) in a simpler, per pixel array which could convert directly to/from FMERaster would be mighty useful.

 

 

Edit: or even implemented directly as methods of FMEraster...

 

 


Reply