Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update coastal module #548

Merged
merged 11 commits into from
Sep 19, 2024
2 changes: 1 addition & 1 deletion Tools/deafrica_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__locales__ = __path__[0] + "/locales"

__version__ = "2.4.9"
__version__ = "2.5.0"


def set_lang(lang=None):
Expand Down
61 changes: 36 additions & 25 deletions Tools/deafrica_tools/areaofinterest.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
"""
Function for defining an area of interest using either a point and buffer or a vector file.
Function for defining an area of interest using either a point and buffer or a vector file.
"""

# Import required packages

# Force GeoPandas to use Shapely instead of PyGEOS
# In a future release, GeoPandas will switch to using Shapely by default.
import os
os.environ['USE_PYGEOS'] = '0'

os.environ["USE_PYGEOS"] = "0"

import geopandas as gpd
from geojson import Feature, FeatureCollection, Point
from shapely.geometry import box
from geojson import Feature, Point, FeatureCollection

def define_area(lat=None, lon=None, buffer=None, lat_buffer=None, lon_buffer=None, vector_path=None):
'''

def define_area(
lat: float = None,
lon: float = None,
buffer: float = None,
lat_buffer: float = None,
lon_buffer: float = None,
vector_path: str = None,
) -> FeatureCollection:
"""
Define an area of interest using either a point and buffer or separate latitude and longitude buffers, or a vector.

Parameters:
-----------
lat : float, optional
Expand All @@ -31,53 +38,57 @@ def define_area(lat=None, lon=None, buffer=None, lat_buffer=None, lon_buffer=Non
The buffer around the center point, extending along the longitude, in degrees.
vector_path : str, optional
The path to a vector defining the area of interest.

Returns:
--------
feature_collection : dict
feature_collection : FeatureCollection
A GeoJSON feature collection representing the area of interest.
'''
"""
# Check if both buffer and separate lat/lon buffers are specified
if buffer is not None and (lat_buffer is not None or lon_buffer is not None):
raise ValueError("Specify either buffer or separate lat_buffer and lon_buffer, not both.")

# Check if either lat_buffer or lon_buffer is provided without the other
if (lat_buffer is not None and lon_buffer is None) or (lat_buffer is None and lon_buffer is not None):
if (lat_buffer is not None and lon_buffer is None) or (
lat_buffer is None and lon_buffer is not None
):
raise ValueError("Both lat_buffer and lon_buffer must be provided together.")

# Ensure buffer values are positive
# if negative values are provided for buffer, lat_buffer, or lon_buffer, they will be converted to their absolute values without raising an error.
# if negative values are provided for buffer, lat_buffer, or lon_buffer,
# they will be converted to their absolute values without raising an error.
if buffer is not None:
buffer = abs(buffer)
if lat_buffer is not None:
lat_buffer = abs(lat_buffer)
if lon_buffer is not None:
lon_buffer = abs(lon_buffer)

# Define area using point and buffer
if lat is not None and lon is not None:
if buffer is not None and (lat_buffer is None or lon_buffer is None):
lat_buffer = lon_buffer = buffer

if lat_buffer is not None and lon_buffer is not None:
lat_range = (lat - lat_buffer, lat + lat_buffer)
lon_range = (lon - lon_buffer, lon + lon_buffer)
box_geom = box(min(lon_range), min(lat_range), max(lon_range), max(lat_range))
aoi = gpd.GeoDataFrame(geometry=[box_geom], crs='EPSG:4326')
aoi = gpd.GeoDataFrame(geometry=[box_geom], crs="EPSG:4326")
else:
aoi = gpd.GeoDataFrame(geometry=[Point(lon, lat).buffer(buffer)], crs='EPSG:4326')
aoi = gpd.GeoDataFrame(geometry=[Point(lon, lat).buffer(buffer)], crs="EPSG:4326")

# Define area using vector
elif vector_path is not None:
aoi = gpd.read_file(vector_path).to_crs("EPSG:4326")
# If neither option is provided, raise an error
else:
raise ValueError("Either lat/lon/buffer or vector_path must be provided.")

# Convert the GeoDataFrame to a GeoJSON FeatureCollection
features = [Feature(geometry=row["geometry"], properties=row.drop("geometry").to_dict()) for _, row in aoi.iterrows()]
features = [
Feature(geometry=row["geometry"], properties=row.drop("geometry").to_dict())
for _, row in aoi.iterrows()
]
feature_collection = FeatureCollection(features)

return feature_collection


return feature_collection
Loading