From e0b6ce75596bc42a200b80da0c61125ecbb8b8fe Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 31 Mar 2023 09:55:06 +0800 Subject: [PATCH] Start region work --- api/__init__.py | 2 + api/s24_coordinates.py | 2 +- api/s32_virtual_district.py | 65 +++++++++++++++++++++++ script/sql/create/24.coordinates.sql | 3 +- script/sql/create/32.virtual_district.sql | 9 ++++ script/sql/drop/24.coordinates.sql | 2 - script/sql/drop/32.virtual_district.sql | 3 ++ tjnetwork.py | 8 +++ 8 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 api/s32_virtual_district.py create mode 100644 script/sql/create/32.virtual_district.sql create mode 100644 script/sql/drop/32.virtual_district.sql diff --git a/api/__init__.py b/api/__init__.py index 02f4cc8..1b04041 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -130,3 +130,5 @@ from .del_cmd import clean_scada_device_data from .s31_scada_element import SCADA_ELEMENT_STATUS_OFFLINE, SCADA_ELEMENT_STATUS_ONLINE 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 diff --git a/api/s24_coordinates.py b/api/s24_coordinates.py index 6c54245..03952af 100644 --- a/api/s24_coordinates.py +++ b/api/s24_coordinates.py @@ -24,7 +24,7 @@ def get_node_coord(name: str, id: str) -> dict[str, float]: def inp_in_coord(line: str) -> str: tokens = line.split() node = tokens[0] - coord = f"'({tokens[1]}, {tokens[2]})'" + coord = f"st_geomfromtext('point({tokens[1]} {tokens[2]})')" return f"insert into coordinates (node, coord) values ('{node}', {coord});" diff --git a/api/s32_virtual_district.py b/api/s32_virtual_district.py new file mode 100644 index 0000000..a166815 --- /dev/null +++ b/api/s32_virtual_district.py @@ -0,0 +1,65 @@ +from .database import * + + +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 + + write(name, 'drop table if exists vd_graph') + write(name, 'create table vd_graph (id serial, source integer, target integer, cost numeric)') + + pipes = read_all(name, 'select node1, node2, length from pipes') + for pipe in pipes: + source = node_index[str(pipe['node1'])] + target = node_index[str(pipe['node2'])] + cost = float(pipe['length']) + write(name, f"insert into vd_graph (source, target, cost) values ({source}, {target}, {cost})") + pumps = read_all(name, 'select node1, node2 from pumps') + for pump in pumps: + source = node_index[str(pump['node1'])] + target = node_index[str(pump['node2'])] + write(name, f"insert into vd_graph (source, target, cost) values ({source}, {target}, 0.0)") + valves = read_all(name, 'select node1, node2 from valves') + for valve in valves: + source = node_index[str(valve['node1'])] + target = node_index[str(valve['node2'])] + write(name, f"insert into vd_graph (source, target, cost) values ({source}, {target}, 0.0)") + + node_distance: dict[str, dict[str, Any]] = {} + for center in centers: + for node, index in node_index.items(): + if node == center: + continue + # TODO: check none + distance = float(read(name, f"select max(agg_cost) as distance from pgr_dijkstraCost('select id, source, target, cost from vd_graph', {index}, {node_index[center]}, false)")['distance']) + if node not in node_distance: + node_distance[node] = { 'center': center, 'distance' : distance } + elif distance < node_distance[node]['distance']: + node_distance[node] = { 'center': center, 'distance' : distance } + + write(name, 'drop table vd_graph') + + 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') + + for center, value in center_node.items(): + write(name, f'drop table if exists vd_{center}') + write(name, f'create table vd_{center} (node varchar(32) primary key references _node(id))') + + for node in value: + write(name, f"insert into vd_{center} values ('{node}')") + + # 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'drop table vd_{center}') diff --git a/script/sql/create/24.coordinates.sql b/script/sql/create/24.coordinates.sql index 692bca7..945acef 100644 --- a/script/sql/create/24.coordinates.sql +++ b/script/sql/create/24.coordinates.sql @@ -3,10 +3,9 @@ create table coordinates ( node varchar(32) primary key references _node(id) -, coord point not null +, coord geometry ); -- delete when delete node -create index coordinates_spgist on coordinates using spgist(coord); create index coordinates_gist on coordinates using gist(coord); diff --git a/script/sql/create/32.virtual_district.sql b/script/sql/create/32.virtual_district.sql new file mode 100644 index 0000000..12edec0 --- /dev/null +++ b/script/sql/create/32.virtual_district.sql @@ -0,0 +1,9 @@ +create table virtual_district +( + id text primary key +, center varchar(32) references _node(id) not null unique +, boundary geometry unique +, nodes varchar(32)[] +); + +create index virtual_district_gist on virtual_district using gist(boundary); diff --git a/script/sql/drop/24.coordinates.sql b/script/sql/drop/24.coordinates.sql index b7f86b0..00c63ee 100644 --- a/script/sql/drop/24.coordinates.sql +++ b/script/sql/drop/24.coordinates.sql @@ -2,6 +2,4 @@ drop index if exists coordinates_gist; -drop index if exists coordinates_spgist; - drop table if exists coordinates; diff --git a/script/sql/drop/32.virtual_district.sql b/script/sql/drop/32.virtual_district.sql new file mode 100644 index 0000000..33921c1 --- /dev/null +++ b/script/sql/drop/32.virtual_district.sql @@ -0,0 +1,3 @@ +drop index if exists virtual_district_gist; + +drop table if exists virtual_district; diff --git a/tjnetwork.py b/tjnetwork.py index d291b6e..856d01a 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -921,3 +921,11 @@ def delete_scada_element(name: str, cs: ChangeSet) -> ChangeSet: def clean_scada_element(name: str) -> ChangeSet: return api.clean_scada_element(name) + + +############################################################ +# virtual_district 32 +############################################################ + +def generate_virtual_district(name: str, centers: list[str]): + return api.generate_virtual_district(name, centers)