Skip to main content
Solved

Loop through list with python and get geometry


Forum|alt.badge.img

Hello,

I have a set of point and a grid partition. each point is assign to a partition

I have build a list containing all point in a partition (listbuilder group by partition_id)

Is there a way to get the feature geometry of each element of the list.

Does the geometry is preserved in a listbuilder ?

if so How can I retreive it within the list of element in python?

so far I only get NoneType in my_list.

I saw that I must do something like my_list = feature.getAttribute("_list{}.<attributeName>")

But what is the attribute name for the geometry ?

later I would like to do something like 

feature.getAllCoordinates() on each element of the list

0684Q00000ArAegQAF.png

def input(self, feature):

    my_list = feature.getAttribute("_list{}")

    # flush the list
    self.fList = []

    if my_list is not None and len(my_list) > 0:
        for item in my_list:
            new_feature = feature.clone()
            self.fList.append(new_feature)

        self.DBScan(self.fList, self.eps, self.minPts)
    else:
        partition = feature.getAttribute("partition")
        self.logger.logMessageString("partition {} as no value : ".format(partition) , fmeobjects.FME_ERROR)

Best answer by david_r

The ListBuilder does not retain the geometries of the list items. Consider using the Aggregator instead, you can specify a list name to hold all the part attributes.

View original
Did this help you find an answer to your question?

7 replies

jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • April 11, 2018

The listBuilder does not perserver geometry, but the Aggregator does, and can build the corresponding list.


david_r
Evangelist
  • Best Answer
  • April 11, 2018

The ListBuilder does not retain the geometries of the list items. Consider using the Aggregator instead, you can specify a list name to hold all the part attributes.


Forum|alt.badge.img
  • Author
  • April 11, 2018
david_r wrote:

The ListBuilder does not retain the geometries of the list items. Consider using the Aggregator instead, you can specify a list name to hold all the part attributes.

Hi,

Although I can see the aggregate in data inspector, I still have the same result in the python caller. The list is None with this line of code

my_list = feature.getAttribute("_list{}")

I think I miss something from your explanation

regards,

Sylvain


Forum|alt.badge.img
  • Author
  • April 11, 2018

@david_r

@jdh

Hi, thank for your reply,

Although I can now see all point aggregated by partition in Inspector, I still have the same result with this line

my_list = feature.getAttribute("_list{}") --> NoneType

I can't retrieve the geometry

Maybe I missed something in your explanation

Regards,

Sylvain


jdh
Contributor
Forum|alt.badge.img+28
  • Contributor
  • April 11, 2018
shotte wrote:

@david_r

@jdh

Hi, thank for your reply,

Although I can now see all point aggregated by partition in Inspector, I still have the same result with this line

my_list = feature.getAttribute("_list{}") --> NoneType

I can't retrieve the geometry

Maybe I missed something in your explanation

Regards,

Sylvain

You need feature.getAttribute("_list{}.attrA") to get a list of attrA.

 

 

For the geometry you will want feature.getGeometry() which will return a multipoint.

 

you can then use things like geom.numParts() to get the number of points, and geom.getPartAt(i) to get the individual points.

 

 

To iterate over all the points in the aggregate you can simply use:

 

geom = feature.getGeometry()

 

for pt in geom:

 

pass

 


david_r
Evangelist
  • April 11, 2018

You won't find the geometries inside the attribute list (it only contains attributes), you'll have to iterate over the aggregate parts and extract the geometry from each part, probably something like this:

from fmeobjects import *

if feature.getGeometryType() == FME_GEOM_AGGREGATE:
    aggregate_parts = feature.splitAggregate(True)
elif feature.getGeometryType() == FME_GEOM_DONUT:
    aggregate_parts = feature.getDonutParts()
else:
    aggregate_parts = [feature,]

for n, part in enumerate(aggregate_parts):
    part_geom = part.getGeometry()
    part_objectid = feature.getAttribute('_list{%s}.OBJECTID' % n)
    # Do something exciting with "part_geom" and "part_objectid" here...

You'll find more information about the FMEGeometry object in the API documentation:

 

http://docs.safe.com/fme/html/FME_Objects_Python_API/index.html

Forum|alt.badge.img
  • Author
  • April 11, 2018
Here my solution,

 

I use an aggregator like suggested and then I used splitAggregate wich give me a list of FME Feature

 

Thanks All

 

Sylvain

 

def input(self, feature):

    # flush the list
    self.fList = feature.splitAggregate(False)

    self.logger.logMessageString("There is {} point : ".format(len(self.fList)), fmeobjects.FME_ERROR)

    self.logger.logMessageString("Starting DBScan: ", fmeobjects.FME_ERROR)
    self.DBScan(self.fList, self.eps, self.minPts)


def DBScan(self, D, eps, minPts):

    corePoints = [f for f in D if self.getNbOfNeighbours(D,f,eps) >= minPts ]

    self.logger.logMessageString("Outputing Core Point: ", fmeobjects.FME_ERROR)

    for f in corePoints:
        self.logger.logMessageString("Outputing point {}: ".format(str(f)), fmeobjects.FME_ERROR)
        self.pyoutput(f)

def distance3D(self, featureA, featureB):

    coorA = featureA.getAllCoordinates()
    coorB = featureB.getAllCoordinates()

    # [node number of current feature][coord component x, y, z]

    xa = coorA[0][0]
    ya = coorA[0][1]
    za = coorA[0][2]

    xb = coorB[0][0]
    yb = coorB[0][1]
    zb = coorB[0][2]

    d = math.sqrt((xa - xb) ** 2 + (ya - yb) ** 2 + (za - zb) ** 2)
    return d

 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings