Select to view content in your preferred language

Select Layer By Attribute User Input problem - Please help

834
3
04-08-2013 05:08 AM
ScottMacDonald
Deactivated User
Hi,

I'm writing a script for a toolbox that gets user input to run a select layer by attribute and location tool on a cities shapefile that contains two fields of interest, cime index (CRIME_IND) and university status (UNIVERSITY), both integers.  The 1st part, select layer by attribute, results in a layer being saved (citiesL) with those attributes and is shown in the code below.

I'm having problems in getting the user to define which attributes to select, none, one or more than one.  If the user chooses to select only crime attributes ("CRIME_INDE" <= 0.02) then only those ones would be saved and if the user chooses to select crime and university status attributes ("CRIME_INDE" <=0.02 AND "UNIVERSITY" = 1) then both those sets of attributes would be saved to the layer file.

Similarily, if the user does not fill in the required fields (by changing their default to nothing) then all the attributes of the cities layer would be effectively be saved to the layer file i.e. no selection by attribute.

When I run the code in the toolbox it completes successfuly but no layer is saved (citiesL).  I'm not sure where I'm going wrong with this and would appreciate any help.

Thanks

scottaidh

# script for user input tool based on select layer by location and attribute
# parameters within feature classes are optional
# scottaidh 8/4/13

# import system modules
import arcpy, os, traceback, arcpy
from arcpy import env
arcpy.env.overwriteOutput = True

# get user supplied path, layers and fields
path = arcpy.GetParameterAsText(0)

try :
 citiesFC = arcpy.GetParameterAsText(1) # cities Layer is cities Feature Layer
 crimefieldindex = arcpy.GetParameterAsText(2) # crime index is CRIME_INDE and is a Double integer
 whereClause1 = "{0} = '{1}'".format(arcpy.AddFieldDelimiters(citiesL, crimeField), crimefieldindex)
 crimeField = arcpy.GetParameterAsText(3) # crimeField is fieldname 'CRIME_INDE' SQL expression
 universityfieldindex = arcpy.GetParameterAsText(4) # universityfieldindex is the UNIVERSITY field and is DOUBLE integer
 whereClause2 = "{0} = '{1}'".format(arcpy.AddFieldDelimiters(citiesL, universityField), universityfieldindex)
 universityField = arcpy.GetParameterAsText(5) # universityField is fieldname 'UNIVERSITY' SQL expression
 outputlayer = arcpy.GetParameterAsText(6) # output layer name
 
 # make a layer from the cities feature class
 arcpy.MakeFeatureLayer_management(citiesFC, "citiesL")
 
 # select the attributes from citiesL from user input
 prj = ""
 prj2 = ""
 if prj.find("CRIME_INDE")>=0:
  crimecount = 1
  print 'using crime index'
 elif prj2.find("UNIVERSITY")>=1:
  unicount = 2
  print 'using university status'
  
 # set field to determine where clause variables 1=crime 2=university 3=crime and university else: none selected
 usecityfield = crimecount + unicount
 
 if usecityfield == 1:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", crimefieldindex)
  arcpy.CopyFeatures_management("citiesL", "citycrime")
 elif usecityfield == 2:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", universityfieldindex)
  arcpy.CopyFeatures_management("citiesL", "cityuni")
 elif usecityfield == 3:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", crimefieldindex + universityfieldindex)
  arcpy.CopyFeatures_management("citiesL", "citycrimeuni")
 else:
  # write selected features to a new featureclass
  arcpy.CopyFeatures_management("citiesL", "SUBSET_SELECTION")

except:
 print arcpy.GetMessages()
Tags (2)
0 Kudos
3 Replies
MathewCoyle
Honored Contributor
You seem to be missing some code. I don't see where you assign a value to your variable citiesL and I don't see where you have set your workspace.
0 Kudos
T__WayneWhitley
Honored Contributor
...agree with Mathew - so your output is probably going to your default or scratch gdb...if you want it going somewhere else, you can set that with a statement, arcpy.env.workspace = r'pathname', where you substitute the appropriate pathname....or you can use the full pathname in your copy statement.

Also, your else block doesn't look right with 'SUBSET_SELECTION'.  You said you want a 'layer', so if all you want is a feature later added to the map with the selection sourced to the orig data, you can use Make Feature Layer.  ...Save To Layer File is another means, basically saves the feature layer outside your map.

I see where you are creating your layer citiesL...but you aren't really doing anything with it - could be entering a query there.  Also, I see where you are attempting to make outputlayer - I may be mistaken, but I think you have to use one of the Set commands, as in SetParameter...then at the script interface make sure you 'tell the tool' that it is output.

Enjoy,
Wayne
0 Kudos
ScottMacDonald
Deactivated User
Thanks,

The workspace is navigated to by the user when the tool is run but anyway its "H:\working\FindSites.gdb\cities"

When the user runs the tool in ArcToolbox a pop-up menu appears similar to this with default paths etc.

Input workspace          H:\workspace\FindSites.gdb
Input feature layer       "cities.shp"
Input min crimeindex    0.02
Input crimeindex field    'CRIME_INDE'
Input min university      1
Input uniindexfield         'UNIVERSITY'
Input output name         "FoundSites.shp"

I need the user to be able to change anything and even not put in any attribute selections.

I'm tryin to write a user input non hard coded version (1) of the working hard-coded script (2) below.

Do you see what I mean now?  Any help would be very much appreciated.

Scottaidh

(1) Generic

# script for user input tool based on select layer by location and attribute
# parameters within feature classes are optional
# scottaidh 8/4/13

# import system modules
import arcpy, os, traceback, arcpy
from arcpy import env
arcpy.env.overwriteOutput = True

# get user supplied path, layers and fields
path = arcpy.GetParameterAsText(0)

try :
citiesFC = arcpy.GetParameterAsText(1) # cities Layer is cities Feature Layer
crimefieldindex = arcpy.GetParameterAsText(2) # crime index is CRIME_INDE and is a Double integer
whereClause1 = "{0} = '{1}'".format(arcpy.AddFieldDelimiters(citiesL, crimeField), crimefieldindex)
crimeField = arcpy.GetParameterAsText(3) # crimeField is fieldname 'CRIME_INDE' SQL expression
universityfieldindex = arcpy.GetParameterAsText(4) # universityfieldindex is the UNIVERSITY field and is DOUBLE integer
whereClause2 = "{0} = '{1}'".format(arcpy.AddFieldDelimiters(citiesL, universityField), universityfieldindex)
universityField = arcpy.GetParameterAsText(5) # universityField is fieldname 'UNIVERSITY' SQL expression
outputlayer = arcpy.GetParameterAsText(6) # output layer name

# select the attributes from citiesFC from user input
prj = ""
prj2 = ""
if prj.find("CRIME_INDE")>=0:
  crimecount = 1
  print 'using crime index'
elif prj2.find("UNIVERSITY")>=1:
  unicount = 2
  print 'using university status'
 
# set field to determine where clause variables 1=crime 2=university 3=crime and university else: none selected
usecityfield = crimecount + unicount
# make feature layer from cities feature class
arcpy.MakeFeatureLayer_management(citiesFC, "citiesL")

if usecityfield == 1:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", crimefieldindex)
  arcpy.CopyFeatures_management("citiesL", "citycrime")
elif usecityfield == 2:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", universityfieldindex)
  arcpy.CopyFeatures_management("citiesL", "cityuni")
elif usecityfield == 3:
  arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", crimefieldindex + universityfieldindex)
  arcpy.CopyFeatures_management("citiesL", "citycrimeuni")
else:
  # write selected features to a new featureclass
  arcpy.CopyFeatures_management("citiesL", "SUBSET_SELECTION")

except:
print arcpy.GetMessages()
[\CODE]
(2) Hard coded-

# select layer by location and attribute

import os, sys, traceback, arcpy
arcpy.env.overwriteOutput = True
try:
    citiesFC = r"H:\working\Findsites.gdb\cities"
    interstatesFC = r"H:\working\Findsites.gdb\interstates"
    countiesFC = r"H:\working\Findsites.gdb\counties"
    cityListFC = r"H:\working\Findsites.gdb\city_list"
    NearestInterstate = r"H:\working\Findsites.gdb\NearRoad"
    # setting variables for spatial join
    workspace = r"H:\working\Findsites.gdb"
    outWorkspace = r"H:\working\Findsites.gdb"
    targetFeatures = "cityListL"
    joinFeatures = "countiesL"
    outfc = r"H:\working\Findsites.gdb\FoundCities"
       
    arcpy.MakeFeatureLayer_management(citiesFC,"citiesL")
    arcpy.SelectLayerByLocation_management("citiesL", "WITHIN_A_DISTANCE", interstatesFC, "30 KILOMETERS", "NEW_SELECTION")
    arcpy.SelectLayerByAttribute_management("citiesL", "SUBSET_SELECTION", "UNIVERSITY = 1 AND CRIME_INDE <= 0.02")
    arcpy.MakeFeatureLayer_management(countiesFC,"countiesL")
    arcpy.SelectLayerByAttribute_management("countiesL", "NEW_SELECTION", "AGE_18_64 >= 25000 AND NO_FARMS87 >= 500")
    arcpy.SelectLayerByLocation_management("citiesL", "INTERSECT", "countiesL", "", "SUBSET_SELECTION")
    arcpy.CopyFeatures_management("citiesL", cityListFC)
    arcpy.AddField_management(cityListFC, "CITYNAME", "TEXT", "", "", "25")
    arcpy.AddField_management(cityListFC, "CRIMEINDEX", "DOUBLE", "", "", "")
    arcpy.AddField_management(cityListFC, "HAS_UNI", "TEXT", "", "", "3")
    arcpy.CalculateField_management(cityListFC, "CITYNAME", "!NAME!", "PYTHON")
    arcpy.CalculateField_management(cityListFC, "CRIMEINDEX", "!CRIME_INDE!", "PYTHON")
    arcpy.CalculateField_management(cityListFC, "HAS_UNI", "!UNIVERSITY!", "PYTHON")
    arcpy.DeleteField_management(cityListFC,["NAME", "LABEL", "CLASS"])
    arcpy.DeleteField_management(cityListFC,["CRIME_INDE", "LABEL", "CLASS"])
    arcpy.DeleteField_management(cityListFC,["UNIVERSITY", "LABEL", "CLASS"])
    arcpy.MakeFeatureLayer_management(cityListFC,"cityListL")
    arcpy.GenerateNearTable_analysis("cityListL", interstatesFC, NearestInterstate, "30 Kilometers")
    arcpy.AddJoin_management("cityListL", "OBJECTID", NearestInterstate, "IN_FID")
   
    # spatially join the narrowed down city/road and counties layers remove unwanted fields and rename others
    # arcpy.SpatialJoin_analysis("cityListL", "countiesL", "H:/working/Findsites.gdb/FoundCities", "#", "#", "")
    # create new fieldMappings
    fieldmappings = arcpy.FieldMappings()
    fieldmappings.addTable(targetFeatures)
    fieldmappings.addTable(joinFeatures)
    NameFieldIndex = fieldmappings.findFieldMapIndex("NAME")
    fieldmap = fieldmappings.getFieldMap(NameFieldIndex)
      
    # Get the output field's properties as a field object
    field = fieldmap.outputField
           
    # Rename the field and pass the updated field object back into the field map
    field.name = "COUNTYNM"
    field.aliasName = "COUNTYNM"
    fieldmap.outputField = field
    # replace old field map in mappings object with new one
    fieldmappings.replaceFieldMap(NameFieldIndex, fieldmap)
       
    # delete fields no longer applicable
    s = fieldmappings.findFieldMapIndex("city_list_ID")
    fieldmappings.removeFieldMap(s)
    t = fieldmappings.findFieldMapIndex("city_list_POPULATION")
    fieldmappings.removeFieldMap(t)
    u = fieldmappings.findFieldMapIndex("city_list_TOTAL_CRIM")
    fieldmappings.removeFieldMap(u)
    v = fieldmappings.findFieldMapIndex("AREA")
    fieldmappings.removeFieldMap(v)
    w = fieldmappings.findFieldMapIndex("POP1990")
    fieldmappings.removeFieldMap(w)
    x = fieldmappings.findFieldMapIndex("POP_SQMILE")
    fieldmappings.removeFieldMap(x)
    y = fieldmappings.findFieldMapIndex("SQ_MILES")
    fieldmappings.removeFieldMap(y)
    z = fieldmappings.findFieldMapIndex("X")
    fieldmappings.removeFieldMap(z)
    a = fieldmappings.findFieldMapIndex("Y")
    fieldmappings.removeFieldMap(a)
    b = fieldmappings.findFieldMapIndex("X_1")
    fieldmappings.removeFieldMap(b)
    c = fieldmappings.findFieldMapIndex("Y_1")
    fieldmappings.removeFieldMap(c)
    d = fieldmappings.findFieldMapIndex("PERIMETER")
    fieldmappings.removeFieldMap(d)
    e = fieldmappings.findFieldMapIndex("GAVPRIMARY")
    fieldmappings.removeFieldMap(e)
    f = fieldmappings.findFieldMapIndex("NearRoad_OBJECTID")
    fieldmappings.removeFieldMap(f)
    g = fieldmappings.findFieldMapIndex("NearRoad_IN_FID")
    fieldmappings.removeFieldMap(g)
    h = fieldmappings.findFieldMapIndex("NearRoad_NEAR_FID")
    fieldmappings.removeFieldMap(h)
   
    #Run the Spatial Join tool, using the defaults for the join operation and join type
    arcpy.SpatialJoin_analysis(targetFeatures, joinFeatures, outfc, "#", "#", fieldmappings)
   
    # order and rename final output fields where appropriate
    arcpy.AddField_management(outfc, "INTERSTATEkm", "SHORT", "3", "1", "")
    arcpy.AddField_management(outfc, "COUNTY", "TEXT", "", "", "14")
    arcpy.AddField_management(outfc, "WORKFORCE", "LONG", "", "", "")
    arcpy.AddField_management(outfc, "FARMS", "LONG", "", "", "")
    arcpy.CalculateField_management(outfc, "INTERSTATEkm", "!NearRoad_NEAR_DIST!", "PYTHON")
    arcpy.CalculateField_management(outfc, "COUNTY", "!COUNTYNM!", "PYTHON")
    arcpy.CalculateField_management(outfc, "WORKFORCE", "!AGE_18_64!", "PYTHON")
    arcpy.CalculateField_management(outfc, "FARMS", "!NO_FARMS87!", "PYTHON")
    arcpy.DeleteField_management(outfc,["NearRoad_NEAR_DIST", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["COUNTYNM", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["AGE_18_64", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["NO_FARMS87", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["OBJECTID_1", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["Shape_Leng", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["Join_Count", "LABEL", "CLASS"])
    arcpy.DeleteField_management(outfc,["TARGET_FID", "LABEL", "CLASS"])
    
except:
# print geoprocessing messages if fails
    print "\n*** LAST GEOPROCESSOR MESSAGE (may not be source of the error)***"; print arcpy.GetMessages()
    print "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]
    print "Python Error Info: " +  str(sys.exc_type)+ ": " + str(sys.exc_value)
[\CODE]
0 Kudos