|
POST
|
Using arcpy.MakeFeatureLayer_management() seems much faster than copying a layer, but when it's run as a script it still doesn't show up in the TOC and can't be referenced later either. A single backslash seems to work fine in the Python Window, "in_memory\pyLyr1."
... View more
10-25-2013
06:18 AM
|
0
|
0
|
350
|
|
POST
|
You may not want to use "lyr.datasource" for your search cursor. I originally did something similar with a DDP map and it disregards any definition queries or selections because it's using the actual source of the data instead of the layer - unless that's what you want. Here's base code I used for updating the text elements in my map. This code did separate the labels into 2 text elements, though, so that way the first half of the features would be in one column, and the second half would be in the second column. I think this might help you. I got some of this from the South Kingston, RI example available from ESRI. import arcpy, os
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "IA_Detail_2010")[0]
#Get page number from data driven page - specified in the tool parameter dialogue box
pageNum = arcpy.GetParameterAsText(0)
ddp = mxd.dataDrivenPages
arcpy.AddMessage(pageNum)
pageID = mxd.dataDrivenPages.getPageIDFromName(pageNum)
mxd.dataDrivenPages.currentPageID = pageID
#Set layer definition query, this contols the rowcount variable
pageFieldValue = pageNum
mapLyr.definitionQuery = '"pageNum" = %s' % pageNum
#Listing the text elements on the page
concatElem1 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "concat1")[0]
concatElem2 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "concat2")[0]
#Finds the number of features in the map and sets up the lists to evenly distribute into the two text elements/columns
rowcount = int(arcpy.GetCount_management("IA_Detail_2010").getOutput(0))
percolumn = round(rowcount / 2.0)
count1 = 1
count2 = rowcount
#Specifies the features being used for the SearchCursor
sortfield = "crash"
rows = arcpy.SearchCursor(mapLyr, "", "", "CONCAT")
fieldrow = arcpy.SearchCursor(mapLyr, "", "", "pageNum", sortfield + " A")
currentpage = ""
text_var1 = str()
text_var2 = str()
#The first for and if block limits the searched rows to the definition query
#The seconded/indented for and if block adds the text fields to the text elements
for row in fieldrow:
if currentpage != row.pageNum:
currentpage = row.pageNum
for row in rows:
if count1 <= percolumn:
text_var1 += '{0}{1}'.format(row.getValue("CONCAT"), os.linesep)
concatElem1.text = text_var1
count1 += 1
elif count2 > percolumn:
text_var2 += '{0}{1}'.format(row.getValue("CONCAT"), os.linesep)
concatElem2.text = text_var2
count2 - 1
else:
pass
else:
pass
#Removed the definition query so all page numbers appear when the script is run next and refresh he layout view
mapLyr.definitionQuery = ""
arcpy.RefreshActiveView()
del mxd, row, rows, rowcount, percolumn, count1, count2
... View more
10-24-2013
10:24 AM
|
0
|
0
|
697
|
|
POST
|
So it can run much much faster, but when I try to have my script create the layer copies to RAM, I get an error because the script doesn't add the layers to the TOC, so when the line setting the RAM layers as variables tries to run, it can't and it says the layer name is out of range. Is there a special way to carry out a "CopyFeatures_management" and have it usable in the script? Here's my layer set up: mxd = arcpy.mapping.MapDocument("Current")
arcpy.env.workspace = "in_memory"
mapLyr1 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid400_IowaSP") [0]
mapLyr2 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid100_IowaSP") [0]
arcpy.CopyFeatures_management(mapLyr1, "in_memory\pyLyr1")
arcpy.CopyFeatures_management(mapLyr2, "in_memory\pyLyr2")
pyLyr1 = arcpy.mapping.ListLayers(mxd, "pyLyr1") [0]
pyLyr2 = arcpy.mapping.ListLayers(mxd, "pyLyr2") [0] I tried and to refresh the active view, but that didn't work. This works fine it I copy and paste everything into the Python window instead of running it as a tool, although it's much slower.
... View more
10-24-2013
10:16 AM
|
0
|
0
|
1891
|
|
POST
|
Holy Cow! I copied the two layers I'm working with to new features "in_memory", then changed all layer references from the real layers to the memory layers, and instead of 10 hours, it's looking more like 45 minutes, assuming the RAM isn't exceeded.
... View more
10-24-2013
09:16 AM
|
0
|
0
|
1891
|
|
POST
|
I tried adding arcpy.env.workspace = "in_memory" near the top of my script, hoping it would put everything in memory, but it doesn't seem any faster. I must have to change all my cursors and selections, too.
... View more
10-24-2013
08:37 AM
|
0
|
0
|
1891
|
|
POST
|
Also, I was working with arcpy.SelectLayerByAttribute_management, this that function have to be performed within ArcMap? It seemed like once I changed my expression from the shapefile location to the layer name it worked. Otherwise I received an error saying it can't select a feature class. That would make sense though because it is Select LAYER, not Select Featureclass.
... View more
10-24-2013
08:33 AM
|
0
|
0
|
1891
|
|
POST
|
I have a script that uses selection sets and cursors and it populates the field accordingly, but because there are so many records (about 130,000) I was wondering if it could be sped up by using in_memory, which I just learned about. I understand that in_memory is good until it's all used up and then it's super slow. I also understand that writing data to RAM is also only temporary and has to be retrieved from RAM back to the HDD. Are there certain instances where it's useful like a new feature layer or table is being created in RAM instead of something like an update cursor? I'll post my code below. import arcpy, os, time
from datetime import datetime
from datetime import timedelta
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr1 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid400_IowaSP") [0]
mapLyr2 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid100_IowaSP") [0]
#alpha will be assigned a letter to rows2 update, there are 16
place = 0
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']
searchrow = 0
ck1 = searchrow
ck2 = ck1 + 1
ck3 = ck2 + 1
ck4 = ck3 + 1
ck5 = ck4 + 1
cl1 = timedelta()
cl2 = timedelta()
cl3 = timedelta()
cl4 = timedelta()
cl5 = timedelta()
rows1 = arcpy.SearchCursor(mapLyr1, "", "", "Name")
rowcount = int(arcpy.GetCount_management(mapLyr1).getOutput(0))
allrows = (rowcount + 0.0)
for row in rows1:
clock1 = datetime.now()
bigtile = str()
arcpy.SelectLayerByAttribute_management(mapLyr1, "NEW_SELECTION", '"FID" = %s' %searchrow)
bigtile = row.getValue("Name")
print bigtile
searchrow = searchrow + 1
prgrow = (searchrow + 0.0)
arcpy.SelectLayerByLocation_management(mapLyr2, "HAVE_THEIR_CENTER_IN", mapLyr1, 0, "ADD_TO_SELECTION")
rows2 = arcpy.UpdateCursor(mapLyr2, "", "", "", "FID")
for row2 in rows2:
row2.tile = bigtile + alpha[place]
rows2.updateRow(row2)
place = place + 1
if place == 16:
place = 0
arcpy.SelectLayerByAttribute_management(mapLyr1, "CLEAR_SELECTION")
arcpy.SelectLayerByAttribute_management(mapLyr2, "CLEAR_SELECTION")
prgrss = ((prgrow / allrows)*100.0)
rowsleft = rowcount - searchrow
clock2 = datetime.now()
clock3 = (clock2 - clock1)
if ck1 == searchrow:
cl1 = clock3
ck1 = ck1 + 5
elif searchrow == ck2:
cl2 = clock3
ck2 = ck3 + 5
elif searchrow == ck3:
cl3 = clock3
ck3 = ck3 + 5
elif searchrow == ck4:
cl4 = clock3
ck4 = ck4 + 5
elif searchrow == ck5:
cl5 = clock3
ck5 = ck5 + 5
if searchrow < 5:
pass
elif searchrow > 4:
clock4 = ((cl1 + cl2 + cl3 + cl4 + cl5)/5)
clock5 = (clock4 * rowsleft)
clock6 = str(clock5)
arcpy.AddMessage("The last 5 iterations averaged %s" %clock4)
arcpy.AddMessage("%s estimated time remaining" %clock6)
arcpy.AddMessage("%d%% completed - row %d out of %d rows" %(prgrss, searchrow, rowcount))
arcpy.AddMessage("______________________________")
del mxd, row, rows1, row2, rows2, searchrow, place, bigtile, rowcount, prgrow, allrows, prgrss, rowsleft, clock1, clock2, clock3
... View more
10-23-2013
09:31 AM
|
0
|
11
|
8528
|
|
POST
|
Thanks for the link. This script is being used on a shapefile with ~8500 features to name the tiles (16x16) within each of those ~8500 features, so about 130,000 features are being calculated. My script ran fine, it just took 8-10 hours. I was looking into a time left message by getting the time at the beginning of each loop and again at the end, then multiplying that by the number of loop cycles left, but I'm using the Python deltatime function and can't figure out how to format it. I tried clock1 = datetime.now() #beginning of loop
clock2 = datetime.now() end of loop
clock3 = ((clock2 - clock1) * rowsleft) # rowsleft is total records minus completed records
clock4 = clock3.strftime('%d Days, %h Hours, %M Minutes, %S Seconds') but I get an error that 'datetime.timedelta' object has no attribute 'strftime' so I'm not sure how to get that working. Anyway, the script does run, it just took a really long time, so I learned it's nice to know when a long script is working properly versus being in an infinite loop.
... View more
10-11-2013
10:26 AM
|
0
|
0
|
867
|
|
POST
|
The problem with row in the nested loop was that it didn't match the row.Update(row) part a couple lines down. The interpreter was just giving me a 99999 error with no description. Here's my working script. The only problem is that my percent calculation doesn't work for some reason. I don't know why, but it always just says 2.00000 percent regardless of what it looks like the calculation should be. This took several hours to run so that's why I included the AddMessage lines to each main loop. import arcpy, os
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr1 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid400_IowaSP") [0]
mapLyr2 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid100_IowaSP") [0]
#alpha will be assigned a letter to rows2 update, there are 16
place = 0
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']
searchrow = 0
rows1 = arcpy.SearchCursor(mapLyr1, "", "", "Name")
rowcount = int(arcpy.GetCount_management(mapLyr1).getOutput(0))
allrows = (rowcount + 0.0)
for row in rows1:
bigtile = str()
arcpy.SelectLayerByAttribute_management(mapLyr1, "NEW_SELECTION", '"FID" = %s' %searchrow)
bigtile = row.getValue("Name")
print bigtile
searchrow = searchrow + 1
prgrow = (searchrow + 0.0)
arcpy.SelectLayerByLocation_management(mapLyr2, "HAVE_THEIR_CENTER_IN", mapLyr1, 0, "ADD_TO_SELECTION")
rows2 = arcpy.UpdateCursor(mapLyr2, "", "", "", "FID")
for row2 in rows2:
row2.tile = bigtile + alpha[place]
rows2.updateRow(row2)
place = place + 1
if place == 16:
place = 0
arcpy.SelectLayerByAttribute_management(mapLyr1, "CLEAR_SELECTION")
arcpy.SelectLayerByAttribute_management(mapLyr2, "CLEAR_SELECTION")
prgrss = ((prgrow / allrows)*100.0)
arcpy.AddMessage("%d current row" %searchrow)
arcpy.AddMessage("%d total rows" %rowcount)
arcpy.AddMessage("%f percent completed" %prgrss)
arcpy.AddMessage("______________________________")
del mxd, row, rows1, row2, rows2, searchrow, place, bigtile, rowcount, prgrow, allrows Edit: fixed variable prgss to match prgrss.
... View more
10-11-2013
04:37 AM
|
0
|
0
|
867
|
|
POST
|
Thanks. That's what I ended up doing. But I didn't realize you could use a defined variable as the index number in the list. I thought it was necessary to format the line with something like alpha[%d] %letterplace. Here's my final script, but it is taking FOREVER to run through all the features. import arcpy, os
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr1 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid400_IowaSP") [0]
mapLyr2 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid100_IowaSP") [0]
#alpha will be assigned a letter to rows2 update, there are 16
place = 0
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']
name = str()
searchrow = 0
rows1 = arcpy.SearchCursor(mapLyr1, "", "", "Name")
rows2 = arcpy.UpdateCursor(mapLyr2, "", "", "tile")
rows = arcpy.UpdateCursor(mapLyr2)
for row in rows1:
name = row.getValue("Name")
print name
arcpy.SelectLayerByAttribute_management(mapLyr1, "NEW_SELECTION", '"FID" = %s' %searchrow)
searchrow = searchrow + 1
arcpy.SelectLayerByLocation_management(mapLyr2, "HAVE_THEIR_CENTER_IN", mapLyr1, 0, "ADD_TO_SELECTION")
for row in rows2:
row.tile = name + alpha[place]
rows2.updateRow(row)
place = place + 1
if place == 16:
place = 0
del mxd, rows, rows1, rows2, searchrow Is it necessary to define "row in rows2:" as "row2 in rows2" since row is in use by rows1? I thought "row" was a keyword used by arcpy, because I think trying "row2 in rows2" was giving me an error.
... View more
10-10-2013
04:54 AM
|
0
|
0
|
867
|
|
POST
|
I need to add a letter to the end of a field name that increases for the selection set. I have two shapefiles I'm working with of mosaiced tiles. My script selects a large tile, copies the name value, then selects the smaller tiles from the second shapefile and assigns it the copied name. But I need each of the smaller tiles to have a letter appended on so they each have different names. It is possible to use a variable on a list to incrementally go to the next letter? Here's my script, and it works with just adding the letter "A" to the end. import arcpy, os
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr1 = arcpy.mapping.ListLayers(mxd, "NEW_BiState_Grid400_IowaSP") [0]
mapLyr2 = arcpy.mapping.ListLayers(mxd, "GridIndexFeatures20") [0]
#alpha will be assigned a letter to rows2 update, there are 16
alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p']
name = str()
searchrow = 0
rows1 = arcpy.SearchCursor(mapLyr1, "", "", "Name")
rows2 = arcpy.UpdateCursor(mapLyr2, "", "", "tile")
rows = arcpy.UpdateCursor(mapLyr2)
for row in rows1:
name = row.getValue("Name")
print name
arcpy.SelectLayerByAttribute_management(mapLyr1, "NEW_SELECTION", '"FID" = %s' %searchrow)
searchrow = searchrow + 1
arcpy.SelectLayerByLocation_management(mapLyr2, "HAVE_THEIR_CENTER_IN", mapLyr1, 0, "ADD_TO_SELECTION")
for row in rows2:
row.tile = name + A
rows2.updateRow(row)
del mxd, rows, rows1, rows2, searchrow
... View more
10-08-2013
10:01 AM
|
0
|
7
|
1229
|
|
POST
|
You're right. I just don't know of another way to loop through each combination to perform all the calculations, and that was the best I could do. It is long, and it was a lot to copy and paste and make changes to, but like I said, I don't know how else to direct the script through each possibility.
... View more
09-23-2013
01:29 PM
|
0
|
0
|
792
|
|
POST
|
Here's one entire block for BUILD_STAT 10 and DIR 1 rows = arcpy.UpdateCursor(mapLyr)
for row in rows:
row.F2010_AB_C = 0 #clear all capacities to 0
row.F2010_BA_C = 0
row.F2019_AB_C = 0
row.F2019_BA_C = 0
row.F2025_AB_C = 0
row.F2025_BA_C = 0
row.F2045_AB_C = 0
row.F2045_BA_C = 0
rows.updateRow(row)
#find capacity variables
rnam = row.getValue("ROAD_NAM")
ffc = row.getValue("LRTP_FFC")
at = row.getValue("TYPE_AREA")
lan10 = row.getValue("F2010_NUML")
lan19 = row.getValue("F2019_NUML")
lan25 = row.getValue("F2025_NUML")
lan45 = row.getValue("F2045_NUML")
dic = {"ROAD_NAM": rnam, "LRTP_FFC": ffc, "TYPE_AREA": at}
#begin capacity calculation
if row.BUILD_STAT == 10 and row.F2010_DIR == 1:
row.F2010_AB_C = capacity(**dic) * lan10
rows.updateRow(row)
if row.F2019_DIR == 1:
row.F2019_AB_C = capacity(**dic) * lan19
rows.updateRow(row)
if row.F2025_DIR == 1:
row.F2025_AB_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2025_DIR == -1:
row.F2025_BA_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2025_AB_C = capacity(**dic) * lan25
row.F2025_BA_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2019_DIR == -1:
row.F2019_BA_C = capacity(**dic) * lan19
rows.updateRow(row)
if row.F2025_DIR == 1:
row.F2025_AB_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2025_DIR == -1:
row.F2025_BA_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2025_AB_C = capacity(**dic) * lan25
row.F2025_BA_C = capacity(**dic) * lan25
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2019_AB_C = capacity(**dic) * lan19
row.F2019_BA_C = capacity(**dic) * lan19
rows.updateRow(row)
if row.F2025_DIR == 1:
row.F2025_AB_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2025_DIR == -1:
row.F2025_BA_C = capacity(**dic) * lan25
rows.updateRow(row)
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2025_AB_C = capacity(**dic) * lan25
row.F2025_BA_C = capacity(**dic) * lan25
if row.F2045_DIR == 1:
row.F2045_AB_C = capacity(**dic) * lan45
rows.updateRow(row)
elif row.F2045_DIR == -1:
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row)
else:
row.F2045_AB_C = capacity(**dic) * lan45
row.F2045_BA_C = capacity(**dic) * lan45
rows.updateRow(row) I realize how long it is, but it does work and that's what matters most to me. But since I'm still pretty new to scripting I'm very happy to learn other ways of coding. I have a little brushing up to do on matrices, but is it possible to replace my entire capacity function with a matrix or table and under the specific conditions a cell value is returned?
... View more
09-20-2013
06:18 AM
|
0
|
0
|
792
|
|
POST
|
Thank you for the reply, Stacy. Actually, the ..DIR fields or 1 and -1 have different results, 1 will calculate for A to B flow of traffic and -1 will calculate for B to A flow. I used else in place of setting the condition to 0 because it's the only other value in that field. Your idea using yr as a variable is excellent, I never would have thought of that. That would work for the majority of my network, but I have to yr variables that do not have a corresponding 'F20%s' value. I originally tried using setValue, but it wouldn't update my attribute values. When I had success with updateCursor I decided to work with that. I did get the whole thing working stretched out with IF statements, and it didn't take as long as I thought it would because it only needed a few value changes with the correct indentation. It's just really long, 868 lines. Since at first when I was just testing to get it working I forgot that each calculation year has a corresponding NUML year, I just had to add three more variables. I thought it would take longer to run on my network which is about 7,900 features, and it only takes about 10 seconds. It's definitely way better than using my capacity calculation in the field calculator tool and manually defining queries and working within the attribute table. There are no input parameters, all the variables are hard coded. Here's my final script: import arcpy, os, sys
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "CUR_Master_Network_2045")[0]
#Single Lane Capacity Generator
def capacity(ROAD_NAM, LRTP_FFC, TYPE_AREA):
if ROAD_NAM == "Interstate 74 Bridge":
return 19000
elif ROAD_NAM == "Interstate 80 Bridge":
return 18000
elif ROAD_NAM == "Interstate 280 Bridge":
return 19000
elif ROAD_NAM == "Centennial Bridge":
return 11000
elif ROAD_NAM == "Arsenal Bridge":
return 9500
elif LRTP_FFC == 1:
return 19000
elif LRTP_FFC == 2:
if TYPE_AREA == 1:
return 8500
elif TYPE_AREA == 2:
return 8650
elif TYPE_AREA == 3:
return 9000
elif TYPE_AREA == 4:
return 9000
elif TYPE_AREA == 5:
return 8000
else:
pass
elif LRTP_FFC == 3:
if TYPE_AREA == 1:
return 8200
elif TYPE_AREA == 2:
return 8300
elif TYPE_AREA == 3:
return 8500
elif TYPE_AREA == 4:
return 8500
elif TYPE_AREA == 5:
return 7500
else:
pass
elif LRTP_FFC == 4:
if TYPE_AREA == 1:
return 6300
elif TYPE_AREA == 2:
return 7500
elif TYPE_AREA == 3:
return 7500
elif TYPE_AREA == 4:
return 7500
elif TYPE_AREA == 5:
return 7500
else:
pass
elif LRTP_FFC == 5:
if TYPE_AREA == 1:
return 5300
elif TYPE_AREA == 2:
return 6500
elif TYPE_AREA == 3:
return 6500
elif TYPE_AREA == 4:
return 6500
elif TYPE_AREA == 5:
return 5700
else:
pass
elif LRTP_FFC == 6:
return 15200
elif LRTP_FFC == 7:
if TYPE_AREA ==1:
return 4800
elif TYPE_AREA == 2:
return 6000
elif TYPE_AREA == 3:
return 6000
elif TYPE_AREA == 4:
return 6000
elif TYPE_AREA == 5:
return 5200
else:
pass
elif LRTP_FFC == 8:
return 99999
else:
return 0
... View more
09-20-2013
06:18 AM
|
0
|
0
|
792
|
|
POST
|
Short Explanation: I have 8 fields I need to calculate that uses 2 fields as variables as to designate which of the 8 fields to calculate. Long Explanation: I have a streets feature class that I need to be able to update traffic capacity for. There are 4 intervals (2010, 2019, 2025, and 2045) and the capacity is calculated with directionality, so for each year interval there are 2 capacity fields - 8 fields total. Each street feature has a field for each year interval that specifies if it's one-way (1 or -1 depending on how the feature was drawn) or two-way. If it's a two-way street then both fields are calculated and if it's one-way then the direction field dictates which field to calculate for. Easy enough. To complicate that a little more I have a field that needs to specify which years street is "valid" for and that dictates which years to calculate capacity for. So far I have my calculation function working; it's my python field calculator script. I also have a single year calculating properly. So the road name, function, area type, and number of lanes are what I'm using to calculate capacity. I'm using an updateCursor to retrieve data values and assign the calculated values. Disregarding the function for now, here's what I have: import arcpy, os, sys
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "CUR_Master_Network_2045")[0]
rows = arcpy.UpdateCursor(mapLyr)
for row in rows:
row.F2010_AB_C = 0 #clear all capacities to 0
row.F2010_BA_C = 0
row.F2019_AB_C = 0
row.F2019_BA_C = 0
row.F2025_AB_C = 0
row.F2025_BA_C = 0
row.F2045_AB_C = 0
row.F2045_BA_C = 0
rows.updateRow(row)
#find capacity variables
rnam = row.getValue("ROAD_NAM")
ffc = row.getValue("LRTP_FFC")
at = row.getValue("TYPE_AREA")
lan = row.getValue("F2010_NUML")
dic = {"ROAD_NAM": rnam, "LRTP_FFC": ffc, "TYPE_AREA": at}
#begin capacity calculation
if row.BUILD_STAT == 10 and row.F2010_DIR == 1:
row.F2010_AB_C = capacity(**dic) * lan
rows.updateRow(row)
elif row.BUILD_STAT == 10 and row.F2010_DIR == -1:
row.F2010_AB_C = capacity(**dic) * lan
rows.updateRow(row)
elif row.BUILD_STAT == 10 and row.F2010_DIR == 0:
row.F2010_AB_C = capacity(**dic) * lan
row.F2010_BA_C = capacity(**dic) * lan
rows.updateRow(row)
else:
pass
del row, rows This is working great, but it's only for a single set of parameters - BUILD_STAT 10 and the three possible directions. What's the best way to add code to calculate not only BUILD_STAT 10 but also 19, 25, and 45 and follow the directions? Do I just need to keep nesting if statements for each BUILD_STAT year? import arcpy, os, sys
#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "CUR_Master_Network_2045")[0]
rows = arcpy.UpdateCursor(mapLyr)
for row in rows:
row.F2010_AB_C = 0 #clear all capacities to 0
row.F2010_BA_C = 0
row.F2019_AB_C = 0
row.F2019_BA_C = 0
row.F2025_AB_C = 0
row.F2025_BA_C = 0
row.F2045_AB_C = 0
row.F2045_BA_C = 0
rows.updateRow(row)
#find capacity variables
rnam = row.getValue("ROAD_NAM")
ffc = row.getValue("LRTP_FFC")
at = row.getValue("TYPE_AREA")
lan = row.getValue("F2010_NUML")
dic = {"ROAD_NAM": rnam, "LRTP_FFC": ffc, "TYPE_AREA": at}
#begin capacity calculation
if row.BUILD_STAT == 10 and row.F2010_DIR == 1:
row.F2010_AB_C = capacity(**dic) * lan
rows.updateRow(row)
if row.F2019_DIR == 1:
row.F2019_AB_C = capacity(**dic) * lan
rows.updateRow(row)
elif row.F2019_DIR == -1:
row.F2019_BA_C = capacity(**dic) * lan
rows.updateRow(row)
else:
row.F2019_AB_C = capacity(**dic) * lan
row.F2019_BA_C = capacity(**dic) * lan
elif row.BUILD_STAT == 10 and row.F2010_DIR == -1:
row.F2010_AB_C = capacity(**dic) * lan
rows.updateRow(row)
if row.F2019_DIR == 1:
row.F2019_AB_C = capacity(**dic) * lan
rows.updateRow(row)
elif row.F2019_DIR == -1:
row.F2019_BA_C = capacity(**dic) * lan
rows.updateRow(row)
else:
row.F2019_AB_C = capacity(**dic) * lan
row.F2019_BA_C = capacity(**dic) * lan
elif row.BUILD_STAT == 10 and row.F2010_DIR == 0:
row.F2010_AB_C = capacity(**dic) * lan
row.F2010_BA_C = capacity(**dic) * lan
rows.updateRow(row)
if row.F2019_DIR == 1:
row.F2019_AB_C = capacity(**dic) * lan
rows.updateRow(row)
elif row.F2019_DIR == -1:
row.F2019_BA_C = capacity(**dic) * lan
rows.updateRow(row)
else:
row.F2019_AB_C = capacity(**dic) * lan
row.F2019_BA_C = capacity(**dic) * lan
else:
pass
del row, rows The only problem is each if and elif will need every possible outcome as it goes through the conditions. Is there a better way?
... View more
09-19-2013
08:46 AM
|
0
|
5
|
1371
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 09-24-2014 08:42 AM | |
| 1 | 01-30-2015 09:21 AM | |
| 1 | 01-30-2015 09:25 AM |
| Online Status |
Offline
|
| Date Last Visited |
11-11-2020
02:24 AM
|