contrail/scr/pages/home_page.py
def update_data_table(upload_n_clicks, encounter_id_selected, ac_ids_selected, update_speeds_n_clicks, add_rows_n_clicks, done_add_rows_n_clicks,\
                      create_n_clicks, start_new_n_clicks, end_new_n_clicks, current_markers, table_data, columns, ac_value, interval, zUp_input, ref_data,\
                      memory_data):
    '''
    Updates data table to display waypoints for the selected encounter and aircraft ids.
    '''

    file_path = DEFAULT_DATA_FILE_PATH
    
    ctx = dash.callback_context.triggered[0]['prop_id'].split('.')[0]


    if ctx == 'load-waypoints-button' and upload_n_clicks > 0:
        return [], columns
        
    elif ctx == 'encounter-ids' or ctx == 'ac-ids':
        if encounter_id_selected is None or encounter_id_selected == [] or ac_ids_selected == []:
            return [], columns
        else:
            # encounter IDs or ac IDs have been updated or loaded in
            ac_ids_to_grab = ac_ids_selected
            if ctx == 'encounter-ids':
                ac_ids_to_grab = memory_data['ac_ids']

            enc_data = parse_enc_data(memory_data, [encounter_id_selected], ac_ids_to_grab, ref_data, file_path)
            enc_data_df = pd.DataFrame(enc_data)
            enc_data_df_sorted = enc_data_df.sort_values(by=['ac_id', 'time'])
            enc_data_df = calculate_turnrate_hor_ver_speeds_df(enc_data_df_sorted)
            return enc_data_df.to_dict('records'), columns

    elif ctx == 'create-mode' and create_n_clicks > 0 and end_new_n_clicks == 0:
        # wipe all data
        return [], columns

    elif ctx == 'update-speeds-button' and update_speeds_n_clicks > 0:
        df = pd.DataFrame(table_data) #.apply(pd.to_numeric, errors='coerce').fillna(0)
        df = calculate_turnrate_hor_ver_speeds_df(df)
        return df.to_dict('records'), columns

    elif ctx == 'add-rows-button' and create_n_clicks == 0:
        if add_rows_n_clicks > 0:
            # add an empty row
            table_data.append({col["id"]: '' for col in columns})
        return table_data, columns
    elif ctx == 'done-add-rows-button' and done_add_rows_n_clicks > 0:
        # FIXME: we need to add an alert check here to make sure that the user
        # inputs xEast, yNorth and zUp at least so we can calculate horizontal vertical speeds
        data = populate_lat_lng_xEast_yNorth(table_data, ref_data)
        df = pd.DataFrame(data).apply(pd.to_numeric, errors='coerce').fillna(0)
        df = df.sort_values(by=['ac_id', 'time'])
        df = calculate_turnrate_hor_ver_speeds_df(df)
        return df.to_dict('records'), columns

    elif ctx == 'marker-layer' and create_n_clicks > 0 and start_new_n_clicks > 0:
        if ac_value is None\
            or not ref_data['ref_lat'] or not ref_data['ref_long']\
            or not ref_data['ref_alt'] or not interval or not zUp_input:
                return dash.no_update, dash.no_update
        
        df = pd.DataFrame(table_data)
        if 'ac_id' not in df.keys() or (len(df.loc[df['ac_id'] == ac_value]) != len(current_markers)):
            timestep = 0

            if 'ac_id' in df.keys():
                if ac_value in df['ac_id'].tolist():
                    df_ac = df.loc[df['ac_id'] == ac_value]
                    last_timestep = max(df_ac['time'])
                    timestep = last_timestep+interval
                
            # in creative mode and user has created another marker 
            # we add each marker to the data as it is created 
            # so we only have to grab last marker in the list
            pos = current_markers[-1]['props']['position']
            xEast, yNorth, _ = pm.geodetic2enu(pos[0], pos[1], zUp_input*FT_TO_M, 
                                                    ref_data['ref_lat'], ref_data['ref_long'], ref_data['ref_alt']*FT_TO_M,
                                                    ell=pm.Ellipsoid('wgs84'), deg=True)
            marker_dict = {'encounter_id': 0, 'ac_id': ac_value, 'time': timestep, 
                            'xEast': xEast*M_TO_NM, 'yNorth': yNorth*M_TO_NM,
                            'lat':pos[0], 'long':pos[1], 'zUp': zUp_input,
                            'heading': 0, 'turn_rate': 0, 'horizontal_speed': 0, 'vertical_speed': 0}
            table_data.append(marker_dict)
        else:
            # an already existing marker was dragged
            # and therefore its position in data table needs to get updated

            df = pd.DataFrame(table_data)

            waypoint = 0
            for i, data_point in df.iterrows():
                if data_point['ac_id'] == ac_value:
                    pos = current_markers[waypoint]['props']['position']
                    xEast, yNorth, zUp = pm.geodetic2enu(pos[0], pos[1], zUp_input*FT_TO_M, 
                                                            ref_data['ref_lat'], ref_data['ref_long'], ref_data['ref_alt']*FT_TO_M,
                                                            ell=pm.Ellipsoid('wgs84'), deg=True)
                    data_point['xEast'] = xEast*M_TO_NM
                    data_point['yNorth'] = yNorth*M_TO_NM
                    data_point['lat'] = pos[0]
                    data_point['long'] = pos[1]
                    df.at[i] = data_point
                    waypoint += 1

            table_data = df.to_dict('records')

        return table_data, columns
        
    elif ctx == 'end-new-button':
        if end_new_n_clicks > 0: 
            if table_data != []:
                df = pd.DataFrame(table_data) 
                df = calculate_turnrate_hor_ver_speeds_df(df)
                return df.to_dict('records'), columns
        
    return dash.no_update, dash.no_update

    Updates data table to display waypoints for the selected encounter and aircraft ids.
    
Updates data table to display waypoints for the selected encounter and aircraft ids.
Updates data table to display waypoints for the selected encounter and aircraft ids .
def update_data_table(upload_n_clicks, encounter_id_selected, ac_ids_selected, update_speeds_n_clicks, add_rows_n_clicks, done_add_rows_n_clicks,\
                      create_n_clicks, start_new_n_clicks, end_new_n_clicks, current_markers, table_data, columns, ac_value, interval, zUp_input, ref_data,\
                      memory_data):
    file_path = DEFAULT_DATA_FILE_PATH
    ctx = dash.callback_context.triggered[0]['prop_id'].split('.')[0]
    if ctx == 'load-waypoints-button' and upload_n_clicks > 0:
        return [], columns
    elif ctx == 'encounter-ids' or ctx == 'ac-ids':
        if encounter_id_selected is None or encounter_id_selected == [] or ac_ids_selected == []:
            return [], columns
        else:
            ac_ids_to_grab = ac_ids_selected
            if ctx == 'encounter-ids':
                ac_ids_to_grab = memory_data['ac_ids']
            enc_data = parse_enc_data(memory_data, [encounter_id_selected], ac_ids_to_grab, ref_data, file_path)
            enc_data_df = pd.DataFrame(enc_data)
            enc_data_df_sorted = enc_data_df.sort_values(by=['ac_id', 'time'])
            enc_data_df = calculate_turnrate_hor_ver_speeds_df(enc_data_df_sorted)
            return enc_data_df.to_dict('records'), columns
    elif ctx == 'create-mode' and create_n_clicks > 0 and end_new_n_clicks == 0:
        return [], columns
    elif ctx == 'update-speeds-button' and update_speeds_n_clicks > 0:
        df = pd.DataFrame(table_data) 
        df = calculate_turnrate_hor_ver_speeds_df(df)
        return df.to_dict('records'), columns
    elif ctx == 'add-rows-button' and create_n_clicks == 0:
        if add_rows_n_clicks > 0:
            table_data.append({col["id"]: '' for col in columns})
        return table_data, columns
    elif ctx == 'done-add-rows-button' and done_add_rows_n_clicks > 0:
        data = populate_lat_lng_xEast_yNorth(table_data, ref_data)
        df = pd.DataFrame(data).apply(pd.to_numeric, errors='coerce').fillna(0)
        df = df.sort_values(by=['ac_id', 'time'])
        df = calculate_turnrate_hor_ver_speeds_df(df)
        return df.to_dict('records'), columns
    elif ctx == 'marker-layer' and create_n_clicks > 0 and start_new_n_clicks > 0:
        if ac_value is None\
            or not ref_data['ref_lat'] or not ref_data['ref_long']\
            or not ref_data['ref_alt'] or not interval or not zUp_input:
                return dash.no_update, dash.no_update
        df = pd.DataFrame(table_data)
        if 'ac_id' not in df.keys() or (len(df.loc[df['ac_id'] == ac_value]) != len(current_markers)):
            timestep = 0
            if 'ac_id' in df.keys():
                if ac_value in df['ac_id'].tolist():
                    df_ac = df.loc[df['ac_id'] == ac_value]
                    last_timestep = max(df_ac['time'])
                    timestep = last_timestep+interval
            pos = current_markers[-1]['props']['position']
            xEast, yNorth, _ = pm.geodetic2enu(pos[0], pos[1], zUp_input*FT_TO_M, 
                                                    ref_data['ref_lat'], ref_data['ref_long'], ref_data['ref_alt']*FT_TO_M,
                                                    ell=pm.Ellipsoid('wgs84'), deg=True)
            marker_dict = {'encounter_id': 0, 'ac_id': ac_value, 'time': timestep, 
                            'xEast': xEast*M_TO_NM, 'yNorth': yNorth*M_TO_NM,
                            'lat':pos[0], 'long':pos[1], 'zUp': zUp_input,
                            'heading': 0, 'turn_rate': 0, 'horizontal_speed': 0, 'vertical_speed': 0}
            table_data.append(marker_dict)
        else:
            df = pd.DataFrame(table_data)
            waypoint = 0
            for i, data_point in df.iterrows():
                if data_point['ac_id'] == ac_value:
                    pos = current_markers[waypoint]['props']['position']
                    xEast, yNorth, zUp = pm.geodetic2enu(pos[0], pos[1], zUp_input*FT_TO_M, 
                                                            ref_data['ref_lat'], ref_data['ref_long'], ref_data['ref_alt']*FT_TO_M,
                                                            ell=pm.Ellipsoid('wgs84'), deg=True)
                    data_point['xEast'] = xEast*M_TO_NM
                    data_point['yNorth'] = yNorth*M_TO_NM
                    data_point['lat'] = pos[0]
                    data_point['long'] = pos[1]
                    df.at[i] = data_point
                    waypoint += 1
            table_data = df.to_dict('records')
        return table_data, columns
    elif ctx == 'end-new-button':
        if end_new_n_clicks > 0: 
            if table_data != []:
                df = pd.DataFrame(table_data) 
                df = calculate_turnrate_hor_ver_speeds_df(df)
                return df.to_dict('records'), columns
    return dash.no_update, dash.no_update
def update_data_table ( upload_n_clicks , encounter_id_selected , ac_ids_selected , update_speeds_n_clicks , add_rows_n_clicks , done_add_rows_n_clicks , create_n_clicks , start_new_n_clicks , end_new_n_clicks , current_markers , table_data , columns , ac_value , interval , zUp_input , ref_data , memory_data ) : file_path = DEFAULT_DATA_FILE_PATH ctx = dash . callback_context . triggered [ 0 ] [ 'prop_id' ] . split ( '.' ) [ 0 ] if ctx == 'load-waypoints-button' and upload_n_clicks > 0 : return [ ] , columns elif ctx == 'encounter-ids' or ctx == 'ac-ids' : if encounter_id_selected is None or encounter_id_selected == [ ] or ac_ids_selected == [ ] : return [ ] , columns else : ac_ids_to_grab = ac_ids_selected if ctx == 'encounter-ids' : ac_ids_to_grab = memory_data [ 'ac_ids' ] enc_data = parse_enc_data ( memory_data , [ encounter_id_selected ] , ac_ids_to_grab , ref_data , file_path ) enc_data_df = pd . DataFrame ( enc_data ) enc_data_df_sorted = enc_data_df . sort_values ( by = [ 'ac_id' , 'time' ] ) enc_data_df = calculate_turnrate_hor_ver_speeds_df ( enc_data_df_sorted ) return enc_data_df . to_dict ( 'records' ) , columns elif ctx == 'create-mode' and create_n_clicks > 0 and end_new_n_clicks == 0 : return [ ] , columns elif ctx == 'update-speeds-button' and update_speeds_n_clicks > 0 : df = pd . DataFrame ( table_data ) df = calculate_turnrate_hor_ver_speeds_df ( df ) return df . to_dict ( 'records' ) , columns elif ctx == 'add-rows-button' and create_n_clicks == 0 : if add_rows_n_clicks > 0 : table_data . append ( { col [ "id" ] : '' for col in columns } ) return table_data , columns elif ctx == 'done-add-rows-button' and done_add_rows_n_clicks > 0 : data = populate_lat_lng_xEast_yNorth ( table_data , ref_data ) df = pd . DataFrame ( data ) . apply ( pd . to_numeric , errors = 'coerce' ) . fillna ( 0 ) df = df . sort_values ( by = [ 'ac_id' , 'time' ] ) df = calculate_turnrate_hor_ver_speeds_df ( df ) return df . to_dict ( 'records' ) , columns elif ctx == 'marker-layer' and create_n_clicks > 0 and start_new_n_clicks > 0 : if ac_value is None or not ref_data [ 'ref_lat' ] or not ref_data [ 'ref_long' ] or not ref_data [ 'ref_alt' ] or not interval or not zUp_input : return dash . no_update , dash . no_update df = pd . DataFrame ( table_data ) if 'ac_id' not in df . keys ( ) or ( len ( df . loc [ df [ 'ac_id' ] == ac_value ] ) != len ( current_markers ) ) : timestep = 0 if 'ac_id' in df . keys ( ) : if ac_value in df [ 'ac_id' ] . tolist ( ) : df_ac = df . loc [ df [ 'ac_id' ] == ac_value ] last_timestep = max ( df_ac [ 'time' ] ) timestep = last_timestep + interval pos = current_markers [ - 1 ] [ 'props' ] [ 'position' ] xEast , yNorth , _ = pm . geodetic2enu ( pos [ 0 ] , pos [ 1 ] , zUp_input * FT_TO_M , ref_data [ 'ref_lat' ] , ref_data [ 'ref_long' ] , ref_data [ 'ref_alt' ] * FT_TO_M , ell = pm . Ellipsoid ( 'wgs84' ) , deg = True ) marker_dict = { 'encounter_id' : 0 , 'ac_id' : ac_value , 'time' : timestep , 'xEast' : xEast * M_TO_NM , 'yNorth' : yNorth * M_TO_NM , 'lat' : pos [ 0 ] , 'long' : pos [ 1 ] , 'zUp' : zUp_input , 'heading' : 0 , 'turn_rate' : 0 , 'horizontal_speed' : 0 , 'vertical_speed' : 0 } table_data . append ( marker_dict ) else : df = pd . DataFrame ( table_data ) waypoint = 0 for i , data_point in df . iterrows ( ) : if data_point [ 'ac_id' ] == ac_value : pos = current_markers [ waypoint ] [ 'props' ] [ 'position' ] xEast , yNorth , zUp = pm . geodetic2enu ( pos [ 0 ] , pos [ 1 ] , zUp_input * FT_TO_M , ref_data [ 'ref_lat' ] , ref_data [ 'ref_long' ] , ref_data [ 'ref_alt' ] * FT_TO_M , ell = pm . Ellipsoid ( 'wgs84' ) , deg = True ) data_point [ 'xEast' ] = xEast * M_TO_NM data_point [ 'yNorth' ] = yNorth * M_TO_NM data_point [ 'lat' ] = pos [ 0 ] data_point [ 'long' ] = pos [ 1 ] df . at [ i ] = data_point waypoint += 1 table_data = df . to_dict ( 'records' ) return table_data , columns elif ctx == 'end-new-button' : if end_new_n_clicks > 0 : if table_data != [ ] : df = pd . DataFrame ( table_data ) df = calculate_turnrate_hor_ver_speeds_df ( df ) return df . to_dict ( 'records' ) , columns return dash . no_update , dash . no_update
Updates data table to display waypoints for the selected encounter and aircraft ids.
Updates data table to display waypoints for the selected encounter and aircraft ids .
'''
    Updates data table to display waypoints for the selected encounter and aircraft ids.
    ''' # encounter IDs or ac IDs have been updated or loaded in # wipe all data #.apply(pd.to_numeric, errors='coerce').fillna(0) # add an empty row # FIXME: we need to add an alert check here to make sure that the user # inputs xEast, yNorth and zUp at least so we can calculate horizontal vertical speeds # in creative mode and user has created another marker  # we add each marker to the data as it is created  # so we only have to grab last marker in the list # an already existing marker was dragged # and therefore its position in data table needs to get updated
upload_n_clicks
encounter_id_selected
ac_ids_selected
update_speeds_n_clicks
add_rows_n_clicks
done_add_rows_n_clicks
create_n_clicks
start_new_n_clicks
end_new_n_clicks
current_markers
table_data
columns
ac_value
interval
zUp_input
ref_data
memory_data