Skip to content

Commit

Permalink
MNT: Update to shapely 2 API and address lint and type issues raised …
Browse files Browse the repository at this point in the history
…by the new linting configs. [skip ci]
  • Loading branch information
Taher Chegini committed Oct 7, 2023
1 parent c223e40 commit 0c99c5a
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 29 deletions.
11 changes: 7 additions & 4 deletions pygeohydro/helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Some helper function for PyGeoHydro."""
# pyright: reportGeneralTypeIssues=false
from __future__ import annotations

import io
from datetime import datetime
from typing import TYPE_CHECKING, Any, NamedTuple, Tuple, Union
from typing import TYPE_CHECKING, Any, NamedTuple, Tuple, Union, cast

import cytoolz.curried as tlz
import geopandas as gpd
Expand All @@ -23,7 +24,7 @@

if TYPE_CHECKING:
import pyproj
from shapely.geometry import MultiPolygon, Polygon
from shapely import MultiPolygon, Polygon

GTYPE = Union[Polygon, MultiPolygon, Tuple[float, float, float, float]]
CRSTYPE = Union[int, str, pyproj.CRS]
Expand Down Expand Up @@ -152,8 +153,10 @@ def get_ssebopeta_urls(dates: tuple[str, str] | int | list[int]) -> list[tuple[p
d_list = [pd.date_range(f"{y}0101", f"{y}1231") for y in years]
date_range = d_list.pop(0)
while d_list:
date_range = date_range.union(d_list.pop(0))
date = d_list.pop(0)
date_range = date_range.union(date) # pyright: ignore[reportOptionalMemberAccess]

date_range = cast("pd.DatetimeIndex", date_range)
base_url = ServiceURL().http.ssebopeta

f_list = [
Expand Down Expand Up @@ -263,7 +266,7 @@ def _county2series(cd: dict[str, dict[str, str]]) -> pd.Series:

def _state_cd(state: str) -> str | None:
try:
return codes.loc[state, "STUSAB"] # type: ignore[no-any-return]
return codes.loc[state, "STUSAB"]
except KeyError:
return None

Expand Down
17 changes: 10 additions & 7 deletions pygeohydro/nlcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from numbers import Number
from ssl import SSLContext

from shapely.geometry import MultiPolygon, Polygon
from shapely import MultiPolygon, Polygon

GTYPE = Union[Polygon, MultiPolygon, Tuple[float, float, float, float]]
CRSTYPE = Union[int, str, pyproj.CRS]
Expand Down Expand Up @@ -144,7 +144,8 @@ def get_map(
resolution: int,
) -> xr.Dataset:
"""Get NLCD response and convert it to ``xarray.DataArray``."""
r_dict = self.wms.getmap_bybox(geometry.bounds, resolution, self.crs)
bbox = cast("tuple[float, float, float, float]", geometry.bounds)
r_dict = self.wms.getmap_bybox(bbox, resolution, self.crs)
gtiff2xarray = tlz.partial(
geoutils.gtiff2xarray, geometry=geometry, geo_crs=self.crs, nodata=255
)
Expand Down Expand Up @@ -222,11 +223,12 @@ def nlcd_bygeom(

if geometry.crs is None:
raise MissingCRSError
_geometry = geometry.to_crs(crs).geometry.to_dict()
_geometry = cast("gpd.GeoDataFrame", geometry.to_crs(crs))
geo_dict = _geometry.geometry.to_dict()

nlcd_wms = NLCD(years=years, region=region, crs=crs, ssl=ssl)

return {i: nlcd_wms.get_map(g, resolution) for i, g in _geometry.items()}
return {i: nlcd_wms.get_map(g, resolution) for i, g in geo_dict.items()}


def nlcd_bycoords(
Expand Down Expand Up @@ -276,8 +278,9 @@ def get_value(da: xr.DataArray, x: float, y: float) -> Number:
values = {
v: [get_value(ds[v], p.x, p.y) for ds, p in zip(ds_list, points_proj)] for v in ds_list[0]
}
return points.to_frame("geometry").merge(
pd.DataFrame(values), left_index=True, right_index=True
points = cast("gpd.GeoDataFrame", points.to_frame("geometry"))
return gpd.GeoDataFrame(
pd.merge(points, pd.DataFrame(values), left_index=True, right_index=True)
)


Expand Down Expand Up @@ -424,7 +427,7 @@ def nlcd_area_percent(
if geo_df.crs is None:
raise MissingCRSError

geoms = geo_df.to_crs(4326).geometry
geoms = geo_df.to_crs(4326).geometry # pyright: ignore[reportOptionalMemberAccess]

wms = NLCD(years={"impervious": year, "cover": year}, region=region, ssl=False)

Expand Down
1 change: 1 addition & 0 deletions pygeohydro/nwis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Accessing NWIS."""
# pyright: reportGeneralTypeIssues=false
from __future__ import annotations

import contextlib
Expand Down
10 changes: 5 additions & 5 deletions pygeohydro/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
from matplotlib.colors import BoundaryNorm, ListedColormap

import hydrosignatures as hs
import pygeoutils as geoutils
from pygeohydro import helpers
from pygeohydro.exceptions import InputTypeError
from pygeohydro.nwis import NWIS
from pygeoogc import utils as ogc_utils

if TYPE_CHECKING:
import pyproj
Expand All @@ -40,7 +40,7 @@ class PlotDataType(NamedTuple):


def prepare_plot_data(daily: pd.DataFrame | pd.Series) -> PlotDataType:
"""Generae a structured data for plotting hydrologic signatures.
"""Generate a structured data for plotting hydrologic signatures.
Parameters
----------
Expand Down Expand Up @@ -201,7 +201,7 @@ def signatures(

if output is not None:
Path(output).parent.mkdir(exist_ok=True, parents=True)
fig.savefig(output, dpi=300)
fig.savefig(output, dpi=300) # pyright: ignore[reportGeneralTypeIssues]

if close:
plt.close(fig)
Expand Down Expand Up @@ -266,7 +266,7 @@ def interactive_map(
10
"""
nwis = NWIS()
bbox = ogc_utils.match_crs(bbox, crs, 4326)
bbox = geoutils.geometry_reproject(bbox, crs, 4326)
query = {"bBox": ",".join(f"{b:.06f}" for b in bbox)}
if isinstance(nwis_kwds, dict):
query.update(nwis_kwds)
Expand Down Expand Up @@ -337,7 +337,7 @@ def interactive_map(
for coords, msg in sites[["Coordinate", "msg"]].itertuples(name=None, index=False):
folium.Marker(
location=next(iter(coords))[::-1],
popup=folium.Popup(msg, max_width=250),
popup=folium.Popup(msg, max_width=250), # pyright: ignore[reportGeneralTypeIssues]
icon=folium.Icon(),
).add_to(imap)

Expand Down
25 changes: 16 additions & 9 deletions pygeohydro/pygeohydro.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
InputTypeError,
InputValueError,
MissingColumnError,
ServiceError,
ZeroMatchedError,
)
from pygeoogc import RetrySession, ServiceURL
from pygeoutils import EmptyResponseError
from pynhd.core import AGRBase, ScienceBase

if TYPE_CHECKING:
from shapely.geometry import MultiPolygon, Polygon
from shapely import MultiPolygon, Polygon

GTYPE = Union[Polygon, MultiPolygon, Tuple[float, float, float, float]]
CRSTYPE = Union[int, str, pyproj.CRS]
Expand Down Expand Up @@ -266,7 +267,8 @@ def __init__(self) -> None:
11: "Concrete",
12: "Other",
}
self.dam_type.update({str(k): v for k, v in self.dam_type.items() if str(k).isdigit()})
dtype_str = {str(k): v for k, v in self.dam_type.items() if str(k).isdigit()}
self.dam_type = {**self.dam_type, **dtype_str}
self.dam_purpose = {
pd.NA: "N/A",
None: "N/A",
Expand All @@ -283,9 +285,8 @@ def __init__(self) -> None:
11: "Grade Stabilization",
12: "Other",
}
self.dam_purpose.update(
{str(k): v for k, v in self.dam_purpose.items() if str(k).isdigit()}
)
purp_str = {str(k): v for k, v in self.dam_purpose.items() if str(k).isdigit()}
self.dam_purpose = {**self.dam_purpose, **purp_str}
self.data_units = {
"distance": "mile",
"damHeight": "ft",
Expand Down Expand Up @@ -758,7 +759,7 @@ def soil_gnatsgo(layers: list[str] | str, geometry: GTYPE, crs: CRSTYPE = 4326)
Notes
-----
This function uses Microsoft's Planetary Computer service to get the data.
The dataset's description and its suppoerted soil properties can be found at:
The dataset's description and its supported soil properties can be found at:
https://planetarycomputer.microsoft.com/dataset/gnatsgo-rasters
Parameters
Expand Down Expand Up @@ -881,7 +882,11 @@ def __init__(
self._get_layers = fiona.listlayers

bins = AGRBase(ServiceURL().restful.ehydro_bins)
self._survey_grid = bins.bygeom(bins.client.client.extent)
extent = bins.client.client.extent
if extent is None:
msg = "Unable to get the extent of eHydro"
raise ServiceError(msg)
self._survey_grid = bins.bygeom(extent)

warnings.filterwarnings("ignore", message=".*3D.*")
warnings.filterwarnings("ignore", message=".*OGR_GEOMETRY_ACCEPT_UNCLOSED_RING.*")
Expand Down Expand Up @@ -909,8 +914,10 @@ def get_depth(fname: Path) -> gpd.GeoDataFrame:

if self._engine == "pyogrio":
with contextlib.suppress(GEOSException):
return gpd.read_file(gdb, layer=self._layer, engine="pyogrio", use_arrow=True)
return gpd.read_file(gdb, layer=self._layer)
return gpd.read_file(
gdb, layer=self._layer, engine="pyogrio", use_arrow=True
) # pyright: ignore[reportGeneralTypeIssues]
return gpd.read_file(gdb, layer=self._layer) # pyright: ignore[reportGeneralTypeIssues]

return gpd.GeoDataFrame(pd.concat((get_depth(f) for f in fnames), ignore_index=True))

Expand Down
1 change: 1 addition & 0 deletions pygeohydro/us_abbrs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""US states and territories Abbreviations from ``us`` package."""
from __future__ import annotations

CONTIGUOUS = [
"AL",
Expand Down
3 changes: 2 additions & 1 deletion pygeohydro/waterdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ def sensor_info(self, sensor_ids: str | list[str]) -> pd.DataFrame:
sensor_ids = [sensor_ids] if isinstance(sensor_ids, str) else sensor_ids
urls = [f"{self.base_url}('{i}')" for i in sensor_ids]
data = pd.json_normalize(self._get_urls(urls))
return data.drop(columns=data.columns[data.columns.str.endswith("Link")])
columns = data.columns[data.columns.str.endswith("Link")]
return data.drop(columns=columns) # pyright: ignore[reportGeneralTypeIssues]

def sensor_property(self, sensor_property: str, sensor_ids: str | list[str]) -> pd.DataFrame:
"""Query a sensor property.
Expand Down
3 changes: 2 additions & 1 deletion pygeohydro/watershed.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import importlib.util
import io
from pathlib import Path
from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING, Union, cast

import geopandas as gpd
import pandas as pd
Expand Down Expand Up @@ -115,6 +115,7 @@ def huc_wb_full(huc_lvl: int) -> gpd.GeoDataFrame:
)
)
huc = huc.reset_index().rename(columns={"level_0": "huc2"}).drop(columns="level_1")
huc = cast("gpd.GeoDataFrame", huc)
return huc


Expand Down
4 changes: 2 additions & 2 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def test_invalid_cover_type(self):
crs="epsg:3542",
ssl=False,
)
cover = lulc[0].cover_2016
cover = lulc[0]
with pytest.raises(InputTypeError, match="DataArray"):
_ = gh.cover_statistics(cover)

Expand All @@ -91,7 +91,7 @@ def test_invalid_cover_values(self):
ssl=False,
)
cover = lulc[0].cover_2016
with pytest.raises(InputValueError, "11"):
with pytest.raises(InputValueError, match="11"):
_ = gh.cover_statistics(cover * 2)


Expand Down

0 comments on commit 0c99c5a

Please sign in to comment.