mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
further breaking up code
This commit is contained in:
parent
24f0404c8d
commit
c0f9462377
18 changed files with 133 additions and 53 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -250,4 +250,5 @@ backend/node_modules
|
||||||
node_modules/
|
node_modules/
|
||||||
backend/.idea
|
backend/.idea
|
||||||
open_uprn/.idea/
|
open_uprn/.idea/
|
||||||
|
conservation_areas/.idea/
|
||||||
|
|
||||||
|
|
|
||||||
2
.idea/Model.iml
generated
2
.idea/Model.iml
generated
|
|
@ -6,7 +6,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/model_data" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/model_data" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.10 (hestia-data)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.10 (conservation_areas)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (hestia-data)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (conservation_areas)" project-jdk-type="Python SDK" />
|
||||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||||
<option name="version" value="3" />
|
<option name="version" value="3" />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import geopandas as gpd
|
import geopandas as gpd
|
||||||
from shapely.geometry import Point
|
from shapely.geometry import Point
|
||||||
from model_data.utils import setup_logger
|
from utils.logger import setup_logger
|
||||||
|
from datatypes.datatypes import OpenUprnCoordinateData
|
||||||
|
|
||||||
logger = setup_logger()
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
@ -39,7 +40,13 @@ class ConservationAreaClient:
|
||||||
self.gov_data = gpd.read_file(self.gov_path)
|
self.gov_data = gpd.read_file(self.gov_path)
|
||||||
self.gov_data = self.gov_data.drop(columns=["dataset"])
|
self.gov_data = self.gov_data.drop(columns=["dataset"])
|
||||||
|
|
||||||
def is_in_conservation_area(self, coordinates: dict):
|
def is_in_conservation_area(self, coordinates: OpenUprnCoordinateData):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Check if a property is in a conservation area
|
||||||
|
:param coordinates: dictionary, which should have the OpenUprnCoordinateData format
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
if not coordinates:
|
if not coordinates:
|
||||||
raise ValueError("Coordinates have not been set, run get_coordinates() first")
|
raise ValueError("Coordinates have not been set, run get_coordinates() first")
|
||||||
53
conservation_areas/app.py
Normal file
53
conservation_areas/app.py
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
"""
|
||||||
|
This application reads in the open uprn data from a static location and loads it into
|
||||||
|
our database for querying from other services
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from conservation_areas.ConservationAreaClient import ConservationAreaClient
|
||||||
|
|
||||||
|
|
||||||
|
def app():
|
||||||
|
conservation_area_client = ConservationAreaClient(
|
||||||
|
historic_england_path=os.path.abspath(
|
||||||
|
os.path.dirname(__file__)
|
||||||
|
) + "/model_data/local_data/Historic_Eng_Conservation_Areas/Conservation_Areas.shp",
|
||||||
|
gov_path=os.path.abspath(
|
||||||
|
os.path.dirname(__file__)
|
||||||
|
) + "/model_data/local_data/gov-conservation-area.geojson"
|
||||||
|
)
|
||||||
|
conservation_area_client.read()
|
||||||
|
|
||||||
|
# We need to iterate through the open uprn data and check if the coordinates are in a conservation area
|
||||||
|
open_uprn_data = [
|
||||||
|
{'UPRN': 6032920, 'X_COORDINATE': 535110.0, 'Y_COORDINATE': 181819.0, 'LATITUDE': 51.5191407,
|
||||||
|
'LONGITUDE': -0.0540506},
|
||||||
|
{'UPRN': 6038625, 'X_COORDINATE': 535374.0, 'Y_COORDINATE': 182784.0, 'LATITUDE': 51.5277492,
|
||||||
|
'LONGITUDE': -0.0498772},
|
||||||
|
{'UPRN': 34153991, 'X_COORDINATE': 523238.74, 'Y_COORDINATE': 178003.02, 'LATITUDE': 51.4875579,
|
||||||
|
'LONGITUDE': -0.226392},
|
||||||
|
{'UPRN': 10008299676, 'X_COORDINATE': 533285.0, 'Y_COORDINATE': 184711.0, 'LATITUDE': 51.5455629,
|
||||||
|
'LONGITUDE': -0.0792445},
|
||||||
|
{'UPRN': 10008299677, 'X_COORDINATE': 533285.0, 'Y_COORDINATE': 184711.0, 'LATITUDE': 51.5455629,
|
||||||
|
'LONGITUDE': -0.0792445},
|
||||||
|
{'UPRN': 100021039066, 'X_COORDINATE': 535506.0, 'Y_COORDINATE': 185624.0, 'LATITUDE': 51.5532385,
|
||||||
|
'LONGITUDE': -0.0468833},
|
||||||
|
{'UPRN': 100021226060, 'X_COORDINATE': 529247.0, 'Y_COORDINATE': 187959.0, 'LATITUDE': 51.5756908,
|
||||||
|
'LONGITUDE': -0.1362513},
|
||||||
|
{'UPRN': 200003489276, 'X_COORDINATE': 533210.0, 'Y_COORDINATE': 179442.0, 'LATITUDE': 51.4982309,
|
||||||
|
'LONGITUDE': -0.0823165}
|
||||||
|
]
|
||||||
|
|
||||||
|
result = [conservation_area_client.is_in_conservation_area(coordinates) for coordinates in open_uprn_data]
|
||||||
|
|
||||||
|
conservation_area_client
|
||||||
|
|
||||||
|
uprns = [
|
||||||
|
int(x) for x in
|
||||||
|
['34153991', '6038625', '100021039066', '100021226060', '10008299676', '10008299677', '6032920', '200003489276']
|
||||||
|
]
|
||||||
|
|
||||||
|
open_uprn_client.data[open_uprn_client.data["UPRN"].isin(
|
||||||
|
uprns
|
||||||
|
)].to_dict("records")
|
||||||
|
# TODO: Add a method to write to the database
|
||||||
16
conservation_areas/requirements.txt
Normal file
16
conservation_areas/requirements.txt
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
attrs==23.1.0
|
||||||
|
certifi==2023.5.7
|
||||||
|
click==8.1.6
|
||||||
|
click-plugins==1.1.1
|
||||||
|
cligj==0.7.2
|
||||||
|
fiona==1.9.4.post1
|
||||||
|
geopandas==0.13.2
|
||||||
|
numpy==1.25.1
|
||||||
|
packaging==23.1
|
||||||
|
pandas==2.0.3
|
||||||
|
pyproj==3.6.0
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
pytz==2023.3
|
||||||
|
shapely==2.0.1
|
||||||
|
six==1.16.0
|
||||||
|
tzdata==2023.3
|
||||||
0
datatypes/__init__.py
Normal file
0
datatypes/__init__.py
Normal file
10
datatypes/datatypes.py
Normal file
10
datatypes/datatypes.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OpenUprnCoordinateData:
|
||||||
|
UPRN: int
|
||||||
|
X_COORDINATE: float
|
||||||
|
Y_COORDINATE: float
|
||||||
|
LATITUDE: float
|
||||||
|
LONGITUDE: float
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import math
|
import math
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from dbfread import DBF
|
from dbfread import DBF
|
||||||
from model_data.utils import setup_logger
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
logger = setup_logger()
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from typing import List, Dict
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
import string
|
import string
|
||||||
from model_data.utils import setup_logger
|
from utils.logger import setup_logger
|
||||||
from fuzzywuzzy import fuzz
|
from fuzzywuzzy import fuzz
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from model_data.EpcClean import EpcClean
|
||||||
|
|
||||||
from statsmodels.stats.outliers_influence import variance_inflation_factor
|
from statsmodels.stats.outliers_influence import variance_inflation_factor
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from model_data.utils import setup_logger
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
logger = setup_logger()
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from tqdm import tqdm
|
||||||
import os
|
import os
|
||||||
from model_data.BoreholeClient import BoreholeClient
|
from model_data.BoreholeClient import BoreholeClient
|
||||||
from model_data.LandRegistryClient import LandRegistryClient
|
from model_data.LandRegistryClient import LandRegistryClient
|
||||||
from model_data.ConservationAreaClient import ConservationAreaClient
|
from conservation_areas.ConservationAreaClient import ConservationAreaClient
|
||||||
|
|
||||||
from model_data.temp_inputs import input_data
|
from model_data.temp_inputs import input_data
|
||||||
from model_data.Property import Property
|
from model_data.Property import Property
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from model_data.utils import setup_logger, is_percentage_or_number, correct_spelling
|
from model_data.utils import is_percentage_or_number, correct_spelling
|
||||||
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
|
|
||||||
class TestLogger:
|
class TestLogger:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import logging
|
|
||||||
import re
|
import re
|
||||||
from textblob import TextBlob
|
from textblob import TextBlob
|
||||||
|
|
||||||
|
|
@ -6,40 +5,6 @@ from textblob import TextBlob
|
||||||
PERCENTAGE_PATTERN = re.compile(r'^\d+%?$')
|
PERCENTAGE_PATTERN = re.compile(r'^\d+%?$')
|
||||||
|
|
||||||
|
|
||||||
def setup_logger(log_file=None, level=logging.INFO, overwrite_handler=False):
|
|
||||||
# Create a logger and set the logging level
|
|
||||||
logger = logging.getLogger()
|
|
||||||
logger.setLevel(level)
|
|
||||||
|
|
||||||
# if logger already has handlers, just return it
|
|
||||||
if logger.hasHandlers() and not overwrite_handler:
|
|
||||||
return logger
|
|
||||||
|
|
||||||
# Define the log message format
|
|
||||||
log_format = "%(asctime)s [%(levelname)s] %(message)s"
|
|
||||||
date_format = "%Y-%m-%d %H:%M:%S"
|
|
||||||
formatter = logging.Formatter(log_format, datefmt=date_format)
|
|
||||||
|
|
||||||
# Create a file handler and set the file path and format
|
|
||||||
if log_file:
|
|
||||||
file_handler = logging.FileHandler(log_file)
|
|
||||||
file_handler.setLevel(level)
|
|
||||||
file_handler.setFormatter(formatter)
|
|
||||||
logger.addHandler(file_handler)
|
|
||||||
|
|
||||||
# Create a console handler and set the format
|
|
||||||
console_handler = logging.StreamHandler()
|
|
||||||
console_handler.setLevel(level)
|
|
||||||
|
|
||||||
# Set the formatter for the handlers
|
|
||||||
console_handler.setFormatter(formatter)
|
|
||||||
|
|
||||||
# Add the handlers to the logger
|
|
||||||
logger.addHandler(console_handler)
|
|
||||||
|
|
||||||
return logger
|
|
||||||
|
|
||||||
|
|
||||||
def is_percentage_or_number(s):
|
def is_percentage_or_number(s):
|
||||||
# re.match returns None if the string does not match the pattern
|
# re.match returns None if the string does not match the pattern
|
||||||
return PERCENTAGE_PATTERN.match(s) is not None
|
return PERCENTAGE_PATTERN.match(s) is not None
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from model_data.utils import setup_logger
|
from utils.logger import setup_logger
|
||||||
|
|
||||||
logger = setup_logger()
|
logger = setup_logger()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,4 @@ def app():
|
||||||
)
|
)
|
||||||
open_uprn_client.read()
|
open_uprn_client.read()
|
||||||
|
|
||||||
uprns = [
|
|
||||||
int(x) for x in
|
|
||||||
['34153991', '6038625', '100021039066', '100021226060', '10008299676', '10008299677', '6032920', '200003489276']
|
|
||||||
]
|
|
||||||
|
|
||||||
open_uprn_client.data[open_uprn_client.data["UPRN"].isin(
|
|
||||||
uprns
|
|
||||||
)].to_dict("records")
|
|
||||||
# TODO: Add a method to write to the database
|
# TODO: Add a method to write to the database
|
||||||
|
|
|
||||||
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
35
utils/logger.py
Normal file
35
utils/logger.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logger(log_file=None, level=logging.INFO, overwrite_handler=False):
|
||||||
|
# Create a logger and set the logging level
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logger.setLevel(level)
|
||||||
|
|
||||||
|
# if logger already has handlers, just return it
|
||||||
|
if logger.hasHandlers() and not overwrite_handler:
|
||||||
|
return logger
|
||||||
|
|
||||||
|
# Define the log message format
|
||||||
|
log_format = "%(asctime)s [%(levelname)s] %(message)s"
|
||||||
|
date_format = "%Y-%m-%d %H:%M:%S"
|
||||||
|
formatter = logging.Formatter(log_format, datefmt=date_format)
|
||||||
|
|
||||||
|
# Create a file handler and set the file path and format
|
||||||
|
if log_file:
|
||||||
|
file_handler = logging.FileHandler(log_file)
|
||||||
|
file_handler.setLevel(level)
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
# Create a console handler and set the format
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(level)
|
||||||
|
|
||||||
|
# Set the formatter for the handlers
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
# Add the handlers to the logger
|
||||||
|
logger.addHandler(console_handler)
|
||||||
|
|
||||||
|
return logger
|
||||||
Loading…
Add table
Reference in a new issue