1
+ import json
1
2
import logging
3
+ import os
2
4
from string import Template
3
5
4
- import dateutil . parser
6
+ import dateutil
5
7
import plotly .graph_objects as go
6
8
from geojson import Feature
7
9
12
14
from ohsome_quality_api .indicators .base import BaseIndicator
13
15
from ohsome_quality_api .ohsome import client as ohsome_client
14
16
from ohsome_quality_api .topics .models import BaseTopic as Topic
17
+ from ohsome_quality_api .trino import client as trino_client
18
+ from ohsome_quality_api .utils .helper_geo import get_bounding_box
19
+
20
+ WORKING_DIR = os .path .dirname (os .path .abspath (__file__ ))
15
21
16
22
17
23
class AttributeCompleteness (BaseIndicator ):
@@ -46,8 +52,10 @@ def __init__(
46
52
attribute_keys : list [str ] | None = None ,
47
53
attribute_filter : str | None = None ,
48
54
attribute_title : str | None = None ,
55
+ feature_flag_sql : bool = False , # Feature flag to use SQL instead of ohsome API queries
49
56
) -> None :
50
57
super ().__init__ (topic = topic , feature = feature )
58
+ self .feature_flag_sql = feature_flag_sql
51
59
self .threshold_yellow = 0.75
52
60
self .threshold_red = 0.25
53
61
self .attribute_keys = attribute_keys
@@ -56,7 +64,9 @@ def __init__(
56
64
self .absolute_value_1 = None
57
65
self .absolute_value_2 = None
58
66
self .description = None
59
- if self .attribute_keys :
67
+ if self .feature_flag_sql :
68
+ self .attribute_filter = attribute_filter
69
+ elif self .attribute_keys :
60
70
self .attribute_filter = build_attribute_filter (
61
71
self .attribute_keys ,
62
72
self .topic .key ,
@@ -74,17 +84,50 @@ def __init__(
74
84
)
75
85
76
86
async def preprocess (self ) -> None :
77
- # Get attribute filter
78
- response = await ohsome_client .query (
79
- self .topic ,
80
- self .feature ,
81
- attribute_filter = self .attribute_filter ,
82
- )
83
- timestamp = response ["ratioResult" ][0 ]["timestamp" ]
84
- self .result .timestamp_osm = dateutil .parser .isoparse (timestamp )
85
- self .result .value = response ["ratioResult" ][0 ]["ratio" ]
86
- self .absolute_value_1 = response ["ratioResult" ][0 ]["value" ]
87
- self .absolute_value_2 = response ["ratioResult" ][0 ]["value2" ]
87
+ if self .feature_flag_sql :
88
+ filter = self .topic .sql_filter
89
+ file_path = os .path .join (WORKING_DIR , "query.sql" )
90
+ with open (file_path , "r" ) as file :
91
+ template = file .read ()
92
+
93
+ bounding_box = get_bounding_box (self .feature )
94
+ geometry = json .dumps (self .feature ["geometry" ])
95
+
96
+ sql = template .format (
97
+ bounding_box = bounding_box ,
98
+ geometry = geometry ,
99
+ filter = filter ,
100
+ )
101
+ query = await trino_client .query (sql )
102
+ results = await trino_client .fetch (query )
103
+ # TODO: Check for None
104
+ self .absolute_value_1 = results [0 ][0 ]
105
+
106
+ filter = self .topic .sql_filter + " AND " + self .attribute_filter
107
+ sql = template .format (
108
+ bounding_box = bounding_box ,
109
+ geometry = geometry ,
110
+ filter = filter ,
111
+ )
112
+ query = await trino_client .query (sql )
113
+ results = await trino_client .fetch (query )
114
+ self .absolute_value_2 = results [0 ][0 ]
115
+
116
+ # timestamp = response["ratioResult"][0]["timestamp"]
117
+ # self.result.timestamp_osm = dateutil.parser.isoparse(timestamp)
118
+ self .result .value = self .absolute_value_2 / self .absolute_value_1
119
+ else :
120
+ # Get attribute filter
121
+ response = await ohsome_client .query (
122
+ self .topic ,
123
+ self .feature ,
124
+ attribute_filter = self .attribute_filter ,
125
+ )
126
+ timestamp = response ["ratioResult" ][0 ]["timestamp" ]
127
+ self .result .timestamp_osm = dateutil .parser .isoparse (timestamp )
128
+ self .result .value = response ["ratioResult" ][0 ]["ratio" ]
129
+ self .absolute_value_1 = response ["ratioResult" ][0 ]["value" ]
130
+ self .absolute_value_2 = response ["ratioResult" ][0 ]["value2" ]
88
131
89
132
def calculate (self ) -> None :
90
133
# result (ratio) can be NaN if no features matching filter1
0 commit comments