3

I am a novice in python programming but I am trying to learn by doing.

I got stuck with this function a while back and can't seem to find a solution or a workaround.

I am writing a script that is trying to select all data in an MXD within a 70m distance from a layer and then export that data to a newly created file geodatabase. I can´t seem to get this to work, all I get is the error:

FDO error: -2147024894 [GDB_Items]

The table was not found. [Output name]

And I somehow manage to get some kind of output, in the form of empty geodatabase tables in the output file geodatabase with the “correct” output names.

I have a suspicion that the problem lies in the feature layers origins. They reside deep in our file tree (for exampel G:\KONSULTUPPDRAG VMN\SAMRÅD\2012\Uppsala\C 55 Örsundsbro - Kvarnbo\Kartor\Grundkartor\Fastighetskartan.gdb\vo) there is nothing I can do about it unfortunately.

Here is my code:

import arcpy, os, re
from unicodedata import normalize

Skapa_mapp = (unicode ("C:\\Users\dabr\\Desktop\KMZtest\\", 'UTF-8'))
Mxd_Natur = arcpy.mapping.MapDocument((unicode ("C:\\Users\\dabr\\Desktop\\KMZ test\\YAYYY_Test1.mxd", 'UTF-8')))
Vag = "c 801"

def Select_and_Export (Mxd_Natur, Skapa_mapp, Vag):
    Db = Skapa_mapp +"KMZ\\KMZ_Databas.gdb\\"                        #Define the output DB

for df in arcpy.mapping.ListDataFrames(Mxd_Natur):                  #Find the road from whitch the selection is made with. 
    for lyr in arcpy.mapping.ListLayers(Mxd_Natur, "", df):
        if lyr.name.lower() == unicode (Vag, 'UTF-8'):
            Utgangslager = lyr

for df in arcpy.mapping.ListDataFrames(Mxd_Natur):                  
    for lyr in arcpy.mapping.ListLayers(Mxd_Natur, "", df):         #Loop trough all the layers in the MXD to make 
                                                                    #a selection and exprt if annything got selected
        Sokvag = lyr.workspacePath                                  #Get the path to the specific layer
        SokvagNamn = lyr.datasetName                                #Get the name of the specific layer
        File_path = Sokvag + "\\" + SokvagNamn                      #Combine to create full path
        print File_path

        if not Sokvag.endswith(".gdb"):                             #layers in mxd can be both from GDB and .shp
            File_path = File_path + ".shp"

        Namn = lyr.name.lower()                                     #    
        Namn = re.sub('[ ]', '_', Namn)                             #create a output name bades on the layer name 
        Namn = normalize('NFKD', Namn).encode('ascii', 'ignore')    #in the mxd


        if arcpy.Exists("TEMP"):                                    #if temporary file exis´ts from previous run, remove it
            arcpy.Delete_management("TEMP")
            print "temp removed"


        arcpy.management.MakeFeatureLayer(File_path,"TEMP")         #Recreata a empty templayer
        arcpy.SelectLayerByLocation_management("TEMP", "WITHIN_A_DISTANCE", Utgangslager, "70 Meters", "NEW_SELECTION") #populate the templayer whit selected objekts?
        out = os.path.join(Db, Namn)                                #Create a path to the output location

        print str(arcpy.GetCount_management("TEMP").getOutput(0))+" Selected from " + Namn      #Show number of selected objekts.

        if int(arcpy.GetCount_management("TEMP").getOutput(0)) > 0: #check if anny objects were selected. if not dont export
            try:

                if "TEMP".endswith(".shp"):                         #test if the temporary layer is based on a shp file?
                    print Namn + " skall shp kopieras"
                    arcpy.CopyFeatures_management("TEMP", out.rstrip(".shp"))        #Coppy selected objekts to FDB
                    print Namn + " shp kopierad"
                else:
                    print Namn + " skall koppiers"
                    arcpy.CopyFeatures_management("TEMP", out)      #Coppy selected objekts to FDB
                    print Namn + " är kopierad"

            except:
               print arcpy.GetMessages()


        else:
            print lyr.name.lower() + " no objekts were selected"

Does anyone see a solution to my problem or perhaps a workaround?

Edit: After some tweaking I stumbled upon the problem and solution. I was using a File GDB as an output in the CopyFeatures_management function. I don’t know why but if I changed it to a personal GDB everything went fine. Can anyone explain why?

4
  • 2
    One thing to try is to turn your strings into raw-strings and remove the double backslash so that "C:\Users\dabr\Desktop\KMZtest\\" becomes r"C:\Users\dabr\Desktop\KMZtest\". The backslash character, "\", is used to escape characters that have special meaning, e.g. "\n" is a newline character, "\t" is a tab character, etc. You can remove the ambiguity in your code by converting your strings to raw-strings as mentioned above, using a forward slash "/" (does not have to be converted to a raw string), or by using the double backslash "\\" everywhere. Commented Nov 9, 2012 at 13:52
  • I went whit the "double backslash \\", this had no direct effect on the outcome. But thanks for helping me write my code better
    – Daniel
    Commented Nov 9, 2012 at 14:51
  • 1
    Sure thing; I usually go with the raw-strings just because it's easier to copy and paste paths from Explorer and add the 'r' to it. Sorry I can't be of more help to you. Commented Nov 9, 2012 at 15:01
  • True, that sounds like a good reason, but sins haven’t gotten the hang of \n,\t,\r and all the rest I´ll play it safe and go with what I know for now. I appreciate you taking the time.
    – Daniel
    Commented Nov 9, 2012 at 15:18

2 Answers 2

1

I wonder if this will help?

replace the following line,

if "TEMP".endswith(".shp"):

with this line

if arcpy.Describe("TEMP").featureClass.catalogPath.endswith(".shp"): 
0
0

You will need to work back in some of your logic. Mostly the naming of your tables and the select by location. My map is using very simple names. If you have trouble post some of the layer names in the map and I can test using those. You will also need to put back in your mxd and file paths.

This code needs to be cleaned up and you should read into better error checking than I am using. Let me know if you have any questions.

import arcpy, os, re
from random import randint

skapa_mapp = (r"C:\Users\ajones\Documents\ArcGIS")
input_mxd = arcpy.mapping.MapDocument(r"C:\Users\ajones\Documents\ArcGIS\tempProjectData\arcpy_mapping.mxd")
vag = "Export_Output_4" # - c 801
db_path = "tempProjectData"   # - KMZ
db_name ="superTemp.mdb"    # - KMZ_Databas.gdb
output_db = skapa_mapp + os.sep + db_path + os.sep + db_name
feature_lyr_name = "TEMP"
def main():


    f_and_list = find_and_list_layers(input_mxd, vag)
    vag_layer = f_and_list[0]
    mxd_layers = f_and_list[1]
    if vag_layer != "":
        selection_stub(mxd_layers)   


def create_feature_layer(in_path, in_name):
    if arcpy.Exists(in_name):
        arcpy.Delete_management(in_name)
        arcpy.AddMessage("Deleted : " + str(in_name) + " feature layer" )
    try:
        feature_layer_result = arcpy.management.MakeFeatureLayer(in_path, in_name)
    except:
        arcpy.AddMessage("Could not create feature layer")

    return feature_layer_result


def find_and_list_layers(input_map, lyr_name ):  # returns a single lyr [0] and a list of layers[1]
    layer_list = []
    for df in arcpy.mapping.ListDataFrames(input_map):
        for lyr in arcpy.mapping.ListLayers(input_map, "", df):
            if lyr.name.lower() != lyr_name.lower():
            # We dont want to find features 70 meters from themselves. Remove them from the list
                layer_list.append(lyr)
            elif lyr.name.lower() == lyr_name.lower():
                matched_layer = lyr
            else:
                arcpy.AddMessage("Could not match a layer with name : " + lyr_name)
                matched_layer = ""
    return_data = [matched_layer, layer_list]
    return return_data


def selection_stub(layers_list):
    for lyr in layers_list:
        if str(lyr.workspacePath).endswith(".gdb"):
            file_path = lyr.workspacePath + os.sep + lyr.datasetName

        else:
            file_path = str(lyr.workspacePath) + os.sep + str(lyr.datasetName) + ".shp"
            print file_path
        output_name = str(lyr.name).lower()[0:7] # you can work your name logic in here. My map is using simple names.
        try:
            feature_lyr = create_feature_layer(file_path, feature_lyr_name)
        except:
            arcpy.AddMessage("could not create feature layer" )
        ##-----feature layer is created process selections.
        try:
            result = arcpy.SelectLayerByLocation_management(feature_lyr, "WITHIN_A_DISTANCE", "", "70 Meters","NEW_SELECTION")
        except:
            arcpy.AddMessage("Could not process selection")

        sf = result.getOutput(0)
        count = arcpy.GetCount_management(sf)
        if count > 0:
            arcpy.AddMessage("Selection Count : " + str(count))
            copy_features_into_db(sf,output_name)

def copy_features_into_db(input_data, db_name):
    print "In copy features : Input data ---  " + str(input_data)

    database = output_db + os.sep + db_name + str(randint(100,299))   # replace this with your name logic.
    print str(database)
    print arcpy.GetCount_management(input_data)
    try:
        arcpy.CopyFeatures_management(input_data, database )
    except:
        print arcpy.GetMessages()
        arcpy.AddMessage("Could not copy features. ")



if __name__ == '__main__':
    main()
3
  • Thanks for taking a look at my code! I’ll see what I can do about the names, I am somewhat tied up in the “old ways” of or mapping architecture and naming, but I’ll see what I can do. I’ll take a look at your code and see if that does the trick.
    – Daniel
    Commented Nov 12, 2012 at 5:32
  • I began to edit my code but I first tried to change the output GDB from file to personal. That did the trick, do you know why this change was enough? I mean, what’s so different between a personal and a file GDB
    – Daniel
    Commented Nov 12, 2012 at 8:23
  • Permissions? When in doubt check permissions.
    – theJones
    Commented Nov 12, 2012 at 18:04

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.