Skip to content
Snippets Groups Projects
get_measurements.py 7.23 KiB
Newer Older
from datetime import datetime

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
        sub_div_ids = []
        # 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))

            'MeasurementID': -1,
            'TimeMeasured': str(datetime.now()),
            '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)

    except Exception as e:
        print(f"Error in getting measurements: {e}")

        # 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:
        # 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
        return 0xFFff0000  # Red
        return 0xffff6a00  # Orange
        return 0xFFb1ff00  # Green
    elif thickness > 8:
        return 0xFF00d6ff  # Blue
    else:
        return 0xFF8C8C8C  # Grey