lucernae/glofas-api-helper

Error fetching layer

Closed this issue · 6 comments

Hi!

I am able to install and import the glofas-api-helper. However, I had problems with fetching the data.

I tried with my own polygong and point (geojson format) and I am getting an error at api.get_feature_info()

feature_info = api.get_feature_info(point_layer)

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
<ipython-input-48-4c1bd0bb3711> in <module>
      1 # Automatically means fetch today's forecast, unless you specify the time slice
      2 #api.time = datetime(year=2020, month=1, day=1)
----> 3 feature_info = api.get_feature_info(point_layer)
      4 # feature info is a list of forecast information for each point layer
      5 feature_info

~/GEO/floods_DS/glofas-api-helper/glofas/layer/reporting_point.py in get_feature_info(self, point_location_layer, srs)
    119                 time=self.time.isoformat()
    120             )
--> 121             result = json.loads(response.read())
    122             reporting_point_result = ReportingPointResult(
    123                 self.time,

~/miniconda2/envs/adamf/lib/python3.7/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    346             parse_int is None and parse_float is None and
    347             parse_constant is None and object_pairs_hook is None and not kw):
--> 348         return _default_decoder.decode(s)
    349     if cls is None:
    350         cls = JSONDecoder

~/miniconda2/envs/adamf/lib/python3.7/json/decoder.py in decode(self, s, _w)
    335 
    336         """
--> 337         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338         end = _w(s, end).end()
    339         if end != len(s):

~/miniconda2/envs/adamf/lib/python3.7/json/decoder.py in raw_decode(self, s, idx)
    353             obj, end = self.scan_once(s, idx)
    354         except StopIteration as err:
--> 355             raise JSONDecodeError("Expecting value", s, err.value) from None
    356         return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

My full snippet:

from glofas.layer.reporting_point import ReportingPointAPI, ReportingPointResult
from osgeo import gdal
from datetime import date, datetime, timedelta

api = ReportingPointAPI()
data_source = gdal.OpenEx('/Users/michael/GEO/floods_DS/test_malawi2.geojson')
#print(data_source)
point_layer = data_source.GetLayer()
print(point_layer)

# Automatically means fetch today's forecast, unless you specify the time slice
#api.time = datetime(year=2020, month=1, day=1)
feature_info = api.get_feature_info(point_layer)
# feature info is a list of forecast information for each point layer
# I GET THE ERROR HERE

reporting_point_result = feature_info[0]
# This is an instance of ReportingPointResult

# Query the information easily
reporting_point_result.station_name
reporting_point_result.country
reporting_point_result.basin
reporting_point_result.coord.lon
reporting_point_result.coord.lat

# forecast array for the following 30 days (EPS max probability of exceeding threshold)

# forecast for Severe alert
reporting_point_result.eps_array(ReportingPointResult.ALERT_LEVEL_SEVERE)

Thanks!

Michael

Ok. Not sure what the error is without proper traceback.
Make sure the point layer and get_feature_info uses the same SRID.
I think the options were restricted by GLOFAS WMS get feature info itself.
Use 4326. Reproject or make sure your geojson point_layer uses 4326
Then set the srid like this:

feature_info = api.get_feature_info(point_layer, srs='EPSG:4326')

My layer's crs is already set to 4326. I also tried with the ones shown above, I still got the exact same error.

Thanks!

I forgot to mention, point layer datasource must contains Point Geometries for the reporting layer you wish to fetch.
If you go to GLOFAS Web Map Viewer, you can click a reporting point (enable the reporting point layer first), then it will show you exact EPSG:4326 coordinate of the reporting point.

This is the result of above snippet. I picked a reporting point in Malawi for example.

>>> from glofas.layer.reporting_point import ReportingPointAPI, ReportingPointResult
>>> from osgeo import gdal
>>> from datetime import date, datetime, timedelta
>>> api = ReportingPointAPI()
>>> data_source = gdal.OpenEx('reporting_point_malawi.geojson')
>>> #print(data_source)
... point_layer = data_source.GetLayer()
>>> print(point_layer)
<osgeo.ogr.Layer; proxy of <Swig Object of type 'OGRLayerShadow *' at 0x113fbf630> >
>>> 
>>> # Automatically means fetch today's forecast, unless you specify the time slice
... #api.time = datetime(year=2020, month=1, day=1)
... feature_info = api.get_feature_info(point_layer, srs='EPSG:4326')
>>> # feature info is a list of forecast information for each point layer
... # I GET THE ERROR HERE
... 
>>> reporting_point_result = feature_info[0]
>>> # This is an instance of ReportingPointResult
... 
>>> # Query the information easily
... reporting_point_result.station_name
'S53 Roadbridge 65312601'
>>> reporting_point_result.country
'Malawi'
>>> reporting_point_result.basin
'Zambezi'
>>> reporting_point_result.coord.lon
34.15
>>> reporting_point_result.coord.lat
-12.85
>>> 
>>> # forecast array for the following 30 days (EPS max probability of exceeding threshold)
... 
>>> # forecast for Severe alert
... reporting_point_result.eps_array(ReportingPointResult.ALERT_LEVEL_SEVERE)
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0]

These are the geojson reportin point layer file for reference:

reporting_point_malawi.geojson.zip

If we want to be more specific to see what the error is, you could catch the exception, and see what is the payload that is causing the error like this:

import json
try:
    feature_info = api.get_feature_info(point_layer, srs='EPSG:4326')
except JSONDecodeError as e:
    print(e.doc)

e.doc will show you the original text to parse, which is the response of GLOFAS API itself.

Oh, it is fixed now! All this time, I thought the idea from my own POI, it will find the nearest GLOFAS reporting point with alert_level_severe. Now I understand. It works now :)

Thank you!

Glad to hear it @mgmanalili .

For some extra explanations:
This library is just to wrap the WMS GetFeatureInfo result returned by GLOFAS, because originally it was returned as HTML frame, so not easily parseable. It does tries to find nearest reporting point but I fixed the search area using WMS spec. In practice you should handle the reporting point search by yourself to not burden GLOFAS API, and only query the needed exact location to this API endpoint.