Solved

How to manipulate attribute values of all features in PythonCaller

  • 23 May 2023
  • 2 replies
  • 24 views

Badge

I would like to manipulate whole ''column'' (list of attribute values) in a PythonCaller but I don't really understand how I can do that.

 

For example in the example here below, I create a new attribute in `input` (=iterating over each each feature, right ?) ; what I am trying to do 

 

1) in `close` : to print all unique values of the newly created attribute

(WITHOUT iterating over each feature, so to work directly on the list of all attribute values that my data contain)

 

2) in `close` (or somewhere else) : to add directly a new attribute to my data by applying a function on the firstly created attribute (again WITHOUT iterating over each feature)

 

Is it possible to do all these things in a Python caller ? 

 

import fme
import fmeobjects
def processFeature(feature):
    pass
 
class FeatureProcessor(object):
    def __init__(self):
        pass
    def input(self,feature):        
        progs_dict = globals()[fme.macroValues['VARNAME_DICT']]
        all_prog_cols = list(progs_dict.keys())
        all_col_attributes = filter(
            lambda x: x in all_prog_cols,
            feature.getAllAttributeNames())
        value_tmp = map(str, map(feature.getAttribute, all_col_attributes))
        value = [i for i in value_tmp if i == 'X']
        if len(value) == 0:
            value = [progs_dict['aucun']]
        feature.setAttribute('MYNEWATTR', ';'.join(value))
        self.pyoutput(feature)
        
    def close(self):
     #### EX 1) I WOULD LIKE TO PRINT ALL UNIQUE VALUES OF THE NEWLY CREATED ATTRIBUTE
      #print(', '.join(set(self.MYNEWATTR)))  # <<< this does not work
 
       #### EX 2) WOULD IT BE POSSIBLE TO CREATE HERE A NEW ATTRIBUTE BASED ON THE NEWLY CREATED ONE WIHTOUT ITERATING OVER ALL FEATURES
      #self.ANOTHERATTR = map(my_python_func,  self.MYNEWATTR) #<<< does not work
 
        pass

 

 

icon

Best answer by mzuer 30 June 2023, 09:36

View original

2 replies

Userlevel 3
Badge +17

Hello @mzuer​ 

For example 1, self.MYNEWATTR does not exist and will error when called in the close method. You would want to define the self.MYNEWATTR set in the __init__ method and then add ';'.join(value) to this set to accumulate unique values to print in the close method.

import fme
import fmeobjects
 
def processFeature(feature):
    pass
 
class FeatureProcessor(object):
    def __init__(self):
        self.MYNEWATTR = {}
        
    def input(self,feature):        
        progs_dict = globals()[fme.macroValues['VARNAME_DICT']]
        all_prog_cols = list(progs_dict.keys())
        all_col_attributes = filter(
            lambda x: x in all_prog_cols,
            feature.getAllAttributeNames())
        value_tmp = map(str, map(feature.getAttribute, all_col_attributes))
        value = [i for i in value_tmp if i == 'X']
        if len(value) == 0:
            value = [progs_dict['aucun']]
        feature.setAttribute('MYNEWATTR', ';'.join(value))
        self.MYNEWATTR.add(';'.join(value))
        self.pyoutput(feature)
        
    def close(self):
        #### EX 1) I WOULD LIKE TO PRINT ALL UNIQUE VALUES OF THE NEWLY CREATED ATTRIBUTE
        print(self.MYNEWATTR) 
        #### EX 2) WOULD IT BE POSSIBLE TO CREATE HERE A NEW ATTRIBUTE BASED ON THE NEWLY CREATED ONE WIHTOUT ITERATING OVER ALL FEATURES
        #self.ANOTHERATTR = map(my_python_func,  self.MYNEWATTR) #<<< does not work 
        pass

For example 2, no, it is not possible to add/alter attribute values of features without performing a function directly on the features like through fmeobjects.FMEFeature.setAttribute().

Badge

thanks for the explanation !

Reply