mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Fix #3589. Users can now configure how the null values are represented in IfcCSV.
This commit is contained in:
@@ -153,7 +153,15 @@ class ExportIfcCsv(bpy.types.Operator):
|
|||||||
ifc_csv = ifccsv.IfcCsv()
|
ifc_csv = ifccsv.IfcCsv()
|
||||||
attributes = [a.name for a in props.csv_attributes]
|
attributes = [a.name for a in props.csv_attributes]
|
||||||
sep = props.csv_custom_delimiter if props.csv_delimiter == "CUSTOM" else props.csv_delimiter
|
sep = props.csv_custom_delimiter if props.csv_delimiter == "CUSTOM" else props.csv_delimiter
|
||||||
ifc_csv.export(ifc_file, results, attributes, output=self.filepath, format=props.format, delimiter=sep)
|
ifc_csv.export(
|
||||||
|
ifc_file,
|
||||||
|
results,
|
||||||
|
attributes,
|
||||||
|
output=self.filepath,
|
||||||
|
format=props.format,
|
||||||
|
delimiter=sep,
|
||||||
|
null=props.null_value,
|
||||||
|
)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -179,7 +187,7 @@ class ImportIfcCsv(bpy.types.Operator):
|
|||||||
ifc_file = ifcopenshell.open(props.csv_ifc_file)
|
ifc_file = ifcopenshell.open(props.csv_ifc_file)
|
||||||
ifc_csv = ifccsv.IfcCsv()
|
ifc_csv = ifccsv.IfcCsv()
|
||||||
sep = props.csv_custom_delimiter if props.csv_delimiter == "CUSTOM" else props.csv_delimiter
|
sep = props.csv_custom_delimiter if props.csv_delimiter == "CUSTOM" else props.csv_delimiter
|
||||||
ifc_csv.Import(ifc_file, self.filepath, delimiter=sep)
|
ifc_csv.Import(ifc_file, self.filepath, delimiter=sep, null=props.null_value)
|
||||||
if not props.should_load_from_memory:
|
if not props.should_load_from_memory:
|
||||||
ifc_file.write(props.csv_ifc_file)
|
ifc_file.write(props.csv_ifc_file)
|
||||||
purge_module_data()
|
purge_module_data()
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class CsvProperties(PropertyGroup):
|
|||||||
csv_ifc_file: StringProperty(default="", name="IFC File")
|
csv_ifc_file: StringProperty(default="", name="IFC File")
|
||||||
ifc_selector: StringProperty(default="", name="IFC Selector")
|
ifc_selector: StringProperty(default="", name="IFC Selector")
|
||||||
csv_attributes: CollectionProperty(name="CSV Attributes", type=StrProperty)
|
csv_attributes: CollectionProperty(name="CSV Attributes", type=StrProperty)
|
||||||
|
null_value: StringProperty(default="N/A", name="Null Value")
|
||||||
csv_delimiter: EnumProperty(
|
csv_delimiter: EnumProperty(
|
||||||
items=[
|
items=[
|
||||||
(";", ";", ""),
|
(";", ";", ""),
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ class BIM_PT_ifccsv(Panel):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(props, "csv_custom_delimiter")
|
row.prop(props, "csv_custom_delimiter")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(props, "null_value")
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
split = row.split(factor=0.5)
|
split = row.split(factor=0.5)
|
||||||
c = split.column()
|
c = split.column()
|
||||||
|
|||||||
+24
-7
@@ -49,12 +49,12 @@ except:
|
|||||||
|
|
||||||
|
|
||||||
class IfcCsv:
|
class IfcCsv:
|
||||||
def __init__(self, output="", delimiter=","):
|
def __init__(self):
|
||||||
self.headers = []
|
self.headers = []
|
||||||
self.results = []
|
self.results = []
|
||||||
self.dataframe = None
|
self.dataframe = None
|
||||||
|
|
||||||
def export(self, ifc_file, elements, attributes, output=None, format=None, delimiter=","):
|
def export(self, ifc_file, elements, attributes, output=None, format=None, delimiter=",", null=None):
|
||||||
self.ifc_file = ifc_file
|
self.ifc_file = ifc_file
|
||||||
self.results = []
|
self.results = []
|
||||||
for element in elements:
|
for element in elements:
|
||||||
@@ -70,7 +70,10 @@ class IfcCsv:
|
|||||||
del attributes[index]
|
del attributes[index]
|
||||||
|
|
||||||
for attribute in attributes:
|
for attribute in attributes:
|
||||||
result.append(ifcopenshell.util.selector.get_element_value(element, attribute))
|
value = ifcopenshell.util.selector.get_element_value(element, attribute)
|
||||||
|
if value is None:
|
||||||
|
value = null
|
||||||
|
result.append(value)
|
||||||
self.results.append(result)
|
self.results.append(result)
|
||||||
|
|
||||||
self.headers = ["GlobalId"]
|
self.headers = ["GlobalId"]
|
||||||
@@ -130,7 +133,7 @@ class IfcCsv:
|
|||||||
self.doc.spreadsheet.addElement(table)
|
self.doc.spreadsheet.addElement(table)
|
||||||
|
|
||||||
if output[-4:].lower() == ".ods":
|
if output[-4:].lower() == ".ods":
|
||||||
output = output[0:-4]
|
output = output[0:-4]
|
||||||
self.doc.save(output, True)
|
self.doc.save(output, True)
|
||||||
|
|
||||||
def export_xlsx(self, output):
|
def export_xlsx(self, output):
|
||||||
@@ -181,7 +184,7 @@ 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, delimiter=","):
|
def Import(self, ifc_file, table, delimiter=",", null="-"):
|
||||||
# Currently only supports CSV.
|
# Currently only supports CSV.
|
||||||
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)
|
||||||
@@ -198,6 +201,8 @@ class IfcCsv:
|
|||||||
for i, value in enumerate(row):
|
for i, value in enumerate(row):
|
||||||
if i == 0:
|
if i == 0:
|
||||||
continue # Skip GlobalId
|
continue # Skip GlobalId
|
||||||
|
if value == null:
|
||||||
|
value = None
|
||||||
ifcopenshell.util.selector.set_element_value(ifc_file, element, headers[i], value)
|
ifcopenshell.util.selector.set_element_value(ifc_file, element, headers[i], value)
|
||||||
|
|
||||||
|
|
||||||
@@ -206,6 +211,10 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("-i", "--ifc", type=str, required=True, help="The IFC file")
|
parser.add_argument("-i", "--ifc", type=str, required=True, help="The IFC file")
|
||||||
parser.add_argument("-s", "--spreadsheet", type=str, default="data.csv", help="The spreadsheet file")
|
parser.add_argument("-s", "--spreadsheet", type=str, default="data.csv", help="The spreadsheet file")
|
||||||
parser.add_argument("-f", "--format", type=str, default="csv", help="The format, chosen from csv, ods, or xlsx")
|
parser.add_argument("-f", "--format", type=str, default="csv", help="The format, chosen from csv, ods, or xlsx")
|
||||||
|
parser.add_argument("-d", "--delimiter", type=str, default=",", help="The delimiter in CSV. Defaults to a comma.")
|
||||||
|
parser.add_argument(
|
||||||
|
"-n", "--null", type=str, default="-", help="How to represent null values. Defaults to a hyphen."
|
||||||
|
)
|
||||||
parser.add_argument("-q", "--query", type=str, default="", help='Specify a IFC query selector, such as "IfcWall"')
|
parser.add_argument("-q", "--query", type=str, default="", help='Specify a IFC query selector, such as "IfcWall"')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-a",
|
"-a",
|
||||||
@@ -221,9 +230,17 @@ if __name__ == "__main__":
|
|||||||
ifc_file = ifcopenshell.open(args.ifc)
|
ifc_file = ifcopenshell.open(args.ifc)
|
||||||
results = ifcopenshell.util.selector.filter_elements(ifc_file, args.query)
|
results = ifcopenshell.util.selector.filter_elements(ifc_file, args.query)
|
||||||
ifc_csv = IfcCsv()
|
ifc_csv = IfcCsv()
|
||||||
ifc_csv.export(ifc_file, results, args.arguments or [], output=args.spreadsheet, format=args.format)
|
ifc_csv.export(
|
||||||
|
ifc_file,
|
||||||
|
results,
|
||||||
|
args.arguments or [],
|
||||||
|
output=args.spreadsheet,
|
||||||
|
format=args.format,
|
||||||
|
delimiter=args.delimiter,
|
||||||
|
null=args.null,
|
||||||
|
)
|
||||||
elif getattr(args, "import"):
|
elif getattr(args, "import"):
|
||||||
ifc_csv = IfcCsv()
|
ifc_csv = IfcCsv()
|
||||||
ifc_file = ifcopenshell.open(args.ifc)
|
ifc_file = ifcopenshell.open(args.ifc)
|
||||||
ifc_csv.Import(ifc_file, args.spreadsheet)
|
ifc_csv.Import(ifc_file, args.spreadsheet, delimiter=args.delimiter, null=args.null)
|
||||||
ifc_file.write(args.ifc)
|
ifc_file.write(args.ifc)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ utility:
|
|||||||
::
|
::
|
||||||
|
|
||||||
$ python -m ifccsv -h
|
$ python -m ifccsv -h
|
||||||
usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-q QUERY] [-a ARGUMENTS [ARGUMENTS ...]] [--export] [--import]
|
usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-d DELIMITER] [-n NULL] [-q QUERY] [-a ARGUMENTS [ARGUMENTS ...]] [--export] [--import]
|
||||||
|
|
||||||
Exports IFC data to and from CSV
|
Exports IFC data to and from CSV
|
||||||
|
|
||||||
@@ -77,8 +77,11 @@ utility:
|
|||||||
The spreadsheet file
|
The spreadsheet file
|
||||||
-f FORMAT, --format FORMAT
|
-f FORMAT, --format FORMAT
|
||||||
The format, chosen from csv, ods, or xlsx
|
The format, chosen from csv, ods, or xlsx
|
||||||
|
-d DELIMITER, --delimiter DELIMITER
|
||||||
|
The delimiter in CSV. Defaults to a comma.
|
||||||
|
-n NULL, --null NULL How to represent null values. Defaults to a hyphen.
|
||||||
-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 ARGUMENTS [ARGUMENTS ...], --arguments ARGUMENTS [ARGUMENTS ...]
|
||||||
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 'type', 'Name' or 'Pset_Foo.Bar'
|
||||||
--export Export from IFC to CSV
|
--export Export from IFC to CSV
|
||||||
@@ -101,7 +104,7 @@ Here is a minimal example of how to use IfcCSV as a library:
|
|||||||
|
|
||||||
# Export our model's elements and their attributes to a CSV.
|
# Export our model's elements and their attributes to a CSV.
|
||||||
ifc_csv = IfcCsv()
|
ifc_csv = IfcCsv()
|
||||||
ifc_csv.export(model, elements, attributes, output="out.csv", format="csv", delimiter=",")
|
ifc_csv.export(model, elements, attributes, output="out.csv", format="csv", delimiter=",", null="-")
|
||||||
|
|
||||||
# Optionally, you can explicitly export to different formats.
|
# Optionally, you can explicitly export to different formats.
|
||||||
# ifc_csv = IfcCsv()
|
# ifc_csv = IfcCsv()
|
||||||
|
|||||||
Reference in New Issue
Block a user