I am still somewhat raw with python, although I am learning and trying to develop some tools. What I do need help with is a script tool which creates an index of rasters. It was created by someone who no longer works here anymore. He was fairly advanced with python and he created a wide variety of script tools. The tool in question does almost exactly what I need, however I would like it to avoid certain file extensions (.OVR, .TOC). I am just unsure of where to place a statement in the code to have these file types ignored.
Hopefully someone can help out.
#------------------------------------------------------------------------------Description:
Generate footprints for all raster products within a directory. Can
optionally perform a recursive traverse to find all rasters within the
tree.
#
Produces a single shapefile output with attributes to identify each raster
dataset found.
#
ArcGIS Version: 10.0
Python Version: 2.6
------------------------------------------------------------------------------
import arcpyimport datetimeimport osimport sys
def message(msg, severity=0): """Notify the user of some event with a message.
Arcpy does not print messages to command line, and print statementsdo not appear within the Arc runtime. This method can act as a globalnotification system for both environments."""# print a message to the command lineprint msg# notify the user within the arc environment# splits a message on \n, making a notification for each line in a# multiline stringtry: for string in msg.split('\n'): # add message under appropriate severity if severity == 0: arcpy.AddMessage(string) elif severity == 1: arcpy.AddWarning(string) elif severity == 2: arcpy.AddError(string)except: # ignore errors passdef listRasters(rasterTypes = "ALL"): """Generate a list of rasters found within a workspace."""
# keep a list of all files for all typesfoundFiles = []if rasterTypes == "ALL": # just gather all file types foundFiles = arcpy.ListRasters("*", rasterTypes)else: # arcpy will not let us specify multiple file types to search for, so # we replicate that ability by appending the file lists for each # specified file type. fileTypes = rasterTypes.split(';') for fileType in fileTypes: foundFiles.extend(arcpy.ListRasters("*", fileType))# return all discovered filesreturn foundFilesdef processRasterList(shapefile, rasterList): """Process a list of rasters into coordinates and attributes.""" # make sure there is some data to be processed # if no data is found, notify the user and move on if not len(rasterList): message("No rasters found.") return
# notify the user work is startingmessage("Processing %d rasters." % len(rasterList))arcpy.SetProgressor("step", "Processing rasters...", 0, len(rasterList))# keep track of if we find any projected dataprojDataFound = Falsefor rasterStr in rasterList: # inform the user which raster is being processed arcpy.SetProgressorLabel("Processing %s" % rasterStr) # Wrap the whole thing in a try block to catch possible problems # Problems are ignored, and the user is notified that a raster was # not processed. try: # make a raster object raster = arcpy.Raster(rasterStr) except: message("Processing raster failed: %s" % rasterStr, 1) message(arcpy.GetMessages(2), 1) # abondon this raster and move on continue # notify the user if projected data is found (prefer geographic) if raster.spatialReference.type == "Unknown": projDataFound = True # generate an array to hold each corner of the raster coords = arcpy.Array() # add each corner of the raster to the array coords.add(raster.extent.lowerLeft) coords.add(raster.extent.upperLeft) coords.add(raster.extent.upperRight) coords.add(raster.extent.lowerRight) # Polygons require the start coordinate to match the end coordinate coords.add(raster.extent.lowerLeft) # make a polygon from the points array rasterPolygon = arcpy.Polygon(coords, raster.spatialReference) try: # use an insert cursor to create new records for this raster fcRows = arcpy.InsertCursor(shapefile, ) # make a new row row = fcRows.newRow() # set all the attributes row.shape = rasterPolygon row.path = raster.path row.filename = raster.name row.type = raster.format row.process_d = str(datetime.date.today()) row.num_rows = raster.height row.num_cols = raster.width row.xmin = raster.extent.XMin row.xmax = raster.extent.XMax row.ymin = raster.extent.YMin row.ymax = raster.extent.YMax row.Projection = raster.spatialReference.name row.datum = raster.spatialReference.spheroidName row.epsg_code = raster.spatialReference.factoryCode row.num_bands = raster.bandCount row.pixelw = raster.meanCellWidth row.pixelh = raster.meanCellHeight row.bit_depth = int(raster.pixelType[1:]) row.comptype = raster.compressionType # insert the row into the featureclass fcRows.insertRow(row) # free up some memory del row del fcRows del coords except: message("Cataloging raster failed: %s" % rasterStr, 1) message(arcpy.GetMessages(2), 1) # update the progress bar position arcpy.SetProgressorPosition()# notify the user if any unprojected data was foundif projDataFound: message("Unprojected data found. Check outputs.", 1)# reset the progress bar to normalarcpy.SetProgressorLabel("Looking for rasters...")arcpy.ResetProgressor()def create_featureclass(fcPath, inMemory=False): """Create a shapefile to store all the data that is collected from a raster list. Also adds all fields required for metadata about each raster.
"""# split the path into its component parts(dirName, fileName) = os.path.split(fcPath)# make all outputs WGS84 GeographicspatialReference = os.path.join(arcpy.GetInstallInfo()["InstallDir"], r"Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj")# get a path to the template shapefiletmplShp = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..', 'data', 'raster_index_tmpl.shp'))# check if creating feature in memoryif inMemory == "true": dirName = "in_memory" fileName = "memoryindex"# create the featureclassarcpy.CreateFeatureclass_management(dirName, fileName, "POLYGON", tmplShp, "DISABLED", "DISABLED", spatialReference)return os.path.join(dirName, fileName)fields come from the template shapefile, this is just for reference
# add appropriate fields to the featureclass
arcpy.AddField_management(fcPath, 'Path', 'TEXT', 254)
arcpy.AddField_management(fcPath, 'Filename', 'TEXT', 254)
arcpy.AddField_management(fcPath, 'Type', 'TEXT', 16)
arcpy.AddField_management(fcPath, 'Process_D', 'DATE')
arcpy.AddField_management(fcPath, 'NUM_Rows', 'LONG')
arcpy.AddField_management(fcPath, 'NUM_Cols', 'LONG')
arcpy.AddField_management(fcPath, 'XMin', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'XMax', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'YMin', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'YMax', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'Projection', 'TEXT', 50)
arcpy.AddField_management(fcPath, 'Datum', 'TEXT', 50)
arcpy.AddField_management(fcPath, 'EPSG_Code', 'TEXT', 6)
arcpy.AddField_management(fcPath, 'NUM_Bands', 'SHORT')
arcpy.AddField_management(fcPath, 'PixelW', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'PixelH', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'BIT_DEPTH', 'SHORT')
arcpy.AddField_management(fcPath, 'Compression', 'TEXT', 20)
def index_rasters(inputWorkspace, outputFeatureClass, processRecursive, inMemoryProcessing, fileTypes = ""): """Process all rasters within a given directory.""" # notify if using in memory processing if inMemoryProcessing == "true": message("Using in memory processing")
# support the ability to index multiple directories at the same time, either# as recursive or not.inputWorkspaces = inputWorkspace.split(';')for inWS in inputWorkspaces: # arc wraps directories in quotes for fun inWS = inWS.replace("'", "") # set the workspace to be the base directory from the user arcpy.env.workspace = inWS # if the user doesn't want to process only certain files, set "ALL" if fileTypes == "": fileTypes = "ALL" try: # create a featureclass to hold all raster metadata if len(inputWorkspaces) == 1 or not arcpy.Exists(outputFeatureClass): featureData = create_featureclass(outputFeatureClass, inMemoryProcessing) # Determine if recursive. No need to walk if not doing a recursive # list. if processRecursive == 'false': message("Gathering raster list from %s" % arcpy.env.workspace) rasterList = listRasters(fileTypes) processRasterList(featureData, rasterList) else: message("Recursive processing started.") for root, dirs, files in os.walk(inWS): # have to do this once for the top level folder arcpy.env.workspace = root message("Gathering raster list from %s" % arcpy.env.workspace) rasterList = listRasters(fileTypes) processRasterList(featureData, rasterList)for subdir in dirs:
arcpy.env.workspace = os.path.join(root, subdir)
message("Gathering raster list from %s" % arcpy.env.workspace)
rasterList = listRasters(fileTypes)
processRasterList(outputFeatureClass, rasterList)
if inMemoryProcessing == "true": # if processing was done in memory, write items to disk arcpy.Merge_management(featureData, outputFeatureClass) # delete the in memory feature class arcpy.Delete_management(featureData) except arcpy.ExecuteError: print arcpy.GetMessages(2) arcpy.AddError(arcpy.GetMessages(2)) except Exception as e: print e.args[0] arcpy.AddError(e.args[0])Test how the script is running. This allows it to run from multiple
environments, or to be included as a module into another script without
destroying environments.
if name == 'main': # gather all arguments that have been passed in argv = tuple(arcpy.GetParameterAsText(i) for i in xrange(arcpy.GetArgumentCount())) index_rasters(*argv)
أكثر...
Hopefully someone can help out.
#------------------------------------------------------------------------------Description:
Generate footprints for all raster products within a directory. Can
optionally perform a recursive traverse to find all rasters within the
tree.
#
Produces a single shapefile output with attributes to identify each raster
dataset found.
#
ArcGIS Version: 10.0
Python Version: 2.6
------------------------------------------------------------------------------
import arcpyimport datetimeimport osimport sys
def message(msg, severity=0): """Notify the user of some event with a message.
Arcpy does not print messages to command line, and print statementsdo not appear within the Arc runtime. This method can act as a globalnotification system for both environments."""# print a message to the command lineprint msg# notify the user within the arc environment# splits a message on \n, making a notification for each line in a# multiline stringtry: for string in msg.split('\n'): # add message under appropriate severity if severity == 0: arcpy.AddMessage(string) elif severity == 1: arcpy.AddWarning(string) elif severity == 2: arcpy.AddError(string)except: # ignore errors passdef listRasters(rasterTypes = "ALL"): """Generate a list of rasters found within a workspace."""
# keep a list of all files for all typesfoundFiles = []if rasterTypes == "ALL": # just gather all file types foundFiles = arcpy.ListRasters("*", rasterTypes)else: # arcpy will not let us specify multiple file types to search for, so # we replicate that ability by appending the file lists for each # specified file type. fileTypes = rasterTypes.split(';') for fileType in fileTypes: foundFiles.extend(arcpy.ListRasters("*", fileType))# return all discovered filesreturn foundFilesdef processRasterList(shapefile, rasterList): """Process a list of rasters into coordinates and attributes.""" # make sure there is some data to be processed # if no data is found, notify the user and move on if not len(rasterList): message("No rasters found.") return
# notify the user work is startingmessage("Processing %d rasters." % len(rasterList))arcpy.SetProgressor("step", "Processing rasters...", 0, len(rasterList))# keep track of if we find any projected dataprojDataFound = Falsefor rasterStr in rasterList: # inform the user which raster is being processed arcpy.SetProgressorLabel("Processing %s" % rasterStr) # Wrap the whole thing in a try block to catch possible problems # Problems are ignored, and the user is notified that a raster was # not processed. try: # make a raster object raster = arcpy.Raster(rasterStr) except: message("Processing raster failed: %s" % rasterStr, 1) message(arcpy.GetMessages(2), 1) # abondon this raster and move on continue # notify the user if projected data is found (prefer geographic) if raster.spatialReference.type == "Unknown": projDataFound = True # generate an array to hold each corner of the raster coords = arcpy.Array() # add each corner of the raster to the array coords.add(raster.extent.lowerLeft) coords.add(raster.extent.upperLeft) coords.add(raster.extent.upperRight) coords.add(raster.extent.lowerRight) # Polygons require the start coordinate to match the end coordinate coords.add(raster.extent.lowerLeft) # make a polygon from the points array rasterPolygon = arcpy.Polygon(coords, raster.spatialReference) try: # use an insert cursor to create new records for this raster fcRows = arcpy.InsertCursor(shapefile, ) # make a new row row = fcRows.newRow() # set all the attributes row.shape = rasterPolygon row.path = raster.path row.filename = raster.name row.type = raster.format row.process_d = str(datetime.date.today()) row.num_rows = raster.height row.num_cols = raster.width row.xmin = raster.extent.XMin row.xmax = raster.extent.XMax row.ymin = raster.extent.YMin row.ymax = raster.extent.YMax row.Projection = raster.spatialReference.name row.datum = raster.spatialReference.spheroidName row.epsg_code = raster.spatialReference.factoryCode row.num_bands = raster.bandCount row.pixelw = raster.meanCellWidth row.pixelh = raster.meanCellHeight row.bit_depth = int(raster.pixelType[1:]) row.comptype = raster.compressionType # insert the row into the featureclass fcRows.insertRow(row) # free up some memory del row del fcRows del coords except: message("Cataloging raster failed: %s" % rasterStr, 1) message(arcpy.GetMessages(2), 1) # update the progress bar position arcpy.SetProgressorPosition()# notify the user if any unprojected data was foundif projDataFound: message("Unprojected data found. Check outputs.", 1)# reset the progress bar to normalarcpy.SetProgressorLabel("Looking for rasters...")arcpy.ResetProgressor()def create_featureclass(fcPath, inMemory=False): """Create a shapefile to store all the data that is collected from a raster list. Also adds all fields required for metadata about each raster.
"""# split the path into its component parts(dirName, fileName) = os.path.split(fcPath)# make all outputs WGS84 GeographicspatialReference = os.path.join(arcpy.GetInstallInfo()["InstallDir"], r"Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj")# get a path to the template shapefiletmplShp = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..', 'data', 'raster_index_tmpl.shp'))# check if creating feature in memoryif inMemory == "true": dirName = "in_memory" fileName = "memoryindex"# create the featureclassarcpy.CreateFeatureclass_management(dirName, fileName, "POLYGON", tmplShp, "DISABLED", "DISABLED", spatialReference)return os.path.join(dirName, fileName)fields come from the template shapefile, this is just for reference
# add appropriate fields to the featureclass
arcpy.AddField_management(fcPath, 'Path', 'TEXT', 254)
arcpy.AddField_management(fcPath, 'Filename', 'TEXT', 254)
arcpy.AddField_management(fcPath, 'Type', 'TEXT', 16)
arcpy.AddField_management(fcPath, 'Process_D', 'DATE')
arcpy.AddField_management(fcPath, 'NUM_Rows', 'LONG')
arcpy.AddField_management(fcPath, 'NUM_Cols', 'LONG')
arcpy.AddField_management(fcPath, 'XMin', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'XMax', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'YMin', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'YMax', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'Projection', 'TEXT', 50)
arcpy.AddField_management(fcPath, 'Datum', 'TEXT', 50)
arcpy.AddField_management(fcPath, 'EPSG_Code', 'TEXT', 6)
arcpy.AddField_management(fcPath, 'NUM_Bands', 'SHORT')
arcpy.AddField_management(fcPath, 'PixelW', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'PixelH', 'FLOAT', 15, 10)
arcpy.AddField_management(fcPath, 'BIT_DEPTH', 'SHORT')
arcpy.AddField_management(fcPath, 'Compression', 'TEXT', 20)
def index_rasters(inputWorkspace, outputFeatureClass, processRecursive, inMemoryProcessing, fileTypes = ""): """Process all rasters within a given directory.""" # notify if using in memory processing if inMemoryProcessing == "true": message("Using in memory processing")
# support the ability to index multiple directories at the same time, either# as recursive or not.inputWorkspaces = inputWorkspace.split(';')for inWS in inputWorkspaces: # arc wraps directories in quotes for fun inWS = inWS.replace("'", "") # set the workspace to be the base directory from the user arcpy.env.workspace = inWS # if the user doesn't want to process only certain files, set "ALL" if fileTypes == "": fileTypes = "ALL" try: # create a featureclass to hold all raster metadata if len(inputWorkspaces) == 1 or not arcpy.Exists(outputFeatureClass): featureData = create_featureclass(outputFeatureClass, inMemoryProcessing) # Determine if recursive. No need to walk if not doing a recursive # list. if processRecursive == 'false': message("Gathering raster list from %s" % arcpy.env.workspace) rasterList = listRasters(fileTypes) processRasterList(featureData, rasterList) else: message("Recursive processing started.") for root, dirs, files in os.walk(inWS): # have to do this once for the top level folder arcpy.env.workspace = root message("Gathering raster list from %s" % arcpy.env.workspace) rasterList = listRasters(fileTypes) processRasterList(featureData, rasterList)for subdir in dirs:
arcpy.env.workspace = os.path.join(root, subdir)
message("Gathering raster list from %s" % arcpy.env.workspace)
rasterList = listRasters(fileTypes)
processRasterList(outputFeatureClass, rasterList)
if inMemoryProcessing == "true": # if processing was done in memory, write items to disk arcpy.Merge_management(featureData, outputFeatureClass) # delete the in memory feature class arcpy.Delete_management(featureData) except arcpy.ExecuteError: print arcpy.GetMessages(2) arcpy.AddError(arcpy.GetMessages(2)) except Exception as e: print e.args[0] arcpy.AddError(e.args[0])Test how the script is running. This allows it to run from multiple
environments, or to be included as a module into another script without
destroying environments.
if name == 'main': # gather all arguments that have been passed in argv = tuple(arcpy.GetParameterAsText(i) for i in xrange(arcpy.GetArgumentCount())) index_rasters(*argv)
أكثر...