Within this short tutorial you will extract knowledge of a real building and use this to populate your knowledge base with assertional knowledge (ABox).
For this purpose we will use the Duplex Apartment a building, which is frequently referred to in Building Information Modelling (BIM) research. Information on the topology of the building is provided as a spreadsheet, which is compliant to the Construction Operations Building Information Exchange - (COBie) standard. We will extract topological information from this file and to populate a knowledge base with instances of the BOT ontology.
The file is stored in the data folder and named 2012-03-23-Duplex-Handover.xlsx. We will load it using the python module xrld
and have a look at the buildings stored within:
import xlrd
import os
Ensure that you use the correct path to access the file on your system!
currentPath = os.getcwd()
pathFolderData = os.path.abspath( os.path.join( currentPath , os.pardir ) )
pathToFile = os.path.join( pathFolderData , "data" , "2012-03-23-Duplex-Handover.xlsx" )
print( "You specify the path to the file as: " , pathToFile )
You specify the path to the file as: /home/jovyan/data/2012-03-23-Duplex-Handover.xlsx
wb = xlrd.open_workbook( pathToFile )
print( "This are the sheets in you file: " )
print( wb.sheet_names() )
This are the sheets in you file: ['Instruction', 'Contact', 'Facility', 'Floor', 'Space', 'Zone', 'Type', 'Component', 'System', 'Assembly', 'Spare', 'Resource', 'Job', 'Impact', 'Document', 'Attribute', 'Coordinate', 'Connection', 'Issue', 'PickLists']
We will now setup again rdflib so we can extract buildings, sites and space from the COBie spreadsheet and use this input to create instances (assertional knowledge - ABox) of BOT.
# Import needed components from rdflib
from rdflib import Graph , Literal , BNode , Namespace , RDF , RDFS , OWL , URIRef
# initiate triple store, i.e. Graph()
g = Graph()
# Add namespaces
g.bind( "owl" , OWL )
BOT = Namespace( "https://w3id.org/bot#" )
g.bind( "bot" , BOT )
NS = Namespace( "https://example.org/DuplexApartmentAbox#" )
g.bind( "" , NS )
# Initiate ontology entity
s = URIRef( "https://example.org/DuplexApartmentAbox" )
p = RDF.type
o = OWL.ontology
g.add( ( s , p , o ) )
We now navigate to the Facility sheet to extract our first entities: the site and building and map it to bot:Site
and bot:Building
:
sh_facility = wb.sheet_by_name( "Facility" )
# Add site
print( "Site IFC ID: " , str( sh_facility.cell_value( 1 , 15 ) ) )
siteID = str( sh_facility.cell_value( 1 , 15 ) )
s = NS[ siteID ]
p = RDF.type
o = BOT[ "Site" ]
g.add( ( s , p , o ) )
# Add building
print( "Building IFC ID: " , str( sh_facility.cell_value( 1 , 17 ) ) )
buiID = str( sh_facility.cell_value( 1 , 17 ) )
s = NS[ buiID ]
p = RDF.type
o = BOT[ "Building" ]
g.add( ( s , p , o ) )
# Add human readable lable
p = RDFS.label
o = Literal( str( sh_facility.cell_value( 1 , 0 ) ) )
g.add( ( s , p , o ) )
Site IFC ID: 1xS3BCk291UvhgP2a6eflN Building IFC ID: 1xS3BCk291UvhgP2a6eflK
We can now also add the fact that the building is located at the site:
s = NS[ siteID ]
p = BOT[ "hasBuilding" ]
o = NS[ buiID ]
g.add( ( s , p , o ) )
Now we can add building storeys:
# Navigate to building storeys sheet
sh_BuiStor = wb.sheet_by_name( "Floor" )
for i in range( 1 , sh_BuiStor.nrows , 1 ):
print( "BuildingStorey IFC ID: " , str( sh_BuiStor.cell_value( i , 6 ) ) )
# create instance
BuiStorID = str( sh_BuiStor.cell_value( i , 6 ) )
s = NS[ BuiStorID ]
p = RDF.type
o = BOT[ "Storey" ]
g.add( ( s , p , o ) )
# Link to building
s = NS[ buiID ]
p = BOT[ "hasStorey" ]
o = NS[ BuiStorID ]
g.add( ( s , p , o ) )
BuildingStorey IFC ID: 1xS3BCk291UvhgP2dvNMKI BuildingStorey IFC ID: 1xS3BCk291UvhgP2dvNMQJ BuildingStorey IFC ID: 1xS3BCk291UvhgP2dvNtSE BuildingStorey IFC ID: 1xS3BCk291UvhgP2dvNsgp
Finally we can extract the spaces:
# Navigate to building spaces sheet
sh_Space = wb.sheet_by_name( "Space" )
for i in range( 1 , sh_Space.nrows , 1 ):
# Security hack
if str( sh_Space.cell_value( i , 8 ) ) == "n/a":
break
print( "Space IFC ID: " , str( sh_Space.cell_value( i , 8 ) ) )
print( "Space name: " , str( sh_Space.cell_value( i , 0 ) ) )
# create instance
SpaceID = str( sh_Space.cell_value( i , 8 ) )
s = NS[ SpaceID ]
p = RDF.type
o = BOT[ "Space" ]
g.add( ( s , p , o ) )
# Add human readable label
p = RDFS.label
o = Literal( str( sh_Space.cell_value( i , 0 ) ) )
g.add( ( s , p , o ) )
# Link to building
s = NS[ buiID ]
p = BOT[ "hasSpace" ]
o = NS[ SpaceID ]
g.add( ( s , p , o ) )
Space IFC ID: 0BTBFw6f90Nfh9rP1dlXru Space name: A104 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3P Space name: B104 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXrr Space name: A101 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3Q Space name: B101 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXr$ Space name: A103 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3S Space name: B103 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXr2 Space name: A102 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_CZ Space name: B102 Space IFC ID: 10mjSDZJj9gPS2PrQaxa3z Space name: A105 Space IFC ID: 10mjSDZJj9gPS2PrQaxa4o Space name: B105 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXre Space name: A204 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3C Space name: B204 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXrc Space name: A202 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3A Space name: B202 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXrb Space name: A203 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_39 Space name: B203 Space IFC ID: 0BTBFw6f90Nfh9rP1dlXri Space name: A201 Space IFC ID: 0BTBFw6f90Nfh9rP1dl_3G Space name: B201 Space IFC ID: 2gRXFgjRn2HPE$YoDLX3FC Space name: B205 Space IFC ID: 2gRXFgjRn2HPE$YoDLX3FV Space name: A205 Space IFC ID: 0pNy6pOyf7JPmXRLgxs3sW Space name: R301
We store the result in a file and examine
g.serialize( destination = "Abox.ttl" , format = "turtle" )
print( "Created Abox.ttl in folder:" )
print( str( os.getcwd() ) )
Created Abox.ttl in folder: /home/jovyan/Notebooks
Or we query our in memory triple store for all instances of type bot:space
:
query = """
PREFIX bot: <https://w3id.org/bot#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?space ?name
WHERE {
?space rdf:type bot:Space .
?space rdfs:label ?name .
}"""
res = g.query( query )
for row in res:
print( "Found space with name: " , row[1] )
Found space with name: B104 Found space with name: A205 Found space with name: B103 Found space with name: A202 Found space with name: R301 Found space with name: A103 Found space with name: B102 Found space with name: A203 Found space with name: B201 Found space with name: B203 Found space with name: B105 Found space with name: A102 Found space with name: A104 Found space with name: B101 Found space with name: A105 Found space with name: A201 Found space with name: A204 Found space with name: B204 Found space with name: B205 Found space with name: A101 Found space with name: B202