Wind Turbines#

Wind turbine positions define the layout of a wind farm, including turbine locations, hub heights, and mapping to WTG specifications.

Data Structure#

Wind turbines are xarray.Dataset objects with the point spatial structure:

Dimensions:  (point, ...)
Variables:
    west_east    (point)  - x coordinate
    south_north  (point)  - y coordinate
    height       (point)  - hub height (meters above ground)
    turbine_id   (point)  - unique turbine identifier
    group_id     (point)  - turbine group identifier (optional)
    wtg_key      (point)  - wind turbine generator key (string)
    crs                   - coordinate reference system

I/O#

Reading from Tutorial Data:

# Load turbines from tutorial data
path = wk.get_tutorial_data("serra_santa_luzia")
data = wk.load_tutorial_data("serra_santa_luzia")
turbines = data.turbines
turbines
<xarray.Dataset> Size: 1kB
Dimensions:      (point: 15)
Coordinates:
    height       (point) int64 120B 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
    south_north  (point) int64 120B 4622313 4622199 4622336 ... 4624252 4624142
    west_east    (point) int64 120B 513914 514161 514425 ... 516060 516295
    turbine_id   (point) int64 120B 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
    group_id     (point) float64 120B 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
    wtg_key      (point) <U9 540B 'Bonus 1MW' 'Bonus 1MW' ... 'Bonus 1MW'
    crs          int8 1B 0
Dimensions without coordinates: point
Data variables:
    *empty*
Attributes:
    Conventions:  CF-1.8
    history:      2024-10-08T07:28:14+00:00:\twindkit==0.8.1.dev25+g2e8f19c\t...

Creating:

Wind turbines are created programmatically (no file format):

Exporting:

windkit.wind_turbines_to_geodataframe() converts to GeoDataFrame for GIS export:

gdf = wk.wind_turbines_to_geodataframe(turbines)
print(f"GeoDataFrame with {len(gdf)} turbines")
gdf.head()
GeoDataFrame with 15 turbines
geometry turbine_id group_id wtg_key
0 POINT Z (513914 4622313 50) 0 0.0 Bonus 1MW
1 POINT Z (514161 4622199 50) 1 0.0 Bonus 1MW
2 POINT Z (514425 4622336 50) 2 0.0 Bonus 1MW
3 POINT Z (513537 4622733 50) 3 0.0 Bonus 1MW
4 POINT Z (513295 4622683 50) 4 0.0 Bonus 1MW

Creating from Arrays#

turbines_new = wk.create_wind_turbines_from_arrays(
    west_east=[0, 0, 0, 0, 0],
    south_north=[0, 500, 1000, 1500, 2000],
    height=[80, 80, 80, 80, 80],
    crs="EPSG:32632",
    turbine_ids=[1, 2, 3, 4, 5],
    group_ids=[0, 0, 1, 1, 1],
    wtg_keys=["wtg1", "wtg1", "wtg2", "wtg2", "wtg2"],
)
turbines_new
<xarray.Dataset> Size: 281B
Dimensions:      (point: 5)
Coordinates:
    height       (point) int64 40B 80 80 80 80 80
    south_north  (point) int64 40B 0 500 1000 1500 2000
    west_east    (point) int64 40B 0 0 0 0 0
    turbine_id   (point) int64 40B 1 2 3 4 5
    group_id     (point) int64 40B 0 0 1 1 1
    wtg_key      (point) <U4 80B 'wtg1' 'wtg1' 'wtg2' 'wtg2' 'wtg2'
    crs          int8 1B 0
Dimensions without coordinates: point
Data variables:
    *empty*
Attributes:
    Conventions:  CF-1.8
    history:      2026-01-29T09:30:25+00:00:\twindkit==2.0.1\tcreate_dataset(

Creating from DataFrame#

The DataFrame must have columns named west_east, south_north, height, and wtg_key:

df = pd.DataFrame({
    "west_east": [0.0, 0.0, 0.0],
    "south_north": [0.0, 500.0, 1000.0],
    "height": [80.0, 80.0, 80.0],
    "wtg_key": ["vestas", "vestas", "vestas"],
})

turbines_from_df = wk.create_wind_turbines_from_dataframe(df, crs="EPSG:32632")
turbines_from_df
<xarray.Dataset> Size: 145B
Dimensions:      (point: 3)
Coordinates:
    height       (point) float64 24B 80.0 80.0 80.0
    south_north  (point) float64 24B 0.0 500.0 1e+03
    west_east    (point) float64 24B 0.0 0.0 0.0
    turbine_id   (point) int64 24B 0 1 2
    group_id     (point) int64 24B 0 0 0
    wtg_key      (point) object 24B 'vestas' 'vestas' 'vestas'
    crs          int8 1B 0
Dimensions without coordinates: point
Data variables:
    *empty*
Attributes:
    Conventions:  CF-1.8
    history:      2026-01-29T09:30:25+00:00:\twindkit==2.0.1\tcreate_dataset(

WTG Key Mapping#

The wtg_key variable maps each turbine to a WTG specification. This allows different turbine types within the same wind farm:

# Wind turbines with different WTG types
turbines_mixed = wk.create_wind_turbines_from_arrays(
    west_east=[0, 100, 200],
    south_north=[0, 0, 0],
    height=[80, 80, 100],
    crs="EPSG:32632",
    wtg_keys=["vestas_v80", "vestas_v80", "vestas_v100"],
)

# Check unique WTG keys
unique_wtgs = np.unique(turbines_mixed.wtg_key.values)
print(f"Unique WTG keys: {unique_wtgs}")
Unique WTG keys: ['vestas_v100' 'vestas_v80']

Validation#

is_valid = wk.is_windturbines(turbines_new)
print(f"Is valid wind turbines dataset: {is_valid}")
Is valid wind turbines dataset: True