I have a polygon shapefile (selected in the attached pic) and a geologic table shapefile containing rock types (text) and an arbitrary corresponding number value (integer). Most polygons exist completely within a certain rock type. However, some polygons cross over multiple, different rock types. I would like to perform some kind of spatial join that determines what the most predominant rock type is within each polygon and assigns a single rock type. None of the merge rules (ie, first, last, max, min, etc) seem to accomplish this. In the screenshot, there are three geologic rock types within the selected polygon. I wish to add only "Kch" as the final attribute. This would seem to be a "majority" rule. However, I don't see an option anywhere for majority other than zonal statistics which produces a raster which I don't want. Thanks!
Solved! Go to Solution.
there is no "one" tool, but a process which may include
Tabulate Intersection (Analysis)—ArcGIS Pro | Documentation
Summarize Within (Analysis)—ArcGIS Pro | Documentation
or some of the other summary tools
Error 100014 is explained here.
Try exporting your shapefiles to fGDB feature classes and try it again.
I'd recommend Tabulate intersection as Dan suggested. Then probably create a new field and use Calculate Field with Python or Arcade to return the Field Name of the rock type field which has the highest Area.
Then you can clean up by deleting all the rock fields if necessary.
I'd certainly just run the Tabulate Intersection first and you'll understand what I mean when you look at the output. Also definitely check out the link dan provided which explains the tool.
there is no "one" tool, but a process which may include
Tabulate Intersection (Analysis)—ArcGIS Pro | Documentation
Summarize Within (Analysis)—ArcGIS Pro | Documentation
or some of the other summary tools
I keep getting "Error 100014" when summarize within fails. I've tried shortening the path, etc. Maybe I'm trying to work with too many polygons (over 25,000)?
I'd recommend Tabulate intersection as Dan suggested. Then probably create a new field and use Calculate Field with Python or Arcade to return the Field Name of the rock type field which has the highest Area.
Then you can clean up by deleting all the rock fields if necessary.
I'd certainly just run the Tabulate Intersection first and you'll understand what I mean when you look at the output. Also definitely check out the link dan provided which explains the tool.
What code/function would I use in calculate field? I've tried getMaxField(!Field1!,!Field2!,!Field3!) with no luck.
python's is max
I don't know what your field names are, but the pythons examples can be found here
Solved: Re: How do I add a field for the predominant geolo... - Esri Community
max([!field1!, !field2!, !field3!])
you provide the ! enclosed field names within [ ] brackets, which is a list, hence the expression finds the maximum in a list of entities
This is a partial screenshot of my table. I've created the Rock Type field and want to populate it with the corresponding field name containing the highest value. So not the actual value. Most cells are null. When using the max function, i get an error that "Certain rows set to NULL due to error while evaluating python expression: TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'".
I can see getMaxField() used for another post. It's not a native function and is defined in the code block at the bottom of field calculator.
This works for me. Ensure you past the following into the 'Code Block' at the bottom of the Field Calculator window.
def maxValue(*args):
filtered = [arg for arg in args if arg is not None]
return (max(filtered)) if filtered else None
then above the Code Block you will have something that looks like <fieldname being calculated> =
in the box below that enter (obviously replace with your fieldnames:
maxValue(!yourField1!, !yourField2! .... )
That returns the max value across all the fields. However, I need to return the field name containing the highest value. In my screen shot above, I need the "Rock Type" field to be calculated in such a way that the resulting values are "Qal_AU", etc.
Ah Ok. Can't be done in Field Calculator as the fieldnames aren't exposed as variables. locals() return nothing useful from what I can see.
Easy enough in a standalone script or Python window with arcpy UpdateCursor.
Update the below with your field names and filepath.
This will modify the input data with no undo. Advise making a copy of your data from testing and sanity-check the results on a subset of data.
import arcpy
#note does not account for equal Max values
#just chooses one of the rock types even if both 50%
#path to your data
#remove from Pro ToC if lock encountered
filepath = r'C:\ArcGIS\GeologyRocks.gdb\Rock_stuff'
#list of field names countaining values
#to get max of
value_fields = ['Granite', 'Sand', 'Clay']
#name of field to be updated with rock types
max_field = ['Predominant_Geology']
fields = value_fields + max_field
#value to write if null or error etc.
null_string = 'unknown'
with arcpy.da.UpdateCursor(filepath, fields) as cursor:
for row in cursor:
values = {fields[i] : row[i] for i in range(len(fields)) if row[i] is not None}
if values:
max_field = max(values, key=values.get)
row[-1] = max_field
else:
row[-1] = null_string
cursor.updateRow(row)