Let me introduce to you, guys, my first Python tool: “Shapefile Archiver”. Usually, I face lots of problems in managing my shapefiles. My first problem is backing them up in a decent way, especially, before starting some experimental things on them (That sounds scary!), while the second problem is that Finder/Windows explorer doesn’t tell me about the shapefile more than its name!. Moreover, Finder/Windows explorer shows the shapefile as a bunch of files (*.shp, *.prj, *.shx, *.dbf,…) which makes me feel annoyed especially because I’m too lazy to open QGIS browser or ArcCataloge every time I want to explore my shapefiles. Therefore, I’ve decided to program a tool to sort all these problems out by a click 🙂 Since I love challenge, I’ve decided to do that with a new programming language to me (Yes!!, you guessed it, it is Python). Let’s start.

My pseudocode was as follows:

Create a folder entitled “Archive” .

Detect the shapefiles in the main folder.

Create a subfolder for every shapefile with the same name of that shapefile inside the “Archive” folder.

Copy every shapefile to its subfolder.

Create a text file, in that subfolder, contains the basic information about this shapefile, i.e. (Name, Type, Is it spatially referenced or not?, type of referencing (projected or geographic), and the unit).

#In the next couple of lines, we will Import the required libraries import glob, sys, os, shutil from osgeo import ogr # To be able to detect the shapefiles, we, first, need to create a shapefile driver: driver = ogr.GetDriverByName('ESRI Shapefile') #Now, we will use “glob.glob” to look for any file that has a “.shp” extension. We need this step to detect the shapefiles form other types of files lstShapefiles= glob.glob("*.shp")

x = os.getcwd() # Getting the path of where the script file is located. #Then, creating the folder “Archive” to that path thesubpath = str(x+"\\Archive")

if os.path.exists(thesubpath): # does it exist? shutil.rmtree(thesubpath) # Yes. Then, overwrite it os.mkdir (thesubpath) # No. Then, create a new one

# looping through the shapefiles to get (the Name, Type, Is the shapefile spatially referenced or not?, type of referencing (projected or geographic), and the unit) for shpFile in lstShapefiles: dataSource = driver.Open(shpFile,0) # the 0 is for reading only, so nothing will affect the data. # Get the Layer myLayer=dataSource.GetLayer() # Get the Geometry type. The output of this is either “1” for point, “2” for polyline or “3” for polygon. shapeType=myLayer.GetGeomType() #a dictionary is used here to refer in “spoken language” what the type of the shapefile is dectype={1:"Point",2:"Polyline",3:"Ploygon"} # Get the Coordinate System. CoordSys = myLayer.GetSpatialRef()

#Create the subfolder with the same name of the shapefile thenewpath = str(thesubpath+"\\"+shpFile[:-4]+"_"+"Info") print "



The path of the sub folder is: "+thenewpath print "The following files have been moved to the previous folder" #Checking if the folder does already exist, if so, it will be over written if os.path.exists(thenewpath): # does it exist? shutil.rmtree(thenewpath) # Yes. Then, overwrite it os.mkdir (thenewpath) # No. Then, create a new one

# looping through the shapefiles and moving them to the subfolders lstfiles= glob.glob(shpFile[:-3]+"*") # since the sapefile consists of more that one file with different extensions, I’ll use the “*” instead of listing all possible extensions # copying process for File in lstfiles: dir_src = x+"\\"+File # defining the source of the file dir_dst = thenewpath+"\\"+File # defining the destination of the file print File

#Make a summary f=open(thenewpath+"\\"+shpFile[:-4]+".txt",'w') # w is for writing if CoordSys.IsProjected(): # is it projected? f.write("Name: "+shpFile[:-4]+"

"+"Type: "+dectype[shapeType]+"

"+"This shapefile is spatially referenced"+"

"+"The coordinate System is Linear"+"

"+"The unit is: "+CoordSys.GetLinearUnitsName()) elif CoordSys.IsGeographic(): # is it geographic? f.write("Name:\t"+shpFile[:-4]+"

Type:\t"+dectype[shapeType]+"

"+"This shapefile is spatially referenced"+"

"+"The coordinate System is Geographic"+"

"+"The unit is: degree") else: f.write("Name:\t"+shpFile[:-4]+"

Type:\t"+dectype[shapeType]+"

"+"This shapefile is not referenced") f.close #Copying the files to the subfolder shutil.copyfile(dir_src,dir_dst) print "



Done :)"

As I mentioned above, this script is meant to create an “Archive” folder just inside the main folder (with the shapefiles). In order to do so, we should know where the script file is located.Checking if the folder does exist or not, if so, it will be over written! “This is incredibly important if you want to update your archiving information. Without these three lines, an error shows up if you want to back up your files again.Well, till now, there is nothing “geospatial” in the code. (The geospatial is coming, guys, right now!!)In the next few lines, we will create a subfolder “_Info” for each shapfile.Well, so far, we created a folder entitled “Archive”. Then, detected the shapefiles in the main folder. After that, we created a subfolder for every shapefile with the same name of that shapefile inside the “Archive” folder. Now, we’ll write a code to copy every shapefile to its subfolder.In the next bunch of lines, we’ll write a code to create a text file in the subfolders to write up the basic information about each shapefile.All what you have to do is to paste this script file among your shapefiles, and it will do the rest The results:Your comments are more than welcomed.