mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Added pushing of spatial data to backend
This commit is contained in:
parent
1f53cb3d44
commit
24e22fa56a
4 changed files with 78 additions and 14 deletions
|
|
@ -45,7 +45,7 @@ class Property(Definitions):
|
|||
windows = None
|
||||
lighting = None
|
||||
|
||||
coordinates = None
|
||||
spatial = None
|
||||
|
||||
def __init__(self, id, postcode, address1, epc_client=None, data=None):
|
||||
self.id = id
|
||||
|
|
@ -129,13 +129,6 @@ class Property(Definitions):
|
|||
else:
|
||||
self.uprn = int(self.data["uprn"])
|
||||
|
||||
def set_coordinates(self, coordinates):
|
||||
"""
|
||||
This method sets the coordinates of the property, given the open uprn data
|
||||
:param coordinates: dictionary
|
||||
"""
|
||||
self.coordinates = {key.lower(): value for key, value in coordinates.items()}
|
||||
|
||||
def set_energy(self):
|
||||
"""
|
||||
Extracts and formats data about the home's energy and co2 consumption
|
||||
|
|
@ -364,6 +357,9 @@ class Property(Definitions):
|
|||
def set_spatial(self, spatial: pd.DataFrame):
|
||||
"""
|
||||
Sets whether the property is in a conservation area given the output of the ConservationAreaClient
|
||||
|
||||
Will store a dictionary, spatial, which is used to populate the property spatial table in the database
|
||||
|
||||
:param spatial: Dataframe, containing the spatial data for the property
|
||||
"""
|
||||
self.in_conservation_area = spatial["conservation_status"].values[0]
|
||||
|
|
@ -373,6 +369,17 @@ class Property(Definitions):
|
|||
if self.in_conservation_area is True | self.is_listed is True | self.is_heritage is True:
|
||||
self.restricted_measures = True
|
||||
|
||||
spatial_dict = spatial.to_dict("records")[0]
|
||||
self.spatial = {
|
||||
"x_coordinate": spatial_dict["X_COORDINATE"],
|
||||
"y_coordinate": spatial_dict["Y_COORDINATE"],
|
||||
"latitude": spatial_dict["LATITUDE"],
|
||||
"longitude": spatial_dict["LONGITUDE"],
|
||||
"conservation_status": spatial_dict["conservation_status"],
|
||||
"is_listed_building": spatial_dict["is_listed_building"],
|
||||
"is_heritage_building": spatial_dict["is_heritage_building"],
|
||||
}
|
||||
|
||||
def set_year_built(self):
|
||||
"""
|
||||
Estimates when the property was built based on as much available data as possible.
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
###
|
||||
import datetime
|
||||
import pytz
|
||||
from sqlalchemy.orm import Session
|
||||
from backend.app.db.models.portfolio import (
|
||||
PropertyModel, PropertyCreationStatus, PortfolioStatus, PropertyTargetsModel, PropertyDetailsEpcModel
|
||||
PropertyModel, PropertyCreationStatus, PortfolioStatus, PropertyTargetsModel, PropertyDetailsEpcModel,
|
||||
PropertyDetailsSpatial
|
||||
)
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
|
||||
def create_property(session, portfolio_id: int, address: str, postcode: str) -> (int, bool):
|
||||
def create_property(session: Session, portfolio_id: int, address: str, postcode: str) -> (int, bool):
|
||||
"""
|
||||
This function will create a record for the property in the database if it does not exist.
|
||||
If it does exist, it will just update the updated_at field.
|
||||
|
|
@ -55,7 +57,9 @@ def create_property(session, portfolio_id: int, address: str, postcode: str) ->
|
|||
return new_property.id, True
|
||||
|
||||
|
||||
def create_property_targets(session, property_id: int, portfolio_id: int, epc_target=None, heat_demand_target=None):
|
||||
def create_property_targets(
|
||||
session: Session, property_id: int, portfolio_id: int, epc_target=None, heat_demand_target=None
|
||||
):
|
||||
"""
|
||||
This function will create a record for the property targets in the database if it does not exist.
|
||||
:param session: The database session
|
||||
|
|
@ -78,7 +82,9 @@ def create_property_targets(session, property_id: int, portfolio_id: int, epc_ta
|
|||
return True
|
||||
|
||||
|
||||
def update_property_data(session, property_id: int, portfolio_id: int, property_data: dict):
|
||||
def update_property_data(
|
||||
session: Session, property_id: int, portfolio_id: int, property_data: dict
|
||||
):
|
||||
now = datetime.datetime.now(pytz.utc)
|
||||
|
||||
try:
|
||||
|
|
@ -103,7 +109,9 @@ def update_property_data(session, property_id: int, portfolio_id: int, property_
|
|||
return True
|
||||
|
||||
|
||||
def create_property_details_epc(session, property_details_epc: dict):
|
||||
def create_property_details_epc(
|
||||
session: Session, property_details_epc: dict
|
||||
):
|
||||
"""
|
||||
This function will create or update a record for the property details EPC in the database.
|
||||
:param session: The database session
|
||||
|
|
@ -128,3 +136,36 @@ def create_property_details_epc(session, property_details_epc: dict):
|
|||
session.flush()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_or_create_property_spatial_details(session: Session, uprn: int, property_details_spatial: dict):
|
||||
"""
|
||||
Update an existing property details record or create a new one based on the UPRN.
|
||||
|
||||
:param session: The SQLAlchemy session for database interaction.
|
||||
:param uprn: The unique property reference number (UPRN) of the property.
|
||||
:param property_details_spatial: A dictionary containing the spatial property details to store or update.
|
||||
:return: True if the operation is successful, otherwise raises an exception.
|
||||
"""
|
||||
|
||||
try:
|
||||
# Attempt to fetch the existing property details
|
||||
existing_property_details = session.query(PropertyDetailsSpatial).filter_by(
|
||||
uprn=uprn
|
||||
).one()
|
||||
|
||||
# Update the fields with the data in property_details
|
||||
for key, value in property_details_spatial.items():
|
||||
setattr(existing_property_details, key, value)
|
||||
|
||||
# Merge the updated property details back into the session and flush
|
||||
session.merge(existing_property_details)
|
||||
session.flush()
|
||||
|
||||
except NoResultFound:
|
||||
# Create a new record if not found
|
||||
new_property_details = PropertyDetailsSpatial(uprn=uprn, **property_details_spatial)
|
||||
session.add(new_property_details)
|
||||
session.flush()
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -155,6 +155,19 @@ class PropertyDetailsEpcModel(Base):
|
|||
adjusted_energy_consumption = Column(Float)
|
||||
|
||||
|
||||
class PropertyDetailsSpatial(Base):
|
||||
__tablename__ = "property_details_spatial"
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uprn = Column(Integer, nullable=False)
|
||||
x_coordinate = Column(Float)
|
||||
y_coordinate = Column(Float)
|
||||
latitude = Column(Float)
|
||||
longitude = Column(Float)
|
||||
conservation_status = Column(Boolean)
|
||||
is_listed_building = Column(Boolean)
|
||||
is_heritage_building = Column(Boolean)
|
||||
|
||||
|
||||
class PropertyDetailsMeter(Base):
|
||||
__tablename__ = 'property_details_meter'
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ from backend.app.db.connection import db_engine
|
|||
from backend.app.db.functions.materials_functions import get_materials
|
||||
from backend.app.db.functions.portfolio_functions import aggregate_portfolio_recommendations
|
||||
from backend.app.db.functions.property_functions import (
|
||||
create_property, create_property_details_epc, create_property_targets, update_property_data
|
||||
create_property, create_property_details_epc, create_property_targets, update_property_data,
|
||||
update_or_create_property_spatial_details
|
||||
)
|
||||
from backend.app.db.functions.recommendations_functions import (
|
||||
create_plan, create_plan_recommendations, upload_recommendations
|
||||
|
|
@ -507,6 +508,8 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
)
|
||||
create_property_details_epc(session, property_details_epc)
|
||||
|
||||
update_or_create_property_spatial_details(session, p.uprn, p.spatial)
|
||||
|
||||
# TODO: TEMP
|
||||
if p.data["uprn"] == "":
|
||||
print("Get rid of me!")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue