|
POST
|
Breaking the problem into smaller steps, we can use a dictionary to group the raster files. I assume the filenames are consistent in format? from datetime import datetime
# lstrasters = glob.glob(di + os.sep + "*Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth_Land.tif")
lstrasters = [ # list from your directory search
'MOD04_3K.A20161.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A20162.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2017152.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2017153.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2017254.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2017255.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2018356.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif',
'MOD04_3K.A2018357.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif'
] # these 'rasters' are for months 1 in 2016 (will error), months 6 and 9 in 2017, and month 12 in 2018
rasters = { 2017: {1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[],9:[],10:[],11:[],12:[]},
2018: {1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[],9:[],10:[],11:[],12:[]}
} # starting dictionary
for r in lstrasters:
jdate = r.split(".")[1][1:] # get date portion, splitting on periods
# jdate = r[10:17] # if date is always 7 characters and same position
year = int(jdate[:4])
month = int(datetime.strptime(jdate, '%Y%j').date().strftime("%m"))
if year in rasters.keys():
rasters[year][month].append(r)
else:
print "ERROR year {}: {}".format(year, r)
for k1,v1 in rasters.iteritems():
print "Year: {}".format(k1)
for k2,v2 in v1.iteritems():
if len(v2):
print "\tMonth: {}".format(k2)
for r in v2:
print '\t\t{}'.format(r)
''' Output:
ERROR year 2016: MOD04_3K.A20161.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
ERROR year 2016: MOD04_3K.A20162.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
Year: 2017
Month: 6
MOD04_3K.A2017152.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
MOD04_3K.A2017153.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
Month: 9
MOD04_3K.A2017254.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
MOD04_3K.A2017255.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
Year: 2018
Month: 12
MOD04_3K.A2018356.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
MOD04_3K.A2018357.mosaic.061.2017271115004.pssgmcrpgs_000501268215.Corrected_Optical_Depth_Land_2-Corrected_Optical_Depth.Land.tif
''' Are you anticipating some invalid Julian dates - day 0 or 367, for example? If so, can you explain a bit more? Next step would be to process your files. I take another look at your code later.
... View more
10-05-2018
05:25 PM
|
1
|
2
|
3545
|
|
POST
|
And after I re-read Esri's comment, I started thinking milliseconds. So "23:59:59" could also miss "23:59:59.9".
... View more
10-05-2018
12:46 PM
|
0
|
0
|
2646
|
|
POST
|
When dealing with date/time, I probably wouldn't use "=" in the query. See Joshua Bixby's second comment in this thread with ESRI's explanation.
... View more
10-05-2018
12:31 PM
|
0
|
2
|
2646
|
|
POST
|
You could try 'Between' and set hours = '00:00:00' and '23:59:59' (between will get both these values and all those inbetween). Or add another day with timedelta. dp = date_past.strftime("%Y-%m-%d")
wc = "Field IS NULL AND DateField BETWEEN DATE '{} 00:00:00' AND DATE '{} 23:59:59' ".format(dp,dp))
... View more
10-05-2018
12:08 PM
|
1
|
0
|
383
|
|
POST
|
Typo on my part, an extra minus in days=180 (updated original code): date_past = datetime.now() - timedelta(days=180)
... View more
10-05-2018
11:15 AM
|
1
|
6
|
2646
|
|
POST
|
Perhaps (you could remove time from formatting, if desired): from datetime import datetime, timedelta
date_past = datetime.now() - timedelta(days=180) # you can add/subtract as required
wc = "Field IS NULL AND DateField < DATE '{}'".format(date_past.strftime("%Y-%m-%d %H:%M:%S"))
print wc
# Field IS NULL AND DateField < DATE '2018-04-08 09:25:35'
... View more
10-05-2018
10:27 AM
|
0
|
8
|
2646
|
|
POST
|
Are you asking about a way to walk through a directory and find gdb's? One way: import arcpy, os
from arcpy import env
workspace = r"C:\Path\to\explore"
for dirpath, dirnames, filenames in arcpy.da.Walk(workspace, datatype="Container"):
for dirname in dirnames:
if ".gdb" in dirname:
env.workspace = os.path.join(dirpath, dirname)
# print env.workspace
tableList = arcpy.ListFeatureClasses()
# print tableList
for table in tableList:
# print
print "{}\t{}\t{}".format(dirpath, dirname, table)
... View more
10-02-2018
02:04 PM
|
1
|
1
|
4264
|
|
POST
|
I would suggest reading the tables into a couple of dictionaries, using a process similar to what is described in Richard Fairhurst's blog: Turbo Charging Data Manipulation with Python Cursors and Dictionaries. One way would be: import arcpy
relatedTbl = r"C:\Path\to\file.gdb\InspectionHistory"
relatedFields = ['OBJECTID', 'IDENTIFIER', 'ESTABLISHMENTNAME', 'CITY', 'INSPDATE'] # IDENTIFIER is the key field and second in field list
relatedWhere = "INSPDATE BETWEEN DATE '2017-09-01' AND DATE'2017-10-01'"
# dictionary in format {'ITEMID': ('IDENTIFIER', 'ITEM1', 'ITEM2', ...), ...}
relatedDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(relatedTbl, relatedFields, where_clause=relatedWhere)}
# print relatedDict
# get a list of keys for parent where clause: v[0] = IDENTIFIER
keyList = []
for k, v in relatedDict.iteritems():
# print k, v[0]
keyList.append(v[0])
parentFC = r"C:\Path\to\file.gdb\RestaurantInspections"
parentFields = ['IDENTIFIER', 'OBJECTID', 'ESTABLISHMENTNAME', 'CITY'] # IDENTIFIER is the key field and is first in field list
parentWhere = "IDENTIFIER IN ('{}')".format("','".join(set(keyList))) # assuming IDENTIFIER is string, using ' -- omit for numeric key
print parentWhere
# dictionary in format {'IDENTIFIER': ('ITEM1', 'ITEM2', ...), ...}
parentDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(parentFC, parentFields, where_clause=parentWhere)}
# print combined results
for k, v in relatedDict.iteritems():
print k, v[0], v[1], v[2], v[3], parentDict[v[0]][0], parentDict[v[0]][1], parentDict[v[0]][2]
... View more
09-30-2018
08:28 PM
|
0
|
0
|
1611
|
|
POST
|
Did you try: lyr.definitionQuery = "BANDID = 'GRNN00A'" Often the field name is not quoted; it depends on the geodatabase type/server.
... View more
09-28-2018
09:47 AM
|
2
|
4
|
2620
|
|
POST
|
Here is the test code I was using inside ArcMap. I've made a number of changes to your original code, including assuming the values for 'SUP' and 'pourc_serv' are in the 'Bati_Service' table; if not, the code will need to be adjusted on line 12. import arcpy
# the table we are using
inTable = "Bati_Service"
# the field that will be created and updated
fieldName = "tax"
# expression is used to compute 'tax' field's value
# we need to pass 'SUP' and 'pourc_serv' to function --
# code assumes these are fields in the table
expression = "getClass(float(!SUP!),float(!pourc_serv!))"
# this is the function that will compute the 'tax' value
codeblock ="""# code starts next line to make indentation easier to read
def getClass(SUP, pourc_serv):
if (SUP < 100.0):
return (pourc_serv /100.0)* SUP * 2.0
elif (SUP >= 100.0 and SUP < 200.0):
return (pourc_serv /100.0)* (SUP * 3.8 )
elif (SUP >= 200.0 and SUP < 400.0):
return (pourc_serv /100)* (SUP * 5.4 )
elif (SUP >= 400.0):
return (pourc_serv /100.0)* (SUP * 6.4 )"""
# Execute AddField
# if field exists a warning message may display, but the script should continue
arcpy.AddField_management(inTable,fieldName, "DOUBLE")
# Execute CalculateField
# this will update the 'tax' field
arcpy.CalculateField_management(inTable,fieldName,expression, "PYTHON_9.3",codeblock)
print 'done' This is what my 'Bati_Service' Table looked like, before: and after: If your table looks much different, add a photo showing some sample data. If you get an error, please post it. If the code works, then you can try pasting it into your button code. The indentation should look similar to the example in my first posting. Hope this helps.
... View more
09-24-2018
07:51 PM
|
0
|
1
|
2258
|
|
POST
|
It is possible the token has expired. But it is more likely that you do not appear to be the same user when the token is pasted into Integromat.
... View more
09-24-2018
12:56 PM
|
0
|
1
|
6045
|
|
POST
|
Per Darren Wiens' suggestion, see the Calculate Field examples - particularly the one with the codeblock example with the 3 double quotes before and after the block since the one you want to use is over multiple lines. You also need to use the expression to pass the SUP and pourc_serv variables (I assume these are fields in your table/feature). The 'tax' will be the return value of the function. And the CalculateField line also needs the proper items. Here's my suggestions for your code. I have not tested it, however I would suggest testing lines 8-25 in its own script before putting it in a button add-in as the add-in is harder to debug. If you get an error message, please post it so we can better help you. class ButtonClass1(object):
"""Implementation for Bouton_addin.button (Button)"""
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
inTable = "Bati_Service"
fieldName = "tax"
expression = "getClass(float(!SUP!),float(!pourc_serv!))"
codeblock ="""
def getClass(SUP, pourc_serv):
if (SUP < 100.0):
return (pourc_serv /100.0)* (SUP * 2.0)
elif (SUP >= 100.0 and SUP < 200.0):
return (pourc_serv /100.0)* (SUP * 3.8 )
elif (SUP >= 200.0 and SUP < 400.0):
return (pourc_serv /100)* (SUP * 5.4 )
elif (SUP >= 400.0):
return (pourc_serv /100.0)* (SUP * 6.4 )"""
# Execute AddField
arcpy.AddField_management(inTable,fieldName, "DOUBLE")
# Execute CalculateField
arcpy.CalculateField_management(inTable,fieldName,expression, "PYTHON_9.3",codeblock)
... View more
09-22-2018
07:55 PM
|
0
|
1
|
2258
|
|
POST
|
Try this change: layerName = 'Street'
for lyr in arcpy.mapping.ListLayers(mxd, layerName): # remove [0]
... View more
09-21-2018
01:04 PM
|
0
|
0
|
2049
|
|
POST
|
Thanks for formatting. It helps to see the indentation. Regarding line 23: selCount = len(lyr.getSelectionSet()) If lyr.getSelectionSet() == None, then len will return an error. You might want to check first: if lyr.getSelectionSet():
selCount = len(lyr.getSelectionSet())
# do other things with the layer selection Since you are using MapDocument("CURRENT"), are you planning to only use the tool inside ArcMap?
... View more
09-21-2018
12:32 PM
|
0
|
0
|
4938
|
|
POST
|
You might try something like: import arcpy,sys, os
arcpy.env.overwriteOutput = True
arcpy.env.workspace = r"C:\GIS\MyGeodatabase.gdb"
mxd = arcpy.mapping.MapDocument("CURRENT")
layerName = 'street'
for lyr in arcpy.mapping.ListLayers(mxd, layerName)[0]:
if lyr.getSelectionSet(): # If there are selected features
arcpy.AddMessage("{} has {} features selected".format(lyr.name, len(lyr.getSelectionSet()))
# Process: Copy Features
arcpy.CopyFeatures_management(Street , street_CopySelected, "", "0", "0", "0")
... View more
09-21-2018
10:46 AM
|
1
|
2
|
2049
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-27-2016 02:23 PM | |
| 1 | 09-09-2017 08:27 PM | |
| 2 | 08-20-2020 06:15 PM | |
| 1 | 10-21-2021 09:15 PM | |
| 1 | 07-19-2018 12:33 PM |
| Online Status |
Offline
|
| Date Last Visited |
02-12-2026
07:13 PM
|