I have an interesting problem. I have been asked to create a set of polygons using dates. Below is an example table showing the data. As you can see the table is sorted by start year.
What I have to do is generate a set of polygons each time the start year, month and day changes. So the first polygon will just contain the first row of data. The second polygon will contain both the first and second and so on.
There is also another element to this. Each row of data has an end year, month and day. If a row has an end year of 2300 then that row will stay in the output once it has been added. If there is an end year that does not equal 2300 then that row will not be included in future versions of the output.
So is there anyone who can help? I have about two hundred tables like the one above. Would like a model builder solution.
Thanks in anticipation.
Paul
Solved! Go to Solution.
Hi Xander,
Thank you so much. It now does what I want it to do. You are a star.
Many thanks
Paul
Please then, mark one of Xander's answers as correct...currently the thread is still open
Hi Dan,
Sorry, how do I do that?
Thanks
Paul
for each thread there should be a greenish star with test beside it saying "correct answer" click on it for the thread that answered your question and NOT this one
I'm glad it worked for you. Good luck!
Hi Xander,
Just one more thing. How can I use your script to run against multiple input shapefiles?
Thanks
Paul
Hi Paul,
That is possible, but it might be necessary to know a little more on the folder structure where you have your input featureclasses and how you want to name the outputs.
Normally a arcpy.ListFeatureclasses() can be used to get a list of featureclasses in the current workspace. In case they are in multiple folders and sub folders the arcpy.da.Walk() is better. Based on the input name, you can create an outputname (like for instance inputname_merged).
The current script can be rewritten as a function to process a single featureclass. This function will be called from the loop through the input featureclasses.
Kind regards, Xander
Hi Xander,
Thanks for the reply.
My shapefiles are currently in this folder C:\Users\PaulBritten\Desktop\tenure\All reserves
and the out put name would be as you suggest with the _merged at the end of the name.
I will admit that I am not a python expert at all and have no idea how to amend/update the python script with any new functionality. Therefore would you mind amending your script?
Many thanks and sorry to be such a pain.
Paul
Hi Paul,
Don't worry, that what the forum is all about... to help one another.
Have a look at the code below. The majority is placed inside a function "MergePolygonsOnDate". The main function (lines 13 - 23) contains the logic for looping through your featureclasses. It will create a list of all the featureclasses in you workspace. Based on the input name it will create the new output names. On line 23 for each featureclass the "MergePolygonsOnDate" is called. I haven't tested the code, so if you run into problems, just post it and I'll have a look.
#-------------------------------------------------------------------------------
# Name: MergePolygonsOnDate_v3.py
# Purpose: Merge polygons on date range
#
# Author: xbakker
#
# Created: 19/08/2014
#-------------------------------------------------------------------------------
import arcpy, os
from datetime import datetime, timedelta
def main():
# specify the workspace
ws = r"C:\Users\PaulBritten\Desktop\tenure\All reserves"
arcpy.env.workspace = ws
arcpy.env.overwriteOutput = True
lst_fc = arcpy.ListFeatureClasses()
for fc in lst_fc:
name, ext = os.path.splitext(fc)
fc_out = "{0}_merged{1}".format(name, ext)
MergePolygonsOnDate(os.path.join(ws, fc), os.path.join(ws, fc_out))
def MergePolygonsOnDate(fc, fc_out):
# change settings
fld_start = "DateFrom" # create date field and fill it with content of StartDate
fld_end = "DateTo" # create date field and fill it with content of EndDate
fld_name = "Name"
fld_outname = "OutputName" # output name
len_outname = 75
# create empty output shapefile
ws_path, fc_out_name = os.path.split(fc_out)
arcpy.CreateFeatureclass_management(ws_path, fc_out_name,
"POLYGON", fc, "SAME_AS_TEMPLATE", "SAME_AS_TEMPLATE", fc)
# add string field
arcpy.AddField_management(fc_out, fld_outname, "TEXT", "", "", len_outname)
flds = ("SHAPE@", fld_start, fld_end, fld_name)
flds_out = ("SHAPE@", fld_start, fld_name, fld_outname)
# create a unique list of dates from start date
lst_dates = list(set([row[0] for row in arcpy.da.SearchCursor(fc, (fld_start))]))
lst_dates.sort()
# insert cursor to store features to new featureclass
with arcpy.da.InsertCursor(fc_out, (flds_out)) as curs_out:
# loop through list of unique dates
for date in lst_dates:
# create an expression
expression = "{0} <= date '{2}' AND {1} >= date '{2}'".format(
arcpy.AddFieldDelimiters(fc, fld_start),
arcpy.AddFieldDelimiters(fc, fld_end), date)
i = 0
# create the searchcursor with the expression
with arcpy.da.SearchCursor(fc, flds, where_clause=expression) as curs:
for row in curs:
pol = row[0]
name = row[3] # take name of first polygon
if i == 0:
# first polygon is just the polygon"
polygon = pol
else:
# next polygons are added with union
polygon = polygon.union(pol)
i += 1
# insert the feature into the output featureclass
datefrom = date
i_date = lst_dates.index(date)
if i_date + 1 > len(lst_dates) - 1:
dateto = ""
outname = "{0} {1} - {2}".format(name, datefrom.strftime('%Y/%m/%d'), dateto)
else:
dateto = lst_dates[i_date + 1] - timedelta(days=1)
outname = "{0} {1} - {2}".format(name, datefrom.strftime('%Y/%m/%d'), dateto.strftime('%Y/%m/%d'))
curs_out.insertRow((polygon, row[1], name, outname))
if __name__ == '__main__':
main()
Hi Xander,
That worked brilliantly.
Many thanks
Paul