Last active
August 29, 2015 13:56
-
-
Save brianbancroft/9233576 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Main Program, used to georeference and index rasters. This is intended to be run in ArcGIS 10.1 or higher. | |
#import basic modules | |
import os, arcpy, shutil | |
#import all modules from 3rd parties | |
import xlrd, xlwt, zipfile | |
############################BEGIN LOCAL FUNCTIONS##################################### | |
###a1. Check for error:### | |
def checkForError(row, rasList): | |
output = "no name match" | |
#Go to first raster in list of rasters - for loop | |
for raster in rasList: | |
#does the raster name match cycled match the one in the excel row object? | |
if str(row[0].value[:-5]) == str(raster[:-5]): | |
#is the bounding of the raster in the excel row object rectangular? | |
if row[5].value == 'Rectangular' or row[5].value == 'rectangular': | |
#are all the numerical fields filled? | |
n = 6 | |
while n < 14: | |
if row[n].value == "" | |
output = "incomplete latlong fields" | |
n += 1 | |
if output != "incomplete latlong fields": | |
output = "" | |
else: | |
output = "bounding not rectangular - manual georef required" | |
return output | |
###a2. addError: ### | |
def addError(inrow, pr, yr, error, wrkBk): | |
#open output workbook using xlrd | |
workbook = xlrd.open_workbook(wrkBk) | |
worksheet = workbook.sheet_by_index(0) | |
#get length of workbook | |
nrows = worksheet.nrows - 1 | |
#create output workbook from scratch | |
outwb = xlwt.Workbook(encoding = 'UTF-8') | |
outws = outwb.add_sheet("log") | |
#populate existing cells from outsheet into new book | |
n = 0 | |
while n <= nrows: | |
m = 0 | |
while m < 17: | |
outws.write(n,m,worksheet.cell(n,m).value) | |
m += 1 | |
n += 1 | |
del m,n | |
#populate new row with the row entries from the source spreadsheet | |
m = 0 | |
while m <= 13: | |
outws.write(n,m, inrow[m].value) | |
m += 1 | |
#add year, province, error type | |
outws.write(n,14,yr) | |
outws.write(n,15,pr) | |
outws.write(n,16,error) | |
#Save and overwrite | |
outwb.save(wrkBk) | |
###a3. georef:### | |
def georef(xlRow, inDir, outDir, inRas, scratch): | |
#set scratch location of georeferenced file | |
outRas = scratch + "/" + inRas | |
inRasPath = inDir + "/" + inRas | |
#Use arcpy.GetRasterProperties_management to get position of raster edges | |
import arcpy | |
fcLeft = arcpy.GetRasterProperties_management(inRasPath, "LEFT") | |
fcRight = arcpy.GetRasterProperties_management(inRasPath, "RIGHT") | |
fcTop = arcpy.GetRasterProperties_management(inRasPath, "TOP") | |
fcBottom = arcpy.GetRasterProperties_management(inRasPath, "BOTTOM") | |
#Use xlrd to get the real-world location of the raster edges in NAD 1927 | |
tgTop = float(xlRow[10].value) | |
tgBottom = float(xlRow[6].value) | |
tgLeft = float(xlRow[9].value * -1) | |
tgRight = float(xlRow[7].value * -1) | |
#Pad data to create the source and destination coordinates to be used. | |
srcPts = ("'" + str(fcRight) + " " + str(fcBottom) + "';'" + str(fcLeft) | |
+ " " + str(fcBottom) + "';'" + str(fcLeft) + " " + str(fcTop) | |
+ "';'" + str(fcRight) + " " + str(fcTop) + "'") | |
destPts = ("'" + str(tgRight) + " " + str(tgBottom) + "';'" + str(tgLeft) | |
+ " " + str(tgBottom)+ "';'" + str(tgLeft) + " " + str(tgTop) | |
+ "';'" + str(tgRight) + " " + str(tgTop) + "'") | |
#Define the projection of the raster to NAD 1927 | |
arcpy.DefineProjection_management(inRasPath, "GEOGCS['GCS_North_American_1927'" + | |
",DATUM['D_North_American_1927',SPHEROID['Clarke_1866'" + | |
",6378206.4,294.9786982]],PRIMEM['Greenwich',0.0],UNIT" + | |
"['Degree',0.0174532925199433]]") | |
removeLayers() | |
#Run the warp_management tool to georeference the raster. | |
#output also goes to the scratch directory + //outRas// | |
arcpy.Warp_management(inRasPath,srcPts,destPts,outRas) | |
removeLayers() | |
#(FUTURE TASK) Add metadata | |
#(Possible future component, add data on where the raster can be found online) | |
#(Zip all files in the //scratch// directory, move the new file to the output directory | |
zipArch = outDir + "/" + inRas[:-6] + ".zip" | |
zip = zipfile.ZipFile(zipArch, 'w') | |
for f in os.listdir(scratch): | |
fl = scratch + "/"+ f | |
if f[:-5] in inRas: | |
zip.write(fl) | |
zip.close() | |
#delete copied raster, all files in the //scratch// directory as well as the directory itself | |
#for f in os.listdir(scratch): | |
# os.remove(scratch + "/" + f) | |
####a4. createFootprint:### | |
def footprint(row, fc, prov, year): | |
#From Excel row, pull xy data into an array of arrays of floats | |
#Example: [[x1,y1],[x2,y2],[x3,y3],[x4,y4]] | |
top = float(row[10].value) | |
bottom = float(row[6].value) | |
left = float(row[9].value * -1) | |
right = float(row[7].value * -1) | |
featArray = [[right, bottom],[left, bottom],[left, top],[right,top]] | |
#Turn Array into a polygon object | |
featGeom = arcpy.Polygon(arcpy.Array([arcpy.Point(*Coords) | |
for Coords in featArray])) | |
#Create insertCursor | |
cursor = arcpy.da.InsertCursor(fc, ("filename", "title", | |
"subtitle", "province", "year", | |
"Grid_Type", "Scale", "SHAPE@")) | |
#Use the cursor to insert a row | |
cursor.insertRow((row[0].value[-5],row[1].value,row[2].value, | |
prov, year, row[3].value[:-10], | |
row[3].value[-8:], featGeom)) | |
removeLayers() | |
############################SECONDARY FUNCTIONS####################################### | |
###b1. Create create footprint | |
def createFootprint(dir): | |
in_table = "raster_footprint.shp" | |
arcpy.CreateFeatureclass_management(dir, in_table) | |
fieldList = ["filename","title","subtitle", | |
"province","year","Grid_Type","Scale"] | |
n = 0 | |
while n < len(fieldList): | |
arcpy.AddField_management(dir + "/" + in_table, fieldList[n] , "TEXT") | |
n += 1 | |
return(dir + "/" + in_table) | |
###b2. Set Coordinate System | |
def setDataFrameGCS(): | |
mxd = arcpy.mapping.MapDocument("CURRENT") | |
df = arcpy.mapping.ListDataFrames(mxd)[0] | |
df.spatialReference = arcpy.SpatialReference(4267) | |
###b3. Create Error Log | |
def createErrorLog(dir): | |
#construct sheet | |
fc = "errorLog-" + str(datetime.date.today()) + ".xls" | |
wb = xlwt.Workbook(encoding = 'UTF-8') | |
ws = wb.add_sheet("log") | |
#Populate first row | |
cellEntry = ["File","Map_Title","Map_Subtitle","grid_type/scale", | |
"projection","bounding","SE_LAT","SE_LONG","SW_LAT", | |
"SW_LONG","NW_LAT","NW_LONG","NE_LAT","NE_LONG", | |
"YEAR","PROVINCE","ERROR"] | |
n = 0 | |
while n < len(cellEntry): | |
ws.write(0,n,cellEntry[n]) | |
n += 1 | |
#save book | |
if os.path.isfile("C:/Temp" + "/" + fc) == False: | |
wb.save(dir + "/" + fc) | |
else: | |
fc = ("errorLog-" + | |
datetime.datetime.now().strftime("%m-%d_t%H%M") + ".xls") | |
wb.save(dir + "/" + fc) | |
return(dir + "/" + fc) | |
###b4. Create Success Log | |
def createLog(dir): | |
#construct sheet | |
fc = "success_log-" + str(datetime.date.today()) + ".xls" | |
wb = xlwt.Workbook(encoding = 'UTF-8') | |
ws = wb.add_sheet("log") | |
#Populate first row | |
cellEntry = ["File","Map_Title","Map_Subtitle","grid_type/scale", | |
"projection","bounding","SE_LAT","SE_LONG","SW_LAT", | |
"SW_LONG","NW_LAT","NW_LONG","NE_LAT","NE_LONG", | |
"YEAR","PROVINCE"] | |
n = 0 | |
while n < len(cellEntry): | |
ws.write(0,n,cellEntry[n]) | |
n += 1 | |
#save book | |
if os.path.isfile("C:/Temp" + "/" + fc) == False: | |
wb.save(dir + "/" + fc) | |
else: | |
fc = ("success_log-" + | |
datetime.datetime.now().strftime("%m-%d_t%H%M") + ".xls") | |
wb.save(dir + "/" + fc) | |
return(dir + "/" + fc) | |
###b5. Remove Layers | |
def removeLayers(): | |
mxd = arcpy.mapping.MapDocument("CURRENT") | |
for df in arcpy.mapping.ListDataFrames(mxd): | |
for lyr in arcpy.mapping.ListLayers(mxd, "", df): | |
arcpy.mapping.RemoveLayer(df, lyr) | |
del mxd | |
############################END LOCAL FUNCTIONS####################################### | |
#########################PARAMETERS######################################## | |
#Get directory with Excel Files (Parameter - from arcgis tool) | |
#1. Scratch File Directory: | |
scratchDir = "C:/Temp/Scratch" #FUTURE PARAMETER | |
#2. Output directory: | |
outputDir = "C:/Temp/outputDir" #FUTURE PARAMETER | |
#3. Excel File Directory: | |
fileDir = "C:/Temp/" #FUTURE PARAMETER | |
#4. geotif directory: | |
tifDir = "C:/Temp/tiffs" | |
#5. unionshape directory | |
unionShapefile = "" | |
#######################END PARAMETERS##################################### | |
#Set Data Frame Coordinate system to NAD 1927: | |
setDataFrameGCS() | |
#Get list of all files within that directory | |
dirList = os.listdir(tifDir) | |
#Get list of tiffs, ensure it is just a list of tiffs with nothing else. | |
tifList = [] | |
for l in dirList: | |
if l[-4:] == ".tif": | |
tifList.append(l) | |
del dirList | |
#List Files, keep only files with "xlsx" extension | |
workbookList = [] | |
dirList = os.listdir(fileDir) | |
for l in dirList: | |
if l[-4:] == "xlsx": | |
if l[:-5] != "Template" or l[:-5] != "template": | |
workbookList.append(l) | |
del dirList | |
#Create errorlog, successlog. | |
errorLog = createErrorLog(outputDir) | |
#successLog = createLog(outputDir) | |
#For loop - for workbook in workbookList | |
for workbookname in workbookList: | |
inFc = fileDir + workbookname | |
#open workbook | |
workbook = xlrd.open_workbook(inFc) | |
#create list of spreadsheeks in open workbook | |
worksheetList = workbook.sheet_names() | |
#For loop - for spreadsheet in spreadsheetList | |
for tabIndex in worksheetList: | |
#Ensure spreadsheet isn't named "template" or "Template" | |
if tabIndex != "Template" and tabIndex != "template": | |
#Open Worksheet | |
worksheet = workbook.sheet_by_name(tabIndex) | |
#Get row count, for loop cycling through rows | |
for rownum in xrange(worksheet.nrows): | |
#skip first row (if rowNum != 0) | |
if rownum != 0: | |
errorMessage = "" | |
#open row | |
worksheetRow = worksheet.row(rownum) | |
#errorMessage = checkForError({tiff list}, {row entry}) | |
errorMessage = checkForError(worksheetRow, tifList) | |
#does errorMessage equal ""? | |
if errorMessage != "" : | |
#Run the addError function | |
addError(worksheetRow, workbookname[:-5], | |
tabIndex, errorMessage, errorLog) | |
else: | |
#If no, run the geoRef function | |
georef(worksheetRow, tifDir, outputDir, | |
worksheetRow[0].value[:-5] + "C.tif", scratchDir) | |
if arcpy.Exists(unionShapefile) != True: | |
#Create new footprint shapefile | |
unionShapefile = createFootprint(outputDir) | |
#Run the footprint function | |
footprint(worksheetRow, unionShapefile, | |
workbookname[:-5], tabIndex) | |
#(future scope): Run the NTS Option | |
#Run the recipt of files index method | |
#Zip footprint file | |
#(future scope)Zip NTS footprint file | |
#delete mxd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First revision: Program altered to comply with parts of style guide (http://legacy.python.org/dev/peps/pep-0008/). Still to follow: Use of modules.