csv2ifc import - rename required column from hierarchy to index #5492

To prevent confusion with 'Hierarchy' column that's added on the export and make current and export compatible.
Indices now always start from 1 for consistency.
This commit is contained in:
Andrej730
2025-04-17 12:36:00 +05:00
parent bebb29f486
commit 209caec49a
6 changed files with 24 additions and 10 deletions
+5
View File
@@ -30,6 +30,11 @@ See example files as a CSV file format reference:
Some notes on the format:
- Empty lines are ignored.
- Importing ods/xlsx is not currently supported, only csv.
- 'Hierarchy' is just an informational column that doesn't affect the import.
E.g. '1', '1.1', '1.1.1', etc.
- 'Index' column is a hierarchy depth that's used for building hierarchy during csv import, starting from 1.
E.g. root items of the same level have index '1', their children have '2', etc.
- 'Index' was preferred for import hierarchy source over 'Hierarchy' as it's easier to edit from the table view.
## Usage IFC to CSV, ODS, XSLS
+15 -5
View File
@@ -30,6 +30,7 @@ from typing import Any, Union, Optional, TypedDict, NotRequired
class CsvHeader(TypedDict):
Index: int
Name: int
Quantity: int
Unit: int
@@ -86,13 +87,16 @@ class Csv2Ifc:
locale.setlocale(locale.LC_ALL, "") # set the system locale
non_sor_fields = {"Property", "Query"}
# TODO: 25-04-17 Deprecated 0 indices, should fully remove later.
min_index = None
with open(self.csv, "r", encoding="utf-8") as csv_file:
reader = csv.reader(csv_file)
for row in reader:
if not row[0]:
continue
# parse header
if row[0] == "Hierarchy":
if not self.headers:
self.has_categories = True
for i, col in enumerate(row):
if not col:
@@ -129,12 +133,18 @@ class Csv2Ifc:
continue
cost_data = self.get_row_cost_data(row)
hierarchy_key = int(row[0])
if hierarchy_key == 1:
index = int(row[self.headers["Index"]])
if min_index is None and index in (0, 1):
if index == 0:
print(
"WARNING. Indices in csv table start from 0, they should start from 1. It will be deprecated soon completely."
)
min_index = index
if index == min_index:
self.cost_items.append(cost_data)
else:
parents[hierarchy_key - 1]["children"].append(cost_data)
parents[hierarchy_key] = cost_data
parents[index - 1]["children"].append(cost_data)
parents[index] = cost_data
def get_row_cost_data(self, row: list[str]) -> CostItem:
name = row[self.headers["Name"]]
+1 -2
View File
@@ -160,9 +160,8 @@ class IfcDataGetter:
@staticmethod
def get_cost_items_data(file: ifcopenshell.file, schedule: ifcopenshell.entity_instance) -> list[CostItem]:
cost_items_data: list[CostItem] = []
index = 0
for cost_item in IfcDataGetter.get_root_costs(schedule):
IfcDataGetter.process_cost_data(file, cost_item, cost_items_data, index)
IfcDataGetter.process_cost_data(file, cost_item, cost_items_data)
return cost_items_data
@staticmethod
+1 -1
View File
@@ -1,4 +1,4 @@
"Hierarchy","Identification","Name","Quantity","Unit","Value"
"Index","Identification","Name","Quantity","Unit","Value"
1,1,"Rates",,,
,,,,,
2,1.1,"Category A",,,
1 Hierarchy Index Identification Name Quantity Unit Value
2 1 1 Rates
3
4 2 1.1 Category A
+1 -1
View File
@@ -1,4 +1,4 @@
Hierarchy,Identification,Name,Quantity,Unit,Contract,Rate,Material Rate,Labor Rate,Subtotal,Property,Query
Index,Identification,Name,Quantity,Unit,Contract,Rate,Material Rate,Labor Rate,Subtotal,Property,Query
1,DB,Design and build,,,,,,,,,
2,DB.1,Design,,,,,,,,,
3,DB.1.1,Architecte,1,unit,40000,,,,40000,,
1 Hierarchy Index Identification Name Quantity Unit Contract Rate Material Rate Labor Rate Subtotal Property Query
2 1 DB Design and build
3 2 DB.1 Design
4 3 DB.1.1 Architecte 1 unit 40000 40000
+1 -1
View File
@@ -1,4 +1,4 @@
"Hierarchy","Identification","Name","Quantity","Unit","Foo","Bar","Baz","Subtotal"
"Index","Identification","Name","Quantity","Unit","Foo","Bar","Baz","Subtotal"
1,1,"Demolition",,,,,,301
,,,,,,,,
2,1.1,"Building A",,,,,,96
1 Hierarchy Index Identification Name Quantity Unit Foo Bar Baz Subtotal
2 1 1 Demolition 301
3
4 2 1.1 Building A 96