|
| 1 | +from __future__ import annotations |
| 2 | + |
1 | 3 | import re |
2 | 4 | from typing import Any |
3 | 5 |
|
4 | 6 | from wikibaseintegrator.datatypes.basedatatype import BaseDataType |
5 | 7 | from wikibaseintegrator.models import Claim |
6 | 8 | from wikibaseintegrator.wbi_config import config |
| 9 | +from wikibaseintegrator.wbi_enums import WikibaseSnakType |
7 | 10 |
|
8 | 11 |
|
9 | 12 | class GlobeCoordinate(BaseDataType): |
10 | 13 | """ |
11 | 14 | Implements the Wikibase data type for globe coordinates |
12 | 15 | """ |
13 | 16 | DTYPE = 'globe-coordinate' |
| 17 | + PTYPE = 'http://wikiba.se/ontology#GlobeCoordinate' |
14 | 18 | sparql_query = ''' |
15 | 19 | SELECT * WHERE {{ |
16 | 20 | ?item_id <{wb_url}/prop/{pid}> ?s . |
@@ -75,8 +79,37 @@ def rounded(datavalue: dict) -> dict: |
75 | 79 |
|
76 | 80 | return super().__eq__(other) |
77 | 81 |
|
78 | | - def get_sparql_value(self) -> str: |
79 | | - return '"Point(' + str(self.mainsnak.datavalue['value']['longitude']) + ' ' + str(self.mainsnak.datavalue['value']['latitude']) + ')"' |
| 82 | + def from_sparql_value(self, sparql_value: dict) -> GlobeCoordinate: |
| 83 | + """ |
| 84 | + Parse data returned by a SPARQL endpoint and set the value to the object |
| 85 | +
|
| 86 | + :param sparql_value: A SPARQL value composed of datatype, type and value |
| 87 | + :return: True if the parsing is successful |
| 88 | + """ |
| 89 | + datatype = sparql_value['datatype'] |
| 90 | + type = sparql_value['type'] |
| 91 | + value = sparql_value['value'] |
| 92 | + |
| 93 | + if datatype != 'http://www.opengis.net/ont/geosparql#wktLiteral': |
| 94 | + raise ValueError('Wrong SPARQL datatype') |
| 95 | + |
| 96 | + if type != 'literal': |
| 97 | + raise ValueError('Wrong SPARQL type') |
| 98 | + |
| 99 | + if value.startswith('http://www.wikidata.org/.well-known/genid/'): |
| 100 | + self.mainsnak.snaktype = WikibaseSnakType.UNKNOWN_VALUE |
| 101 | + else: |
| 102 | + pattern = re.compile(r'^Point\((.*) (.*)\)$') |
| 103 | + matches = pattern.match(value) |
| 104 | + if not matches: |
| 105 | + raise ValueError('Invalid SPARQL value') |
| 106 | + |
| 107 | + self.set_value(longitude=float(matches.group(1)), latitude=float(matches.group(2))) |
| 108 | + |
| 109 | + return self |
| 110 | + |
| 111 | + def get_sparql_value(self, **kwargs: Any) -> str: |
| 112 | + return '"Point(' + str(self.mainsnak.datavalue['value']['longitude']) + ' ' + str(self.mainsnak.datavalue['value']['latitude']) + ')"^^geo:wktLiteral' |
80 | 113 |
|
81 | 114 | def parse_sparql_value(self, value, type='literal', unit='1') -> bool: |
82 | 115 | pattern = re.compile(r'^"?Point\((.*) (.*)\)"?(?:\^\^geo:wktLiteral)?$') |
|
0 commit comments