docs: def geoframe(self, *args, **kwargs):
          """Return a Geo dataframe"""
  
          from geopandas import GeoDataFrame
          import geopandas as gpd
          from shapely.geometry.polygon import BaseGeometry
          from shapely.wkt import loads
  
          gdf = None
          try:
              gdf = self.resolved_url.geoframe(*args, **kwargs)
          except AttributeError:
              pass
  
          if gdf is None:
              try:
                  gdf = self.resolved_url.geo_generator.geoframe(*args, **kwargs)
              except AttributeError:
                  pass
  
          if gdf is None:
              try:
                  gdf = self.row_generator.geoframe(*args, **kwargs)
              except AttributeError:
                  pass
  
          if gdf is None:
              try:
  
                  gdf = GeoDataFrame(self.dataframe(*args, **kwargs))
  
                  first = next(gdf.iterrows())[1]['geometry']
  
                  if isinstance(first, str):
                      # We have a GeoDataframe, but the geometry column is still strings, so
                      # it must be converted
                      shapes = [loads(row['geometry']) for i, row in gdf.iterrows()]
  
                  elif not isinstance(first, BaseGeometry):
                      # If we are reading a metatab package, the geometry column's type should be
                      # 'geometry' which will give the geometry values class type of
                      # rowpipe.valuetype.geo.ShapeValue. However, there are other
                      # types of objects that have a 'shape' property.
  
                      shapes = [row['geometry'].shape for i, row in gdf.iterrows()]
  
                  else:
                      shapes = gdf['geometry']
  
                  gdf['geometry'] = gpd.GeoSeries(shapes)
                  gdf.set_geometry('geometry')
  
                  # Wild guess. This case should be most often for Metatab processed geo files,
                  # which are all 4326
                  if gdf.crs is None:
                      gdf.crs = {'init': 'epsg:4326'}
  
  
              except KeyError as e:
                  raise ResourceError("Failed to create GeoDataFrame for resource '{}': No geometry column".format(self.name))
              except (KeyError,TypeError) as e:
                  raise ResourceError("Failed to create GeoDataFrame for resource '{}': {}".format(self.name, str(e)))
  
          assert gdf.crs is not None
          return gdf