span8
span4
span8
span4
Hi
I am trying to use this python script which would be very helpful for me. I have a huge amount of data from a WFS which needs to be tiled in a good way. @takashi had a very good code, but I can’t get it to work in 2017.10.154 edition (the version I have).
I have a test file with more than 2000 points and I want tiles with 230 points each.
I have python installed on my computer and I am using the python caller.
I get error messages:
” FME Configuration: No destination coordinate system set
PythonFactory failed to load python symbol `FeatureProcessor'
Factory proxy not initialized f_4(PythonFactory): PythonFactory failed to process feature”
Why is that?
Any suggestions?
/Regards, Tobias
Hi @trydlinge,
In your PythonCaller, please change the Class or Function to Process Features to 'NonUniformBoxGenerator'. It is presently set to the default 'FeatureProcessor', but there is no class or function with that name in your script.
The script was created for the old pyfme module (maybe in FME 2013 and earlier), so it may not work in the current FME even if you have modified the parameter setting. This is updated version.
Note: Your sample data contains many duplicate points. In my observation, the maximum number of duplicates was 1330, so this script cannot finish iteration for dividing bounding box if you set 230 (less than 1330) to stopping condition. If you need to separate the duplicate points into groups having 230 or less points, the script would not be useful.
import fmeobjects class NonUniformBoxGenerator(object): def __init__(self): self.points = [] # List of (x, y, point feature) self.boxId = 0 # Bounding Box ID def input(self, feature): # Extract coordinate and store the point feature. coord = feature.getCoordinate(0) self.points.append((coord[0], coord[1], feature)) def close(self): # Calculate initial extent. xmin, ymin, p = self.points[0] xmax, ymax = xmin, ymin for x, y, p in self.points[1:]: if x < xmin: xmin = x elif xmax < x: xmax = x if y < ymin: ymin = y elif ymax < y: ymax = y # Start creating boxes. self.createBoundingBox((xmin, ymin, xmax, ymax), self.points) # This method will be called recursively to divide box by four, # until the number of inside points becomes less than 230. def createBoundingBox(self, extent, points): xmin, ymin, xmax, ymax = extent if len(points) < 230: # Create a box polygon; output the polygon and inside points. # Output features can be classified by the GeometryFilter. coords = [(xmin,ymin),(xmax,ymin),(xmax,ymax),(xmin,ymax),(xmin,ymin)] boundary = fmeobjects.FMELine(coords) box = fmeobjects.FMEFeature() box.setGeometry(fmeobjects.FMEPolygon(boundary)) box.setAttribute('_box_id', self.boxId) self.pyoutput(box) for x, y, p in points: p.setAttribute('_box_id', self.boxId) self.pyoutput(p) self.boxId += 1 else: # Calculate extent of divided boxes. xc = (xmin + xmax) * 0.5 # Center X yc = (ymin + ymax) * 0.5 # Center Y extentList = [ (xmin, ymin, xc, yc), # bottom-left (xc, ymin, xmax, yc), # bottom-right (xmin, yc, xc, ymax), # top-left (xc, yc, xmax, ymax) # top-right ] # Collect inside points for each box. pointsList = [[], [], [], []] for x, y, p in points: if y < yc: if x < xc: # bottom-left pointsList[0].append((x, y, p)) else: # bottom-right pointsList[1].append((x, y, p)) else: if x < xc: # top-left pointsList[2].append((x, y, p)) else: # top-right pointsList[3].append((x, y, p)) del points # save memory # Call the method for each box. for extent, points in zip(extentList, pointsList): self.createBoundingBox(extent, points)
© 2019 Safe Software Inc | Legal