Passed
Pull Request — dev (#826)
by
unknown
01:27
created

create_synthetic_buildings()   B

Complexity

Conditions 6

Size

Total Lines 52
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 52
rs 8.2506
c 0
b 0
f 0
cc 6
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
from geoalchemy2.shape import to_shape
2
from sqlalchemy import Column, Float, Integer, String, func, REAL
3
from sqlalchemy.ext.declarative import declarative_base
4
import geopandas as gpd
5
import numpy as np
6
import pandas as pd
7
8
from egon.data import db
9
from egon.data.datasets import Dataset
10
from egon.data.datasets.electricity_demand import (
11
    EgonDemandRegioZensusElectricity,
12
)
13
from egon.data.datasets.electricity_demand.temporal import calc_load_curves_cts
14
from egon.data.datasets.electricity_demand_timeseries.hh_buildings import (
15
    OsmBuildingsSynthetic,
16
)
17
from egon.data.datasets.electricity_demand_timeseries.tools import (
18
    random_ints_until_sum,
19
    random_point_in_square,
20
    specific_int_until_sum,
21
    write_table_to_postgis,
22
    write_table_to_postgres,
23
)
24
from egon.data.datasets.zensus_mv_grid_districts import MapZensusGridDistricts
25
import egon.data.config
26
27
engine = db.engine()
28
Base = declarative_base()
29
30
data_config = egon.data.config.datasets()
31
RANDOM_SEED = egon.data.config.settings()["egon-data"]["--random-seed"]
32
33
import saio
34
35
# import db tables
36
saio.register_schema("openstreetmap", engine=engine)
37
saio.register_schema("society", engine=engine)
38
saio.register_schema("demand", engine=engine)
39
saio.register_schema("boundaries", engine=engine)
40
41
from saio.boundaries import egon_map_zensus_buildings_filtered_all
42
from saio.demand import egon_demandregio_zensus_electricity
43
from saio.openstreetmap import (
44
    osm_amenities_not_in_buildings_filtered,
45
    osm_amenities_shops_filtered,
46
    osm_buildings_filtered,
47
    osm_buildings_filtered_with_amenities,
48
    osm_buildings_synthetic,
49
)
50
from saio.society import destatis_zensus_population_per_ha
51
52
53
class EgonCtsElectricityDemandBuildingShare(Base):
54
    __tablename__ = "egon_cts_electricity_demand_building_share"
55
    __table_args__ = {"schema": "demand"}
56
57
    id = Column(Integer, primary_key=True)
58
    scenario = Column(String, primary_key=True)
59
    bus_id = Column(Integer, index=True)
60
    profile_share = Column(Float)
61
62
63
class CtsPeakLoads(Base):
64
    __tablename__ = "egon_cts_peak_loads"
65
    __table_args__ = {"schema": "demand"}
66
67
    building_id = Column(String, primary_key=True)
68
    cts_peak_load_in_w_2035 = Column(REAL)
69
    cts_peak_load_in_w_2050 = Column(REAL)
70
71
72
def amenities_without_buildings():
73
    """
74
75
    Returns
76
    -------
77
    pd.DataFrame
78
        Table of amenities without buildings
79
80
    """
81
    with db.session_scope() as session:
82
        cells_query = (
83
            session.query(
84
                destatis_zensus_population_per_ha.id.label(
85
                    "zensus_population_id"
86
                ),
87
                # TODO can be used for square around amenity
88
                #  (1 geom_amenity: 1 geom_building)
89
                #  not unique amenity_ids yet
90
                osm_amenities_not_in_buildings_filtered.geom_amenity,
91
                osm_amenities_not_in_buildings_filtered.egon_amenity_id,
92
                # egon_demandregio_zensus_electricity.demand,
93
                # # TODO can be used to generate n random buildings
94
                # # (n amenities : 1 randombuilding)
95
                # func.count(
96
                #     osm_amenities_not_in_buildings_filtered.egon_amenity_id
97
                # ).label("n_amenities_inside"),
98
                # destatis_zensus_population_per_ha.geom,
99
            )
100
            .filter(
101
                func.st_within(
102
                    osm_amenities_not_in_buildings_filtered.geom_amenity,
103
                    destatis_zensus_population_per_ha.geom,
104
                )
105
            )
106
            .filter(
107
                destatis_zensus_population_per_ha.id
108
                == egon_demandregio_zensus_electricity.zensus_population_id
109
            )
110
            .filter(
111
                egon_demandregio_zensus_electricity.sector == "service",
112
                egon_demandregio_zensus_electricity.scenario == "eGon2035"
113
                #         ).group_by(
114
                #             egon_demandregio_zensus_electricity.zensus_population_id,
115
                #             destatis_zensus_population_per_ha.geom,
116
            )
117
        )
118
    # # TODO can be used to generate n random buildings
119
    # df_cells_with_amenities_not_in_buildings = gpd.read_postgis(
120
    #     cells_query.statement, cells_query.session.bind, geom_col="geom"
121
    # )
122
    #
123
124
    # # TODO can be used for square around amenity
125
    df_synthetic_buildings_for_amenities = gpd.read_postgis(
126
        cells_query.statement,
127
        cells_query.session.bind,
128
        geom_col="geom_amenity",
129
    )
130
    return df_synthetic_buildings_for_amenities
131
132
133
def place_buildings_with_amenities(df, amenities=None, max_amenities=None):
134
    """
135
    Building centers are placed randomly within census cells.
136
    The Number of buildings is derived from n_amenity_inside, the selected
137
    method and number of amenities per building.
138
    """
139
    if isinstance(max_amenities, int):
140
        # amount of amenities is randomly generated within bounds (max_amenities,
141
        # amenities per cell)
142
        df["n_amenities_inside"] = df["n_amenities_inside"].apply(
143
            random_ints_until_sum, args=[max_amenities]
144
        )
145
    if isinstance(amenities, int):
146
        # Specific amount of amenities per building
147
        df["n_amenities_inside"] = df["n_amenities_inside"].apply(
148
            specific_int_until_sum, args=[amenities]
149
        )
150
151
    # Unnest each building
152
    df = df.explode(column="n_amenities_inside")
153
154
    # building count per cell
155
    df["building_count"] = df.groupby(["zensus_population_id"]).cumcount() + 1
156
157
    # generate random synthetic buildings
158
    edge_length = 5
159
    # create random points within census cells
160
    points = random_point_in_square(geom=df["geom"], tol=edge_length / 2)
161
162
    df.reset_index(drop=True, inplace=True)
163
    # Store center of polygon
164
    df["geom_point"] = points
165
    # Drop geometry of census cell
166
    df = df.drop(columns=["geom"])
167
168
    return df
169
170
171
def create_synthetic_buildings(df, points=None, crs="EPSG:3035"):
172
    """
173
    Synthetic buildings are generated around points.
174
    """
175
    if isinstance(points, str) and points in df.columns:
176
        points = df[points]
177
    elif isinstance(points, gpd.GeoSeries):
178
        pass
179
    else:
180
        raise ValueError("Points are of the wrong type")
181
182
    # Create building using a square around point
183
    edge_length = 5
184
    df["geom_building"] = points.buffer(distance=edge_length / 2, cap_style=3)
185
186
    if "geom_point" not in df.columns:
187
        df["geom_point"] = df["geom_building"].centroid
188
189
    # TODO Check CRS
190
    df = gpd.GeoDataFrame(
191
        df,
192
        crs=crs,
193
        geometry="geom_building",
194
    )
195
196
    # TODO remove after implementation of egon_building_id
197
    df.rename(columns={"id": "egon_building_id"}, inplace=True)
198
199
    # get max number of building ids from synthetic residential table
200
    with db.session_scope() as session:
201
        max_synth_residential_id = session.execute(
202
            func.max(OsmBuildingsSynthetic.id)
203
        ).scalar()
204
    max_synth_residential_id = int(max_synth_residential_id)
205
206
    # create sequential ids
207
    df["egon_building_id"] = range(
208
        max_synth_residential_id + 1,
209
        max_synth_residential_id + df.shape[0] + 1,
210
    )
211
212
    df["area"] = df["geom_building"].area
213
    # set building type of synthetic building
214
    df["building"] = "cts"
215
    # TODO remove in #772
216
    df = df.rename(
217
        columns={
218
            # "zensus_population_id": "cell_id",
219
            "egon_building_id": "id",
220
        }
221
    )
222
    return df
223
224
225
def buildings_with_amenities():
226
    """"""
227
    with db.session_scope() as session:
228
        cells_query = (
229
            session.query(
230
                osm_buildings_filtered_with_amenities.id.label(
231
                    "egon_building_id"
232
                ),
233
                osm_buildings_filtered_with_amenities.building,
234
                osm_buildings_filtered_with_amenities.n_amenities_inside,
235
                osm_buildings_filtered_with_amenities.area,
236
                osm_buildings_filtered_with_amenities.geom_building,
237
                osm_buildings_filtered_with_amenities.geom_point,
238
                egon_map_zensus_buildings_filtered_all.zensus_population_id,
239
            )
240
            .filter(
241
                osm_buildings_filtered_with_amenities.id
242
                == egon_map_zensus_buildings_filtered_all.id
243
            )
244
            .filter(
245
                egon_demandregio_zensus_electricity.zensus_population_id
246
                == egon_map_zensus_buildings_filtered_all.zensus_population_id
247
            )
248
            .filter(
249
                egon_demandregio_zensus_electricity.sector == "service",
250
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
251
            )
252
        )
253
    df_amenities_in_buildings = pd.read_sql(
254
        cells_query.statement, cells_query.session.bind, index_col=None
255
    )
256
257
    # TODO necessary?
258
    df_amenities_in_buildings["geom_building"] = df_amenities_in_buildings[
259
        "geom_building"
260
    ].apply(to_shape)
261
    df_amenities_in_buildings["geom_point"] = df_amenities_in_buildings[
262
        "geom_point"
263
    ].apply(to_shape)
264
265
    # # Count amenities per building
266
    # df_amenities_in_buildings["n_amenities_inside"] = 1
267
    # df_amenities_in_buildings[
268
    #     "n_amenities_inside"
269
    # ] = df_amenities_in_buildings.groupby("egon_building_id")[
270
    #     "n_amenities_inside"
271
    # ].transform(
272
    #     "sum"
273
    # )
274
275
    # # Only keep one building for multiple amenities
276
    # df_amenities_in_buildings = df_amenities_in_buildings.drop_duplicates(
277
    #     "egon_building_id"
278
    # )
279
    # df_amenities_in_buildings["building"] = "cts"
280
    # TODO maybe remove later
281
    df_amenities_in_buildings.sort_values("egon_building_id").reset_index(
282
        drop=True, inplace=True
283
    )
284
    df_amenities_in_buildings.rename(
285
        columns={
286
            # "zensus_population_id": "cell_id",
287
            "egon_building_id": "id"
288
        },
289
        inplace=True,
290
    )
291
292
    return df_amenities_in_buildings
293
294
295
# TODO maybe replace with tools.write_table_to_db
296
def write_synthetic_buildings_to_db(df_synthetic_buildings):
297
    """"""
298
    if not "geom_point" in df_synthetic_buildings.columns:
299
        df_synthetic_buildings["geom_point"] = df_synthetic_buildings[
300
            "geom_building"
301
        ].centroid
302
303
    df_synthetic_buildings = df_synthetic_buildings.rename(
304
        columns={
305
            "zensus_population_id": "cell_id",
306
            "egon_building_id": "id",
307
        }
308
    )
309
    # Only take existing columns
310
    columns = [
311
        column.key for column in OsmBuildingsSynthetic.__table__.columns
312
    ]
313
    df_synthetic_buildings = df_synthetic_buildings.loc[:, columns]
314
315
    dtypes = {i: OsmBuildingsSynthetic.__table__.columns[i].type for i in OsmBuildingsSynthetic.__table__.columns.keys()}
316
317
    # Write new buildings incl coord into db
318
    df_synthetic_buildings.to_postgis(
319
        name=OsmBuildingsSynthetic.__tablename__,
320
        con=engine,
321
        if_exists="append",
322
        # schema="openstreetmap",
323
        schema=OsmBuildingsSynthetic.__table_args__["schema"],
324
        # dtype={
325
        #     "id": OsmBuildingsSynthetic.id.type,
326
        #     "cell_id": OsmBuildingsSynthetic.cell_id.type,
327
        #     "geom_building": OsmBuildingsSynthetic.geom_building.type,
328
        #     "geom_point": OsmBuildingsSynthetic.geom_point.type,
329
        #     "n_amenities_inside": OsmBuildingsSynthetic.n_amenities_inside.type,
330
        #     "building": OsmBuildingsSynthetic.building.type,
331
        #     "area": OsmBuildingsSynthetic.area.type,
332
        # },
333
        dtype=dtypes,
334
    )
335
336
337
def buildings_without_amenities():
338
    """ """
339
    # buildings_filtered in cts-demand-cells without amenities
340
    with db.session_scope() as session:
341
342
        # Synthetic Buildings
343
        q_synth_buildings = session.query(
344
            osm_buildings_synthetic.cell_id.cast(Integer).label(
345
                "zensus_population_id"
346
            ),
347
            osm_buildings_synthetic.id.cast(Integer).label("id"),
348
            osm_buildings_synthetic.area.label("area"),
349
            osm_buildings_synthetic.geom_building.label("geom_building"),
350
            osm_buildings_synthetic.geom_point.label("geom_point"),
351
        )
352
353
        # Buildings filtered
354
        q_buildings_filtered = session.query(
355
            egon_map_zensus_buildings_filtered_all.zensus_population_id,
356
            osm_buildings_filtered.id,
357
            osm_buildings_filtered.area,
358
            osm_buildings_filtered.geom_building,
359
            osm_buildings_filtered.geom_point,
360
        ).filter(
361
            osm_buildings_filtered.id
362
            == egon_map_zensus_buildings_filtered_all.id
363
        )
364
365
        # Amenities + zensus_population_id
366
        q_amenities = (
367
            session.query(
368
                destatis_zensus_population_per_ha.id.label(
369
                    "zensus_population_id"
370
                ),
371
            )
372
            .filter(
373
                func.st_within(
374
                    osm_amenities_shops_filtered.geom_amenity,
375
                    destatis_zensus_population_per_ha.geom,
376
                )
377
            )
378
            .distinct(destatis_zensus_population_per_ha.id)
379
        )
380
381
        # Cells with CTS demand but without amenities
382
        q_cts_without_amenities = (
383
            session.query(
384
                egon_demandregio_zensus_electricity.zensus_population_id,
385
            )
386
            .filter(
387
                egon_demandregio_zensus_electricity.sector == "service",
388
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
389
            )
390
            .filter(
391
                egon_demandregio_zensus_electricity.zensus_population_id.notin_(
392
                    q_amenities
393
                )
394
            )
395
            .distinct()
396
        )
397
398
        # Buildings filtered + synthetic buildings residential in
399
        # cells with CTS demand but without amenities
400
        cells_query = q_synth_buildings.union(q_buildings_filtered).filter(
401
            egon_map_zensus_buildings_filtered_all.zensus_population_id.in_(
402
                q_cts_without_amenities
403
            )
404
        )
405
406
    # df_buildings_without_amenities = pd.read_sql(
407
    #     cells_query.statement, cells_query.session.bind, index_col=None)
408
    df_buildings_without_amenities = gpd.read_postgis(
409
        cells_query.statement,
410
        cells_query.session.bind,
411
        geom_col="geom_building",
412
    )
413
414
    df_buildings_without_amenities = df_buildings_without_amenities.rename(
415
        columns={
416
            # "zensus_population_id": "cell_id",
417
            "egon_building_id": "id",
418
        }
419
    )
420
421
    return df_buildings_without_amenities
422
423
424
def select_cts_buildings(df_buildings_without_amenities):
425
    """ """
426
    # TODO Adapt method
427
    # Select one building each cell
428
    # take the first
429
    df_buildings_with_cts_demand = (
430
        df_buildings_without_amenities.drop_duplicates(
431
            # subset="cell_id", keep="first"
432
            subset="zensus_population_id", keep="first"
433
        ).reset_index(drop=True)
434
    )
435
    df_buildings_with_cts_demand["n_amenities_inside"] = 1
436
    df_buildings_with_cts_demand["building"] = "cts"
437
438
    return df_buildings_with_cts_demand
439
440
441
def cells_with_cts_demand_only(df_buildings_without_amenities):
442
    """"""
443
    # cells mit amenities
444
    with db.session_scope() as session:
445
        sub_query = (
446
            session.query(
447
                destatis_zensus_population_per_ha.id.label(
448
                    "zensus_population_id"
449
                ),
450
            )
451
            .filter(
452
                func.st_within(
453
                    osm_amenities_shops_filtered.geom_amenity,
454
                    destatis_zensus_population_per_ha.geom,
455
                )
456
            )
457
            .distinct(destatis_zensus_population_per_ha.id)
458
        )
459
460
        cells_query = (
461
            session.query(
462
                egon_demandregio_zensus_electricity.zensus_population_id,
463
                egon_demandregio_zensus_electricity.scenario,
464
                egon_demandregio_zensus_electricity.sector,
465
                egon_demandregio_zensus_electricity.demand,
466
                destatis_zensus_population_per_ha.geom,
467
            )
468
            .filter(
469
                egon_demandregio_zensus_electricity.sector == "service",
470
                egon_demandregio_zensus_electricity.scenario == "eGon2035",
471
            )
472
            .filter(
473
                egon_demandregio_zensus_electricity.zensus_population_id.notin_(
474
                    sub_query
475
                )
476
            )
477
            .filter(
478
                egon_demandregio_zensus_electricity.zensus_population_id
479
                == destatis_zensus_population_per_ha.id
480
            )
481
        )
482
483
    df_cts_cell_without_amenities = gpd.read_postgis(
484
        cells_query.statement,
485
        cells_query.session.bind,
486
        geom_col="geom",
487
        index_col=None,
488
    )
489
490
    # TODO maybe remove
491
    df_buildings_without_amenities = df_buildings_without_amenities.rename(
492
        columns={"cell_id": "zensus_population_id"}
493
    )
494
495
    # Census cells with only cts demand
496
    df_cells_only_cts_demand = df_cts_cell_without_amenities.loc[
497
        ~df_cts_cell_without_amenities["zensus_population_id"].isin(
498
            df_buildings_without_amenities["zensus_population_id"].unique()
499
        )
500
    ]
501
502
    df_cells_only_cts_demand.reset_index(drop=True, inplace=True)
503
504
    return df_cells_only_cts_demand
505
506
507
def calc_census_cell_share(scenario="eGon2035"):
508
    """"""
509
510
    with db.session_scope() as session:
511
        cells_query = (
512
            session.query(
513
                EgonDemandRegioZensusElectricity, MapZensusGridDistricts.bus_id
514
            )
515
            .filter(EgonDemandRegioZensusElectricity.sector == "service")
516
            .filter(EgonDemandRegioZensusElectricity.scenario == scenario)
517
            .filter(
518
                EgonDemandRegioZensusElectricity.zensus_population_id
519
                == MapZensusGridDistricts.zensus_population_id
520
            )
521
        )
522
523
    df_demand_regio_electricity_demand = pd.read_sql(
524
        cells_query.statement,
525
        cells_query.session.bind,
526
        index_col="zensus_population_id",
527
    )
528
529
    # get demand share of cell per bus
530
    # share ist für scenarios identisch
531
    df_census_share = df_demand_regio_electricity_demand[
532
        "demand"
533
    ] / df_demand_regio_electricity_demand.groupby("bus_id")[
534
        "demand"
535
    ].transform(
536
        "sum"
537
    )
538
    df_census_share = df_census_share.rename("cell_share")
539
540
    df_census_share = pd.concat(
541
        [df_census_share, df_demand_regio_electricity_demand[["bus_id", "scenario"]]], axis=1
542
    )
543
544
    df_census_share.reset_index(inplace=True)
545
    return df_census_share
546
547
548
def calc_building_demand_profile_share(df_cts_buildings, scenario="eGon2035"):
549
    """
550
    Share of cts electricity demand profile per bus for every selected building
551
    """
552
553
    def calc_building_amenity_share(df_cts_buildings):
554
        """"""
555
        df_building_amenity_share = 1 / df_cts_buildings.groupby(
556
            "zensus_population_id")["n_amenities_inside"].transform("sum")
557
        df_building_amenity_share = pd.concat(
558
            [
559
                df_building_amenity_share.rename("building_amenity_share"),
560
                df_cts_buildings[["zensus_population_id", "id"]],
561
            ],
562
            axis=1,
563
        )
564
        return df_building_amenity_share
565
566
    df_building_amenity_share = calc_building_amenity_share(df_cts_buildings)
567
568
    df_census_cell_share = calc_census_cell_share(scenario)
569
570
    df_demand_share = pd.merge(left=df_building_amenity_share, right=df_census_cell_share,
571
                               left_on="zensus_population_id", right_on="zensus_population_id")
572
    df_demand_share["profile_share"] = df_demand_share["building_amenity_share"].multiply(
573
        df_demand_share["cell_share"])
574
575
    return df_demand_share[["id", "bus_id", "scenario", "profile_share"]]
576
577
578
def calc_building_profiles(df_demand_share=None, egon_building_id=None, scenario="eGon2035"):
579
    """
580
581
    """
582
583
    if not isinstance(df_demand_share, pd.DataFrame):
584
        with db.session_scope() as session:
585
            cells_query = session.query(EgonCtsElectricityDemandBuildingShare)
586
587
        df_demand_share = pd.read_sql(
588
            cells_query.statement, cells_query.session.bind, index_col=None)
589
590
    df_cts_profiles = calc_load_curves_cts(scenario)
591
592
    # Only calculate selected building profile if egon_building_id is given
593
    if isinstance(egon_building_id, int) and egon_building_id in df_demand_share["id"]:
594
        df_demand_share = df_demand_share.loc[
595
            df_demand_share["id"] == egon_building_id]
596
597
    df_building_profiles = pd.DataFrame()
598
    for bus_id, df in df_demand_share.groupby('bus_id'):
599
        shares = df.set_index("id", drop=True)["profile_share"]
600
        profile = df_cts_profiles.loc[:, bus_id]
601
        building_profiles = profile.apply(lambda x: x * shares)
0 ignored issues
show
introduced by
The variable shares does not seem to be defined in case the for loop on line 598 is not entered. Are you sure this can never be the case?
Loading history...
602
        df_building_profiles = pd.concat([df_building_profiles, building_profiles], axis=1)
603
604
    return df_building_profiles
605
606
607
def cts_to_buildings():
608
609
    # Buildings with amenities
610
    df_buildings_with_amenities = buildings_with_amenities()
611
612
    # Create synthetic buildings for amenites without buildings
613
    df_amenities_without_buildings = amenities_without_buildings()
614
    df_amenities_without_buildings["n_amenities_inside"] = 1
615
    df_synthetic_buildings_with_amenities = create_synthetic_buildings(
616
        df_amenities_without_buildings, points="geom_amenity"
617
    )
618
619
    # TODO write to DB and remove renaming
620
    # write_synthetic_buildings_to_db(df_synthetic_buildings_with_amenities)
621
    write_table_to_postgis(df_synthetic_buildings_with_amenities.rename(
622
        columns={
623
            "zensus_population_id": "cell_id",
624
            "egon_building_id": "id",
625
        }),
626
        OsmBuildingsSynthetic,
627
        drop=False)
628
629
    # Cells without amenities but CTS demand and buildings
630
    df_buildings_without_amenities = buildings_without_amenities()
631
632
    # TODO Fix Adhoc Bugfix duplicated buildings
633
    mask = df_buildings_without_amenities.loc[
634
        df_buildings_without_amenities['id'].isin(
635
            df_buildings_with_amenities['id'])].index
636
    df_buildings_without_amenities = df_buildings_without_amenities.drop(
637
        index=mask).reset_index(drop=True)
638
639
    df_buildings_without_amenities = select_cts_buildings(
640
        df_buildings_without_amenities
641
    )
642
    df_buildings_without_amenities["n_amenities_inside"] = 1
643
644
    # Create synthetic amenities and buildings in cells with only CTS demand
645
    df_cells_with_cts_demand_only = cells_with_cts_demand_only(
646
        df_buildings_without_amenities
647
    )
648
    # Only 1 Amenity per cell
649
    df_cells_with_cts_demand_only["n_amenities_inside"] = 1
650
    # Only 1 Amenity per Building
651
    df_cells_with_cts_demand_only = place_buildings_with_amenities(
652
        df_cells_with_cts_demand_only, amenities=1
653
    )
654
    # Leads to only 1 building per cell
655
    df_synthetic_buildings_without_amenities = (
656
        create_synthetic_buildings(
657
            df_cells_with_cts_demand_only, points="geom_point"
658
        )
659
    )
660
661
    # TODO write to DB and remove renaming
662
    # write_synthetic_buildings_to_db(df_synthetic_buildings_without_amenities)
663
    write_table_to_postgis(df_synthetic_buildings_without_amenities.rename(
664
        columns={
665
            "zensus_population_id": "cell_id",
666
            "egon_building_id": "id",
667
        }),
668
        OsmBuildingsSynthetic,
669
        drop=False)
670
671
    # Concat all buildings
672
    columns = ["zensus_population_id", "id", "geom_building", "n_amenities_inside"]
673
    # columns = ["zensus_population_id", "id", "geom_building", "n_amenities_inside", "table"]
674
    # df_buildings_with_amenities["table"] = "df_buildings_with_amenities"
675
    # df_synthetic_buildings_with_amenities["table"] = "df_synthetic_buildings_with_amenities"
676
    # df_buildings_without_amenities["table"] = "df_buildings_without_amenities"
677
    # df_synthetic_buildings_without_amenities["table"] = "df_synthetic_buildings_without_amenities"
678
679
    df_cts_buildings = pd.concat(
680
        [
681
            df_buildings_with_amenities[columns],
682
            df_synthetic_buildings_with_amenities[columns],
683
            df_buildings_without_amenities[columns],
684
            df_synthetic_buildings_without_amenities[columns],
685
        ],
686
        axis=0,
687
        ignore_index=True,
688
    )
689
    # TODO maybe remove after #772
690
    df_cts_buildings["id"] = df_cts_buildings["id"].astype(int)
691
692
    df_demand_share_2035 = calc_building_demand_profile_share(df_cts_buildings,
693
                                                         scenario="eGon2035")
694
    df_demand_share_100RE = calc_building_demand_profile_share(df_cts_buildings,
695
                                                         scenario="eGon100RE")
696
697
    df_demand_share = pd.concat([df_demand_share_2035, df_demand_share_100RE],
698
                                axis=0, ignore_index=True)
699
700
    # TODO Why are there nonunique ids?
701
    #  needs to be removed as soon as 'id' is unique
702
    df_demand_share = df_demand_share.drop_duplicates(subset="id")
703
704
    write_table_to_postgres(df_demand_share,
705
                            EgonCtsElectricityDemandBuildingShare,
706
                            drop=True)
707
708
    return df_cts_buildings, df_demand_share
709
710
711
def get_peak_load_cts_buildings():
712
713
    df_building_profiles = calc_building_profiles()
714
    df_peak_load = df_building_profiles.max(axis=1)
715
716
    CtsPeakLoads.__table__.drop(bind=engine, checkfirst=True)
717
    CtsPeakLoads.__table__.create(bind=engine, checkfirst=True)
718
719
    # Write peak loads into db
720
    with db.session_scope() as session:
721
        session.bulk_insert_mappings(
722
            CtsPeakLoads,
723
            df_peak_load.to_dict(orient="records"),
724
        )
725
726
    return df_cts_buildings, df_building_amenity_share
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable df_cts_buildings does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable df_building_amenity_share does not seem to be defined.
Loading history...
727
728
729
class CtsElectricityBuildings(Dataset):
730
    def __init__(self, dependencies):
731
        super().__init__(
732
            name="CtsElectricityBuildings",
733
            version="0.0.0.",
734
            dependencies=dependencies,
735
            tasks=(cts_to_buildings),
736
        )
737