Merge remote-tracking branch 'origin/master' into graphics-to-doc-img

This commit is contained in:
Fabian Neumann 2024-05-06 10:03:20 +02:00
commit 9318dd6b2b
11 changed files with 837 additions and 885 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 208 KiB

View File

@ -135,7 +135,7 @@ as part of the `Stromnetze Research Initiative
Workflow Workflow
======== ========
.. image:: ../doc/img/workflow.png .. image:: img/workflow.png
:class: full-width :class: full-width
:align: center :align: center

View File

@ -21,8 +21,7 @@ Having downloaded the necessary data,
With these and the externally extracted ENTSO-E online map topology With these and the externally extracted ENTSO-E online map topology
(``data/entsoegridkit``), it can build a base PyPSA network with the following rules: (``data/entsoegridkit``), it can build a base PyPSA network with the following rules:
- :mod:`base_network` builds and stores the base network with all buses, HVAC lines and HVDC links, while - :mod:`base_network` builds and stores the base network with all buses, HVAC lines and HVDC links, and determines `Voronoi cells <https://en.wikipedia.org/wiki/Voronoi_diagram>`__ for all substations.
- :mod:`build_bus_regions` determines `Voronoi cells <https://en.wikipedia.org/wiki/Voronoi_diagram>`__ for all substations.
Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules: Then the process continues by calculating conventional power plant capacities, potentials, and per-unit availability time series for variable renewable energy carriers and hydro power plants with the following rules:
@ -35,13 +34,6 @@ Then the process continues by calculating conventional power plant capacities, p
The central rule :mod:`add_electricity` then ties all the different data inputs The central rule :mod:`add_electricity` then ties all the different data inputs
together into a detailed PyPSA network stored in ``networks/elec.nc``. together into a detailed PyPSA network stored in ``networks/elec.nc``.
.. _busregions:
Rule ``build_bus_regions``
=============================
.. automodule:: build_bus_regions
.. _cutout: .. _cutout:
Rule ``build_cutout`` Rule ``build_cutout``

View File

@ -186,7 +186,7 @@ Upcoming Release
* Data on existing renewable capacities is now consistently taken from powerplantmatching (instead of being retrieved separately); the dataset has also been updated to include 2023 values. * Data on existing renewable capacities is now consistently taken from powerplantmatching (instead of being retrieved separately); the dataset has also been updated to include 2023 values.
* Added shapes to .nc file for different stages of the network object in `base_network`, `build_bus_regions`, and `cluster_network`. * Added shapes to .nc file for different stages of the network object in `base_network`, `simplify_network`, and `cluster_network`; the `build_bus_regions` rule is now integrated into the `base_network` rule.
* Fix p_nom_min of renewables generators for myopic approach and add check of existing capacities in `add_land_use_constraint_m`. * Fix p_nom_min of renewables generators for myopic approach and add check of existing capacities in `add_land_use_constraint_m`.

View File

@ -133,32 +133,31 @@ This triggers a workflow of multiple preceding jobs that depend on each rule's i
graph[bgcolor=white, margin=0]; graph[bgcolor=white, margin=0];
node[shape=box, style=rounded, fontname=sans, fontsize=10, penwidth=2]; node[shape=box, style=rounded, fontname=sans, fontsize=10, penwidth=2];
edge[penwidth=2, color=grey]; edge[penwidth=2, color=grey];
0[label = "solve_network", color = "0.39 0.6 0.85", style="rounded"]; 0[label = "solve_network", color = "0.24 0.6 0.85", style="rounded"];
1[label = "prepare_network\nll: copt\nopts: Co2L-24H", color = "0.29 0.6 0.85", style="rounded"]; 1[label = "prepare_network\nll: vopt\nopts: Co2L-3H", color = "0.10 0.6 0.85", style="rounded"];
2[label = "add_extra_components", color = "0.28 0.6 0.85", style="rounded"]; 2[label = "add_extra_components", color = "0.33 0.6 0.85", style="rounded"];
3[label = "cluster_network\nclusters: 6", color = "0.19 0.6 0.85", style="rounded"]; 3[label = "cluster_network\nclusters: 128", color = "0.59 0.6 0.85", style="rounded"];
4[label = "simplify_network\nsimpl: ", color = "0.01 0.6 0.85", style="rounded"]; 4[label = "simplify_network\nsimpl: ", color = "0.18 0.6 0.85", style="rounded"];
5[label = "add_electricity", color = "0.49 0.6 0.85", style="rounded"]; 5[label = "add_electricity", color = "0.48 0.6 0.85", style="rounded"];
6[label = "build_renewable_profiles\ntechnology: solar", color = "0.21 0.6 0.85", style="rounded"]; 6[label = "build_renewable_profiles\ntechnology: solar", color = "0.29 0.6 0.85", style="rounded"];
7[label = "base_network", color = "0.27 0.6 0.85", style="rounded"]; 7[label = "base_network", color = "0.30 0.6 0.85", style="rounded"];
8[label = "build_shapes", color = "0.26 0.6 0.85", style="rounded"]; 8[label = "build_shapes", color = "0.61 0.6 0.85", style="rounded"];
9[label = "retrieve_databundle", color = "0.59 0.6 0.85", style="rounded"]; 9[label = "retrieve_databundle", color = "0.06 0.6 0.85", style="rounded"];
10[label = "retrieve_natura_raster", color = "0.47 0.6 0.85", style="rounded"]; 10[label = "retrieve_natura_raster", color = "0.03 0.6 0.85", style="rounded"];
11[label = "build_bus_regions", color = "0.13 0.6 0.85", style="rounded"]; 11[label = "retrieve_cutout\ncutout: europe-2013-sarah", color = "0.50 0.6 0.85", style="rounded"];
12[label = "retrieve_cutout\ncutout: be-03-2013-era5", color = "0.36 0.6 0.85", style="rounded,dashed"]; 12[label = "build_renewable_profiles\ntechnology: onwind", color = "0.29 0.6 0.85", style="rounded"];
13[label = "build_renewable_profiles\ntechnology: onwind", color = "0.21 0.6 0.85", style="rounded"]; 13[label = "retrieve_cutout\ncutout: europe-2013-era5", color = "0.50 0.6 0.85", style="rounded"];
14[label = "build_renewable_profiles\ntechnology: offwind-ac", color = "0.21 0.6 0.85", style="rounded"]; 14[label = "build_renewable_profiles\ntechnology: offwind-ac", color = "0.29 0.6 0.85", style="rounded"];
15[label = "build_ship_raster", color = "0.00 0.6 0.85", style="rounded"]; 15[label = "build_ship_raster", color = "0.16 0.6 0.85", style="rounded"];
16[label = "retrieve_ship_raster", color = "0.51 0.6 0.85", style="rounded,dashed"]; 16[label = "retrieve_ship_raster", color = "0.53 0.6 0.85", style="rounded"];
17[label = "build_renewable_profiles\ntechnology: offwind-dc", color = "0.21 0.6 0.85", style="rounded"]; 17[label = "build_renewable_profiles\ntechnology: offwind-dc", color = "0.29 0.6 0.85", style="rounded"];
18[label = "build_line_rating", color = "0.05 0.6 0.85", style="rounded"]; 18[label = "build_hydro_profile", color = "0.47 0.6 0.85", style="rounded"];
19[label = "retrieve_cost_data\nyear: 2030", color = "0.15 0.6 0.85", style="rounded"]; 19[label = "retrieve_cost_data\nyear: 2030", color = "0.21 0.6 0.85", style="rounded"];
20[label = "build_powerplants", color = "0.54 0.6 0.85", style="rounded"]; 20[label = "build_powerplants", color = "0.56 0.6 0.85", style="rounded"];
21[label = "build_electricity_demand", color = "0.52 0.6 0.85", style="rounded"]; 21[label = "build_electricity_demand", color = "0.54 0.6 0.85", style="rounded"];
22[label = "retrieve_electricity_demand", color = "0.22 0.6 0.85", style="rounded"]; 22[label = "retrieve_electricity_demand", color = "0.34 0.6 0.85", style="rounded"];
23[label = "copy_config", color = "0.44 0.6 0.85", style="rounded"]; 23[label = "retrieve_synthetic_electricity_demand", color = "0.65 0.6 0.85", style="rounded"];
1 -> 0 1 -> 0
23 -> 0
2 -> 1 2 -> 1
19 -> 1 19 -> 1
3 -> 2 3 -> 2
@ -167,15 +166,14 @@ This triggers a workflow of multiple preceding jobs that depend on each rule's i
19 -> 3 19 -> 3
5 -> 4 5 -> 4
19 -> 4 19 -> 4
11 -> 4 7 -> 4
6 -> 5 6 -> 5
13 -> 5 12 -> 5
14 -> 5 14 -> 5
17 -> 5 17 -> 5
7 -> 5
18 -> 5 18 -> 5
7 -> 5
19 -> 5 19 -> 5
11 -> 5
20 -> 5 20 -> 5
9 -> 5 9 -> 5
21 -> 5 21 -> 5
@ -185,37 +183,32 @@ This triggers a workflow of multiple preceding jobs that depend on each rule's i
10 -> 6 10 -> 6
8 -> 6 8 -> 6
11 -> 6 11 -> 6
12 -> 6
8 -> 7 8 -> 7
9 -> 8 9 -> 8
8 -> 11 7 -> 12
7 -> 11 9 -> 12
7 -> 13 10 -> 12
9 -> 13 8 -> 12
10 -> 13 13 -> 12
8 -> 13
11 -> 13
12 -> 13
7 -> 14 7 -> 14
9 -> 14 9 -> 14
10 -> 14 10 -> 14
15 -> 14 15 -> 14
8 -> 14 8 -> 14
11 -> 14 13 -> 14
12 -> 14
16 -> 15 16 -> 15
12 -> 15 13 -> 15
7 -> 17 7 -> 17
9 -> 17 9 -> 17
10 -> 17 10 -> 17
15 -> 17 15 -> 17
8 -> 17 8 -> 17
11 -> 17 13 -> 17
12 -> 17 8 -> 18
7 -> 18 13 -> 18
12 -> 18
7 -> 20 7 -> 20
22 -> 21 22 -> 21
23 -> 21
} }
| |
@ -226,28 +219,25 @@ In the terminal, this will show up as a list of jobs to be run:
Building DAG of jobs... Building DAG of jobs...
Job stats: Job stats:
job count job count
--------------------------- ------- ------------------------------------- -------
add_electricity 1 add_electricity 1
add_extra_components 1 add_extra_components 1
base_network 1 build_line_rating 1
build_bus_regions 1 build_renewable_profiles 4
build_electricity_demand 1 build_ship_raster 1
build_line_rating 1 cluster_network 1
build_powerplants 1 prepare_network 1
build_renewable_profiles 4 retrieve_cost_data 1
build_shapes 1 retrieve_cutout 1
build_ship_raster 1 retrieve_databundle 1
cluster_network 1 retrieve_electricity_demand 1
copy_config 1 retrieve_natura_raster 1
prepare_network 1 retrieve_ship_raster 1
retrieve_cost_data 1 retrieve_synthetic_electricity_demand 1
retrieve_databundle 1 simplify_network 1
retrieve_electricity_demand 1 solve_network 1
retrieve_natura_raster 1 total 19
simplify_network 1
solve_network 1
total 22
``snakemake`` then runs these jobs in the correct order. ``snakemake`` then runs these jobs in the correct order.

File diff suppressed because it is too large Load Diff

View File

@ -86,7 +86,9 @@ rule base_network:
offshore_shapes=resources("offshore_shapes.geojson"), offshore_shapes=resources("offshore_shapes.geojson"),
europe_shape=resources("europe_shape.geojson"), europe_shape=resources("europe_shape.geojson"),
output: output:
resources("networks/base.nc"), base_network=resources("networks/base.nc"),
regions_onshore=resources("regions_onshore.geojson"),
regions_offshore=resources("regions_offshore.geojson"),
log: log:
logs("base_network.log"), logs("base_network.log"),
benchmark: benchmark:
@ -127,27 +129,6 @@ rule build_shapes:
"../scripts/build_shapes.py" "../scripts/build_shapes.py"
rule build_bus_regions:
params:
countries=config_provider("countries"),
input:
country_shapes=resources("country_shapes.geojson"),
offshore_shapes=resources("offshore_shapes.geojson"),
base_network=resources("networks/base.nc"),
output:
regions_onshore=resources("regions_onshore.geojson"),
regions_offshore=resources("regions_offshore.geojson"),
log:
logs("build_bus_regions.log"),
threads: 1
resources:
mem_mb=1000,
conda:
"../envs/environment.yaml"
script:
"../scripts/build_bus_regions.py"
if config["enable"].get("build_cutout", False): if config["enable"].get("build_cutout", False):
rule build_cutout: rule build_cutout:

View File

@ -5,10 +5,7 @@
# coding: utf-8 # coding: utf-8
""" """
Creates the network topology from a `ENTSO-E map extract. Creates the network topology from an `ENTSO-E map extract <https://github.com/PyPSA/GridKit/tree/master/entsoe>`_ (March 2022) as a PyPSA network.
<https://github.com/PyPSA/GridKit/tree/master/entsoe>`_ (March 2022) as a PyPSA
network.
Relevant Settings Relevant Settings
----------------- -----------------
@ -59,8 +56,19 @@ Outputs
.. image:: img/base.png .. image:: img/base.png
:scale: 33 % :scale: 33 %
- ``resources/regions_onshore.geojson``:
.. image:: img/regions_onshore.png
:scale: 33 %
- ``resources/regions_offshore.geojson``:
.. image:: img/regions_offshore.png
:scale: 33 %
Description Description
----------- -----------
Creates the network topology from an ENTSO-E map extract, and create Voronoi shapes for each bus representing both onshore and offshore regions.
""" """
import logging import logging
@ -75,11 +83,11 @@ import shapely
import shapely.prepared import shapely.prepared
import shapely.wkt import shapely.wkt
import yaml import yaml
from _helpers import configure_logging, get_snapshots, set_scenario_config from _helpers import REGION_COLS, configure_logging, get_snapshots, set_scenario_config
from packaging.version import Version, parse from packaging.version import Version, parse
from scipy import spatial from scipy import spatial
from scipy.sparse import csgraph from scipy.sparse import csgraph
from shapely.geometry import LineString, Point from shapely.geometry import LineString, Point, Polygon
PD_GE_2_2 = parse(pd.__version__) >= Version("2.2") PD_GE_2_2 = parse(pd.__version__) >= Version("2.2")
@ -779,9 +787,147 @@ def base_network(
return n return n
def voronoi_partition_pts(points, outline):
"""
Compute the polygons of a voronoi partition of `points` within the polygon
`outline`. Taken from
https://github.com/FRESNA/vresutils/blob/master/vresutils/graph.py.
Attributes
----------
points : Nx2 - ndarray[dtype=float]
outline : Polygon
Returns
-------
polygons : N - ndarray[dtype=Polygon|MultiPolygon]
"""
points = np.asarray(points)
if len(points) == 1:
polygons = [outline]
else:
xmin, ymin = np.amin(points, axis=0)
xmax, ymax = np.amax(points, axis=0)
xspan = xmax - xmin
yspan = ymax - ymin
# to avoid any network positions outside all Voronoi cells, append
# the corners of a rectangle framing these points
vor = spatial.Voronoi(
np.vstack(
(
points,
[
[xmin - 3.0 * xspan, ymin - 3.0 * yspan],
[xmin - 3.0 * xspan, ymax + 3.0 * yspan],
[xmax + 3.0 * xspan, ymin - 3.0 * yspan],
[xmax + 3.0 * xspan, ymax + 3.0 * yspan],
],
)
)
)
polygons = []
for i in range(len(points)):
poly = Polygon(vor.vertices[vor.regions[vor.point_region[i]]])
if not poly.is_valid:
poly = poly.buffer(0)
with np.errstate(invalid="ignore"):
poly = poly.intersection(outline)
polygons.append(poly)
return polygons
def build_bus_shapes(n, country_shapes, offshore_shapes, countries):
country_shapes = gpd.read_file(country_shapes).set_index("name")["geometry"]
offshore_shapes = gpd.read_file(offshore_shapes)
offshore_shapes = offshore_shapes.reindex(columns=REGION_COLS).set_index("name")[
"geometry"
]
onshore_regions = []
offshore_regions = []
for country in countries:
c_b = n.buses.country == country
onshore_shape = country_shapes[country]
onshore_locs = (
n.buses.loc[c_b & n.buses.onshore_bus]
.sort_values(
by="substation_lv", ascending=False
) # preference for substations
.drop_duplicates(subset=["x", "y"], keep="first")[["x", "y"]]
)
onshore_regions.append(
gpd.GeoDataFrame(
{
"name": onshore_locs.index,
"x": onshore_locs["x"],
"y": onshore_locs["y"],
"geometry": voronoi_partition_pts(
onshore_locs.values, onshore_shape
),
"country": country,
}
)
)
if country not in offshore_shapes.index:
continue
offshore_shape = offshore_shapes[country]
offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]]
offshore_regions_c = gpd.GeoDataFrame(
{
"name": offshore_locs.index,
"x": offshore_locs["x"],
"y": offshore_locs["y"],
"geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape),
"country": country,
}
)
offshore_regions_c = offshore_regions_c.loc[offshore_regions_c.area > 1e-2]
offshore_regions.append(offshore_regions_c)
shapes = pd.concat(onshore_regions, ignore_index=True)
return onshore_regions, offshore_regions, shapes
def append_bus_shapes(n, shapes, type):
"""
Append shapes to the network. If shapes with the same component and type
already exist, they will be removed.
Parameters:
n (pypsa.Network): The network to which the shapes will be appended.
shapes (geopandas.GeoDataFrame): The shapes to be appended.
**kwargs: Additional keyword arguments used in `n.madd`.
Returns:
None
"""
remove = n.shapes.query("component == 'Bus' and type == @type").index
n.mremove("Shape", remove)
offset = n.shapes.index.astype(int).max() + 1 if not n.shapes.empty else 0
shapes = shapes.rename(lambda x: int(x) + offset)
n.madd(
"Shape",
shapes.index,
geometry=shapes.geometry,
idx=shapes.name,
component="Bus",
type=type,
)
if __name__ == "__main__": if __name__ == "__main__":
if "snakemake" not in globals(): if "snakemake" not in globals():
from _helpers import mock_snakemake from _helpers import mock_snakemake
snakemake = mock_snakemake("base_network") snakemake = mock_snakemake("base_network")
@ -803,5 +949,22 @@ if __name__ == "__main__":
snakemake.config, snakemake.config,
) )
onshore_regions, offshore_regions, shapes = build_bus_shapes(
n,
snakemake.input.country_shapes,
snakemake.input.offshore_shapes,
snakemake.params.countries,
)
shapes.to_file(snakemake.output.regions_onshore)
append_bus_shapes(n, shapes, "onshore")
if offshore_regions:
shapes = pd.concat(offshore_regions, ignore_index=True)
shapes.to_file(snakemake.output.regions_offshore)
append_bus_shapes(n, shapes, "offshore")
else:
offshore_shapes.to_frame().to_file(snakemake.output.regions_offshore)
n.meta = snakemake.config n.meta = snakemake.config
n.export_to_netcdf(snakemake.output[0]) n.export_to_netcdf(snakemake.output.base_network)

View File

@ -1,218 +0,0 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Creates Voronoi shapes for each bus representing both onshore and offshore
regions.
Relevant Settings
-----------------
.. code:: yaml
countries:
.. seealso::
Documentation of the configuration file ``config/config.yaml`` at
:ref:`toplevel_cf`
Inputs
------
- ``resources/country_shapes.geojson``: confer :ref:`shapes`
- ``resources/offshore_shapes.geojson``: confer :ref:`shapes`
- ``networks/base.nc``: confer :ref:`base`
Outputs
-------
- ``resources/regions_onshore.geojson``:
.. image:: img/regions_onshore.png
:scale: 33 %
- ``resources/regions_offshore.geojson``:
.. image:: img/regions_offshore.png
:scale: 33 %
Description
-----------
"""
import logging
import geopandas as gpd
import numpy as np
import pandas as pd
import pypsa
from _helpers import REGION_COLS, configure_logging, set_scenario_config
from scipy.spatial import Voronoi
from shapely.geometry import Polygon
logger = logging.getLogger(__name__)
def voronoi_partition_pts(points, outline):
"""
Compute the polygons of a voronoi partition of `points` within the polygon
`outline`. Taken from
https://github.com/FRESNA/vresutils/blob/master/vresutils/graph.py.
Attributes
----------
points : Nx2 - ndarray[dtype=float]
outline : Polygon
Returns
-------
polygons : N - ndarray[dtype=Polygon|MultiPolygon]
"""
points = np.asarray(points)
if len(points) == 1:
polygons = [outline]
else:
xmin, ymin = np.amin(points, axis=0)
xmax, ymax = np.amax(points, axis=0)
xspan = xmax - xmin
yspan = ymax - ymin
# to avoid any network positions outside all Voronoi cells, append
# the corners of a rectangle framing these points
vor = Voronoi(
np.vstack(
(
points,
[
[xmin - 3.0 * xspan, ymin - 3.0 * yspan],
[xmin - 3.0 * xspan, ymax + 3.0 * yspan],
[xmax + 3.0 * xspan, ymin - 3.0 * yspan],
[xmax + 3.0 * xspan, ymax + 3.0 * yspan],
],
)
)
)
polygons = []
for i in range(len(points)):
poly = Polygon(vor.vertices[vor.regions[vor.point_region[i]]])
if not poly.is_valid:
poly = poly.buffer(0)
with np.errstate(invalid="ignore"):
poly = poly.intersection(outline)
polygons.append(poly)
return polygons
def append_bus_shapes(n, shapes, type):
"""
Append shapes to the network. If shapes with the same component and type
already exist, they will be removed.
Parameters:
n (pypsa.Network): The network to which the shapes will be appended.
shapes (geopandas.GeoDataFrame): The shapes to be appended.
**kwargs: Additional keyword arguments used in `n.madd`.
Returns:
None
"""
remove = n.shapes.query("component == 'Bus' and type == @type").index
n.mremove("Shape", remove)
offset = n.shapes.index.astype(int).max() + 1 if not n.shapes.empty else 0
shapes = shapes.rename(lambda x: int(x) + offset)
n.madd(
"Shape",
shapes.index,
geometry=shapes.geometry,
idx=shapes.name,
component="Bus",
type=type,
)
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake("build_bus_regions")
configure_logging(snakemake)
set_scenario_config(snakemake)
countries = snakemake.params.countries
base_network = snakemake.input.base_network
n = pypsa.Network(base_network)
country_shapes = gpd.read_file(snakemake.input.country_shapes).set_index("name")[
"geometry"
]
offshore_shapes = gpd.read_file(snakemake.input.offshore_shapes)
offshore_shapes = offshore_shapes.reindex(columns=REGION_COLS).set_index("name")[
"geometry"
]
onshore_regions = []
offshore_regions = []
for country in countries:
c_b = n.buses.country == country
onshore_shape = country_shapes[country]
onshore_locs = (
n.buses.loc[c_b & n.buses.onshore_bus]
.sort_values(
by="substation_lv", ascending=False
) # preference for substations
.drop_duplicates(subset=["x", "y"], keep="first")[["x", "y"]]
)
onshore_regions.append(
gpd.GeoDataFrame(
{
"name": onshore_locs.index,
"x": onshore_locs["x"],
"y": onshore_locs["y"],
"geometry": voronoi_partition_pts(
onshore_locs.values, onshore_shape
),
"country": country,
}
)
)
if country not in offshore_shapes.index:
continue
offshore_shape = offshore_shapes[country]
offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]]
offshore_regions_c = gpd.GeoDataFrame(
{
"name": offshore_locs.index,
"x": offshore_locs["x"],
"y": offshore_locs["y"],
"geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape),
"country": country,
}
)
offshore_regions_c = offshore_regions_c.loc[offshore_regions_c.area > 1e-2]
offshore_regions.append(offshore_regions_c)
shapes = pd.concat(onshore_regions, ignore_index=True)
shapes.to_file(snakemake.output.regions_onshore)
append_bus_shapes(n, shapes, "onshore")
if offshore_regions:
shapes = pd.concat(offshore_regions, ignore_index=True)
shapes.to_file(snakemake.output.regions_offshore)
append_bus_shapes(n, shapes, "offshore")
else:
offshore_shapes.to_frame().to_file(snakemake.output.regions_offshore)
# save network with shapes
n.export_to_netcdf(base_network)

View File

@ -135,7 +135,7 @@ import pypsa
import seaborn as sns import seaborn as sns
from _helpers import configure_logging, set_scenario_config, update_p_nom_max from _helpers import configure_logging, set_scenario_config, update_p_nom_max
from add_electricity import load_costs from add_electricity import load_costs
from build_bus_regions import append_bus_shapes from base_network import append_bus_shapes
from packaging.version import Version, parse from packaging.version import Version, parse
from pypsa.clustering.spatial import ( from pypsa.clustering.spatial import (
busmap_by_greedy_modularity, busmap_by_greedy_modularity,

View File

@ -95,7 +95,7 @@ import pypsa
import scipy as sp import scipy as sp
from _helpers import configure_logging, set_scenario_config, update_p_nom_max from _helpers import configure_logging, set_scenario_config, update_p_nom_max
from add_electricity import load_costs from add_electricity import load_costs
from build_bus_regions import append_bus_shapes from base_network import append_bus_shapes
from cluster_network import cluster_regions, clustering_for_n_clusters from cluster_network import cluster_regions, clustering_for_n_clusters
from pypsa.clustering.spatial import ( from pypsa.clustering.spatial import (
aggregateoneport, aggregateoneport,