Select to view content in your preferred language

Python: select by Location and assign value from the source to the target

2269
13
03-06-2014 05:10 PM
RyanFadd
Emerging Contributor
Hi All

I have a polygon layer with a 'lot' field and a points layer. I would like to use python to select the points by location (to find what points are contained in what polygons) and assign the value in the 'lot' field from the polygon layer to the point that is contained in the relevant polygon feature. Not sure how to create that link between the 2 layers...

Any help is much appreciated.
Thank you
Tags (2)
0 Kudos
13 Replies
GregSnelling
Regular Contributor
There are 3 ways I can think of:

1) Use arcpy to spatially join the lot attribute from the polygon to the point.
http://resources.arcgis.com/en/help/main/10.1/index.html#//00080000000q000000


2) Use ArcPy to convert polygons to points and keep the attributes.  The points will be populated with the Lot values.
http://http://resources.arcgis.com/en/help/main/10.1/index.html#/Feature_To_Point/00170000003m000000...

3) Use ArcPy to Select By Location, then calculate the point field values to equal lot number from the selected polygon feature; then use iterations of this process for each polygon in your feature class. 

In my opinion I'd go with option 2 because it's the easiest. Option 3 is probably a more of a "learning experience".


Have fun!

G
0 Kudos
DavidBuehler
Frequent Contributor

Ryan,

Did you ever find a solution to your question?  Which option did you choose?

0 Kudos
DarrenWiens2
MVP Honored Contributor

What's wrong with Spatial Join?

0 Kudos
DavidBuehler
Frequent Contributor

Darren,

In my workflow option 3 might be a better an option. Spatial Join produces a  whole new feature class as an output, instead of transferring an attribute from a selected polygon to the point features within the selected polygon.  Thoughts?

0 Kudos
DarrenWiens2
MVP Honored Contributor

Oh I see. It probably depends somewhat on the size of the datasets. Suppose there are 1000 points. You could do 1000 individual selections/field calculations, or 1 spatial join (to an in-memory feature class if you don't want to keep it) then 1 join then 1 field calculation. I'm guessing the second option is faster, but haven't tested.

0 Kudos
DavidBuehler
Frequent Contributor

Darren,

I know I am not an efficient python scripter, so bear with me. I have attempted to script it with spatial join. The goal is to calculate the zone of a concern for only the ones that the zone field is null. Both feature classes are in an enterprise environment (the concerns and the zones).  Here is what I have so far from testing on a file geodatabase.  I am not sure it is joining properly and the field calculator dies. Any suggestions?

# import modules
import arcpy

# Set workspaces
workspace = r'C:\ESRITest\GeoReportingSystem\Testing9116\Testing9116.gdb'
outWorkspace = r'C:\ESRITest\GeoReportingSystem\Testing9116\Scratch.gdb'

targetFeatures = r'C:\ESRITest\GeoReportingSystem\Testing9116\Testing9116.gdb\GeoReporting'
joinFeatures = r'C:\ESRITest\GeoReportingSystem\Testing9116\Testing9116.gdb\GRSAldermanic'

outfc = r'C:\ESRITest\GeoReportingSystem\Testing9116\Scratch.gdb\AldermanicSJ'

fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(targetFeatures)
fieldmappings.addTable(joinFeatures)

# Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script
# The following inputs are layers or table views: "GeoReporting Features", "GRSAldermanic"
arcpy.SpatialJoin_analysis(target_features=targetFeatures, join_features=joinFeatures, out_feature_class=outfc, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_COMMON", field_mapping=fieldmappings, match_option="INTERSECT", search_radius="", distance_field_name="")

print "Done with Spatial Join"

# Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script
# The following inputs are layers or table views: "AldermanicSJ"
arcpy.DeleteField_management(in_table=outfc, drop_field="SpecificConcern;DescriptionOfConcern;ReportingEmail;DateClosed;ConcernStatus;PriorityLevel;PrimaryDepartment;PrimaryContact;PrimaryInformation;DeptLogging;ReportingMethod;FollowUpRequest;FollowUpContactInfo;AldermanicDistrict;ApproriateYN;NUMVOTES;DaysToClose;Match_Addr;Loc_Name;created_user;created_date;last_edited_user;last_edited_date;Address;Visibility;Report_ID;DISTRICTID")

print "Done with Deleting Fields"

arcpy.MakeFeatureLayer_management(outfc, "outfc_view")
arcpy.MakeFeatureLayer_management(targetFeatures, "GRE_view")
# arcpy.MakeFeatureLayer_management(targetFeatures, "GRE_view")
arcpy.AddJoin_management("GRE_view", "ConcernID", "outfc_view", "ConcernID")

print "Joined Up Sir"

fieldName1 = "GRE_view.AldermanicDistrict"
fieldName2 = "!outfc_view.NAME!"

# Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script
# The following inputs are layers or table views: "GeoReporting Features"
arcpy.CalculateField_management(in_table=targetFeatures, field=fieldName1, expression=fieldName2, expression_type="PYTHON", code_block="")

print "Field Calculation Done"

arcpy.RemoveJoin_management(in_layer_or_view=targetFeatures)

print "Removed Join"

arcpy.DeleteFeatures_management(outfc)

print "Spatial Join feature class deleted"
0 Kudos
DarrenWiens2
MVP Honored Contributor

Perhaps try expression_type="PYTHON_9.3". If that doesn't work, can you provide the error message?

0 Kudos
DavidBuehler
Frequent Contributor

ExecuteError: Failed to execute. Parameters are not valid.

Error 000728: Field GRE_view.AldermanicDistrict does not exist within table

Failed to to execute (CalculateField).

0 Kudos
DarrenWiens2
MVP Honored Contributor

Have you tried running through the workflow manually to see exactly what's going on? You could also verify the field names like:

print [i.name for i in arcpy.ListFields('GRE_view')‍‍]
0 Kudos