import os import dearpygui.dearpygui as dpg import tifffile import numpy as np from map_edit_constants import TREE_COLOR, ROAD_COLOR, BUILDING_COLOR, LAYER_TO_COLOR from map_edit import dump_height_map, load_height_map, update_texture from generator import LCZ from paths import BASE_PATH from utils import show_message, set_main_window_value, get_config, get_config_file_path, delete_item_and_clear_alias, delete_item_children_and_clear_aliases, set_map_window_value, get_map_window_value, get_height_map_file_path def delete_emission_point_clb(s, a, u): n = dpg.get_item_user_data('emission_settings_window') prefix = f'{get_config_file_path()}.passive_tracers.tracer_{n}.point_emission' keys = ['value', 'begin', 'xpos', 'ypos', 'zpos', 'sx', 'sy', 'sz'] config = get_config() for key in keys: path = f'passive_tracers.tracer_{n}.point_emission.{key}' del config[path] set_main_window_value('config', config) delete_item_children_and_clear_aliases(prefix) dpg.hide_item('emission_settings_window') tag = f'emission_point_{n}_triangle' dpg.delete_item(tag) def set_emission_point_value_clb(s, value, u): n = dpg.get_item_user_data('emission_settings_window') key = s.split('_')[-1] path = f'{get_config_file_path()}.passive_tracers.tracer_{n}.point_emission.{key}' if dpg.does_item_exist(path): dpg.set_value(path, value) config = get_config() config[path].value = value set_main_window_value('config', config) def clear_map(): delete_item_and_clear_alias('map_buildings_texture') delete_item_and_clear_alias('map_trees_texture') delete_item_and_clear_alias('map_roads_texture') delete_item_children_and_clear_aliases('map_drawlist') settings = { 'buildings_map': None, 'trees_map': None, 'roads_map': None, 'height_map_file_path': None, 'drawing': False, 'prev_coords': None, 'current_action': None, 'max_height': 0 } dpg.set_item_user_data('map_window', settings) def map_window_on_close_clb(s, a, u): clear_map() def construct_map_layers(w, h): dpg.set_item_width('map_child_window', w) dpg.set_item_height('map_child_window', h) dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag='map_buildings_texture', parent='textures') dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag='map_trees_texture', parent='textures') dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag='map_roads_texture', parent='textures') dpg.bind_item_theme('map_child_window', 'map_image_theme') dpg.add_drawlist(w, h, tag=f'map_drawlist', parent='map_child_window', pos=[0, 0]) dpg.draw_image(f'map_buildings_texture', color=BUILDING_COLOR, tag=f'map_buildings_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') dpg.draw_image(f'map_trees_texture', color=TREE_COLOR, tag=f'map_trees_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') dpg.draw_image(f'map_roads_texture', color=ROAD_COLOR, tag=f'map_roads_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') def map_open_layer_clb(s, a, u): height_map_file_path = a['file_path_name'] layer = dpg.get_value('layer_radio_button') if height_map_file_path.endswith('txt'): try: height_map = load_height_map(height_map_file_path) except FileNotFoundError: show_message('no file found') return except Exception: show_message('bad file format') return max_height = np.max(height_map) height_map /= max_height else: height_map = tifffile.imread(height_map_file_path) max_height = 1 h, w = height_map.shape delete_item_and_clear_alias(f'map_{layer}_texture') if dpg.does_alias_exist(f'map_{layer}_texture'): dpg.remove_alias(f'map_{layer}_texture') delete_item_and_clear_alias(f'map_{layer}_image') if dpg.does_alias_exist(f'map_{layer}_image'): dpg.remove_alias(f'map_{layer}_image') set_map_window_value(f'{layer}_map', height_map) dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag=f'map_{layer}_texture', parent='textures') dpg.draw_image(f'map_{layer}_texture', color=LAYER_TO_COLOR[layer], tag=f'map_{layer}_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') dpg.set_value('layer', layer) update_texture() def map_open_clb(s, a, u): height_map_file_path = a['file_path_name'] if height_map_file_path.endswith('txt'): try: height_map = load_height_map(height_map_file_path) except FileNotFoundError: show_message('no file found') return except Exception: show_message('bad file format') return max_height = np.max(height_map) height_map /= max_height else: height_map = tifffile.imread(height_map_file_path) max_height = 1 h, w = height_map.shape clear_map() set_map_window_value('buildings_map', height_map) set_map_window_value('roads_map', np.zeros((h, w))) set_map_window_value('trees_map', np.zeros((h, w))) set_map_window_value('height_map_file_path', height_map_file_path) set_map_window_value('max_height', max_height) construct_map_layers(w, h) dpg.set_value('layer', 'buildings') update_texture() dpg.show_item('map_window') def generate_map_clb(s, a, u): height_map = LCZ(config_path=os.path.join(BASE_PATH, 'configs', f'{s}.json')).to_height_map(dtype=np.float64) max_height = np.max(height_map) height_map /= max_height h, w = height_map.shape clear_map() set_map_window_value('buildings_map', height_map) set_map_window_value('roads_map', np.zeros((h, w))) set_map_window_value('trees_map', np.zeros((h, w))) set_map_window_value('height_map_file_path', 'map.txt') set_map_window_value('max_height', max_height) construct_map_layers(w, h) dpg.set_value('layer', 'buildings') update_texture() dpg.show_item('map_window') def save_map(file_path): if file_path.endswith('.tif') or file_path.endswith('.tiff'): with TiffWriter(file_path) as tif: tif.write(get_map_window_value('buildings_map')) tif.write(get_map_window_value('roads_map')) tif.write(get_map_window_value('trees_map')) else: dump_height_map(get_map_window_value('buildings_map'), file_path) def map_save_clb(s, a, u): file_path = get_height_map_file_path() save_map(file_path) show_message('file saved successfully:)') def map_save_as_clb(s, a, u): file_path = a['file_path_name'] save_map(file_path) show_message('file saved successfully:)') def open_map_save_as_dialog_clb(s, a, u): dpg.show_item('map_save_as') def open_map_open_dialog_clb(s, a, u): dpg.show_item('map_open') def open_map_open_layer_dialog_clb(s, a, u): dpg.show_item('map_open_layer') def set_action_clb(s, a, u): set_map_window_value('current_action', s) def set_action_none_clb(s, a, u): set_map_window_value('current_action', None)