|
POST
|
Upon testing in v10.1, indeed the 'sort_fields' named parameter/kwarg appears to work as advertised.
... View more
04-22-2013
01:47 PM
|
0
|
0
|
2200
|
|
POST
|
I'm not sure if the traditional (non data access) cursors support named parameters (which is what you are doing with the 'sort_fields' named parameter in your code). I think it would either have to be like this: In traditional cursors: FRows = arcpy.SearchCursor(flayer,"", "", "", "FLAG A") Or in data access cursors like this: FRows = arcpy.da.SearchCursor(flayer,["*"], sql_clause=(None, 'ORDER BY FLAG')) This thread might help: http://forums.arcgis.com/threads/64580-SQL-sort-parameter-syntax-for-da.cursors
... View more
04-22-2013
08:57 AM
|
0
|
0
|
2200
|
|
POST
|
Don't know if it would help you in this case, but in the past I have made a "look up" reference table that includes the road segment IDs that each of my routes traverse... that way I can just make a "view" of my routes for summary/analysis purposes on-demand instead of keeping the actual spatial data for each route (which after a point becomes impractical). The routes are composed of the original road segments anyway - so it begs the question for the need to store redundant spatial data. Per your original bug assertion, here's some code to test where arcpy.ListFeatureClasses breaks... I got up to 5000+ FC's able to be listed before I killed it... I was using the in_memeory workspace though for speeds sake... FGDB is way slower. import arcpy
arcpy.env.overwriteOutput = True
arcpy.env.workspace = arcpy.env.scratchGDB #I used in_memory instead to test it
loopCount = 1
fcName = "fc_" + str(loopCount)
arcpy.CreateFeatureclass_management(arcpy.env.workspace, fcName, "POINT")
fcListCount = 1
while fcListCount > 0:
loopCount = loopCount + 1
fcName = "fc_" + str(loopCount)
fcListCount = len(arcpy.ListFeatureClasses())
arcpy.CreateFeatureclass_management(arcpy.env.workspace, fcName, "POINT")
fcListCount = len(arcpy.ListFeatureClasses())
print "At loop count = " + str(loopCount) + " there were " + str(fcListCount) + " featureclasses listed..."
... View more
04-19-2013
01:17 PM
|
0
|
0
|
3486
|
|
POST
|
a recursive function is one that calls itself, not one that loops per se I often find that it's easier to implement "recursion" in a loop of some sort though. Maybe what I think of as "recursion" isn't technically recursion... I'm not a formally trained programmer by any means, so appologies if what I say is utter nonsense! That said - Here's a practical ArcGIS/Python example of something I would consider recursion. This code assigns a unique identifier (a "cluster ID" if you will) to features that within a given distance of each other (basically a "select by location" that keeps executing as long as the selected set grows. Once there are no more features to select, then it tries to select another seed feature (that hasn't already been assigned a CLUSTER_ID value) in which to "grow" the next cluster from. It uses while loops and not function calls, although I supose it could be re-written to do that. import sys, string, os, arcpy
inLayer = arcpy.GetParameterAsText(0) #input layer
clusterIdField = arcpy.GetParameterAsText(1) #the name of the 'CLUSTER_ID' field that will be added to inLayer
selectionMethod = arcpy.GetParameterAsText(2) #the selectbylocation method (such as WITHIN_A_DISTANCE or INTERSECT)
distThreshold = arcpy.GetParameterAsText(3) #A distance threashold if using the WITHIN_A_DISTANCE selection method
selectionBuffer = arcpy.GetParameterAsText(4) #A max number of features to be selected set at once... performace gets slow if selection gets too big
if selectionBuffer in ("","#",None):
selectionBuffer = 500
if int(selectionBuffer) < 1:
selectionBuffer = 500
fieldList = arcpy.ListFields(inLayer, clusterIdField)
if fieldList == []:
arcpy.AddField_management(inLayer, clusterIdField, "LONG")
else:
if fieldList[0].type not in ["SmallInteger","Integer","Double","Float"]:
arcpy.AddError("ERROR: Existing " + str(clusterIdField) + " field type must be a numeric type (not a type of " + str(fieldList[0].type) + "! Exiting script..."); sys.exit(1)
oidFieldName = arcpy.Describe(inLayer).oidFieldName
arcpy.AddMessage("Cataloging " + str(oidFieldName) + " values...")
oidDict = {}
for r in arcpy.da.SearchCursor(inLayer, ["OID@"]):
oidDict[r[0]] = -1
featureCount = len(oidDict)
if featureCount == 0:
arcpy.AddError("ERROR: Could not find any features to identify! Exiting script...");sys.exit(1)
arcpy.AddMessage("Looking for clusters...")
identifiedFeatures = 0
clusterId = 0
arcpy.MakeFeatureLayer_management(inLayer, "fl1", "") #Test to see if this helps clear the memory leak
arcpy.SetProgressor("step", "Progress", 0, 100, 1)
pctDone = 0
while identifiedFeatures < featureCount:
clusterId = clusterId + 1
try:
nextOidSeedValue = (key for key,value in oidDict.items() if value == -1).next()
except:
break
arcpy.SelectLayerByAttribute_management("fl1", "NEW_SELECTION", oidFieldName + " = " + str(nextOidSeedValue))
globalPreSelectionOidSet = set()
globalPostSelectionOidSet = set([nextOidSeedValue])
loopCount = 0 #for fun
bufferReductionCount = 0 #for fun
while len(globalPostSelectionOidSet) > len(globalPreSelectionOidSet):
loopCount = loopCount + 1
preSelectionOidSet = set([r[0] for r in arcpy.da.SearchCursor("fl1", ["OID@"])])
globalPreSelectionOidSet = globalPreSelectionOidSet.union(preSelectionOidSet)
arcpy.SelectLayerByLocation_management("fl1", selectionMethod, "fl1", distThreshold, "NEW_SELECTION")
postSelectionOidSet = set([r[0] for r in arcpy.da.SearchCursor("fl1", ["OID@"])])
globalPostSelectionOidSet = globalPostSelectionOidSet.union(postSelectionOidSet)
if len(postSelectionOidSet) > int(selectionBuffer):
recentSelectionOidList = list(globalPostSelectionOidSet.difference(globalPreSelectionOidSet))
recentSelectionOidList.sort()
if len(recentSelectionOidList) > 0:
bufferReductionCount = bufferReductionCount + 1
arcpy.SelectLayerByAttribute_management("fl1", "NEW_SELECTION", oidFieldName + " in (" + ",".join(str(i) for i in recentSelectionOidList) + ")")
for oidValue in globalPostSelectionOidSet:
identifiedFeatures = identifiedFeatures + 1
oidDict[oidValue] = clusterId
pctDoneUpdate = int(identifiedFeatures/float(featureCount) * 100)
pctDoneDiff = pctDoneUpdate - pctDone
if pctDoneDiff >= 1:
for i in range(0,pctDoneDiff):
arcpy.SetProgressorPosition()
pctDone = pctDoneUpdate
arcpy.AddMessage("Updating attribute table...")
updateRows = arcpy.da.UpdateCursor(inLayer, ["OID@",clusterIdField])
for updateRow in updateRows:
updateRow[1] = oidDict[updateRow[0]]
updateRows.updateRow(updateRow)
del updateRow, updateRows
arcpy.AddMessage("Identified " + str(clusterId) + " cluster(s) for " + str(identifiedFeatures) + " features")
... View more
04-19-2013
09:37 AM
|
0
|
0
|
2221
|
|
POST
|
Note sure about your specific case or the exact logic you are employing in your workflow, but the general method of recursion relies on using a while loop. a basic hypothetical example: myFC = r"C:\temp\test.gdb\test"
featuresProcessedCount = 0
featureCount = int(arcpy.GetCount_management(myFC).getOutput(0))
while featuresProcessedCount < featureCount:
do something
featuresProcessedCount = featuresProcessedCount + 1
... View more
04-18-2013
03:30 PM
|
0
|
0
|
2221
|
|
POST
|
Your script has some issues with strings vs. variables and also how you are defining paths. For example: 1. In Python, cityList is not the same thing as 'cityList'.... the 1st referes to a variable since it isn't in quotes, but the second is a string object since it is in quotes 2. Python is picky how you define paths. All of these are okay: path = r"H:\here\it\is"
path = "H:\\here\\it\is"
path = "H:/here/it/is" This is not okay though: path = "H://here//it//is" I took the liberty to rewrite your code. Notice how the FCs are defined as variables up near the top, and they use a consistent path delimiter method. This code "should" work: 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"
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.CalculateField_management(cityListFC, "CITYNAME", "!NAME!", "PYTHON")
except:
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)
... View more
04-04-2013
01:49 PM
|
0
|
0
|
1490
|
|
POST
|
You need to put quotes around "CITYNAME" since it is text and not a variable. So instead of: arcpy.CalculateField_management(CityList, CITYNAME, expression1, "PYTHON", "") it needs to be: arcpy.CalculateField_management(CityList, "CITYNAME", expression1, "PYTHON", "")
... View more
04-04-2013
10:23 AM
|
0
|
0
|
1490
|
|
POST
|
A last ditch idea: subprocess the gp command? As the subprocess ends, so does the lock.
... View more
04-03-2013
07:37 AM
|
0
|
0
|
742
|
|
POST
|
Not sure what's going on exactly, but some ideas that might help: 1. Ditch the "with" statement stuff... I think this was implemented by ESRI to reduce confusion about cursorsstill retaining a lock on the database upon failure. It's nice, but not critical... I do not use it... but maybe I should... Anyway the more simple "old way" syntax is then something like: updateRows = arcpy.da.UpdateCursor(myTbl, ["MY_FIELD"])
for updateRow in updateRows:
fieldValue = updateRow[0]
field value = fieldValue + 10
updateRows.updateRow(updateRow)
del updateRow, updateRows 2. This might be useful info: http://forums.arcgis.com/threads/70773-Row-objects-in-the-Data-Access-module?p=248106&viewfull=1#post248106. It presents a more "user friendly" way of setting/getting the field values (by field name and not directly by index). So the code above would then look like this: updateRows = arcpy.da.UpdateCursor(myTbl, ["MY_FIELD"])
for updateRow in updateRows:
fieldValue = updateRow[updateRows.fields.index("MY_FIELD")]
field value = fieldValue + 10
updateRows.updateRow(updateRow)
del updateRow, updateRows Hope some of this helps.
... View more
04-02-2013
09:57 AM
|
0
|
0
|
5116
|
|
POST
|
Are you sue there is no lock on the table when you were trying to run the update cursor (you aren't looking at it in ArcCatalog, etc. at the same time you are trying to run your update)? Can you execute this line successfully: arcpy.da.UpdateCursor(table_to_update, ["*"]). If so, maybe it's an issue with your specified field name?
... View more
04-02-2013
08:34 AM
|
0
|
0
|
5116
|
|
POST
|
1) Learn Python - since you are dealing with so many datasets you will want to automate this. 2) You can "aggregate" a months worth of data (for example, get the mean UV level for all the rasters from May 1978), using the 'Cell Statistics' Spatial Analyst tool: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//009z0000007q000000.htm 3. You can use the 'Combine' Spatial Analyst tool (http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//009z0000007r000000.htm) to, in effect, overlay all your month-based aggregates into a single raster, where the output raster will have fields coresponding to you mothly aggregates... such as 'JAN_1978','FEB_1978', etc. You could then use the Combine raster output for analysis... For example, export the attribute table to a PivotTable in Excel.
... View more
03-13-2013
09:28 AM
|
0
|
0
|
2523
|
|
POST
|
Per what Lucas said, the .fidset property only works when there is a selected set - Note that a definition query is NOT a selection. The oidValueList = [r[0] for r in arcpy.da.SearchCursor(myLayer, ["OID@"])]. method will return a list regardless of a selection or not. If there is a selected set on the feature layer/table view, then only those selected OID values will be returned. Otherwise, if there is no selected records, then all the OIDs in the feature layer/table view will be returned.
... View more
03-13-2013
09:19 AM
|
0
|
0
|
6343
|
|
POST
|
BTW: Per your actual question, the .fidset Describe property lists the OBJECTID value, no matter what it's called.
... View more
03-13-2013
09:01 AM
|
0
|
0
|
6343
|
|
POST
|
You can use describe to figure out what the 'oidFieldName' is (whether it be FID, OID, OBJECTID, or something else). oidFieldName = arcpy.Describe(myLayer).oidFieldName Worth mentioning - If you have v10.1, the data access cursors allow a MUCH faster and better way of getting a list of the selected OID values than the .fidSet describe property: oidValueList = [r[0] for r in arcpy.da.SearchCursor(myLayer, ["OID@"])]
... View more
03-13-2013
08:59 AM
|
0
|
0
|
6343
|
|
POST
|
Were you able to figure out which specific PATH value was required to get you up and running? Surely not all of those...
... View more
03-11-2013
10:24 AM
|
0
|
0
|
2214
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-25-2014 12:57 PM | |
| 1 | 08-29-2024 08:23 AM | |
| 1 | 08-29-2024 08:21 AM | |
| 1 | 02-13-2012 09:06 AM | |
| 2 | 10-05-2010 07:50 PM |
| Online Status |
Offline
|
| Date Last Visited |
08-30-2024
12:25 AM
|