import ezdxf import pandas as pd import numpy as np import networkx as nx import math import scipy import sqlite3 import subprocess TEIGHA_PATH = "C:/Daten/nc/Ingenieurbüro/20 Projekte/Kanalplanung/Teigha File Converter 4.3.2/TeighaFileConverter.exe" """ Funktionsweise der Kanal_Tools: Daten mit QGIS aufbereiten ibp_calc() ibp_calc_netz() ibp_calc_hydraulik() """ inp_file = 'D:/Daten/nc/Ingenieurbüro/20 Projekte/Kanalplanung/kanalplanung.gpkg' md = QgsProviderRegistry.instance().providerMetadata("ogr") gpkg_con = md.createConnection( inp_file, {}) def ibp_all(): ibp_calc() ibp_calc_netz() ibp_hydraulik() ## Funktion um einen globalen Layer-Filter zu setzen def ibp_filter(filter): #alle Layer gpkg_con.executeSql("UPDATE projekt SET aktiv = 0;") #for i in self.iface.mapCanvas().layers(): # idx = i.fields().indexFromName('ibpprj') # if idx >= 0: # i.setSubsetString("ibpprj LIKE '%"+self.act.currentText()+"%'") text, ok = QInputDialog().getText(self, "QInputDialog().getText()","User name:", QLineEdit.Normal) #for row in QgsProject.instance().mapLayers().values(): # #if row.name() in ["haltung", "schacht", "rw_einzugsgebiete"]: # if re.search(r".*kanalplanung.gpkg\|layername=(haltung|schacht|rw_einzugsgebiete).*", row.source()): # if re.search(r".*kanalplanung.gpkg\|layername=(haltung_sp)", row.source()): # row.setSubsetString("") # elif filter != "": # row.setSubsetString(""""ibpprj" = '{0}'""".format(filter)) # gpkg_con.executeSql("UPDATE projekt SET aktiv = 1 WHERE nr='{}';".format(filter)) # else: # row.setSubsetString("") def ibp_calc(): query = """UPDATE haltung SET zul_sch_fid = (SELECT s.fid FROM schacht s WHERE distance(geomfromgpb(s.geom),startpoint(geomfromgpb(haltung.geom))) < 0.05 LIMIT 1), abl_sch_fid = (SELECT s.fid FROM schacht s WHERE distance(geomfromgpb(s.geom),endpoint(geomfromgpb(haltung.geom))) < 0.05 LIMIT 1);""" res = gpkg_con.executeSql(query) query = """UPDATE sw_fallrohre SET (du, dn, anmerkung, kurz) = (SELECT du, dn, anmerkung, kurz FROM config_gegenstaende where config_gegenstaende.gegenstand = sw_fallrohre.gegenstand);""" res = gpkg_con.executeSql(query) query = """UPDATE schacht SET (ezg_direkt_A, ezg_direkt_Aum, ezg_direkt_Aus) = (SELECT sum(rw_ezg.A), sum(rw_ezg.Aum),sum(rw_ezg.Aus) FROM rw_einzugsgebiete rw_ezg WHERE rw_ezg.schacht_fid = schacht.fid), (sw_du_sum) = (SELECT sum(swf.du) FROM sw_fallrohre swf WHERE swf.schacht_fid = schacht.fid), sh = IIF(sh_fix > 0, sh_fix, (SELECT min(sh) FROM ( SELECT haltung.zul_sh as sh FROM haltung WHERE haltung.zul_sch_fid = schacht.fid and haltung.zul_sh > 0 UNION SELECT haltung.abl_sh as sh FROM haltung WHERE haltung.abl_sch_fid = schacht.fid and haltung.abl_sh > 0)));""" res = gpkg_con.executeSql(query) query = """UPDATE schacht SET ezg_direkt_psi_m = ezg_direkt_Aum/ezg_direkt_A, ezg_direkt_psi_s = ezg_direkt_Aus/ezg_direkt_A;""" res = gpkg_con.executeSql(query) query = """DROP TABLE IF EXISTS haltung_sp;""" res = gpkg_con.executeSql(query) query = """CREATE TABLE haltung_sp AS SELECT s1z.name, s1a.name, s2z.name, s2a.name, a.zul_sch_fid, a.abl_sch_fid, b.zul_sch_fid, b.abl_sch_fid, ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom)) geometry, AsText(ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom))) txt, ifnull(ST_InterpolatePoint(ST_AddMeasure(geomfromgpb(a.geom),0, 1),ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom)))*a.c_laenge,0) d1, ifnull(a.zul_sh - a.c_laenge / (ST_InterpolatePoint(ST_AddMeasure(geomfromgpb(a.geom),0, 1),ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom)))*a.c_laenge) * a.gefaelle / 1000,0) h1, ifnull(ST_InterpolatePoint(ST_AddMeasure(geomfromgpb(b.geom),0, 1),ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom)))*b.c_laenge,0) d2, ifnull(b.zul_sh - b.c_laenge / (ST_InterpolatePoint(ST_AddMeasure(geomfromgpb(b.geom),0, 1),ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom)))*b.c_laenge) * b.gefaelle / 1000,0) h2, a.di di1, b.di, b.art FROM haltung a, haltung b LEFT JOIN schacht s1z on a.zul_sch_fid = s1z.fid LEFT JOIN schacht s1a on a.abl_sch_fid = s1a.fid LEFT JOIN schacht s2z on b.zul_sch_fid = s1z.fid LEFT JOIN schacht s2a on b.abl_sch_fid = s1z.fid WHERE geometry not NULL and GeometryType(ST_Intersection(GeomfromGPB(a.geom), GeomfromGPB(b.geom))) = "POINT" and round(d1,2) > 0 and d1 < a.c_laenge;""" res = gpkg_con.executeSql(query) query = """DROP TABLE IF EXISTS haltung_calc_graph;""" res = gpkg_con.executeSql(query) query = """CREATE TABLE haltung_calc_graph AS WITH RECURSIVE graph(n,sn_fid,en_fid,du_sum,sw_k,Qpump,Qc, Aus, Aum) AS ( SELECT h.fid, h.zul_sch_fid, h.abl_sch_fid, schc.sw_du_sum, schc.sw_k, schc.Qpump, schc.Qc, schc.ezg_direkt_Aus, schc.ezg_direkt_Aum FROM haltung h LEFT join schacht schc on h.zul_sch_fid = schc.fid UNION SELECT n, h.zul_sch_fid, h.abl_sch_fid, schc.sw_du_sum, schc.sw_k, schc.Qpump, schc.Qc, schc.ezg_direkt_Aus, schc.ezg_direkt_Aum FROM graph LEFT JOIN haltung h on h.abl_sch_fid = graph.sn_fid LEFT JOIN schacht schc on h.zul_sch_fid = schc.fid ) SELECT n fid,sn_fid zul_sch_fid,en_fid abl_sch_fid, sum(du_sum) du_sum,max(sw_k) sw_k,sum(Qpump) Qpump,sum(Qc) Qc, sum(Aus) Aus, sum(Aum) Aum FROM graph WHERE sn_fid IS NOT NULL and en_fid IS NOT NULL GROUP BY n;""" res = gpkg_con.executeSql(query) query = """UPDATE haltung SET (du_sum, Qww, Qpump, Qc, Aus, Aum) = (SELECT ifnull(g.du_sum,0), ifnull(g.sw_k*sqrt(g.du_sum),0), ifnull(g.Qpump,0), ifnull(g.Qc,0), ifnull(g.Aus,0), ifnull(g.Aum,0) FROM haltung_calc_graph g WHERE g.fid = haltung.fid), (sw_k, bem_regen) = (SELECT sw_k, rohr_bem_regen FROM projekt WHERE projekt.nr = haltung.ibpprj), c_laenge = GLength(geomfromgpb(geom)) ;""" res = gpkg_con.executeSql(query) query = """UPDATE haltung SET Qsw = ifnull(sw_k * sqrt(du_sum)+Qpump+Qc, 0), Qrr = ifnull(Aus*bem_regen/10000,0 ), zul_fuellg = IIF(haltung.art = 'SW', IIF(haltung.Qpump = 0, 0.5, 0.7), IIF(haltung.art='RW',0.9,NULL) );""" res = gpkg_con.executeSql(query) query = """UPDATE haltung SET Qtot = Qsw + Qrr;""" res = gpkg_con.executeSql(query) query = """UPDATE schacht SET (ezg_total_Aus, ezg_total_Aum) = (SELECT sum(haltung.Aus), sum(haltung.Aum) FROM haltung WHERE haltung.abl_sch_fid = schacht.fid);""" res = gpkg_con.executeSql(query) ## Funktion um einen Schnitt zu erstellen # Ausgangsdaten-Tabelle: haltung, haltung_sp, schacht, sw_fallrohre # Ergebnis-Tablle: haltung_calc_hydraulik def ibp_schnitt(schnitte_filename, hor, fok, schnitte_masstab, schnitte, ibpprj): mx,my = schnitte_masstab graph = nx.DiGraph() query = """SELECT ifnull(zul_sch_fid,0) zul_sch_fid, ifnull(abl_sch_fid,0) abl_sch_fid, s1.name zul_sch, s2.name abl_sch FROM haltung join schacht s1 on s1.fid = haltung.zul_sch_fid join schacht s2 on s2.fid = haltung.abl_sch_fid WHERE haltung.ibpprj = '{}'""".format(ibpprj) res = gpkg_con.executeSql(query) translate_fid = {} for row in res: if row[0] is not NULL and row[1] is not NULL: graph.add_edge(row[0], row[1]) translate_fid[row[2]] = row[0] translate_fid[row[3]] = row[1] # ZEICHNE SCHNITT s_doc = ezdxf.readfile("C:/tmp/schnitte_temp.dxf") # Vorlagendatei s_msp = s_doc.modelspace() pos = {} for schn in schnitte: [source_nam, target_nam, basis] = schn source = translate_fid[source_nam] target = translate_fid[target_nam] [bx,by] = basis if bx == 0: pos[by] = 0 elif bx < 10: bx = pos[by] print("Von: ",source_nam," Nach: ",target_nam,) path = nx.shortest_path(graph, source=source, target=target) print(path) ########################################### # Lade Leitungen und Querungen für den aktuellen Schnitt ########################################### ltg = [] quer = [] for i in range(len(path)-1): query = """SELECT ifnull(c_laenge,0) c_laenge, ifnull(zul_sh,0) zul_sh, ifnull(abl_sh,0) abl_sh, mat, ifnull(di,0) di, ifnull(gefaelle,0) gefaelle, art FROM haltung WHERE zul_sch_fid='{}' and abl_sch_fid='{}'""".format(path[i],path[i+1]) res = gpkg_con.executeSql(query) ltg.append({'dist': res[0][0], 'sh_a': res[0][1], 'sh_e': res[0][2], 'mat_dim': res[0][3], 'di': res[0][4], 'gef': res[0][5], 'art': res[0][6], 'zu': path[i], 'ab': path[i+1]}) query = "SELECT d1, di, h2, art FROM haltung_sp WHERE zul_sch_fid='{}' and abl_sch_fid='{}'".format(path[i],path[i+1]) res = gpkg_con.executeSql(query) for j in res: print(j) quer.append({'dist': float(j[0]), 'dn': j[1], 'sh': float(j[2]), 'art': j[3], 'zu1': path[i], 'ab1': path[i+1]}) ########################################### # Lade Punkte für den aktellen Schnitt ########################################### #ws = wb.sheets['Punkte'] pkt = [] for i in range(len(path)): query = "SELECT name, dh, sh, symbol, schacht_dn, art FROM schacht WHERE fid='{}'".format(path[i]) res = gpkg_con.executeSql(query) res[0] = [0 if x == NULL else x for x in res[0]] pkt.append({'name': res[0][0], 'dh': res[0][1], 'sh': res[0][2], 'symb': res[0][3], 'dn': res[0][4], 'art': res[0][5], 'fid': path[i]}) ########################################### # Lade die Fallrohre für den aktuellen Schnitt ########################################### fr_dat = [] fr_dat = pd.DataFrame() # Wähle die Fallrohre, die für den aktuellen Schnitt notwendig sind aus for i in range(len(path)): query = "SELECT swf.schacht_fid, swf.kurz, swf.geschoss FROM sw_fallrohre swf WHERE swf.schacht_fid='{}'".format(path[i]) res = gpkg_con.executeSql(query) for i in res: print(i) # ALTE VERSION #fr_dat = fr_dat.append({'schacht_fid': i[0], # 'objekt': i[1], # 'geschoss': i[2] # }, ignore_index=True) new_row = [{'schacht_fid': i[0], 'objekt': i[1], 'geschoss': i[2]}] fr_dat = pd.concat([fr_dat, pd.DataFrame(new_row)], ignore_index=True) if len(fr_dat) > 0: # y-Verschiebung nach oben pro Geschoss (benötigt) - Werte 1 bis Anzahl der Geschosse df3 = pd.DataFrame() query = "SELECT swf.geschoss FROM sw_fallrohre swf JOIN schacht s ON swf.schacht_fid = s.fid WHERE s.ibpprj='{}'".format(ibpprj) res = gpkg_con.executeSql(query) for i in res: # ALTE VERSION # df3 = df3.append({'geschoss': i[0]}, ignore_index=True) new_row = [{'geschoss': i[0]}] df3 = pd.concat([df3, pd.DataFrame(new_row)], ignore_index=True) #for r in range(8,200): # df3 = df3.append({'geschoss': ws.range((r,6)).value}, ignore_index=True) # x-Verschiebung nach rechts (nicht benötigt, da durch Fallrohrposition vorgegeben) fr_dat['x'] = 0 df3 = df3[['geschoss']].drop_duplicates().dropna() df3['y'] = df3['geschoss'].astype(str).str[:2].astype(int)-10 fr_dat = fr_dat.merge(df3, on='geschoss', how='left') # Symbole je Fallrohr ordnen conditions = [(fr_dat['objekt'] == 'BW'),(fr_dat['objekt'] == 'DU'), (fr_dat['objekt'] == 'WB'),(fr_dat['objekt'] == 'WC'), (fr_dat['objekt'] == 'GM'),(fr_dat['objekt'] == 'SP'),(fr_dat['objekt'] == 'WM')] choices = list(range(7,0,-1)) fr_dat['order'] = np.select(conditions, choices, default=0) # Symbol-Nummer und maximale Symbolanzahl je Zeile ermitteln fr_dat['elem_nr'] = fr_dat.sort_values("order").groupby(['geschoss','schacht_fid']).cumcount()+1 fr_dat['elem_nr_max'] = fr_dat.groupby(['geschoss','schacht_fid'])['geschoss'].transform('size') # Breite je Symbol zuweisen choices = [11,5,4,4,4,4,4] #alte Breiten choices = [i/4 for i in choices] fr_dat['width'] = np.select(conditions, choices, default=0) # Breiten aufsummieren fr_dat['width_csum'] = fr_dat.sort_values("order").groupby(['geschoss','schacht_fid'])['width'].cumsum()-fr_dat['width'] fr_dat['x1'] = fr_dat.x-fr_dat.width_csum fr_dat['y1'] = 5*mx + fr_dat.y*20*mx #5 = Basisabstand von FOK // 20 = Geschosshöhe jeweils in mm fr_dat['symbol'] = "IBP_EW_"+fr_dat['objekt']+"_SCHN" ########################################### # zeichne den Schnitt ########################################### # Angaben in Millimeter band = {} band['hoehe'] = 8*mx band['titel_breite'] = 70*mx # Einheit = Millimeter * mx # my nur für Höhenanpassung oberhalb des Horizontes notwendig!! titelfelder = ['Station', 'Geländehöhe', 'Schachtsohle', 'Leitungsohle', 'Deckelhöhe', 'Länge', 'Gefälle', 'Material / DN', 'Punkt'] titelfelder_einhei = ['m', 'mNN','mNN','mNN','mNN','m','%.','',''] x_hor = bx+band['titel_breite'] # Starpunkt Zeichnung y_hor = by+len(titelfelder)*band['hoehe'] #OK Bänder ########################################### # Titelfelder Bänder ########################################### titelfelder_line_dxfatt = {'layer': "##IBP_Schnitt_Fett"} titelfelder_text_dxfatt = {'style': 'IBP_Norm', 'height': 5.0*mx, 'layer': "##IBP_Schnitt_Text_50", 'width': 0.7} s_msp.add_line((bx,by), (bx+band['titel_breite'], by+0), dxfattribs=titelfelder_line_dxfatt) for i, v in enumerate(titelfelder, 1): s_msp.add_line((bx+0, by+i*band['hoehe']), (bx+band['titel_breite'], by+i*band['hoehe']), dxfattribs=titelfelder_line_dxfatt) y_txt = (i)*band['hoehe']-band['hoehe']/2 s_msp.add_text(v+":", dxfattribs=titelfelder_text_dxfatt).set_pos((bx+5*mx, by+y_txt), align='MIDDLE_LEFT') if titelfelder_einhei[i-1] != '': s_msp.add_text("["+titelfelder_einhei[i-1]+"]", dxfattribs=titelfelder_text_dxfatt).set_pos((bx+band['titel_breite']-15*mx, by+y_txt), align='MIDDLE_RIGHT') s_msp.add_line((bx, by), (bx, by+i*band['hoehe']), dxfattribs=titelfelder_line_dxfatt) s_msp.add_line((bx+band['titel_breite']-10*mx, by), (bx+band['titel_breite']-10*mx, by+i*band['hoehe']), dxfattribs=titelfelder_line_dxfatt) s_msp.add_text("Horizont: {:.2f}mNN".format(hor), dxfattribs=titelfelder_text_dxfatt ).set_pos((bx+band['titel_breite']-10*mx, y_hor), align='BOTTOM_RIGHT') ########################################### # Inhalte Bänder ########################################### # Bänder anlegen: laeng = 0 laen = [0] band_beschr_dxfattrib = {'style': 'IBP_Norm', 'height': 2.5*mx, 'layer': "##IBP_Schnitt_Text_25", 'width': 0.7} band_beschr90_dxfattrib = {'style': 'IBP_Norm', 'height': 2.0*mx, 'layer': "##IBP_Schnitt_Text_20", 'width': 0.7, 'rotation': 90} band_schnr_dxfattrib = {'style': 'IBP_Norm', 'height': 3.5*mx, 'layer': "##IBP_Schnitt_Text_35", 'width': 0.7} band_linie_fein_dxfattrib = {'layer': "##IBP_Schnitt_Fein"} band_linie_fett_dxfattrib = {'layer': "##IBP_Schnitt_Fett"} # Leitungsdaten: # Vertikale Linie an der Basis s_msp.add_line((x_hor,by),(x_hor,y_hor), dxfattribs=band_linie_fein_dxfattrib) for i in ltg: xp = x_hor+laeng+i['dist']/2 # Schreibe Länge in Band zl = 6 # Zeilennummer s_msp.add_text("{:.2f}".format(i['dist']), dxfattribs=band_beschr_dxfattrib).set_pos((xp, by+(zl-.5)*band['hoehe']), align='MIDDLE_CENTER') # Schreibe Gef in Band zl = 7 # Zeilennummer s_msp.add_text("{:.2f}".format(i['gef']), dxfattribs=band_beschr_dxfattrib).set_pos((xp, by+(zl-.5)*band['hoehe']), align='MIDDLE_CENTER') # Schreibe Material / Dim in Band zl = 8 # Zeilennummer s_msp.add_text(i['mat_dim'], dxfattribs=band_beschr_dxfattrib).set_pos((xp, by+(zl-.5)*band['hoehe']), align='MIDDLE_CENTER') laeng = laeng + i['dist'] laen.append(laeng) s_msp.add_line((x_hor+laeng,by),(x_hor+laeng,y_hor), dxfattribs=band_linie_fein_dxfattrib) # Schreibe Sohlhöhen in Band zl = 4 # Zeilennummer s_msp.add_text("{:.2f}".format(i['sh_a']), dxfattribs=band_beschr90_dxfattrib).set_pos((x_hor+laeng-i['dist']+1*mx, by+(zl-0.9)*band['hoehe']), align='TOP_LEFT') s_msp.add_text("{:.2f}".format(i['sh_e']), dxfattribs=band_beschr90_dxfattrib).set_pos((x_hor+laeng-1*mx, by+(zl-0.9)*band['hoehe']), align='BOTTOM_LEFT') # Horizontale Einfassungen der Bänder s_msp.add_line((x_hor, by), (x_hor+laeng+20*mx, by), dxfattribs=band_linie_fett_dxfattrib) for i, v in enumerate(titelfelder, 1): s_msp.add_line((x_hor, by+i*band['hoehe']), (x_hor+laeng+20*mx, by+i*band['hoehe']), dxfattribs=band_linie_fett_dxfattrib) # Vertikale Einfassung der Bänder hinten s_msp.add_line((x_hor+laeng+20*mx, by), (x_hor+laeng+20*mx, by+i*band['hoehe']), dxfattribs=band_linie_fett_dxfattrib) # Punktdaten for i, j in enumerate(pkt): # Schreibe Name in Band zl = 9 # Zeilennummer s_msp.add_text(j['name'], dxfattribs=band_schnr_dxfattrib ).set_pos((x_hor+laen[i]+1*mx, by+(zl-.5)*band['hoehe']), align='MIDDLE_LEFT') # Schreibe DH in Band zl = 5 # Zeilennummer s_msp.add_text("{:.2f}".format(j['dh']), dxfattribs=band_beschr90_dxfattrib ).set_pos((x_hor+laen[i]+1*mx, by+(zl-.9)*band['hoehe']), align='TOP_LEFT') # Schreibe SH in Band zl = 3 # Zeilennummer s_msp.add_text("{:.2f}".format(j['sh']), dxfattribs=band_beschr90_dxfattrib ).set_pos((x_hor+laen[i]+1*mx, by+(zl-.9)*band['hoehe']), align='TOP_LEFT') # Schreibe Station in Band zl = 1 # Zeilennummer s_msp.add_text("{:.2f}".format(laen[i]), dxfattribs=band_beschr90_dxfattrib ).set_pos((x_hor+laen[i]+1*mx, by+(zl-.9)*band['hoehe']), align='TOP_LEFT') pos[by] = x_hor+laeng+20*mx+20*mx ########################################### # Zeichne Schnitt-Grafik ########################################### ueho = mx/my # Überhöhungsfaktor graf_linie_ltg = {} graf_linie_ltg['SW'] = {'layer': "##IBP_Schnitt_Leitung_SW"} graf_linie_ltg['RW'] = {'layer': "##IBP_Schnitt_Leitung_RW"} graf_linie_ltg['MW'] = {'layer': "##IBP_Schnitt_Leitung_MW"} graf_linie_ltg['Bestand SW'] = {'layer': "##IBP_Schnitt_Leitung_Best_SW"} graf_linie_ltg['Bestand RW'] = {'layer': "##IBP_Schnitt_Leitung_Best_RW"} graf_linie_ltg['Bestand MW'] = {'layer': "##IBP_Schnitt_Leitung_Best_MW"} graf_linie_schacht = {'layer': "##IBP_Schnitt_Schacht"} graf_linie_geb = {'layer': "##IBP_Schnitt_Gebaeude"} graf_symb_ew = {'xscale': 1, 'yscale': 1, 'rotation': 0, 'layer': 'KANAL-SW_Planung_Schnitt_Sym'} # zeichne Leitungen for i,j in enumerate(ltg): s_msp.add_line( (x_hor+laen[i], y_hor+(j['sh_a']-hor)*ueho), (x_hor+laen[i+1], y_hor+(j['sh_e']-hor)*ueho), dxfattribs=graf_linie_ltg[j['art']]) s_msp.add_line(( x_hor+laen[i], y_hor+(j['sh_a']-hor+j['di']/1000)*ueho), (x_hor+laen[i+1],y_hor+(j['sh_e']-hor+j['di']/1000)*ueho), dxfattribs=graf_linie_ltg[j['art']]) print(quer) for k in quer: if j['zu'] == k['zu1'] and j['ab'] == k['ab1']: s_msp.add_circle((x_hor+laen[i]+k['dist'], y_hor+(k['sh']-hor+k['dn']/2/1000)*ueho), #@ToDo bei Überhöhung eigentlich Ellipse!!!! k['dn']/2/1000, dxfattribs=graf_linie_ltg[k['art']]) #s_msp.add_ellipse # Zeichne Punkte for i,j in enumerate(pkt): x_a = x_hor+laen[i] #Aktuelle X-Position #vertikale Linie s_msp.add_line((x_a, y_hor),(x_a,y_hor+(max(j['dh'],j['sh'])-hor)*ueho), dxfattribs=band_linie_fein_dxfattrib) sh_e = ltg[i-1]['sh_a'] if i > 0 else j['sh'] dh = j['dh'] if j['dh'] > 0 else j['sh'] s_msp.add_line((x_a-j['dn']/2/1000, y_hor+(min(dh,j['sh'])-hor)*ueho), (x_a-j['dn']/2/1000, y_hor+((max(dh,j['sh'],sh_e)-hor)*ueho)), dxfattribs=graf_linie_schacht) s_msp.add_line((x_a+j['dn']/2/1000, y_hor+(min(dh,j['sh'])-hor)*ueho), (x_a+j['dn']/2/1000, y_hor+(max(dh,j['sh'],sh_e)-hor)*ueho), dxfattribs=graf_linie_schacht) s_msp.add_line((x_a-j['dn']/2/1000, y_hor+(min(dh,j['sh'])-hor)*ueho), (x_a+j['dn']/2/1000, y_hor+(min(dh,j['sh'])-hor)*ueho), dxfattribs=graf_linie_schacht) s_msp.add_line((x_a-j['dn']/2/1000, y_hor+(max(dh,j['sh'],sh_e)-hor)*ueho), (x_a+j['dn']/2/1000, y_hor+(max(dh,j['sh'],sh_e)-hor)*ueho), dxfattribs=graf_linie_schacht) # Wenn Fallrohr dann EW-Gegenstände zeichnen if j['symb'] == "Fallrohr": abst = 2.5*mx*ueho #45° gewinkelte Linie #Zeichne Fallrohre: xp = x_a-j['dn']/2/1000 yp = y_hor+(j['sh']-hor)*ueho points = [(xp,yp),(xp-abst,yp+abst),(xp-abst,yp+50*mx*ueho)] s_msp.add_lwpolyline(points, dxfattribs=graf_linie_ltg[j["art"]]) xp = x_a+j['dn']/2/1000 points = [(xp,yp),(xp-abst,yp+abst),(xp-abst,yp+50*mx*ueho)] s_msp.add_lwpolyline(points, dxfattribs=graf_linie_ltg[j["art"]]) #Zeichne Gegenstände mit Leitung for index, row in fr_dat.iterrows(): xp = x_a + row['x1'] - abst - 8*mx #8*mx = Abstand von der Fallleitung yp = y_hor + (fok-hor + row['y1'])*ueho if row['schacht_fid'] == j['fid']: s_msp.add_blockref(row['symbol'], [xp,yp], dxfattribs=graf_symb_ew) #Leitung horizontal und Geschosslinie if(row['elem_nr'] == row['elem_nr_max']): # Leitung x2 = x_a + row['x'] - 2*abst # Abzgl. 2x 45° Schräge points = [(xp,yp), (x2,yp), (x2+abst,yp-abst)] s_msp.add_lwpolyline(points, dxfattribs=graf_linie_ltg["SW"]) # Gebäudelinie yp = y_hor + ((fok-hor)*10*my + 20*row['y']*mx)*ueho s_msp.add_line((xp-5*abst,yp),(x2+5*abst,yp), dxfattribs=graf_linie_geb) ########################################### # Layout-Rahmen ########################################### s_msp.add_line( (bx-10*mx ,by-10*mx), (pos[by]-10*mx ,by-10*mx), dxfattribs={'layer': "##IBP_nicht_drucken"}) s_doc.saveas(schnitte_filename) ibp_dxf_to_dwg(schnitte_filename.split("/")[-1],schnitte_filename.replace(schnitte_filename.split("/")[-1],"")) #ibp_dxf_to_dwg(schnitte_filename.split("/")[-1]) def reduce_list(input_list: list) -> list: """ Entfernung der Teilstücke welche in den vorangegangenen Pfaden schon beeinhaltet sind :param input_list: Liste mit Listen welche alle Pfade beinhaltet :return: Reduzierte Liste, Teilstücke wurden entfernt """ output_list = [] seen_values = set() for group in sorted(input_list,key=len)[::-1]: if not set(group).issubset(seen_values): output_list.append(group) seen_values.update(group) return output_list def ibp_calc_netz(): #-- Bestimme Schachtanschlüsse und Länge gpkg_con.executeSql("""UPDATE haltung SET zul_sch_fid = (SELECT fid FROM schacht s WHERE distance(geomfromgpb(s.geom), startpoint(geomfromgpb(haltung.geom))) < 0.1 LIMIT 1), abl_sch_fid = (SELECT fid FROM schacht s WHERE distance(geomfromgpb(s.geom), endpoint(geomfromgpb(haltung.geom))) < 0.1 LIMIT 1);""") #-- Reset zu Beginn gpkg_con.executeSql("UPDATE schacht SET sh = 0;") gpkg_con.executeSql("UPDATE haltung SET zul_sh = 0, abl_sh = 0, c_laenge = ST_Length(geomfromgpb(geom)), gefaelle = gefaelle_vorg;") #-- Setze fixierte Sohlhöhen gpkg_con.executeSql("UPDATE schacht SET sh = sh_fix WHERE sh_fix > 0;") #-- Setze fixierte Schachthöhen auf Haltungen gpkg_con.executeSql("""UPDATE haltung SET zul_sh = (SELECT sh_fix FROM schacht WHERE schacht.fid = haltung.zul_sch_fid) WHERE haltung.zul_sch_fid IN (SELECT schacht.fid FROM schacht WHERE schacht.sh_fix > 0);""") gpkg_con.executeSql("""UPDATE haltung SET abl_sh = (SELECT sh_fix FROM schacht WHERE schacht.fid = haltung.abl_sch_fid) WHERE haltung.abl_sch_fid in (SELECT schacht.fid FROM schacht WHERE schacht.sh_fix > 0);""") gpkg_con.executeSql("UPDATE haltung SET zul_sh = zul_sh_fix WHERE zul_sh_fix > 0;") gpkg_con.executeSql("UPDATE haltung SET abl_sh = abl_sh_fix WHERE abl_sh_fix > 0;") graph = nx.DiGraph() cols = ["zul_sch_fid", "abl_sch_fid"] query = "SELECT "+",".join(cols)+" FROM haltung" res = gpkg_con.executeSql(query) dat = [dict(zip(cols, row)) for row in res] #print(dat) for row in dat: graph.add_edge(row["zul_sch_fid"], row["abl_sch_fid"]) cols = ["schacht_bezug", "zul_sch_fid", "abl_sch_fid"] query = "SELECT "+",".join(cols)+" FROM haltung WHERE (schacht_bezug > 0) and (zul_sh = 0 or abl_sh = 0 or zul_sh is null or abl_sh is null) ORDER BY schacht_bezug" res = gpkg_con.executeSql(query) dat = [dict(zip(cols, row)) for row in res] #print(dat) """ Nachfolgender Code ist ggf. in eine Schleife zu packen, Wenn eine Abhängigkeit sich erst löst wenn andere Berechnungen fertig gestellt sind. Ggf. muss auch die initial-Abfrage noch leicht modifiziert werden """ paths = [] for i in dat: source_fid = i['schacht_bezug'] target_fid = i['zul_sch_fid'] #print(source_fid, target_fid) try: path = nx.shortest_path(graph, source=source_fid, target=target_fid) path.append(i['abl_sch_fid']) path.insert(0,1) #print("oben", path, source_fid, target_fid) paths.append(path) except nx.NetworkXNoPath: try: path = nx.shortest_path(graph, source=target_fid, target=source_fid) path = path[::-1] path.insert(0,-1) #print("unten", path, source_fid, target_fid) paths.append(path) except nx.NetworkXNoPath: print("no path", source_fid, target_fid) except: print("error", source_fid, target_fid, i) break cnt = 0 cnt_query = "SELECT COUNT(*) FROM haltung WHERE abl_sh = 0 or zul_sh = 0" while cnt != gpkg_con.executeSql(cnt_query)[0][0]: cnt = gpkg_con.executeSql(cnt_query)[0][0] for path in paths: direction = path[0] path = path[1:] ## von Oben nach unten: if direction == 1: for i in range(len(path)-1): query = """UPDATE haltung SET abl_sh = zul_sh-gefaelle/1000*c_laenge WHERE zul_sch_fid={0} and abl_sch_fid={1} and zul_sh > 0;""".format(path[i],path[i+1]) res = gpkg_con.executeSql(query) if i < len(path)-2: ## ggf. anpassen query = """UPDATE haltung SET zul_sh = (SELECT abl_sh FROM haltung WHERE zul_sch_fid={0} and abl_sch_fid={1} and abl_sh > 0) WHERE zul_sch_fid ={1} and abl_sch_fid = {2};""".format(path[i],path[i+1],path[i+2]) #print(query) res = gpkg_con.executeSql(query) ## von unten nach oben: elif direction == -1: for i in range(len(path)-1): query = """UPDATE haltung SET zul_sh = abl_sh+gefaelle/1000*c_laenge WHERE abl_sch_fid={0} and zul_sch_fid={1} and abl_sh > 0;""".format(path[i],path[i+1]) res = gpkg_con.executeSql(query) #if path[i] == 198 and path[i+1] == 184: # print(query) if i < len(path)-2: ## ggf. anpassen query = """UPDATE haltung SET abl_sh = (SELECT zul_sh FROM haltung WHERE abl_sch_fid={0} and zul_sch_fid={1} and zul_sh > 0) WHERE abl_sch_fid ={1} and zul_sch_fid = {2};""".format(path[i],path[i+1],path[i+2]) res = gpkg_con.executeSql(query) gpkg_con.executeSql("""UPDATE haltung SET zul_sh = (SELECT sh+stichmas FROM schacht WHERE schacht.fid = haltung.zul_sch_fid) WHERE haltung.zul_sh = 0 or haltung.zul_sh IS NULL;""") gpkg_con.executeSql("""UPDATE haltung SET abl_sh = (SELECT sh+stichmas FROM schacht WHERE schacht.fid = haltung.abl_sch_fid) WHERE haltung.abl_sh = 0 or haltung.abl_sh IS NULL;""") gpkg_con.executeSql("""UPDATE schacht SET sh = IIF(sh_fix > 0, sh_fix, (SELECT min(ber_sh) FROM ( SELECT abl_sh ber_sh FROM haltung WHERE abl_sch_fid = schacht.fid and abl_sh > 0 UNION SELECT zul_sh ber_sh FROM haltung WHERE zul_sch_fid = schacht.fid and zul_sh > 0 ) WHERE ber_sh > 0)-stichmas);""") gpkg_con.executeSql("""UPDATE haltung SET gefaelle = (zul_sh - abl_sh)/c_laenge*1000 WHERE zul_sh > 0 and abl_sh > 0""") gpkg_con.executeSql("""UPDATE haltung SET gefaelle = NULL WHERE zul_sh = 0 or abl_sh = 0 or zul_sh is null or abl_sh is null""") ################################################################################################################################################ ################################################################################################################################################ # Berechnet die Hydraulik der Leitungen # Ausgangsdaten-Tabelle: haltung # Ergebnis-Tablle: haltung_calc_hydraulik def ibp_hydraulik(ibpprj = ""): con = sqlite3.connect(inp_file) query = "PRAGMA table_info(haltung)" col = gpkg_con.executeSql(query) coln = [] for i in col: coln.append(i[1]) coln = ['fid','di','gefaelle','Qtot','ibpprj'] query = 'SELECT '+",".join(coln)+' FROM haltung WHERE 0<'+" and 0 < ".join(coln)+' ' #query = 'SELECT '+",".join(coln)+' FROM haltung WHERE ibpprj = "{0}"'.format(ibpprj) res = gpkg_con.executeSql(query) df = pd.DataFrame(res, columns = coln) df['Av']=(df['di']/1000)**2/4*np.pi nu = 0.00000131 g = 9.81 kb = 0.50 df = df.dropna() df['vv'] = -2*np.log10(2.51*nu/(4*df['di']/4000*np.sqrt(8*g*df['di']/4000*df['gefaelle']/1000))+kb/(1000*(14.84*df['di']/4000)))*np.sqrt(8*g*df['di']/4000*df['gefaelle']/1000) df['Qv'] = df['Av']*df['vv']*1000 df['ausl'] = df['Qtot']/df['Qv'] def ber_ht(df,ht): di_m = df['di']/1000 r_m = di_m/2 nu = 0.00000131 g = 9.81 kb = 0.50 #Kreissegment: # Quelle Wikipedia: https://de.wikipedia.org/wiki/Kreissegment # At = r_m**2*np.arccos(1-ht/r_m)-(r_m-ht)*np.sqrt(2*r_m*ht-ht**2) At = (df['di']/1000)**2/8*((4*np.arcsin(np.emath.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.emath.sqrt(ht/(df['di']/1000)))))) #Iu = 0.5*di_m*(4*np.arcsin(np.sqrt(ht/di_m))) Iu = 0.5*df['di']/1000*(4*np.arcsin(np.emath.sqrt(ht/(df['di']/1000)))) #Iu = Iu.fillna(0) rhy = At/Iu #vt = -2*np.log10(2.51*nu/(4*rhy*np.sqrt(8*g*rhy*df['gefaelle']/1000))+kb/(1000*14.84*rhy))*np.sqrt(8*g*rhy*df['gefaelle']/1000) vt = -2*np.log10(2.51*nu/(4*rhy*np.emath.sqrt(8*g*rhy*df['gefaelle']/1000))+kb/(1000*(14.84*rhy)))*np.emath.sqrt(8*g*rhy*df['gefaelle']/1000) #vt = vt.fillna(0) Qt=At*vt*1000 return Qt df['ht'] = np.ones(len(df['ausl'])) #func = lambda ht : df['Qtot'] - (((df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))*(-2*np.log10(2.51*nu/(4*(((df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))/(0.5*df['di']/1000*(4*np.arcsin(np.sqrt(ht/(df['di']/1000))))))*np.sqrt(8*g*(((df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))/(0.5*df['di']/1000*(4*np.arcsin(np.sqrt(ht/(df['di']/1000))))))*df['gefaelle']/1000))+kb/(1000*(14.84*(((df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))/(0.5*df['di']/1000*(4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))))*np.sqrt(8*g*(((df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(ht/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(ht/(df['di']/1000)))))))/(0.5*df['di']/1000*(4*np.arcsin(np.sqrt(ht/(df['di']/1000))))))*df['gefaelle']/1000))*1000) for index, row in df.iterrows(): if row['Qtot'] < 0.01: df['ht'][index] = 0 else: func = lambda ht : row['Qtot'] - ber_ht(row,ht) erg = scipy.optimize.fsolve(func, 0.001, full_output=True) if erg[2] > 1: erg = scipy.optimize.fsolve(func, 0.01, full_output=True) if erg[2] > 1: print(index, " ", row['fid'], " ", erg) df['ht'][index] = erg[0] #df['ht'] = scipy.optimize.fsolve(func, np.ones(len(df['ausl']))*0.1) df['h/d'] = df['ht']/df['di']*1000 df['At'] = (df['di']/1000)**2/8*((4*np.arcsin(np.sqrt(df['ht']/(df['di']/1000))))-np.sin((4*np.arcsin(np.sqrt(df['ht']/(df['di']/1000)))))) df['Iu'] = 0.5*df['di']/1000*(4*np.arcsin(np.sqrt(df['ht']/(df['di']/1000)))) df['rhy'] = df['At']/df['Iu'] df['vt'] = -2*np.log10(2.51*nu/(4*df['rhy']*np.sqrt(8*g*df['rhy']*df['gefaelle']/1000))+kb/(1000*(14.84*df['rhy'])))*np.sqrt(8*g*df['rhy']*df['gefaelle']/1000) df['Qt'] = df['At']*df['vt']*1000 df['tau'] = 1000*g*df['rhy']*df['gefaelle']/1000 df.to_sql('haltung_calc_hydraulik',con,if_exists='replace')