Read folder paths out of text file and project the shapefiles

1104
8
Jump to solution
07-31-2017 01:12 AM
JohannesBierer
Occasional Contributor III

The following python code should read out of a text file folder paths and project the shapefiles in this folder. Unfortunately this works only with the last (folder) line? Any suggestions why this doesn't work?

# Import arcpy module
import arcpy, os

fname = r"H:\python_scripte\ProjizierenMulti\test.txt"

with open(fname) as f:
    for line in f:
        
        print line
        
        arcpy.env.workspace = line
        workspace = arcpy.env.workspace
        arcpy.env.overwriteOutput = True

        # Use the ListFeatureClasses function to return a list of
        #  shapefiles.
        featureclasses = arcpy.ListFeatureClasses()

        # Copy shapefiles to a file geodatabase
        for fc in featureclasses:
            print "Projiziere " + fc

            outfile = os.path.splitext(fc)[0] + "_E.shp"
                
            spatialRef = arcpy.Describe(fc).spatialReference

            print spatialRef.name

            Ftype = arcpy.Describe(fc).datatype

            print Ftype
                
            if Ftype == "ShapeFile": 
                
                if spatialRef.name == "DHDN_3_Degree_Gauss_Zone_3":
                                        
                    arcpy.Project_management(fc, outfile, "PROJCS['ETRS_1989_UTM_Zone_32N_8stellen',GEOGCS['GCS_ETRS_1989',DATUM['D_ETRS_1989',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Transverse_Mercator'],PARAMETER['False_Easting',32500000.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',9.0],PARAMETER['Scale_Factor',0.9996],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]", "DHDN_To_ETRS_1989_3", "PROJCS['DHDN_3_Degree_Gauss_Zone_3',GEOGCS['GCS_Deutsches_Hauptdreiecksnetz',DATUM['D_Deutsches_Hauptdreiecksnetz',SPHEROID['Bessel_1841',6377397.155,299.1528128]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Gauss_Kruger'],PARAMETER['False_Easting',3500000.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',9.0],PARAMETER['Scale_Factor',1.0],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]")
                    
f.close()
0 Kudos
1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Emeritus

Then you should be able to narrow down where it isn't working from your other print statements.

Why don't you read the whole text file, put each folder path into a list, then run through that list instead rather than assuming that it will read one line at a time.  It would definitely be cleaner and remove any doubt that it has something to do with how the text file is read.  Worth a shot

View solution in original post

8 Replies
DanPatterson_Retired
MVP Emeritus

put a print statement on line 36 or 38 to print the fc name and the outfile. as a check

0 Kudos
JohannesBierer
Occasional Contributor III

If I do this it prints the fc name of the shape in the last folder of the txt file and correctly the name of the shape + "_E.shp" as the projected shapefile?

0 Kudos
JohannesBierer
Occasional Contributor III

Somehow it loops through the first for ... loop without going to the second for ... loop. Can't you use two for loops in one script?

0 Kudos
DanPatterson_Retired
MVP Emeritus

Then you should be able to narrow down where it isn't working from your other print statements.

Why don't you read the whole text file, put each folder path into a list, then run through that list instead rather than assuming that it will read one line at a time.  It would definitely be cleaner and remove any doubt that it has something to do with how the text file is read.  Worth a shot

Luke_Pinner
MVP Regular Contributor

It's probably because you're not stripping the newline/carriage return character off each line and the last line doesn't have a trailing return.

Try line = line.strip() in the body of your for loop.

JohannesBierer
Occasional Contributor III

Now I use a list with:

flist = open(fname).read().splitlines()

And this does the job quite well 🙂

0 Kudos
Luke_Pinner_DAWE
New Contributor II

Yep that'll do it. One caveat... you may need to avoid that syntax (i.e reading the whole file into memory) if processing very large files. 

Another option is to use a "generator" expression. Generators iterate over something one at a time and don't load the whole list into memory. For reading a file, you could do something like:

flist = (line.rstrip() for line in open(fname))
for f in flist:
    do something with f
‍‍‍‍‍‍‍

or

for f in (line.rstrip() for line in open(fname)):
    do something with f
‍‍‍‍‍

Note the generator expression is similar to a list comprehension, i.e. [line.rstrip() for line in open(fname)] but uses parentheses instead of square brackets around the code.  A list comprehension will build the whole list in memory, but a generator will only access one element as required.

JohannesBierer
Occasional Contributor III

Thank you Luke Pinner for the explanation concerning generator expressions.

0 Kudos