mirror of
https://github.com/jdejaegh/python-irceline.git
synced 2025-06-26 19:35:40 +02:00
Add RIO IFDM client
This commit is contained in:
parent
c878bf8f81
commit
3b2e88213e
11 changed files with 921 additions and 64 deletions
|
@ -1,6 +1,6 @@
|
||||||
from .api import IrcelineApiError
|
from .api import IrcelineApiError
|
||||||
from .rio import IrcelineRioClient
|
from .rio import IrcelineRioClient
|
||||||
from .forecast import IrcelineForecastClient
|
from .forecast import IrcelineForecastClient
|
||||||
from .data import RioFeature, ForecastFeature, FeatureValue, BelAqiIndex
|
from .data import RioFeature, ForecastFeature, FeatureValue
|
||||||
|
|
||||||
__version__ = '2.0.0'
|
__version__ = '2.0.0'
|
||||||
|
|
|
@ -2,17 +2,18 @@ import asyncio
|
||||||
import socket
|
import socket
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Tuple, List, Set
|
from typing import Tuple, List, Set
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import async_timeout
|
import async_timeout
|
||||||
|
from aiohttp import ClientResponse
|
||||||
|
|
||||||
from .data import IrcelineFeature
|
from .data import IrcelineFeature
|
||||||
from .utils import SizedDict
|
from .utils import SizedDict
|
||||||
|
|
||||||
_rio_wfs_base_url = 'https://geo.irceline.be/wfs'
|
_rio_wfs_base_url = 'https://geo.irceline.be/wfs'
|
||||||
_forecast_wms_base_url = 'https://geo.irceline.be/forecast/wms'
|
_forecast_wms_base_url = 'https://geo.irceline.be/forecast/wms'
|
||||||
# noinspection HttpUrlsUsage
|
_rio_ifdm_wms_base_url = 'https://geobelair.irceline.be/rioifdm/wms'
|
||||||
# There is not HTTPS version of this endpoint
|
|
||||||
_user_agent = 'github.com/jdejaegh/python-irceline'
|
_user_agent = 'github.com/jdejaegh/python-irceline'
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,3 +66,38 @@ class IrcelineBaseClient(ABC):
|
||||||
raise IrcelineApiError(f"Something really wrong happened! {exception}") from exception
|
raise IrcelineApiError(f"Something really wrong happened! {exception}") from exception
|
||||||
|
|
||||||
|
|
||||||
|
class IrcelineBaseWmsClient(IrcelineBaseClient, ABC):
|
||||||
|
_default_querystring = {"service": "WMS",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"request": "GetFeatureInfo",
|
||||||
|
"info_format": "application/json",
|
||||||
|
"width": "1",
|
||||||
|
"height": "1",
|
||||||
|
"srs": "EPSG:4326",
|
||||||
|
"X": "1",
|
||||||
|
"Y": "1"}
|
||||||
|
_epsilon = 0.00001
|
||||||
|
_base_url = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_capabilities(xml_string: str) -> Set[str]:
|
||||||
|
try:
|
||||||
|
root = ElementTree.fromstring(xml_string)
|
||||||
|
except ElementTree.ParseError:
|
||||||
|
return set()
|
||||||
|
|
||||||
|
path = './/Capability/Layer/Layer/Name'
|
||||||
|
feature_type_names = {t.text for t in root.findall(path)}
|
||||||
|
return feature_type_names
|
||||||
|
|
||||||
|
async def get_capabilities(self) -> Set[str]:
|
||||||
|
"""
|
||||||
|
Fetch the list of possible features from the WMS server
|
||||||
|
:return: set of features available on the WMS server
|
||||||
|
"""
|
||||||
|
querystring = {"service": "WMS",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"request": "GetCapabilities"}
|
||||||
|
r: ClientResponse = await self._api_wrapper(self._base_url, querystring)
|
||||||
|
|
||||||
|
return self._parse_capabilities(await r.text())
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from enum import StrEnum, Enum
|
from enum import StrEnum
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,14 @@ class RioFeature(IrcelineFeature):
|
||||||
SO2_HMEAN = 'rio:so2_hmean'
|
SO2_HMEAN = 'rio:so2_hmean'
|
||||||
|
|
||||||
|
|
||||||
|
class RioIfdmFeature(IrcelineFeature):
|
||||||
|
PM25_HMEAN = 'rioifdm:pm25_hmean'
|
||||||
|
NO2_HMEAN = 'rioifdm:no2_hmean'
|
||||||
|
PM10_HMEAN = 'rioifdm:pm10_hmean'
|
||||||
|
O3_HMEAN = 'rioifdm:o3_hmean'
|
||||||
|
BELAQI = 'rioifdm:belaqi'
|
||||||
|
|
||||||
|
|
||||||
class ForecastFeature(IrcelineFeature):
|
class ForecastFeature(IrcelineFeature):
|
||||||
NO2_MAXHMEAN = 'forecast:no2_maxhmean'
|
NO2_MAXHMEAN = 'forecast:no2_maxhmean'
|
||||||
NO2_DMEAN = 'forecast:no2_dmean'
|
NO2_DMEAN = 'forecast:no2_dmean'
|
||||||
|
@ -40,20 +48,7 @@ class ForecastFeature(IrcelineFeature):
|
||||||
BELAQI = 'forecast:belaqi'
|
BELAQI = 'forecast:belaqi'
|
||||||
|
|
||||||
|
|
||||||
class BelAqiIndex(Enum):
|
|
||||||
EXCELLENT = 1
|
|
||||||
VERY_GOOD = 2
|
|
||||||
GOOD = 3
|
|
||||||
FAIRLY_GOOD = 4
|
|
||||||
MODERATE = 5
|
|
||||||
POOR = 6
|
|
||||||
VERY_POOR = 7
|
|
||||||
BAD = 8
|
|
||||||
VERY_BAD = 9
|
|
||||||
HORRIBLE = 10
|
|
||||||
|
|
||||||
|
|
||||||
class FeatureValue(TypedDict):
|
class FeatureValue(TypedDict):
|
||||||
# Timestamp at which the value was computed
|
# Timestamp at which the value was computed
|
||||||
timestamp: datetime | date | None
|
timestamp: datetime | date | None
|
||||||
value: int | float | BelAqiIndex | None
|
value: int | float | None
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
from datetime import date, timedelta, datetime
|
from datetime import date, timedelta, datetime
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from typing import List, Tuple, Dict, Set
|
from typing import List, Tuple, Dict
|
||||||
from xml.etree import ElementTree
|
|
||||||
|
|
||||||
from aiohttp import ClientResponse, ClientResponseError
|
from aiohttp import ClientResponse, ClientResponseError
|
||||||
|
|
||||||
from .api import IrcelineBaseClient, _forecast_wms_base_url, IrcelineApiError
|
from .api import IrcelineApiError, IrcelineBaseWmsClient, _forecast_wms_base_url
|
||||||
from .data import ForecastFeature, FeatureValue
|
from .data import ForecastFeature, FeatureValue
|
||||||
|
|
||||||
|
|
||||||
class IrcelineForecastClient(IrcelineBaseClient):
|
class IrcelineForecastClient(IrcelineBaseWmsClient):
|
||||||
_epsilon = 0.00001
|
_base_url = _forecast_wms_base_url
|
||||||
|
|
||||||
async def get_data(self,
|
async def get_data(self,
|
||||||
features: List[ForecastFeature],
|
features: List[ForecastFeature],
|
||||||
|
@ -26,22 +25,14 @@ class IrcelineForecastClient(IrcelineBaseClient):
|
||||||
timestamp = date.today()
|
timestamp = date.today()
|
||||||
result = dict()
|
result = dict()
|
||||||
lat, lon = position
|
lat, lon = position
|
||||||
base_querystring = {"service": "WMS",
|
base_querystring = (self._default_querystring |
|
||||||
"version": "1.1.1",
|
{"bbox": f"{lon},{lat},{lon + self._epsilon},{lat + self._epsilon}"})
|
||||||
"request": "GetFeatureInfo",
|
|
||||||
"info_format": "application/json",
|
|
||||||
"width": "1",
|
|
||||||
"height": "1",
|
|
||||||
"srs": "EPSG:4326",
|
|
||||||
"bbox": f"{lon},{lat},{lon + self._epsilon},{lat + self._epsilon}",
|
|
||||||
"X": "1",
|
|
||||||
"Y": "1"}
|
|
||||||
|
|
||||||
for feature, d in product(features, range(4)):
|
for feature, d in product(features, range(4)):
|
||||||
querystring = base_querystring | {"layers": f"{feature}_d{d}",
|
querystring = base_querystring | {"layers": f"{feature}_d{d}",
|
||||||
"query_layers": f"{feature}_d{d}"}
|
"query_layers": f"{feature}_d{d}"}
|
||||||
try:
|
try:
|
||||||
r: ClientResponse = await self._api_wrapper(_forecast_wms_base_url, querystring)
|
r: ClientResponse = await self._api_wrapper(self._base_url, querystring)
|
||||||
r: dict = await r.json()
|
r: dict = await r.json()
|
||||||
result[(feature, timestamp + timedelta(days=d))] = FeatureValue(
|
result[(feature, timestamp + timedelta(days=d))] = FeatureValue(
|
||||||
value=r.get('features', [{}])[0].get('properties', {}).get('GRAY_INDEX'),
|
value=r.get('features', [{}])[0].get('properties', {}).get('GRAY_INDEX'),
|
||||||
|
@ -50,26 +41,3 @@ class IrcelineForecastClient(IrcelineBaseClient):
|
||||||
result[(feature, timestamp + timedelta(days=d))] = FeatureValue(value=None, timestamp=None)
|
result[(feature, timestamp + timedelta(days=d))] = FeatureValue(value=None, timestamp=None)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def get_capabilities(self) -> Set[str]:
|
|
||||||
"""
|
|
||||||
Fetch the list of possible features from the WMS server
|
|
||||||
:return: set of features available on the WMS server
|
|
||||||
"""
|
|
||||||
querystring = {"service": "WMS",
|
|
||||||
"version": "1.1.1",
|
|
||||||
"request": "GetCapabilities"}
|
|
||||||
r: ClientResponse = await self._api_wrapper(_forecast_wms_base_url, querystring)
|
|
||||||
|
|
||||||
return self._parse_capabilities(await r.text())
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_capabilities(xml_string: str) -> Set[str]:
|
|
||||||
try:
|
|
||||||
root = ElementTree.fromstring(xml_string)
|
|
||||||
except ElementTree.ParseError:
|
|
||||||
return set()
|
|
||||||
|
|
||||||
path = './/Capability/Layer/Layer/Name'
|
|
||||||
feature_type_names = {t.text for t in root.findall(path)}
|
|
||||||
return feature_type_names
|
|
||||||
|
|
|
@ -2,15 +2,19 @@ from datetime import datetime, date, UTC, timedelta
|
||||||
from typing import List, Tuple, Dict, Set
|
from typing import List, Tuple, Dict, Set
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
from aiohttp import ClientResponse
|
from aiohttp import ClientResponse, ClientResponseError
|
||||||
|
|
||||||
from .api import IrcelineBaseClient, _rio_wfs_base_url, IrcelineApiError
|
from .api import IrcelineBaseClient, _rio_wfs_base_url, IrcelineApiError, _rio_ifdm_wms_base_url, IrcelineBaseWmsClient
|
||||||
from .data import RioFeature, FeatureValue
|
from .data import RioFeature, FeatureValue, RioIfdmFeature
|
||||||
from .utils import epsg_transform
|
from .utils import epsg_transform
|
||||||
|
|
||||||
|
|
||||||
class IrcelineRioClient(IrcelineBaseClient):
|
class IrcelineRioClient(IrcelineBaseClient):
|
||||||
"""API client for RIO interpolated IRCEL - CELINE open data"""
|
"""
|
||||||
|
API client for RIO interpolated IRCEL - CELINE open data
|
||||||
|
RIO is more coarse grained for interpolation than RIO IFDM and allows to request multiple features in the same
|
||||||
|
request, which may be faster.
|
||||||
|
"""
|
||||||
|
|
||||||
async def get_data(self,
|
async def get_data(self,
|
||||||
features: List[RioFeature],
|
features: List[RioFeature],
|
||||||
|
@ -124,3 +128,41 @@ class IrcelineRioClient(IrcelineBaseClient):
|
||||||
result[name] = FeatureValue(timestamp=timestamp, value=value)
|
result[name] = FeatureValue(timestamp=timestamp, value=value)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class IrcelineRioIfdmClient(IrcelineBaseWmsClient):
|
||||||
|
"""
|
||||||
|
API client for RIO IFDM interpolated IRCEL - CELINE open data
|
||||||
|
RIO IFDM is more fine-grained for interpolation than RIO but only allows one feature to be request at a time, which
|
||||||
|
may be slower
|
||||||
|
"""
|
||||||
|
_base_url = _rio_ifdm_wms_base_url
|
||||||
|
|
||||||
|
async def get_data(self,
|
||||||
|
features: List[RioIfdmFeature],
|
||||||
|
position: Tuple[float, float]
|
||||||
|
) -> Dict[RioIfdmFeature, FeatureValue]:
|
||||||
|
"""
|
||||||
|
Get interpolated concentrations for the given features at the given position.
|
||||||
|
:param features: pollutants to get the forecasts for
|
||||||
|
:param position: (lat, long)
|
||||||
|
:return: dict where key is RioIfdmFeature and value is a FeatureValue
|
||||||
|
"""
|
||||||
|
result = dict()
|
||||||
|
lat, lon = position
|
||||||
|
base_querystring = (self._default_querystring |
|
||||||
|
{"bbox": f"{lon},{lat},{lon + self._epsilon},{lat + self._epsilon}"})
|
||||||
|
print({"bbox": f"{lon},{lat},{lon + self._epsilon},{lat + self._epsilon}"})
|
||||||
|
|
||||||
|
for feature in features:
|
||||||
|
querystring = base_querystring | {"layers": f"{feature}", "query_layers": f"{feature}"}
|
||||||
|
try:
|
||||||
|
r: ClientResponse = await self._api_wrapper(self._base_url, querystring)
|
||||||
|
r: dict = await r.json()
|
||||||
|
result[feature] = FeatureValue(
|
||||||
|
value=r.get('features', [{}])[0].get('properties', {}).get('GRAY_INDEX'),
|
||||||
|
timestamp=datetime.fromisoformat(r.get('timeStamp')) if 'timeStamp' in r else None)
|
||||||
|
except (IrcelineApiError, ClientResponseError, IndexError):
|
||||||
|
result[feature] = FeatureValue(value=None, timestamp=None)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
17
tests/fixtures/ifdm_interpolation_feature_info.json
vendored
Normal file
17
tests/fixtures/ifdm_interpolation_feature_info.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"id": "",
|
||||||
|
"geometry": null,
|
||||||
|
"properties": {
|
||||||
|
"GRAY_INDEX": 84.33950805664062
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalFeatures": "unknown",
|
||||||
|
"numberReturned": 1,
|
||||||
|
"timeStamp": "2024-06-30T15:43:07.222Z",
|
||||||
|
"crs": null
|
||||||
|
}
|
694
tests/fixtures/rio_ifdm_capabilities.xml
vendored
Normal file
694
tests/fixtures/rio_ifdm_capabilities.xml
vendored
Normal file
|
@ -0,0 +1,694 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE WMT_MS_Capabilities SYSTEM "https://geobelair.irceline.be/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd">
|
||||||
|
<WMT_MS_Capabilities version="1.1.1" updateSequence="4129">
|
||||||
|
<Service>
|
||||||
|
<Name>OGC:WMS</Name>
|
||||||
|
<Title>IRCEL - CELINE - Web Map Service</Title>
|
||||||
|
<Abstract>A compliant implementation of WMS plus most of the SLD extension (dynamic styling). Can also generate
|
||||||
|
PDF, SVG, KML, GeoRSS
|
||||||
|
</Abstract>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>WFS</Keyword>
|
||||||
|
<Keyword>WMS</Keyword>
|
||||||
|
<Keyword>GEOSERVER</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="http://geo.irceline.be/rioifdm/wms"/>
|
||||||
|
<ContactInformation>
|
||||||
|
<ContactPersonPrimary>
|
||||||
|
<ContactPerson>IRCEL - CELINE</ContactPerson>
|
||||||
|
<ContactOrganization>Belgian Interregional Environment Agency</ContactOrganization>
|
||||||
|
</ContactPersonPrimary>
|
||||||
|
<ContactPosition/>
|
||||||
|
<ContactAddress>
|
||||||
|
<AddressType/>
|
||||||
|
<Address>Gaucheretstraat 92-94 Rue Gaucheret</Address>
|
||||||
|
<City>Brussels</City>
|
||||||
|
<StateOrProvince/>
|
||||||
|
<PostCode>1030</PostCode>
|
||||||
|
<Country>Belgium</Country>
|
||||||
|
</ContactAddress>
|
||||||
|
<ContactVoiceTelephone>+(32)(0)2 227 57 01</ContactVoiceTelephone>
|
||||||
|
<ContactFacsimileTelephone/>
|
||||||
|
<ContactElectronicMailAddress>info@irceline.be</ContactElectronicMailAddress>
|
||||||
|
</ContactInformation>
|
||||||
|
<Fees>NONE</Fees>
|
||||||
|
<AccessConstraints>NONE</AccessConstraints>
|
||||||
|
</Service>
|
||||||
|
<Capability>
|
||||||
|
<Request>
|
||||||
|
<GetCapabilities>
|
||||||
|
<Format>application/vnd.ogc.wms_xml</Format>
|
||||||
|
<Format>text/xml</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
<Post>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Post>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</GetCapabilities>
|
||||||
|
<GetMap>
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<Format>application/atom xml</Format>
|
||||||
|
<Format>application/atom+xml</Format>
|
||||||
|
<Format>application/json;type=utfgrid</Format>
|
||||||
|
<Format>application/openlayers</Format>
|
||||||
|
<Format>application/openlayers2</Format>
|
||||||
|
<Format>application/openlayers3</Format>
|
||||||
|
<Format>application/pdf</Format>
|
||||||
|
<Format>application/rss xml</Format>
|
||||||
|
<Format>application/rss+xml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kml xml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kml+xml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kml+xml;mode=networklink</Format>
|
||||||
|
<Format>application/vnd.google-earth.kmz</Format>
|
||||||
|
<Format>application/vnd.google-earth.kmz xml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kmz+xml</Format>
|
||||||
|
<Format>application/vnd.google-earth.kmz;mode=networklink</Format>
|
||||||
|
<Format>atom</Format>
|
||||||
|
<Format>image/geotiff</Format>
|
||||||
|
<Format>image/geotiff8</Format>
|
||||||
|
<Format>image/gif</Format>
|
||||||
|
<Format>image/gif;subtype=animated</Format>
|
||||||
|
<Format>image/jpeg</Format>
|
||||||
|
<Format>image/png8</Format>
|
||||||
|
<Format>image/png; mode=8bit</Format>
|
||||||
|
<Format>image/svg</Format>
|
||||||
|
<Format>image/svg xml</Format>
|
||||||
|
<Format>image/svg+xml</Format>
|
||||||
|
<Format>image/tiff</Format>
|
||||||
|
<Format>image/tiff8</Format>
|
||||||
|
<Format>image/vnd.jpeg-png</Format>
|
||||||
|
<Format>image/vnd.jpeg-png8</Format>
|
||||||
|
<Format>kml</Format>
|
||||||
|
<Format>kmz</Format>
|
||||||
|
<Format>openlayers</Format>
|
||||||
|
<Format>rss</Format>
|
||||||
|
<Format>text/html; subtype=openlayers</Format>
|
||||||
|
<Format>text/html; subtype=openlayers2</Format>
|
||||||
|
<Format>text/html; subtype=openlayers3</Format>
|
||||||
|
<Format>utfgrid</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</GetMap>
|
||||||
|
<GetFeatureInfo>
|
||||||
|
<Format>text/plain</Format>
|
||||||
|
<Format>application/vnd.ogc.gml</Format>
|
||||||
|
<Format>text/xml</Format>
|
||||||
|
<Format>application/vnd.ogc.gml/3.1.1</Format>
|
||||||
|
<Format>text/xml; subtype=gml/3.1.1</Format>
|
||||||
|
<Format>text/html</Format>
|
||||||
|
<Format>application/json</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
<Post>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Post>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</GetFeatureInfo>
|
||||||
|
<DescribeLayer>
|
||||||
|
<Format>application/vnd.ogc.wms_xml</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</DescribeLayer>
|
||||||
|
<GetLegendGraphic>
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<Format>image/jpeg</Format>
|
||||||
|
<Format>application/json</Format>
|
||||||
|
<Format>image/gif</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</GetLegendGraphic>
|
||||||
|
<GetStyles>
|
||||||
|
<Format>application/vnd.ogc.sld+xml</Format>
|
||||||
|
<DCPType>
|
||||||
|
<HTTP>
|
||||||
|
<Get>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?SERVICE=WMS&"/>
|
||||||
|
</Get>
|
||||||
|
</HTTP>
|
||||||
|
</DCPType>
|
||||||
|
</GetStyles>
|
||||||
|
</Request>
|
||||||
|
<Exception>
|
||||||
|
<Format>application/vnd.ogc.se_xml</Format>
|
||||||
|
<Format>application/vnd.ogc.se_inimage</Format>
|
||||||
|
<Format>application/vnd.ogc.se_blank</Format>
|
||||||
|
<Format>application/json</Format>
|
||||||
|
</Exception>
|
||||||
|
<UserDefinedSymbolization SupportSLD="1" UserLayer="1" UserStyle="1" RemoteWFS="1"/>
|
||||||
|
<Layer>
|
||||||
|
<Title>IRCEL - CELINE - Web Map Service</Title>
|
||||||
|
<Abstract>A compliant implementation of WMS plus most of the SLD extension (dynamic styling). Can also
|
||||||
|
generate PDF, SVG, KML, GeoRSS
|
||||||
|
</Abstract>
|
||||||
|
<!--Limited list of EPSG projections:-->
|
||||||
|
<SRS>EPSG:3857</SRS>
|
||||||
|
<SRS>EPSG:4258</SRS>
|
||||||
|
<SRS>EPSG:4326</SRS>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<SRS>EPSG:900913</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<AuthorityURL name="IRCEL - CELINE">
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://geo.irceline.be"/>
|
||||||
|
</AuthorityURL>
|
||||||
|
<Identifier authority="IRCEL - CELINE">http://geo.irceline.be</Identifier>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>belaqi</Name>
|
||||||
|
<Title>belaqi</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>belaqi</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>belaqi_raster_discrete_belair</Name>
|
||||||
|
<Title>AQ index for raster (discrete colour schale)</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Classic concentration color progression.</Abstract>
|
||||||
|
<LegendURL width="36" height="250">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=belaqi"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>belaqi_dm1</Name>
|
||||||
|
<Title>belaqi_dm1</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>belaqi_dmean_dm1</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>belaqi_raster_discrete_belair</Name>
|
||||||
|
<Title>AQ index for raster (discrete colour schale)</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Classic concentration color progression.</Abstract>
|
||||||
|
<LegendURL width="36" height="250">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=belaqi_dm1"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>belaqi_dm2</Name>
|
||||||
|
<Title>belaqi_dm2</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>belaqi_dmean_dm2</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>belaqi_raster_discrete_belair</Name>
|
||||||
|
<Title>AQ index for raster (discrete colour schale)</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Classic concentration color progression.</Abstract>
|
||||||
|
<LegendURL width="36" height="250">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=belaqi_dm2"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>belaqi_dm3</Name>
|
||||||
|
<Title>belaqi_dm3</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>belaqi_dmean_dm3</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>belaqi_raster_discrete_belair</Name>
|
||||||
|
<Title>AQ index for raster (discrete colour schale)</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Classic concentration color progression.</Abstract>
|
||||||
|
<LegendURL width="36" height="250">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=belaqi_dm3"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>no2_dm1</Name>
|
||||||
|
<Title>no2_dm1</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>no2_dmean_dm1</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>no2_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Nitrogen dioxide (NO2) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for Nitrogen dioxide (NO2).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="80" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=no2_dm1"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>no2_dm2</Name>
|
||||||
|
<Title>no2_dm2</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>no2_dmean_dm2</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>no2_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Nitrogen dioxide (NO2) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for Nitrogen dioxide (NO2).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="80" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=no2_dm2"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>no2_dm3</Name>
|
||||||
|
<Title>no2_dm3</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>no2_dmean_dm3</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>no2_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Nitrogen dioxide (NO2) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for Nitrogen dioxide (NO2).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="80" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=no2_dm3"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>no2_hmean</Name>
|
||||||
|
<Title>no2_hmean</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>no2_hmean</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>no2_hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Nitrogen dioxide (NO2) hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Hourly mean concentration classes for Nitrogen dioxide (NO2).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="80" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=no2_hmean"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>o3_dm1</Name>
|
||||||
|
<Title>o3_dm1</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>o3_max8hmean_dm1</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>o3_max8hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Ozone (O3) daily max 8-hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily max 8-hourly mean concentration classes for Ozone (O3).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=o3_dm1"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>o3_dm2</Name>
|
||||||
|
<Title>o3_dm2</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>o3_max8hmean_dm2</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>o3_max8hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Ozone (O3) daily max 8-hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily max 8-hourly mean concentration classes for Ozone (O3).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=o3_dm2"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>o3_dm3</Name>
|
||||||
|
<Title>o3_dm3</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>o3_max8hmean_dm3</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>o3_max8hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Ozone (O3) daily max 8-hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily max 8-hourly mean concentration classes for Ozone (O3).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=o3_dm3"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>o3_hmean</Name>
|
||||||
|
<Title>o3_hmean</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>o3_hmean</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>o3_hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>Ozone (O3) hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Annual mean concentration classes for Ozone (O3).</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=o3_hmean"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm10_dm1</Name>
|
||||||
|
<Title>pm10_dm1</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm10_dmean_dm1</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm10_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM10) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM10).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm10_dm1"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm10_dm2</Name>
|
||||||
|
<Title>pm10_dm2</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm10_dmean_dm2</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm10_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM10) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM10).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm10_dm2"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm10_dm3</Name>
|
||||||
|
<Title>pm10_dm3</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm10_dmean_dm3</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm10_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM10) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM10).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm10_dm3"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm10_hmean</Name>
|
||||||
|
<Title>pm10_hmean</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm10_hmean</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm10_hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM10) hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Hourly mean concentration classes for particulate matter
|
||||||
|
(PM10).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm10_hmean"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm25_dm1</Name>
|
||||||
|
<Title>pm25_dm1</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm25_dmean_dm1</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm25_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM25) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM25).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm25_dm1"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm25_dm2</Name>
|
||||||
|
<Title>pm25_dm2</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm25_dmean_dm2</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm25_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM25) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM25).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm25_dm2"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm25_dm3</Name>
|
||||||
|
<Title>pm25_dm3</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm25_dmean_dm3</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm25_dmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM25) daily mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Daily mean concentration classes for particulate matter
|
||||||
|
(PM25).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm25_dm3"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
<Layer queryable="1" opaque="0">
|
||||||
|
<Name>pm25_hmean</Name>
|
||||||
|
<Title>pm25_hmean</Title>
|
||||||
|
<Abstract/>
|
||||||
|
<KeywordList>
|
||||||
|
<Keyword>pm25_hmean</Keyword>
|
||||||
|
<Keyword>WCS</Keyword>
|
||||||
|
<Keyword>GeoTIFF</Keyword>
|
||||||
|
</KeywordList>
|
||||||
|
<SRS>EPSG:31370</SRS>
|
||||||
|
<LatLonBoundingBox minx="2.4804079470216474" miny="49.461523892203324" maxx="6.494748595696256"
|
||||||
|
maxy="51.54189845090732"/>
|
||||||
|
<BoundingBox SRS="EPSG:31370" minx="18950.0" miny="18650.0" maxx="297550.0" maxy="248050.0"/>
|
||||||
|
<Style>
|
||||||
|
<Name>pm25_hmean_raster_discrete_belair</Name>
|
||||||
|
<Title>particulate matter (PM25) hourly mean concentrations</Title>
|
||||||
|
<Abstract>BelAQI index colour scale. Hourly mean concentration classes for particulate matter
|
||||||
|
(PM25).
|
||||||
|
</Abstract>
|
||||||
|
<LegendURL width="87" height="252">
|
||||||
|
<Format>image/png</Format>
|
||||||
|
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
|
||||||
|
xlink:href="https://geobelair.irceline.be/rioifdm/wms?request=GetLegendGraphic&version=1.1.1&format=image%2Fpng&width=20&height=20&layer=pm25_hmean"/>
|
||||||
|
</LegendURL>
|
||||||
|
</Style>
|
||||||
|
</Layer>
|
||||||
|
</Layer>
|
||||||
|
</Capability>
|
||||||
|
</WMT_MS_Capabilities>
|
|
@ -95,7 +95,7 @@ async def test_api_forecast():
|
||||||
client = IrcelineForecastClient(session)
|
client = IrcelineForecastClient(session)
|
||||||
|
|
||||||
features = [ForecastFeature.NO2_DMEAN, ForecastFeature.O3_MAXHMEAN]
|
features = [ForecastFeature.NO2_DMEAN, ForecastFeature.O3_MAXHMEAN]
|
||||||
_ = await client.get_data(features, pos)
|
result = await client.get_data(features, pos)
|
||||||
|
|
||||||
base = {"service": "WMS",
|
base = {"service": "WMS",
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
@ -119,6 +119,9 @@ async def test_api_forecast():
|
||||||
|
|
||||||
session.request.assert_has_calls(calls, any_order=True)
|
session.request.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
assert v['value'] == 10.853286743164062
|
||||||
|
|
||||||
|
|
||||||
def test_parse_capabilities_with_error():
|
def test_parse_capabilities_with_error():
|
||||||
result = IrcelineForecastClient._parse_capabilities("wow there no valid XML")
|
result = IrcelineForecastClient._parse_capabilities("wow there no valid XML")
|
||||||
|
|
|
@ -64,7 +64,7 @@ async def test_format_result_dmean():
|
||||||
|
|
||||||
|
|
||||||
def test_parse_capabilities():
|
def test_parse_capabilities():
|
||||||
data = get_api_data('capabilities.xml', plain=True)
|
data = get_api_data('rio_capabilities.xml', plain=True)
|
||||||
result = IrcelineRioClient._parse_capabilities(data)
|
result = IrcelineRioClient._parse_capabilities(data)
|
||||||
|
|
||||||
expected = {'rio:so2_anmean_be', 'rio:o3_hmean', 'rio:bc_anmean_vl', 'rio:o3_anmean_be', 'rio:pm10_hmean_vl',
|
expected = {'rio:so2_anmean_be', 'rio:o3_hmean', 'rio:bc_anmean_vl', 'rio:o3_anmean_be', 'rio:pm10_hmean_vl',
|
||||||
|
@ -117,7 +117,7 @@ async def test_api_rio():
|
||||||
|
|
||||||
|
|
||||||
async def test_api_rio_get_capabilities():
|
async def test_api_rio_get_capabilities():
|
||||||
session = get_mock_session(text_file='capabilities.xml')
|
session = get_mock_session(text_file='rio_capabilities.xml')
|
||||||
|
|
||||||
client = IrcelineRioClient(session)
|
client = IrcelineRioClient(session)
|
||||||
_ = await client.get_capabilities()
|
_ = await client.get_capabilities()
|
||||||
|
|
102
tests/test_api_rio_ifdm.py
Normal file
102
tests/test_api_rio_ifdm.py
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from unittest.mock import call
|
||||||
|
|
||||||
|
from freezegun import freeze_time
|
||||||
|
|
||||||
|
from src.open_irceline.api import _rio_ifdm_wms_base_url, _user_agent
|
||||||
|
from src.open_irceline.data import RioIfdmFeature, FeatureValue
|
||||||
|
from src.open_irceline.rio import IrcelineRioIfdmClient
|
||||||
|
from tests.conftest import get_api_data, get_mock_session
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_capabilities():
|
||||||
|
data = get_api_data('rio_ifdm_capabilities.xml', plain=True)
|
||||||
|
result = IrcelineRioIfdmClient._parse_capabilities(data)
|
||||||
|
|
||||||
|
expected = {'no2_dm3', 'belaqi_dm2', 'pm10_hmean', 'belaqi_dm1', 'pm25_dm3', 'pm25_dm2', 'pm10_dm1', 'o3_dm3',
|
||||||
|
'no2_dm1', 'pm10_dm3', 'pm25_dm1', 'belaqi', 'belaqi_dm3', 'pm10_dm2', 'o3_dm2', 'pm25_hmean', 'o3_dm1',
|
||||||
|
'o3_hmean', 'no2_dm2', 'no2_hmean'}
|
||||||
|
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
for f in RioIfdmFeature:
|
||||||
|
assert f"{f.split(':')[1]}" in result
|
||||||
|
|
||||||
|
|
||||||
|
async def test_aget_capabilities():
|
||||||
|
session = get_mock_session(text_file='rio_ifdm_capabilities.xml')
|
||||||
|
|
||||||
|
client = IrcelineRioIfdmClient(session)
|
||||||
|
_ = await client.get_capabilities()
|
||||||
|
|
||||||
|
session.request.assert_called_once_with(
|
||||||
|
method='GET',
|
||||||
|
url=_rio_ifdm_wms_base_url,
|
||||||
|
params={"service": "WMS",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"request": "GetCapabilities"},
|
||||||
|
headers={'User-Agent': _user_agent}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@freeze_time(datetime.fromisoformat("2024-06-30T13:00:21.520Z"))
|
||||||
|
async def test_api_forecast_error():
|
||||||
|
pos = (50.4657, 4.8647)
|
||||||
|
session = get_mock_session('forecast_wms_feature_info_invalid.json')
|
||||||
|
|
||||||
|
client = IrcelineRioIfdmClient(session)
|
||||||
|
|
||||||
|
features = [RioIfdmFeature.NO2_HMEAN, RioIfdmFeature.O3_HMEAN]
|
||||||
|
result = await client.get_data(features, pos)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
assert v == FeatureValue(timestamp=datetime.fromisoformat("2024-06-30T13:00:21.520Z"), value=None)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_api_forecast():
|
||||||
|
pos = (50.4657, 4.8647)
|
||||||
|
lat, lon = pos
|
||||||
|
session = get_mock_session('forecast_wms_feature_info.json')
|
||||||
|
|
||||||
|
client = IrcelineRioIfdmClient(session)
|
||||||
|
|
||||||
|
features = [RioIfdmFeature.NO2_HMEAN, RioIfdmFeature.O3_HMEAN]
|
||||||
|
result = await client.get_data(features, pos)
|
||||||
|
|
||||||
|
base = {"service": "WMS",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"request": "GetFeatureInfo",
|
||||||
|
"info_format": "application/json",
|
||||||
|
"width": "1",
|
||||||
|
"height": "1",
|
||||||
|
"srs": "EPSG:4326",
|
||||||
|
"bbox": f"{lon},{lat},{lon + 0.00001},{lat + 0.00001}",
|
||||||
|
"X": "1",
|
||||||
|
"Y": "1"}
|
||||||
|
|
||||||
|
calls = [call(
|
||||||
|
method='GET',
|
||||||
|
url=_rio_ifdm_wms_base_url,
|
||||||
|
params=base | {"layers": f"{feature}",
|
||||||
|
"query_layers": f"{feature}"},
|
||||||
|
headers={'User-Agent': _user_agent},
|
||||||
|
)
|
||||||
|
for feature in features]
|
||||||
|
|
||||||
|
session.request.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
assert v['value'] == 10.853286743164062
|
||||||
|
|
||||||
|
|
||||||
|
async def test_api_forecast_no_field():
|
||||||
|
pos = (50.4657, 4.8647)
|
||||||
|
session = get_mock_session('forecast_wms_feature_info_no_field.json')
|
||||||
|
|
||||||
|
client = IrcelineRioIfdmClient(session)
|
||||||
|
|
||||||
|
features = [RioIfdmFeature.NO2_HMEAN, RioIfdmFeature.O3_HMEAN]
|
||||||
|
result = await client.get_data(features, pos)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
assert v == FeatureValue(timestamp=None, value=None)
|
Loading…
Add table
Reference in a new issue