topologicpy 0.5.4__py3-none-any.whl → 0.5.6__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/Cell.py +0 -23
- topologicpy/CellComplex.py +0 -3
- topologicpy/Face.py +157 -14
- topologicpy/Graph.py +612 -51
- topologicpy/Plotly.py +2025 -2025
- topologicpy/Topology.py +41 -26
- topologicpy/__init__.py +1 -1
- {topologicpy-0.5.4.dist-info → topologicpy-0.5.6.dist-info}/METADATA +3 -2
- {topologicpy-0.5.4.dist-info → topologicpy-0.5.6.dist-info}/RECORD +12 -12
- {topologicpy-0.5.4.dist-info → topologicpy-0.5.6.dist-info}/LICENSE +0 -0
- {topologicpy-0.5.4.dist-info → topologicpy-0.5.6.dist-info}/WHEEL +0 -0
- {topologicpy-0.5.4.dist-info → topologicpy-0.5.6.dist-info}/top_level.txt +0 -0
topologicpy/Graph.py
CHANGED
@@ -527,6 +527,329 @@ class Graph:
|
|
527
527
|
lcc = Graph.LocalClusteringCoefficient(graph, vertices)
|
528
528
|
acc = round(sum(lcc)/float(len(lcc)), mantissa)
|
529
529
|
return acc
|
530
|
+
|
531
|
+
@staticmethod
|
532
|
+
def BOTGraph(graph,
|
533
|
+
bidirectional=False,
|
534
|
+
includeAttributes=False,
|
535
|
+
includeLabel=False,
|
536
|
+
siteLabel = "Site_0001",
|
537
|
+
siteDictionary = None,
|
538
|
+
buildingLabel = "Building_0001",
|
539
|
+
buildingDictionary = None ,
|
540
|
+
storeyPrefix = "Storey",
|
541
|
+
floorLevels =[],
|
542
|
+
labelKey="label",
|
543
|
+
typeKey="type",
|
544
|
+
spaceType = "space",
|
545
|
+
wallType = "wall",
|
546
|
+
slabType = "slab",
|
547
|
+
doorType = "door",
|
548
|
+
windowType = "window",
|
549
|
+
contentType = "content"
|
550
|
+
):
|
551
|
+
"""
|
552
|
+
Creates an RDF graph according to the BOT ontology. See https://w3c-lbd-cg.github.io/bot/.
|
553
|
+
|
554
|
+
Parameters
|
555
|
+
----------
|
556
|
+
graph : topologic.Graph
|
557
|
+
The input graph.
|
558
|
+
bidirectional : bool , optional
|
559
|
+
If set to True, reverse relationships are created wherever possible. Otherwise, they are not. The default is False.
|
560
|
+
includeAttributes : bool , optional
|
561
|
+
If set to True, the attributes associated with vertices in the graph are written out. Otherwise, they are not. The default is False.
|
562
|
+
includeLabel : bool , optional
|
563
|
+
If set to True, a label is attached to each node. Otherwise, it is not. The default is False.
|
564
|
+
siteLabel : str , optional
|
565
|
+
The desired site label. The default is "Site_0001".
|
566
|
+
siteDictionary : dict , optional
|
567
|
+
The dictionary of site attributes to include in the output. The default is None.
|
568
|
+
buildingLabel : str , optional
|
569
|
+
The desired building label. The default is "Building_0001".
|
570
|
+
buildingDictionary : dict , optional
|
571
|
+
The dictionary of building attributes to include in the output. The default is None.
|
572
|
+
storeyPrefix : str , optional
|
573
|
+
The desired prefixed to use for each building storey. The default is "Storey".
|
574
|
+
floorLevels : list , optional
|
575
|
+
The list of floor levels. This should be a numeric list, sorted from lowest to highest.
|
576
|
+
If not provided, floorLevels will be computed automatically based on the vertices' 'z' attribute.
|
577
|
+
typeKey : str , optional
|
578
|
+
The dictionary key to use to look up the type of the node. The default is "type".
|
579
|
+
labelKey : str , optional
|
580
|
+
The dictionary key to use to look up the label of the node. The default is "label".
|
581
|
+
spaceType : str , optional
|
582
|
+
The dictionary string value to use to look up vertices of type "space". The default is "space".
|
583
|
+
wallType : str , optional
|
584
|
+
The dictionary string value to use to look up vertices of type "wall". The default is "wall".
|
585
|
+
slabType : str , optional
|
586
|
+
The dictionary string value to use to look up vertices of type "slab". The default is "slab".
|
587
|
+
doorType : str , optional
|
588
|
+
The dictionary string value to use to look up vertices of type "door". The default is "door".
|
589
|
+
windowType : str , optional
|
590
|
+
The dictionary string value to use to look up vertices of type "window". The default is "window".
|
591
|
+
contentType : str , optional
|
592
|
+
The dictionary string value to use to look up vertices of type "content". The default is "contents".
|
593
|
+
|
594
|
+
Returns
|
595
|
+
-------
|
596
|
+
rdflib.graph.Graph
|
597
|
+
The rdf graph using the BOT ontology.
|
598
|
+
"""
|
599
|
+
|
600
|
+
from topologicpy.Helper import Helper
|
601
|
+
import os
|
602
|
+
import warnings
|
603
|
+
|
604
|
+
try:
|
605
|
+
from rdflib import Graph as RDFGraph
|
606
|
+
from rdflib import URIRef, Literal, Namespace
|
607
|
+
from rdflib.namespace import RDF, RDFS
|
608
|
+
except:
|
609
|
+
print("Graph.BOTGraph - Installing required rdflib library.")
|
610
|
+
try:
|
611
|
+
os.system("pip install rdflib")
|
612
|
+
except:
|
613
|
+
os.system("pip install rdflib --user")
|
614
|
+
try:
|
615
|
+
from rdflib import Graph as RDFGraph
|
616
|
+
from rdflib import URIRef, Literal, Namespace
|
617
|
+
from rdflib.namespace import RDF, RDFS
|
618
|
+
print("Graph.BOTGraph - rdflib library installed correctly.")
|
619
|
+
except:
|
620
|
+
warnings.warn("Graph.BOTGraph - Error: Could not import rdflib. Please try to install rdflib manually. Returning None.")
|
621
|
+
return None
|
622
|
+
|
623
|
+
if floorLevels == None:
|
624
|
+
floorLevels = []
|
625
|
+
json_data = Graph.JSONData(graph, vertexLabelKey=labelKey)
|
626
|
+
# Create an empty RDF graph
|
627
|
+
bot_graph = RDFGraph()
|
628
|
+
|
629
|
+
# Define namespaces
|
630
|
+
rdf = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
631
|
+
rdfs = Namespace("http://www.w3.org/2000/01/rdf-schema#")
|
632
|
+
bot = Namespace("https://w3id.org/bot#")
|
633
|
+
|
634
|
+
# Define a custom prefix mapping
|
635
|
+
bot_graph.namespace_manager.bind("bot", bot)
|
636
|
+
|
637
|
+
# Add site
|
638
|
+
site_uri = URIRef(siteLabel)
|
639
|
+
bot_graph.add((site_uri, rdf.type, bot.Site))
|
640
|
+
if includeLabel:
|
641
|
+
bot_graph.add((site_uri, RDFS.label, Literal(siteLabel)))
|
642
|
+
if isinstance(siteDictionary, topologic.Dictionary):
|
643
|
+
keys = Dictionary.Keys(siteDictionary)
|
644
|
+
for key in keys:
|
645
|
+
value = Dictionary.ValueAtKey(siteDictionary, key)
|
646
|
+
if not (key == labelKey) and not (key == typeKey):
|
647
|
+
bot_graph.add((site_uri, bot[key], Literal(value)))
|
648
|
+
# Add building
|
649
|
+
building_uri = URIRef(buildingLabel)
|
650
|
+
bot_graph.add((building_uri, rdf.type, bot.Building))
|
651
|
+
if includeLabel:
|
652
|
+
bot_graph.add((building_uri, RDFS.label, Literal(buildingLabel)))
|
653
|
+
if isinstance(buildingDictionary, topologic.Dictionary):
|
654
|
+
keys = Dictionary.Keys(buildingDictionary)
|
655
|
+
for key in keys:
|
656
|
+
value = Dictionary.ValueAtKey(buildingDictionary, key)
|
657
|
+
if key == labelKey:
|
658
|
+
if includeLabel:
|
659
|
+
bot_graph.add((building_uri, RDFS.label, Literal(value)))
|
660
|
+
elif key != typeKey:
|
661
|
+
bot_graph.add((building_uri, bot[key], Literal(value)))
|
662
|
+
# Add stories
|
663
|
+
# if floor levels are not given, then need to be computed
|
664
|
+
if len(floorLevels) == 0:
|
665
|
+
for node, attributes in json_data['vertices'].items():
|
666
|
+
if slabType.lower() in attributes[typeKey].lower():
|
667
|
+
floorLevels.append(attributes["z"])
|
668
|
+
floorLevels = list(set(floorLevels))
|
669
|
+
floorLevels.sort()
|
670
|
+
floorLevels = floorLevels[:-1]
|
671
|
+
storey_uris = []
|
672
|
+
n = max(len(str(len(floorLevels))),4)
|
673
|
+
for i, floor_level in enumerate(floorLevels):
|
674
|
+
storey_uri = URIRef(storeyPrefix+"_"+str(i+1).zfill(n))
|
675
|
+
bot_graph.add((storey_uri, rdf.type, bot.Storey))
|
676
|
+
if includeLabel:
|
677
|
+
bot_graph.add((storey_uri, RDFS.label, Literal(storeyPrefix+"_"+str(i+1).zfill(n))))
|
678
|
+
storey_uris.append(storey_uri)
|
679
|
+
|
680
|
+
# Add triples to relate building to site and stories to building
|
681
|
+
bot_graph.add((site_uri, bot.hasBuilding, building_uri))
|
682
|
+
if bidirectional:
|
683
|
+
bot_graph.add((building_uri, bot.isPartOf, site_uri)) # might not be needed
|
684
|
+
|
685
|
+
for storey_uri in storey_uris:
|
686
|
+
bot_graph.add((building_uri, bot.hasStorey, storey_uri))
|
687
|
+
if bidirectional:
|
688
|
+
bot_graph.add((storey_uri, bot.isPartOf, building_uri)) # might not be needed
|
689
|
+
|
690
|
+
# Add vertices as RDF resources
|
691
|
+
for node, attributes in json_data['vertices'].items():
|
692
|
+
node_uri = URIRef(node)
|
693
|
+
if spaceType.lower() in attributes[typeKey].lower():
|
694
|
+
bot_graph.add((node_uri, rdf.type, bot.Space))
|
695
|
+
# Find the storey it is on
|
696
|
+
z = attributes["z"]
|
697
|
+
level = Helper.Position(z, floorLevels)
|
698
|
+
if level > len(storey_uris):
|
699
|
+
level = len(storey_uris)
|
700
|
+
storey_uri = storey_uris[level-1]
|
701
|
+
bot_graph.add((storey_uri, bot.hasSpace, node_uri))
|
702
|
+
if bidirectional:
|
703
|
+
bot_graph.add((node_uri, bot.isPartOf, storey_uri)) # might not be needed
|
704
|
+
elif windowType.lower() in attributes[typeKey].lower():
|
705
|
+
bot_graph.add((node_uri, rdf.type, bot.Window))
|
706
|
+
elif doorType.lower() in attributes[typeKey].lower():
|
707
|
+
bot_graph.add((node_uri, rdf.type, bot.Door))
|
708
|
+
elif wallType.lower() in attributes[typeKey].lower():
|
709
|
+
bot_graph.add((node_uri, rdf.type, bot.Wall))
|
710
|
+
elif slabType.lower() in attributes[typeKey].lower():
|
711
|
+
bot_graph.add((node_uri, rdf.type, bot.Slab))
|
712
|
+
else:
|
713
|
+
bot_graph.add((node_uri, rdf.type, bot.Element))
|
714
|
+
|
715
|
+
if includeAttributes:
|
716
|
+
for key, value in attributes.items():
|
717
|
+
if key == labelKey:
|
718
|
+
if includeLabel:
|
719
|
+
bot_graph.add((node_uri, RDFS.label, Literal(value)))
|
720
|
+
elif key != typeKey:
|
721
|
+
bot_graph.add((node_uri, bot[key], Literal(value)))
|
722
|
+
if includeLabel:
|
723
|
+
for key, value in attributes.items():
|
724
|
+
if key == labelKey:
|
725
|
+
bot_graph.add((node_uri, RDFS.label, Literal(value)))
|
726
|
+
|
727
|
+
# Add edges as RDF triples
|
728
|
+
for edge, attributes in json_data['edges'].items():
|
729
|
+
source = attributes["source"]
|
730
|
+
target = attributes["target"]
|
731
|
+
source_uri = URIRef(source)
|
732
|
+
target_uri = URIRef(target)
|
733
|
+
if spaceType.lower() in json_data['vertices'][source][typeKey].lower() and spaceType.lower() in json_data['vertices'][target][typeKey].lower():
|
734
|
+
bot_graph.add((source_uri, bot.adjacentTo, target_uri))
|
735
|
+
if bidirectional:
|
736
|
+
bot_graph.add((target_uri, bot.adjacentTo, source_uri))
|
737
|
+
elif spaceType.lower() in json_data['vertices'][source][typeKey].lower() and wallType.lower() in json_data['vertices'][target][typeKey].lower():
|
738
|
+
bot_graph.add((target_uri, bot.interfaceOf, source_uri))
|
739
|
+
elif spaceType.lower() in json_data['vertices'][source][typeKey].lower() and slabType.lower() in json_data['vertices'][target][typeKey].lower():
|
740
|
+
bot_graph.add((target_uri, bot.interfaceOf, source_uri))
|
741
|
+
elif spaceType.lower() in json_data['vertices'][source][typeKey].lower() and contentType.lower() in json_data['vertices'][target][typeKey].lower():
|
742
|
+
bot_graph.add((source_uri, bot.containsElement, target_uri))
|
743
|
+
if bidirectional:
|
744
|
+
bot_graph.add((target_uri, bot.isPartOf, source_uri))
|
745
|
+
else:
|
746
|
+
bot_graph.add((source_uri, bot.connectsTo, target_uri))
|
747
|
+
if bidirectional:
|
748
|
+
bot_graph.add((target_uri, bot.connectsTo, source_uri))
|
749
|
+
return bot_graph
|
750
|
+
|
751
|
+
@staticmethod
|
752
|
+
def BOTString(graph,
|
753
|
+
format="turtle",
|
754
|
+
bidirectional=False,
|
755
|
+
includeAttributes=False,
|
756
|
+
includeLabel=False,
|
757
|
+
siteLabel = "Site_0001",
|
758
|
+
siteDictionary = None,
|
759
|
+
buildingLabel = "Building_0001",
|
760
|
+
buildingDictionary = None ,
|
761
|
+
storeyPrefix = "Storey",
|
762
|
+
floorLevels =[],
|
763
|
+
labelKey="label",
|
764
|
+
typeKey="type",
|
765
|
+
spaceType = "space",
|
766
|
+
wallType = "wall",
|
767
|
+
slabType = "slab",
|
768
|
+
doorType = "door",
|
769
|
+
windowType = "window",
|
770
|
+
contentType = "content",
|
771
|
+
):
|
772
|
+
|
773
|
+
"""
|
774
|
+
Returns an RDF graph serialized string according to the BOT ontology. See https://w3c-lbd-cg.github.io/bot/.
|
775
|
+
|
776
|
+
Parameters
|
777
|
+
----------
|
778
|
+
graph : topologic.Graph
|
779
|
+
The input graph.
|
780
|
+
format : str , optional
|
781
|
+
The desired output format, the options are listed below. Thde default is "turtle".
|
782
|
+
turtle, ttl or turtle2 : Turtle, turtle2 is just turtle with more spacing & linebreaks
|
783
|
+
xml or pretty-xml : RDF/XML, Was the default format, rdflib < 6.0.0
|
784
|
+
json-ld : JSON-LD , There are further options for compact syntax and other JSON-LD variants
|
785
|
+
ntriples, nt or nt11 : N-Triples , nt11 is exactly like nt, only utf8 encoded
|
786
|
+
n3 : Notation-3 , N3 is a superset of Turtle that also caters for rules and a few other things
|
787
|
+
trig : Trig , Turtle-like format for RDF triples + context (RDF quads) and thus multiple graphs
|
788
|
+
trix : Trix , RDF/XML-like format for RDF quads
|
789
|
+
nquads : N-Quads , N-Triples-like format for RDF quads
|
790
|
+
bidirectional : bool , optional
|
791
|
+
If set to True, reverse relationships are created wherever possible. Otherwise, they are not. The default is False.
|
792
|
+
includeAttributes : bool , optional
|
793
|
+
If set to True, the attributes associated with vertices in the graph are written out. Otherwise, they are not. The default is False.
|
794
|
+
includeLabel : bool , optional
|
795
|
+
If set to True, a label is attached to each node. Otherwise, it is not. The default is False.
|
796
|
+
siteLabel : str , optional
|
797
|
+
The desired site label. The default is "Site_0001".
|
798
|
+
siteDictionary : dict , optional
|
799
|
+
The dictionary of site attributes to include in the output. The default is None.
|
800
|
+
buildingLabel : str , optional
|
801
|
+
The desired building label. The default is "Building_0001".
|
802
|
+
buildingDictionary : dict , optional
|
803
|
+
The dictionary of building attributes to include in the output. The default is None.
|
804
|
+
storeyPrefix : str , optional
|
805
|
+
The desired prefixed to use for each building storey. The default is "Storey".
|
806
|
+
floorLevels : list , optional
|
807
|
+
The list of floor levels. This should be a numeric list, sorted from lowest to highest.
|
808
|
+
If not provided, floorLevels will be computed automatically based on the vertices' 'z' attribute.
|
809
|
+
typeKey : str , optional
|
810
|
+
The dictionary key to use to look up the type of the node. The default is "type".
|
811
|
+
labelKey : str , optional
|
812
|
+
The dictionary key to use to look up the label of the node. The default is "label".
|
813
|
+
spaceType : str , optional
|
814
|
+
The dictionary string value to use to look up vertices of type "space". The default is "space".
|
815
|
+
wallType : str , optional
|
816
|
+
The dictionary string value to use to look up vertices of type "wall". The default is "wall".
|
817
|
+
slabType : str , optional
|
818
|
+
The dictionary string value to use to look up vertices of type "slab". The default is "slab".
|
819
|
+
doorType : str , optional
|
820
|
+
The dictionary string value to use to look up vertices of type "door". The default is "door".
|
821
|
+
windowType : str , optional
|
822
|
+
The dictionary string value to use to look up vertices of type "window". The default is "window".
|
823
|
+
contentType : str , optional
|
824
|
+
The dictionary string value to use to look up vertices of type "content". The default is "contents".
|
825
|
+
|
826
|
+
|
827
|
+
Returns
|
828
|
+
-------
|
829
|
+
str
|
830
|
+
The rdf graph serialized string using the BOT ontology.
|
831
|
+
"""
|
832
|
+
|
833
|
+
bot_graph = Graph.BOTGraph(graph,
|
834
|
+
bidirectional=bidirectional,
|
835
|
+
includeAttributes=includeAttributes,
|
836
|
+
includeLabel=includeLabel,
|
837
|
+
siteLabel=siteLabel,
|
838
|
+
siteDictionary=siteDictionary,
|
839
|
+
buildingLabel=buildingLabel,
|
840
|
+
buildingDictionary=buildingDictionary,
|
841
|
+
storeyPrefix=storeyPrefix,
|
842
|
+
floorLevels=floorLevels,
|
843
|
+
labelKey=labelKey,
|
844
|
+
typeKey=typeKey,
|
845
|
+
spaceType = spaceType,
|
846
|
+
wallType = wallType,
|
847
|
+
slabType = slabType,
|
848
|
+
doorType = doorType,
|
849
|
+
windowType = windowType,
|
850
|
+
contentType = contentType
|
851
|
+
)
|
852
|
+
return bot_graph.serialize(format=format)
|
530
853
|
|
531
854
|
@staticmethod
|
532
855
|
def BetweenessCentrality(graph, vertices=None, sources=None, destinations=None, tolerance=0.001):
|
@@ -1469,6 +1792,7 @@ class Graph:
|
|
1469
1792
|
from topologicpy.Edge import Edge
|
1470
1793
|
from topologicpy.Cluster import Cluster
|
1471
1794
|
from topologicpy.Topology import Topology
|
1795
|
+
from topologicpy.Aperture import Aperture
|
1472
1796
|
|
1473
1797
|
def mergeDictionaries(sources):
|
1474
1798
|
if isinstance(sources, list) == False:
|
@@ -1687,7 +2011,7 @@ class Graph:
|
|
1687
2011
|
|
1688
2012
|
cells = []
|
1689
2013
|
_ = topology.Cells(None, cells)
|
1690
|
-
if (viaSharedTopologies
|
2014
|
+
if any([viaSharedTopologies, viaSharedApertures, toExteriorTopologies, toExteriorApertures, toContents]):
|
1691
2015
|
for aCell in cells:
|
1692
2016
|
if useInternalVertex == True:
|
1693
2017
|
vCell = Topology.InternalVertex(aCell, tolerance=tolerance)
|
@@ -1710,9 +2034,9 @@ class Graph:
|
|
1710
2034
|
contents = []
|
1711
2035
|
_ = aCell.Contents(contents)
|
1712
2036
|
for aFace in faces:
|
1713
|
-
|
1714
|
-
_ = aFace.Cells(topology,
|
1715
|
-
if len(
|
2037
|
+
cells1 = []
|
2038
|
+
_ = aFace.Cells(topology, cells1)
|
2039
|
+
if len(cells1) > 1:
|
1716
2040
|
sharedTopologies.append(aFace)
|
1717
2041
|
apertures = []
|
1718
2042
|
_ = aFace.Apertures(apertures)
|
@@ -1724,6 +2048,7 @@ class Graph:
|
|
1724
2048
|
_ = aFace.Apertures(apertures)
|
1725
2049
|
for anAperture in apertures:
|
1726
2050
|
exteriorApertures.append(anAperture)
|
2051
|
+
|
1727
2052
|
if viaSharedTopologies:
|
1728
2053
|
for sharedTopology in sharedTopologies:
|
1729
2054
|
if useInternalVertex == True:
|
@@ -1746,6 +2071,8 @@ class Graph:
|
|
1746
2071
|
contents = []
|
1747
2072
|
_ = sharedTopology.Contents(contents)
|
1748
2073
|
for content in contents:
|
2074
|
+
if isinstance(content, topologic.Aperture):
|
2075
|
+
content = Aperture.Topology(content)
|
1749
2076
|
if useInternalVertex == True:
|
1750
2077
|
vst2 = Topology.InternalVertex(content, tolerance)
|
1751
2078
|
else:
|
@@ -1767,38 +2094,38 @@ class Graph:
|
|
1767
2094
|
for sharedAperture in sharedApertures:
|
1768
2095
|
sharedAp = sharedAperture.Topology()
|
1769
2096
|
if useInternalVertex == True:
|
1770
|
-
|
2097
|
+
vsa = Topology.InternalVertex(sharedAp, tolerance)
|
1771
2098
|
else:
|
1772
|
-
|
2099
|
+
vsa = sharedAp.CenterOfMass()
|
1773
2100
|
d1 = sharedAp.GetDictionary()
|
1774
|
-
|
2101
|
+
vsa = topologic.Vertex.ByCoordinates(vsa.X()+(tolerance*100), vsa.Y()+(tolerance*100), vsa.Z()+(tolerance*100))
|
1775
2102
|
if storeBRep:
|
1776
2103
|
d2 = Dictionary.ByKeysValues(["brep", "brepType", "brepTypeString"], [Topology.BREPString(sharedAperture), Topology.Type(sharedAperture), Topology.TypeAsString(sharedAperture)])
|
1777
2104
|
d3 = mergeDictionaries2([d1, d2])
|
1778
|
-
_ =
|
2105
|
+
_ = vsa.SetDictionary(d3)
|
1779
2106
|
else:
|
1780
|
-
_ =
|
1781
|
-
vertices.append(
|
1782
|
-
tempe = Edge.ByStartVertexEndVertex(vCell,
|
2107
|
+
_ = vsa.SetDictionary(d1)
|
2108
|
+
vertices.append(vsa)
|
2109
|
+
tempe = Edge.ByStartVertexEndVertex(vCell, vsa, tolerance=tolerance)
|
1783
2110
|
tempd = Dictionary.ByKeysValues(["relationship"],["Via Shared Apertures"])
|
1784
2111
|
_ = tempe.SetDictionary(tempd)
|
1785
2112
|
edges.append(tempe)
|
1786
2113
|
if toExteriorTopologies:
|
1787
2114
|
for exteriorTopology in exteriorTopologies:
|
1788
2115
|
if useInternalVertex == True:
|
1789
|
-
|
2116
|
+
vet = Topology.InternalVertex(exteriorTopology, tolerance)
|
1790
2117
|
else:
|
1791
|
-
|
1792
|
-
_ =
|
2118
|
+
vet = exteriorTopology.CenterOfMass()
|
2119
|
+
_ = vet.SetDictionary(exteriorTopology.GetDictionary())
|
1793
2120
|
d1 = exteriorTopology.GetDictionary()
|
1794
2121
|
if storeBRep:
|
1795
2122
|
d2 = Dictionary.ByKeysValues(["brep", "brepType", "brepTypeString"], [Topology.BREPString(exteriorTopology), Topology.Type(exteriorTopology), Topology.TypeAsString(exteriorTopology)])
|
1796
2123
|
d3 = mergeDictionaries2([d1, d2])
|
1797
|
-
_ =
|
2124
|
+
_ = vet.SetDictionary(d3)
|
1798
2125
|
else:
|
1799
|
-
_ =
|
1800
|
-
vertices.append(
|
1801
|
-
tempe = Edge.ByStartVertexEndVertex(vCell,
|
2126
|
+
_ = vet.SetDictionary(d1)
|
2127
|
+
vertices.append(vet)
|
2128
|
+
tempe = Edge.ByStartVertexEndVertex(vCell, vet, tolerance=tolerance)
|
1802
2129
|
tempd = Dictionary.ByKeysValues(["relationship"],["To Exterior Topologies"])
|
1803
2130
|
_ = tempe.SetDictionary(tempd)
|
1804
2131
|
edges.append(tempe)
|
@@ -1806,6 +2133,8 @@ class Graph:
|
|
1806
2133
|
contents = []
|
1807
2134
|
_ = exteriorTopology.Contents(contents)
|
1808
2135
|
for content in contents:
|
2136
|
+
if isinstance(content, topologic.Aperture):
|
2137
|
+
content = Aperture.Topology(content)
|
1809
2138
|
if useInternalVertex == True:
|
1810
2139
|
vst2 = Topology.InternalVertex(content, tolerance)
|
1811
2140
|
else:
|
@@ -1819,7 +2148,7 @@ class Graph:
|
|
1819
2148
|
else:
|
1820
2149
|
_ = vst2.SetDictionary(d1)
|
1821
2150
|
vertices.append(vst2)
|
1822
|
-
tempe = Edge.ByStartVertexEndVertex(
|
2151
|
+
tempe = Edge.ByStartVertexEndVertex(vet, vst2, tolerance=tolerance)
|
1823
2152
|
tempd = Dictionary.ByKeysValues(["relationship"],["To Contents"])
|
1824
2153
|
_ = tempe.SetDictionary(tempd)
|
1825
2154
|
edges.append(tempe)
|
@@ -1827,19 +2156,19 @@ class Graph:
|
|
1827
2156
|
for exteriorAperture in exteriorApertures:
|
1828
2157
|
extTop = exteriorAperture.Topology()
|
1829
2158
|
if useInternalVertex == True:
|
1830
|
-
|
2159
|
+
vea = Topology.InternalVertex(extTop, tolerance)
|
1831
2160
|
else:
|
1832
|
-
|
2161
|
+
vea = exteriorAperture.Topology().CenterOfMass()
|
1833
2162
|
d1 = exteriorAperture.Topology().GetDictionary()
|
1834
|
-
|
2163
|
+
vea = topologic.Vertex.ByCoordinates(vea.X()+(tolerance*100), vea.Y()+(tolerance*100), vea.Z()+(tolerance*100))
|
1835
2164
|
if storeBRep:
|
1836
2165
|
d2 = Dictionary.ByKeysValues(["brep", "brepType", "brepTypeString"], [Topology.BREPString(exteriorAperture), Topology.Type(exteriorAperture), Topology.TypeAsString(exteriorAperture)])
|
1837
2166
|
d3 = mergeDictionaries2([d1, d2])
|
1838
|
-
_ =
|
2167
|
+
_ = vea.SetDictionary(d3)
|
1839
2168
|
else:
|
1840
|
-
_ =
|
1841
|
-
vertices.append(
|
1842
|
-
tempe = Edge.ByStartVertexEndVertex(vCell,
|
2169
|
+
_ = vea.SetDictionary(d1)
|
2170
|
+
vertices.append(vea)
|
2171
|
+
tempe = Edge.ByStartVertexEndVertex(vCell, vea, tolerance=tolerance)
|
1843
2172
|
tempd = Dictionary.ByKeysValues(["relationship"],["To Exterior Apertures"])
|
1844
2173
|
_ = tempe.SetDictionary(tempd)
|
1845
2174
|
edges.append(tempe)
|
@@ -1847,20 +2176,22 @@ class Graph:
|
|
1847
2176
|
contents = []
|
1848
2177
|
_ = aCell.Contents(contents)
|
1849
2178
|
for content in contents:
|
2179
|
+
if isinstance(content, topologic.Aperture):
|
2180
|
+
content = Aperture.Topology(content)
|
1850
2181
|
if useInternalVertex == True:
|
1851
|
-
|
2182
|
+
vcn = Topology.InternalVertex(content, tolerance)
|
1852
2183
|
else:
|
1853
|
-
|
1854
|
-
|
2184
|
+
vcn = content.CenterOfMass()
|
2185
|
+
vcn = topologic.Vertex.ByCoordinates(vcn.X()+(tolerance*100), vcn.Y()+(tolerance*100), vcn.Z()+(tolerance*100))
|
1855
2186
|
d1 = content.GetDictionary()
|
1856
2187
|
if storeBRep:
|
1857
2188
|
d2 = Dictionary.ByKeysValues(["brep", "brepType", "brepTypeString"], [Topology.BREPString(content), Topology.Type(content), Topology.TypeAsString(content)])
|
1858
2189
|
d3 = mergeDictionaries2([d1, d2])
|
1859
|
-
_ =
|
2190
|
+
_ = vcn.SetDictionary(d3)
|
1860
2191
|
else:
|
1861
|
-
_ =
|
1862
|
-
vertices.append(
|
1863
|
-
tempe = Edge.ByStartVertexEndVertex(vCell,
|
2192
|
+
_ = vcn.SetDictionary(d1)
|
2193
|
+
vertices.append(vcn)
|
2194
|
+
tempe = Edge.ByStartVertexEndVertex(vCell, vcn, tolerance=tolerance)
|
1864
2195
|
tempd = Dictionary.ByKeysValues(["relationship"],["To Contents"])
|
1865
2196
|
_ = tempe.SetDictionary(tempd)
|
1866
2197
|
edges.append(tempe)
|
@@ -1885,7 +2216,7 @@ class Graph:
|
|
1885
2216
|
vertices = []
|
1886
2217
|
edges = []
|
1887
2218
|
if useInternalVertex == True:
|
1888
|
-
vCell = Topology.InternalVertex(
|
2219
|
+
vCell = Topology.InternalVertex(topology, tolerance=tolerance)
|
1889
2220
|
else:
|
1890
2221
|
vCell = topology.CenterOfMass()
|
1891
2222
|
d1 = topology.GetDictionary()
|
@@ -1920,7 +2251,7 @@ class Graph:
|
|
1920
2251
|
tempd = Dictionary.ByKeysValues(["relationship"],["To Outposts"])
|
1921
2252
|
_ = tempe.SetDictionary(tempd)
|
1922
2253
|
edges.append(tempe)
|
1923
|
-
if (toExteriorTopologies
|
2254
|
+
if any([toExteriorTopologies, toExteriorApertures, toContents]):
|
1924
2255
|
faces = Topology.Faces(topology)
|
1925
2256
|
exteriorTopologies = []
|
1926
2257
|
exteriorApertures = []
|
@@ -1951,6 +2282,8 @@ class Graph:
|
|
1951
2282
|
contents = []
|
1952
2283
|
_ = exteriorTopology.Contents(contents)
|
1953
2284
|
for content in contents:
|
2285
|
+
if isinstance(content, topologic.Aperture):
|
2286
|
+
content = Aperture.Topology(content)
|
1954
2287
|
if useInternalVertex == True:
|
1955
2288
|
vst2 = Topology.InternalVertex(content, tolerance)
|
1956
2289
|
else:
|
@@ -1992,6 +2325,8 @@ class Graph:
|
|
1992
2325
|
contents = []
|
1993
2326
|
_ = topology.Contents(contents)
|
1994
2327
|
for content in contents:
|
2328
|
+
if isinstance(content, topologic.Aperture):
|
2329
|
+
content = Aperture.Topology(content)
|
1995
2330
|
if useInternalVertex == True:
|
1996
2331
|
vst = Topology.InternalVertex(content, tolerance)
|
1997
2332
|
else:
|
@@ -2094,7 +2429,7 @@ class Graph:
|
|
2094
2429
|
|
2095
2430
|
topFaces = []
|
2096
2431
|
_ = topology.Faces(None, topFaces)
|
2097
|
-
if (viaSharedTopologies
|
2432
|
+
if any([viaSharedTopologies, viaSharedApertures, toExteriorTopologies, toExteriorApertures, toContents == True]):
|
2098
2433
|
for aFace in topFaces:
|
2099
2434
|
if useInternalVertex == True:
|
2100
2435
|
vFace = Topology.InternalVertex(aFace, tolerance=tolerance)
|
@@ -2145,6 +2480,8 @@ class Graph:
|
|
2145
2480
|
contents = []
|
2146
2481
|
_ = sharedTopology.Contents(contents)
|
2147
2482
|
for content in contents:
|
2483
|
+
if isinstance(content, topologic.Aperture):
|
2484
|
+
content = Aperture.Topology(content)
|
2148
2485
|
if useInternalVertex == True:
|
2149
2486
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2150
2487
|
else:
|
@@ -2203,6 +2540,8 @@ class Graph:
|
|
2203
2540
|
contents = []
|
2204
2541
|
_ = exteriorTopology.Contents(contents)
|
2205
2542
|
for content in contents:
|
2543
|
+
if isinstance(content, topologic.Aperture):
|
2544
|
+
content = Aperture.Topology(content)
|
2206
2545
|
if useInternalVertex == True:
|
2207
2546
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2208
2547
|
else:
|
@@ -2244,6 +2583,8 @@ class Graph:
|
|
2244
2583
|
contents = []
|
2245
2584
|
_ = aFace.Contents(contents)
|
2246
2585
|
for content in contents:
|
2586
|
+
if isinstance(content, topologic.Aperture):
|
2587
|
+
content = Aperture.Topology(content)
|
2247
2588
|
if useInternalVertex == True:
|
2248
2589
|
vst = Topology.InternalVertex(content, tolerance)
|
2249
2590
|
else:
|
@@ -2388,6 +2729,8 @@ class Graph:
|
|
2388
2729
|
contents = []
|
2389
2730
|
_ = exteriorTopology.Contents(contents)
|
2390
2731
|
for content in contents:
|
2732
|
+
if isinstance(content, topologic.Aperture):
|
2733
|
+
content = Aperture.Topology(content)
|
2391
2734
|
if useInternalVertex == True:
|
2392
2735
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2393
2736
|
else:
|
@@ -2429,6 +2772,8 @@ class Graph:
|
|
2429
2772
|
contents = []
|
2430
2773
|
_ = topology.Contents(contents)
|
2431
2774
|
for content in contents:
|
2775
|
+
if isinstance(content, topologic.Aperture):
|
2776
|
+
content = Aperture.Topology(content)
|
2432
2777
|
if useInternalVertex == True:
|
2433
2778
|
vst = Topology.InternalVertex(content, tolerance)
|
2434
2779
|
else:
|
@@ -2590,6 +2935,8 @@ class Graph:
|
|
2590
2935
|
contents = []
|
2591
2936
|
_ = sharedTopology.Contents(contents)
|
2592
2937
|
for content in contents:
|
2938
|
+
if isinstance(content, topologic.Aperture):
|
2939
|
+
content = Aperture.Topology(content)
|
2593
2940
|
if useInternalVertex == True:
|
2594
2941
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2595
2942
|
else:
|
@@ -2639,6 +2986,8 @@ class Graph:
|
|
2639
2986
|
contents = []
|
2640
2987
|
_ = vst.Contents(contents)
|
2641
2988
|
for content in contents:
|
2989
|
+
if isinstance(content, topologic.Aperture):
|
2990
|
+
content = Aperture.Topology(content)
|
2642
2991
|
if useInternalVertex == True:
|
2643
2992
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2644
2993
|
else:
|
@@ -2680,6 +3029,8 @@ class Graph:
|
|
2680
3029
|
contents = []
|
2681
3030
|
_ = anEdge.Contents(contents)
|
2682
3031
|
for content in contents:
|
3032
|
+
if isinstance(content, topologic.Aperture):
|
3033
|
+
content = Aperture.Topology(content)
|
2683
3034
|
if useInternalVertex == True:
|
2684
3035
|
vst = Topology.InternalVertex(content, tolerance)
|
2685
3036
|
else:
|
@@ -2830,6 +3181,8 @@ class Graph:
|
|
2830
3181
|
contents = []
|
2831
3182
|
_ = vst.Contents(contents)
|
2832
3183
|
for content in contents:
|
3184
|
+
if isinstance(content, topologic.Aperture):
|
3185
|
+
content = Aperture.Topology(content)
|
2833
3186
|
if useInternalVertex == True:
|
2834
3187
|
vst2 = Topology.InternalVertex(content, tolerance)
|
2835
3188
|
else:
|
@@ -2880,6 +3233,8 @@ class Graph:
|
|
2880
3233
|
contents = []
|
2881
3234
|
_ = topology.Contents(contents)
|
2882
3235
|
for content in contents:
|
3236
|
+
if isinstance(content, topologic.Aperture):
|
3237
|
+
content = Aperture.Topology(content)
|
2883
3238
|
if useInternalVertex == True:
|
2884
3239
|
vst = Topology.InternalVertex(content, tolerance)
|
2885
3240
|
else:
|
@@ -2929,7 +3284,6 @@ class Graph:
|
|
2929
3284
|
if not isinstance(topology, topologic.Topology):
|
2930
3285
|
print("Graph.ByTopology - Error: The input topology is not a valid topology. Returning None.")
|
2931
3286
|
return None
|
2932
|
-
topology = Topology.Copy(topology)
|
2933
3287
|
graph = None
|
2934
3288
|
item = [topology, None, None, None, direct, directApertures, viaSharedTopologies, viaSharedApertures, toExteriorTopologies, toExteriorApertures, toContents, None, useInternalVertex, storeBRep, tolerance]
|
2935
3289
|
vertices = []
|
@@ -3699,6 +4053,159 @@ class Graph:
|
|
3699
4053
|
except:
|
3700
4054
|
return False
|
3701
4055
|
|
4056
|
+
@staticmethod
|
4057
|
+
def ExportToBOT(graph,
|
4058
|
+
path,
|
4059
|
+
format="turtle",
|
4060
|
+
overwrite = False,
|
4061
|
+
bidirectional=False,
|
4062
|
+
includeAttributes=False,
|
4063
|
+
includeLabel=False,
|
4064
|
+
siteLabel = "Site_0001",
|
4065
|
+
siteDictionary = None,
|
4066
|
+
buildingLabel = "Building_0001",
|
4067
|
+
buildingDictionary = None ,
|
4068
|
+
storeyPrefix = "Storey",
|
4069
|
+
floorLevels =[],
|
4070
|
+
labelKey="label",
|
4071
|
+
typeKey="type",
|
4072
|
+
sourceKey="source",
|
4073
|
+
targetKey="target",
|
4074
|
+
spaceType = "space",
|
4075
|
+
wallType = "wall",
|
4076
|
+
slabType = "slab",
|
4077
|
+
doorType = "door",
|
4078
|
+
windowType = "window",
|
4079
|
+
contentType = "content",
|
4080
|
+
):
|
4081
|
+
|
4082
|
+
"""
|
4083
|
+
Returns an RDF graph serialized string according to the BOT ontology. See https://w3c-lbd-cg.github.io/bot/.
|
4084
|
+
|
4085
|
+
Parameters
|
4086
|
+
----------
|
4087
|
+
graph : topologic.Graph
|
4088
|
+
The input graph.
|
4089
|
+
format : str , optional
|
4090
|
+
The desired output format, the options are listed below. Thde default is "turtle".
|
4091
|
+
turtle, ttl or turtle2 : Turtle, turtle2 is just turtle with more spacing & linebreaks
|
4092
|
+
xml or pretty-xml : RDF/XML, Was the default format, rdflib < 6.0.0
|
4093
|
+
json-ld : JSON-LD , There are further options for compact syntax and other JSON-LD variants
|
4094
|
+
ntriples, nt or nt11 : N-Triples , nt11 is exactly like nt, only utf8 encoded
|
4095
|
+
n3 : Notation-3 , N3 is a superset of Turtle that also caters for rules and a few other things
|
4096
|
+
trig : Trig , Turtle-like format for RDF triples + context (RDF quads) and thus multiple graphs
|
4097
|
+
trix : Trix , RDF/XML-like format for RDF quads
|
4098
|
+
nquads : N-Quads , N-Triples-like format for RDF quads
|
4099
|
+
path : str
|
4100
|
+
The desired path to where the RDF/BOT file will be saved.
|
4101
|
+
overwrite : bool , optional
|
4102
|
+
If set to True, any existing file is overwritten. Otherwise, it is not. The default is False.
|
4103
|
+
bidirectional : bool , optional
|
4104
|
+
If set to True, reverse relationships are created wherever possible. Otherwise, they are not. The default is False.
|
4105
|
+
includeAttributes : bool , optional
|
4106
|
+
If set to True, the attributes associated with vertices in the graph are written out. Otherwise, they are not. The default is False.
|
4107
|
+
includeLabel : bool , optional
|
4108
|
+
If set to True, a label is attached to each node. Otherwise, it is not. The default is False.
|
4109
|
+
siteLabel : str , optional
|
4110
|
+
The desired site label. The default is "Site_0001".
|
4111
|
+
siteDictionary : dict , optional
|
4112
|
+
The dictionary of site attributes to include in the output. The default is None.
|
4113
|
+
buildingLabel : str , optional
|
4114
|
+
The desired building label. The default is "Building_0001".
|
4115
|
+
buildingDictionary : dict , optional
|
4116
|
+
The dictionary of building attributes to include in the output. The default is None.
|
4117
|
+
storeyPrefix : str , optional
|
4118
|
+
The desired prefixed to use for each building storey. The default is "Storey".
|
4119
|
+
floorLevels : list , optional
|
4120
|
+
The list of floor levels. This should be a numeric list, sorted from lowest to highest.
|
4121
|
+
If not provided, floorLevels will be computed automatically based on the nodes' 'z' attribute.
|
4122
|
+
typeKey : str , optional
|
4123
|
+
The dictionary key to use to look up the type of the node. The default is "type".
|
4124
|
+
labelKey : str , optional
|
4125
|
+
The dictionary key to use to look up the label of the node. The default is "label".
|
4126
|
+
spaceType : str , optional
|
4127
|
+
The dictionary string value to use to look up nodes of type "space". The default is "space".
|
4128
|
+
wallType : str , optional
|
4129
|
+
The dictionary string value to use to look up nodes of type "wall". The default is "wall".
|
4130
|
+
slabType : str , optional
|
4131
|
+
The dictionary string value to use to look up nodes of type "slab". The default is "slab".
|
4132
|
+
doorType : str , optional
|
4133
|
+
The dictionary string value to use to look up nodes of type "door". The default is "door".
|
4134
|
+
windowType : str , optional
|
4135
|
+
The dictionary string value to use to look up nodes of type "window". The default is "window".
|
4136
|
+
contentType : str , optional
|
4137
|
+
The dictionary string value to use to look up nodes of type "content". The default is "contents".
|
4138
|
+
format : str , optional
|
4139
|
+
The desired output format, the options are listed below. Thde default is "turtle".
|
4140
|
+
turtle, ttl or turtle2 : Turtle, turtle2 is just turtle with more spacing & linebreaks
|
4141
|
+
xml or pretty-xml : RDF/XML, Was the default format, rdflib < 6.0.0
|
4142
|
+
json-ld : JSON-LD , There are further options for compact syntax and other JSON-LD variants
|
4143
|
+
ntriples, nt or nt11 : N-Triples , nt11 is exactly like nt, only utf8 encoded
|
4144
|
+
n3 : Notation-3 , N3 is a superset of Turtle that also caters for rules and a few other things
|
4145
|
+
trig : Trig , Turtle-like format for RDF triples + context (RDF quads) and thus multiple graphs
|
4146
|
+
trix : Trix , RDF/XML-like format for RDF quads
|
4147
|
+
nquads : N-Quads , N-Triples-like format for RDF quads
|
4148
|
+
|
4149
|
+
Returns
|
4150
|
+
-------
|
4151
|
+
str
|
4152
|
+
The rdf graph serialized string using the BOT ontology.
|
4153
|
+
"""
|
4154
|
+
from os.path import exists
|
4155
|
+
bot_graph = Graph.BOTGraph(graph,
|
4156
|
+
bidirectional=bidirectional,
|
4157
|
+
includeAttributes=includeAttributes,
|
4158
|
+
includeLabel=includeLabel,
|
4159
|
+
siteLabel=siteLabel,
|
4160
|
+
siteDictionary=siteDictionary,
|
4161
|
+
buildingLabel=buildingLabel,
|
4162
|
+
buildingDictionary=buildingDictionary,
|
4163
|
+
storeyPrefix=storeyPrefix,
|
4164
|
+
floorLevels=floorLevels,
|
4165
|
+
labelKey=labelKey,
|
4166
|
+
typeKey=typeKey,
|
4167
|
+
spaceType = spaceType,
|
4168
|
+
wallType = wallType,
|
4169
|
+
slabType = slabType,
|
4170
|
+
doorType = doorType,
|
4171
|
+
windowType = windowType,
|
4172
|
+
contentType = contentType
|
4173
|
+
)
|
4174
|
+
if "turtle" in format.lower() or "ttl" in format.lower() or "turtle2" in format.lower():
|
4175
|
+
ext = ".ttl"
|
4176
|
+
elif "xml" in format.lower() or "pretty=xml" in format.lower() or "rdf/xml" in format.lower():
|
4177
|
+
ext = ".xml"
|
4178
|
+
elif "json" in format.lower():
|
4179
|
+
ext = ".json"
|
4180
|
+
elif "ntriples" in format.lower() or "nt" in format.lower() or "nt11" in format.lower():
|
4181
|
+
ext = ".nt"
|
4182
|
+
elif "n3" in format.lower() or "notation" in format.lower():
|
4183
|
+
ext = ".n3"
|
4184
|
+
elif "trig" in format.lower():
|
4185
|
+
ext = ".trig"
|
4186
|
+
elif "trix" in format.lower():
|
4187
|
+
ext = ".trix"
|
4188
|
+
elif "nquads" in format.lower():
|
4189
|
+
ext = ".nquads"
|
4190
|
+
else:
|
4191
|
+
format = "turtle"
|
4192
|
+
ext = ".ttl"
|
4193
|
+
n = len(ext)
|
4194
|
+
# Make sure the file extension is .brep
|
4195
|
+
ext = path[len(path)-n:len(path)]
|
4196
|
+
if ext.lower() != ext:
|
4197
|
+
path = path+ext
|
4198
|
+
if not overwrite and exists(path):
|
4199
|
+
print("Graph.ExportToBOT - Error: a file already exists at the specified path and overwrite is set to False. Returning None.")
|
4200
|
+
return None
|
4201
|
+
status = False
|
4202
|
+
try:
|
4203
|
+
bot_graph.serialize(destination=path, format=format)
|
4204
|
+
status = True
|
4205
|
+
except:
|
4206
|
+
status = False
|
4207
|
+
return status
|
4208
|
+
|
3702
4209
|
@staticmethod
|
3703
4210
|
def ExportToCSV(graph, path, graphLabel, graphFeatures="",
|
3704
4211
|
graphIDHeader="graph_id", graphLabelHeader="label", graphFeaturesHeader="feat",
|
@@ -4409,7 +4916,7 @@ class Graph:
|
|
4409
4916
|
return True
|
4410
4917
|
|
4411
4918
|
@staticmethod
|
4412
|
-
def ExportToJSON(graph, path, vertexLabelKey="", edgeLabelKey="", indent=4, sortKeys=False, mantissa=6, overwrite=False):
|
4919
|
+
def ExportToJSON(graph, path, verticesKey="vertices", edgesKey="edges", vertexLabelKey="", edgeLabelKey="", xKey="x", yKey="y", zKey="z", indent=4, sortKeys=False, mantissa=6, overwrite=False):
|
4413
4920
|
"""
|
4414
4921
|
Exports the input graph to a JSON file.
|
4415
4922
|
|
@@ -4419,12 +4926,22 @@ class Graph:
|
|
4419
4926
|
The input graph.
|
4420
4927
|
path : str
|
4421
4928
|
The path to the JSON file.
|
4929
|
+
verticesKey : str , optional
|
4930
|
+
The desired key name to call vertices. The default is "vertices".
|
4931
|
+
edgesKey : str , optional
|
4932
|
+
The desired key name to call edges. The default is "edges".
|
4422
4933
|
vertexLabelKey : str , optional
|
4423
4934
|
If set to a valid string, the vertex label will be set to the value at this key. Otherwise it will be set to Vertex_XXXX where XXXX is a sequential unique number.
|
4424
4935
|
Note: If vertex labels are not unique, they will be forced to be unique.
|
4425
4936
|
edgeLabelKey : str , optional
|
4426
4937
|
If set to a valid string, the edge label will be set to the value at this key. Otherwise it will be set to Edge_XXXX where XXXX is a sequential unique number.
|
4427
4938
|
Note: If edge labels are not unique, they will be forced to be unique.
|
4939
|
+
xKey : str , optional
|
4940
|
+
The desired key name to use for x-coordinates. The default is "x".
|
4941
|
+
yKey : str , optional
|
4942
|
+
The desired key name to use for y-coordinates. The default is "y".
|
4943
|
+
zKey : str , optional
|
4944
|
+
The desired key name to use for z-coordinates. The default is "z".
|
4428
4945
|
indent : int , optional
|
4429
4946
|
The desired amount of indent spaces to use. The default is 4.
|
4430
4947
|
sortKeys : bool , optional
|
@@ -4458,7 +4975,7 @@ class Graph:
|
|
4458
4975
|
except:
|
4459
4976
|
raise Exception("Graph.ExportToJSON - Error: Could not create a new file at the following location: "+path)
|
4460
4977
|
if (f):
|
4461
|
-
jsondata = Graph.JSONData(graph, vertexLabelKey=vertexLabelKey, edgeLabelKey=edgeLabelKey, mantissa=mantissa)
|
4978
|
+
jsondata = Graph.JSONData(graph, verticesKey=verticesKey, edgesKey=edgesKey, vertexLabelKey=vertexLabelKey, edgeLabelKey=edgeLabelKey, xKey=xKey, yKey=yKey, zKey=zKey, mantissa=mantissa)
|
4462
4979
|
if jsondata != None:
|
4463
4980
|
json.dump(jsondata, f, indent=indent, sort_keys=sortKeys)
|
4464
4981
|
f.close()
|
@@ -5113,7 +5630,17 @@ class Graph:
|
|
5113
5630
|
return vertices
|
5114
5631
|
|
5115
5632
|
@staticmethod
|
5116
|
-
def JSONData(graph,
|
5633
|
+
def JSONData(graph,
|
5634
|
+
verticesKey="vertices",
|
5635
|
+
edgesKey="edges",
|
5636
|
+
vertexLabelKey="",
|
5637
|
+
edgeLabelKey="",
|
5638
|
+
sourceKey="source",
|
5639
|
+
targetKey="target",
|
5640
|
+
xKey="x",
|
5641
|
+
yKey="y",
|
5642
|
+
zKey="z",
|
5643
|
+
mantissa=6):
|
5117
5644
|
"""
|
5118
5645
|
Converts the input graph into JSON data.
|
5119
5646
|
|
@@ -5121,12 +5648,26 @@ class Graph:
|
|
5121
5648
|
----------
|
5122
5649
|
graph : topologic.Graph
|
5123
5650
|
The input graph.
|
5651
|
+
verticesKey : str , optional
|
5652
|
+
The desired key name to call vertices. The default is "vertices".
|
5653
|
+
edgesKey : str , optional
|
5654
|
+
The desired key name to call edges. The default is "edges".
|
5124
5655
|
vertexLabelKey : str , optional
|
5125
5656
|
If set to a valid string, the vertex label will be set to the value at this key. Otherwise it will be set to Vertex_XXXX where XXXX is a sequential unique number.
|
5126
5657
|
Note: If vertex labels are not unique, they will be forced to be unique.
|
5127
5658
|
edgeLabelKey : str , optional
|
5128
5659
|
If set to a valid string, the edge label will be set to the value at this key. Otherwise it will be set to Edge_XXXX where XXXX is a sequential unique number.
|
5129
5660
|
Note: If edge labels are not unique, they will be forced to be unique.
|
5661
|
+
sourceKey : str , optional
|
5662
|
+
The dictionary key used to store the source vertex. The default is "source".
|
5663
|
+
targetKey : str , optional
|
5664
|
+
The dictionary key used to store the target vertex. The default is "source".
|
5665
|
+
xKey : str , optional
|
5666
|
+
The desired key name to use for x-coordinates. The default is "x".
|
5667
|
+
yKey : str , optional
|
5668
|
+
The desired key name to use for y-coordinates. The default is "y".
|
5669
|
+
zKey : str , optional
|
5670
|
+
The desired key name to use for z-coordinates. The default is "z".
|
5130
5671
|
mantissa : int , optional
|
5131
5672
|
The desired length of the mantissa. The default is 6.
|
5132
5673
|
|
@@ -5144,16 +5685,16 @@ class Graph:
|
|
5144
5685
|
|
5145
5686
|
vertices = Graph.Vertices(graph)
|
5146
5687
|
j_data = {}
|
5147
|
-
j_data[
|
5148
|
-
j_data[
|
5688
|
+
j_data[verticesKey] = {}
|
5689
|
+
j_data[edgesKey] = {}
|
5149
5690
|
n = max(len(str(len(vertices))), 4)
|
5150
5691
|
v_labels = []
|
5151
5692
|
v_dicts = []
|
5152
5693
|
for i, v in enumerate(vertices):
|
5153
5694
|
d = Topology.Dictionary(v)
|
5154
|
-
d = Dictionary.SetValueAtKey(d,
|
5155
|
-
d = Dictionary.SetValueAtKey(d,
|
5156
|
-
d = Dictionary.SetValueAtKey(d,
|
5695
|
+
d = Dictionary.SetValueAtKey(d, xKey, Vertex.X(v, mantissa=mantissa))
|
5696
|
+
d = Dictionary.SetValueAtKey(d, yKey, Vertex.Y(v, mantissa=mantissa))
|
5697
|
+
d = Dictionary.SetValueAtKey(d, zKey, Vertex.Z(v, mantissa=mantissa))
|
5157
5698
|
v_dict = Dictionary.PythonDictionary(d)
|
5158
5699
|
v_label = Dictionary.ValueAtKey(d, vertexLabelKey)
|
5159
5700
|
if isinstance(v_label, str):
|
@@ -5164,7 +5705,7 @@ class Graph:
|
|
5164
5705
|
v_dicts.append(v_dict)
|
5165
5706
|
v_labels = Helper.MakeUnique(v_labels)
|
5166
5707
|
for i, v_label in enumerate(v_labels):
|
5167
|
-
j_data[
|
5708
|
+
j_data[verticesKey][v_label] = v_dicts[i]
|
5168
5709
|
|
5169
5710
|
edges = Graph.Edges(graph)
|
5170
5711
|
n = len(str(len(edges)))
|
@@ -5179,8 +5720,8 @@ class Graph:
|
|
5179
5720
|
ev_label = v_labels[evi]
|
5180
5721
|
d = Topology.Dictionary(e)
|
5181
5722
|
|
5182
|
-
d = Dictionary.SetValueAtKey(d,
|
5183
|
-
d = Dictionary.SetValueAtKey(d,
|
5723
|
+
d = Dictionary.SetValueAtKey(d, sourceKey, sv_label)
|
5724
|
+
d = Dictionary.SetValueAtKey(d, targetKey, ev_label)
|
5184
5725
|
e_dict = Dictionary.PythonDictionary(d)
|
5185
5726
|
e_label = Dictionary.ValueAtKey(d, edgeLabelKey)
|
5186
5727
|
if isinstance(e_label, str):
|
@@ -5191,12 +5732,22 @@ class Graph:
|
|
5191
5732
|
e_dicts.append(e_dict)
|
5192
5733
|
e_labels = Helper.MakeUnique(e_labels)
|
5193
5734
|
for i, e_label in enumerate(e_labels):
|
5194
|
-
j_data[
|
5735
|
+
j_data[edgesKey][e_label] = e_dicts[i]
|
5195
5736
|
|
5196
5737
|
return j_data
|
5197
5738
|
|
5198
5739
|
@staticmethod
|
5199
|
-
def JSONString(graph,
|
5740
|
+
def JSONString(graph,
|
5741
|
+
verticesKey="vertices",
|
5742
|
+
edgesKey="edges",
|
5743
|
+
vertexLabelKey="",
|
5744
|
+
edgeLabelKey="",
|
5745
|
+
xKey = "x",
|
5746
|
+
yKey = "y",
|
5747
|
+
zKey = "z",
|
5748
|
+
indent=4,
|
5749
|
+
sortKeys=False,
|
5750
|
+
mantissa=6):
|
5200
5751
|
"""
|
5201
5752
|
Converts the input graph into JSON data.
|
5202
5753
|
|
@@ -5204,12 +5755,22 @@ class Graph:
|
|
5204
5755
|
----------
|
5205
5756
|
graph : topologic.Graph
|
5206
5757
|
The input graph.
|
5758
|
+
verticesKey : str , optional
|
5759
|
+
The desired key name to call vertices. The default is "vertices".
|
5760
|
+
edgesKey : str , optional
|
5761
|
+
The desired key name to call edges. The default is "edges".
|
5207
5762
|
vertexLabelKey : str , optional
|
5208
5763
|
If set to a valid string, the vertex label will be set to the value at this key. Otherwise it will be set to Vertex_XXXX where XXXX is a sequential unique number.
|
5209
5764
|
Note: If vertex labels are not unique, they will be forced to be unique.
|
5210
5765
|
edgeLabelKey : str , optional
|
5211
5766
|
If set to a valid string, the edge label will be set to the value at this key. Otherwise it will be set to Edge_XXXX where XXXX is a sequential unique number.
|
5212
5767
|
Note: If edge labels are not unique, they will be forced to be unique.
|
5768
|
+
xKey : str , optional
|
5769
|
+
The desired key name to use for x-coordinates. The default is "x".
|
5770
|
+
yKey : str , optional
|
5771
|
+
The desired key name to use for y-coordinates. The default is "y".
|
5772
|
+
zKey : str , optional
|
5773
|
+
The desired key name to use for z-coordinates. The default is "z".
|
5213
5774
|
indent : int , optional
|
5214
5775
|
The desired amount of indent spaces to use. The default is 4.
|
5215
5776
|
sortKeys : bool , optional
|
@@ -5224,7 +5785,7 @@ class Graph:
|
|
5224
5785
|
|
5225
5786
|
"""
|
5226
5787
|
import json
|
5227
|
-
json_data = Graph.JSONData(graph, vertexLabelKey=vertexLabelKey, edgeLabelKey=edgeLabelKey, mantissa=mantissa)
|
5788
|
+
json_data = Graph.JSONData(graph, verticesKey=verticesKey, edgesKey=edgesKey, vertexLabelKey=vertexLabelKey, edgeLabelKey=edgeLabelKey, xKey=xKey, yKey=yKey, zKey=zKey, mantissa=mantissa)
|
5228
5789
|
json_string = json.dumps(json_data, indent=indent, sort_keys=sortKeys)
|
5229
5790
|
return json_string
|
5230
5791
|
|