I have countless roof surfaces as MultiPatches from which I would like to determine the highest point (x,y,z) using FME. I can determine the highest Z-value of a roof surface without any problems, but I always get only the Z-value and not the corresponding X and Y coordinates. One possibility would be to calculate a small elevation model for each roof and then use the X and Y coordinates from the cell with the highest Z value, but I would like to avoid this diversions if possible. Is there another more efficient way in FME to determine the highest point (X,Y,Z) of a multi-patch area?
Not sure if this is the best way but I would try to do this with PointClouds as these are fast.
- PointCloudCombiner
- High Vector Feature Interpolation to prevent densifying. Like 100 meters.
- Group by RoofId to create a pointcloud for each roof.
- PointCloudStatisticsCalculator to find the max z.
- Group by RoofId.
- PointCloudFilter
- @Component(z)==@Value(z.max)
- PointCloudCoercer
- Individual points.
- CoordinateExtractor
@nielsgerrits Thanks a lot for this perfect working workflow. Unfortunately, I only found the time to implement it today. It worked perfectly and the result is almost what I wanted. Special roof shapes, such as flat roofs or the roof ridge, were still problematic. I always got a dot grid or a row of dots. To eliminate this, I added a Matcher-Transformer.
My current problem is still points of an overall roof, which consists of different (independent) roof surfaces. I still get one point for each roof surface. I tried is with the Neighboorfinder, but without the right result.
Special roof shapes, such as flat roofs or the roof ridge, were still problematic. I always got a dot grid or a row of dots. To eliminate this, I added a Matcher-Transformer.
With a flat surface this is expected, as there are multiple points with the same max z.
My current problem is still points of an overall roof, which consists of different (independent) roof surfaces. I still get one point for each roof surface. I tried is with the Neighboorfinder, but without the right result.
Do these independent roof surfaces share an ID? Like:
Surface 1 - RoofId 1
Surface 2 - RoofId 1
Because then you can use the Group By functionality in FME to find the max z for each RoofId, instead of the max z for each surface.
Special roof shapes, such as flat roofs or the roof ridge, were still problematic. I always got a dot grid or a row of dots. To eliminate this, I added a Matcher-Transformer.
With a flat surface this is expected, as there are multiple points with the same max z.
My current problem is still points of an overall roof, which consists of different (independent) roof surfaces. I still get one point for each roof surface. I tried is with the Neighboorfinder, but without the right result.
Do these independent roof surfaces share an ID? Like:
Surface 1 - RoofId 1
Surface 2 - RoofId 1
Because then you can use the Group By functionality in FME to find the max z for each RoofId, instead of the max z for each surface.
Unfortunately, they do not have an ID that would allow them to be combined into one roof (only a few roofs are already finished). This is planned, but will not be completed within the next x years 8-(. So unfortunately I am left with the "Spatial Relation" approach.
With the Neighboorfinder Transformer, however, I have not yet found a way to influence the output so that the highest point is always played. Sometimes it works and the highest point is played, sometimes a lower point.
Unfortunately, they do not have an ID that would allow them to be combined into one roof (only a few roofs are already finished). This is planned, but will not be completed within the next x years 8-(. So unfortunately I am left with the "Spatial Relation" approach.
With the Neighboorfinder Transformer, however, I have not yet found a way to influence the output so that the highest point is always played. Sometimes it works and the highest point is played, sometimes a lower point.
Then you have to group the roofparts to roofs before looking for the max z.
One way to do this is buffer surfaces, dissolve buffers, generate ID for each dissolve, then relate the roofparts to the dissolved roofs using the NeighborFinder.