Support water distribution
This commit is contained in:
@@ -2,8 +2,9 @@ import ctypes
|
||||
import platform
|
||||
import os
|
||||
import math
|
||||
import collections
|
||||
from .s0_base import get_node_links, get_link_nodes
|
||||
from typing import Any
|
||||
from .s0_base import get_node_links, get_link_nodes, is_pipe
|
||||
from .s5_pipes import get_pipe
|
||||
from .database import read, try_read, read_all, write
|
||||
from .s24_coordinates import node_has_coord, get_node_coord
|
||||
|
||||
@@ -89,35 +90,53 @@ def _angle_of_node_link(node: str, link: str, nodes, links) -> float:
|
||||
return _angle(v)
|
||||
|
||||
|
||||
class Topology:
|
||||
def __init__(self, db: str, nodes: list[str]) -> None:
|
||||
self._nodes: dict[str, Any] = {}
|
||||
self._max_x_node = ''
|
||||
for node in nodes:
|
||||
if not node_has_coord(db, node):
|
||||
continue
|
||||
if get_node_links(db, node) == 0:
|
||||
continue
|
||||
self._nodes[node] = get_node_coord(db, node) | { 'links': [] }
|
||||
if self._max_x_node == '' or self._nodes[node]['x'] > self._nodes[self._max_x_node]['x']:
|
||||
self._max_x_node = node
|
||||
|
||||
self._links = {}
|
||||
for node in self._nodes:
|
||||
for link in get_node_links(db, node):
|
||||
candidate = True
|
||||
link_nodes = get_link_nodes(db, link)
|
||||
for link_node in link_nodes:
|
||||
if link_node not in self._nodes:
|
||||
candidate = False
|
||||
break
|
||||
if candidate:
|
||||
length = get_pipe(db, link)['length'] if is_pipe(db, link) else 0.0
|
||||
self._links[link] = { 'node1' : link_nodes[0], 'node2' : link_nodes[1], 'length' : length }
|
||||
|
||||
if link not in self._nodes[link_nodes[0]]['links']:
|
||||
self._nodes[link_nodes[0]]['links'].append(link)
|
||||
if link not in self._nodes[link_nodes[1]]['links']:
|
||||
self._nodes[link_nodes[1]]['links'].append(link)
|
||||
|
||||
def nodes(self):
|
||||
return self._nodes
|
||||
|
||||
def max_x_node(self):
|
||||
return self._max_x_node
|
||||
|
||||
def links(self):
|
||||
return self._links
|
||||
|
||||
|
||||
def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]:
|
||||
new_nodes = {}
|
||||
max_x_node = ''
|
||||
for node in nodes:
|
||||
if not node_has_coord(name, node):
|
||||
continue
|
||||
if get_node_links(name, node) == 0:
|
||||
continue
|
||||
new_nodes[node] = get_node_coord(name, node) | { 'links': [] }
|
||||
if max_x_node == '' or new_nodes[node]['x'] > new_nodes[max_x_node]['x']:
|
||||
max_x_node = node
|
||||
topology = Topology(name, nodes)
|
||||
t_nodes = topology.nodes()
|
||||
t_links = topology.links()
|
||||
|
||||
new_links = {}
|
||||
for node in new_nodes:
|
||||
for link in get_node_links(name, node):
|
||||
candidate = True
|
||||
link_nodes = get_link_nodes(name, link)
|
||||
for link_node in link_nodes:
|
||||
if link_node not in new_nodes:
|
||||
candidate = False
|
||||
break
|
||||
if candidate:
|
||||
new_links[link] = { 'node1' : link_nodes[0], 'node2' : link_nodes[1] }
|
||||
if link not in new_nodes[link_nodes[0]]['links']:
|
||||
new_nodes[link_nodes[0]]['links'].append(link)
|
||||
if link not in new_nodes[link_nodes[1]]['links']:
|
||||
new_nodes[link_nodes[1]]['links'].append(link)
|
||||
|
||||
cursor = max_x_node
|
||||
cursor = topology.max_x_node()
|
||||
in_angle = 0
|
||||
|
||||
paths: list[str] = []
|
||||
@@ -125,8 +144,8 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]
|
||||
paths.append(cursor)
|
||||
sorted_links = []
|
||||
overlapped_link = ''
|
||||
for link in new_nodes[cursor]['links']:
|
||||
angle = _angle_of_node_link(cursor, link, new_nodes, new_links)
|
||||
for link in t_nodes[cursor]['links']:
|
||||
angle = _angle_of_node_link(cursor, link, t_nodes, t_links)
|
||||
if angle == in_angle:
|
||||
overlapped_link = link
|
||||
continue
|
||||
@@ -135,7 +154,7 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]
|
||||
# work into a branch, return
|
||||
if len(sorted_links) == 0:
|
||||
cursor = paths[-2]
|
||||
in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, new_nodes, new_links)
|
||||
in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links)
|
||||
continue
|
||||
|
||||
sorted_links = sorted(sorted_links, key=lambda s:s[0])
|
||||
@@ -145,17 +164,17 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]
|
||||
out_link = link
|
||||
break
|
||||
|
||||
cursor = new_links[out_link]['node1'] if cursor == new_links[out_link]['node2'] else new_links[out_link]['node2']
|
||||
cursor = t_links[out_link]['node1'] if cursor == t_links[out_link]['node2'] else t_links[out_link]['node2']
|
||||
# end up trip :)
|
||||
if cursor == max_x_node:
|
||||
if cursor == topology.max_x_node():
|
||||
paths.append(cursor)
|
||||
break
|
||||
|
||||
in_angle = _angle_of_node_link(cursor, out_link, new_nodes, new_links)
|
||||
in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links)
|
||||
|
||||
boundary: list[tuple[float, float]] = []
|
||||
for node in paths:
|
||||
boundary.append((new_nodes[node]['x'], new_nodes[node]['y']))
|
||||
boundary.append((t_nodes[node]['x'], t_nodes[node]['y']))
|
||||
|
||||
return boundary
|
||||
|
||||
|
||||
Reference in New Issue
Block a user