Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/github-actions-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,15 @@ jobs:
run: |
python check-duplicates.py --input ../BDNS_Abbreviations_Register.csv
working-directory: ./tools/

- name: Check sorted
run: |
python tools/sort.py

- name: validate ifc4_3 mappings
run: |
python tools/validate_ifc4_3.py

- name: validate unique ifc4_3 mappings
run: |
python tools/validate_unique_default_mappings.py
100 changes: 100 additions & 0 deletions BDNS_Abbreviations_Core.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
execute:
echo: false
tbl-cap-location: bottom
format:
html:
page-layout: custom
toc: false
jupyter:
jupytext:
text_representation:
extension: .qmd
format_name: quarto
format_version: '1.0'
jupytext_version: 1.16.1
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
---

# Building Device and Asset Naming Standards initiative

{{< include release.md >}}

```{python}
import pandas as pd
import re
from itables import init_notebook_mode, show
import re

import bsdd
from IPython.display import Markdown

IFC4X3_URI = "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3"


def ifc_strip_enum(ifc_class: str) -> str:
return re.sub(r"([A-Z0-9_]+_?)$", "", ifc_class)


def ifc_class_is_enum(ifc_class: str) -> bool:
return ifc_strip_enum(ifc_class) != ifc_class


def get_ifc_classes(client=None):
if client is None:
client = bsdd.Client()

def get_batch(i):
return client.get_classes(
IFC4X3_URI,
use_nested_classes=False,
class_type="Class",
offset=i[0],
limit=i[1],
)["classes"]

ifc_classes = {}
for i in [(0, 1000), (1000, 2000)]: # 1418 classes in total. 1000 max request limit
ifc_classes = ifc_classes | {x["code"]: x for x in get_batch(i)}
return ifc_classes

ifc_classes = get_ifc_classes()
ifc_core = [x for x in ifc_classes if not ifc_class_is_enum(x)]
len_ifc_core = len(ifc_core)

init_notebook_mode(all_interactive=True)
df = pd.read_csv("BDNS_Abbreviations_Register.csv") # .query("'IfcDistributionSystem' in ifc4_3")
df["ifc4_3"] = df.ifc4_3.str.replace("NOTDEFINED", "")
df = df[df['is_ifc_default']==1]
len_bdns_mappings= len(df)

missing = [x for x in ifc_core if x not in df['ifc4_3'].to_list()]
md_missing = ", ".join(missing)

df["ifc4_3"] = [
'<a href="https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/{}" target="_blank">{}</a>'.format(x, x)
for x in df["ifc4_3"]
]
```


Number of IfcEntities = `{python} len_ifc_core`, Number of BDNS mappings to core IfcEntities = `{python} len_bdns_mappings`

::: {.callout-note collapse="true"}
## IfcEntities missing from core mapping

`{python} md_missing`

:::

```{python}
show(df,
buttons=["pageLength", "csvHtml5"],
lengthMenu=[20, 50, 100, 500],
style="table-layout:auto;width:100%;float:left",
allow_html=True,
)
```
1,594 changes: 843 additions & 751 deletions BDNS_Abbreviations_Register.csv

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions BDNS_Abbreviations_Register.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,18 @@ from itables import init_notebook_mode, show

init_notebook_mode(all_interactive=True)
df = pd.read_csv("BDNS_Abbreviations_Register.csv")
df["ifc4_3"] = df.ifc4_3.str.replace("NOTDEFINED", "")
df["ifc4_3"] = [
'<a href="https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/{}" target="_blank">{}</a>'.format(x, x)
'<a href="https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/{}" target="_blank">{}</a>'.format(
x, x
)
for x in df["ifc4_3"]
]
show(df, buttons=["pageLength", "csvHtml5"], lengthMenu=[20, 50, 100, 500], style="table-layout:auto;width:100%;float:left")
show(
df,
buttons=["pageLength", "csvHtml5"],
lengthMenu=[20, 50, 100, 500],
style="table-layout:auto;width:100%;float:left",
allow_html=True,
)
```
2 changes: 2 additions & 0 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ website:
text: Naming Specification Syntax
- href: BDNS_Abbreviations_Register.qmd
text: Abbreviations Register
- href: BDNS_Abbreviations_Core.qmd
text: Abbreviations Core

format:
html:
Expand Down
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies:
- python>=3.8
- jupyter
- quarto
- itables
- itables>2.4.0
- pyfiglet
- pandas
- pip
Expand Down
93 changes: 93 additions & 0 deletions scripts/25JUL-update-ifc-mappings/add-can-be-connected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
asset_abbreviation,can_be_connected
ATB,1
AHR,1
ALR,1
BEAM,0
BRG,0
BHL,0
BRDG,0
PROXY,0
ELEM,0
BUR,1
CCF,0
CCS,0
CFT,0
CFN,0
CMN,0
COL,0
CMA,1
CNV,0
COV,0
CTW,0
DCE,0
DCT,0
DSYS,0
DFT,0
EWC,0
EFT,1
EMT,1
ETC,1
ASM,0
ENG,1
EVCL,1
FSTN,0
FSP,1
FIN,0
FOT,0
FUR,0
GEO,0
GRD,0
GRP,0
IPD,0
INT,0
JB,0
KRB,0
LMP,1
LQT,0
MCF,0
MED,1
MBR,0
MTA,1
MRD,0
MCN,1
NAV,1
OPN,0
PAV,0
PIL,0
PFT,0
PLT,0
PDV,1
PTU,1
RAIL,0
RLG,0
RAMP,0
RAMPFL,0
RFB,0
RFM,0
ROOF,0
SAN,0
SNS,1
SHD,1
SIGN,1
SLB,0
SOL,1
SPACE,0
SZONE,0
STR,0
STRFL,0
SWD,1
SFE,0
TEN,0
TAN,0
TCN,0
TRACK,0
TRE,0
TBN,0
UCE,0
UEQ,1
VCL,1
VIBDMP,1
VIBISO,1
WALL,1
WSTT,1
ZONE,1
27 changes: 27 additions & 0 deletions scripts/25JUL-update-ifc-mappings/add_can_be_connected.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pathlib
import csv
import re
import itertools

BDNS_REGISTER = pathlib.Path(__file__).parent.parent.parent / "BDNS_Abbreviations_Register.csv"

def read_csv(path: pathlib.Path) -> list[list]:
"""Read a CSV file and return its content as a list of lists."""
return list(csv.reader(path.read_text().split("\n")))

def write_csv(path: pathlib.Path, data: list[list]) -> None:
"""Write a list of lists to a CSV file."""
with path.open("w", newline="") as f:
csv.writer(f).writerows(data)

abbreviations = read_csv(BDNS_REGISTER)
can_be_connected = {x[0]: x[1] for x in read_csv(pathlib.Path(__file__).parent / "add-can-be-connected.csv")[1:]}

for k,v in can_be_connected.items():
for n, x in enumerate(abbreviations):
if x[1] == k:
abbreviations[n][2] = v
break

write_csv(BDNS_REGISTER, abbreviations)
print("done")
27 changes: 27 additions & 0 deletions scripts/25JUL-update-ifc-mappings/add_is_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pathlib
import csv
import re

BDNS_REGISTER = pathlib.Path(__file__).parent.parent.parent / "BDNS_Abbreviations_Register.csv"


def read_csv(path: pathlib.Path) -> list[list]:
"""Read a CSV file and return its content as a list of lists."""
return list(csv.reader(path.read_text().split("\n")))

def write_csv(path: pathlib.Path, data: list[list]) -> None:
"""Write a list of lists to a CSV file."""
with path.open("w", newline="") as f:
csv.writer(f).writerows(data)

def ifc_strip_enum(ifc_class: str) -> str:
return re.sub(r"([A-Z0-9_]+_?)$", "", ifc_class)


def ifc_class_is_enum(ifc_class: str) -> bool:
return ifc_strip_enum(ifc_class) != ifc_class

abbreviations = read_csv(BDNS_REGISTER)
abbreviations = [[*x, *["is_ifc_default"]] if n == 0 else [*x, *[0]] for n, x in enumerate(abbreviations)]

write_csv(BDNS_REGISTER, abbreviations)
Loading