This script works, but leaves out the geometry and original attributes. My hunch is there’s something wrong with the close(self) function, but I’m stumped. The code takes a feature id number and list of nearby ids from a NeighborFinder list, where it matches them up and assigns a _group_id attribute to use with the Aggregator. Really, it should be part of NeighborFinder. The way I had been grouping features is to use two or more AttributeCreators and assign a common Id from the feature and id list. It’s a hassle because you end up with duplicate features. Very inelegent.
I have seen a few posts on missing attributes, but I can’t see how they apply to my code:
import fme
import fmeobjects
from collections import defaultdict
class FeatureProcessor(object):
    def __init__(self):
        self.og_ids = []
        self.closest = []
        self.lines = []
    def input(self, feature: fmeobjects.FMEFeature):
        id_number = feature.getAttribute('_count_Glaz_H')
        if id_number is not None:
            self.og_ids.append(id_number)
        nearby_ids = feature.getAttribute('_closest{}._count_Glaz_H')
        if nearby_ids is not None:
            self.closest.append(nearby_ids)
    def create_lines_list(self):
        for id_number, nearby_ids in zip(self.og_ids, self.closest):
            if isinstance(nearby_ids, list):
                nearby_ids = ','.join(map(str, nearby_ids))
            line = {
                'Id Number': id_number,
                'Nearby Ids': [int(nearby_id) for nearby_id in nearby_ids.split(',') if nearby_id.strip().isdigit()]
            }
            self.lines.append(line)
        return self.lines
    def assign_group_ids_to_lines(self, lines):
        adjacency_list = defaultdict(list)
        for line in lines:
            id_num = line['Id Number']
            nearby_ids = line['Nearby Ids']
            for nearby_id in nearby_ids:
                adjacency_list[id_num].append(nearby_id)
                adjacency_list[nearby_id].append(id_num)
        def dfs(node, visited, group_id):
            stack = [node]
            while stack:
                current = stack.pop()
                if current not in visited:
                    visited.add(current)
                    for line in self.lines:
                        if line['Id Number'] == current:
                            line['Group Id'] = group_id
                            break
                    for neighbor in adjacency_list[current]:
                        if neighbor not in visited:
                            stack.append(neighbor)
        visited = set()
        group_id = 1
        for line in self.lines:
            id_num = line['Id Number']
            if id_num not in visited:
                dfs(id_num, visited, group_id)
                group_id += 1
        return self.lines
    def close(self):
        self.create_lines_list()
        lines_with_group_ids = self.assign_group_ids_to_lines(self.lines)
        for line in lines_with_group_ids:
            feature = fmeobjects.FMEFeature()
            feature.setAttribute('_group_id', line.get('Group Id', 0))
            self.pyoutput(feature)
    def process_group(self):
        pass
Any insight is appreciated.
Thanks,
-L
