geomash 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,673 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Geomash
3
+ class TGN
4
+
5
+ def self.tgn_enabled
6
+ Geomash.config[:tgn_enabled] || true
7
+ end
8
+
9
+ =begin
10
+ 81010/nation
11
+ 81175/state
12
+ 81165/region
13
+ 84251/neighborhood
14
+ 83002/inhabited place
15
+
16
+ nations
17
+ <http://vocab.getty.edu/tgn/7012149> <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300128207>
18
+
19
+ States (political divisions):
20
+ <http://vocab.getty.edu/tgn/7007517> <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000776> .
21
+
22
+ Counties: (Suffolk - http://vocab.getty.edu/aat/300000771)
23
+ <http://vocab.getty.edu/tgn/1002923> <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000771> .
24
+
25
+ Neighborhood: (Boston)
26
+ <http://vocab.getty.edu/tgn/7013445> <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347> .
27
+
28
+
29
+ Provinces:
30
+ http://vocab.getty.edu/aat/300000774
31
+
32
+ Departments:
33
+ http://vocab.getty.edu/aat/300000772
34
+
35
+ Governates:
36
+ http://vocab.getty.edu/aat/300235093
37
+
38
+ Territories:
39
+ http://vocab.getty.edu/aat/300135982
40
+
41
+ + http://vocab.getty.edu/resource/getty/search?q=territory&luceneIndex=Brief&indexDataset=AAT&_form=%2Fresource%2Fgetty%2Fsearch
42
+
43
+ dependent state:
44
+ http://vocab.getty.edu/aat/300387176
45
+
46
+
47
+ union territory:
48
+ http://vocab.getty.edu/aat/300387122
49
+
50
+ national district:
51
+ http://vocab.getty.edu/aat/300387081
52
+
53
+
54
+ Roxbury:
55
+ http://vocab.getty.edu/tgn/7015002.json
56
+
57
+
58
+
59
+ #South Carolina - http://vocab.getty.edu/tgn/7007712
60
+
61
+ SELECT ?object_identifier
62
+ WHERE
63
+ {
64
+ ?x <http://purl.org/dc/elements/1.1/identifier> 7007712 .
65
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_country .
66
+ {
67
+ SELECT ?parent_country ?identifier_country ?aat_place_id
68
+ WHERE {
69
+ ?parent_country <http://purl.org/dc/elements/1.1/identifier> ?identifier_country .
70
+ ?parent_country <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_place_id .
71
+ ?parent_country <http://www.w3.org/2000/01/rdf-schema#label> ?country_label .
72
+ }
73
+ GROUP BY ?parent_country
74
+ }
75
+ }
76
+ GROUP BY ?object_identifier
77
+
78
+ primary_tgn_response = Typhoeus::Request.get("http://vocab.getty.edu/tgn/#{tgn_id}.json")
79
+
80
+
81
+ when 'http://vocab.getty.edu/ontology#placeTypePreferred'
82
+ place_type_base[:aat_id] = ntriple['Object']['value']
83
+ when 'http://www.w3.org/2004/02/skos/core#prefLabel'
84
+ if ntriple['Object']['xml:lang'].present? && ntriple['Object']['xml:lang'] == 'en'
85
+ place_type_base[:label_en] = ntriple['Object']['value']
86
+ else if ntriple['Object']['xml:lang'].blank?
87
+ place_type_base[:label_default] = ntriple['Object']['value']
88
+
89
+
90
+ tgn_main_term_info = {}
91
+ broader_place_type_list = ["http://vocab.getty.edu/tgn/"#{tgn_id}]
92
+
93
+ primary_tgn_response = Typhoeus::Request.get("http://vocab.getty.edu/download/json", :params=>{:uri=>"http://vocab.getty.edu/tgn/#{tgn_id}.json"})
94
+ as_json_tgn_response = JSON.parse(primary_tgn_response.body)
95
+
96
+ as_json_tgn_response['results']['bindings'].each do |ntriple|
97
+ case ntriple['Predicate']['value']
98
+ when 'http://www.w3.org/2004/02/skos/core#prefLabel'
99
+ if ntriple['Object']['xml:lang'].present? && ntriple['Object']['xml:lang'] == 'en'
100
+ tgn_main_term_info[:label_en] = ntriple['Object']['value']
101
+ elsif ntriple['Object']['xml:lang'].blank?
102
+ tgn_main_term_info[:label_default] = ntriple['Object']['value']
103
+ end
104
+ when 'http://vocab.getty.edu/ontology#placeTypePreferred'
105
+ tgn_main_term_info[:aat_place] = ntriple['Object']['value']
106
+ when 'http://vocab.getty.edu/ontology#broaderPreferredExtended'
107
+ broader_place_type_list << ntriple['Object']['value']
108
+ end
109
+
110
+ end
111
+
112
+ query = "SELECT ?identifier_place ?place_label_default ?place_label_en ?aat_pref WHERE {"
113
+
114
+ broader_place_type_list.each do |place_uri|
115
+ query += %{{<#{place_uri}> <http://purl.org/dc/elements/1.1/identifier> ?identifier_place .
116
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_en
117
+ FILTER langMatches( lang(?place_label_en), "en" )
118
+ }
119
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_default
120
+ FILTER langMatches( lang(?place_label_default), "" )
121
+ }
122
+ <#{place_uri}> <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_pref
123
+ } UNION
124
+ }
125
+ end
126
+
127
+ query = query[0..-12]
128
+ query += ". } GROUP BY ?identifier_place ?place_label_default ?place_label_en ?aat_pref"
129
+
130
+ tgn_response_for_aat = Typhoeus::Request.get("http://vocab.getty.edu/sparql.json", :params=>{:query=>query})
131
+ as_json_tgn_response_for_aat = JSON.parse(tgn_response_for_aat.body)
132
+
133
+ as_json_tgn_response_for_aat["results"]["bindings"].each do |aat_response|
134
+ #aat_response['identifier_place']['value']
135
+ #aat_response['place_label_default']['value']
136
+ #....
137
+ end
138
+
139
+
140
+
141
+
142
+
143
+ EXAMPLE SPARQL:
144
+
145
+ SELECT ?identifier_place ?place_label_default ?place_label_en ?aat_pref
146
+ WHERE {
147
+ {<http://vocab.getty.edu/tgn/1000001> <http://purl.org/dc/elements/1.1/identifier> ?identifier_place .
148
+ OPTIONAL {<http://vocab.getty.edu/tgn/1000001> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_en
149
+ FILTER langMatches( lang(?place_label_en), "en" )
150
+ }
151
+ OPTIONAL {<http://vocab.getty.edu/tgn/1000001> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_default
152
+ FILTER langMatches( lang(?place_label_default), "" )
153
+ }
154
+ <http://vocab.getty.edu/tgn/1000001> <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_pref
155
+ } UNION
156
+ {<http://vocab.getty.edu/tgn/7012149> <http://purl.org/dc/elements/1.1/identifier> ?identifier_place .
157
+ OPTIONAL {<http://vocab.getty.edu/tgn/7012149> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_en
158
+ FILTER langMatches( lang(?place_label_en), "en" )
159
+ }
160
+ OPTIONAL {<http://vocab.getty.edu/tgn/7012149> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_default
161
+ FILTER langMatches( lang(?place_label_default), "" )
162
+ }
163
+ <http://vocab.getty.edu/tgn/7012149> <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_pref
164
+ } UNION
165
+ {<http://vocab.getty.edu/tgn/7029392> <http://purl.org/dc/elements/1.1/identifier> ?identifier_place .
166
+ OPTIONAL {<http://vocab.getty.edu/tgn/7029392> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_en
167
+ FILTER langMatches( lang(?place_label_en), "en" )
168
+ }
169
+ OPTIONAL {<http://vocab.getty.edu/tgn/7029392> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_default
170
+ FILTER langMatches( lang(?place_label_default), "" )
171
+ }
172
+ <http://vocab.getty.edu/tgn/7012149> <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_pref
173
+ } .
174
+
175
+
176
+ }
177
+ GROUP BY ?identifier_place ?place_label_default ?place_label_en ?aat_pref
178
+
179
+
180
+
181
+
182
+ =end
183
+
184
+ def self.get_tgn_data(tgn_id)
185
+ return nil if Geomash::TGN.tgn_enabled != true
186
+
187
+ tgn_id = tgn_id.strip
188
+
189
+ tgn_main_term_info = {}
190
+ broader_place_type_list = []
191
+
192
+ primary_tgn_response = Typhoeus::Request.get("http://vocab.getty.edu/download/json", :params=>{:uri=>"http://vocab.getty.edu/tgn/#{tgn_id}.json"})
193
+
194
+ return nil if(primary_tgn_response.response_code == 404) #Couldn't find TGN... FIXME: additional check needed if TGN is down?
195
+
196
+ as_json_tgn_response = JSON.parse(primary_tgn_response.body)
197
+
198
+ #There is a bug with some TGN JSON files currently. Example: http://vocab.getty.edu/tgn/7014203.json . Per an email
199
+ # with Getty, this is a hackish workaround for now.
200
+ if(as_json_tgn_response['results'].blank?)
201
+ query = %{
202
+ PREFIX tgn: <http://vocab.getty.edu/tgn/>
203
+ PREFIX gvp: <http://vocab.getty.edu/ontology#>
204
+ PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
205
+ PREFIX dct: <http://purl.org/dc/terms/>
206
+ PREFIX bibo: <http://purl.org/ontology/bibo/>
207
+ PREFIX skosxl: <http://www.w3.org/2008/05/skos-xl#>
208
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
209
+ PREFIX iso: <http://purl.org/iso25964/skos-thes#>
210
+ PREFIX foaf: <http://xmlns.com/foaf/0.1/>
211
+ PREFIX schema: <http://schema.org/>
212
+ CONSTRUCT {
213
+ ?s ?p1 ?o1.
214
+ ?ac ?p2 ?o2.
215
+ ?t ?p3 ?o3.
216
+ ?ss ?p4 ?o4.
217
+ ?ts ?p6 ?o6.
218
+ ?st ?p7 ?o7.
219
+ ?ar ?p8 ?o8.
220
+ ?l1 ?p9 ?o9.
221
+ ?l2 ?pA ?oA.
222
+ ?pl ?pB ?oB.
223
+ ?ge ?pC ?oC.
224
+ } WHERE {
225
+ BIND (tgn:#{tgn_id} as ?s)
226
+ {?s ?p1 ?o1 FILTER(!isBlank(?o1) &&
227
+ !(?p1 in (gvp:narrowerExtended, skos:narrowerTransitive, skos:semanticRelation)))}
228
+ UNION {?s skos:changeNote ?ac. ?ac ?p2 ?o2}
229
+ UNION {?s dct:source ?ss. ?ss a bibo:DocumentPart. ?ss ?p4 ?o4}
230
+ UNION {?s skos:scopeNote|skosxl:prefLabel|skosxl:altLabel ?t.
231
+ {?t ?p3 ?o3 FILTER(!isBlank(?o3))}
232
+ UNION {?t dct:source ?ts. ?ts a bibo:DocumentPart. ?ts ?p6 ?o6}}
233
+ UNION {?st rdf:subject ?s. ?st ?p7 ?o7}
234
+ UNION {?s skos:member/^rdf:first ?l1. ?l1 ?p9 ?o9}
235
+ UNION {?s iso:subordinateArray ?ar FILTER NOT EXISTS {?ar skosxl:prefLabel ?t1}.
236
+ {?ar ?p8 ?o8}
237
+ UNION {?ar skos:member/^rdf:first ?l2. ?l2 ?pA ?oA}}
238
+ UNION {?s foaf:focus ?pl.
239
+ {?pl ?pB ?oB}
240
+ UNION {?pl schema:geo ?ge. ?ge ?pC ?oC}}
241
+ }
242
+ }
243
+
244
+ query = query.squish
245
+
246
+ primary_tgn_response = Typhoeus::Request.post("http://vocab.getty.edu/sparql.json", :body=>{:query=>query})
247
+ as_json_tgn_response = JSON.parse(primary_tgn_response.body)
248
+ end
249
+
250
+ #FIXME: Temporary hack to determine more cases of non-blank/english place name conflicts that require resolution.
251
+ label_remaining_check = false
252
+
253
+ as_json_tgn_response['results']['bindings'].each do |ntriple|
254
+ case ntriple['Predicate']['value']
255
+ when 'http://www.w3.org/2004/02/skos/core#prefLabel'
256
+ if ntriple['Object']['xml:lang'].present? && ntriple['Object']['xml:lang'] == 'en'
257
+ tgn_main_term_info[:label_en] = ntriple['Object']['value']
258
+ elsif ntriple['Object']['xml:lang'].present? && ntriple['Object']['xml:lang'] == 'zh-latn-pinyin'
259
+ tgn_main_term_info[:label_other] = ntriple['Object']['value']
260
+ elsif ntriple['Object']['xml:lang'].blank?
261
+ tgn_main_term_info[:label_default] = ntriple['Object']['value']
262
+ else
263
+ label_remaining_check = true if tgn_main_term_info[:label_remaining].present?
264
+ tgn_main_term_info[:label_remaining] = ntriple['Object']['value']
265
+ end
266
+ when 'http://www.w3.org/2004/02/skos/core#altLabel'
267
+ if ntriple['Object']['xml:lang'].present? && ntriple['Object']['xml:lang'] == 'en'
268
+ tgn_main_term_info[:label_alt] = ntriple['Object']['value']
269
+ end
270
+ when 'http://vocab.getty.edu/ontology#placeTypePreferred'
271
+ tgn_main_term_info[:aat_place] = ntriple['Object']['value']
272
+ when 'http://schema.org/latitude'
273
+ tgn_main_term_info[:latitude] = ntriple['Object']['value']
274
+ when 'http://schema.org/longitude'
275
+ tgn_main_term_info[:longitude] = ntriple['Object']['value']
276
+ when 'http://vocab.getty.edu/ontology#broaderPreferredExtended'
277
+ broader_place_type_list << ntriple['Object']['value']
278
+ end
279
+
280
+ end
281
+
282
+ # coordinates
283
+ coords = nil
284
+ if tgn_main_term_info[:latitude].present?
285
+ coords = {}
286
+ coords[:latitude] = tgn_main_term_info[:latitude]
287
+ coords[:longitude] = tgn_main_term_info[:longitude]
288
+ coords[:combined] = tgn_main_term_info[:latitude] + ',' + tgn_main_term_info[:longitude]
289
+ end
290
+
291
+ hier_geo = {}
292
+ #Default term to best label language...
293
+ tgn_term = tgn_main_term_info[:label_en]
294
+ tgn_term ||= tgn_main_term_info[:label_default]
295
+ tgn_term ||= tgn_main_term_info[:label_other]
296
+ tgn_term ||= tgn_main_term_info[:label_alt]
297
+ if tgn_term.blank?
298
+ if label_remaining_check
299
+ raise "Could not determine a single label for TGN: " + tgn_id
300
+ else
301
+ tgn_term = tgn_main_term_info[:label_remaining]
302
+ end
303
+ end
304
+
305
+ tgn_term_type = tgn_main_term_info[:aat_place].split('/').last
306
+
307
+ #Initial Term
308
+ if tgn_term.present? && tgn_term_type.present?
309
+ case tgn_term_type
310
+ when '300128176' #continent
311
+ hier_geo[:continent] = tgn_term
312
+ when '300128207' #nations
313
+ hier_geo[:country] = tgn_term
314
+ when '300000774' #province
315
+ hier_geo[:province] = tgn_term
316
+ when '300236112', '300182722', '300387194', '300387052' #region, union, semi-independent political entity
317
+ hier_geo[:region] = tgn_term
318
+ when '300000776', '300000772', '300235093' #state, department, governorate
319
+ hier_geo[:state] = tgn_term
320
+ when '300387081' #national district
321
+ if tgn_term == 'District of Columbia'
322
+ hier_geo[:state] = tgn_term
323
+ else
324
+ hier_geo[:territory] = tgn_term
325
+ end
326
+ when '300135982', '300387176', '300387122' #territory, dependent state, union territory
327
+ hier_geo[:territory] = tgn_term
328
+ when '300000771' #county
329
+ hier_geo[:county] = tgn_term
330
+ when '300008347' #inhabited place
331
+ hier_geo[:city] = tgn_term
332
+ when '300000745' #neighborhood
333
+ hier_geo[:city_section] = tgn_term
334
+ when '300008791', '300387062' #island
335
+ hier_geo[:island] = tgn_term
336
+ when '300387575', '300387346', '300167671', '300387178', '300387082' #'81101/area', '22101/general region', '83210/deserted settlement', '81501/historical region', '81126/national division'
337
+ hier_geo[:area] = tgn_term
338
+ else
339
+ non_hier_geo = tgn_term
340
+ end
341
+
342
+ #Broader places
343
+ #FIXME: could parse xml:lang instead of the three optional clauses now... didn't expect places to lack a default preferred label.
344
+
345
+ query = "SELECT ?identifier_place ?place_label_default ?place_label_en ?place_label_remaining ?aat_pref WHERE {"
346
+
347
+ broader_place_type_list.each do |place_uri|
348
+ query += %{{<#{place_uri}> <http://purl.org/dc/elements/1.1/identifier> ?identifier_place .
349
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_en
350
+ FILTER langMatches( lang(?place_label_en), "en" )
351
+ }
352
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_default
353
+ FILTER langMatches( lang(?place_label_default), "" )
354
+ }
355
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_latn_pinyin
356
+ FILTER langMatches( lang(?place_label_latn_pinyin), "zh-latn-pinyin" )
357
+ }
358
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#altLabel> ?place_label_alt
359
+ FILTER langMatches( lang(?place_label_alt), "en" )
360
+ }
361
+ OPTIONAL {<#{place_uri}> <http://www.w3.org/2004/02/skos/core#prefLabel> ?place_label_remaining
362
+ FILTER(!langMatches( lang(?place_label_remaining), "" ) && !langMatches( lang(?place_label_remaining), "en" ) && !langMatches( lang(?place_label_remaining), "zh-latn-pinyin" ))
363
+ }
364
+ <#{place_uri}> <http://vocab.getty.edu/ontology#placeTypePreferred> ?aat_pref
365
+ } UNION
366
+ }
367
+ end
368
+
369
+ query = query[0..-12]
370
+ query += ". } GROUP BY ?identifier_place ?place_label_default ?place_label_en ?place_label_latn_pinyin ?place_label_alt ?place_label_remaining ?aat_pref"
371
+ query = query.squish
372
+
373
+ tgn_response_for_aat = Typhoeus::Request.post("http://vocab.getty.edu/sparql.json", :body=>{:query=>query})
374
+ as_json_tgn_response_for_aat = JSON.parse(tgn_response_for_aat.body)
375
+
376
+ as_json_tgn_response_for_aat["results"]["bindings"].each do |aat_response|
377
+ tgn_term_type = aat_response['aat_pref']['value'].split('/').last
378
+
379
+ if aat_response['place_label_en'].present? && aat_response['place_label_en']['value'] != '-'
380
+ tgn_term = aat_response['place_label_en']['value']
381
+ elsif aat_response['place_label_default'].present? && aat_response['place_label_default']['value'] != '-'
382
+ tgn_term = aat_response['place_label_default']['value']
383
+ elsif aat_response['place_label_latn_pinyin'].present? && aat_response['place_label_latn_pinyin']['value'] != '-'
384
+ tgn_term = aat_response['place_label_latn_pinyin']['value']
385
+ elsif aat_response['place_label_alt'].present? && aat_response['place_label_alt']['value'] != '-'
386
+ tgn_term = aat_response['place_label_alt']['value']
387
+ else
388
+ tgn_term = aat_response['place_label_remaining']['value']
389
+ end
390
+
391
+ case tgn_term_type
392
+ when '300128176' #continent
393
+ hier_geo[:continent] = tgn_term
394
+ when '300128207' #nation
395
+ hier_geo[:country] = tgn_term
396
+ when '300000774' #province
397
+ hier_geo[:province] = tgn_term
398
+ when '300236112', '300182722', '300387194', '300387052' #region, union, semi-independent political entity
399
+ hier_geo[:region] = tgn_term
400
+ when '300000776', '300000772', '300235093' #state, department, governorate
401
+ hier_geo[:state] = tgn_term
402
+ when '300387081' #national district
403
+ if tgn_term == 'District of Columbia'
404
+ hier_geo[:state] = tgn_term
405
+ else
406
+ hier_geo[:territory] = tgn_term
407
+ end
408
+ when '300135982', '300387176', '300387122' #territory, dependent state, union territory
409
+ hier_geo[:territory] = tgn_term
410
+ when '300000771' #county
411
+ hier_geo[:county] = tgn_term
412
+ when '300008347' #inhabited place
413
+ hier_geo[:city] = tgn_term
414
+ when '300000745' #neighborhood
415
+ hier_geo[:city_section] = tgn_term
416
+ when '300008791', '300387062' #island
417
+ hier_geo[:island] = tgn_term
418
+ when '300387575', '300387346', '300167671', '300387178', '300387082' #'81101/area', '22101/general region', '83210/deserted settlement', '81501/historical region', '81126/national division'
419
+ hier_geo[:area] = tgn_term
420
+ end
421
+ end
422
+
423
+ tgn_data = {}
424
+ tgn_data[:coords] = coords
425
+ tgn_data[:hier_geo] = hier_geo.length > 0 ? hier_geo : nil
426
+ tgn_data[:non_hier_geo] = non_hier_geo ? non_hier_geo : nil
427
+
428
+ else
429
+
430
+ tgn_data = nil
431
+
432
+ end
433
+
434
+ return tgn_data
435
+
436
+ end
437
+
438
+
439
+ def self.tgn_id_from_geo_hash(geo_hash)
440
+ return nil if Geomash::TGN.tgn_enabled != true
441
+
442
+ geo_hash = geo_hash.clone
443
+
444
+ max_retry = 3
445
+ sleep_time = 60 # In seconds
446
+ retry_count = 0
447
+
448
+ return_hash = {}
449
+
450
+ state_part = geo_hash[:state_part]
451
+
452
+ country_code = Geomash::Constants::COUNTRY_TGN_LOOKUP[geo_hash[:country_part]][:tgn_id] unless Geomash::Constants::COUNTRY_TGN_LOOKUP[geo_hash[:country_part]].blank?
453
+ country_code ||= ''
454
+
455
+
456
+ country_part = Geomash::Constants::COUNTRY_TGN_LOOKUP[geo_hash[:country_part]][:tgn_country_name] unless Geomash::Constants::COUNTRY_TGN_LOOKUP[geo_hash[:country_part]].blank?
457
+ country_part ||= geo_hash[:country_part]
458
+ country_part ||= ''
459
+
460
+ city_part = geo_hash[:city_part]
461
+
462
+ neighborhood_part = geo_hash[:neighborhood_part]
463
+
464
+
465
+
466
+ if city_part.blank? && state_part.blank?
467
+ # Limit to nations
468
+ query = %{SELECT ?object_identifier
469
+ WHERE
470
+ {
471
+ ?x <http://purl.org/dc/elements/1.1/identifier> ?object_identifier .
472
+ ?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300128207> .
473
+ ?x <http://www.w3.org/2004/02/skos/core#prefLabel> ?object_label .
474
+ FILTER regex(?object_label, "^#{country_part}$", "i" )
475
+ }}
476
+ elsif state_part.present? && city_part.blank? && country_code == 7012149
477
+ #Limit to states
478
+ query = %{SELECT ?object_identifier
479
+ WHERE
480
+ {
481
+ ?x <http://purl.org/dc/elements/1.1/identifier> ?object_identifier .
482
+ ?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000776> .
483
+ ?x <http://www.w3.org/2000/01/rdf-schema#label> ?object_label .
484
+ FILTER regex(?object_label, "^#{state_part}$", "i" )
485
+
486
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> <http://vocab.getty.edu/tgn/7012149> .
487
+ }}
488
+ elsif state_part.present? && city_part.blank?
489
+ #Limit to regions
490
+
491
+ query = %{SELECT ?object_identifier
492
+ WHERE
493
+ {
494
+ ?x <http://purl.org/dc/elements/1.1/identifier> ?object_identifier .
495
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000774>} UNION
496
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000772>} UNION
497
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300235093>} UNION
498
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300135982>} UNION
499
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387176>} UNION
500
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387122>} UNION
501
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000776>} UNION
502
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300236112>} UNION
503
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347>} UNION
504
+ {?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387081>} .
505
+ ?x <http://www.w3.org/2000/01/rdf-schema#label> ?object_label .
506
+ FILTER regex(?object_label, "^#{state_part}$", "i" )
507
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_country .
508
+ {
509
+ SELECT ?parent_country ?identifier_country
510
+ WHERE {
511
+ ?parent_country <http://purl.org/dc/elements/1.1/identifier> ?identifier_country .
512
+ ?parent_country <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300128207> .
513
+ ?parent_country <http://www.w3.org/2000/01/rdf-schema#label> ?country_label .
514
+ FILTER regex(?country_label, "^#{country_part}$", "i" )
515
+ }
516
+
517
+ }
518
+ }
519
+ GROUP BY ?object_identifier
520
+ }
521
+
522
+ #FIXME Temporary: For Geomash.parse('Aknīste (Latvia)', true), seems to be a neighborhood placed in state
523
+ # {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347>} UNION
524
+ elsif state_part.present? && city_part.present? && neighborhood_part.blank?
525
+ #Limited to only inhabited places at the moment...
526
+ query = %{SELECT ?object_identifier
527
+ WHERE
528
+ {
529
+ ?x <http://purl.org/dc/elements/1.1/identifier> ?object_identifier .
530
+ ?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347> .
531
+ ?x <http://www.w3.org/2000/01/rdf-schema#label> ?object_label .
532
+ FILTER regex(?object_label, "^#{city_part}$", "i" )
533
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_country .
534
+ {
535
+ SELECT ?parent_country ?identifier_country
536
+ WHERE {
537
+ ?parent_country <http://purl.org/dc/elements/1.1/identifier> ?identifier_country .
538
+ ?parent_country <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300128207> .
539
+ ?parent_country <http://www.w3.org/2000/01/rdf-schema#label> ?country_label .
540
+ FILTER regex(?country_label, "^#{country_part}$", "i" )
541
+ }
542
+
543
+ }
544
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_state .
545
+ {
546
+ SELECT ?parent_state ?identifier_state
547
+ WHERE {
548
+ ?parent_state <http://purl.org/dc/elements/1.1/identifier> ?identifier_state .
549
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000774>} UNION
550
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000772>} UNION
551
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300235093>} UNION
552
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300135982>} UNION
553
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387176>} UNION
554
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387122>} UNION
555
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000776>} UNION
556
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300236112>} UNION
557
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347>} UNION
558
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387081>} .
559
+ ?parent_state <http://www.w3.org/2000/01/rdf-schema#label> ?state_label .
560
+ FILTER regex(?state_label, "^#{state_part}$", "i" )
561
+ }
562
+
563
+ }
564
+
565
+ }
566
+ GROUP BY ?object_identifier
567
+ }
568
+
569
+
570
+ elsif state_part.present? && city_part.present? && neighborhood_part.present?
571
+ #Limited to only to neighborhoods currently...
572
+ query = %{SELECT ?object_identifier
573
+ WHERE
574
+ {
575
+ ?x <http://purl.org/dc/elements/1.1/identifier> ?object_identifier .
576
+ ?x <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000745> .
577
+ ?x <http://www.w3.org/2000/01/rdf-schema#label> ?object_label .
578
+ FILTER regex(?object_label, "^#{neighborhood_part}$", "i" )
579
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_country .
580
+ {
581
+ SELECT ?parent_country ?identifier_country
582
+ WHERE {
583
+ ?parent_country <http://purl.org/dc/elements/1.1/identifier> ?identifier_country .
584
+ ?parent_country <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300128207> .
585
+ ?parent_country <http://www.w3.org/2000/01/rdf-schema#label> ?country_label .
586
+ FILTER regex(?country_label, "^#{country_part}$", "i" )
587
+ }
588
+
589
+ }
590
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_state .
591
+ {
592
+ SELECT ?parent_state ?identifier_state
593
+ WHERE {
594
+ ?parent_state <http://purl.org/dc/elements/1.1/identifier> ?identifier_state .
595
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000774>} UNION
596
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000772>} UNION
597
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300235093>} UNION
598
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300135982>} UNION
599
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387176>} UNION
600
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387122>} UNION
601
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300000776>} UNION
602
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300236112>} UNION
603
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347>} UNION
604
+ {?parent_state <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300387081>} .
605
+ ?parent_state <http://www.w3.org/2000/01/rdf-schema#label> ?state_label .
606
+ FILTER regex(?state_label, "^#{state_part}$", "i" )
607
+ }
608
+
609
+ }
610
+
611
+ ?x <http://vocab.getty.edu/ontology#broaderPreferredExtended> ?parent_city .
612
+ {
613
+ SELECT ?parent_city ?identifier_city
614
+ WHERE {
615
+ ?parent_city <http://purl.org/dc/elements/1.1/identifier> ?identifier_city .
616
+ ?parent_city <http://vocab.getty.edu/ontology#placeTypePreferred> <http://vocab.getty.edu/aat/300008347> .
617
+ ?parent_city <http://www.w3.org/2000/01/rdf-schema#label> ?city_label .
618
+ FILTER regex(?city_label, "^#{city_part}$", "i" )
619
+ }
620
+
621
+ }
622
+
623
+ }
624
+ GROUP BY ?object_identifier
625
+ }
626
+
627
+
628
+ else
629
+ return nil
630
+ end
631
+
632
+ begin
633
+
634
+ if retry_count > 0
635
+ sleep(sleep_time)
636
+ end
637
+ retry_count = retry_count + 1
638
+
639
+ query = query.squish
640
+ tgn_response = Typhoeus::Request.get("http://vocab.getty.edu/sparql.json", :params=>{:query=>query})
641
+
642
+ end until (tgn_response.code != 500 || retry_count == max_retry)
643
+
644
+
645
+
646
+
647
+ unless tgn_response.code == 500
648
+ as_json = JSON.parse(tgn_response.body)
649
+
650
+ #This is ugly and needs to be redone to achieve better recursive...
651
+ if as_json["results"]["bindings"].present? && as_json["results"]["bindings"].first["object_identifier"].present?
652
+ return_hash[:id] = as_json["results"]["bindings"].first["object_identifier"]["value"]
653
+ return_hash[:rdf] = "http://vocab.getty.edu/tgn/#{return_hash[:id]}.rdf"
654
+ else
655
+ return nil
656
+ end
657
+ end
658
+
659
+ if tgn_response.code == 500
660
+ raise 'TGN Server appears to not be responding for Geographic query: ' + query
661
+ end
662
+
663
+ if return_hash.present?
664
+ return_hash[:original_string_differs] = Geomash::Standardizer.parsed_and_original_check(geo_hash)
665
+ return return_hash
666
+ else
667
+ return nil
668
+ end
669
+ end
670
+
671
+
672
+ end
673
+ end