Weibull parameters of wind speeds - 150 m above ground level#

import os
from zipfile import ZipFile

import cartopy.crs as ccrs
import contextily as cx
import geopandas as gpd
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib_scalebar.scalebar import ScaleBar

from h2ss import data as rd
from h2ss import functions as fns
plt.rcParams["xtick.major.size"] = 0
plt.rcParams["ytick.major.size"] = 0
# base data download directory
DATA_DIR = os.path.join("data", "weibull-parameters-wind-speeds")

FILE_NAME = "Weibull_150m_params_ITM.zip"

URL = f"https://seaiopendata.blob.core.windows.net/wind/{FILE_NAME}"

DATA_FILE = os.path.join(DATA_DIR, FILE_NAME)

# basemap cache directory
cx.set_cache_dir(os.path.join("data", "basemaps"))
rd.download_data(url=URL, data_dir=DATA_DIR, file_name=FILE_NAME)
Data 'Weibull_150m_params_ITM.zip' already exists in 'data/weibull-parameters-wind-speeds'.
Data downloaded on: 2023-12-31 00:18:52.534921+00:00
Download URL: https://seaiopendata.blob.core.windows.net/wind/Weibull_150m_params_ITM.zip
SHA256 hash: d946e0c65417b0dc7325d3cec9c5d71d8bf80225bc85ee788349ad15b92cd767
ZipFile(DATA_FILE).namelist()
['Weibull_150m_c_ITM.cpg',
 'Weibull_150m_c_ITM.dbf',
 'Weibull_150m_c_ITM.prj',
 'Weibull_150m_c_ITM.sbn',
 'Weibull_150m_c_ITM.sbx',
 'Weibull_150m_c_ITM.shp',
 'Weibull_150m_c_ITM.shp.xml',
 'Weibull_150m_c_ITM.shx',
 'Weibull_150m_k_ITM.cpg',
 'Weibull_150m_k_ITM.dbf',
 'Weibull_150m_k_ITM.prj',
 'Weibull_150m_k_ITM.sbn',
 'Weibull_150m_k_ITM.sbx',
 'Weibull_150m_k_ITM.shp',
 'Weibull_150m_k_ITM.shp.xml',
 'Weibull_150m_k_ITM.shx',
 'Weibull_40m_k_ITM.zip']
weibull_c = rd.read_shapefile_from_zip(
    data_path=os.path.join(DATA_FILE), endswith="c_ITM.shp"
)
weibull_k = rd.read_shapefile_from_zip(
    data_path=os.path.join(DATA_FILE), endswith="k_ITM.shp"
)
weibull_c.crs
<Projected CRS: EPSG:2157>
Name: IRENET95 / Irish Transverse Mercator
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Ireland - onshore. United Kingdom (UK) - Northern Ireland (Ulster) - onshore.
- bounds: (-10.56, 51.39, -5.34, 55.43)
Coordinate Operation:
- name: Irish Transverse Mercator
- method: Transverse Mercator
Datum: IRENET95
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
weibull_k.crs
<Projected CRS: EPSG:2157>
Name: IRENET95 / Irish Transverse Mercator
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Ireland - onshore. United Kingdom (UK) - Northern Ireland (Ulster) - onshore.
- bounds: (-10.56, 51.39, -5.34, 55.43)
Coordinate Operation:
- name: Irish Transverse Mercator
- method: Transverse Mercator
Datum: IRENET95
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
weibull_c.shape
(2518, 6)
weibull_k.shape
(353, 6)
weibull_c.columns
Index(['FID_Weibul', 'Value', 'FID_Grid', 'Shape_Leng', 'Shape_Area',
       'geometry'],
      dtype='object')
weibull_k.columns
Index(['FID_Weibul', 'Value', 'FID_Grid', 'Shape_Leng', 'Shape_Area',
       'geometry'],
      dtype='object')
weibull_c.head()
FID_Weibul Value FID_Grid Shape_Leng Shape_Area geometry
0 1 5.9 23 6485.392772 2.628766e+06 POLYGON ((469500.000 579500.000, 468500.000 57...
1 2 6.0 23 11430.320784 8.017942e+06 POLYGON ((470500.000 581500.000, 470500.000 58...
2 2 6.0 33 8026.363916 2.503502e+06 POLYGON ((470499.999 581998.183, 468499.999 58...
3 3 6.1 23 6485.447461 2.628810e+06 POLYGON ((470500.000 579500.000, 469500.000 57...
4 3 6.1 34 16233.724878 7.909965e+06 MULTIPOLYGON (((493500.000 586500.000, 492500....
weibull_k.head()
FID_Weibul Value FID_Grid Shape_Leng Shape_Area geometry
0 1 1.5 23 31375.956480 5.094710e+07 POLYGON ((470686.569 561616.211, 471500.000 55...
1 2 1.6 23 112841.312826 2.875967e+08 MULTIPOLYGON (((469463.639 582025.159, 470359....
2 2 1.6 24 61933.596119 1.803478e+08 POLYGON ((499218.002 555385.132, 501224.182 55...
3 2 1.6 33 38544.777250 3.352720e+07 MULTIPOLYGON (((479500.000 596500.000, 477500....
4 2 1.6 34 23979.626674 1.695664e+07 MULTIPOLYGON (((490872.910 585937.775, 491500....
ds, extent = rd.read_dat_file(dat_path=os.path.join("data", "kish-basin"))
xmin, ymin, xmax, ymax = extent.total_bounds
ax = weibull_c.to_crs(3857).plot(
    column="Value",
    cmap="flare",
    figsize=(6, 6),
    legend=True,
    legend_kwds={"label": "c"},
)
cx.add_basemap(ax, source=cx.providers.CartoDB.Positron)
plt.tick_params(labelbottom=False, labelleft=False)
plt.tight_layout()
plt.show()
../_images/ecc2bc3f663b61230b08475918afdae4d3850c7bdf966bb8d6de28fb93945780.png
ax = weibull_k.to_crs(3857).plot(
    column="Value",
    cmap="flare",
    figsize=(6, 6),
    legend=True,
    legend_kwds={"label": "k"},
)
cx.add_basemap(ax, source=cx.providers.CartoDB.Positron)
plt.tick_params(labelbottom=False, labelleft=False)
plt.tight_layout()
plt.show()
../_images/5d9aeedf47b406e3c04747ae20cb5957006b50f96479ac20c7bec3910b78bd58.png
# wind farms in the area
wind_farms = fns.constraint_wind_farm(
    data_path=os.path.join(
        "data", "wind-farms", "marine-area-consent-wind.zip"
    )
)
# shape of the halite
shape = rd.halite_shape(dat_xr=ds)
# land boundary
land = rd.read_shapefile_from_zip(
    data_path=os.path.join(
        "data", "boundaries", "osi-provinces-ungeneralised-2019.zip"
    )
)

land = land.dissolve().to_crs(rd.CRS)
# crop to wind farm and basin extent
extent_wf = gpd.GeoDataFrame(
    geometry=(
        gpd.GeoDataFrame(geometry=wind_farms.dissolve().envelope)
        .overlay(gpd.GeoDataFrame(geometry=extent), how="union")
        .dissolve()
        .envelope
    )
)
weibull_c = weibull_c.to_crs(rd.CRS).overlay(extent_wf, how="intersection")
weibull_k = weibull_k.to_crs(rd.CRS).overlay(extent_wf, how="intersection")
# crop land boundary from c and k
weibull_c = weibull_c.overlay(land, how="difference")
weibull_k = weibull_k.overlay(land, how="difference")
def plot_map(df, label):
    """Plotting helper function"""
    plt.figure(figsize=(10, 10))
    ax1 = plt.axes(projection=ccrs.epsg(rd.CRS))

    # add halite boundary - use buffering to smooth the outline
    shape.buffer(1000).buffer(-1000).boundary.plot(
        ax=ax1, color="black", linewidth=2
    )

    # wind farms
    colours = ["lime", "darkslategrey", "deepskyblue"]
    for index, colour in zip(range(len(wind_farms)), colours):
        wind_farms.iloc[[index]].plot(
            ax=ax1,
            hatch="///",
            facecolor="none",
            edgecolor=colour,
            linewidth=2,
            zorder=2,
        )
    legend_handles = [
        mpatches.Patch(
            facecolor="none",
            hatch="////",
            edgecolor=colours[x],
            label=list(wind_farms["name"])[x],
        )
        for x in range(len(wind_farms))
    ]

    legend_handles.append(
        mpatches.Patch(
            facecolor="none",
            edgecolor="black",
            label="Kish Basin halite",
            linewidth=2,
        )
    )

    df.plot(
        column="Value",
        cmap="flare",
        figsize=(6, 6),
        legend=True,
        ax=ax1,
        zorder=1,
        legend_kwds={"label": label},
    )

    cx.add_basemap(
        ax1, crs=rd.CRS, source=cx.providers.CartoDB.Voyager, zoom=10
    )
    ax1.gridlines(
        draw_labels={"bottom": "x", "left": "y"},
        alpha=0.25,
        color="darkslategrey",
    )
    ax1.add_artist(
        ScaleBar(1, box_alpha=0, location="lower right", color="darkslategrey")
    )
    ax1.legend(handles=legend_handles, loc="upper right")

    plt.title(None)
    plt.tight_layout()
    plt.show()
plot_map(weibull_c, "c")
../_images/378b7fd89681f04f8bd187ce6341cdc2a7e7fb3ebc08b41a4a3db07a26207f7d.png
plot_map(weibull_k, "k")
../_images/3f434a04a9cd35c1712d85fdc0d14cfafa498461a6503ce30c7d96eb7750b78c.png
# areas intersecting with wind farms
weibull_c = weibull_c.overlay(wind_farms, how="intersection")
weibull_k = weibull_k.overlay(wind_farms, how="intersection")
# compute c and k over wind farms
weibull_c = wind_farms.merge(
    weibull_c.dissolve(by="name", aggfunc={"Value": ["min", "max", "mean"]}),
    on="name",
)
weibull_k = wind_farms.merge(
    weibull_k.dissolve(by="name", aggfunc={"Value": ["min", "max", "mean"]}),
    on="name",
)
weibull_c[["name", ("Value", "min"), ("Value", "max"), ("Value", "mean")]]
name (Value, min) (Value, max) (Value, mean)
0 Codling Wind Park 10.2 10.8 10.500000
1 Dublin Array 9.9 10.6 10.292857
2 North Irish Sea Array 10.7 11.2 10.950000
weibull_k[["name", ("Value", "min"), ("Value", "max"), ("Value", "mean")]]
name (Value, min) (Value, max) (Value, mean)
0 Codling Wind Park 1.9 2.0 1.950000
1 Dublin Array 1.9 2.0 1.950000
2 North Irish Sea Array 2.1 2.2 2.133333