How do I clip a shapefile to a single-part shapefile using ArcGIS 9.3.1 and Python 2.5?

Example: I have a set of lines (lines.shp) I am trying to clip to each record in a shapefile called Grids.shp In grids.shp there is a field called [NAME] with a record for each grid; grid-1, grid-2, ...

The grids represent Map extents, and the lines will be roads/streams/other base layers (could not post base layers publicly so have provided Lines.shp as an example).

I have been trying to use the SearchCursor method but have some trouble defining objects and whatnot as I am new to Python. I got this same process to work in V10 but the V10 syntax is way different/simpler, especially for cursors and uses Python 2.6

EDIT (working script! thank you so much everyone): Clip_wCursor_v2a.py ESRI Forum with python script attached.

# ---------------------------------------------------------------------------
# Clip_wCursor_v2.py
# Created for ArcGIS 9.3.1
#   (clip generated by ArcGIS/ModelBuilder)
# Attempted cursor mods by a newb, Donovan
# ---------------------------------------------------------------------------

# Import system modules
import sys
import string
import os
import arcgisscripting

# Create the Geoprocessor object
gp = arcgisscripting.create(9.3)

# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")

# Designate a workspace
gp.workspace = r"C:\gis\data"

# Assign variables...
clipto = "grids.shp" # grids to clip to
clipit = "lines.shp" # features to be clipped

# Cursor time...
rows = gp.SearchCursor(grids)
row = rows.Next()
feat = row.Shape # used as the clip_features in the Clip_analysis
while row:
    n = str(row.NAME) # assign a variable for the processing message based on a field
    print "clipping to: " +n # tells you what grid was clipped
    # Clip_analysis <in_features> <clip_features> <out_feature_class> {cluster_tolerance}
    # output format, grid_1_c.shp, grid_2_c.shp, etc...
    gp.Clip_analysis(clipit, feat, str(row.NAME)+"_c"+".shp", "") #update str if necessary

# reset the array...
del rows
del gp

print "...fin..."
print "no error checking happened, examine your workspace..."

appreciate all the input,

I could only mark one as the correct answer, and i considered the fact that my original error was because of the lack of a while and improper use of row in the clip function, although the makefeaturelayer method is definitely valid!

  • Added a comment to answer your newest question about the row object problem. – Nathanus Apr 5 '11 at 3:57
  • @nath thanks, finally got it working but it seemed to work outside the while loop, would it matter? I haven't bothered to test it as it's working the way it is – SaultDon Apr 5 '11 at 17:16
  • I wasn't sure if the row.Shape reference would update along with the row loop, but I guess it does. I work in Arc10, so my cursors are iterable (while loops give me headaches :) ). – Nathanus Apr 5 '11 at 17:18

Since your cursor isn't iterable, use a while loop instead of a for loop:

rows = gp.SearchCursor(grids)
row = rows.Next()
while row: 
    ...do something with each row...
    row = rows.Next()
| improve this answer | |
  • Don't you just need the row = rows.Next() in the while loop? – djq Apr 4 '11 at 19:19
  • @celenius- I put the "do something..." line in there as a place holder. As I understand it, OP wants to run a clip with each feature. – Derek Swingley Apr 4 '11 at 20:30
  • 1
    thanks for this simpler cursor process, I've updated my script to incorporate this and it got all the way to the clip, but the clip is what has failed. I am trying some more troubleshooting in the morning and will get the post updated. – SaultDon Apr 5 '11 at 2:51
  • @Swingley I forget... is 10 the first version where cursors are iterable? – Nathanus Apr 5 '11 at 12:32

For one thing, I am pretty sure that when using a for loop, .next() is not required, since it automatically iterates through the object. In the case of while, however, the .next() method is necessary to continue moving through the rows. I'm not sure if your use of row as a reference to the .next() method is a problem in the iteration you start with the loop, but I would consider changing the row in the loop to something else for readability if nothing else. Also, your clip should be inside the loop if you want it to process for every row. Have you considered simply using Make Feature Layer to create a layer to clip against, using a unique key (like the object id) for layer creation?

Assuming you have 100 grids....

clipby = grids+"_LYR"
for id in xrange(0,101):
    gp.MakeFeatureLayer_management (grids, clipby, " [object_id] ="+id)
    gp.Clip_analysis(lines, clipy, Output, "")

A bit hackish, maybe, but it's worked for me when I want to avoid cursors (which I almost always do).

Update For your new problem,

Traceback (most recent call last):
  File "C:\gis\script\Clip_wCursor_v2.py", line 26, in <module>
    gp.Clip_analysis(lines, row, str(row.NAME)+"_c"+".shp", "")
RuntimeError: Object: Error in executing tool  

This is because the row object is not a valid feature to clip by (it is a cursor object). If I am reading the post from ESRI correctly, you need to create a reference to the row's shape, which can be done by grid = row.SHAPE. If you change your clip line to

grid = row.SHAPE
gp.Clip_analysis(lines, grid, str(row.NAME)+"_c"+".shp", "")  

Everything should work.

P.S. Create the row.SHAPE reference inside your while loop. It may work outside, but let's play it safe.

| improve this answer | |
  • I think I fixed the row reference and they are in the proper spots (if at all). The clip is inside the loop now, and the makefeaturelayer method already makes a bit of sense from looking at it so will try that and post my results. Using the searchcursor was a requested method but not required. I am going to compare the two methods. Thanks. – SaultDon Apr 5 '11 at 3:07

Remember that in Python, indentation is everything, including variable scope. So even if the cursor were iterable, gname would only be in scope during the loop (which effectively does nothing), then when you get to the Output = line, Python will complain that gname doesn't exist.

In addition, instead of creating a grid shapefile and using that as a cookie cutter, you could do it in code using, for example, this Python recipe. This would be more useful if you had to cut up vector data on a regular basis.

| improve this answer | |
  • thanks for pointing out these formatting errors, still learning these things, and I have learned that indenting is best done with spaces and not the TAB key, also took note of the order of my variables and operations (trying to get the terminology right) – SaultDon Apr 4 '11 at 23:22
  • also, your suggested 'recipe' is beyond my cooking level, i will examine it some more – SaultDon Apr 4 '11 at 23:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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