Skip to main content

Hello,

I want to calculate slope between neighbor points. I want to use python caller to do something like take the first point (pointID is smallest) go to the next one , calculate the slope between the points and write it in a new attribute (_slope). Then go to the next point (so 2nd and 3rd) calculate slope and save the value.

I am new with python in fme, so could you help me?

If the points are in order, this can be done without using a python caller using Adjacent attribute handling. If you have the coordinates exposed, by selecting enable adjacent feature attributes and choosing 1 subsequent feature, you can access the coordinate attributes of the next feature to use in whatever formula you are using for calculating a slope.


import fmeobjects
from functools import reduce
from math import sin, pi

def left_slope(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    
    a_x = float(feature_a.getAttribute('x'))    
    a_y = float(feature_a.getAttribute('y'))
    a_z = float(feature_a.getAttribute('z'))

    b_x = float(feature_b.getAttribute('x'))
    b_y = float(feature_b.getAttribute('y'))
    b_z = float(feature_b.getAttribute('z'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 

    planar_distance = ((a_x-b_x)**2 + (a_y - b_y)**2)**(1/2) 
    delta_z = b_z - a_z
    slope_degree = sin(delta_z/planar_distance) * 180 /pi

    feature_a.setAttribute('_slope', slope_degree)
    return feature_b

class FeatureProcessor(object):
    def __init__(self):
        self.features = e]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left_slope, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

Here is a funky solution. It assumes feature are sorted by your point ID definition.


import fmeobjects
from functools import reduce
from math import sin, pi

def left_slope(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    
    a_x = float(feature_a.getAttribute('x'))    
    a_y = float(feature_a.getAttribute('y'))
    a_z = float(feature_a.getAttribute('z'))

    b_x = float(feature_b.getAttribute('x'))
    b_y = float(feature_b.getAttribute('y'))
    b_z = float(feature_b.getAttribute('z'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 

    planar_distance = ((a_x-b_x)**2 + (a_y - b_y)**2)**(1/2) 
    delta_z = b_z - a_z
    slope_degree = sin(delta_z/planar_distance) * 180 /pi

    feature_a.setAttribute('_slope', slope_degree)
    return feature_b

class FeatureProcessor(object):
    def __init__(self):
        self.features = e]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left_slope, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

Here is a funky solution. It assumes feature are sorted by your point ID definition.

Thank, it solved my problem. Now I want to multiply the slope_degrees the same way (first point * secod pont, second point * third point). I am using the following script, but it gives an error, like: 

Python Exception <TypeError>: float() argument must be a string or a number
Traceback (most recent call last):
  File "<string>", line 23, in close
  File "<string>", line 9, in left
TypeError: float() argument must be a string or a number
PythonCaller_3(PythonFactory): PythonFactory failed to close properly
PythonCaller_3(PythonFactory): A fatal error has occurred. Check the logfile above for details

Here is my code, can you help me where is my mistake?

import fme
import fmeobjects
from functools import reduce

def left(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    a_z = float(feature_a.getAttribute('_slope'))
    b_z = float(feature_b.getAttribute('_slope'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 
 
    _slope_elojel = b_z - a_z
    feature_a.setAttribute('_slope_elojel', _slope_elojel)
    return feature_b
 
class FeatureProcessor(object):
    def __init__(self):
        self.features = t]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

import fmeobjects
from functools import reduce
from math import sin, pi

def left_slope(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    
    a_x = float(feature_a.getAttribute('x'))    
    a_y = float(feature_a.getAttribute('y'))
    a_z = float(feature_a.getAttribute('z'))

    b_x = float(feature_b.getAttribute('x'))
    b_y = float(feature_b.getAttribute('y'))
    b_z = float(feature_b.getAttribute('z'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 

    planar_distance = ((a_x-b_x)**2 + (a_y - b_y)**2)**(1/2) 
    delta_z = b_z - a_z
    slope_degree = sin(delta_z/planar_distance) * 180 /pi

    feature_a.setAttribute('_slope', slope_degree)
    return feature_b

class FeatureProcessor(object):
    def __init__(self):
        self.features = e]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left_slope, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

Here is a funky solution. It assumes feature are sorted by your point ID definition.

I totally forgot to mention to use coordinateextracor first to extract x,y,z from index 0 on a point feature class. Sort by pointID


import fmeobjects
from functools import reduce
from math import sin, pi

def left_slope(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    
    a_x = float(feature_a.getAttribute('x'))    
    a_y = float(feature_a.getAttribute('y'))
    a_z = float(feature_a.getAttribute('z'))

    b_x = float(feature_b.getAttribute('x'))
    b_y = float(feature_b.getAttribute('y'))
    b_z = float(feature_b.getAttribute('z'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 

    planar_distance = ((a_x-b_x)**2 + (a_y - b_y)**2)**(1/2) 
    delta_z = b_z - a_z
    slope_degree = sin(delta_z/planar_distance) * 180 /pi

    feature_a.setAttribute('_slope', slope_degree)
    return feature_b

class FeatureProcessor(object):
    def __init__(self):
        self.features = e]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left_slope, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

Here is a funky solution. It assumes feature are sorted by your point ID definition.

Hi, I think this error message will occure at the last feature processing. Cause _slope is missing on the last feature. you need to add a condition before casting to float. I can look at it tomorrow.

Thank, it solved my problem. Now I want to multiply the slope_degrees the same way (first point * secod pont, second point * third point). I am using the following script, but it gives an error, like: 

Python Exception <TypeError>: float() argument must be a string or a number
Traceback (most recent call last):
  File "<string>", line 23, in close
  File "<string>", line 9, in left
TypeError: float() argument must be a string or a number
PythonCaller_3(PythonFactory): PythonFactory failed to close properly
PythonCaller_3(PythonFactory): A fatal error has occurred. Check the logfile above for details

Here is my code, can you help me where is my mistake?

import fme
import fmeobjects
from functools import reduce

def left(feature_a, feature_b):
    # Note last feature wont have a slope attribute cause there is no feature to compare With
    a_z = float(feature_a.getAttribute('_slope'))
    b_z = float(feature_b.getAttribute('_slope'))
    
    # NOTE!! Evaluate formula before using, this is just from the far back of my head 
 
    _slope_elojel = b_z - a_z
    feature_a.setAttribute('_slope_elojel', _slope_elojel)
    return feature_b
 
class FeatureProcessor(object):
    def __init__(self):
        self.features = r]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left, self.features) 
        for feature in self.features:
            self.pyoutput(feature)

Here is an update:

 

import fme
import fmeobjects
from functools import reduce

def isnumeric(x):
    try:
        float(x)
        return True
    except:
        return False

def left(feature_a, feature_b):
    # Note last 2 feature wont have a _slope_elojel attribute cause there is no feature to compare With
    a_z = float(feature_a.getAttribute('_slope')) # exists in our case
    # Last feature_b has no slope
    b_z = feature_b.getAttribute('_slope')
    if isnumeric(b_z):
        b_z = float(b_z)
        _slope_elojel = b_z - a_z
        feature_a.setAttribute('_slope_elojel', _slope_elojel)
    return feature_b

class FeatureProcessor(object):
    def __init__(self):
        self.features = r]
    def input(self,feature):
        self.features.append(feature)
    def close(self):
        reduce(left, self.features)
        for feature in self.features:
            self.pyoutput(feature)

Reply