mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
You can now customise the display of empty strings in IfcCSV.
This commit is contained in:
@@ -205,6 +205,7 @@ class ExportIfcCsv(bpy.types.Operator):
|
|||||||
delimiter=sep,
|
delimiter=sep,
|
||||||
include_global_id=props.include_global_id,
|
include_global_id=props.include_global_id,
|
||||||
null=props.null_value,
|
null=props.null_value,
|
||||||
|
empty=props.empty_value,
|
||||||
bool_true=props.true_value,
|
bool_true=props.true_value,
|
||||||
bool_false=props.false_value,
|
bool_false=props.false_value,
|
||||||
sort=sort,
|
sort=sort,
|
||||||
@@ -244,6 +245,7 @@ class ImportIfcCsv(bpy.types.Operator):
|
|||||||
attributes=attributes,
|
attributes=attributes,
|
||||||
delimiter=sep,
|
delimiter=sep,
|
||||||
null=props.null_value,
|
null=props.null_value,
|
||||||
|
empty=props.empty_value,
|
||||||
bool_true=props.true_value,
|
bool_true=props.true_value,
|
||||||
bool_false=props.false_value,
|
bool_false=props.false_value,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class CsvProperties(PropertyGroup):
|
|||||||
should_preserve_existing: BoolProperty(default=False, name="Preserve Existing")
|
should_preserve_existing: BoolProperty(default=False, name="Preserve Existing")
|
||||||
include_global_id: BoolProperty(default=True, name="Include GlobalId")
|
include_global_id: BoolProperty(default=True, name="Include GlobalId")
|
||||||
null_value: StringProperty(default="N/A", name="Null Value")
|
null_value: StringProperty(default="N/A", name="Null Value")
|
||||||
|
empty_value: StringProperty(default="-", name="Empty String Value")
|
||||||
true_value: StringProperty(default="YES", name="True Value")
|
true_value: StringProperty(default="YES", name="True Value")
|
||||||
false_value: StringProperty(default="NO", name="False Value")
|
false_value: StringProperty(default="NO", name="False Value")
|
||||||
csv_delimiter: EnumProperty(
|
csv_delimiter: EnumProperty(
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class BIM_PT_ifccsv(Panel):
|
|||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, "null_value")
|
row.prop(props, "null_value")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
row.prop(props, "empty_value")
|
||||||
|
row = layout.row()
|
||||||
row.prop(props, "true_value")
|
row.prop(props, "true_value")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, "false_value")
|
row.prop(props, "false_value")
|
||||||
|
|||||||
+19
-14
@@ -70,6 +70,7 @@ class IfcCsv:
|
|||||||
include_global_id=True,
|
include_global_id=True,
|
||||||
delimiter=",",
|
delimiter=",",
|
||||||
null="-",
|
null="-",
|
||||||
|
empty="",
|
||||||
bool_true="YES",
|
bool_true="YES",
|
||||||
bool_false="NO",
|
bool_false="NO",
|
||||||
sort=None,
|
sort=None,
|
||||||
@@ -96,6 +97,8 @@ class IfcCsv:
|
|||||||
value = ifcopenshell.util.selector.get_element_value(element, attribute)
|
value = ifcopenshell.util.selector.get_element_value(element, attribute)
|
||||||
if value is None:
|
if value is None:
|
||||||
value = null
|
value = null
|
||||||
|
elif value == "":
|
||||||
|
value = empty
|
||||||
elif value is True:
|
elif value is True:
|
||||||
value = bool_true
|
value = bool_true
|
||||||
elif value is False:
|
elif value is False:
|
||||||
@@ -368,17 +371,17 @@ class IfcCsv:
|
|||||||
results.update([p.Name for p in element.Quantities])
|
results.update([p.Name for p in element.Quantities])
|
||||||
return ["{}.{}".format(pset_qto_name, n) for n in results]
|
return ["{}.{}".format(pset_qto_name, n) for n in results]
|
||||||
|
|
||||||
def Import(self, ifc_file, table, attributes=None, delimiter=",", null="-", bool_true="YES", bool_false="NO"):
|
def Import(self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO"):
|
||||||
ext = table.split(".")[-1].lower()
|
ext = table.split(".")[-1].lower()
|
||||||
|
|
||||||
if ext == "csv":
|
if ext == "csv":
|
||||||
self.import_csv(ifc_file, table, attributes, delimiter, null, bool_true, bool_false)
|
self.import_csv(ifc_file, table, attributes, delimiter, null, empty, bool_true, bool_false)
|
||||||
elif ext == "ods":
|
elif ext == "ods":
|
||||||
self.import_ods(ifc_file, table, attributes, null, bool_true, bool_false)
|
self.import_ods(ifc_file, table, attributes, null, empty, bool_true, bool_false)
|
||||||
elif ext == "xlsx":
|
elif ext == "xlsx":
|
||||||
self.import_xlsx(ifc_file, table, attributes, null, bool_true, bool_false)
|
self.import_xlsx(ifc_file, table, attributes, null, empty, bool_true, bool_false)
|
||||||
|
|
||||||
def import_csv(self, ifc_file, table, attributes=None, delimiter=",", null="-", bool_true="YES", bool_false="NO"):
|
def import_csv(self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO"):
|
||||||
with open(table, newline="", encoding="utf-8") as f:
|
with open(table, newline="", encoding="utf-8") as f:
|
||||||
reader = csv.reader(f, delimiter=delimiter)
|
reader = csv.reader(f, delimiter=delimiter)
|
||||||
headers = []
|
headers = []
|
||||||
@@ -390,17 +393,17 @@ class IfcCsv:
|
|||||||
elif len(attributes) == len(headers) - 1:
|
elif len(attributes) == len(headers) - 1:
|
||||||
attributes.insert(0, "") # The GlobalId column
|
attributes.insert(0, "") # The GlobalId column
|
||||||
continue
|
continue
|
||||||
self.process_row(ifc_file, row, headers, attributes, null, bool_true, bool_false)
|
self.process_row(ifc_file, row, headers, attributes, null, empty, 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, empty, bool_true, bool_false):
|
||||||
df = pd.read_excel(table)
|
df = pd.read_excel(table)
|
||||||
self.import_pd(ifc_file, df, attributes, null, bool_true, bool_false)
|
self.import_pd(ifc_file, df, attributes, null, empty, 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, empty, bool_true, bool_false):
|
||||||
df = pd.read_excel(table, engine="odf")
|
df = pd.read_excel(table, engine="odf")
|
||||||
self.import_pd(ifc_file, df, attributes, null, bool_true, bool_false)
|
self.import_pd(ifc_file, df, attributes, null, empty, 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="-", empty="", bool_true="YES", bool_false="NO"):
|
||||||
headers = df.columns.tolist()
|
headers = df.columns.tolist()
|
||||||
|
|
||||||
if not attributes:
|
if not attributes:
|
||||||
@@ -409,9 +412,9 @@ class IfcCsv:
|
|||||||
attributes.insert(0, "") # The GlobalId column
|
attributes.insert(0, "") # The GlobalId column
|
||||||
|
|
||||||
for _, row in df.iterrows():
|
for _, row in df.iterrows():
|
||||||
self.process_row(ifc_file, row.tolist(), headers, attributes, null, bool_true, bool_false)
|
self.process_row(ifc_file, row.tolist(), headers, attributes, null, empty, bool_true, bool_false)
|
||||||
|
|
||||||
def process_row(self, ifc_file, row, headers, attributes, null, bool_true, bool_false):
|
def process_row(self, ifc_file, row, headers, attributes, null, empty, bool_true, bool_false):
|
||||||
try:
|
try:
|
||||||
element = ifc_file.by_guid(row[0])
|
element = ifc_file.by_guid(row[0])
|
||||||
except:
|
except:
|
||||||
@@ -422,6 +425,8 @@ class IfcCsv:
|
|||||||
continue # Skip GlobalId
|
continue # Skip GlobalId
|
||||||
if value == null:
|
if value == null:
|
||||||
value = None
|
value = None
|
||||||
|
elif value == empty:
|
||||||
|
value = ""
|
||||||
elif value == bool_true:
|
elif value == bool_true:
|
||||||
value = True
|
value = True
|
||||||
elif value == bool_false:
|
elif value == bool_false:
|
||||||
@@ -449,7 +454,7 @@ if __name__ == "__main__":
|
|||||||
help="Specify attributes that are part of the extract, using the IfcQuery syntax such as 'class', 'Name' or 'Pset_Foo.Bar'",
|
help="Specify attributes that are part of the extract, using the IfcQuery syntax such as 'class', 'Name' or 'Pset_Foo.Bar'",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-h", "--headers", nargs="+", help="Specify human readable headers that correlate to each attribute."
|
"--headers", nargs="+", help="Specify human readable headers that correlate to each attribute."
|
||||||
)
|
)
|
||||||
parser.add_argument("--sort", nargs="+", help="Specify one or more attributes to sort by.")
|
parser.add_argument("--sort", nargs="+", help="Specify one or more attributes to sort by.")
|
||||||
parser.add_argument("--order", nargs="+", help="Choose the sort order from ASC or DESC for each sorted attribute.")
|
parser.add_argument("--order", nargs="+", help="Choose the sort order from ASC or DESC for each sorted attribute.")
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ utility:
|
|||||||
::
|
::
|
||||||
|
|
||||||
$ python -m ifccsv -h
|
$ python -m ifccsv -h
|
||||||
usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-d DELIMITER] [-n NULL] [-q QUERY] [-a ARGUMENTS [ARGUMENTS ...]] [--export] [--import]
|
usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-d DELIMITER] [-n NULL] [--bool_true BOOL_TRUE] [--bool_false BOOL_FALSE] [-q QUERY] [-a ATTRIBUTES [ATTRIBUTES ...]] [--headers HEADERS [HEADERS ...]] [--sort SORT [SORT ...]]
|
||||||
|
[--order ORDER [ORDER ...]] [--export] [--import]
|
||||||
|
|
||||||
Exports IFC data to and from CSV
|
Exports IFC data to and from CSV
|
||||||
|
|
||||||
@@ -80,12 +81,22 @@ utility:
|
|||||||
-d DELIMITER, --delimiter DELIMITER
|
-d DELIMITER, --delimiter DELIMITER
|
||||||
The delimiter in CSV. Defaults to a comma.
|
The delimiter in CSV. Defaults to a comma.
|
||||||
-n NULL, --null NULL How to represent null values. Defaults to a hyphen.
|
-n NULL, --null NULL How to represent null values. Defaults to a hyphen.
|
||||||
|
--bool_true BOOL_TRUE
|
||||||
|
How to represent true values. Defaults to YES.
|
||||||
|
--bool_false BOOL_FALSE
|
||||||
|
How to represent false values. Defaults to NO.
|
||||||
-q QUERY, --query QUERY
|
-q QUERY, --query QUERY
|
||||||
Specify a IFC query selector, such as "IfcWall"
|
Specify a IFC query selector, such as "IfcWall"
|
||||||
-a ARGUMENTS [ARGUMENTS ...], --arguments ARGUMENTS [ARGUMENTS ...]
|
-a ATTRIBUTES [ATTRIBUTES ...], --attributes ATTRIBUTES [ATTRIBUTES ...]
|
||||||
Specify attributes that are part of the extract, using the IfcQuery syntax such as 'type', 'Name' or 'Pset_Foo.Bar'
|
Specify attributes that are part of the extract, using the IfcQuery syntax such as 'class', 'Name' or 'Pset_Foo.Bar'
|
||||||
--export Export from IFC to CSV
|
--headers HEADERS [HEADERS ...]
|
||||||
--import Import from CSV to IFC
|
Specify human readable headers that correlate to each attribute.
|
||||||
|
--sort SORT [SORT ...]
|
||||||
|
Specify one or more attributes to sort by.
|
||||||
|
--order ORDER [ORDER ...]
|
||||||
|
Choose the sort order from ASC or DESC for each sorted attribute.
|
||||||
|
--export Export from IFC to the desired format.
|
||||||
|
--import Import from the autodetected format to IFC.
|
||||||
$ python -m ifccsv -i model.ifc -s out.csv -f csv -q .IfcProduct -a "Name" "Description" --export
|
$ python -m ifccsv -i model.ifc -s out.csv -f csv -q .IfcProduct -a "Name" "Description" --export
|
||||||
$ cat out.csv
|
$ cat out.csv
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user