66import typing
77from pathlib import Path
88
9+ from django .contrib .gis .db .models .functions import AsWKT
910from django .core .files .base import ContentFile
1011from django .db import models
1112from django .db .models .fields .files import FieldFile
@@ -43,7 +44,7 @@ def regenerate_project_stats_by_types_csv():
4344 "project_type" : None ,
4445 "project_type_display" : MANUAL_FIELD ,
4546 "projects_count" : models .Count ("*" ),
46- "total_area_sqkm" : models .F ("total_area" ),
47+ "total_area_sqkm" : models .Sum ("total_area" ),
4748 "total_number_of_results" : models .Count ("number_of_results" ),
4849 "total_number_of_results_progress" : models .Count ("number_of_results_for_progress" ),
4950 "average_number_of_users_per_project" : models .Avg ("number_of_contributor_users" ),
@@ -75,8 +76,10 @@ def regenerate_project_stats_by_types_csv():
7576
7677def regenerate_projects_csv (temp_projects_csv : typing .IO ): # type: ignore[reportMissingTypeArgument]
7778 logger .info ("Processing regenerate_projects_csv" )
79+
7880 fieldnames = {
7981 "id" : None ,
82+ "firebase_id" : None ,
8083 "name" : Project .generate_name_query (),
8184 "description" : None ,
8285 "look_for" : None ,
@@ -90,8 +93,10 @@ def regenerate_projects_csv(temp_projects_csv: typing.IO): # type: ignore[repor
9093 "status" : None ,
9194 "status_display" : MANUAL_FIELD ,
9295 "area_sqkm" : models .F ("aoi_geometry__total_area" ),
93- "centroid" : None , # TODO: use this after removing from model models.F("aoi_geometry__centroid"),
94- "geom" : models .F ("aoi_geometry__geometry" ),
96+ # TODO: Change _centroid to centroid after `centroid` field is removed from the project's table
97+ "centroid" : MANUAL_FIELD ,
98+ "_centroid" : AsWKT ("aoi_geometry__centroid" ),
99+ "geom" : AsWKT ("aoi_geometry__geometry" ),
95100 "progress" : None , # NOTE: This is changed to float later
96101 "number_of_contributor_users" : None ,
97102 "number_of_results" : None ,
@@ -100,6 +105,9 @@ def regenerate_projects_csv(temp_projects_csv: typing.IO): # type: ignore[repor
100105 }
101106
102107 projects_aggregate_qs = _project_queryset (fieldnames )
108+
109+ fieldnames .pop ("_centroid" )
110+
103111 writer = csv .DictWriter (temp_projects_csv , fieldnames = fieldnames )
104112 writer .writeheader ()
105113
@@ -113,6 +121,8 @@ def regenerate_projects_csv(temp_projects_csv: typing.IO): # type: ignore[repor
113121 name = image_file ,
114122 ),
115123 )
124+ # TODO: Remove this logic to set centroid after `centroid` field is removed from the project's table
125+ data ["centroid" ] = data .pop ("_centroid" )
116126 data ["image_url" ] = image_file_url
117127 data ["status_display" ] = ProjectStatusEnum (data ["status" ]).label
118128 data ["project_type_display" ] = ProjectTypeEnum (data ["project_type" ]).label
@@ -144,6 +154,13 @@ def _regenerate_projects_centroid_for_geometry_field(
144154 tmp_geojson_outfile = Config .TEMP_DIR / f"projects_centroid_{ geometry_field } _{ get_random_string (6 )} .geojson"
145155 inputfile_without_path = projects_csv_inputfile .name .split ("/" )[- 1 ].replace (".csv" , "" )
146156
157+ # TODO: Use EXCLUDE after upgrading gdal to > 3.9.0 https://github.com/OSGeo/gdal/pull/8675
158+ # With that, we can use `SELECT * EXCLUDE(geom), CAST(...` to exclude one column
159+ with Path .open (projects_csv_inputfile , "r" ) as fp :
160+ csv_reader = csv .DictReader (fp )
161+ inputfile_columns = [column for column in csv_reader .fieldnames or [] if column != "geom" ]
162+ inputfile_columns_str = "," .join (inputfile_columns )
163+
147164 subprocess .run ( # noqa: S603
148165 [
149166 "/usr/bin/ogr2ogr" ,
@@ -154,7 +171,7 @@ def _regenerate_projects_centroid_for_geometry_field(
154171 str (tmp_geojson_outfile ),
155172 str (projects_csv_inputfile ),
156173 "-sql" ,
157- f'SELECT * , CAST({ geometry_field } as geometry) FROM "{ inputfile_without_path } "' ,
174+ f'SELECT { inputfile_columns_str } , CAST({ geometry_field } as geometry) FROM "{ inputfile_without_path } "' ,
158175 ],
159176 check = True ,
160177 )
0 commit comments