Skip to content

Commit 04bb090

Browse files
committed
Various fixes, especially for pair_from_sources.
1 parent 9fa4947 commit 04bb090

6 files changed

Lines changed: 67 additions & 33 deletions

File tree

src/ocsge_pv/geometrize_declarations.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ def main() -> None:
178178
if cli_args.verbose:
179179
logger.setLevel(logging.DEBUG)
180180
# Read configuration
181-
logger.debug("Loading configuration...")
181+
logger.info("Loading configuration...")
182182
configuration = load_configuration(cli_args.path)
183183
# Connect to OGR datasources
184-
logger.debug("Preparing OGR entities...")
184+
logger.info("Preparing OGR entities...")
185185
declaration_ogr_ds = ogr.Open(f'PG: {configuration["main_database"]["_pg_string"]}')
186186
cadastre_ogr_ds = ogr.Open(f'PG: {configuration["cadastre_database"]["_pg_string"]}')
187187
# Compute SRS and conversions
@@ -212,7 +212,7 @@ def main() -> None:
212212
or (is_declaration_srs_latlon and not is_cadastre_srs_latlon)
213213
)
214214
# Georeference declarations
215-
logger.debug("Computing declarations' geometries...")
215+
logger.info("Computing declarations' geometries...")
216216
declaration_update_list = []
217217
for declaration_feature in declaration_ogr_layer:
218218
try:
@@ -241,7 +241,7 @@ def main() -> None:
241241
new_geom = temp_geom
242242
declaration_update_list.append((farm_fid, new_geom.ExportToWkt()))
243243
# Write output
244-
logger.debug("Updating geometries in database...")
244+
logger.info("Updating geometries in database...")
245245
declaration_pkey = declaration_ogr_layer.GetFIDColumn()
246246
write_output(configuration["main_database"], declaration_update_list, declaration_pkey)
247247
logger.info("End of declaration data geometry edition.")

src/ocsge_pv/import_declarations.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,13 @@ def main() -> None:
456456
cli_args = cli_arg_parser()
457457
if cli_args.verbose:
458458
logger.setLevel(logging.DEBUG)
459-
logger.debug("Loading configuration...")
459+
logger.info("Loading configuration...")
460460
configuration = load_configuration(cli_args.path)
461-
logger.debug("Fetching data...")
461+
logger.info("Fetching data...")
462462
input_data = query_source_api(configuration["input"])
463-
logger.debug("Formating data...")
463+
logger.info("Formating data...")
464464
output_data = format_source_result(input_data)
465-
logger.debug("Writing into database...")
465+
logger.info("Writing into database...")
466466
write_output(configuration["output"], output_data)
467467
logger.info("End of declaration data import.")
468468
return 0

src/ocsge_pv/pair_from_sources.py

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import logging
1313
import os
1414
from pathlib import Path
15+
import sys
1516
import traceback
1617
from typing import Dict, List, Tuple
1718
from zoneinfo import ZoneInfo
@@ -24,8 +25,10 @@
2425

2526
# -- GLOBALS --
2627
NAME = "pair_from_sources"
28+
TRACE = 5
2729
logging.basicConfig(level=logging.INFO,
2830
format="%(asctime)s %(name)s(%(funcName)s) %(levelname)s: %(message)s")
31+
logging.addLevelName(TRACE, "TRACE")
2932
logging.captureWarnings(True)
3033
logger = logging.getLogger(NAME)
3134
ogr.UseExceptions()
@@ -63,6 +66,11 @@ def cli_arg_parser() -> argparse.Namespace:
6366
action="store_true",
6467
help="output more logs"
6568
)
69+
parser.add_argument("-vv", "--very_verbose",
70+
dest="very_verbose",
71+
action="store_true",
72+
help="output even more logs"
73+
)
6674
return parser.parse_args()
6775

6876
def load_configuration(path: Path) -> Dict:
@@ -107,47 +115,52 @@ def write_output(output_conf: Dict, out_link_list: List[Tuple]) -> None:
107115
update_list (List[Tuple]): list of (fid, geometry) of declarations to update
108116
declaration_pkey (str): name of the private key column for declarations
109117
"""
118+
new_pairs_count = 0
110119
with psycopg.connect(output_conf["_pg_string"]) as conn:
111120
cur = conn.cursor()
112121
try:
113122
with conn.transaction():
114123
for link_obj in out_link_list:
124+
logger.log(TRACE, f"Treating pair {link_obj}.")
115125
# Vérification d'existence du lien
116126
cur.execute(
117127
sql.SQL(
118128
"SELECT * FROM {table} WHERE {decl_key} = %s AND {dete_key} = %s"
119129
).format(
120130
table=sql.Identifier(output_conf["schema"],
121131
output_conf["tables"]["links"]),
122-
decl_key=sql.Identifier(out_link_declar_fkey),
123-
dete_key=sql.Identifier(out_link_detect_fkey)
132+
decl_key=sql.Identifier("declaration_id"),
133+
dete_key=sql.Identifier("detection_id")
124134
),
125135
(
126-
link_obj[out_link_declar_fkey],
127-
link_obj[out_link_detect_fkey]
136+
link_obj["declaration_id"],
137+
link_obj["detection_id"]
128138
)
129139
)
130140
result = cur.fetchone()
131141
# Ajout si inexistant
132142
if result is None:
143+
logger.log(TRACE, f"Pair {link_obj} does not exist and will be inserted.")
133144
cur.execute(
134145
sql.SQL(
135146
"INSERT INTO {table} ({decl_key}, {dete_key}) VALUES (%s, %s)"
136147
).format(
137148
table=sql.Identifier(output_conf["schema"],
138149
output_conf["tables"]["links"]),
139-
decl_key=sql.Identifier(out_link_declar_fkey),
140-
dete_key=sql.Identifier(out_link_detect_fkey)
150+
decl_key=sql.Identifier("declaration_id"),
151+
dete_key=sql.Identifier("detection_id")
141152
),
142153
(
143-
link_obj[out_link_declar_fkey],
144-
link_obj[out_link_detect_fkey]
154+
link_obj["declaration_id"],
155+
link_obj["detection_id"]
145156
)
146157
)
158+
new_pairs_count += 1
147159
except Exception as exc:
148160
logger.error(traceback.format_exc())
149161
conn.rollback()
150162
raise exc
163+
logger.debug(f"{new_pairs_count} new pairs inserted in database.")
151164

152165
# -- MAIN FUNCTION --
153166
def main() -> None:
@@ -163,58 +176,74 @@ def main() -> None:
163176
try:
164177
logger.info("Start of declarations' pairing with detections.")
165178
cli_args = cli_arg_parser()
166-
if cli_args.verbose:
179+
log_level_description = "normal"
180+
if cli_args.very_verbose:
181+
logger.setLevel(logging.getLevelName("TRACE"))
182+
log_level_description = "very verbose"
183+
elif cli_args.verbose:
167184
logger.setLevel(logging.DEBUG)
185+
log_level_description = "verbose"
186+
logger.info(f"Logging level: '{logger.getEffectiveLevel()}' ({log_level_description})")
168187
# Read configuration
169-
logger.debug("Loading configuration...")
188+
logger.info("Loading configuration...")
170189
configuration = load_configuration(cli_args.path)
171190
# OGR layers and spatial references
172-
logger.debug("Preparing OGR entities...")
191+
logger.info("Preparing OGR entities...")
173192
latlon_sr_name_list = ['WGS 84']
174193
ogr_pg_connection = ogr.Open(("PG: " + configuration["main_database"]["_pg_string"]))
175194
## Declarations layer
176-
declaration_table = ".".join(configuration["main_database"]["schema"],
177-
configuration["main_database"]["tables"]["declararations"])
195+
declaration_table = ".".join((configuration["main_database"]["schema"],
196+
configuration["main_database"]["tables"]["declarations"]))
178197
declaration_ogr_layer = ogr_pg_connection.GetLayerByName(declaration_table)
179198
if declaration_ogr_layer is None:
180199
raise Exception(f"Declaration layer '{declaration_table}' was not loaded.")
200+
logger.log(TRACE,
201+
f"FID column for declaration layer: '{declaration_ogr_layer.GetFIDColumn()}'")
181202
declaration_osr_sr = declaration_ogr_layer.GetSpatialRef()
182203
if declaration_osr_sr is None:
183204
raise Exception(
184205
f"Spatial reference for declaration layer '{declaration_table}' was not found.")
185206
is_declaration_sr_latlon = (declaration_osr_sr.EPSGTreatsAsLatLong()
186207
or declaration_osr_sr.GetName() in latlon_sr_name_list)
208+
logger.debug(f"Declarations layer's SRS: {declaration_osr_sr.GetName()}")
187209
## Detections layer
188-
detection_table = ".".join(configuration["main_database"]["schema"],
189-
configuration["main_database"]["tables"]["detections"])
210+
detection_table = ".".join((configuration["main_database"]["schema"],
211+
configuration["main_database"]["tables"]["detections"]))
190212
detection_ogr_layer = ogr_pg_connection.GetLayerByName(detection_table)
191213
if detection_ogr_layer is None:
192214
raise Exception(f"Detection layer '{detection_table}' was not loaded.")
215+
logger.log(TRACE,
216+
f"FID column for detection layer: '{detection_ogr_layer.GetFIDColumn()}'")
193217
detection_osr_sr = detection_ogr_layer.GetSpatialRef()
194218
if detection_osr_sr is None:
195219
raise Exception(
196220
f"Spatial reference for detection layer '{detection_table}' was not found.")
197221
is_detection_sr_latlon = (detection_osr_sr.EPSGTreatsAsLatLong()
198222
or detection_osr_sr.GetName() in latlon_sr_name_list)
223+
logger.debug(f"Detections layer's SRS: {detection_osr_sr.GetName()}")
199224
## Pairing layer
200-
pairing_table = ".".join(configuration["main_database"]["schema"],
201-
configuration["main_database"]["tables"]["links"])
225+
pairing_table = ".".join((configuration["main_database"]["schema"],
226+
configuration["main_database"]["tables"]["links"]))
202227
pairing_ogr_layer = ogr_pg_connection.GetLayerByName(pairing_table)
203228
if pairing_ogr_layer is None:
204229
raise Exception(f"Pairing layer '{pairing_table}' was not loaded.")
205230
## Coordinates transformations
206231
coordinates_transformation = None
207232
need_coordinates_swap = False # True if the two spatial references use a different axis order
208233
if detection_osr_sr != declaration_osr_sr:
234+
logger.debug("Coordinates transformation is necessary.")
209235
coordinates_transformation = osr.CoordinateTransformation(
210236
declaration_osr_sr, detection_osr_sr)
211237
need_coordinates_swap = (
212238
(is_detection_sr_latlon and not is_declaration_sr_latlon)
213239
or (is_declaration_sr_latlon and not is_detection_sr_latlon)
214240
)
241+
if need_coordinates_swap:
242+
logger.debug("Axis order swapping is necessary for this transformation.")
215243
# Data fetching
216-
logger.debug("Fetching source data...")
244+
logger.info("Fetching source data...")
217245
## Declarations (with non-null geometries and installation dates)
246+
logger.debug("Fetching declarations with non-null spatial and temproal attributes.")
218247
declaration_dict = {}
219248
for farm_feature in declaration_ogr_layer:
220249
farm_id = farm_feature.GetFID()
@@ -231,17 +260,20 @@ def main() -> None:
231260
new_geom.SwapXY()
232261
new_geom.Transform(coordinates_transformation)
233262
declaration_dict[farm_id]["geom"] = new_geom.Clone()
263+
logger.debug(f"{len(declaration_dict)} declarations fetched.")
234264
## Detections
265+
logger.debug("Fetching detections.")
235266
detection_dict = {}
236267
for farm_feature in detection_ogr_layer:
237268
farm_id = farm_feature.GetFID()
238269
detection_dict[farm_id] = {
239270
"millesime": farm_feature.GetField("millesime"),
240271
}
241272
detection_dict[farm_id]["geom"] = farm_feature.geometry().Clone()
273+
logger.debug(f"{len(detection_dict)} detections fetched.")
242274
ogr_pg_connection = None
243275
# Pairing
244-
logger.debug("Computing pairs...")
276+
logger.info("Computing pairs...")
245277
out_link_list = []
246278
for detection_id in detection_dict.keys():
247279
for declaration_id in declaration_dict.keys():
@@ -258,10 +290,12 @@ def main() -> None:
258290
is_pair = geom_intersect_bool and time_intersect_bool
259291
if is_pair:
260292
link_obj = {}
261-
link_obj[out_link_declar_fkey] = declaration_id
262-
link_obj[out_link_detect_fkey] = detection_id
293+
link_obj["declaration_id"] = declaration_id
294+
link_obj["detection_id"] = detection_id
263295
out_link_list.append(link_obj)
264-
logger.debug("Writing pairs in database...")
296+
logger.debug(f"{len(out_link_list)} pairs. (Include previously existing pairs.)")
297+
## TODO? check if some previous pairs no longer exist?
298+
logger.info("Writing pairs in database...")
265299
write_output(configuration["main_database"], out_link_list)
266300
logger.info("End of declarations' pairing with detections.")
267301
return 0

src/ocsge_pv/resources/pair_config.model.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"schema": "schema's name",
99
"tables": {
1010
"detections": "detections table's name",
11-
"declararations": "declarations table's name",
11+
"declarations": "declarations table's name",
1212
"links": "links table's name"
1313
}
1414
}

src/ocsge_pv/resources/pair_config.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"host": {
1313
"description": "Database hostname",
1414
"type": "string",
15-
"oneOf": [
15+
"anyOf": [
1616
{
1717
"format": "hostname"
1818
},

tests/fixtures/pair_config.ok.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"schema": "photovoltaic",
99
"tables": {
1010
"detections": "detection",
11-
"declararations": "declaration",
11+
"declarations": "declaration",
1212
"links": "declaration_detection"
1313
}
1414
}

0 commit comments

Comments
 (0)