mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 09:32:37 +00:00
Minor fixes, and IfcCSV now uses pandas to import ODS/XLSX for more robust importing.
This commit is contained in:
+5
-33
@@ -91,10 +91,6 @@ class IfcCsv:
|
|||||||
|
|
||||||
for element in elements:
|
for element in elements:
|
||||||
result = []
|
result = []
|
||||||
for index, attribute in enumerate(attributes):
|
|
||||||
if "*" in attribute:
|
|
||||||
attributes.extend(self.get_wildcard_attributes(attribute))
|
|
||||||
del attributes[index]
|
|
||||||
|
|
||||||
for attribute in attributes:
|
for attribute in attributes:
|
||||||
value = ifcopenshell.util.selector.get_element_value(element, attribute)
|
value = ifcopenshell.util.selector.get_element_value(element, attribute)
|
||||||
@@ -262,7 +258,7 @@ class IfcCsv:
|
|||||||
reverse = sort_data["order"] == "DESC"
|
reverse = sort_data["order"] == "DESC"
|
||||||
self.results = sorted(self.results, key=lambda x: natural_sort(x[i]), reverse=reverse)
|
self.results = sorted(self.results, key=lambda x: natural_sort(x[i]), reverse=reverse)
|
||||||
else:
|
else:
|
||||||
if include_global_id and len(self.results[0]) > 1:
|
if include_global_id and len(list(self.results[0])) > 1:
|
||||||
self.results = sorted(self.results, key=lambda x: x[1])
|
self.results = sorted(self.results, key=lambda x: x[1])
|
||||||
elif not include_global_id:
|
elif not include_global_id:
|
||||||
self.results = sorted(self.results, key=lambda x: x[0])
|
self.results = sorted(self.results, key=lambda x: x[0])
|
||||||
@@ -397,36 +393,12 @@ class IfcCsv:
|
|||||||
self.process_row(ifc_file, row, headers, attributes, null, bool_true, bool_false)
|
self.process_row(ifc_file, row, headers, attributes, null, bool_true, bool_false)
|
||||||
|
|
||||||
def import_xlsx(self, ifc_file, table, attributes, null, bool_true, bool_false):
|
def import_xlsx(self, ifc_file, table, attributes, null, bool_true, bool_false):
|
||||||
workbook = openpyxl.load_workbook(filename=table, read_only=True)
|
df = pd.read_excel(table)
|
||||||
worksheet = workbook.active # Assuming data is on the first sheet
|
self.import_pd(ifc_file, df, attributes, null, bool_true, bool_false)
|
||||||
headers = None
|
|
||||||
|
|
||||||
for row in worksheet.iter_rows(values_only=True):
|
|
||||||
if not headers:
|
|
||||||
headers = list(row)
|
|
||||||
if not attributes:
|
|
||||||
attributes = [None] * len(headers)
|
|
||||||
elif len(attributes) == len(headers) - 1:
|
|
||||||
attributes.insert(0, "") # The GlobalId column
|
|
||||||
continue
|
|
||||||
self.process_row(ifc_file, row, headers, attributes, null, bool_true, bool_false)
|
|
||||||
|
|
||||||
def import_ods(self, ifc_file, table, attributes, null, bool_true, bool_false):
|
def import_ods(self, ifc_file, table, attributes, null, bool_true, bool_false):
|
||||||
doc = load(table)
|
df = pd.read_excel(table, engine="odf")
|
||||||
first_sheet = doc.spreadsheet.getElementsByType(Table)[0]
|
self.import_pd(ifc_file, df, attributes, null, bool_true, bool_false)
|
||||||
rows = first_sheet.getElementsByType(TableRow)
|
|
||||||
headers = None
|
|
||||||
|
|
||||||
for row in rows:
|
|
||||||
values = [cell.getElementsByType(P)[0].childNodes[0].data for cell in row.getElementsByType(TableCell)]
|
|
||||||
if not headers:
|
|
||||||
headers = values
|
|
||||||
if not attributes:
|
|
||||||
attributes = [None] * len(headers)
|
|
||||||
elif len(attributes) == len(headers) - 1:
|
|
||||||
attributes.insert(0, "") # The GlobalId column
|
|
||||||
continue
|
|
||||||
self.process_row(ifc_file, values, headers, attributes, null, bool_true, bool_false)
|
|
||||||
|
|
||||||
def import_pd(self, ifc_file, df, attributes=None, null="-", bool_true="YES", bool_false="NO"):
|
def import_pd(self, ifc_file, df, attributes=None, null="-", bool_true="YES", bool_false="NO"):
|
||||||
headers = df.columns.tolist()
|
headers = df.columns.tolist()
|
||||||
|
|||||||
@@ -808,7 +808,8 @@ class Selector:
|
|||||||
value = len(list(value))
|
value = len(list(value))
|
||||||
elif isinstance(value, (list, tuple)):
|
elif isinstance(value, (list, tuple)):
|
||||||
value = len(value)
|
value = len(value)
|
||||||
value = 1
|
else:
|
||||||
|
value = 1
|
||||||
elif key == "class":
|
elif key == "class":
|
||||||
value = value.is_a()
|
value = value.is_a()
|
||||||
elif key == "id":
|
elif key == "id":
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class TestGetElementValue(test.bootstrap.IFC4):
|
|||||||
assert subject.get_element_value(element, "material.item.Name.0") == "L1"
|
assert subject.get_element_value(element, "material.item.Name.0") == "L1"
|
||||||
assert subject.get_element_value(element, "material.item.Name.1") == "L2"
|
assert subject.get_element_value(element, "material.item.Name.1") == "L2"
|
||||||
assert subject.get_element_value(element, '"material"."item"."Name"') == ["L1", "L2"]
|
assert subject.get_element_value(element, '"material"."item"."Name"') == ["L1", "L2"]
|
||||||
assert subject.get_element_value(element, 'r"material"."item"."Name"') == ["L1", "L2"]
|
assert subject.get_element_value(element, 'material."item"."Name"') == ["L1", "L2"]
|
||||||
# Provide shortform for convenience
|
# Provide shortform for convenience
|
||||||
assert subject.get_element_value(element, "mat.i.Name") == ["L1", "L2"]
|
assert subject.get_element_value(element, "mat.i.Name") == ["L1", "L2"]
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ class TestGetElementValue(test.bootstrap.IFC4):
|
|||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
assert subject.get_element_value(element, "material.item.Name.0") is None
|
assert subject.get_element_value(element, "material.item.Name.0") is None
|
||||||
|
|
||||||
def test_selceting_a_list_item_that_fails_silently(self):
|
def test_selecting_a_list_item_that_fails_silently(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
|
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
|
||||||
material2 = ifcopenshell.api.run("material.add_material", self.file, name="CON02")
|
material2 = ifcopenshell.api.run("material.add_material", self.file, name="CON02")
|
||||||
@@ -99,6 +99,24 @@ class TestGetElementValue(test.bootstrap.IFC4):
|
|||||||
assert subject.get_element_value(element, "material.item.Name.0") == "L1"
|
assert subject.get_element_value(element, "material.item.Name.0") == "L1"
|
||||||
assert subject.get_element_value(element, "material.item.Name.1") is None
|
assert subject.get_element_value(element, "material.item.Name.1") is None
|
||||||
|
|
||||||
|
def test_selecting_a_pset(self):
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
|
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
|
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Foobar")
|
||||||
|
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Foo": "Bar"})
|
||||||
|
assert subject.get_element_value(element, "Foobar.Foo") == "Bar"
|
||||||
|
assert subject.get_element_value(element, "Foobar./F.*/") == "Bar"
|
||||||
|
assert subject.get_element_value(element, "/Foo.*/./F.*/") == "Bar"
|
||||||
|
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Baz": 123})
|
||||||
|
assert subject.get_element_value(element, "/Foo.*/./B.*/") == 123
|
||||||
|
assert subject.get_element_value(element, "/Foo.*/./.*/") == ["Bar", 123]
|
||||||
|
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Bay": 123.3})
|
||||||
|
assert subject.get_element_value(element, "/Foo.*/./B.*/") == [123, 123.3]
|
||||||
|
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Pset_WallCommon")
|
||||||
|
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Status": ["New"]})
|
||||||
|
assert subject.get_element_value(element, "/Pset_.*Common/.Status") == ["New"]
|
||||||
|
assert subject.get_element_value(element, "/Pset_.*Common/.Status.0") == "New"
|
||||||
|
|
||||||
|
|
||||||
class TestFilterElements(test.bootstrap.IFC4):
|
class TestFilterElements(test.bootstrap.IFC4):
|
||||||
def test_selecting_by_globalid(self):
|
def test_selecting_by_globalid(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user