3

I'm trying to iterate through a feature class and select each feature one by one by using the OBJECTID field. When I use a single value, the SelectLayerByAttribute works, but how do I compare the OBJEECTID to a variable that increases in count through the loop. The program is then suppose to create a layer for each feature in the feature class. This is what I have so far:

import arcpy
import os
arcpy.env.workspace = "C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb"
arcpy.env.overwriteOutput=True
inlayer = "C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb\ZonesPolyline"


with arcpy.da.SearchCursor(inlayer, ("OID@", "SHAPE@AREA")) as cursor:
    i = 1
    for row in cursor:
        print("Feature {0} has an area of {1}".format(row[0], row[1]))
        outlayer = "ZonePolygon"
        arcpy.MakeFeatureLayer_management (inlayer, outlayer)
        arcpy.SelectLayerByAttribute_management (outlayer, "NEW_SELECTION", """           "OBJECTID" = 1 """)
        output = r'C:\Users\Daimon Nurse\Desktop\Grounds Project\DFMGROUNDS.gdb'
        outfile = os.path.join (output, i)
        arcpy.CopyFeatures_management(outlayer, outfile)
        print i
        i = i + 1
3
  • Rather than do MakeFeatureLayer+SelectLayerByAttribute+CopyFeatures, I think it is much cleaner to just use the Select_analysis tool.
    – PolyGeo
    Commented Jan 7, 2015 at 1:52
  • As an aside your variable naming suggests that you may be using layers as just another name for datasets (feature classes, shapefiles). There is a useful Q&A here on the difference between them: gis.stackexchange.com/questions/26336/…
    – PolyGeo
    Commented Jan 7, 2015 at 3:26
  • not sure , but i think what your trying to achieve is similar to something i have been doing similar question Commented Jun 19, 2015 at 20:28

2 Answers 2

3

Instead of using a where_clause of:

"""           "OBJECTID" = 1 """

I think you should try:

'"OBJECTID" = {0}'.format(i)

Also, instead of:

outfile = os.path.join (output, i)

try:

outfile = os.path.join(output, "fc{0}".format(i))

What I have used in both of the above is Python string formatting. Python strings can be delimited using single or double quotes. I used single in the first so as not to clash with double quotes that indicated the field name. In the second I used double quotes because I think they look better.

I added "fc" to your feature class name because I don't think ArcGIS will like a feature class name that is, or starts with, a number.

Also take a look at:

arcpy.env.workspace = "C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb"
arcpy.env.overwriteOutput=True
inlayer = "C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb\ZonesPolyline"

which needs to escape the single backslashes in your pathnames e.g.:

arcpy.env.workspace = r"C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb"
arcpy.env.overwriteOutput=True
inlayer = r"C:\Users\Daimon Nurse\Desktop\DFMPROJECT\DFMPROJECT.gdb\ZonesPolyline"
6
  • This solved the problem :arcpy.SelectLayerByAttribute_management (outlayer, "NEW_SELECTION", '"OBJECTID" = {0}'.format(i) ) Commented Jan 7, 2015 at 2:20
  • How do I use it in : output = r'C:\Users\Daimon Nurse\Desktop\Grounds Project\DFMGROUNDS.gdb' outfile = os.path.join (output, {0}.format(i)) arcpy.CopyFeatures_management(outlayer, outfile) Commented Jan 7, 2015 at 2:20
  • Traceback : File "C:\Python27\ArcGIS10.1\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript exec codeObject in main.__dict__ File "C:\Users\Daimon Nurse\Desktop\DFMPROJECT\Scripts\polylinetopolygon.py", line 17, in <module> arcpy.CopyFeatures_management(outlayer, outfile) File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\management.py", line 2226, in CopyFeatures raise e ExecuteError: ERROR 000210: Cannot create output C:\Users\Daimon Nurse\Desktop\Grounds Project\DFMGROUNDS.gdb\fc1 Failed to execute (CopyFeatures). Commented Jan 7, 2015 at 2:42
  • Perhaps research/ask about the 000210 error separately - it is frequently seen and in this case I am guessing that either your file geodatabase does not exist or your feature class already exists.
    – PolyGeo
    Commented Jan 7, 2015 at 2:49
  • I have double checked, the geodatabase does exists on file and the feature class has not been created as yet. I even used the Select_anaylsis tool and I still get the 000210 error Commented Jan 7, 2015 at 3:09
1

I think you should leverage the 'where clause' of the MakeFeatureLayer. Here is an extract of a much larger script that does most of what you want to do:

desc = arcpy.Describe(InFC)
OIDfield = desc.OIDFieldName

with arcpy.da.SearchCursor(InFC,[OIDfield,"SHAPE@AREA"]) as SCur:
    for Ft in SCur:
        arcpy.MakeFeatureLayer_management(InFC,"Layer","%s = %d" % (OIDfield,Ft[0]))
        # do some stuff
        arcpy.Delete_management("Layer") # remove the layer for each iteration

Note: the search cursor uses square brackets on the fields, not parenthesis: SearchCursor(inlayer, ("OID@", "SHAPE@AREA")) is incorrect, SearchCursor(inlayer, ["OID@", "SHAPE@AREA"]) is correct.

I get the OIDFieldName using code (via Describe in Table Properties) so it will work for shapefiles and geodatabase feature classes, OID@ should also work but I can't say for sure - I've always done it that way as I need the field name for the query.

Notes on string formatting:

PolyGeo has shown one sort of format using '"OBJECTID" = {0}'.format(i), I mostly use the % style of formatting '"OBJECTID" = %d' % i. Either way works; I prefer the % formatting as it's more like C and I'm used to reading it that way.

2
  • +1 Just as an aside there is a Q&A at Stack Overflow on Python string formatting: % vs. .format.
    – PolyGeo
    Commented Jan 7, 2015 at 2:44
  • Also @PolyGeo you need to know what type the variable is which is a big problem in Python with its duck-typing. If you say "%s" % var and var isn't a string it wont like it, "{0}".format(var) works for string, int and floating point. I say .format is better however I still prefer not to use it. Commented Jan 7, 2015 at 2:57

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.