Files
KSP_project/topology_api/seed/seed_layout.py
T

124 lines
5.6 KiB
Python

# topology_api/seed/seed_layout.py
"""Seed diagram layout and node positions for the engineering overview SVG."""
import json
from topology_api.db import write_cursor
def seed():
with write_cursor() as cur:
# Get base
cur.execute("SELECT id FROM bases WHERE code = 'guanghan'")
base_id = cur.fetchone()["id"]
# Upsert layout
cur.execute("""
INSERT INTO diagram_layouts (id, base_id, layout_key, name,
canvas_width, canvas_height, is_default)
VALUES (gen_random_uuid(), %(base)s, 'engineering_overview_v1',
'工程总图 v1', 1500, 1900, true)
ON CONFLICT (base_id, layout_key) DO UPDATE
SET name = EXCLUDED.name, is_default = true
RETURNING id
""", {"base": base_id})
layout_id = cur.fetchone()["id"]
print(f"Layout: {layout_id}")
# Component key → component_id mapping
cur.execute("SELECT component_key, id FROM components WHERE base_id = %(base)s",
{"base": base_id})
comp_map = {r["component_key"]: r["id"] for r in cur.fetchall()}
# Layout and concise engineering labels. All visual semantics live here,
# not in the Wiki page.
nodes = [
# Core cross
("core_cabin", 630, 470, 240, 200, "core-card", None, 10,
"四向安装节点", "北 / 东 / 南 / 西", {}, ["core_cabin"]),
("habitat_2", 630, 220, 240, 140, "node-card", "居住舱#2", 5,
"核心舱北部安装口", "4铺位 + 2睡袋", {}, ["habitat_2"]),
("habitat_1", 630, 760, 240, 120, "node-card", "居住舱#1", 5,
"核心舱南部安装口", None, {}, ["habitat_1"]),
("greenhouse", 330, 490, 220, 160, "node-card", "温室模块", 5,
"核心舱西部安装口", "远端连接吴刚二号", {}, ["greenhouse"]),
("lab_module", 950, 490, 220, 160, "node-card", "实验舱", 5,
"核心舱东部安装口", "三温区实验舱", {}, ["lab_module"]),
("wugang_2", 40, 495, 210, 150, "vehicle-card", None, 3,
"Block 2 载人着陆器", "温室远端接口", {}, ["wugang_2"]),
# Power cross
("power_module_hub", 650, 1260, 200, 180, "power-node-card",
"电力模块", 8, "四向安装节点", "核电与资源中枢", {},
["power_module_hub"]),
("power_storage_rack", 600, 990, 300, 160, "power-card",
"北部模块", 5, "电力模块存储支架", "加压走道端",
{"radiator": True}, ["power_storage_rack"]),
("nuclear_reactor", 620, 1540, 260, 150, "power-card",
"南部模块", 5, "核反应堆", "30%功率",
{"radiator": True}, ["nuclear_reactor"]),
# Power west/east groups (multiple DB components per SVG node)
("power_west_group", 280, 1250, 260, 200, "power-card",
"西部模块", 5, "ISRU · 采矿", "矿石 / 燃料存储",
{"radiator": True},
["isru_module", "mining_module", "ore_fuel_storage"]),
("power_east_group", 960, 1250, 260, 200, "power-card",
"东部模块", 5, "核燃料存储 · 离心机", None,
{"radiator": True},
["fuel_storage_mod", "centrifuge_mod"]),
# Bingluns
("binglun_1", 30, 1280, 210, 140, "vehicle-card", None, 2,
"电力模块西侧", "燃料运输", {}, ["binglun_1"]),
("binglun_2", 645, 1740, 210, 120, "vehicle-card", None, 2,
"电力模块南侧", None, {}, ["binglun_2"]),
("binglun_3", 1260, 1280, 210, 140, "vehicle-card", None, 2,
"电力模块东侧", "Block 2", {}, ["binglun_3"]),
]
# Delete existing nodes and re-insert
cur.execute("DELETE FROM diagram_nodes WHERE layout_id = %(lid)s",
{"lid": layout_id})
for (
node_key, x, y, w, h, style, label, z, display_meta,
display_hint, decorations, member_keys,
) in nodes:
primary_component_id = (
comp_map[member_keys[0]] if len(member_keys) == 1 else None
)
cur.execute("""
INSERT INTO diagram_nodes
(id, layout_id, component_id, node_key, x, y,
width, height, style_key, label_override, z_index,
display_meta, display_hint, decorations)
VALUES (gen_random_uuid(), %(lid)s, %(cid)s, %(nkey)s,
%(x)s, %(y)s, %(w)s, %(h)s,
%(style)s, %(label)s, %(z)s,
%(meta)s, %(hint)s, %(decorations)s)
RETURNING id
""", {
"lid": layout_id, "cid": primary_component_id,
"nkey": node_key,
"x": x, "y": y, "w": w, "h": h,
"style": style, "label": label, "z": z,
"meta": display_meta, "hint": display_hint,
"decorations": json.dumps(decorations),
})
node_id = cur.fetchone()["id"]
for display_order, member_key in enumerate(member_keys):
cur.execute("""
INSERT INTO diagram_node_members
(diagram_node_id, component_id, display_order)
VALUES (%(node)s, %(component)s, %(display_order)s)
""", {
"node": node_id,
"component": comp_map[member_key],
"display_order": display_order,
})
print(f"Nodes inserted: {len(nodes)}")
if __name__ == "__main__":
seed()