FME Geometry, PythonCaller, GenerativeArt

#main_script import fmeobjects import numpy as np from fmeobjects import FMELine, FMEPoint, FMEPolygon import numpy as np import math from sklearn.cluster import KMeans from sklearn.neighbors import KDTree from sklearn.decomposition import PCA """ Generate a network of connected points: """ def generate_connected_network(n_points=55, n_clusters=3, n_neighbors=11, seed=7): rng = np.random.RandomState(seed) # generate rand points raw_points = rng.randn(n_points, 2) * 33 # clustering kmeans = KMeans(n_clusters=n_clusters, random_state=seed, n_init=10) labels = kmeans.fit_predict(raw_points) # Connect neighbors by KDTree tree = KDTree(raw_points) distances, indices = tree.query(raw_points, k=n_neighbors + 1) # +1 because self is included edges_idx = set() for i, neighbors in enumerate(indices): for j in neighbors[1:]: # skip self (index 0) edge = (min(i, j), max(i, j)) # undirected edges_idx.add(edge) # 4. Rotate with PCA (align principal axis to X) pca = PCA(n_components=2) points = pca.fit_transform(raw_points) # edge list edges = [ ((points[i][0], points[i][1]), (points[j][0], points[j][1])) for i, j in edges_idx ] return points, edges, labels class FeatureProcessor(object): def __init__(self): pass def input(self, feature: fmeobjects.FMEFeature): points, lines, b = generate_connected_network(n_points=55, n_clusters=3, n_neighbors=2, seed=7) # output the star boundary for i,line in enumerate(lines): tri_ring = (list(map(tuple, line))) tri_line = FMELine([tuple(p) for p in tri_ring]) out_feat = fmeobjects.FMEFeature(feature) out_feat.setGeometry(tri_line) self.pyoutput(out_feat) for i,point in enumerate(points): pt_coords = tuple(point) pt = FMEPoint() newX, newY = pt_coords newZ = 0 pt.setXYZ(newX, newY, newZ) out_feat = fmeobjects.FMEFeature(feature) out_feat.setGeometry(pt) out_feat.setAttribute("label",str(b[i])) self.pyoutput(out_feat)