docs: def project_gdf(gdf, to_crs=None, to_latlong=False):
      """
      Project a GeoDataFrame to the UTM zone appropriate for its geometries'
      centroid.
  
      The simple calculation in this function works well for most latitudes, but
      won't work for some far northern locations like Svalbard and parts of far
      northern Norway.
  
      Parameters
      ----------
      gdf : GeoDataFrame
          the gdf to be projected
      to_crs : dict
          if not None, just project to this CRS instead of to UTM
      to_latlong : bool
          if True, projects to latlong instead of to UTM
  
      Returns
      -------
      GeoDataFrame
      """
      assert len(gdf) > 0, 'You cannot project an empty GeoDataFrame.'
      start_time = time.time()
  
      # if gdf has no gdf_name attribute, create one now
      if not hasattr(gdf, 'gdf_name'):
          gdf.gdf_name = 'unnamed'
  
      # if to_crs was passed-in, use this value to project the gdf
      if to_crs is not None:
          projected_gdf = gdf.to_crs(to_crs)
  
      # if to_crs was not passed-in, calculate the centroid of the geometry to
      # determine UTM zone
      else:
          if to_latlong:
              # if to_latlong is True, project the gdf to latlong
              latlong_crs = settings.default_crs
              projected_gdf = gdf.to_crs(latlong_crs)
              log('Projected the GeoDataFrame "{}" to default_crs in {:,.2f} seconds'.format(gdf.gdf_name, time.time()-start_time))
          else:
              # else, project the gdf to UTM
              # if GeoDataFrame is already in UTM, just return it
              if (gdf.crs is not None) and ('proj' in gdf.crs) and (gdf.crs['proj'] == 'utm'):
                  return gdf
  
              # calculate the centroid of the union of all the geometries in the
              # GeoDataFrame
              avg_longitude = gdf['geometry'].unary_union.centroid.x
  
              # calculate the UTM zone from this avg longitude and define the UTM
              # CRS to project
              utm_zone = int(math.floor((avg_longitude + 180) / 6.) + 1)
              utm_crs = {'datum': 'WGS84',
                         'ellps': 'WGS84',
                         'proj' : 'utm',
                         'zone' : utm_zone,
                         'units': 'm'}
  
              # project the GeoDataFrame to the UTM CRS
              projected_gdf = gdf.to_crs(utm_crs)
              log('Projected the GeoDataFrame "{}" to UTM-{} in {:,.2f} seconds'.format(gdf.gdf_name, utm_zone, time.time()-start_time))
  
      projected_gdf.gdf_name = gdf.gdf_name
      return projected_gdf