The goal of this exercise was to use a suite of loops to clip and project a directory of scanned USGS topographic sheets into a seamless raster. Below are the objectives for this exercise:
- Set up the script by importing modules.
- Create variables, set up the workspace and create empty lists.
- Create a spatial reference object using the coordinate system of a tile index.
- Use an IF statement to set up a loop to read files in a directory by employing a walk statement to traverse a workspace and find files with specific criteria.
- Measure the progress of the loop.
- Add all the files of the specified criteria to a raster list.
- For each of the rasters in the list – set up a processing loop.
- Add a counter to track our progress.
- Forrmat the name of the raster.
- Project all the rasters.
- Create a polygon of the rasters topo footprint including the collar.
- Add the name of the raster to a new field.
- Add the tile to a list of tiles for a merge function.
- Merge the tiles.
- Create If statement to set up a for in loop.
- Create a search cursor and clip the rasters.
- Merge the rasters together.
Methods
Above is a flow chart of the workflow for this exercise.
Results
Below is the script created for this exercise.
#-------------------------------------------------------------------
# Name: Exercise 8: Raster processing with Booleans and Loops
# Purpose: To use a suite of loops to clip and project a directory of
# scanned USGS topographic sheets into a seamless raster.
#
# Author: Laura Hartley, hartlelj
#
# Date: 8/3/2016
#-------------------------------------------------------------------
#Ensure the program is working
print "script initialized"
#import system modules
import os
import shutil
import time
import datetime
import arcpy
from arcpy import env
from arcpy.sa import*
from arcpy.ddd import *
#Allow the script to overwrite existing files
arcpy.env.workspace = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Topos"
arcpy.env.overwriteOutput = True
arcpy.env.outputCoordinateSystem = arcpy.SpatialReference("WGS 1984 UTM Zone 16N")
arcpy.CheckOutExtension('3D')
arcpy.CheckOutExtension('spatial')
#Create Variables
print "Obtaining a list of rasters" ,datetime.datetime.now().strftime("%H:%M:%S")
workspace = r"C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Topos"
geodatabasePath = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Ex8.gdb"
#Make a feature dataset in your geodatabase using the WGS84 UTM Zone #16N CS
featureDatasetPath = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Ex8.gdb\WisconsinTiles"
#Make a scratch geodatabse for the clipped topos
clipGeodatabasePath = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Ex8.gdb"
#Set up lists and file locations
rasters = []
tileList = []
mergedFolderLocation = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Ex8.gdb"
mergedName = "KettleMoraine_Merged"
field = "FILENAME"
clipTileIndex = "C:\Users\lhartley13\Documents\ArcGIS\ex\EXAMPLE8\Ex8.gdb\WisconsinTiles\Wisconsin_24kTileIndex"
createIndex = True
clipRasters = True
mosaicRasters = True
mergedTiles = os.path.join(featureDatasetPath,mergedName)+"_TileFootprints"
#Create spatial reference object using the coordinate system of the #tile index
sr = arcpy.Describe(clipTileIndex).spatialReference
#If the boolean for create index is true, run the following code.
if(createIndex==True):
walk = arcpy.da.Walk(workspace, type="TIF")
i=0
j=0
k=0
for dirpath, dirnames, filenames in walk:
for filename in filenames:
rasters.append(os.path.join(dirpath,filename))
i=i+1
for raster in rasters:
k=i-j
print str(k) + "rasters remaining"
outName = os.path.basename(raster).rstrip(os.path.splitext (raster)[1])
print outName
outName = str(outName)
outName2 = outName.replace(" ","_")
print outName2
#By splitting the string using the index of the 3rd character, we skip the WI_ in the filename
shortened=str(outName[3:])
endIndex=shortened.index("_")+3
#Using these two new indicies, we make a new string of only the file's name
name1 = str(outName[3:endIndex])
name2 = name1.replace(" ","_")
rasterProj = os.path.join(clipGeodatabasePath,name2)+ "_Proj"
rasterTile = os.path.join(featureDatasetPath,name2)+ "_Footprint"
#Objective ten
print "Projecting" + name2 ,datetime.datetime.now().strftime("%H:%M:%S")
arcpy.ProjectRaster_management(raster,rasterProj,"","BILINEAR")
#Create a polygon of the topo's footprint, including the #collar
print "Calculating raster domain"
arcpy.RasterDomain_3d(rasterProj,rasterTile,"POLYGON")
#Add field to hold the projected raster's path name in the #polygon's attribute table
print "Adding a field"
arcpy.AddField_management(rasterTile,field,"TEXT")
#The following expression will be used to set the new #field's value to the projected
#raster's name, using an update cursor
expression = str(rasterProj)
print "Calculating field" ,datetime.datetime.now().strftime("%H:%M:%S")
with arcpy.da.UpdateCursor(rasterTile,field) as cursor:
for row in cursor:
row[0] = expression
#update row must be used for the changes to take #effect
cursor.updateRow(row)
del cursor
#Adding the tile to a list of tiles for a merge function
tileList.append(rasterTile)
j = j+1
print ""
#Merging the tiles to make a complete tile index
print "Merging the tiles" ,datetime.datetime.now().strftime("%H:%M:%S")
arcpy.Merge_management(tileList,mergedTiles)
#Objective fifteen
if(clipRasters==True):
#creating a cursor to iterate through the rasters, tile by tile
print "Clipping the collars off of the rasters" ,datetime.datetime.now().strftime("%H:%M:%S")
cursorForTopos = arcpy.da.SearchCursor(mergedTiles, field)
rastersToMosaic=[]
for row in cursorForTopos:
#Take the name from the filename field
inputRaster = str(row[0])
inputRasterName = os.path.basename(inputRaster).rstrip(os.path.splitext(inputRaster)[1])
clipBoundary = "ClipBoundary"
arcpy.MakeFeatureLayer_management(clipTileIndex,clipBoundary)
rasterBoundary = "Raster Boundary"
rasterNameField=arcpy.AddFieldDelimiters(mergedTiles,field)
value = "'%s'" % inputRaster
layerCreationSQLExpression = "%s = %s" % (rasterNameField,value)
arcpy.MakeFeatureLayer_management(mergedTiles,rasterBoundary,layerCreationSQLExpression)
arcpy.SelectLayerByLocation_management(clipBoundary,"HAVE_THEIR_CENTER_IN",rasterBoundary,"","NEW_SELECTION")
outputRaster = os.path.join(clipGeodatabasePath,inputRasterName)+"_Clip"
if arcpy.Exists(outputRaster):
print inputRasterName + "has already been clipped"
rastersToMosaic.append(outputRaster)
else:
print "Clipping" + inputRasterName ,datetime.datetime.now().strftime("%H:%M:%S")
arcpy.Clip_management(inputRaster,"",outputRaster,clipBoundary,"","ClippingGeometry","NO_MAINTAIN_EXTENT")
print inputRasterName + "Clipped" ,datetime.datetime.now().strftime("%H:%M:%S")
rastersToMosaic.append(outputRaster)
del cursorForTopos
if(mosaicRasters==True):
print "Mosaicing Topos" ,datetime.datetime.now().strftime("%H:%M:%S")
arcpy.MosaicToNewRaster_management(rastersToMosaic,mergedFolderLocation,mergedName,sr,"8_BIT_UNSIGNED","",3)
print "Mosaicing complete" ,datetime.datetime.now().strftime("%H:%M:%S")
print "script complete!" ,datetime.datetime.now().strftime("%H:%M:%S")
No comments:
Post a Comment