Spaces:
Sleeping
Sleeping
first main commit
Browse files- .gitignore +2 -0
- app.py +208 -0
- requirements.txt +9 -0
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
original.zip
|
2 |
+
temp.zip
|
app.py
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
# coding: utf-8
|
3 |
+
|
4 |
+
|
5 |
+
import zipfile
|
6 |
+
import os
|
7 |
+
import tempfile
|
8 |
+
import xml.etree.ElementTree as ET
|
9 |
+
import requests
|
10 |
+
import shutil
|
11 |
+
import streamlit as st
|
12 |
+
|
13 |
+
|
14 |
+
def elevation_change(bcf_list, z_error_correction_in_metres: float):
|
15 |
+
|
16 |
+
update_data_list = []
|
17 |
+
|
18 |
+
for individual_file in file_list:
|
19 |
+
|
20 |
+
if 'viewpoint' in individual_file:
|
21 |
+
|
22 |
+
bcf_guid = individual_file.split('/', 1)[0]
|
23 |
+
parsed_markup_file = file_open.open(bcf_guid + '/markup.bcf')
|
24 |
+
xml_tree_markup = ET.parse(parsed_markup_file)
|
25 |
+
xml_root_markup = xml_tree_markup.getroot()
|
26 |
+
|
27 |
+
for topic_data in xml_root_markup.iter('Topic'):
|
28 |
+
|
29 |
+
component_guids = []
|
30 |
+
component_batids = []
|
31 |
+
parsed_viewpoint_file = file_open.open(individual_file)
|
32 |
+
xml_tree_viewpoint = ET.parse(parsed_viewpoint_file)
|
33 |
+
xml_root_viewpoint = xml_tree_viewpoint.getroot()
|
34 |
+
|
35 |
+
updateZValue(xml_root_viewpoint, 'CameraViewPoint', z_error_correction_in_metres)
|
36 |
+
|
37 |
+
for bitmap_data in xml_root_viewpoint.iter('Bitmap'):
|
38 |
+
|
39 |
+
updateZValue(bitmap_data, 'Location', z_error_correction_in_metres)
|
40 |
+
|
41 |
+
for clipping_plane_data in xml_root_viewpoint.iter('ClippingPlane'):
|
42 |
+
|
43 |
+
updateZValue(clipping_plane_data, 'Location', z_error_correction_in_metres)
|
44 |
+
|
45 |
+
for line_data in xml_root_viewpoint.iter('Line'):
|
46 |
+
|
47 |
+
updateZValue(line_data, 'StartPoint', z_error_correction_in_metres)
|
48 |
+
updateZValue(line_data, 'EndPoint', z_error_correction_in_metres)
|
49 |
+
|
50 |
+
individual_xml_update = {
|
51 |
+
'individual_file':individual_file,
|
52 |
+
'xml_string_update': ET.tostring(xml_root_viewpoint)
|
53 |
+
}
|
54 |
+
|
55 |
+
update_data_list.append(individual_xml_update)
|
56 |
+
|
57 |
+
return update_data_list
|
58 |
+
|
59 |
+
|
60 |
+
def updateZip(zipname, filename, data):
|
61 |
+
# generate a temp file
|
62 |
+
tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname))
|
63 |
+
os.close(tmpfd)
|
64 |
+
|
65 |
+
# create a temp copy of the archive without filename
|
66 |
+
with zipfile.ZipFile(zipname, 'r') as zin:
|
67 |
+
with zipfile.ZipFile(tmpname, 'w') as zout:
|
68 |
+
zout.comment = zin.comment # preserve the comment
|
69 |
+
for item in zin.infolist():
|
70 |
+
if item.filename != filename:
|
71 |
+
zout.writestr(item, zin.read(item.filename))
|
72 |
+
|
73 |
+
# replace with the temp archive
|
74 |
+
os.remove(zipname)
|
75 |
+
os.rename(tmpname, zipname)
|
76 |
+
|
77 |
+
# now add filename with its new data
|
78 |
+
with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf:
|
79 |
+
zf.writestr(filename, data)
|
80 |
+
|
81 |
+
|
82 |
+
def updateZipForMultipleFiles(file_names_and_data, zipname='temp.zip'):
|
83 |
+
# generate a temp file
|
84 |
+
|
85 |
+
# test_dataset.save_to_disk("test.hf")
|
86 |
+
tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname))
|
87 |
+
os.close(tmpfd)
|
88 |
+
|
89 |
+
# create a temp copy of the archive without filename
|
90 |
+
with zipfile.ZipFile(zipname, 'r') as zin:
|
91 |
+
with zipfile.ZipFile(tmpname, 'w') as zout:
|
92 |
+
zout.comment = zin.comment # preserve the comment
|
93 |
+
for item in zin.infolist():
|
94 |
+
if not 'viewpoint' in item.filename:
|
95 |
+
zout.writestr(item, zin.read(item.filename))
|
96 |
+
|
97 |
+
# replace with the temp archive
|
98 |
+
os.remove(zipname)
|
99 |
+
os.rename(tmpname, zipname)
|
100 |
+
|
101 |
+
# now add filename with its new data
|
102 |
+
for individual_update in file_names_and_data:
|
103 |
+
with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf:
|
104 |
+
zf.writestr(individual_update['individual_file'], individual_update['xml_string_update'])
|
105 |
+
|
106 |
+
|
107 |
+
def updateZValue(xml_data, xml_element_to_iterate, z_error_correction_in_metres):
|
108 |
+
|
109 |
+
for location_data in xml_data.iter(xml_element_to_iterate):
|
110 |
+
|
111 |
+
existing_z = float(location_data.find('Z').text)
|
112 |
+
new_z = existing_z + z_error_correction_in_metres
|
113 |
+
location_data.find('Z').text = str(new_z)
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
st.markdown(
|
120 |
+
'''
|
121 |
+
# Adjust the height of all issues in a BCF file
|
122 |
+
|
123 |
+
Provide any spreadsheet (using a dropbox link) that has a column of revit IDs.
|
124 |
+
A typical Revit ID is `60f91daf-3dd7-4283-a86d-24137b73f3da-0001fd0b`.
|
125 |
+
This app will convert the ID to `3CPy6r22DAahSW8AIIobik`.
|
126 |
+
|
127 |
+
|
128 |
+
Select the sheet witin the spreadsheet and the column with the IDs.
|
129 |
+
|
130 |
+
|
131 |
+
Only the selected sheet will be returned, you can cut and paste the sheet back into the origial spreadsheet.
|
132 |
+
'''
|
133 |
+
)
|
134 |
+
|
135 |
+
|
136 |
+
bcf_file_button = st.text_input(
|
137 |
+
"Dropbox link to BCF file",
|
138 |
+
key="bcf_file_button"
|
139 |
+
)
|
140 |
+
|
141 |
+
# In[ ]:
|
142 |
+
|
143 |
+
if bcf_file_button:
|
144 |
+
|
145 |
+
bcf_file_path = st.session_state.bcf_file_button
|
146 |
+
path_original = 'original.zip'
|
147 |
+
path_updated = 'temp.zip'
|
148 |
+
|
149 |
+
if '=0' in bcf_file_path:
|
150 |
+
|
151 |
+
bcf_file_path = bcf_file_path.replace('=0', '=1')
|
152 |
+
|
153 |
+
if '.bcf' in bcf_file_path:
|
154 |
+
|
155 |
+
partial_filename = bcf_file_path.rsplit('/')[-1]
|
156 |
+
filename = partial_filename.split('.bcf')[0]
|
157 |
+
bcf_file_path = bcf_file_path.replace('.bcf', '.zip')
|
158 |
+
|
159 |
+
|
160 |
+
r = requests.get(bcf_file_path, stream=True)
|
161 |
+
if r.status_code == 200:
|
162 |
+
with open(path_original, 'wb') as f:
|
163 |
+
for chunk in r:
|
164 |
+
f.write(chunk)
|
165 |
+
shutil.copy2(path_original, path_updated)
|
166 |
+
file_open = zipfile.ZipFile(path_original)
|
167 |
+
file_list = file_open.namelist()
|
168 |
+
|
169 |
+
height_change_button = st.number_input(
|
170 |
+
"Height of the sheet to be returned",
|
171 |
+
# value=float,
|
172 |
+
format="%.3f",
|
173 |
+
min_value=-1000.0,
|
174 |
+
max_value=1000.0,
|
175 |
+
step=0.001,
|
176 |
+
key="height_change_button"
|
177 |
+
)
|
178 |
+
|
179 |
+
if height_change_button:
|
180 |
+
|
181 |
+
height_change = st.session_state.height_change_button
|
182 |
+
|
183 |
+
update_bcf_info = elevation_change(
|
184 |
+
file_list,
|
185 |
+
height_change,
|
186 |
+
)
|
187 |
+
|
188 |
+
updateZipForMultipleFiles(
|
189 |
+
update_bcf_info,
|
190 |
+
)
|
191 |
+
|
192 |
+
with open(path_updated, "rb") as fp:
|
193 |
+
btn = st.download_button(
|
194 |
+
label="Download BCF file",
|
195 |
+
data=fp,
|
196 |
+
file_name=f"{filename}_height_{height_change}.bcf",
|
197 |
+
mime="application/zip"
|
198 |
+
)
|
199 |
+
|
200 |
+
else:
|
201 |
+
|
202 |
+
st.write('Please provide a valid BCF file')
|
203 |
+
|
204 |
+
|
205 |
+
|
206 |
+
|
207 |
+
|
208 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
zipfile
|
3 |
+
tempfile
|
4 |
+
elementpath
|
5 |
+
requests
|
6 |
+
shutil
|
7 |
+
# sqlalchemy
|
8 |
+
# psycopg2-binary
|
9 |
+
# https://www.dropbox.com/s/9yfqtw4qldma1kf/ifc-0.3.18h.tar.gz?dl=1
|