topologicpy 0.5.8__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Aperture.py +72 -72
- topologicpy/Cell.py +2169 -2169
- topologicpy/CellComplex.py +1137 -1137
- topologicpy/Cluster.py +1288 -1280
- topologicpy/Color.py +423 -393
- topologicpy/Context.py +79 -79
- topologicpy/DGL.py +3213 -3136
- topologicpy/Dictionary.py +698 -695
- topologicpy/Edge.py +1187 -1187
- topologicpy/EnergyModel.py +1180 -1171
- topologicpy/Face.py +2141 -2141
- topologicpy/Graph.py +7768 -7700
- topologicpy/Grid.py +353 -353
- topologicpy/Helper.py +507 -507
- topologicpy/Honeybee.py +461 -461
- topologicpy/Matrix.py +271 -271
- topologicpy/Neo4j.py +521 -521
- topologicpy/Plotly.py +2 -2
- topologicpy/Polyskel.py +541 -541
- topologicpy/Shell.py +1768 -1768
- topologicpy/Speckle.py +508 -508
- topologicpy/Topology.py +7060 -6988
- topologicpy/Vector.py +905 -905
- topologicpy/Vertex.py +1585 -1585
- topologicpy/Wire.py +3050 -3050
- topologicpy/__init__.py +22 -38
- topologicpy/version.py +1 -0
- {topologicpy-0.5.8.dist-info → topologicpy-6.0.0.dist-info}/LICENSE +661 -704
- topologicpy-6.0.0.dist-info/METADATA +751 -0
- topologicpy-6.0.0.dist-info/RECORD +32 -0
- topologicpy/bin/linux/topologic/__init__.py +0 -2
- topologicpy/bin/linux/topologic/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/macos/topologic/__init__.py +0 -2
- topologicpy/bin/windows/topologic/TKBO-f6b191de.dll +0 -0
- topologicpy/bin/windows/topologic/TKBRep-e56a600e.dll +0 -0
- topologicpy/bin/windows/topologic/TKBool-7b8d47ae.dll +0 -0
- topologicpy/bin/windows/topologic/TKFillet-0ddbf0a8.dll +0 -0
- topologicpy/bin/windows/topologic/TKG2d-2e2dee3d.dll +0 -0
- topologicpy/bin/windows/topologic/TKG3d-6674513d.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomAlgo-d240e370.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomBase-df87aba5.dll +0 -0
- topologicpy/bin/windows/topologic/TKMath-45bd625a.dll +0 -0
- topologicpy/bin/windows/topologic/TKMesh-d6e826b1.dll +0 -0
- topologicpy/bin/windows/topologic/TKOffset-79b9cc94.dll +0 -0
- topologicpy/bin/windows/topologic/TKPrim-aa430a86.dll +0 -0
- topologicpy/bin/windows/topologic/TKShHealing-bb48be89.dll +0 -0
- topologicpy/bin/windows/topologic/TKTopAlgo-7d0d1e22.dll +0 -0
- topologicpy/bin/windows/topologic/TKernel-08c8cfbb.dll +0 -0
- topologicpy/bin/windows/topologic/__init__.py +0 -2
- topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
- topologicpy-0.5.8.dist-info/METADATA +0 -96
- topologicpy-0.5.8.dist-info/RECORD +0 -91
- {topologicpy-0.5.8.dist-info → topologicpy-6.0.0.dist-info}/WHEEL +0 -0
- {topologicpy-0.5.8.dist-info → topologicpy-6.0.0.dist-info}/top_level.txt +0 -0
topologicpy/Neo4j.py
CHANGED
@@ -1,522 +1,522 @@
|
|
1
|
-
# Copyright (C) 2024
|
2
|
-
# Wassim Jabi <wassim.jabi@gmail.com>
|
3
|
-
#
|
4
|
-
# This program is free software: you can redistribute it and/or modify it under
|
5
|
-
# the terms of the GNU Affero General Public License as published by the Free Software
|
6
|
-
# Foundation, either version 3 of the License, or (at your option) any later
|
7
|
-
# version.
|
8
|
-
#
|
9
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
-
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
12
|
-
# details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU Affero General Public License along with
|
15
|
-
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
-
|
17
|
-
import time
|
18
|
-
import random
|
19
|
-
import os
|
20
|
-
import warnings
|
21
|
-
|
22
|
-
try:
|
23
|
-
import py2neo
|
24
|
-
from py2neo import NodeMatcher,RelationshipMatcher
|
25
|
-
from py2neo.data import spatial as sp
|
26
|
-
except:
|
27
|
-
print("Neo4j - Installing required py2neo library.")
|
28
|
-
try:
|
29
|
-
os.system("pip install py2neo")
|
30
|
-
except:
|
31
|
-
os.system("pip install py2neo --user")
|
32
|
-
try:
|
33
|
-
import py2neo
|
34
|
-
from py2neo import NodeMatcher,RelationshipMatcher
|
35
|
-
from py2neo.data import spatial as sp
|
36
|
-
except:
|
37
|
-
warnings.warn("Neo4j - Error: Could not import py2neo")
|
38
|
-
|
39
|
-
class Neo4j:
|
40
|
-
|
41
|
-
@staticmethod
|
42
|
-
def NodeToVertex(node):
|
43
|
-
"""
|
44
|
-
Converts the input neo4j node to a topologic vertex.
|
45
|
-
|
46
|
-
Parameters
|
47
|
-
----------
|
48
|
-
node : Neo4j.Node
|
49
|
-
The input neo4j node.
|
50
|
-
|
51
|
-
Returns
|
52
|
-
-------
|
53
|
-
topologic.Vertex
|
54
|
-
The output topologic vertex.
|
55
|
-
|
56
|
-
"""
|
57
|
-
from topologicpy.Vertex import Vertex
|
58
|
-
from topologicpy.Topology import Topology
|
59
|
-
from topologicpy.Dictionary import Dictionary
|
60
|
-
|
61
|
-
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
62
|
-
x = node['x']
|
63
|
-
y = node['y']
|
64
|
-
z = node['z']
|
65
|
-
vertex = Vertex.ByCoordinates(x, y, z)
|
66
|
-
else:
|
67
|
-
x = random.uniform(0, 1000)
|
68
|
-
y = random.uniform(0, 1000)
|
69
|
-
z = random.uniform(0, 1000)
|
70
|
-
vertex = Vertex.ByCoordinates(x, y, z)
|
71
|
-
keys = list(node.keys())
|
72
|
-
values = list(node.values())
|
73
|
-
d = Dictionary.ByKeysValues(keys, values)
|
74
|
-
vertex = Topology.SetDictionary(vertex, d)
|
75
|
-
return vertex
|
76
|
-
|
77
|
-
|
78
|
-
@staticmethod
|
79
|
-
def NodesByCypher(neo4jGraph, cypher):
|
80
|
-
dataList = neo4jGraph.run(cypher).data()
|
81
|
-
nodes = []
|
82
|
-
for data in dataList:
|
83
|
-
path = data['p']
|
84
|
-
nodes += list(path.nodes)
|
85
|
-
return nodes
|
86
|
-
|
87
|
-
@staticmethod
|
88
|
-
def NodesBySubGraph(subGraph):
|
89
|
-
data = subGraph.data()
|
90
|
-
nodes = []
|
91
|
-
for data in subGraph:
|
92
|
-
path = data['p']
|
93
|
-
nodes += list(path.nodes)
|
94
|
-
return nodes
|
95
|
-
|
96
|
-
@staticmethod
|
97
|
-
def SubGraphByCypher(neo4jGraph, cypher):
|
98
|
-
return neo4jGraph.run(cypher).to_subgraph()
|
99
|
-
|
100
|
-
@staticmethod
|
101
|
-
def SubGraphExportToGraph(subGraph, tolerance=0.0001):
|
102
|
-
"""
|
103
|
-
Exports the input neo4j graph to a topologic graph.
|
104
|
-
|
105
|
-
Parameters
|
106
|
-
----------
|
107
|
-
subGraph : Neo4j.SubGraph
|
108
|
-
The input neo4j subgraph.
|
109
|
-
tolerance : float , optional
|
110
|
-
The desired tolerance. The default is 0.0001.
|
111
|
-
|
112
|
-
Returns
|
113
|
-
-------
|
114
|
-
topologic.Graph
|
115
|
-
The output topologic graph.
|
116
|
-
|
117
|
-
"""
|
118
|
-
from topologicpy.Vertex import Vertex
|
119
|
-
from topologicpy.Edge import Edge
|
120
|
-
from topologicpy.Topology import Topology
|
121
|
-
from topologicpy.Dictionary import Dictionary
|
122
|
-
from topologicpy.Graph import Graph
|
123
|
-
|
124
|
-
def randomVertex(vertices, minDistance):
|
125
|
-
flag = True
|
126
|
-
while flag:
|
127
|
-
x = random.uniform(0, 1000)
|
128
|
-
y = random.uniform(0, 1000)
|
129
|
-
z = random.uniform(0, 1000)
|
130
|
-
v = Vertex.ByCoordinates(x, y, z)
|
131
|
-
test = False
|
132
|
-
if len(vertices) < 1:
|
133
|
-
return v
|
134
|
-
for vertex in vertices:
|
135
|
-
d = Vertex.Distance(v, vertex)
|
136
|
-
if d < minDistance:
|
137
|
-
test = True
|
138
|
-
break
|
139
|
-
if test == False:
|
140
|
-
return v
|
141
|
-
else:
|
142
|
-
continue
|
143
|
-
|
144
|
-
nodes = subGraph.nodes
|
145
|
-
relationships = list(subGraph.relationships)
|
146
|
-
vertices = []
|
147
|
-
edges = []
|
148
|
-
for node in nodes:
|
149
|
-
#Check if they have X, Y, Z coordinates
|
150
|
-
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
151
|
-
x = node['x']
|
152
|
-
y = node['y']
|
153
|
-
z = node['z']
|
154
|
-
vertex = Vertex.ByCoordinates(x, y, z)
|
155
|
-
else:
|
156
|
-
vertex = randomVertex(vertices, 1)
|
157
|
-
keys = list(node.keys())
|
158
|
-
keys.append("identity")
|
159
|
-
values = [node.identity]
|
160
|
-
for key in keys:
|
161
|
-
values.append(node[key])
|
162
|
-
d = Dictionary.ByKeysValues(keys, values)
|
163
|
-
vertex = Topology.SetDictionary(vertex, d)
|
164
|
-
vertices.append(vertex)
|
165
|
-
for relationship in relationships:
|
166
|
-
keys = list(relationship.keys())
|
167
|
-
keys.append("identity")
|
168
|
-
values = [relationship.identity]
|
169
|
-
for key in keys:
|
170
|
-
values.append(node[key])
|
171
|
-
sv = vertices[nodes.index(relationship.start_node)]
|
172
|
-
ev = vertices[nodes.index(relationship.end_node)]
|
173
|
-
edge = Edge.ByVertices([sv, ev], tolerance=tolerance)
|
174
|
-
if relationship.start_node['name']:
|
175
|
-
sv_name = relationship.start_node['name']
|
176
|
-
else:
|
177
|
-
sv_name = 'None'
|
178
|
-
if relationship.end_node['name']:
|
179
|
-
ev_name = relationship.end_node['name']
|
180
|
-
else:
|
181
|
-
ev_name = 'None'
|
182
|
-
d = Dictionary.ByKeysValues(["relationship_type", "from", "to"], [relationship.__class__.__name__, sv_name, ev_name])
|
183
|
-
if d:
|
184
|
-
_ = Topology.SetDictionary(edge, d)
|
185
|
-
edges.append(edge)
|
186
|
-
return Graph.ByVerticesEdges(vertices,edges)
|
187
|
-
|
188
|
-
@staticmethod
|
189
|
-
def ExportToGraph(neo4jGraph, tolerance=0.0001):
|
190
|
-
"""
|
191
|
-
Exports the input neo4j graph to a topologic graph.
|
192
|
-
|
193
|
-
Parameters
|
194
|
-
----------
|
195
|
-
neo4jGraph : Neo4j.Graph
|
196
|
-
The input neo4j graph.
|
197
|
-
tolerance : float , optional
|
198
|
-
The desired tolerance. The default is 0.0001.
|
199
|
-
|
200
|
-
Returns
|
201
|
-
-------
|
202
|
-
topologic.Graph
|
203
|
-
The output topologic graph.
|
204
|
-
|
205
|
-
"""
|
206
|
-
from topologicpy.Vertex import Vertex
|
207
|
-
from topologicpy.Edge import Edge
|
208
|
-
from topologicpy.Topology import Topology
|
209
|
-
from topologicpy.Dictionary import Dictionary
|
210
|
-
from topologicpy.Graph import Graph
|
211
|
-
|
212
|
-
def randomVertex(vertices, minDistance):
|
213
|
-
flag = True
|
214
|
-
while flag:
|
215
|
-
x = random.uniform(0, 1000)
|
216
|
-
y = random.uniform(0, 1000)
|
217
|
-
z = random.uniform(0, 1000)
|
218
|
-
v = Vertex.ByCoordinates(x, y, z)
|
219
|
-
test = False
|
220
|
-
if len(vertices) < 1:
|
221
|
-
return v
|
222
|
-
for vertex in vertices:
|
223
|
-
d = Vertex.Distance(v, vertex)
|
224
|
-
if d < minDistance:
|
225
|
-
test = True
|
226
|
-
break
|
227
|
-
if test == False:
|
228
|
-
return v
|
229
|
-
else:
|
230
|
-
continue
|
231
|
-
|
232
|
-
node_labels = neo4jGraph.schema.node_labels
|
233
|
-
relationship_types = neo4jGraph.schema.relationship_types
|
234
|
-
node_matcher = NodeMatcher(neo4jGraph)
|
235
|
-
relationship_matcher = RelationshipMatcher(neo4jGraph)
|
236
|
-
vertices = []
|
237
|
-
edges = []
|
238
|
-
nodes = []
|
239
|
-
for node_label in node_labels:
|
240
|
-
nodes = nodes + (list(node_matcher.match(node_label)))
|
241
|
-
for node in nodes:
|
242
|
-
#Check if they have X, Y, Z coordinates
|
243
|
-
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
244
|
-
x = node['x']
|
245
|
-
y = node['y']
|
246
|
-
z = node['z']
|
247
|
-
vertex = Vertex.ByCoordinates(x, y, z)
|
248
|
-
else:
|
249
|
-
vertex = randomVertex(vertices, 1)
|
250
|
-
keys = list(node.keys())
|
251
|
-
values = []
|
252
|
-
for key in keys:
|
253
|
-
values.append(node[key])
|
254
|
-
d = Dictionary.ByKeysValues(keys, values)
|
255
|
-
vertex = Topology.SetDictionary(vertex, d)
|
256
|
-
vertices.append(vertex)
|
257
|
-
for node in nodes:
|
258
|
-
for relationship_type in relationship_types:
|
259
|
-
relationships = list(relationship_matcher.match([node], r_type=relationship_type))
|
260
|
-
for relationship in relationships:
|
261
|
-
sv = vertices[nodes.index(relationship.start_node)]
|
262
|
-
ev = vertices[nodes.index(relationship.end_node)]
|
263
|
-
edge = Edge.ByVertices([sv, ev], tolerance=tolerance)
|
264
|
-
if relationship.start_node['name']:
|
265
|
-
sv_name = relationship.start_node['name']
|
266
|
-
else:
|
267
|
-
sv_name = 'None'
|
268
|
-
if relationship.end_node['name']:
|
269
|
-
ev_name = relationship.end_node['name']
|
270
|
-
else:
|
271
|
-
ev_name = 'None'
|
272
|
-
d = Dictionary.ByKeysValues(["relationship_type", "from", "to"], [relationship_type, sv_name, ev_name])
|
273
|
-
if d:
|
274
|
-
_ = Topology.SetDictionary(edge, d)
|
275
|
-
edges.append(edge)
|
276
|
-
return Graph.ByVerticesEdges(vertices,edges)
|
277
|
-
|
278
|
-
@staticmethod
|
279
|
-
def AddGraph(neo4jGraph, graph, labelKey=None, relationshipKey=None, bidirectional=True, deleteAll=True, tolerance=0.0001):
|
280
|
-
"""
|
281
|
-
Adds the input topologic graph to the input neo4j graph
|
282
|
-
|
283
|
-
Parameters
|
284
|
-
----------
|
285
|
-
neo4jGraph : Neo4j.Graph
|
286
|
-
The input neo4j graph.
|
287
|
-
graph : topologic.Graph
|
288
|
-
The input topologic graph.
|
289
|
-
categoryKey : str
|
290
|
-
The category key in the dictionary under which to look for the category value.
|
291
|
-
tolerance : float , optional
|
292
|
-
The desired tolerance. The default is 0.0001.
|
293
|
-
|
294
|
-
Returns
|
295
|
-
-------
|
296
|
-
Neo4j.Graph
|
297
|
-
The input neo4j graph with the input topologic graph added to it.
|
298
|
-
|
299
|
-
"""
|
300
|
-
from topologicpy.Vertex import Vertex
|
301
|
-
from topologicpy.Topology import Topology
|
302
|
-
from topologicpy.Graph import Graph
|
303
|
-
from topologicpy.Dictionary import Dictionary
|
304
|
-
gmt = time.gmtime()
|
305
|
-
timestamp = str(gmt.tm_zone)+"_"+str(gmt.tm_year)+"_"+str(gmt.tm_mon)+"_"+str(gmt.tm_wday)+"_"+str(gmt.tm_hour)+"_"+str(gmt.tm_min)+"_"+str(gmt.tm_sec)
|
306
|
-
vertices = Graph.Vertices(graph)
|
307
|
-
edges = Graph.Edges(graph)
|
308
|
-
tx = neo4jGraph.begin()
|
309
|
-
nodes = []
|
310
|
-
for i in range(len(vertices)):
|
311
|
-
vDict = Topology.Dictionary(vertices[i])
|
312
|
-
keys = Dictionary.Keyus(vDict)
|
313
|
-
values = Dictionary.Values(vDict)
|
314
|
-
keys.append("x")
|
315
|
-
keys.append("y")
|
316
|
-
keys.append("z")
|
317
|
-
keys.append("timestamp")
|
318
|
-
keys.append("location")
|
319
|
-
values.append(vertices[i].X())
|
320
|
-
values.append(vertices[i].Y())
|
321
|
-
values.append(vertices[i].Z())
|
322
|
-
values.append(timestamp)
|
323
|
-
values.append(sp.CartesianPoint([vertices[i].X(),vertices[i].Y(),vertices[i].Z()]))
|
324
|
-
zip_iterator = zip(keys, values)
|
325
|
-
pydict = dict(zip_iterator)
|
326
|
-
if labelKey == 'None':
|
327
|
-
nodeName = "TopologicGraphVertex"
|
328
|
-
else:
|
329
|
-
nodeName = str(values[keys.index(labelKey)])
|
330
|
-
n = py2neo.Node(nodeName, **pydict)
|
331
|
-
neo4jGraph.cypher.execute("CREATE INDEX FOR (n:%s) on (n.name)" %
|
332
|
-
n.nodelabel)
|
333
|
-
tx.create(n)
|
334
|
-
nodes.append(n)
|
335
|
-
for i in range(len(edges)):
|
336
|
-
e = edges[i]
|
337
|
-
sv = e.StartVertex()
|
338
|
-
ev = e.EndVertex()
|
339
|
-
sn = nodes[Vertex.Index(sv, vertices, tolerance)]
|
340
|
-
en = nodes[Vertex.Index(ev, vertices, tolerance)]
|
341
|
-
relationshipType = Dictionary.ValueAtKey(e, relationshipKey)
|
342
|
-
if not (relationshipType):
|
343
|
-
relationshipType = "Connected To"
|
344
|
-
snen = py2neo.Relationship(sn, relationshipType, en)
|
345
|
-
tx.create(snen)
|
346
|
-
snen = py2neo.Relationship(en, relationshipType, sn)
|
347
|
-
tx.create(snen)
|
348
|
-
neo4jGraph.commit(tx)
|
349
|
-
return neo4jGraph
|
350
|
-
|
351
|
-
|
352
|
-
@staticmethod
|
353
|
-
def ByParameters(url, username, password):
|
354
|
-
"""
|
355
|
-
Returns a Neo4j graph by the input parameters.
|
356
|
-
|
357
|
-
Parameters
|
358
|
-
----------
|
359
|
-
url : str
|
360
|
-
The URL of the server.
|
361
|
-
username : str
|
362
|
-
The username to use for logging in.
|
363
|
-
password : str
|
364
|
-
The password to use for logging in.
|
365
|
-
|
366
|
-
Returns
|
367
|
-
-------
|
368
|
-
Neo4j.Graph
|
369
|
-
The returned Neo4j graph.
|
370
|
-
|
371
|
-
"""
|
372
|
-
return py2neo.Graph(url, auth=(username, password))
|
373
|
-
|
374
|
-
@staticmethod
|
375
|
-
def DeleteAll(neo4jGraph):
|
376
|
-
"""
|
377
|
-
Deletes all entities in the input Neo4j graph.
|
378
|
-
|
379
|
-
Parameters
|
380
|
-
----------
|
381
|
-
neo4jGraph : Neo4j Graph
|
382
|
-
The input Neo4jGraph.
|
383
|
-
|
384
|
-
Returns
|
385
|
-
-------
|
386
|
-
Neo4J Graph
|
387
|
-
The returned empty graph.
|
388
|
-
|
389
|
-
"""
|
390
|
-
neo4jGraph.delete_all()
|
391
|
-
return neo4jGraph
|
392
|
-
|
393
|
-
@staticmethod
|
394
|
-
def NodeLabels(neo4jGraph):
|
395
|
-
"""
|
396
|
-
Returns all the node labels used in the input neo4j graph.
|
397
|
-
|
398
|
-
Parameters
|
399
|
-
----------
|
400
|
-
neo4jGraph : Newo4j.Graph
|
401
|
-
The input neo4j graph.
|
402
|
-
|
403
|
-
Returns
|
404
|
-
-------
|
405
|
-
list
|
406
|
-
The list of node labels used in the input neo4j graph.
|
407
|
-
|
408
|
-
"""
|
409
|
-
return list(neo4jGraph.schema.node_labels)
|
410
|
-
|
411
|
-
@staticmethod
|
412
|
-
def RelationshipTypes(neo4jGraph):
|
413
|
-
"""
|
414
|
-
Returns all the relationship types used in the input neo4j graph.
|
415
|
-
|
416
|
-
Parameters
|
417
|
-
----------
|
418
|
-
neo4jGraph : Newo4j.Graph
|
419
|
-
The input neo4j graph.
|
420
|
-
|
421
|
-
Returns
|
422
|
-
-------
|
423
|
-
list
|
424
|
-
The list of relationship types used in the input neo4j graph.
|
425
|
-
|
426
|
-
"""
|
427
|
-
return list(neo4jGraph.schema.relationship_types)
|
428
|
-
|
429
|
-
@staticmethod
|
430
|
-
def SetGraph(neo4jGraph, graph, labelKey=None, relationshipKey=None, bidirectional=True, deleteAll=True, tolerance=0.0001):
|
431
|
-
"""
|
432
|
-
Sets the input topologic graph to the input neo4jGraph.
|
433
|
-
|
434
|
-
Parameters
|
435
|
-
----------
|
436
|
-
neo4jGraph : Neo4j.Graph
|
437
|
-
The input neo4j graph.
|
438
|
-
graph : topologic.Graph
|
439
|
-
The input topologic graph.
|
440
|
-
labelKey : str , optional
|
441
|
-
The dictionary key under which to find the vertex's label value. The default is None which means the vertex gets the name 'TopologicGraphVertex'.
|
442
|
-
relationshipKey : str , optional
|
443
|
-
The dictionary key under which to find the edge's relationship value. The default is None which means the edge gets the relationship type 'Connected To'.
|
444
|
-
bidirectional : bool , optional
|
445
|
-
If set to True, the edges in the neo4j graph are set to be bi-drectional.
|
446
|
-
deleteAll : bool , optional
|
447
|
-
If set to True, all previous entities are deleted before adding the new entities.
|
448
|
-
tolerance : float , optional
|
449
|
-
The desired tolerance. The default is 0.0001.
|
450
|
-
|
451
|
-
Returns
|
452
|
-
-------
|
453
|
-
neo4jGraph : TYPE
|
454
|
-
The input neo4j graph with the input topologic graph added to it.
|
455
|
-
|
456
|
-
"""
|
457
|
-
from topologicpy.Vertex import Vertex
|
458
|
-
from topologicpy.Graph import Graph
|
459
|
-
from topologicpy.Topology import Topology
|
460
|
-
from topologicpy.Dictionary import Dictionary
|
461
|
-
|
462
|
-
import time
|
463
|
-
gmt = time.gmtime()
|
464
|
-
timestamp = str(gmt.tm_zone)+"_"+str(gmt.tm_year)+"_"+str(gmt.tm_mon)+"_"+str(gmt.tm_wday)+"_"+str(gmt.tm_hour)+"_"+str(gmt.tm_min)+"_"+str(gmt.tm_sec)
|
465
|
-
|
466
|
-
vertices = Graph.Vertices(graph)
|
467
|
-
edges = Graph.Edges(graph)
|
468
|
-
tx = neo4jGraph.begin()
|
469
|
-
nodes = []
|
470
|
-
for i in range(len(vertices)):
|
471
|
-
vDict = Topology.Dictionary(vertices[i])
|
472
|
-
if not vDict:
|
473
|
-
keys = []
|
474
|
-
values = []
|
475
|
-
else:
|
476
|
-
keys = Dictionary.Keys(vDict)
|
477
|
-
if not keys:
|
478
|
-
keys = []
|
479
|
-
values = Dictionary.Values(vDict)
|
480
|
-
if not values:
|
481
|
-
values = []
|
482
|
-
keys.append("x")
|
483
|
-
keys.append("y")
|
484
|
-
keys.append("z")
|
485
|
-
keys.append("timestamp")
|
486
|
-
keys.append("location")
|
487
|
-
values.append(vertices[i].X())
|
488
|
-
values.append(vertices[i].Y())
|
489
|
-
values.append(vertices[i].Z())
|
490
|
-
values.append(timestamp)
|
491
|
-
values.append(sp.CartesianPoint([vertices[i].X(),vertices[i].Y(),vertices[i].Z()]))
|
492
|
-
zip_iterator = zip(keys, values)
|
493
|
-
pydict = dict(zip_iterator)
|
494
|
-
if (labelKey == 'None') or (not (labelKey)):
|
495
|
-
nodeName = "TopologicGraphVertex"
|
496
|
-
else:
|
497
|
-
nodeName = str(Dictionary.ValueAtKey(vDict, labelKey))
|
498
|
-
n = py2neo.Node(nodeName, **pydict)
|
499
|
-
tx.create(n)
|
500
|
-
nodes.append(n)
|
501
|
-
for i in range(len(edges)):
|
502
|
-
e = edges[i]
|
503
|
-
sv = e.StartVertex()
|
504
|
-
ev = e.EndVertex()
|
505
|
-
sn = nodes[Vertex.Index(vertex=sv, vertices=vertices, strict=False, tolerance=tolerance)]
|
506
|
-
en = nodes[Vertex.Index(vertex=ev, vertices=vertices, strict=False, tolerance=tolerance)]
|
507
|
-
ed = Topology.Dictionary(e)
|
508
|
-
if relationshipKey:
|
509
|
-
relationshipType = Dictionary.ValueAtKey(ed, relationshipKey)
|
510
|
-
else:
|
511
|
-
relationshipType = "Connected To"
|
512
|
-
if not (relationshipType):
|
513
|
-
relationshipType = "Connected To"
|
514
|
-
snen = py2neo.Relationship(sn, relationshipType, en)
|
515
|
-
tx.create(snen)
|
516
|
-
if bidirectional:
|
517
|
-
snen = py2neo.Relationship(en, relationshipType, sn)
|
518
|
-
tx.create(snen)
|
519
|
-
if deleteAll:
|
520
|
-
neo4jGraph.delete_all()
|
521
|
-
neo4jGraph.commit(tx)
|
1
|
+
# Copyright (C) 2024
|
2
|
+
# Wassim Jabi <wassim.jabi@gmail.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify it under
|
5
|
+
# the terms of the GNU Affero General Public License as published by the Free Software
|
6
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
7
|
+
# version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
12
|
+
# details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License along with
|
15
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
import time
|
18
|
+
import random
|
19
|
+
import os
|
20
|
+
import warnings
|
21
|
+
|
22
|
+
try:
|
23
|
+
import py2neo
|
24
|
+
from py2neo import NodeMatcher,RelationshipMatcher
|
25
|
+
from py2neo.data import spatial as sp
|
26
|
+
except:
|
27
|
+
print("Neo4j - Installing required py2neo library.")
|
28
|
+
try:
|
29
|
+
os.system("pip install py2neo")
|
30
|
+
except:
|
31
|
+
os.system("pip install py2neo --user")
|
32
|
+
try:
|
33
|
+
import py2neo
|
34
|
+
from py2neo import NodeMatcher,RelationshipMatcher
|
35
|
+
from py2neo.data import spatial as sp
|
36
|
+
except:
|
37
|
+
warnings.warn("Neo4j - Error: Could not import py2neo")
|
38
|
+
|
39
|
+
class Neo4j:
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def NodeToVertex(node):
|
43
|
+
"""
|
44
|
+
Converts the input neo4j node to a topologic vertex.
|
45
|
+
|
46
|
+
Parameters
|
47
|
+
----------
|
48
|
+
node : Neo4j.Node
|
49
|
+
The input neo4j node.
|
50
|
+
|
51
|
+
Returns
|
52
|
+
-------
|
53
|
+
topologic.Vertex
|
54
|
+
The output topologic vertex.
|
55
|
+
|
56
|
+
"""
|
57
|
+
from topologicpy.Vertex import Vertex
|
58
|
+
from topologicpy.Topology import Topology
|
59
|
+
from topologicpy.Dictionary import Dictionary
|
60
|
+
|
61
|
+
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
62
|
+
x = node['x']
|
63
|
+
y = node['y']
|
64
|
+
z = node['z']
|
65
|
+
vertex = Vertex.ByCoordinates(x, y, z)
|
66
|
+
else:
|
67
|
+
x = random.uniform(0, 1000)
|
68
|
+
y = random.uniform(0, 1000)
|
69
|
+
z = random.uniform(0, 1000)
|
70
|
+
vertex = Vertex.ByCoordinates(x, y, z)
|
71
|
+
keys = list(node.keys())
|
72
|
+
values = list(node.values())
|
73
|
+
d = Dictionary.ByKeysValues(keys, values)
|
74
|
+
vertex = Topology.SetDictionary(vertex, d)
|
75
|
+
return vertex
|
76
|
+
|
77
|
+
|
78
|
+
@staticmethod
|
79
|
+
def NodesByCypher(neo4jGraph, cypher):
|
80
|
+
dataList = neo4jGraph.run(cypher).data()
|
81
|
+
nodes = []
|
82
|
+
for data in dataList:
|
83
|
+
path = data['p']
|
84
|
+
nodes += list(path.nodes)
|
85
|
+
return nodes
|
86
|
+
|
87
|
+
@staticmethod
|
88
|
+
def NodesBySubGraph(subGraph):
|
89
|
+
data = subGraph.data()
|
90
|
+
nodes = []
|
91
|
+
for data in subGraph:
|
92
|
+
path = data['p']
|
93
|
+
nodes += list(path.nodes)
|
94
|
+
return nodes
|
95
|
+
|
96
|
+
@staticmethod
|
97
|
+
def SubGraphByCypher(neo4jGraph, cypher):
|
98
|
+
return neo4jGraph.run(cypher).to_subgraph()
|
99
|
+
|
100
|
+
@staticmethod
|
101
|
+
def SubGraphExportToGraph(subGraph, tolerance=0.0001):
|
102
|
+
"""
|
103
|
+
Exports the input neo4j graph to a topologic graph.
|
104
|
+
|
105
|
+
Parameters
|
106
|
+
----------
|
107
|
+
subGraph : Neo4j.SubGraph
|
108
|
+
The input neo4j subgraph.
|
109
|
+
tolerance : float , optional
|
110
|
+
The desired tolerance. The default is 0.0001.
|
111
|
+
|
112
|
+
Returns
|
113
|
+
-------
|
114
|
+
topologic.Graph
|
115
|
+
The output topologic graph.
|
116
|
+
|
117
|
+
"""
|
118
|
+
from topologicpy.Vertex import Vertex
|
119
|
+
from topologicpy.Edge import Edge
|
120
|
+
from topologicpy.Topology import Topology
|
121
|
+
from topologicpy.Dictionary import Dictionary
|
122
|
+
from topologicpy.Graph import Graph
|
123
|
+
|
124
|
+
def randomVertex(vertices, minDistance):
|
125
|
+
flag = True
|
126
|
+
while flag:
|
127
|
+
x = random.uniform(0, 1000)
|
128
|
+
y = random.uniform(0, 1000)
|
129
|
+
z = random.uniform(0, 1000)
|
130
|
+
v = Vertex.ByCoordinates(x, y, z)
|
131
|
+
test = False
|
132
|
+
if len(vertices) < 1:
|
133
|
+
return v
|
134
|
+
for vertex in vertices:
|
135
|
+
d = Vertex.Distance(v, vertex)
|
136
|
+
if d < minDistance:
|
137
|
+
test = True
|
138
|
+
break
|
139
|
+
if test == False:
|
140
|
+
return v
|
141
|
+
else:
|
142
|
+
continue
|
143
|
+
|
144
|
+
nodes = subGraph.nodes
|
145
|
+
relationships = list(subGraph.relationships)
|
146
|
+
vertices = []
|
147
|
+
edges = []
|
148
|
+
for node in nodes:
|
149
|
+
#Check if they have X, Y, Z coordinates
|
150
|
+
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
151
|
+
x = node['x']
|
152
|
+
y = node['y']
|
153
|
+
z = node['z']
|
154
|
+
vertex = Vertex.ByCoordinates(x, y, z)
|
155
|
+
else:
|
156
|
+
vertex = randomVertex(vertices, 1)
|
157
|
+
keys = list(node.keys())
|
158
|
+
keys.append("identity")
|
159
|
+
values = [node.identity]
|
160
|
+
for key in keys:
|
161
|
+
values.append(node[key])
|
162
|
+
d = Dictionary.ByKeysValues(keys, values)
|
163
|
+
vertex = Topology.SetDictionary(vertex, d)
|
164
|
+
vertices.append(vertex)
|
165
|
+
for relationship in relationships:
|
166
|
+
keys = list(relationship.keys())
|
167
|
+
keys.append("identity")
|
168
|
+
values = [relationship.identity]
|
169
|
+
for key in keys:
|
170
|
+
values.append(node[key])
|
171
|
+
sv = vertices[nodes.index(relationship.start_node)]
|
172
|
+
ev = vertices[nodes.index(relationship.end_node)]
|
173
|
+
edge = Edge.ByVertices([sv, ev], tolerance=tolerance)
|
174
|
+
if relationship.start_node['name']:
|
175
|
+
sv_name = relationship.start_node['name']
|
176
|
+
else:
|
177
|
+
sv_name = 'None'
|
178
|
+
if relationship.end_node['name']:
|
179
|
+
ev_name = relationship.end_node['name']
|
180
|
+
else:
|
181
|
+
ev_name = 'None'
|
182
|
+
d = Dictionary.ByKeysValues(["relationship_type", "from", "to"], [relationship.__class__.__name__, sv_name, ev_name])
|
183
|
+
if d:
|
184
|
+
_ = Topology.SetDictionary(edge, d)
|
185
|
+
edges.append(edge)
|
186
|
+
return Graph.ByVerticesEdges(vertices,edges)
|
187
|
+
|
188
|
+
@staticmethod
|
189
|
+
def ExportToGraph(neo4jGraph, tolerance=0.0001):
|
190
|
+
"""
|
191
|
+
Exports the input neo4j graph to a topologic graph.
|
192
|
+
|
193
|
+
Parameters
|
194
|
+
----------
|
195
|
+
neo4jGraph : Neo4j.Graph
|
196
|
+
The input neo4j graph.
|
197
|
+
tolerance : float , optional
|
198
|
+
The desired tolerance. The default is 0.0001.
|
199
|
+
|
200
|
+
Returns
|
201
|
+
-------
|
202
|
+
topologic.Graph
|
203
|
+
The output topologic graph.
|
204
|
+
|
205
|
+
"""
|
206
|
+
from topologicpy.Vertex import Vertex
|
207
|
+
from topologicpy.Edge import Edge
|
208
|
+
from topologicpy.Topology import Topology
|
209
|
+
from topologicpy.Dictionary import Dictionary
|
210
|
+
from topologicpy.Graph import Graph
|
211
|
+
|
212
|
+
def randomVertex(vertices, minDistance):
|
213
|
+
flag = True
|
214
|
+
while flag:
|
215
|
+
x = random.uniform(0, 1000)
|
216
|
+
y = random.uniform(0, 1000)
|
217
|
+
z = random.uniform(0, 1000)
|
218
|
+
v = Vertex.ByCoordinates(x, y, z)
|
219
|
+
test = False
|
220
|
+
if len(vertices) < 1:
|
221
|
+
return v
|
222
|
+
for vertex in vertices:
|
223
|
+
d = Vertex.Distance(v, vertex)
|
224
|
+
if d < minDistance:
|
225
|
+
test = True
|
226
|
+
break
|
227
|
+
if test == False:
|
228
|
+
return v
|
229
|
+
else:
|
230
|
+
continue
|
231
|
+
|
232
|
+
node_labels = neo4jGraph.schema.node_labels
|
233
|
+
relationship_types = neo4jGraph.schema.relationship_types
|
234
|
+
node_matcher = NodeMatcher(neo4jGraph)
|
235
|
+
relationship_matcher = RelationshipMatcher(neo4jGraph)
|
236
|
+
vertices = []
|
237
|
+
edges = []
|
238
|
+
nodes = []
|
239
|
+
for node_label in node_labels:
|
240
|
+
nodes = nodes + (list(node_matcher.match(node_label)))
|
241
|
+
for node in nodes:
|
242
|
+
#Check if they have X, Y, Z coordinates
|
243
|
+
if ('x' in node.keys()) and ('y' in node.keys()) and ('z' in node.keys()) or ('X' in node.keys()) and ('Y' in node.keys()) and ('Z' in node.keys()):
|
244
|
+
x = node['x']
|
245
|
+
y = node['y']
|
246
|
+
z = node['z']
|
247
|
+
vertex = Vertex.ByCoordinates(x, y, z)
|
248
|
+
else:
|
249
|
+
vertex = randomVertex(vertices, 1)
|
250
|
+
keys = list(node.keys())
|
251
|
+
values = []
|
252
|
+
for key in keys:
|
253
|
+
values.append(node[key])
|
254
|
+
d = Dictionary.ByKeysValues(keys, values)
|
255
|
+
vertex = Topology.SetDictionary(vertex, d)
|
256
|
+
vertices.append(vertex)
|
257
|
+
for node in nodes:
|
258
|
+
for relationship_type in relationship_types:
|
259
|
+
relationships = list(relationship_matcher.match([node], r_type=relationship_type))
|
260
|
+
for relationship in relationships:
|
261
|
+
sv = vertices[nodes.index(relationship.start_node)]
|
262
|
+
ev = vertices[nodes.index(relationship.end_node)]
|
263
|
+
edge = Edge.ByVertices([sv, ev], tolerance=tolerance)
|
264
|
+
if relationship.start_node['name']:
|
265
|
+
sv_name = relationship.start_node['name']
|
266
|
+
else:
|
267
|
+
sv_name = 'None'
|
268
|
+
if relationship.end_node['name']:
|
269
|
+
ev_name = relationship.end_node['name']
|
270
|
+
else:
|
271
|
+
ev_name = 'None'
|
272
|
+
d = Dictionary.ByKeysValues(["relationship_type", "from", "to"], [relationship_type, sv_name, ev_name])
|
273
|
+
if d:
|
274
|
+
_ = Topology.SetDictionary(edge, d)
|
275
|
+
edges.append(edge)
|
276
|
+
return Graph.ByVerticesEdges(vertices,edges)
|
277
|
+
|
278
|
+
@staticmethod
|
279
|
+
def AddGraph(neo4jGraph, graph, labelKey=None, relationshipKey=None, bidirectional=True, deleteAll=True, tolerance=0.0001):
|
280
|
+
"""
|
281
|
+
Adds the input topologic graph to the input neo4j graph
|
282
|
+
|
283
|
+
Parameters
|
284
|
+
----------
|
285
|
+
neo4jGraph : Neo4j.Graph
|
286
|
+
The input neo4j graph.
|
287
|
+
graph : topologic.Graph
|
288
|
+
The input topologic graph.
|
289
|
+
categoryKey : str
|
290
|
+
The category key in the dictionary under which to look for the category value.
|
291
|
+
tolerance : float , optional
|
292
|
+
The desired tolerance. The default is 0.0001.
|
293
|
+
|
294
|
+
Returns
|
295
|
+
-------
|
296
|
+
Neo4j.Graph
|
297
|
+
The input neo4j graph with the input topologic graph added to it.
|
298
|
+
|
299
|
+
"""
|
300
|
+
from topologicpy.Vertex import Vertex
|
301
|
+
from topologicpy.Topology import Topology
|
302
|
+
from topologicpy.Graph import Graph
|
303
|
+
from topologicpy.Dictionary import Dictionary
|
304
|
+
gmt = time.gmtime()
|
305
|
+
timestamp = str(gmt.tm_zone)+"_"+str(gmt.tm_year)+"_"+str(gmt.tm_mon)+"_"+str(gmt.tm_wday)+"_"+str(gmt.tm_hour)+"_"+str(gmt.tm_min)+"_"+str(gmt.tm_sec)
|
306
|
+
vertices = Graph.Vertices(graph)
|
307
|
+
edges = Graph.Edges(graph)
|
308
|
+
tx = neo4jGraph.begin()
|
309
|
+
nodes = []
|
310
|
+
for i in range(len(vertices)):
|
311
|
+
vDict = Topology.Dictionary(vertices[i])
|
312
|
+
keys = Dictionary.Keyus(vDict)
|
313
|
+
values = Dictionary.Values(vDict)
|
314
|
+
keys.append("x")
|
315
|
+
keys.append("y")
|
316
|
+
keys.append("z")
|
317
|
+
keys.append("timestamp")
|
318
|
+
keys.append("location")
|
319
|
+
values.append(vertices[i].X())
|
320
|
+
values.append(vertices[i].Y())
|
321
|
+
values.append(vertices[i].Z())
|
322
|
+
values.append(timestamp)
|
323
|
+
values.append(sp.CartesianPoint([vertices[i].X(),vertices[i].Y(),vertices[i].Z()]))
|
324
|
+
zip_iterator = zip(keys, values)
|
325
|
+
pydict = dict(zip_iterator)
|
326
|
+
if labelKey == 'None':
|
327
|
+
nodeName = "TopologicGraphVertex"
|
328
|
+
else:
|
329
|
+
nodeName = str(values[keys.index(labelKey)])
|
330
|
+
n = py2neo.Node(nodeName, **pydict)
|
331
|
+
neo4jGraph.cypher.execute("CREATE INDEX FOR (n:%s) on (n.name)" %
|
332
|
+
n.nodelabel)
|
333
|
+
tx.create(n)
|
334
|
+
nodes.append(n)
|
335
|
+
for i in range(len(edges)):
|
336
|
+
e = edges[i]
|
337
|
+
sv = e.StartVertex()
|
338
|
+
ev = e.EndVertex()
|
339
|
+
sn = nodes[Vertex.Index(sv, vertices, tolerance)]
|
340
|
+
en = nodes[Vertex.Index(ev, vertices, tolerance)]
|
341
|
+
relationshipType = Dictionary.ValueAtKey(e, relationshipKey)
|
342
|
+
if not (relationshipType):
|
343
|
+
relationshipType = "Connected To"
|
344
|
+
snen = py2neo.Relationship(sn, relationshipType, en)
|
345
|
+
tx.create(snen)
|
346
|
+
snen = py2neo.Relationship(en, relationshipType, sn)
|
347
|
+
tx.create(snen)
|
348
|
+
neo4jGraph.commit(tx)
|
349
|
+
return neo4jGraph
|
350
|
+
|
351
|
+
|
352
|
+
@staticmethod
|
353
|
+
def ByParameters(url, username, password):
|
354
|
+
"""
|
355
|
+
Returns a Neo4j graph by the input parameters.
|
356
|
+
|
357
|
+
Parameters
|
358
|
+
----------
|
359
|
+
url : str
|
360
|
+
The URL of the server.
|
361
|
+
username : str
|
362
|
+
The username to use for logging in.
|
363
|
+
password : str
|
364
|
+
The password to use for logging in.
|
365
|
+
|
366
|
+
Returns
|
367
|
+
-------
|
368
|
+
Neo4j.Graph
|
369
|
+
The returned Neo4j graph.
|
370
|
+
|
371
|
+
"""
|
372
|
+
return py2neo.Graph(url, auth=(username, password))
|
373
|
+
|
374
|
+
@staticmethod
|
375
|
+
def DeleteAll(neo4jGraph):
|
376
|
+
"""
|
377
|
+
Deletes all entities in the input Neo4j graph.
|
378
|
+
|
379
|
+
Parameters
|
380
|
+
----------
|
381
|
+
neo4jGraph : Neo4j Graph
|
382
|
+
The input Neo4jGraph.
|
383
|
+
|
384
|
+
Returns
|
385
|
+
-------
|
386
|
+
Neo4J Graph
|
387
|
+
The returned empty graph.
|
388
|
+
|
389
|
+
"""
|
390
|
+
neo4jGraph.delete_all()
|
391
|
+
return neo4jGraph
|
392
|
+
|
393
|
+
@staticmethod
|
394
|
+
def NodeLabels(neo4jGraph):
|
395
|
+
"""
|
396
|
+
Returns all the node labels used in the input neo4j graph.
|
397
|
+
|
398
|
+
Parameters
|
399
|
+
----------
|
400
|
+
neo4jGraph : Newo4j.Graph
|
401
|
+
The input neo4j graph.
|
402
|
+
|
403
|
+
Returns
|
404
|
+
-------
|
405
|
+
list
|
406
|
+
The list of node labels used in the input neo4j graph.
|
407
|
+
|
408
|
+
"""
|
409
|
+
return list(neo4jGraph.schema.node_labels)
|
410
|
+
|
411
|
+
@staticmethod
|
412
|
+
def RelationshipTypes(neo4jGraph):
|
413
|
+
"""
|
414
|
+
Returns all the relationship types used in the input neo4j graph.
|
415
|
+
|
416
|
+
Parameters
|
417
|
+
----------
|
418
|
+
neo4jGraph : Newo4j.Graph
|
419
|
+
The input neo4j graph.
|
420
|
+
|
421
|
+
Returns
|
422
|
+
-------
|
423
|
+
list
|
424
|
+
The list of relationship types used in the input neo4j graph.
|
425
|
+
|
426
|
+
"""
|
427
|
+
return list(neo4jGraph.schema.relationship_types)
|
428
|
+
|
429
|
+
@staticmethod
|
430
|
+
def SetGraph(neo4jGraph, graph, labelKey=None, relationshipKey=None, bidirectional=True, deleteAll=True, tolerance=0.0001):
|
431
|
+
"""
|
432
|
+
Sets the input topologic graph to the input neo4jGraph.
|
433
|
+
|
434
|
+
Parameters
|
435
|
+
----------
|
436
|
+
neo4jGraph : Neo4j.Graph
|
437
|
+
The input neo4j graph.
|
438
|
+
graph : topologic.Graph
|
439
|
+
The input topologic graph.
|
440
|
+
labelKey : str , optional
|
441
|
+
The dictionary key under which to find the vertex's label value. The default is None which means the vertex gets the name 'TopologicGraphVertex'.
|
442
|
+
relationshipKey : str , optional
|
443
|
+
The dictionary key under which to find the edge's relationship value. The default is None which means the edge gets the relationship type 'Connected To'.
|
444
|
+
bidirectional : bool , optional
|
445
|
+
If set to True, the edges in the neo4j graph are set to be bi-drectional.
|
446
|
+
deleteAll : bool , optional
|
447
|
+
If set to True, all previous entities are deleted before adding the new entities.
|
448
|
+
tolerance : float , optional
|
449
|
+
The desired tolerance. The default is 0.0001.
|
450
|
+
|
451
|
+
Returns
|
452
|
+
-------
|
453
|
+
neo4jGraph : TYPE
|
454
|
+
The input neo4j graph with the input topologic graph added to it.
|
455
|
+
|
456
|
+
"""
|
457
|
+
from topologicpy.Vertex import Vertex
|
458
|
+
from topologicpy.Graph import Graph
|
459
|
+
from topologicpy.Topology import Topology
|
460
|
+
from topologicpy.Dictionary import Dictionary
|
461
|
+
|
462
|
+
import time
|
463
|
+
gmt = time.gmtime()
|
464
|
+
timestamp = str(gmt.tm_zone)+"_"+str(gmt.tm_year)+"_"+str(gmt.tm_mon)+"_"+str(gmt.tm_wday)+"_"+str(gmt.tm_hour)+"_"+str(gmt.tm_min)+"_"+str(gmt.tm_sec)
|
465
|
+
|
466
|
+
vertices = Graph.Vertices(graph)
|
467
|
+
edges = Graph.Edges(graph)
|
468
|
+
tx = neo4jGraph.begin()
|
469
|
+
nodes = []
|
470
|
+
for i in range(len(vertices)):
|
471
|
+
vDict = Topology.Dictionary(vertices[i])
|
472
|
+
if not vDict:
|
473
|
+
keys = []
|
474
|
+
values = []
|
475
|
+
else:
|
476
|
+
keys = Dictionary.Keys(vDict)
|
477
|
+
if not keys:
|
478
|
+
keys = []
|
479
|
+
values = Dictionary.Values(vDict)
|
480
|
+
if not values:
|
481
|
+
values = []
|
482
|
+
keys.append("x")
|
483
|
+
keys.append("y")
|
484
|
+
keys.append("z")
|
485
|
+
keys.append("timestamp")
|
486
|
+
keys.append("location")
|
487
|
+
values.append(vertices[i].X())
|
488
|
+
values.append(vertices[i].Y())
|
489
|
+
values.append(vertices[i].Z())
|
490
|
+
values.append(timestamp)
|
491
|
+
values.append(sp.CartesianPoint([vertices[i].X(),vertices[i].Y(),vertices[i].Z()]))
|
492
|
+
zip_iterator = zip(keys, values)
|
493
|
+
pydict = dict(zip_iterator)
|
494
|
+
if (labelKey == 'None') or (not (labelKey)):
|
495
|
+
nodeName = "TopologicGraphVertex"
|
496
|
+
else:
|
497
|
+
nodeName = str(Dictionary.ValueAtKey(vDict, labelKey))
|
498
|
+
n = py2neo.Node(nodeName, **pydict)
|
499
|
+
tx.create(n)
|
500
|
+
nodes.append(n)
|
501
|
+
for i in range(len(edges)):
|
502
|
+
e = edges[i]
|
503
|
+
sv = e.StartVertex()
|
504
|
+
ev = e.EndVertex()
|
505
|
+
sn = nodes[Vertex.Index(vertex=sv, vertices=vertices, strict=False, tolerance=tolerance)]
|
506
|
+
en = nodes[Vertex.Index(vertex=ev, vertices=vertices, strict=False, tolerance=tolerance)]
|
507
|
+
ed = Topology.Dictionary(e)
|
508
|
+
if relationshipKey:
|
509
|
+
relationshipType = Dictionary.ValueAtKey(ed, relationshipKey)
|
510
|
+
else:
|
511
|
+
relationshipType = "Connected To"
|
512
|
+
if not (relationshipType):
|
513
|
+
relationshipType = "Connected To"
|
514
|
+
snen = py2neo.Relationship(sn, relationshipType, en)
|
515
|
+
tx.create(snen)
|
516
|
+
if bidirectional:
|
517
|
+
snen = py2neo.Relationship(en, relationshipType, sn)
|
518
|
+
tx.create(snen)
|
519
|
+
if deleteAll:
|
520
|
+
neo4jGraph.delete_all()
|
521
|
+
neo4jGraph.commit(tx)
|
522
522
|
return neo4jGraph
|