diff --git a/src/backend/app/db/postgis_utils.py b/src/backend/app/db/postgis_utils.py index 9a3b146228..6c1cf55b1f 100644 --- a/src/backend/app/db/postgis_utils.py +++ b/src/backend/app/db/postgis_utils.py @@ -537,7 +537,9 @@ def get_address_from_lat_lon(latitude, longitude): } headers = {"Accept-Language": "en"} # Set the language to English - log.debug("Getting Nominatim address from project centroid") + log.debug( + f"Getting Nominatim address from project lat ({latitude}) lon ({longitude})" + ) response = requests.get(base_url, params=params, headers=headers) if (status_code := response.status_code) != 200: log.error(f"Getting address string failed: {status_code}") diff --git a/src/backend/app/projects/project_schemas.py b/src/backend/app/projects/project_schemas.py index d3525b8fd7..17ccc06d61 100644 --- a/src/backend/app/projects/project_schemas.py +++ b/src/backend/app/projects/project_schemas.py @@ -149,8 +149,7 @@ class ProjectIn(BaseModel): task_num_buildings: Optional[int] = None data_extract_type: Optional[str] = None outline_geojson: Union[FeatureCollection, Feature, Polygon] - # city: str - # country: str + location_str: Optional[str] = None @computed_field @property @@ -170,17 +169,6 @@ def centroid(self) -> Optional[Any]: return None return write_wkb(read_wkb(self.outline).centroid) - @computed_field - @property - def location_str(self) -> Optional[str]: - """Compute geocoded location string from centroid.""" - if not self.centroid: - return None - geom = read_wkb(self.centroid) - latitude, longitude = geom.y, geom.x - address = get_address_from_lat_lon(latitude, longitude) - return address if address is not None else "" - @computed_field @property def project_name_prefix(self) -> str: @@ -201,6 +189,27 @@ def prepend_hash_to_tags(cls, hashtags: List[str]) -> Optional[List[str]]: return hashtags_with_hash + @model_validator(mode="after") + def generate_location_str(self) -> Self: + """Generate location string after centroid is generated. + + NOTE chaining computed_field didn't seem to work here so a + model_validator was used for final stage validation. + """ + if not self.centroid: + log.warning("Project has no centroid, location string not determined") + return self + + if self.location_str is not None: + # Prevent running triggering multiple times if already set + return self + + geom = read_wkb(self.centroid) + latitude, longitude = geom.y, geom.x + address = get_address_from_lat_lon(latitude, longitude) + self.location_str = address if address is not None else "" + return self + class ProjectUpload(ProjectIn, ODKCentralIn): """Project upload details, plus ODK credentials."""