Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 48 additions & 13 deletions ckanext/dcat/profiles/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ def _add_agent_to_graph(self, subject_ref, predicate, agent_dict):
self.g.add((org_ref, FOAF.name, Literal(sub_org["name"])))

return agent_ref

def _add_contact_to_graph(self, subject, predicate, contact):
contact_uri = contact.get("uri")
if contact_uri:
Expand Down Expand Up @@ -1008,43 +1008,78 @@ def _add_contact_to_graph(self, subject, predicate, contact):
"url",
_type=URIRef,
)


def _add_spatial_value_to_graph(self, spatial_ref, predicate, value):
"""
Adds spatial triples to the graph. Assumes that value is a GeoJSON string
or object.
Adds spatial triples to the graph. Assumes that value is a WKT string or a
GeoJSON string or object.
"""
value_is_wkt = None
value_is_geojson = None

spatial_formats = aslist(
config.get("ckanext.dcat.output_spatial_format", DEFAULT_SPATIAL_FORMATS)
)

if isinstance(value, str):
try:
value = json.loads(value)
value = json.dumps(json.loads(value))
value_is_geojson = True
except (TypeError, ValueError):
return
try:
wkt.loads(value)
value_is_wkt = True
except ValueError:
return
elif isinstance(value, dict):
value = json.dumps(value)
value_is_geojson = True
else:
return

if "wkt" in spatial_formats:
# WKT, because GeoDCAT-AP says so
try:
if value_is_geojson:
# Transform geojson -> wkt
try:
wkt_value = wkt.dumps(json.loads(value), decimals=4)
except (TypeError, ValueError, InvalidGeoJSONException):
wkt_value = None
else:
wkt_value = value

if wkt_value:
self.g.add(
(
spatial_ref,
predicate,
Literal(
wkt.dumps(value, decimals=4),
wkt_value,
datatype=GSP.wktLiteral,
),
)
)
except (TypeError, ValueError, InvalidGeoJSONException):
pass

if "geojson" in spatial_formats:
# GeoJSON
self.g.add((spatial_ref, predicate, Literal(json.dumps(value), datatype=GEOJSON_IMT)))
if value_is_wkt:
# Transform wkt -> geojson
try:
geojson_value = json.dumps(wkt.loads(value))
except (TypeError, ValueError, InvalidGeoJSONException):
geojson_value = None
else:
geojson_value = value

if geojson_value:
self.g.add(
(
spatial_ref,
predicate,
Literal(
geojson_value,
datatype=GEOJSON_IMT
)
)
)

def _add_spatial_to_dict(self, dataset_dict, key, spatial):
if spatial.get(key):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,40 @@ def test_spatial(self):
wkt_cent = wkt.dumps(json.loads(extras['spatial_centroid']), decimals=4)
assert self._triple(g, spatial, DCAT.centroid, wkt_cent, GSP.wktLiteral)

def test_spatial_input_in_wkt(self):
dataset = {
'id': '4b6fe9ca-dc77-4cec-92a4-55c6624a5bd6',
'name': 'test-dataset',
'extras': [
{'key': 'spatial_uri', 'value': 'http://sws.geonames.org/6361390/'},
{'key': 'spatial_text', 'value': 'Tarragona'},
{'key': 'spatial', 'value': 'POLYGON ((1.1871 41.0786, 1.1871 41.1655, 1.3752 41.1655, 1.3752 41.0786, 1.1871 41.0786))'},
{'key': 'spatial_bbox', 'value': 'POLYGON ((1.1871 41.0786, 1.1871 41.1655, 1.3752 41.1655, 1.3752 41.0786, 1.1871 41.0786))'},
{'key': 'spatial_centroid', 'value': 'POINT (2.2811 42.122)'},

]
}
extras = self._extras(dataset)

s = RDFSerializer(profiles=DCAT_AP_PROFILES)
g = s.g

dataset_ref = s.graph_from_dataset(dataset)

spatial = self._triple(g, dataset_ref, DCT.spatial, None)[2]
assert spatial
assert str(spatial) == extras['spatial_uri']
assert self._triple(g, spatial, RDF.type, DCT.Location)
assert self._triple(g, spatial, SKOS.prefLabel, extras['spatial_text'])

assert len([t for t in g.triples((spatial, LOCN.geometry, None))]) == 1
assert len([t for t in g.triples((spatial, DCAT.bbox, None))]) == 1
assert len([t for t in g.triples((spatial, DCAT.centroid, None))]) == 1

assert self._triple(g, spatial, LOCN.geometry, extras['spatial'], GSP.wktLiteral)
assert self._triple(g, spatial, DCAT.bbox, extras['spatial_bbox'], GSP.wktLiteral)
assert self._triple(g, spatial, DCAT.centroid, extras['spatial_centroid'], GSP.wktLiteral)

@pytest.mark.ckan_config("ckanext.dcat.output_spatial_format", "geojson")
def test_spatial_geojson(self):
dataset = {
Expand Down