I am looking to apply a Select By Location protocol to my data, but need to first query individual IDs in my target and source layer (the same ID in each table, one at a time). How do I loop through a query? I have far too many IDs to manually set a query in each table then perform the selection.
Is there a way to create a looping model (with parameters) or script that will systematically select each (matching) ID in my target and source layers then perform the tools I specify?
I have used the Iterate Feature Selection tool in ModelBuilder to select by ID field in my target layer, but ModelBuilder will not let me have two iterators in the model (even if I could, there is no way to guarantee the iterators are selecting the same IDs at the same time). I have tried linking the Value output of the iterator to a Select by Attribute tool for my source layer but the value can only be set as the whole expression, not part of it.
So I am nearly there.
enter image description here
After extensive discussion with Roy this is the code I've come up with. Unfortunately, while no errors pop up when I run it, nothing actually happens. The process is marked as completely immediately after I run it and nothing has changed. Any thoughts?
rows = arcpy.SearchCursor("hmb_logbook_2009")
for row in rows:
whereClause = '"trip_id" = ' + str(row.trip_id)
arcpy.MakeFeatureLayer_management("hmb_logbook_2009", "currentLines", whereClause)
arcpy.SelectLayerByLocation_management("hmb2009", "WITHIN_A_DISTANCE", "currentLines", "1 Miles", "NEW_SELECTION")
arcpy.SelectLayerByAttribute_managemet("hmb2009", "SUBSET_SELECTION", ' "trip_id" = ' + str(row.trip_id))
arcpy.CalculateField_management("hmb2009", "match_activity", 1)
arcpy.SelectLayerByAttribute_managemet("hmb2009", "CLEAR_SELECTION")
arcpy.Delete_management("currentLines")
del row, rows
1 Answer 1
@Geoist is right. You'll have much more control over this using Python -- you can nest as many loops as you damn well please.
Pseudo Code:
- Create a search cursor
- Loop through each record with a for loop
- Compose a whereClause using the ObjectID (unique identifier)
- Make feature layer
- Select by location
- etc. (delete feature layer to end the loop)
Code Example:
try:
polys = arcpy.SearchCursor(polygonFeatures)
for poly in polys:
# Create a clause to select only the current record
whereClause = '"OBJECTID" = ' + str(poly.OBJECTID)
# Create a feature layer from the current row only
arcpy.MakeFeatureLayer_management(polygonFeatures, "currentPolygon", whereclause)
# Select all features from thisFeature that intersect the feature layer
arcpy.SelectLayerByLocation_management(thisFeature, "INTERSECT", "currentPolygon")
# Do your thing with your spatial selection (this example: create a new featureclass)
arcpy.Copy_management(thisFeature, outFeatureClass)
arcpy.Delete_management("currentPolygon")
except:
print arcpy.GetMessages()
finally:
# This will run if the script is successful or not.
if row:
del row, rows
-
The Model Builder is good for testing out and visualizing workflows. It is also great starting point for developing scripts, using the export option to export to your scripting language of choice. That being said, it can be very difficult to build a model that runs consistently across different sessions, connections and machines. In the long run, the extra effort necessary to develop a script is worthwhile for the added flexibility, control and stability. Have fun.Brent Edwards– Brent Edwards2012年08月01日 13:06:48 +00:00Commented Aug 1, 2012 at 13:06
-
Agreed - I use model builder for documenting my analysis (it's much easier for most people to understand than looking at code). That being said I don't like to export models to scripts. It's sort of like using Dreamweaver to make a website WYSIWYG style -- I'm not a fan of the code it churns out. Might just be a personal style preference tho.Roy– Roy2012年08月01日 13:14:25 +00:00Commented Aug 1, 2012 at 13:14
-
I understand where and for clauses, my problem is that if I use Python I am nesting an arcpy tool (Select By Location) in a Cursor and for whatever reason that doesn't work for me. I get an error that there is a lock on the layer. I will try it again though.AlmaThom– AlmaThom2012年08月01日 16:59:16 +00:00Commented Aug 1, 2012 at 16:59
-
If that's the case we need the error messages -- I use this technique regularly, and can confirm that it works.Roy– Roy2012年08月01日 17:11:14 +00:00Commented Aug 1, 2012 at 17:11
-
1Then you might as well continue to use an UpdateCursor now -- use a
try:
,except:
andfinally:
block to make sure you delete your cursor at the end of your script as illustrated in my sample code.Roy– Roy2012年08月01日 17:24:52 +00:00Commented Aug 1, 2012 at 17:24
foreach
andfor
processes.