calc_flowdirection.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. '''calc flow direction.
  2. step1. division block.
  3. step2. appoint source.
  4. setp3. calc flow direction.
  5. '''
  6. from systemrelation import systemdatautils
  7. import networkx as nx
  8. from systemrelation import revit_const
  9. def calc(project_id,block_id):
  10. '''
  11. calc block flow direction.
  12. :param project_id:
  13. :param block_id:
  14. :return:
  15. '''
  16. block_datas=systemdatautils.get_connected_block_data(project_id,block_id)
  17. source_datas=systemdatautils.get_connected_block_source_data(project_id,block_id)
  18. # get roots
  19. roots=list(i.source_id for i in source_datas)
  20. g = nx.Graph()
  21. for item in block_datas:
  22. item.direction=None
  23. g.add_edge(item.id1,item.id2);
  24. G = g.to_directed()
  25. # get leaves
  26. leaves=list(v for v,d in G.out_degree() if d==1)
  27. G_new=nx.DiGraph()
  28. try:
  29. for i in range(len(roots)):
  30. root=roots[i]
  31. for leaf in leaves:
  32. paths = nx.all_simple_paths(G, root, leaf)
  33. for path in paths:
  34. # remove contain source path
  35. if is_path_contain_root(path, roots, root):
  36. continue
  37. # set path direction
  38. for j in range(len(path) - 1):
  39. G_new.add_edge(path[j], path[j + 1],weight=str(j))
  40. # add source direct to source path.
  41. for j in range(i + 1, len(roots)):
  42. next_root=roots[j]
  43. paths = list(nx.all_simple_paths(G, root, next_root))
  44. for path in paths:
  45. if len(path) == 2:
  46. G_new.add_edge(root, next_root,weight="0")
  47. G_new.add_edge(next_root, root,weight="0")
  48. except Exception as ex:
  49. print(ex)
  50. for edge in G_new.edges:
  51. edge_data=G_new.get_edge_data(edge[0],edge[1])
  52. weight=edge_data["weight"]
  53. set_edge_direction(block_datas,edge,weight)
  54. return block_datas
  55. def is_path_contain_root(path, roots, cur_root):
  56. '''
  57. judge whether path contain root node except cur_root.
  58. :param path:
  59. :param roots:
  60. :param cur_root:
  61. :return:
  62. '''
  63. result = False
  64. for root in roots:
  65. if root == cur_root:
  66. continue
  67. result = (root in path)
  68. if result:
  69. break
  70. return result
  71. def set_edge_direction(block_datas,edge,weight):
  72. '''
  73. set connected_block direction.
  74. connector1 to connector2.sign:1
  75. connector2 to connector1.sign:-1
  76. both way.sign:0
  77. un calc.sign:None
  78. :param block_datas:
  79. :param edge:
  80. :return:
  81. '''
  82. for block_data in block_datas:
  83. # connector1 to connector2.sign:1
  84. if block_data.id1 == edge[0] and block_data.id2 == edge[1]:
  85. j=1
  86. block_data.direction=(block_data.direction+j if block_data.direction else j)
  87. block_data.block_id=str(weight)
  88. # connector2 to connector1.sing:-1
  89. if block_data.id1 == edge[1] and block_data.id2 == edge[0]:
  90. j = -1
  91. block_data.direction=(block_data.direction+j if block_data.direction else j)
  92. block_data.block_id = str(weight)