Breaking Out a Time Enabled Layer into sub-layers organized by Month Year

Discussion created by gnewburyiv on Feb 7, 2013
Thought I'd post some code I just wrote.  Situation is I have a master index feature class showing footprints of imagery collects over the last 8 years. I'm going to publish these as a pdf document, but many of the collects are over the same areas, so I wanted to break out the collects by month and year, so that in the table of contents end-users could turn layers on and off without being overwhelmed by all of the polygons. I had a time field in the feature class and so i figured why should i have to go through and manually create a layer for each month.

The following code takes an existing layer, in my case I named it as 'defaultLayer' in the arcmap TOC, makes a copy, sets the definition query, and then moves it to the group folder for the year.  All of the year calcs are based on the time field. I created the group year folders manually. See the attached image and code below. Note, it is a simple script, there is no error catching. so just use it as inspiration for what you need to get done. It is intended to be run from within ArcMap. When looking at the code. the time field is 'Date_Completed_AsDate'.


from datetime import date
import calendar

def jump_by_month(start_date, end_date, month_step=1):
    current_date = start_date
    while current_date < end_date:
        yield current_date
        carry, new_month = divmod(current_date.month - 1 + month_step, 12)
        new_month += 1
        current_date = current_date.replace(year=current_date.year + carry, month=new_month)

mxd = arcpy.mapping.MapDocument("Current")
mmf = arcpy.mapping.ListDataFrames(mxd,"*Main*")[0]
defaultLayer = arcpy.mapping.ListLayers(mxd,"defaultLayer",mmf)[0]
for layerMonth in jump_by_month(defaultLayer.time.startTime, defaultLayer.time.endTime):   
    # Make a copy of the the layer by adding the layer back to the top, then get the new reference to it
    addLayer = arcpy.mapping.ListLayers(mxd,"defaultLayer",mmf)[0]

    # Change the Name of the Layer = layerMonth.strftime("%b %Y")
    # Setup the Definition Query
    begMonth = layerMonth
    endMonth = layerMonth + datetime.timedelta(calendar.monthrange(begMonth.year,begMonth.month)[1]) - datetime.timedelta(0,1)
    print "begMonth: " + begMonth.strftime("%Y-%m-%d %H:%M:%S") + "\t endMonth : " + endMonth.strftime("%Y-%m-%d %H:%M:%S")
    defQuery = """ "Date_Completed_AsDate" >= date ' """ + begMonth.strftime("%Y-%m-%d %H:%M:%S") + """' AND  "Date_Completed_AsDate" <= date '""" + endMonth.strftime("%Y-%m-%d %H:%M:%S") + "'"
    addLayer.definitionQuery = defQuery

    # Add it to the Group Layer    
    targetGroupLayer = arcpy.mapping.ListLayers(mxd, layerMonth.year ,mmf)[0]
    arcpy.mapping.AddLayerToGroup(mmf, targetGroupLayer, addLayer, "BOTTOM")

    # Remove the copy made at the top
    removeLayer = arcpy.mapping.ListLayers(mxd,layerMonth.strftime("%b %Y"),mmf)[0]
    arcpy.mapping.RemoveLayer(mmf, removeLayer)