|
1 | 1 | import httpx |
2 | 2 | import os |
| 3 | +import warnings |
3 | 4 | from typing import List, Dict, Any, Optional, Union |
4 | 5 | from datetime import datetime |
5 | 6 | import pandas as pd |
6 | 7 | import json |
7 | | -import geopandas as gpd |
8 | 8 | from datetime import datetime |
9 | 9 | from zoneinfo import ZoneInfo |
10 | 10 | import re |
| 11 | +try: |
| 12 | + import geopandas as gpd |
| 13 | + gpd = True |
| 14 | +except ImportError: |
| 15 | + warnings.warn("Geopandas is not installed. Data frames containing geometry will be returned as pandas DataFrames.", ImportWarning) |
| 16 | + gpd = False |
| 17 | + |
| 18 | + |
11 | 19 |
|
12 | 20 | BASE_API = "https://api.waterdata.usgs.gov/ogcapi/" |
13 | 21 | API_VERSION = "v0" |
@@ -388,18 +396,27 @@ def _get_resp_data(resp: httpx.Response) -> pd.DataFrame: |
388 | 396 | pandas DataFrame containing the feature properties and each row's service-specific id. |
389 | 397 | Returns an empty pandas DataFrame if no features are returned. |
390 | 398 | """ |
| 399 | + # Check if it's an empty response |
391 | 400 | body = resp.json() |
392 | 401 | if not body.get("numberReturned"): |
393 | 402 | return pd.DataFrame() |
394 | | - #df = pd.json_normalize( |
395 | | - # resp.json()["features"], |
396 | | - # sep="_") |
397 | | - #df = df.drop(columns=["type", "geometry", "AsGeoJSON(geometry)"], errors="ignore") |
398 | | - #df.columns = [col.replace("properties_", "") for col in df.columns] |
399 | 403 |
|
| 404 | + # If geopandas not installed, return a pandas dataframe |
| 405 | + if not gpd: |
| 406 | + df = pd.json_normalize( |
| 407 | + body["features"], |
| 408 | + sep="_") |
| 409 | + df = df.drop(columns=["type", "geometry", "AsGeoJSON(geometry)"], errors="ignore") |
| 410 | + df.columns = [col.replace("properties_", "") for col in df.columns] |
| 411 | + return df |
| 412 | + |
| 413 | + # Organize json into geodataframe and make sure id column comes along. |
400 | 414 | df = gpd.GeoDataFrame.from_features(body["features"]) |
401 | 415 | df["id"] = pd.json_normalize(body["features"])["id"].values |
| 416 | + df = df[["id"] + [col for col in df.columns if col != "id"]] |
402 | 417 |
|
| 418 | + # If no geometry present, then return pandas dataframe. A geodataframe |
| 419 | + # is not needed. |
403 | 420 | if df["geometry"].isnull().all(): |
404 | 421 | df = pd.DataFrame(df.drop(columns="geometry")) |
405 | 422 |
|
@@ -506,7 +523,7 @@ def _rejigger_cols(df: pd.DataFrame, properties: Optional[List[str]], output_id: |
506 | 523 |
|
507 | 524 | Returns |
508 | 525 | ------- |
509 | | - pd.DataFrame |
| 526 | + pd.DataFrame or gpd.GeoDataFrame |
510 | 527 | The DataFrame with columns rearranged and/or renamed according to the specified properties and output_id. |
511 | 528 | """ |
512 | 529 | if properties and not all(pd.isna(properties)): |
|
0 commit comments