diff --git a/app/native/wndb/inp_in.py b/app/native/wndb/inp_in.py index ac77464..183202e 100644 --- a/app/native/wndb/inp_in.py +++ b/app/native/wndb/inp_in.py @@ -1,6 +1,6 @@ import datetime import os -from .project_backup import * +from .project import * from .database import ChangeSet, write from .sections import * from .s0_base import get_region_type @@ -15,7 +15,7 @@ from .s8_tags import inp_in_tag from .s9_demands import inp_in_demand from .s10_status import inp_in_status from .s11_patterns import pattern_v3_types, inp_in_pattern -from .s12_curves import curve_types, inp_in_curve +from .s12_curves import curve_types, inp_in_curve from .s13_controls import inp_in_control from .s14_rules import inp_in_rule from .s15_energy import inp_in_energy @@ -32,50 +32,52 @@ from .s24_coordinates import inp_in_coord from .s25_vertices import inp_in_vertex from .s26_labels import inp_in_label from .s27_backdrop import inp_in_backdrop -from .s32_region import inp_in_region,inp_in_bound,inp_in_regionnodes -from .s32_region_util import from_postgis_polygon,to_postgis_polygon +from .s32_region import inp_in_region, inp_in_bound, inp_in_regionnodes +from .s32_region_util import from_postgis_polygon, to_postgis_polygon -#DingZQ, 2024-12-28, export inp +# DingZQ, 2024-12-28, export inp from .inp_out import export_inp -_S = 'S' -_L = 'L' +_S = "S" +_L = "L" + + +def _inp_in_option(section: list[str], version: str = "3") -> str: + return inp_in_option_v3(section) if version == "3" else inp_in_option(section) -def _inp_in_option(section: list[str], version: str = '3') -> str: - return inp_in_option_v3(section) if version == '3' else inp_in_option(section) _handler = { - TITLE : (_S, inp_in_title), - JUNCTIONS : (_L, inp_in_junction), # line, demand_outside - RESERVOIRS : (_L, inp_in_reservoir), - TANKS : (_L, inp_in_tank), - PIPES : (_L, inp_in_pipe), - PUMPS : (_L, inp_in_pump), - VALVES : (_L, inp_in_valve), - TAGS : (_L, inp_in_tag), - DEMANDS : (_L, inp_in_demand), - STATUS : (_L, inp_in_status), - PATTERNS : (_L, inp_in_pattern), # line, fixed - CURVES : (_L, inp_in_curve), - CONTROLS : (_L, inp_in_control), - RULES : (_L, inp_in_rule), - ENERGY : (_L, inp_in_energy), - EMITTERS : (_L, inp_in_emitter), - QUALITY : (_L, inp_in_quality), - SOURCES : (_L, inp_in_source), - REACTIONS : (_L, inp_in_reaction), - MIXING : (_L, inp_in_mixing), - TIMES : (_S, inp_in_time), - REPORT : (_S, inp_in_report), - OPTIONS : (_S, _inp_in_option), # line, version - COORDINATES : (_L, inp_in_coord), - VERTICES : (_L, inp_in_vertex), - REGION : (_L, inp_in_region), - BOUND : (_L, inp_in_bound), - REGION_NODES : (_L, inp_in_regionnodes), - LABELS : (_L, inp_in_label), - BACKDROP : (_S, inp_in_backdrop), - #END : 'END', + TITLE: (_S, inp_in_title), + JUNCTIONS: (_L, inp_in_junction), # line, demand_outside + RESERVOIRS: (_L, inp_in_reservoir), + TANKS: (_L, inp_in_tank), + PIPES: (_L, inp_in_pipe), + PUMPS: (_L, inp_in_pump), + VALVES: (_L, inp_in_valve), + TAGS: (_L, inp_in_tag), + DEMANDS: (_L, inp_in_demand), + STATUS: (_L, inp_in_status), + PATTERNS: (_L, inp_in_pattern), # line, fixed + CURVES: (_L, inp_in_curve), + CONTROLS: (_L, inp_in_control), + RULES: (_L, inp_in_rule), + ENERGY: (_L, inp_in_energy), + EMITTERS: (_L, inp_in_emitter), + QUALITY: (_L, inp_in_quality), + SOURCES: (_L, inp_in_source), + REACTIONS: (_L, inp_in_reaction), + MIXING: (_L, inp_in_mixing), + TIMES: (_S, inp_in_time), + REPORT: (_S, inp_in_report), + OPTIONS: (_S, _inp_in_option), # line, version + COORDINATES: (_L, inp_in_coord), + VERTICES: (_L, inp_in_vertex), + REGION: (_L, inp_in_region), + BOUND: (_L, inp_in_bound), + REGION_NODES: (_L, inp_in_regionnodes), + LABELS: (_L, inp_in_label), + BACKDROP: (_S, inp_in_backdrop), + # END : 'END', } _level_1 = [ @@ -120,14 +122,16 @@ _level_4 = [ REGION_NODES, ] -map_regiontype={ +map_regiontype = { # map the region types from desktop to server - 'DISTRIBUTION':'WDA', - 'DMA':'DMA', - 'PMA':'PMA', - 'VD':'VD', - 'SA':'SA', + "DISTRIBUTION": "WDA", + "DMA": "DMA", + "PMA": "PMA", + "VD": "VD", + "SA": "SA", } + + class SQLBatch: def __init__(self, project: str, count: int = 100) -> None: self.batch: list[str] = [] @@ -140,13 +144,13 @@ class SQLBatch: self.flush() def flush(self) -> None: - write(self.project, ''.join(self.batch)) + write(self.project, "".join(self.batch)) self.batch.clear() def _print_time(desc: str) -> datetime.datetime: now = datetime.datetime.now() - time = now.strftime('%Y-%m-%d %H:%M:%S') + time = now.strftime("%Y-%m-%d %H:%M:%S") print(f"{time}: {desc}") return now @@ -154,7 +158,7 @@ def _print_time(desc: str) -> datetime.datetime: def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]: offset: dict[str, list[int]] = {} - current = '' + current = "" demand_outside = False with open(inp) as f: @@ -164,22 +168,22 @@ def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]: break line = line.strip() - if line.startswith('['): + if line.startswith("["): for s in section_name: - if line.startswith(f'[{s}'): + if line.startswith(f"[{s}"): if s not in offset: offset[s] = [] offset[s].append(f.tell()) current = s break - elif line != '' and line.startswith(';') == False: + elif line != "" and line.startswith(";") == False: if current == DEMANDS: demand_outside = True - + return (offset, demand_outside) -def parse_file(project: str, inp: str, version: str = '3') -> None: +def parse_file(project: str, inp: str, version: str = "3") -> None: start = _print_time(f'Start reading file "{inp}"...') _print_time("First scan...") @@ -188,7 +192,7 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: levels = _level_1 + _level_2 + _level_3 + _level_4 # parse the whole section rather than line - sections : dict[str, list[str]]= {} + sections: dict[str, list[str]] = {} for [s, t] in _handler.items(): if t[0] == _S: sections[s] = [] @@ -197,13 +201,13 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: current_pattern = None current_curve = None curve_type_desc_line = None - current_region =None - current_bound=[] + current_region = None + current_bound = [] current_bound.clear() - region_list={} - current_region_nodes=[] + region_list = {} + current_region_nodes = [] current_region_nodes.clear() - + sql_batch = SQLBatch(project) _print_time("Second scan...") with open(inp) as f: @@ -228,82 +232,101 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: break line = line.strip() - if line.startswith('['): + if line.startswith("["): break - elif line == '': + elif line == "": continue if is_s: sections[s].append(line) else: - if line.startswith(';'): - if version != '3': #v2 - line = line.removeprefix(';') - if s == PATTERNS: # ;desc + if line.startswith(";"): + if version != "3": # v2 + line = line.removeprefix(";") + if s == PATTERNS: # ;desc pass - elif s == CURVES: # ;type: desc + elif s == CURVES: # ;type: desc curve_type_desc_line = line continue if s == PATTERNS: tokens = line.split() - if tokens[1].upper() in pattern_v3_types: #v3 - sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") + if tokens[1].upper() in pattern_v3_types: # v3 + sql_batch.add( + f"insert into _pattern (id) values ('{tokens[0]}');" + ) current_pattern = tokens[0] - if tokens[1].upper() == 'VARIABLE': + if tokens[1].upper() == "VARIABLE": variable_patterns.append(tokens[0]) continue if current_pattern != tokens[0]: - sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');") + sql_batch.add( + f"insert into _pattern (id) values ('{tokens[0]}');" + ) current_pattern = tokens[0] elif s == CURVES: tokens = line.split() - if tokens[1].upper() in curve_types: #v3 - sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');") + if tokens[1].upper() in curve_types: # v3 + sql_batch.add( + f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');" + ) current_curve = tokens[0] continue if current_curve != tokens[0]: type = curve_types[0] if curve_type_desc_line != None: - type = curve_type_desc_line.split(':')[0].strip() - sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") + type = curve_type_desc_line.split(":")[0].strip() + sql_batch.add( + f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');" + ) current_curve = tokens[0] curve_type_desc_line = None - elif s== REGION: + elif s == REGION: tokens = line.split() - region_list[tokens[0]]=tokens[1] + region_list[tokens[0]] = tokens[1] elif s == BOUND: tokens = line.split() - if(tokens[0]!=current_region and len(current_bound)>0): - #insert the previous region after get all the vertex of the attatched geometry + if tokens[0] != current_region and len(current_bound) > 0: + # insert the previous region after get all the vertex of the attatched geometry current_bound.append(current_bound[0]) - current_geometry=to_postgis_polygon(current_bound) - region_type=map_regiontype[region_list[tokens[0]]] - sql_batch.add(f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');") - #start the new region + current_geometry = to_postgis_polygon(current_bound) + region_type = map_regiontype[region_list[tokens[0]]] + sql_batch.add( + f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');" + ) + # start the new region current_bound.clear() - vertex_point=(float(tokens[1]),float(tokens[2])) + vertex_point = (float(tokens[1]), float(tokens[2])) current_bound.append(vertex_point) - current_region=tokens[0] - elif s==REGION_NODES: + current_region = tokens[0] + elif s == REGION_NODES: tokens = line.split() - if(tokens[0]!=current_region and len(current_region_nodes)>0): - #insert the previous region after get all the vertex of the attatched geometry - sql_batch.add(get_insert_into_region_sql(current_region,current_region_nodes)) - #start the new region + if ( + tokens[0] != current_region + and len(current_region_nodes) > 0 + ): + # insert the previous region after get all the vertex of the attatched geometry + sql_batch.add( + get_insert_into_region_sql( + current_region, current_region_nodes + ) + ) + # start the new region current_region_nodes.clear() current_region_nodes.append(tokens[1]) - current_region=tokens[0] + current_region = tokens[0] if s == JUNCTIONS: sql_batch.add(handler(line, demand_outside)) elif s == PATTERNS: - sql_batch.add(handler(line, current_pattern not in variable_patterns)) - elif s==BOUND or s==REGION_NODES: + sql_batch.add( + handler(line, current_pattern not in variable_patterns) + ) + elif s == BOUND or s == REGION_NODES: continue else: sql_batch.add(handler(line)) @@ -315,114 +338,122 @@ def parse_file(project: str, inp: str, version: str = '3') -> None: sql_batch.add(handler(sections[s], version)) else: sql_batch.add(handler(sections[s])) - #need to insert the last region into database - if len(current_bound)>0: + # need to insert the last region into database + if len(current_bound) > 0: current_bound.append(current_bound[0]) - current_geometry=to_postgis_polygon(current_bound) - region_type=map_regiontype[region_list[current_region]] - sql_batch.add(f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');") - #reset the current region to none for the [REGION_NODES] session reading - #current_region=None - #need to insert the last region_nodes into database - if len(current_region_nodes)>0: - sql_batch.add(get_insert_into_region_sql(current_region,current_region_nodes)) - #current_region=None + current_geometry = to_postgis_polygon(current_bound) + region_type = map_regiontype[region_list[current_region]] + sql_batch.add( + f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');" + ) + # reset the current region to none for the [REGION_NODES] session reading + # current_region=None + # need to insert the last region_nodes into database + if len(current_region_nodes) > 0: + sql_batch.add( + get_insert_into_region_sql(current_region, current_region_nodes) + ) + # current_region=None sql_batch.flush() end = _print_time(f'End reading file "{inp}"') print(f"Total (in second): {(end-start).seconds}(s)") -def get_insert_into_region_sql(region:str,nodes:list[str])->str: - str_sql='' + +def get_insert_into_region_sql(region: str, nodes: list[str]) -> str: + str_sql = "" str_nodes = str(nodes).replace("'", "''") - r_type=region[0:region.index('_')] - if r_type == 'DMA' or r_type == 'SA' or r_type == 'VD': - table = '' - if r_type == 'DMA': - table = 'region_dma' - elif r_type == 'SA': - table = 'region_sa' - source=region[region.index('_')+1:] - str_sql=f"insert into region_sa(id,time_index,source,nodes) values ('{region}', 0,'{source}','{str_nodes}');" - elif r_type == 'VD': - table = 'region_vd' + r_type = region[0 : region.index("_")] + if r_type == "DMA" or r_type == "SA" or r_type == "VD": + table = "" + if r_type == "DMA": + table = "region_dma" + elif r_type == "SA": + table = "region_sa" + source = region[region.index("_") + 1 :] + str_sql = f"insert into region_sa(id,time_index,source,nodes) values ('{region}', 0,'{source}','{str_nodes}');" + elif r_type == "VD": + table = "region_vd" return str_sql -def read_inp(project: str, inp: str, version: str = '3') -> bool: - if version != '3' and version != '2': - version = '2' + +def read_inp(project: str, inp: str, version: str = "3") -> bool: + if version != "3" and version != "2": + version = "2" if is_project_open(project): - close_project(project) + close_project(project) if have_project(project): - delete_project(project) + delete_project(project) create_project(project) open_project(project) parse_file(project, inp, version) - '''try: + """try: parse_file(project, inp, version) except: close_project(project) delete_project(project) - return False''' + return False""" close_project(project) return True -#DingZQ, 2024-12-28, convert v3 to v2 + +# DingZQ, 2024-12-28, convert v3 to v2 def convert_inp_v3_to_v2(inp: str) -> ChangeSet: - project = 'v3Tov2' + project = "v3Tov2" if is_project_open(project): - close_project(project) + close_project(project) if have_project(project): - delete_project(project) + delete_project(project) create_project(project) open_project(project) - filename = f'inp/{project}_temp.inp' + filename = f"inp/{project}_temp.inp" if os.path.exists(filename): os.remove(filename) - with open(filename, 'w') as f: + with open(filename, "w") as f: f.write(inp) - - parse_file(project, filename, '3') - '''try: + parse_file(project, filename, "3") + + """try: parse_file(project, inp, version) except: close_project(project) delete_project(project) - return False''' + return False""" - return export_inp(project, '2') + return export_inp(project, "2") -def import_inp(project: str, cs: ChangeSet, version: str = '3') -> bool: - if version != '3' and version != '2': - version = '2' - if 'inp' not in cs.operations[0]: +def import_inp(project: str, cs: ChangeSet, version: str = "3") -> bool: + if version != "3" and version != "2": + version = "2" + + if "inp" not in cs.operations[0]: return False - filename = f'inp/{project}_temp.inp' + filename = f"inp/{project}_temp.inp" if os.path.exists(filename): os.remove(filename) _print_time(f'Start writing temp file "{filename}"...') - with open(filename, 'w',encoding="GBK") as f: - f.write(str(cs.operations[0]['inp'])) + with open(filename, "w", encoding="GBK") as f: + f.write(str(cs.operations[0]["inp"])) _print_time(f'End writing temp file "{filename}"...') result = read_inp(project, filename, version) - #os.remove(filename) + # os.remove(filename) return result diff --git a/app/native/wndb/inp_out.py b/app/native/wndb/inp_out.py index 6cf3f0d..aa7de7e 100644 --- a/app/native/wndb/inp_out.py +++ b/app/native/wndb/inp_out.py @@ -1,5 +1,5 @@ import os -from .project_backup import * +from .project import * from .database import ChangeSet from .sections import * from .s1_title import inp_out_title diff --git a/app/native/wndb/s34_sa_cal.py b/app/native/wndb/s34_sa_cal.py index 4304b6d..025b4c1 100644 --- a/app/native/wndb/s34_sa_cal.py +++ b/app/native/wndb/s34_sa_cal.py @@ -1,6 +1,6 @@ import os import ctypes -from .project_backup import have_project +from .project import have_project from .inp_out import dump_inp def calculate_service_area(name: str) -> list[dict[str, list[str]]]: