By Mads Holten Rasmussen
v1
This advanced topic tutorial is part of a series in the Linked Building Data (LBD) School 🏫
The slides are quite detailed and text-heavy as they are supposed to be read rather than presented.
As I have been using the technologies for a while there might be topics that I take for granted and therefore skip over too fast. Please let me know if this is the case! 🙏
Also, since this is something I do in my freetime, please support me by buying me a coffee 🤗☕💙
All the following examples express the exact same thing: The fact that resource https://ex.com/a is a bot:Building.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ]
}
]
{
"@context": {
"inst": "https://ex.com/",
"bot": "https://w3id.org/bot#"
},
"@id": "inst:a",
"@type": [ "bot:Building" ]
}
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#"
},
"@id": "a",
"@type": "bot:Building"
}
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#"
},
"@graph": [{
"@id": "a",
"@type": "bot:Building"
}]
}
These examples show an expanded version and various compacted versions of the exact same fact and by the end of this lecture, you will understand why.
The below example is the expanded version of the fact.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ]
}
]
This is the simplest form of JSON-LD and it will always look the same.
Let's extend it with a datatype property.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "My Building"
}]
}
]
We see that leteral values are expressed with a @value.
The value is implicitly specified as a string, so the below means the same thing.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "My Building",
"@type": "http://www.w3.org/2001/XMLSchema#string"
}]
}
]
We can also use the special @language property to specify a language.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "My Building",
"@language": "en"
}]
}
]
Or specify more languages, just as in other RDF serializations.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"http://www.w3.org/2000/01/rdf-schema#label": [
{
"@value": "My Building",
"@language": "en"
},
{
"@value": "Min Bygning",
"@language": "da"
}
]
}
]
We can also extend it with an object property instead by using the @id property and thereby indicate that it is a reference to a URI.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"https://w3id.org/bot#hasStorey": [{
"@id": "https://ex.com/b"
}]
}
]
We might even describe this other resource in the same document.
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"https://w3id.org/bot#hasStorey": [{
"@id": "https://ex.com/b"
}]
},
{
"@id": "https://ex.com/b",
"@type": [ "https://w3id.org/bot#Storey" ]
}
]
Let's continue with the below expanded example and make it more compact and simple to read. We use the below example for this:
[
{
"@id": "https://ex.com/a",
"@type": [ "https://w3id.org/bot#Building" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "My Building"
}],
"https://example.com#numberOfStoreys": [{
"@value": "2",
"@type": "http://www.w3.org/2001/XMLSchema#integer"
}],
"https://w3id.org/bot#hasStorey": [
{
"@id": "https://ex.com/b"
},
{
"@id": "https://ex.com/c"
}
]
},
{
"@id": "https://ex.com/b",
"@type": [ "https://w3id.org/bot#Storey" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "Level 1"
}]
},
{
"@id": "https://ex.com/c",
"@type": [ "https://w3id.org/bot#Storey" ],
"http://www.w3.org/2000/01/rdf-schema#label": [{
"@value": "Level 2"
}]
}
]
We can compact the JSON-LD by specifying a @context for it. So first we specify a @base URI for the namespace in which the instances belong.
{
"@context": {
"@base": "https://ex.com/"
}
}
You can see the results in this JSON-LD playground example
This will simplify all resource @ids so "https://ex.com/a" becomes "a"
Next, we specify the prefixes we are using (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#"
}
}
You can probably imagine how this shortens all the URIs like in Turtle syntax.
We can even use the context to specify our own keys that will be used in the JSON. For example, we can use "name" instead of "rdfs:label" (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
}
}
}
You can probably imagine how this shortens all the URIs like in Turtle syntax.
We can also specify datatypes in the @context so they don't need to be part of the dataset (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
}
}
}
The result is that ex:numberOfStoreys is also just returned as a single string value.
The result is that our JSON body is now way cleaner since the @context specifies all the metadata:
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
}
},
"@graph": [
{
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{ "@id": "b" },
{ "@id": "c" }
]
},
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1"
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2"
}
]
}
Note the @graph array here which is used when there are multiple resources in the dataset. Also, you can see that property values are no longer returned as arrays if there is only one value.
Sometimes you deal with properties where there can potentially be more values, and then you would like to force it to be returned as an array. If not, you will have situations where it is a string and other where it is a list, which is hard to deal with in implementations.
Let's say we might have more names for a resource. We can specify this using @container = @set
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label",
"@container": "@set"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
}
},
"@graph": [
{
"@id": "a",
"@type": "bot:Building",
"name": ["My Building"],
"storeyCount": "2",
"bot:hasStorey": [
{ "@id": "b" },
{ "@id": "c" }
]
},
{
"@id": "b",
"@type": "bot:Storey",
"name": ["Level 1"]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": ["Level 2"]
}
]
}
A flat graph structure like the one from the previous example is super flexible from a data management perspective. However, for application purpuses, it is useful to use a tree representation. With Framing you can do exactly that!
Let's continue with the dataset from before and add framing instructions (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
}
},
"@type": "bot:Building",
"bot:hasStorey": {}
}
This specifies that the root of the tree is a bot:Building with the relationship bot:hasStorey to something else.
The result is a tree structure starting with the building and then having the storeys as children of that building.
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label",
"@container": "@set"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
}
},
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1"
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2"
}
]
}
Of course, this gets more interesting with deeper structures, so let's extend the example with a site and 6 spaces.
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@graph": [
{
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": [
{ "@id": "a" }
]
},
{
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{ "@id": "b" },
{ "@id": "c" }
]
},
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{ "@id": "b1" },
{ "@id": "b2" },
{ "@id": "b3" }
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": [
{ "@id": "c1" },
{ "@id": "c2" },
{ "@id": "c3" }
]
},
{
"@id": "b1",
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2"
},
{
"@id": "b2",
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3"
},
{
"@id": "b3",
"@type": "bot:Space",
"name": "Space 1.3",
"area": "5.6"
},
{
"@id": "c1",
"@type": "bot:Space",
"name": "Space 2.1",
"area": "20.2"
},
{
"@id": "c2",
"@type": "bot:Space",
"name": "Space 2.2",
"area": "11.3"
},
{
"@id": "c3",
"@type": "bot:Space",
"name": "Space 2.3",
"area": "5.6"
}
]
}
All we need to do is extend the frame a bit to include the new relationships (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@type": "bot:Site",
"bot:hasBuilding": {
"bot:hasStorey": {
"bot:hasSpace": {}
}
}
}
The result is a tree structure starting with the site, then the building, its storeys and lastly the spaces of these storeys.
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": {
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{
"@id": "b1",
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2"
},
{
"@id": "b2",
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3"
},
{
"@id": "b3",
"@type": "bot:Space",
"name": "Space 1.3",
"area": "5.6"
}
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": [
{
"@id": "c1",
"@type": "bot:Space",
"name": "Space 2.1",
"area": "20.2"
},
{
"@id": "c2",
"@type": "bot:Space",
"name": "Space 2.2",
"area": "11.3"
},
{
"@id": "c3",
"@type": "bot:Space",
"name": "Space 2.3",
"area": "5.6"
}
]
}
]
}
}
But one problem occurs when more resources are referring to the same resource. Let's for example extend our example by specifying that Space 1.1 and Space 1.2 are both adjacent to the same Wall
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@graph": [
{
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": [
{ "@id": "a" }
]
},
{
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{ "@id": "b" },
{ "@id": "c" }
]
},
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{ "@id": "b1" },
{ "@id": "b2" },
{ "@id": "b3" }
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": [
{ "@id": "c1" },
{ "@id": "c2" },
{ "@id": "c3" }
]
},
{
"@id": "b1",
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2",
"bot:adjacentElement": [
{ "@id": "d" }
]
},
{
"@id": "b2",
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3",
"bot:adjacentElement": [
{ "@id": "d" }
]
},
{
"@id": "b3",
"@type": "bot:Space",
"name": "Space 1.3",
"area": "5.6"
},
{
"@id": "c1",
"@type": "bot:Space",
"name": "Space 2.1",
"area": "20.2"
},
{
"@id": "c2",
"@type": "bot:Space",
"name": "Space 2.2",
"area": "11.3"
},
{
"@id": "c3",
"@type": "bot:Space",
"name": "Space 2.3",
"area": "5.6"
},
{
"@id": "d",
"@type": ["bot:Element", "ifc:IfcWall"],
"name": "Wall 222"
}
]
}
We extend the frame to include this new relationship (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@type": "bot:Site",
"bot:hasBuilding": {
"bot:hasStorey": {
"bot:hasSpace": {
"bot:adjacentElement": {}
}
}
}
}
But the result is that the wall is only embedded first time. Next time it is simply referred to by its @id
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": {
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{
"@id" : "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{
"@id": "b1",
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2",
"bot:adjacentElement": {
"@id": "d",
"@type": [
"bot:Element",
"ifc:IfcWall"
],
"name": "Wall 222"
}
},
{
"@id": "b2",
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3",
"bot:adjacentElement": {
"@id": "d"
}
}
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": null
}
]
}
}
What's even worse is that all spaces that don't have a bot:adjacentElement are left out.
So let's fix this by first specifying another property that exists on spaces (since some won't have binidngs to bot:adjacentElement). For example @type = bot:Space.
Further, we add the @embed = @always instruction to specify that the full object reference should be included every time (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@type": "bot:Site",
"bot:hasBuilding": {
"bot:hasStorey": {
"bot:hasSpace": {
"@type": "bot:Space",
"bot:adjacentElement": {
"@embed": "@always"
}
}
}
}
}
Now we have the tree structure that we wanted!
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
}
},
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": {
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{
"@id": "b1",
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2",
"bot:adjacentElement": {
"@id": "d",
"@type": [
"bot:Element",
"ifc:IfcWall"
],
"name": "Wall 222"
}
},
{
"@id": "b2",
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3",
"bot:adjacentElement": {
"@id": "d",
"@type": [
"bot:Element",
"ifc:IfcWall"
],
"name": "Wall 222"
}
},
{
"@id": "b3",
"@type": "bot:Space",
"name": "Space 1.3",
"area": "5.6",
"bot:adjacentElement": null
}
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": [
{
"@id": "c1",
"@type": "bot:Space",
"name": "Space 2.1",
"area": "20.2",
"bot:adjacentElement": null
},
{
"@id": "c2",
"@type": "bot:Space",
"name": "Space 2.2",
"area": "11.3",
"bot:adjacentElement": null
},
{
"@id": "c3",
"@type": "bot:Space",
"name": "Space 2.3",
"area": "5.6",
"bot:adjacentElement": null
}
]
}
]
}
}
Now spaces that don't have adjacent elements simply have a null reference for that property.
One last thing we can do with framing is that we can express @reverse relationships. BOT only describes the bot:hasSpace relationship from a storey to a space, but what if we wanted to have a relationship from the space to the storey? We can do that! (see results).
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
},
"ex:spaceOfStorey": {
"@reverse": "bot:hasSpace"
}
},
"@type": "bot:Site",
"bot:hasBuilding": {
"bot:hasStorey": {
"bot:hasSpace": {
"@type": "bot:Space",
"ex:spaceOfStorey": {
"@embed": "@always"
},
"bot:adjacentElement": {
"@embed": "@always"
}
}
}
}
}
Final result
{
"@context": {
"@base": "https://ex.com/",
"bot": "https://w3id.org/bot#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"ex": "https://example.com#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ifc": "http://ifcowl.openbimstandards.org/IFC2X3_Final#",
"name": {
"@id": "rdfs:label"
},
"storeyCount": {
"@id": "ex:numberOfStoreys",
"@type": "xsd:integer"
},
"area": {
"@id": "ex:area",
"@type": "xsd:decimal"
},
"ex:spaceOfStorey": {
"@reverse": "bot:hasSpace"
}
},
"@id": "s",
"@type": "bot:Site",
"name": "Our campus",
"bot:hasBuilding": {
"@id": "a",
"@type": "bot:Building",
"name": "My Building",
"storeyCount": "2",
"bot:hasStorey": [
{
"@id": "b",
"@type": "bot:Storey",
"name": "Level 1",
"bot:hasSpace": [
{
"@id": "b1",
"ex:spaceOfStorey": { "@id": "b" },
"@type": "bot:Space",
"name": "Space 1.1",
"area": "20.2",
"bot:adjacentElement": {
"@id": "d",
"@type": [
"bot:Element",
"ifc:IfcWall"
],
"name": "Wall 222"
}
},
{
"@id": "b2",
"ex:spaceOfStorey": { "@id": "b" },
"@type": "bot:Space",
"name": "Space 1.2",
"area": "11.3",
"bot:adjacentElement": {
"@id": "d",
"@type": [
"bot:Element",
"ifc:IfcWall"
],
"name": "Wall 222"
}
},
{
"@id": "b3",
"ex:spaceOfStorey": { "@id": "b" },
"@type": "bot:Space",
"name": "Space 1.3",
"area": "5.6",
"bot:adjacentElement": null
}
]
},
{
"@id": "c",
"@type": "bot:Storey",
"name": "Level 2",
"bot:hasSpace": [
{
"@id": "c1",
"ex:spaceOfStorey": { "@id": "c" },
"@type": "bot:Space",
"name": "Space 2.1",
"area": "20.2",
"bot:adjacentElement": null
},
{
"@id": "c2",
"ex:spaceOfStorey": { "@id": "c" },
"@type": "bot:Space",
"name": "Space 2.2",
"area": "11.3",
"bot:adjacentElement": null
},
{
"@id": "c3",
"ex:spaceOfStorey": { "@id": "c" },
"@type": "bot:Space",
"name": "Space 2.3",
"area": "5.6",
"bot:adjacentElement": null
}
]
}
]
}
}
At the LBD School overview you can find more lectures