xy_process.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import random
  2. import copy
  3. def generate_unique_id():
  4. """生成一个随机的整数ID"""
  5. return random.randint(1000000, 99999999)
  6. def _points_list_to_xy_dicts(points: list) -> list:
  7. """
  8. 后端 -> 前端
  9. [[x, y], ...] => [{"id": 123, "x": x, "y": y}, ...]
  10. """
  11. if not points:
  12. return []
  13. return [
  14. {"id": generate_unique_id(), "x": p[0], "y": p[1]}
  15. for p in points if len(p) >= 2
  16. ]
  17. def _xy_dicts_to_points_list(xy_dicts: list) -> list:
  18. """
  19. 前端 -> 后端
  20. [{"id": 123, "x": x, "y": y}, ...] => [[x, y], ...]
  21. """
  22. if not xy_dicts:
  23. return []
  24. # 兼容处理:万一前端传回来的已经是列表列表格式,直接返回
  25. if len(xy_dicts) > 0 and isinstance(xy_dicts[0], list):
  26. return xy_dicts
  27. return [
  28. [d.get("x"), d.get("y")]
  29. for d in xy_dicts
  30. if "x" in d and "y" in d
  31. ]
  32. def convert_internal_to_xy_format(internal_json: dict) -> dict:
  33. """
  34. 将后端存储的 JSON 转换为前端需要的 XY + ID 格式
  35. 1. points 变为对象列表
  36. 2. defects 中的每一项增加 id
  37. """
  38. if not internal_json:
  39. return {}
  40. # 深拷贝以免修改原始缓存或对象
  41. data = copy.deepcopy(internal_json)
  42. result = data.get("result", {})
  43. # 1. 处理 Center Result (Box Result)
  44. # 路径通常是: result -> center_result -> box_result -> inner_box/outer_box -> shapes -> points
  45. center_result = result.get("center_result", {})
  46. box_result = center_result.get("box_result", {})
  47. for box_key in ["inner_box", "outer_box"]:
  48. if box_key in box_result:
  49. shapes = box_result[box_key].get("shapes", [])
  50. for shape in shapes:
  51. if "points" in shape:
  52. shape["points"] = _points_list_to_xy_dicts(shape["points"])
  53. if "rect_box" in shape:
  54. shape["rect_box"] = _points_list_to_xy_dicts(shape["rect_box"])
  55. # 2. 处理 Defect Result
  56. # 路径通常是: result -> defect_result -> defects -> [item] -> (id & points)
  57. defect_result = result.get("defect_result", {})
  58. defects = defect_result.get("defects", [])
  59. for defect in defects:
  60. # 给缺陷本身加一个 ID
  61. if "id" not in defect:
  62. defect["id"] = generate_unique_id()
  63. # 处理缺陷的坐标点
  64. if "points" in defect:
  65. defect["points"] = _points_list_to_xy_dicts(defect["points"])
  66. return data
  67. def convert_xy_to_internal_format(frontend_json: dict) -> dict:
  68. """
  69. 将前端传来的 XY + ID 格式还原为后端存储格式
  70. 1. points 还原为 [[x,y]]
  71. 2. 丢弃为了前端展示生成的临时 ID (defects 里的 id 可以保留也可以丢弃,这里选择保留以免影响逻辑,但 points 里的必须变回列表)
  72. """
  73. if not frontend_json:
  74. return {}
  75. data = copy.deepcopy(frontend_json)
  76. result = data.get("result", {})
  77. # 1. 处理 Center Result
  78. center_result = result.get("center_result", {})
  79. box_result = center_result.get("box_result", {})
  80. for box_key in ["inner_box", "outer_box"]:
  81. if box_key in box_result:
  82. shapes = box_result[box_key].get("shapes", [])
  83. for shape in shapes:
  84. if "points" in shape:
  85. shape["points"] = _xy_dicts_to_points_list(shape["points"])
  86. if "rect_box" in shape:
  87. shape["rect_box"] = _xy_dicts_to_points_list(shape["rect_box"])
  88. # 2. 处理 Defect Result
  89. defect_result = result.get("defect_result", {})
  90. defects = defect_result.get("defects", [])
  91. for defect in defects:
  92. # points 还原
  93. if "points" in defect:
  94. defect["points"] = _xy_dicts_to_points_list(defect["points"])
  95. # 这里的 defect["id"] 如果后端不需要存储,可以 del defect["id"]
  96. # if "id" in defect: del defect["id"]
  97. return data