From 25e95443e50f224ab39b2fd5e664de0b8a402616 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 4 Jun 2024 14:56:59 +0200 Subject: [PATCH] Parse dcat:spatialResolutionInMeters as float According to the spec this should be typed as an xsd:Decimal, but we are parsing it as int: https://www.w3.org/TR/vocab-dcat-3/#Property:dataset_spatial_resolution --- ckanext/dcat/profiles/base.py | 20 ++++++++++++++++++- ckanext/dcat/profiles/euro_dcat_ap_2.py | 2 +- .../tests/test_euro_dcatap_2_profile_parse.py | 6 ++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ckanext/dcat/profiles/base.py b/ckanext/dcat/profiles/base.py index 4b652b91..80711b3f 100644 --- a/ckanext/dcat/profiles/base.py +++ b/ckanext/dcat/profiles/base.py @@ -230,7 +230,7 @@ def _object_value_int_list(self, subject, predicate): Both subject and predicate must be rdflib URIRef or BNode objects - If the value can not be parsed as intger, returns an empty list + If the value can not be parsed as integer, returns an empty list """ object_values = [] for object in self.g.objects(subject, predicate): @@ -241,6 +241,24 @@ def _object_value_int_list(self, subject, predicate): pass return object_values + def _object_value_float_list(self, subject, predicate): + """ + Given a subject and a predicate, returns the value of the object as a + list of floats + + Both subject and predicate must be rdflib URIRef or BNode objects + + If the value can not be parsed as a float, returns an empty list + """ + object_values = [] + for object in self.g.objects(subject, predicate): + if object: + try: + object_values.append(float(object)) + except ValueError: + pass + return object_values + def _object_value_list(self, subject, predicate): """ Given a subject and a predicate, returns a list with all the values of diff --git a/ckanext/dcat/profiles/euro_dcat_ap_2.py b/ckanext/dcat/profiles/euro_dcat_ap_2.py index 6f40e3ab..5e699303 100644 --- a/ckanext/dcat/profiles/euro_dcat_ap_2.py +++ b/ckanext/dcat/profiles/euro_dcat_ap_2.py @@ -54,7 +54,7 @@ def parse_dataset(self, dataset_dict, dataset_ref): self._add_spatial_to_dict(dataset_dict, key, spatial) # Spatial resolution in meters - spatial_resolution_in_meters = self._object_value_int_list( + spatial_resolution_in_meters = self._object_value_float_list( dataset_ref, DCAT.spatialResolutionInMeters ) if spatial_resolution_in_meters: diff --git a/ckanext/dcat/tests/test_euro_dcatap_2_profile_parse.py b/ckanext/dcat/tests/test_euro_dcatap_2_profile_parse.py index eb964824..69ffe7d1 100644 --- a/ckanext/dcat/tests/test_euro_dcatap_2_profile_parse.py +++ b/ckanext/dcat/tests/test_euro_dcatap_2_profile_parse.py @@ -353,7 +353,7 @@ def test_spatial_resolution_in_meters_multiple(self): dataset = URIRef('http://example.org/datasets/1') g.add((dataset, RDF.type, DCAT.Dataset)) - spatial_resolution_in_meters = 30 + spatial_resolution_in_meters = 30.5 g.add((dataset, DCAT.spatialResolutionInMeters, Literal(spatial_resolution_in_meters, datatype=XSD.decimal))) spatial_resolution_in_meters_2 = 20 @@ -368,9 +368,7 @@ def test_spatial_resolution_in_meters_multiple(self): extras = self._extras(datasets[0]) spatial_resolution_list = json.loads(extras['spatial_resolution_in_meters']) - assert len(spatial_resolution_list) == 2 - assert spatial_resolution_in_meters in spatial_resolution_list - assert spatial_resolution_in_meters_2 in spatial_resolution_list + assert sorted(spatial_resolution_list) == [20.0, 30.5] def test_isreferencedby_multiple(self): g = Graph()