This commit is contained in:
DingZQ
2023-06-12 23:06:20 +08:00
6 changed files with 692 additions and 520 deletions

View File

@@ -25,6 +25,13 @@ def to_postgis_polygon(boundary: list[tuple[float, float]]) -> str:
return f'polygon(({polygon[:-1]}))' return f'polygon(({polygon[:-1]}))'
def to_postgis_linestring(boundary: list[tuple[float, float]]) -> str:
line = ''
for pt in boundary:
line += f'{pt[0]} {pt[1]},'
return f'linestring({line[:-1]})'
def get_nodes_in_boundary(name: str, boundary: list[tuple[float, float]]) -> list[str]: def get_nodes_in_boundary(name: str, boundary: list[tuple[float, float]]) -> list[str]:
api = 'get_nodes_in_boundary' api = 'get_nodes_in_boundary'
write(name, f"delete from temp_region where id = '{api}'") write(name, f"delete from temp_region where id = '{api}'")
@@ -105,7 +112,7 @@ class Topology:
if self._max_x_node == '' or self._nodes[node]['x'] > self._nodes[self._max_x_node]['x']: if self._max_x_node == '' or self._nodes[node]['x'] > self._nodes[self._max_x_node]['x']:
self._max_x_node = node self._max_x_node = node
self._links = {} self._links: dict[str, Any] = {}
self._link_list: list[str] = [] self._link_list: list[str] = []
for node in self._nodes: for node in self._nodes:
for link in get_node_links(db, node): for link in get_node_links(db, node):
@@ -140,18 +147,22 @@ class Topology:
return self._link_list return self._link_list
def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]: def _calculate_boundary(cursor: str, t_nodes: dict[str, Any], t_links: dict[str, Any]) -> tuple[list[str], dict[str, list[str]], list[tuple[float, float]]]:
topology = Topology(name, nodes)
t_nodes = topology.nodes()
t_links = topology.links()
cursor = topology.max_x_node()
in_angle = 0 in_angle = 0
paths: list[str] = [] vertices: list[str] = []
path: dict[str, list[str]] = {}
while True: while True:
#print(cursor) # prevent duplicated node
paths.append(cursor) if len(vertices) > 0 and cursor == vertices[-1]:
break
# prevent duplicated path
if len(vertices) >= 3 and vertices[0] == vertices[-1] and vertices[1] == cursor:
break
vertices.append(cursor)
sorted_links = [] sorted_links = []
overlapped_link = '' overlapped_link = ''
for link in t_nodes[cursor]['links']: for link in t_nodes[cursor]['links']:
@@ -163,11 +174,9 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]
# work into a branch, return # work into a branch, return
if len(sorted_links) == 0: if len(sorted_links) == 0:
cursor = paths[-2] path[overlapped_link] = []
if cursor == topology.max_x_node(): cursor = vertices[-2]
paths.append(cursor) in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links)
break
in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links)
continue continue
sorted_links = sorted(sorted_links, key=lambda s:s[0]) sorted_links = sorted(sorted_links, key=lambda s:s[0])
@@ -177,18 +186,168 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]
out_link = link out_link = link
break break
path[out_link] = []
cursor = t_links[out_link]['node1'] if cursor == t_links[out_link]['node2'] else t_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 == topology.max_x_node():
paths.append(cursor)
break
in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links) in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links)
boundary: list[tuple[float, float]] = [] boundary: list[tuple[float, float]] = []
for node in paths: for node in vertices:
boundary.append((t_nodes[node]['x'], t_nodes[node]['y'])) boundary.append((t_nodes[node]['x'], t_nodes[node]['y']))
return (vertices, path, boundary)
def _collect_new_links(in_links: dict[str, list[str]], t_nodes: dict[str, Any], t_links: dict[str, Any], new_nodes: dict[str, Any], new_links: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
for link, pts in in_links.items():
node1 = t_links[link]['node1']
node2 = t_links[link]['node2']
x1, x2 = t_nodes[node1]['x'], t_nodes[node2]['x']
y1, y2 = t_nodes[node1]['y'], t_nodes[node2]['y']
if node1 not in new_nodes:
new_nodes[node1] = { 'x': x1, 'y': y1, 'links': [] }
if node2 not in new_nodes:
new_nodes[node2] = { 'x': x2, 'y': y2, 'links': [] }
x_delta = x2 - x1
y_delta = y2 - y1
use_x = abs(x_delta) > abs(y_delta)
if len(pts) == 0:
new_links[link] = t_links[link]
else:
sorted_nodes: list[tuple[float, str]] = []
sorted_nodes.append((0.0, node1))
sorted_nodes.append((1.0, node2))
i = 0
for pt in pts:
x, y = new_nodes[pt]['x'], new_nodes[pt]['y']
percent = ((x - x1) / x_delta) if use_x else ((y - y1) / y_delta)
sorted_nodes.append((percent, pt))
i += 1
sorted_nodes = sorted(sorted_nodes, key=lambda s:s[0])
for i in range(1, len(sorted_nodes)):
l = sorted_nodes[i - 1][1]
r = sorted_nodes[i][1]
new_link = f'LINK_[{l}]_[{r}]'
new_links[new_link] = { 'node1': l, 'node2': r }
return (new_nodes, new_links)
def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]:
topology = Topology(name, nodes)
t_nodes = topology.nodes()
t_links = topology.links()
vertices, path, boundary = _calculate_boundary(topology.max_x_node(), t_nodes, t_links)
#return boundary
api = 'calculate_boundary'
write(name, f"delete from temp_region where id = '{api}'")
# use linestring instead of polygon to reduce strict limitation
# TODO: linestring can not work well
write(name, f"insert into temp_region (id, boundary) values ('{api}', '{to_postgis_polygon(boundary)}')")
write(name, f'delete from temp_node')
for node in nodes:
write(name, f"insert into temp_node values ('{node}')")
for row in read_all(name, f"select n.node from coordinates as c, temp_node as n, temp_region as r where c.node = n.node and ST_Intersects(c.coord, r.boundary) and r.id = '{api}'"):
node = row['node']
write(name, f"delete from temp_node where node = '{node}'")
outside_nodes: list[str] = []
for row in read_all(name, "select node from temp_node"):
outside_nodes.append(row['node'])
# no outside nodes, return
if len(outside_nodes) == 0:
write(name, f'delete from temp_node')
write(name, f"delete from temp_region where id = '{api}'")
return boundary
new_nodes: dict[str, Any] = {}
new_links: dict[str, Any] = {}
boundary_links: dict[str, list[str]] = {}
write(name, "delete from temp_link_2")
for node in outside_nodes:
for link in t_nodes[node]['links']:
node1 = t_links[link]['node1']
node2 = t_links[link]['node2']
if node1 in outside_nodes and node2 not in outside_nodes and node2 not in vertices and link:
if link not in boundary:
boundary_links[link] = []
line = f"LINESTRING({t_nodes[node1]['x']} {t_nodes[node1]['y']}, {t_nodes[node2]['x']} {t_nodes[node2]['y']})"
write(name, f"insert into temp_link_2 values ('{link}', '{line}')")
if node2 in outside_nodes and node1 not in outside_nodes and node1 not in vertices:
if link not in boundary:
boundary_links[link] = []
line = f"LINESTRING({t_nodes[node1]['x']} {t_nodes[node1]['y']}, {t_nodes[node2]['x']} {t_nodes[node2]['y']})"
write(name, f"insert into temp_link_2 values ('{link}', '{line}')")
if node1 in outside_nodes and node2 in outside_nodes:
x1, x2 = t_nodes[node1]['x'], t_nodes[node2]['x']
y1, y2 = t_nodes[node1]['y'], t_nodes[node2]['y']
if node1 not in new_nodes:
new_nodes[node1] = { 'x': x1, 'y': y1, 'links': [] }
if node2 not in new_nodes:
new_nodes[node2] = { 'x': x2, 'y': y2, 'links': [] }
if link not in new_links:
new_links[link] = t_links[link]
# no boundary links, return
if len(boundary_links) == 0:
write(name, "delete from temp_link_2")
write(name, f'delete from temp_node')
write(name, f"delete from temp_region where id = '{api}'")
return boundary
write(name, "delete from temp_link_1")
for link, _ in path.items():
node1 = t_links[link]['node1']
node2 = t_links[link]['node2']
line = f"LINESTRING({t_nodes[node1]['x']} {t_nodes[node1]['y']}, {t_nodes[node2]['x']} {t_nodes[node2]['y']})"
write(name, f"insert into temp_link_1 (link, geom) values ('{link}', '{line}')")
has_intersection = False
for row in read_all(name, f"select l1.link as l, l2.link as r, st_astext(st_intersection(l1.geom, l2.geom)) as p from temp_link_1 as l1, temp_link_2 as l2 where st_intersects(l1.geom, l2.geom)"):
has_intersection = True
link1, link2, pt = str(row['l']), str(row['r']), str(row['p'])
pts = pt.lower().removeprefix('point(').removesuffix(')').split(' ')
xy = (float(pts[0]), float(pts[1]))
new_node = f'NODE_[{link1}]_[{link2}]'
new_nodes[new_node] = { 'x': xy[0], 'y': xy[1], 'links': [] }
path[link1].append(new_node)
boundary_links[link2].append(new_node)
# no intersection, return
if not has_intersection:
write(name, "delete from temp_link_1")
write(name, "delete from temp_link_2")
write(name, 'delete from temp_node')
write(name, f"delete from temp_region where id = '{api}'")
return boundary
new_nodes, new_links = _collect_new_links(path, t_nodes, t_links, new_nodes, new_links)
new_nodes, new_links = _collect_new_links(boundary_links, t_nodes, t_links, new_nodes, new_links)
for link, values in new_links.items():
new_nodes[values['node1']]['links'].append(link)
new_nodes[values['node2']]['links'].append(link)
_, _, boundary = _calculate_boundary(topology.max_x_node(), new_nodes, new_links)
write(name, "delete from temp_link_1")
write(name, "delete from temp_link_2")
write(name, 'delete from temp_node')
write(name, f"delete from temp_region where id = '{api}'")
return boundary return boundary

View File

@@ -2,7 +2,7 @@ import ctypes
import os import os
from .database import * from .database import *
from .s0_base import get_nodes from .s0_base import get_nodes
from .s32_region_util import get_nodes_in_region, to_postgis_polygon from .s32_region_util import get_nodes_in_region
from .s32_region_util import Topology from .s32_region_util import Topology
from .s32_region import get_region from .s32_region import get_region

View File

@@ -1,480 +1,481 @@
[TITLE] [TITLE]
EPANET Example Network 3 EPANET Example Network 3
Example showing how the percent of Lake water in a dual-source Example showing how the percent of Lake water in a dual-source
system changes over time. system changes over time.
[JUNCTIONS] [JUNCTIONS]
;ID Elev Demand Pattern ;ID Elev Demand Pattern
10 147 0 ; 10 147 0 ;
15 32 1 3 ; 15 32 1 3 ;
20 129 0 ; 20 129 0 ;
35 12.5 1 4 ; 35 12.5 1 4 ;
40 131.9 0 ; 40 131.9 0 ;
50 116.5 0 ; 50 116.5 0 ;
60 0 0 ; 60 0 0 ;
601 0 0 ; 601 0 0 ;
61 0 0 ; 61 0 0 ;
101 42 189.95 ; 101 42 189.95 ;
103 43 133.2 ; 103 43 133.2 ;
105 28.5 135.37 ; 105 28.5 135.37 ;
107 22 54.64 ; 107 22 54.64 ;
109 20.3 231.4 ; 109 20.3 231.4 ;
111 10 141.94 ; 111 10 141.94 ;
113 2 20.01 ; 113 2 20.01 ;
115 14 52.1 ; 115 14 52.1 ;
117 13.6 117.71 ; 117 13.6 117.71 ;
119 2 176.13 ; 119 2 176.13 ;
120 0 0 ; 120 0 0 ;
121 -2 41.63 ; 121 -2 41.63 ;
123 11 1 2 ; 123 11 1 2 ;
125 11 45.6 ; 125 11 45.6 ;
127 56 17.66 ; 127 56 17.66 ;
129 51 0 ; 129 51 0 ;
131 6 42.75 ; 131 6 42.75 ;
139 31 5.89 ; 139 31 5.89 ;
141 4 9.85 ; 141 4 9.85 ;
143 -4.5 6.2 ; 143 -4.5 6.2 ;
145 1 27.63 ; 145 1 27.63 ;
147 18.5 8.55 ; 147 18.5 8.55 ;
149 16 27.07 ; 149 16 27.07 ;
151 33.5 144.48 ; 151 33.5 144.48 ;
153 66.2 44.17 ; 153 66.2 44.17 ;
157 13.1 51.79 ; 157 13.1 51.79 ;
159 6 41.32 ; 159 6 41.32 ;
161 4 15.8 ; 161 4 15.8 ;
163 5 9.42 ; 163 5 9.42 ;
164 5 0 ; 164 5 0 ;
166 -2 2.6 ; 166 -2 2.6 ;
167 -5 14.56 ; 167 -5 14.56 ;
169 -5 0 ; 169 -5 0 ;
171 -4 39.34 ; 171 -4 39.34 ;
173 -4 0 ; 173 -4 0 ;
177 8 58.17 ; 177 8 58.17 ;
179 8 0 ; 179 8 0 ;
181 8 0 ; 181 8 0 ;
183 11 0 ; 183 11 0 ;
184 16 0 ; 184 16 0 ;
185 16 25.65 ; 185 16 25.65 ;
187 12.5 0 ; 187 12.5 0 ;
189 4 107.92 ; 189 4 107.92 ;
191 25 81.9 ; 191 25 81.9 ;
193 18 71.31 ; 193 18 71.31 ;
195 15.5 0 ; 195 15.5 0 ;
197 23 17.04 ; 197 23 17.04 ;
199 -2 119.32 ; 199 -2 119.32 ;
201 0.1 44.61 ; 201 0.1 44.61 ;
203 2 1 5 ; 203 2 1 5 ;
204 21 0 ; 204 21 0 ;
205 21 65.36 ; 205 21 65.36 ;
206 1 0 ; 206 1 0 ;
207 9 69.39 ; 207 9 69.39 ;
208 16 0 ; 208 16 0 ;
209 -2 0.87 ; 209 -2 0.87 ;
211 7 8.67 ; 211 7 8.67 ;
213 7 13.94 ; 213 7 13.94 ;
215 7 92.19 ; 215 7 92.19 ;
217 6 24.22 ; 217 6 24.22 ;
219 4 41.32 ; 219 4 41.32 ;
225 8 22.8 ; 225 8 22.8 ;
229 10.5 64.18 ; 229 10.5 64.18 ;
231 5 16.48 ; 231 5 16.48 ;
237 14 15.61 ; 237 14 15.61 ;
239 13 44.61 ; 239 13 44.61 ;
241 13 0 ; 241 13 0 ;
243 14 4.34 ; 243 14 4.34 ;
247 18 70.38 ; 247 18 70.38 ;
249 18 0 ; 249 18 0 ;
251 30 24.16 ; 251 30 24.16 ;
253 36 54.52 ; 253 36 54.52 ;
255 27 40.39 ; 255 27 40.39 ;
257 17 0 ; 257 17 0 ;
259 25 0 ; 259 25 0 ;
261 0 0 ; 261 0 0 ;
263 0 0 ; 263 0 0 ;
265 0 0 ; 265 0 0 ;
267 21 0 ; 267 21 0 ;
269 0 0 ; 269 0 0 ;
271 6 0 ; 271 6 0 ;
273 8 0 ; 273 8 0 ;
275 10 0 ; 275 10 0 ;
[RESERVOIRS] [RESERVOIRS]
;ID Head Pattern ;ID Head Pattern
River 220.0 ; River 220.0 ;
Lake 167.0 ; Lake 167.0 ;
[TANKS] [TANKS]
;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve
1 131.9 13.1 .1 32.1 85 0 ; 1 131.9 13.1 .1 32.1 85 0 ;
2 116.5 23.5 6.5 40.3 50 0 ; 2 116.5 23.5 6.5 40.3 50 0 ;
3 129.0 29.0 4.0 35.5 164 0 ; 3 129.0 29.0 4.0 35.5 164 0 ;
[PIPES] [PIPES]
;ID Node1 Node2 Length Diameter Roughness MinorLoss Status ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status
20 3 20 99 99 199 0 Open ; 20 3 20 99 99 199 0 Open ;
40 1 40 99 99 199 0 Open ; 40 1 40 99 99 199 0 Open ;
50 2 50 99 99 199 0 Open ; 50 2 50 99 99 199 0 Open ;
60 River 60 1231 24 140 0 Open ; 60 River 60 1231 24 140 0 Open ;
101 10 101 14200 18 110 0 Open ; 101 10 101 14200 18 110 0 Open ;
103 101 103 1350 16 130 0 Open ; 103 101 103 1350 16 130 0 Open ;
105 101 105 2540 12 130 0 Open ; 105 101 105 2540 12 130 0 Open ;
107 105 107 1470 12 130 0 Open ; 107 105 107 1470 12 130 0 Open ;
109 103 109 3940 16 130 0 Open ; 109 103 109 3940 16 130 0 Open ;
111 109 111 2000 12 130 0 Open ; 111 109 111 2000 12 130 0 Open ;
112 115 111 1160 12 130 0 Open ; 112 115 111 1160 12 130 0 Open ;
113 111 113 1680 12 130 0 Open ; 113 111 113 1680 12 130 0 Open ;
114 115 113 2000 8 130 0 Open ; 114 115 113 2000 8 130 0 Open ;
115 107 115 1950 8 130 0 Open ; 115 107 115 1950 8 130 0 Open ;
116 113 193 1660 12 130 0 Open ; 116 113 193 1660 12 130 0 Open ;
117 263 105 2725 12 130 0 Open ; 117 263 105 2725 12 130 0 Open ;
119 115 117 2180 12 130 0 Open ; 119 115 117 2180 12 130 0 Open ;
120 119 120 730 12 130 0 Open ; 120 119 120 730 12 130 0 Open ;
121 120 117 1870 12 130 0 Open ; 121 120 117 1870 12 130 0 Open ;
122 121 120 2050 8 130 0 Open ; 122 121 120 2050 8 130 0 Open ;
123 121 119 2000 30 141 0 Open ; 123 121 119 2000 30 141 0 Open ;
125 123 121 1500 30 141 0 Open ; 125 123 121 1500 30 141 0 Open ;
129 121 125 930 24 130 0 Open ; 129 121 125 930 24 130 0 Open ;
131 125 127 3240 24 130 0 Open ; 131 125 127 3240 24 130 0 Open ;
133 20 127 785 20 130 0 Open ; 133 20 127 785 20 130 0 Open ;
135 127 129 900 24 130 0 Open ; 135 127 129 900 24 130 0 Open ;
137 129 131 6480 16 130 0 Open ; 137 129 131 6480 16 130 0 Open ;
145 129 139 2750 8 130 0 Open ; 145 129 139 2750 8 130 0 Open ;
147 139 141 2050 8 130 0 Open ; 147 139 141 2050 8 130 0 Open ;
149 143 141 1400 8 130 0 Open ; 149 143 141 1400 8 130 0 Open ;
151 15 143 1650 8 130 0 Open ; 151 15 143 1650 8 130 0 Open ;
153 145 141 3510 12 130 0 Open ; 153 145 141 3510 12 130 0 Open ;
155 147 145 2200 12 130 0 Open ; 155 147 145 2200 12 130 0 Open ;
159 147 149 880 12 130 0 Open ; 159 147 149 880 12 130 0 Open ;
161 149 151 1020 8 130 0 Open ; 161 149 151 1020 8 130 0 Open ;
163 151 153 1170 12 130 0 Open ; 163 151 153 1170 12 130 0 Open ;
169 125 153 4560 8 130 0 Open ; 169 125 153 4560 8 130 0 Open ;
171 119 151 3460 12 130 0 Open ; 171 119 151 3460 12 130 0 Open ;
173 119 157 2080 30 141 0 Open ; 173 119 157 2080 30 141 0 Open ;
175 157 159 2910 30 141 0 Open ; 175 157 159 2910 30 141 0 Open ;
177 159 161 2000 30 141 0 Open ; 177 159 161 2000 30 141 0 Open ;
179 161 163 430 30 141 0 Open ; 179 161 163 430 30 141 0 Open ;
180 163 164 150 14 130 0 Open ; 180 163 164 150 14 130 0 Open ;
181 164 166 490 14 130 0 Open ; 181 164 166 490 14 130 0 Open ;
183 265 169 590 30 141 0 Open ; 183 265 169 590 30 141 0 Open ;
185 167 169 60 8 130 0 Open ; 185 167 169 60 8 130 0 Open ;
186 187 204 99.9 8 130 0 Open ; 186 187 204 99.9 8 130 0 Open ;
187 169 171 1270 30 141 0 Open ; 187 169 171 1270 30 141 0 Open ;
189 171 173 50 30 141 0 Open ; 189 171 173 50 30 141 0 Open ;
191 271 171 760 24 130 0 Open ; 191 271 171 760 24 130 0 Open ;
193 35 181 30 24 130 0 Open ; 193 35 181 30 24 130 0 Open ;
195 181 177 30 12 130 0 Open ; 195 181 177 30 12 130 0 Open ;
197 177 179 30 12 130 0 Open ; 197 177 179 30 12 130 0 Open ;
199 179 183 210 12 130 0 Open ; 199 179 183 210 12 130 0 Open ;
201 40 179 1190 12 130 0 Open ; 201 40 179 1190 12 130 0 Open ;
202 185 184 99.9 8 130 0 Open ; 202 185 184 99.9 8 130 0 Open ;
203 183 185 510 8 130 0 Open ; 203 183 185 510 8 130 0 Open ;
204 184 205 4530. 12 130 0 Open ; 204 184 205 4530. 12 130 0 Open ;
205 204 185 1325. 12 130 0 Open ; 205 204 185 1325. 12 130 0 Open ;
207 189 183 1350 12 130 0 Open ; 207 189 183 1350 12 130 0 Open ;
209 189 187 500 8 130 0 Open ; 209 189 187 500 8 130 0 Open ;
211 169 269 646 12 130 0 Open ; 211 169 269 646 12 130 0 Open ;
213 191 187 2560 12 130 0 Open ; 213 191 187 2560 12 130 0 Open ;
215 267 189 1230 12 130 0 Open ; 215 267 189 1230 12 130 0 Open ;
217 191 193 520 12 130 0 Open ; 217 191 193 520 12 130 0 Open ;
219 193 195 360 12 130 0 Open ; 219 193 195 360 12 130 0 Open ;
221 161 195 2300 8 130 0 Open ; 221 161 195 2300 8 130 0 Open ;
223 197 191 1150 12 130 0 Open ; 223 197 191 1150 12 130 0 Open ;
225 111 197 2790 12 130 0 Open ; 225 111 197 2790 12 130 0 Open ;
229 173 199 4000 24 141 0 Open ; 229 173 199 4000 24 141 0 Open ;
231 199 201 630 24 141 0 Open ; 231 199 201 630 24 141 0 Open ;
233 201 203 120 24 130 0 Open ; 233 201 203 120 24 130 0 Open ;
235 199 273 725 12 130 0 Open ; 235 199 273 725 12 130 0 Open ;
237 205 207 1200 12 130 0 Open ; 237 205 207 1200 12 130 0 Open ;
238 207 206 450 12 130 0 Open ; 238 207 206 450 12 130 0 Open ;
239 275 207 1430 12 130 0 Open ; 239 275 207 1430 12 130 0 Open ;
240 206 208 510 12 130 0 Open ; 240 206 208 510 12 130 0 Open ;
241 208 209 885 12 130 0 Open ; 241 208 209 885 12 130 0 Open ;
243 209 211 1210 16 130 0 Open ; 243 209 211 1210 16 130 0 Open ;
245 211 213 990 16 130 0 Open ; 245 211 213 990 16 130 0 Open ;
247 213 215 4285 16 130 0 Open ; 247 213 215 4285 16 130 0 Open ;
249 215 217 1660 16 130 0 Open ; 249 215 217 1660 16 130 0 Open ;
251 217 219 2050 14 130 0 Open ; 251 217 219 2050 14 130 0 Open ;
257 217 225 1560 12 130 0 Open ; 257 217 225 1560 12 130 0 Open ;
261 213 229 2200 8 130 0 Open ; 261 213 229 2200 8 130 0 Open ;
263 229 231 1960 12 130 0 Open ; 263 229 231 1960 12 130 0 Open ;
269 211 237 2080 12 130 0 Open ; 269 211 237 2080 12 130 0 Open ;
271 237 229 790 8 130 0 Open ; 271 237 229 790 8 130 0 Open ;
273 237 239 510 12 130 0 Open ; 273 237 239 510 12 130 0 Open ;
275 239 241 35 12 130 0 Open ; 275 239 241 35 12 130 0 Open ;
277 241 243 2200 12 130 0 Open ; 277 241 243 2200 12 130 0 Open ;
281 241 247 445 10 130 0 Open ; 281 241 247 445 10 130 0 Open ;
283 239 249 430 12 130 0 Open ; 283 239 249 430 12 130 0 Open ;
285 247 249 10 12 130 0 Open ; 285 247 249 10 12 130 0 Open ;
287 247 255 1390 10 130 0 Open ; 287 247 255 1390 10 130 0 Open ;
289 50 255 925 10 130 0 Open ; 289 50 255 925 10 130 0 Open ;
291 255 253 1100 10 130 0 Open ; 291 255 253 1100 10 130 0 Open ;
293 255 251 1100 8 130 0 Open ; 293 255 251 1100 8 130 0 Open ;
295 249 251 1450 12 130 0 Open ; 295 249 251 1450 12 130 0 Open ;
297 120 257 645 8 130 0 Open ; 297 120 257 645 8 130 0 Open ;
299 257 259 350 8 130 0 Open ; 299 257 259 350 8 130 0 Open ;
301 259 263 1400 8 130 0 Open ; 301 259 263 1400 8 130 0 Open ;
303 257 261 1400 8 130 0 Open ; 303 257 261 1400 8 130 0 Open ;
305 117 261 645 12 130 0 Open ; 305 117 261 645 12 130 0 Open ;
307 261 263 350 12 130 0 Open ; 307 261 263 350 12 130 0 Open ;
309 265 267 1580 8 130 0 Open ; 309 265 267 1580 8 130 0 Open ;
311 193 267 1170 12 130 0 Open ; 311 193 267 1170 12 130 0 Open ;
313 269 189 646 12 130 0 Open ; 313 269 189 646 12 130 0 Open ;
315 181 271 260 24 130 0 Open ; 315 181 271 260 24 130 0 Open ;
317 273 275 2230 8 130 0 Open ; 317 273 275 2230 8 130 0 Open ;
319 273 205 645 12 130 0 Open ; 319 273 205 645 12 130 0 Open ;
321 163 265 1200 30 141 0 Open ; 321 163 265 1200 30 141 0 Open ;
323 201 275 300 12 130 0 Open ; 323 201 275 300 12 130 0 Open ;
325 269 271 1290 8 130 0 Open ; 325 269 271 1290 8 130 0 Open ;
329 61 123 45500 30 140 0 Open ; 329 61 123 45500 30 140 0 Open ;
330 60 601 1 30 140 0 Closed ; 330 60 601 1 30 140 0 Closed ;
333 601 61 1 30 140 0 Open ; 333 601 61 1 30 140 0 Open ;
[PUMPS] [PUMPS]
;ID Node1 Node2 Parameters ;ID Node1 Node2 Parameters
10 Lake 10 HEAD 1 ; 10 Lake 10 HEAD 1 ;
335 60 61 HEAD 2 ; 335 60 61 HEAD 2 ;
[VALVES] [VALVES]
;ID Node1 Node2 Diameter Type Setting MinorLoss ;ID Node1 Node2 Diameter Type Setting MinorLoss
[TAGS] [TAGS]
[DEMANDS] [DEMANDS]
;Junction Demand Pattern Category ;Junction Demand Pattern Category
[STATUS] [STATUS]
;ID Status/Setting ;ID Status/Setting
10 Closed 10 Closed
[PATTERNS] [PATTERNS]
;ID Multipliers ;ID Multipliers
;General Default Demand Pattern ;General Default Demand Pattern
1 1.34 1.94 1.46 1.44 .76 .92 1 1.34 1.94 1.46 1.44 .76 .92
1 .85 1.07 .96 1.1 1.08 1.19 1 .85 1.07 .96 1.1 1.08 1.19
1 1.16 1.08 .96 .83 .79 .74 1 1.16 1.08 .96 .83 .79 .74
1 .64 .64 .85 .96 1.24 1.67 1 .64 .64 .85 .96 1.24 1.67
;Demand Pattern for Node 123 ;Demand Pattern for Node 123
2 0 0 0 0 0 1219 2 0 0 0 0 0 1219
2 0 0 0 1866 1836 1818 2 0 0 0 1866 1836 1818
2 1818 1822 1822 1817 1824 1816 2 1818 1822 1822 1817 1824 1816
2 1833 1817 1830 1814 1840 1859 2 1833 1817 1830 1814 1840 1859
;Demand Pattern for Node 15 ;Demand Pattern for Node 15
3 620 620 620 620 620 360 3 620 620 620 620 620 360
3 360 0 0 0 0 360 3 360 0 0 0 0 360
3 360 360 360 360 0 0 3 360 360 360 360 0 0
3 0 0 0 0 360 360 3 0 0 0 0 360 360
;Demand Pattern for Node 35 ;Demand Pattern for Node 35
4 1637 1706 1719 1719 1791 1819 4 1637 1706 1719 1719 1791 1819
4 1777 1842 1815 1825 1856 1801 4 1777 1842 1815 1825 1856 1801
4 1819 1733 1664 1620 1613 1620 4 1819 1733 1664 1620 1613 1620
4 1616 1647 1627 1627 1671 1668 4 1616 1647 1627 1627 1671 1668
;Demand Pattern for Node 203 ;Demand Pattern for Node 203
5 4439 4531 4511 4582 4531 4582 5 4439 4531 4511 4582 4531 4582
5 4572 4613 4643 4643 4592 4613 5 4572 4613 4643 4643 4592 4613
5 4531 4521 4449 4439 4449 4460 5 4531 4521 4449 4439 4449 4460
5 4439 4419 4368 4399 4470 4480 5 4439 4419 4368 4399 4470 4480
[CURVES] [CURVES]
;ID X-Value Y-Value ;ID X-Value Y-Value
;PUMP: Pump Curve for Pump 10 (Lake Source) ;PUMP: Pump Curve for Pump 10 (Lake Source)
1 0 104. 1 0 104.
1 2000. 92. 1 2000. 92.
1 4000. 63. 1 4000. 63.
;PUMP: Pump Curve for Pump 335 (River Source) ;PUMP: Pump Curve for Pump 335 (River Source)
2 0 200. 2 0 200.
2 8000. 138. 2 8000. 138.
2 14000. 86. 2 14000. 86.
[CONTROLS] [CONTROLS]
;Lake source operates only part of the day ;Lake source operates only part of the day
Link 10 OPEN AT TIME 1 Link 10 OPEN AT TIME 1
Link 10 CLOSED AT TIME 15 Link 10 CLOSED AT TIME 15
;Pump 335 controlled by level in Tank 1 ;Pump 335 controlled by level in Tank 1
;When pump is closed, bypass pipe is opened ;When pump is closed, bypass pipe is opened
Link 335 OPEN IF Node 1 BELOW 17.1 Link 335 OPEN IF Node 1 BELOW 17.1
Link 335 CLOSED IF Node 1 ABOVE 19.1 Link 335 CLOSED IF Node 1 ABOVE 19.1
Link 330 CLOSED IF Node 1 BELOW 17.1 Link 330 CLOSED IF Node 1 BELOW 17.1
Link 330 OPEN IF Node 1 ABOVE 19.1 Link 330 OPEN IF Node 1 ABOVE 19.1
[RULES] [RULES]
[ENERGY] [ENERGY]
Global Efficiency 75 Global Efficiency 75
Global Price 0.0 Global Price 0.0
Demand Charge 0.0 Demand Charge 0.0
[EMITTERS] [EMITTERS]
;Junction Coefficient ;Junction Coefficient
[QUALITY] [QUALITY]
;Node InitQual ;Node InitQual
[SOURCES] [SOURCES]
;Node Type Quality Pattern ;Node Type Quality Pattern
[REACTIONS] [REACTIONS]
;Type Pipe/Tank Coefficient ;Type Pipe/Tank Coefficient
[REACTIONS] [REACTIONS]
Order Bulk 1 Order Bulk 1
Order Tank 1 Order Tank 1
Order Wall 1 Order Wall 1
Global Bulk 0.0 Global Bulk 0.0
Global Wall 0.0 Global Wall 0.0
Limiting Potential 0.0 Limiting Potential 0.0
Roughness Correlation 0.0 Roughness Correlation 0.0
[MIXING] [MIXING]
;Tank Model ;Tank Model
[TIMES] [TIMES]
Duration 24:00 Duration 24:00
Hydraulic Timestep 1:00 Hydraulic Timestep 1:00
Quality Timestep 0:05 Quality Timestep 0:05
Pattern Timestep 1:00 Pattern Timestep 1:00
Pattern Start 0:00 Pattern Start 0:00
Report Timestep 1:00 Report Timestep 1:00
Report Start 0:00 Report Start 0:00
Start ClockTime 12 am Start ClockTime 12 am
Statistic None Statistic None
[REPORT] [REPORT]
Status Yes Status Yes
Summary No Summary No
Page 0 Page 0
[OPTIONS] [OPTIONS]
Units GPM Units GPM
Headloss H-W Headloss H-W
Specific Gravity 1.0 Specific Gravity 1.0
Viscosity 1.0 Viscosity 1.0
Trials 40 Trials 40
Accuracy 0.001 Accuracy 0.001
CHECKFREQ 2 CHECKFREQ 2
MAXCHECK 10 MAXCHECK 10
DAMPLIMIT 0 DAMPLIMIT 0
Unbalanced Continue 10 Unbalanced Continue 10
Pattern 1 Pattern 1
Demand Multiplier 1.0 Demand Multiplier 1.0
Emitter Exponent 0.5 Emitter Exponent 0.5
Quality Trace Lake Quality Trace Lake
Diffusivity 1.0 Diffusivity 1.0
Tolerance 0.01 Tolerance 0.01
[COORDINATES] [COORDINATES]
;Node X-Coord Y-Coord ;Node X-Coord Y-Coord
10 9.00 27.85 10 9.00 27.85
15 38.68 23.76 15 38.68 23.76
20 29.44 26.91 20 29.44 26.91
35 25.46 10.52 35 25.46 10.52
40 27.02 9.81 40 27.02 9.81
50 33.01 3.01 50 33.01 3.01
60 23.90 29.94 60 23.90 29.94
601 23.00 29.49 601 23.00 29.49
61 23.71 29.03 61 23.71 29.03
101 13.81 22.94 101 13.81 22.94
103 12.96 21.31 103 12.96 21.31
105 16.97 21.28 105 16.97 21.28
107 18.45 20.46 107 18.45 20.46
109 17.64 18.92 109 17.64 18.92
111 20.21 17.53 111 20.21 17.53
113 22.04 16.61 113 22.04 16.61
115 20.98 19.18 115 20.98 19.18
117 21.69 21.28 117 21.69 21.28
119 23.70 22.76 119 23.70 22.76
120 22.08 23.10 120 22.08 23.10
121 23.54 25.50 121 23.54 25.50
123 23.37 27.31 123 23.37 27.31
125 24.59 25.64 125 24.59 25.64
127 29.29 26.40 127 29.29 26.40
129 30.32 26.39 129 30.32 26.39
131 37.89 29.55 131 37.89 29.55
139 33.28 24.54 139 33.28 24.54
141 35.68 23.08 141 35.68 23.08
143 37.47 21.97 143 37.47 21.97
145 33.02 19.29 145 33.02 19.29
147 30.24 20.38 147 30.24 20.38
149 29.62 20.74 149 29.62 20.74
151 28.29 21.39 151 28.29 21.39
153 28.13 22.63 153 28.13 22.63
157 24.85 20.16 157 24.85 20.16
159 23.12 17.50 159 23.12 17.50
161 25.10 15.28 161 25.10 15.28
163 25.39 14.98 163 25.39 14.98
164 25.98 15.14 164 25.98 15.14
166 26.48 15.13 166 26.48 15.13
167 25.88 12.98 167 25.88 12.98
169 25.68 12.74 169 25.68 12.74
171 26.65 11.80 171 26.65 11.80
173 26.87 11.59 173 26.87 11.59
179 25.71 10.40 177 26.00 10.50
181 25.72 10.74 179 25.71 10.40
183 25.45 10.18 181 25.72 10.74
184 25.15 9.52 183 25.45 10.18
185 25.01 9.67 184 25.15 9.52
187 23.64 11.04 185 25.01 9.67
189 24.15 11.37 187 23.64 11.04
191 22.10 14.07 189 24.15 11.37
193 22.88 14.35 191 22.10 14.07
195 23.18 14.72 193 22.88 14.35
197 20.97 15.18 195 23.18 14.72
199 29.42 8.44 197 20.97 15.18
201 30.89 8.57 199 29.42 8.44
203 31.14 8.89 201 30.89 8.57
204 23.80 10.90 203 31.14 8.89
205 29.20 6.46 204 23.80 10.90
206 31.66 6.64 205 29.20 6.46
207 31.00 6.61 206 31.66 6.64
208 32.54 6.81 207 31.00 6.61
209 33.76 6.59 208 32.54 6.81
211 34.20 5.54 209 33.76 6.59
213 35.26 6.16 211 34.20 5.54
215 39.95 8.73 213 35.26 6.16
217 42.11 8.67 215 39.95 8.73
219 44.86 9.32 217 42.11 8.67
225 43.53 7.38 219 44.86 9.32
229 36.16 3.49 225 43.53 7.38
231 38.38 2.54 229 36.16 3.49
237 35.37 3.08 231 38.38 2.54
239 35.76 2.31 237 35.37 3.08
241 35.87 2.11 239 35.76 2.31
243 37.04 0.00 241 35.87 2.11
247 35.02 2.05 243 37.04 0.00
249 35.02 1.81 247 35.02 2.05
251 34.15 1.10 249 35.02 1.81
253 32.17 1.88 251 34.15 1.10
255 33.51 2.45 253 32.17 1.88
257 21.17 23.32 255 33.51 2.45
259 20.80 23.40 257 21.17 23.32
261 20.79 21.45 259 20.80 23.40
263 20.32 21.57 261 20.79 21.45
265 25.39 13.60 263 20.32 21.57
267 23.38 12.95 265 25.39 13.60
269 25.03 12.14 267 23.38 12.95
271 25.97 11.00 269 25.03 12.14
273 29.16 7.38 271 25.97 11.00
275 31.07 8.29 273 29.16 7.38
River 24.15 31.06 275 31.07 8.29
Lake 8.00 27.53 River 24.15 31.06
1 27.46 9.84 Lake 8.00 27.53
2 32.99 3.45 1 27.46 9.84
3 29.41 27.27 2 32.99 3.45
3 29.41 27.27
[VERTICES]
;Link X-Coord Y-Coord [VERTICES]
;Link X-Coord Y-Coord
[LABELS]
;X-Coord Y-Coord Label & Anchor Node [LABELS]
8.00 29.42 "LAKE" ;X-Coord Y-Coord Label & Anchor Node
25.00 31.10 "RIVER" 8.00 29.42 "LAKE"
25.00 31.10 "RIVER"
[BACKDROP]
DIMENSIONS 6.16 -1.55 46.70 32.61 [BACKDROP]
UNITS None DIMENSIONS 6.16 -1.55 46.70 32.61
FILE UNITS None
OFFSET 0.00 0.00 FILE
OFFSET 0.00 0.00
[END]
[END]

View File

@@ -25,9 +25,17 @@ create table temp_node
); );
create table temp_link create table temp_link_1
( (
link varchar(32) primary key references _link(id) link varchar(32) primary key references _link(id)
, geom geometry not null unique
);
create table temp_link_2
(
link varchar(32) primary key references _link(id)
, geom geometry not null unique
); );

View File

@@ -1,6 +1,8 @@
drop table if exists temp_vd_topology; drop table if exists temp_vd_topology;
drop table if exists temp_link; drop table if exists temp_link_2;
drop table if exists temp_link_1;
drop table if exists temp_node; drop table if exists temp_node;

View File

@@ -5832,9 +5832,9 @@ class TestApi:
dmas = calculate_district_metering_area_for_nodes(p, get_nodes(p), 3) dmas = calculate_district_metering_area_for_nodes(p, get_nodes(p), 3)
assert len(dmas) == 3 assert len(dmas) == 3
assert dmas[0] == ['173', '184', '185', '199', '2', '201', '203', '205', '206', '207', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '273', '275', '50'] assert dmas[0] == ['117', '119', '120', '121', '123', '125', '127', '129', '131', '139', '141', '143', '145', '147', '149', '15', '151', '153', '157', '159', '161', '195', '20', '257', '259', '261', '263', '3', '60', '601', '61', 'River']
assert dmas[1] == ['1', '10', '101', '103', '109', '111', '113', '161', '163', '164', '166', '167', '169', '171', '179', '181', '183', '187', '189', '191', '193', '195', '197', '204', '265', '267', '269', '271', '35', '40', 'Lake'] assert dmas[1] == ['1', '163', '164', '166', '167', '169', '171', '173', '177', '179', '181', '183', '184', '185', '187', '189', '191', '193', '199', '201', '203', '204', '205', '207', '265', '267', '269', '271', '273', '275', '35', '40']
assert dmas[2] == ['105', '107', '115', '117', '119', '120', '121', '123', '125', '127', '129', '131', '139', '141', '143', '145', '147', '149', '15', '151', '153', '157', '159', '20', '257', '259', '261', '263', '3', '60', '601', '61', 'River'] assert dmas[2] == ['10', '101', '103', '105', '107', '109', '111', '113', '115', '197', '2', '206', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '50', 'Lake']
self.leave(p) self.leave(p)
@@ -5844,15 +5844,15 @@ class TestApi:
read_inp(p, f'./inp/net3.inp', '3') read_inp(p, f'./inp/net3.inp', '3')
open_project(p) open_project(p)
assert get_node_coord(p, '177') == { 'x' : 0.0, 'y' : 0.0 }
add_region(p, ChangeSet({'id': 'r', 'boundary': [(-10000.0, -10000.0), (10000.0, -10000.0), (10000.0, 10000.0), (-10000.0, 10000.0), (-10000.0, -10000.0)]})) add_region(p, ChangeSet({'id': 'r', 'boundary': [(-10000.0, -10000.0), (10000.0, -10000.0), (10000.0, 10000.0), (-10000.0, 10000.0), (-10000.0, -10000.0)]}))
nodes = get_nodes_in_region(p, 'r') nodes = get_nodes_in_region(p, 'r')
assert len(nodes) == 97 assert len(nodes) == 97
dmas = calculate_district_metering_area_for_region(p, 'r', 3) dmas = calculate_district_metering_area_for_region(p, 'r', 3)
assert dmas == [['10', '60', '601', '61', '101', '103', '105', '107', '109', '111', '113', '115', '117', '119', '120', '121', '123', '125', '145', '147', '149', '151', '153', '157', '159', '197', '257', '259', '261', '263', 'River', 'Lake'], ['35', '40', '161', '163', '164', '166', '167', '169', '171', '173', '179', '181', '183', '184', '185', '187', '189', '191', '193', '195', '199', '201', '203', '204', '205', '207', '265', '267', '269', '271', '273', '275', '1', '177'], ['15', '20', '50', '127', '129', '131', '139', '141', '143', '206', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '2', '3']] assert dmas[0] == ['15', '20', '60', '601', '61', '117', '119', '120', '121', '123', '125', '127', '129', '131', '139', '141', '143', '145', '147', '149', '151', '153', '157', '159', '161', '195', '257', '259', '261', '263', 'River', '3']
assert dmas[1] == ['50', '171', '173', '184', '199', '201', '203', '205', '206', '207', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '273', '275', '2']
assert dmas[2] == ['10', '35', '40', '101', '103', '105', '107', '109', '111', '113', '115', '163', '164', '166', '167', '169', '177', '179', '181', '183', '185', '187', '189', '191', '193', '197', '204', '265', '267', '269', '271', 'Lake', '1']
self.leave(p) self.leave(p)
@@ -5864,9 +5864,9 @@ class TestApi:
dmas = calculate_district_metering_area_for_network(p, 3) dmas = calculate_district_metering_area_for_network(p, 3)
assert len(dmas) == 3 assert len(dmas) == 3
assert dmas[0] == ['173', '184', '185', '199', '2', '201', '203', '205', '206', '207', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '273', '275', '50'] assert dmas[0] == ['117', '119', '120', '121', '123', '125', '127', '129', '131', '139', '141', '143', '145', '147', '149', '15', '151', '153', '157', '159', '161', '195', '20', '257', '259', '261', '263', '3', '60', '601', '61', 'River']
assert dmas[1] == ['1', '10', '101', '103', '109', '111', '113', '161', '163', '164', '166', '167', '169', '171', '179', '181', '183', '187', '189', '191', '193', '195', '197', '204', '265', '267', '269', '271', '35', '40', 'Lake'] assert dmas[1] == ['1', '163', '164', '166', '167', '169', '171', '173', '177', '179', '181', '183', '184', '185', '187', '189', '191', '193', '199', '201', '203', '204', '205', '207', '265', '267', '269', '271', '273', '275', '35', '40']
assert dmas[2] == ['105', '107', '115', '117', '119', '120', '121', '123', '125', '127', '129', '131', '139', '141', '143', '145', '147', '149', '15', '151', '153', '157', '159', '20', '257', '259', '261', '263', '3', '60', '601', '61', 'River'] assert dmas[2] == ['10', '101', '103', '105', '107', '109', '111', '113', '115', '197', '2', '206', '208', '209', '211', '213', '215', '217', '219', '225', '229', '231', '237', '239', '241', '243', '247', '249', '251', '253', '255', '50', 'Lake']
self.leave(p) self.leave(p)
@@ -6150,13 +6150,16 @@ class TestApi:
assert cs[1]['id'] == 'DMA_[DMA_1_1]_2_2' assert cs[1]['id'] == 'DMA_[DMA_1_1]_2_2'
cs = generate_sub_district_metering_area(p, 'DMA_1_2', 3).operations cs = generate_sub_district_metering_area(p, 'DMA_1_2', 3).operations
assert len(cs) == 2 assert len(cs) == 3
assert cs[0]['operation'] == API_ADD assert cs[0]['operation'] == API_ADD
assert cs[0]['type'] == 'district_metering_area' assert cs[0]['type'] == 'district_metering_area'
assert cs[0]['id'] == 'DMA_[DMA_1_2]_2_2' assert cs[0]['id'] == 'DMA_[DMA_1_2]_2_1'
assert cs[1]['operation'] == API_ADD assert cs[1]['operation'] == API_ADD
assert cs[1]['type'] == 'district_metering_area' assert cs[1]['type'] == 'district_metering_area'
assert cs[1]['id'] == 'DMA_[DMA_1_2]_2_3' assert cs[1]['id'] == 'DMA_[DMA_1_2]_2_2'
assert cs[2]['operation'] == API_ADD
assert cs[2]['type'] == 'district_metering_area'
assert cs[2]['id'] == 'DMA_[DMA_1_2]_2_3'
cs = generate_sub_district_metering_area(p, 'DMA_1_3', 2).operations cs = generate_sub_district_metering_area(p, 'DMA_1_3', 2).operations
assert len(cs) == 2 assert len(cs) == 2
@@ -6168,10 +6171,10 @@ class TestApi:
assert cs[1]['id'] == 'DMA_[DMA_1_3]_2_2' assert cs[1]['id'] == 'DMA_[DMA_1_3]_2_2'
dmas = get_all_district_metering_area_ids(p) dmas = get_all_district_metering_area_ids(p)
assert len(dmas) == 9 assert len(dmas) == 10
cs = generate_district_metering_area(p, 3).operations cs = generate_district_metering_area(p, 3).operations
assert len(cs) == 12 assert len(cs) == 13
dmas = get_all_district_metering_area_ids(p) dmas = get_all_district_metering_area_ids(p)
assert len(dmas) == 3 assert len(dmas) == 3
@@ -6585,8 +6588,7 @@ class TestApi:
open_project(p) open_project(p)
result = calculate_demand_to_network(p, 100.0) result = calculate_demand_to_network(p, 100.0)
assert result == {'10': 3.2923444181778216, '101': 4.194261304565972, '103': 1.226514223391597, '105': 1.561545046227298, '107': 0.7929449232512782, '109': 1.3772201298574833, '111': 1.7690554866687873, '113': 1.2381069854274345, '115': 1.6902247048250931, '117': 1.088560355165132, '119': 1.9174428407275061, '120': 1.2276734995951808, '121': 1.502421959844527, '123': 10.897196313687157, '125': 2.0240962514572103, '127': 1.141887060529984, '129': 2.3486935884606575, '131': 1.5024219598445272, '139': 1.1129051554403906, '141': 1.6137124753885663, '143': 0.7071584841860814, '145': 1.3238934244926313, '147': 0.7141141414075839, '149': 0.44052495736182123, '15': 0.38256114718263423, '151': 1.3099821100496263, '153': 1.328530529306966, '157': 1.1569576511765725, '159': 1.1384092319192327, '161': 1.0966752885902182, '163': 0.41270232847581145, '164': 0.14838735405871872, '166': 0.11360906795120652, '167': 0.01391131444300488, '169': 0.5949405476791755, '171': 0.48225890069083593, '173': 0.9390137249028294, '179': 0.32459733700344723, '181': 0.06723801980785693, '183': 0.4799403482836684, '184': 1.0734665789944717, '185': 0.4486167052628357, '187': 0.732639375140852, '189': 0.8638926269106031, '191': 0.9807476682318441, '193': 0.8601829430591352, '195': 0.6167349403065497, '197': 0.9135096484239872, '199': 1.2415848140381855, '20': 0.20496003279360525, '201': 0.2434480027525854, '203': 0.02782262888600976, '204': 0.33037053249729426, '205': 1.4780771595692686, '206': 0.22258103108807809, '207': 0.7141141414075839, '208': 0.3234380607998635, '209': 0.48573672930158707, '211': 0.9923404302676815, '213': 1.7331179243576913, '215': 1.378379406061067, '217': 1.2218771185772621, '219': 0.47530324346933345, '225': 0.3616941755181269, '229': 1.1476834415479027, '231': 0.4544362718048261, '237': 0.7836707136226083, '239': 0.22605885969882933, '241': 0.6213720451208846, '243': 0.5100815295768456, '247': 0.42777291912240006, '249': 0.4382064049546538, '251': 0.5912308638277075, '253': 0.2550407647884228, '255': 1.0468264118361172, '257': 0.5552933015166115, '259': 0.405746671254309, '261': 0.5552933015166115, '263': 1.0375522022074473, '265': 0.7813521612154408, '267': 0.9227838580526571, '269': 0.5986502315306435, '271': 0.535585606055688, '273': 0.8346788665802929, '275': 0.9181467532383222, '35': 0.00695565722150244, '40': 0.2988614052838882, '50': 0.23741976649394997, '60': 0.28564565656303353, '601': 0.00046371048143349603, '61': 10.549645307852751} assert result == {'10': 3.2914286561977604, '101': 4.1930946753955975, '103': 1.226173069808884, '105': 1.5611107041895715, '107': 0.7927243664927, '109': 1.3768370575925843, '111': 1.7685634258302052, '113': 1.237762607330707, '115': 1.689754570681808, '117': 1.0882575732991893, '119': 1.9169095061095407, '120': 1.2273320235610663, '121': 1.5020040628282736, '123': 10.894165270513714, '125': 2.0235332513103135, '127': 1.1415694458995753, '129': 2.34804030192136, '131': 1.5020040628282738, '139': 1.1125956020950176, '141': 1.6132636230377755, '143': 0.7069617888312091, '145': 1.323525184992198, '147': 0.713915511344303, '149': 0.4404024258292778, '15': 0.3824547382201623, '151': 1.3096177399660103, '153': 1.3281610000009272, '157': 1.1566358446779454, '159': 1.1380925846430283, '161': 1.0963702495644652, '163': 0.4125875357769024, '164': 0.14834608027933568, '166': 0.11357746771386638, '167': 0.01390744502618772, '169': 0.5947750656199615, '171': 0.482124760907841, '173': 0.9387525392676711, '177': 0.01390744502618772, '179': 0.3314607731241407, '181': 0.07417304013966784, '183': 0.4798068534034764, '184': 1.0731679954457753, '185': 0.44849192301951035, '187': 0.7324355923041763, '189': 0.8636523361262574, '191': 0.9804748743462343, '193': 0.859943684119274, '195': 0.6165633961609889, '197': 0.9132555567196603, '199': 1.241239468587254, '20': 0.2049030233858324, '201': 0.24338028795828512, '203': 0.02781489005237544, '204': 0.3302786402969147, '205': 1.4776660340324455, '206': 0.2225191204190035, '207': 0.713915511344303, '208': 0.32334809685886445, '209': 0.48560162216438785, '211': 0.9920644118680574, '213': 1.7326358595125533, '215': 1.3779960113447665, '217': 1.2215372548001548, '219': 0.4751710383947471, '225': 0.3615935706808807, '229': 1.1473642146604868, '231': 0.45430987085546554, '237': 0.7834527364752415, '239': 0.22599598167555046, '241': 0.6211992111697181, '243': 0.5099396509602164, '247': 0.4276539345552724, '249': 0.4380845183249132, '251': 0.5910664136129782, '253': 0.2549698254801082, '255': 1.0465352382206259, '257': 0.5551388472953265, '259': 0.4056338132638085, '261': 0.5551388472953265, '263': 1.0372636082031674, '265': 0.7811348289708769, '267': 0.9225271867371188, '269': 0.5984837176269449, '271': 0.5354366335082272, '273': 0.8344467015712631, '275': 0.9178913717283894, '35': 0.00695372251309386, '40': 0.29877827731259954, '50': 0.23735372844693708, '60': 0.28556620453772114, '601': 0.000463581500872924, '61': 10.546710935609457}
self.leave(p) self.leave(p)