-
Notifications
You must be signed in to change notification settings - Fork 4
/
generate_graph.py
128 lines (100 loc) · 5.4 KB
/
generate_graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# -*- coding: utf-8 -*-
from argparse import ArgumentParser
from os.path import basename
from datetime import datetime
from json import loads
from baselutils import fclrprint
from rdflib import Graph, URIRef, Literal, XSD, Namespace, RDF
LMG = Namespace('https://linked-maps.isi.edu/resource/')
GEO = Namespace('http://www.opengis.net/ont/geosparql#')
PROV = Namespace('http://www.w3.org/ns/prov#')
DCTERMS = Namespace('http://purl.org/dc/terms/')
class LinkedMapGraph:
''' A graph holding the nodes and relations of the pre-processed maps. '''
def __init__(self, json_file_name):
''' Init the linked map graph and read the WKT literals file,
and map each gid to its WKT literal. '''
self.dt = Graph()
self.dt.bind('lmg', LMG)
self.dt.bind('geo', GEO)
self.dt.bind('prov', PROV)
self.dt.bind('dcterms', DCTERMS)
self.gid2wkt = dict()
with open(json_file_name, "r") as read_file:
for line_r in read_file:
gid_wkt_entry = loads(line_r)
self.gid2wkt[gid_wkt_entry['gid']] = gid_wkt_entry['wkt']
def add_geo_feature_node(self, segment_gid, segment_name, segment_years):
''' Add a segment to the graph '''
# geo:Feature
seg_feat_uri = URIRef(LMG[str(segment_gid)])
self.dt.add((seg_feat_uri, RDF.type, GEO['Feature']))
# geo:Geometry
seg_geo_uri = URIRef(LMG[str(segment_gid) + '_sc_' + segment_name.lower()])
self.dt.add((seg_geo_uri, RDF.type, GEO['Geometry']))
# geo:Feature --geo:hasGeometry--> geo:Geometry
self.dt.add((seg_feat_uri, GEO['hasGeometry'], seg_geo_uri))
# --dcterms:created--> LITERAL^^xsd:dateTime
d_now = datetime.today()
self.dt.add((seg_feat_uri, DCTERMS['created'], Literal(d_now.isoformat(), datatype=XSD.dateTime)))
# --dcterms:date--> LITERAL^^xsd:dateTime
for seg_yr in segment_years:
seg_yr_dt_obj = datetime.strptime(str(seg_yr), '%Y')
self.dt.add((seg_feat_uri, DCTERMS['date'], Literal(seg_yr_dt_obj.isoformat(), datatype=XSD.dateTime)))
# --geo:asWKT--> "<http://www.opengis.net/def/crs/OGC/1.3/CRS84> LITERAL"^^geo:wktLiteral
# TODO: add CRS84 prefix
self.dt.add((seg_geo_uri, GEO['asWKT'], Literal(self.gid2wkt[segment_gid], datatype=GEO['wktLiteral'])))
# TODO: add provenance information
# --prov:wasGeneratedBy--> prov:Activity
# --prov:wasAssociatedWith--> foaf:Organization, prov:Agent
# TODO: add Positional Accuracy (buff)
def add_geo_child_to_parent(self, parent_geo_feat_id, child_geo_feat_id):
''' Link a child segment to its parent segment. '''
parent_geo_feat_uri = URIRef(LMG[str(parent_geo_feat_id)])
child_geo_feat_uri = URIRef(LMG[str(child_geo_feat_id)])
self.dt.add((parent_geo_feat_uri, GEO['sfContains'], child_geo_feat_uri))
self.dt.add((child_geo_feat_uri, GEO['sfWithin'], parent_geo_feat_uri))
# add dates of parent to its child
for date in self.dt.objects(parent_geo_feat_uri, DCTERMS['date']):
self.dt.add((child_geo_feat_uri, DCTERMS['date'], date))
def add_openstreetmap_uris_to_gid(self, geo_feat_id, list_of_osm_uris):
''' Link segment to additional OpenStreetMap URIs. '''
geo_feat_uri = URIRef(LMG[str(geo_feat_id)])
for osm_uri in list_of_osm_uris:
self.dt.add((geo_feat_uri, GEO['sfOverlaps'], URIRef(osm_uri)))
def main():
ap = ArgumentParser(description='Process line segmetation output files (jl) and generate (ttl) file containing triples.\n\tUSAGE: python %s -g GEOMETRY_FILE -s SEGMENTS_FILE -r RELATIONS_FILE -l OSM_URIS_FILE' % (basename(__file__)))
ap.add_argument('-g', '--geometry_file', help='File (jl) holding the geometry info (wkt).', type=str)
ap.add_argument('-s', '--segments_file', help='File (jl) holding segments info (metadata).', type=str)
ap.add_argument('-r', '--relations_file', help='File (jl) holding relations info (parents, children).', type=str)
ap.add_argument('-l', '--osm_uris_file', help='File (jl) holding OpenStreetMap info.', type=str)
ap.add_argument('-o', '--output_file', help='The output file (ttl) with the generated triples.', default='linked_maps.maps.ttl', type=str)
args = ap.parse_args()
if args.geometry_file and args.relations_file and args.segments_file:
fclrprint('Going to process files %s, %s, %s...' % (args.geometry_file, args.segments_file, args.relations_file))
# initialize graph with gid-to-wkt mapping file
lm_graph = LinkedMapGraph(args.geometry_file)
# load segments info
with open(args.segments_file) as read_file:
for line_r in read_file:
seg_dict = loads(line_r)
lm_graph.add_geo_feature_node(seg_dict['gid'], seg_dict['name'], seg_dict['years'])
# load relations info
with open(args.relations_file) as read_file:
for line_r in read_file:
rel_dict = loads(line_r)
lm_graph.add_geo_child_to_parent(rel_dict['parent_gid'], rel_dict['child_gid'])
# load OpenStreetMap info
if args.osm_uris_file:
with open(args.osm_uris_file) as read_file:
for line_r in read_file:
osm_dict = loads(line_r)
lm_graph.add_openstreetmap_uris_to_gid(osm_dict['gid'], osm_dict['osm_uris'])
# materialize triples
lm_graph.dt.serialize(args.output_file, format="turtle")
fclrprint('Done, generated ttl file %s!' % (args.output_file), 'g')
else:
fclrprint('Geometry, segments and relations files were not provided.', 'r')
exit(1)
if __name__ == '__main__':
main()