Exercise 3 | Custom Transformers and Published Parameters |
Data | Neighborhoods (Google KML) |
Overall Goal | Edit a custom transformer to use published parameters |
Demonstrates | Published parameters and custom transformers |
Start Workspace | C:\FMEData2017\Workspaces\DesktopAdvanced\CustomTransformers-Ex3-Begin.fmw |
End Workspace | C:\FMEData2017\Workspaces\DesktopAdvanced\CustomTransformers-Ex3-Complete.fmw C:\FMEData2017\Workspaces\DesktopAdvanced\CustomTransformers-Ex3-Complete-Advanced.fmw |
A colleague - with our help - has created a custom transformer that calculates density for a particular area. However, we need to work on it further to make it more generic - and to expand its capabilities.
This transformer was created using the automatic schema handling parameter and the workspace will already be handling schema properly. So, to an extent we don't have to worry - but there are improvements we can make.
1) Start Workbench
Continue with the workspace from exercise 2, or open the workspace: C:\FMEData2017\Workspaces\DesktopAdvanced\CustomTransformers-Ex3-Begin.fmw
Notice that, currently there are two instances of the custom transformer. Both produce an attribute with the same name (DensityValue). It would be helpful if the user of the custom transformer could define what the name of that attribute should be. Let's set up the transformer to allow that.
First Officer Transformer says... |
This is why - so far - we've had the two transformers in parallel streams. If we had them in series in the same stream then the results of the second custom transformer would overwrite the results of the first. |
Click on the tab labelled DensityEvaluator to switch the canvas to the custom transformer definition. Inspect the parameters for the ExpressionEvaluator. Next to New Attribute (DensityResult) click the down-arrow and choose User Parameter > Create User Parameter:
When prompted, click OK to accept the default settings. Return to the main tab and check the parameters for each custom transformer instance. There should be the option to set the name of the attribute to output:
You can now move the instances so they are joined in sequence (rather than parallel) and change the two output attribute names to something different (PopulationDensity2001 and PopulationDensity2011):
First Officer Transformer says… |
At first glance it might appear that we've simply reverted the custom transformer right back to where we started from. To an extent, that's true. However, the point is that we've now got a solution that can work in other scenarios (i.e. where something other than population density is being calculated). |
2) Set Parameter Prompts
Looking at the custom transformer parameters we can also see that the prompt for the attribute to analyze is called "TotalPopulation2001". Obviously this is not very generic.
Return to the custom transformer definition tab and browse the Navigator window to find the related published parameter. Right-click on the parameter and choose Edit Definition.
In the dialog that opens set the parameter name to DensityAttribute and the prompt to Attribute to Analyze:
Click OK to close the dialog. Return to the main tab and check the custom transformer parameters to prove the label change worked, and run the workspace to show that the output is still correct.
First Officer Transformer says… |
It's because we chose to handle schema automatically that we can simply change this user parameter name and not worry about where it is used. FME will handle the name change wherever is necessary. |
3) Implement Units Selection
At the moment this workspace is calculating the number of items (in this exercise, persons) per square kilometre of land. This works for the original scenario, however, other uses of this transformer might find different units to be more useful.
Therefore we’ll implement a parameter for users to be able to select their units of choice.
In the custom transformer definition, browse the Navigator window and right-click on the entry labelled User Parameters. Select the Add Parameter option.
.1 UPDATE |
In 2017.1 this is now called Create User Parameter |
In the Add/Edit User Parameter dialog, set the following parameters:
Type | Choice with Alias |
Name | DensityUnits |
Prompt | Density Units |
Uncheck the check box parameter labelled Optional because the user has to select a value.
Now click the [...] button to the right of the Configuration parameter. This opens a dialog in which to define choices for the user to select from. Make two entries into this dialog
Display Name | Value |
---|---|
Sq Metres | 1 |
Sq Kilometres | 0.000001 |
To save you counting, that's five zeros after the decimal place.
Click OK to close that dialog.
Back in the Add/Edit User Parameter dialog set:
Attribute Assignment | Off |
Default Value | Sq Kilometres |
Then click OK to close this dialog and add the published parameter.
First Officer Transformer says… |
Feel free to add any other units that you want. The units for this coordinate system are in metres, which is why that has a value of 1. So other units would need to be a fraction of that; for example square miles would be (I think) 0.0000003861 |
4) Implement Parameter
Now we’ve defined a published parameter that the user can set the units with, but we still have to apply it in the custom transformer.
Inspect the parameters for the AreaCalculator transformer. For the Multiplier field, click the drop-down arrow and select the newly defined user parameter, DensityUnits:
Back in the main canvas the custom transformer now has a parameter for the end user to select the output density units:
Experiment by running the workspace using different units, to prove that the changes were implemented properly. Notice that, because Attribute Assignment was set to "Off" that the end-user isn't able to select an attribute.
Advanced Exercise |
Although it’s not needed for this population density calculation, another useful function for this transformer would be the ability to apply a weighting to the density calculations. If you have time, carry out the following steps to set it up.
The weighting will come from an incoming attribute, which means we need to be able to handle this in the custom transformer’s schema. |
5) Add RandomNumberGenerator
Our source data doesn't have any fields we could reasonably use for weighting the output. Therefore return to the Main canvas tab and add a RandomNumberGenerator transformer in order to generate a test attribute:
Inspect the parameters dialog for the RandomNumberGenerator and, for the purposes of this exercise, set:
Minimum Value | 0.1 |
Maximum Value | 1 |
Decimal Places | 1 |
Result Attribute | WeightingAttribute |
6) Expose Attribute in Custom Transformer
Now we have an attribute we need to expose it in the custom transformer, in order to use it.
Return to the DensityEvaluator tab where the transformer is defined. Inspect the parameters for the Input port object. Put a checkmark against the WeightingAttribute attribute:
This will cause the attribute to be exposed in the custom transformer definition.
It will also cause a user parameter to be created. Locate the parameter in the Navigator window (it should be called WEIGHTINGATTRIBUTE) right-click on it and choose Edit Definition.
Put a checkmark in the Optional field, as this should not be compulsory (the user might not have an attribute to weight the results by):
7) Duplicate ExpressionEvaluator
Now we can use the attribute inside the custom transformer.
Make a duplicate copy of the existing ExpressionEvaluator and connect it in parallel to the current one. Then put a Tester in beforehand where the Passed port goes to one ExpressionEvaluator and the Failed port goes to the other:
8) Set up Tester
Inspect the Tester parameters and make a test for where WeightingAttribute > 0
9) Adjust Equation
Now that the attribute is exposed in the custom transformer, we can use it in the equation for calculating density. Inspect the parameters for the ExpressionEvaluator transformer connected to the Tester:Passed port.
Change the equation to:
@Value(TotalPopulation2001)/(@Value(NeighborhoodArea)*@Value(WeightingAttribute))
i.e. multiply the existing NeighborhoodArea attribute by the WeightingAttribute and place parentheses around that part of the expression.
Save the parameter changes and run the workspace to check the result. Remember – the results will be different every time because we’re generating the weighting attribute randomly at run time!
Experiment selecting the weighting attribute in the main canvas, and not selecting it. When no attribute is selected then the features should pass through the Failed port and no weighting is used in the calculation:
First Officer Transformer says… |
It may seem odd – especially to experienced users – that we would use the attribute in the expression, and not the published parameter. But this is all part of how FME handles this behavior automatically. It avoids the author needing to know about published parameters and how to use them, and uses hidden functionality to replace the attribute with the published parameter wherever necessary. |
CONGRATULATIONS |
By completing this exercise you have learned how to:
|