From 20da69c7a6efc3d7bad46f5d127ba010b10ea2af Mon Sep 17 00:00:00 2001 From: wqy Date: Fri, 19 Jan 2024 00:08:04 +0800 Subject: [PATCH] Improve SA algorithm --- api/s34_sa_cal.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/api/s34_sa_cal.py b/api/s34_sa_cal.py index fd656f6..1a6faf1 100644 --- a/api/s34_sa_cal.py +++ b/api/s34_sa_cal.py @@ -1,3 +1,73 @@ +import os +import ctypes +from .project import have_project +from .inp_out import dump_inp + +def calculate_service_area(name: str) -> list[dict[str, list[str]]]: + if not have_project(name): + raise Exception(f'Not found project [{name}]') + + dir = os.path.abspath(os.getcwd()) + + inp_str = os.path.join(os.path.join(dir, 'db_inp'), name + '.db.inp') + dump_inp(name, inp_str, '2') + + toolkit = ctypes.CDLL(os.path.join(os.path.join(dir, 'api'), 'toolkit.dll')) + + inp = ctypes.c_char_p(inp_str.encode()) + + handle = ctypes.c_ulonglong() + toolkit.TK_ServiceArea_Start(inp, ctypes.byref(handle)) + + c_nodeCount = ctypes.c_size_t() + toolkit.TK_ServiceArea_GetNodeCount(handle, ctypes.byref(c_nodeCount)) + nodeCount = c_nodeCount.value + + nodeIds: list[str] = [] + + for n in range(0, nodeCount): + id = ctypes.c_char_p() + toolkit.TK_ServiceArea_GetNodeId(handle, ctypes.c_size_t(n), ctypes.byref(id)) + nodeIds.append(id.value.decode()) + + c_timeCount = ctypes.c_size_t() + toolkit.TK_ServiceArea_GetTimeCount(handle, ctypes.byref(c_timeCount)) + timeCount = c_timeCount.value + + results: list[dict[str, list[str]]] = [] + + for t in range(0, timeCount): + c_sourceCount = ctypes.c_size_t() + toolkit.TK_ServiceArea_GetSourceCount(handle, ctypes.c_size_t(t), ctypes.byref(c_sourceCount)) + sourceCount = c_sourceCount.value + + sources = ctypes.POINTER(ctypes.c_size_t)() + toolkit.TK_ServiceArea_GetSources(handle, ctypes.c_size_t(t), ctypes.byref(sources)) + + result: dict[str, list[str]] = {} + for s in range(0, sourceCount): + result[nodeIds[sources[s]]] = [] + + for n in range(0, nodeCount): + concentration = ctypes.POINTER(ctypes.c_double)() + toolkit.TK_ServiceArea_GetConcentration(handle, ctypes.c_size_t(t), ctypes.c_size_t(n), ctypes.byref(concentration)) + + maxS = sources[0] + maxC = concentration[0] + for s in range(1, sourceCount): + if concentration[s] > maxC: + maxS = sources[s] + maxC = concentration[s] + + result[nodeIds[maxS]].append(nodeIds[n]) + + results.append(result) + + toolkit.TK_ServiceArea_End(handle) + + return results + +''' import sys import json from queue import Queue @@ -7,7 +77,6 @@ from .s0_base import get_node_links, get_link_nodes sys.path.append('..') from epanet.epanet import run_project - def _calculate_service_area(name: str, inp, time_index: int = 0) -> dict[str, list[str]]: sources : dict[str, list[str]] = {} for node_result in inp['node_results']: @@ -126,3 +195,4 @@ def calculate_service_area(name: str) -> list[dict[str, list[str]]]: result.append(sas) return result +'''