def setup_type(self): ''' set up basic parameters (name, type of use) ''' layout = self.ui.parameter_group.layout() clear_layout(layout) self.params = Params(layout, help_file='definitionen_flaechen.txt', ) self.params.name = Param(self.area.name, LineEdit(width=300), label='Name') self.params.add(Seperator(margin=0)) ha = round(self.area.geom.area()) / 10000 self.area.area = ha self.params.area = Param(ha, label='Größe', unit='ha') self.params.typ = Param( self.types[self.area.nutzungsart][0], ComboBox([t[0] for t in self.types], width=300), label='Nutzungsart' ) # user changed type of use def type_changed(): name = self.params.name.value type_labels = [t[0] for t in self.types] tou_id = type_labels.index(self.params.typ.value) self.area.nutzungsart = tou_id tou_label = self.types[tou_id][0] self.ui.area_combo.setItemText( self.ui.area_combo.currentIndex(), f'{name} ({tou_label})' ) self.area.name = name self.area.save() # update connector names connector = self.connectors.get(id_teilflaeche=self.area.id) connector.name_teilflaeche = self.area.name connector.save() if self.typ: self.typ.clear(self.area) self.setup_type_params() self.canvas.refreshAllLayers() Traffic.reset() self.params.changed.connect(type_changed) self.params.show(title='Teilfläche definieren')
def create_presets(self, net_id: int, phase_id: int) -> tuple: ''' create a combobox with presets for shares for a specific phase and type of infrastructure element ''' applyable_rules = self.applyable_aufteilungsregeln.filter( IDNetz=net_id, IDPhase=phase_id) rules = [] for applyable_rule in applyable_rules: rule_id = applyable_rule.IDAufteilungsregel rule = self.aufteilungsregeln.get(IDAufteilungsregel=rule_id) rules.append(rule) options = (['Aufteilungsregel wählen'] + [rule.Aufteilungsregel for rule in rules]) preset_combo = ComboBox(options, [None] + rules) preset_combo.input.model().item(0).setEnabled(False) return preset_combo, options
def setup_point_params(self, point: 'Feature'): ''' set up the parameters in the UI to edit the given point measure ''' if self.point_params: self.point_params.close() ui_group = self.ui.point_parameter_group layout = ui_group.layout() clear_layout(layout) if not point: return self.point_params = Params( layout, help_file='infrastruktur_punktmassnahme.txt') self.point_params.bezeichnung = Param( point.bezeichnung, LineEdit(width=300), label='Bezeichnung') punktelemente = list(self.netzelemente.filter(Typ='Punkt')) type_names = [p.Netzelement for p in punktelemente] typ = self.netzelemente.get(IDNetzelement=point.IDNetzelement) type_combo = ComboBox( ['nicht gesetzt'] + type_names, data=[None] + list(punktelemente), width=300) self.point_params.typ = Param( typ.Netzelement if typ else 'nicht gesetzt', type_combo, label='Erschließungsnetz' ) self.point_params.add(Seperator(margin=0)) self.point_params.euro_EH = Param( point.Euro_EH, DoubleSpinBox(), unit='€', label='Kosten der erstmaligen Herstellung' ) self.point_params.euro_BU = Param( point.Cent_BU / 100, DoubleSpinBox(), unit='€', label='Jährliche Kosten für Betrieb und Unterhaltung' ) self.point_params.euro_EN = Param( point.Euro_EN, DoubleSpinBox(), unit='€', label='Erneuerungskosten nach Ablauf der Lebensdauer' ) self.point_params.lebensdauer = Param( point.Lebensdauer, SpinBox(minimum=1, maximum=1000), label='Technische oder wirtschaftliche \n' 'Lebensdauer bis zur Erneuerung', unit='Jahr(e)' ) def save(): point.bezeichnung = self.point_params.bezeichnung.value typ = type_combo.get_data() point.IDNetzelement = typ.IDNetzelement if typ else 0 point.IDNetz = typ.IDNetz if typ else 0 point.Lebensdauer = self.point_params.lebensdauer.value point.Euro_EH = self.point_params.euro_EH.value point.Euro_EN = self.point_params.euro_EN.value point.Cent_BU = self.point_params.euro_BU.value * 100 point.save() # lazy way to update the combo box self.fill_points_combo(select=point) self.point_params.show() self.point_params.changed.connect(save) last_row = self.point_params.layout.children()[-1] button = QPushButton() icon_path = 'iconset_mob/20190619_iconset_mob_delete_1.png' icon = QIcon(os.path.join(self.project.settings.IMAGE_PATH, icon_path)) button.setText('Maßnahme entfernen') button.setIcon(icon) button.setToolTip( '<p><span style=" font-weight:600;">Maßnahme entfernen</span>' '</p><p>Löscht die aktuell gewählte Maßnahme. ' '<br/>Dieser Schritt kann nicht rückgängig gemacht werden. </p>') last_row.insertWidget(0, button) button.clicked.connect(self.remove_point)
def setup_params(self, market): ''' set up the parameters to change attributes of the given status quo market in the scenario ''' if self.params: self.params.close() layout = self.param_group.layout() clear_layout(layout) if not market: self.param_group.setVisible(False) return self.param_group.setVisible(True) self.params = Params( layout, help_file='standortkonkurrenz_veraenderte_maerkte.txt') self.params.name = Param(market.name, label='Name') self.params.add(Seperator(margin=0)) self.params.kette = Param(market.kette, label='Anbieter') self.params.nullfall = Param( market.betriebstyp_nullfall, label='Betriebstyp im Nullfall', ) closed_label = 'Markt geschlossen' type_ids = [typ.id_betriebstyp for typ in self.typen] type_labels = [] for tid in type_ids: type_labels.append(closed_label if tid == 0 else self.detailed_type_label(tid)) type_combo = ComboBox(type_labels, data=type_ids, width=300) typ = market.id_betriebstyp_planfall self.params.planfall = Param( closed_label if typ == 0 else self.detailed_type_label(typ), type_combo, label='Betriebstyp im Planfall', value_label=closed_label if typ == 0 else market.betriebstyp_planfall) close_check = Checkbox() self.params.gets_closed = Param(typ == 0, close_check, label='Markt im Planfall schließen') self.params.gets_closed.hide_in_overview = True def closed_toggled(checked): if checked: type_combo.set_value(closed_label) close_check.changed.connect(closed_toggled) def type_changed(value): close_check.set_value(value == closed_label) type_combo.changed.connect(type_changed) def save(): id_bt = type_combo.get_data() bt = self.typen.get(id_betriebstyp=id_bt).name market.id_betriebstyp_planfall = id_bt market.betriebstyp_planfall = bt vkfl = self.market_tool.betriebstyp_to_vkfl( market.id_betriebstyp_planfall, market.id_kette) market.vkfl_planfall = vkfl market.save() self.canvas.refreshAllLayers() # lazy way to update the combo box self.fill_combo(select=market) self.changed.emit() self.params.show(title='Markt im Planfall verändern') self.params.changed.connect(save)
def setup_params(self, market): ''' set up the parameters to edit the given scenario market ''' # ToDo: that's mostly the same as in EditNullfallMarkets, # might be merged if self.params: self.params.close() layout = self.param_group.layout() clear_layout(layout) if not market: self.param_group.setVisible(False) return self.param_group.setVisible(True) self.params = Params( layout, help_file='standortkonkurrenz_geplante_maerkte.txt') self.params.name = Param(market.name, LineEdit(width=300), label='Name') self.params.add(Seperator(margin=0)) # 'nicht aufgeführt' (kette 0) is first, rest alphabetical order ketten = sorted(self.ketten, key=lambda k: k.name.lower() if k.name != 'nicht aufgeführt' else '') chain_ids = [typ.id_kette for typ in ketten] chain_labels = [kette.name for kette in ketten] chain_combo = ComboBox(chain_labels, data=chain_ids, width=300) value = self.ketten.get(id_kette=market.id_kette).name self.params.kette = Param(value, chain_combo, label='Anbieter') type_ids = [typ.id_betriebstyp for typ in self.typen] type_labels = [self.detailed_type_label(i) for i in type_ids if i > 0] type_combo = ComboBox(type_labels, data=type_ids, width=300) self.params.typ = Param(self.detailed_type_label( market.id_betriebstyp_planfall), type_combo, label='Neue Märkte', value_label=market.betriebstyp_planfall) def save(): market.name = self.params.name.value id_bt = type_combo.get_data() bt = self.typen.get(id_betriebstyp=id_bt).name market.id_betriebstyp_planfall = id_bt market.betriebstyp_planfall = bt market.id_kette = chain_combo.get_data() market.kette = self.ketten.get(id_kette=market.id_kette).name vkfl = self.market_tool.betriebstyp_to_vkfl( market.id_betriebstyp_planfall, market.id_kette) market.vkfl_planfall = vkfl market.save() self.canvas.refreshAllLayers() # lazy way to update the combo box self.fill_combo(select=market) self.changed.emit() self.params.show(title='Neuen Markt im Planfall bearbeiten') self.params.changed.connect(save) # markets on project areas can not be deleted if market.id_teilflaeche < 0: last_row = self.params.layout.children()[-1] button = QPushButton() icon_path = 'iconset_mob/20190619_iconset_mob_delete_1.png' icon = QIcon( os.path.join(self.project.settings.IMAGE_PATH, icon_path)) button.setText('Markt entfernen') button.setIcon(icon) button.setToolTip( '<p><span style=" font-weight:600;">Markt entfernen</span>' '</p><p>Löscht den aktuell gewählten Markt. ' '<br/>Dieser Schritt kann nicht rückgängig gemacht ' 'werden. </p>') last_row.insertWidget(0, button) button.clicked.connect(lambda: self.remove_market(market))
def setup_params(self, area): ''' set the parameters according to the data of the given area ''' self.area = area clear_layout(self.layout) self.params = Params(self.layout, help_file='definitionen_gewerbe.txt') self.params.add(Title('Bezugszeitraum')) self.params.beginn_nutzung = Param( area.beginn_nutzung, SpinBox(minimum=2000, maximum=2100), label='Beginn des Bezuges', repr_format='%d' ) self.params.aufsiedlungsdauer = Param( area.aufsiedlungsdauer, SpinBox(minimum=1, maximum=100), label='Dauer des Bezuges (Jahre, 1 = Bezug wird noch\n' 'im Jahr des Bezugsbeginns abgeschlossen)', unit='Jahr(e)' ) self.params.add(Seperator(margin=10)) self.params.add( Title('Voraussichtlicher Anteil der Branchen an der Nettofläche')) preset_names = self.df_industry_types_base[ 'Name_Gewerbegebietstyp'].values preset_ids = self.df_industry_types_base['IDGewerbegebietstyp'].values options = ['Gebietstyp wählen'] + list(preset_names) self.preset_combo = ComboBox(options, [-1] + list(preset_ids)) self.preset_combo.input.model().item(0).setEnabled(False) param = Param(0, self.preset_combo, label='Vorschlagswerte') param.hide_in_overview = True self.params.add(param, name='gebietstyp') # break grid layout self.params.add( QSpacerItem(0, 3, QSizePolicy.Fixed, QSizePolicy.Minimum)) def values_changed(): if self.auto_check.value: n_jobs = self.estimate_jobs() self.ap_slider.set_value(n_jobs) def slider_changed(): self.preset_combo.set_value(options[0]) values_changed() def preset_changed(): self.set_industry_presets(self.preset_combo.input.currentData()) values_changed() self.preset_combo.changed.connect(preset_changed) dependency = SumDependency(100) for branche in self.branchen: feature = self.gewerbeanteile.get( id_branche=branche.id, id_teilflaeche=self.area.id ) value = feature.anteil_definition if feature else 0 slider = Slider(maximum=100, width=200, lockable=True) param = Param( value, slider, label=f'{branche.Name_Branche_ProjektCheck}', unit='%' ) slider.changed.connect(slider_changed) dependency.add(param) self.params.add(param, name=branche.param_gewerbenutzung) self.params.add(Seperator()) self.params.add(Title('Voraussichtliche Anzahl an Arbeitsplätzen')) self.auto_check = Checkbox() self.params.auto_check = Param( bool(self.area.ap_ist_geschaetzt), self.auto_check, label='Automatische Schätzung' ) self.ap_slider = Slider(maximum=10000) self.params.arbeitsplaetze_insgesamt = Param( self.area.ap_gesamt, self.ap_slider, label='Zahl der Arbeitsplätze\n' 'nach Vollbezug (Summe über alle Branchen)' ) def toggle_auto_check(): # disable input for manual setting of jobs # when auto check is enabled read_only = self.auto_check.value for _input in [self.ap_slider.slider, self.ap_slider.spinbox]: _input.setAttribute(Qt.WA_TransparentForMouseEvents, read_only) _input.setFocusPolicy(Qt.NoFocus if read_only else Qt.StrongFocus) _input.update() values_changed() self.auto_check.changed.connect(toggle_auto_check) toggle_auto_check() # set to default preset if assignment is new if len(self.gewerbeanteile) == 0: self.set_industry_presets(self.DEFAULT_INDUSTRY_ID) ap_gesamt = self.estimate_jobs() self.params.arbeitsplaetze_insgesamt.value = ap_gesamt self.save() self.params.changed.connect(self.save) self.params.show( title='Gewerbe: Bezugszeitraum und Maß der baulichen Nutzung')
class Gewerbe: ''' sub-domain of project area definitions. Set up the structure of a project area with industry as the type of use ''' # Default Gewerbegebietstyp DEFAULT_INDUSTRY_ID = 2 # analysis period BETRACHTUNGSZEITRAUM_JAHRE = 15 def __init__(self, project, layout): self.layout = layout self.gewerbeanteile = Gewerbeanteile.features(create=True) self.ap_nach_jahr = ApProJahr.features(create=True) self.projektrahmendaten = Projektrahmendaten.features() self.basedata = project.basedata self.branchen = list(self.basedata.get_table( 'Gewerbe_Branchen', 'Definition_Projekt' ).features().filter(ID_Branche_ProjektCheck__gt=0)) presets = self.basedata.get_table( 'Vorschlagswerte_Branchenstruktur', 'Definition_Projekt' ) self.df_presets_base = presets.to_pandas() density = self.basedata.get_table( 'Dichtekennwerte_Gewerbe', 'Definition_Projekt' ) self.df_density_base = density.to_pandas() industry_types = self.basedata.get_table( 'Gewerbegebietstypen', 'Definition_Projekt' ) self.df_industry_types_base = industry_types.to_pandas() default_idx = self.df_industry_types_base['IDGewerbegebietstyp'] == \ self.DEFAULT_INDUSTRY_ID self.df_industry_types_base.loc[ default_idx, 'Name_Gewerbegebietstyp'] += ' (default)' def set_industry_presets(self, preset_id): ''' set all sector values to database presets of given industry id ''' if preset_id == -1: return idx = self.df_presets_base['IDGewerbegebietstyp'] == preset_id presets = self.df_presets_base[idx] for branche in self.branchen: param = getattr(self.params, branche.param_gewerbenutzung) p_idx = presets['ID_Branche_ProjektCheck'] == branche.id preset = int(presets[p_idx]['Vorschlagswert_in_Prozent'].values[0]) param.value = preset def estimate_jobs(self): ''' calculate estimation of number of jobs set estimated jobs to sectors of industry ''' gemeindetyp = self.area.gemeinde_typ df_kennwerte = self.df_density_base[ self.df_density_base['Gemeindetyp_ProjektCheck'] == gemeindetyp] jobs_sum = 0 for branche in self.branchen: param = getattr(self.params, branche.param_gewerbenutzung) idx = df_kennwerte['ID_Branche_ProjektCheck'] == branche.id jobs_per_ha = int(df_kennwerte[idx]['AP_pro_ha_brutto'].values[0]) jobs_ind = round(self.area.area * (param.input.value / 100.) * jobs_per_ha) branche.estimated_jobs = jobs_ind branche.jobs_per_ha = jobs_per_ha jobs_sum += jobs_ind return jobs_sum def setup_params(self, area): ''' set the parameters according to the data of the given area ''' self.area = area clear_layout(self.layout) self.params = Params(self.layout, help_file='definitionen_gewerbe.txt') self.params.add(Title('Bezugszeitraum')) self.params.beginn_nutzung = Param( area.beginn_nutzung, SpinBox(minimum=2000, maximum=2100), label='Beginn des Bezuges', repr_format='%d' ) self.params.aufsiedlungsdauer = Param( area.aufsiedlungsdauer, SpinBox(minimum=1, maximum=100), label='Dauer des Bezuges (Jahre, 1 = Bezug wird noch\n' 'im Jahr des Bezugsbeginns abgeschlossen)', unit='Jahr(e)' ) self.params.add(Seperator(margin=10)) self.params.add( Title('Voraussichtlicher Anteil der Branchen an der Nettofläche')) preset_names = self.df_industry_types_base[ 'Name_Gewerbegebietstyp'].values preset_ids = self.df_industry_types_base['IDGewerbegebietstyp'].values options = ['Gebietstyp wählen'] + list(preset_names) self.preset_combo = ComboBox(options, [-1] + list(preset_ids)) self.preset_combo.input.model().item(0).setEnabled(False) param = Param(0, self.preset_combo, label='Vorschlagswerte') param.hide_in_overview = True self.params.add(param, name='gebietstyp') # break grid layout self.params.add( QSpacerItem(0, 3, QSizePolicy.Fixed, QSizePolicy.Minimum)) def values_changed(): if self.auto_check.value: n_jobs = self.estimate_jobs() self.ap_slider.set_value(n_jobs) def slider_changed(): self.preset_combo.set_value(options[0]) values_changed() def preset_changed(): self.set_industry_presets(self.preset_combo.input.currentData()) values_changed() self.preset_combo.changed.connect(preset_changed) dependency = SumDependency(100) for branche in self.branchen: feature = self.gewerbeanteile.get( id_branche=branche.id, id_teilflaeche=self.area.id ) value = feature.anteil_definition if feature else 0 slider = Slider(maximum=100, width=200, lockable=True) param = Param( value, slider, label=f'{branche.Name_Branche_ProjektCheck}', unit='%' ) slider.changed.connect(slider_changed) dependency.add(param) self.params.add(param, name=branche.param_gewerbenutzung) self.params.add(Seperator()) self.params.add(Title('Voraussichtliche Anzahl an Arbeitsplätzen')) self.auto_check = Checkbox() self.params.auto_check = Param( bool(self.area.ap_ist_geschaetzt), self.auto_check, label='Automatische Schätzung' ) self.ap_slider = Slider(maximum=10000) self.params.arbeitsplaetze_insgesamt = Param( self.area.ap_gesamt, self.ap_slider, label='Zahl der Arbeitsplätze\n' 'nach Vollbezug (Summe über alle Branchen)' ) def toggle_auto_check(): # disable input for manual setting of jobs # when auto check is enabled read_only = self.auto_check.value for _input in [self.ap_slider.slider, self.ap_slider.spinbox]: _input.setAttribute(Qt.WA_TransparentForMouseEvents, read_only) _input.setFocusPolicy(Qt.NoFocus if read_only else Qt.StrongFocus) _input.update() values_changed() self.auto_check.changed.connect(toggle_auto_check) toggle_auto_check() # set to default preset if assignment is new if len(self.gewerbeanteile) == 0: self.set_industry_presets(self.DEFAULT_INDUSTRY_ID) ap_gesamt = self.estimate_jobs() self.params.arbeitsplaetze_insgesamt.value = ap_gesamt self.save() self.params.changed.connect(self.save) self.params.show( title='Gewerbe: Bezugszeitraum und Maß der baulichen Nutzung') def save(self): ''' write the current parameter values to the database ''' for branche in self.branchen: feature = self.gewerbeanteile.get(id_branche=branche.id, id_teilflaeche=self.area.id) if not feature: feature = self.gewerbeanteile.add( id_branche=branche.id, id_teilflaeche=self.area.id ) feature.name_teilflaeche = self.area.name feature.anteil_definition = getattr( self.params, branche.param_gewerbenutzung).value feature.name_branche = branche.Name_Branche_ProjektCheck feature.anzahl_jobs_schaetzung = getattr( branche, 'estimated_jobs', 0) feature.dichtekennwert = getattr( branche, 'jobs_per_ha', 0) feature.save() self.area.beginn_nutzung = self.params.beginn_nutzung.value self.area.aufsiedlungsdauer = self.params.aufsiedlungsdauer.value self.area.ap_gesamt = self.params.arbeitsplaetze_insgesamt.value self.area.ap_ist_geschaetzt = self.params.auto_check.value self.area.save() # just estimate for output in case auto estimation is deactivated # (estimated values needed in any case) self.estimate_jobs() self.set_growth(self.area) self.set_percentages(self.area) self.set_ways(self.area) Traffic.reset() MunicipalTaxRevenue.reset_gewerbe_einzelhandel() def clear(self, area): ''' clear all data related to industry as the type of use of the given area ''' MunicipalTaxRevenue.reset_gewerbe_einzelhandel() self.gewerbeanteile.filter(id_teilflaeche=area.id).delete() self.ap_nach_jahr.filter(id_teilflaeche=area.id).delete() area.ap_gesamt = None area.save() def set_growth(self, area): ''' calculate and store the development of the number of employees ''' n_jobs = area.ap_gesamt begin = area.beginn_nutzung duration = area.aufsiedlungsdauer end = begin + self.BETRACHTUNGSZEITRAUM_JAHRE - 1 self.ap_nach_jahr.filter(id_teilflaeche=area.id).delete() for progress in range(0, end - begin + 1): proc_factor = (float(progress + 1) / duration if progress + 1 <= duration else 1) year = begin + progress self.ap_nach_jahr.add( id_teilflaeche=self.area.id, name_teilflaeche=self.area.name, jahr=year, arbeitsplaetze=n_jobs * proc_factor ) def set_percentages(self, area): ''' this already could have done when saving, but is here based on the old ArcGIS code ''' df = self.gewerbeanteile.filter(id_teilflaeche=area.id).to_pandas() df['anteil_branche'] = df['anteil_definition'] * df['dichtekennwert'] df['anteil_branche'] /= df['anteil_branche'].sum() df['anteil_branche'] *= 100 df = df.round({'anteil_branche': 0}) self.gewerbeanteile.update_pandas(df) def set_ways(self, area): ''' calculate and store the daily ways done by the employees of the area ''' df_anteile = self.gewerbeanteile.filter( id_teilflaeche=area.id).to_pandas() df_basedata = (self.basedata.get_table( 'Gewerbe_Branchen', 'Definition_Projekt').features().filter( ID_Branche_ProjektCheck__gt=0).to_pandas()) df_basedata.rename(columns={'ID_Branche_ProjektCheck': 'id_branche'}, inplace=True) estimated = df_anteile['anzahl_jobs_schaetzung'] estimated_sum = estimated.sum() preset = area.ap_gesamt cor_factor = preset / estimated_sum if estimated_sum > 0 else 0 joined = df_anteile.merge(df_basedata, on='id_branche', how='left') n_ways = estimated * cor_factor * joined['Wege_je_Beschäftigten'] n_ways_miv = n_ways * joined['Anteil_Pkw_Fahrer'] / 100 area.wege_gesamt = int(n_ways.sum()) area.wege_miv = int(n_ways_miv.sum()) area.save() def close(self): ''' close parameters ''' if hasattr(self, 'params'): self.params.close()
def setup_params(self, area): ''' set the parameters according to the data of the given area ''' self.area = area clear_layout(self.layout) self.params = Params(self.layout, help_file='definitionen_wohnen.txt') self.params.add(Title('Bezugszeitraum')) self.params.beginn_nutzung = Param( area.beginn_nutzung, SpinBox(minimum=2000, maximum=2100), label='Beginn des Bezuges', repr_format='%d' ) self.params.aufsiedlungsdauer = Param( area.aufsiedlungsdauer, SpinBox(minimum=1, maximum=100), label='Dauer des Bezuges', unit='Jahr(e)') self.params.add(Seperator()) self.params.add(Title('Anzahl Wohneinheiten nach Gebäudetypen')) # load the building presets to select from preset_names, idx = np.unique(self.df_presets['Gebietstyp'].values, return_index=True) idx.sort() preset_names = self.df_presets['Gebietstyp'].values[idx] options = ['Gebietstyp wählen'] + list(preset_names) self.preset_combo = ComboBox(options) self.preset_combo.input.model().item(0).setEnabled(False) param = Param(0, self.preset_combo, label='Vorschlagswerte') param.hide_in_overview = True self.params.add(param, name='gebietstyp') self.params.add( QSpacerItem(0, 3, QSizePolicy.Fixed, QSizePolicy.Minimum)) # preset is selected def preset_changed(gebietstyp): presets = self.df_presets[self.df_presets['Gebietstyp']==gebietstyp] for idx, preset in presets.iterrows(): id_bt = preset['IDGebaeudetyp'] bt = self.gebaeudetypen_base.get(id=id_bt) param = self.params.get(bt.param_we) param.input.value = self.area.area * preset['WE_pro_Hektar'] self.preset_combo.changed.connect(preset_changed) for bt in self.gebaeudetypen_base: param_name = bt.param_we feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) value = feature.we if feature else 0 slider = Slider(maximum=2000) self.params.add(Param( value, slider, label=f'... in {bt.display_name}'), name=param_name ) slider.changed.connect( lambda: self.preset_combo.set_value(options[0])) self.params.add(Seperator()) self.params.add(Title('Mittlere Anzahl Bewohner pro Wohneinheit\n' '(3 Jahre nach Bezug)')) for bt in self.gebaeudetypen_base: param_name = bt.param_ew_je_we feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) # set to default if no feature yet value = feature.ew_je_we if feature else bt.default_ew_je_we self.params.add(Param( value, DoubleSpinBox(step=0.1, maximum=50), label=f'... in {bt.display_name}'), name=param_name ) self.params.add(Seperator()) self.params.add(Title('Anteil der Bewohner unter 18 Jahre')) # load the age presets to select from for bt in self.gebaeudetypen_base: param_name = bt.param_anteil_u18 feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) # set to default if no feature yet value = feature.anteil_u18 if feature else bt.default_anteil_u18 self.params.add(Param( value, Slider(maximum=60), unit='%', label=f'... in {bt.display_name}'), name=param_name ) self.params.changed.connect(self.save) self.params.show( title='Wohnen: Bezugszeitraum, Maß der baulichen Nutzung, ' 'Haushaltsstrukturen')
class Wohnen: ''' sub-domain of project area definitions. Set up the structure of a residential project area ''' def __init__(self, project, layout): self.basedata = project.basedata self.gebaeudetypen_base = self.basedata.get_table( 'Wohnen_Gebaeudetypen', 'Definition_Projekt' ).features() self.df_presets = self.basedata.get_table( 'WE_nach_Gebietstyp', 'Definition_Projekt' ).to_pandas() self.wohneinheiten = Wohneinheiten.features(create=True) self.layout = layout def setup_params(self, area): ''' set the parameters according to the data of the given area ''' self.area = area clear_layout(self.layout) self.params = Params(self.layout, help_file='definitionen_wohnen.txt') self.params.add(Title('Bezugszeitraum')) self.params.beginn_nutzung = Param( area.beginn_nutzung, SpinBox(minimum=2000, maximum=2100), label='Beginn des Bezuges', repr_format='%d' ) self.params.aufsiedlungsdauer = Param( area.aufsiedlungsdauer, SpinBox(minimum=1, maximum=100), label='Dauer des Bezuges', unit='Jahr(e)') self.params.add(Seperator()) self.params.add(Title('Anzahl Wohneinheiten nach Gebäudetypen')) # load the building presets to select from preset_names, idx = np.unique(self.df_presets['Gebietstyp'].values, return_index=True) idx.sort() preset_names = self.df_presets['Gebietstyp'].values[idx] options = ['Gebietstyp wählen'] + list(preset_names) self.preset_combo = ComboBox(options) self.preset_combo.input.model().item(0).setEnabled(False) param = Param(0, self.preset_combo, label='Vorschlagswerte') param.hide_in_overview = True self.params.add(param, name='gebietstyp') self.params.add( QSpacerItem(0, 3, QSizePolicy.Fixed, QSizePolicy.Minimum)) # preset is selected def preset_changed(gebietstyp): presets = self.df_presets[self.df_presets['Gebietstyp']==gebietstyp] for idx, preset in presets.iterrows(): id_bt = preset['IDGebaeudetyp'] bt = self.gebaeudetypen_base.get(id=id_bt) param = self.params.get(bt.param_we) param.input.value = self.area.area * preset['WE_pro_Hektar'] self.preset_combo.changed.connect(preset_changed) for bt in self.gebaeudetypen_base: param_name = bt.param_we feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) value = feature.we if feature else 0 slider = Slider(maximum=2000) self.params.add(Param( value, slider, label=f'... in {bt.display_name}'), name=param_name ) slider.changed.connect( lambda: self.preset_combo.set_value(options[0])) self.params.add(Seperator()) self.params.add(Title('Mittlere Anzahl Bewohner pro Wohneinheit\n' '(3 Jahre nach Bezug)')) for bt in self.gebaeudetypen_base: param_name = bt.param_ew_je_we feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) # set to default if no feature yet value = feature.ew_je_we if feature else bt.default_ew_je_we self.params.add(Param( value, DoubleSpinBox(step=0.1, maximum=50), label=f'... in {bt.display_name}'), name=param_name ) self.params.add(Seperator()) self.params.add(Title('Anteil der Bewohner unter 18 Jahre')) # load the age presets to select from for bt in self.gebaeudetypen_base: param_name = bt.param_anteil_u18 feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) # set to default if no feature yet value = feature.anteil_u18 if feature else bt.default_anteil_u18 self.params.add(Param( value, Slider(maximum=60), unit='%', label=f'... in {bt.display_name}'), name=param_name ) self.params.changed.connect(self.save) self.params.show( title='Wohnen: Bezugszeitraum, Maß der baulichen Nutzung, ' 'Haushaltsstrukturen') def save(self): ''' write the current parameter values to the database ''' we_sum = 0 for bt in self.gebaeudetypen_base: feature = self.wohneinheiten.get(id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) if not feature: feature = self.wohneinheiten.add( id_gebaeudetyp=bt.id, id_teilflaeche=self.area.id) we = getattr(self.params, bt.param_we).value feature.we = we we_sum += we ew_je_we = getattr(self.params, bt.param_ew_je_we).value feature.ew_je_we = ew_je_we anteil_u18 = getattr(self.params, bt.param_anteil_u18).value feature.anteil_u18 = anteil_u18 cor_factor = ew_je_we / bt.Ew_pro_WE_Referenz feature.korrekturfaktor = cor_factor feature.name_gebaeudetyp = bt.NameGebaeudetyp feature.save() self.area.beginn_nutzung = self.params.beginn_nutzung.value self.area.aufsiedlungsdauer = self.params.aufsiedlungsdauer.value self.area.we_gesamt = we_sum Traffic.reset() MunicipalTaxRevenue.reset_wohnen() self.area.save() job = WohnenDevelopment(self.basedata, self.area) dialog = ProgressDialog( job, auto_close=True, parent=self.layout.parentWidget()) dialog.show() def clear(self, area): ''' clear all data related to residential use of the given area ''' self.wohneinheiten.filter(id_teilflaeche=area.id).delete() area.we_gesamt = None area.ew = 0 area.save() MunicipalTaxRevenue.reset_wohnen() def close(self): ''' close parameters ''' if hasattr(self, 'params'): self.params.close()