{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "3e61c1aa-b033-4628-939c-81f08eeaa32c", "metadata": {}, "source": [ "**Note**: many of the jupyter notebooks provided here have SVG figures as cell outputs, which will only be displayed by JupyterLab or Jupyter Notebook if the notebook is marked as **trusted** (In JupyterLab: Ctrl+Shift+C -> Trust Notebook)." ] }, { "cell_type": "markdown", "id": "5ec7e27e-3eef-427a-ac74-f4f6ea49c935", "metadata": {}, "source": [ "# Data Input" ] }, { "cell_type": "markdown", "id": "fca2771e-61e8-4f29-a6ae-8bbce26c4762", "metadata": {}, "source": [ "There are 4 alternatives to import wind farm layout data for use within **OptiWindNet**:\n", "- Numpy arrays through OptiWindNet API\n", "- [windIO](https://github.com/IEAWindSystems/windIO) YAML file\n", "- `.yaml` file (OptiWindNet schema)\n", "- `.osm.pbf` file" ] }, { "cell_type": "code", "execution_count": 1, "id": "fa29e2ac-26f7-4927-bebf-eeef30a5ab37", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.svg import svgplot" ] }, { "cell_type": "markdown", "id": "1bcfeda4-e9da-4305-b7ab-22c38f96f199", "metadata": {}, "source": [ "## Numpy arrays + OptiWindNet API" ] }, { "cell_type": "code", "execution_count": 2, "id": "b8a5532f-804f-4eb2-86f2-8147957f6288", "metadata": {}, "outputs": [], "source": [ "from itertools import pairwise\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 3, "id": "1d2c0acc-b5ff-4ca0-b447-786a8d9c7ad2", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.importer import L_from_site" ] }, { "cell_type": "code", "execution_count": 4, "id": "72d3bcf0-f118-4ad0-834f-9b1adac69740", "metadata": {}, "outputs": [], "source": [ "# all coordinates are sequences of (x, y) pairs\n", "# if input coordinates are in arrays X and Y, use `np.hstack((X, Y))`\n", "border = np.array( # coordinate sequence defines the polygon, last-first segment implicit\n", " [[1951, 200], [1951, 1383], [386, 1383], [650, 708], [624, 678],\n", " [4, 1036], [4, 3], [1152, 3], [917, 819], [957, 854]],\n", " dtype=float)\n", "# 'obstacles' is an optional location attribute\n", "obstacles = [\n", " # - obstacles must be strictly inside the border polygon\n", " # - undefined behavior if obstacles and border overlap\n", " # first obstacle\n", " np.array([[1540, 920], [1600, 940], [1600, 1150], [1400, 1200]]),\n", " # [second obstacle] ...\n", "]\n", "substations = np.array([[696, 1063],], dtype=float)\n", "turbines = np.array(\n", " [[1940, 279], [1920, 703], [1475, 696], [1839, 1250],\n", " [1277, 1296], [442, 1359], [737, 435], [1060, 26],\n", " [522, 176], [87, 35], [184, 417], [71, 878]],\n", " dtype=float\n", ")\n", "R = substations.shape[0]\n", "T = turbines.shape[0]\n", "border_sizes = np.array([border.shape[0]] +\n", " [obstacle.shape[0] for obstacle in obstacles])\n", "B = border_sizes.sum()\n", "obstacle_idxs = np.cumsum(border_sizes) + T" ] }, { "cell_type": "code", "execution_count": 5, "id": "a2e25924-55f9-4025-af72-c6714c7a7511", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L = L_from_site(\n", " R=R, T=T, B=B,\n", " border=np.arange(T, T + border.shape[0]),\n", " obstacles=[np.arange(a, b) for a, b in pairwise(obstacle_idxs)],\n", " name='Example Location',\n", " handle='example',\n", " VertexC=np.vstack((turbines, border, *obstacles, substations)),\n", ")\n", "svgplot(L)" ] }, { "cell_type": "markdown", "id": "ac064931-e789-467f-8378-0e64d098d46a", "metadata": {}, "source": [ "## windIO YAML file" ] }, { "cell_type": "markdown", "id": "4a574d32-1e8f-4a1f-8478-28692cedd52d", "metadata": {}, "source": [ "See the [windIO documentation](https://ieawindsystems.github.io/windIO/main/index.html) for more information on that format." ] }, { "cell_type": "code", "execution_count": 6, "id": "04ee20fd-5a9b-47bf-a5fc-4a02c7c2ad79", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.importer import L_from_windIO" ] }, { "cell_type": "code", "execution_count": 7, "id": "13ac9203-2158-4e4f-81cb-7ffb3de07d06", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L = L_from_windIO('data/IEA37_Borssele_Irregular_System.yaml')\n", "svgplot(L)" ] }, { "cell_type": "markdown", "id": "c91748c9-5a27-4363-8c04-508e54c54831", "metadata": {}, "source": [ "## YAML input file" ] }, { "cell_type": "code", "execution_count": 8, "id": "f9d1c872-2453-419e-9e02-57e309b29441", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.importer import L_from_yaml" ] }, { "cell_type": "code", "execution_count": 9, "id": "501eb6be-c087-46c2-85cd-11b5de328c57", "metadata": {}, "outputs": [], "source": [ "with open('data/example_location.yaml', 'w') as yaml_file:\n", " yaml_file.write('''\n", "# coordinate format can be \"planar\" or \"latlon\"\n", "# - for \"latlon\" examples, see `optiwindnet/data/*.yaml`\n", "# - this field is optional, default is \"latlon\"\n", "# - coordinates are converted to floats, so floats may be used as well\n", "COORDINATE_FORMAT: planar\n", "\n", "# handle is optional (if omited, one is derived from the file name)\n", "HANDLE: example\n", "\n", "# extents define a polygon:\n", "# - do not repeat the initial vertex at the end\n", "# - line breaks are optional\n", "EXTENTS: [\n", " [1951, 200],\n", " [1951, 1383],\n", " [386, 1383],\n", " [650, 708],\n", " [624, 678],\n", " [4, 1036],\n", " [4, 3],\n", " [1152, 3],\n", " [917, 819],\n", " [957, 854]\n", "]\n", "\n", "# obstacles is optional and must be a list of polygons (even if 1 obstacle)\n", "# - obstacles must be strictly inside the extents polygon\n", "# - the parser will not complain about borders of obstacles overlapping\n", "# borders of extents, but optiwindnet will behave unpredictably\n", "OBSTACLES: [\n", " [ # first obstacle\n", " [1540, 920],\n", " [1600, 940],\n", " [1600, 1150],\n", " [1400, 1200],\n", " ],\n", " # [second obstacle]\n", "]\n", "\n", "SUBSTATIONS: [\n", " [696, 1063],\n", "]\n", "\n", "TURBINES: [\n", " [1940, 279],\n", " [1920, 703],\n", " [1475, 696],\n", " [1839, 1250],\n", " [1277, 1296],\n", " [442, 1359],\n", " [737, 435],\n", " [1060, 26],\n", " [522, 176],\n", " [87, 35],\n", " [184, 417],\n", " [71, 878],\n", "]\n", "''')" ] }, { "cell_type": "code", "execution_count": 10, "id": "552e7fe1-810e-4453-a420-3d6c43e6ee2f", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L = L_from_yaml('data/example_location.yaml')\n", "svgplot(L)" ] }, { "cell_type": "markdown", "id": "ace13a16-228e-419c-b014-e7bba9da09e5", "metadata": {}, "source": [ "## OSM.PBF input file (OpenStreetMap Protobuffer Format)" ] }, { "cell_type": "markdown", "id": "8530db3e-a4b1-4e94-b97c-714fe14f44fb", "metadata": {}, "source": [ "The JOSM open-source map editor is recommended if using this format: . In addition, the JOSM plugin **pbf** is required to save in the `.osm.pbf` format. The plugin **opendata** is useful for importing many common GIS file formats." ] }, { "cell_type": "markdown", "id": "71c381c7-9040-4c32-b01f-9d5328265a2c", "metadata": {}, "source": [ "The OpenStreetMaps objects used for representing a windfarm location are:\n", "- *nodes*\n", "- *ways*\n", "- *multipolygons* (relation between closed ways)\n", "\n", "Wind turbines are represented by *nodes* with the tag `power=generator`. Substations are represented either by *nodes* or by closed *ways* tagged `power=substation` or `power=transformer`. Substations based on *ways* will be reduced to the point at the centroid of the polygon defined by the *way*.\n", "\n", "The border of the windfarm can be a closed *way* tagged `power=plant`. If obstacles are required, then the closed *way* for the border must be combined with the closed *ways* for the obstacles in a *multipolygon* with the tag `power=plant` (in which case the *ways* themselves should not be tagged)." ] }, { "cell_type": "markdown", "id": "66e8ff88-400c-4a1a-a182-19d60cf1270a", "metadata": {}, "source": [ "See `optiwindnet/data/*.osm.pbf` for more examples." ] }, { "cell_type": "code", "execution_count": 11, "id": "ebff6d6c-ae49-4634-adc8-d780dbd3ae6d", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.importer import L_from_pbf" ] }, { "cell_type": "code", "execution_count": 12, "id": "0fa84ade-8012-4d54-a68c-e2896563924f", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L = L_from_pbf('data/example_location.osm.pbf')\n", "svgplot(L)" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }