4

I have two shapefiles that contain position information for individuals, one is their reported location (line segments) and the other is their high-frequency recorded location (point data); they have an ID field that is common between them. What I am looking to do is identify the reported locations in the larger recorded data set with a spatial selection. The problem is my data is so condensed that I cannot do a simple select by location. There is too much overlap of individual locations. I also have over 1,000 individual IDs so I don't want to individually query each ID.

What I am looking for is a way to use possibly a cursor to go through each unique ID, query only the records in each table that share that ID, then do the spatial selection. I am very new to cursors and scripting in general so I don't know if a cursor can be used for two tables. (This may be irrelevant but for this process I can convert my line data to point data if having the same type of shapefiles is important.)

(Removed previous code that I am no longer using)

I am also unaware if maybe Make Query Table will work for this (I have never used it).
Thanks!

UPDATE: Here is a new code that I worked on with a fellow GIS person. GOOD NEWS! After leaving ArcGIS alone for a while, my code ran! It went as expected, but only did one iteration on one ID. The iteration should be implied in the Cursor as far as I know, or is there a line of code I'm missing that tells the Cursor to repeat for all IDs?

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_management("hmb2009", "SUBSET_SELECTION", ' "trip_id" = ' + str(row.trip_id))
    arcpy.CalculateField_management("hmb2009", "match_activity", 1)
    arcpy.SelectLayerByAttribute_management("hmb2009", "CLEAR_SELECTION")
    arcpy.Delete_management("currentLines")
del row, rows 

UPDATE 2: So I have troubleshooted, and the reason the code only ran once is this error associated with my Make Feature Layer tool. Here is the error message: ERROR 000622: Failed to execute (Make Feature Layer). Parameters are not valid. ERROR 000628: Cannot set input into parameter in_features.
I tried putting the full address into that tool (only that one) instead of referencing the layer in the map and it works!

6
  • re "I know I shouldn't use arcpy tools in a Cursor", I don't think there's anything wrong with what you've done. The cursor simply allows you to iterate through the selected features - you can do what you need once you have a pointer to the record Jul 31, 2012 at 6:26
  • When I run the above script I get this error: ERROR 999999: Error executing function. Cannot acquire a lock. Cannot acquire a lock. [The table reported_lines is being written by another process.] Failed to execute (SelectLayerByLocation). The good news is it does not have my problem of a Cursor within a Cursor, the bad news is it does not like my Select tool. Any ideas?
    – AlmaThom
    Jul 31, 2012 at 16:36
  • I am assuming the issue is that the Select tool and the Cursor cannot simultaneously access the data, I have been looking online for other cases of people using arcpy tools inside a Cursor and am turning up nothing. Does anyone have experience with this?
    – AlmaThom
    Jul 31, 2012 at 16:49
  • you're using an UpdateCursor, which is an editing operation (requiring exclusive access to the table). Can you use a SearchCursor instead? Also, try closing any applications which are looking at the table (ArcCatalog, ArcMap, etc) as they may be locking it. If your script crashes, try closing and reopening Python to remove the lock. Jul 31, 2012 at 23:00
  • PS try installing PythonWin from the ArcGIS DVD as it allows you to step through your code in debug mode, to see when the error occurs. I suspect you'll find that the error isn't being thrown by the SelectByLocation line, but by the UpdateCursor (or something else) Aug 1, 2012 at 1:23

2 Answers 2

1
rows = arcpy.SearchCursor("hmb_logbook_2009")

It's not certain that arcpy will know how to find the file. Try specifying the full path to hmb_logbook_2009.

To debug this, put a PythonWin breakpoint on the line above, then step through your code using F10. You can also type the commands manually into the interactive window. This will give you a better feel for where the errors are occurring.

(Depending on what you're trying to do, it may make more sense to put the whereClause in the searchCursor, but that's a separate issue.)

Keep with it, you'll work it out eventually and it'll be worth it in the end!

4
  • Row by row this one turned out to be the problem child, you're right. Even with a full path, it still crashes PythonWin. Can you clarify what you mean by "it may make more sense to put the whereClause in the searchCursor"? I'm assuming you mean writing the clause into the arcpy.SearchCursor(...) rather than inside the for block? Would that make a difference?
    – AlmaThom
    Aug 2, 2012 at 0:34
  • Can you bundle the whole project up (datasets and code) and put it somewhere publicly accessible (eg Dropbox)? Aug 2, 2012 at 1:15
  • Unfortunately this data is highly proprietary and I would get in a lot of trouble for sharing it, even a small subset that has been edited. Not that it is much use without the data, but here is my code: dl.dropbox.com/u/24597880/SearchCursor.py
    – AlmaThom
    Aug 2, 2012 at 15:56
  • Specifying the full path in that line (and a few others) has finally done the trick, thanks!
    – AlmaThom
    Aug 2, 2012 at 18:49
1

Might be worth trying something with a relate... then a sub-selection by location. Would avoid having to code... (i.e. create a relationship between the two FC's, do a spatial selection, create a layer from the spatial selection, then use the relate to narrow the selection down to only those records that share the ID AND that are within your spatial selection).

Alternatively as above suggestion by Stephen Lead... break the code down into parts and run them in the interactive window. I also sometimes cheat and build as far as I can in Model Builder, then convert to a Python script, and work with it from there.

1
  • I thought about using relate, but as far as I know there is no way to get that type of setup to iterate for every ID.
    – AlmaThom
    Aug 2, 2012 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.