1

How do I only select .shp's to read and then convert to .geojson. The homefolder has 3 different shapefiles and this code currently converts every single file in the folder to a .json. Just trying to speed up the running process. I have some other issues too with naming conventions that I will deal with next. Among other things, this is a work in progress.

homefolder = "D:/UW/Winter_2016/501/pythonProject/publicLandsData/newShapefiles/"

# read the shapefiles
filenames = os.listdir(homefolder)

for filename in filenames:
  reader = shapefile.Reader(homefolder + os.path.splitext(os.path.basename(filename))[0])
  print filename 
  fields = reader.fields[1:]
  field_names = [field[0] for field in fields]
  buffer = []
  print filename + "buffer dictionary done"
  for sr in reader.shapeRecords():
      atr = dict(zip(field_names, sr.record))
      geom = sr.shape.__geo_interface__
      buffer.append(dict(type="Feature", \
      geometry=geom, properties=atr)) 

# write the GeoJSON file
#currently it saves into the wrong directory..and all one shapefile, might be nice to be in multiple geojson's 
#list directory "homefolder" in variable filenames
  filenames = os.listdir(homefolder)

  for filename in filenames:
#for loop to rename local government to loca
    geojson = open(((os.path.splitext(os.path.basename(filename))[0]) + ".json"), "w")
    #os.rename(os.path.join(homefolder, filename), os.path.join(homefolder, (filename.replace('.shp', 'shp'))))
    geojson.write(dumps({"type": "FeatureCollection",\
      " features": buffer}, indent=2) + "\n")
    geojson.close()

I have tried using basename, selecting only ".shp" files with .endwith() etc to no avail. Suggestions?

I found this shp to geojson conversion code at the link below: https://gist.github.com/frankrowe/6071443

2 Answers 2

3

Try replacing line 4 with this:

filenames = [ f for f in os.listdir(homefolder) if os.path.isfile(os.path.join(homefolder,f)) and f.endswith(".shp")]

This will create a list containing only files with the extension ".shp"

Expanded for clarity:

# create empty list
filenames = []
# begin iterating over files in homefolder directory
for f in os.listdir(homefolder):
    # if the file is indeed a file and it ends with .shp append the name to the list
    if os.path.isfile(os.path.join(homefolder,f)) and f.endswith(".shp"):
        filenames.append(f)
7
  • at first I thought this was right, then after further inspection this is only converting one of the shapefiles into geoJSON...suggestions?
    – Staley
    Mar 7, 2016 at 21:55
  • still only grabbing one of the shapefiles and converting it into three files all identical to one another...
    – Staley
    Mar 7, 2016 at 22:02
  • do I need filename +1 in there to go to the next .shp?
    – Staley
    Mar 7, 2016 at 22:03
  • Does the resulting list from the above code contain all the shape files you want to convert?
    – nwduncan
    Mar 7, 2016 at 22:03
  • yes printed the filename list and federal.shp, state.shp and local.shp are listed correctly. only the state.shp is being converted in all three outputs. must be something wrong with reader = shapefile.Reader() line...
    – Staley
    Mar 7, 2016 at 22:07
1

Look at PyShp_geointerface.py with a generator

import shapefile
def records(filename):
   # generator
   reader = shapefile.Reader(filename)
   fields = reader.fields[1:]
   field_names = [field[0] for field in fields]
   for sr in reader.shapeRecords():
      geom = sr.shape.__geo_interface__
      atr = dict(zip(field_names, sr.record))
      yield dict(geometry=geom,properties=atr)
 # for one file
  buffer = [rec for rec in records('shapefile.shp')]
  result = {"type": "FeatureCollection"," features": buffer}

For many files, simply loop through the files

for dir, subdir, files in os.walk(a_folder):
    for fname in files:
        if fname.endswith(".shp"):
           buffer = [rec for rec in records(os.path.join(dir, fname))]
           result = {"type": "FeatureCollection"," features": buffer}
           # write the resulting GeoJSON file
           name = os.path.splitext(fname[0]+'.geojson')
           with open(name, "w") as outfile:
               json.dump(result,outfile)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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