Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to write a script in arcpy that checks to see if elevation values in a point file are found in a dictionary, and if they are to produce a new point file with just those entries. Sounds simple enough, but for some reason SelectByAttributes keeps returning the full dataset and not selecting properly. Further, this runs so slowly that I'm convinced there's a quicker way to do this, perhaps by making an array and writing a new point file with InsertCursor. Here's a snippet of my dysfunctional code:

import arcpy, collections
#transects_pts is a point shpfile with fields ID and elev
transect_pts = r'C:\transect_pts.shp'
inputRows = arcpy.SearchCursor(transect_pts,'','','ID; elev','ID')
layer = arcpy.MakeLayer_management(transects_pts,"tlayer")
#tdict is a default dict containing {ID: [elev1,elev2,elev3]}
for row in inputRows:
    for m in tdict:
        if row.elev in tdict[m]:
            arcpy.SelectLayerByAttribute_management(layer,"ADD_TO_SELECTION")
arcpy.CopyFeatures_management(layer,"new_transect_pts")

If anyone has some insight, or a better way to do this, please help me!

share|improve this question
    
Are your elevation values integers or floating points? Matching operations can get screwed up with floats because of varying levels of precision used to store the data. –  dmahr Mar 27 '12 at 23:34
    
To add to that...using the search cursor shouldn't be necessary. –  Justin Mar 28 '12 at 3:21

2 Answers 2

If you have three elevations in a list elevList = [elev1, elev2, elev3], you can do something like..the qry is the tricky part. Check this out.

for elev in elevList:
    #The query here is the trick
    #depends on the data source and field type 
    qry = "elevField=" + elev
    #Also I hate MakeFeatureLayer in loops because
    #you have to find unique output names held in memory
    #and arcpy.Delete_management(outputLyr) doesn't seem
    #to work for me..
    arcpy.MakeFeatureLayer_managment(input, "output" + elev, qry)
    arcpy.CopyFeatures_management("output" + elev, r"C:\Workspace" + "\\" + "output" + elev)

The idea here is to substitute select layer by attribute with the built in qry in MakeFeatureLayer

share|improve this answer
up vote 0 down vote accepted

Thanks for the tip! This method works a lot better than select by attribute, which is so difficult to use. I tweaked the code a bit, and here is my final solution which works like a charm:

import collections
tdict2 = collections.defaultdict(list)
fidList = []
inputRows = arcpy.SearchCursor(transects_pts)
for irow in inputRows:
    tdict2[irow.FID] = [irow.TID,irow.elev]
del irow
del inputRows
for fid,tidelevList in tdict2.iteritems():
    for tid,elevList in tdictConcat.iteritems():
        if tidelevList[1] in elevList and tidelevList[0] == tid:
            fidList.append(fid)
fidListString = str(fidList).strip('[]')
qry = '"FID" in(%s)' % fidListString
arcpy.Select_analysis(transects_pts,"bankheights.shp",qry)

Oddly enough, as the floating values in the attribute table differed from the actual values when pulled from the cursor (the attribute table values were mysteriously truncated), I needed to access the data with the Search Cursor. As these values were the ones I needed to set equal to the dictionary values, the cursor was essential. However, instead of querying each entry (which took quite a while), I wrote all the values to a dictionary and queried that instead (magnitudes of time difference). Aside from some minor changes in logic, the logic of using one query helped significantly.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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