Преглед изворни кода

mxg:add system relation calc

mengxiangge пре 5 година
родитељ
комит
ebca2fe800

+ 0 - 2
.idea/.gitignore

@@ -1,2 +0,0 @@
-# Default ignored files
-/workspace.xml

+ 0 - 7
.idea/dictionaries/highing.xml

@@ -1,7 +0,0 @@
-<component name="ProjectDictionaryState">
-  <dictionary name="highing">
-    <words>
-      <w>revit</w>
-    </words>
-  </dictionary>
-</component>

+ 0 - 6
.idea/inspectionProfiles/profiles_settings.xml

@@ -1,6 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="USE_PROJECT_PROFILE" value="false" />
-    <version value="1.0" />
-  </settings>
-</component>

+ 1 - 1
.idea/misc.xml

@@ -3,5 +3,5 @@
   <component name="JavaScriptSettings">
     <option name="languageLevel" value="ES6" />
   </component>
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (fry)" project-jdk-type="Python SDK" />
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
 </project>

+ 3 - 2
.idea/relations.iml

@@ -2,10 +2,11 @@
 <module type="PYTHON_MODULE" version="4">
   <component name="NewModuleRootManager">
     <content url="file://$MODULE_DIR$" />
-    <orderEntry type="jdk" jdkName="Python 3.7 (fry)" jdkType="Python SDK" />
+    <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
   <component name="TestRunnerService">
-    <option name="PROJECT_TEST_RUNNER" value="Unittests" />
+    <option name="projectConfiguration" value="Twisted Trial" />
+    <option name="PROJECT_TEST_RUNNER" value="Twisted Trial" />
   </component>
 </module>

+ 0 - 0
systemrelation/__init__.py


+ 187 - 0
systemrelation/graph_model.py

@@ -0,0 +1,187 @@
+"""Graph Model.
+
+"""
+from enum import Enum
+from systemrelation import graph_model
+from systemrelation import systemdatautils
+from systemrelation import systemutils
+
+
+class SystemEdge:
+	"""Graph Edge."""
+	# edge data.contain all edge element
+	flow_direction = 0
+
+	def __init__(self, system_data):
+		self.system_data = system_data
+# @property
+# def start_vertex(self):
+# 	return self.start_vertex
+#
+# @property
+# def end_vertex(self):
+# 	return self.end_vertex
+
+
+class SystemVertex:
+	"""Graph Vertex.
+	"""
+	vertex_type = 0
+
+	def __init__(self, system_data):
+		self.system_data = system_data
+
+	def __str__(self):
+		return str(self.system_data.source_id)
+
+
+class SystemGraph:
+	"""System Graph
+	"""
+	# system edge array.
+	system_graph_id = ''
+	# system type Name
+	system_name = ""
+
+	def __init__(self):
+		self.system_edges = []
+
+	def add_edge(self, c1, c2, elements):
+		edge = SystemEdge(elements)
+		edge.start_vertex = SystemVertex(elements[0])
+		edge.end_vertex = SystemVertex(elements[-1])
+		self.system_edges.append(edge)
+		return edge
+
+
+class FloorGraph:
+	"""FLoor Graph.
+	May contain one or more SystemGraph.
+	"""
+
+	def __init__(self, floor_id, system_name, domain):
+		self.floor_id = floor_id
+		self.system_name = system_name
+		self.domain = domain
+		floor_connectors = systemdatautils.get_connectors_data(floor_id, system_name, domain)
+		floor_connectors = systemutils.sort_connectors(floor_connectors)
+		floor_connectors = list(map(systemutils.add_attr_is_used, floor_connectors))
+		self.connector_data = (floor_connectors)
+		self.element_data = systemutils.list_to_dict(systemdatautils.get_element_data(floor_id))
+		self.system_graphs = []
+
+	def get_floor_graphs(self):
+		"""Get current floor graph.
+		system_name,domain
+		"""
+		for connector in self.connector_data:
+			system_graph = graph_model.SystemGraph()
+			graph_next_connectors = [connector]
+			# dept-first
+			for connector in graph_next_connectors:
+				self.get_path(connector, system_graph, graph_next_connectors)
+			if len(system_graph.system_edges) != 0:
+				self.system_graphs.append(system_graph)
+				print("Next loop:",connector.source_id)
+		return self.system_graphs
+
+	def get_path(self, connector, system_graph, graph_next_connectors):
+		"""
+		Get Graph_Edge start with connector,end with triple ,cross,equipment.
+		:param connector:
+		:return:Graph_Edge
+		"""
+		system_edge = None
+		if (connector.is_used):
+			return system_edge
+		try:
+			#Add other side to be Spreaded
+			graph_next_connectors.extend(self.get_other_connectors(connector))
+			edge_elements = [self.get_element(connector.belong)]
+			current_connector = connector
+			while (current_connector is not None):
+				current_connector.is_used = True
+				connecteds = self.get_connecteds(current_connector.connect_id_json)
+				if len(connecteds) > 1:
+					raise Exception("connected to many.connector_id:", current_connector.connect_id_json)
+				#Open Connector
+				if len(connecteds) == 0:
+					if current_connector != connector:
+						system_edge = system_graph.add_edge(connector, current_connector, edge_elements)
+					break
+				next_connector = connecteds[0]
+				if next_connector is not None and next_connector.domain == connector.domain and next_connector.mep_system_type == connector.mep_system_type:
+					next_element = self.get_element(next_connector.belong)
+					edge_elements.append(next_element)
+					other_connectors = self.get_other_connectors(next_connector)
+					if systemutils.is_break_condition(next_element) or len(other_connectors) != 1:
+						print(next_connector.source_id)
+						next_connector.is_used = True
+						if(len(other_connectors) != 1):
+							graph_next_connectors.extend(other_connectors)
+						system_edge = system_graph.add_edge(connector, next_connector, edge_elements)
+						break
+					if len(other_connectors)==1:
+						next_connector.is_used = True
+						current_connector = other_connectors[0]
+						continue
+				current_connector = None
+		except Exception as e:
+			print(e)
+
+		return system_edge
+
+	def get_other_connectors(self, use_connector):
+		"""
+		Get the  connector owner other connectors.
+		belong,domian,mep_system_type same.
+		is_used==False.
+		:param use_connector:
+		:return:
+		"""
+		connectors = [connector for connector in self.connector_data if
+					  connector != use_connector and connector.belong == use_connector.belong and connector.domain == use_connector.domain and connector.mep_system_type == use_connector.mep_system_type]
+		connectors = [connector for connector in connectors if bool(1 - connector.is_used)]
+		return connectors
+
+	def get_connecteds(self, connetor_id):
+		"""
+		Get Ref Connector. may have two.like system logic connector
+		:param connetor_id:
+		:return:
+		"""
+		connectors = list(self.get_connector(id) for id in connetor_id)
+		return connectors
+
+	def get_connector(self, connector_id):
+		"""
+		Get Connector by Id.
+		:param connector_id:
+		:return:
+		"""
+		cons = list(c for c in self.connector_data if c.id == connector_id)
+		return cons[0]
+
+	def get_element(self, element_id):
+		"""
+		Get Element by Id.
+		:param eleemnt_id:
+		:return:
+		"""
+		return self.element_data[element_id]
+
+
+class SystemFlowDirection(Enum):
+	"""Edge Flow Direction.
+	"""
+	flow_in = 1
+	flow_out = -1
+	flow_undefine = 0
+
+
+class SystemVertexType(Enum):
+	"""Vertex Type.
+	"""
+	real_point = 0
+	imaginary_point = 1
+	hollow_dot = 2

+ 11 - 0
systemrelation/revit_const.py

@@ -0,0 +1,11 @@
+"""const.
+
+"""
+EQUIPMENT='Equipment'
+COMPONENT='EquipPart'
+FACILITY=[EQUIPMENT,COMPONENT]
+OTHER='Other'
+CONNECTOR='Connector'
+DUCT='Duct'
+PIPE='Pipe'
+MEPCURVE=[DUCT,PIPE]

+ 10 - 0
systemrelation/system_test.py

@@ -0,0 +1,10 @@
+from systemrelation import graph_model
+from systemrelation import systemgraph_display
+
+if '__main__'==__name__:
+	model_id="0ebf6b7ae97211e9a27c57c0742fab4c"
+	system_name="冷冻水供水管"
+	domain="DomainPiping"
+	g=graph_model.FloorGraph(model_id,system_name,domain)
+	g.get_floor_graphs()
+	systemgraph_display.show_floor(g)

+ 152 - 0
systemrelation/systemdatautils.py

@@ -0,0 +1,152 @@
+"""PipeNetwork Data .
+
+"""
+import test
+from systemrelation import systemutils
+def get_dicdata(sql,dic):
+	data=test.get_data(sql)
+	dic_data=[dict(zip(dic,item)) for item in data]
+	return list(dic_data)
+def get_element_data(model_id):
+	"""
+	Cache all Element from Db
+	:return:
+	"""
+	element_data=[]
+	component_sql="select * from revit.component where model_id='%s'"%(model_id)
+	COMPONENT_KEYS = [
+		'id',
+		'model_id',
+		'local_id',
+		'local_name',
+		'family',
+		'location',
+		'outline',
+		'source_id',
+		'name',
+		'revit_id',
+		'parameters',
+		'type',
+		'tag',
+		'owner',
+		'last_update',
+		'create_time',
+		'owner_id',
+		'family_name',
+		'owner_source_id'
+	]
+	element_data.extend(get_dicdata(component_sql,COMPONENT_KEYS))
+
+	equipment_sql="select * from revit.equipment where model_id='%s'"%(model_id)
+	EQUIPMENT_KEYS = [
+		'id',
+		'model_id',
+		'local_id',
+		'local_name',
+		'family',
+		'location',
+		'outline',
+		'last_update',
+		'create_time',
+		'source_id',
+		'name',
+		'parameters',
+		'revit_id',
+		'type',
+		'tag',
+		'family_name',
+	]
+	element_data.extend(get_dicdata(equipment_sql,EQUIPMENT_KEYS))
+
+	other_sql="select * from revit.other where model_id='%s'"%(model_id)
+	OTHER_KEYS = [
+		'id',
+		'model_id',
+		'connected_ids',
+		'source_id',
+		'name',
+		'revit_id',
+		'type',
+		'create_time',
+		'last_update',
+		'location',
+		'outline'
+	]
+	element_data.extend(get_dicdata(other_sql,OTHER_KEYS))
+
+	pipe_sql = "select * from revit.pipe where model_id='%s'" % (model_id)
+	PIPE_KEYS = [
+		'id',
+		'model_id',
+		'location',
+		'outline',
+		'connected_ids',
+		'mep_system_type',
+		'diameter',
+		'source_id',
+		'name',
+		'revit_id',
+		'type',
+		'last_update',
+		'create_time',
+		'parameters'
+	]
+	element_data.extend(get_dicdata(pipe_sql, PIPE_KEYS))
+
+	duct_sql="select * from revit.duct where model_id='%s'"%(model_id)
+	DUCT_KEYS = [
+		'id',
+		'model_id',
+		'location',
+		'outline',
+		'connected_ids',
+		'mep_system_type',
+		'shape',
+		'diameter',
+		'width',
+		'height',
+		'source_id',
+		'revit_id',
+		'name',
+		'type',
+		'last_update',
+		'create_time',
+		'parameters'
+	]
+	element_data.extend(get_dicdata(duct_sql,DUCT_KEYS))
+	element_data=list(map(systemutils.dic2obj, element_data))
+	return element_data
+
+def get_connectors_data(model_id, system_name, domain):
+	"""Cache all connector from Db。"""
+	connector_data=[]
+	connector_sql = "SELECT * FROM revit.connector where model_id='%s' and mep_system_type='%s' and domain='%s'" % (model_id,system_name,domain)
+	print(connector_sql)
+	CONNECTOR_KEYS = [
+		'id',
+		'model_id',
+		'belong',
+		'belong_type',
+		'origin',
+		'domain',
+		'description',
+		'connected',
+		'owner',
+		'connected_ids',
+		'mep_system_type',
+		'source_id',
+		'revit_id',
+		'type',
+		'create_time',
+		'last_update',
+		'connect_id_json'
+	]
+	connector_data.extend(get_dicdata(connector_sql, CONNECTOR_KEYS))
+	connector_data=list(map(systemutils.dic2obj,connector_data))
+	return connector_data
+if '__main__'==__name__:
+	model_id="cf4e11a0e25811e999b6dbc4c75fa946"
+	system_name="喷淋管"
+	domain="DomainPiping"
+	g=get_connectors_data(model_id,system_name,domain)
+	print (g)

+ 13 - 0
systemrelation/systemgraph_display.py

@@ -0,0 +1,13 @@
+import networkx as nx
+import matplotlib.pyplot as plt
+
+def show_system(system_graph):
+	g=nx.Graph()
+	for e in system_graph.system_edges:
+		g.add_edge(e.start_vertex.system_data.source_id,e.end_vertex.system_data.source_id)
+	nx.draw(g,with_labels=True)
+	plt.show()
+
+def show_floor(floor_graph):
+	for s in floor_graph.system_graphs:
+		show_system(s)

+ 70 - 0
systemrelation/systemutils.py

@@ -0,0 +1,70 @@
+"""system calc utils.
+1. get connectors where model_id='@model_id' and belong_type='Equipment' and mep_system_type='@system_name'
+2. get path start with connector,end with triple ,cross,equipment,end
+"""
+
+from systemrelation import revit_const
+from functools import cmp_to_key
+
+def path2edge(elements):
+	"""
+	Convert path to GraphtEdge
+	:param elements:
+	:return:
+	"""
+	pass
+
+
+def graph_arrange(graph):
+	"""
+	Combine Vertex that connect to virtul Vertex
+	:param graph:
+	:return:
+	"""
+	pass
+
+
+def connector_sort(connector1, connector2):
+	"""Use Define Sort rule"""
+	dic = {revit_const.EQUIPMENT: 0, revit_const.COMPONENT: 1, revit_const.OTHER: 2, revit_const.PIPE: 3,
+			revit_const.DUCT: 4}
+	x = dic[connector1.belong_type]
+	y = dic[connector2.belong_type]
+	return 1 if x > y else -1
+
+
+def sort_connectors(connectors):
+	"""Sort Connector order by Equipment>EquipPart>Other>Pipe>Duct"""
+	return sorted(connectors, key=cmp_to_key(lambda x,y:connector_sort(x,y)))
+
+
+def is_break_condition(element):
+	"""Path end Condition."""
+	res = element.type in revit_const.FACILITY
+	return res
+
+
+def dic2obj(d):
+	"""Convert Dict to Object.
+	"""
+	top = type('new', (object,), d)
+	seqs = tuple, list, set, frozenset
+	for i, j in d.items():
+		if isinstance(j, dict):
+			setattr(top, i, dic2obj(j))
+		elif isinstance(j, seqs):
+			setattr(top, i,
+					type(j)(dic2obj(sj) if isinstance(sj, dict) else sj for sj in j))
+		else:
+			setattr(top, i, j)
+	return top
+
+def list_to_dict(lis):
+    ids = [idx.id for idx in lis]
+    dic = dict(zip(ids, lis))
+    return dic
+
+def add_attr_is_used(x):
+	""""""
+	x.is_used=False
+	return x

+ 3 - 2
test.py

@@ -11,13 +11,14 @@ def get_data(sql):
     record = []
     try:
         connection = psycopg2.connect(
-            database='postgres',
+            database='datacenter',
             user='postgres',
             password='123456',
-            host='192.168.20.250',
+            host='192.168.20.235',
             port='5432'
         )
         cursor = connection.cursor()
+        print(sql)
         cursor.execute(sql)
         record = cursor.fetchall()
     except (Exception, psycopg2.Error) as error: