Skip to content

Instantly share code, notes, and snippets.

@brianbancroft
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianbancroft/9233576 to your computer and use it in GitHub Desktop.
Save brianbancroft/9233576 to your computer and use it in GitHub Desktop.
#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
@brianbancroft
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment