from psycopg.rows import dict_row from ..core.connection import project_connection from ..core.database import read_all, sql_literal, try_read, write from ..core.connection import project_connection from ..model.elements import get_link_nodes from psycopg.rows import dict_row def sql_update_coord(node: str, x: float, y: float) -> str: geom = f"st_setsrid(st_makepoint({sql_literal(x)}, {sql_literal(y)}), 900914)" return f"update gis.node_geometries set geom = {geom} where node_id = {sql_literal(node)};" def sql_insert_coord(node: str, x: float, y: float) -> str: geom = f"st_setsrid(st_makepoint({sql_literal(x)}, {sql_literal(y)}), 900914)" return f"insert into gis.node_geometries (node_id, geom) values ({sql_literal(node)}, {geom});" def sql_delete_coord(node: str) -> str: return f"delete from gis.node_geometries where node_id = {sql_literal(node)};" def from_postgis_point(coord: str) -> dict[str, float]: xy = coord.lower().removeprefix('point(').removesuffix(')').split(' ') return { 'x': float(xy[0]), 'y': float(xy[1]) } def get_node_coord(name: str, node: str) -> dict[str, float]: row = try_read( name, "select st_astext(geom) as coord_geom from gis.node_geometries where node_id = %s", (node,), ) if row == None: write(name, sql_insert_coord(node, 0.0, 0.0)) return {'x': 0.0, 'y': 0.0} return from_postgis_point(row['coord_geom']) # DingZQ 2025-01-03, get nodes in extent # return node id list # node_id:junction:x:y def get_nodes_in_extent(name: str, x1: float, y1: float, x2: float, y2: float) -> list[str]: nodes = [] objs = read_all(name, 'select node_id, st_astext(geom) as coord_geom from gis.node_geometries') for obj in objs: node_id = obj['node_id'] coord = from_postgis_point(obj['coord_geom']) x = coord['x'] y = coord['y'] if x1 <= x <= x2 and y1 <= y <= y2: nodes.append(f"{node_id}:junction:{x}:{y}") return nodes # DingZQ 2025-01-03, get links in extent # return link id list # link_id:pipe:node_id1:node_id2 def get_links_in_extent(name: str, x1: float, y1: float, x2: float, y2: float) -> list[str]: node_ids = set([s.split(':')[0] for s in get_nodes_in_extent(name, x1, y1, x2, y2)]) all_link_ids = [] with project_connection(name) as conn: with conn.cursor(row_factory=dict_row) as cur: cur.execute("select link_id from network.pipes") for record in cur: all_link_ids.append(record['link_id']) links = [] for link_id in all_link_ids: nodes = get_link_nodes(name, link_id) if nodes[0] in node_ids and nodes[1] in node_ids: links.append(f"{link_id}:pipe:{nodes[0]}:{nodes[1]}") return links def node_has_coord(name: str, node: str) -> bool: return try_read( name, "select node_id from gis.node_geometries where node_id = %s", (node,) ) != None #-------------------------------------------------------------- # [EPA2][EPA3][IN][OUT] # id x y #-------------------------------------------------------------- # exception ! need merge to node change set ! def inp_in_coord(line: str) -> str: tokens = line.split() node = tokens[0] x, y = float(tokens[1]), float(tokens[2]) return sql_insert_coord(node, x, y) def inp_out_coord(name: str) -> list[str]: lines = [] objs = read_all(name, 'select node_id, st_astext(geom) as coord_geom from gis.node_geometries') for obj in objs: node = obj['node_id'] coord = from_postgis_point(obj['coord_geom']) x = coord['x'] y = coord['y'] lines.append(f'{node} {x} {y}') return lines