diff --git a/src/ifc5d/README.md b/src/ifc5d/README.md index cd7fa2ab1b..c0d7d7f298 100644 --- a/src/ifc5d/README.md +++ b/src/ifc5d/README.md @@ -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 diff --git a/src/ifc5d/ifc5d/csv2ifc.py b/src/ifc5d/ifc5d/csv2ifc.py index 8ef2208107..6a04a630e5 100644 --- a/src/ifc5d/ifc5d/csv2ifc.py +++ b/src/ifc5d/ifc5d/csv2ifc.py @@ -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"]] diff --git a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py index a670d423aa..17d005106b 100644 --- a/src/ifc5d/ifc5d/ifc5Dspreadsheet.py +++ b/src/ifc5d/ifc5d/ifc5Dspreadsheet.py @@ -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 diff --git a/src/ifc5d/rates.csv b/src/ifc5d/rates.csv index 824084c52b..de91f1294c 100644 --- a/src/ifc5d/rates.csv +++ b/src/ifc5d/rates.csv @@ -1,4 +1,4 @@ -"Hierarchy","Identification","Name","Quantity","Unit","Value" +"Index","Identification","Name","Quantity","Unit","Value" 1,1,"Rates",,, ,,,,, 2,1.1,"Category A",,, diff --git a/src/ifc5d/sample_cost_schedule_house_FR.csv b/src/ifc5d/sample_cost_schedule_house_FR.csv index de9da092a4..6be7d7a39a 100644 --- a/src/ifc5d/sample_cost_schedule_house_FR.csv +++ b/src/ifc5d/sample_cost_schedule_house_FR.csv @@ -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,, diff --git a/src/ifc5d/schedule.csv b/src/ifc5d/schedule.csv index c57458bee9..fcf243d095 100644 --- a/src/ifc5d/schedule.csv +++ b/src/ifc5d/schedule.csv @@ -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