Observed groundwater levels#

Measured groundwater levels from SGU’s monitoring stations, available as client.levels.observed. See Groundwater levels for a walkthrough.

Methods#

get_stations

Get groundwater monitoring stations.

get_station

Get a specific groundwater monitoring station by ID.

get_station_by_name

Convenience function to get a station by name ('station_id' or 'station_name').

get_stations_by_names

Convenience function to get multiple stations by name ('station_id' or 'station_name').

get_measurements

Get groundwater level measurements.

get_measurement

Get a specific groundwater level measurement by ID.

get_measurements_by_name

Get measurements for a specific station by name with optional time filtering.

get_measurements_by_names

Get measurements for multiple stations by name with optional time filtering.

Models#

GroundwaterStationCollection

Collection of groundwater monitoring stations (GeoJSON FeatureCollection).

GroundwaterStation

A groundwater monitoring station (GeoJSON Feature).

GroundwaterStationProperties

Properties for a groundwater monitoring station.

GroundwaterMeasurementCollection

Collection of groundwater level measurements (GeoJSON FeatureCollection).

GroundwaterMeasurement

A groundwater level measurement (GeoJSON Feature).

GroundwaterMeasurementProperties

Properties for a groundwater level measurement.

Client#

class ObservedGroundwaterLevelClient(base_client)[source]#

Client for observed groundwater level-related SGU API endpoints.

get_stations(bbox=None, datetime=None, limit=None, filter_expr=None, sortby=None, **kwargs)[source]#

Get groundwater monitoring stations.

Parameters:
  • bbox (list[float] | None) – Bounding box as [min_lon, min_lat, max_lon, max_lat]

  • datetime (str | None) – Date/time filter (RFC 3339 format or interval)

  • limit (int | None) – Maximum number of features to return (automatically paginated if needed)

  • filter_expr (str | None) – CQL filter expression

  • sortby (list[str] | None) – List of sort expressions (e.g., [‘+name’, ‘-date’])

  • **kwargs (Any) – Additional query parameters

Return type:

GroundwaterStationCollection

Returns:

Typed collection of groundwater monitoring stations

Example

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     # get stations in southern Sweden
...     stations = client.levels.observed.get_stations(
...         bbox=[12.0, 55.0, 16.0, 58.0]
...     )
...     # filter stations by municipality using CQL
...     stations = client.levels.observed.get_stations(
...         filter_expr="kommun='Uppsala' AND akvifer='JS'"
...     )
get_station(station_id)[source]#

Get a specific groundwater monitoring station by ID. This endpoint is provided by the OGC API but likely not used by any user.

Parameters:

station_id (str) – Station identifier

Return type:

GroundwaterStation

Returns:

Typed groundwater monitoring station

Raises:

ValueError – If station not found or multiple stations returned

get_measurements(bbox=None, datetime=None, limit=None, filter_expr=None, sortby=None, tmin=None, tmax=None, **kwargs)[source]#

Get groundwater level measurements.

This method is used internally by convenience functions like get_measurements_by_name() by constructing filter expressions. A user may also do this, but readability is greater when using the built-in convenience functions.

Parameters:
  • bbox (list[float] | None) – Bounding box as [min_lon, min_lat, max_lon, max_lat]

  • datetime (str | None) – Raw OGC date/time filter; prefer tmin/tmax

  • limit (int | None) – Maximum number of features to return (automatically paginated if needed)

  • filter_expr (str | None) – CQL filter expression

  • sortby (list[str] | None) – List of sort expressions (e.g., [‘+date’, ‘-value’])

  • tmin (str | datetime | None) – Earliest observation date (ISO string or datetime object)

  • tmax (str | datetime | None) – Latest observation date (ISO string or datetime object)

  • **kwargs (Any) – Additional query parameters

Return type:

GroundwaterMeasurementCollection

Returns:

Typed collection of groundwater level measurements

get_measurement(measurement_id)[source]#

Get a specific groundwater level measurement by ID. This endpoint is provided by the OGGC API but likely not used by any user.

Parameters:

measurement_id (str) – Measurement identifier

Return type:

GroundwaterMeasurement

Returns:

Typed groundwater level measurement

Raises:

ValueError – If measurement not found or multiple measurements returned

get_station_by_name(station_id=None, station_name=None, **kwargs)[source]#

Convenience function to get a station by name (‘station_id’ or ‘station_name’).

Parameters:
  • station_id (str | None) – Station identifier (maps to ‘platsbeteckning’ in API)

  • station_name (str | None) – Station name (maps to ‘obsplatsnamn’ in API)

  • **kwargs (Any) – Additional query parameters (e.g., limit)

Return type:

GroundwaterStation

Returns:

Typed groundwater monitoring station

Raises:

Example

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     # find station by platsbeteckning (recommended)
...     station = client.levels.observed.get_station_by_name(station_id="95_2")
...     # find station by obsplatsnamn
...     station = client.levels.observed.get_station_by_name(
...         station_name="Lagga_2"
...     )
...     print(station.properties.aquifer_description)
get_stations_by_names(station_id=None, station_name=None, **kwargs)[source]#

Convenience function to get multiple stations by name (‘station_id’ or ‘station_name’).

Parameters:
  • station_id (list[str] | None) – List of station identifiers (maps to ‘platsbeteckning’ in API)

  • station_name (list[str] | None) – List of station names (maps to ‘obsplatsnamn’ in API)

  • **kwargs (Any) – Additional query parameters (e.g., limit)

Return type:

GroundwaterStationCollection

Returns:

Typed collection of groundwater monitoring stations

Raises:
  • SGUNotFoundError – If any of the requested stations is not found.

  • ValueError – If not exactly one of station_id or station_name is provided.

Example

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     # get multiple stations by their IDs
...     stations = client.levels.observed.get_stations_by_names(
...         station_id=["95_2", "101_1", "102_3"]
...     )
...     for station in stations.features:
...         print(f"{station.properties.station_id}: {station.properties.aquifer_code}")
get_measurements_by_name(station_id=None, station_name=None, tmin=None, tmax=None, limit=None, **kwargs)[source]#

Get measurements for a specific station by name with optional time filtering.

Parameters:
  • station_id (str | None) – Station identifier (maps to ‘platsbeteckning’ in API)

  • station_name (str | None) – Station name (maps to ‘obsplatsnamn’ in API)

  • tmin (str | datetime | None) – Start time (ISO string or datetime object)

  • tmax (str | datetime | None) – End time (ISO string or datetime object)

  • limit (int | None) – Maximum number of measurements to return

  • **kwargs (Any) – Additional query parameters

Return type:

GroundwaterMeasurementCollection

Returns:

Typed collection of groundwater level measurements

Raises:
  • SGUNotFoundError – If a station_name matches no station.

  • SGUAmbiguousError – If a station_name matches several stations.

  • ValueError – If not exactly one of station_id or station_name is provided, or if the looked-up station has no station_id.

Example

>>> from sgu_client import SGUClient
>>> from datetime import datetime, timezone
>>> with SGUClient() as client:
...     # get all measurements for a station
...     measurements = client.levels.observed.get_measurements_by_name(
...         station_id="95_2",
...         limit=100
...     )
...     # get measurements with time filtering
...     measurements = client.levels.observed.get_measurements_by_name(
...         station_id="95_2",
...         tmin=datetime(2020, 1, 1, tzinfo=timezone.utc),
...         tmax=datetime(2021, 1, 1, tzinfo=timezone.utc)
...     )
...     # using ISO string for time filtering
...     measurements = client.levels.observed.get_measurements_by_name(
...         station_id="95_2",
...         tmin="2020-01-01T00:00:00Z",
...         tmax="2021-01-01T00:00:00Z"
...     )
get_measurements_by_names(station_id=None, station_name=None, tmin=None, tmax=None, limit=None, **kwargs)[source]#

Get measurements for multiple stations by name with optional time filtering.

Parameters:
  • station_id (list[str] | None) – List of station identifiers (maps to ‘platsbeteckning’ in API)

  • station_name (list[str] | None) – List of station names (maps to ‘obsplatsnamn’ in API)

  • tmin (str | datetime | None) – Start time (ISO string or datetime object)

  • tmax (str | datetime | None) – End time (ISO string or datetime object)

  • limit (int | None) – Maximum number of measurements to return

  • **kwargs (Any) – Additional query parameters

Return type:

GroundwaterMeasurementCollection

Returns:

Typed collection of groundwater level measurements

Raises:
  • SGUNotFoundError – If any station_name matches no station.

  • ValueError – If not exactly one of station_id or station_name is provided, or if a looked-up station has no station_id.

Example

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     # get measurements for multiple stations
...     measurements = client.levels.observed.get_measurements_by_names(
...         station_id=["95_2", "101_1"],
...         tmin="2020-01-01T00:00:00Z",
...         tmax="2021-01-01T00:00:00Z",
...         limit=1000
...     )
...     print(f"Found {len(measurements.features)} measurements")

Model details#

Pydantic models for groundwater data from SGU API.

pydantic model GroundwaterStationProperties[source]#

Properties for a groundwater monitoring station.

field row_id: int [Required] (alias 'rowid')#

Row ID

field station_id: str | None = None (alias 'platsbeteckning')#

Station identifier

field station_name: str | None = None (alias 'obsplatsnamn')#

Observation station name

field sample_site_id: str | None = None (alias 'provplatsid')#

Sample site ID

field active_since: Annotated[datetime | None] = None (alias 'fdat')#

Active since date (midnight UTC)

Constraints:
  • func = <function _parse_api_datetime at 0x7fa47d9d60c0>

  • json_schema_input_type = PydanticUndefined

field active_until: Annotated[datetime | None] = None (alias 'tdat')#

Active until date (midnight UTC); None for a live station

Constraints:
  • func = <function _parse_api_datetime at 0x7fa47d9d60c0>

  • json_schema_input_type = PydanticUndefined

field reference_level: float | None = None (alias 'refniva')#

Reference level

field elevation_method: str | None = None (alias 'hojdmetod')#

Height/elevation measurement method

field elevation_system: str | None = None (alias 'hojdsystem')#

Height/elevation reference system

field well_height: float | None = None (alias 'rorhojd')#

Pipe height

field well_length: float | None = None (alias 'rorlangd')#

Pipe length

field aquifer_code: str | None = None (alias 'akvifer')#

Aquifer code

field aquifer_description: str | None = None (alias 'akvifer_tx')#

Aquifer description

field soil_code: str | None = None (alias 'jordart')#

Soil type code

field soil_description: str | None = None (alias 'jordart_tx')#

Soil type description

field soil_genesis_code: str | None = None (alias 'genes_jord')#

Soil genesis code

field soil_genesis_description: str | None = None (alias 'genes_jord_tx')#

Soil genesis description

field overlying_soil_code: str | None = None (alias 'jord_ovan_jord')#

Soil above soil code

field overlying_soil_description: str | None = None (alias 'jord_ovan_jord_tx')#

Soil above soil description

field soil_depth: float | None = None (alias 'jorddjup')#

Soil depth

field soil_depth_qualifier: str | None = None (alias 'tecken_jorddjup')#

Soil depth sign/qualifier

field inner_diameter: float | None = None (alias 'idiam')#

Inner diameter

field well_material_code: str | None = None (alias 'brunnsmtrl')#

Well material code

field well_material_description: str | None = None (alias 'brunnsmtrl_tx')#

Well material description

field borehole_completion: float | None = None (alias 'borrhalslutning')#

Borehole closure/completion

field screen_length: float | None = None (alias 'sillangd')#

Screen length

field hydrogeological_setting_code: str | None = None (alias 'geohylag')#

Geohydrological position code

field hydrogeological_setting_description: str | None = None (alias 'geohylag_tx')#

Geohydrological position description

field municipality_code: str | None = None (alias 'kommunkod')#

Municipality code

field municipality: str | None = None (alias 'kommun')#

Municipality

field county_code: str | None = None (alias 'lanskod')#

County code

field county: str | None = None (alias 'lan')#

County

field eu_groundwater_body: str | None = None (alias 'eucd_gwb')#

EU groundwater body

field north_coordinate: float | None = None (alias 'n')#

North coordinate

field east_coordinate: float | None = None (alias 'e')#

East coordinate

field aquifer_symbol: str | None = None (alias 'symbol_magasin')#

Aquifer symbol

field impact_symbol: str | None = None (alias 'symbol_paverkan')#

Impact symbol

field station_remark: str | None = None (alias 'stationsanmarkning')#

Station note/remarks

field comments: str | None = None (alias 'kommentar')#

Comment

pydantic model GroundwaterStation[source]#

A groundwater monitoring station (GeoJSON Feature).

geometry is null for stations without a location.

pydantic model GroundwaterMeasurementProperties[source]#

Properties for a groundwater level measurement.

field row_id: int [Required] (alias 'rowid')#

Row ID

field station_id: str | None = None (alias 'platsbeteckning')#

Station identifier

field observation_date: Annotated[datetime | None] = None (alias 'obsdatum')#

Observation timestamp (UTC)

Constraints:
  • func = <function _parse_api_datetime at 0x7fa47d9d60c0>

  • json_schema_input_type = PydanticUndefined

field water_level_below_ground_m: float | None = None (alias 'grundvattenniva_m_urok')#

Groundwater level (m below ground)

field water_level_masl_m: float | None = None (alias 'grundvattenniva_m_o_h')#

Groundwater level (m above sea level)

field water_level_below_surface_m: float | None = None (alias 'grundvattenniva_m_u_markyta')#

Groundwater level (m below surface)

field measurement_method: str | None = None (alias 'metod_for_matning')#

Measurement method

field level_remark: str | None = None (alias 'nivaanmarkning')#

Level note/remarks

field last_updated: Annotated[datetime | None] = None (alias 'lastupdate')#

Last update timestamp (UTC)

Constraints:
  • func = <function _parse_api_datetime at 0x7fa47d9d60c0>

  • json_schema_input_type = PydanticUndefined

pydantic model GroundwaterMeasurement[source]#

A groundwater level measurement (GeoJSON Feature).

pydantic model GroundwaterStationCollection[source]#

Collection of groundwater monitoring stations (GeoJSON FeatureCollection).

Its DataFrame has longitude and latitude columns, null for stations without a location.

Examples

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     stations = client.levels.observed.get_stations(limit=10)
...     df = stations.to_dataframe()
...     print(df[['station_id', 'station_name', 'longitude', 'latitude']].head())
pydantic model GroundwaterMeasurementCollection[source]#

Collection of groundwater level measurements (GeoJSON FeatureCollection).

Its DataFrame has no geometry columns. Sorted by observation_date; to_series() defaults to water_level_masl_m.

Examples

>>> from sgu_client import SGUClient
>>> with SGUClient() as client:
...     measurements = client.levels.observed.get_measurements_by_name(
...         station_id="95_2", limit=100
...     )
...     df = measurements.to_dataframe()
...     print(df[['observation_date', 'water_level_masl_m', 'station_id']].head())
...     series = measurements.to_series()