From a62700d27e0fa2e84ec037dcff71f9e0f1a75112 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Sat, 29 Apr 2023 11:11:05 +0800 Subject: [PATCH] Support to calculate virtual district --- api/__init__.py | 2 +- api/s32_virtual_district.py | 43 +++++++++++++++++++++++++++---------- tjnetwork.py | 4 ++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/api/__init__.py b/api/__init__.py index a3e264d..de43ec5 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -132,4 +132,4 @@ from .s31_scada_element import SCADA_ELEMENT_STATUS_OFFLINE, SCADA_ELEMENT_STATU from .s31_scada_element import get_scada_element_schema, get_scada_elements, get_scada_element, set_scada_element, add_scada_element, delete_scada_element from .del_cmd import clean_scada_element -from .s32_virtual_district import generate_virtual_district \ No newline at end of file +from .s32_virtual_district import calculate_virtual_district \ No newline at end of file diff --git a/api/s32_virtual_district.py b/api/s32_virtual_district.py index a166815..85b8585 100644 --- a/api/s32_virtual_district.py +++ b/api/s32_virtual_district.py @@ -1,17 +1,23 @@ from .database import * +from .s0_base import get_node_links - -def generate_virtual_district(name: str, centers: list[str]): - i = 0 - node_index: dict[str, int] = {} - rows = read_all(name, 'select id from _node') - for row in rows: - i += 1 - node_index[str(row['id'])] = i - +def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, Any]: write(name, 'drop table if exists vd_graph') write(name, 'create table vd_graph (id serial, source integer, target integer, cost numeric)') + # map node name to index + i = 0 + isolated_nodes = [] + node_index: dict[str, int] = {} + for row in read_all(name, 'select id from _node'): + node = str(row['id']) + if get_node_links(name, node) == []: + isolated_nodes.append(node) + continue + i += 1 + node_index[node] = i + + # build topology graph pipes = read_all(name, 'select node1, node2, length from pipes') for pipe in pipes: source = node_index[str(pipe['node1'])] @@ -29,6 +35,7 @@ def generate_virtual_district(name: str, centers: list[str]): target = node_index[str(valve['node2'])] write(name, f"insert into vd_graph (source, target, cost) values ({source}, {target}, 0.0)") + # dijkstra distance node_distance: dict[str, dict[str, Any]] = {} for center in centers: for node, index in node_index.items(): @@ -41,15 +48,18 @@ def generate_virtual_district(name: str, centers: list[str]): elif distance < node_distance[node]['distance']: node_distance[node] = { 'center': center, 'distance' : distance } + # destroy topology graph write(name, 'drop table vd_graph') + # reorganize the distance result center_node: dict[str, list[str]] = {} for node, value in node_distance.items(): if value['center'] not in center_node: center_node[value['center']] = [] center_node[value['center']].append(node) - write(name, 'delete from virtual_district') + # write(name, 'delete from virtual_district') + vds: list[dict[str, Any]] = [] for center, value in center_node.items(): write(name, f'drop table if exists vd_{center}') @@ -60,6 +70,17 @@ def generate_virtual_district(name: str, centers: list[str]): # TODO: check none boundary = read(name, f'select st_astext(st_convexhull(st_collect(array(select coord from coordinates where node in (select * from vd_{center}))))) as boundary' )['boundary'] - write(name, f"insert into virtual_district (id, center, boundary) values ('vd_{center}', '{center}', st_geomfromtext('{boundary}'))") + # write(name, f"insert into virtual_district (id, center, boundary) values ('vd_{center}', '{center}', st_geomfromtext('{boundary}'))") + + outlines = str(boundary).removeprefix('POLYGON((').removesuffix('))').split(',') + outline_tuples = [] + for pt in outlines: + xy = pt.split(' ') + outline_tuples.append((float(xy[0]), float(xy[1]))) + + vd = { 'center': center, 'nodes': value, 'boundary': outline_tuples } + vds.append(vd) write(name, f'drop table vd_{center}') + + return { 'virtual_districts': vds, 'isolated_nodes': isolated_nodes } diff --git a/tjnetwork.py b/tjnetwork.py index 3f4e5d3..b84f50d 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -939,5 +939,5 @@ def clean_scada_element(name: str) -> ChangeSet: # virtual_district 32 ############################################################ -def generate_virtual_district(name: str, centers: list[str]): - return api.generate_virtual_district(name, centers) +def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, Any]: + return api.calculate_virtual_district(name, centers)