Solved

Loop through list with python and get geometry

  • 11 April 2018
  • 7 replies
  • 13 views

Badge

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)

icon

Best answer by david_r 11 April 2018, 18:00

View original

7 replies

Badge +22

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

Userlevel 4

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.

Badge

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

Badge

@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

Badge +22

@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

 

Userlevel 4

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
Badge
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