From 2bd314cc913739e7a663a91e9ab3f04ecca81fc0 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Thu, 8 Jun 2023 22:00:15 +0800 Subject: [PATCH 1/6] Enhance boundary algorithm --- api/s32_region_util.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/api/s32_region_util.py b/api/s32_region_util.py index d76d9f2..6a4f6cc 100644 --- a/api/s32_region_util.py +++ b/api/s32_region_util.py @@ -150,8 +150,16 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] paths: list[str] = [] while True: - #print(cursor) + # prevent duplicated node + if len(paths) > 0 and cursor == paths[-1]: + break + + # prevent duplicated path + if len(paths) >= 3 and paths[0] == paths[-1] and paths[1] == cursor: + break + paths.append(cursor) + sorted_links = [] overlapped_link = '' for link in t_nodes[cursor]['links']: @@ -164,10 +172,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] - if cursor == topology.max_x_node(): - paths.append(cursor) - break - in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links) + in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links) continue sorted_links = sorted(sorted_links, key=lambda s:s[0]) @@ -178,11 +183,6 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] break 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) boundary: list[tuple[float, float]] = [] From a631b3669490f9eb34acad4a0e183679c40d348e Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 9 Jun 2023 08:58:12 +0800 Subject: [PATCH 2/6] Fix net3 --- inp/net3.inp | 961 ++++++++++++++++++++++++++------------------------- 1 file changed, 481 insertions(+), 480 deletions(-) diff --git a/inp/net3.inp b/inp/net3.inp index 5355958..4fb1d6b 100644 --- a/inp/net3.inp +++ b/inp/net3.inp @@ -1,480 +1,481 @@ -[TITLE] -EPANET Example Network 3 -Example showing how the percent of Lake water in a dual-source -system changes over time. - -[JUNCTIONS] -;ID Elev Demand Pattern - 10 147 0 ; - 15 32 1 3 ; - 20 129 0 ; - 35 12.5 1 4 ; - 40 131.9 0 ; - 50 116.5 0 ; - 60 0 0 ; - 601 0 0 ; - 61 0 0 ; - 101 42 189.95 ; - 103 43 133.2 ; - 105 28.5 135.37 ; - 107 22 54.64 ; - 109 20.3 231.4 ; - 111 10 141.94 ; - 113 2 20.01 ; - 115 14 52.1 ; - 117 13.6 117.71 ; - 119 2 176.13 ; - 120 0 0 ; - 121 -2 41.63 ; - 123 11 1 2 ; - 125 11 45.6 ; - 127 56 17.66 ; - 129 51 0 ; - 131 6 42.75 ; - 139 31 5.89 ; - 141 4 9.85 ; - 143 -4.5 6.2 ; - 145 1 27.63 ; - 147 18.5 8.55 ; - 149 16 27.07 ; - 151 33.5 144.48 ; - 153 66.2 44.17 ; - 157 13.1 51.79 ; - 159 6 41.32 ; - 161 4 15.8 ; - 163 5 9.42 ; - 164 5 0 ; - 166 -2 2.6 ; - 167 -5 14.56 ; - 169 -5 0 ; - 171 -4 39.34 ; - 173 -4 0 ; - 177 8 58.17 ; - 179 8 0 ; - 181 8 0 ; - 183 11 0 ; - 184 16 0 ; - 185 16 25.65 ; - 187 12.5 0 ; - 189 4 107.92 ; - 191 25 81.9 ; - 193 18 71.31 ; - 195 15.5 0 ; - 197 23 17.04 ; - 199 -2 119.32 ; - 201 0.1 44.61 ; - 203 2 1 5 ; - 204 21 0 ; - 205 21 65.36 ; - 206 1 0 ; - 207 9 69.39 ; - 208 16 0 ; - 209 -2 0.87 ; - 211 7 8.67 ; - 213 7 13.94 ; - 215 7 92.19 ; - 217 6 24.22 ; - 219 4 41.32 ; - 225 8 22.8 ; - 229 10.5 64.18 ; - 231 5 16.48 ; - 237 14 15.61 ; - 239 13 44.61 ; - 241 13 0 ; - 243 14 4.34 ; - 247 18 70.38 ; - 249 18 0 ; - 251 30 24.16 ; - 253 36 54.52 ; - 255 27 40.39 ; - 257 17 0 ; - 259 25 0 ; - 261 0 0 ; - 263 0 0 ; - 265 0 0 ; - 267 21 0 ; - 269 0 0 ; - 271 6 0 ; - 273 8 0 ; - 275 10 0 ; - -[RESERVOIRS] -;ID Head Pattern - River 220.0 ; - Lake 167.0 ; - -[TANKS] -;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve - 1 131.9 13.1 .1 32.1 85 0 ; - 2 116.5 23.5 6.5 40.3 50 0 ; - 3 129.0 29.0 4.0 35.5 164 0 ; - -[PIPES] -;ID Node1 Node2 Length Diameter Roughness MinorLoss Status - 20 3 20 99 99 199 0 Open ; - 40 1 40 99 99 199 0 Open ; - 50 2 50 99 99 199 0 Open ; - 60 River 60 1231 24 140 0 Open ; - 101 10 101 14200 18 110 0 Open ; - 103 101 103 1350 16 130 0 Open ; - 105 101 105 2540 12 130 0 Open ; - 107 105 107 1470 12 130 0 Open ; - 109 103 109 3940 16 130 0 Open ; - 111 109 111 2000 12 130 0 Open ; - 112 115 111 1160 12 130 0 Open ; - 113 111 113 1680 12 130 0 Open ; - 114 115 113 2000 8 130 0 Open ; - 115 107 115 1950 8 130 0 Open ; - 116 113 193 1660 12 130 0 Open ; - 117 263 105 2725 12 130 0 Open ; - 119 115 117 2180 12 130 0 Open ; - 120 119 120 730 12 130 0 Open ; - 121 120 117 1870 12 130 0 Open ; - 122 121 120 2050 8 130 0 Open ; - 123 121 119 2000 30 141 0 Open ; - 125 123 121 1500 30 141 0 Open ; - 129 121 125 930 24 130 0 Open ; - 131 125 127 3240 24 130 0 Open ; - 133 20 127 785 20 130 0 Open ; - 135 127 129 900 24 130 0 Open ; - 137 129 131 6480 16 130 0 Open ; - 145 129 139 2750 8 130 0 Open ; - 147 139 141 2050 8 130 0 Open ; - 149 143 141 1400 8 130 0 Open ; - 151 15 143 1650 8 130 0 Open ; - 153 145 141 3510 12 130 0 Open ; - 155 147 145 2200 12 130 0 Open ; - 159 147 149 880 12 130 0 Open ; - 161 149 151 1020 8 130 0 Open ; - 163 151 153 1170 12 130 0 Open ; - 169 125 153 4560 8 130 0 Open ; - 171 119 151 3460 12 130 0 Open ; - 173 119 157 2080 30 141 0 Open ; - 175 157 159 2910 30 141 0 Open ; - 177 159 161 2000 30 141 0 Open ; - 179 161 163 430 30 141 0 Open ; - 180 163 164 150 14 130 0 Open ; - 181 164 166 490 14 130 0 Open ; - 183 265 169 590 30 141 0 Open ; - 185 167 169 60 8 130 0 Open ; - 186 187 204 99.9 8 130 0 Open ; - 187 169 171 1270 30 141 0 Open ; - 189 171 173 50 30 141 0 Open ; - 191 271 171 760 24 130 0 Open ; - 193 35 181 30 24 130 0 Open ; - 195 181 177 30 12 130 0 Open ; - 197 177 179 30 12 130 0 Open ; - 199 179 183 210 12 130 0 Open ; - 201 40 179 1190 12 130 0 Open ; - 202 185 184 99.9 8 130 0 Open ; - 203 183 185 510 8 130 0 Open ; - 204 184 205 4530. 12 130 0 Open ; - 205 204 185 1325. 12 130 0 Open ; - 207 189 183 1350 12 130 0 Open ; - 209 189 187 500 8 130 0 Open ; - 211 169 269 646 12 130 0 Open ; - 213 191 187 2560 12 130 0 Open ; - 215 267 189 1230 12 130 0 Open ; - 217 191 193 520 12 130 0 Open ; - 219 193 195 360 12 130 0 Open ; - 221 161 195 2300 8 130 0 Open ; - 223 197 191 1150 12 130 0 Open ; - 225 111 197 2790 12 130 0 Open ; - 229 173 199 4000 24 141 0 Open ; - 231 199 201 630 24 141 0 Open ; - 233 201 203 120 24 130 0 Open ; - 235 199 273 725 12 130 0 Open ; - 237 205 207 1200 12 130 0 Open ; - 238 207 206 450 12 130 0 Open ; - 239 275 207 1430 12 130 0 Open ; - 240 206 208 510 12 130 0 Open ; - 241 208 209 885 12 130 0 Open ; - 243 209 211 1210 16 130 0 Open ; - 245 211 213 990 16 130 0 Open ; - 247 213 215 4285 16 130 0 Open ; - 249 215 217 1660 16 130 0 Open ; - 251 217 219 2050 14 130 0 Open ; - 257 217 225 1560 12 130 0 Open ; - 261 213 229 2200 8 130 0 Open ; - 263 229 231 1960 12 130 0 Open ; - 269 211 237 2080 12 130 0 Open ; - 271 237 229 790 8 130 0 Open ; - 273 237 239 510 12 130 0 Open ; - 275 239 241 35 12 130 0 Open ; - 277 241 243 2200 12 130 0 Open ; - 281 241 247 445 10 130 0 Open ; - 283 239 249 430 12 130 0 Open ; - 285 247 249 10 12 130 0 Open ; - 287 247 255 1390 10 130 0 Open ; - 289 50 255 925 10 130 0 Open ; - 291 255 253 1100 10 130 0 Open ; - 293 255 251 1100 8 130 0 Open ; - 295 249 251 1450 12 130 0 Open ; - 297 120 257 645 8 130 0 Open ; - 299 257 259 350 8 130 0 Open ; - 301 259 263 1400 8 130 0 Open ; - 303 257 261 1400 8 130 0 Open ; - 305 117 261 645 12 130 0 Open ; - 307 261 263 350 12 130 0 Open ; - 309 265 267 1580 8 130 0 Open ; - 311 193 267 1170 12 130 0 Open ; - 313 269 189 646 12 130 0 Open ; - 315 181 271 260 24 130 0 Open ; - 317 273 275 2230 8 130 0 Open ; - 319 273 205 645 12 130 0 Open ; - 321 163 265 1200 30 141 0 Open ; - 323 201 275 300 12 130 0 Open ; - 325 269 271 1290 8 130 0 Open ; - 329 61 123 45500 30 140 0 Open ; - 330 60 601 1 30 140 0 Closed ; - 333 601 61 1 30 140 0 Open ; - -[PUMPS] -;ID Node1 Node2 Parameters - 10 Lake 10 HEAD 1 ; - 335 60 61 HEAD 2 ; - -[VALVES] -;ID Node1 Node2 Diameter Type Setting MinorLoss - -[TAGS] - -[DEMANDS] -;Junction Demand Pattern Category - -[STATUS] -;ID Status/Setting - 10 Closed - -[PATTERNS] -;ID Multipliers -;General Default Demand Pattern - 1 1.34 1.94 1.46 1.44 .76 .92 - 1 .85 1.07 .96 1.1 1.08 1.19 - 1 1.16 1.08 .96 .83 .79 .74 - 1 .64 .64 .85 .96 1.24 1.67 -;Demand Pattern for Node 123 - 2 0 0 0 0 0 1219 - 2 0 0 0 1866 1836 1818 - 2 1818 1822 1822 1817 1824 1816 - 2 1833 1817 1830 1814 1840 1859 -;Demand Pattern for Node 15 - 3 620 620 620 620 620 360 - 3 360 0 0 0 0 360 - 3 360 360 360 360 0 0 - 3 0 0 0 0 360 360 -;Demand Pattern for Node 35 - 4 1637 1706 1719 1719 1791 1819 - 4 1777 1842 1815 1825 1856 1801 - 4 1819 1733 1664 1620 1613 1620 - 4 1616 1647 1627 1627 1671 1668 -;Demand Pattern for Node 203 - 5 4439 4531 4511 4582 4531 4582 - 5 4572 4613 4643 4643 4592 4613 - 5 4531 4521 4449 4439 4449 4460 - 5 4439 4419 4368 4399 4470 4480 - -[CURVES] -;ID X-Value Y-Value -;PUMP: Pump Curve for Pump 10 (Lake Source) - 1 0 104. - 1 2000. 92. - 1 4000. 63. -;PUMP: Pump Curve for Pump 335 (River Source) - 2 0 200. - 2 8000. 138. - 2 14000. 86. - -[CONTROLS] -;Lake source operates only part of the day -Link 10 OPEN AT TIME 1 -Link 10 CLOSED AT TIME 15 - -;Pump 335 controlled by level in Tank 1 -;When pump is closed, bypass pipe is opened -Link 335 OPEN IF Node 1 BELOW 17.1 -Link 335 CLOSED IF Node 1 ABOVE 19.1 -Link 330 CLOSED IF Node 1 BELOW 17.1 -Link 330 OPEN IF Node 1 ABOVE 19.1 - - -[RULES] - -[ENERGY] - Global Efficiency 75 - Global Price 0.0 - Demand Charge 0.0 - -[EMITTERS] -;Junction Coefficient - -[QUALITY] -;Node InitQual - -[SOURCES] -;Node Type Quality Pattern - -[REACTIONS] -;Type Pipe/Tank Coefficient - - -[REACTIONS] - Order Bulk 1 - Order Tank 1 - Order Wall 1 - Global Bulk 0.0 - Global Wall 0.0 - Limiting Potential 0.0 - Roughness Correlation 0.0 - -[MIXING] -;Tank Model - -[TIMES] - Duration 24:00 - Hydraulic Timestep 1:00 - Quality Timestep 0:05 - Pattern Timestep 1:00 - Pattern Start 0:00 - Report Timestep 1:00 - Report Start 0:00 - Start ClockTime 12 am - Statistic None - -[REPORT] - Status Yes - Summary No - Page 0 - -[OPTIONS] - Units GPM - Headloss H-W - Specific Gravity 1.0 - Viscosity 1.0 - Trials 40 - Accuracy 0.001 - CHECKFREQ 2 - MAXCHECK 10 - DAMPLIMIT 0 - Unbalanced Continue 10 - Pattern 1 - Demand Multiplier 1.0 - Emitter Exponent 0.5 - Quality Trace Lake - Diffusivity 1.0 - Tolerance 0.01 - -[COORDINATES] -;Node X-Coord Y-Coord - 10 9.00 27.85 - 15 38.68 23.76 - 20 29.44 26.91 - 35 25.46 10.52 - 40 27.02 9.81 - 50 33.01 3.01 - 60 23.90 29.94 - 601 23.00 29.49 - 61 23.71 29.03 - 101 13.81 22.94 - 103 12.96 21.31 - 105 16.97 21.28 - 107 18.45 20.46 - 109 17.64 18.92 - 111 20.21 17.53 - 113 22.04 16.61 - 115 20.98 19.18 - 117 21.69 21.28 - 119 23.70 22.76 - 120 22.08 23.10 - 121 23.54 25.50 - 123 23.37 27.31 - 125 24.59 25.64 - 127 29.29 26.40 - 129 30.32 26.39 - 131 37.89 29.55 - 139 33.28 24.54 - 141 35.68 23.08 - 143 37.47 21.97 - 145 33.02 19.29 - 147 30.24 20.38 - 149 29.62 20.74 - 151 28.29 21.39 - 153 28.13 22.63 - 157 24.85 20.16 - 159 23.12 17.50 - 161 25.10 15.28 - 163 25.39 14.98 - 164 25.98 15.14 - 166 26.48 15.13 - 167 25.88 12.98 - 169 25.68 12.74 - 171 26.65 11.80 - 173 26.87 11.59 - 179 25.71 10.40 - 181 25.72 10.74 - 183 25.45 10.18 - 184 25.15 9.52 - 185 25.01 9.67 - 187 23.64 11.04 - 189 24.15 11.37 - 191 22.10 14.07 - 193 22.88 14.35 - 195 23.18 14.72 - 197 20.97 15.18 - 199 29.42 8.44 - 201 30.89 8.57 - 203 31.14 8.89 - 204 23.80 10.90 - 205 29.20 6.46 - 206 31.66 6.64 - 207 31.00 6.61 - 208 32.54 6.81 - 209 33.76 6.59 - 211 34.20 5.54 - 213 35.26 6.16 - 215 39.95 8.73 - 217 42.11 8.67 - 219 44.86 9.32 - 225 43.53 7.38 - 229 36.16 3.49 - 231 38.38 2.54 - 237 35.37 3.08 - 239 35.76 2.31 - 241 35.87 2.11 - 243 37.04 0.00 - 247 35.02 2.05 - 249 35.02 1.81 - 251 34.15 1.10 - 253 32.17 1.88 - 255 33.51 2.45 - 257 21.17 23.32 - 259 20.80 23.40 - 261 20.79 21.45 - 263 20.32 21.57 - 265 25.39 13.60 - 267 23.38 12.95 - 269 25.03 12.14 - 271 25.97 11.00 - 273 29.16 7.38 - 275 31.07 8.29 - River 24.15 31.06 - Lake 8.00 27.53 - 1 27.46 9.84 - 2 32.99 3.45 - 3 29.41 27.27 - -[VERTICES] -;Link X-Coord Y-Coord - -[LABELS] -;X-Coord Y-Coord Label & Anchor Node - 8.00 29.42 "LAKE" - 25.00 31.10 "RIVER" - -[BACKDROP] - DIMENSIONS 6.16 -1.55 46.70 32.61 - UNITS None - FILE - OFFSET 0.00 0.00 - -[END] +[TITLE] +EPANET Example Network 3 +Example showing how the percent of Lake water in a dual-source +system changes over time. + +[JUNCTIONS] +;ID Elev Demand Pattern + 10 147 0 ; + 15 32 1 3 ; + 20 129 0 ; + 35 12.5 1 4 ; + 40 131.9 0 ; + 50 116.5 0 ; + 60 0 0 ; + 601 0 0 ; + 61 0 0 ; + 101 42 189.95 ; + 103 43 133.2 ; + 105 28.5 135.37 ; + 107 22 54.64 ; + 109 20.3 231.4 ; + 111 10 141.94 ; + 113 2 20.01 ; + 115 14 52.1 ; + 117 13.6 117.71 ; + 119 2 176.13 ; + 120 0 0 ; + 121 -2 41.63 ; + 123 11 1 2 ; + 125 11 45.6 ; + 127 56 17.66 ; + 129 51 0 ; + 131 6 42.75 ; + 139 31 5.89 ; + 141 4 9.85 ; + 143 -4.5 6.2 ; + 145 1 27.63 ; + 147 18.5 8.55 ; + 149 16 27.07 ; + 151 33.5 144.48 ; + 153 66.2 44.17 ; + 157 13.1 51.79 ; + 159 6 41.32 ; + 161 4 15.8 ; + 163 5 9.42 ; + 164 5 0 ; + 166 -2 2.6 ; + 167 -5 14.56 ; + 169 -5 0 ; + 171 -4 39.34 ; + 173 -4 0 ; + 177 8 58.17 ; + 179 8 0 ; + 181 8 0 ; + 183 11 0 ; + 184 16 0 ; + 185 16 25.65 ; + 187 12.5 0 ; + 189 4 107.92 ; + 191 25 81.9 ; + 193 18 71.31 ; + 195 15.5 0 ; + 197 23 17.04 ; + 199 -2 119.32 ; + 201 0.1 44.61 ; + 203 2 1 5 ; + 204 21 0 ; + 205 21 65.36 ; + 206 1 0 ; + 207 9 69.39 ; + 208 16 0 ; + 209 -2 0.87 ; + 211 7 8.67 ; + 213 7 13.94 ; + 215 7 92.19 ; + 217 6 24.22 ; + 219 4 41.32 ; + 225 8 22.8 ; + 229 10.5 64.18 ; + 231 5 16.48 ; + 237 14 15.61 ; + 239 13 44.61 ; + 241 13 0 ; + 243 14 4.34 ; + 247 18 70.38 ; + 249 18 0 ; + 251 30 24.16 ; + 253 36 54.52 ; + 255 27 40.39 ; + 257 17 0 ; + 259 25 0 ; + 261 0 0 ; + 263 0 0 ; + 265 0 0 ; + 267 21 0 ; + 269 0 0 ; + 271 6 0 ; + 273 8 0 ; + 275 10 0 ; + +[RESERVOIRS] +;ID Head Pattern + River 220.0 ; + Lake 167.0 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + 1 131.9 13.1 .1 32.1 85 0 ; + 2 116.5 23.5 6.5 40.3 50 0 ; + 3 129.0 29.0 4.0 35.5 164 0 ; + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + 20 3 20 99 99 199 0 Open ; + 40 1 40 99 99 199 0 Open ; + 50 2 50 99 99 199 0 Open ; + 60 River 60 1231 24 140 0 Open ; + 101 10 101 14200 18 110 0 Open ; + 103 101 103 1350 16 130 0 Open ; + 105 101 105 2540 12 130 0 Open ; + 107 105 107 1470 12 130 0 Open ; + 109 103 109 3940 16 130 0 Open ; + 111 109 111 2000 12 130 0 Open ; + 112 115 111 1160 12 130 0 Open ; + 113 111 113 1680 12 130 0 Open ; + 114 115 113 2000 8 130 0 Open ; + 115 107 115 1950 8 130 0 Open ; + 116 113 193 1660 12 130 0 Open ; + 117 263 105 2725 12 130 0 Open ; + 119 115 117 2180 12 130 0 Open ; + 120 119 120 730 12 130 0 Open ; + 121 120 117 1870 12 130 0 Open ; + 122 121 120 2050 8 130 0 Open ; + 123 121 119 2000 30 141 0 Open ; + 125 123 121 1500 30 141 0 Open ; + 129 121 125 930 24 130 0 Open ; + 131 125 127 3240 24 130 0 Open ; + 133 20 127 785 20 130 0 Open ; + 135 127 129 900 24 130 0 Open ; + 137 129 131 6480 16 130 0 Open ; + 145 129 139 2750 8 130 0 Open ; + 147 139 141 2050 8 130 0 Open ; + 149 143 141 1400 8 130 0 Open ; + 151 15 143 1650 8 130 0 Open ; + 153 145 141 3510 12 130 0 Open ; + 155 147 145 2200 12 130 0 Open ; + 159 147 149 880 12 130 0 Open ; + 161 149 151 1020 8 130 0 Open ; + 163 151 153 1170 12 130 0 Open ; + 169 125 153 4560 8 130 0 Open ; + 171 119 151 3460 12 130 0 Open ; + 173 119 157 2080 30 141 0 Open ; + 175 157 159 2910 30 141 0 Open ; + 177 159 161 2000 30 141 0 Open ; + 179 161 163 430 30 141 0 Open ; + 180 163 164 150 14 130 0 Open ; + 181 164 166 490 14 130 0 Open ; + 183 265 169 590 30 141 0 Open ; + 185 167 169 60 8 130 0 Open ; + 186 187 204 99.9 8 130 0 Open ; + 187 169 171 1270 30 141 0 Open ; + 189 171 173 50 30 141 0 Open ; + 191 271 171 760 24 130 0 Open ; + 193 35 181 30 24 130 0 Open ; + 195 181 177 30 12 130 0 Open ; + 197 177 179 30 12 130 0 Open ; + 199 179 183 210 12 130 0 Open ; + 201 40 179 1190 12 130 0 Open ; + 202 185 184 99.9 8 130 0 Open ; + 203 183 185 510 8 130 0 Open ; + 204 184 205 4530. 12 130 0 Open ; + 205 204 185 1325. 12 130 0 Open ; + 207 189 183 1350 12 130 0 Open ; + 209 189 187 500 8 130 0 Open ; + 211 169 269 646 12 130 0 Open ; + 213 191 187 2560 12 130 0 Open ; + 215 267 189 1230 12 130 0 Open ; + 217 191 193 520 12 130 0 Open ; + 219 193 195 360 12 130 0 Open ; + 221 161 195 2300 8 130 0 Open ; + 223 197 191 1150 12 130 0 Open ; + 225 111 197 2790 12 130 0 Open ; + 229 173 199 4000 24 141 0 Open ; + 231 199 201 630 24 141 0 Open ; + 233 201 203 120 24 130 0 Open ; + 235 199 273 725 12 130 0 Open ; + 237 205 207 1200 12 130 0 Open ; + 238 207 206 450 12 130 0 Open ; + 239 275 207 1430 12 130 0 Open ; + 240 206 208 510 12 130 0 Open ; + 241 208 209 885 12 130 0 Open ; + 243 209 211 1210 16 130 0 Open ; + 245 211 213 990 16 130 0 Open ; + 247 213 215 4285 16 130 0 Open ; + 249 215 217 1660 16 130 0 Open ; + 251 217 219 2050 14 130 0 Open ; + 257 217 225 1560 12 130 0 Open ; + 261 213 229 2200 8 130 0 Open ; + 263 229 231 1960 12 130 0 Open ; + 269 211 237 2080 12 130 0 Open ; + 271 237 229 790 8 130 0 Open ; + 273 237 239 510 12 130 0 Open ; + 275 239 241 35 12 130 0 Open ; + 277 241 243 2200 12 130 0 Open ; + 281 241 247 445 10 130 0 Open ; + 283 239 249 430 12 130 0 Open ; + 285 247 249 10 12 130 0 Open ; + 287 247 255 1390 10 130 0 Open ; + 289 50 255 925 10 130 0 Open ; + 291 255 253 1100 10 130 0 Open ; + 293 255 251 1100 8 130 0 Open ; + 295 249 251 1450 12 130 0 Open ; + 297 120 257 645 8 130 0 Open ; + 299 257 259 350 8 130 0 Open ; + 301 259 263 1400 8 130 0 Open ; + 303 257 261 1400 8 130 0 Open ; + 305 117 261 645 12 130 0 Open ; + 307 261 263 350 12 130 0 Open ; + 309 265 267 1580 8 130 0 Open ; + 311 193 267 1170 12 130 0 Open ; + 313 269 189 646 12 130 0 Open ; + 315 181 271 260 24 130 0 Open ; + 317 273 275 2230 8 130 0 Open ; + 319 273 205 645 12 130 0 Open ; + 321 163 265 1200 30 141 0 Open ; + 323 201 275 300 12 130 0 Open ; + 325 269 271 1290 8 130 0 Open ; + 329 61 123 45500 30 140 0 Open ; + 330 60 601 1 30 140 0 Closed ; + 333 601 61 1 30 140 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + 10 Lake 10 HEAD 1 ; + 335 60 61 HEAD 2 ; + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + 10 Closed + +[PATTERNS] +;ID Multipliers +;General Default Demand Pattern + 1 1.34 1.94 1.46 1.44 .76 .92 + 1 .85 1.07 .96 1.1 1.08 1.19 + 1 1.16 1.08 .96 .83 .79 .74 + 1 .64 .64 .85 .96 1.24 1.67 +;Demand Pattern for Node 123 + 2 0 0 0 0 0 1219 + 2 0 0 0 1866 1836 1818 + 2 1818 1822 1822 1817 1824 1816 + 2 1833 1817 1830 1814 1840 1859 +;Demand Pattern for Node 15 + 3 620 620 620 620 620 360 + 3 360 0 0 0 0 360 + 3 360 360 360 360 0 0 + 3 0 0 0 0 360 360 +;Demand Pattern for Node 35 + 4 1637 1706 1719 1719 1791 1819 + 4 1777 1842 1815 1825 1856 1801 + 4 1819 1733 1664 1620 1613 1620 + 4 1616 1647 1627 1627 1671 1668 +;Demand Pattern for Node 203 + 5 4439 4531 4511 4582 4531 4582 + 5 4572 4613 4643 4643 4592 4613 + 5 4531 4521 4449 4439 4449 4460 + 5 4439 4419 4368 4399 4470 4480 + +[CURVES] +;ID X-Value Y-Value +;PUMP: Pump Curve for Pump 10 (Lake Source) + 1 0 104. + 1 2000. 92. + 1 4000. 63. +;PUMP: Pump Curve for Pump 335 (River Source) + 2 0 200. + 2 8000. 138. + 2 14000. 86. + +[CONTROLS] +;Lake source operates only part of the day +Link 10 OPEN AT TIME 1 +Link 10 CLOSED AT TIME 15 + +;Pump 335 controlled by level in Tank 1 +;When pump is closed, bypass pipe is opened +Link 335 OPEN IF Node 1 BELOW 17.1 +Link 335 CLOSED IF Node 1 ABOVE 19.1 +Link 330 CLOSED IF Node 1 BELOW 17.1 +Link 330 OPEN IF Node 1 ABOVE 19.1 + + +[RULES] + +[ENERGY] + Global Efficiency 75 + Global Price 0.0 + Demand Charge 0.0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk 0.0 + Global Wall 0.0 + Limiting Potential 0.0 + Roughness Correlation 0.0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Pattern Timestep 1:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic None + +[REPORT] + Status Yes + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1.0 + Viscosity 1.0 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Trace Lake + Diffusivity 1.0 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + 10 9.00 27.85 + 15 38.68 23.76 + 20 29.44 26.91 + 35 25.46 10.52 + 40 27.02 9.81 + 50 33.01 3.01 + 60 23.90 29.94 + 601 23.00 29.49 + 61 23.71 29.03 + 101 13.81 22.94 + 103 12.96 21.31 + 105 16.97 21.28 + 107 18.45 20.46 + 109 17.64 18.92 + 111 20.21 17.53 + 113 22.04 16.61 + 115 20.98 19.18 + 117 21.69 21.28 + 119 23.70 22.76 + 120 22.08 23.10 + 121 23.54 25.50 + 123 23.37 27.31 + 125 24.59 25.64 + 127 29.29 26.40 + 129 30.32 26.39 + 131 37.89 29.55 + 139 33.28 24.54 + 141 35.68 23.08 + 143 37.47 21.97 + 145 33.02 19.29 + 147 30.24 20.38 + 149 29.62 20.74 + 151 28.29 21.39 + 153 28.13 22.63 + 157 24.85 20.16 + 159 23.12 17.50 + 161 25.10 15.28 + 163 25.39 14.98 + 164 25.98 15.14 + 166 26.48 15.13 + 167 25.88 12.98 + 169 25.68 12.74 + 171 26.65 11.80 + 173 26.87 11.59 + 177 26.00 10.50 + 179 25.71 10.40 + 181 25.72 10.74 + 183 25.45 10.18 + 184 25.15 9.52 + 185 25.01 9.67 + 187 23.64 11.04 + 189 24.15 11.37 + 191 22.10 14.07 + 193 22.88 14.35 + 195 23.18 14.72 + 197 20.97 15.18 + 199 29.42 8.44 + 201 30.89 8.57 + 203 31.14 8.89 + 204 23.80 10.90 + 205 29.20 6.46 + 206 31.66 6.64 + 207 31.00 6.61 + 208 32.54 6.81 + 209 33.76 6.59 + 211 34.20 5.54 + 213 35.26 6.16 + 215 39.95 8.73 + 217 42.11 8.67 + 219 44.86 9.32 + 225 43.53 7.38 + 229 36.16 3.49 + 231 38.38 2.54 + 237 35.37 3.08 + 239 35.76 2.31 + 241 35.87 2.11 + 243 37.04 0.00 + 247 35.02 2.05 + 249 35.02 1.81 + 251 34.15 1.10 + 253 32.17 1.88 + 255 33.51 2.45 + 257 21.17 23.32 + 259 20.80 23.40 + 261 20.79 21.45 + 263 20.32 21.57 + 265 25.39 13.60 + 267 23.38 12.95 + 269 25.03 12.14 + 271 25.97 11.00 + 273 29.16 7.38 + 275 31.07 8.29 + River 24.15 31.06 + Lake 8.00 27.53 + 1 27.46 9.84 + 2 32.99 3.45 + 3 29.41 27.27 + +[VERTICES] +;Link X-Coord Y-Coord + +[LABELS] +;X-Coord Y-Coord Label & Anchor Node + 8.00 29.42 "LAKE" + 25.00 31.10 "RIVER" + +[BACKDROP] + DIMENSIONS 6.16 -1.55 46.70 32.61 + UNITS None + FILE + OFFSET 0.00 0.00 + +[END] From 83f4bc063b0208835f96fcbec8d14a2eba62cadf Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 9 Jun 2023 09:34:00 +0800 Subject: [PATCH 3/6] Remove unused import --- api/s33_dma_cal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/s33_dma_cal.py b/api/s33_dma_cal.py index c06f76b..5f30967 100644 --- a/api/s33_dma_cal.py +++ b/api/s33_dma_cal.py @@ -2,7 +2,7 @@ import ctypes import os from .database import * 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 import get_region From 2c5ca5ef53522e540476daf890019d21c7cd13c9 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 9 Jun 2023 09:34:53 +0800 Subject: [PATCH 4/6] Add more temp table for calculation --- script/sql/create/32.region.sql | 10 +++++++++- script/sql/drop/32.region.sql | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/script/sql/create/32.region.sql b/script/sql/create/32.region.sql index 9f52f6a..588836b 100644 --- a/script/sql/create/32.region.sql +++ b/script/sql/create/32.region.sql @@ -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) +, geom geometry not null unique +); + + +create table temp_link_2 +( + link varchar(32) primary key references _link(id) +, geom geometry not null unique ); diff --git a/script/sql/drop/32.region.sql b/script/sql/drop/32.region.sql index 9b38883..8a28409 100644 --- a/script/sql/drop/32.region.sql +++ b/script/sql/drop/32.region.sql @@ -1,6 +1,8 @@ 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; From 2b424e47100b43ced8026ae5d38ffaccd05ad020 Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 9 Jun 2023 09:36:11 +0800 Subject: [PATCH 5/6] Improve boundary algorithm --- api/s32_region_util.py | 183 ++++++++++++++++++++++++++++++++++++++--- test_tjnetwork.py | 34 ++++---- 2 files changed, 188 insertions(+), 29 deletions(-) diff --git a/api/s32_region_util.py b/api/s32_region_util.py index 6a4f6cc..d5ec1c0 100644 --- a/api/s32_region_util.py +++ b/api/s32_region_util.py @@ -25,6 +25,13 @@ def to_postgis_polygon(boundary: list[tuple[float, float]]) -> str: 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]: api = 'get_nodes_in_boundary' 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']: self._max_x_node = node - self._links = {} + self._links: dict[str, Any] = {} self._link_list: list[str] = [] for node in self._nodes: for link in get_node_links(db, node): @@ -140,25 +147,21 @@ class Topology: return self._link_list -def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]: - topology = Topology(name, nodes) - t_nodes = topology.nodes() - t_links = topology.links() - - cursor = topology.max_x_node() +def _calculate_boundary(name: str, cursor: str, t_nodes: dict[str, Any], t_links: dict[str, Any]) -> tuple[list[str], dict[str, list[str]], list[tuple[float, float]]]: in_angle = 0 - paths: list[str] = [] + vertices: list[str] = [] + path: dict[str, list[str]] = {} while True: # prevent duplicated node - if len(paths) > 0 and cursor == paths[-1]: + if len(vertices) > 0 and cursor == vertices[-1]: break # prevent duplicated path - if len(paths) >= 3 and paths[0] == paths[-1] and paths[1] == cursor: + if len(vertices) >= 3 and vertices[0] == vertices[-1] and vertices[1] == cursor: break - paths.append(cursor) + vertices.append(cursor) sorted_links = [] overlapped_link = '' @@ -171,7 +174,8 @@ 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] + path[overlapped_link] = [] + cursor = vertices[-2] in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links) continue @@ -182,13 +186,166 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] out_link = link break + path[out_link] = [] cursor = t_links[out_link]['node1'] if cursor == t_links[out_link]['node2'] else t_links[out_link]['node2'] in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links) boundary: list[tuple[float, float]] = [] - for node in paths: + for node in vertices: 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(name, 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 + write(name, f"insert into temp_region (id, boundary) values ('{api}', '{to_postgis_linestring(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) + + 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(name, 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 diff --git a/test_tjnetwork.py b/test_tjnetwork.py index 108e778..1f7e717 100644 --- a/test_tjnetwork.py +++ b/test_tjnetwork.py @@ -5832,9 +5832,9 @@ class TestApi: dmas = calculate_district_metering_area_for_nodes(p, get_nodes(p), 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[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[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[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', '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] == ['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) @@ -5844,15 +5844,15 @@ class TestApi: read_inp(p, f'./inp/net3.inp', '3') 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)]})) nodes = get_nodes_in_region(p, 'r') assert len(nodes) == 97 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) @@ -5864,9 +5864,9 @@ class TestApi: dmas = calculate_district_metering_area_for_network(p, 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[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[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[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', '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] == ['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) @@ -6150,13 +6150,16 @@ class TestApi: assert cs[1]['id'] == 'DMA_[DMA_1_1]_2_2' 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]['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]['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 assert len(cs) == 2 @@ -6168,10 +6171,10 @@ class TestApi: assert cs[1]['id'] == 'DMA_[DMA_1_3]_2_2' dmas = get_all_district_metering_area_ids(p) - assert len(dmas) == 9 + assert len(dmas) == 10 cs = generate_district_metering_area(p, 3).operations - assert len(cs) == 12 + assert len(cs) == 13 dmas = get_all_district_metering_area_ids(p) assert len(dmas) == 3 @@ -6585,8 +6588,7 @@ class TestApi: open_project(p) 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) From a4f477f8eb8cc795fec10850d82d3d1e228930dc Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Fri, 9 Jun 2023 21:24:16 +0800 Subject: [PATCH 6/6] Refine code --- api/s32_region_util.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/s32_region_util.py b/api/s32_region_util.py index d5ec1c0..7970343 100644 --- a/api/s32_region_util.py +++ b/api/s32_region_util.py @@ -147,7 +147,7 @@ class Topology: return self._link_list -def _calculate_boundary(name: str, cursor: str, t_nodes: dict[str, Any], t_links: dict[str, Any]) -> tuple[list[str], dict[str, 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]]]: in_angle = 0 vertices: list[str] = [] @@ -241,14 +241,15 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] t_nodes = topology.nodes() t_links = topology.links() - vertices, path, boundary = _calculate_boundary(name, topology.max_x_node(), t_nodes, t_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 - write(name, f"insert into temp_region (id, boundary) values ('{api}', '{to_postgis_linestring(boundary)}')") + # 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: @@ -325,6 +326,7 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] 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") @@ -339,7 +341,7 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] new_nodes[values['node1']]['links'].append(link) new_nodes[values['node2']]['links'].append(link) - _, _, boundary = _calculate_boundary(name, topology.max_x_node(), new_nodes, new_links) + _, _, 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")