Solved

Transformer for equivalent of Update Column in MapInfo with 2 polygon files

  • 5 February 2020
  • 7 replies
  • 6 views

Badge

Hello All,

I have 2 polygon MapInfo files - land classification and farms. I want to update columns in the Farms table with the classification/s in the Land Classification table where they overlap. I can't work out how to do this as there may be multiple (though not overlapping) classification polygon areas for each Farm, so I want to update the % overlap for each column - Grade 1, Grade 2 etc. I can produce separate files for each grade, but not then update columns in the master Farms table.

Any help would be much appreciated.

Thanks,

Jane

icon

Best answer by bwn 6 February 2020, 12:48

View original

7 replies

Userlevel 2
Badge +12

Try This:First use AreaCalculator on the farms to calculate FarmArea.

Then do the AreaonAreaOverlayer to get overlaps of farm and land classification.

Each new area has the farm and class attributes.

Another AreaCalculator will get the area of the overlap in _area.

The percentage can be calculated using ExpressionEvaluator as 100 * FarmArea/_area

Hope this helps.

Badge

Many thanks Erik, I shall give it a go. It was getting late after a long day - I meant "Transformer" of course instead of Translator.

Badge +3

A bit of a warning on AreaOnAreaOverlayer. If the Farm polygons happen to also overlay each other then they will possibly not get the attributes of Land Classifications since Attribute Merging is done on first come-first serve basis in the Transformer depending on the order that the Features enter the single Input Port and one Farm may just merge the attributes from another overlaying Farm rather than a Land Classification. I find to use it when feeding it multiple layers that I need to tightly control it with the Group By set to a group identifier that only overlays one feature from the layer I want to update, with a corresponding group identifier that corresponds to spatially related features from the layer I want to get the values from.

An alternative is to use Clipper with Merge Attributes enabled, with the Farms as the Clippee and the Land Classifications as the Clipper. It is a little bit slower than AreaOnAreaOverlayer, but at least all the Output features are the Farms Polygons only (AreaOnAreaOverlayer will output any sections of the Land Classifications that don't overlay a Farm and these will need to be filtered out). Another advantage is that if there are farms that overlap each other in any place, they won't clip each other.

Badge

A bit of a warning on AreaOnAreaOverlayer. If the Farm polygons happen to also overlay each other then they will possibly not get the attributes of Land Classifications since Attribute Merging is done on first come-first serve basis in the Transformer depending on the order that the Features enter the single Input Port and one Farm may just merge the attributes from another overlaying Farm rather than a Land Classification. I find to use it when feeding it multiple layers that I need to tightly control it with the Group By set to a group identifier that only overlays one feature from the layer I want to update, with a corresponding group identifier that corresponds to spatially related features from the layer I want to get the values from.

An alternative is to use Clipper with Merge Attributes enabled, with the Farms as the Clippee and the Land Classifications as the Clipper. It is a little bit slower than AreaOnAreaOverlayer, but at least all the Output features are the Farms Polygons only (AreaOnAreaOverlayer will output any sections of the Land Classifications that don't overlay a Farm and these will need to be filtered out). Another advantage is that if there are farms that overlap each other in any place, they won't clip each other.

Thank you - I went with the Clipper route with Merge Attributes, then AreaCalculator, Aggregator and Expression Evaluator for % overlap, and I end up with a table with all the grades in one column - so there can be multiple records for each Farm whereas I want one record for each Farm with the grades in separate columns. So I then use Testers to split them out and in MapInfo use Update Column to populate the separate Grade1, Grade2, Grade3 etc. columns in the final MapInfo table of Farms (one record for each Farm) with the percentage overlap of grade. I can't see how to do this in FME I'm afraid.

Badge +3

Thank you - I went with the Clipper route with Merge Attributes, then AreaCalculator, Aggregator and Expression Evaluator for % overlap, and I end up with a table with all the grades in one column - so there can be multiple records for each Farm whereas I want one record for each Farm with the grades in separate columns.  So I then use Testers to split them out and in MapInfo use Update Column to populate the separate Grade1, Grade2, Grade3 etc. columns in the final MapInfo table of Farms (one record for each Farm) with the percentage overlap of grade.  I can't see how to do this in FME I'm afraid.

@janem There are lots of different ways to CrossTab in FME:

  • One method may be to use AttributePivoter. Set "Group Rows By" = FarmID; "Group Columns By" = GradeID; "Attribute to Analyze" = PercentageArea (As a Sum)
  • A similar method is to rename the Single Attribute "PercentageArea" to Eg. "Grade 1", "Grade 2", "Grade 3 etc. based on the what the value is for that Farm Feature. With FME, think of it this way: The "Name" of an Attribute isn't a fixed field name like in database tables, it is actually just another property/value for that particular Attribute on that particular Feature. The Attribute Name can be recalculated to a different value, on a feature-by-feature basis. Knowing this, the "PercentageArea" attribute for every feature can be renamed dynamically with a formula Eg. a BulkAttributeRenamer in Regular Expression Mode
Selected Attributes: PercentageArea
Text to Find = .+
String = @Value(GradeID)

This way then the Attribute "PercentageArea" would be renamed to "Grade 1" if GradeID's value was "Grade 1" or be renamed to "Grade 2" if the value of GradeID was similarly "Grade 2" etc. If these were then sent to an Aggregator, Group By = Farm ID and Merge Attributes, then this will create a single feature for each Farm, with any values of PercentageArea appearing in separately named Attributes "Grade 1", "Grade 2" etc.

All the above methods though require an AttributeExposer at the end unless writing dynamically, since the Pivot Column Attribute Names are being set by formulae rather than a hard-coded string, and you have to "tell" FME what the resulting Attribute Name values will be since it won't know them until running the Workspace.

Yet another method is to use AttributeCreator in Conditional Value mode, whereby an Attribute "Grade 1" can be created but only get a value if the GradeID = "Grade 1" Else Null or Nothing. This can be a little tedious filling it out if there are a lot of Farm Grade values, but it doesn't require an AttributeExposer as at the same time you are setting the schema statically in the workspace.

Badge

@janem There are lots of different ways to CrossTab in FME:

  • One method may be to use AttributePivoter. Set "Group Rows By" = FarmID; "Group Columns By" = GradeID; "Attribute to Analyze" = PercentageArea (As a Sum)
  • A similar method is to rename the Single Attribute "PercentageArea" to Eg. "Grade 1", "Grade 2", "Grade 3 etc. based on the what the value is for that Farm Feature. With FME, think of it this way: The "Name" of an Attribute isn't a fixed field name like in database tables, it is actually just another property/value for that particular Attribute on that particular Feature. The Attribute Name can be recalculated to a different value, on a feature-by-feature basis. Knowing this, the "PercentageArea" attribute for every feature can be renamed dynamically with a formula Eg. a BulkAttributeRenamer in Regular Expression Mode
Selected Attributes: PercentageArea
Text to Find = .+
String = @Value(GradeID)

This way then the Attribute "PercentageArea" would be renamed to "Grade 1" if GradeID's value was "Grade 1" or be renamed to "Grade 2" if the value of GradeID was similarly "Grade 2" etc. If these were then sent to an Aggregator, Group By = Farm ID and Merge Attributes, then this will create a single feature for each Farm, with any values of PercentageArea appearing in separately named Attributes "Grade 1", "Grade 2" etc.

All the above methods though require an AttributeExposer at the end unless writing dynamically, since the Pivot Column Attribute Names are being set by formulae rather than a hard-coded string, and you have to "tell" FME what the resulting Attribute Name values will be since it won't know them until running the Workspace.

Yet another method is to use AttributeCreator in Conditional Value mode, whereby an Attribute "Grade 1" can be created but only get a value if the GradeID = "Grade 1" Else Null or Nothing. This can be a little tedious filling it out if there are a lot of Farm Grade values, but it doesn't require an AttributeExposer as at the same time you are setting the schema statically in the workspace.

Many thanks again - I like the sound of the BulkAttributeRenamer which seems to do what I want.  When I get time again I will have a try with that.

Badge

Just an update to this - I found that the BulkAttributeRenamer worked perfectly with the next dataset I was analysing - ancient woodland on farms. So I had a Clipper, AreaCalculator, Aggregator, FeatureJoiner using Inner Join and keeping the Unjoined Left features, ExpressionEvaluators (100*@Value(AW_area_ha)/@Value(Area_ha) and @Value(PercOverlapbyAW)*@Value(Area_ha)/100) to calculate percentage and ha overlap, BulkAttributeRenamer which takes the values out of PercOverlapbyAW and puts them into PAWS and ASNW (the values in the STATUS column) columns, Aggregator on FarmID and merging incoming attributes, AttributeExposer for the PAWS and ASNW fields, and NullAttributeMapper to make Null "Missing (Selected Attributes Only)" Empty values map to 0 (otherwise they populate in the MapInfo table with -9999).

I end up with a MapInfo table of all farm boundaries, with attributes for the percentage overlap of ancient woodland, split by type (PAWS and ASNW) into 2 columns.

I shall be able to use this workflow many more times, so very grateful for all help!

 

Reply