The properties of each discrete geometry are available as columns of the DataFrame, along with the geometry itself.
## GeoPandas and RasterFrames
You can also convert a [GeoPandas][GeoPandas] GeoDataFrame to a Spark DataFrame, preserving the geometry column. This means that any vector format that can be read with [OGR][OGR] can be converted to a Spark DataFrame. In the example below, we expect the same schema as the DataFrame defined above by the GeoJSON reader. Note that in a GeoPandas DataFrame there can be heterogeneous geometry types in the column, which may fail Spark's schema inference.
```python, read_and_normalize
import geopandas
from shapely.geometry import MultiPolygon
def poly_or_mp_to_mp(g):
""" Normalize polygons or multipolygons to all be multipolygons. """
The `geometry` column will have a Spark user-defined type that is compatible with [Shapely][Shapely] when working with Python via PySpark. This means that when the data is collected to the driver, it will be a Shapely geometry object.
```python, show_geom
the_first = df.first()
print(type(the_first['geometry']))
```
Since it is a geometry we can do things like this:
```python, show_wkt
the_first['geometry'].wkt
```
You can also write user-defined functions that take geometries as input, output, or both, via user defined types in the [geomesa_pyspark.types](https://github.com/locationtech/rasterframes/blob/develop/pyrasterframes/src/main/python/geomesa_pyspark/types.py) module. Here is a simple **but inefficient** example of a user-defined function that uses both a geometry input and output to compute the centroid of a geometry. Observe in a sample of the data the geometry columns print as well known text (wkt).
As documented in the @ref:[function reference](reference.md), various user-defined functions implemented by GeoMesa are also available for use. The example below uses a GeoMesa user-defined function to compute the centroid of a geometry. It is logically equivalent to the example above, but more efficient.
```python, native_centroid
from pyrasterframes.rasterfunctions import st_centroid
The RasterFrames vector functions and GeoMesa functions also provide a variety of spatial relations that are useful in combination with the geometric properties of projected rasters. In this example, we use the @ref:[built-in Landsat catalog](raster-catalogs.md#using-built-in-experimental-catalogs) which provides an extent. We will convert the extent to a polygon and filter to those within approximately 50 km of a selected point.
```python, spatial_relation, evaluate=True
from pyrasterframes.rasterfunctions import st_geometry, st_bufferPoint, st_intersects, st_point