3

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 : 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
    row=rows.next()

# 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!

3
  • Added a comment to answer your newest question about the row object problem.
    – Nathanus
    Commented Apr 5, 2011 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
    Commented Apr 5, 2011 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
    Commented Apr 5, 2011 at 17:18

3 Answers 3

6

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()
6
  • Don't you just need the row = rows.Next() in the while loop?
    – djq
    Commented Apr 4, 2011 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. Commented Apr 4, 2011 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
    Commented Apr 5, 2011 at 2:51
  • @Swingley I forget... is 10 the first version where cursors are iterable?
    – Nathanus
    Commented Apr 5, 2011 at 12:32
  • @Nathanus- yep: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… Commented Apr 5, 2011 at 15:07
5

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, "")
    gp.Delete_management(clipby)  

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.

1
  • 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
    Commented Apr 5, 2011 at 3:07
2

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.

2
  • 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
    Commented Apr 4, 2011 at 23:22
  • also, your suggested 'recipe' is beyond my cooking level, i will examine it some more
    – SaultDon
    Commented Apr 4, 2011 at 23:23

Your Answer

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

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