def getXSAtPoint(point, numpoints, width, file=None): tpoint = f'POINT({point[1]} {point[0]})' df = pd.DataFrame({ 'pointofinterest': ['this'], 'Lat': [point[0]], 'Lon': [point[1]] }) gpd_pt = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.Lon, df.Lat)) gpd_pt.set_crs(epsg=4326, inplace=True) gpd_pt.to_crs(epsg=3857, inplace=True) comid = getCIDFromLatLon(point) print(f'comid = {comid}') strm_seg = NLDI().getfeature_byid("comid", "3561878", basin=False).to_crs('epsg:3857') xs = XSGen(point=gpd_pt, cl_geom=strm_seg, ny=100, width=1000) xs_line = xs.get_xs() # get topo polygon with buffer to ensure there is enough topography to interpolate xs line # With coarsest DEM (30m) 100. m should bb = xs_line.total_bounds - ((100., 100., -100., -100.)) dem = py3dep.get_map("DEM", tuple(bb), resolution=10, geo_crs="EPSG:3857", crs="epsg:3857") x, y = xs.get_xs_points() dsi = dem.interp(x=('z', x), y=('z', y)) pdsi = dsi.to_dataframe() # gpdsi = gpd.GeoDataFrame(pdsi, gpd.points_from_xy(pdsi.x.values, pdsi.y.values)) gpdsi = dataframe_to_geodataframe(pdsi) gpdsi.set_crs(epsg=3857, inplace=True) gpdsi.to_crs(epsg=4326, inplace=True) if (file): if not isinstance(file, str): # with open(file, "w") as f: file.write(gpdsi.to_json()) file.close() return 0 else: with open(file, "w") as f: f.write(gpdsi.to_json()) f.close() # gpdsi.to_file(file, driver="GeoJSON") return 0 else: return gpdsi
def get_streamflow( self, station_ids: Union[List[str], str], dates: Tuple[str, str], mmd: bool = False ) -> pd.DataFrame: """Get daily streamflow observations from USGS. Parameters ---------- station_ids : str, list The gage ID(s) of the USGS station. dates : tuple Start and end dates as a tuple (start, end). mmd : bool Convert cms to mm/day based on the contributing drainage area of the stations. Returns ------- pandas.DataFrame Streamflow data observations in cubic meter per second (cms) """ if not isinstance(station_ids, (str, list)): raise InvalidInputType("ids", "str or list") station_ids = station_ids if isinstance(station_ids, list) else [station_ids] if not isinstance(dates, tuple) or len(dates) != 2: raise InvalidInputType("dates", "tuple", "(start, end)") start = pd.to_datetime(dates[0]) end = pd.to_datetime(dates[1]) siteinfo = self.get_info(self.query_byid(station_ids)) check_dates = siteinfo.loc[ ( (siteinfo.stat_cd == "00003") & (start < siteinfo.begin_date) & (end > siteinfo.end_date) ), "site_no", ].tolist() nas = [s for s in station_ids if s in check_dates] if len(nas) > 0: raise InvalidInputRange( "Daily Mean data unavailable for the specified time " + "period for the following stations:\n" + ", ".join(nas) ) payload = { "format": "json", "sites": ",".join(station_ids), "startDT": start.strftime("%Y-%m-%d"), "endDT": end.strftime("%Y-%m-%d"), "parameterCd": "00060", "statCd": "00003", "siteStatus": "all", } resp = self.session.post(f"{self.url}/dv", payload) time_series = resp.json()["value"]["timeSeries"] r_ts = { t["sourceInfo"]["siteCode"][0]["value"]: t["values"][0]["value"] for t in time_series } def to_df(col, dic): discharge = pd.DataFrame.from_records(dic, exclude=["qualifiers"], index=["dateTime"]) discharge.index = pd.to_datetime(discharge.index) discharge.columns = [col] return discharge qobs = pd.concat([to_df(f"USGS-{s}", t) for s, t in r_ts.items()], axis=1) # Convert cfs to cms qobs = qobs.astype("float64") * 0.028316846592 if mmd: nldi = NLDI() basins_dict = { f"USGS-{s}": nldi.getfeature_byid("nwissite", f"USGS-{s}", basin=True).geometry for s in station_ids } basins = gpd.GeoDataFrame.from_dict(basins_dict, orient="index") basins.columns = ["geometry"] basins = basins.set_crs(DEF_CRS) eck4 = "+proj=eck4 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs" area = basins.to_crs(eck4).area ms2mmd = 1000.0 * 24.0 * 3600.0 qobs = qobs.apply(lambda x: x / area.loc[x.name] * ms2mmd) return qobs
from shapely import geometry import geopandas as gpd import json def getFeatures(gdf): """Function to parse features from GeoDataFrame in such a manner that rasterio wants them""" import json return [json.loads(gdf.to_json())['features'][0]['geometry']] band_of_interest = 1 # DEM with rio.open('Mads_1_COG.tif') as dataset: elev = dataset.read(1) basin = NLDI().getfeature_byid("comid", "13294318", basin=True).to_crs('epsg:4269') ax = plt.subplot(111) show(dataset, ax=ax) basin.plot(ax=ax, facecolor="none", edgecolor='black', lw=0.7) plt.show() #Subset to bounding box of basin demdata = rio.open('Mads_1.tif') show((demdata, 1), cmap='terrain') print(demdata.crs, basin.crs) # print(basin.boundary.to_json()) basin_coords = getFeatures(basin) minx, miny, maxx, maxy = basin.total_bounds p1 = geometry.Point(minx, miny) p2 = geometry.Point(minx, maxy)
"""Tests for PyNHD package.""" import io import pytest from shapely.geometry import box import pynhd as nhd from pynhd import NLDI, WaterData STA_ID = "01031500" station_id = f"USGS-{STA_ID}" site = "nwissite" UM = "upstreamMain" UT = "upstreamTributaries" nldi = NLDI() @pytest.mark.flaky(max_runs=3) def test_nldi_navigate(): stm = nldi.navigate_byid(site, station_id, UM, site) st100 = nldi.navigate_byid(site, station_id, UM, site, distance=100) pp = nldi.navigate_byid(site, station_id, UT, "huc12pp") wqp = nldi.navigate_byloc((-70, 44), UT, "wqp") assert ( st100.shape[0] == 2 and stm.shape[0] == 2 and pp.shape[0] == 12 and wqp.comid.iloc[0] == "6710923" )