67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
from .database import *
|
|
from .s0_base import get_node_links
|
|
|
|
|
|
def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, list[Any]]:
|
|
write(name, 'delete from temp_vd_topology')
|
|
|
|
# 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'])]
|
|
target = node_index[str(pipe['node2'])]
|
|
cost = float(pipe['length'])
|
|
write(name, f"insert into temp_vd_topology (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 temp_vd_topology (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 temp_vd_topology (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():
|
|
if node == center:
|
|
node_distance[node] = { 'center': center, 'distance' : 0.0 }
|
|
continue
|
|
# TODO: check none
|
|
distance = float(read(name, f"select max(agg_cost) as distance from pgr_dijkstraCost('select id, source, target, cost from temp_vd_topology', {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, 'delete from temp_vd_topology')
|
|
|
|
# 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)
|
|
|
|
vds: list[dict[str, Any]] = []
|
|
|
|
for center, value in center_node.items():
|
|
vds.append({ 'center': center, 'nodes': value })
|
|
|
|
return { 'virtual_districts': vds, 'isolated_nodes': isolated_nodes }
|