Exemplo n.º 1
0
class CloneProject(Worker):
    '''
    worker for cloning a project
    '''
    def __init__(self, project_name, project, parent=None):
        super().__init__(parent=parent)
        self.project_name = project_name
        self.origin_project = project
        self.project_manager = ProjectManager()

    def work(self):

        cloned_project = self.project_manager.create_project(
            self.project_name, create_folder=False)
        self.log('Kopiere Projektordner...')

        # copy template folder
        try:
            shutil.copytree(self.origin_project.path, cloned_project.path)
        except Exception as e:
            self.error.emit(str(e))
            self.project_manager.remove_project(self.project_name)
            return
        self.log('Neues Projekt erfolgreich angelegt '
                 f'unter {cloned_project.path}')
        return cloned_project
Exemplo n.º 2
0
    def create(self, **kwargs):

        area = kwargs['area']

        features = Gewerbeanteile.features().filter(id_teilflaeche=area.id)
        df = features.to_pandas()

        basedata = ProjectManager().basedata
        df_branchen = basedata.get_table('Gewerbe_Branchen',
                                         'Definition_Projekt').to_pandas()
        colors = plt.cm.Accent(np.linspace(0, 1, len(df)))
        idx = df['anteil_branche'] > 0
        df = df[idx]
        colors = colors[idx]

        df_branchen.rename(columns={'ID_Branche_ProjektCheck': 'id_branche'},
                           inplace=True)
        joined = df.merge(df_branchen, on='id_branche')

        figure = plt.figure()
        subplot = figure.add_subplot(111)
        ax = joined['anteil_branche'].plot(
            kind='pie',
            labels=[''] * len(df),
            autopct='%.0f%%',
            figsize=(8, 8),
            title=' ',
            #shadow=True,
            #explode=[0.1] * len(table_df),
            colors=colors,
            ax=subplot)
        #title = ax.set_title(self.title)
        #title.set_position((.5, 1.0))
        plt.figtext(.5,
                    .92,
                    self.title,
                    horizontalalignment='center',
                    fontsize=12)  #, fontweight='bold')

        ax.set_ylabel('')
        ax.set_xlabel('')
        ax.legend(joined['Name_Branche_ProjektCheck'],
                  loc='upper center',
                  bbox_to_anchor=(0.5, 0.05))
        # didn't find a way to pass custom colors directly
        for color, handle in zip(colors, ax.get_legend().legendHandles):
            handle.set_linewidth(2.0)
            handle.set_color(color)
        box = ax.get_position()
        ax.set_position([box.x0, box.y0 + box.y0 * 0.5, box.width, box.height])
        figure.tight_layout()
        figure.subplots_adjust(bottom=0.2)

        return figure
 def setUpClass(cls):
     cls.project_manager = ProjectManager()
     cls.project_manager.basedata = Geopackage(base_path='.',
                                               read_only=True)
     if cls.projectname in [p.name for p in cls.project_manager.projects]:
         cls.project_manager.remove_project(cls.projectname)
     cls.workspace = None
Exemplo n.º 4
0
 def setUpClass(cls):
     cls.project_manager = ProjectManager()
     if cls.projectname in [p.name for p in cls.project_manager.projects]:
         cls.project_manager.remove_project(cls.projectname)
     cls.project = cls.project_manager.create_project(cls.projectname)
     cls.project_manager.active_project = cls.project
     cls.workspace = None
Exemplo n.º 5
0
    def create(self, **kwargs):
        project = kwargs.get('project', ProjectManager().active_project)
        self.title = (f'{project.name}: Kosten der punktuellen Maßnahmen '
                      '(nur erstmalige Herstellung)')
        x_label = ('Kosten der punktuellen Maßnahmen '
                   '(nur erstmalige Herstellung)')

        point_df = ErschliessungsnetzPunkte.features(create=True).to_pandas()

        base_df = project.basedata.get_table('Netze_und_Netzelemente',
                                             'Kosten',
                                             fields=['IDNetz',
                                                     'Netz']).to_pandas()
        # duplicate entries for 'IDNetz'/'Netz' combinations
        del base_df['fid']
        base_df.drop_duplicates(inplace=True)

        joined = point_df.merge(base_df, on='IDNetz', how='right')
        joined.fillna(0, inplace=True)
        grouped = joined.groupby(by='IDNetz')
        categories = []
        costs = []
        for id_netz, grouped_df in grouped:
            categories.append(grouped_df['Netz'].values[0])
            costs.append(grouped_df['Euro_EH'].sum())

        figure, ax = plt.subplots(figsize=(10, 5))
        y_pos = np.arange(len(categories))
        bar_width = 0.5
        patches = ax.barh(y_pos, costs, height=bar_width, align='center')
        text_offset = max([
            patch.get_x() + patch.get_width()
            for patch in patches.get_children()
        ]) * 0.02
        for i, patch in enumerate(patches.get_children()):
            width = patch.get_x() + patch.get_width()
            y = patch.get_y() + bar_width / 2
            ax.text(width + text_offset,
                    y,
                    locale.format_string("%d", width, grouping=True) + ' €',
                    color='black',
                    ha='left',
                    va='center')
        x_min, x_max = ax.get_xlim()
        ax.set_xlim(x_min, x_max * 1.2)

        ax.set_yticks(y_pos)
        ax.set_yticklabels(categories)
        ax.set_title(self.title)
        ax.set_xlabel(x_label)
        ax.get_xaxis().set_major_formatter(
            mticker.FuncFormatter(lambda x, p: locale.format_string(
                "%d", x, grouping=True) + ' €'))
        ax.xaxis.grid(True, which='major')
        box = ax.get_position()
        ax.set_position(
            [box.x0 + box.width * 0.12, box.y0, box.width * 0.88, box.height])

        return figure
Exemplo n.º 6
0
def next_working_day(min_days_infront=2):
    '''
    get the next working day in germany (no holidays, no saturdays, no sundays
    in all federal states)
    requires the basetable "Feriendichte" to hold days infront of today

    Parameters
    ----------
    min_days_infront : int (default: 2)
       returned day will be at least n days infront

    Returns
    -------
    datetime.date
       the next day without holidays,
       if day is out of range of basetable: today + min_days_infront
    '''

    today = np.datetime64(date.today())

    basedata = ProjectManager().basedata

    day = today + np.timedelta64(min_days_infront,'D')
    # get working days (excl. holidays)
    where = ("Wochentag <> 'Samstag' and "
             "Wochentag <> 'Sonntag' and "
             "Anteil_Ferien_Bevoelkerung = 0")
    table = basedata.get_table('Feriendichte', 'Basisdaten_deutschland')
    table.where = where
    df_density = table.to_pandas()
    # can't compare directly because datetime64 has no length
    dates = pd.to_datetime(df_density['Datum'], format='%Y/%m/%d %H:%M:%S.%f')
    df_density['Datum'] = dates.dt.tz_convert(None)
    df_density.sort_values('Datum', inplace=True)
    infront = np.where(df_density['Datum'] >= day)[0]
    if len(infront) > 0:
        # get the first day matching all conditions
        day = df_density.iloc[infront[0]]['Datum']
    return pd.Timestamp(day).date()
Exemplo n.º 7
0
    def create(self, **kwargs):
        project = kwargs.get('project', ProjectManager().active_project)

        self.title = (f'{project.name}: Länge der zusätzlichen '
                      'Infrastrukturnetze (ohne punktuelle Maßnahmen)')
        x_label = u"Meter zusätzliche Netzlänge (ohne punktuelle Maßnahmen)"

        linien_df = ErschliessungsnetzLinien.features(create=True).to_pandas()

        base_df = project.basedata.get_table('Netze_und_Netzelemente',
                                             'Kosten',
                                             fields=['IDNetz',
                                                     'Netz']).to_pandas()
        # duplicate entries for 'IDNetz'/'Netz' combinations
        del base_df['fid']
        base_df.drop_duplicates(inplace=True)

        joined = linien_df.merge(base_df, on='IDNetz', how='right')
        joined.fillna(0, inplace=True)
        grouped = joined.groupby(by='IDNetz')
        categories = []
        lengths = []
        for id_netz, grouped_df in grouped:
            categories.append(grouped_df['Netz'].values[0])
            lengths.append(grouped_df['length'].sum())

        figure, ax = plt.subplots(figsize=(10, 5))
        ax.tick_params(axis='both', which='major', labelsize=9)
        y_pos = np.arange(len(categories))
        bar_width = 0.5
        patches = ax.barh(y_pos, lengths, height=bar_width, align='center')
        # Anfang Barlabels
        text_offset = max([
            patch.get_x() + patch.get_width()
            for patch in patches.get_children()
        ]) * 0.02
        for i, patch in enumerate(patches.get_children()):
            width = patch.get_x() + patch.get_width()
            y = patch.get_y()
            ax.text(width + text_offset,
                    y + bar_width / 2,
                    locale.format_string("%d", width, grouping=True) + ' m',
                    color='black',
                    ha='left',
                    va='center')
        x_min, x_max = ax.get_xlim()
        ax.set_xlim(x_min, x_max * 1.2)
        # Ende Barlabels
        ax.set_yticks(y_pos)
        ax.set_yticklabels(categories)
        ax.set_title(self.title)
        ax.set_xlabel(x_label)
        ax.xaxis.grid(True, which='major')
        ax.get_xaxis().set_major_formatter(
            mticker.FuncFormatter(lambda x, p: locale.format_string(
                "%d", x, grouping=True) + ' m'))
        box = ax.get_position()
        ax.set_position(
            [box.x0 + box.width * 0.12, box.y0, box.width * 0.88, box.height])

        return figure
Exemplo n.º 8
0
    def create(self, **kwargs):
        project = kwargs.get('project', ProjectManager().active_project)
        self.title = (f'Vergleich: Erschließungskosten pro {self._unit} '
                      '(in den ersten 25 Jahren)')
        x_label = (f'Gesamtkosten der Erschließung pro {self._unit} '
                   '(in den ersten 25 Jahren)')
        tou = self._type_of_use.value

        df_areas = Teilflaechen.features(project=project).filter(
            nutzungsart=tou).to_pandas()

        df_reference = project.basedata.get_table('Vergleichswerte',
                                                  'Kosten').to_pandas()

        df_costs = Gesamtkosten.features(project=project).to_pandas()

        # there is only one row for each type of use
        df_reference = df_reference[df_reference['IDNutzungsart'] ==
                                    tou].iloc[0]
        x = df_areas[self._column].sum()
        total_costs = df_costs['Euro'].sum()
        costs_per_x = int((total_costs / x) / 1000) * 1000 if x > 0 else 0
        reference = df_reference['Wert']

        categories = [
            u'Vergleichswert (Schätzung):\n{}'.format(
                df_reference['Beschreibung']),
            f'Projekt "{project.name}" (alle Netze, '
            '\nKostenphasen und Kostenträger)'
        ]
        categories = ['\n'.join(wrap(c, 40)) for c in categories]

        figure, ax = plt.subplots(figsize=(9, 4))
        y_pos = np.arange(len(categories))
        bar_width = 0.5
        patches = ax.barh(y_pos, [reference, costs_per_x],
                          height=bar_width,
                          align='center')  #, color=[ '#99aaff', '#2c64ff'])
        # Anfang Barlabels
        text_offset = max([
            patch.get_x() + patch.get_width()
            for patch in patches.get_children()
        ]) * 0.02
        for i, patch in enumerate(patches.get_children()):
            width = patch.get_x() + patch.get_width()
            y = patch.get_y()
            ax.text(width + text_offset,
                    y + bar_width / 2,
                    locale.format_string("%d", width, grouping=True) + ' €',
                    color='black',
                    ha='left',
                    va='center')
        x_min, x_max = ax.get_xlim()
        ax.set_xlim(x_min, x_max * 1.2)
        # Ende Barlabels
        ax.tick_params(axis='both', which='major', labelsize=9)
        ax.set_yticks(y_pos)
        ax.set_yticklabels(categories)
        ax.set_title(self.title)
        ax.set_xlabel(x_label)
        ax.get_xaxis().set_major_formatter(
            mticker.FuncFormatter(lambda x, p: locale.format_string(
                "%d", x, grouping=True) + ' €'))
        ax.xaxis.grid(True, which='major')
        box = ax.get_position()
        ax.set_position(
            [box.x0 + box.width * 0.2, box.y0, box.width * 0.8, box.height])
        return figure
Exemplo n.º 9
0
    def create(self, **kwargs):
        project = kwargs.get('project', ProjectManager().active_project)
        years = kwargs.get('years', 20)
        self.title = (f'{project.name}: Aufteilung der Gesamtkosten '
                      'auf die Kostenträger')
        y_label = ('Kosten der erstmaligen Herstellung, \n'
                   'Betriebs- und Unterhaltungskosten in den \n'
                   f'ersten {years} Jahren sowie Erneuerungskosten \n'
                   f'(anteilig für die ersten {years} Jahre)')

        df_shares = GesamtkostenTraeger.get_table(project=project).to_pandas()

        df_shareholders = project.basedata.get_table('Kostentraeger',
                                                     'Kosten').to_pandas()
        categories = df_shareholders['Kostentraeger']
        cols = df_shareholders['spalte']

        pos_idx = np.arange(len(categories))

        figure, ax = plt.subplots(figsize=(12, 5))
        colors = self.colors

        summed = np.zeros(len(cols))

        for j, (index, net_share) in enumerate(df_shares.iterrows()):
            data = []
            for i, col in enumerate(cols):
                data.append(net_share[col])
            patches = ax.bar(pos_idx, data, bottom=summed, color=colors[j])
            for i, rect in enumerate(patches.get_children()):
                value = data[i]
                bottom = summed[i]
                if value != 0:
                    color = 'black'
                    if j in [1, 2]:
                        color = 'white'
                    ax.text(i,
                            bottom + value / 2.,
                            locale.format_string("%d", value, grouping=True) +
                            ' €',
                            ha='center',
                            va='center',
                            color=color)

            summed += data

        ax.set_xticks(pos_idx)
        ax.set_xticklabels(categories)
        ax.set_title(self.title)
        ax.set_ylabel(y_label, rotation=90, labelpad=15)
        ax.get_yaxis().set_major_formatter(
            mticker.FuncFormatter(lambda y, p: locale.format_string(
                "%d", y, grouping=True) + ' €'))
        ax.yaxis.grid(True, which='major')

        box = ax.get_position()
        ax.set_position([
            box.x0 + box.width * 0.2, box.y0 + box.height * 0.25,
            box.width * 0.8, box.height * 0.75
        ])

        # Put the legend to the right of the current axis
        ax.legend(df_shares['Netz'],
                  loc='center left',
                  bbox_to_anchor=(0, -0.35))
        # didn't find a way to pass custom colors directly
        for color, handle in zip(colors, ax.get_legend().legendHandles):
            handle.set_color(color)
        return figure
Exemplo n.º 10
0
    def create(self, **kwargs):
        years = kwargs.get('years', 20)
        project = kwargs.get('project', ProjectManager().active_project)
        legend = [
            '1 - Kosten der erstmaligen Herstellung',
            '2 - Kosten für Betrieb und Unterhaltung in den '
            f'ersten {years} Jahren',
            '3 - Anteilige Kosten der Erneuerung (bezogen auf '
            f'einen Zeitraum von {years} Jahren)'
        ]
        self.title = (f"{project.name}: Gesamtkosten der infrastrukturellen "
                      f"Maßnahmen in den ersten {years} Jahren")
        x_label = u"Kosten für Netzerweiterungen und punktuelle Maßnahmen"

        df_costs = Gesamtkosten.get_table(project=project).to_pandas()

        u, u_idx = np.unique(df_costs['Netz'], return_index=True)
        categories = df_costs['Netz'][np.sort(u_idx)]

        pos_idx = np.arange(len(categories))

        bar_width = 0.2
        spacing = 1.15

        figure, ax = plt.subplots(figsize=(10, 6))
        plt.gca().invert_yaxis()
        grouped = df_costs.groupby(by='IDKostenphase')
        phase_names = []

        text_offset = max(df_costs['Euro']) * 0.07 if len(df_costs) > 0 else 0
        for i, (phase_id, group) in enumerate(grouped):
            costs = group['Euro'].values
            patches = ax.barh(pos_idx + i * bar_width * spacing,
                              costs,
                              height=bar_width,
                              align='center')
            phase_names.append(legend[group['IDKostenphase'].values[0] - 1])

            for index, patch in enumerate(patches):
                width = patch.get_width()
                ax.text(width + text_offset,
                        pos_idx[index] + i * bar_width * spacing,
                        locale.format_string("%d", width, grouping=True) +
                        ' €',
                        ha='center',
                        va='center')

        ax.tick_params(axis='both', which='major', labelsize=9)
        ax.set_yticks(pos_idx + bar_width * spacing)
        ax.set_yticklabels(categories)
        ax.set_title(self.title)
        ax.set_xlabel(x_label)
        ax.get_xaxis().set_major_formatter(
            mticker.FuncFormatter(lambda x, p: locale.format_string(
                "%d", x, grouping=True) + ' €'))
        ax.xaxis.grid(True, which='major')
        xmin, xmax = ax.get_xlim()
        ax.set_xlim(left=None, right=xmax * 1.1, emit=True, auto=False)

        box = ax.get_position()

        ax.set_position([
            box.x0 + box.width * 0.12, box.y0 + box.height * 0.2,
            box.width * 0.88, box.height * 0.8
        ])

        # Put a legend to the right of the current axis
        ax.legend(phase_names, loc='center left', bbox_to_anchor=(0, -0.3))
        return figure
Exemplo n.º 11
0
 def __init__(self, project_name, area_layer, epsg, parent=None):
     super().__init__(parent=parent)
     self.project_name = project_name
     self.project_manager = ProjectManager()
     self.area_layer = area_layer
     self.epsg = epsg
Exemplo n.º 12
0
class ProjectInitialization(Worker):
    '''
    worker for creating a new project with some basic setup depending on
    location and size of the included areas
    '''
    def __init__(self, project_name, area_layer, epsg, parent=None):
        super().__init__(parent=parent)
        self.project_name = project_name
        self.project_manager = ProjectManager()
        self.area_layer = area_layer
        self.epsg = epsg

    def work(self):
        try:
            return self.create_project()
        except Exception as e:
            if self.project_areas is not None:
                self.project_areas.workspace.close()
            self.project_manager.remove_project(self.project)
            self.log('Projekt nach Fehler wieder entfernt.')
            raise e

    def create_project(self):
        self.project = self.project_manager.create_project(self.project_name)
        self.project_areas = None
        source_crs = self.area_layer.crs()
        target_crs = QgsCoordinateReferenceSystem(f'epsg:{self.epsg}')
        self.project_areas = Teilflaechen.features(project=self.project,
                                                   create=True)

        # remove z-values from imported areas (they might mess up the geometries
        # later)
        try:
            parameters = {
                'INPUT': self.area_layer,
                'DROP_Z_VALUES': True,
                'OUTPUT': 'memory:'
            }
            area_layer = processing.run('native:dropmzvalues',
                                        parameters)['OUTPUT']
        # native:dropmzvalues is not always available (e.g. in tests)
        except QgsProcessingException:
            area_layer = self.area_layer
        layer_features = list(area_layer.getFeatures())

        self.log(f'Neues Projekt angelegt im Ordner {self.project.path}')
        self.set_progress(10)

        trans_geoms = []

        self.log(f'Füge {len(layer_features)} Fläche(n) hinzu...')
        tr = QgsCoordinateTransform(source_crs, target_crs,
                                    QgsProject.instance())
        if not layer_features:
            raise Exception(
                'Es wurden keine Flächen im Eingangslayer gefunden')
        for area in layer_features:
            geom = area.geometry()
            geom.transform(tr)
            trans_geoms.append(geom)

        # gather additional information about areas

        basedata = self.project_manager.basedata
        ags_feats = get_ags(layer_features,
                            basedata,
                            source_crs=source_crs,
                            use_centroid=True)
        ags = [f.AGS for f in ags_feats]
        gem_names = [f.GEN for f in ags_feats]
        gem_types = [f.Gemeindetyp for f in ags_feats]
        if len(np.unique(ags)) > 1:
            raise Exception("Die Teilflächen liegen nicht in "
                            "der selben Gemeinde")
        project_ags = ags[0]

        centroids = [geom.centroid().asPoint() for geom in trans_geoms]
        xs = [centroid.x() for centroid in centroids]
        ys = [centroid.y() for centroid in centroids]
        project_centroid = QgsPointXY(np.mean(xs), np.mean(ys))

        max_dist = getattr(settings, 'MAX_AREA_DISTANCE', None)

        self.set_progress(33)

        self.log(f'Überprüfe die Flächenlage...')
        if max_dist is not None and len(layer_features) > 1:
            distances = []
            for i in range(len(layer_features)):
                for j in range(i):
                    dist = np.linalg.norm(
                        np.subtract((xs[i], ys[i]), (xs[j], ys[j])))
                    distances.append(dist)
            if distances and max(distances) > max_dist:
                raise Exception("Der Abstand zwischen den Schwerpunkten der "
                                "Teilflächen darf nicht größer "
                                "als {} m sein!".format(max_dist))
        self.set_progress(50)

        traffic_connectors = Connectors.features(project=self.project,
                                                 create=True)

        self.log(f'Berechne Projektrahmendaten...')
        # create areas and connections to roads
        now = datetime.now()
        for i, feature in enumerate(layer_features):
            area = self.project_areas.add(
                nutzungsart=Nutzungsart.UNDEFINIERT.value,
                name=f'Flaeche_{i+1}',
                validiert=0,
                aufsiedlungsdauer=1,
                beginn_nutzung=now.year,
                ags_bkg=ags[i],
                gemeinde_name=gem_names[i],
                gemeinde_typ=gem_types[i],
                geom=trans_geoms[i])
            traffic_connectors.add(id_teilflaeche=area.id,
                                   name_teilflaeche=area.name,
                                   geom=centroids[i])
        self.set_progress(50)

        # general project data
        project_frame = Projektrahmendaten.features(project=self.project,
                                                    create=True)
        local_versions = self.project_manager.local_versions(
            settings.basedata_path)
        # newest local version
        basedata_version = local_versions[0]
        project_frame.add(ags=ags[0],
                          gemeinde_name=gem_names[0],
                          gemeinde_typ=gem_types[0],
                          projekt_name=self.project.name,
                          geom=project_centroid,
                          datum=now.strftime("%d.%m.%Y"),
                          basisdaten_version=basedata_version['version'],
                          basisdaten_datum=basedata_version['date'])
        self.set_progress(60)

        # create selectable centers around the areas for the market competition
        # domain

        sk_radius = getattr(settings, 'PROJECT_RADIUS', 20000)
        self.log(
            f'Ermittle Gemeinden im Umkreis von {int(sk_radius/1000)} km...')

        workspace = basedata.get_workspace('Basisdaten_deutschland')
        vg_table = workspace.get_table('Verwaltungsgemeinschaften')
        buffer = QgsGeometry.fromPointXY(QgsPointXY(*project_centroid)).buffer(
            sk_radius, 20)
        vg_table.spatial_filter(buffer.asWkt())
        centers = Centers.features(project=self.project, create=True)
        rs_list = []
        for row in vg_table:
            centers.add(
                name=row['GEN'],
                rs=row['RS'],
                geom=row['geom'],
                # -1 indicates that it is a vg for selection and output only
                nutzerdefiniert=-1)
            rs_list.append(row['RS'])

        project_rs = None
        gem_table = workspace.get_table('bkg_gemeinden')
        for row in gem_table:
            cut_rs = row['RS'][:9]
            ags = row['AGS']
            if cut_rs in rs_list:
                if ags == project_ags:
                    project_rs = cut_rs
                centers.add(
                    name=row['GEN'],
                    rs=cut_rs,
                    ags=ags,
                    geom=row['geom'],
                    # 0 indicates gemeinden, for calculations only
                    nutzerdefiniert=0)

        # preselect the VG the project is in
        if project_rs:
            project_vg = centers.get(rs=project_rs, nutzerdefiniert=-1)
            project_vg.auswahl = -1
            project_vg.save()

        self.set_progress(100)

        return self.project
Exemplo n.º 13
0
 def __init__(self, project_name, project, parent=None):
     super().__init__(parent=parent)
     self.project_name = project_name
     self.origin_project = project
     self.project_manager = ProjectManager()