Skip to content
1 change: 1 addition & 0 deletions backend/bounding_polygons.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def get_state_polygon(state):
# private helpers ============================
def _make_shape(obj, as_wkt):
poly = shape(obj["geometry"])
poly = poly.simplify(0.1)
if as_wkt:
return poly.wkt
return poly
Expand Down
82 changes: 43 additions & 39 deletions backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,46 +61,31 @@
from .connectors.usgs.source import NWISSiteSource, NWISWaterLevelSource
from .connectors.wqp.source import WQPSiteSource, WQPAnalyteSource, WQPWaterLevelSource

SOURCE_KEYS = (
"bernco",
"bor",
"cabq",
"ebid",
"nmbgmr_amp",
"nmed_dwb",
"nmose_isc_seven_rivers",
"nmose_roswell",
"nwis",
"pvacd",
"wqp",
)

SOURCE_DICT = {
"bernco": BernCoSiteSource,
"bor": BORSiteSource,
"cabq": CABQSiteSource,
"ebid": EBIDSiteSource,
"nmbgmr_amp": NMBGMRSiteSource,
"nmed_dwb": DWBSiteSource,
"nmose_isc_seven_rivers": ISCSevenRiversSiteSource,
"nmose_roswell": NMOSERoswellSiteSource,
"nwis": NWISSiteSource,
"pvacd": PVACDSiteSource,
"wqp": WQPSiteSource,
}

SOURCE_KEYS = list(SOURCE_DICT.keys())

def get_source(source):
if source == "bernco":
return BernCoSiteSource()
elif source == "bor":
return BORSiteSource()
elif source == "cabq":
return CABQSiteSource()
elif source == "ebid":
return EBIDSiteSource()
elif source == "nmbgmr_amp":
return NMBGMRSiteSource()
elif source == "nmed_dwb":
return DWBSiteSource()
elif source == "nmose_isc_seven_rivers":
return ISCSevenRiversSiteSource()
elif source == "nmose_roswell":
return NMOSERoswellSiteSource()
elif source == "nwis":
return NWISSiteSource()
elif source == "pvacd":
return PVACDSiteSource()
elif source == "wqp":
return WQPSiteSource()

return None
try:
klass = SOURCE_DICT[source]
except KeyError:
raise ValueError(f"Unknown source {source}")

if klass:
return klass()


class Config(Loggable):
Expand All @@ -116,6 +101,8 @@ class Config(Loggable):
county: str = ""
wkt: str = ""

sites_only = False

# sources
use_source_bernco: bool = True
use_source_bor: bool = True
Expand Down Expand Up @@ -186,6 +173,17 @@ def __init__(self, model=None, payload=None):
for s in SOURCE_KEYS:
setattr(self, f"use_source_{s}", s in payload.get("sources", []))

def finalize(self):
self._update_output_units()
self.make_output_directory()
self.update_output_name()
self.make_output_path()

def all_site_sources(self):
sources = self.water_level_sources()
sources.extend(self.analyte_sources())
return sources

def analyte_sources(self):
sources = []

Expand Down Expand Up @@ -383,8 +381,14 @@ def _validate_county(self):
return bool(get_county_polygon(self.county))

return True
def make_output_directory(self):
"""
Create the output directory if it doesn't exist.
"""
if not os.path.exists(self.output_dir):
os.mkdir(self.output_dir)

def _update_output_name(self):
def update_output_name(self):
"""
Generate a unique output name based on existing directories in the output directory.

Expand Down Expand Up @@ -419,7 +423,7 @@ def _update_output_name(self):

self.output_name = output_name

def _make_output_path(self):
def make_output_path(self):
if not os.path.exists(self.output_path):
os.mkdir(self.output_path)

Expand Down
41 changes: 22 additions & 19 deletions backend/connectors/nmbgmr/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,33 @@ def get_records(self):
if config.site_limit:
params["limit"] = config.site_limit

if config.parameter.lower() != "waterlevels":
params["parameter"] = get_analyte_search_param(
config.parameter, NMBGMR_ANALYTE_MAPPING
)
else:
params["parameter"] = "Manual groundwater levels"
if not config.sites_only:

if config.parameter.lower() != "waterlevels":
params["parameter"] = get_analyte_search_param(
config.parameter, NMBGMR_ANALYTE_MAPPING
)
else:
params["parameter"] = "Manual groundwater levels"

# tags="features" because the response object is a GeoJSON
sites = self._execute_json_request(
_make_url("locations"), params, tag="features", timeout=30
)
for site in sites:
print(f"Obtaining well data for {site['properties']['point_id']}")
well_data = self._execute_json_request(
_make_url("wells"),
params={"pointid": site["properties"]["point_id"]},
tag="",
)
site["properties"]["formation"] = well_data["formation"]
site["properties"]["well_depth"] = well_data["well_depth_ftbgs"]
site["properties"]["well_depth_units"] = FEET
# site["properties"]["formation"] = None
# site["properties"]["well_depth"] = None
# site["properties"]["well_depth_units"] = FEET
if not config.sites_only:
for site in sites:
print(f"Obtaining well data for {site['properties']['point_id']}")
well_data = self._execute_json_request(
_make_url("wells"),
params={"pointid": site["properties"]["point_id"]},
tag="",
)
site["properties"]["formation"] = well_data["formation"]
site["properties"]["well_depth"] = well_data["well_depth_ftbgs"]
site["properties"]["well_depth_units"] = FEET
# site["properties"]["formation"] = None
# site["properties"]["well_depth"] = None
# site["properties"]["well_depth_units"] = FEET

return sites

Expand Down
6 changes: 3 additions & 3 deletions backend/connectors/nmbgmr/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def _transform(self, record):
"vertical_datum": props["altitude_datum"],
"usgs_site_id": props["site_id"],
"alternate_site_id": props["alternate_site_id"],
"formation": props["formation"],
"well_depth": props["well_depth"],
"well_depth_units": props["well_depth_units"],
"formation": props.get("formation", ""),
"well_depth": props.get("well_depth", ""),
"well_depth_units": props.get("well_depth_units", ""),
}
return rec

Expand Down
40 changes: 27 additions & 13 deletions backend/connectors/nmenv/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,43 @@ def health(self):
return self.get_records(top=10, analyte="TDS")

def get_records(self, *args, **kw):

analyte = None
if "analyte" in kw:
analyte = kw["analyte"]
elif self.config:
analyte = self.config.parameter

analyte = get_analyte_search_param(analyte, DWB_ANALYTE_MAPPING)
if analyte is None:
return []

service = self.get_service()
ds = service.datastreams()
q = ds.query()
fs = [f"ObservedProperty/id eq {analyte}"]
if self.config:
if self.config.sites_only:
ds = service.things()
q = ds.query()
fs = []
if self.config.has_bounds():
fs.append(
f"st_within(Thing/Location/location, geography'{self.config.bounding_wkt()}')"
f"st_within(Locations/location, geography'{self.config.bounding_wkt()}')"
)

q = q.filter(" and ".join(fs))
q = q.expand("Thing/Locations")
return [ds.thing.locations.entities[0] for ds in q.list()]
q = q.expand("Locations")
if fs:
q = q.filter(" and ".join(fs))
return [thing.locations.entities[0] for thing in q.list()]
else:
analyte = get_analyte_search_param(analyte, DWB_ANALYTE_MAPPING)
if analyte is None:
return []

ds = service.datastreams()
q = ds.query()
fs = [f"ObservedProperty/id eq {analyte}"]
if self.config:
if self.config.has_bounds():
fs.append(
f"st_within(Thing/Location/location, geography'{self.config.bounding_wkt()}')"
)

q = q.filter(" and ".join(fs))
q = q.expand("Thing/Locations")
return [di.thing.locations.entities[0] for di in q.list()]


class DWBAnalyteSource(STAnalyteSource):
Expand Down
18 changes: 9 additions & 9 deletions backend/connectors/wqp/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ def get_records(self):
}
if config.has_bounds():
params["bBox"] = ",".join([str(b) for b in config.bbox_bounding_points()])

if config.parameter.lower() != "waterlevels":
params["characteristicName"] = get_analyte_search_param(
config.parameter, WQP_ANALYTE_MAPPING
)
else:
# every record with pCode 30210 (depth in m) has a corresponding
# record with pCode 72019 (depth in ft) but not vice versa
params["pCode"] = "30210"
if not config.sites_only:
if config.parameter.lower() != "waterlevels":
params["characteristicName"] = get_analyte_search_param(
config.parameter, WQP_ANALYTE_MAPPING
)
else:
# every record with pCode 30210 (depth in m) has a corresponding
# record with pCode 72019 (depth in ft) but not vice versa
params["pCode"] = "30210"

params.update(get_date_range(config))

Expand Down
Loading