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

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')