3

So I'm fairly new to arcpy and have been trying to figure out a relatively simple select by location/extract features to new layer automation in ArcMap. What I am trying to do is select features from about 40 target layers from an SDE database that are within a parish/county layer then extract them to new layers that go by the same layer name they are being outputted from but in a different location.

Below I have a couple of general issues:

1) The first for loop does not work because it will not accept "fc" as input. What I was planning out was to have it loop through each feature class and apply the parish/county layer over it to apply the selection. Of course, this does not work. This may just be due to my misuse of "fc".

2) The second for loop runs but it stops once it gets tot he second iteration/layer of the loop because it can't overwrite the filename that was already created in the first iteration. This for loop is intended to loop through each feature class and extract the same feature class to a different folder using the same layer name it was outputted from.I should also mention that the layer names go by "HM_Production.DBO.Agriculture", HM_Production.DBO.Banking", etc. and when I check the file its trying to overwrite, it has it outputted as "HM_Production.DBO". I assume this has something to do with the dot notation of the layer name?

EDIT: This is what I'm using now. It's a combination of everything so far. It goes through everything fine but is still giving me the output error of "line 2434, in CopyFeatures raise e ExecuteError: ERROR 000210: Cannot create output C:\output\HM_Production_DBO_WATER_Water_Storage_Unit.shp Failed to execute (CopyFeatures). I should also mention that all of the scripts that have been suggested have the same issue. :

import arcpy
from arcpy import env

env.workspace = r'C:\ArcScratch\HM_Production.sde'

stateFeature = r'C:\ArcScratch\State\Parishes_LDOTD_2007.shp'
parish = "Orleans"
nameField = "PARISH"



arcpy.MakeFeatureLayer_management(stateFeature, 'SelectionStateLayer', '"' +     
str(nameField) + '" = ' + "'" + str(parish) + "'")

for fc in arcpy.ListFeatureClasses():

    if arcpy.Exists('lyr'):
        arcpy.Delete_management('lyr')

    arcpy.MakeFeatureLayer_management(fc, 'lyr')
    arcpy.SelectLayerByLocation_management('lyr', "WITHIN", 'SelectionStateLayer')

    outname = fc.replace(".","_") #replace all . with _
    outpath = r"C:\output\{0}.shp".format(outname)

    if arcpy.Exists(outpath):
        arcpy.Delete_management(output)

    arcpy.CopyFeatures_management('lyr', outpath)

arcpy.Delete_management('lyr')
  • 1
    It won't solve all your problems, but do check the slashes in the third-to-last line and preface the string with a lower-case r in case you happen to get a string escape character when you build your output string. – J Kelly Mar 31 '15 at 14:49
  • 1
    Also, if you've set an environment, I'm not sure you need the "*" argument. Try it with empty parentheses (). – J Kelly Mar 31 '15 at 14:50
  • Ok, one thing is that the if arcpy.Exists() statements are off, and that's my fault because I posted bad code earlier. Please see my newly edited post! Sorry about that! Whatever you're checking is what should be deleted in the if statement. Again, that's my fault! – mr.adam Mar 31 '15 at 20:05
  • Hmm I corrected that and now Im getting: line 30, in <module> arcpy.CopyFeatures_management('lyr', outpath) File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\management.py", line 2434, in CopyFeatures raise e ExecuteError: ERROR 000210: Cannot create output C:\output\HM_Production_DBO_WATER_Water_Storage_Unit.shp Failed to execute (CopyFeatures – TacoB0t Mar 31 '15 at 20:08
  • 1
    I did. And, yes, c:\output exists lol but nothing gets created in the folder. I tried running this by some of my co-workers on the development side and they say it's a permissions issue. Will try a few things tomorrow and update you all. I think it's an issue on my end at this point. Thanks for the help everyone! – TacoB0t Mar 31 '15 at 22:31
1

As @GeoJohn pointed out, the CopyFeatures operation in the second loop should be added to the first loop.

I think the real problem is that you are trying to place feature classes from an SDE environment into a normal directory. Shapefiles are the format you need if you want the final datasets to sit in C:\output. When you passed the feature class name "HM_Production.DBO.Banking" to the CopyFeatures operation as the output path, I think it probably interpreted ".Banking" as the desired file extension, which is not really going to work. So I think you were right to suspect the "." in the feature class names.

Here's what you should have in the loop directly before the CopyFeatures line:

outname = fc.replace(".","_") #replace all . with _
outpath = r"C:\output\{0}_{1}.shp".format(outname,str(index)) #index as @GeoJohn mentioned if necessary
arcpy.CopyFeatures_mangement(fc, outpath)

Technically if you leave the "." in the name and just add ".shp" to the end I think it should work, but it's cleaner to replace them all in my opinion.

Generally, I'd also recommend cleaning the code up with some string formatting, because constructing queries and path names can get messy, and little details will trip you up. Try something like this:

query = '"{0}" = \'{1}\''.format(parish, nameField)
arcpy.MakeFeatureLayer_management(stateLayer, 'SelectionStateLayer',query)

EDIT: I don't think that the indexing is necessary because you can't actually have feature classes with the same name in the same workspace. This means that the output datasets should all already have unique names, and we can delete them if they already exist in the output folder from previous tool iterations (which I would guess is the issue you're having now). This is the loop I would use:

for fc in arcpy.ListFeatureClasses:

    if arcpy.Exists('lyr'):
        arcpy.Delete_management('lyr')

    arcpy.MakeFeatureLayer_management(fc, 'lyr')
    arcpy.SelectLayerByLocation_management('lyr', "WITHIN", 'SelectionStateLayer')

    outname = fc.replace(".","_") #replace all . with _
    outpath = r"C:\output\{0}.shp".format(outname)

    if arcpy.Exists(outpath):
        arcpy.Delete_management(outpath)

    arcpy.CopyFeatures_mangement('lyr', outpath)

arcpy.Delete_management('lyr') # cleanup at the very end
  • Yah, queries like this can be a pain. @mr.adam has laid out a nice and clear highly recommended variable substitution that would be a better alternative. – GeoJohn Mar 31 '15 at 16:23
  • It's also easier to throw it into a print statement to double check it. Copying and pasting strings constructed with a lot of + and stuff is a recipe for disaster. – mr.adam Mar 31 '15 at 16:25
0

The following corrected script should do everything you need it to. A few things have been changed from previous iterations.

import arcpy
from arcpy import env

env.workspace = r'C:\ArcScratch\HM_Production.sde'

stateFeature = r'C:\ArcScratch\State\Parishes_LDOTD_2007.shp'
parish = "Orleans"
nameField = "PARISH"

arcpy.MakeFeatureLayer_management(stateFeature, 'SelectionStateLayer', '"' +     
str(nameField) + '" = ' + "'" + str(parish) + "'")

index = 0

for fc in arcpy.ListFeatureClasses():
    arcpy.MakeFeatureLayer_management(fc, 'fc_lyr')
    arcpy.SelectLayerByLocation_management('fc_lyr', "INTERSECT", 'SelectionStateLayer')
    arcpy.CopyFeatures_management('fc_lyr', r'C:\output\new_feature_' + str(index))
    index += 1
    arcpy.Delete_management('fc_lyr')

arcpy.Delete_management('SelectionStateLayer')

The copy features line had some incorrect syntax.

  • This code and the one suggested by adam gives me the same output error that I mention in the edit of my quesiton. – TacoB0t Mar 31 '15 at 19:57
0

The first for loop will not work for a couple reasons:

1.) As @J Kelly mentioned, you don't need the "*" argument. It should just be ().

2.) Also, you are trying to use the SelectLayerByLocation on a feature class, so you will need a line preceding this that actually makes the feature an "in memory" layer. arcpy.MakeFeatureLayer_management

The second for loop is unnecessary altogether. If I'm understanding this correctly, you should just put the CopyFeatures command within the first loop immediately after the select command and make sure to use the "in memory" layer name in single quotes as the input.

As for the naming convention, you will have to do something that gives each output a unique name. For example:

newFeat = "my_feature"
index = 0
for fc in arcpy.ListFeatureClasses():
    #all the other code
    arcpy.CopyFeatures_mangement(fc, r'C:\output\' + str(newFeat) + "_" + str(index))
    index += 1

@J Kelly is also correct in mentioning the "/" in the third from last line. Use r'C:/output' instead.

You are on the right track but keep using the online help for arcpy for all of your syntax.

  • Another thought just occurred to me... Make sure that the "WITHIN" selection type is what you need, my guess is that you probably want "INTERSECT". – GeoJohn Mar 31 '15 at 15:29
  • 1
    just fyi you're missing a closing parenthesis at the end of the CopyFeatures line, also, I agree that in_memory is a good idea, but the OP does already create a feature layer called "SelectionStateLayer" so I think the select by location should be working correctly. – mr.adam Mar 31 '15 at 15:50
  • @mr.adam The "layer" you are selecting from has to be a layer. Thanks for the parentheses comment, it's fixed now. – GeoJohn Mar 31 '15 at 15:53
  • 1
    ah, yes, I gotchya. – mr.adam Mar 31 '15 at 15:58
  • 1
    I edited my answer, try that loop out and see how it goes. I would guess that there was a new_feature_0.shp dataset already in the folder from previous iterations. It may be worthwhile to do the CopyFeatures operation one time with the normal tool dialog in arcmap to make sure there is no problem with the data itself... – mr.adam Mar 31 '15 at 16:54

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.