Spatial filter
Spatial Filter
Spatial polars expressions which produce a boolean series can be used in polars filter context. If we want to limit the rows in our dataframe to just the rows in a certain geographic extent we can use the .spatial.intersects() expression with a shapely geometry object to filter our dataframe to just those rows.
Note
This example makes use the geodatasets python package to access some spatial data easily.
Calling geodatasets.get_path() will download data the specified data to the machine and return the path to the downloaded file. If the file has already been downloaded it will simply return the path to the file.
See downloading and caching for further details.
Use mask or bbox if possible
This example reads data, filters it, then displays it on a map. If you only need data from a specific area in your workflow, using the mask or bbox parameters in the creation of the lazy/dataframe will result in a better performance, as the filter would be applied by pyogrio when reading the data.
import geodatasets
import polars as pl
import shapely
from lonboard import viz
from spatial_polars import read_spatial
nyc_earnings_df = read_spatial(geodatasets.get_path("geoda.nyc_earnings")) # (1)!
print(f"There are {len(nyc_earnings_df):,} rows in the dataframe before filter.")
nyc_earnings_df = nyc_earnings_df.with_columns(
pl.col("geometry").spatial.reproject(4326) # (2)!
)
polygon = shapely.Polygon( # (3)!
(
(-73.89257606917118, 40.78508934389371),
(-73.87251149764286, 40.78511666797557),
(-73.86103571752412, 40.80049834119043),
(-73.89517435900939, 40.79976075792865),
(-73.89257606917118, 40.78508934389371),
)
)
filtered_nyc_earnings_df = nyc_earnings_df.filter(
pl.col("geometry").spatial.intersects(polygon) # (4)!
)
print(
f"There are {len(filtered_nyc_earnings_df):,} rows in the dataframe after filter."
)
lonboard_map = viz( # (5)!
polygon, # (6)!
polygon_kwargs={
"get_fill_color": (0, 0, 0, 0), # (7)!
"get_line_color": (255, 0, 0, 255),
"get_line_width": 35,
},
)
filtered_polygonlayer = filtered_nyc_earnings_df.spatial.to_polygonlayer( # (8)!
fill_color=(0, 0, 255)
)
lonboard_map.layers = list(lonboard_map.layers) + [filtered_polygonlayer] # (9)!
lonboard_map
- Read the nyc_earnings geodataset into a dataframe
- Reproject the data to WGS84 so we can use longitude/latitude coordinates for our filter polygon
- Create a shapely polygon we can use to filter the rows in the dataframe, this polygon covers all of Rikers Island
- Use .spatial.intersects to filter the dataframe to return the rows that intersect our polygon
- Use lonboard's viz function to make a map
- Create the map's layer from our boundary polygon
- Symbolize the polygon with no fill color, make the outline red, and make the outline 35 meters wide
- Make a polygonlayer from our filtered dataframe
- Add our filtered polygonlayer to our map