Upload zwischenstand
parent
480f434688
commit
f2c4862502
@ -0,0 +1,176 @@
|
||||
|
||||
|
||||
import toml
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
toml_string = """
|
||||
|
||||
[kanalplanung]
|
||||
|
||||
inp_file = "C:/Daten/nc/Ingenieurbüro/20 Projekte/Kanalplanung/kanalplanung.gpkg"
|
||||
"""
|
||||
|
||||
prj = '0122' # Projektnummer als Filter
|
||||
|
||||
|
||||
|
||||
#toml.load("config.toml")
|
||||
cfg = toml.loads(toml_string)
|
||||
|
||||
md = QgsProviderRegistry.instance().providerMetadata("ogr")
|
||||
gpkg_con = md.createConnection( cfg['kanalplanung']['inp_file'], {})
|
||||
#gpkg_con.fields('public','schacht')
|
||||
|
||||
query = "SELECT * FROM schacht_versickerung"
|
||||
|
||||
col = ['s.ezg_total_Aum','sv.fz','sv.di','sv.wandst','sv.da','sv.n','sv.r_5','sv.tiefe','sv.r_mas','sv.D_mas','sv.z_v','sv.Q_s','sv.D']
|
||||
## col_dict = {j:i for i,j in enumerate(col)}
|
||||
|
||||
#Ermittle Index von Objekt
|
||||
#col.index('sv.di')
|
||||
|
||||
col_str = ''
|
||||
|
||||
|
||||
query = "UPDATE schacht_versickerung SET d_a = d_i+2*wandst"
|
||||
res = gpkg_con.execSql(query)
|
||||
|
||||
query = """UPDATE schacht_versickerung SET
|
||||
k_f = (SELECT
|
||||
pr.kf
|
||||
FROM schacht s JOIN projekt pr ON pr.nr = s.ibpprj
|
||||
WHERE s.fid = schacht_versickerung.schacht_fid) WHERE k_f is NULL
|
||||
|
||||
|
||||
|
||||
"""
|
||||
res = gpkg_con.execSql(query)
|
||||
|
||||
query = """SELECT
|
||||
s.fid as fid,
|
||||
sv.schacht_fid,
|
||||
s.ezg_total_Aum,
|
||||
sv.f_z,
|
||||
sv.d_i,
|
||||
sv.wandst,
|
||||
sv.d_a,
|
||||
sv.n,
|
||||
sv.r_5,
|
||||
sv.tiefe,
|
||||
sv.r_mas,
|
||||
sv.D_mas,
|
||||
sv.z_v,
|
||||
sv.Q_s,
|
||||
sv.D,
|
||||
sv.k_f
|
||||
FROM schacht s
|
||||
JOIN schacht_versickerung sv ON s.fid = sv.schacht_fid
|
||||
JOIN projekt pr ON pr.nr = s.ibpprj
|
||||
"""
|
||||
|
||||
# Spaltennamen in das Ergebnis-Array integrieren
|
||||
dat = []
|
||||
|
||||
res = gpkg_con.execSql(query)
|
||||
for row in res.rows():
|
||||
d = {}
|
||||
for i,j in enumerate(res.columns()):
|
||||
d[j] = row[i]
|
||||
dat.append(d)
|
||||
|
||||
#res = gpkg_con.executeSql(query)
|
||||
#res = res[0]
|
||||
#res_dict = {j:res[i] for i,j in enumerate(col)}
|
||||
#
|
||||
#i = res[0]
|
||||
#
|
||||
#D = i[13]
|
||||
#r = i[7].replace("[","").replace("]","").replace("\n","").split(";")
|
||||
#z = []
|
||||
#
|
||||
#
|
||||
#
|
||||
#def z_v(r, D):
|
||||
# (A_u * r - math.pi * d_a**2/4 * k_f/2) / (d_i**2 * math.pi / 4 * D * f_z + d_a * math.pi * k_f/4) * n
|
||||
|
||||
|
||||
for d in dat:
|
||||
#via Numpy:
|
||||
r = np.fromstring(d['r_5'].replace(',','.'), sep=';')
|
||||
D = np.fromstring(d['D'].replace(',','.'), sep=';')
|
||||
|
||||
z = (d['ezg_total_Aum']*10**-7 * r - math.pi * d['d_a']**2/4 * d['k_f']/2) / (d['d_i']**2 * math.pi / (4 * D * 60 * d['f_z']) + d['d_a'] * math.pi * d['k_f']/4) * d['n']
|
||||
|
||||
z_max = z.max()
|
||||
idx = z.argmax()
|
||||
D_z_max = D[idx]
|
||||
r_z_max = r[idx]
|
||||
Q_s = (math.pi*d['d_i']**2/4+math.pi*d['d_i']*z_max/2)*d['n'] * d['k_f']/2
|
||||
|
||||
#r = d['r_5'].replace("[","").replace("]","").replace(",",".").replace("\n","").split(";")
|
||||
#r = [float(i) for i in r]
|
||||
#D = d['D'].replace("[","").replace("]","").replace("\n","").split(";")
|
||||
#D = [float(i) for i in D]
|
||||
|
||||
#z = []
|
||||
#
|
||||
#for i, j in enumerate(D):
|
||||
# #z.append(z_v(r[i], j))
|
||||
# z.append(
|
||||
# (d['ezg_total_Aum']*10**-7 * r[i] - math.pi * d['da']**2/4 * d['kf']/2) / (d['di']**2 * math.pi / (4 * D[i] * 60 * d['fz']) + d['da'] * math.pi * d['kf']/4) * d['n'])
|
||||
|
||||
#z_max = max(z)
|
||||
#idx = z.index(z_max)
|
||||
#D_z_max = D[idx]
|
||||
#r_z_max = r[idx]
|
||||
|
||||
#z_str = np.array2string(r)
|
||||
|
||||
query = """UPDATE schacht_versickerung SET
|
||||
z = '{}',
|
||||
z_v = {},
|
||||
r_mas = {},
|
||||
D_mas = {},
|
||||
Q_s = {}
|
||||
WHERE schacht_fid = {}""".format(np.array2string(z).replace("[","").replace("]","").replace(" ",";"), z_max, r_z_max, D_z_max, Q_s, d['schacht_fid'])
|
||||
print(query)
|
||||
gpkg_con.execSql(query)
|
||||
|
||||
#https://github.com/geopandas/geopandas/issues/2794
|
||||
#https://gist.github.com/MaxDragonheart/46445a150aac9d528dadd2ec877203a5
|
||||
#https://github.com/geopandas/geopandas/issues/1035
|
||||
|
||||
|
||||
#
|
||||
# PLOT-DIAGRAMM
|
||||
#
|
||||
|
||||
|
||||
plt.style.use('_mpl-gallery')
|
||||
|
||||
# make data
|
||||
x = D
|
||||
x = np.append(0, x)
|
||||
y = z
|
||||
y = np.append(0, y)
|
||||
|
||||
# plot
|
||||
fig, ax = plt.subplots(facecolor='white', figsize=[8/2.54*1.4, 8/2.54*1.4], dpi=100)
|
||||
#fig.subplots_adjust(top=0.15,bottom=0.15,left=0.15,right=0.15)
|
||||
|
||||
ax.plot(x, y, linewidth=2.0)
|
||||
|
||||
ax.set_xlim(0, D_z_max+120)
|
||||
ax.set_xlabel('Dauerstufe [min]')
|
||||
ax.set_ylim(0, z_max+1)
|
||||
ax.set_ylabel('Wasserstand [m]')
|
||||
ax.set_title('Schachtversickerung')
|
||||
|
||||
ax
|
||||
|
||||
#plt.show()
|
||||
plt.savefig('C:\\Daten\\nc\\Ingenieurbüro\\20 Projekte\\Kanalplanung\\Grafiken\\berechnet\\a138-schachtversickerung_{}.png'.format(d['schacht_fid']), bbox_inches="tight", transparent=True)
|
||||
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
/***************************************************************************
|
||||
GemeindeMessdatenImport
|
||||
A QGIS plugin
|
||||
Importiert Messdaten
|
||||
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
|
||||
-------------------
|
||||
begin : 2024-02-01
|
||||
copyright : (C) 2024 by Sebastian Pertl
|
||||
email : sebastian.pertl@fridolfing.bayern.de
|
||||
git sha : $Format:%H$
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
This script initializes the plugin, making it known to QGIS.
|
||||
"""
|
||||
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
def classFactory(iface): # pylint: disable=invalid-name
|
||||
"""Load GemeindeMessdatenImport class from file GemeindeMessdatenImport.
|
||||
|
||||
:param iface: A QGIS interface instance.
|
||||
:type iface: QgsInterface
|
||||
"""
|
||||
#
|
||||
from .ibpTools import ibpTools
|
||||
return ibpTools(iface)
|
@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
[qgs_cad]
|
||||
import_layer_prefix = "_IBP_QIN_"
|
||||
|
||||
|
||||
|
||||
[iface]
|
||||
host = "localhost"
|
||||
port = 8080
|
||||
debug = false
|
||||
|
||||
|
||||
|
@ -0,0 +1,294 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
/***************************************************************************
|
||||
GemeindeMessdatenImport
|
||||
A QGIS plugin
|
||||
Importiert Messdaten im TXT-Format in die Gemeindeeigene Messdaten-Datenbank.
|
||||
|
||||
|
||||
-------------------
|
||||
begin : 2024-02-01
|
||||
git sha : $Format:%H$
|
||||
copyright : (C) 2024 by Sebastian Pertl
|
||||
email : sebastian.pertl@fridolfing.bayern.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
"""
|
||||
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtWidgets import QAction, QComboBox
|
||||
|
||||
from qgis.PyQt import uic
|
||||
from qgis.PyQt import QtWidgets
|
||||
from qgis.PyQt.QtWidgets import QFileDialog
|
||||
|
||||
from qgis.core import QgsVectorLayer, QgsVectorFileWriter, QgsProviderRegistry
|
||||
from qgis.utils import iface
|
||||
|
||||
# Initialize Qt resources from file resources.py
|
||||
from .resources import *
|
||||
# Import the code for the dialog
|
||||
#from .gdeMessdatenImport_dialog import GemeindeMessdatenImportDialog
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
|
||||
class GemeindeMessdatenImport:
|
||||
"""QGIS Plugin Implementation."""
|
||||
|
||||
def __init__(self, iface):
|
||||
"""Constructor.
|
||||
|
||||
:param iface: An interface instance that will be passed to this class
|
||||
which provides the hook by which you can manipulate the QGIS
|
||||
application at run time.
|
||||
:type iface: QgsInterface
|
||||
"""
|
||||
# Save reference to the QGIS interface
|
||||
self.iface = iface
|
||||
# initialize plugin directory
|
||||
self.plugin_dir = os.path.dirname(__file__)
|
||||
|
||||
# Declare instance attributes
|
||||
# Eintrag Menüband Oben
|
||||
self.actions = []
|
||||
self.menu = u'&Gemeinde Messdaten Import'
|
||||
|
||||
# Check if plugin was started the first time in current QGIS session
|
||||
# Must be set in initGui() to survive plugin reloads
|
||||
self.first_start = None
|
||||
|
||||
def initGui(self):
|
||||
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
|
||||
|
||||
#
|
||||
self.toolBar = self.iface.addToolBar("Gemeinde Pertl tools")
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_txt.png')
|
||||
self.act1 = QAction(QIcon(icon_path), u'Import Messdaten', self.iface.mainWindow())
|
||||
self.act1.triggered.connect(self.run1)
|
||||
self.toolBar.addAction(self.act1)
|
||||
self.iface.addPluginToMenu(self.menu, self.act1)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_dupl.png')
|
||||
self.act2 = QAction(QIcon(icon_path), u'Lösche Vorhandene', self.iface.mainWindow())
|
||||
self.act2.triggered.connect(self.run2)
|
||||
self.toolBar.addAction(self.act2)
|
||||
self.iface.addPluginToMenu(self.menu, self.act2)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_db.png')
|
||||
self.act3 = QAction(QIcon(icon_path), u'Gemeinde Übertrag', self.iface.mainWindow())
|
||||
self.act3.triggered.connect(self.run3)
|
||||
self.toolBar.addAction(self.act3)
|
||||
self.iface.addPluginToMenu(self.menu, self.act3)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_db.png')
|
||||
self.act4 = QComboBox(self.iface.mainWindow())
|
||||
self.act4.addItem('KG')
|
||||
self.act4.addItem('EG')
|
||||
self.act4.addItem('1.OG')
|
||||
self.act4.addItem('2.OG')
|
||||
self.act4.addItem('3.OG')
|
||||
self.act4.currentTextChanged.connect(self.run4)
|
||||
self.toolBar.addWidget(self.act4)
|
||||
#self.toolBar.addAction(self.act4)
|
||||
#self.iface.addPluginToMenu(self.menu, self.act4)
|
||||
|
||||
self.first_start = True
|
||||
|
||||
|
||||
def unload(self):
|
||||
"""Removes the plugin menu item and icon from QGIS GUI."""
|
||||
for action in self.actions:
|
||||
self.iface.removePluginMenu(u'&Gemeinde Messdaten Import', action)
|
||||
self.iface.removeToolBarIcon(action)
|
||||
|
||||
def run_init(self):
|
||||
# Create the dialog with elements (after translation) and keep reference
|
||||
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
|
||||
if self.first_start == True:
|
||||
self.first_start = False
|
||||
self.dlg = GemeindeMessdatenImportDialog()
|
||||
|
||||
|
||||
def run1(self):
|
||||
"""Run method that performs all the real work"""
|
||||
|
||||
self.run_init()
|
||||
self.dlg.run()
|
||||
|
||||
result = True
|
||||
if result:
|
||||
# Do something useful here - delete the line containing pass and
|
||||
# substitute with your code.
|
||||
pass
|
||||
|
||||
def run2(self):
|
||||
"""Run method that performs all the real work"""
|
||||
|
||||
self.run_init()
|
||||
self.dlg.run_del_dup()
|
||||
|
||||
result = True
|
||||
if result:
|
||||
# Do something useful here - delete the line containing pass and
|
||||
# substitute with your code.
|
||||
pass
|
||||
|
||||
def run3(self):
|
||||
"""Run method that performs all the real work"""
|
||||
|
||||
self.run_init()
|
||||
self.dlg.run_save()
|
||||
|
||||
result = True
|
||||
if result:
|
||||
# Do something useful here - delete the line containing pass and
|
||||
# substitute with your code.
|
||||
pass
|
||||
|
||||
def run4(self):
|
||||
print(self.act4.currentIndex())
|
||||
print(self.act4.currentText())
|
||||
|
||||
|
||||
class GemeindeMessdatenImportDialog():
|
||||
def __init__(self, parent=None):
|
||||
"""Constructor."""
|
||||
|
||||
self.inp_file = 'T:/RIWA-GIS/Layer/fridolfing.gpkg'
|
||||
|
||||
self.md = QgsProviderRegistry.instance().providerMetadata("ogr")
|
||||
self.con = self.md.createConnection( self.inp_file, {})
|
||||
|
||||
|
||||
def run(self):
|
||||
|
||||
qfd = QFileDialog()
|
||||
filename = QFileDialog.getOpenFileName(qfd, "Wähle Vermessungsdaten","::{645ff040-5081-101b-9f08-00aa002f954e}", '*.txt')
|
||||
|
||||
csv = filename[0]
|
||||
rutacsv = 'file:///' + csv + '?delimiter=,&xField=field3&yField=field2'
|
||||
tabla = QgsVectorLayer(rutacsv, os.path.basename(csv), 'delimitedtext')
|
||||
|
||||
opt = QgsVectorFileWriter.SaveVectorOptions()
|
||||
opt.EditionCapability = QgsVectorFileWriter.CanAddNewLayer
|
||||
opt.layerName = "messdaten_imp"
|
||||
opt.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
|
||||
QgsVectorFileWriter.writeAsVectorFormat(tabla, self.inp_file, opt)
|
||||
|
||||
# Datensätze bereinigen
|
||||
query = """UPDATE messdaten_imp SET
|
||||
field6 = replace(field6 ,"HSDV:",""),
|
||||
field7 = replace(field7 ,"VSDV:",""),
|
||||
field8 = replace(field8 ,"STATUS:",""),
|
||||
field9 = replace(field9 ,"SATS:",""),
|
||||
field10 = replace(field10,"AGE:",""),
|
||||
field11 = replace(field11,"PDOP:",""),
|
||||
field12 = replace(field12,"HDOP:",""),
|
||||
field13 = replace(field13,"VDOP:",""),
|
||||
field14 = replace(field14,"TDOP:",""),
|
||||
field15 = replace(field15,"GDOP:",""),
|
||||
field16 = replace(field16,"NSDV:",""),
|
||||
field17 = replace(field17,"ESDV:",""),
|
||||
field18 = replace(field18,"DATE:",""),
|
||||
field19 = replace(field19,"TIME:","");"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
## Erzeuge Geometrie für Vorschau
|
||||
#query = """UPDATE messdaten_imp SET geom = AsGPB(setsrid(makepoint(field3, field2), 25832));"""
|
||||
#con.executeSql(query)
|
||||
|
||||
# Datum formatieren
|
||||
query = """UPDATE messdaten_imp SET field18 = substr(field18,7,4)||'-'||substr(field18,1,2)||'-'||substr(field18,4,2);"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
iface.mapCanvas().refreshAllLayers()
|
||||
|
||||
def run_del_dup(self):
|
||||
# Duplikate löschen
|
||||
query = """DELETE FROM messdaten_imp WHERE field3 || field2 || field4 in (SELECT rw || hw || höhe FROM messdaten);"""
|
||||
self.con.executeSql(query)
|
||||
query = """DELETE FROM messdaten_imp WHERE field1 in (SELECT Nummer FROM messdaten);"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
iface.mapCanvas().refreshAllLayers()
|
||||
|
||||
|
||||
def run_save(self):
|
||||
|
||||
# Daten übertragen
|
||||
query = """INSERT INTO
|
||||
messdaten
|
||||
(
|
||||
"fid",
|
||||
"geom",
|
||||
"Nummer",
|
||||
"RW",
|
||||
"HW",
|
||||
"Höhe",
|
||||
"Beschreibung",
|
||||
"HSDV",
|
||||
"VSDV",
|
||||
"STATUS",
|
||||
"SATS",
|
||||
"AGE",
|
||||
"PDOP",
|
||||
"HDOP",
|
||||
"VDOP",
|
||||
"TDOP",
|
||||
"GDOP",
|
||||
"NSDV",
|
||||
"ESDV",
|
||||
"aufnahme_dat",
|
||||
"aufnahme_uhr",
|
||||
"import_dat",
|
||||
"Anmerkung",
|
||||
"Quelle"
|
||||
)
|
||||
SELECT
|
||||
NULL,
|
||||
AsGPB(setsrid(makepoint(field3, field2), 25832)),
|
||||
field1,
|
||||
field3,
|
||||
field2,
|
||||
field4,
|
||||
field5,
|
||||
field6 ,
|
||||
field7 ,
|
||||
field8 ,
|
||||
field9 ,
|
||||
field10,
|
||||
field11,
|
||||
field12,
|
||||
field13,
|
||||
field14,
|
||||
field15,
|
||||
field16,
|
||||
field17, --ESDV
|
||||
field18,
|
||||
field19,
|
||||
DATE('now'),
|
||||
'',
|
||||
'Vermessung Bauhof'
|
||||
FROM messdaten_imp;"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
# Anzahl der Objekte aktuallisieren
|
||||
query = """DELETE FROM messdaten_imp WHERE field1 in (SELECT Nummer FROM messdaten);"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
# Import-Tabelle leeren
|
||||
query = """DELETE FROM messdaten_imp;"""
|
||||
self.con.executeSql(query)
|
||||
|
||||
iface.mapCanvas().refreshAllLayers()
|
@ -0,0 +1,475 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
/***************************************************************************
|
||||
GemeindeMessdatenImport
|
||||
A QGIS plugin
|
||||
Importiert Messdaten im TXT-Format in die Gemeindeeigene Messdaten-Datenbank.
|
||||
|
||||
|
||||
-------------------
|
||||
begin : 2024-02-01
|
||||
git sha : $Format:%H$
|
||||
copyright : (C) 2024 by Sebastian Pertl
|
||||
email : sebastian.pertl@fridolfing.bayern.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
"""
|
||||
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtWidgets import QAction, QComboBox
|
||||
|
||||
from qgis.PyQt import uic
|
||||
from qgis.PyQt import QtWidgets
|
||||
from qgis.PyQt.QtWidgets import QFileDialog, QMessageBox, QInputDialog, QLineEdit
|
||||
|
||||
#from qgis.core import QgsVectorLayer, QgsVectorFileWriter, QgsProviderRegistry
|
||||
#from qgis.core import QgsProject, QgsFeature
|
||||
from qgis.core import *
|
||||
from qgis.utils import iface
|
||||
import qgis.core
|
||||
|
||||
import toml
|
||||
|
||||
# Initialize Qt resources from file resources.py
|
||||
# from .resources import *
|
||||
# Import the code for the dialog
|
||||
#from .gdeMessdatenImport_dialog import GemeindeMessdatenImportDialog
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
import ezdxf
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import networkx as nx
|
||||
import math
|
||||
import scipy
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import win32com.client
|
||||
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
import time
|
||||
|
||||
hostName = "localhost"
|
||||
serverPort = 8080
|
||||
|
||||
|
||||
file_path = "D:/Daten/nc/Ingenieurbüro/98-CAD-Daten/Tools-QGIS/ibpTools/"
|
||||
with open(file_path + 'config.toml', 'r') as f:
|
||||
CFG = toml.load(f)
|
||||
|
||||
|
||||
class MyServer(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
|
||||
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
|
||||
self.wfile.write(bytes("<body>", "utf-8"))
|
||||
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
|
||||
self.wfile.write(bytes("</body></html>", "utf-8"))
|
||||
|
||||
basepath = os.path.dirname(os.path.realpath(__file__))
|
||||
TEIGHA_PATH = basepath.replace("\\","/") + "/Teigha File Converter 4.3.2/TeighaFileConverter.exe"
|
||||
|
||||
|
||||
tmp_folder = r"C:/tmp"
|
||||
|
||||
|
||||
class ibpTools:
|
||||
"""QGIS Plugin Implementation."""
|
||||
|
||||
def __init__(self, iface):
|
||||
"""Constructor.
|
||||
|
||||
:param iface: An interface instance that will be passed to this class
|
||||
which provides the hook by which you can manipulate the QGIS
|
||||
application at run time.
|
||||
:type iface: QgsInterface
|
||||
"""
|
||||
# Save reference to the QGIS interface
|
||||
self.iface = iface
|
||||
# initialize plugin directory
|
||||
self.plugin_dir = os.path.dirname(__file__)
|
||||
|
||||
# Declare instance attributes
|
||||
# Eintrag Menüband Oben
|
||||
self.actions = []
|
||||
self.menu = u'&IBP: Kanalplanung-Tools'
|
||||
|
||||
# Check if plugin was started the first time in current QGIS session
|
||||
# Must be set in initGui() to survive plugin reloads
|
||||
self.first_start = None
|
||||
|
||||
inp_file = 'D:/Daten/nc/Ingenieurbüro/20 Projekte/Kanalplanung/kanalplanung.gpkg'
|
||||
self.md = QgsProviderRegistry.instance().providerMetadata("ogr")
|
||||
self.gpkg_con = self.md.createConnection( inp_file, {})
|
||||
|
||||
self.doc = False
|
||||
|
||||
def initGui(self):
|
||||
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
|
||||
|
||||
#
|
||||
self.toolBar = self.iface.addToolBar("IBP: Kanalplanung-Tools")
|
||||
|
||||
self.actList = []
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_filter.png')
|
||||
act = QAction(QIcon(icon_path), u'Setze Projektfilter', self.iface.mainWindow())
|
||||
act.triggered.connect(self.run_projectFilter)
|
||||
self.actList.append(act)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_setup.png')
|
||||
act = QAction(QIcon(icon_path), u'Initialisiere BricsCAD', self.iface.mainWindow())
|
||||
act.triggered.connect(self.run_setup)
|
||||
self.actList.append(act)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_import.png')
|
||||
act = QAction(QIcon(icon_path), u'Importiere von BricsCAD', self.iface.mainWindow())
|
||||
act.triggered.connect(self.run_import_from_bricscad)
|
||||
self.actList.append(act)
|
||||
|
||||
icon_path = os.path.join(self.plugin_dir, 'icon_export.png')
|
||||
act = QAction(QIcon(icon_path), u'Übertrag in BricsCAD', self.iface.mainWindow())
|
||||
act.triggered.connect(self.run_export_to_bricscad)
|
||||
self.actList.append(act)
|
||||
|
||||
|
||||
for i in self.actList:
|
||||
self.toolBar.addAction(i)
|
||||
self.iface.addPluginToMenu(self.menu, i)
|
||||
|
||||
|
||||
|
||||
self.first_start = True
|
||||
|
||||
|
||||
def unload(self):
|
||||
"""Removes the plugin menu item and icon from QGIS GUI."""
|
||||
for action in self.actions:
|
||||
self.iface.removePluginMenu(u'&IBP: Kanalplanung-Tools', action)
|
||||
self.iface.removeToolBarIcon(action)
|
||||
|
||||
def run_projectFilter(self):
|
||||
qid = QInputDialog()
|
||||
filter, ok = QInputDialog.getText( qid, "Projektfilter", "Projektnummmer", QLineEdit.Normal, "")
|
||||
|
||||
self.gpkg_con.executeSql("UPDATE projekt SET aktiv = 0;")
|
||||
|
||||
if filter != "":
|
||||
self.gpkg_con.executeSql("UPDATE projekt SET aktiv = 1 WHERE nr='{}';".format(filter))
|
||||
|
||||
#for i in self.iface.mapCanvas().layers():
|
||||
for i in QgsProject.instance().mapLayers().values():
|
||||
if type(i) == type(QgsVectorLayer()):
|
||||
idx = i.fields().indexFromName('ibpprj')
|
||||
if idx >= 0:
|
||||
i.setSubsetString("ibpprj LIKE '%"+filter+"%'")
|
||||
|
||||
else:
|
||||
row.setSubsetString("")
|
||||
|
||||
def run_setup(self):
|
||||
self.acad = win32com.client.Dispatch("BricscadApp.AcadApplication")
|
||||
self.doc = self.acad.ActiveDocument
|
||||
self.model = self.doc.ModelSpace
|
||||
|
||||
QMessageBox.information(None, "Information", "BricsCAD gestartet und Datei gewählt: "+self.doc.name)
|
||||
|
||||
def run_import_from_bricscad(self):
|
||||
"""
|
||||
Lädt alle Layer von BricsCAD in QGIS die mit "_IBP_QIN_" beginnen.
|
||||
"""
|
||||
|
||||
if self.doc == False:
|
||||
QMessageBox.warning(None, "Warnung", "Verbindung noch nicht initialisiert!")
|
||||
else:
|
||||
self.doc.save()
|
||||
|
||||
ibp_dwg_to_dxf(self.doc.name, self.doc.path.replace("\\","/"))
|
||||
|
||||
file_path = self.doc.path.replace("\\","/")+self.doc.name.replace(".dwg",".dxf")
|
||||
print(file_path)
|
||||
s_doc = ezdxf.readfile(file_path)
|
||||
s_msp = s_doc.modelspace()
|
||||
|
||||
# QGIS-Daten
|
||||
laylist = {}
|
||||
laylist['cad_punkt'] = {"qgis_handle":[], "add_new":[], "qgis_lay": None}
|
||||
laylist['cad_linie'] = {"qgis_handle":[], "add_new":[], "qgis_lay": None}
|
||||
|
||||
#@todo: Wenn Layer nicht existiert soll er neu angelegt werden
|
||||
for key, val in laylist.items():
|
||||
val['qgis_lay'] = QgsProject.instance().mapLayersByName(key)[0]
|
||||
val['qgis_lay'].startEditing()
|
||||
for i in val['qgis_lay'].getFeatures():
|
||||
if i['doc'] == self.doc.name:
|
||||
val['qgis_handle'].append(i['handle'])
|
||||
|
||||
# Übertrage alle Elemente des Bricscad Layer "_IBP_QIN_..." in QGIS
|
||||
cad_qgis_obj = []
|
||||
for i in s_msp.query('*[layer?"{}.*"]'.format(CFG['qgs_cad']['import_layer_prefix'])):
|
||||
cad_qgis_obj.append(i)
|
||||
|
||||
#print(cad_qgis_obj)
|
||||
|
||||
for i in cad_qgis_obj:
|
||||
layer = ""
|
||||
if i.dxftype() in ["INSERT","POINT","CIRCLE"]:
|
||||
layer = "cad_punkt"
|
||||
elif i.dxftype() in ["LINE","LWPOLYLINE"]:
|
||||
layer = "cad_linie"
|
||||
else:
|
||||
continue
|
||||
new_feat = False
|
||||
|
||||
if i.dxf.handle not in laylist[layer]['qgis_handle']:
|
||||
new_feat = True
|
||||
feature = QgsFeature(laylist[layer]['qgis_lay'].fields())
|
||||
feature['layer'] = i.dxf.layer
|
||||
feature['handle'] = i.dxf.handle
|
||||
feature['doc'] = self.doc.name
|
||||
feature['type'] = i.dxftype()
|
||||
else:
|
||||
for j in laylist[layer]['qgis_lay'].getFeatures():
|
||||
if j['handle'] == i.dxf.handle and j['doc'] == self.doc.name:
|
||||
feature = j
|
||||
|
||||
if i.dxftype() == "LINE":
|
||||
geom = QgsGeometry.fromPolylineXY([QgsPointXY(i.dxf.start[0],i.dxf.start[1]),
|
||||
QgsPointXY(i.dxf.end[0],i.dxf.end[1])])
|
||||
elif i.dxftype() == "INSERT":
|
||||
geom = QgsGeometry.fromPointXY(QgsPointXY(i.dxf.insert[0],i.dxf.insert[1]))
|
||||
feature['block_name'] = i.dxf.name
|
||||
elif i.dxftype() == "LWPOLYLINE":
|
||||
pts = []
|
||||
for j in i.vertices():
|
||||
pts.append(QgsPointXY(j[0],j[1]))
|
||||
##Kontrolle ob geschlossen
|
||||
if i.dxf.flags == 1:
|
||||
geom = QgsGeometry.fromPolygonXY([pts])
|
||||
else:
|
||||
geom = QgsGeometry.fromPolylineXY(pts)
|
||||
elif i.dxftype() == "POINT":
|
||||
geom = QgsGeometry.fromPointXY(QgsPointXY(i.dxf.location[0],i.dxf.location[1]))
|
||||
elif i.dxftype() == "CIRCLE":
|
||||
geom = QgsGeometry.fromPointXY(QgsPointXY(i.dxf.center[0],i.dxf.center[1]))
|
||||
|
||||
if new_feat:
|
||||
feature.setGeometry(geom)
|
||||
laylist[layer]['add_new'].append(feature)
|
||||
else:
|
||||
laylist[layer]['qgis_lay'].updateFeature(feature)
|
||||
laylist[layer]['qgis_lay'].changeGeometry(feature.id(), geom)
|
||||
|
||||
for key, val in laylist.items():
|
||||
val['qgis_lay'].commitChanges()
|
||||
val['qgis_lay'].dataProvider().addFeatures(val['add_new'])
|
||||
|
||||
self.iface.mapCanvas().refreshAllLayers()
|
||||
|
||||
def run_export_to_bricscad(self):
|
||||
|
||||
if self.doc == False:
|
||||
QMessageBox.warning(None, "Warnung", "Verbindung noch nicht initialisiert!")
|
||||
else:
|
||||
lgp_file = self.doc.path.replace("\\","/")+self.doc.name.replace(".dwg","_Lageplan.dxf")
|
||||
|
||||
try:
|
||||
ibp_dwg_to_dxf(lgp_file.split("/")[-1].replace(".dxf",".dwg"),lgp_file.replace(lgp_file.split("/")[-1],""))
|
||||
lgp_doc = ezdxf.readfile(lgp_file)
|
||||
except:
|
||||
lgp_doc = ezdxf.readfile('C:/Daten/nc/Ingenieurbüro/99-Vorlagen/ezdxf_vorl.dxf')
|
||||
|
||||
lgp_msp = lgp_doc.modelspace()
|
||||
|
||||
lay = QgsProject.instance().mapLayersByName('schacht')[0]
|
||||
lay.startEditing()
|
||||
|
||||
for i in lay.getFeatures():
|
||||
if i['schacht_dn'] > 0:
|
||||
rad = i['schacht_dn']/1000/2
|
||||
else:
|
||||
if i['fallrohr'] > 0:
|
||||
rad = i['fallrohr']/1000/2
|
||||
else:
|
||||
rad = 0.05
|
||||
|
||||
if len(lgp_msp.query().filter(lambda e: "QGIS:schacht:symb:{}".format(i['fid']) in e.get_hyperlink())) == 1:
|
||||
# Element vorhanden
|
||||
#ent_symb = lgp_msp.query('*[handle=="'+i['cad_out_handle_symb']+'"]')[0]
|
||||
ent_symb = lgp_msp.query().filter(lambda e: "QGIS:schacht:symb:{}".format(i['fid']) in e.get_hyperlink())[0]
|
||||
else:
|
||||
# Element anlegen
|
||||
ent_symb = lgp_msp.add_circle((0,0), 1)
|
||||
ent_symb.dxf.layer = '_IBP_QO_EW_{}_SCH'.format(i['art'])
|
||||
|
||||
ent_symb.dxf.center = (i.geometry().asPoint().x(), i.geometry().asPoint().y())
|
||||
ent_symb.dxf.radius = rad
|
||||
|
||||
if len(lgp_msp.query().filter(lambda e: "QGIS:schacht:txt1:{}".format(i['fid']) in e.get_hyperlink())) == 1:
|
||||
# Element vorhanden
|
||||
# ent_txt = lgp_msp.query('*[handle=="{}"]'.format(i['cad_out_handle_txt']))[0]
|
||||
ent_txt = lgp_msp.query().filter(lambda e: "QGIS:schacht:txt1:{}".format(i['fid']) in e.get_hyperlink())[0]
|
||||
else:
|
||||
# Element anlegen
|
||||
ent_txt = lgp_msp.add_mtext("abc")
|
||||
ent_txt.dxf.insert = ent_symb.dxf.center
|
||||
ent_txt.dxf.layer = '_IBP_QO_EW_{}_SCH_Txt'.format(i['art'])
|
||||
ent_txt.dxf.char_height = 0.25
|
||||
ent_txt.dxf.style = 'IBP_Norm'
|
||||
|
||||
ent_txt.text = "{}".format(i['name'])
|
||||
if i['schacht_dn'] != NULL:
|
||||
ent_txt.text+="\nDN{:.0f}".format(i['schacht_dn'])
|
||||
if i['dh'] != NULL:
|
||||
ent_txt.text+="\nDH: {:.2f}".format(i['dh'])
|
||||
if i['sh'] != NULL:
|
||||
ent_txt.text+="\nSH: {:.2f}".format(i['sh'])
|
||||
|
||||
#i['cad_out_handle_symb'] = ent_symb.dxf.handle
|
||||
#i['cad_out_handle_txt'] = ent_txt.dxf.handle
|
||||
|
||||
ent_symb.set_hyperlink("QGIS:schacht:symb:{}".format(i['fid']))
|
||||
ent_txt.set_hyperlink("QGIS:schacht:txt1:{}".format(i['fid']))
|
||||
|
||||
|
||||
#lay.commitChanges()
|
||||
|
||||
lay = QgsProject.instance().mapLayersByName('haltung')[0]
|
||||
lay.startEditing()
|
||||
|
||||
for i in lay.getFeatures():
|
||||
points = []
|
||||
for j in i.geometry().vertices():
|
||||
points.append((j.x(),j.y()))
|
||||
|
||||
qry = lgp_msp.query().filter(lambda e: "QGIS:haltung:symb:{}".format(i['fid']) in e.get_hyperlink())
|
||||
if len(qry) == 1:
|
||||
# Element vorhanden
|
||||
#ent_symb = lgp_msp.query('*[handle=="{}"]'.format(i['cad_out_handle_symb']))[0]
|
||||
ent_symb = qry[0]
|
||||
else:
|
||||
# Element anlegen
|
||||
ent_symb = lgp_msp.add_lwpolyline(points)
|
||||
ent_symb.dxf.layer = '_IBP_QO_EW_{}_Lei'.format(i['art'])
|
||||
|
||||
#i['cad_out_handle_symb'] = ent_symb.dxf.handle
|
||||
ent_symb.set_hyperlink("QGIS:haltung:symb:{}".format(i['fid']))
|
||||
|
||||
mid_point = i.geometry().interpolate(i.geometry().length()/2)
|
||||
mid_point_c = [mid_point.asPoint().x(), mid_point.asPoint().y()]
|
||||
mid_angle = i.geometry().interpolateAngle(i.geometry().length()/2)
|
||||
mid_angle_deg = 90-mid_angle/math.pi*180
|
||||
if mid_angle_deg < 0:
|
||||
mid_angle_deg+= 360
|
||||
if mid_angle_deg > 90 and mid_angle_deg < 270:
|
||||
mid_angle_deg-= 180
|
||||
|
||||
qry = lgp_msp.query().filter(lambda e: "QGIS:haltung:txt1:{}".format(i['fid']) in e.get_hyperlink())
|
||||
if len(qry) == 1:
|
||||
# Element vorhanden
|
||||
#ent_txt = lgp_msp.query('*[handle=="{}"]'.format(i['cad_out_handle_txt']))[0]
|
||||
ent_txt = qry[0]
|
||||
else:
|
||||
# Element anlegen
|
||||
ent_txt = lgp_msp.add_mtext("abc")
|
||||
ent_txt.dxf.insert = [mid_point_c[0]+math.cos((mid_angle_deg+90)/180*math.pi)*.1,
|
||||
mid_point_c[1]+math.sin((mid_angle_deg+90)/180*math.pi)*.1]
|
||||
ent_txt.dxf.layer = '_IBP_QO_EW_{}_Lei_Txt'.format(i['art'])
|
||||
ent_txt.dxf.rotation = mid_angle_deg
|
||||
ent_txt.dxf.attachment_point = ezdxf.lldxf.const.MTEXT_BOTTOM_CENTER
|
||||
ent_txt.dxf.char_height = 0.25
|
||||
ent_txt.dxf.style = 'IBP_Norm'
|
||||
ent_txt.text = "{}".format(i['mat'])
|
||||
#i['cad_out_handle_txt'] = ent_txt.dxf.handle
|
||||
ent_txt.set_hyperlink("QGIS:haltung:txt1:{}".format(i['fid']))
|
||||
|
||||
qry = lgp_msp.query().filter(lambda e: "QGIS:haltung:txt2:{}".format(i['fid']) in e.get_hyperlink())
|
||||
if len(qry) == 1:
|
||||
# Element vorhanden
|
||||
#ent_txt = lgp_msp.query('*[handle=="{}"]'.format(i['cad_out_handle_txt2']))[0]
|
||||
ent_txt = qry[0]
|
||||
else:
|
||||
# Element anlegen
|
||||
ent_txt = lgp_msp.add_mtext("abc")
|
||||
ent_txt.dxf.insert = [mid_point_c[0]-math.cos((mid_angle_deg+90)/180*math.pi)*.1,
|
||||
mid_point_c[1]-math.sin((mid_angle_deg+90)/180*math.pi)*.1]
|
||||
ent_txt.dxf.layer = '_IBP_QO_EW_{}_Lei_Txt'.format(i['art'])
|
||||
ent_txt.dxf.rotation = mid_angle_deg
|
||||
ent_txt.dxf.attachment_point = ezdxf.lldxf.const.MTEXT_TOP_CENTER
|
||||
ent_txt.dxf.char_height = 0.25
|
||||
ent_txt.dxf.style = 'IBP_Norm'
|
||||
if i['gefaelle'] == qgis.core.NULL:
|
||||
ent_txt.text = '{:.2f}m'.format(i['c_laenge'])
|
||||
else:
|
||||
ent_txt.text = '{:.2f}‰; {:.2f}m'.format(i['gefaelle'], i['c_laenge'])
|
||||
#i['cad_out_handle_txt2'] = ent_txt.dxf.handle
|
||||
ent_txt.set_hyperlink("QGIS:haltung:txt2:{}".format(i['fid']))
|
||||
|
||||
|
||||
#lay.updateFeature(i) #Update-QGIS-Layer
|
||||
|
||||
|
||||
|
||||
lay.commitChanges()
|
||||
|
||||
lgp_doc.saveas(lgp_file)
|
||||
ibp_dxf_to_dwg(lgp_file.split("/")[-1],lgp_file.replace(lgp_file.split("/")[-1],""))
|
||||
|
||||
def run_init(self):
|
||||
# Create the dialog with elements (after translation) and keep reference
|
||||
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
|
||||
if self.first_start == True:
|
||||
self.first_start = False
|
||||
self.dlg = ibpToolsDialog()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# PARAMS:
|
||||
# Input folder
|
||||
# Output folder
|
||||
# Output version: ACAD9, ACAD10, ACAD12, ACAD14, ACAD2000, ACAD2004, ACAD2007, ACAD20010, ACAD2013, ACAD2018
|
||||
# Output file type: DWG, DXF, DXB
|
||||
# Recurse Input Folder: 0, 1
|
||||
# Audit each file: 0, 1
|
||||
# (Optional) Input files filter: *.DWG, *.DXF
|
||||
|
||||
def ibp_dwg_to_dxf(file, INPUT_FOLDER = tmp_folder, OUTPUT_FOLDER = tmp_folder, RECURSIVE = "0", AUDIT = "1"):
|
||||
if INPUT_FOLDER != tmp_folder and OUTPUT_FOLDER == tmp_folder:
|
||||
OUTPUT_FOLDER = INPUT_FOLDER
|
||||
OUTVER = "ACAD2018"
|
||||
OUTFORMAT = "DXF"
|
||||
# Command to run
|
||||
cmd = [TEIGHA_PATH, INPUT_FOLDER, OUTPUT_FOLDER, OUTVER, OUTFORMAT, RECURSIVE, AUDIT, file]
|
||||
|
||||
# Run
|
||||
subprocess.run(cmd, shell=True)
|
||||
|
||||
|
||||
def ibp_dxf_to_dwg(file, INPUT_FOLDER = tmp_folder, OUTPUT_FOLDER = tmp_folder, RECURSIVE = "0", AUDIT = "1"):
|
||||
if INPUT_FOLDER != tmp_folder and OUTPUT_FOLDER == tmp_folder:
|
||||
OUTPUT_FOLDER = INPUT_FOLDER
|
||||
OUTVER = "ACAD2018"
|
||||
OUTFORMAT = "DWG"
|
||||
# Command to run
|
||||
cmd = [TEIGHA_PATH, INPUT_FOLDER, OUTPUT_FOLDER, OUTVER, OUTFORMAT, RECURSIVE, AUDIT, file]
|
||||
|
||||
# Run
|
||||
subprocess.run(cmd, shell=True)
|
||||
|
Loading…
Reference in New Issue