Batch define projection with Python

3773
6
09-22-2010 07:56 AM
SofiaStouki
New Contributor II
Hi all,

I am fairly new to Python and I have been trying to make a script work-to assign a GC system to a number of shapefiles in a folder.(The GC system is currently Unknown so I cannot use the other tools in batch mode)

I am using Python 2.5 and Arc 9.3.1 but I keep getting errors
( for fc in fcS:
TypeError: 'geoprocessing list object' object is not iterable)

that don't really tip me off about what it s going wrong (newbie)

My code is:
import arcgisscripting
gp = arcgisscripting.create()

gp.workspace = "P:\Proj"
gp.toolbox = "management"
coordsys = "Coordinate Systems/Projected Coordinate Systems/National Grids/British National Grid.prj"
fcs = gp.ListFeatureClasses()
for fc in fcS:
gp.defineprojection(fcS, coordsys)

I am certain there are a lot of errors there, but if anyone can assist with the iteration/listing of the shapefiles in the folder it would be great.

Thanks in advance for any suggestions.
S.
0 Kudos
6 Replies
JamesHood
Occasional Contributor
Try this.  It should clean up most of the minor errors.


import arcgisscripting, sys, os
gp = arcgisscripting.create()

# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")


#workspace
gp.Workspace = "P:\\Proj"

coordsys = "C:\\Program Files\\ArcGISCoordinate Systems\\Projected Coordinate Systems\\National Grids\\British National Grid.prj"

#List all features in  gp.workspace
fcs = gp.ListFeatureClasses("", "")
fc = fcs.Next()

for fc in fcs:
     gp.defineprojection(fcS, coordsys)
     print fc + " is defined."



The directory of your tool box and coordinate file may differ from mine.  check that in case of error.
0 Kudos
SofiaStouki
New Contributor II
Hi James,

thanks for your code. I tried it (after checking the paths) and I still get the same error

<type 'exceptions.TypeError'>: 'geoprocessing list object' object is not iterable
Failed to execute (Script).

I really don t know too many things about this, but a) does this mean it cannot locate the workspace and consequently cannot iterate through the folder?

b) Is it just a case of replacing the backshlashes with forward ones?

Thanks in advance for any suggestions!
S.
0 Kudos
SofiaStouki
New Contributor II
Sorry for double posting but I got the script to work from the Python shell. It seems like the errors were caused by different syntax rules for ArcGIS v. 9.3. I found these threads to be very useful in my attempts to make this work

( http://forums.esri.com/Thread.asp?c=93&f=1729&t=263822
http://resources.arcgis.com/content/kbase?fa=articleShow&d=31879)

The complete code now is:

import arcgisscripting, sys, os
gp = arcgisscripting.create(9.3)
gp.Overwriteoutput = 1
# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")


#workspace
gp.workspace = "P:\ProjTest"

coordsys = "C:/Program Files/ArcGIS/Coordinate Systems/Projected Coordinate Systems/National Grids/British National Grid.prj"

#List all features in  gp.workspace
fcs = gp.ListFeatureClasses("*")
#fc = fcs.Next()

for fc in fcs:
     gp.defineprojection(fc, coordsys)
     print fc + " is defined."

I hope this might help someone else as well. James, thanks again for your help!
S.
0 Kudos
CedricWannaz
New Contributor II
Hi Sofia and James,

You had the error because the Geoprocessor method ListFeatureClasses() returns a Python List, as described here. Under Syntax, you can see the type that is returned:
object.ListFeatureClasses({wildCard} As String, {FeatureType} As String) As Python List


A way to scan a list in Python is as you do with your for loop:
for anElement in myList:
      do something ..


but lists don't have a Next() method that you initially tried to call with "fc = fcs.Next()". This is a confusion with iterable objects that, for example, methods for creating cursors usually return. The documentation for the SearchCursor() method available here states under syntax that the return is an object (and no more a simple Python List):

object.SearchCursor(InputValue As String, {WhereClause} As String, {SpatialReference} As Object, {FieldList} As String, {SortFields} As String) As Object


This object that is returned has methods, and one of them is called Next(), that returns the next element as an object. This is illustrated in the Geoprocessor Programming Model that available here as a PDF. The left column contains methods of the Geoprocessor, and the other "boxes" contain descriptions (properties, methods) of the objects that these methods return. If you lookup SearchCursor() in the left column, you will see that it returns an object that contains the rows, and that this object has a Next() method that returns another object: the next row. This object has a property called FieldName and a method called GetValue(), and so on ..

The Geoprocessor and all the objects that are returned by the different toolboxes are a quite complex structure, and it is almost impossible to guess (at least in the beginning) what is the type of the objects that we are dealing with, without using the help (the information about the type of returned values) and (to a lesser extent) the programming model.

Cheers,

Cedric
0 Kudos
SofiaStouki
New Contributor II
It makes sense, especially seeing the differences in syntax for each version. It just makes me wish that the rules were more uniform, regardless of which product you are using.

Anyway, thanks for the links-the geoprocessor model is very useful to have as a reference.:)

Cheers,
S.
0 Kudos
JoeFlannery
Occasional Contributor III
Sofia:

Have you seen ESRI's Batch Define Coordinate System python script in the Samples Toolbox for ArcMap?

http://resources.arcgis.com/content/kbase?fa=articleShow&d=30873
0 Kudos