Newer
Older
from server.consts import LAKE_RELATIONS_PATH
from server.ModelFromNVE.icemodellingscripts.getIceThicknessLakes import get_raw_dates, ice_prognosis_raw_data
def get_measurements(self, lake_name):
Retrieves LiDar data for a given lake, and adds weather data to each subdivision.
Parameters:
self (BaseHTTPRequestHandler): A instance of a BaseHTTPRequestHandler
lake_name (str): The name of the requested file/lake
"""
# Define file path to lidar data file
file_path = os.path.join(LAKE_RELATIONS_PATH, lake_name + '_lidar_data.json')
# Lists to store processed data
measurements = []
# Some lakes may not have any recent lidar data, so must check if the file exists
if os.path.exists(file_path):
# Read the newest lidar data from JSON file
with open(file_path, 'r') as file:
lidar_data = json.load(file)
# Iterate over all fetched rows
for measurement in lidar_data:
processed_subdivs = []
# Create new measurement object
new_measurement = {
'MeasurementID': measurement['MeasurementID'],
'TimeMeasured': str(datetime.now()),
'CenterLat': measurement['CenterLat'],
'CenterLon': measurement['CenterLon'],
'Sensor': measurement['Sensor'],
'Subdivisions': [],
}
for sub_division in measurement['Subdivisions']:
subdiv_id = sub_division['SubdivID']
center_lat = sub_division['CenLatitude']
center_lng = sub_division['CenLongitude']
thicknesses = sub_division['Heights']
# Create new subdivision object
sub_division = {
'SubdivID': subdiv_id,
'GroupID': 0,
'MinThickness': sub_division['MinThickness'],
'AvgThickness': sub_division['AvgThickness'],
'CenLatitude': center_lat,
'CenLongitude': center_lng,
'Accuracy': sub_division['Accuracy'],
'Color': calculateColor(sub_division['MinThickness'], ),
# NB color calculated based on average thickness, should be minimum
# Fetch weather data from the NVE model
'IceStats': get_raw_dates(
ice_prognosis_raw_data(sub_div_id=subdiv_id, x=center_lat, y=center_lng))
}
sub_div_ids.append(subdiv_id)
# Append processed subdivision data
processed_subdivs.append(sub_division)
# Append processed measurement and subdivisions
new_measurement['Subdivisions'].append(processed_subdivs)
measurements.append(new_measurement)
# Populate remaining non-processed subdivisions and create "invalid" or "proxy" measurement to store them
remaining_sub_divs = fill_remaining_subdivisions(lake_name, sub_div_ids)
print("Len remaining_sub_divs: ", len(remaining_sub_divs))
print("Sub_div_ids: ", sub_div_ids)
print("Len measurements: ", len(measurements))
measurements[-1] = {
'CenterLat': None,
'CenterLon': None,
'Sensor': None,
'Subdivisions': remaining_sub_divs
}
# Write the newest measurements to file
with open(LAKE_RELATIONS_PATH + lake_name.lower() + '_measurements.json', 'w') as f:
json.dump(measurements, f)
if len(measurements) == 0:
response_data = json.dumps(['no measurements'])
else:
# Convert list of dictionaries to JSON
response_data = json.dumps(measurements, indent=4)
print(f"Error in getting measurements: {e}")
response_data = '[]'
# Set headers
self.send_response(500)
self.send_header("Content-type", "application/json")
self.end_headers()
# Set headers
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
# Write processed data to response object
self.wfile.write(response_data.encode('utf-8'))
def fill_remaining_subdivisions(lake_name: str, sub_div_ids: list):
"""
Returns a list of subdivision dictionaries for subdivisions without measurements.
Parameters:
lake_name (str): The name of the requested file/lake
sub_div_ids (list): A list of ids (int) of all subdivisions that have already been processed
Returns:
sub_divisions (list): A list of subdivision dictionaries
"""
# Read the lake relation for the requested lake
with open(LAKE_RELATIONS_PATH + lake_name + '_div.json', 'r') as file:
relation = json.load(file)
sub_divisions = []
# Loop through each feature and extract all subdivisions
for sub_div in relation['features']:
sub_div_id = int(sub_div['properties']['sub_div_id'])
# Only get subdivisions that are not in the list
if sub_div_id not in sub_div_ids:
center_lat = sub_div['properties']['sub_div_center'][0]
center_lng = sub_div['properties']['sub_div_center'][1]
# Fetch weather data for each subdivision from the NVE model
ice_stats = get_raw_dates(ice_prognosis_raw_data(sub_div_id=sub_div_id, x=center_lat, y=center_lng))
total_ice_thickness = ice_stats[0]['Total ice (m)']
# Create new subdivision object
sub_division = {
'SubdivID': sub_div_id,
'GroupID': None,
'MinThickness': total_ice_thickness,
'AvgThickness': total_ice_thickness,
'CenLatitude': center_lat,
'CenLongitude': center_lng,
'Accuracy': None,
# Calculate ice thickness based on total ice, temporary
# 'Color': calculateColor(ice_stats[0]['Total ice (m)']),
'Color': calculateColor(random.randint(0, 20)), # NB placeholder
'IceStats': ice_stats,
}
sub_divisions.append(sub_division)
return sub_divisions
except FileNotFoundError as e:
print("Failed to find relation file: ", e)
except Exception as e:
print("Failed to add remaining subdivisions: ", e)
def calculateColor(thickness: float): # NB neither final colors nor ranges
if 0 < thickness <= 4:
elif 4 < thickness <= 6:
elif 6 < thickness <= 8:
return 0xFFb1ff00 # Green
elif thickness > 8:
return 0xFF00d6ff # Blue
else:
return 0xFF8C8C8C # Grey