Model Builder - Write calculated output to shapefile field

735
5
08-26-2013 12:17 PM
by Anonymous User
Not applicable
Original User: blingenfelder

I am somewhat new to creating models and have run into a problem with the one that I am currently working on.  My goal is to Iterate rows of one shapefile, "sections", and perform a select by location to find the "tracts" that have their centroid in each section.  Then, I would like to summarize a field for these selected tracts within each section. 

I have successfully done this and output the values to a table, although the table will only keep one record at a time, overwriting the table each time instead of adding a new row.  Even so, I am trying to figure out a way to add this calculated value to a field of the current record in the iteration of my "sections" shapefile.

I have explored the option of trying to do a table join, but I don't think that this will work because of the many to one (tracts to section) relationship and that there is no unique key between the two.  I will attach my script and graphic.  Any advice would help, thanks in advance!

[ATTACH=CONFIG]26997[/ATTACH]


# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------
# Test.py
# Created on: 2013-08-26 15:08:04.00000
#   (generated by ArcGIS/ModelBuilder)
# Description: 
# ---------------------------------------------------------------------------

# Import arcpy module
import arcpy

# Load required toolboxes
arcpy.ImportToolbox("Model Functions")


# Local variables:
LPMGIS_LEASE_ACTIVE_TRACT = "Core Layers\\LPMGIS.LEASE.ACTIVE_TRACT"
Sections_Result = "Sections_Result"
Sections = "Sections"
I_Sections = "I_Sections_FID"
LPMGIS_LEASE_ACTIVE_TRACT__3_ = "Core Layers\\LPMGIS.LEASE.ACTIVE_TRACT"
grs_acre_sum = "U:\\SectionAcreageTest\\grs_acre_sum"

# Process: Iterate Row Selection
arcpy.IterateRowSelection_mb(Sections, "", "false")

# Process: Select Layer By Location
arcpy.SelectLayerByLocation_management(LPMGIS_LEASE_ACTIVE_TRACT, "HAVE_THEIR_CENTER_IN", I_Sections, "", "NEW_SELECTION")

# Process: Summary Statistics
arcpy.Statistics_analysis(LPMGIS_LEASE_ACTIVE_TRACT__3_, grs_acre_sum, "T_GRS_AREA SUM", "")

# Process: Get Field Value
arcpy.GetFieldValue_mb(grs_acre_sum, "SUM_T_GRS_AREA", "Double", "0")

0 Kudos
5 Replies
by Anonymous User
Not applicable
Original User: dmhoneycutt

Seems to me that you could avoid all the iteration and just use the Spatial Join tool.

target_features = The sections
join_features = tracts
join_operation = JOIN_ONE_TO_MANY
match_option = HAVE_THEIR_CENTER_IN

The field map is where you define whether you want the Sum / Mean / Min / Max of a particular field.
0 Kudos
by Anonymous User
Not applicable
Original User: blingenfelder

Thanks for the response.. After trying out a few different methods with the spatial join, I thought I had it.  First, I had to make it a 1 to 1 in order to keep the correct number of records from sections.  This method does work, but only in some cases.  It seems that it sort of works backwards for my purpose.

Instead of selecting the Tracts that have their center within the Section, it goes by the center of the Section being within a Tract.  Therefore, if a Section contains Tracts, but none in its center, the resulting sum is 0, when it should be say 80.  If I were to switch the target and selecting features, it would instead output tract polys when I need section polys.

I don't think that I will be able to accomplish what I am trying to with a join, unless I had a common field.  But I basically have the correct answer as a value with the iterations and just need to populate a field of the currently selected row of Sections.  I am wondering if there is some way to say "[Sections.Field]" = "[Grs_acre_sum.Field]" where Grs_acre_sum is the table output by the summary statistics.  Is this possible?
0 Kudos
DaleHoneycutt
Regular Contributor
In your model, you could use the Calculate Field tool with variable substitution.  The model variable "Value (2)" contains the value of Grs_acre_sum.  First, add a field to your sections named something like "GRS_acres".  Then, in your model, add the Calculate Field tool.  The input table is t_sections, the field is GRS_acres, and the value is %Value (2)%.  This should work in theory, but I haven't tested it for syntax - but I think you get the idea.

As an alternative, you could run the Feature To Point tool on your tracts. Be sure to check the "Inside" option.  This will create a point feature class of tract centroids with all the attributes of the tracts.  Now that you have centroid points, just about any overlay operation will get you what you want.  You could run Spatial Join with the target=sections, join=centroids, join one_to_many, with the INTERSECT option.  Or run Identity or Intersect followed by Summary Statistics.  But the easiest is probably Spatial Join.

After re-reading the doc, I discovered that the HAVE_THEIR_CENTER_IN option doesn't do what you'd like it to do (and what I thought it would do) -- it's the centroid of the target features that is used.
0 Kudos
by Anonymous User
Not applicable
Original User: rfairhur24

Thanks for the response.. After trying out a few different methods with the spatial join, I thought I had it.  First, I had to make it a 1 to 1 in order to keep the correct number of records from sections.  This method does work, but only in some cases.  It seems that it sort of works backwards for my purpose.

Instead of selecting the Tracts that have their center within the Section, it goes by the center of the Section being within a Tract.  Therefore, if a Section contains Tracts, but none in its center, the resulting sum is 0, when it should be say 80.  If I were to switch the target and selecting features, it would instead output tract polys when I need section polys.

I don't think that I will be able to accomplish what I am trying to with a join, unless I had a common field.  But I basically have the correct answer as a value with the iterations and just need to populate a field of the currently selected row of Sections.  I am wondering if there is some way to say "[Sections.Field]" = "[Grs_acre_sum.Field]" where Grs_acre_sum is the table output by the summary statistics.  Is this possible?


Do the Spatial Join as an Intersect with the Tract Centroids by creating a Centroid point layer from the Tract first, then doing the spatial join.  If you have an Advanced license you can use the Feature to Point tool to extract the Centroid points of the tracts to a point layer.

If you don't have an Advanced license you can still extract the Centroids of the tracts into a point feature layer. 

1.  First create two double fields in your tracts for the X and Y coordinates of the Centroid and use the Geometry Calculator to calculate those values.
2.  Then export the attributes of the tract features to a stand alone table.
3.  Use the Make XY Events Layer with the exported table Centroid coordinates to make a point layer. 

Now you can use that XY Event layer with the Spatial Join as the Join features and apply the normal Intersect as the match option.
0 Kudos
by Anonymous User
Not applicable
Original User: blingenfelder

That's it!  the variable substitution worked great!  I had tried almost the same thing before, but did not know about variable substitution and did not include the '%' on either side of the value.  Thank you!

-Brad
0 Kudos