from typing import Any from ..core.database import ( ChangeSet, DatabaseCommand, execute_command, g_add_prefix, g_delete_prefix, g_update_prefix, read_all, sql_literal, try_read, ) def get_vertex_schema(name: str) -> dict[str, dict[str, Any]]: return { 'link' : {'type': 'str' , 'optional': False , 'readonly': True }, 'coords' : {'type': 'list' , 'optional': False , 'readonly': False, 'element': { 'x' : {'type': 'float' , 'optional': False , 'readonly': False }, 'y' : {'type': 'float' , 'optional': False , 'readonly': False } }}} def get_vertex(name: str, link: str) -> dict[str, Any]: cus = read_all(name, "select st_x(geom) as x, st_y(geom) as y from gis.link_vertices where link_id = %s order by sequence_no", (link,)) cs = [] for r in cus: cs.append({ 'x': float(r['x']), 'y': float(r['y']) }) return { 'link': link, 'coords': cs } def _set_vertex(name: str, cs: ChangeSet) -> DatabaseCommand: link = cs.operations[0]['link'] new = { 'link': link, 'coords': [] } f_link = sql_literal(link) statement = f"delete from gis.link_vertices where link_id = {f_link};" for sequence_no, xy in enumerate(cs.operations[0]['coords']): x, y = float(xy['x']), float(xy['y']) f_x, f_y = sql_literal(x), sql_literal(y) statement += f"\ninsert into gis.link_vertices (link_id, sequence_no, geom) values ({f_link}, {sequence_no}, st_setsrid(st_makepoint({f_x}, {f_y}), 900914));" new['coords'].append({ 'x': x, 'y': y }) change = { 'type': 'vertex' } | new return DatabaseCommand(statement, [change]) def set_vertex(name: str, cs: ChangeSet) -> ChangeSet: result = _set_vertex(name, cs) result.changes[0] |= g_update_prefix return execute_command(name, result) def _add_vertex(name: str, cs: ChangeSet) -> DatabaseCommand: result = _set_vertex(name, cs) result.changes[0] |= g_add_prefix return result def _delete_vertex(name: str, cs: ChangeSet) -> DatabaseCommand: cs.operations[0]['coords'] = [] result = _set_vertex(name, cs) result.changes[0] |= g_delete_prefix return result def add_vertex(name: str, cs: ChangeSet) -> ChangeSet: result = _add_vertex(name, cs) return execute_command(name, result) def delete_vertex(name: str, cs: ChangeSet) -> ChangeSet: result = _delete_vertex(name, cs) return execute_command(name, result) def get_all_vertex_links(name: str) -> list[str]: result : list[str] = [] rows = read_all(name, 'select distinct link_id from gis.link_vertices order by link_id') for row in rows: result.append(str(row['link_id'])) return result def get_all_vertices(name: str) -> list[dict[str, Any]]: return read_all(name, 'select link_id, sequence_no, st_x(geom) as x, st_y(geom) as y from gis.link_vertices order by link_id, sequence_no') #-------------------------------------------------------------- # [EPA2][IN][OUT] # id x y # [EPA3][NOT SUPPORT] #-------------------------------------------------------------- def inp_in_vertex(line: str) -> str: tokens = line.split() link = tokens[0] x = float(tokens[1]) y = float(tokens[2]) link_sql = sql_literal(link) return f"insert into gis.link_vertices (link_id, sequence_no, geom) values ({link_sql}, (select coalesce(max(sequence_no) + 1, 0) from gis.link_vertices where link_id = {link_sql}), st_setsrid(st_makepoint({sql_literal(x)}, {sql_literal(y)}), 900914));" def inp_out_vertex(name: str) -> list[str]: lines = [] objs = read_all(name, "select link_id, st_x(geom) as x, st_y(geom) as y from gis.link_vertices order by link_id, sequence_no") for obj in objs: link = obj['link_id'] x = obj['x'] y = obj['y'] lines.append(f"{link} {x} {y}") return lines def delete_vertex_by_link(name: str, link: str) -> ChangeSet: row = try_read(name, "select * from gis.link_vertices where link_id = %s", (link,)) if row == None: return ChangeSet() return ChangeSet(g_delete_prefix | {'type': 'vertex', 'link' : link})