Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have been trying to create a Python script that will convert all shape files within a folder from GCS WGS 84 to Web Mercator. Below is the code I have so far but what I'm struggling with is how to iterate thru each of the files while creating a new name for the output (the new projected file in Web Mercator). Any ideas on how I could change this code to make this work? I know I don't have the output parameter right but I think everything else is right.

import arcpy
import glob
inFCFolder = "C:\Data"
def projectToWebM():
    for f in glob.glob(r""+ inFCFolder + "\*.shp"):
        try:
            arcpy.Project_management(f, f + r"\Project\*.shp","PROJCS['WGS_1984_Web_Mercator_Auxiliary_Sphere',GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Mercator_Auxiliary_Sphere'],PARAMETER['False_Easting',0.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',0.0],PARAMETER['Standard_Parallel_1',0.0],PARAMETER['Auxiliary_Sphere_Type',0.0],UNIT['Meter',1.0]]","#","GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]]")
        except:
            print 'Error: Unable to project ' + f

if __name__== '__main__':
    projectToWebM()
share|improve this question
add comment

4 Answers

up vote 6 down vote accepted
## Your code:
##
## import arcpy
## import glob
##
##
## inFCFolder = "C:\Data"
## def projectToWebM():
##     for f in glob.glob(r""+ inFCFolder + "\*.shp"):
##         try:
##             arcpy.Project_management(f, f + r"\Project\*.shp","PROJCS['WGS_1984_Web_Mercator_Auxiliary_Sphere',GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Mercator_Auxiliary_Sphere'],PARAMETER['False_Easting',0.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',0.0],PARAMETER['Standard_Parallel_1',0.0],PARAMETER['Auxiliary_Sphere_Type',0.0],UNIT['Meter',1.0]]","#","GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]]")
##         except:
##             print 'Error: Unable to project ' + f
##
## if __name__== '__main__':
##     projectToWebM()

# I would suggest something like this:

import arcpy
import glob
import os

# Normally the '\' character is an escape character, so you will need to use the
# r'C:\Data' raw string format, or use 'C:\\Data' to get a "backslash" in your string
# literal.
#
# See: http://docs.python.org/reference/lexical_analysis.html#literals
inFCFolder = r'C:\Data'

def projectToWebM():
    for f in glob.glob(inFCFolder + r'\*.shp'):
        try:
            # Let arcpy create a scratch name, and use os.path.basename to transfer part
            # of the original file name to the new file name.
            scratch_name = arcpy.CreateScratchName('wm_' + os.path.basename(f).replace('.shp', '') + '_', \
                                                   '', \
                                                   'Shapefile', \
                                                   inFCFolder)
            # To make it simple, I'm outputting the new projected shapefiles to the same
            # directory that they came from (guaranteed to exist). It looks like you will
            # want to put them in the "Project" folder from looking at your code. Also,
            # if your data is already projected (as in has a defined spatial reference),
            # you don't need to specify a fifth "in_coor_system" parameter.
            arcpy.Project_management(f, scratch_name, \
                                     r"PROJCS['WGS_1984_Web_Mercator_Auxiliary_Sphere'," + \
                                     r"GEOGCS['GCS_WGS_1984'," + \
                                     r"DATUM['D_WGS_1984'," + \
                                     r"SPHEROID['WGS_1984',6378137.0,298.257223563]]," + \
                                     r"PRIMEM['Greenwich',0.0]," + \
                                     r"UNIT['Degree',0.0174532925199433]]," + \
                                     r"PROJECTION['Mercator_Auxiliary_Sphere']," + \
                                     r"PARAMETER['False_Easting',0.0]," + \
                                     r"PARAMETER['False_Northing',0.0]," + \
                                     r"PARAMETER['Central_Meridian',0.0]," + \
                                     r"PARAMETER['Standard_Parallel_1',0.0]," + \
                                     r"PARAMETER['Auxiliary_Sphere_Type',0.0],"+ \
                                     r"UNIT['Meter',1.0]]")
        except:
            print 'Error: Unable to project ' + f

if __name__== '__main__':
    projectToWebM()
share|improve this answer
    
Thanks again Allan, that works. I was kind of hoping I could put the new projected wm files in a new folder but this works. Some reason it adds a "0" to the end of all the file names. I can't figure out why or how to prevent it. I think it has something to do with the basename.replace method. Any ideas? –  wilbev Sep 27 '11 at 23:05
    
scratch_name = arcpy.CreateScratchName() will add the zero (or other numbers) to make sure that file names are unique. You could remove the scratch name portion. Also, you can specify an output folder to use. I didn't in the example because a directory structure cant be sure to be the same all of the time. –  Allan Adair Sep 28 '11 at 6:20
    
Hi Allan, is it possible to pass a variable in output coordinate string? variable is UTM zone e.g. 17N –  Deep Aug 28 '12 at 14:37
add comment

I did something very similar (ETRS_1989_To_WGS_1984) this morning. The key how to iterate thru all shapefiles within a dir is to use the ListFeatureClasses function to generate a Python List of shapefiles and for loop thru this list. Hope it helps.

# Import modules
import arcpy
from arcpy import env
import os

# Set environment settings
env.workspace = "C:...\\ETRS1989"

# Set local variables
outWorkspace = "C:...\\WGS84"

# Use ListFeatureClasses to generate a list of shapefiles
fcList = arcpy.ListFeatureClasses()

# Set coordinate system only for those inputs which have a defined spatial reference
for infc in fcList:
    # Determine if the input has a defined coordinate system
    dsc = arcpy.Describe(infc)
    sr = dsc.spatialReference

    if sr.Name == "Unknown":
        # skip
        continue
    else:
        # Determine the new output feature class path and name
        outFeatureClass = os.path.join(outWorkspace, infc.strip(".shp") + "_wgs84.shp")
        # Set output coordinate system
        outCS = "C:/Program Files/ArcGIS/Desktop10.0/Coordinate Systems/Geographic Coordinate Systems/World/WGS 1984.prj"
        # Set transform method
        transform_method = "ETRS_1989_To_WGS_1984"

        arcpy.Project_management(infc, outFeatureClass, outCS, transform_method)
share|improve this answer
add comment

I'm not familiar with glob but I just looked it up and it seems like you are using it to recursively go through your folders looking for shapefiles which sounds like it will be very useful.

I think your problem is that you are trying to pass a wildcard (i.e. f + r"\Project*.shp") into the Project tool at each iteration of for loop.

Before you get to the Project_management line I think you need to have already set a variable (perhaps fProjected) to the specific name of your output file so that you can pass that into each iteration of the Project tool.

The os module is likely to be helpful in breaking up the old full filename and assembling the new one.

share|improve this answer
add comment

OK, what you need to do is have a randomiser to append to the original file name, as that seems to be the issue.

I would also disaggregate the way you do glob. I do it thus:

    sNames = r"C:\projdata\working\data\*.shp"
    itFileNames = glob.iglob(sNames) 
        for vFile in itFileNames: 

I would also add the random:

    import random
    hld = 'abcdefghijhijklmnopqrstuvwxyz'

to append it to the old file name, to create the new file name.

What you have to remember, is the line:

arcpy.Project_management(f, f + r"\Project\*.shp",....

f + r"\Project*.shp",.... will be this (if you are using glob):

"C:\inFCFolder\newfile.shp\Project\*.shp"

You need to have a file name in the second parameter.

So, strip the file name from f. Strip the .shp off the name, append some random letters, then add .shp and this will work.

EDIT:

Sorry, but to get the file name out you need to do this:

    import os
    filename = os.path.basename(f)
    filename = filename[0:len(filename)-4] + random.choice(hld) + random.choice(hld) + random.choice(hld) + ".shp"
    arcpy.Project_management(f, "C:\\PathToProject\\Projections\\" + filename, etc.......

Hope that helps.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.