Uploading and opening shapefiles (which consist of 3 files)

What I’m trying to do:

I want the user to be able to upload a shapefile which is actually a collection of three files. The idea is to enable the fileloader to accept three files (.shp, .dbf, .shx), upload them to some temp directory and then use the shapefile module to read the file(s) because the shapefile package will accept either a directory or the .shp file and then search for the other files.

What I’ve tried and what’s not working:

I have no idea how I can save the uploaded files to a temporary directory. They are all binary files.

Any ideas are welcome!
Rob

Ok, got it after some reading and experimenting :slight_smile:

@anvil.server.callable
def upload_shapefile(shpfiles):  
  # create a random filename
  filename = str(uuid.uuid4())  
  # copy the files to a temp location
  for file in shpfiles:
    with open(f"{filename}{Path(file.name).suffix}", "wb") as fp:
      fp.write(file.get_bytes())
  
  # read the shapefile
  shape = shapefile.Reader(file.name)         
  feature = shape.shapeRecords()[0]
  first = feature.shape.__geo_interface__
  if not first["type"] == "LineString":
      raise NotImplementedError(
          f"Upload only handles LineString geometries but got a '{first['type']}' geometry."
      )
  points = [(p[0], p[1]) for p in first["coordinates"]]

  dl = 0
  points_with_chainage = []
  for i, p in enumerate(points):
      if i > 0:
          dl += hypot(
              points_with_chainage[-1][1] - p[0], points_with_chainage[-1][2] - p[1]
          )
      points_with_chainage.append((dl, *p))

  # remove the files
  for file_path in glob.glob(f'{filename}.*'):
    try:
        os.remove(file_path)        
    except:
        print("Error while deleting file : ", file_path)

  return points_with_chainage