My client would like his shapefiles reprojected and I would like to get a script that can batch process all the files located in the same folder. I am new to Python and ArcPy but am very interested. We are using ArcMap10 as our platform software. Any help or advice would be greatly appreciated.
2 Answers
The batch project tool is designed for just such a task
The help files provide a really clear standalone python example, which can be adapted to meet your needs:
# Name: BatchProject.py
# Description: Changes coordinate systems of several datasets in a batch.
import arcpy
from arcpy import env
# Set workspace environment
env.workspace = "C:/data/wgs1972.gdb"
# Input feature classes
input_features = ["cities", "counties", "blocks", "crime"]
# Output workspace
out_workspace = "C:/data/output.gdb"
# Output coordinate system - leave it empty
out_cs = ''
# Template dataset - it has GCS_WGS_1984 coordinate system
template = "C:/data/wgs1984.gdb/stateparks"
# Geographic transformation -
transformation = "WGS_1972_To_WGS_1984_1"
try:
res = arcpy.BatchProject(input_features, out_workspace, out_cs, template, transformation)
if res.maxSeverity == 0:
print "projection of all datasets successful"
else:
print "failed to project one or more datasets"
except:
print res.getMessages()
And here is my slight modifications of the script to run on a collection of shapefiles of unknown names, with my additional comments in block capitals, to try and outline what is happening where.
# Name: BatchProject.py
# Description: Changes coordinate systems of several datasets in a batch.
import arcpy, os #USE OPERATING SYSTEM FUNCTIONS
from arcpy import env
#THIS IS THE PATH TO YOUR DATA
mypath = "C:/data/"
#THIS IS AN EMPTY LIST WHERE WE WILL STORE OUR SHAPEFILE NAMES
shapefiles = []
# Set workspace environment
env.workspace = mypath
# Input feature classes
#HERE WE WILL USE THE OS.PATH FUNCTIONS TO GET A CRUDE LIST OF ALL
#OF THE SHAPEFILES IN THE DIRECTORY, BY GETTING A LIST OF ALL FILES
#IN THE DIRECTORY AND THEN FILTERING OUT ONLY FILES WITH THE .SHP EXTENSION
for filename in os.listdir(mypath):
if filename.endswith('.shp'):
shapefiles.append(filename)
# Output workspace
#THIS IS WHERE THE REPROJECTED SHAPEFILES WILL BE SAVED, THIS FOLDER MUST EXIST
out_workspace = "C:/data/output"
# Output coordinate system - leave it empty
#IF YOU ARE NOT USING A TEMPLATE SHAPEFILE,
#YOUR PROJECTION PARAMETERS WOULD GO IN HERE
out_cs = ''
# Template dataset - it has GCS_WGS_1984 coordinate system
template = "C:/data/stateparks.shp"
# Geographic transformation -
transformation = "WGS_1972_To_WGS_1984_1"
#THE TRY/EXCEPT STRUCTURE IS USED TO CATCH ANY ERRORS AND RETURN THE ERROR MESSAGES
try:
#THIS LINE SETS UP THE BATCHPROJECT PARAMETERS
res = arcpy.BatchProject(input_features, out_workspace, out_cs, template, transformation)
if res.maxSeverity == 0: #THIS RUNS THE PROJECTION FOR ALL OF THE LISTED LAYERS
print "projection of all datasets successful"
else:
print "failed to project one or more datasets"
except:
print res.getMessages() #DISPLAYS ANY ERROR MESSAGES
This code is quite extensive; the same result could be achieved in many fewer lines, however this (I hope!) gives you a good overview of the arcpy object.
-
4One caveat: all of the shapefiles being processed have to be in the same projection initially, so that the same transformation can be used. Commented Sep 7, 2012 at 14:16
-
Thanks that looks like exactly what i was looking for. Much apprecieted!– JasonCommented Sep 10, 2012 at 11:00
If you want your output as a shapefile instead of a geodatabase, you can use the second codeblock of sgrieve and replace the try:
part with the following:
try:
for shapefile in shapefiles:
arcpy.Project_management(mypath + os.sep + shapefile, mypath + os.sep + "porj" + shapefile, out_cs, transformation)
else:
print "failed to project one or more datasets"
The output shapefiles will be renamed with proj as prefix.