You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

782 lines
38 KiB
Python

3 months ago
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')