修复引用错误

This commit is contained in:
2026-03-09 18:11:24 +08:00
parent 0d8a7f5cb7
commit 7345210bdd
3 changed files with 176 additions and 145 deletions
+171 -140
View File
@@ -1,6 +1,6 @@
import datetime import datetime
import os import os
from .project_backup import * from .project import *
from .database import ChangeSet, write from .database import ChangeSet, write
from .sections import * from .sections import *
from .s0_base import get_region_type 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 .s9_demands import inp_in_demand
from .s10_status import inp_in_status from .s10_status import inp_in_status
from .s11_patterns import pattern_v3_types, inp_in_pattern 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 .s13_controls import inp_in_control
from .s14_rules import inp_in_rule from .s14_rules import inp_in_rule
from .s15_energy import inp_in_energy 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 .s25_vertices import inp_in_vertex
from .s26_labels import inp_in_label from .s26_labels import inp_in_label
from .s27_backdrop import inp_in_backdrop from .s27_backdrop import inp_in_backdrop
from .s32_region import inp_in_region,inp_in_bound,inp_in_regionnodes 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_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 from .inp_out import export_inp
_S = 'S' _S = "S"
_L = 'L' _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 = { _handler = {
TITLE : (_S, inp_in_title), TITLE: (_S, inp_in_title),
JUNCTIONS : (_L, inp_in_junction), # line, demand_outside JUNCTIONS: (_L, inp_in_junction), # line, demand_outside
RESERVOIRS : (_L, inp_in_reservoir), RESERVOIRS: (_L, inp_in_reservoir),
TANKS : (_L, inp_in_tank), TANKS: (_L, inp_in_tank),
PIPES : (_L, inp_in_pipe), PIPES: (_L, inp_in_pipe),
PUMPS : (_L, inp_in_pump), PUMPS: (_L, inp_in_pump),
VALVES : (_L, inp_in_valve), VALVES: (_L, inp_in_valve),
TAGS : (_L, inp_in_tag), TAGS: (_L, inp_in_tag),
DEMANDS : (_L, inp_in_demand), DEMANDS: (_L, inp_in_demand),
STATUS : (_L, inp_in_status), STATUS: (_L, inp_in_status),
PATTERNS : (_L, inp_in_pattern), # line, fixed PATTERNS: (_L, inp_in_pattern), # line, fixed
CURVES : (_L, inp_in_curve), CURVES: (_L, inp_in_curve),
CONTROLS : (_L, inp_in_control), CONTROLS: (_L, inp_in_control),
RULES : (_L, inp_in_rule), RULES: (_L, inp_in_rule),
ENERGY : (_L, inp_in_energy), ENERGY: (_L, inp_in_energy),
EMITTERS : (_L, inp_in_emitter), EMITTERS: (_L, inp_in_emitter),
QUALITY : (_L, inp_in_quality), QUALITY: (_L, inp_in_quality),
SOURCES : (_L, inp_in_source), SOURCES: (_L, inp_in_source),
REACTIONS : (_L, inp_in_reaction), REACTIONS: (_L, inp_in_reaction),
MIXING : (_L, inp_in_mixing), MIXING: (_L, inp_in_mixing),
TIMES : (_S, inp_in_time), TIMES: (_S, inp_in_time),
REPORT : (_S, inp_in_report), REPORT: (_S, inp_in_report),
OPTIONS : (_S, _inp_in_option), # line, version OPTIONS: (_S, _inp_in_option), # line, version
COORDINATES : (_L, inp_in_coord), COORDINATES: (_L, inp_in_coord),
VERTICES : (_L, inp_in_vertex), VERTICES: (_L, inp_in_vertex),
REGION : (_L, inp_in_region), REGION: (_L, inp_in_region),
BOUND : (_L, inp_in_bound), BOUND: (_L, inp_in_bound),
REGION_NODES : (_L, inp_in_regionnodes), REGION_NODES: (_L, inp_in_regionnodes),
LABELS : (_L, inp_in_label), LABELS: (_L, inp_in_label),
BACKDROP : (_S, inp_in_backdrop), BACKDROP: (_S, inp_in_backdrop),
#END : 'END', # END : 'END',
} }
_level_1 = [ _level_1 = [
@@ -120,14 +122,16 @@ _level_4 = [
REGION_NODES, REGION_NODES,
] ]
map_regiontype={ map_regiontype = {
# map the region types from desktop to server # map the region types from desktop to server
'DISTRIBUTION':'WDA', "DISTRIBUTION": "WDA",
'DMA':'DMA', "DMA": "DMA",
'PMA':'PMA', "PMA": "PMA",
'VD':'VD', "VD": "VD",
'SA':'SA', "SA": "SA",
} }
class SQLBatch: class SQLBatch:
def __init__(self, project: str, count: int = 100) -> None: def __init__(self, project: str, count: int = 100) -> None:
self.batch: list[str] = [] self.batch: list[str] = []
@@ -140,13 +144,13 @@ class SQLBatch:
self.flush() self.flush()
def flush(self) -> None: def flush(self) -> None:
write(self.project, ''.join(self.batch)) write(self.project, "".join(self.batch))
self.batch.clear() self.batch.clear()
def _print_time(desc: str) -> datetime.datetime: def _print_time(desc: str) -> datetime.datetime:
now = datetime.datetime.now() 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}") print(f"{time}: {desc}")
return now 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]: def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]:
offset: dict[str, list[int]] = {} offset: dict[str, list[int]] = {}
current = '' current = ""
demand_outside = False demand_outside = False
with open(inp) as f: with open(inp) as f:
@@ -164,22 +168,22 @@ def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]:
break break
line = line.strip() line = line.strip()
if line.startswith('['): if line.startswith("["):
for s in section_name: for s in section_name:
if line.startswith(f'[{s}'): if line.startswith(f"[{s}"):
if s not in offset: if s not in offset:
offset[s] = [] offset[s] = []
offset[s].append(f.tell()) offset[s].append(f.tell())
current = s current = s
break break
elif line != '' and line.startswith(';') == False: elif line != "" and line.startswith(";") == False:
if current == DEMANDS: if current == DEMANDS:
demand_outside = True demand_outside = True
return (offset, demand_outside) 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}"...') start = _print_time(f'Start reading file "{inp}"...')
_print_time("First scan...") _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 levels = _level_1 + _level_2 + _level_3 + _level_4
# parse the whole section rather than line # parse the whole section rather than line
sections : dict[str, list[str]]= {} sections: dict[str, list[str]] = {}
for [s, t] in _handler.items(): for [s, t] in _handler.items():
if t[0] == _S: if t[0] == _S:
sections[s] = [] sections[s] = []
@@ -197,11 +201,11 @@ def parse_file(project: str, inp: str, version: str = '3') -> None:
current_pattern = None current_pattern = None
current_curve = None current_curve = None
curve_type_desc_line = None curve_type_desc_line = None
current_region =None current_region = None
current_bound=[] current_bound = []
current_bound.clear() current_bound.clear()
region_list={} region_list = {}
current_region_nodes=[] current_region_nodes = []
current_region_nodes.clear() current_region_nodes.clear()
sql_batch = SQLBatch(project) sql_batch = SQLBatch(project)
@@ -228,82 +232,101 @@ def parse_file(project: str, inp: str, version: str = '3') -> None:
break break
line = line.strip() line = line.strip()
if line.startswith('['): if line.startswith("["):
break break
elif line == '': elif line == "":
continue continue
if is_s: if is_s:
sections[s].append(line) sections[s].append(line)
else: else:
if line.startswith(';'): if line.startswith(";"):
if version != '3': #v2 if version != "3": # v2
line = line.removeprefix(';') line = line.removeprefix(";")
if s == PATTERNS: # ;desc if s == PATTERNS: # ;desc
pass pass
elif s == CURVES: # ;type: desc elif s == CURVES: # ;type: desc
curve_type_desc_line = line curve_type_desc_line = line
continue continue
if s == PATTERNS: if s == PATTERNS:
tokens = line.split() tokens = line.split()
if tokens[1].upper() in pattern_v3_types: #v3 if tokens[1].upper() in pattern_v3_types: # v3
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] current_pattern = tokens[0]
if tokens[1].upper() == 'VARIABLE': if tokens[1].upper() == "VARIABLE":
variable_patterns.append(tokens[0]) variable_patterns.append(tokens[0])
continue continue
if current_pattern != tokens[0]: 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] current_pattern = tokens[0]
elif s == CURVES: elif s == CURVES:
tokens = line.split() tokens = line.split()
if tokens[1].upper() in curve_types: #v3 if tokens[1].upper() in curve_types: # v3
sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');") sql_batch.add(
f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');"
)
current_curve = tokens[0] current_curve = tokens[0]
continue continue
if current_curve != tokens[0]: if current_curve != tokens[0]:
type = curve_types[0] type = curve_types[0]
if curve_type_desc_line != None: if curve_type_desc_line != None:
type = curve_type_desc_line.split(':')[0].strip() type = curve_type_desc_line.split(":")[0].strip()
sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');") sql_batch.add(
f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');"
)
current_curve = tokens[0] current_curve = tokens[0]
curve_type_desc_line = None curve_type_desc_line = None
elif s== REGION: elif s == REGION:
tokens = line.split() tokens = line.split()
region_list[tokens[0]]=tokens[1] region_list[tokens[0]] = tokens[1]
elif s == BOUND: elif s == BOUND:
tokens = line.split() tokens = line.split()
if(tokens[0]!=current_region and len(current_bound)>0): if tokens[0] != current_region and len(current_bound) > 0:
#insert the previous region after get all the vertex of the attatched geometry # insert the previous region after get all the vertex of the attatched geometry
current_bound.append(current_bound[0]) current_bound.append(current_bound[0])
current_geometry=to_postgis_polygon(current_bound) current_geometry = to_postgis_polygon(current_bound)
region_type=map_regiontype[region_list[tokens[0]]] 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}');") sql_batch.add(
#start the new region f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');"
)
# start the new region
current_bound.clear() 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_bound.append(vertex_point)
current_region=tokens[0] current_region = tokens[0]
elif s==REGION_NODES: elif s == REGION_NODES:
tokens = line.split() tokens = line.split()
if(tokens[0]!=current_region and len(current_region_nodes)>0): if (
#insert the previous region after get all the vertex of the attatched geometry tokens[0] != current_region
sql_batch.add(get_insert_into_region_sql(current_region,current_region_nodes)) and len(current_region_nodes) > 0
#start the new region ):
# 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.clear()
current_region_nodes.append(tokens[1]) current_region_nodes.append(tokens[1])
current_region=tokens[0] current_region = tokens[0]
if s == JUNCTIONS: if s == JUNCTIONS:
sql_batch.add(handler(line, demand_outside)) sql_batch.add(handler(line, demand_outside))
elif s == PATTERNS: elif s == PATTERNS:
sql_batch.add(handler(line, current_pattern not in variable_patterns)) sql_batch.add(
elif s==BOUND or s==REGION_NODES: handler(line, current_pattern not in variable_patterns)
)
elif s == BOUND or s == REGION_NODES:
continue continue
else: else:
sql_batch.add(handler(line)) 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)) sql_batch.add(handler(sections[s], version))
else: else:
sql_batch.add(handler(sections[s])) sql_batch.add(handler(sections[s]))
#need to insert the last region into database # need to insert the last region into database
if len(current_bound)>0: if len(current_bound) > 0:
current_bound.append(current_bound[0]) current_bound.append(current_bound[0])
current_geometry=to_postgis_polygon(current_bound) current_geometry = to_postgis_polygon(current_bound)
region_type=map_regiontype[region_list[current_region]] 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}');") sql_batch.add(
#reset the current region to none for the [REGION_NODES] session reading f"insert into region(id, boundary,r_type) values ('{current_region}', '{current_geometry}','{region_type}');"
#current_region=None )
#need to insert the last region_nodes into database # reset the current region to none for the [REGION_NODES] session reading
if len(current_region_nodes)>0: # current_region=None
sql_batch.add(get_insert_into_region_sql(current_region,current_region_nodes)) # need to insert the last region_nodes into database
#current_region=None 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() sql_batch.flush()
end = _print_time(f'End reading file "{inp}"') end = _print_time(f'End reading file "{inp}"')
print(f"Total (in second): {(end-start).seconds}(s)") 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("'", "''") str_nodes = str(nodes).replace("'", "''")
r_type=region[0:region.index('_')] r_type = region[0 : region.index("_")]
if r_type == 'DMA' or r_type == 'SA' or r_type == 'VD': if r_type == "DMA" or r_type == "SA" or r_type == "VD":
table = '' table = ""
if r_type == 'DMA': if r_type == "DMA":
table = 'region_dma' table = "region_dma"
elif r_type == 'SA': elif r_type == "SA":
table = 'region_sa' table = "region_sa"
source=region[region.index('_')+1:] source = region[region.index("_") + 1 :]
str_sql=f"insert into region_sa(id,time_index,source,nodes) values ('{region}', 0,'{source}','{str_nodes}');" str_sql = f"insert into region_sa(id,time_index,source,nodes) values ('{region}', 0,'{source}','{str_nodes}');"
elif r_type == 'VD': elif r_type == "VD":
table = 'region_vd' table = "region_vd"
return str_sql return str_sql
def read_inp(project: str, inp: str, version: str = '3') -> bool:
if version != '3' and version != '2': def read_inp(project: str, inp: str, version: str = "3") -> bool:
version = '2' if version != "3" and version != "2":
version = "2"
if is_project_open(project): if is_project_open(project):
close_project(project) close_project(project)
if have_project(project): if have_project(project):
delete_project(project) delete_project(project)
create_project(project) create_project(project)
open_project(project) open_project(project)
parse_file(project, inp, version) parse_file(project, inp, version)
'''try: """try:
parse_file(project, inp, version) parse_file(project, inp, version)
except: except:
close_project(project) close_project(project)
delete_project(project) delete_project(project)
return False''' return False"""
close_project(project) close_project(project)
return True 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: def convert_inp_v3_to_v2(inp: str) -> ChangeSet:
project = 'v3Tov2' project = "v3Tov2"
if is_project_open(project): if is_project_open(project):
close_project(project) close_project(project)
if have_project(project): if have_project(project):
delete_project(project) delete_project(project)
create_project(project) create_project(project)
open_project(project) open_project(project)
filename = f'inp/{project}_temp.inp' filename = f"inp/{project}_temp.inp"
if os.path.exists(filename): if os.path.exists(filename):
os.remove(filename) os.remove(filename)
with open(filename, 'w') as f: with open(filename, "w") as f:
f.write(inp) f.write(inp)
parse_file(project, filename, '3') parse_file(project, filename, "3")
'''try: """try:
parse_file(project, inp, version) parse_file(project, inp, version)
except: except:
close_project(project) close_project(project)
delete_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 return False
filename = f'inp/{project}_temp.inp' filename = f"inp/{project}_temp.inp"
if os.path.exists(filename): if os.path.exists(filename):
os.remove(filename) os.remove(filename)
_print_time(f'Start writing temp file "{filename}"...') _print_time(f'Start writing temp file "{filename}"...')
with open(filename, 'w',encoding="GBK") as f: with open(filename, "w", encoding="GBK") as f:
f.write(str(cs.operations[0]['inp'])) f.write(str(cs.operations[0]["inp"]))
_print_time(f'End writing temp file "{filename}"...') _print_time(f'End writing temp file "{filename}"...')
result = read_inp(project, filename, version) result = read_inp(project, filename, version)
#os.remove(filename) # os.remove(filename)
return result return result
+1 -1
View File
@@ -1,5 +1,5 @@
import os import os
from .project_backup import * from .project import *
from .database import ChangeSet from .database import ChangeSet
from .sections import * from .sections import *
from .s1_title import inp_out_title from .s1_title import inp_out_title
+1 -1
View File
@@ -1,6 +1,6 @@
import os import os
import ctypes import ctypes
from .project_backup import have_project from .project import have_project
from .inp_out import dump_inp from .inp_out import dump_inp
def calculate_service_area(name: str) -> list[dict[str, list[str]]]: def calculate_service_area(name: str) -> list[dict[str, list[str]]]: