diff --git a/.github/workflows/github_test_action.yml b/.github/workflows/github_test_action.yml
index 504384211..a816bec26 100644
--- a/.github/workflows/github_test_action.yml
+++ b/.github/workflows/github_test_action.yml
@@ -314,7 +314,8 @@ jobs:
- name: Check docs for Python ${{ matrix.python-version }}
uses: e2nIEE/sphinx-action@master
with:
- pre-build-command: "python -m pip install --upgrade pip;
- python -m pip install .[docs];"
+ pre-build-command: "apt update && apt upgrade -y && apt install -y build-essential gfortran cmake pkg-config libopenblas-dev;
+ python -m pip install --upgrade pip;
+ python -m pip install .[docs];"
build-command: "sphinx-build -b html . _build -W"
docs-folder: "doc/"
diff --git a/.install_julia.sh b/.install_julia.sh
index a260cecfc..2f3b351fd 100755
--- a/.install_julia.sh
+++ b/.install_julia.sh
@@ -86,8 +86,7 @@ case $(uname) in
curl -L "$BASEURL/linux/$ARCH/$JULIANAME-$SUFFIX.tar.gz" | tar -xz
sudo ln -s $PWD/julia-*/bin/julia /usr/local/bin/julia
julia -e 'import Pkg; Pkg.add("PyCall");'
- julia -e 'import Pkg; Pkg.add("PowerModels"); Pkg.add("Ipopt");'
- julia -e 'import Pkg; Pkg.add("JSON"); Pkg.add("JuMP"); Pkg.add("Cbc"); Pkg.add("Juniper");'
+ julia -e 'import Pkg; Pkg.Registry.update(); Pkg.add("PandaModels"); Pkg.build(); Pkg.resolve();'
;;
Darwin)
if [ -e /usr/local/bin/julia ]; then
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 376c04ba4..097e6028b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,16 @@
Change Log
=============
+[upcoming release] - 2024-..-..
+-------------------------------
+- [ADDED] pandas series accessor for geo column
+- [FIXED] Increasing geojson precision as the default precision might cause problems with pandahub
+- [ADDED] Add GeographicalRegion and SubGeographicalRegion names and ids to bus df in cim converter
+- [CHANGED] Capitalize first letter of columns busbar_id, busbar_name and substation_id in bus df for cim converter
+- [FIXED] Do not modify pandas options when importing pandapower
+- [ADDED] improved lightsim2grid documentation including compatibitliy issues
+- [FIXED] cim2pp: set default xml encoding to None to avoid error after changing to lxml
+
[2.14.11] - 2024-07-08
-------------------------------
- [FIXED] Lightsim2grid version
@@ -16,7 +26,12 @@ Change Log
[upcoming release] - 2024-..-..
-------------------------------
-- [ADDED] pf2pp: possibility to convert a specific varaint and scenario
+- [FIXED] PandaModels OPF with 'bus_dc' key errors
+- [FIXED] julia tests
+- [FIXED] copy array element to standard python scalar
+- [FIXED] passing literal json to 'read_json' is deprecated
+- [FIXED] replacing deprecated in1d with isin
+- [ADDED] A switch to disable updating the vk and vkr values for trafo3w
- [FIXED] cast the column to the correct type before assigning values
- [FIXED] replacement for deprecated namespaces scipy.sparse.csc and scipy.sparse.csr
- [FIXED] copy array element to standard python scalar
@@ -81,7 +96,11 @@ Change Log
- [ADDED] Add VSC element, dc buses, dc lines, and hybrid AC/DC power flow calculation
- [CHANGED] accelerate _integrate_power_elements_connected_with_switch_buses() in get_equivalent()
- [CHANGED] accelerate distributed slack power flow calculation by using sparse-aware operations in _subnetworks()
+- [CHANGED] Trafo Controllers can now be added to elements that are out of service, changed self.nothing_to_do()
- [ADDED] Discrete shunt controller for local voltage regulation with shunt steps
+- [ADDED] fix lengths missmatch of output if ignore_zero_length is False in plotting utility function coords_from_node_geodata() and rename ignore_zero_length by ignore_no_geo_diff
+- [ADDED] cim2pp converter: Using lxml to parse XML files (better performance)
+- [ADDED] possibility to load JSON files with unknown object models and just store the models as dictionaries in the network
[2.14.7] - 2024-06-14
-------------------------------
diff --git a/doc/powerflow/ac.rst b/doc/powerflow/ac.rst
index bc6e46c55..331e4abc0 100644
--- a/doc/powerflow/ac.rst
+++ b/doc/powerflow/ac.rst
@@ -13,12 +13,69 @@ pandapower uses PYPOWER to solve the power flow problem:
If you are interested in the pypower casefile that pandapower is using for power flow, you can find it in net["_ppc"].
However all necessary informations are written into the pandpower format net, so the pandapower user should not usually have to deal with pypower.
-If available, the librabry lightsim2grid is used as a backend for power flow simulation instead of the
-implementation in pandapower, leading to a boost in performance. The library lightsim2grid is implemented in C++ and
-can either be installed with pip install lightsim2grid, or built from source. More about the library and the
-installation guide can be found in the `documentation `_ or
+Accelerating Packages
+-------------------------
+
+Two external packages are available which let accelerate pandapower's power flow command :code:`runppp`:
+
+1. numba
+2. lightsim2grid
+
+If available, i.e. installed on the operating computer, the code will check by default all
+prerequisites to use the external packages. numba is a python JIT compiler,
+cf. `link `_. In constrast, the library lightsim2grid
+is used as a backend for power flow simulation instead of the
+implementation in pandapower. It leads to a boost in performance. The library lightsim2grid is
+implemented in C++ and can either be installed with pip install lightsim2grid, or built from source.
+More about the library and the installation guide can be found in the
+`documentation `_ or
its GitHub `repository `_.
+lightsim2grid Compatibility
+```````````````````````````````
+
+lightsim2grid is supported if all the following conditions are met:
+
+1. The lightsim2grid library is installed and available.
+2. The selected power flow algorithm is Newton-Raphson (algorithm='nr').
+3. Voltage-dependent loads are not enabled (voltage_depend_loads=False).
+4. Either:
+
+ * There is only one slack bus in the network, or
+ * Distributed slack is enabled (distributed_slack=True).
+
+5. None of the following elements are present in the grid model:
+
+ * Controllable shunts, including SVC, SSC, or VSC elements.
+ * Controllable impedances, such as TCSC elements.
+ * DC elements, including DC buses (bus_dc) or DC lines (line_dc).
+
+6. Temperature-Dependent Power Flow is not requested (tdpf=False).
+
+When lightsim2grid is Not Supported
+```````````````````````````````````````
+
+If any of the above conditions are not met, lightsim2grid cannot be used. In such cases:
+
+* If lightsim2grid='auto' (default), the fallback to the standard pandapower implementation occurs without a detailed message.
+* If lightsim2grid=True is explicitly set, an appropriate error or warning is raised or logged, depending on the condition.
+
+Common Limitations of lightsim2grid
+````````````````````````````````````````
+
+lightsim2grid does not currently support:
+
+* Algorithms other than Newton-Raphson
+* Voltage-dependent loads
+* Multiple slack buses without distributed slack
+* Grids containing any of the following advanced elements:
+
+ * Controllable shunts (SVC, SSC, VSC)
+ * Controllable impedances (TCSC)
+ * DC buses or DC lines
+
+* Temperature-Dependent Power Flow (tdpf=True)
+
Temperature-Dependent Power Flow (TDPF)
---------------------------------------
diff --git a/pandapower/__init__.py b/pandapower/__init__.py
index acf95de67..120ddb725 100644
--- a/pandapower/__init__.py
+++ b/pandapower/__init__.py
@@ -17,6 +17,9 @@
from pandapower.runpm import *
from pandapower.pf.runpp_3ph import runpp_3ph
+import geojson
+geojson.geometry.DEFAULT_PRECISION = 8
+
import pandas as pd
pd.options.mode.chained_assignment = None # default='warn'
diff --git a/pandapower/auxiliary.py b/pandapower/auxiliary.py
index 0b08f4634..94715b8b7 100644
--- a/pandapower/auxiliary.py
+++ b/pandapower/auxiliary.py
@@ -33,6 +33,7 @@
from importlib.metadata import PackageNotFoundError
from typing_extensions import deprecated
+from geojson import loads, GeoJSON
import numpy as np
import pandas as pd
import scipy as sp
@@ -58,9 +59,16 @@
import pandaplan.core.pplog as logging
except ImportError:
import logging
+try:
+ from geopandas import GeoSeries
+ from shapely import from_geojson
+ geopandas_available = True
+except ImportError:
+ geopandas_available = False
logger = logging.getLogger(__name__)
+
def log_to_level(msg, passed_logger, level):
if level == "error":
passed_logger.error(msg)
@@ -343,6 +351,85 @@ def __repr__(self): # pragma: no cover
return "\n".join(lines)
+@pd.api.extensions.register_series_accessor("geojson")
+class GeoAccessor:
+ """
+ pandas Series accessor for the geo column. It facilitates the use of geojson strings.
+ NaN entrys are dropped using the accessor!
+ """
+ def __init__(self, pandas_obj):
+ self._validate(pandas_obj)
+ self._obj = pandas_obj
+
+ @staticmethod
+ def _validate(obj):
+ try:
+ if not obj.dropna().apply(loads).apply(isinstance, args=(GeoJSON,)).all():
+ raise AttributeError("Can only use .geojson accessor with geojson string values!")
+ except Exception as e:
+ raise AttributeError(f"Can only use .geojson accessor with geojson string values!: {e}")
+ if not geopandas_available:
+ soft_dependency_error("GeoAccessor", "geopandas")
+
+ @staticmethod
+ def _extract_coords(x):
+ if x["type"] == "Point":
+ return np.array(x["coordinates"])
+ return [np.array(y) for y in x["coordinates"]]
+
+ @property
+ def _coords(self):
+ """
+ Extracts the geometry coordinates from the GeoJSON strings.
+ It is not recommended to use the standalone coordinates.
+ Important informations like the crs or latlon/lonlat are lost as a result.
+ """
+ return self._obj.dropna().apply(loads).apply(self._extract_coords)
+
+ @property
+ def as_geo_obj(self):
+ """
+ Loads the GeoJSON objects.
+ """
+ return self._obj.dropna().apply(loads)
+
+ @property
+ def type(self):
+ """
+ Extracts the geometry type of the GeoJSON string.
+ """
+ return self._obj.dropna().apply(loads).apply(lambda x: str(x["type"]))
+
+ @property
+ def as_shapely_obj(self):
+ """
+ Converts the GeoJSON strings to shapely geometrys.
+ """
+ return self._obj.dropna().apply(from_geojson)
+
+ @property
+ def as_geoseries(self):
+ """
+ Converts the PandasSeries to a GeoSeries with shapely geometrys.
+ """
+ return GeoSeries(self._obj.dropna().pipe(from_geojson), crs=4326, index=self._obj.dropna().index)
+
+ def __getattr__(self, item):
+ """
+ Enables access to all methods or attribute calls from a GeoSeries.
+ """
+ geoms = self.as_geoseries
+ if hasattr(geoms, item):
+ geoms_item = getattr(geoms, item)
+ if callable(geoms_item):
+ def wrapper(*args, **kwargs):
+ return geoms_item(*args, **kwargs)
+ return wrapper
+ else:
+ return geoms_item
+ raise AttributeError(f"'GeoAccessor' object has no attribute '{item}'")
+
+
def plural_s(number):
return "" if number == 1 else "s"
@@ -1186,9 +1273,11 @@ def _check_if_numba_is_installed(level="warning"):
def _check_lightsim2grid_compatibility(net, lightsim2grid, voltage_depend_loads, algorithm, distributed_slack, tdpf):
"""
- Implement some checks to decide whether the package lightsim2grid can be used. The package implements a backend for
- power flow calculation in C++ and provides a speed-up. If lightsim2grid is "auto" (default), we don't bombard the
- user with messages. Otherwise, if lightsim2grid is True bus cannot be used, we inform the user abot it.
+ Implement some checks to decide whether the package lightsim2grid can be used. These checks are
+ documentated in :code:`doc\powerflow\ac.rst` The package implements a backend for power flow
+ calculation in C++ and provides a speed-up. If lightsim2grid
+ is "auto" (default), we don't bombard the user with messages. Otherwise, if lightsim2grid is
+ True bus cannot be used, we inform the user abot it.
"""
if not lightsim2grid:
return False # early return :)
diff --git a/pandapower/build_branch.py b/pandapower/build_branch.py
index 4c5dfbfd5..45d455aa3 100644
--- a/pandapower/build_branch.py
+++ b/pandapower/build_branch.py
@@ -10,7 +10,6 @@
import numpy as np
import pandas as pd
-from pandapower import DC_BUS_TYPE
from pandapower.auxiliary import get_values
from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_R, BR_X, BR_B, BR_G, TAP, SHIFT, BR_STATUS, RATE_A, \
@@ -22,13 +21,13 @@
GAMMA, EPSILON, T_AMBIENT_C, T_REF_C, branch_cols_tdpf
from pandapower.pypower.idx_brch_sc import branch_cols_sc
from pandapower.pypower.idx_bus import BASE_KV, VM, VA, BUS_TYPE, BUS_AREA, ZONE, VMAX, VMIN, PQ
-from pandapower.pypower.idx_bus_dc import DC_BUS_AREA, DC_VM, DC_ZONE, DC_VMAX, DC_VMIN, DC_P, DC_BASE_KV
+from pandapower.pypower.idx_bus_dc import DC_BUS_AREA, DC_VM, DC_ZONE, DC_VMAX, DC_VMIN, DC_P, DC_BASE_KV, DC_BUS_TYPE
from pandapower.pypower.idx_bus_sc import C_MIN, C_MAX
from pandapower.pypower.idx_tcsc import TCSC_F_BUS, TCSC_T_BUS, TCSC_X_L, TCSC_X_CVAR, TCSC_SET_P, \
TCSC_THYRISTOR_FIRING_ANGLE, TCSC_STATUS, TCSC_CONTROLLABLE, tcsc_cols, TCSC_MIN_FIRING_ANGLE, TCSC_MAX_FIRING_ANGLE
-def _build_branch_ppc(net, ppc):
+def _build_branch_ppc(net, ppc, update_vk_values: bool=True):
"""
Takes the empty ppc network and fills it with the branch values. The branch
datatype will be np.complex 128 afterwards.
@@ -65,9 +64,9 @@ def _build_branch_ppc(net, ppc):
if "line" in lookup:
_calc_line_parameter(net, ppc)
if "trafo" in lookup:
- _calc_trafo_parameter(net, ppc)
+ _calc_trafo_parameter(net, ppc, update_vk_values=update_vk_values)
if "trafo3w" in lookup:
- _calc_trafo3w_parameter(net, ppc)
+ _calc_trafo3w_parameter(net, ppc, update_vk_values=update_vk_values)
if "impedance" in lookup:
_calc_impedance_parameter(net, ppc)
if "xward" in lookup:
@@ -141,17 +140,18 @@ def _initialize_branch_lookup(net, dc=False):
return end
-def _calc_trafo3w_parameter(net, ppc):
+def _calc_trafo3w_parameter(net, ppc, update_vk_values: bool=True):
bus_lookup = net["_pd2ppc_lookups"]["bus"]
branch = ppc["branch"]
f, t = net["_pd2ppc_lookups"]["branch"]["trafo3w"]
- trafo_df = _trafo_df_from_trafo3w(net)
+ trafo_df = _trafo_df_from_trafo3w(net, update_vk_values=update_vk_values)
hv_bus = get_trafo_values(trafo_df, "hv_bus").astype(np.int64)
lv_bus = get_trafo_values(trafo_df, "lv_bus").astype(np.int64)
in_service = get_trafo_values(trafo_df, "in_service").astype(np.int64)
branch[f:t, F_BUS] = bus_lookup[hv_bus]
branch[f:t, T_BUS] = bus_lookup[lv_bus]
- r, x, g, b, g_asym, b_asym, ratio, shift = _calc_branch_values_from_trafo_df(net, ppc, trafo_df)
+ r, x, g, b, g_asym, b_asym, ratio, shift = _calc_branch_values_from_trafo_df(net, ppc, trafo_df,
+ update_vk_values=update_vk_values)
branch[f:t, BR_R] = r
branch[f:t, BR_X] = x
branch[f:t, BR_G] = g
@@ -162,13 +162,15 @@ def _calc_trafo3w_parameter(net, ppc):
branch[f:t, SHIFT] = shift
branch[f:t, BR_STATUS] = in_service
# always set RATE_A for completeness
+ # RATE_A is conisdered by the (PowerModels) OPF. If zero -> unlimited
if "max_loading_percent" in trafo_df:
max_load = get_trafo_values(trafo_df, "max_loading_percent")
sn_mva = get_trafo_values(trafo_df, "sn_mva")
branch[f:t, RATE_A] = max_load / 100. * sn_mva
else:
- sn_mva = get_trafo_values(trafo_df, "sn_mva")
- branch[f:t, RATE_A] = sn_mva
+ # PowerModels considers "0" as "no limit"
+ # todo: inf and convert only when using PowerModels to 0., pypower opf converts the zero to inf
+ branch[f:t, RATE_A] = 0. if net["_options"]["mode"] == "opf" else 100.
def _calc_line_parameter(net, ppc, elm="line", ppc_elm="branch"):
@@ -244,13 +246,16 @@ def _calc_line_parameter(net, ppc, elm="line", ppc_elm="branch"):
branch[f:t, BR_STATUS] = line["in_service"].values
# always set RATE_A for completeness:
# RATE_A is conisdered by the (PowerModels) OPF. If zero -> unlimited
- # TODO: check why OPF test fails if 100 instead of 0
- max_load = line.max_loading_percent.values if "max_loading_percent" in line else 0.
- vr = net.bus.loc[line["from_bus"].values, "vn_kv"].values * np.sqrt(3.)
- max_i_ka = line.max_i_ka.values
- df = line.df.values
- # This calculates the maximum apparent power at 1.0 p.u.
- branch[f:t, RATE_A] = max_load / 100. * max_i_ka * df * parallel * vr
+ if "max_loading_percent" in line:
+ max_load = line.max_loading_percent.values
+ vr = net.bus.loc[line["from_bus"].values, "vn_kv"].values * np.sqrt(3.)
+ max_i_ka = line.max_i_ka.values
+ df = line.df.values
+ branch[f:t, RATE_A] = max_load / 100. * max_i_ka * df * parallel * vr
+ else:
+ # PowerModels considers "0" as "no limit"
+ # todo: inf and convert only when using PowerModels to 0., pypower opf converts the zero to inf
+ branch[f:t, RATE_A] = 0. if mode == "opf" else 100.
def _calc_line_dc_parameter(net, ppc, elm="line_dc", ppc_elm="branch_dc"):
@@ -321,15 +326,20 @@ def _calc_line_dc_parameter(net, ppc, elm="line_dc", ppc_elm="branch_dc"):
branch_dc[f:t, DC_BR_STATUS] = line_dc["in_service"].values
# always set RATE_A for completeness:
# RATE_A is conisdered by the (PowerModels) OPF. If zero -> unlimited
- max_load = line_dc.max_loading_percent.values if "max_loading_percent" in line_dc else 0.
- vr = net.bus_dc.loc[line_dc["from_bus_dc"].values, "vn_kv"].values * np.sqrt(3.)
- max_i_ka = line_dc.max_i_ka.values
- df = line_dc.df.values
- # This calculates the maximum apparent power at 1.0 p.u.
- branch_dc[f:t, DC_RATE_A] = max_load / 100. * max_i_ka * df * parallel * vr
+ if "max_loading_percent" in line_dc:
+ max_load = line_dc.max_loading_percent.values
+ vr = net.bus_dc.loc[line_dc["from_bus_dc"].values, "vn_kv"].values * np.sqrt(3.)
+ max_i_ka = line_dc.max_i_ka.values
+ df = line_dc.df.values
+ # This calculates the maximum apparent power at 1.0 p.u.
+ branch_dc[f:t, DC_RATE_A] = max_load / 100. * max_i_ka * df * parallel * vr
+ else:
+ # PowerModels considers "0" as "no limit"
+ # todo: inf and convert only when using PowerModels to 0., pypower opf converts the zero to inf
+ branch_dc[f:t, DC_RATE_A] = 0. if mode == "opf" else 100.
-def _calc_trafo_parameter(net, ppc):
+def _calc_trafo_parameter(net, ppc, update_vk_values: bool=True):
'''
Calculates the transformer parameter in per unit.
@@ -350,7 +360,7 @@ def _calc_trafo_parameter(net, ppc):
parallel = trafo["parallel"].values
branch[f:t, F_BUS] = bus_lookup[trafo["hv_bus"].values]
branch[f:t, T_BUS] = bus_lookup[trafo["lv_bus"].values]
- r, x, g, b, g_asym, b_asym, ratio, shift = _calc_branch_values_from_trafo_df(net, ppc)
+ r, x, g, b, g_asym, b_asym, ratio, shift = _calc_branch_values_from_trafo_df(net, ppc, update_vk_values=update_vk_values)
branch[f:t, BR_R] = r
branch[f:t, BR_X] = x
branch[f:t, BR_G] = g
@@ -364,10 +374,16 @@ def _calc_trafo_parameter(net, ppc):
raise UserWarning("Rating factor df must be positive. Transformers with false "
"rating factors: %s" % trafo.query('df<=0').index.tolist())
# always set RATE_A for completeness
- max_load = trafo.max_loading_percent.values if "max_loading_percent" in trafo else 100
- sn_mva = trafo.sn_mva.values
- df = trafo.df.values
- branch[f:t, RATE_A] = max_load / 100. * sn_mva * df * parallel
+ # RATE_A is conisdered by the (PowerModels) OPF. If zero -> unlimited
+ if "max_loading_percent" in trafo:
+ max_load = trafo.max_loading_percent.values
+ sn_mva = trafo.sn_mva.values
+ df = trafo.df.values
+ branch[f:t, RATE_A] = max_load / 100. * sn_mva * df * parallel
+ else:
+ # PowerModels considers "0" as "no limit"
+ # todo: inf and convert only when using PowerModels to 0., pypower opf converts the zero to inf
+ branch[f:t, RATE_A] = 0. if net["_options"]["mode"] == "opf" else 100.
def get_trafo_values(trafo_df, par):
@@ -377,7 +393,7 @@ def get_trafo_values(trafo_df, par):
return trafo_df[par].values
-def _calc_branch_values_from_trafo_df(net, ppc, trafo_df=None, sequence=1):
+def _calc_branch_values_from_trafo_df(net, ppc, trafo_df=None, sequence=1, update_vk_values=True):
"""
Calculates the MAT/PYPOWER-branch-attributes from the pandapower trafo dataframe.
@@ -420,16 +436,18 @@ def _calc_branch_values_from_trafo_df(net, ppc, trafo_df=None, sequence=1):
vn_trafo_hv, vn_trafo_lv, shift = _calc_tap_from_dataframe(net, trafo_df)
ratio = _calc_nominal_ratio_from_dataframe(ppc, trafo_df, vn_trafo_hv, vn_trafo_lv,
bus_lookup)
- r, x, g, b, g_asym, b_asym = _calc_r_x_y_from_dataframe(net, trafo_df, vn_trafo_lv, vn_lv, ppc, sequence=sequence)
+ r, x, g, b, g_asym, b_asym = _calc_r_x_y_from_dataframe(net, trafo_df, vn_trafo_lv, vn_lv, ppc, sequence=sequence,
+ update_vk_values=update_vk_values)
return r, x, g, b, g_asym, b_asym, ratio, shift
-def _calc_r_x_y_from_dataframe(net, trafo_df, vn_trafo_lv, vn_lv, ppc, sequence=1):
+def _calc_r_x_y_from_dataframe(net, trafo_df, vn_trafo_lv, vn_lv, ppc, sequence=1, update_vk_values=True):
mode = net["_options"]["mode"]
trafo_model = net["_options"]["trafo_model"]
r, x = _calc_r_x_from_dataframe(mode, trafo_df, vn_lv, vn_trafo_lv, net.sn_mva,
- sequence=sequence, characteristic=net.get("characteristic"))
+ sequence=sequence, characteristic=net.get("characteristic"),
+ update_vk_values=update_vk_values)
if mode == "sc":
if net._options.get("use_pre_fault_voltage", False):
@@ -654,7 +672,7 @@ def _get_vk_values(trafo_df, characteristic, trafotype="2W"):
vk_value = get_trafo_values(trafo_df, vk_var)
if use_tap_dependent_impedance and vk_var in char_columns:
vals += (_calc_tap_dependent_value(
- trafo_df, tap_pos, vk_value, vk_var, tap_dependent_impedance,
+ tap_pos, vk_value, tap_dependent_impedance,
characteristic, all_characteristic_idx[:, index_column[vk_var]]),)
else:
vals += (vk_value,)
@@ -662,27 +680,33 @@ def _get_vk_values(trafo_df, characteristic, trafotype="2W"):
return vals
-def _calc_tap_dependent_value(trafo_df, tap_pos, value, variable, tap_dependent_impedance,
- characteristic, characteristic_idx):
+def _calc_tap_dependent_value(tap_pos, value, tap_dependent_impedance, characteristic, characteristic_idx):
# we skip the trafos with NaN characteristics even if tap_dependent_impedance is True (we already checked for missing characteristics)
relevant_idx = tap_dependent_impedance & ~np.isnan(characteristic_idx)
vk_characteristic = np.zeros_like(tap_dependent_impedance, dtype="object")
vk_characteristic[relevant_idx] = characteristic.loc[characteristic_idx[relevant_idx], 'object'].values
# here dtype must be float otherwise the load flow calculation will fail
- return np.where(relevant_idx,
- [c(t).item() if f else np.nan for f, t, c in zip(relevant_idx, tap_pos, vk_characteristic)],
- value)#.astype(np.float64) # astype not necessary, but if it fails then uncommenting this may help
+ def custom_func(f, t, c):
+ return c(t).item() if f else np.nan
-def _calc_r_x_from_dataframe(mode, trafo_df, vn_lv, vn_trafo_lv, sn_mva, sequence=1,
- characteristic=None):
+ custom_func_vec = np.vectorize(custom_func)
+ return np.where(relevant_idx, custom_func_vec(relevant_idx, tap_pos, vk_characteristic), value)
+
+
+def _calc_r_x_from_dataframe(mode, trafo_df, vn_lv, vn_trafo_lv, sn_mva, sequence=1, characteristic=None,
+ update_vk_values=True):
"""
Calculates (Vectorized) the resitance and reactance according to the
transformer values
"""
parallel = get_trafo_values(trafo_df, "parallel")
if sequence == 1:
- vk_percent, vkr_percent = _get_vk_values(trafo_df, characteristic)
+ if update_vk_values:
+ vk_percent, vkr_percent = _get_vk_values(trafo_df, characteristic)
+ else:
+ vk_percent = get_trafo_values(trafo_df, "vk_percent")
+ vkr_percent = get_trafo_values(trafo_df, "vkr_percent")
elif sequence == 0:
vk_percent = get_trafo_values(trafo_df, "vk0_percent")
@@ -706,7 +730,6 @@ def _calc_r_x_from_dataframe(mode, trafo_df, vn_lv, vn_trafo_lv, sn_mva, sequenc
def _calc_nominal_ratio_from_dataframe(ppc, trafo_df, vn_hv_kv, vn_lv_kv, bus_lookup):
"""
Calculates (Vectorized) the off nominal tap ratio::
-
(vn_hv_kv / vn_lv_kv) / (ub1_in_kv / ub2_in_kv)
INPUT:
@@ -966,8 +989,8 @@ def _branches_with_oos_buses(net, ppc, dc=False):
t_bus = line_buses[:, 1]
# determine on which side of the line the oos bus is located
- mask_from = np.in1d(f_bus, bus_oos)
- mask_to = np.in1d(t_bus, bus_oos)
+ mask_from = np.isin(f_bus, bus_oos)
+ mask_to = np.isin(t_bus, bus_oos)
mask_and = mask_to & mask_from
if np.any(mask_and):
@@ -986,7 +1009,7 @@ def _branches_with_oos_buses(net, ppc, dc=False):
ls_info = np.zeros((n_oos_buses_at_lines, 3), dtype=np.int64)
ls_info[:, 0] = mask_to[mask_or] & ~mask_from[mask_or]
ls_info[:, 1] = oos_buses_at_lines
- ls_info[:, 2] = np.nonzero(np.in1d(net[line_table].index, line_is_idx[mask_or]))[0]
+ ls_info[:, 2] = np.nonzero(np.isin(net[line_table].index, line_is_idx[mask_or]))[0]
# ls_info = list(map(mapfunc,
# line_switches["bus"].values,
@@ -1156,7 +1179,7 @@ def get_is_lines(net):
_is_elements["line"] = net["line"][net["line"]["in_service"].values.astype(bool)]
-def _trafo_df_from_trafo3w(net, sequence=1):
+def _trafo_df_from_trafo3w(net, sequence=1, update_vk_values=True):
trafo2 = dict()
sides = ["hv", "mv", "lv"]
mode = net._options["mode"]
@@ -1169,7 +1192,7 @@ def _trafo_df_from_trafo3w(net, sequence=1):
if sequence==1:
mode_tmp = "type_c" if mode == "sc" and net._options.get("use_pre_fault_voltage", False) else mode
_calculate_sc_voltages_of_equivalent_transformers(t3, trafo2, mode_tmp, characteristic=net.get(
- 'characteristic'))
+ 'characteristic'), update_vk_values=update_vk_values)
elif sequence==0:
if mode != "sc":
raise NotImplementedError(
@@ -1203,8 +1226,12 @@ def _trafo_df_from_trafo3w(net, sequence=1):
return {var: np.concatenate([trafo2[var][side] for side in sides]) for var in trafo2.keys()}
-def _calculate_sc_voltages_of_equivalent_transformers(t3, t2, mode, characteristic):
- vk_hv, vkr_hv, vk_mv, vkr_mv, vk_lv, vkr_lv = _get_vk_values(t3, characteristic, "3W")
+def _calculate_sc_voltages_of_equivalent_transformers(t3, t2, mode, characteristic, update_vk_values=True):
+ if update_vk_values:
+ vk_hv, vkr_hv, vk_mv, vkr_mv, vk_lv, vkr_lv = _get_vk_values(t3, characteristic, "3W")
+ else:
+ vk_hv, vkr_hv, vk_mv, vkr_mv, vk_lv, vkr_lv = (t3['vk_hv_percent'], t3['vkr_hv_percent'], t3['vk_mv_percent'],
+ t3['vkr_mv_percent'], t3['vk_lv_percent'], t3['vkr_lv_percent'])
vk_3w = np.stack([vk_hv, vk_mv, vk_lv])
vkr_3w = np.stack([vkr_hv, vkr_mv, vkr_lv])
@@ -1293,7 +1320,8 @@ def _calculate_3w_tap_changers(t3, t2, sides):
if any_at_star_point & np.any(mask_star_point := (tap_mask & at_star_point)):
t = tap_arrays["tap_step_percent"][side][mask_star_point] * np.exp(1j * np.deg2rad(tap_arrays["tap_step_degree"][side][mask_star_point]))
tap_pos = tap_arrays["tap_pos"][side][mask_star_point]
- t_corrected = 100 * t / (100 + (t * tap_pos))
+ tap_neutral = tap_arrays["tap_neutral"][side][mask_star_point]
+ t_corrected = 100 * t / (100 + (t * (tap_pos-tap_neutral)))
tap_arrays["tap_step_percent"][side][mask_star_point] = np.abs(t_corrected)
tap_arrays["tap_side"][side][mask_star_point] = "lv" if side == "hv" else "hv"
tap_arrays["tap_step_degree"][side][mask_star_point] = np.rad2deg(np.angle(t_corrected))
diff --git a/pandapower/control/controller/trafo/ContinuousTapControl.py b/pandapower/control/controller/trafo/ContinuousTapControl.py
index 612b94b14..20e07d68b 100644
--- a/pandapower/control/controller/trafo/ContinuousTapControl.py
+++ b/pandapower/control/controller/trafo/ContinuousTapControl.py
@@ -50,18 +50,18 @@ def __init__(self, net, element_index, vm_set_pu, tol=1e-3, side="lv", element="
self.vm_set_pu = vm_set_pu
def _set_t_nom(self, net):
- vn_hv_kv = read_from_net(net, self.element, self.controlled_element_index, 'vn_hv_kv', self._read_write_flag)
- hv_bus = read_from_net(net, self.element, self.controlled_element_index, 'hv_bus', self._read_write_flag)
+ vn_hv_kv = read_from_net(net, self.element, self.element_index, 'vn_hv_kv', self._read_write_flag)
+ hv_bus = read_from_net(net, self.element, self.element_index, 'hv_bus', self._read_write_flag)
vn_hv_bus_kv = read_from_net(net, "bus", hv_bus, 'vn_kv', self._read_write_flag)
if self.element == "trafo3w" and self.side == "mv":
- vn_mv_kv = read_from_net(net, self.element, self.controlled_element_index, 'vn_mv_kv', self._read_write_flag)
- mv_bus = read_from_net(net, self.element, self.controlled_element_index, 'mv_bus', self._read_write_flag)
+ vn_mv_kv = read_from_net(net, self.element, self.element_index, 'vn_mv_kv', self._read_write_flag)
+ mv_bus = read_from_net(net, self.element, self.element_index, 'mv_bus', self._read_write_flag)
vn_mv_bus_kv = read_from_net(net, "bus", mv_bus, 'vn_kv', self._read_write_flag)
self.t_nom = vn_mv_kv / vn_hv_kv * vn_hv_bus_kv / vn_mv_bus_kv
else:
- vn_lv_kv = read_from_net(net, self.element, self.controlled_element_index, 'vn_lv_kv', self._read_write_flag)
- lv_bus = read_from_net(net, self.element, self.controlled_element_index, 'lv_bus', self._read_write_flag)
+ vn_lv_kv = read_from_net(net, self.element, self.element_index, 'vn_lv_kv', self._read_write_flag)
+ lv_bus = read_from_net(net, self.element, self.element_index, 'lv_bus', self._read_write_flag)
vn_lv_bus_kv = read_from_net(net, "bus", lv_bus, 'vn_kv', self._read_write_flag)
self.t_nom = vn_lv_kv / vn_hv_kv * vn_hv_bus_kv / vn_lv_bus_kv
@@ -77,7 +77,7 @@ def control_step(self, net):
if self.nothing_to_do(net):
return
- delta_vm_pu = read_from_net(net, "res_bus", self.controlled_bus, 'vm_pu', self._read_write_flag) - self.vm_set_pu
+ delta_vm_pu = read_from_net(net, "res_bus", self.trafobus, 'vm_pu', self._read_write_flag) - self.vm_set_pu
tc = delta_vm_pu / self.tap_step_percent * 100 / self.t_nom
self.tap_pos = self.tap_pos + tc * self.tap_side_coeff * self.tap_sign
if self.check_tap_bounds:
@@ -87,7 +87,7 @@ def control_step(self, net):
# necessary in case the dtype of the column is int
if net[self.element].tap_pos.dtype != "float":
net[self.element].tap_pos = net[self.element].tap_pos.astype(float)
- write_to_net(net, self.element, self.controlled_element_index, "tap_pos", self.tap_pos, self._read_write_flag)
+ write_to_net(net, self.element, self.element_index, "tap_pos", self.tap_pos, self._read_write_flag)
def is_converged(self, net):
"""
@@ -97,10 +97,10 @@ def is_converged(self, net):
if self.nothing_to_do(net):
return True
- vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu", self._read_write_flag)
+ vm_pu = read_from_net(net, "res_bus", self.trafobus, "vm_pu", self._read_write_flag)
# this is possible in case the trafo is set out of service by the connectivity check
is_nan = np.isnan(vm_pu)
- self.tap_pos = read_from_net(net, self.element, self.controlled_element_index, "tap_pos", self._read_write_flag)
+ self.tap_pos = read_from_net(net, self.element, self.element_index, "tap_pos", self._read_write_flag)
difference = 1 - self.vm_set_pu / vm_pu
if self.check_tap_bounds:
diff --git a/pandapower/control/controller/trafo/DiscreteTapControl.py b/pandapower/control/controller/trafo/DiscreteTapControl.py
index d2647d778..aaa1d80db 100644
--- a/pandapower/control/controller/trafo/DiscreteTapControl.py
+++ b/pandapower/control/controller/trafo/DiscreteTapControl.py
@@ -108,9 +108,9 @@ def control_step(self, net):
if self.nothing_to_do(net):
return
- vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu", self._read_write_flag)
+ vm_pu = read_from_net(net, "res_bus", self.trafobus, "vm_pu", self._read_write_flag)
self.tap_pos = read_from_net(
- net, self.element, self.controlled_element_index, "tap_pos", self._read_write_flag)
+ net, self.element, self.element_index, "tap_pos", self._read_write_flag)
increment = np.where(
self.tap_side_coeff * self.tap_sign == 1,
@@ -126,7 +126,7 @@ def control_step(self, net):
self._hunting_taps = self._hunting_taps[1:, :]
# WRITE TO NET
- write_to_net(net, self.element, self.controlled_element_index, 'tap_pos',
+ write_to_net(net, self.element, self.element_index, 'tap_pos',
self.tap_pos, self._read_write_flag)
def is_converged(self, net):
@@ -136,11 +136,11 @@ def is_converged(self, net):
if self.nothing_to_do(net):
return True
- vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu", self._read_write_flag)
+ vm_pu = read_from_net(net, "res_bus", self.trafobus, "vm_pu", self._read_write_flag)
# this is possible in case the trafo is set out of service by the connectivity check
is_nan = np.isnan(vm_pu)
self.tap_pos = read_from_net(
- net, self.element, self.controlled_element_index, "tap_pos", self._read_write_flag)
+ net, self.element, self.element_index, "tap_pos", self._read_write_flag)
reached_limit = np.where(self.tap_side_coeff * self.tap_sign == 1,
(vm_pu < self.vm_lower_pu) & (self.tap_pos == self.tap_min) |
diff --git a/pandapower/control/controller/trafo_control.py b/pandapower/control/controller/trafo_control.py
index 267238786..d3cb3ae44 100644
--- a/pandapower/control/controller/trafo_control.py
+++ b/pandapower/control/controller/trafo_control.py
@@ -46,7 +46,7 @@ def __init__(self, net, element_index, side, tol, in_service, element, level=0,
self._set_side(side)
self._set_read_write_flag(net)
- self._set_valid_controlled_index_and_bus(net)
+ # self._set_valid_controlled_index_and_bus(net)
self._set_tap_parameters(net)
self._set_tap_side_coeff(net)
@@ -54,6 +54,8 @@ def __init__(self, net, element_index, side, tol, in_service, element, level=0,
self.set_recycle(net)
+ self.trafobus = read_from_net(net, self.element, self.element_index, self.side + '_bus', self._read_write_flag)
+
def _set_read_write_flag(self, net):
# if someone changes indices of the controller from single index to array and vice versa
self._read_write_flag, _ = _detect_read_write_flag(net, self.element, self.element_index, "tap_pos")
@@ -67,25 +69,36 @@ def initialize_control(self, net):
# update trafo tap parameters
# we assume side does not change after the controller is created
self._set_read_write_flag(net)
- self._set_valid_controlled_index_and_bus(net)
+ # self._set_valid_controlled_index_and_bus(net)
if self.nothing_to_do(net):
return
self._set_tap_parameters(net)
self._set_tap_side_coeff(net)
def nothing_to_do(self, net):
- # if the controller shouldn't do anything, return True
- if self.controlled_element_index is None or (
- self._read_write_flag != 'single_index' and len(self.controlled_element_index) == 0):
- return True
- return False
+ element_in_service = read_from_net(net, self.element, self.element_index, 'in_service', self._read_write_flag)
+ ext_grid_bus = np.isin(self.trafobus, net.ext_grid.loc[net.ext_grid.in_service, 'bus'].values)
+ element_index_in_net = np.isin(self.element_index, net[self.element].index.values)
+ self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), np.logical_not(ext_grid_bus))
+ if isinstance(self.element_index, np.int64) or isinstance(self.element_index, int):
+ # if the controller shouldn't do anything, return True
+ if not element_in_service or ext_grid_bus or not element_index_in_net or (
+ self._read_write_flag != 'single_index' and len(self.element_index) == 0):
+ return True
+ return False
+ else:
+ # if the controller shouldn't do anything, return True
+ if np.all(~element_in_service[self.controlled]) or np.all(ext_grid_bus[self.controlled]) or np.all(~element_index_in_net[self.controlled]) or (
+ self._read_write_flag != 'single_index' and len(self.element_index) == 0):
+ return True
+ return False
def _set_tap_side_coeff(self, net):
- tap_side = read_from_net(net, self.element, self.controlled_element_index, 'tap_side', self._read_write_flag)
+ tap_side = read_from_net(net, self.element, self.element_index, 'tap_side', self._read_write_flag)
if (len(np.setdiff1d(tap_side, ['hv', 'lv'])) > 0 and self.element == "trafo") or \
(len(np.setdiff1d(tap_side, ['hv', 'lv', 'mv'])) > 0 and self.element == "trafo3w"):
raise ValueError("Trafo tap side (in net.%s) has to be either hv or lv, "
- "but received: %s for trafo %s" % (self.element, tap_side, self.controlled_element_index))
+ "but received: %s for trafo %s" % (self.element, tap_side, self.element_index))
if self._read_write_flag == "single_index":
self.tap_side_coeff = 1 if tap_side == 'hv' else -1
@@ -113,29 +126,25 @@ def _set_side(self, side):
self.side = side
def _set_valid_controlled_index_and_bus(self, net):
- self.trafobus = read_from_net(net, self.element, self.element_index, self.side + '_bus', self._read_write_flag)
element_in_service = read_from_net(net, self.element, self.element_index, 'in_service', self._read_write_flag)
ext_grid_bus = np.isin(self.trafobus, net.ext_grid.loc[net.ext_grid.in_service, 'bus'].values)
element_index_in_net = np.isin(self.element_index, net[self.element].index.values)
- controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), np.logical_not(ext_grid_bus))
- if self._read_write_flag == 'single_index':
- self.controlled_element_index = self.element_index if controlled else None
- self.controlled_bus = self.trafobus if controlled else None
- else:
- self.controlled_element_index = self.element_index[controlled]
- self.controlled_bus = self.trafobus[controlled]
+ self.controlled = np.logical_and(np.logical_and(element_in_service, element_index_in_net), np.logical_not(ext_grid_bus))
+ if self._read_write_flag != 'single_index':
+ self.element_index = self.element_index[self.controlled]
+ self.trafobus = self.trafobus[self.controlled]
- if np.all(~controlled):
+ if np.all(~self.controlled):
logger.warning("All controlled buses are not valid: controller has no effect")
def _set_tap_parameters(self, net):
- self.tap_min = read_from_net(net, self.element, self.controlled_element_index, "tap_min", self._read_write_flag)
- self.tap_max = read_from_net(net, self.element, self.controlled_element_index, "tap_max", self._read_write_flag)
- self.tap_neutral = read_from_net(net, self.element, self.controlled_element_index, "tap_neutral", self._read_write_flag)
- self.tap_step_percent = read_from_net(net, self.element, self.controlled_element_index, "tap_step_percent", self._read_write_flag)
- self.tap_step_degree = read_from_net(net, self.element, self.controlled_element_index, "tap_step_degree", self._read_write_flag)
+ self.tap_min = read_from_net(net, self.element, self.element_index, "tap_min", self._read_write_flag)
+ self.tap_max = read_from_net(net, self.element, self.element_index, "tap_max", self._read_write_flag)
+ self.tap_neutral = read_from_net(net, self.element, self.element_index, "tap_neutral", self._read_write_flag)
+ self.tap_step_percent = read_from_net(net, self.element, self.element_index, "tap_step_percent", self._read_write_flag)
+ self.tap_step_degree = read_from_net(net, self.element, self.element_index, "tap_step_degree", self._read_write_flag)
- self.tap_pos = read_from_net(net, self.element, self.controlled_element_index, "tap_pos", self._read_write_flag)
+ self.tap_pos = read_from_net(net, self.element, self.element_index, "tap_pos", self._read_write_flag)
if self._read_write_flag == "single_index":
self.tap_sign = 1 if np.isnan(self.tap_step_degree) else np.sign(np.cos(np.deg2rad(self.tap_step_degree)))
if (self.tap_sign == 0) | (np.isnan(self.tap_sign)):
@@ -163,7 +172,7 @@ def set_recycle(self, net):
net.controller.at[self.index, 'recycle'] = recycle
# def timestep(self, net):
- # self.tap_pos = net[self.element].at[self.controlled_element_index, "tap_pos"]
+ # self.tap_pos = net[self.element].at[self.element_index, "tap_pos"]
def __repr__(self):
s = '%s of %s %s' % (self.__class__.__name__, self.element, self.element_index)
diff --git a/pandapower/convert_format.py b/pandapower/convert_format.py
index a0d546d0a..da07420a5 100644
--- a/pandapower/convert_format.py
+++ b/pandapower/convert_format.py
@@ -11,8 +11,10 @@
from pandapower._version import __version__, __format_version__
from pandapower.create import create_empty_network, create_poly_cost
+from pandapower.plotting import geo
from pandapower.results import reset_results
from pandapower.control import TrafoController
+import pandapower.plotting.geo as geo
try:
import pandaplan.core.pplog as logging
@@ -22,14 +24,6 @@
logger = logging.getLogger(__name__)
-def _compare_version(
- net_version,
- compare_version: Union[str, int],
- compare: Callable[[Version, Version], bool] = lambda x, y: x < y
-) -> bool:
- return compare(Version(str(net_version)), Version(str(compare_version)))
-
-
def convert_format(net, elements_to_deserialize=None):
"""
Converts old nets to new format to ensure consistency. The converted net is returned.
@@ -46,6 +40,7 @@ def convert_format(net, elements_to_deserialize=None):
_add_missing_columns(net, elements_to_deserialize)
_create_seperate_cost_tables(net, elements_to_deserialize)
if Version(str(net.format_version)) < Version("3.0.0"):
+ _convert_geo_data(net, elements_to_deserialize)
_convert_group_element_index(net)
_convert_trafo_controller_parameter_names(net)
if Version(str(net.format_version)) < Version("2.4.0"):
@@ -56,7 +51,7 @@ def convert_format(net, elements_to_deserialize=None):
_convert_to_mw(net)
_update_trafo_parameter_names(net, elements_to_deserialize)
reset_results(net)
- if isinstance(net.format_version, float) and net.format_version < 1.6:
+ if Version(str(net.format_version)) < Version("1.6"):
set_data_type_of_columns_to_default(net)
_convert_objects(net, elements_to_deserialize)
_update_characteristics(net, elements_to_deserialize)
@@ -74,7 +69,7 @@ def _convert_geo_data(net, elements_to_deserialize=None):
or (_check_elements_to_deserialize('line_geodata', elements_to_deserialize)
and _check_elements_to_deserialize('line', elements_to_deserialize))):
if hasattr(net, 'bus_geodata') or hasattr(net, 'line_geodata'):
- if _compare_version(net.format_version, "1.6"):
+ if Version(str(net.format_version)) < Version("1.6"):
net.bus_geodata = pd.DataFrame.from_dict(net.bus_geodata)
net.line_geodata = pd.DataFrame.from_dict(net.line_geodata)
geo.convert_geodata_to_geojson(net)
@@ -154,6 +149,8 @@ def _convert_trafo_controller_parameter_names(net):
elif "trafotype" in controller.__dict__.keys():
controller.__dict__["element"] = controller.__dict__.pop("trafotype")
+ if "controlled_bus" in controller.__dict__.keys():
+ controller.__dict__["trafobus"] = controller.__dict__.pop("controlled_bus")
def _convert_bus_pq_meas_to_load_reference(net, elements_to_deserialize):
if _check_elements_to_deserialize('measurement', elements_to_deserialize):
diff --git a/pandapower/converter/cim/cim2pp/build_pp_net.py b/pandapower/converter/cim/cim2pp/build_pp_net.py
index 1872fc5fd..4686fc9b2 100644
--- a/pandapower/converter/cim/cim2pp/build_pp_net.py
+++ b/pandapower/converter/cim/cim2pp/build_pp_net.py
@@ -18,8 +18,6 @@
logger = logging.getLogger('cim.cim2pp.build_pp_net')
-pd.set_option('display.max_columns', 900)
-pd.set_option('display.max_rows', 90000)
sc = cim_tools.get_pp_net_special_columns_dict()
diff --git a/pandapower/converter/cim/cim2pp/converter_classes/connectivitynodes/connectivityNodesCim16.py b/pandapower/converter/cim/cim2pp/converter_classes/connectivitynodes/connectivityNodesCim16.py
index f1de75cf8..34bfd4484 100644
--- a/pandapower/converter/cim/cim2pp/converter_classes/connectivitynodes/connectivityNodesCim16.py
+++ b/pandapower/converter/cim/cim2pp/converter_classes/connectivitynodes/connectivityNodesCim16.py
@@ -248,6 +248,18 @@ def _prepare_connectivity_nodes_cim16(self) -> Tuple[pd.DataFrame, pd.DataFrame]
bb = bb.drop_duplicates(subset=['rdfId'], keep='first')
connectivity_nodes = pd.merge(connectivity_nodes, bb, how='left', on='rdfId')
+ if "Substation" in connectivity_nodes.columns:
+ # add (sub) geographical regions
+ sgr = self.cimConverter.cim['eq']['SubGeographicalRegion'][['rdfId', 'name', 'Region']]
+ regions = pd.merge(self.cimConverter.cim['eq']['Substation'], sgr, left_on="Region", right_on="rdfId",
+ suffixes=["_substation", "_SubGeographicalRegion"])
+ regions = pd.merge(self.cimConverter.cim['eq']['GeographicalRegion'], regions, left_on="rdfId", right_on="Region_SubGeographicalRegion")
+ regions = regions.rename(columns={'name': 'GeographicalRegion_name', 'name_SubGeographicalRegion': 'SubGeographicalRegion_name',
+ 'rdfId': 'GeographicalRegion_id', 'rdfId_SubGeographicalRegion': 'SubGeographicalRegion_id'})
+ regions = regions.drop(columns=['name_substation', 'Region_substation', 'Region_SubGeographicalRegion'])
+ connectivity_nodes = pd.merge(connectivity_nodes, regions, how='left', left_on='Substation', right_on='rdfId_substation')
+ connectivity_nodes = connectivity_nodes.drop(columns=["rdfId_substation"])
+
connectivity_nodes = connectivity_nodes.rename(columns={'rdfId': sc['o_id'], 'TopologicalNode': sc['ct'],
'nominalVoltage': 'vn_kv', 'name_substation': 'zone'})
connectivity_nodes['in_service'] = True
diff --git a/pandapower/converter/cim/cim2pp/converter_classes/impedance/seriesCompensatorsCim16.py b/pandapower/converter/cim/cim2pp/converter_classes/impedance/seriesCompensatorsCim16.py
index 030e75701..824e568dd 100644
--- a/pandapower/converter/cim/cim2pp/converter_classes/impedance/seriesCompensatorsCim16.py
+++ b/pandapower/converter/cim/cim2pp/converter_classes/impedance/seriesCompensatorsCim16.py
@@ -107,7 +107,7 @@ def _prepare_series_compensators_cim16(self) -> pd.DataFrame:
ser_comp['gf_pu'] = 0.
ser_comp['bf_pu'] = 0.
ser_comp['gt_pu'] = 0.
- ser_comp['bf_pu'] = 0.
+ ser_comp['bt_pu'] = 0.
ser_comp['in_service'] = ser_comp.connected & ser_comp.connected2
ser_comp = ser_comp.rename(columns={'rdfId_Terminal': sc['t_from'], 'rdfId_Terminal2': sc['t_to'],
'rdfId': sc['o_id'], 'index_bus': 'from_bus', 'index_bus2': 'to_bus'})
diff --git a/pandapower/converter/cim/cim2pp/from_cim.py b/pandapower/converter/cim/cim2pp/from_cim.py
index dfcc0f1d4..d93dd8d21 100644
--- a/pandapower/converter/cim/cim2pp/from_cim.py
+++ b/pandapower/converter/cim/cim2pp/from_cim.py
@@ -94,7 +94,7 @@ def get_converter_classes():
return converter_classes
-def from_cim(file_list: List[str] = None, encoding: str = 'utf-8', convert_line_to_switch: bool = False,
+def from_cim(file_list: List[str] = None, encoding: str = None, convert_line_to_switch: bool = False,
line_r_limit: float = 0.1, line_x_limit: float = 0.1,
repair_cim: Union[str, interfaces.CIMRepair] = None,
repair_cim_class: Type[interfaces.CIMRepair] = None,
@@ -103,6 +103,7 @@ def from_cim(file_list: List[str] = None, encoding: str = 'utf-8', convert_line_
custom_converter_classes: Dict = None,
cgmes_version: str = '2.4.15', **kwargs) -> \
pandapower.auxiliary.pandapowerNet:
+ # Nur zum Testen, kann wieder gelöscht werden
"""
Convert a CIM net to a pandapower net from XML files.
Additional parameters for kwargs:
@@ -122,7 +123,7 @@ def from_cim(file_list: List[str] = None, encoding: str = 'utf-8', convert_line_
if there are errors in the conversion. Default: True.
:param file_list: The path to the CGMES files as a list.
- :param encoding: The encoding from the files. Optional, default: utf-8
+ :param encoding: The encoding from the files. Optional, default: None
:param convert_line_to_switch: Set this parameter to True to enable line -> switch conversion. All lines with a
resistance lower or equal than line_r_limit or a reactance lower or equal than line_x_limit will become a
switch. Optional, default: False
diff --git a/pandapower/converter/cim/cim_classes.py b/pandapower/converter/cim/cim_classes.py
index 685d2c6ac..5c6c6ea92 100644
--- a/pandapower/converter/cim/cim_classes.py
+++ b/pandapower/converter/cim/cim_classes.py
@@ -12,8 +12,7 @@
from typing import Dict, List
import pandas as pd
import numpy as np
-import xml.etree.ElementTree
-import xml.etree.cElementTree as xmlET
+from lxml import etree
from .other_classes import ReportContainer, Report, LogLevel, ReportCode
from .cim_tools import get_cim_schema
@@ -35,14 +34,14 @@ def __init__(self, cim: Dict[str, Dict[str, pd.DataFrame]] = None, cgmes_version
self.file_names: Dict[str, str] = dict()
self.report_container = ReportContainer()
- def parse_files(self, file_list: List[str] or str = None, encoding: str = 'utf-8', prepare_cim_net: bool = False,
+ def parse_files(self, file_list: List[str] or str = None, encoding: str = None, prepare_cim_net: bool = False,
set_data_types: bool = False) -> CimParser:
"""
Parse CIM XML files from a storage.
:param file_list: The path to the CGMES files as a list. Note: The files need a FullModel to parse the
CGMES profile. Optional, default: None.
- :param encoding: The encoding from the files. Optional, default: utf-8
+ :param encoding: The encoding from the files. Optional, default: None
:param prepare_cim_net: Set this parameter to True to prepare the parsed cim data according to the
CimConverter. Optional, default: False
:param set_data_types: Set this parameter to True to set the cim data types at the parsed data. Optional,
@@ -389,7 +388,7 @@ def _parse_element(self, element, parsed=None):
def _get_df(self, items):
return pd.DataFrame([self._parse_element(child) for child in iter(items)])
- def _get_cgmes_profile_from_xml(self, root: xml.etree.ElementTree.Element, ignore_errors: bool = False,
+ def _get_cgmes_profile_from_xml(self, root: etree.Element, ignore_errors: bool = False,
default_profile: str = 'unknown') -> str:
"""
Get the CGMES profile from the XML file.
@@ -486,17 +485,16 @@ def _parse_source_file(self, file: str, output: dict, encoding: str, profile_nam
temp_dir.cleanup()
del temp_dir, temp_dir_path
return
- with open(file, mode='r', encoding=encoding, errors='ignore') as f:
- cim_str = f.read()
- xml_tree = xmlET.fromstring(cim_str)
+ parser = etree.XMLParser(encoding=encoding, resolve_entities=False)
+ xml_tree = etree.parse(file, parser)
if profile_name is None:
- prf = self._get_cgmes_profile_from_xml(xml_tree)
+ prf = self._get_cgmes_profile_from_xml(xml_tree.getroot())
else:
prf = profile_name
self.file_names[prf] = file
- self._parse_xml_tree(xml_tree, prf, output)
+ self._parse_xml_tree(xml_tree.getroot(), prf, output)
- def _parse_xml_tree(self, xml_tree: xmlET, profile_name: str, output: Dict | None = None):
+ def _parse_xml_tree(self, xml_tree: etree.ElementTree, profile_name: str, output: Dict | None = None):
output = self.cim if output is None else output
# get all CIM elements to parse
element_types = pd.Series([ele.tag for ele in list(xml_tree)])
@@ -507,6 +505,8 @@ def _parse_xml_tree(self, xml_tree: xmlET, profile_name: str, output: Dict | Non
if prf not in ns_dict.keys():
ns_dict[prf] = dict()
for _, element_type in element_types.items():
+ if not isinstance(element_type, str):
+ continue
element_type_c = re.sub('{.*}', '', element_type)
prf_content[element_type_c] = self._get_df(xml_tree.findall(element_type))
# rename the columns (remove the namespaces)
diff --git a/pandapower/converter/cim/cim_tools.py b/pandapower/converter/cim/cim_tools.py
index 9668b2387..e04b92988 100644
--- a/pandapower/converter/cim/cim_tools.py
+++ b/pandapower/converter/cim/cim_tools.py
@@ -24,7 +24,7 @@ def get_pp_net_special_columns_dict() -> Dict[str, str]:
'o_prf': 'origin_profile', 'ct': 'cim_topnode', 'tc': 'tapchanger_class', 'tc_id': 'tapchanger_id',
'pte_id': 'PowerTransformerEnd_id', 'pte_id_hv': 'PowerTransformerEnd_id_hv',
'pte_id_mv': 'PowerTransformerEnd_id_mv', 'pte_id_lv': 'PowerTransformerEnd_id_lv',
- 'cnc_id': 'ConnectivityNodeContainer_id', 'sub_id': 'substation_id', 'src': 'source', 'name': 'name',
+ 'cnc_id': 'ConnectivityNodeContainer_id', 'sub_id': 'Substation_id', 'src': 'source', 'name': 'name',
'desc': 'description', 'a_id': 'analog_id'})
@@ -50,8 +50,9 @@ def extend_pp_net_cim(net: pandapowerNet, override: bool = True) -> pandapowerNe
fill_dict: Dict[str, Dict[str, List[str]]] = dict()
fill_dict['bus'] = dict()
- fill_dict['bus'][np_str_type] = [sc['o_prf'], sc['ct'], sc['cnc_id'], sc['sub_id'], 'description', 'busbar_id',
- 'busbar_name']
+ fill_dict['bus'][np_str_type] = [sc['o_prf'], sc['ct'], sc['cnc_id'], sc['sub_id'], 'description', 'Busbar_id',
+ 'Busbar_name', 'GeographicalRegion_id', 'GeographicalRegion_name',
+ 'SubGeographicalRegion_id', 'SubGeographicalRegion_name']
fill_dict['ext_grid'] = dict()
fill_dict['ext_grid'][np_str_type] = [sc['t'], sc['sub'], 'description']
diff --git a/pandapower/converter/pandamodels/from_pm.py b/pandapower/converter/pandamodels/from_pm.py
index acb22a768..a66e9d25d 100644
--- a/pandapower/converter/pandamodels/from_pm.py
+++ b/pandapower/converter/pandamodels/from_pm.py
@@ -38,11 +38,6 @@ def read_pm_results_to_net(net, ppc, ppci, result_pm):
_extract_results(net, result)
else:
neti = deepcopy(net)
- removed_keys = set(net.keys()) - pp_elements(res_elements=True) - \
- {"_options", "_is_elements", "_pd2ppc_lookups", "res_bus", "res_switch"} | \
- {"measurement"}
- for rk in removed_keys:
- neti.pop(rk)
for tp, ri in result.items():
add_time_series_data_to_net(neti, net.controller, tp)
_extract_results(neti, ri)
diff --git a/pandapower/converter/pandamodels/to_pm.py b/pandapower/converter/pandamodels/to_pm.py
index 0227f570a..6818e154b 100644
--- a/pandapower/converter/pandamodels/to_pm.py
+++ b/pandapower/converter/pandamodels/to_pm.py
@@ -154,6 +154,7 @@ def convert_to_pm_structure(net, opf_flow_lim="S", from_time_step=None, to_time_
ppci = build_ne_branch(net, ppci)
net["_ppc_opf"] = ppci
pm = ppc_to_pm(net, ppci)
+ # todo: somewhere here should RATE_A be converted to 0., because only PowerModels uses 0 as no limits (pypower opf converts the zero to inf)
pm = add_pm_options(pm, net)
pm = add_params_to_pm(net, pm)
if from_time_step is not None and to_time_step is not None:
diff --git a/pandapower/converter/powerfactory/pp_import_functions.py b/pandapower/converter/powerfactory/pp_import_functions.py
index b979a817f..5310ff914 100644
--- a/pandapower/converter/powerfactory/pp_import_functions.py
+++ b/pandapower/converter/powerfactory/pp_import_functions.py
@@ -3,14 +3,17 @@
import numbers
import re
from itertools import combinations
+from typing import Literal, Optional, Union
+import geojson
import networkx as nx
-
import numpy as np
+from pandas import DataFrame
+
import pandapower as pp
+from pandapower.results import reset_results
from pandapower.auxiliary import ADict
import pandapower.control as control
-from pandas import DataFrame, Series
try:
import pandaplan.core.pplog as logging
@@ -19,21 +22,31 @@
logger = logging.getLogger(__name__)
-
-# make wrapper for GetAttribute
-def ga(element, attr):
- return element.GetAttribute(attr)
+# Define global variables
+line_dict = {}
+trafo_dict = {}
+switch_dict = {}
+bus_dict = {}
+grf_map = {}
# import network to pandapower:
-def from_pf(dict_net, pv_as_slack=True, pf_variable_p_loads='plini', pf_variable_p_gen='pgini',
- flag_graphics='GPS', tap_opt="nntap", export_controller=True, handle_us="Deactivate",
- max_iter=None, is_unbalanced=False, create_sections=True):
- global line_dict
+def from_pf(
+ dict_net,
+ pv_as_slack=True,
+ pf_variable_p_loads='plini',
+ pf_variable_p_gen='pgini',
+ flag_graphics: Literal["GPS", "no geodata"] = 'GPS',
+ tap_opt="nntap",
+ export_controller=True,
+ handle_us: Literal["Deactivate", "Drop", "Nothing"] = "Deactivate",
+ max_iter=None,
+ is_unbalanced=False,
+ create_sections=True
+):
+ global line_dict, trafo_dict, switch_dict, bus_dict, grf_map
line_dict = {}
- global trafo_dict
trafo_dict = {}
- global switch_dict
switch_dict = {}
logger.debug("__name__: %s" % __name__)
logger.debug('started from_pf')
@@ -45,10 +58,8 @@ def from_pf(dict_net, pv_as_slack=True, pf_variable_p_loads='plini', pf_variable
grid_name = dict_net['ElmNet'].loc_name
base_sn_mva = dict_net['global_parameters']['base_sn_mva']
net = pp.create_empty_network(grid_name, sn_mva=base_sn_mva)
- net['bus_geodata'] = DataFrame(columns=['x', 'y'])
- net['line_geodata'] = DataFrame(columns=['coords'])
- pp.results.reset_results(net, mode="pf_3ph")
+ reset_results(net, mode="pf_3ph")
if max_iter is not None:
pp.set_user_pf_options(net, max_iteration=max_iter)
logger.info('creating grid %s' % grid_name)
@@ -57,9 +68,7 @@ def from_pf(dict_net, pv_as_slack=True, pf_variable_p_loads='plini', pf_variable
logger.debug('creating buses')
# create buses:
- global bus_dict
bus_dict = {}
- global grf_map
grf_map = dict_net.get('graphics', {})
logger.debug('the graphic mapping is: %s' % grf_map)
@@ -342,12 +351,12 @@ def add_additional_attributes(item, net, element, element_id, attr_list=None, at
obj = item
for a in attr.split('.'):
if hasattr(obj, 'HasAttribute') and obj.HasAttribute(a):
- obj = ga(obj, a)
+ obj = obj.GetAttributes(a)
if obj is not None and isinstance(obj, str):
net[element].loc[element_id, attr_dict[attr]] = obj
elif item.HasAttribute(attr):
- chr_name = ga(item, attr)
+ chr_name = item.GetAttributes(attr)
if chr_name is not None:
if isinstance(chr_name, (str, numbers.Number)):
net[element].loc[element_id, attr_dict[attr]] = chr_name
@@ -362,24 +371,25 @@ def add_additional_attributes(item, net, element, element_id, attr_list=None, at
def create_bus(net, item, flag_graphics, is_unbalanced):
# add geo data
if flag_graphics == 'GPS':
- x = ga(item, 'e:GPSlon')
- y = ga(item, 'e:GPSlat')
+ x = item.GetAttributes('e:GPSlon')
+ y = item.GetAttributes('e:GPSlat')
elif flag_graphics == 'graphic objects':
graphic_object = get_graphic_object(item)
if graphic_object:
- x = ga(graphic_object, 'rCenterX')
- y = ga(graphic_object, 'rCenterY')
+ x = graphic_object.GetAttributes('rCenterX')
+ y = graphic_object.GetAttributes('rCenterY')
# add gr coord data
else:
x, y = 0, 0
else:
x, y = 0, 0
- # only values > 0+-1e-3 are entered into the bus_geodata
- if x > 1e-3 or y > 1e-3:
- geodata = (x, y)
- else:
- geodata = None
+ # Commented out because geojson is set up to do the precision handling
+ # # only values > 0+-1e-3 are entered into the bus.geo
+ # if x > 1e-3 or y > 1e-3:
+ # geodata = (x, y)
+ # else:
+ # geodata = None
usage = ["b", "m", "n"]
params = {
@@ -387,7 +397,7 @@ def create_bus(net, item, flag_graphics, is_unbalanced):
'vn_kv': item.uknom,
'in_service': not bool(item.outserv),
'type': usage[item.iUsage],
- 'geodata': geodata
+ 'geodata': geojson.dumps(geojson.Point((x, y))),
}
system_type = {0: "ac", 1: "dc", 2: "ac/bi"}[item.systype]
@@ -447,12 +457,12 @@ def get_pf_bus_results(net, item, bid, is_unbalanced, system_type):
if is_unbalanced:
bus_type = "res_bus_3ph"
result_variables = {
- "pf_vm_a_pu": "m:u:A",
- "pf_va_a_degree": "m:phiu:A",
- "pf_vm_b_pu": "m:u:B",
- "pf_va_b_degree": "m:phiu:B",
- "pf_vm_c_pu": "m:u:C",
- "pf_va_c_degree": "m:phiu:C",
+ "pf_vm_a_pu": "m:u:A",
+ "pf_va_a_degree": "m:phiu:A",
+ "pf_vm_b_pu": "m:u:B",
+ "pf_va_b_degree": "m:phiu:B",
+ "pf_vm_c_pu": "m:u:C",
+ "pf_va_c_degree": "m:phiu:C",
}
elif system_type == "ac":
bus_type = "res_bus"
@@ -467,7 +477,7 @@ def get_pf_bus_results(net, item, bid, is_unbalanced, system_type):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(0):
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
# dc bus voltage can be negative:
net[bus_type].at[bid, res_var_pp] = np.abs(res) if "vm_pu" in res_var_pp else res
@@ -475,7 +485,7 @@ def get_pf_bus_results(net, item, bid, is_unbalanced, system_type):
# # This one deletes all the results :(
# # Don't use it
# def find_bus_index_in_net(item, net=None):
-# foreign_key = int(ga(item, 'for_name'))
+# foreign_key = int(item.GetAttributes('for_name'))
# return foreign_key
@@ -484,32 +494,32 @@ def get_pf_bus_results(net, item, bid, is_unbalanced, system_type):
# def find_bus_index_in_net(item, net):
# usage = ["b", "m", "n"]
# # to be sure that the bus is the correct one
-# name = ga(item, 'loc_name')
-# bus_type = usage[ga(item, 'iUsage')]
+# name = item.GetAttributes('loc_name')
+# bus_type = usage[item.GetAttributes('iUsage')]
# logger.debug('looking for bus <%s> in net' % name)
#
# if item.HasAttribute('cpSubstat'):
-# substat = ga(item, 'cpSubstat')
+# substat = item.GetAttributes('cpSubstat')
# if substat is not None:
-# descr = ga(substat, 'loc_name')
+# descr = substat.GetAttributes('loc_name')
# logger.debug('bus <%s> has substat, descr is <%s>' % (name, descr))
# else:
# # omg so ugly :(
-# descr = ga(item, 'desc')
+# descr = item.GetAttributes('desc')
# descr = descr[0] if len(descr) > 0 else ""
# logger.debug('substat is none, descr of bus <%s> is <%s>' % (name, descr))
# else:
-# descr = ga(item, 'desc')
+# descr = item.GetAttributes('desc')
# descr = descr[0] if len(descr) > 0 else ""
# logger.debug('no attribute "substat", descr of bus <%s> is <%s>' % (name, descr))
#
# try:
-# zone = ga(item, 'Grid')
-# zone_name = ga(zone, 'loc_name').split('.ElmNet')[0]
+# zone = item.GetAttributes('Grid')
+# zone_name = zone.GetAttributes('loc_name').split('.ElmNet')[0]
# logger.debug('zone "Grid" found: <%s>' % zone_name)
# except:
-# zone = ga(item, 'cpGrid')
-# zone_name = ga(zone, 'loc_name').split('.ElmNet')[0]
+# zone = item.GetAttributes('cpGrid')
+# zone_name = zone.GetAttributes('loc_name').split('.ElmNet')[0]
# logger.debug('zone "cpGrid" found: <%s>' % zone_name)
#
# temp_df_a = net.bus[net.bus.zone == zone_name]
@@ -563,12 +573,12 @@ def get_connection_nodes(net, item, num_nodes):
item, pf_class))
if pf_class == "ElmTr2":
- v.append(ga(item, 't:utrn_h'))
- v.append(ga(item, 't:utrn_l'))
+ v.append(item.GetAttributes('t:utrn_h'))
+ v.append(item.GetAttributes('t:utrn_l'))
elif pf_class == "ElmTr3":
- v.append(ga(item, 't:utrn3_h'))
- v.append(ga(item, 't:utrn3_m'))
- v.append(ga(item, 't:utrn3_l'))
+ v.append(item.GetAttributes('t:utrn3_h'))
+ v.append(item.GetAttributes('t:utrn3_m'))
+ v.append(item.GetAttributes('t:utrn3_l'))
else:
v = [net[table].vn_kv.at[existing_bus] for _ in buses]
@@ -625,23 +635,17 @@ def create_connection_switches(net, item, number_switches, et, buses, elements):
def get_coords_from_buses(net, from_bus, to_bus, **kwargs):
- coords = []
- if from_bus in net.bus_geodata.index:
- x1, y1 = net.bus_geodata.loc[from_bus, ['x', 'y']]
- has_coords = True
- else:
- x1, y1 = np.nan, np.nan
- has_coords = False
+ coords: list[tuple[float, float]] = []
+ from_geo: Optional[str] = None
+ to_geo: Optional[str] = None
+ if from_bus in net.bus.index:
+ from_geo: str = net.bus.loc[from_bus, ['geo']]
- if to_bus in net.bus_geodata.index:
- x2, y2 = net.bus_geodata.loc[to_bus, ['x', 'y']]
- has_coords = True
- else:
- x2, y2 = np.nan, np.nan
- has_coords = False
+ if to_bus in net.bus.index:
+ to_geo: str = net.bus.loc[to_bus, ['geo']]
- if has_coords:
- coords = [[x1, y1], [x2, y2]]
+ if from_geo and to_geo:
+ coords = [geojson.utils.coords(geojson.loads(from_geo)), geojson.utils.coords(geojson.loads(to_geo))]
logger.debug('got coords from buses: %s' % coords)
else:
logger.debug('no coords for line between buses %d and %d' % (from_bus, to_bus))
@@ -656,7 +660,7 @@ def get_coords_from_item(item):
c = tuple((x, y) for [y, x] in coords)
except ValueError:
try:
- c = tuple((x, y) for [y, x, z] in coords)
+ c = tuple((x, y, z) for [y, x, z] in coords)
except ValueError:
c = []
return c
@@ -684,7 +688,6 @@ def get_coords_from_grf_object(item):
if len(coords) == 0:
coords = [[graphic_object.rCenterX, graphic_object.rCenterY]] * 2
logger.debug('extracted line coords from graphic object: %s' % coords)
- # net.line_geodata.loc[lid, 'coords'] = coords
else:
coords = []
@@ -757,13 +760,21 @@ def create_line(net, item, flag_graphics, create_sections, is_unbalanced):
logger.debug('line <%s> created' % params['name'])
-def point_len(p1, p2):
+def point_len(
+ p1: tuple[Union[float, int], Union[float, int]],
+ p2: tuple[Union[float, int], Union[float, int]]) -> float:
+ """
+ Calculate distance between p1 and p2
+ """
x1, y1 = p1
x2, y2 = p2
return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
-def calc_len_coords(coords):
+def calc_len_coords(coords: list[tuple[Union[float, int], Union[float, int]]]) -> float:
+ """
+ Calculate the sum of point distances in list of coords
+ """
tot_len = 0
for i in range(len(coords) - 1):
tot_len += point_len(coords[i], coords[i + 1])
@@ -859,6 +870,11 @@ def get_section_coords(coords, sec_len, start_len, scale_factor):
def segment_buses(net, bus1, bus2, num_sections, line_name): # , sec_len, start_len, coords):
+ """
+ splits bus1, bus2 line so that it creates num_sections amount of lines.
+ Yields start, end for each line segment.
+ e.g. Yields bus1, a, a, bus2 for num_sections = 2.
+ """
yield bus1
m = 1
# if coords:
@@ -874,11 +890,13 @@ def segment_buses(net, bus1, bus2, num_sections, line_name): # , sec_len, start
# split_len = 0
while m < num_sections:
- bus_name = "%s (Muff %u)" % (line_name, m)
+ bus_name = f"{line_name} (Muff {m})"
vn_kv = net.bus.at[bus1, "vn_kv"]
zone = net.bus.at[bus1, "zone"]
- k = pp.create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone)
+ bus = pp.create_bus(net, name=bus_name, type='ls', vn_kv=vn_kv, zone=zone)
+ # TODO: implement coords for segmentation buses.
+ # Handle coords if line has multiple coords.
# if coords:
# split_len += sec_len[m - 1] * scale_factor
#
@@ -888,9 +906,9 @@ def segment_buses(net, bus1, bus2, num_sections, line_name): # , sec_len, start
# logger.warning('bus %d has 0 coords, bus1: %d, bus2: %d' % k, bus1, bus2)
if "description" in net.bus:
- net.bus.at[k, "description"] = u""
- yield k
- yield k
+ net.bus.at[bus, "description"] = ""
+ yield bus
+ yield bus
m += 1
else:
yield bus2
@@ -902,7 +920,7 @@ def create_line_sections(net, item_list, line, bus1, bus2, coords, parallel, is_
item_list.sort(key=lambda x: x.index) # to ensure they are in correct order
if line.HasResults(-1): # -1 for 'c' results (whatever that is...)
- line_loading = ga(line, 'c:loading')
+ line_loading = line.GetAttributes('c:loading')
else:
line_loading = np.nan
@@ -928,10 +946,10 @@ def create_line_sections(net, item_list, line, bus1, bus2, coords, parallel, is_
scaling_factor = sum(sec_len) / calc_len_coords(coords)
sec_coords = get_section_coords(coords, sec_len=item.dline, start_len=item.rellen,
scale_factor=scaling_factor)
- net.line_geodata.loc[sid, 'coords'] = sec_coords
+ net.line.loc[sid, 'geo'] = geojson.dumps(geojson.LineString(sec_coords))
# p1 = sec_coords[0]
# p2 = sec_coords[-1]
- net.bus_geodata.loc[bus2, ['x', 'y']] = sec_coords[-1]
+ net.bus.loc[bus2, ['geo']] = geojson.dumps(geojson.Point(sec_coords[-1]))
except ZeroDivisionError:
logger.warning("Could not generate geodata for line !!")
@@ -1084,15 +1102,15 @@ def get_pf_line_results(net, item, lid, is_unbalanced, ac):
if is_unbalanced:
line_type = "res_line_3ph"
result_variables = {
- "pf_i_a_from_ka": "m:I:bus1:A",
- "pf_i_a_to_ka": "m:I:bus2:A",
- "pf_i_b_from_ka": "m:I:bus1:B",
- "pf_i_b_to_ka": "m:I:bus2:B",
- "pf_i_c_from_ka": "m:I:bus1:C",
- "pf_i_c_to_ka": "m:I:bus2:C",
- "pf_i_n_from_ka": "m:I0x3:bus1",
- "pf_i_n_to_ka": "m:I0x3:bus2",
- "pf_loading_percent": "c:loading",
+ "pf_i_a_from_ka": "m:I:bus1:A",
+ "pf_i_a_to_ka": "m:I:bus2:A",
+ "pf_i_b_from_ka": "m:I:bus1:B",
+ "pf_i_b_to_ka": "m:I:bus2:B",
+ "pf_i_c_from_ka": "m:I:bus1:C",
+ "pf_i_c_to_ka": "m:I:bus2:C",
+ "pf_i_n_from_ka": "m:I0x3:bus1",
+ "pf_i_n_to_ka": "m:I0x3:bus2",
+ "pf_loading_percent": "c:loading",
}
elif ac:
line_type = "res_line"
@@ -1104,7 +1122,7 @@ def get_pf_line_results(net, item, lid, is_unbalanced, ac):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(-1): # -1 for 'c' results (whatever that is...)
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
net[line_type].at[lid, res_var_pp] = res
@@ -1132,14 +1150,14 @@ def create_line_type(net, item, cable_in_air=False):
type_data = {
"r_ohm_per_km": item.rline,
"x_ohm_per_km": item.xline,
- "c_nf_per_km": item.cline*item.frnom/50 * 1e3, # internal unit for C in PF is uF
+ "c_nf_per_km": item.cline * item.frnom / 50 * 1e3, # internal unit for C in PF is uF
"q_mm2": item.qurs,
"max_i_ka": max_i_ka if max_i_ka != 0 else 1e-3,
"endtemp_degree": item.rtemp,
"type": line_or_cable,
"r0_ohm_per_km": item.rline0,
"x0_ohm_per_km": item.xline0,
- "c0_nf_per_km": item.cline0*item.frnom/50 * 1e3, # internal unit for C in PF is uF
+ "c0_nf_per_km": item.cline0 * item.frnom / 50 * 1e3, # internal unit for C in PF is uF
"alpha": item.alpha
}
pp.create_std_type(net, type_data, name, "line")
@@ -1236,8 +1254,8 @@ def create_ext_net(net, item, pv_as_slack, is_unbalanced):
# if item.HasResults(0): # 'm' results...
# # sm:r, sm:i don't work...
# logger.debug('<%s> has results' % name)
- # net['res_' + elm].at[xid, "pf_p"] = ga(item, 'm:P:bus1')
- # net['res_' + elm].at[xid, "pf_q"] = ga(item, 'm:Q:bus1')
+ # net['res_' + elm].at[xid, "pf_p"] = item.GetAttributes('m:P:bus1')
+ # net['res_' + elm].at[xid, "pf_q"] = item.GetAttributes('m:Q:bus1')
# else:
# net['res_' + elm].at[xid, "pf_p"] = np.nan
# net['res_' + elm].at[xid, "pf_q"] = np.nan
@@ -1257,12 +1275,12 @@ def get_pf_ext_grid_results(net, item, xid, is_unbalanced):
if is_unbalanced:
ext_grid_type = "res_ext_grid_3ph"
result_variables = {
- "pf_p_a": "m:P:bus1:A",
- "pf_q_a": "m:Q:bus1:A",
- "pf_p_b": "m:P:bus1:B",
- "pf_q_b": "m:Q:bus1:B",
- "pf_p_c": "m:P:bus1:C",
- "pf_q_c": "m:Q:bus1:C",
+ "pf_p_a": "m:P:bus1:A",
+ "pf_q_a": "m:Q:bus1:A",
+ "pf_p_b": "m:P:bus1:B",
+ "pf_q_b": "m:Q:bus1:B",
+ "pf_p_c": "m:P:bus1:C",
+ "pf_q_c": "m:Q:bus1:C",
}
else:
ext_grid_type = "res_ext_grid"
@@ -1274,7 +1292,7 @@ def get_pf_ext_grid_results(net, item, xid, is_unbalanced):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(0):
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
net[ext_grid_type].at[xid, res_var_pp] = res
@@ -1364,11 +1382,11 @@ def ask_load_params(item, pf_variable_p_loads, dict_net, variables):
if pf_variable_p_loads == 'm:P:bus1' and not item.HasResults(0):
raise RuntimeError('load %s does not have results and is ignored' % item.loc_name)
if 'p_mw' in variables:
- params.p_mw = ga(item, pf_variable_p_loads) * multiplier
+ params.p_mw = item.GetAttributes(pf_variable_p_loads) * multiplier
if 'q_mvar' in variables:
- params.q_mvar = ga(item, map_power_var(pf_variable_p_loads, 'q')) * multiplier
+ params.q_mvar = item.GetAttributes(map_power_var(pf_variable_p_loads, 'q')) * multiplier
if 'sn_mva' in variables:
- params.sn_mva = ga(item, map_power_var(pf_variable_p_loads, 's')) * multiplier
+ params.sn_mva = item.GetAttributes(map_power_var(pf_variable_p_loads, 's')) * multiplier
kap = -1 if item.pf_recap == 1 else 1
try:
@@ -1396,17 +1414,17 @@ def ask_unbalanced_load_params(item, pf_variable_p_loads, dict_net, variables):
if pf_variable_p_loads == 'm:P:bus1' and not item.HasResults(0):
raise RuntimeError('load %s does not have results and is ignored' % item.loc_name)
if 'p_mw' in variables:
- params.p_a_mw = ga(item, pf_variable_p_loads + "r")
- params.p_b_mw = ga(item, pf_variable_p_loads + "s")
- params.p_c_mw = ga(item, pf_variable_p_loads + "t")
+ params.p_a_mw = item.GetAttributes(pf_variable_p_loads + "r")
+ params.p_b_mw = item.GetAttributes(pf_variable_p_loads + "s")
+ params.p_c_mw = item.GetAttributes(pf_variable_p_loads + "t")
if 'q_mvar' in variables:
- params.q_a_mvar = ga(item, map_power_var(pf_variable_p_loads, 'q') + "r")
- params.q_b_mvar = ga(item, map_power_var(pf_variable_p_loads, 'q') + "s")
- params.q_c_mvar = ga(item, map_power_var(pf_variable_p_loads, 'q') + "t")
+ params.q_a_mvar = item.GetAttributes(map_power_var(pf_variable_p_loads, 'q') + "r")
+ params.q_b_mvar = item.GetAttributes(map_power_var(pf_variable_p_loads, 'q') + "s")
+ params.q_c_mvar = item.GetAttributes(map_power_var(pf_variable_p_loads, 'q') + "t")
if 'sn_mva' in variables:
- params.sn_a_mva = ga(item, map_power_var(pf_variable_p_loads, 's') + "r")
- params.sn_b_mva = ga(item, map_power_var(pf_variable_p_loads, 's') + "s")
- params.sn_c_mva = ga(item, map_power_var(pf_variable_p_loads, 's') + "t")
+ params.sn_a_mva = item.GetAttributes(map_power_var(pf_variable_p_loads, 's') + "r")
+ params.sn_b_mva = item.GetAttributes(map_power_var(pf_variable_p_loads, 's') + "s")
+ params.sn_c_mva = item.GetAttributes(map_power_var(pf_variable_p_loads, 's') + "t")
kap = -1 if item.pf_recap == 1 else 1
try:
@@ -1589,9 +1607,9 @@ def split_line_add_bus_old(net, item, parent):
raise RuntimeError('incorrect length for section %s: %.3f' % (sec, sec_len_b))
# get coords
- if sid in net.line_geodata.index.values:
+ if net.line.at[sid, 'geo'].notna():
logger.debug('line has coords')
- coords = net.line_geodata.at[sid, 'coords']
+ coords = geojson.utils.coords(geojson.loads(net.line.at[sid, 'geo']))
logger.debug('old geodata of line %d: %s' % (sid, coords))
# get coords for 2 split lines
@@ -1619,12 +1637,17 @@ def split_line_add_bus_old(net, item, parent):
logger.debug('created new bus in net: %s' % net.bus.loc[bus])
# create new line
- lid = pp.create_line(net, from_bus=bus, to_bus=net.line.at[sid, 'to_bus'],
- length_km=sec_len_b,
- std_type=net.line.at[sid, 'std_type'],
- name=net.line.at[sid, 'name'], df=net.line.at[sid, 'df'])
+ lid = pp.create_line(
+ net,
+ from_bus=bus,
+ to_bus=net.line.at[sid, 'to_bus'],
+ length_km=sec_len_b,
+ std_type=net.line.at[sid, 'std_type'],
+ name=net.line.at[sid, 'name'],
+ df=net.line.at[sid, 'df'],
+ geodata=coords_b
+ )
net.line.at[lid, 'section'] = net.line.at[sid, 'section']
- net.line_geodata.loc[lid, 'coords'] = coords_b
if not net.line.loc[sid, 'section_idx']:
net.line.loc[sid, 'section_idx'] = 0
@@ -1635,7 +1658,7 @@ def split_line_add_bus_old(net, item, parent):
net.line.at[sid, 'to_bus'] = bus
net.line.at[sid, 'length_km'] = sec_len_a
- net.line_geodata.loc[sid, 'coords'] = coords_a
+ net.line.at[sid, 'geo'] = geojson.dumps(geojson.LineString(coords_a))
logger.debug('changed: %s' % net.line.loc[sid])
else:
# no new bus/line are created: take the to_bus
@@ -1656,7 +1679,7 @@ def create_load(net, item, pf_variable_p_loads, dict_net, is_unbalanced):
ask = ask_unbalanced_load_params if is_unbalanced else ask_load_params
if load_class == 'ElmLodlv':
- # if bool(ga(item, 'e:cHasPartLod')):
+ # if bool(item.GetAttributes('e:cHasPartLod')):
# logger.info('ElmLodlv %s has partial loads - skip' % item.loc_name)
# part_lods = item.GetContents('*.ElmLodlvp')
# logger.debug('%s' % part_lods)
@@ -1689,9 +1712,6 @@ def create_load(net, item, pf_variable_p_loads, dict_net, is_unbalanced):
load_type.kqu0,
load_type.kqu1,
load_type.kqu]
- #if #(load_type.kpu0!=load_type.kqu0 or \
- #load_type.kpu1!=load_type.kqu1 or \
- #load_type.kpu!=load_type.kqu) or \
if (pf_params[:3]!=pf_params[3:]) or \
(pf_params[:3]!=[0,1,2]) or \
(pf_params[3:]!=[0,1,2]):
@@ -1799,8 +1819,8 @@ def create_load(net, item, pf_variable_p_loads, dict_net, is_unbalanced):
# if not is_unbalanced:
# if item.HasResults(0): # 'm' results...
# logger.debug('<%s> has results' % params.name)
- # net["res_load"].at[ld, "pf_p"] = ga(item, 'm:P:bus1')
- # net["res_load"].at[ld, "pf_q"] = ga(item, 'm:Q:bus1')
+ # net["res_load"].at[ld, "pf_p"] = item.GetAttributes('m:P:bus1')
+ # net["res_load"].at[ld, "pf_q"] = item.GetAttributes('m:Q:bus1')
# else:
# net["res_load"].at[ld, "pf_p"] = np.nan
# net["res_load"].at[ld, "pf_q"] = np.nan
@@ -1831,7 +1851,7 @@ def get_pf_load_results(net, item, ld, is_unbalanced):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(0):
- res = ga(item, res_var_pf) * get_power_multiplier(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf) * get_power_multiplier(item, res_var_pf)
net[load_type].at[ld, res_var_pp] = res
@@ -1841,11 +1861,11 @@ def ask_gen_params(item, pf_variable_p_gen, *vars):
if pf_variable_p_gen == 'm:P:bus1' and not item.HasResults(0):
raise RuntimeError('generator %s does not have results and is ignored' % item.loc_name)
if 'p_mw' in vars:
- params.p_mw = ga(item, pf_variable_p_gen) * multiplier
+ params.p_mw = item.GetAttributes(pf_variable_p_gen) * multiplier
if 'q_mvar' in vars:
- params.q_mvar = ga(item, map_power_var(pf_variable_p_gen, 'q')) * multiplier
+ params.q_mvar = item.GetAttributes(map_power_var(pf_variable_p_gen, 'q')) * multiplier
if 'sn_mva' in vars:
- params.sn_mva = ga(item, map_power_var(pf_variable_p_gen, 'sn')) * multiplier
+ params.sn_mva = item.GetAttributes(map_power_var(pf_variable_p_gen, 'sn')) * multiplier
params.scaling = item.scale0 if pf_variable_p_gen == 'pgini' else 1
# p_mw = p_mw, q_mvar = q_mvar, scaling = scaling
@@ -1861,25 +1881,25 @@ def ask_unbalanced_sgen_params(item, pf_variable_p_sgen, *vars):
technology = item.phtech
if technology in [0, 1]: # (0-1: 3PH)
if 'p_mw' in vars:
- params.p_a_mw = ga(item, pf_variable_p_sgen) / 3
- params.p_b_mw = ga(item, pf_variable_p_sgen) / 3
- params.p_c_mw = ga(item, pf_variable_p_sgen) / 3
+ params.p_a_mw = item.GetAttributes(pf_variable_p_sgen) / 3
+ params.p_b_mw = item.GetAttributes(pf_variable_p_sgen) / 3
+ params.p_c_mw = item.GetAttributes(pf_variable_p_sgen) / 3
if 'q_mvar' in vars:
- params.q_a_mvar = ga(item, map_power_var(pf_variable_p_sgen, 'q')) / 3
- params.q_b_mvar = ga(item, map_power_var(pf_variable_p_sgen, 'q')) / 3
- params.q_c_mvar = ga(item, map_power_var(pf_variable_p_sgen, 'q')) / 3
+ params.q_a_mvar = item.GetAttributes(map_power_var(pf_variable_p_sgen, 'q')) / 3
+ params.q_b_mvar = item.GetAttributes(map_power_var(pf_variable_p_sgen, 'q')) / 3
+ params.q_c_mvar = item.GetAttributes(map_power_var(pf_variable_p_sgen, 'q')) / 3
elif technology in [2, 3, 4]: # (2-4: 1PH)
if 'p_mw' in vars:
- params.p_a_mw = ga(item, pf_variable_p_sgen)
+ params.p_a_mw = item.GetAttributes(pf_variable_p_sgen)
params.p_b_mw = 0
params.p_c_mw = 0
if 'q_mvar' in vars:
- params.q_a_mvar = ga(item, map_power_var(pf_variable_p_sgen, 'q'))
+ params.q_a_mvar = item.GetAttributes(map_power_var(pf_variable_p_sgen, 'q'))
params.q_b_mvar = 0
params.q_c_mvar = 0
if 'sn_mva' in vars:
- params.sn_mva = ga(item, map_power_var(pf_variable_p_sgen, 's'))
+ params.sn_mva = item.GetAttributes(map_power_var(pf_variable_p_sgen, 's'))
params.scaling = item.scale0 if pf_variable_p_sgen == 'pgini' else 1
return params
@@ -1909,7 +1929,7 @@ def create_sgen_genstat(net, item, pv_as_slack, pf_variable_p_gen, dict_net, is_
return
params.update(ask(item, pf_variable_p_gen, 'p_mw', 'q_mvar', 'sn_mva'))
- logger.debug('genstat parameters: ' % params)
+ logger.debug(f'genstat parameters: {params}')
params.in_service = monopolar_in_service(item)
@@ -1941,7 +1961,7 @@ def create_sgen_genstat(net, item, pv_as_slack, pf_variable_p_gen, dict_net, is_
# create...
pstac = item.c_pstac # "None" if station controller is not available
- if pstac is not None and export_ctrl:
+ if pstac is not None and not pstac.outserv and export_ctrl:
if pstac.i_droop:
av_mode = 'constq'
else:
@@ -2057,7 +2077,7 @@ def get_pf_sgen_results(net, item, sg, is_unbalanced, element='sgen'):
res = np.nan
if item.HasResults(0):
if res_var_pf is not None:
- res = ga(item, res_var_pf) * get_power_multiplier(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf) * get_power_multiplier(item, res_var_pf)
else:
res = np.nan
net[sgen_type].at[sg, res_var_pp] = res
@@ -2095,8 +2115,8 @@ def create_sgen_neg_load(net, item, pf_variable_p_loads, dict_net):
if item.HasResults(0): # 'm' results...
logger.debug('<%s> has results' % params.name)
- net.res_sgen.at[sg, "pf_p"] = -ga(item, 'm:P:bus1')
- net.res_sgen.at[sg, "pf_q"] = -ga(item, 'm:Q:bus1')
+ net.res_sgen.at[sg, "pf_p"] = -item.GetAttributes('m:P:bus1')
+ net.res_sgen.at[sg, "pf_q"] = -item.GetAttributes('m:Q:bus1')
else:
net.res_sgen.at[sg, "pf_p"] = np.nan
net.res_sgen.at[sg, "pf_q"] = np.nan
@@ -2153,7 +2173,7 @@ def create_sgen_sym(net, item, pv_as_slack, pf_variable_p_gen, dict_net, export_
pstac = item.c_pstac
# "None" if station controller is not available
- if pstac is not None and export_ctrl:
+ if pstac is not None and not pstac.outserv and export_ctrl:
if pstac.i_droop:
av_mode = 'constq'
else:
@@ -2195,8 +2215,8 @@ def create_sgen_sym(net, item, pv_as_slack, pf_variable_p_gen, dict_net, export_
if item.HasResults(0): # 'm' results...
logger.debug('<%s> has results' % name)
- net['res_' + element].at[sid, "pf_p"] = ga(item, 'm:P:bus1') * multiplier
- net['res_' + element].at[sid, "pf_q"] = ga(item, 'm:Q:bus1') * multiplier
+ net['res_' + element].at[sid, "pf_p"] = item.GetAttributes('m:P:bus1') * multiplier
+ net['res_' + element].at[sid, "pf_q"] = item.GetAttributes('m:Q:bus1') * multiplier
else:
net['res_' + element].at[sid, "pf_p"] = np.nan
net['res_' + element].at[sid, "pf_q"] = np.nan
@@ -2210,10 +2230,10 @@ def create_sgen_asm(net, item, pf_variable_p_gen, dict_net):
dict_net['global_parameters']['global_generation_scaling']
multiplier = get_power_multiplier(item, pf_variable_p_gen)
- p_res = ga(item, 'pgini') * multiplier
- q_res = ga(item, 'qgini') * multiplier
+ p_res = item.GetAttributes('pgini') * multiplier
+ q_res = item.GetAttributes('qgini') * multiplier
if item.HasResults(0):
- q_res = ga(item, 'm:Q:bus1') / global_scaling * multiplier
+ q_res = item.GetAttributes('m:Q:bus1') / global_scaling * multiplier
else:
logger.warning('reactive power for asynchronous generator is not exported properly '
'(advanced modelling of asynchronous generators not implemented)')
@@ -2248,8 +2268,8 @@ def create_sgen_asm(net, item, pf_variable_p_gen, dict_net):
attr_list=["sernum", "chr_name", "cpSite.loc_name"])
if item.HasResults(0):
- net.res_sgen.at[sid, 'pf_p'] = ga(item, 'm:P:bus1') * multiplier
- net.res_sgen.at[sid, 'pf_q'] = ga(item, 'm:Q:bus1') * multiplier
+ net.res_sgen.at[sid, 'pf_p'] = item.GetAttributes('m:P:bus1') * multiplier
+ net.res_sgen.at[sid, 'pf_q'] = item.GetAttributes('m:Q:bus1') * multiplier
else:
net.res_sgen.at[sid, 'pf_p'] = np.nan
net.res_sgen.at[sid, 'pf_q'] = np.nan
@@ -2360,11 +2380,11 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc
tap_pos = np.nan
if pf_type.itapch:
if tap_opt == "nntap":
- tap_pos = ga(item, "nntap")
+ tap_pos = item.GetAttributes("nntap")
logger.debug("got tap %f from nntap" % tap_pos)
elif tap_opt == "c:nntap":
- tap_pos = ga(item, "c:nntap")
+ tap_pos = item.GetAttributes("c:nntap")
logger.debug("got tap %f from c:nntap" % tap_pos)
else:
raise ValueError('could not read current tap position: tap_opt = %s' % tap_opt)
@@ -2373,9 +2393,9 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc
# In PowerFactory, if the first tap changer is absent, the second is also, even if the check was there
if pf_type.itapch and pf_type.itapch2:
if tap_opt == "nntap":
- tap_pos2 = ga(item, "nntap2")
+ tap_pos2 = item.GetAttributes("nntap2")
elif tap_opt == "c:nntap":
- tap_pos2 = ga(item, "c:nntap2")
+ tap_pos2 = item.GetAttributes("c:nntap2")
if std_type is not None:
tid = pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, name=name,
@@ -2386,16 +2406,31 @@ def create_trafo(net, item, export_controller=True, tap_opt="nntap", is_unbalanc
logger.debug('created trafo at index <%d>' % tid)
else:
logger.info("Create Trafo 3ph")
- tid = pp.create_transformer_from_parameters(net, hv_bus=bus1, lv_bus=bus2, name=name,
- tap_pos=tap_pos,
- in_service=in_service, parallel=item.ntnum, df=item.ratfac,
- sn_mva=pf_type.strn, vn_hv_kv=pf_type.utrn_h, vn_lv_kv=pf_type.utrn_l,
- vk_percent=pf_type.uktr, vkr_percent=pf_type.uktrr,
- pfe_kw=pf_type.pfe, i0_percent=pf_type.curmg,
- vector_group=pf_type.vecgrp[:-1], vk0_percent=pf_type.uk0tr,
- vkr0_percent=pf_type.ur0tr, mag0_percent=pf_type.zx0hl_n,
- mag0_rx=pf_type.rtox0_n, si0_hv_partial=pf_type.zx0hl_h,
- shift_degree=pf_type.nt2ag * 30, tap2_pos=tap_pos2)
+ tid = pp.create_transformer_from_parameters(
+ net,
+ hv_bus=bus1,
+ lv_bus=bus2,
+ name=name,
+ tap_pos=tap_pos,
+ in_service=in_service,
+ parallel=item.ntnum,
+ df=item.ratfac,
+ sn_mva=pf_type.strn,
+ vn_hv_kv=pf_type.utrn_h,
+ vn_lv_kv=pf_type.utrn_l,
+ vk_percent=pf_type.uktr,
+ vkr_percent=pf_type.uktrr,
+ pfe_kw=pf_type.pfe,
+ i0_percent=pf_type.curmg,
+ vector_group=pf_type.vecgrp[:-1],
+ vk0_percent=pf_type.uk0tr,
+ vkr0_percent=pf_type.ur0tr,
+ mag0_percent=pf_type.zx0hl_n,
+ mag0_rx=pf_type.rtox0_n,
+ si0_hv_partial=pf_type.zx0hl_h,
+ shift_degree=pf_type.nt2ag * 30,
+ tap2_pos=tap_pos2
+ )
trafo_dict[item] = tid
# add value for voltage setpoint
@@ -2467,15 +2502,15 @@ def get_pf_trafo_results(net, item, tid, is_unbalanced):
if is_unbalanced:
trafo_type = "res_trafo_3ph"
result_variables = {
- "pf_i_a_hv_ka": "m:I:bushv:A",
- "pf_i_a_lv_ka": "m:I:buslv:A",
- "pf_i_b_hv_ka": "m:I:bushv:B",
- "pf_i_b_lv_ka": "m:I:buslv:B",
- "pf_i_c_hv_ka": "m:I:bushv:C",
- "pf_i_c_lv_ka": "m:I:buslv:C",
- "pf_i_n_hv_ka": "m:I0x3:bushv",
- "pf_i_n_lv_ka": "m:I0x3:buslv",
- "pf_loading_percent": "c:loading",
+ "pf_i_a_hv_ka": "m:I:bushv:A",
+ "pf_i_a_lv_ka": "m:I:buslv:A",
+ "pf_i_b_hv_ka": "m:I:bushv:B",
+ "pf_i_b_lv_ka": "m:I:buslv:B",
+ "pf_i_c_hv_ka": "m:I:bushv:C",
+ "pf_i_c_lv_ka": "m:I:buslv:C",
+ "pf_i_n_hv_ka": "m:I0x3:bushv",
+ "pf_i_n_lv_ka": "m:I0x3:buslv",
+ "pf_loading_percent": "c:loading",
}
else:
trafo_type = "res_trafo"
@@ -2486,7 +2521,7 @@ def get_pf_trafo_results(net, item, tid, is_unbalanced):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(-1): # -1 for 'c' results (whatever that is...)
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
net[trafo_type].at[tid, res_var_pp] = res
@@ -2555,21 +2590,21 @@ def create_trafo3w(net, item, tap_opt='nntap'):
ts = ["h", "m", "l"][side[0]]
# figure out current tap position
if tap_opt == "nntap":
- tap_pos = ga(item, 'n3tap_' + ts)
+ tap_pos = item.GetAttributes('n3tap_' + ts)
logger.debug("got tap %f from n3tap" % tap_pos)
elif tap_opt == "c:nntap":
- tap_pos = ga(item, "c:n3tap_" + ts)
+ tap_pos = item.GetAttributes("c:n3tap_" + ts)
logger.debug("got tap %f from c:n3tap" % tap_pos)
else:
raise ValueError('could not read current tap position: tap_opt = %s' % tap_opt)
params.update({
'tap_side': ts + 'v', # hv, mv, lv
- 'tap_step_percent': ga(item, 't:du3tp_' + ts),
- 'tap_step_degree': ga(item, 't:ph3tr_' + ts),
- 'tap_min': ga(item, 't:n3tmn_' + ts),
- 'tap_max': ga(item, 't:n3tmx_' + ts),
- 'tap_neutral': ga(item, 't:n3tp0_' + ts),
+ 'tap_step_percent': item.GetAttributes('t:du3tp_' + ts),
+ 'tap_step_degree': item.GetAttributes('t:ph3tr_' + ts),
+ 'tap_min': item.GetAttributes('t:n3tmn_' + ts),
+ 'tap_max': item.GetAttributes('t:n3tmx_' + ts),
+ 'tap_neutral': item.GetAttributes('t:n3tp0_' + ts),
'tap_pos': tap_pos
})
@@ -2583,7 +2618,7 @@ def create_trafo3w(net, item, tap_opt='nntap'):
logger.debug('successfully created trafo3w from parameters: %d' % tid)
# testen
- # net.trafo3w.loc[tid, 'tap_step_degree'] = ga(item, 't:ph3tr_h')
+ # net.trafo3w.loc[tid, 'tap_step_degree'] = item.GetAttributes('t:ph3tr_h')
# adding switches
# False if open, True if closed, None if no switch
@@ -2598,7 +2633,7 @@ def create_trafo3w(net, item, tap_opt='nntap'):
# assign loading from power factory results
if item.HasResults(-1): # -1 for 'c' results (whatever that is...)
logger.debug('trafo3w <%s> has results' % item.loc_name)
- loading = ga(item, 'c:loading')
+ loading = item.GetAttributes('c:loading')
net.res_trafo3w.at[tid, "pf_loading"] = loading
else:
net.res_trafo3w.at[tid, "pf_loading"] = np.nan
@@ -2608,12 +2643,12 @@ def create_trafo3w(net, item, tap_opt='nntap'):
if pf_type.itapzdep:
x_points = (net.trafo3w.at[tid, "tap_min"], net.trafo3w.at[tid, "tap_neutral"], net.trafo3w.at[tid, "tap_max"])
for side in ("hv", "mv", "lv"):
- vk_min = ga(pf_type, f"uktr3mn_{side[0]}")
+ vk_min = pf_type.GetAttributes(f"uktr3mn_{side[0]}")
vk_neutral = net.trafo3w.at[tid, f"vk_{side}_percent"]
- vk_max = ga(pf_type, f"uktr3mx_{side[0]}")
- vkr_min = ga(pf_type, f"uktrr3mn_{side[0]}")
+ vk_max = pf_type.GetAttributes(f"uktr3mx_{side[0]}")
+ vkr_min = pf_type.GetAttributes(f"uktrr3mn_{side[0]}")
vkr_neutral = net.trafo3w.at[tid, f"vkr_{side}_percent"]
- vkr_max = ga(pf_type, f"uktrr3mx_{side[0]}")
+ vkr_max = pf_type.GetAttributes(f"uktrr3mx_{side[0]}")
# todo zero-sequence parameters (must be implemented in build_branch first)
pp.control.create_trafo_characteristics(net, trafotable="trafo3w", trafo_index=tid,
variable=f"vk_{side}_percent", x_points=x_points,
@@ -2669,7 +2704,7 @@ def create_coup(net, item, is_fuse=False):
# # false approach, completely irrelevant
# def create_switch(net, item):
# switch_types = {"cbk": "CB", "sdc": "LBS", "swt": "LS", "dct": "DS"}
-# name = ga(item, 'loc_name')
+# name = item.GetAttributes('loc_name')
# logger.debug('>> creating switch <%s>' % name)
#
# pf_bus1 = item.GetNode(0)
@@ -2684,8 +2719,8 @@ def create_coup(net, item, is_fuse=False):
# bus2 = find_bus_index_in_net(pf_bus2, net)
# logger.debug('switch %s connects buses <%d> and <%d>' % (name, bus1, bus2))
#
-# switch_is_closed = bool(ga(item, 'on_off'))
-# switch_usage = switch_types[ga(item, 'aUsage')]
+# switch_is_closed = bool(item.GetAttributes('on_off'))
+# switch_usage = switch_types[item.GetAttributes('aUsage')]
#
# cd = pp.create_switch(net, name=name, bus=bus1, element=bus2, et='b',
# closed=switch_is_closed, type=switch_usage)
@@ -2700,6 +2735,12 @@ def create_shunt(net, item):
logger.error("Cannot add Shunt '%s': not connected" % item.loc_name)
return
+ def calc_p_mw_and_q_mvar(r: float, x: float) -> tuple[float, float]:
+ if r == 0 and x == 0:
+ return 0, 0
+ divisor: float = (r ** 2 + x ** 2)
+ return (item.ushnm ** 2 * r) / divisor * multiplier, (item.ushnm ** 2 * x) / divisor * multiplier
+
multiplier = get_power_multiplier(item, 'Qact')
bus, _ = get_connection_nodes(net, item, 1)
params = {
@@ -2712,87 +2753,62 @@ def create_shunt(net, item):
'max_step': item.ncapx
}
print(item.loc_name)
+ r_val: float = .0
+ x_val: float = .0
if item.shtype == 0:
# Shunt is a R-L-C element
-
- R = item.rrea
- X = -1e6 / item.bcap + item.xrea
- if R == 0 and X == 0: #TODO put this into one function
- p_mw = 0
- params['q_mvar'] = 0
- else:
- p_mw = (item.ushnm ** 2 * R) / (R ** 2 + X ** 2) * multiplier
- params['q_mvar'] = (item.ushnm ** 2 * X) / (R ** 2 + X ** 2) * multiplier
- sid = pp.create_shunt(net, p_mw=p_mw, **params)
+ r_val = item.rrea
+ x_val = -1e6 / item.bcap + item.xrea
elif item.shtype == 1:
# Shunt is an R-L element
-
- R = item.rrea
- X = item.xrea
- if R == 0 and X == 0: #TODO put this into one function
- p_mw = 0
- params['q_mvar'] = 0
- else:
- p_mw = (item.ushnm ** 2 * R) / (R ** 2 + X ** 2) * multiplier
- params['q_mvar'] = (item.ushnm ** 2 * X) / (R ** 2 + X ** 2) * multiplier
- sid = pp.create_shunt(net, p_mw=p_mw, **params)
+ r_val = item.rrea
+ x_val = item.xrea
elif item.shtype == 2:
# Shunt is a capacitor bank
- B = item.bcap*1e-6
- G = item.gparac*1e-6
-
- R = G/(G**2 + B**2)
- X = -B/(G**2 + B**2)
- if R == 0 and X == 0: #TODO put this into one function
- p_mw = 0
- params['q_mvar'] = 0
- else:
- p_mw = (item.ushnm ** 2 * R) / (R ** 2 + X ** 2) * multiplier
- params['q_mvar'] = (item.ushnm ** 2 * X) / (R ** 2 + X ** 2) * multiplier
- sid = pp.create_shunt(net, p_mw=p_mw, **params)
+ b = item.bcap*1e-6
+ g = item.gparac*1e-6
+
+ r_val = g / (g ** 2 + b ** 2)
+ x_val = -b / (g ** 2 + b ** 2)
elif item.shtype == 3:
# Shunt is a R-L-C, Rp element
+ rp = item.rpara
+ rs = item.rrea
+ xl = item.xrea
+ bc = -item.bcap * 1e-6
- Rp = item.rpara
- Rs = item.rrea
- Xl = item.xrea
- Bc = -item.bcap * 1e-6
-
- R = Rp * (Rp * Rs + Rs ** 2 + Xl ** 2) / ((Rp + Rs) ** 2 + Xl ** 2)
- X = 1 / Bc + (Xl * Rp ** 2) / ((Rp + Rs) ** 2 + Xl ** 2)
- if R == 0 and X == 0: #TODO put this into one function
- p_mw = 0
- params['q_mvar'] = 0
- else:
- p_mw = (item.ushnm ** 2 * R) / (R ** 2 + X ** 2) * multiplier
- params['q_mvar'] = (item.ushnm ** 2 * X) / (R ** 2 + X ** 2) * multiplier
- sid = pp.create_shunt(net, p_mw=p_mw, **params)
+ r_val = rp * (rp * rs + rs ** 2 + xl ** 2) / ((rp + rs) ** 2 + xl ** 2)
+ x_val = 1 / bc + (xl * rp ** 2) / ((rp + rs) ** 2 + xl ** 2)
elif item.shtype == 4:
# Shunt is a R-L-C1-C2, Rp element
-
- Rp = item.rpara
- Rs = item.rrea
- Xl = item.xrea
- B1 = 2 * np.pi * 50 * item.c1 * 1e-6
- B2 = 2 * np.pi * 50 * item.c2 * 1e-6
-
- Z = Rp * (Rs + 1j * (Xl - 1 / B1)) / (Rp + Rs + 1j * (Xl - 1 / B1)) - 1j / B2
- R = np.real(Z)
- X = np.imag(Z)
- if R == 0 and X == 0: #TODO put this into one function
- p_mw = 0
- params['q_mvar'] = 0
- else:
- p_mw = (item.ushnm ** 2 * R) / (R ** 2 + X ** 2) * multiplier
- params['q_mvar'] = (item.ushnm ** 2 * X) / (R ** 2 + X ** 2) * multiplier
+ rp = item.rpara
+ rs = item.rrea
+ xl = item.xrea
+ b1 = 2 * np.pi * 50 * item.c1 * 1e-6
+ b2 = 2 * np.pi * 50 * item.c2 * 1e-6
+
+ z = rp * (rs + 1j * (xl - 1 / b1)) / (rp + rs + 1j * (xl - 1 / b1)) - 1j / b2
+ r_val = np.real(z)
+ x_val = np.imag(z)
+
+ if 0 <= item.shtype <= 4:
+ p_mw, params['q_mvar'] = calc_p_mw_and_q_mvar(r_val, x_val)
sid = pp.create_shunt(net, p_mw=p_mw, **params)
- add_additional_attributes(item, net, element='shunt', element_id=sid,
- attr_list=['cpSite.loc_name'], attr_dict={"cimRdfId": "origin_id"})
+ add_additional_attributes(
+ item,
+ net,
+ element='shunt',
+ element_id=sid,
+ attr_list=['cpSite.loc_name'],
+ attr_dict={"cimRdfId": "origin_id"}
+ )
+ else:
+ raise AttributeError(f"Shunt type {item.shtype} not valid: {item}")
if item.HasResults(0):
- net.res_shunt.loc[sid, 'pf_p'] = ga(item, 'm:P:bus1') * multiplier
- net.res_shunt.loc[sid, 'pf_q'] = ga(item, 'm:Q:bus1') * multiplier
+ net.res_shunt.loc[sid, 'pf_p'] = item.GetAttributes('m:P:bus1') * multiplier
+ net.res_shunt.loc[sid, 'pf_q'] = item.GetAttributes('m:Q:bus1') * multiplier
else:
net.res_shunt.loc[sid, 'pf_p'] = np.nan
net.res_shunt.loc[sid, 'pf_q'] = np.nan
@@ -2897,8 +2913,8 @@ def create_vac(net, item):
params['name'], item.itype))
if item.HasResults(0): # -1 for 'c' results (whatever that is...)
- net['res_%s' % elm].at[xid, "pf_p"] = -ga(item, 'm:P:bus1')
- net['res_%s' % elm].at[xid, "pf_q"] = -ga(item, 'm:Q:bus1')
+ net['res_%s' % elm].at[xid, "pf_p"] = -item.GetAttributes('m:P:bus1')
+ net['res_%s' % elm].at[xid, "pf_q"] = -item.GetAttributes('m:Q:bus1')
else:
net['res_%s' % elm].at[xid, "pf_p"] = np.nan
net['res_%s' % elm].at[xid, "pf_q"] = np.nan
@@ -2927,6 +2943,7 @@ def create_sind(net, item):
logger.debug('created series reactor %s as per unit impedance at index %d' %
(net.impedance.at[sind, 'name'], sind))
+
def create_scap(net, item):
# series capacitor is modelled as per-unit impedance, values in Ohm are calculated into values in
# per unit at creation
@@ -2936,11 +2953,11 @@ def create_scap(net, item):
logger.error("Cannot add Scap '%s': not connected" % item.loc_name)
return
- if (item.gcap==0) or (item.bcap==0):
+ if (item.gcap == 0) or (item.bcap == 0):
logger.info('not creating series capacitor for %s' % item.loc_name)
else:
- r_ohm = item.gcap/(item.gcap**2 + item.bcap**2)
- x_ohm = -item.bcap/(item.gcap**2 + item.bcap**2)
+ r_ohm = item.gcap / (item.gcap ** 2 + item.bcap ** 2)
+ x_ohm = -item.bcap / (item.gcap ** 2 + item.bcap ** 2)
scap = pp.create_series_reactor_as_impedance(net, from_bus=bus1, to_bus=bus2, r_ohm=r_ohm,
x_ohm=x_ohm, sn_mva=item.Sn,
name=item.loc_name,
@@ -2965,8 +2982,8 @@ def _get_vsc_control_modes(item, mono=True):
f" {item.loc_name} not implemented: {c_m}")
if item.HasResults(0):
- p_set_dc = -ga(item, f"m:P:{dc_bus_str}")
- q_set_ac = -ga(item, "m:Q:busac") * scaling
+ p_set_dc = -item.GetAttributes(f"m:P:{dc_bus_str}")
+ q_set_ac = -item.GetAttributes("m:Q:busac") * scaling
else:
p_set_dc = -item.psetp * scaling # does not work - in PowerFactory, the P set-point relates to AC side
q_set_ac = -item.qsetp * scaling
@@ -2986,7 +3003,6 @@ def _get_vsc_control_modes(item, mono=True):
def create_vscmono(net, item):
-
(bus, bus_dc), _ = get_connection_nodes(net, item, 2)
sn_mva = item.Snom
@@ -3021,7 +3037,9 @@ def create_vscmono(net, item):
}
if params["r_dc_ohm"] == 0:
- logger.warning(f"VSCmono element {params['name']} has no DC resistive loss factor - power flow will not converge!")
+ logger.warning(
+ f"VSCmono element {params['name']} has no DC resistive loss factor - power flow will not converge!"
+ )
vid = pp.create_vsc(net, **params)
logger.debug(f'created VSC {vid} for vscmono {item.loc_name}')
@@ -3033,7 +3051,7 @@ def create_vscmono(net, item):
for res_var_pp, res_var_pf in result_variables.items():
res = np.nan
if item.HasResults(0):
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
net.res_vsc.at[vid, res_var_pp] = -res
@@ -3081,22 +3099,20 @@ def create_vsc(net, item):
if item.HasResults(0):
for res_var_pp, res_var_pf in result_variables.items():
- res = ga(item, res_var_pf)
+ res = item.GetAttributes(res_var_pf)
net.res_vsc.at[vid_1, res_var_pp] = -res / 2
net.res_vsc.at[vid_2, res_var_pp] = -res / 2
- net.res_vsc.at[vid_1, "pf_p_dc_mw"] = -ga(item, "m:P:busdm")
- net.res_vsc.at[vid_2, "pf_p_dc_mw"] = -ga(item, "m:P:busdp")
+ net.res_vsc.at[vid_1, "pf_p_dc_mw"] = -item.GetAttributes("m:P:busdm")
+ net.res_vsc.at[vid_2, "pf_p_dc_mw"] = -item.GetAttributes("m:P:busdp")
else:
net.res_vsc.loc[vid_1, ["pf_p_mw", "pf_q_mvar", "pf_p_dc_mw"]] = np.nan
net.res_vsc.loc[vid_2, ["pf_p_mw", "pf_q_mvar", "pf_p_dc_mw"]] = np.nan
-
def create_stactrl(net, item):
stactrl_in_service = True
if item.outserv:
logger.info(f"Station controller {item.loc_name} is out of service")
- stactrl_in_service = False
return
machines = [m for m in item.psym if m is not None]
@@ -3160,7 +3176,7 @@ def create_stactrl(net, item):
distribution.append(item.cvqq / 100)
i = i + 1
- if item.imode != 0:
+ if item.imode > 2:
raise NotImplementedError(f"{item}: reactive power distribution {item.imode=} not implemented")
phase = item.i_phase
@@ -3252,15 +3268,15 @@ def create_stactrl(net, item):
if not has_path and not control_mode == 0 and not item.i_droop:
return
- if control_mode == 0: #### VOLTAGE CONTROL
+ if control_mode == 0: # VOLTAGE CONTROL
# controlled_node = item.rembar
controlled_node = item.cpCtrlNode
bus = bus_dict[controlled_node] # controlled node
- if item.uset_mode == 0: #### Station controller
+ if item.uset_mode == 0: # Station controller
v_setpoint_pu = item.usetp
else:
- v_setpoint_pu = controlled_node.vtarget #### Bus target voltage
+ v_setpoint_pu = controlled_node.vtarget # Bus target voltage
if item.i_droop: # Enable Droop
bsc = pp.control.BinarySearchControl(net, ctrl_in_service=stactrl_in_service,
@@ -3289,28 +3305,49 @@ def create_stactrl(net, item):
# q_control_mode = item.qu_char # 0: "Const Q", 1: "Q(V) Characteristic", 2: "Q(P) Characteristic"
# q_control_terminal = q_control_cubicle.cterm # terminal of the cubicle
if item.qu_char == 0:
- pp.control.BinarySearchControl(net, ctrl_in_service=stactrl_in_service,
- output_element=gen_element, output_variable="q_mvar",
- output_element_index=gen_element_index,
- output_element_in_service=gen_element_in_service,
- input_element=res_element_table,
- output_values_distribution=distribution, damping_factor=0.9,
- input_variable=variable, input_element_index=res_element_index,
- set_point=item.qsetp, voltage_ctrl=False, tol=1e-6)
+ pp.control.BinarySearchControl(
+ net, ctrl_in_service=stactrl_in_service,
+ output_element=gen_element,
+ output_variable="q_mvar",
+ output_element_index=gen_element_index,
+ output_element_in_service=gen_element_in_service,
+ input_element=res_element_table,
+ output_values_distribution=distribution,
+ damping_factor=0.9,
+ input_variable=variable,
+ input_element_index=res_element_index,
+ set_point=item.qsetp,
+ voltage_ctrl=False, tol=1e-6
+ )
elif item.qu_char == 1:
controlled_node = item.refbar
bus = bus_dict[controlled_node] # controlled node
- bsc = pp.control.BinarySearchControl(net, ctrl_in_service=stactrl_in_service,
- output_element=gen_element, output_variable="q_mvar",
- output_element_index=gen_element_index,
- output_element_in_service=gen_element_in_service,
- input_element=res_element_table,
- output_values_distribution=distribution, damping_factor=0.9,
- input_variable=variable, input_element_index=res_element_index,
- set_point=item.qsetp, voltage_ctrl=False, bus_idx=bus, tol=1e-6)
- pp.control.DroopControl(net, q_droop_mvar=item.Srated * 100 / item.ddroop, bus_idx=bus,
- vm_set_pu=item.udeadbup, vm_set_ub=item.udeadbup, vm_set_lb=item.udeadblow,
- controller_idx=bsc.index, voltage_ctrl=False)
+ bsc = pp.control.BinarySearchControl(
+ net, ctrl_in_service=stactrl_in_service,
+ output_element=gen_element,
+ output_variable="q_mvar",
+ output_element_index=gen_element_index,
+ output_element_in_service=gen_element_in_service,
+ input_element=res_element_table,
+ output_values_distribution=distribution,
+ damping_factor=0.9,
+ input_variable=variable,
+ input_element_index=res_element_index,
+ set_point=item.qsetp,
+ voltage_ctrl=False,
+ bus_idx=bus,
+ tol=1e-6
+ )
+ pp.control.DroopControl(
+ net,
+ q_droop_mvar=item.Srated * 100 / item.ddroop,
+ bus_idx=bus,
+ vm_set_pu=item.udeadbup,
+ vm_set_ub=item.udeadbup,
+ vm_set_lb=item.udeadblow,
+ controller_idx=bsc.index,
+ voltage_ctrl=False
+ )
else:
raise NotImplementedError
else:
@@ -3337,28 +3374,34 @@ def split_line_at_length(net, line, length_pos):
std_type = net.line.at[line, 'std_type']
name = net.line.at[line, 'name']
- new_line = pp.create_line(net, from_bus=bus, to_bus=bus2, length_km=new_length,
- std_type=std_type, name=name, df=net.line.at[line, 'df'],
- parallel=net.line.at[line, 'parallel'],
- in_service=net.line.at[line, 'in_service'])
+ new_line = pp.create_line(
+ net,
+ from_bus=bus,
+ to_bus=bus2,
+ length_km=new_length,
+ std_type=std_type,
+ name=name,
+ df=net.line.at[line, 'df'],
+ parallel=net.line.at[line, 'parallel'],
+ in_service=net.line.at[line, 'in_service']
+ )
if 'max_loading_percent' in net.line.columns:
net.line.loc[new_line, 'max_loading_percent'] = net.line.at[line, 'max_loading_percent']
- if 'line_geodata' in net.keys() and line in net.line_geodata.index.values:
- coords = net.line_geodata.at[line, 'coords']
+ if net.line.loc[line, 'geo'].notna():
+ coords = geojson.utils.coords(geojson.loads(net.line.loc[line, 'geo']))
scaling_factor = old_length / calc_len_coords(coords)
- sec_coords_a = get_section_coords(coords, sec_len=length_pos, start_len=0.,
- scale_factor=scaling_factor)
-
- sec_coords_b = get_section_coords(coords, sec_len=new_length, start_len=length_pos,
- scale_factor=scaling_factor)
+ sec_coords_a = get_section_coords(coords, sec_len=length_pos, start_len=0., scale_factor=scaling_factor)
+ sec_coords_b = get_section_coords(
+ coords, sec_len=new_length, start_len=length_pos, scale_factor=scaling_factor
+ )
- net.line_geodata.loc[line, 'coords'] = sec_coords_a
- net.line_geodata.loc[new_line, 'coords'] = sec_coords_b
+ net.line.loc[line, 'geo'] = geojson.dumps(geojson.LineString(sec_coords_a))
+ net.line.loc[new_line, 'geo'] = geojson.dumps(geojson.LineString(sec_coords_b))
- net.bus_geodata.loc[bus, ['x', 'y']] = sec_coords_b[0]
+ net.bus.loc[bus, ['geo']] = geojson.Point(sec_coords_b[0])
return bus
@@ -3367,16 +3410,14 @@ def get_lodlvp_length_pos(line_item, lod_item):
sections = line_item.GetContents('*.ElmLnesec')
if len(sections) > 0:
sections.sort(lambda x: x.index)
- sections_start = [s.rellen for s in sections]
sections_end = [s.rellen + s.dline for s in sections]
else:
- sections_start = [0]
sections_end = [line_item.dline]
loads = line_item.GetContents('*.ElmLodlvp')
if len(loads) > 0:
loads.sort(lambda x: x.rellen)
- loads_start = [l.rellen for l in loads]
+ loads_start = [load.rellen for load in loads]
else:
loads_start = [0]
@@ -3421,7 +3462,8 @@ def split_line(net, line_idx, pos_at_line, line_item):
return bus_j
elif (pos_at_line - line_length) > tol:
raise ValueError(
- 'Position at line is higher than the line length itself! Line length: %.7f, position at line: %.7f (line: \n%s)' % (
+ 'Position at line is higher than the line length itself!\
+ Line length: %.7f, position at line: %.7f (line: \n%s)' % (
# line_length, pos_at_line, line_item.loc_name))
line_length, pos_at_line, net.line.loc[line_dict[line_item]]))
else:
@@ -3459,7 +3501,7 @@ def split_line(net, line_idx, pos_at_line, line_item):
net.line.at[new_line, 'order'] = net.line.at[line_idx, 'order'] + 1
net.res_line.at[new_line, 'pf_loading'] = net.res_line.at[line_idx, 'pf_loading']
- if line_idx in net.line_geodata.index.values:
+ if line_idx in net.line.index:
logger.debug('setting new coords')
set_new_coords(net, new_bus, line_idx, new_line, line_length, pos_at_line)
@@ -3524,7 +3566,7 @@ def break_coords_sections(coords, section_length, scale_factor_length):
# set up new coordinates for line sections that are split by the new bus of the ElmLodlvp
def set_new_coords(net, bus_id, line_idx, new_line_idx, line_length, pos_at_line):
- line_coords = net.line_geodata.at[line_idx, 'coords']
+ line_coords = net.line.at[line_idx, 'geo']
logger.debug('got coords for line %s' % line_idx)
scale_factor_length = get_scale_factor(line_length, line_coords)
@@ -3533,11 +3575,10 @@ def set_new_coords(net, bus_id, line_idx, new_line_idx, line_length, pos_at_line
logger.debug('calculated new coords: %s, %s ' % (section_coords, new_coords))
- net.line_geodata.at[line_idx, 'coords'] = section_coords
- net.line_geodata.at[new_line_idx, 'coords'] = new_coords
+ net.line.at[line_idx, 'geo'] = geojson.dumps(geojson.LineString(section_coords))
+ net.line.at[new_line_idx, 'geo'] = geojson.dumps(geojson.LineString(new_coords))
- net.bus_geodata.at[bus_id, 'x'] = new_coords[0][0]
- net.bus_geodata.at[bus_id, 'y'] = new_coords[0][1]
+ net.bus.at[bus_id, 'geo'] = geojson.dumps(geojson.Point(new_coords[0]))
# gather info about ElmLodlvp in a dict
@@ -3680,7 +3721,7 @@ def split_all_lines(net, lvp_dict):
# val = [(92, 1, 0.025, 0.1), (91, 2, 0.031, 0.2), (90, 2, 0.032, 0.3)]
for load_item, pos_at_line, (p, q) in val:
logger.debug(load_item)
- ## calculate at once and then read from dict - not good approach! don't do it
+ # calculate at once and then read from dict - not good approach! don't do it
# section, pos_at_sec = get_pos_at_sec(net, net_dgs, lvp_dict, line, load_idx)
# section = pas[load_idx]['section']
# pos_at_sec = pas[load_idx]['pos']
@@ -3702,7 +3743,7 @@ def split_all_lines(net, lvp_dict):
net.res_load.at[new_load, 'pf_p'] = p
net.res_load.at[new_load, 'pf_q'] = q
else:
- # const I not implemented for sgen...
+ # const I is not implemented for sgen
new_load = pp.create_sgen(net, new_bus, name=load_item.loc_name, p_mw=p, q_mvar=q)
logger.debug('created sgen %s' % new_load)
net.res_sgen.at[new_load, 'pf_p'] = p
diff --git a/pandapower/diagnostic.py b/pandapower/diagnostic.py
index c52431dc6..29a32157f 100644
--- a/pandapower/diagnostic.py
+++ b/pandapower/diagnostic.py
@@ -8,7 +8,6 @@
import pandas as pd
import numpy as np
import pandapower as pp
-from pandapower import replace_xward_by_ward
try:
import pandaplan.core.pplog as logging
@@ -21,7 +20,7 @@
from pandapower.auxiliary import (LoadflowNotConverged, OPFNotConverged, ControllerNotConverged,
NetCalculationNotConverged)
from pandapower.run import runpp
-from pandapower.toolbox import get_connected_elements
+from pandapower.toolbox import get_connected_elements, replace_xward_by_ward
from pandapower.diagnostic_reports import diagnostic_report
# separator between log messages
diff --git a/pandapower/estimation/state_estimation.py b/pandapower/estimation/state_estimation.py
index d5a7d6fce..36e49fdd6 100644
--- a/pandapower/estimation/state_estimation.py
+++ b/pandapower/estimation/state_estimation.py
@@ -333,7 +333,7 @@ def perform_chi2_test(self, v_in_out=None, delta_in_out=None,
self.logger.debug("Result of Chi^2 test:")
self.logger.debug("Number of measurements: %d" % m)
self.logger.debug("Number of state variables: %d" % n)
- self.logger.debug("Performance index: %.2f" % J)
+ self.logger.debug("Performance index: %.2f" % J.item())
self.logger.debug("Chi^2 test threshold: %.2f" % test_thresh)
if J <= test_thresh:
@@ -421,7 +421,7 @@ def perform_rn_max_test(self, v_in_out=None, delta_in_out=None,
else:
self.logger.debug(
"Largest normalized residual test failed (%.1f > %.1f)."
- % (max(rN), rn_max_threshold))
+ % (max(rN).item(), rn_max_threshold))
# Identify bad data: Determine index corresponding to max(rN):
idx_rN = np.argsort(rN, axis=0)[-1]
diff --git a/pandapower/file_io.py b/pandapower/file_io.py
index 4a56a7ac5..a864e4fbc 100644
--- a/pandapower/file_io.py
+++ b/pandapower/file_io.py
@@ -238,7 +238,7 @@ def _from_excel_old(xls):
def from_json(filename, convert=True, encryption_key=None, elements_to_deserialize=None,
keep_serialized_elements=True, add_basic_std_types=False, replace_elements=None,
- empty_dict_like_object=None):
+ empty_dict_like_object=None, ignore_unknown_objects=False):
"""
Load a pandapower network from a JSON file.
The index of the returned network is not necessarily in the same order as the original network.
@@ -270,6 +270,9 @@ def from_json(filename, convert=True, encryption_key=None, elements_to_deseriali
the data of the json string. Give another dict-like object to start filling that alternative
object with the json data.
+ **ignore_unknown_objects** (bool, False) - If set to True, ignore any objects that cannot be
+ deserialized instead of raising an error
+
OUTPUT:
**net** (dict) - The pandapower format network
@@ -294,12 +297,13 @@ def from_json(filename, convert=True, encryption_key=None, elements_to_deseriali
keep_serialized_elements=keep_serialized_elements,
add_basic_std_types=add_basic_std_types,
replace_elements=replace_elements,
- empty_dict_like_object=empty_dict_like_object)
+ empty_dict_like_object=empty_dict_like_object,
+ ignore_unknown_objects=ignore_unknown_objects)
def from_json_string(json_string, convert=False, encryption_key=None, elements_to_deserialize=None,
keep_serialized_elements=True, add_basic_std_types=False,
- replace_elements=None, empty_dict_like_object=None):
+ replace_elements=None, empty_dict_like_object=None, ignore_unknown_objects=False):
"""
Load a pandapower network from a JSON string.
The index of the returned network is not necessarily in the same order as the original network.
@@ -330,6 +334,9 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t
the data of the json string. Give another dict-like object to start filling that alternative
object with the json data.
+ **ignore_unknown_objects** (bool, False) - If set to True, ignore any objects that cannot be
+ deserialized instead of raising an error
+
OUTPUT:
**net** (dict) - The pandapower format network
@@ -347,10 +354,12 @@ def from_json_string(json_string, convert=False, encryption_key=None, elements_t
if elements_to_deserialize is None:
net = json.loads(json_string, cls=io_utils.PPJSONDecoder,
- empty_dict_like_object=empty_dict_like_object)
+ empty_dict_like_object=empty_dict_like_object,
+ ignore_unknown_objects=ignore_unknown_objects)
else:
net = json.loads(json_string, cls=io_utils.PPJSONDecoder, deserialize_pandas=False,
- empty_dict_like_object=empty_dict_like_object)
+ empty_dict_like_object=empty_dict_like_object,
+ ignore_unknown_objects=ignore_unknown_objects)
net_dummy = create_empty_network()
if ('version' not in net.keys()) | (Version(net.version) < Version('2.1.0')):
raise UserWarning('table selection is only possible for nets above version 2.0.1. '
diff --git a/pandapower/grid_equivalents/rei_generation.py b/pandapower/grid_equivalents/rei_generation.py
index 5bf5c8c81..c217776e7 100644
--- a/pandapower/grid_equivalents/rei_generation.py
+++ b/pandapower/grid_equivalents/rei_generation.py
@@ -261,7 +261,7 @@ def _create_net_zpbn(net, boundary_buses, all_internal_buses, all_external_buses
sn_mva=Sn, index=max_sgen_idx+len(net_zpbn.sgen)+1)
elif elm == "gen":
vm_pu = v[key+"_vm_total"][v.ext_bus == int(re.findall(r"\d+", busstr)[0])].values.real
- elm_idx = pp.create_gen(net_zpbn, i, float(P), float(vm_pu), name=key+"_rei_"+busstr,
+ elm_idx = pp.create_gen(net_zpbn, i, float(P), float(vm_pu.item()), name=key+"_rei_"+busstr,
sn_mva=Sn, index=max_gen_idx+len(net_zpbn.gen)+1)
# ---- match other columns
diff --git a/pandapower/io_utils.py b/pandapower/io_utils.py
index 6058b0e08..a24771a93 100644
--- a/pandapower/io_utils.py
+++ b/pandapower/io_utils.py
@@ -21,7 +21,7 @@
import pandas.errors
from deepdiff.diff import DeepDiff
from packaging.version import Version
-from pandapower import __version__
+from pandapower._version import __version__
import networkx
import numpy
import geojson
@@ -489,17 +489,18 @@ class FromSerializableRegistry():
class_name = ''
module_name = ''
- def __init__(self, obj, d, pp_hook_funct):
+ def __init__(self, obj, d, pp_hook_funct, ignore_unknown_objects=False):
self.obj = obj
self.d = d
self.pp_hook = pp_hook_funct
+ self.ignore_unknown_objects = ignore_unknown_objects
@from_serializable.register(class_name='Series', module_name='pandas.core.series')
def Series(self):
is_multiindex = self.d.pop('is_multiindex', False)
index_name = self.d.pop('index_name', None)
index_names = self.d.pop('index_names', None)
- ser = pd.read_json(self.obj, precise_float=True, **self.d)
+ ser = pd.read_json(io.StringIO(self.obj), precise_float=True, **self.d)
# restore index name and Multiindex
if index_name is not None:
@@ -577,7 +578,9 @@ def DataFrame(self):
# recreate jsoned objects
for col in ('object', 'controller'): # "controller" for backwards compatibility
if (col in df.columns):
- df[col] = df[col].apply(self.pp_hook)
+ df[col] = df[col].apply(partial(
+ self.pp_hook, ignore_unknown_objects=self.ignore_unknown_objects
+ ))
if 'geo' in df.columns:
df['geo'] = df['geo'].dropna().apply(json.dumps).apply(geojson.loads)
return df
@@ -627,12 +630,28 @@ def function(self):
@from_serializable.register()
def rest(self):
- module = importlib.import_module(self.module_name)
- class_ = getattr(module, self.class_name)
+ try:
+ module = importlib.import_module(self.module_name)
+ except ModuleNotFoundError as e:
+ if self.ignore_unknown_objects:
+ warn(f"Module {self.module_name} not found. Returning object as is.")
+ return json.loads(self.obj)
+ else:
+ raise e
+ try:
+ class_ = getattr(module, self.class_name)
+ except AttributeError as e:
+ if self.ignore_unknown_objects:
+ warn(f"Class {self.class_name} not found in module {self.module_name}. Returning object as is.")
+ return json.loads(self.obj)
+ else:
+ raise e
if isclass(class_) and issubclass(class_, JSONSerializableClass):
if isinstance(self.obj, str):
self.obj = json.loads(self.obj, cls=PPJSONDecoder,
- object_hook=pp_hook)
+ object_hook=partial(
+ pp_hook, ignore_unknown_objects=self.ignore_unknown_objects
+ ))
# backwards compatibility
if "net" in self.obj:
del self.obj["net"]
@@ -689,16 +708,18 @@ def __init__(self, **kwargs):
deserialize_pandas = kwargs.pop('deserialize_pandas', True)
empty_dict_like_object = kwargs.pop('empty_dict_like_object', None)
registry_class = kwargs.pop("registry_class", FromSerializableRegistry)
+ ignore_unknown_objects = kwargs.pop("ignore_unknown_objects", False)
super_kwargs = {"object_hook": partial(pp_hook,
deserialize_pandas=deserialize_pandas,
empty_dict_like_object=empty_dict_like_object,
- registry_class=registry_class)}
+ registry_class=registry_class,
+ ignore_unknown_objects=ignore_unknown_objects)}
super_kwargs.update(kwargs)
super().__init__(**super_kwargs)
def pp_hook(d, deserialize_pandas=True, empty_dict_like_object=None,
- registry_class=FromSerializableRegistry):
+ registry_class=FromSerializableRegistry, ignore_unknown_objects=False):
try:
if '_module' in d and '_class' in d:
if 'pandas' in d['_module'] and not deserialize_pandas:
@@ -713,7 +734,8 @@ def pp_hook(d, deserialize_pandas=True, empty_dict_like_object=None,
else:
# obj = {"_init": d, "_state": dict()} # backwards compatibility
obj = {key: val for key, val in d.items() if key not in ['_module', '_class']}
- fs = registry_class(obj, d, pp_hook)
+ fs = registry_class(obj, d, pp_hook, ignore_unknown_objects)
+
fs.class_name = d.pop('_class', '')
fs.module_name = d.pop('_module', '')
fs.empty_dict_like_object = empty_dict_like_object
diff --git a/pandapower/networks/ieee_europen_lv_asymmetric.py b/pandapower/networks/ieee_europen_lv_asymmetric.py
index 14292bd70..24a9f996d 100644
--- a/pandapower/networks/ieee_europen_lv_asymmetric.py
+++ b/pandapower/networks/ieee_europen_lv_asymmetric.py
@@ -5,7 +5,7 @@
import os
import pandapower as pp
-from pandapower import pp_dir
+from pandapower.__init__ import pp_dir
def ieee_european_lv_asymmetric(scenario="on_peak_566", **kwargs):
diff --git a/pandapower/networks/lv_schutterwald.py b/pandapower/networks/lv_schutterwald.py
index 714ba6e63..01839e84c 100644
--- a/pandapower/networks/lv_schutterwald.py
+++ b/pandapower/networks/lv_schutterwald.py
@@ -9,7 +9,7 @@
import pandapower as pp
import pandapower.topology as top
import pandapower.plotting.geo as geo
-from pandapower import pp_dir
+from pandapower.__init__ import pp_dir
def lv_schutterwald(separation_by_sub=False, include_heat_pumps=False, **kwargs):
diff --git a/pandapower/networks/mv_oberrhein.py b/pandapower/networks/mv_oberrhein.py
index 4b566f549..c43abe314 100644
--- a/pandapower/networks/mv_oberrhein.py
+++ b/pandapower/networks/mv_oberrhein.py
@@ -10,8 +10,7 @@
import pandapower as pp
import pandapower.topology as top
-import pandapower.plotting.geo as geo
-from pandapower import pp_dir
+from pandapower.__init__ import pp_dir
def mv_oberrhein(scenario="load", cosphi_load=0.98, cosphi_pv=1.0, include_substations=False,
diff --git a/pandapower/networks/power_system_test_cases.py b/pandapower/networks/power_system_test_cases.py
index 4854ee107..596ea0381 100644
--- a/pandapower/networks/power_system_test_cases.py
+++ b/pandapower/networks/power_system_test_cases.py
@@ -8,7 +8,8 @@
import pandapower as pp
import pandapower.toolbox
-from pandapower import pp_dir
+from pandapower.file_io import from_json
+from pandapower.__init__ import pp_dir
import pandapower.plotting.geo as geo
@@ -61,7 +62,7 @@ def _change_ref_bus(net, ref_bus_idx, ext_grid_p=0):
def sorted_from_json(path, **kwargs):
- net = pp.from_json(path, **kwargs)
+ net = from_json(path, **kwargs)
for elm in pandapower.toolbox.pp_elements():
net[elm].sort_index(inplace=True)
return net
diff --git a/pandapower/networks/synthetic_voltage_control_lv_networks.py b/pandapower/networks/synthetic_voltage_control_lv_networks.py
index 6523cab36..c1b7edb71 100644
--- a/pandapower/networks/synthetic_voltage_control_lv_networks.py
+++ b/pandapower/networks/synthetic_voltage_control_lv_networks.py
@@ -3,10 +3,10 @@
# Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics
# and Energy System Technology (IEE), Kassel. All rights reserved.
-import io
import pandapower as pp
import pandas as pd
from numpy import nan, append
+from geojson import Point, dumps
def create_synthetic_voltage_control_lv_network(network_class="rural_1"):
@@ -187,13 +187,94 @@ def create_synthetic_voltage_control_lv_network(network_class="rural_1"):
# set bus geo data
bus_geo = {
- "rural_1": '{"x":{"0":0.0,"1":0.0,"2":-1.6666666667,"3":-1.6666666667,"4":-0.1666666667,"5":-0.6666666667,"6":-1.1666666667,"7":-1.6666666667,"8":0.3333333333,"9":-0.1666666667,"10":-0.6666666667,"11":-1.6666666667,"12":1.8333333333,"13":1.3333333333,"14":0.8333333333,"15":0.3333333333,"16":-0.1666666667,"17":-0.6666666667,"18":-1.1666666667,"19":2.3333333333,"20":1.8333333333,"21":1.3333333333,"22":0.8333333333,"23":0.3333333333,"24":-0.1666666667,"25":-1.1666666667},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":2.0,"5":3.0,"6":4.0,"7":5.0,"8":3.0,"9":4.0,"10":5.0,"11":6.0,"12":2.0,"13":3.0,"14":4.0,"15":5.0,"16":6.0,"17":7.0,"18":8.0,"19":3.0,"20":4.0,"21":5.0,"22":6.0,"23":7.0,"24":8.0,"25":9.0}}',
- "rural_2": '{"x":{"0":0.0,"1":0.0,"2":-2.5,"3":-2.5,"4":-1.0,"5":-1.5,"6":-2.0,"7":-0.5,"8":-1.0,"9":-2.0,"10":1.0,"11":0.5,"12":0.0,"13":1.5,"14":1.0,"15":0.0,"16":2.5,"17":2.5},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":2.0,"5":3.0,"6":4.0,"7":3.0,"8":4.0,"9":5.0,"10":2.0,"11":3.0,"12":4.0,"13":3.0,"14":4.0,"15":5.0,"16":2.0,"17":3.0}}',
- "village_1": '{"x":{"0":0.0,"1":0.0,"2":-3.0,"3":-3.5,"4":-4.0,"5":-4.5,"6":-5.0,"7":-5.5,"8":-6.0,"9":-6.5,"10":-7.0,"11":-2.5,"12":-3.0,"13":-3.5,"14":-4.0,"15":-4.5,"16":-5.0,"17":-5.5,"18":-6.0,"19":-7.0,"20":-1.0,"21":-1.5,"22":-2.0,"23":-2.5,"24":-3.0,"25":-3.5,"26":-4.0,"27":-4.5,"28":-5.0,"29":-5.5,"30":-6.0,"31":-6.5,"32":-7.0,"33":-7.5,"34":-8.0,"35":-8.5,"36":-0.5,"37":-1.0,"38":-1.5,"39":-2.0,"40":-2.5,"41":-3.0,"42":-3.5,"43":-4.0,"44":-4.5,"45":-5.0,"46":-5.5,"47":-6.0,"48":-6.5,"49":-7.0,"50":-7.5,"51":-8.5,"52":1.0,"53":0.5,"54":0.0,"55":-0.5,"56":-1.0,"57":1.5,"58":1.0,"59":0.5,"60":0.0,"61":-1.0,"62":3.0,"63":2.5,"64":2.0,"65":1.5,"66":1.0,"67":0.5,"68":0.0,"69":-0.5,"70":-1.0,"71":3.5,"72":3.0,"73":2.5,"74":2.0,"75":1.5,"76":1.0,"77":0.5,"78":0.0,"79":-1.0},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":14.0,"33":15.0,"34":16.0,"35":17.0,"36":3.0,"37":4.0,"38":5.0,"39":6.0,"40":7.0,"41":8.0,"42":9.0,"43":10.0,"44":11.0,"45":12.0,"46":13.0,"47":14.0,"48":15.0,"49":16.0,"50":17.0,"51":18.0,"52":2.0,"53":3.0,"54":4.0,"55":5.0,"56":6.0,"57":3.0,"58":4.0,"59":5.0,"60":6.0,"61":7.0,"62":2.0,"63":3.0,"64":4.0,"65":5.0,"66":6.0,"67":7.0,"68":8.0,"69":9.0,"70":10.0,"71":3.0,"72":4.0,"73":5.0,"74":6.0,"75":7.0,"76":8.0,"77":9.0,"78":10.0,"79":11.0}}',
- "village_2": '{"x":{"0":0.0,"1":0.0,"2":-3.0,"3":-3.5,"4":-4.0,"5":-4.5,"6":-5.0,"7":-5.5,"8":-6.0,"9":-6.5,"10":-7.0,"11":-2.5,"12":-3.0,"13":-3.5,"14":-4.0,"15":-4.5,"16":-5.0,"17":-5.5,"18":-6.0,"19":-7.0,"20":-1.0,"21":-1.5,"22":-2.0,"23":-2.5,"24":-3.0,"25":-3.5,"26":-4.0,"27":-4.5,"28":-5.0,"29":-5.5,"30":-6.0,"31":-6.5,"32":-0.5,"33":-1.0,"34":-1.5,"35":-2.0,"36":-2.5,"37":-3.0,"38":-3.5,"39":-4.0,"40":-4.5,"41":-5.0,"42":-5.5,"43":-6.5,"44":1.0,"45":0.5,"46":0.0,"47":-0.5,"48":-1.0,"49":1.5,"50":1.0,"51":0.5,"52":0.0,"53":-1.0,"54":3.0,"55":2.5,"56":2.0,"57":1.5,"58":1.0,"59":0.5,"60":0.0,"61":-0.5,"62":-1.0,"63":-1.5,"64":3.5,"65":3.0,"66":2.5,"67":2.0,"68":1.5,"69":1.0,"70":0.5,"71":0.0,"72":-0.5,"73":-1.5},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":3.0,"33":4.0,"34":5.0,"35":6.0,"36":7.0,"37":8.0,"38":9.0,"39":10.0,"40":11.0,"41":12.0,"42":13.0,"43":14.0,"44":2.0,"45":3.0,"46":4.0,"47":5.0,"48":6.0,"49":3.0,"50":4.0,"51":5.0,"52":6.0,"53":7.0,"54":2.0,"55":3.0,"56":4.0,"57":5.0,"58":6.0,"59":7.0,"60":8.0,"61":9.0,"62":10.0,"63":11.0,"64":3.0,"65":4.0,"66":5.0,"67":6.0,"68":7.0,"69":8.0,"70":9.0,"71":10.0,"72":11.0,"73":12.0}}',
- "suburb_1": '{"x":{"0":0.0,"1":0.0,"2":-9.5,"3":-10.0,"4":-10.5,"5":-11.0,"6":-11.5,"7":-12.0,"8":-12.5,"9":-13.0,"10":-13.5,"11":-9.0,"12":-9.5,"13":-10.0,"14":-10.5,"15":-11.0,"16":-11.5,"17":-12.0,"18":-12.5,"19":-13.5,"20":-7.5,"21":-8.0,"22":-8.5,"23":-9.0,"24":-9.5,"25":-10.0,"26":-10.5,"27":-11.0,"28":-11.5,"29":-12.0,"30":-12.5,"31":-13.0,"32":-13.5,"33":-14.0,"34":-14.5,"35":-15.0,"36":-15.5,"37":-7.0,"38":-7.5,"39":-8.0,"40":-8.5,"41":-9.0,"42":-9.5,"43":-10.0,"44":-10.5,"45":-11.0,"46":-11.5,"47":-12.0,"48":-12.5,"49":-13.0,"50":-13.5,"51":-14.0,"52":-14.5,"53":-15.5,"54":-5.5,"55":-6.0,"56":-6.5,"57":-7.0,"58":-7.5,"59":-5.0,"60":-5.5,"61":-6.0,"62":-6.5,"63":-7.5,"64":-3.5,"65":-4.0,"66":-4.5,"67":-5.0,"68":-5.5,"69":-6.0,"70":-6.5,"71":-7.0,"72":-7.5,"73":-8.0,"74":-8.5,"75":-9.0,"76":-9.5,"77":-3.0,"78":-3.5,"79":-4.0,"80":-4.5,"81":-5.0,"82":-5.5,"83":-6.0,"84":-6.5,"85":-7.0,"86":-7.5,"87":-8.0,"88":-8.5,"89":-9.5,"90":-1.5,"91":-2.0,"92":-2.5,"93":-3.0,"94":-3.5,"95":-4.0,"96":-4.5,"97":-5.0,"98":-1.0,"99":-1.5,"100":-2.0,"101":-2.5,"102":-3.0,"103":-3.5,"104":-4.0,"105":-5.0,"106":0.0,"107":0.0,"108":1.5,"109":1.0,"110":0.5,"111":0.0,"112":-0.5,"113":-1.0,"114":-1.5,"115":-2.0,"116":-2.5,"117":2.0,"118":1.5,"119":1.0,"120":0.5,"121":0.0,"122":-0.5,"123":-1.0,"124":-1.5,"125":-2.5,"126":3.5,"127":3.0,"128":2.5,"129":2.0,"130":1.5,"131":1.0,"132":0.5,"133":0.0,"134":-0.5,"135":-1.0,"136":-1.5,"137":-2.0,"138":-2.5,"139":-3.0,"140":-3.5,"141":-4.0,"142":-4.5,"143":4.0,"144":3.5,"145":3.0,"146":2.5,"147":2.0,"148":1.5,"149":1.0,"150":0.5,"151":0.0,"152":-0.5,"153":-1.0,"154":-1.5,"155":-2.0,"156":-2.5,"157":-3.0,"158":-3.5,"159":-4.5,"160":5.5,"161":5.0,"162":4.5,"163":4.0,"164":3.5,"165":6.0,"166":5.5,"167":5.0,"168":4.5,"169":3.5,"170":7.5,"171":7.0,"172":6.5,"173":6.0,"174":5.5,"175":5.0,"176":4.5,"177":4.0,"178":3.5,"179":3.0,"180":2.5,"181":2.0,"182":1.5,"183":8.0,"184":7.5,"185":7.0,"186":6.5,"187":6.0,"188":5.5,"189":5.0,"190":4.5,"191":4.0,"192":3.5,"193":3.0,"194":2.5,"195":1.5,"196":9.5,"197":9.0,"198":8.5,"199":8.0,"200":10.0,"201":9.5,"202":9.0,"203":8.0},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":14.0,"33":15.0,"34":16.0,"35":17.0,"36":18.0,"37":3.0,"38":4.0,"39":5.0,"40":6.0,"41":7.0,"42":8.0,"43":9.0,"44":10.0,"45":11.0,"46":12.0,"47":13.0,"48":14.0,"49":15.0,"50":16.0,"51":17.0,"52":18.0,"53":19.0,"54":2.0,"55":3.0,"56":4.0,"57":5.0,"58":6.0,"59":3.0,"60":4.0,"61":5.0,"62":6.0,"63":7.0,"64":2.0,"65":3.0,"66":4.0,"67":5.0,"68":6.0,"69":7.0,"70":8.0,"71":9.0,"72":10.0,"73":11.0,"74":12.0,"75":13.0,"76":14.0,"77":3.0,"78":4.0,"79":5.0,"80":6.0,"81":7.0,"82":8.0,"83":9.0,"84":10.0,"85":11.0,"86":12.0,"87":13.0,"88":14.0,"89":15.0,"90":2.0,"91":3.0,"92":4.0,"93":5.0,"94":6.0,"95":7.0,"96":8.0,"97":9.0,"98":3.0,"99":4.0,"100":5.0,"101":6.0,"102":7.0,"103":8.0,"104":9.0,"105":10.0,"106":2.0,"107":3.0,"108":2.0,"109":3.0,"110":4.0,"111":5.0,"112":6.0,"113":7.0,"114":8.0,"115":9.0,"116":10.0,"117":3.0,"118":4.0,"119":5.0,"120":6.0,"121":7.0,"122":8.0,"123":9.0,"124":10.0,"125":11.0,"126":2.0,"127":3.0,"128":4.0,"129":5.0,"130":6.0,"131":7.0,"132":8.0,"133":9.0,"134":10.0,"135":11.0,"136":12.0,"137":13.0,"138":14.0,"139":15.0,"140":16.0,"141":17.0,"142":18.0,"143":3.0,"144":4.0,"145":5.0,"146":6.0,"147":7.0,"148":8.0,"149":9.0,"150":10.0,"151":11.0,"152":12.0,"153":13.0,"154":14.0,"155":15.0,"156":16.0,"157":17.0,"158":18.0,"159":19.0,"160":2.0,"161":3.0,"162":4.0,"163":5.0,"164":6.0,"165":3.0,"166":4.0,"167":5.0,"168":6.0,"169":7.0,"170":2.0,"171":3.0,"172":4.0,"173":5.0,"174":6.0,"175":7.0,"176":8.0,"177":9.0,"178":10.0,"179":11.0,"180":12.0,"181":13.0,"182":14.0,"183":3.0,"184":4.0,"185":5.0,"186":6.0,"187":7.0,"188":8.0,"189":9.0,"190":10.0,"191":11.0,"192":12.0,"193":13.0,"194":14.0,"195":15.0,"196":2.0,"197":3.0,"198":4.0,"199":5.0,"200":3.0,"201":4.0,"202":5.0,"203":6.0}}'
+ "rural_1": {0: [0.0, 0.0], 1: [0.0, 1.0], 2: [-1.6666666667, 2.0], 3: [-1.6666666667, 3.0],
+ 4: [-0.1666666667, 2.0], 5: [-0.6666666667, 3.0], 6: [-1.1666666667, 4.0], 7: [-1.6666666667, 5.0],
+ 8: [0.3333333333, 3.0], 9: [-0.1666666667, 4.0], 10: [-0.6666666667, 5.0], 11: [-1.6666666667, 6.0],
+ 12: [1.8333333333, 2.0], 13: [1.3333333333, 3.0], 14: [0.8333333333, 4.0], 15: [0.3333333333, 5.0],
+ 16: [-0.1666666667, 6.0], 17: [-0.6666666667, 7.0], 18: [-1.1666666667, 8.0],
+ 19: [2.3333333333, 3.0], 20: [1.8333333333, 4.0], 21: [1.3333333333, 5.0], 22: [0.8333333333, 6.0],
+ 23: [0.3333333333, 7.0], 24: [-0.1666666667, 8.0], 25: [-1.1666666667, 9.0]
+ },
+ "rural_2": {0: [0.0, 0.0], 1: [0.0, 1.0], 2: [-2.5, 2.0], 3: [-2.5, 3.0], 4: [-1.0, 2.0], 5: [-1.5, 3.0],
+ 6: [-2.0, 4.0], 7: [-0.5, 3.0], 8: [-1.0, 4.0], 9: [-2.0, 5.0], 10: [1.0, 2.0], 11: [0.5, 3.0],
+ 12: [0.0, 4.0], 13: [1.5, 3.0], 14: [1.0, 4.0], 15: [0.0, 5.0], 16: [2.5, 2.0], 17: [2.5, 3.0]
+ },
+ "village_1": {0: [0.0, 0.0], 1: [0.0, 1.0], 2: [-3.0, 2.0], 3: [-3.5, 3.0], 4: [-4.0, 4.0], 5: [-4.5, 5.0],
+ 6: [-5.0, 6.0], 7: [-5.5, 7.0], 8: [-6.0, 8.0], 9: [-6.5, 9.0], 10: [-7.0, 10.0], 11: [-2.5, 3.0],
+ 12: [-3.0, 4.0], 13: [-3.5, 5.0], 14: [-4.0, 6.0], 15: [-4.5, 7.0], 16: [-5.0, 8.0],
+ 17: [-5.5, 9.0], 18: [-6.0, 10.0], 19: [-7.0, 11.0], 20: [-1.0, 2.0], 21: [-1.5, 3.0],
+ 22: [-2.0, 4.0], 23: [-2.5, 5.0], 24: [-3.0, 6.0], 25: [-3.5, 7.0], 26: [-4.0, 8.0],
+ 27: [-4.5, 9.0], 28: [-5.0, 10.0], 29: [-5.5, 11.0], 30: [-6.0, 12.0], 31: [-6.5, 13.0],
+ 32: [-7.0, 14.0], 33: [-7.5, 15.0], 34: [-8.0, 16.0], 35: [-8.5, 17.0], 36: [-0.5, 3.0],
+ 37: [-1.0, 4.0], 38: [-1.5, 5.0], 39: [-2.0, 6.0], 40: [-2.5, 7.0], 41: [-3.0, 8.0],
+ 42: [-3.5, 9.0], 43: [-4.0, 10.0], 44: [-4.5, 11.0], 45: [-5.0, 12.0], 46: [-5.5, 13.0],
+ 47: [-6.0, 14.0], 48: [-6.5, 15.0], 49: [-7.0, 16.0], 50: [-7.5, 17.0], 51: [-8.5, 18.0],
+ 52: [1.0, 2.0], 53: [0.5, 3.0], 54: [0.0, 4.0], 55: [-0.5, 5.0], 56: [-1.0, 6.0], 57: [1.5, 3.0],
+ 58: [1.0, 4.0], 59: [0.5, 5.0], 60: [0.0, 6.0], 61: [-1.0, 7.0], 62: [3.0, 2.0], 63: [2.5, 3.0],
+ 64: [2.0, 4.0], 65: [1.5, 5.0], 66: [1.0, 6.0], 67: [0.5, 7.0], 68: [0.0, 8.0], 69: [-0.5, 9.0],
+ 70: [-1.0, 10.0], 71: [3.5, 3.0], 72: [3.0, 4.0], 73: [2.5, 5.0], 74: [2.0, 6.0], 75: [1.5, 7.0],
+ 76: [1.0, 8.0], 77: [0.5, 9.0], 78: [0.0, 10.0], 79: [-1.0, 11.0]
+ },
+ "village_2": {0: [0.0, 0.0], 1: [0.0, 1.0], 2: [-3.0, 2.0], 3: [-3.5, 3.0], 4: [-4.0, 4.0], 5: [-4.5, 5.0],
+ 6: [-5.0, 6.0], 7: [-5.5, 7.0], 8: [-6.0, 8.0], 9: [-6.5, 9.0], 10: [-7.0, 10.0], 11: [-2.5, 3.0],
+ 12: [-3.0, 4.0], 13: [-3.5, 5.0], 14: [-4.0, 6.0], 15: [-4.5, 7.0], 16: [-5.0, 8.0],
+ 17: [-5.5, 9.0], 18: [-6.0, 10.0], 19: [-7.0, 11.0], 20: [-1.0, 2.0], 21: [-1.5, 3.0],
+ 22: [-2.0, 4.0], 23: [-2.5, 5.0], 24: [-3.0, 6.0], 25: [-3.5, 7.0], 26: [-4.0, 8.0],
+ 27: [-4.5, 9.0], 28: [-5.0, 10.0], 29: [-5.5, 11.0], 30: [-6.0, 12.0], 31: [-6.5, 13.0],
+ 32: [-0.5, 3.0], 33: [-1.0, 4.0], 34: [-1.5, 5.0], 35: [-2.0, 6.0], 36: [-2.5, 7.0],
+ 37: [-3.0, 8.0], 38: [-3.5, 9.0], 39: [-4.0, 10.0], 40: [-4.5, 11.0], 41: [-5.0, 12.0],
+ 42: [-5.5, 13.0], 43: [-6.5, 14.0], 44: [1.0, 2.0], 45: [0.5, 3.0], 46: [0.0, 4.0],
+ 47: [-0.5, 5.0], 48: [-1.0, 6.0], 49: [1.5, 3.0], 50: [1.0, 4.0], 51: [0.5, 5.0], 52: [0.0, 6.0],
+ 53: [-1.0, 7.0], 54: [3.0, 2.0], 55: [2.5, 3.0], 56: [2.0, 4.0], 57: [1.5, 5.0], 58: [1.0, 6.0],
+ 59: [0.5, 7.0], 60: [0.0, 8.0], 61: [-0.5, 9.0], 62: [-1.0, 10.0], 63: [-1.5, 11.0],
+ 64: [3.5, 3.0], 65: [3.0, 4.0], 66: [2.5, 5.0], 67: [2.0, 6.0], 68: [1.5, 7.0], 69: [1.0, 8.0],
+ 70: [0.5, 9.0], 71: [0.0, 10.0], 72: [-0.5, 11.0], 73: [-1.5, 12.0]
+ },
+ "suburb_1": {0: [0.0, 0.0], 1: [0.0, 1.0], 2: [-9.5, 2.0], 3: [-10.0, 3.0], 4: [-10.5, 4.0], 5: [-11.0, 5.0],
+ 6: [-11.5, 6.0], 7: [-12.0, 7.0], 8: [-12.5, 8.0], 9: [-13.0, 9.0], 10: [-13.5, 10.0],
+ 11: [-9.0, 3.0], 12: [-9.5, 4.0], 13: [-10.0, 5.0], 14: [-10.5, 6.0], 15: [-11.0, 7.0],
+ 16: [-11.5, 8.0], 17: [-12.0, 9.0], 18: [-12.5, 10.0], 19: [-13.5, 11.0], 20: [-7.5, 2.0],
+ 21: [-8.0, 3.0], 22: [-8.5, 4.0], 23: [-9.0, 5.0], 24: [-9.5, 6.0], 25: [-10.0, 7.0],
+ 26: [-10.5, 8.0], 27: [-11.0, 9.0], 28: [-11.5, 10.0], 29: [-12.0, 11.0], 30: [-12.5, 12.0],
+ 31: [-13.0, 13.0], 32: [-13.5, 14.0], 33: [-14.0, 15.0], 34: [-14.5, 16.0], 35: [-15.0, 17.0],
+ 36: [-15.5, 18.0], 37: [-7.0, 3.0], 38: [-7.5, 4.0], 39: [-8.0, 5.0], 40: [-8.5, 6.0],
+ 41: [-9.0, 7.0], 42: [-9.5, 8.0], 43: [-10.0, 9.0], 44: [-10.5, 10.0], 45: [-11.0, 11.0],
+ 46: [-11.5, 12.0], 47: [-12.0, 13.0], 48: [-12.5, 14.0], 49: [-13.0, 15.0], 50: [-13.5, 16.0],
+ 51: [-14.0, 17.0], 52: [-14.5, 18.0], 53: [-15.5, 19.0], 54: [-5.5, 2.0], 55: [-6.0, 3.0],
+ 56: [-6.5, 4.0], 57: [-7.0, 5.0], 58: [-7.5, 6.0], 59: [-5.0, 3.0], 60: [-5.5, 4.0],
+ 61: [-6.0, 5.0], 62: [-6.5, 6.0], 63: [-7.5, 7.0], 64: [-3.5, 2.0], 65: [-4.0, 3.0],
+ 66: [-4.5, 4.0], 67: [-5.0, 5.0], 68: [-5.5, 6.0], 69: [-6.0, 7.0], 70: [-6.5, 8.0],
+ 71: [-7.0, 9.0], 72: [-7.5, 10.0], 73: [-8.0, 11.0], 74: [-8.5, 12.0], 75: [-9.0, 13.0],
+ 76: [-9.5, 14.0], 77: [-3.0, 3.0], 78: [-3.5, 4.0], 79: [-4.0, 5.0], 80: [-4.5, 6.0],
+ 81: [-5.0, 7.0], 82: [-5.5, 8.0], 83: [-6.0, 9.0], 84: [-6.5, 10.0], 85: [-7.0, 11.0],
+ 86: [-7.5, 12.0], 87: [-8.0, 13.0], 88: [-8.5, 14.0], 89: [-9.5, 15.0], 90: [-1.5, 2.0],
+ 91: [-2.0, 3.0], 92: [-2.5, 4.0], 93: [-3.0, 5.0], 94: [-3.5, 6.0], 95: [-4.0, 7.0],
+ 96: [-4.5, 8.0], 97: [-5.0, 9.0], 98: [-1.0, 3.0], 99: [-1.5, 4.0], 100: [-2.0, 5.0],
+ 101: [-2.5, 6.0], 102: [-3.0, 7.0], 103: [-3.5, 8.0], 104: [-4.0, 9.0], 105: [-5.0, 10.0],
+ 106: [0.0, 2.0], 107: [0.0, 3.0], 108: [1.5, 2.0], 109: [1.0, 3.0], 110: [0.5, 4.0],
+ 111: [0.0, 5.0], 112: [-0.5, 6.0], 113: [-1.0, 7.0], 114: [-1.5, 8.0], 115: [-2.0, 9.0],
+ 116: [-2.5, 10.0], 117: [2.0, 3.0], 118: [1.5, 4.0], 119: [1.0, 5.0], 120: [0.5, 6.0],
+ 121: [0.0, 7.0], 122: [-0.5, 8.0], 123: [-1.0, 9.0], 124: [-1.5, 10.0], 125: [-2.5, 11.0],
+ 126: [3.5, 2.0], 127: [3.0, 3.0], 128: [2.5, 4.0], 129: [2.0, 5.0], 130: [1.5, 6.0],
+ 131: [1.0, 7.0], 132: [0.5, 8.0], 133: [0.0, 9.0], 134: [-0.5, 10.0], 135: [-1.0, 11.0],
+ 136: [-1.5, 12.0], 137: [-2.0, 13.0], 138: [-2.5, 14.0], 139: [-3.0, 15.0], 140: [-3.5, 16.0],
+ 141: [-4.0, 17.0], 142: [-4.5, 18.0], 143: [4.0, 3.0], 144: [3.5, 4.0], 145: [3.0, 5.0],
+ 146: [2.5, 6.0], 147: [2.0, 7.0], 148: [1.5, 8.0], 149: [1.0, 9.0], 150: [0.5, 10.0],
+ 151: [0.0, 11.0], 152: [-0.5, 12.0], 153: [-1.0, 13.0], 154: [-1.5, 14.0], 155: [-2.0, 15.0],
+ 156: [-2.5, 16.0], 157: [-3.0, 17.0], 158: [-3.5, 18.0], 159: [-4.5, 19.0], 160: [5.5, 2.0],
+ 161: [5.0, 3.0], 162: [4.5, 4.0], 163: [4.0, 5.0], 164: [3.5, 6.0], 165: [6.0, 3.0],
+ 166: [5.5, 4.0], 167: [5.0, 5.0], 168: [4.5, 6.0], 169: [3.5, 7.0], 170: [7.5, 2.0],
+ 171: [7.0, 3.0], 172: [6.5, 4.0], 173: [6.0, 5.0], 174: [5.5, 6.0], 175: [5.0, 7.0],
+ 176: [4.5, 8.0], 177: [4.0, 9.0], 178: [3.5, 10.0], 179: [3.0, 11.0], 180: [2.5, 12.0],
+ 181: [2.0, 13.0], 182: [1.5, 14.0], 183: [8.0, 3.0], 184: [7.5, 4.0], 185: [7.0, 5.0],
+ 186: [6.5, 6.0], 187: [6.0, 7.0], 188: [5.5, 8.0], 189: [5.0, 9.0], 190: [4.5, 10.0],
+ 191: [4.0, 11.0], 192: [3.5, 12.0], 193: [3.0, 13.0], 194: [2.5, 14.0], 195: [1.5, 15.0],
+ 196: [9.5, 2.0], 197: [9.0, 3.0], 198: [8.5, 4.0], 199: [8.0, 5.0], 200: [10.0, 3.0],
+ 201: [9.5, 4.0], 202: [9.0, 5.0], 203: [8.0, 6.0]
+ }
}
- net.bus_geodata = pd.read_json(io.StringIO(bus_geo[network_class]))
- # Match bus.index
- net.bus_geodata = net.bus_geodata.loc[net.bus.index]
+ net.bus.geo = net.bus.apply(
+ lambda row: dumps(Point(bus_geo[network_class][row.name])),
+ axis=1
+ )
return net
diff --git a/pandapower/pd2ppc.py b/pandapower/pd2ppc.py
index 6992dc378..c72577a99 100644
--- a/pandapower/pd2ppc.py
+++ b/pandapower/pd2ppc.py
@@ -93,7 +93,7 @@ def _check_slack_at_vsc_bus(ppci):
"this configuration is not implemented.")
-def _pd2ppc(net, sequence=None):
+def _pd2ppc(net, sequence=None, **kwargs):
"""
Converter Flow:
1. Create an empty pypower datatructure
@@ -153,8 +153,10 @@ def _pd2ppc(net, sequence=None):
# Calculates ppc0 branch impedances from branch elements
_build_branch_ppc_zero(net, ppc)
else:
+ # get config if trafo3w vk and vkr values should be recalculated
+ update_vk_values = kwargs.get("update_vk_values", True)
# Calculates ppc1/ppc2 branch impedances from branch elements
- _build_branch_ppc(net, ppc)
+ _build_branch_ppc(net, ppc, update_vk_values)
_build_branch_dc_ppc(net, ppc)
_build_tcsc_ppc(net, ppc, mode)
diff --git a/pandapower/pd2ppc_zero.py b/pandapower/pd2ppc_zero.py
index 8be6f32d2..e34ce4f90 100644
--- a/pandapower/pd2ppc_zero.py
+++ b/pandapower/pd2ppc_zero.py
@@ -11,7 +11,7 @@
from itertools import product
import pandapower.auxiliary as aux
-from pandapower import DC_NONE, DC_BUS_TYPE
+from pandapower.pypower.idx_bus_dc import DC_NONE, DC_BUS_TYPE
from pandapower.build_bus import _build_bus_ppc, _build_svc_ppc, _build_ssc_ppc, _build_vsc_ppc, _build_bus_dc_ppc
from pandapower.build_gen import _build_gen_ppc
# from pandapower.pd2ppc import _ppc2ppci, _init_ppc
diff --git a/pandapower/pf/run_bfswpf.py b/pandapower/pf/run_bfswpf.py
index 2f077ba8a..e73cafad7 100644
--- a/pandapower/pf/run_bfswpf.py
+++ b/pandapower/pf/run_bfswpf.py
@@ -73,8 +73,8 @@ def _make_bibc_bcbv(bus, branch, graph):
# if multiple networks get subnetwork branches
if norefs > 1:
- branches_sub_mask = (np.in1d(branches_arr[:, 0], buses_ordered_bfs) &
- np.in1d(branches_arr[:, 1], buses_ordered_bfs))
+ branches_sub_mask = (np.isin(branches_arr[:, 0], buses_ordered_bfs) &
+ np.isin(branches_arr[:, 1], buses_ordered_bfs))
branches = np.sort(branches_arr[branches_sub_mask, :], axis=1)
else:
branches = np.sort(branches_arr, axis=1)
@@ -252,7 +252,7 @@ def _bfswpf(DLF, bus, gen, branch, baseMVA, Ybus, Sbus, V0, ref, pv, pq, buses_o
Ysh = _makeYsh_bfsw(bus, branch, baseMVA)
# detect generators on PV buses which have status ON
- gen_pv = np.in1d(gen[:, GEN_BUS], pv) & (gen[:, GEN_STATUS] > 0)
+ gen_pv = np.isin(gen[:, GEN_BUS], pv) & (gen[:, GEN_STATUS] > 0)
qg_lim = np.zeros(ngen, dtype=bool) # initialize generators which violated Q limits
Iinj = np.conj(Sbus / V0) - Ysh * V0 # Initial current injections
diff --git a/pandapower/plotting/collections.py b/pandapower/plotting/collections.py
index 02674e4b5..e060c1d2c 100644
--- a/pandapower/plotting/collections.py
+++ b/pandapower/plotting/collections.py
@@ -36,8 +36,7 @@
class TextPath: # so that the test does not fail
pass
-from pandapower import pandapowerNet
-from pandapower.auxiliary import soft_dependency_error
+from pandapower.auxiliary import soft_dependency_error, pandapowerNet
from pandapower.plotting.patch_makers import load_patches, node_patches, gen_patches, \
sgen_patches, ext_grid_patches, trafo_patches, storage_patches, ward_patches, xward_patches, vsc_patches
from pandapower.plotting.plotting_toolbox import _rotate_dim2, coords_from_node_geodata, \
@@ -552,7 +551,7 @@ def create_line_collection(net: pandapowerNet, lines=None,
node_geodata=net.bus.geo,
table_name="line",
node_name="bus",
- ignore_zero_length=True)
+ ignore_no_geo_diff=True)
line_geodata = line_geodata.combine_first(pd.Series(geos, index=line_index_successful))
diff --git a/pandapower/plotting/geo.py b/pandapower/plotting/geo.py
index 36e673201..52926f3d1 100644
--- a/pandapower/plotting/geo.py
+++ b/pandapower/plotting/geo.py
@@ -18,7 +18,7 @@
from numpy import array
import pandapower
-from pandapower.auxiliary import soft_dependency_error
+from pandapower.auxiliary import soft_dependency_error, pandapowerNet
# get logger (same as in simple_plot)
try:
@@ -231,7 +231,7 @@ def convert_epsg_bus_geodata(net, epsg_in=4326, epsg_out=31467):
return net
-def convert_crs(net: pandapower.pandapowerNet or 'pandapipes.pandapipesNet', epsg_in=4326, epsg_out=31467):
+def convert_crs(net: pandapowerNet or 'pandapipes.pandapipesNet', epsg_in=4326, epsg_out=31467):
"""
This function works for pandapowerNet and pandapipesNet. Documentation will refer to names from pandapower.
Converts bus and line geodata in net from epsg_in to epsg_out
@@ -285,7 +285,7 @@ def _geo_branch_transformer(r):
def dump_to_geojson(
- net: pandapower.pandapowerNet or 'pandapipes.pandapipesNet',
+ net: pandapowerNet or 'pandapipes.pandapipesNet',
nodes: Union[bool, List[int]] = False,
branches: Union[bool, List[int]] = False,
switches: Union[bool, List[int]] = False,
@@ -501,7 +501,7 @@ def update_props(r: pd.Series) -> None:
def convert_geodata_to_geojson(
- net: pandapower.pandapowerNet or 'pandapipes.pandapipesNet',
+ net: pandapowerNet or 'pandapipes.pandapipesNet',
delete: bool = True,
lonlat: bool = False) -> None:
"""
@@ -566,7 +566,7 @@ def convert_geodata_to_geojson(
def convert_gis_to_geojson(
- net: pandapower.pandapowerNet or 'pandapipes.pandapipesNet',
+ net: pandapowerNet or 'pandapipes.pandapipesNet',
delete: bool = True) -> None:
"""
Transforms the bus and line geodataframes of a net into a geojson object.
diff --git a/pandapower/plotting/plotly/mapbox_plot.py b/pandapower/plotting/plotly/mapbox_plot.py
index bbb8795aa..d1ee39021 100644
--- a/pandapower/plotting/plotly/mapbox_plot.py
+++ b/pandapower/plotting/plotly/mapbox_plot.py
@@ -91,7 +91,7 @@ def geo_data_to_latlong(net, projection):
def set_mapbox_token(token):
- from pandapower import pp_dir
+ from pandapower.__init__ import pp_dir
path = os.path.join(pp_dir, "plotting", "plotly")
filename = os.path.join(path, 'mapbox_token.txt')
with open(filename, "w") as mapbox_file:
@@ -99,7 +99,7 @@ def set_mapbox_token(token):
def _get_mapbox_token():
- from pandapower import pp_dir
+ from pandapower.__init__ import pp_dir
path = os.path.join(pp_dir, "plotting", "plotly")
filename = os.path.join(path, 'mapbox_token.txt')
with open(filename, "r") as mapbox_file:
diff --git a/pandapower/plotting/plotly/simple_plotly.py b/pandapower/plotting/plotly/simple_plotly.py
index 4193739d7..db64ff56d 100644
--- a/pandapower/plotting/plotly/simple_plotly.py
+++ b/pandapower/plotting/plotly/simple_plotly.py
@@ -116,7 +116,7 @@ def simple_plotly(net, respect_switches=True, use_line_geo=None, on_map=False,
**respect_switches** (bool, True) - Respect switches when artificial geodata is created
**use_line_geo** (bool, True) - defines if lines patches are based on
- net.line_geodata of the lines (True) or on net.bus_geodata of the connected buses (False)
+ net.line.geo of the lines (True) or on net.bus.geo of the connected buses (False)
**on_map** (bool, False) - enables using mapbox plot in plotly.
If provided geodata are not real geo-coordinates in lon/lat form, on_map will be set to False.
diff --git a/pandapower/plotting/plotly/vlevel_plotly.py b/pandapower/plotting/plotly/vlevel_plotly.py
index 409baf916..eda70a6e0 100644
--- a/pandapower/plotting/plotly/vlevel_plotly.py
+++ b/pandapower/plotting/plotly/vlevel_plotly.py
@@ -35,8 +35,8 @@ def vlevel_plotly(net, respect_switches=True, use_line_geo=None, colors_dict=Non
OPTIONAL:
**respect_switches** (bool, True) - Respect switches when artificial geodata is created
- **use_line_geo** (bool, True) - defines if lines patches are based on net.line_geodata
- of the lines (True) or on net.bus_geodata of the connected buses (False)
+ **use_line_geo** (bool, True) - defines if lines patches are based on net.line.geo
+ of the lines (True) or on net.bus.geo of the connected buses (False)
*colors_dict** (dict, None) - dictionary for customization of colors for each voltage level
in the form: voltage : color
diff --git a/pandapower/plotting/plotting_toolbox.py b/pandapower/plotting/plotting_toolbox.py
index 11d19a39a..39cfc127d 100644
--- a/pandapower/plotting/plotting_toolbox.py
+++ b/pandapower/plotting/plotting_toolbox.py
@@ -144,7 +144,7 @@ def get_index_array(indices, net_table_indices):
def coords_from_node_geodata(element_indices, from_nodes, to_nodes, node_geodata, table_name,
- node_name="Bus", ignore_zero_length=True, node_geodata_to=None):
+ node_name="Bus", ignore_no_geo_diff=True, node_geodata_to=None):
"""
Auxiliary function to get the node coordinates for a number of branches with respective from
and to nodes. The branch elements for which there is no geodata available are not included in
@@ -162,9 +162,9 @@ def coords_from_node_geodata(element_indices, from_nodes, to_nodes, node_geodata
:type table_name: str
:param node_name: Name of the node type (only for logging)
:type node_name: str, default "Bus"
- :param ignore_zero_length: States if branches should be left out, if their length is zero, i.e. \
+ :param ignore_no_geo_diff: States if branches should be left out, if their length is zero, i.e. \
from_node_coords = to_node_coords
- :type ignore_zero_length: bool, default True
+ :type ignore_no_geo_diff: bool, default True
:param node_geodata_to: Dataframe containing x and y coordinates of the "to" nodes (optional, default node_geodata)
:type node_geodata_to: pd.DataFrame
:return: Return values are:\
@@ -192,15 +192,19 @@ def coords_from_node_geodata(element_indices, from_nodes, to_nodes, node_geodata
)
node_geodata = node_geodata.apply(_get_coords_from_geojson)
- coords = [f'{{"coordinates": [[{x_from}, {y_from}], [{x_to}, {y_to}]], "type": "LineString"}}'
- for [x_from, y_from], [x_to, y_to]
- in zip(node_geodata.loc[fb_with_geo[not_nan]],
- node_geodata.loc[tb_with_geo[not_nan]])
- if not ignore_zero_length or (ignore_zero_length and not (x_from == x_to and y_from == y_to))]
- return coords, np.array(element_indices)[in_geo & not_nan]
-
-
-def set_line_geodata_from_bus_geodata(net, line_index=None, overwrite=False, ignore_zero_length=True):
+ coords, no_geo_diff = zip(*[
+ (f'{{"coordinates": [[{x_from}, {y_from}], [{x_to}, {y_to}]], "type": "LineString"}}',
+ x_from == x_to and y_from == y_to) for [x_from, y_from], [x_to, y_to] in zip(
+ node_geodata.loc[fb_with_geo[not_nan]], node_geodata.loc[tb_with_geo[not_nan]])])
+ # if not ignore_no_geo_diff or (ignore_no_geo_diff and not ())]
+ coords, no_geo_diff = np.array(coords), np.array(no_geo_diff)
+ if ignore_no_geo_diff:
+ return coords, np.array(element_indices)[in_geo & not_nan]
+ else:
+ return coords[~no_geo_diff], np.array(element_indices)[in_geo & not_nan][~no_geo_diff]
+
+
+def set_line_geodata_from_bus_geodata(net, line_index=None, overwrite=False, ignore_no_geo_diff=True):
"""
Sets coordinates in net.line.geo based on the from_bus and to_bus coordinates
in net.bus.geo
@@ -227,7 +231,7 @@ def set_line_geodata_from_bus_geodata(net, line_index=None, overwrite=False, ign
node_geodata=net.bus.geo,
table_name="line",
node_name="bus",
- ignore_zero_length=ignore_zero_length)
+ ignore_no_geo_diff=ignore_no_geo_diff)
net.line.loc[line_index_successful, 'geo'] = geos
diff --git a/pandapower/powerflow.py b/pandapower/powerflow.py
index 574f21e56..243a04ebb 100644
--- a/pandapower/powerflow.py
+++ b/pandapower/powerflow.py
@@ -59,7 +59,7 @@ def _powerflow(net, **kwargs):
"branch": array([], dtype=int64), "branch_dc": array([], dtype=int64)}
# convert pandapower net to ppc
- ppc, ppci = _pd2ppc(net)
+ ppc, ppci = _pd2ppc(net, **kwargs)
# store variables
net["_ppc"] = ppc
@@ -81,6 +81,7 @@ def _recycled_powerflow(net, **kwargs):
algorithm = options["algorithm"]
ac = options["ac"]
recycle = options["recycle"]
+ update_vk_values = kwargs.get("update_vk_values", True)
ppci = {"bus": net["_ppc"]["internal"]["bus"],
"gen": net["_ppc"]["internal"]["gen"],
"branch": net["_ppc"]["internal"]["branch"],
@@ -104,9 +105,9 @@ def _recycled_powerflow(net, **kwargs):
# update trafo in branch and Ybus
lookup = net._pd2ppc_lookups["branch"]
if "trafo" in lookup:
- _calc_trafo_parameter(net, ppc)
+ _calc_trafo_parameter(net, ppc, update_vk_values=update_vk_values)
if "trafo3w" in lookup:
- _calc_trafo3w_parameter(net, ppc)
+ _calc_trafo3w_parameter(net, ppc, update_vk_values=update_vk_values)
if "gen" in recycle and recycle["gen"]:
# updates the ppc["gen"] part
diff --git a/pandapower/protection/utility_functions.py b/pandapower/protection/utility_functions.py
index 7ae26364e..b1f3ad034 100644
--- a/pandapower/protection/utility_functions.py
+++ b/pandapower/protection/utility_functions.py
@@ -1,8 +1,9 @@
# This function includes various function used for general functionalities such as plotting, grid search
import copy
-from typing import overload, List, Tuple
+from typing import List, Tuple
+from matplotlib.collections import PatchCollection
from typing_extensions import deprecated
import geojson
@@ -16,6 +17,7 @@
import pandapower as pp
import pandapower.plotting as plot
+from pandapower import pandapowerNet
from pandapower.topology.create_graph import create_nxgraph
import warnings
@@ -122,7 +124,8 @@ def create_sc_bus(net_copy, sc_line_id, sc_fraction):
x1, y1 = _get_coords_from_bus_idx(net, aux_line.from_bus)[0]
x2, y2 = _get_coords_from_bus_idx(net, aux_line.to_bus)[0]
- net.bus.geo.at[max_idx_bus + 1] = geojson.dumps(geojson.Point((sc_fraction * (x2 - x1) + x1, sc_fraction * (y2 - y1) + y1)), sort_keys=True)
+ net.bus.geo.at[max_idx_bus + 1] = geojson.dumps(
+ geojson.Point((sc_fraction * (x2 - x1) + x1, sc_fraction * (y2 - y1) + y1)), sort_keys=True)
return net
@@ -145,21 +148,9 @@ def calc_faults_at_full_line(net, line, location_step_size=0.01, start_location=
return fault_currents
-def get_line_idx(net, switch_id):
- # get the line id from swithc id
- line_idx = net.switch.element.at[switch_id]
- return line_idx
-
-
-def get_bus_idx(net, switch_id):
- # get the bus id using switch if
- bus_idx = net.switch.bus.at[switch_id]
- return bus_idx
-
-
def get_opposite_side_bus_from_switch(net, switch_id):
# get the frm and to bus of switch
- line_idx = get_line_idx(net, switch_id)
+ line_idx = net.switch.element.at[switch_id]
is_from_bus = get_from_bus_info_switch(net, switch_id)
if is_from_bus:
@@ -184,33 +175,15 @@ def get_opposite_side_bus_from_bus_line(net, bus_idx, line_idx):
def get_from_bus_info_switch(net, switch_id):
# get the from bus of given switch id
- bus_idx = get_bus_idx(net, switch_id)
- line_idx = get_line_idx(net, switch_id)
-
- for line in net.line.index: # can be written better
- if line == line_idx:
- if bus_idx == net.line.from_bus.at[line_idx]: # asks if switch is at from_bus
- is_from_bus = True
- # sc_fraction = 0.95
- else: # else it is at to_bus
- is_from_bus = False
- # sc_fraction = 0.05
+ bus_idx = net.switch.bus.at[switch_id]
+ line_idx = net.switch.element.at[switch_id]
- return is_from_bus
+ return bus_idx == net.line.from_bus.at[line_idx]
def get_from_bus_info_bus_line(net, bus_idx, line_idx):
# get bus nfo of given line
- for line in net.line.index: # can be written better
- if line == line_idx:
- if bus_idx == net.line.from_bus.at[line_idx]: # asks if switch is at from_bus
- is_from_bus = True
- # sc_fraction = 0.95
- else: # else it is at to_bus
- is_from_bus = False
- # sc_fraction = 0.05
-
- return is_from_bus
+ return bus_idx == net.line.from_bus.at[line_idx]
def get_line_impedance(net, line_idx):
@@ -218,23 +191,19 @@ def get_line_impedance(net, line_idx):
line_length = net.line.length_km.at[line_idx]
line_r_per_km = net.line.r_ohm_per_km.at[line_idx]
line_x_per_km = net.line.x_ohm_per_km.at[line_idx]
- Z_line = complex(line_r_per_km * line_length, line_x_per_km * line_length) # Z = R + jX
- return Z_line
+ z_line = complex(line_r_per_km * line_length, line_x_per_km * line_length) # Z = R + jX
+ return z_line
-def get_lowest_impedance_line(net, lines):
+def get_lowest_impedance_line(net: pandapowerNet, lines):
# get the low impedenceline
- i = 0
+ min_imp_line = None
+ min_impedance = float('inf')
for line in lines:
impedance = abs(get_line_impedance(net, line))
- if i == 0:
- min_imp_line = line
+ if impedance < min_impedance:
min_impedance = impedance
- else:
- if impedance < min_impedance:
- min_impedance = impedance
- min_imp_line = line
- i += 1
+ min_imp_line = line
return min_imp_line
@@ -260,6 +229,42 @@ def fuse_bus_switches(net, bus_switches):
return net
+def get_fault_annotation(net: pandapowerNet, fault_current: float = .0, font_size_bus: float = 0.06) -> PatchCollection:
+ max_bus_idx = max(net.bus.dropna(subset=['geo']).index)
+ fault_text = f'\tI_sc = {fault_current}kA'
+
+ fault_geo_x_y: Tuple[float, float] = next(geojson.utils.coords(geojson.loads(net.bus.geo.at[max_bus_idx])))
+ fault_geo_x_y = (fault_geo_x_y[0], fault_geo_x_y[1] - font_size_bus + 0.02)
+
+ # list of new geo data for line (half position of switch)
+ fault_annotate: PatchCollection = plot.create_annotation_collection(
+ texts=[fault_text],
+ coords=[fault_geo_x_y],
+ size=font_size_bus,
+ prop=None
+ )
+
+ return fault_annotate
+
+
+def get_sc_location_annotation(net: pandapowerNet, sc_location: float, font_size_bus: float = 0.06) -> PatchCollection:
+ max_bus_idx = max(net.bus.dropna(subset=['geo']).index)
+ sc_text = f'\tsc_location: {sc_location * 100}%'
+
+ # list of new geo data for line (middle of position of switch)
+ sc_geo_x_y = next(geojson.utils.coords(geojson.loads(net.bus.geo.at[max_bus_idx])))
+ sc_geo_x_y = (sc_geo_x_y[0], sc_geo_x_y[1] + 0.02)
+
+ sc_annotate: PatchCollection = plot.create_annotation_collection(
+ texts=[sc_text],
+ coords=[sc_geo_x_y],
+ size=font_size_bus,
+ prop=None
+ )
+
+ return sc_annotate
+
+
def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_annotations=True):
# plot the tripped grid of net_sc
if MPLCURSORS_INSTALLED:
@@ -348,6 +353,8 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann
line_text = []
line_geodata = []
+ fault_current: float = .0
+
# for Switches in trip_decisions:
for line in net.line.index:
@@ -362,20 +369,22 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann
respect_in_service=False)
bus_list = list(get_bus_index)
+ bus_coords: List[Tuple[float, float]] = [
+ geojson.utils.coords(geojson.loads(net.bus.geo.at[bus])) for bus in bus_list
+ ]
# TODO:
# place annotations on middle of the line
- line_geo_x = (net.bus_geodata.iloc[bus_list[0]].x + net.bus_geodata.iloc[bus_list[1]].x) / 2
-
- line_geo_y = ((net.bus_geodata.iloc[bus_list[0]].y + net.bus_geodata.iloc[bus_list[1]].y) / 2) + 0.05
+ line_geo_x = (bus_coords[0][0] + bus_coords[1][0]) / 2
+ line_geo_y = ((bus_coords[0][1] + bus_coords[1][1]) / 2) + 0.05
line_geo_x_y = [line_geo_x, line_geo_y]
# list of new geo data for line (half position of switch)
line_geodata.append(tuple(line_geo_x_y))
- fault_current = round(net.res_bus_sc['ikss_ka'].at[max(net.bus.index)],
- 2) # round(Switches['Fault Current'],2)
+ fault_current = round(net.res_bus_sc['ikss_ka'].at[max(net.bus.index)], 2)
+ # round(Switches['Fault Current'],2)
line_text.append(text_line)
@@ -385,67 +394,27 @@ def plot_tripped_grid(net, trip_decisions, sc_location, bus_size=0.055, plot_ann
# Bus Annotatations
bus_text = []
- for i in net.bus_geodata.index:
+ for i in net.bus.geo.dropna().index:
bus_texts = 'bus_' + str(i)
bus_text.append(bus_texts)
bus_text = bus_text[:-1]
- bus_geodata = net.bus_geodata[['x', 'y']]
+ bus_geodata = net.bus.geo.dropna().apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list()
# placing bus
- bus_geodata['x'] = bus_geodata['x'] - 0.11
- bus_geodata['y'] = bus_geodata['y'] + 0.095
+ bus_index = [(x[0] - 0.11, x[1] + 0.095) for x in bus_geodata]
# TODO:
- bus_index = [tuple(x) for x in bus_geodata.to_numpy()]
bus_annotate = plot.create_annotation_collection(texts=bus_text, coords=bus_index, size=0.06, prop=None)
collection.append(bus_annotate)
# Short circuit annotations
- fault_geodata = []
-
- fault_text = []
-
- fault_texts = ' I_sc = ' + str(fault_current) + 'kA'
-
- font_size_bus = 0.06 # font size of fault location text
-
- fault_geo_x = net.bus_geodata.iloc[max(net.bus_geodata.index)][0]
- fault_geo_y = net.bus_geodata.iloc[max(net.bus_geodata.index)][1] - font_size_bus + 0.02
-
- fault_geo_x_y = [fault_geo_x, fault_geo_y]
-
- # list of new geo data for line (half position of switch)
- fault_geodata.append(tuple(fault_geo_x_y))
-
- fault_text.append(fault_texts)
- fault_annotate = plot.create_annotation_collection(texts=fault_text, coords=fault_geodata, size=0.06, prop=None)
-
- collection.append(fault_annotate)
+ collection.append(get_fault_annotation(net, fault_current))
# sc_location annotation
- sc_text = []
- sc_geodata = []
-
- sc_texts = ' sc_location: ' + str(sc_location * 100) + '%'
-
- # font_size_bus=0.06 # font size of sc location
-
- sc_geo_x = net.bus_geodata.iloc[max(net.bus_geodata.index)][0]
-
- sc_geo_y = net.bus_geodata.iloc[max(net.bus_geodata.index)][1] + 0.02
-
- sc_geo_x_y = [sc_geo_x, sc_geo_y]
-
- # list of new geo data for line (middle of position of switch)
- sc_geodata.append(tuple(sc_geo_x_y))
-
- sc_text.append(sc_texts)
- sc_annotate = plot.create_annotation_collection(texts=sc_text, coords=sc_geodata, size=0.06, prop=None)
-
- collection.append(sc_annotate)
+ collection.append(get_sc_location_annotation(net, sc_location))
# switch annotations
# from pandapower.protection.implemeutility_functions import switch_geodata
@@ -595,7 +564,9 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus
bus_list = list(get_bus_index)
# place annotations on middle of the line
- bus_coords = list(zip(*net.bus.geo.iloc[bus_list[0:2]].apply(geojson.loads).apply(geojson.utils.coords).apply(next).to_list()))
+ bus_coords = list(
+ zip(*net.bus.geo.iloc[bus_list[0:2]].apply(geojson.loads).apply(geojson.utils.coords).apply(
+ next).to_list()))
line_geo_x_y = [sum(x) / 2 for x in bus_coords]
line_geo_x_y[1] += 0.05
@@ -610,7 +581,7 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus
line_annotate = plot.create_annotation_collection(texts=line_text, coords=line_geodata, size=0.06, prop=None)
collection.append(line_annotate)
- # Bus Annotatations
+ # Bus Annotations
bus_text = []
for i in net.bus.index:
bus_texts = f'bus_{i}'
@@ -626,42 +597,13 @@ def plot_tripped_grid_protection_device(net, trip_decisions, sc_location, sc_bus
bus_annotate = plot.create_annotation_collection(texts=bus_text, coords=bus_geodata, size=0.06, prop=None)
collection.append(bus_annotate)
- font_size_bus = 0.06 # font size of fault location text
max_bus_idx = max(net.bus.dropna(subset=['geo']).index)
# Short circuit annotations
- fault_geodata = []
- fault_text = []
- fault_texts = f'\tI_sc = {fault_current}kA'
-
- fault_geo_x_y = next(geojson.utils.coords(geojson.loads(net.bus.geo.at[max_bus_idx])))
- fault_geo_x_y = (fault_geo_x_y[0], fault_geo_x_y[1] - font_size_bus + 0.02)
-
- # list of new geo data for line (half position of switch)
- fault_geodata.append(fault_geo_x_y)
-
- fault_text.append(fault_texts)
- fault_annotate = plot.create_annotation_collection(texts=fault_text, coords=fault_geodata, size=0.06, prop=None)
-
- collection.append(fault_annotate)
+ collection.append(get_fault_annotation(net, fault_current))
# sc_location annotation
- sc_text = []
- sc_geodata = []
- sc_texts = f'\tsc_location: {sc_location * 100}%'
-
- # font_size_bus=0.06 # font size of sc location
-
- sc_geo_x_y = next(geojson.utils.coords(geojson.loads(net.bus.geo.at[max_bus_idx])))
- sc_geo_x_y = (sc_geo_x_y[0], sc_geo_x_y[1] + 0.02)
-
- # list of new geo data for line (middle of position of switch)
- sc_geodata.append(sc_geo_x_y)
-
- sc_text.append(sc_texts)
- sc_annotate = plot.create_annotation_collection(texts=sc_text, coords=sc_geodata, size=0.06, prop=None)
-
- collection.append(sc_annotate)
+ collection.append(get_sc_location_annotation(net, sc_location))
# switch annotations
# from pandapower.protection.utility_functions import switch_geodata
@@ -699,7 +641,7 @@ def get_connected_lines(net, bus_idx):
# first one. E.g. the from_bus given the to_bus of a line.
@deprecated("Use pandapower.next_bus(net, bus, element_id instead!")
def next_buses(net, bus, element_id):
- return pp.next_bus(net,bus,element_id)
+ return pp.next_bus(net, bus, element_id)
# get the connected bus listr from start to end bus
@@ -896,89 +838,59 @@ def bus_path_from_to_bus(net, radial_start_bus, loop_start_bus, end_bus):
return bus_path
-def get_switches_in_path(net, pathes):
+def get_switches_in_path(net, paths):
"""function calculate the switching times from the bus path"""
- Lines_in_path = []
+ lines_in_path: List[List] = []
- for path in pathes:
- Lines_at_path = []
+ for path in paths:
+ lines_at_path: set = set()
for bus in path:
- Lines_at_paths = []
- lines_at_bus = pp.get_connected_elements(net, "l", bus)
-
- for line in lines_at_bus:
- Lines_at_path.append(line)
-
- for Line1 in Lines_at_path:
- if net.line.from_bus[Line1] in path:
- if net.line.to_bus[Line1] in path:
- if Line1 not in Lines_at_paths:
- Lines_at_paths.append(Line1)
-
- Lines_in_path.append(Lines_at_paths)
+ lines_at_path.update(pp.get_connected_elements(net, "l", bus))
- switches_in_net = net.switch.index
- switches_in_path = []
+ lines_at_paths = [
+ line for line in lines_at_path
+ if net.line.from_bus[line] in path and net.line.to_bus[line] in path
+ ]
- for Linepath in Lines_in_path:
- switches_at_path = []
+ lines_in_path.append(lines_at_paths)
- for Line in Linepath:
-
- for switch in switches_in_net:
- if net.switch.et[switch] == "l":
- if net.switch.element[switch] == Line:
- switches_at_path.append(switch)
- switches_in_path.append(switches_at_path)
+ switches_in_path = [
+ [net.switch[(net.switch['et'] == 'l') & (net.switch['element'] == line)].index for line in line_path]
+ for line_path in lines_in_path
+ ]
return switches_in_path
-def get_vi_angle(net, switch_id, powerflow_results=False):
+def get_vi_angle(net: pandapowerNet, switch_id: int, **kwargs) -> float:
"""calculate the angle between voltage and current with reference to voltage"""
- pp.runpp(net)
- line_idx = get_line_idx(net, switch_id)
- bus_idx = get_bus_idx(net, switch_id)
-
- if powerflow_results:
-
- if get_from_bus_info_switch(net, switch_id):
-
- P = net.res_line.p_from_mw.at[line_idx]
- Q = net.res_line.q_from_mvar.at[line_idx]
+ if "powerflow_results" in kwargs:
+ logger.warning(
+ "The powerflow_results argument is deprecated and will be removed in the future."
+ )
- vm = net.bus.vn_kv.at[bus_idx] * net.res_line.vm_from_pu.at[line_idx]
- else:
- P = net.res_line.p_to_mw.at[line_idx]
- Q = net.res_line.q_to_mvar.at[line_idx]
+ pp.runpp(net)
+ line_idx = net.switch.element.at[switch_id]
- vm = net.bus.vn_kv.at[bus_idx] * net.res_line.vm_to_pu.at[line_idx]
+ if get_from_bus_info_switch(net, switch_id):
+ p = net.res_line_sc.p_from_mw.at[line_idx]
+ q = net.res_line_sc.q_from_mvar.at[line_idx]
else:
-
- if get_from_bus_info_switch(net, switch_id):
-
- P = net.res_line_sc.p_from_mw.at[line_idx]
- Q = net.res_line_sc.q_from_mvar.at[line_idx]
-
- vm = net.bus.vn_kv.at[bus_idx] * net.res_line_sc.vm_from_pu.at[line_idx]
-
- else:
- P = net.res_line_sc.p_to_mw.at[line_idx]
- Q = net.res_line_sc.q_to_mvar.at[line_idx]
- vm = net.bus.vn_kv.at[bus_idx] * net.res_line_sc.vm_to_pu.at[line_idx]
-
- if P > 0 and Q > 0:
- vi_angle = math.degrees(math.atan(Q / P))
- elif P < 0 and Q >= 0:
- vi_angle = math.degrees(math.atan(Q / P)) + 180
- elif P < 0 and Q < 0:
- vi_angle = math.degrees(math.atan(Q / P)) - 180
- elif P == 0 and Q > 0:
+ p = net.res_line_sc.p_to_mw.at[line_idx]
+ q = net.res_line_sc.q_to_mvar.at[line_idx]
+
+ if p > 0 and q > 0:
+ vi_angle = math.degrees(math.atan(q / p))
+ elif p < 0 <= q:
+ vi_angle = math.degrees(math.atan(q / p)) + 180
+ elif p < 0 and q < 0:
+ vi_angle = math.degrees(math.atan(q / p)) - 180
+ elif p == 0 < q:
vi_angle = 90
- elif P == 0 and Q < 0:
+ elif p == 0 > q:
vi_angle = -90
else:
vi_angle = math.inf
@@ -1007,8 +919,8 @@ def bus_path_multiple_ext_bus(net):
elif len(from_bus_path) != len(to_bus_path):
if len(from_bus_path) > 1 and len(to_bus_path) > 1:
- minlen = min(len(from_bus_path), len(to_bus_path))
- if from_bus_path[minlen - 1] != to_bus_path[minlen - 1]:
+ min_len = min(len(from_bus_path), len(to_bus_path))
+ if from_bus_path[min_len - 1] != to_bus_path[min_len - 1]:
if len(from_bus_path) < len(to_bus_path):
from_bus_path.append(to_bus_path[-1])
max_bus_path.append(from_bus_path)
@@ -1025,19 +937,19 @@ def bus_path_multiple_ext_bus(net):
return bus_path
- # get the line path from the given bus path
+# get the line path from the given bus path
def get_line_path(net, bus_path):
""" Function return the list of line path from the given bus path"""
- line_path=[]
- for i in range(len(bus_path)-1):
- bus1=bus_path[i]
- bus2=bus_path[i+1]
- line1=net.line[(net.line.from_bus==bus1) & (net.line.to_bus==bus2)].index.to_list()
- line2=net.line[(net.line.from_bus==bus2) & (net.line.to_bus==bus1)].index.to_list()
- if len(line2)==0:
+ line_path = []
+ for i in range(len(bus_path) - 1):
+ bus1 = bus_path[i]
+ bus2 = bus_path[i + 1]
+ line1 = net.line[(net.line.from_bus == bus1) & (net.line.to_bus == bus2)].index.to_list()
+ line2 = net.line[(net.line.from_bus == bus2) & (net.line.to_bus == bus1)].index.to_list()
+ if len(line2) == 0:
line_path.append(line1[0])
- if len(line1)==0:
+ if len(line1) == 0:
line_path.append(line2[0])
return line_path
diff --git a/pandapower/pypower/newtonpf.py b/pandapower/pypower/newtonpf.py
index 6a4003635..a22fee238 100644
--- a/pandapower/pypower/newtonpf.py
+++ b/pandapower/pypower/newtonpf.py
@@ -14,19 +14,18 @@
from numpy import float64, array, angle, sqrt, square, exp, linalg, conj, r_, inf, arange, zeros, \
max, zeros_like, column_stack, flatnonzero, nan_to_num
from pandapower.pypower.bustypes import bustypes_dc
-from pandapower.pypower.idx_brch_dc import DC_BR_R, DC_PF, DC_IF, DC_PT, DC_IT, DC_BR_STATUS
+from pandapower.pypower.idx_brch_dc import DC_BR_R, DC_PF, DC_IF, DC_PT, DC_IT, DC_BR_STATUS, DC_F_BUS, DC_T_BUS
from scipy.sparse import csr_matrix, eye, vstack
from scipy.sparse.linalg import spsolve
from pandapower.auxiliary import _sum_by_group
-from pandapower import VSC_STATUS, VSC_BUS, VSC_INTERNAL_BUS, DC_F_BUS, DC_T_BUS
from pandapower.pf.iwamoto_multiplier import _iwamoto_step
from pandapower.pf.makeYbus_facts import makeYbus_svc, makeYft_tcsc, calc_y_svc_pu, \
makeYbus_ssc_vsc, make_Ybus_facts, make_Yft_facts
-from pandapower.pypower.idx_bus_dc import DC_PD, DC_VM, DC_BUS_TYPE, DC_NONE, DC_BUS_I, DC_REF, DC_P, DC_B2B, DC_BASE_KV
+from pandapower.pypower.idx_bus_dc import DC_PD, DC_VM, DC_BUS_TYPE, DC_NONE, DC_BUS_I, DC_REF, DC_P
from pandapower.pypower.idx_vsc import VSC_CONTROLLABLE, VSC_MODE_AC, VSC_VALUE_AC, VSC_MODE_DC, VSC_VALUE_DC, VSC_R, \
VSC_X, VSC_Q, VSC_P, VSC_BUS_DC, VSC_P_DC, VSC_MODE_AC_SL, VSC_MODE_AC_V, VSC_MODE_AC_Q, VSC_MODE_DC_P, \
- VSC_MODE_DC_V, VSC_INTERNAL_BUS_DC, VSC_R_DC, VSC_PL_DC
+ VSC_MODE_DC_V, VSC_INTERNAL_BUS_DC, VSC_R_DC, VSC_PL_DC, VSC_STATUS, VSC_BUS, VSC_INTERNAL_BUS
from pandapower.pypower.makeSbus import makeSbus
from pandapower.pf.create_jacobian import create_jacobian_matrix, get_fastest_jacobian_function
from pandapower.pypower.idx_gen import PG
diff --git a/pandapower/pypower/printpf.py b/pandapower/pypower/printpf.py
index d6a8e6573..8a0d9cec0 100644
--- a/pandapower/pypower/printpf.py
+++ b/pandapower/pypower/printpf.py
@@ -659,7 +659,7 @@ def printpf(baseMVA, bus=None, gen=None, branch=None, f=None, success=None,
fd.write('\n================================================================================')
fd.write('\n| Branch Flow Constraints |')
fd.write('\n================================================================================')
- fd.write('\nBrnch From "From" End Limit "To" End To')
+ fd.write('\nBranch From "From" End Limit "To" End To')
fd.write(strg)
fd.write('\n----- ----- ------- -------- -------- -------- ------- -----')
for i in range(nl):
diff --git a/pandapower/results_bus.py b/pandapower/results_bus.py
index 3fbde81e0..4981d35e3 100644
--- a/pandapower/results_bus.py
+++ b/pandapower/results_bus.py
@@ -7,7 +7,6 @@
import numpy as np
import pandas as pd
from numpy import complex128
-from pandapower import VSC_INTERNAL_BUS
from pandapower.auxiliary import _sum_by_group, sequence_to_phase, _sum_by_group_nvals
from pandapower.pypower.idx_bus import VM, VA, PD, QD, LAM_P, LAM_Q, BASE_KV, NONE, BS, BUS_TYPE, BUS_I
from pandapower.pypower.idx_bus_dc import DC_VM, DC_BUS_TYPE, DC_NONE, DC_PD, DC_BUS_I
@@ -16,7 +15,7 @@
from pandapower.build_bus import _get_motor_pq, _get_symmetric_pq_of_unsymetric_element
from pandapower.pypower.idx_ssc import SSC_X_CONTROL_VM, SSC_X_CONTROL_VA, SSC_Q, SSC_INTERNAL_BUS
from pandapower.pypower.idx_svc import SVC_THYRISTOR_FIRING_ANGLE, SVC_Q, SVC_X_PU
-from pandapower.pypower.idx_vsc import VSC_Q, VSC_P, VSC_P_DC, VSC_BUS_DC, VSC_INTERNAL_BUS_DC
+from pandapower.pypower.idx_vsc import VSC_Q, VSC_P, VSC_P_DC, VSC_BUS_DC, VSC_INTERNAL_BUS_DC, VSC_INTERNAL_BUS
try:
import pandaplan.core.pplog as logging
diff --git a/pandapower/run.py b/pandapower/run.py
index 456a9b9eb..8760eaac2 100644
--- a/pandapower/run.py
+++ b/pandapower/run.py
@@ -177,12 +177,12 @@ def runpp(net, algorithm='nr', calculate_voltage_angles=True, init="auto",
**KWARGS**:
- **lightsim2grid** ((bool,str), "auto") - whether to use the package lightsim2grid for power flow backend
+ **lightsim2grid** ((bool,str), "auto") - whether to use the package lightsim2grid for power
+ flow backend. For more details on compatibility, check out pandapower's documentation.
- **numba** (bool, True) - Activation of numba JIT compiler in the newton solver
-
- If set to True, the numba JIT compiler is used to generate matrices for the powerflow,
- which leads to significant speed improvements.
+ **numba** (bool, True) - Activation of numba JIT compiler in the newton solver.
+ If set to True, the numba JIT compiler is used to generate matrices for the powerflow,
+ which leads to significant speed improvements.
**switch_rx_ratio** (float, 2) - rx_ratio of bus-bus-switches. If the impedance of switches
defined in net.switch.z_ohm is zero, buses connected by a closed bus-bus switch are fused to
@@ -225,6 +225,7 @@ def runpp(net, algorithm='nr', calculate_voltage_angles=True, init="auto",
**tdpf_update_r_theta** (bool, True) - TDPF parameter, whether to update R_Theta in Newton-Raphson or to assume a constant R_Theta (either from net.line.r_theta, if set, or from a calculation based on the thermal model of Ngoko et.al.)
+ **update_vk_values** (bool, True) - If True vk and vkr values of trafo3w are recalculated based on characteristics, otherwise the values from the table are used. Can improve performance for large models.
"""
# if dict 'user_pf_options' is present in net, these options overrule the net._options
diff --git a/pandapower/shortcircuit/ppc_conversion.py b/pandapower/shortcircuit/ppc_conversion.py
index c31d469bb..923297a73 100644
--- a/pandapower/shortcircuit/ppc_conversion.py
+++ b/pandapower/shortcircuit/ppc_conversion.py
@@ -25,7 +25,7 @@
def _get_is_ppci_bus(net, bus):
- is_bus = bus[np.in1d(bus, net._is_elements_final["bus_is_idx"])]
+ is_bus = bus[np.isin(bus, net._is_elements_final["bus_is_idx"])]
ppci_bus = np.unique(net._pd2ppc_lookups["bus"][is_bus])
return ppci_bus
diff --git a/pandapower/shortcircuit/toolbox.py b/pandapower/shortcircuit/toolbox.py
index 8c93fb6ee..47529d50d 100644
--- a/pandapower/shortcircuit/toolbox.py
+++ b/pandapower/shortcircuit/toolbox.py
@@ -77,10 +77,10 @@ def detect_power_station_unit(net, mode="auto",
# Check parallel trafo
if not len(np.intersect1d(connected_bus_at_lv_side, trafo_lv_bus)) == 1:
raise UserWarning("Failure in power station units detection! Parallel trafos on generator detected!")
- if np.in1d(required_gen_bus, gen_bus_at_lv_side).sum() > 1:
+ if np.isin(required_gen_bus, gen_bus_at_lv_side).sum() > 1:
logger.info("More than 1 gen detected at the lv side of a power station trafo! Will not be considered as power station unit")
continue
- net.gen.loc[np.in1d(net.gen.bus.values, gen_bus_at_lv_side),
+ net.gen.loc[np.isin(net.gen.bus.values, gen_bus_at_lv_side),
"power_station_trafo"] = t_ix
diff --git a/pandapower/test/__init__.py b/pandapower/test/__init__.py
index 7b985f732..0611f8b4b 100644
--- a/pandapower/test/__init__.py
+++ b/pandapower/test/__init__.py
@@ -1,5 +1,5 @@
import os
-from pandapower import pp_dir
+from pandapower.__init__ import pp_dir
test_path = os.path.join(pp_dir, 'test')
tutorials_path = os.path.join(os.path.dirname(pp_dir), 'tutorials')
diff --git a/pandapower/test/api/test_auxiliary.py b/pandapower/test/api/test_auxiliary.py
index be6c60a24..33e532bf3 100644
--- a/pandapower/test/api/test_auxiliary.py
+++ b/pandapower/test/api/test_auxiliary.py
@@ -303,6 +303,7 @@ def test_characteristic(file_io):
with pytest.raises(NotImplementedError):
c3([0])
+
def test_log_characteristic_property():
net = pp.create_empty_network()
c = LogSplineCharacteristic(net, [10, 1000, 10000], [1000, 0.1, 0.001], interpolator_kind="Pchip", extrapolate=False)
@@ -310,6 +311,52 @@ def test_log_characteristic_property():
c([2])
+def test_geo_accessor_geojson():
+ net = pp.create_empty_network()
+ b1 = pp.create_bus(net, 10, geodata=(1, 1))
+ b2 = pp.create_bus(net, 10, geodata=(2, 2))
+ l = pp.create_lines(
+ net,
+ [b1, b1],
+ [b2, b2],
+ [1.5, 3],
+ std_type="48-AL1/8-ST1A 10.0",
+ geodata=[[(1, 1), (2, 2), (3, 3)], [(1, 1), (1, 2)]],
+ )
+ pp.create_line(net, b1, b2, 1.5, std_type="48-AL1/8-ST1A 10.0")
+
+ assert len(net.line.geo.geojson._coords) == 2
+ assert np.array_equal(net.line.geo.geojson._coords.at[l[0]], [[1, 1], [2, 2], [3, 3]])
+ assert np.array_equal(net.line.geo.geojson._coords.at[l[1]], [[1, 1], [1, 2]])
+ assert np.array_equal(net.bus.geo.geojson._coords.at[b1], [1, 1])
+ assert np.array_equal(net.bus.geo.geojson._coords.at[b2], [2, 2])
+ assert net.bus.geo.geojson.type.at[b1] == "Point"
+ assert net.bus.geo.geojson.type.at[b2] == "Point"
+ assert net.line.geo.geojson.type.at[l[0]] == "LineString"
+ assert net.line.geo.geojson.type.at[l[1]] == "LineString"
+ assert set(net.line.geo.geojson.as_geo_obj.at[l[0]].keys()) == {"coordinates", "type"}
+ assert set(net.line.geo.geojson.as_geo_obj.at[l[1]].keys()) == {"coordinates", "type"}
+ assert set(net.bus.geo.geojson.as_geo_obj.at[b1].keys()) == {"coordinates", "type"}
+ assert set(net.bus.geo.geojson.as_geo_obj.at[b2].keys()) == {"coordinates", "type"}
+
+
+@pytest.mark.skipif(not GEOPANDAS_INSTALLED, reason="geopandas is not installed")
+def test_geo_accessor_geopandas():
+ net = pp.networks.mv_oberrhein()
+ reference_point = (7.781067, 48.389774)
+ radius_m = 2200
+ circle_polygon = gpd.GeoSeries([shapely.geometry.Point(reference_point)],
+ crs=4326).to_crs(epsg=31467).buffer(radius_m).to_crs(epsg=4326).iloc[0]
+ assert net.line.geo.geojson.within(circle_polygon).sum() == 11
+ assert all(net.line[net.line.geo.geojson.within(circle_polygon)].index == [14, 17, 46, 47, 55, 116,
+ 117, 118, 120, 121, 134])
+
+ line = shapely.geometry.LineString([[7.8947079593416, 48.40549007606241],
+ [7.896048283667894, 48.41060722903666],
+ [7.896173712216692, 48.41100311474432]])
+
+ assert net.line.geo.geojson.as_shapely_obj.at[0] == line
+ assert np.allclose(net.line.geo.geojson.total_bounds, [7.74426069, 48.32845845, 7.93829196, 48.47484423])
if __name__ == '__main__':
diff --git a/pandapower/test/api/test_file_io.py b/pandapower/test/api/test_file_io.py
index e9393297c..a71a3aab0 100644
--- a/pandapower/test/api/test_file_io.py
+++ b/pandapower/test/api/test_file_io.py
@@ -229,7 +229,7 @@ def test_json_encoding_decoding():
net = networks.mv_oberrhein()
net.tuple = (1, "4")
net.mg = topology.create_nxgraph(net)
- s = set(['1', 4])
+ s = {'1', 4}
t = tuple(['2', 3])
f = frozenset(['12', 3])
a = np.array([1., 2.])
@@ -601,5 +601,36 @@ def test_multi_index():
assert_frame_equal(df, df2)
+def test_ignore_unknown_objects():
+ net = pp.networks.create_kerber_dorfnetz()
+ control.ContinuousTapControl(net, 0, 1.02)
+ json_str = pp.to_json(net)
+ net2 = pp.from_json_string(json_str, ignore_unknown_objects=False)
+
+ # in general, reloaded net should be equal to original net
+ assert isinstance(net2.controller.object.at[0], control.ContinuousTapControl)
+ assert_net_equal(net, net2)
+
+ # slightly change the class name of the controller so that it cannot be identified
+ # by file_io anymore, but can still be loaded as dict if ignore_unknown_objects=True
+ json_str2 = json_str.replace("pandapower.control.controller.trafo.ContinuousTapControl",
+ "pandapower.control.controller.trafo.ContinuousTapControl2")
+ with pytest.raises(ModuleNotFoundError):
+ pp.from_json_string(json_str2, ignore_unknown_objects=False)
+ json_str3 = json_str.replace("\"ContinuousTapControl", "\"ContinuousTapControl2")
+ with pytest.raises(AttributeError):
+ pp.from_json_string(json_str3, ignore_unknown_objects=False)
+ net3 = pp.from_json_string(json_str2, ignore_unknown_objects=True)
+ assert isinstance(net3.controller.object.at[0], dict)
+ net4 = pp.from_json_string(json_str3, ignore_unknown_objects=True)
+ assert isinstance(net4.controller.object.at[0], dict)
+
+ # make sure that the loaded net equals the original net except for the controller
+ net3.controller.object.at[0] = net.controller.object.at[0]
+ net4.controller.object.at[0] = net.controller.object.at[0]
+ assert_net_equal(net, net3)
+ assert_net_equal(net, net4)
+
+
if __name__ == "__main__":
pytest.main([__file__, "-xs"])
diff --git a/pandapower/test/control/test_continuous_tap_control.py b/pandapower/test/control/test_continuous_tap_control.py
index b1e24057c..dd1f25388 100644
--- a/pandapower/test/control/test_continuous_tap_control.py
+++ b/pandapower/test/control/test_continuous_tap_control.py
@@ -288,6 +288,11 @@ def test_continuous_tap_control_side_hv_reversed_3w():
assert np.allclose(net.res_trafo3w.vm_hv_pu.values, 1.02, atol=tol)
assert not np.allclose(net.trafo3w.tap_pos.values, 0)
+def test_continuous_trafo_control_with_oos_trafo():
+ net = pp.networks.mv_oberrhein()
+ # switch transformer out of service
+ net.trafo.loc[114, 'in_service'] = False
+ ContinuousTapControl(net=net, element_index=114, vm_set_pu=1.0, tol=0.001)
if __name__ == '__main__':
pytest.main([__file__, "-xs"])
diff --git a/pandapower/test/control/test_discrete_tap_control.py b/pandapower/test/control/test_discrete_tap_control.py
index 5a12eaab2..3798d8d09 100644
--- a/pandapower/test/control/test_discrete_tap_control.py
+++ b/pandapower/test/control/test_discrete_tap_control.py
@@ -39,13 +39,13 @@ def test_discrete_tap_control_lv():
logger.info("case1: low voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -1
# increase voltage from 1.0 pu to 1.03 pu
@@ -56,13 +56,13 @@ def test_discrete_tap_control_lv():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -2
# reduce voltage from 1.03 pu to 0.949 pu
net.ext_grid.vm_pu = 0.949
@@ -72,13 +72,13 @@ def test_discrete_tap_control_lv():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 1
@@ -100,13 +100,13 @@ def test_discrete_tap_control_hv():
logger.info("case1: low voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 1
# increase voltage from 1.0 pu to 1.03 pu
net.ext_grid.vm_pu = 1.03
@@ -116,13 +116,13 @@ def test_discrete_tap_control_hv():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 2
# increase voltage from 1.0 pu to 1.03 pu
net.ext_grid.vm_pu = 0.949
@@ -132,13 +132,13 @@ def test_discrete_tap_control_hv():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -1
@@ -160,13 +160,13 @@ def test_discrete_tap_control_lv_from_tap_step_percent():
logger.info("case1: low voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -1
# check if it changes the lower and upper limits
@@ -187,13 +187,13 @@ def test_discrete_tap_control_lv_from_tap_step_percent():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -2
# reduce voltage from 1.03 pu to 0.969 pu
net.ext_grid.vm_pu = 0.969
@@ -203,13 +203,13 @@ def test_discrete_tap_control_lv_from_tap_step_percent():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 1
@@ -231,13 +231,13 @@ def test_discrete_tap_control_hv_from_tap_step_percent():
logger.info("case1: low voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 1
# check if it changes the lower and upper limits
@@ -258,13 +258,13 @@ def test_discrete_tap_control_hv_from_tap_step_percent():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == 2
# reduce voltage from 1.03 pu to 0.969 pu
net.ext_grid.vm_pu = 0.969
@@ -274,13 +274,13 @@ def test_discrete_tap_control_hv_from_tap_step_percent():
logger.info("case2: high voltage")
logger.info("before control: trafo voltage at low voltage bus is %f, tap position is %u"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
# run control
pp.runpp(net, run_control=True)
logger.info(
"after DiscreteTapControl: trafo voltage at low voltage bus is %f, tap position is %f"
- % (net.res_bus.vm_pu[net.trafo.lv_bus].values, net.trafo.tap_pos.values))
+ % (net.res_bus.vm_pu[net.trafo.lv_bus].values.item(), net.trafo.tap_pos.values.item()))
assert net.trafo.tap_pos.at[0] == -1
@@ -390,6 +390,11 @@ def test_continuous_tap_control_side_mv():
assert all(_vm_in_desired_area(net, 1.01, 1.03, "mv", trafo_table="trafo3w"))
assert not np.allclose(net.trafo3w.tap_pos.values, 0)
+def test_discrete_trafo_control_with_oos_trafo():
+ net = pp.networks.mv_oberrhein()
+ # switch transformer out of service
+ net.trafo.loc[114, 'in_service'] = False
+ DiscreteTapControl(net=net, element_index=114, vm_lower_pu=1.01, vm_upper_pu=1.03)
if __name__ == '__main__':
pytest.main([__file__, "-xs"])
diff --git a/pandapower/test/control/test_vm_set_tap_control.py b/pandapower/test/control/test_vm_set_tap_control.py
index 61e87d42c..033a3dfd9 100644
--- a/pandapower/test/control/test_vm_set_tap_control.py
+++ b/pandapower/test/control/test_vm_set_tap_control.py
@@ -28,21 +28,21 @@ def test_continuous_p():
pp.runpp(net, run_control=True)
# we expect the tap to converge at upper voltage limit
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.05) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps
# power sums up to 15kW
net.sgen.at[gid, "p_mw"] = 5
pp.runpp(net, run_control=True)
# we expect the tap to converge at 1.0 pu
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.) < eps
# generation now cancels load
net.sgen.at[gid, "p_mw"] = 10
pp.runpp(net, run_control=True)
# we expect the tap to converge at lower voltage limit
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 0.95) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps
# testing limits
# power flowing back
@@ -50,7 +50,7 @@ def test_continuous_p():
pp.runpp(net, run_control=True)
# we expect the tap to converge at lower voltage limit and not drop even lower
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 0.95) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps
# excessive load
net.sgen.at[gid, "p_mw"] = 0
@@ -58,7 +58,7 @@ def test_continuous_p():
pp.runpp(net, run_control=True)
# we expect the tap to converge at upper voltage limit and not to go beyond
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.05) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps
def test_continuous_i():
@@ -81,21 +81,21 @@ def test_continuous_i():
pp.runpp(net, run_control=True)
# we expect the tap to converge at upper voltage limit
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.05) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps
# power sums up to 15kW
net.sgen.at[gid, "p_mw"] = 5
pp.runpp(net, run_control=True)
# we expect the tap to converge at 1.0 pu
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.) < eps
# generation now cancels load
net.sgen.at[gid, "p_mw"] = 10
pp.runpp(net, run_control=True)
# we expect the tap to converge at lower voltage limit
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 0.95) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps
# testing limits
# power flowing back
@@ -103,7 +103,7 @@ def test_continuous_i():
pp.runpp(net, run_control=True)
# we expect the tap to converge at lower voltage limit and not drop even lower
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 0.95) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 0.95) < eps
# excessive load
net.sgen.at[gid, "p_mw"] = 0
@@ -111,7 +111,7 @@ def test_continuous_i():
pp.runpp(net, run_control=True)
# we expect the tap to converge at upper voltage limit and not to go beyond
- assert abs(net.res_bus.vm_pu.at[c.controlled_bus] - 1.05) < eps
+ assert abs(net.res_bus.vm_pu.at[c.trafobus] - 1.05) < eps
if __name__ == '__main__':
pytest.main([__file__, "-xs"])
\ No newline at end of file
diff --git a/pandapower/test/converter/test_from_cim.py b/pandapower/test/converter/test_from_cim.py
index ad34382aa..6faf2220a 100644
--- a/pandapower/test/converter/test_from_cim.py
+++ b/pandapower/test/converter/test_from_cim.py
@@ -1106,7 +1106,7 @@ def test_fullgrid_bus(fullgrid_v2):
assert 'tp' == element_0['origin_profile'].item()
assert '_4c66b132-0977-1e4c-b9bb-d8ce2e912e35' == element_0['cim_topnode'].item()
assert math.isnan(element_0['ConnectivityNodeContainer_id'].item())
- assert math.isnan(element_0['substation_id'].item())
+ assert math.isnan(element_0['Substation_id'].item())
assert 'BBRUS151; BGENT_51' == element_0['description'].item()
element_1 = fullgrid_v2.bus[fullgrid_v2.bus['origin_id'] == '_1098b1c9-dc85-40ce-b65c-39ae02a3afaa']
diff --git a/pandapower/test/loadflow/test_results.py b/pandapower/test/loadflow/test_results.py
index 9f5c98e8a..c20882ab7 100644
--- a/pandapower/test/loadflow/test_results.py
+++ b/pandapower/test/loadflow/test_results.py
@@ -6,7 +6,7 @@
import pandas as pd
import pytest
import numpy as np
-from numpy import in1d, isnan, isclose, allclose
+from numpy import isin, isnan, isclose, allclose
import pandapower as pp
import pandapower.control
@@ -644,7 +644,7 @@ def test_trafo3w(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=2e-2, l_tol=
@pytest.mark.parametrize("tap_pos", (-1, 2))
@pytest.mark.parametrize("tap_side", ('hv', 'mv', 'lv'))
-@pytest.mark.parametrize("tap_step_degree", (15, 30))
+@pytest.mark.parametrize("tap_step_degree", (0, 15, 30))
def test_trafo3w_tap(tap_pos, tap_side, tap_step_degree):
results = pd.read_csv(os.path.join(pp.pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results.csv"), sep=";", decimal=",")
@@ -670,6 +670,41 @@ def test_trafo3w_tap(tap_pos, tap_side, tap_step_degree):
"index==@index & element=='bus' & variable==@variable").value,
rtol=0, atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}"
+@pytest.mark.parametrize("tap_pos", (2, 5))
+@pytest.mark.parametrize("tap_side", ('hv', 'mv', 'lv'))
+@pytest.mark.parametrize("tap_step_degree", (0, 15, 30))
+def test_trafo3w_tap_neutral_not_zero(tap_pos, tap_side, tap_step_degree):
+ results = pd.read_csv(os.path.join(pp.pp_dir, "test", "test_files", "test_results_files", "trafo_3w_tap_results_neutral_not_zero.csv"), sep=";", decimal=",")
+
+ if results.query("tap_side == @tap_side & tap_pos == @tap_pos & tap_step_degree == @tap_step_degree").empty:
+ pytest.skip(f"Skipping combination: tap_side={tap_side}, tap_pos={tap_pos}, tap_step_degree={tap_step_degree}")
+
+ net = pp.from_json(os.path.join(pp.pp_dir, "test", "test_files","test_trafo3w_tap.json")) #
+
+ net.trafo3w.loc[[0, 1], 'tap_min'] += 3
+ net.trafo3w.loc[[0, 1], 'tap_max'] += 3
+ net.trafo3w.loc[[0, 1], 'tap_neutral'] += 3
+
+ net.trafo3w.loc[0, 'tap_at_star_point']= False
+ net.trafo3w.loc[1, 'tap_at_star_point']= True
+
+ net.trafo3w.loc[0, "tap_side"] = tap_side
+ net.trafo3w.loc[1, "tap_side"] = tap_side
+ net.trafo3w.loc[0, "tap_pos"] = tap_pos
+ net.trafo3w.loc[1, "tap_pos"] = tap_pos
+ net.trafo3w.loc[0, "tap_step_degree"] = tap_step_degree
+ net.trafo3w.loc[1, "tap_step_degree"] = tap_step_degree
+ pp.runpp(net)
+
+ for index in range(8):
+ for variable, tol in zip(("vm_pu", "va_degree"), (1e-6, 1e-3)):
+ assert np.isclose(net.res_bus.at[index, variable], results.query(
+ "tap_side==@tap_side & tap_pos==@tap_pos & tap_step_degree==@tap_step_degree &"
+ "index==@index & element=='bus' & variable==@variable").value,
+ rtol=0, atol=tol), f"failed for bus {index=}, {variable}, value {net.res_bus.at[index, variable]}"
+
+
+
def test_impedance(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_tol=1e-3):
net = result_test_network
buses = net.bus[net.bus.zone == "test_impedance"]
@@ -815,7 +850,7 @@ def test_shunt_split(result_test_network, v_tol=1e-6, i_tol=1e-6, s_tol=5e-3, l_
def test_open(result_test_network):
net = result_test_network
buses = net.bus[net.bus.zone == "two_open_switches_on_deactive_line"]
- lines = net['line'][in1d(net['line'].from_bus, buses.index) | in1d(net['line'].to_bus, buses.index)]
+ lines = net['line'][isin(net['line'].from_bus, buses.index) | isin(net['line'].to_bus, buses.index)]
assert isnan(net['res_line'].at[lines.index[1], "i_ka"])
diff --git a/pandapower/test/loadflow/test_runpp.py b/pandapower/test/loadflow/test_runpp.py
index 957dca777..278fdb353 100644
--- a/pandapower/test/loadflow/test_runpp.py
+++ b/pandapower/test/loadflow/test_runpp.py
@@ -578,6 +578,17 @@ def test_bsfw_algorithm_with_branch_loops():
assert np.allclose(va_nr, va_alg)
+def test_disabling_vk_update():
+ net = example_simple()
+ pp.runpp(net, calculate_voltage_angles="auto")
+ net.trafo.loc[:, "vk_percent"] = 100.
+ net.trafo.loc[:, "vkr_percent"] = 100.
+
+ pp.runpp(net, calculate_voltage_angles="auto", update_vk_values=False)
+
+ assert net.res_trafo.loc[0, 'loading_percent'] > 70.
+
+
@pytest.mark.slow
def test_pypower_algorithms_iter():
alg_to_test = ['fdbx', 'fdxb', 'gs']
diff --git a/pandapower/test/opf/test_pandamodels_runpm.py b/pandapower/test/opf/test_pandamodels_runpm.py
index 4c5e4b8f3..ff874a2ac 100644
--- a/pandapower/test/opf/test_pandamodels_runpm.py
+++ b/pandapower/test/opf/test_pandamodels_runpm.py
@@ -208,7 +208,7 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf):
pp.create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=2)
# pp.runopp(net)
- pp.runpm_ac_opf(net, correct_pm_network_data=False)
+ pp.runpm_ac_opf(net)
consistency_checks(net)
np.allclose(p_gen, net.res_gen.p_mw.values)
@@ -217,7 +217,7 @@ def test_compare_pwl_and_poly(net_3w_trafo_opf):
np.allclose(va_bus, net.res_bus.va_degree.values)
# pp.rundcopp(net)
- pp.runpm_dc_opf(net, correct_pm_network_data=False)
+ pp.runpm_dc_opf(net)
consistency_checks(net, test_q=False)
np.allclose(p_gen, net.res_gen.p_mw.values)
diff --git a/pandapower/test/plotting/test_geo.py b/pandapower/test/plotting/test_geo.py
index 2559bb0a8..a3aac1c1e 100644
--- a/pandapower/test/plotting/test_geo.py
+++ b/pandapower/test/plotting/test_geo.py
@@ -10,6 +10,7 @@
import geojson
import pandas as pd
import pytest
+from pandas.testing import assert_frame_equal, assert_index_equal
import pandapower.plotting.geo as geo
from pandapower.test.helper_functions import create_test_network
@@ -54,30 +55,48 @@ def get_network_and_result(net, request):
def test__node_geometries_from_geodata(get_network_and_result):
pytest.importorskip("geopandas")
- from geopandas import testing
_net, expected = get_network_and_result
_bus_geojson_to_geodata_(_net)
result = geo._node_geometries_from_geodata(_net.bus_geodata)
- testing.assert_geodataframe_equal(result, expected)
+ # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function
+ # can't be adapted
+ assert result.shape == expected.shape
+ assert isinstance(result, type(expected))
+ assert (result.geom_equals_exact(expected.geometry, tolerance=1 * 10 ** (-6)) |
+ (result.geometry.is_empty & expected.geometry.is_empty) |
+ (result.geometry.isna() & expected.geometry.isna())).all()
+ left2 = result.select_dtypes(exclude="geometry")
+ right2 = expected.select_dtypes(exclude="geometry")
+ assert_index_equal(result.columns, expected.columns, exact="equiv", obj="GeoDataFrame.columns")
+ assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv", obj="GeoDataFrame")
def test__branch_geometries_from_geodata(get_network_and_result):
pytest.importorskip("geopandas")
- from geopandas import testing
_net, expected = get_network_and_result
_line_geojson_to_geodata_(_net)
result = geo._branch_geometries_from_geodata(_net.line_geodata)
- testing.assert_geodataframe_equal(result, expected)
+ # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function
+ # can't be adapted
+ assert result.shape == expected.shape
+ assert isinstance(result, type(expected))
+ assert (result.geom_equals_exact(expected.geometry, tolerance=1 * 10 ** (-6)) |
+ (result.geometry.is_empty & expected.geometry.is_empty) |
+ (result.geometry.isna() & expected.geometry.isna())).all()
+ left2 = result.select_dtypes(exclude="geometry")
+ right2 = expected.select_dtypes(exclude="geometry")
+ assert_index_equal(result.columns, expected.columns, exact="equiv", obj="GeoDataFrame.columns")
+ assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv",
+ obj="GeoDataFrame")
def test__transform_node_geometry_to_geodata(get_network_and_result):
pytest.importorskip("geopandas")
- from geopandas import testing
_net, expected = get_network_and_result
_bus_geojson_to_geodata_(_net)
@@ -85,19 +104,40 @@ def test__transform_node_geometry_to_geodata(get_network_and_result):
# Transforming to geodata to test the inverse...
_net.bus_geodata = geo._node_geometries_from_geodata(_net.bus_geodata)
result = geo._transform_node_geometry_to_geodata(_net.bus_geodata)
- testing.assert_geodataframe_equal(result, expected)
+ # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function
+ # can't be adapted
+ assert result.shape == expected.shape
+ assert isinstance(result, type(expected))
+ assert (result.geom_equals_exact(expected.geometry, tolerance=1 * 10 ** (-6)) |
+ (result.geometry.is_empty & expected.geometry.is_empty) |
+ (result.geometry.isna() & expected.geometry.isna())).all()
+ left2 = result.select_dtypes(exclude="geometry")
+ right2 = expected.select_dtypes(exclude="geometry")
+ assert_index_equal(result.columns, expected.columns, exact="equiv", obj="GeoDataFrame.columns")
+ assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv",
+ obj="GeoDataFrame")
def test__transform_branch_geometry_to_coords(get_network_and_result):
pytest.importorskip("geopandas")
- from geopandas import testing
_net, expected = get_network_and_result
_line_geojson_to_geodata_(_net)
_net.line_geodata = geo._branch_geometries_from_geodata(_net.line_geodata)
result = geo._transform_branch_geometry_to_coords(_net.line_geodata)
- testing.assert_geodataframe_equal(result, expected)
+ # is mostly the same as assert_geodataframe_equal with check_less_precise=True, but the tolerance in the function
+ # can't be adapted
+ assert result.shape == expected.shape
+ assert isinstance(result, type(expected))
+ assert (result.geom_equals_exact(expected.geometry, tolerance=1 * 10 ** (-6)) |
+ (result.geometry.is_empty & expected.geometry.is_empty) |
+ (result.geometry.isna() & expected.geometry.isna())).all()
+ left2 = result.select_dtypes(exclude="geometry")
+ right2 = expected.select_dtypes(exclude="geometry")
+ assert_index_equal(result.columns, expected.columns, exact="equiv", obj="GeoDataFrame.columns")
+ assert_frame_equal(left2, right2, check_dtype=True, check_index_type="equiv", check_column_type="equiv",
+ obj="GeoDataFrame")
def test__convert_xy_epsg():
@@ -261,7 +301,6 @@ def test_dump_to_geojson():
assert dumps(result, sort_keys=True) == '{"features": [{"geometry": {"coordinates": [[1.0, 2.0], [3.0, 4.0]], "type": "LineString"}, "id": "line-0", "properties": {"c_nf_per_km": 720.0, "df": 1.0, "from_bus": 1, "g_us_per_km": 0.0, "i_from_ka": 7.0, "i_ka": 7.0, "i_to_ka": 7.0, "ices": 0.389985, "in_service": true, "length_km": 1.0, "loading_percent": 7.0, "max_i_ka": 0.328, "name": "line1", "p_from_mw": 7.0, "p_to_mw": 7.0, "parallel": 1, "pl_mw": 7.0, "pp_index": 0, "pp_type": "line", "q_from_mvar": 7.0, "q_to_mvar": 7.0, "ql_mvar": 7.0, "r_ohm_per_km": 0.2067, "std_type": null, "to_bus": 7, "type": null, "va_from_degree": 7.0, "va_to_degree": 7.0, "vm_from_pu": 7.0, "vm_to_pu": 7.0, "x_ohm_per_km": 0.1897522}, "type": "Feature"}], "type": "FeatureCollection"}'
-
def test_convert_geodata_to_geojson():
pytest.importorskip("geojson")
pytest.importorskip("pandapower")
@@ -295,6 +334,5 @@ def test_convert_gis_to_geojson():
pytest.skip("Not implemented")
-
if __name__ == "__main__":
pytest.main(["test_geo.py"])
diff --git a/pandapower/test/test_files/test_results_files/trafo_3w_tap_results_neutral_not_zero.csv b/pandapower/test/test_files/test_results_files/trafo_3w_tap_results_neutral_not_zero.csv
new file mode 100644
index 000000000..6e07ba49b
--- /dev/null
+++ b/pandapower/test/test_files/test_results_files/trafo_3w_tap_results_neutral_not_zero.csv
@@ -0,0 +1,129 @@
+tap_side;tap_pos;tap_step_degree;element;name;index;variable;value
+hv;5;0;bus;0_Slack;0;vm_pu;1
+hv;5;0;bus;0_Slack;0;va_degree;0
+hv;5;0;bus;1_HV;1;vm_pu;0,998129
+hv;5;0;bus;1_HV;1;va_degree;-0,093039
+hv;5;0;bus;2_MV;2;vm_pu;0,898854
+hv;5;0;bus;2_MV;2;va_degree;-0,686136
+hv;5;0;bus;3_LV;3;vm_pu;0,903326
+hv;5;0;bus;3_LV;3;va_degree;-0,394202
+hv;5;0;bus;4_Slack;4;vm_pu;1
+hv;5;0;bus;4_Slack;4;va_degree;0
+hv;5;0;bus;5_HV;5;vm_pu;0,998127
+hv;5;0;bus;5_HV;5;va_degree;-0,092972
+hv;5;0;bus;6_MV;6;vm_pu;0,898367
+hv;5;0;bus;6_MV;6;va_degree;-0,723542
+hv;5;0;bus;7_LV;7;vm_pu;0,902842
+hv;5;0;bus;7_LV;7;va_degree;-0,431292
+hv;2;0;bus;0_Slack;0;vm_pu;1
+hv;2;0;bus;0_Slack;0;va_degree;0
+hv;2;0;bus;1_HV;1;vm_pu;0,998009
+hv;2;0;bus;1_HV;1;va_degree;-0,092674
+hv;2;0;bus;2_MV;2;vm_pu;1,042353
+hv;2;0;bus;2_MV;2;va_degree;-0,583495
+hv;2;0;bus;3_LV;3;vm_pu;1,046203
+hv;2;0;bus;3_LV;3;va_degree;-0,366142
+hv;2;0;bus;4_Slack;4;vm_pu;1
+hv;2;0;bus;4_Slack;4;va_degree;0
+hv;2;0;bus;5_HV;5;vm_pu;0,99801
+hv;2;0;bus;5_HV;5;va_degree;-0,092708
+hv;2;0;bus;6_MV;6;vm_pu;1,042629
+hv;2;0;bus;6_MV;6;va_degree;-0,565781
+hv;2;0;bus;7_LV;7;vm_pu;1,046477
+hv;2;0;bus;7_LV;7;va_degree;-0,348542
+mv;5;0;bus;0_Slack;0;vm_pu;1
+mv;5;0;bus;0_Slack;0;va_degree;0
+mv;5;0;bus;1_HV;1;vm_pu;0,998058
+mv;5;0;bus;1_HV;1;va_degree;-0,092876
+mv;5;0;bus;2_MV;2;vm_pu;1,089856
+mv;5;0;bus;2_MV;2;va_degree;-0,555702
+mv;5;0;bus;3_LV;3;vm_pu;0,993842
+mv;5;0;bus;3_LV;3;va_degree;-0,374824
+mv;5;0;bus;4_Slack;4;vm_pu;1
+mv;5;0;bus;4_Slack;4;va_degree;0
+mv;5;0;bus;5_HV;5;vm_pu;0,998055
+mv;5;0;bus;5_HV;5;va_degree;-0,092822
+mv;5;0;bus;6_MV;6;vm_pu;1,088759
+mv;5;0;bus;6_MV;6;va_degree;-0,61575
+mv;5;0;bus;7_LV;7;vm_pu;0,993837
+mv;5;0;bus;7_LV;7;va_degree;-0,374788
+mv;2;0;bus;0_Slack;0;vm_pu;1
+mv;2;0;bus;0_Slack;0;va_degree;0
+mv;2;0;bus;1_HV;1;vm_pu;0,998054
+mv;2;0;bus;1_HV;1;va_degree;-0,092788
+mv;2;0;bus;2_MV;2;vm_pu;0,9397
+mv;2;0;bus;2_MV;2;va_degree;-0,653191
+mv;2;0;bus;3_LV;3;vm_pu;0,993834
+mv;2;0;bus;3_LV;3;va_degree;-0,374766
+mv;2;0;bus;4_Slack;4;vm_pu;1
+mv;2;0;bus;4_Slack;4;va_degree;0
+mv;2;0;bus;5_HV;5;vm_pu;0,998055
+mv;2;0;bus;5_HV;5;va_degree;-0,092822
+mv;2;0;bus;6_MV;6;vm_pu;0,940291
+mv;2;0;bus;6_MV;6;va_degree;-0,61575
+mv;2;0;bus;7_LV;7;vm_pu;0,993837
+mv;2;0;bus;7_LV;7;va_degree;-0,374788
+lv;5;0;bus;0_Slack;0;vm_pu;1
+lv;5;0;bus;0_Slack;0;va_degree;0
+lv;5;0;bus;1_HV;1;vm_pu;0,998056
+lv;5;0;bus;1_HV;1;va_degree;-0,092829
+lv;5;0;bus;2_MV;2;vm_pu;0,989781
+lv;5;0;bus;2_MV;2;va_degree;-0,615751
+lv;5;0;bus;3_LV;3;vm_pu;1,093532
+lv;5;0;bus;3_LV;3;va_degree;-0,356789
+lv;5;0;bus;4_Slack;4;vm_pu;1
+lv;5;0;bus;4_Slack;4;va_degree;0
+lv;5;0;bus;5_HV;5;vm_pu;0,998055
+lv;5;0;bus;5_HV;5;va_degree;-0,092822
+lv;5;0;bus;6_MV;6;vm_pu;0,98978
+lv;5;0;bus;6_MV;6;va_degree;-0,61575
+lv;5;0;bus;7_LV;7;vm_pu;1,093221
+lv;5;0;bus;7_LV;7;va_degree;-0,374788
+lv;2;0;bus;0_Slack;0;vm_pu;1
+lv;2;0;bus;0_Slack;0;va_degree;0
+lv;2;0;bus;1_HV;1;vm_pu;0,998055
+lv;2;0;bus;1_HV;1;va_degree;-0,092817
+lv;2;0;bus;2_MV;2;vm_pu;0,98978
+lv;2;0;bus;2_MV;2;va_degree;-0,61575
+lv;2;0;bus;3_LV;3;vm_pu;0,943978
+lv;2;0;bus;3_LV;3;va_degree;-0,385997
+lv;2;0;bus;4_Slack;4;vm_pu;1
+lv;2;0;bus;4_Slack;4;va_degree;0
+lv;2;0;bus;5_HV;5;vm_pu;0,998055
+lv;2;0;bus;5_HV;5;va_degree;-0,092822
+lv;2;0;bus;6_MV;6;vm_pu;0,98978
+lv;2;0;bus;6_MV;6;va_degree;-0,61575
+lv;2;0;bus;7_LV;7;vm_pu;0,944145
+lv;2;0;bus;7_LV;7;va_degree;-0,374788
+hv;5;15;bus;0_Slack;0;vm_pu;1
+hv;5;15;bus;0_Slack;0;va_degree;0
+hv;5;15;bus;1_HV;1;vm_pu;0,998127
+hv;5;15;bus;1_HV;1;va_degree;-0,093034
+hv;5;15;bus;2_MV;2;vm_pu;0,901427
+hv;5;15;bus;2_MV;2;va_degree;-2,035887
+hv;5;15;bus;3_LV;3;vm_pu;0,905886
+hv;5;15;bus;3_LV;3;va_degree;-1,74561
+hv;5;15;bus;4_Slack;4;vm_pu;1
+hv;5;15;bus;4_Slack;4;va_degree;0
+hv;5;15;bus;5_HV;5;vm_pu;0,998125
+hv;5;15;bus;5_HV;5;va_degree;-0,092969
+hv;5;15;bus;6_MV;6;vm_pu;0,900955
+hv;5;15;bus;6_MV;6;va_degree;-2,07209
+hv;5;15;bus;7_LV;7;vm_pu;0,905417
+hv;5;15;bus;7_LV;7;va_degree;-1,781509
+hv;2;30;bus;0_Slack;0;vm_pu;1
+hv;2;30;bus;0_Slack;0;va_degree;0
+hv;2;30;bus;1_HV;1;vm_pu;0,998016
+hv;2;30;bus;1_HV;1;va_degree;-0,092697
+hv;2;30;bus;2_MV;2;vm_pu;1,034638
+hv;2;30;bus;2_MV;2;va_degree;0,908979
+hv;2;30;bus;3_LV;3;vm_pu;1,038516
+hv;2;30;bus;3_LV;3;va_degree;1,129574
+hv;2;30;bus;4_Slack;4;vm_pu;1
+hv;2;30;bus;4_Slack;4;va_degree;0
+hv;2;30;bus;5_HV;5;vm_pu;0,998017
+hv;2;30;bus;5_HV;5;va_degree;-0,092725
+hv;2;30;bus;6_MV;6;vm_pu;1,034873
+hv;2;30;bus;6_MV;6;va_degree;0,924241
+hv;2;30;bus;7_LV;7;vm_pu;1,038751
+hv;2;30;bus;7_LV;7;va_degree;1,144736
diff --git a/pandapower/test/toolbox/test_grid_modification.py b/pandapower/test/toolbox/test_grid_modification.py
index 717759016..bb19022db 100644
--- a/pandapower/test/toolbox/test_grid_modification.py
+++ b/pandapower/test/toolbox/test_grid_modification.py
@@ -213,6 +213,22 @@ def test_merge_with_characteristics():
assert merged.trafo.loc[1, "vk_percent_characteristic"] == 1
+def test_merge_nets_with_custom_elements():
+ from pandapower.networks.simple_pandapower_test_networks import simple_four_bus_system
+
+ df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
+ # create two networks
+ net1 = simple_four_bus_system()
+ net2 = simple_four_bus_system()
+
+ net2["test"] = df.copy()
+ res_net1 = pp.merge_nets(net1, net2, validate=False)
+ res_net2 = pp.merge_nets(net2, net1, validate=False)
+ assert df.equals(res_net1["test"])
+ assert df.equals(res_net2["test"])
+ assert pp.nets_equal(res_net1, res_net2)
+
+
def test_select_subnet():
# This network has switches of type 'l' and 't'
net = nw.create_cigre_network_mv()
diff --git a/pandapower/timeseries/read_batch_results.py b/pandapower/timeseries/read_batch_results.py
index 3f6f1c352..44cf62346 100644
--- a/pandapower/timeseries/read_batch_results.py
+++ b/pandapower/timeseries/read_batch_results.py
@@ -2,7 +2,7 @@
from numpy import real, vectorize, deg2rad, maximum, sqrt, empty, zeros, nan, int64
-from pandapower import F_BUS, T_BUS
+from pandapower.pypower.idx_brch import F_BUS, T_BUS
from pandapower.pf.pfsoln_numba import calc_branch_flows_batch
from pandapower.pypower.idx_bus import BASE_KV
from pandapower.results_branch import _get_trafo3w_lookups
diff --git a/pandapower/timeseries/run_time_series.py b/pandapower/timeseries/run_time_series.py
index 5822b8d98..d382cb8cd 100644
--- a/pandapower/timeseries/run_time_series.py
+++ b/pandapower/timeseries/run_time_series.py
@@ -7,8 +7,7 @@
import tqdm
import pandapower as pp
-from pandapower import LoadflowNotConverged, OPFNotConverged
-from pandapower.auxiliary import ControllerNotConverged, NetCalculationNotConverged
+from pandapower.auxiliary import ControllerNotConverged
from pandapower.control import prepare_run_ctrl, run_control
from pandapower.control.util.diagnostic import control_diagnostic
from pandapower.timeseries.output_writer import OutputWriter
diff --git a/pandapower/timeseries/ts_runpp.py b/pandapower/timeseries/ts_runpp.py
index 431f02920..708eeb3b6 100644
--- a/pandapower/timeseries/ts_runpp.py
+++ b/pandapower/timeseries/ts_runpp.py
@@ -1,6 +1,4 @@
import inspect
-import collections
-import functools
import numpy as np
from numpy import complex128, zeros
@@ -12,20 +10,17 @@
from pandapower.control.controller.trafo_control import TrafoController
from pandapower.auxiliary import _clean_up
from pandapower.build_branch import _calc_trafo_parameter, _calc_trafo3w_parameter
-from pandapower.build_bus import _calc_pq_elements_and_add_on_ppc, \
- _calc_shunts_and_add_on_ppc
-from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_R, BR_X, BR_B, TAP, SHIFT, BR_STATUS, RATE_A
+from pandapower.build_bus import _calc_pq_elements_and_add_on_ppc
from pandapower.pypower.idx_bus import PD, QD
from pandapower.pd2ppc import _pd2ppc
from pandapower.pypower.idx_bus_dc import DC_PD
-from pandapower.pypower.makeSbus import _get_Sbus, _get_Cg, makeSbus
+from pandapower.pypower.makeSbus import makeSbus
from pandapower.pf.pfsoln_numba import pfsoln as pfsoln_full, pf_solution_single_slack
from pandapower.powerflow import LoadflowNotConverged, _add_auxiliary_elements
from pandapower.results import _copy_results_ppci_to_ppc, _extract_results, _get_aranged_lookup
from pandapower.results_branch import _get_branch_flows, _get_line_results, _get_trafo3w_results, _get_trafo_results
-from pandapower.results_bus import write_pq_results_to_element, _get_bus_v_results, _get_bus_results, _get_bus_dc_results
+from pandapower.results_bus import _get_bus_results, _get_bus_dc_results
from pandapower.results_gen import _get_gen_results
-from pandapower.timeseries.output_writer import OutputWriter
try:
import pandaplan.core.pplog as logging
diff --git a/pandapower/toolbox/data_modification.py b/pandapower/toolbox/data_modification.py
index a8164fedb..87e2f6b77 100644
--- a/pandapower/toolbox/data_modification.py
+++ b/pandapower/toolbox/data_modification.py
@@ -376,7 +376,7 @@ def create_continuous_elements_index(net, start=0, add_df_to_reindex=set()):
if et in net and isinstance(net[et], pd.DataFrame):
if et in ["bus_geodata", "line_geodata"]:
- logger.info(et + " don't need to bo included to 'add_df_to_reindex'. It is " +
+ logger.info(et + " don't need to be included to 'add_df_to_reindex'. It is " +
"already included by et=='" + et.split("_")[0] + "'.")
else:
reindex_elements(net, et, new_index)
diff --git a/pandapower/toolbox/element_selection.py b/pandapower/toolbox/element_selection.py
index a473b80c6..dc606e7dd 100644
--- a/pandapower/toolbox/element_selection.py
+++ b/pandapower/toolbox/element_selection.py
@@ -12,7 +12,7 @@
from pandapower.auxiliary import ets_to_element_types
-from pandapower import __version__
+from pandapower._version import __version__
try:
import pandaplan.core.pplog as logging
diff --git a/pandapower/topology/create_graph.py b/pandapower/topology/create_graph.py
index 0b1d07cab..cc6b06f69 100644
--- a/pandapower/topology/create_graph.py
+++ b/pandapower/topology/create_graph.py
@@ -148,7 +148,7 @@ def create_nxgraph(net, respect_switches=True, include_lines=True, include_imped
mask = (net.switch.et.values == "l") & open_sw
if mask.any():
open_lines = net.switch.element.values[mask]
- open_lines_mask = np.in1d(indices[:, INDEX], open_lines)
+ open_lines_mask = np.isin(indices[:, INDEX], open_lines)
in_service &= ~open_lines_mask
parameter[:, WEIGHT] = line.length_km.values
@@ -221,7 +221,7 @@ def create_nxgraph(net, respect_switches=True, include_lines=True, include_imped
mask = (net.switch.et.values == "t") & open_sw
if mask.any():
open_trafos = net.switch.element.values[mask]
- open_trafos_mask = np.in1d(indices[:, INDEX], open_trafos)
+ open_trafos_mask = np.isin(indices[:, INDEX], open_trafos)
in_service &= ~open_trafos_mask
if calc_branch_impedances:
@@ -264,7 +264,7 @@ def create_nxgraph(net, respect_switches=True, include_lines=True, include_imped
if respect_switches and len(open_trafo3w):
for BUS in [F_BUS, T_BUS]:
- open_switch = np.in1d(indices[:, INDEX] + indices[:, BUS] * 1j,
+ open_switch = np.isin(indices[:, INDEX] + indices[:, BUS] * 1j,
open_trafo3w)
in_service &= ~open_switch
if calc_branch_impedances:
diff --git a/pyproject.toml b/pyproject.toml
index 06b2411a8..98b08cea7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,6 +42,7 @@ dependencies = [
"tqdm",
"deepdiff",
"geojson",
+ "lxml",
"typing_extensions~=4.9",
]
keywords = [
@@ -61,8 +62,8 @@ Changelog = "https://github.com/e2nIEE/pandapower/blob/develop/CHANGELOG.rst"
docs = ["numpydoc", "matplotlib", "sphinx", "sphinx_rtd_theme", "sphinx-pyproject"]
plotting = ["plotly>=3.1.1", "matplotlib", "igraph", "geopandas>=1.0"]
test = ["pytest~=8.1", "pytest-xdist", "nbmake"]
-performance = ["ortools", "numba>=0.25", "lightsim2grid>=0.9.0"]
-fileio = ["xlsxwriter", "openpyxl", "cryptography", "geopandas", "psycopg2"]
+performance = ["ortools", "numba>=0.25", "lightsim2grid==0.9.0"]
+fileio = ["xlsxwriter", "openpyxl", "cryptography", "geopandas>=1.0", "psycopg2"]
converter = ["matpowercaseframes"]
pgm = ["power-grid-model-io"]
control = ["shapely"]
@@ -70,7 +71,7 @@ all = [
"numpydoc", "sphinx", "sphinx_rtd_theme", "sphinx-pyproject",
"plotly>=3.1.1", "matplotlib", "igraph", "geopandas>=1.0",
"pytest~=8.1", "pytest-xdist", "nbmake",
- "ortools", "numba>=0.25", "lightsim2grid>=0.9.0",
+ "ortools", "numba>=0.25", "lightsim2grid==0.9.0",
"xlsxwriter", "openpyxl", "cryptography", "psycopg2",
"matpowercaseframes",
"power-grid-model-io"
diff --git a/tutorials/Working with GeoJSON.ipynb b/tutorials/Working with GeoJSON.ipynb
new file mode 100644
index 000000000..5ea820028
--- /dev/null
+++ b/tutorials/Working with GeoJSON.ipynb
@@ -0,0 +1,7915 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "61a0f50a-318c-4a8b-98e9-17c3bc14b839",
+ "metadata": {},
+ "source": [
+ "## Working with GeoJSON"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dc6d7b2d-deb2-4da2-aa31-420c66b63edf",
+ "metadata": {},
+ "source": [
+ "In the 3.0 release of pandapower, significant changes have been made to how geospatial data is stored in the net object. Previously, geospatial data was stored in the *line_geodata* and *bus_geodata* tables. However, this structure caused several problems:\n",
+ "\n",
+ "- In what projection are the data points stored?\n",
+ "- What do x and y represent? Does x represent latitude, longitude or something else?\n",
+ "- Copmatibility issues with frontend services and QGIS\n",
+ "\n",
+ "To resolve this ambiguity, all geospatial data has now been moved to the line and bus tables under the *geo* column. The geometries are stored as GeoJSON objects. [GeoJSON](https://datatracker.ietf.org/doc/html/rfc7946) is a widely used standard for geospatial data, supporting points, lines, and polygons in a unified format with explicit projection definitions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "fe634b5e-44ca-43f3-befb-1aecbe995a56",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandapower as pp\n",
+ "import pandapower.networks as pn\n",
+ "import pandas as pd\n",
+ "pd.set_option(\"display.max_colwidth\", 120)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "08f8a836-ea70-4f20-af4b-3f25166fa9cd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "net = pn.mv_oberrhein()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "2bed640f-1894-4b71-9b93-8899dd047f6c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 {\"coordinates\": [[7.8947079593416, 48.40549007606241], [7.896048283667894, 48.41060722903666], [7.896173712216692, 4...\n",
+ "1 {\"coordinates\": [[7.8947079593416, 48.40549007606241], [7.892690190852129, 48.40551636934287], [7.887502065342014, 4...\n",
+ "2 {\"coordinates\": [[7.8947079593416, 48.40549007606241], [7.895064345442788, 48.40360449047714]], \"type\": \"LineString\"}\n",
+ "3 {\"coordinates\": [[7.895064345442788, 48.40360449047714], [7.89613191775149, 48.39796660294922]], \"type\": \"LineString\"}\n",
+ "4 {\"coordinates\": [[7.89613191775149, 48.39796660294922], [7.897077173332039, 48.39788292247765], [7.9009358501319475,...\n",
+ "Name: geo, dtype: object \n",
+ "\n",
+ "0 {\"coordinates\": [7.765225672614365, 48.41091584192147], \"type\": \"Point\"}\n",
+ "1 {\"coordinates\": [7.778809539550178, 48.40987064550492], \"type\": \"Point\"}\n",
+ "2 {\"coordinates\": [7.779195765893586, 48.4120381144602], \"type\": \"Point\"}\n",
+ "3 {\"coordinates\": [7.775204689771646, 48.40610336882051], \"type\": \"Point\"}\n",
+ "4 {\"coordinates\": [7.76606484746611, 48.4124244421834], \"type\": \"Point\"}\n",
+ "Name: geo, dtype: object\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(net.line.geo.head(), \"\\n\")\n",
+ "print(net.bus.geo.head())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "74af88da-10fe-43dd-a8ce-6b3ec57ab9ad",
+ "metadata": {},
+ "source": [
+ "To make working with these new geospatial data easier and more efficient, a pandas series accessor has been introduced. This accessor allows direct interaction with GeoJSON data and integrates functions provided by GeoSeries in geopandas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "ee923be1-9fa4-4141-8099-9c2d96b4a169",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from shapely.geometry import shape, Point, Polygon\n",
+ "from geopandas import GeoSeries\n",
+ "from pandapower.plotting import simple_plotly, create_line_trace, create_bus_trace\n",
+ "import plotly.graph_objects as go"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9b18429f-ffae-481b-bbcf-278aeed2fd1e",
+ "metadata": {},
+ "source": [
+ "Create a reference point and a polygon to check what elements are inside a certain radius. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "8de3ac01-8008-42cc-b669-23cf029424e5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reference_point = (7.781067, 48.389774)\n",
+ "radius_m = 2200\n",
+ "circle_polygon = GeoSeries([Point(reference_point)], crs=4326).to_crs(epsg=31467).buffer(radius_m).to_crs(epsg=4326).iloc[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4cea9b32-fe45-4c95-8842-a7e688c82e2f",
+ "metadata": {},
+ "source": [
+ "Access the GeoJSON accessor and the needed GeoSeries methods."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "f1052155-c72c-4ec2-86ec-9b871c2de3f6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([ 7.74426069, 48.32845845, 7.93829196, 48.47484423])"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "lines_intersect = net.line[net.line.geo.geojson.intersects(circle_polygon)].index\n",
+ "buses_within = net.bus[net.bus.geo.geojson.within(circle_polygon)].index\n",
+ "net.line.geo.geojson.total_bounds"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e7966a23-87e9-4dae-a256-c0170234e4fb",
+ "metadata": {},
+ "source": [
+ "And plot the results"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "32231088-02e8-497d-9cae-279aba140370",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " \n",
+ " "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.plotly.v1+json": {
+ "config": {
+ "plotlyServerURL": "https://plot.ly"
+ },
+ "data": [
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": true,
+ "text": "Index: 0
Name: Line 0
Length: 0.586 km
R: 0.094 Ohm
X: 0.069 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89470796,
+ 7.89604828,
+ 7.89617371
+ ],
+ "y": [
+ 48.40549008,
+ 48.41060723,
+ 48.41100311
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 1
Name: Line 1
Length: 1.374 km
R: 0.221 Ohm
X: 0.161 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89470796,
+ 7.89269019,
+ 7.88750207,
+ 7.87852914
+ ],
+ "y": [
+ 48.40549008,
+ 48.40551637,
+ 48.40575964,
+ 48.40552685
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 2
Name: Line 2
Length: 0.206 km
R: 0.033 Ohm
X: 0.024 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89470796,
+ 7.89506435
+ ],
+ "y": [
+ 48.40549008,
+ 48.40360449
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 3
Name: Line 3
Length: 0.617 km
R: 0.099 Ohm
X: 0.072 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89506435,
+ 7.89613192
+ ],
+ "y": [
+ 48.40360449,
+ 48.3979666
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 4
Name: Line 4
Length: 0.382 km
R: 0.061 Ohm
X: 0.045 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89613192,
+ 7.89707717,
+ 7.90093585,
+ 7.90130481
+ ],
+ "y": [
+ 48.3979666,
+ 48.39788292,
+ 48.39783123,
+ 48.39757192
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 5
Name: Line 5
Length: 3.303 km
R: 0.532 Ohm
X: 0.386 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78157825,
+ 7.78241594,
+ 7.78757125,
+ 7.80563692,
+ 7.81137059
+ ],
+ "y": [
+ 48.36717009,
+ 48.367589,
+ 48.37274714,
+ 48.38813105,
+ 48.38535297
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 6
Name: Line 6
Length: 0.35 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78157825,
+ 7.78412315,
+ 7.78580944
+ ],
+ "y": [
+ 48.36717009,
+ 48.3667497,
+ 48.36588431
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 7
Name: Line 7
Length: 0.736 km
R: 0.118 Ohm
X: 0.086 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78157825,
+ 7.78187454,
+ 7.78091314,
+ 7.77915169,
+ 7.77724287,
+ 7.77577656,
+ 7.77569591
+ ],
+ "y": [
+ 48.36717009,
+ 48.36700871,
+ 48.36559507,
+ 48.36620372,
+ 48.36639702,
+ 48.36481251,
+ 48.36446775
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 10
Name: Line 10
Length: 0.313 km
R: 0.05 Ohm
X: 0.037 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76147904,
+ 7.75838011
+ ],
+ "y": [
+ 48.35023997,
+ 48.34834127
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 11
Name: Line 11
Length: 0.258 km
R: 0.042 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75569132,
+ 7.75642284,
+ 7.75645615,
+ 7.75838011
+ ],
+ "y": [
+ 48.34750562,
+ 48.34759206,
+ 48.34812068,
+ 48.34834127
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 12
Name: Line 12
Length: 0.435 km
R: 0.07 Ohm
X: 0.051 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75598728,
+ 7.75493654,
+ 7.75226417,
+ 7.7490983
+ ],
+ "y": [
+ 48.38553948,
+ 48.38515046,
+ 48.38528923,
+ 48.38651875
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 14
Name: Line 14
Length: 0.357 km
R: 0.058 Ohm
X: 0.042 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75598728,
+ 7.75586722,
+ 7.7565325,
+ 7.75620547,
+ 7.75669407,
+ 7.75527749
+ ],
+ "y": [
+ 48.38553948,
+ 48.38577499,
+ 48.38647184,
+ 48.38674957,
+ 48.38741536,
+ 48.38787178
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 15
Name: Line 15
Length: 0.254 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81672668,
+ 7.81622594,
+ 7.81440186
+ ],
+ "y": [
+ 48.38789817,
+ 48.38787587,
+ 48.38940745
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 16
Name: Line 16
Length: 0.635 km
R: 0.102 Ohm
X: 0.074 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81192866,
+ 7.81348597,
+ 7.81397942,
+ 7.81428296,
+ 7.81686386,
+ 7.81672668
+ ],
+ "y": [
+ 48.38755402,
+ 48.38824938,
+ 48.38770218,
+ 48.38637651,
+ 48.38743514,
+ 48.38789817
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 17
Name: Line 17
Length: 1.3 km
R: 0.209 Ohm
X: 0.152 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76396796,
+ 7.77111891
+ ],
+ "y": [
+ 48.39721686,
+ 48.40810119
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 18
Name: Line 18
Length: 0.139 km
R: 0.022 Ohm
X: 0.016 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77111891,
+ 7.76965603,
+ 7.76946387
+ ],
+ "y": [
+ 48.40810119,
+ 48.40897041,
+ 48.40913221
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 20
Name: Line 20
Length: 0.632 km
R: 0.102 Ohm
X: 0.074 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.83613832,
+ 7.83612548,
+ 7.83739965,
+ 7.84120448,
+ 7.84164512
+ ],
+ "y": [
+ 48.40115573,
+ 48.40114719,
+ 48.40180507,
+ 48.40398808,
+ 48.40414471
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 21
Name: Line 21
Length: 0.112 km
R: 0.018 Ohm
X: 0.013 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.83613832,
+ 7.83578331,
+ 7.83571694
+ ],
+ "y": [
+ 48.40115573,
+ 48.40022903,
+ 48.40021513
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 22
Name: Line 22
Length: 0.312 km
R: 0.05 Ohm
X: 0.036 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8893131,
+ 7.88800433,
+ 7.88846812
+ ],
+ "y": [
+ 48.41271759,
+ 48.41442695,
+ 48.41556286
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 24
Name: Line 24
Length: 0.695 km
R: 0.112 Ohm
X: 0.081 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88846812,
+ 7.8790417
+ ],
+ "y": [
+ 48.41556286,
+ 48.41572609
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 25
Name: Line 25
Length: 0.235 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90130341,
+ 7.90201885,
+ 7.90263858
+ ],
+ "y": [
+ 48.41377255,
+ 48.41396058,
+ 48.4152001
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 26
Name: Line 26
Length: 0.561 km
R: 0.09 Ohm
X: 0.066 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89638358,
+ 7.89759947,
+ 7.89789524,
+ 7.90183054,
+ 7.90263858
+ ],
+ "y": [
+ 48.41424248,
+ 48.41442463,
+ 48.41538087,
+ 48.41552371,
+ 48.4152001
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 27
Name: Line 27
Length: 0.522 km
R: 0.084 Ohm
X: 0.061 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81091684,
+ 7.80981003,
+ 7.81328782
+ ],
+ "y": [
+ 48.43490897,
+ 48.43301239,
+ 48.43169169
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 28
Name: Line 28
Length: 0.283 km
R: 0.034 Ohm
X: 0.032 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81328782,
+ 7.81279149,
+ 7.81092206,
+ 7.80946722
+ ],
+ "y": [
+ 48.43169169,
+ 48.43138573,
+ 48.43111791,
+ 48.43003727
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 29
Name: Line 29
Length: 1.688 km
R: 0.272 Ohm
X: 0.197 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81593058,
+ 7.81744827,
+ 7.8154392,
+ 7.81828689,
+ 7.82563195,
+ 7.82449029
+ ],
+ "y": [
+ 48.46357677,
+ 48.46330569,
+ 48.4608867,
+ 48.45821173,
+ 48.45715225,
+ 48.45412175
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 30
Name: Line 30
Length: 1.073 km
R: 0.173 Ohm
X: 0.125 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80501543,
+ 7.8082015,
+ 7.81153875,
+ 7.81182781,
+ 7.81550992,
+ 7.81538774,
+ 7.81593058
+ ],
+ "y": [
+ 48.46296614,
+ 48.46152072,
+ 48.46377225,
+ 48.46392051,
+ 48.46287434,
+ 48.46354503,
+ 48.46357677
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 32
Name: Line 32
Length: 0.324 km
R: 0.052 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81599919,
+ 7.81749857,
+ 7.81777506,
+ 7.8195498
+ ],
+ "y": [
+ 48.45200045,
+ 48.45179274,
+ 48.45227496,
+ 48.45155157
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 34
Name: Line 34
Length: 0.309 km
R: 0.05 Ohm
X: 0.036 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80022205,
+ 7.80011359,
+ 7.80061038,
+ 7.79950378
+ ],
+ "y": [
+ 48.46640752,
+ 48.46713886,
+ 48.46829712,
+ 48.46870231
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 35
Name: Line 35
Length: 0.541 km
R: 0.087 Ohm
X: 0.063 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80752534,
+ 7.80022205
+ ],
+ "y": [
+ 48.46584322,
+ 48.46640752
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 36
Name: Line 36
Length: 0.296 km
R: 0.036 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8060588,
+ 7.80642131,
+ 7.80559996,
+ 7.80673406
+ ],
+ "y": [
+ 48.4359944,
+ 48.43620557,
+ 48.43694878,
+ 48.43815272
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 37
Name: Line 37
Length: 0.48 km
R: 0.059 Ohm
X: 0.054 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8060588,
+ 7.80533577,
+ 7.80519949,
+ 7.80460343,
+ 7.80466609
+ ],
+ "y": [
+ 48.4359944,
+ 48.4362301,
+ 48.43479354,
+ 48.43346182,
+ 48.43251067
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 38
Name: Line 38
Length: 0.711 km
R: 0.084 Ohm
X: 0.228 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76944157,
+ 7.76608392,
+ 7.76574338
+ ],
+ "y": [
+ 48.41414363,
+ 48.41861893,
+ 48.41987793
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 39
Name: Line 39
Length: 0.242 km
R: 0.039 Ohm
X: 0.028 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76944157,
+ 7.76973028,
+ 7.77054216,
+ 7.77150376
+ ],
+ "y": [
+ 48.41414363,
+ 48.41394093,
+ 48.41413473,
+ 48.41297284
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 40
Name: Line 40
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76944157,
+ 7.76840613,
+ 7.76779918,
+ 7.76713218,
+ 7.76659341
+ ],
+ "y": [
+ 48.41414363,
+ 48.41437144,
+ 48.41460782,
+ 48.41456685,
+ 48.41394964
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 41
Name: Line 41
Length: 0.345 km
R: 0.055 Ohm
X: 0.04 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81091684,
+ 7.8117633,
+ 7.81235889,
+ 7.81213406
+ ],
+ "y": [
+ 48.43490897,
+ 48.434804,
+ 48.43586959,
+ 48.43725275
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 42
Name: Line 42
Length: 1.621 km
R: 0.261 Ohm
X: 0.19 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75962984,
+ 7.75828376,
+ 7.75716085,
+ 7.75346128,
+ 7.75312516
+ ],
+ "y": [
+ 48.34441059,
+ 48.34240156,
+ 48.34188624,
+ 48.33596248,
+ 48.33198343
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 43
Name: Line 43
Length: 0.782 km
R: 0.126 Ohm
X: 0.091 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75312516,
+ 7.76187712,
+ 7.76124005
+ ],
+ "y": [
+ 48.33198343,
+ 48.3303465,
+ 48.32945775
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 44
Name: Line 44
Length: 0.248 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75312516,
+ 7.75357352,
+ 7.75339537
+ ],
+ "y": [
+ 48.33198343,
+ 48.3302089,
+ 48.32979038
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 45
Name: Line 45
Length: 2.611 km
R: 0.42 Ohm
X: 0.305 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8790417,
+ 7.87741614,
+ 7.85466459,
+ 7.84538508
+ ],
+ "y": [
+ 48.41572609,
+ 48.41575402,
+ 48.42084885,
+ 48.42296455
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 46
Name: Line 46
Length: 1.158 km
R: 0.186 Ohm
X: 0.136 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77749826,
+ 7.78873191
+ ],
+ "y": [
+ 48.40850593,
+ 48.40904312,
+ 48.4038838
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 47
Name: Line 47
Length: 1.526 km
R: 0.246 Ohm
X: 0.179 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78873191,
+ 7.80573238,
+ 7.80577582
+ ],
+ "y": [
+ 48.4038838,
+ 48.39607413,
+ 48.39606378
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 48
Name: Line 48
Length: 2.033 km
R: 0.327 Ohm
X: 0.238 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.84263834,
+ 7.86375666
+ ],
+ "y": [
+ 48.39811545,
+ 48.40965934
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 49
Name: Line 49
Length: 0.997 km
R: 0.161 Ohm
X: 0.117 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.86375666,
+ 7.86622592,
+ 7.87554357,
+ 7.87852914
+ ],
+ "y": [
+ 48.40965934,
+ 48.40835437,
+ 48.40633627,
+ 48.40552685
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 50
Name: Line 50
Length: 0.804 km
R: 0.129 Ohm
X: 0.094 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81265378,
+ 7.81224648,
+ 7.81164404,
+ 7.80993094,
+ 7.80608736,
+ 7.80577582
+ ],
+ "y": [
+ 48.39170089,
+ 48.39208848,
+ 48.3932605,
+ 48.3941038,
+ 48.39455474,
+ 48.39606378
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 51
Name: Line 51
Length: 0.947 km
R: 0.153 Ohm
X: 0.111 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.84263834,
+ 7.84203085,
+ 7.83909688,
+ 7.83989267,
+ 7.84139083,
+ 7.842892,
+ 7.84208706,
+ 7.84164512
+ ],
+ "y": [
+ 48.39811545,
+ 48.39828929,
+ 48.40038691,
+ 48.40115019,
+ 48.4022093,
+ 48.40261122,
+ 48.40386263,
+ 48.40414471
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 52
Name: Line 52
Length: 0.929 km
R: 0.11 Ohm
X: 0.297 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78665902,
+ 7.78697406,
+ 7.79905951
+ ],
+ "y": [
+ 48.43625936,
+ 48.43621079,
+ 48.43759153
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 53
Name: Line 53
Length: 0.778 km
R: 0.092 Ohm
X: 0.249 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77637635,
+ 7.78665902
+ ],
+ "y": [
+ 48.43784809,
+ 48.43625936
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 54
Name: Line 54
Length: 0.713 km
R: 0.087 Ohm
X: 0.08 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79905951,
+ 7.79926973,
+ 7.80294669,
+ 7.80443842,
+ 7.80526684,
+ 7.80673406
+ ],
+ "y": [
+ 48.43759153,
+ 48.43836508,
+ 48.43811625,
+ 48.43774645,
+ 48.43721361,
+ 48.43815272
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 55
Name: Line 55
Length: 1.136 km
R: 0.183 Ohm
X: 0.133 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76396796,
+ 7.76495858,
+ 7.76629087,
+ 7.7659259,
+ 7.76376563,
+ 7.76270002,
+ 7.76157105,
+ 7.76147033
+ ],
+ "y": [
+ 48.39721686,
+ 48.39694908,
+ 48.39667324,
+ 48.39581646,
+ 48.39356873,
+ 48.39201827,
+ 48.38930585,
+ 48.38881634
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 56
Name: Line 56
Length: 2.149 km
R: 0.346 Ohm
X: 0.251 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.84538508,
+ 7.82134675,
+ 7.81812248
+ ],
+ "y": [
+ 48.42296455,
+ 48.42844094,
+ 48.42974203
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 57
Name: Line 57
Length: 0.811 km
R: 0.131 Ohm
X: 0.095 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81434875,
+ 7.81661465
+ ],
+ "y": [
+ 48.43503248,
+ 48.44215898
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 58
Name: Line 58
Length: 0.47 km
R: 0.076 Ohm
X: 0.055 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.83405306,
+ 7.83429351,
+ 7.83604853,
+ 7.83517172,
+ 7.83584018
+ ],
+ "y": [
+ 48.46664643,
+ 48.46690297,
+ 48.46785146,
+ 48.4694022,
+ 48.47002488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 59
Name: Line 59
Length: 3.155 km
R: 0.508 Ohm
X: 0.369 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87260819,
+ 7.87120517,
+ 7.86568507,
+ 7.85567453,
+ 7.83429197,
+ 7.83405306
+ ],
+ "y": [
+ 48.45794147,
+ 48.45816151,
+ 48.45958978,
+ 48.45952178,
+ 48.46491575,
+ 48.46664643
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 60
Name: Line 60
Length: 0.58 km
R: 0.093 Ohm
X: 0.068 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.82727201,
+ 7.82773651,
+ 7.82914139,
+ 7.83186634,
+ 7.8335644,
+ 7.83405306
+ ],
+ "y": [
+ 48.46648941,
+ 48.46658586,
+ 48.46719882,
+ 48.46600061,
+ 48.46663092,
+ 48.46664643
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 61
Name: Line 61
Length: 0.618 km
R: 0.1 Ohm
X: 0.072 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81894107,
+ 7.82727201
+ ],
+ "y": [
+ 48.46584214,
+ 48.46648941
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 62
Name: Line 62
Length: 1.006 km
R: 0.12 Ohm
X: 0.322 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76153339,
+ 7.77637635
+ ],
+ "y": [
+ 48.43987488,
+ 48.43784809
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 63
Name: Line 63
Length: 0.222 km
R: 0.036 Ohm
X: 0.026 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.78701848,
+ 7.78662366,
+ 7.78600346
+ ],
+ "y": [
+ 48.46045784,
+ 48.45994229,
+ 48.4585943
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 64
Name: Line 64
Length: 0.936 km
R: 0.151 Ohm
X: 0.11 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79891555,
+ 7.79884316,
+ 7.78719486,
+ 7.78701848
+ ],
+ "y": [
+ 48.46284776,
+ 48.46255155,
+ 48.46047176,
+ 48.46045784
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 65
Name: Line 65
Length: 1.341 km
R: 0.216 Ohm
X: 0.157 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79305306,
+ 7.79508502,
+ 7.7949182,
+ 7.79616509,
+ 7.78883056,
+ 7.78670975,
+ 7.7864642,
+ 7.78701848
+ ],
+ "y": [
+ 48.46585031,
+ 48.46578218,
+ 48.46500727,
+ 48.46263647,
+ 48.461078,
+ 48.46104579,
+ 48.46053878,
+ 48.46045784
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 67
Name: Line 67
Length: 0.26 km
R: 0.042 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81137059,
+ 7.81159537,
+ 7.81106554,
+ 7.81136875,
+ 7.81192866
+ ],
+ "y": [
+ 48.38535297,
+ 48.38592827,
+ 48.38643007,
+ 48.3871739,
+ 48.38755402
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 68
Name: Line 68
Length: 1.804 km
R: 0.29 Ohm
X: 0.211 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90849453,
+ 7.90939134,
+ 7.92408252,
+ 7.92629214,
+ 7.93125749
+ ],
+ "y": [
+ 48.39773842,
+ 48.39944778,
+ 48.39840209,
+ 48.39898093,
+ 48.3980943
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 69
Name: Line 69
Length: 0.59 km
R: 0.095 Ohm
X: 0.069 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.93125749,
+ 7.93285196,
+ 7.93773871
+ ],
+ "y": [
+ 48.3980943,
+ 48.39632695,
+ 48.39605777
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 70
Name: Line 70
Length: 0.368 km
R: 0.059 Ohm
X: 0.043 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90485626,
+ 7.90565763,
+ 7.90302727
+ ],
+ "y": [
+ 48.42317236,
+ 48.423879,
+ 48.42556885
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 71
Name: Line 71
Length: 0.162 km
R: 0.026 Ohm
X: 0.019 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90302727,
+ 7.90431342,
+ 7.90432357
+ ],
+ "y": [
+ 48.42556885,
+ 48.42674696,
+ 48.42675459
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 72
Name: Line 72
Length: 1.455 km
R: 0.234 Ohm
X: 0.17 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90302727,
+ 7.90042277,
+ 7.89592512,
+ 7.89306465,
+ 7.8883681,
+ 7.88777356
+ ],
+ "y": [
+ 48.42556885,
+ 48.42678215,
+ 48.43071547,
+ 48.43187132,
+ 48.43274836,
+ 48.43320652
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 73
Name: Line 73
Length: 0.466 km
R: 0.075 Ohm
X: 0.054 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90115002,
+ 7.90298335,
+ 7.9045586,
+ 7.90759827
+ ],
+ "y": [
+ 48.42189392,
+ 48.42021485,
+ 48.41985264,
+ 48.42108182
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 74
Name: Line 74
Length: 0.53 km
R: 0.085 Ohm
X: 0.062 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90759827,
+ 7.90753143,
+ 7.90529898,
+ 7.90828612
+ ],
+ "y": [
+ 48.42108182,
+ 48.42140869,
+ 48.4225983,
+ 48.42418937
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 75
Name: Line 75
Length: 0.304 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90115002,
+ 7.90485626
+ ],
+ "y": [
+ 48.42189392,
+ 48.42317236
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 76
Name: Line 76
Length: 0.347 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75752837,
+ 7.75743197,
+ 7.75456734
+ ],
+ "y": [
+ 48.3495233,
+ 48.35033194,
+ 48.35261081
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 77
Name: Line 77
Length: 2.122 km
R: 0.342 Ohm
X: 0.248 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75706106,
+ 7.76129469,
+ 7.75752837
+ ],
+ "y": [
+ 48.36812437,
+ 48.35405755,
+ 48.3495233
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 78
Name: Line 78
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.91778262,
+ 7.91291408
+ ],
+ "y": [
+ 48.42400659,
+ 48.42255372
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 79
Name: Line 79
Length: 0.275 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.91291408,
+ 7.91460816,
+ 7.91393385
+ ],
+ "y": [
+ 48.42255372,
+ 48.42455518,
+ 48.42590629
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 80
Name: Line 80
Length: 0.428 km
R: 0.069 Ohm
X: 0.05 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90933438,
+ 7.90960971,
+ 7.91052635,
+ 7.91170676,
+ 7.91260163,
+ 7.91393385
+ ],
+ "y": [
+ 48.42618849,
+ 48.42620031,
+ 48.42567694,
+ 48.42624241,
+ 48.42551677,
+ 48.42590629
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 81
Name: Line 81
Length: 0.338 km
R: 0.054 Ohm
X: 0.039 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.91291408,
+ 7.9149878,
+ 7.91378673
+ ],
+ "y": [
+ 48.42255372,
+ 48.42109714,
+ 48.42043868
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 82
Name: Line 82
Length: 0.349 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90933438,
+ 7.91062827,
+ 7.90828612
+ ],
+ "y": [
+ 48.42618849,
+ 48.42540398,
+ 48.42418937
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 85
Name: Line 85
Length: 0.329 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8884535,
+ 7.88614206,
+ 7.88603646
+ ],
+ "y": [
+ 48.41021512,
+ 48.41132488,
+ 48.41239165
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 86
Name: Line 86
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8893131,
+ 7.88675468,
+ 7.88626878,
+ 7.88603646
+ ],
+ "y": [
+ 48.41271759,
+ 48.41253887,
+ 48.41264631,
+ 48.41239165
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 87
Name: Line 87
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90172272,
+ 7.90147838,
+ 7.90130481
+ ],
+ "y": [
+ 48.40051529,
+ 48.39898139,
+ 48.39757192
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 90
Name: Line 90
Length: 0.315 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89617371,
+ 7.89836453,
+ 7.89989694
+ ],
+ "y": [
+ 48.41100311,
+ 48.41119729,
+ 48.41219988
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 91
Name: Line 91
Length: 2.528 km
R: 0.407 Ohm
X: 0.296 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.93283542,
+ 7.93111133,
+ 7.92478234,
+ 7.91378673
+ ],
+ "y": [
+ 48.40163972,
+ 48.40314742,
+ 48.41145849,
+ 48.42043868
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 92
Name: Line 92
Length: 0.093 km
R: 0.015 Ohm
X: 0.011 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89437546,
+ 7.89460962,
+ 7.89638358
+ ],
+ "y": [
+ 48.41295983,
+ 48.41328729,
+ 48.41424248
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 93
Name: Line 93
Length: 0.387 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8893131,
+ 7.89437546
+ ],
+ "y": [
+ 48.41271759,
+ 48.41295983
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 94
Name: Line 94
Length: 0.272 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.89989694,
+ 7.90151744,
+ 7.90130341
+ ],
+ "y": [
+ 48.41219988,
+ 48.4124301,
+ 48.41377255
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 95
Name: Line 95
Length: 0.247 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.93283542,
+ 7.93445481,
+ 7.93628735
+ ],
+ "y": [
+ 48.40163972,
+ 48.40146312,
+ 48.40091852
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 96
Name: Line 96
Length: 0.25 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.93628735,
+ 7.93787155,
+ 7.93829196
+ ],
+ "y": [
+ 48.40091852,
+ 48.39967434,
+ 48.39911502
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 97
Name: Line 97
Length: 0.459 km
R: 0.074 Ohm
X: 0.054 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.93773871,
+ 7.93790841,
+ 7.93663385,
+ 7.93681572,
+ 7.93773403,
+ 7.93754769,
+ 7.93829196
+ ],
+ "y": [
+ 48.39605777,
+ 48.3962261,
+ 48.39706036,
+ 48.39826119,
+ 48.3986056,
+ 48.39883465,
+ 48.39911502
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 98
Name: Line 98
Length: 0.366 km
R: 0.059 Ohm
X: 0.043 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75339537,
+ 7.7558693,
+ 7.75792025
+ ],
+ "y": [
+ 48.32979038,
+ 48.32897412,
+ 48.32845845
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 99
Name: Line 99
Length: 0.291 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75962984,
+ 7.75782277,
+ 7.75578023
+ ],
+ "y": [
+ 48.34441059,
+ 48.34403542,
+ 48.34396313
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 100
Name: Line 100
Length: 0.299 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90591947,
+ 7.90587019,
+ 7.90775174,
+ 7.90849453
+ ],
+ "y": [
+ 48.39621703,
+ 48.39677807,
+ 48.39705376,
+ 48.39773842
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 101
Name: Line 101
Length: 0.236 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90205872,
+ 7.90261989,
+ 7.90443237
+ ],
+ "y": [
+ 48.39529931,
+ 48.39512339,
+ 48.39390775
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 102
Name: Line 102
Length: 0.489 km
R: 0.079 Ohm
X: 0.057 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90443237,
+ 7.90720374,
+ 7.90819035,
+ 7.90794776,
+ 7.9083386
+ ],
+ "y": [
+ 48.39390775,
+ 48.39294498,
+ 48.39430049,
+ 48.3944891,
+ 48.3949975
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 103
Name: Line 103
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.9083386,
+ 7.90787741,
+ 7.90591947
+ ],
+ "y": [
+ 48.3949975,
+ 48.3963407,
+ 48.39621703
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 104
Name: Line 104
Length: 0.238 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77541442,
+ 7.77589723,
+ 7.77627383,
+ 7.77670102
+ ],
+ "y": [
+ 48.3593875,
+ 48.36023212,
+ 48.36082142,
+ 48.36133205
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 105
Name: Line 105
Length: 0.177 km
R: 0.029 Ohm
X: 0.021 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77670102,
+ 7.77713313,
+ 7.77757114,
+ 7.77756681
+ ],
+ "y": [
+ 48.36133205,
+ 48.36134284,
+ 48.36244816,
+ 48.36261088
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 106
Name: Line 106
Length: 0.283 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77603927,
+ 7.77632396,
+ 7.77541442
+ ],
+ "y": [
+ 48.35663792,
+ 48.35789023,
+ 48.3593875
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 107
Name: Line 107
Length: 0.615 km
R: 0.099 Ohm
X: 0.072 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77032597,
+ 7.77212983,
+ 7.77603927
+ ],
+ "y": [
+ 48.35975183,
+ 48.35778043,
+ 48.35663792
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 108
Name: Line 108
Length: 1.278 km
R: 0.206 Ohm
X: 0.149 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77032597,
+ 7.76147904
+ ],
+ "y": [
+ 48.35975183,
+ 48.35023997
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 109
Name: Line 109
Length: 0.147 km
R: 0.024 Ohm
X: 0.017 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77569591,
+ 7.77641956,
+ 7.77756681
+ ],
+ "y": [
+ 48.36446775,
+ 48.36350223,
+ 48.36261088
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 110
Name: Line 110
Length: 0.253 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75578023,
+ 7.75504431,
+ 7.75395235,
+ 7.75385941
+ ],
+ "y": [
+ 48.34396313,
+ 48.34426775,
+ 48.34552928,
+ 48.34577289
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 111
Name: Line 111
Length: 0.214 km
R: 0.034 Ohm
X: 0.025 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75618441,
+ 7.7562193,
+ 7.75569132
+ ],
+ "y": [
+ 48.34562366,
+ 48.34600529,
+ 48.34750562
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 112
Name: Line 112
Length: 0.415 km
R: 0.067 Ohm
X: 0.049 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75569132,
+ 7.75419626,
+ 7.75453023,
+ 7.75269597
+ ],
+ "y": [
+ 48.34750562,
+ 48.34758219,
+ 48.34920225,
+ 48.34979926
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 113
Name: Line 113
Length: 0.18 km
R: 0.029 Ohm
X: 0.021 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75618441,
+ 7.75608475,
+ 7.75403123,
+ 7.75385941
+ ],
+ "y": [
+ 48.34562366,
+ 48.34553329,
+ 48.34569381,
+ 48.34577289
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 114
Name: Line 114
Length: 0.562 km
R: 0.09 Ohm
X: 0.066 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75269597,
+ 7.75181083,
+ 7.74517856
+ ],
+ "y": [
+ 48.34979926,
+ 48.34979996,
+ 48.34907864
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 116
Name: Line 116
Length: 0.399 km
R: 0.064 Ohm
X: 0.047 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75780411,
+ 7.75917051,
+ 7.76226955
+ ],
+ "y": [
+ 48.38819904,
+ 48.38730208,
+ 48.38622196
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 117
Name: Line 117
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76226955,
+ 7.76344386,
+ 7.7644815
+ ],
+ "y": [
+ 48.38622196,
+ 48.38591421,
+ 48.38725384
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 118
Name: Line 118
Length: 0.37 km
R: 0.06 Ohm
X: 0.043 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.7644815,
+ 7.76213031,
+ 7.76276391,
+ 7.76147033
+ ],
+ "y": [
+ 48.38725384,
+ 48.38794756,
+ 48.38852075,
+ 48.38881634
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 119
Name: Line 119
Length: 0.251 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.7490983,
+ 7.74791722,
+ 7.74990855
+ ],
+ "y": [
+ 48.38651875,
+ 48.38670319,
+ 48.38849988
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 120
Name: Line 120
Length: 0.304 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75780411,
+ 7.75698634,
+ 7.75516628,
+ 7.75527749
+ ],
+ "y": [
+ 48.38819904,
+ 48.38848522,
+ 48.38875367,
+ 48.38787178
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 121
Name: Line 121
Length: 0.233 km
R: 0.037 Ohm
X: 0.027 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75423985,
+ 7.75489924,
+ 7.75490995,
+ 7.75612888
+ ],
+ "y": [
+ 48.38198803,
+ 48.38177685,
+ 48.38177159,
+ 48.38124748,
+ 48.38127334
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 122
Name: Line 122
Length: 0.118 km
R: 0.019 Ohm
X: 0.014 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.74776625,
+ 7.7490983
+ ],
+ "y": [
+ 48.38593046,
+ 48.38651875
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 123
Name: Line 123
Length: 0.397 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75041699,
+ 7.7512397
+ ],
+ "y": [
+ 48.38198803,
+ 48.38256216,
+ 48.38363665
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 124
Name: Line 124
Length: 0.52 km
R: 0.084 Ohm
X: 0.061 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.7512397,
+ 7.75163773,
+ 7.750171,
+ 7.74884833,
+ 7.74776625
+ ],
+ "y": [
+ 48.38363665,
+ 48.38424806,
+ 48.38471159,
+ 48.38478902,
+ 48.38593046
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 125
Name: Line 125
Length: 1.526 km
R: 0.246 Ohm
X: 0.179 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75471952,
+ 7.75706106
+ ],
+ "y": [
+ 48.38198803,
+ 48.37590247,
+ 48.36812437
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 126
Name: Line 126
Length: 0.254 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.74776625,
+ 7.7473456,
+ 7.74426069
+ ],
+ "y": [
+ 48.38593046,
+ 48.38664415,
+ 48.38747799
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 127
Name: Line 127
Length: 1.601 km
R: 0.19 Ohm
X: 0.512 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76574338,
+ 7.75852885
+ ],
+ "y": [
+ 48.41987793,
+ 48.43345788
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 128
Name: Line 128
Length: 0.473 km
R: 0.076 Ohm
X: 0.055 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76574338,
+ 7.76644776,
+ 7.76739671
+ ],
+ "y": [
+ 48.41987793,
+ 48.42002993,
+ 48.42373656
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 129
Name: Line 129
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77518896,
+ 7.77674239,
+ 7.77880954
+ ],
+ "y": [
+ 48.4106662,
+ 48.41077816,
+ 48.40987065
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 130
Name: Line 130
Length: 0.295 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76522567,
+ 7.76483782,
+ 7.76606485
+ ],
+ "y": [
+ 48.41091584,
+ 48.41125561,
+ 48.41242444
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 131
Name: Line 131
Length: 0.417 km
R: 0.067 Ohm
X: 0.049 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.7617981,
+ 7.76399226,
+ 7.76572294,
+ 7.76606485
+ ],
+ "y": [
+ 48.41348695,
+ 48.41182097,
+ 48.41245092,
+ 48.41242444
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 132
Name: Line 132
Length: 0.323 km
R: 0.052 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76946387,
+ 7.76943184,
+ 7.7665952,
+ 7.76522567
+ ],
+ "y": [
+ 48.40913221,
+ 48.40915918,
+ 48.40969202,
+ 48.41091584
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 133
Name: Line 133
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77599056,
+ 7.77674873,
+ 7.77861783,
+ 7.77919577
+ ],
+ "y": [
+ 48.41297438,
+ 48.41331062,
+ 48.41231411,
+ 48.41203811
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 134
Name: Line 134
Length: 0.282 km
R: 0.045 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77576803,
+ 7.77520469
+ ],
+ "y": [
+ 48.40850593,
+ 48.40798048,
+ 48.40610337
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 135
Name: Line 135
Length: 0.396 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.76659341,
+ 7.76544426,
+ 7.76267774,
+ 7.7617981
+ ],
+ "y": [
+ 48.41394964,
+ 48.41402817,
+ 48.41423953,
+ 48.41348695
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 136
Name: Line 136
Length: 0.371 km
R: 0.06 Ohm
X: 0.043 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77150376,
+ 7.77342658,
+ 7.77532817,
+ 7.77599056
+ ],
+ "y": [
+ 48.41297284,
+ 48.41358426,
+ 48.41284311,
+ 48.41297438
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 137
Name: Line 137
Length: 0.274 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77583421,
+ 7.77591886,
+ 7.77518896
+ ],
+ "y": [
+ 48.40850593,
+ 48.40895948,
+ 48.41002749,
+ 48.4106662
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 138
Name: Line 138
Length: 0.329 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.77518896,
+ 7.77615683,
+ 7.77606931,
+ 7.77543634,
+ 7.77599056
+ ],
+ "y": [
+ 48.4106662,
+ 48.41108201,
+ 48.41202505,
+ 48.41266512,
+ 48.41297438
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 139
Name: Line 139
Length: 0.499 km
R: 0.08 Ohm
X: 0.058 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.83571694,
+ 7.83401712,
+ 7.8326561,
+ 7.83058701
+ ],
+ "y": [
+ 48.40021513,
+ 48.39984603,
+ 48.39850087,
+ 48.39753675
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 140
Name: Line 140
Length: 0.316 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.83571694,
+ 7.8358586,
+ 7.8368015,
+ 7.83782535
+ ],
+ "y": [
+ 48.40021513,
+ 48.39919649,
+ 48.39847232,
+ 48.3990085
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 141
Name: Line 141
Length: 0.388 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81434875,
+ 7.81325053,
+ 7.81253272,
+ 7.8128154,
+ 7.81257537,
+ 7.81213406
+ ],
+ "y": [
+ 48.43503248,
+ 48.43528857,
+ 48.43543937,
+ 48.43601104,
+ 48.437316,
+ 48.43725275
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 142
Name: Line 142
Length: 0.07 km
R: 0.011 Ohm
X: 0.008 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81440186,
+ 7.8142915,
+ 7.81375095
+ ],
+ "y": [
+ 48.38940745,
+ 48.38938411,
+ 48.38919055
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 143
Name: Line 143
Length: 0.286 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81440186,
+ 7.81428393,
+ 7.8127534,
+ 7.81265378
+ ],
+ "y": [
+ 48.38940745,
+ 48.38967584,
+ 48.39156961,
+ 48.39170089
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 144
Name: Line 144
Length: 1.517 km
R: 0.244 Ohm
X: 0.178 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.82229551,
+ 7.8238694,
+ 7.82106089,
+ 7.82234704,
+ 7.82409718,
+ 7.82817169,
+ 7.82922235,
+ 7.83034891,
+ 7.83058701
+ ],
+ "y": [
+ 48.38807328,
+ 48.38845699,
+ 48.3902318,
+ 48.39111773,
+ 48.3930508,
+ 48.3948561,
+ 48.39670488,
+ 48.39743032,
+ 48.39753675
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 145
Name: Line 145
Length: 0.719 km
R: 0.116 Ohm
X: 0.084 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81702049,
+ 7.81878871,
+ 7.81943944,
+ 7.82266554,
+ 7.82198478,
+ 7.82281578,
+ 7.82229551
+ ],
+ "y": [
+ 48.38429982,
+ 48.38482288,
+ 48.38520652,
+ 48.38641133,
+ 48.387031,
+ 48.38770494,
+ 48.38807328
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 146
Name: Line 146
Length: 0.22 km
R: 0.035 Ohm
X: 0.026 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81550141,
+ 7.81654608,
+ 7.81760243,
+ 7.81702049
+ ],
+ "y": [
+ 48.38288709,
+ 48.38240623,
+ 48.38311519,
+ 48.38429982
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 147
Name: Line 147
Length: 0.21 km
R: 0.034 Ohm
X: 0.025 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81800216,
+ 7.81735047,
+ 7.81627775,
+ 7.81599919
+ ],
+ "y": [
+ 48.45286283,
+ 48.4523668,
+ 48.45247233,
+ 48.45200045
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 148
Name: Line 148
Length: 0.239 km
R: 0.039 Ohm
X: 0.028 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81599919,
+ 7.81594703,
+ 7.81544555,
+ 7.81487777,
+ 7.81386611
+ ],
+ "y": [
+ 48.45200045,
+ 48.45184899,
+ 48.45198309,
+ 48.45113912,
+ 48.45138395
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 149
Name: Line 149
Length: 0.345 km
R: 0.055 Ohm
X: 0.04 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.82260854,
+ 7.81800216
+ ],
+ "y": [
+ 48.45231101,
+ 48.45286283
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 150
Name: Line 150
Length: 0.327 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.82260854,
+ 7.82256678,
+ 7.82319722,
+ 7.82449029
+ ],
+ "y": [
+ 48.45231101,
+ 48.45266208,
+ 48.45431913,
+ 48.45412175
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 151
Name: Line 151
Length: 0.553 km
R: 0.068 Ohm
X: 0.062 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80946722,
+ 7.80854958,
+ 7.80464847,
+ 7.80466609
+ ],
+ "y": [
+ 48.43003727,
+ 48.43027934,
+ 48.43083045,
+ 48.43251067
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 152
Name: Line 152
Length: 0.146 km
R: 0.024 Ohm
X: 0.017 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80946722,
+ 7.80939155,
+ 7.81078043
+ ],
+ "y": [
+ 48.43003727,
+ 48.4299802,
+ 48.42871494
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 153
Name: Line 153
Length: 0.482 km
R: 0.078 Ohm
X: 0.056 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81434875,
+ 7.81587268,
+ 7.81541879,
+ 7.81753115
+ ],
+ "y": [
+ 48.43503248,
+ 48.43497042,
+ 48.43310111,
+ 48.43283117
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 154
Name: Line 154
Length: 0.443 km
R: 0.071 Ohm
X: 0.052 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81812248,
+ 7.81808382,
+ 7.81713512,
+ 7.81746181,
+ 7.81664213,
+ 7.81753115
+ ],
+ "y": [
+ 48.42974203,
+ 48.42987869,
+ 48.43023546,
+ 48.43069249,
+ 48.43088424,
+ 48.43283117
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 156
Name: Line 156
Length: 0.284 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81812248,
+ 7.81640506,
+ 7.81702793,
+ 7.81719863
+ ],
+ "y": [
+ 48.42974203,
+ 48.42919601,
+ 48.428887,
+ 48.4281192
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 157
Name: Line 157
Length: 1.082 km
R: 0.128 Ohm
X: 0.346 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90923486,
+ 7.90348365,
+ 7.90031707,
+ 7.8959583
+ ],
+ "y": [
+ 48.4561543,
+ 48.45358185,
+ 48.45301795,
+ 48.45361129
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 158
Name: Line 158
Length: 0.689 km
R: 0.082 Ohm
X: 0.221 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8959583,
+ 7.89568627,
+ 7.88830762
+ ],
+ "y": [
+ 48.45361129,
+ 48.4547515,
+ 48.45601148
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 161
Name: Line 161
Length: 0.468 km
R: 0.057 Ohm
X: 0.052 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88830762,
+ 7.88776916,
+ 7.88367481,
+ 7.88212331
+ ],
+ "y": [
+ 48.45601148,
+ 48.45627719,
+ 48.45609713,
+ 48.45630215
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 162
Name: Line 162
Length: 2.595 km
R: 0.308 Ohm
X: 0.83 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88546159,
+ 7.91396063
+ ],
+ "y": [
+ 48.4585246,
+ 48.4569382
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 163
Name: Line 163
Length: 0.306 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.80752534,
+ 7.80754102,
+ 7.81003126,
+ 7.81053946,
+ 7.8112944
+ ],
+ "y": [
+ 48.46584322,
+ 48.46596098,
+ 48.46600036,
+ 48.46630498,
+ 48.466147
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 164
Name: Line 164
Length: 0.566 km
R: 0.091 Ohm
X: 0.066 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81894107,
+ 7.81480813,
+ 7.81294305,
+ 7.8112944
+ ],
+ "y": [
+ 48.46584214,
+ 48.46581066,
+ 48.46590381,
+ 48.466147
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 165
Name: Line 165
Length: 0.365 km
R: 0.043 Ohm
X: 0.117 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.91309968,
+ 7.91279093,
+ 7.9120236,
+ 7.90923486
+ ],
+ "y": [
+ 48.4566322,
+ 48.45683348,
+ 48.45740074,
+ 48.4561543
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 167
Name: Line 167
Length: 0.464 km
R: 0.075 Ohm
X: 0.054 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79891555,
+ 7.80501543
+ ],
+ "y": [
+ 48.46284776,
+ 48.46296614
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 168
Name: Line 168
Length: 0.42 km
R: 0.068 Ohm
X: 0.049 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79950378,
+ 7.79789121,
+ 7.79674274
+ ],
+ "y": [
+ 48.46870231,
+ 48.46588425,
+ 48.46588038
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 169
Name: Line 169
Length: 0.272 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.79674274,
+ 7.79411097,
+ 7.79305306
+ ],
+ "y": [
+ 48.46588038,
+ 48.46590636,
+ 48.46585031
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 170
Name: Line 170
Length: 0.285 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87725311,
+ 7.87671923,
+ 7.87675502,
+ 7.87697289,
+ 7.87715626
+ ],
+ "y": [
+ 48.46499297,
+ 48.46561508,
+ 48.46636841,
+ 48.46654892,
+ 48.46740551
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 171
Name: Line 171
Length: 0.77 km
R: 0.124 Ohm
X: 0.09 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8758161,
+ 7.87553451,
+ 7.87598516,
+ 7.87548683,
+ 7.87663709,
+ 7.87744195,
+ 7.87845944,
+ 7.87715626
+ ],
+ "y": [
+ 48.47236011,
+ 48.47232304,
+ 48.47165336,
+ 48.4711409,
+ 48.46913517,
+ 48.46937138,
+ 48.46779457,
+ 48.46740551
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 172
Name: Line 172
Length: 0.264 km
R: 0.032 Ohm
X: 0.03 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88344689,
+ 7.88378722,
+ 7.88260716
+ ],
+ "y": [
+ 48.46135559,
+ 48.46292134,
+ 48.46302758
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 173
Name: Line 173
Length: 0.197 km
R: 0.024 Ohm
X: 0.022 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88260716,
+ 7.88401855,
+ 7.88432076
+ ],
+ "y": [
+ 48.46302758,
+ 48.46350368,
+ 48.46419159
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 174
Name: Line 174
Length: 0.28 km
R: 0.045 Ohm
X: 0.033 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88023004,
+ 7.88045814,
+ 7.88260716
+ ],
+ "y": [
+ 48.46216934,
+ 48.46323446,
+ 48.46302758
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 175
Name: Line 175
Length: 0.398 km
R: 0.049 Ohm
X: 0.045 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88546159,
+ 7.88510802,
+ 7.88463276,
+ 7.8840797,
+ 7.88379148,
+ 7.88340999,
+ 7.88344689
+ ],
+ "y": [
+ 48.4585246,
+ 48.45925446,
+ 48.46021773,
+ 48.46019306,
+ 48.46086262,
+ 48.46087555,
+ 48.46135559
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 177
Name: Line 177
Length: 0.293 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.8758161,
+ 7.87666867
+ ],
+ "y": [
+ 48.47236011,
+ 48.47484423
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 178
Name: Line 178
Length: 0.449 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87990442,
+ 7.87881309,
+ 7.8762772,
+ 7.8758161
+ ],
+ "y": [
+ 48.46999586,
+ 48.4713525,
+ 48.4716203,
+ 48.47236011
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 179
Name: Line 179
Length: 0.551 km
R: 0.089 Ohm
X: 0.064 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88088449,
+ 7.88165,
+ 7.88259545,
+ 7.88105677,
+ 7.87990442
+ ],
+ "y": [
+ 48.46626641,
+ 48.46667163,
+ 48.4670659,
+ 48.46954176,
+ 48.46999586
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 180
Name: Line 180
Length: 1.42 km
R: 0.229 Ohm
X: 0.166 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88777356,
+ 7.88466467,
+ 7.87836276,
+ 7.87625272
+ ],
+ "y": [
+ 48.43320652,
+ 48.43560077,
+ 48.44264826,
+ 48.44299303
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 181
Name: Line 181
Length: 0.54 km
R: 0.087 Ohm
X: 0.063 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88517175,
+ 7.88450517,
+ 7.88091238,
+ 7.87808299
+ ],
+ "y": [
+ 48.45375027,
+ 48.45379718,
+ 48.45401796,
+ 48.45477828
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 182
Name: Line 182
Length: 0.355 km
R: 0.043 Ohm
X: 0.04 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87808299,
+ 7.87790893,
+ 7.87858024,
+ 7.87701423,
+ 7.87771765
+ ],
+ "y": [
+ 48.45477828,
+ 48.45486293,
+ 48.45553885,
+ 48.45634075,
+ 48.45713891
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 183
Name: Line 183
Length: 0.338 km
R: 0.041 Ohm
X: 0.038 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88212331,
+ 7.87980154,
+ 7.87771765
+ ],
+ "y": [
+ 48.45630215,
+ 48.45668177,
+ 48.45713891
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 184
Name: Line 184
Length: 0.44 km
R: 0.071 Ohm
X: 0.051 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88546159,
+ 7.88352252,
+ 7.88060094,
+ 7.88076055
+ ],
+ "y": [
+ 48.4585246,
+ 48.4583596,
+ 48.45867551,
+ 48.45936355
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 185
Name: Line 185
Length: 1.095 km
R: 0.176 Ohm
X: 0.128 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88517175,
+ 7.88530198,
+ 7.88291376,
+ 7.87922427,
+ 7.87688954
+ ],
+ "y": [
+ 48.45375027,
+ 48.45321614,
+ 48.44925911,
+ 48.44679416,
+ 48.44659344
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 186
Name: Line 186
Length: 0.346 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88517175,
+ 7.88695118,
+ 7.88692885,
+ 7.88824433
+ ],
+ "y": [
+ 48.45375027,
+ 48.45372929,
+ 48.45278221,
+ 48.45231709
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 187
Name: Line 187
Length: 0.41 km
R: 0.066 Ohm
X: 0.048 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87688954,
+ 7.87686341,
+ 7.87640856,
+ 7.87643942,
+ 7.87625272
+ ],
+ "y": [
+ 48.44659344,
+ 48.44509708,
+ 48.44445558,
+ 48.44349227,
+ 48.44299303
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 189
Name: Line 189
Length: 0.446 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87260819,
+ 7.87239645,
+ 7.87493521,
+ 7.87520041
+ ],
+ "y": [
+ 48.45794147,
+ 48.45828506,
+ 48.46130227,
+ 48.46134835
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 190
Name: Line 190
Length: 0.314 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87520041,
+ 7.87515322,
+ 7.87712123,
+ 7.87750063
+ ],
+ "y": [
+ 48.46134835,
+ 48.46161584,
+ 48.46328049,
+ 48.46363931
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 191
Name: Line 191
Length: 0.152 km
R: 0.024 Ohm
X: 0.018 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87750063,
+ 7.87725311
+ ],
+ "y": [
+ 48.46363931,
+ 48.46499297
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 192
Name: Line 192
Length: 0.397 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88088449,
+ 7.88213238,
+ 7.88358692,
+ 7.88432076
+ ],
+ "y": [
+ 48.46626641,
+ 48.46601268,
+ 48.46585855,
+ 48.46419159
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "lines",
+ "showlegend": false,
+ "text": "Index: 193
Name: Line 193
Length: 1.006 km
R: 0.12 Ohm
X: 0.322 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75852885,
+ 7.7589569,
+ 7.75843138,
+ 7.76153339
+ ],
+ "y": [
+ 48.43345788,
+ 48.43510804,
+ 48.43782243,
+ 48.43987488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": true,
+ "text": "Index: 66
Name: Line 66
Length: 0.446 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81137059,
+ 7.81131879,
+ 7.81550141
+ ],
+ "y": [
+ 48.38535297,
+ 48.38527882,
+ 48.38288709
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": false,
+ "text": "Index: 8
Name: Line 8
Length: 0.146 km
R: 0.023 Ohm
X: 0.017 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.75838011,
+ 7.75808461,
+ 7.75752837
+ ],
+ "y": [
+ 48.34834127,
+ 48.34860058,
+ 48.3495233
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": false,
+ "text": "Index: 23
Name: Line 23
Length: 1.188 km
R: 0.191 Ohm
X: 0.139 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.88846812,
+ 7.89363213,
+ 7.90115002
+ ],
+ "y": [
+ 48.41556286,
+ 48.41919475,
+ 48.42189392
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": false,
+ "text": "Index: 88
Name: Line 88
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.90130481,
+ 7.90122937,
+ 7.90205872
+ ],
+ "y": [
+ 48.39757192,
+ 48.3966186,
+ 48.39529931
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": false,
+ "text": "Index: 188
Name: Line 188
Length: 0.386 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.87771765,
+ 7.87260819
+ ],
+ "y": [
+ 48.45713891,
+ 48.45794147
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "disconnected lines",
+ "line": {
+ "color": "rgb(128, 128, 128)",
+ "dash": "dot",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "disconnected branches",
+ "showlegend": false,
+ "text": "Index: 31
Name: Line 31
Length: 0.967 km
R: 0.156 Ohm
X: 0.113 Ohm
",
+ "type": "scatter",
+ "x": [
+ 7.81661465,
+ 7.8195498
+ ],
+ "y": [
+ 48.44215898,
+ 48.45155157
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "marker": {
+ "color": "rgb(128, 128, 128)",
+ "size": 1,
+ "symbol": "circle"
+ },
+ "mode": "markers",
+ "name": "edge_center",
+ "showlegend": false,
+ "text": [
+ "Index: 0
Name: Line 0
Length: 0.586 km
R: 0.094 Ohm
X: 0.069 Ohm
",
+ "Index: 1
Name: Line 1
Length: 1.374 km
R: 0.221 Ohm
X: 0.161 Ohm
",
+ "Index: 2
Name: Line 2
Length: 0.206 km
R: 0.033 Ohm
X: 0.024 Ohm
",
+ "Index: 3
Name: Line 3
Length: 0.617 km
R: 0.099 Ohm
X: 0.072 Ohm
",
+ "Index: 4
Name: Line 4
Length: 0.382 km
R: 0.061 Ohm
X: 0.045 Ohm
",
+ "Index: 5
Name: Line 5
Length: 3.303 km
R: 0.532 Ohm
X: 0.386 Ohm
",
+ "Index: 6
Name: Line 6
Length: 0.35 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "Index: 7
Name: Line 7
Length: 0.736 km
R: 0.118 Ohm
X: 0.086 Ohm
",
+ "Index: 10
Name: Line 10
Length: 0.313 km
R: 0.05 Ohm
X: 0.037 Ohm
",
+ "Index: 11
Name: Line 11
Length: 0.258 km
R: 0.042 Ohm
X: 0.03 Ohm
",
+ "Index: 12
Name: Line 12
Length: 0.435 km
R: 0.07 Ohm
X: 0.051 Ohm
",
+ "Index: 14
Name: Line 14
Length: 0.357 km
R: 0.058 Ohm
X: 0.042 Ohm
",
+ "Index: 15
Name: Line 15
Length: 0.254 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "Index: 16
Name: Line 16
Length: 0.635 km
R: 0.102 Ohm
X: 0.074 Ohm
",
+ "Index: 17
Name: Line 17
Length: 1.3 km
R: 0.209 Ohm
X: 0.152 Ohm
",
+ "Index: 18
Name: Line 18
Length: 0.139 km
R: 0.022 Ohm
X: 0.016 Ohm
",
+ "Index: 20
Name: Line 20
Length: 0.632 km
R: 0.102 Ohm
X: 0.074 Ohm
",
+ "Index: 21
Name: Line 21
Length: 0.112 km
R: 0.018 Ohm
X: 0.013 Ohm
",
+ "Index: 22
Name: Line 22
Length: 0.312 km
R: 0.05 Ohm
X: 0.036 Ohm
",
+ "Index: 24
Name: Line 24
Length: 0.695 km
R: 0.112 Ohm
X: 0.081 Ohm
",
+ "Index: 25
Name: Line 25
Length: 0.235 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "Index: 26
Name: Line 26
Length: 0.561 km
R: 0.09 Ohm
X: 0.066 Ohm
",
+ "Index: 27
Name: Line 27
Length: 0.522 km
R: 0.084 Ohm
X: 0.061 Ohm
",
+ "Index: 28
Name: Line 28
Length: 0.283 km
R: 0.034 Ohm
X: 0.032 Ohm
",
+ "Index: 29
Name: Line 29
Length: 1.688 km
R: 0.272 Ohm
X: 0.197 Ohm
",
+ "Index: 30
Name: Line 30
Length: 1.073 km
R: 0.173 Ohm
X: 0.125 Ohm
",
+ "Index: 32
Name: Line 32
Length: 0.324 km
R: 0.052 Ohm
X: 0.038 Ohm
",
+ "Index: 34
Name: Line 34
Length: 0.309 km
R: 0.05 Ohm
X: 0.036 Ohm
",
+ "Index: 35
Name: Line 35
Length: 0.541 km
R: 0.087 Ohm
X: 0.063 Ohm
",
+ "Index: 36
Name: Line 36
Length: 0.296 km
R: 0.036 Ohm
X: 0.033 Ohm
",
+ "Index: 37
Name: Line 37
Length: 0.48 km
R: 0.059 Ohm
X: 0.054 Ohm
",
+ "Index: 38
Name: Line 38
Length: 0.711 km
R: 0.084 Ohm
X: 0.228 Ohm
",
+ "Index: 39
Name: Line 39
Length: 0.242 km
R: 0.039 Ohm
X: 0.028 Ohm
",
+ "Index: 40
Name: Line 40
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "Index: 41
Name: Line 41
Length: 0.345 km
R: 0.055 Ohm
X: 0.04 Ohm
",
+ "Index: 42
Name: Line 42
Length: 1.621 km
R: 0.261 Ohm
X: 0.19 Ohm
",
+ "Index: 43
Name: Line 43
Length: 0.782 km
R: 0.126 Ohm
X: 0.091 Ohm
",
+ "Index: 44
Name: Line 44
Length: 0.248 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "Index: 45
Name: Line 45
Length: 2.611 km
R: 0.42 Ohm
X: 0.305 Ohm
",
+ "Index: 46
Name: Line 46
Length: 1.158 km
R: 0.186 Ohm
X: 0.136 Ohm
",
+ "Index: 47
Name: Line 47
Length: 1.526 km
R: 0.246 Ohm
X: 0.179 Ohm
",
+ "Index: 48
Name: Line 48
Length: 2.033 km
R: 0.327 Ohm
X: 0.238 Ohm
",
+ "Index: 49
Name: Line 49
Length: 0.997 km
R: 0.161 Ohm
X: 0.117 Ohm
",
+ "Index: 50
Name: Line 50
Length: 0.804 km
R: 0.129 Ohm
X: 0.094 Ohm
",
+ "Index: 51
Name: Line 51
Length: 0.947 km
R: 0.153 Ohm
X: 0.111 Ohm
",
+ "Index: 52
Name: Line 52
Length: 0.929 km
R: 0.11 Ohm
X: 0.297 Ohm
",
+ "Index: 53
Name: Line 53
Length: 0.778 km
R: 0.092 Ohm
X: 0.249 Ohm
",
+ "Index: 54
Name: Line 54
Length: 0.713 km
R: 0.087 Ohm
X: 0.08 Ohm
",
+ "Index: 55
Name: Line 55
Length: 1.136 km
R: 0.183 Ohm
X: 0.133 Ohm
",
+ "Index: 56
Name: Line 56
Length: 2.149 km
R: 0.346 Ohm
X: 0.251 Ohm
",
+ "Index: 57
Name: Line 57
Length: 0.811 km
R: 0.131 Ohm
X: 0.095 Ohm
",
+ "Index: 58
Name: Line 58
Length: 0.47 km
R: 0.076 Ohm
X: 0.055 Ohm
",
+ "Index: 59
Name: Line 59
Length: 3.155 km
R: 0.508 Ohm
X: 0.369 Ohm
",
+ "Index: 60
Name: Line 60
Length: 0.58 km
R: 0.093 Ohm
X: 0.068 Ohm
",
+ "Index: 61
Name: Line 61
Length: 0.618 km
R: 0.1 Ohm
X: 0.072 Ohm
",
+ "Index: 62
Name: Line 62
Length: 1.006 km
R: 0.12 Ohm
X: 0.322 Ohm
",
+ "Index: 63
Name: Line 63
Length: 0.222 km
R: 0.036 Ohm
X: 0.026 Ohm
",
+ "Index: 64
Name: Line 64
Length: 0.936 km
R: 0.151 Ohm
X: 0.11 Ohm
",
+ "Index: 65
Name: Line 65
Length: 1.341 km
R: 0.216 Ohm
X: 0.157 Ohm
",
+ "Index: 67
Name: Line 67
Length: 0.26 km
R: 0.042 Ohm
X: 0.03 Ohm
",
+ "Index: 68
Name: Line 68
Length: 1.804 km
R: 0.29 Ohm
X: 0.211 Ohm
",
+ "Index: 69
Name: Line 69
Length: 0.59 km
R: 0.095 Ohm
X: 0.069 Ohm
",
+ "Index: 70
Name: Line 70
Length: 0.368 km
R: 0.059 Ohm
X: 0.043 Ohm
",
+ "Index: 71
Name: Line 71
Length: 0.162 km
R: 0.026 Ohm
X: 0.019 Ohm
",
+ "Index: 72
Name: Line 72
Length: 1.455 km
R: 0.234 Ohm
X: 0.17 Ohm
",
+ "Index: 73
Name: Line 73
Length: 0.466 km
R: 0.075 Ohm
X: 0.054 Ohm
",
+ "Index: 74
Name: Line 74
Length: 0.53 km
R: 0.085 Ohm
X: 0.062 Ohm
",
+ "Index: 75
Name: Line 75
Length: 0.304 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "Index: 76
Name: Line 76
Length: 0.347 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "Index: 77
Name: Line 77
Length: 2.122 km
R: 0.342 Ohm
X: 0.248 Ohm
",
+ "Index: 78
Name: Line 78
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 79
Name: Line 79
Length: 0.275 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "Index: 80
Name: Line 80
Length: 0.428 km
R: 0.069 Ohm
X: 0.05 Ohm
",
+ "Index: 81
Name: Line 81
Length: 0.338 km
R: 0.054 Ohm
X: 0.039 Ohm
",
+ "Index: 82
Name: Line 82
Length: 0.349 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "Index: 85
Name: Line 85
Length: 0.329 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "Index: 86
Name: Line 86
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "Index: 87
Name: Line 87
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 90
Name: Line 90
Length: 0.315 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "Index: 91
Name: Line 91
Length: 2.528 km
R: 0.407 Ohm
X: 0.296 Ohm
",
+ "Index: 92
Name: Line 92
Length: 0.093 km
R: 0.015 Ohm
X: 0.011 Ohm
",
+ "Index: 93
Name: Line 93
Length: 0.387 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "Index: 94
Name: Line 94
Length: 0.272 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "Index: 95
Name: Line 95
Length: 0.247 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "Index: 96
Name: Line 96
Length: 0.25 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "Index: 97
Name: Line 97
Length: 0.459 km
R: 0.074 Ohm
X: 0.054 Ohm
",
+ "Index: 98
Name: Line 98
Length: 0.366 km
R: 0.059 Ohm
X: 0.043 Ohm
",
+ "Index: 99
Name: Line 99
Length: 0.291 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "Index: 100
Name: Line 100
Length: 0.299 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 101
Name: Line 101
Length: 0.236 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "Index: 102
Name: Line 102
Length: 0.489 km
R: 0.079 Ohm
X: 0.057 Ohm
",
+ "Index: 103
Name: Line 103
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 104
Name: Line 104
Length: 0.238 km
R: 0.038 Ohm
X: 0.028 Ohm
",
+ "Index: 105
Name: Line 105
Length: 0.177 km
R: 0.029 Ohm
X: 0.021 Ohm
",
+ "Index: 106
Name: Line 106
Length: 0.283 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "Index: 107
Name: Line 107
Length: 0.615 km
R: 0.099 Ohm
X: 0.072 Ohm
",
+ "Index: 108
Name: Line 108
Length: 1.278 km
R: 0.206 Ohm
X: 0.149 Ohm
",
+ "Index: 109
Name: Line 109
Length: 0.147 km
R: 0.024 Ohm
X: 0.017 Ohm
",
+ "Index: 110
Name: Line 110
Length: 0.253 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "Index: 111
Name: Line 111
Length: 0.214 km
R: 0.034 Ohm
X: 0.025 Ohm
",
+ "Index: 112
Name: Line 112
Length: 0.415 km
R: 0.067 Ohm
X: 0.049 Ohm
",
+ "Index: 113
Name: Line 113
Length: 0.18 km
R: 0.029 Ohm
X: 0.021 Ohm
",
+ "Index: 114
Name: Line 114
Length: 0.562 km
R: 0.09 Ohm
X: 0.066 Ohm
",
+ "Index: 116
Name: Line 116
Length: 0.399 km
R: 0.064 Ohm
X: 0.047 Ohm
",
+ "Index: 117
Name: Line 117
Length: 0.261 km
R: 0.042 Ohm
X: 0.031 Ohm
",
+ "Index: 118
Name: Line 118
Length: 0.37 km
R: 0.06 Ohm
X: 0.043 Ohm
",
+ "Index: 119
Name: Line 119
Length: 0.251 km
R: 0.04 Ohm
X: 0.029 Ohm
",
+ "Index: 120
Name: Line 120
Length: 0.304 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "Index: 121
Name: Line 121
Length: 0.233 km
R: 0.037 Ohm
X: 0.027 Ohm
",
+ "Index: 122
Name: Line 122
Length: 0.118 km
R: 0.019 Ohm
X: 0.014 Ohm
",
+ "Index: 123
Name: Line 123
Length: 0.397 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "Index: 124
Name: Line 124
Length: 0.52 km
R: 0.084 Ohm
X: 0.061 Ohm
",
+ "Index: 125
Name: Line 125
Length: 1.526 km
R: 0.246 Ohm
X: 0.179 Ohm
",
+ "Index: 126
Name: Line 126
Length: 0.254 km
R: 0.041 Ohm
X: 0.03 Ohm
",
+ "Index: 127
Name: Line 127
Length: 1.601 km
R: 0.19 Ohm
X: 0.512 Ohm
",
+ "Index: 128
Name: Line 128
Length: 0.473 km
R: 0.076 Ohm
X: 0.055 Ohm
",
+ "Index: 129
Name: Line 129
Length: 0.298 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 130
Name: Line 130
Length: 0.295 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "Index: 131
Name: Line 131
Length: 0.417 km
R: 0.067 Ohm
X: 0.049 Ohm
",
+ "Index: 132
Name: Line 132
Length: 0.323 km
R: 0.052 Ohm
X: 0.038 Ohm
",
+ "Index: 133
Name: Line 133
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 134
Name: Line 134
Length: 0.282 km
R: 0.045 Ohm
X: 0.033 Ohm
",
+ "Index: 135
Name: Line 135
Length: 0.396 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "Index: 136
Name: Line 136
Length: 0.371 km
R: 0.06 Ohm
X: 0.043 Ohm
",
+ "Index: 137
Name: Line 137
Length: 0.274 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "Index: 138
Name: Line 138
Length: 0.329 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "Index: 139
Name: Line 139
Length: 0.499 km
R: 0.08 Ohm
X: 0.058 Ohm
",
+ "Index: 140
Name: Line 140
Length: 0.316 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "Index: 141
Name: Line 141
Length: 0.388 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "Index: 142
Name: Line 142
Length: 0.07 km
R: 0.011 Ohm
X: 0.008 Ohm
",
+ "Index: 143
Name: Line 143
Length: 0.286 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "Index: 144
Name: Line 144
Length: 1.517 km
R: 0.244 Ohm
X: 0.178 Ohm
",
+ "Index: 145
Name: Line 145
Length: 0.719 km
R: 0.116 Ohm
X: 0.084 Ohm
",
+ "Index: 146
Name: Line 146
Length: 0.22 km
R: 0.035 Ohm
X: 0.026 Ohm
",
+ "Index: 147
Name: Line 147
Length: 0.21 km
R: 0.034 Ohm
X: 0.025 Ohm
",
+ "Index: 148
Name: Line 148
Length: 0.239 km
R: 0.039 Ohm
X: 0.028 Ohm
",
+ "Index: 149
Name: Line 149
Length: 0.345 km
R: 0.055 Ohm
X: 0.04 Ohm
",
+ "Index: 150
Name: Line 150
Length: 0.327 km
R: 0.053 Ohm
X: 0.038 Ohm
",
+ "Index: 151
Name: Line 151
Length: 0.553 km
R: 0.068 Ohm
X: 0.062 Ohm
",
+ "Index: 152
Name: Line 152
Length: 0.146 km
R: 0.024 Ohm
X: 0.017 Ohm
",
+ "Index: 153
Name: Line 153
Length: 0.482 km
R: 0.078 Ohm
X: 0.056 Ohm
",
+ "Index: 154
Name: Line 154
Length: 0.443 km
R: 0.071 Ohm
X: 0.052 Ohm
",
+ "Index: 156
Name: Line 156
Length: 0.284 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "Index: 157
Name: Line 157
Length: 1.082 km
R: 0.128 Ohm
X: 0.346 Ohm
",
+ "Index: 158
Name: Line 158
Length: 0.689 km
R: 0.082 Ohm
X: 0.221 Ohm
",
+ "Index: 161
Name: Line 161
Length: 0.468 km
R: 0.057 Ohm
X: 0.052 Ohm
",
+ "Index: 162
Name: Line 162
Length: 2.595 km
R: 0.308 Ohm
X: 0.83 Ohm
",
+ "Index: 163
Name: Line 163
Length: 0.306 km
R: 0.049 Ohm
X: 0.036 Ohm
",
+ "Index: 164
Name: Line 164
Length: 0.566 km
R: 0.091 Ohm
X: 0.066 Ohm
",
+ "Index: 165
Name: Line 165
Length: 0.365 km
R: 0.043 Ohm
X: 0.117 Ohm
",
+ "Index: 167
Name: Line 167
Length: 0.464 km
R: 0.075 Ohm
X: 0.054 Ohm
",
+ "Index: 168
Name: Line 168
Length: 0.42 km
R: 0.068 Ohm
X: 0.049 Ohm
",
+ "Index: 169
Name: Line 169
Length: 0.272 km
R: 0.044 Ohm
X: 0.032 Ohm
",
+ "Index: 170
Name: Line 170
Length: 0.285 km
R: 0.046 Ohm
X: 0.033 Ohm
",
+ "Index: 171
Name: Line 171
Length: 0.77 km
R: 0.124 Ohm
X: 0.09 Ohm
",
+ "Index: 172
Name: Line 172
Length: 0.264 km
R: 0.032 Ohm
X: 0.03 Ohm
",
+ "Index: 173
Name: Line 173
Length: 0.197 km
R: 0.024 Ohm
X: 0.022 Ohm
",
+ "Index: 174
Name: Line 174
Length: 0.28 km
R: 0.045 Ohm
X: 0.033 Ohm
",
+ "Index: 175
Name: Line 175
Length: 0.398 km
R: 0.049 Ohm
X: 0.045 Ohm
",
+ "Index: 177
Name: Line 177
Length: 0.293 km
R: 0.047 Ohm
X: 0.034 Ohm
",
+ "Index: 178
Name: Line 178
Length: 0.449 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "Index: 179
Name: Line 179
Length: 0.551 km
R: 0.089 Ohm
X: 0.064 Ohm
",
+ "Index: 180
Name: Line 180
Length: 1.42 km
R: 0.229 Ohm
X: 0.166 Ohm
",
+ "Index: 181
Name: Line 181
Length: 0.54 km
R: 0.087 Ohm
X: 0.063 Ohm
",
+ "Index: 182
Name: Line 182
Length: 0.355 km
R: 0.043 Ohm
X: 0.04 Ohm
",
+ "Index: 183
Name: Line 183
Length: 0.338 km
R: 0.041 Ohm
X: 0.038 Ohm
",
+ "Index: 184
Name: Line 184
Length: 0.44 km
R: 0.071 Ohm
X: 0.051 Ohm
",
+ "Index: 185
Name: Line 185
Length: 1.095 km
R: 0.176 Ohm
X: 0.128 Ohm
",
+ "Index: 186
Name: Line 186
Length: 0.346 km
R: 0.056 Ohm
X: 0.041 Ohm
",
+ "Index: 187
Name: Line 187
Length: 0.41 km
R: 0.066 Ohm
X: 0.048 Ohm
",
+ "Index: 189
Name: Line 189
Length: 0.446 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "Index: 190
Name: Line 190
Length: 0.314 km
R: 0.051 Ohm
X: 0.037 Ohm
",
+ "Index: 191
Name: Line 191
Length: 0.152 km
R: 0.024 Ohm
X: 0.018 Ohm
",
+ "Index: 192
Name: Line 192
Length: 0.397 km
R: 0.064 Ohm
X: 0.046 Ohm
",
+ "Index: 193
Name: Line 193
Length: 1.006 km
R: 0.12 Ohm
X: 0.322 Ohm
",
+ "Index: 66
Name: Line 66
Length: 0.446 km
R: 0.072 Ohm
X: 0.052 Ohm
",
+ "Index: 8
Name: Line 8
Length: 0.146 km
R: 0.023 Ohm
X: 0.017 Ohm
",
+ "Index: 23
Name: Line 23
Length: 1.188 km
R: 0.191 Ohm
X: 0.139 Ohm
",
+ "Index: 88
Name: Line 88
Length: 0.296 km
R: 0.048 Ohm
X: 0.035 Ohm
",
+ "Index: 188
Name: Line 188
Length: 0.386 km
R: 0.062 Ohm
X: 0.045 Ohm
",
+ "Index: 31
Name: Line 31
Length: 0.967 km
R: 0.156 Ohm
X: 0.113 Ohm
"
+ ],
+ "type": "scatter",
+ "x": [
+ 7.89537812,
+ 7.883015605000001,
+ 7.894886155,
+ 7.895598135,
+ 7.8990065099999995,
+ 7.796604085,
+ 7.7828507,
+ 7.7781972800000005,
+ 7.759929575,
+ 7.75741813,
+ 7.753600355,
+ 7.75644977,
+ 7.8153139,
+ 7.8141311899999994,
+ 7.767543435,
+ 7.77038747,
+ 7.839302065,
+ 7.835960815,
+ 7.888658715,
+ 7.88375491,
+ 7.9023287149999994,
+ 7.89986289,
+ 7.811548925,
+ 7.811856775000001,
+ 7.821959420000001,
+ 7.809870125,
+ 7.817636815,
+ 7.800361985,
+ 7.803873695,
+ 7.80616701,
+ 7.80490146,
+ 7.767762745,
+ 7.77102296,
+ 7.768102655,
+ 7.812061095,
+ 7.755311065,
+ 7.7575011400000005,
+ 7.75334934,
+ 7.866040365,
+ 7.783115085,
+ 7.797232145000001,
+ 7.8531975,
+ 7.870884745,
+ 7.80800915,
+ 7.84064175,
+ 7.793016785000001,
+ 7.781517685,
+ 7.80110821,
+ 7.7648457650000005,
+ 7.833365915,
+ 7.815481699999999,
+ 7.8356101250000005,
+ 7.84498325,
+ 7.830503865000001,
+ 7.8231065399999995,
+ 7.76895487,
+ 7.78631356,
+ 7.79301901,
+ 7.792497825,
+ 7.8112171450000005,
+ 7.91673693,
+ 7.935295334999999,
+ 7.90434245,
+ 7.903670345,
+ 7.898173945,
+ 7.9037709750000005,
+ 7.9067925500000005,
+ 7.90300314,
+ 7.755999655,
+ 7.759177875,
+ 7.91534835,
+ 7.91376112,
+ 7.9111165549999996,
+ 7.913950939999999,
+ 7.909457195,
+ 7.88729778,
+ 7.88803389,
+ 7.90160055,
+ 7.897269120000001,
+ 7.919284535,
+ 7.8954965999999995,
+ 7.89184428,
+ 7.90070719,
+ 7.9353710799999995,
+ 7.93707945,
+ 7.936724785,
+ 7.754632335,
+ 7.7568015,
+ 7.906810965,
+ 7.90352613,
+ 7.905818055,
+ 7.90689844,
+ 7.77608553,
+ 7.777352135,
+ 7.77586919,
+ 7.7740845499999995,
+ 7.765902505,
+ 7.776993185,
+ 7.75449833,
+ 7.75595531,
+ 7.754363245,
+ 7.75505799,
+ 7.748494695,
+ 7.76072003,
+ 7.76396268,
+ 7.763305904999999,
+ 7.748912884999999,
+ 7.75607631,
+ 7.754904595,
+ 7.748432275,
+ 7.75214581,
+ 7.749509665,
+ 7.75589029,
+ 7.745803145,
+ 7.762136115000001,
+ 7.766922235,
+ 7.777775965,
+ 7.765451335,
+ 7.76289518,
+ 7.76801352,
+ 7.77768328,
+ 7.77548636,
+ 7.764061,
+ 7.774377375,
+ 7.775876535,
+ 7.776113069999999,
+ 7.83333661,
+ 7.83633005,
+ 7.81267406,
+ 7.814021225,
+ 7.813518665,
+ 7.82322211,
+ 7.82105249,
+ 7.817074255,
+ 7.81681411,
+ 7.815161659999999,
+ 7.82030535,
+ 7.822882,
+ 7.806599025000001,
+ 7.81008599,
+ 7.815645735,
+ 7.81705197,
+ 7.81726377,
+ 7.90190036,
+ 7.891996945,
+ 7.885721985,
+ 7.89971111,
+ 7.8087861400000005,
+ 7.8168746,
+ 7.91062923,
+ 7.801965490000001,
+ 7.798697495000001,
+ 7.7954268550000005,
+ 7.876737125,
+ 7.8760619599999995,
+ 7.883617055,
+ 7.883312855,
+ 7.8815326500000005,
+ 7.88435623,
+ 7.876242384999999,
+ 7.877545145,
+ 7.88182611,
+ 7.8815137150000005,
+ 7.882708774999999,
+ 7.877797235,
+ 7.880962425,
+ 7.88206173,
+ 7.881069015,
+ 7.886940015,
+ 7.876635985,
+ 7.87366583,
+ 7.876137225,
+ 7.87737687,
+ 7.88285965,
+ 7.75869414,
+ 7.8134101000000005,
+ 7.75780649,
+ 7.897391075,
+ 7.901644045,
+ 7.87516292,
+ 7.8180822249999995
+ ],
+ "y": [
+ 48.408048655,
+ 48.405643245,
+ 48.404547285,
+ 48.400785545,
+ 48.397857075000005,
+ 48.380439095,
+ 48.366959895,
+ 48.366300370000005,
+ 48.34929062,
+ 48.348230975,
+ 48.385219844999995,
+ 48.387082465,
+ 48.388641660000005,
+ 48.387039345,
+ 48.402659025,
+ 48.408535799999996,
+ 48.402896575,
+ 48.400692379999995,
+ 48.41357227,
+ 48.415644475,
+ 48.41458034,
+ 48.415452290000005,
+ 48.43235204,
+ 48.43125182,
+ 48.45768199,
+ 48.462646485,
+ 48.45203385,
+ 48.46771799,
+ 48.46612537,
+ 48.43755075,
+ 48.43412768,
+ 48.416381279999996,
+ 48.413553785000005,
+ 48.41448963,
+ 48.435336795,
+ 48.33892436,
+ 48.331164965,
+ 48.331096165000005,
+ 48.418301435000004,
+ 48.40646346,
+ 48.399978965,
+ 48.403887395,
+ 48.40734532,
+ 48.39432927,
+ 48.401679745,
+ 48.43690116,
+ 48.437053725,
+ 48.438240664999995,
+ 48.394692594999995,
+ 48.425702745,
+ 48.43859573,
+ 48.46862683,
+ 48.462218765,
+ 48.466599715,
+ 48.466165775,
+ 48.438861485000004,
+ 48.459268295,
+ 48.461511654999995,
+ 48.461857235,
+ 48.386801985000005,
+ 48.398924935,
+ 48.39619236,
+ 48.424723924999995,
+ 48.426157905,
+ 48.42874881,
+ 48.420033745,
+ 48.423393835,
+ 48.42253314,
+ 48.351471375,
+ 48.36109096,
+ 48.423280155,
+ 48.42355445,
+ 48.425959675,
+ 48.42182543,
+ 48.424796674999996,
+ 48.41077,
+ 48.412628229999996,
+ 48.39974834,
+ 48.4111002,
+ 48.415948584999995,
+ 48.413764885,
+ 48.41283871,
+ 48.41231499,
+ 48.40119082,
+ 48.40029643,
+ 48.397660775,
+ 48.329382249999995,
+ 48.343999275,
+ 48.396915915,
+ 48.394515569999996,
+ 48.393426364999996,
+ 48.396278865,
+ 48.36052677,
+ 48.3618955,
+ 48.358638865,
+ 48.357209174999994,
+ 48.3549959,
+ 48.363056555,
+ 48.344898515,
+ 48.346755455,
+ 48.348392219999994,
+ 48.345613549999996,
+ 48.3494393,
+ 48.38676202,
+ 48.386584025000005,
+ 48.3876007,
+ 48.387601535,
+ 48.388619445,
+ 48.381509535,
+ 48.386224604999995,
+ 48.382275095,
+ 48.384750305,
+ 48.37201342,
+ 48.38706107,
+ 48.426667905,
+ 48.421883245000004,
+ 48.410324405,
+ 48.411840025000004,
+ 48.41265396,
+ 48.409425600000006,
+ 48.41281236499999,
+ 48.407041925,
+ 48.41413385,
+ 48.413213685,
+ 48.409493485,
+ 48.41155353,
+ 48.39917345,
+ 48.398834405,
+ 48.435725205,
+ 48.38928733,
+ 48.390622725,
+ 48.392084264999994,
+ 48.385808925,
+ 48.38276071,
+ 48.452419565,
+ 48.451561104999996,
+ 48.45258692,
+ 48.453490605,
+ 48.430554895,
+ 48.429347570000004,
+ 48.434035765000004,
+ 48.430788365,
+ 48.42946902,
+ 48.453299900000005,
+ 48.45538149,
+ 48.45618716,
+ 48.4577314,
+ 48.46598067,
+ 48.4658264,
+ 48.45677752,
+ 48.462906950000004,
+ 48.46729328,
+ 48.46589337,
+ 48.465991745,
+ 48.470138035000005,
+ 48.462138464999995,
+ 48.46326563,
+ 48.463131020000006,
+ 48.460205395,
+ 48.47360217,
+ 48.4714864,
+ 48.468303829999996,
+ 48.439124515,
+ 48.45390757,
+ 48.4559398,
+ 48.45649196,
+ 48.458517555,
+ 48.448026635000005,
+ 48.45325575,
+ 48.444776329999996,
+ 48.459793665,
+ 48.462448165,
+ 48.464316139999994,
+ 48.465935615,
+ 48.436465235,
+ 48.384082955,
+ 48.34906194,
+ 48.420544335,
+ 48.395958955,
+ 48.45754019,
+ 48.446855275000004
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "2W transformers",
+ "line": {
+ "color": "rgb(0, 128, 0)",
+ "width": 5
+ },
+ "mode": "lines",
+ "name": "2W transformers",
+ "showlegend": true,
+ "text": "Index: 114
Name: HV/MV Transformer 0
V_n HV: 110.0 kV
V_n LV: 20.0 kV
Tap pos.: -2.0
",
+ "type": "scatter",
+ "x": [
+ 7.91396063,
+ 7.91396063,
+ 7.91396063
+ ],
+ "y": [
+ 48.4569382,
+ 48.4569382,
+ 48.4569382
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "2W transformers",
+ "line": {
+ "color": "rgb(0, 128, 0)",
+ "width": 5
+ },
+ "mode": "lines",
+ "name": "2W transformers",
+ "showlegend": false,
+ "text": "Index: 142
Name: HV/MV Transformer 1
V_n HV: 110.0 kV
V_n LV: 20.0 kV
Tap pos.: -3.0
",
+ "type": "scatter",
+ "x": [
+ 7.76153339,
+ 7.76153339,
+ 7.76153339
+ ],
+ "y": [
+ 48.43987488,
+ 48.43987488,
+ 48.43987488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "2W transformers",
+ "marker": {
+ "color": "rgb(0, 128, 0)",
+ "size": 1,
+ "symbol": "circle"
+ },
+ "mode": "markers",
+ "name": "edge_center",
+ "showlegend": false,
+ "text": [
+ "Index: 114
Name: HV/MV Transformer 0
V_n HV: 110.0 kV
V_n LV: 20.0 kV
Tap pos.: -2.0
",
+ "Index: 142
Name: HV/MV Transformer 1
V_n HV: 110.0 kV
V_n LV: 20.0 kV
Tap pos.: -3.0
"
+ ],
+ "type": "scatter",
+ "x": [
+ 7.91396063,
+ 7.76153339
+ ],
+ "y": [
+ 48.4569382,
+ 48.43987488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "marker": {
+ "color": "rgb(255, 255, 0)",
+ "size": 20,
+ "symbol": "square"
+ },
+ "mode": "markers",
+ "name": "external grid",
+ "text": [
+ "Index: 0
Name: External Grid 0
V_m: 1.0 p.u.
V_a: 0.0 °
",
+ "Index: 1
Name: External Grid 1
V_m: 1.0 p.u.
V_a: 0.0 °
"
+ ],
+ "type": "scatter",
+ "x": [
+ 7.91396063,
+ 7.76153339
+ ],
+ "y": [
+ 48.4569382,
+ 48.43987488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "marker": {
+ "color": "rgb(0, 0, 255)",
+ "size": 10,
+ "symbol": "circle"
+ },
+ "mode": "markers",
+ "name": "buses",
+ "text": [
+ "Index: 0
Name: Bus 0
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.122 MW
",
+ "Index: 1
Name: Bus 1
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.092 MW
",
+ "Index: 2
Name: Bus 2
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 3
Name: Bus 3
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 4
Name: Bus 4
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.092 MW
",
+ "Index: 5
Name: Bus 5
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 6
Name: Bus 6
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 7
Name: Bus 7
V_n: 20.0 kV
",
+ "Index: 8
Name: Bus 8
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.137 MW
",
+ "Index: 29
Name: Bus 9
V_n: 20.0 kV
Static generation: 0.400 MW
",
+ "Index: 30
Name: Bus 10
V_n: 20.0 kV
",
+ "Index: 31
Name: Bus 11
V_n: 20.0 kV
Static generation: 0.800 MW
",
+ "Index: 32
Name: Bus 12
V_n: 20.0 kV
Static generation: 0.200 MW
",
+ "Index: 33
Name: Bus 13
V_n: 20.0 kV
Static generation: 0.856 MW
",
+ "Index: 34
Name: Bus 14
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 35
Name: Bus 15
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.155 MW
",
+ "Index: 36
Name: Bus 16
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 37
Name: Bus 17
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 38
Name: Bus 18
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.049 MW
",
+ "Index: 39
Name: Bus 19
V_n: 20.0 kV
",
+ "Index: 40
Name: Bus 20
V_n: 20.0 kV
Static generation: 0.160 MW
",
+ "Index: 41
Name: Bus 21
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.140 MW
",
+ "Index: 42
Name: Bus 22
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 43
Name: Bus 23
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 44
Name: Bus 24
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.295 MW
",
+ "Index: 45
Name: Bus 25
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.093 MW
",
+ "Index: 46
Name: Bus 26
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 47
Name: Bus 27
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.140 MW
",
+ "Index: 48
Name: Bus 28
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 49
Name: Bus 29
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.093 MW
",
+ "Index: 50
Name: Bus 30
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 51
Name: Bus 31
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 52
Name: Bus 32
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 53
Name: Bus 33
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 54
Name: Bus 34
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.137 MW
",
+ "Index: 55
Name: Bus 35
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 56
Name: Bus 36
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.295 MW
",
+ "Index: 57
Name: Bus 37
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 58
Name: Bus 38
V_n: 110.0 kV
",
+ "Index: 64
Name: Bus 39
V_n: 20.0 kV
",
+ "Index: 65
Name: Bus 40
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.295 MW
",
+ "Index: 71
Name: Bus 41
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.155 MW
",
+ "Index: 72
Name: Bus 42
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 73
Name: Bus 43
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 74
Name: Bus 44
V_n: 20.0 kV
",
+ "Index: 75
Name: Bus 45
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 76
Name: Bus 46
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 77
Name: Bus 47
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.155 MW
",
+ "Index: 78
Name: Bus 48
V_n: 20.0 kV
",
+ "Index: 79
Name: Bus 49
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 80
Name: Bus 50
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 81
Name: Bus 51
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 82
Name: Bus 52
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 83
Name: Bus 53
V_n: 20.0 kV
Static generation: 0.315 MW
",
+ "Index: 84
Name: Bus 54
V_n: 20.0 kV
Static generation: 0.500 MW
",
+ "Index: 85
Name: Bus 55
V_n: 20.0 kV
Static generation: 0.300 MW
",
+ "Index: 86
Name: Bus 56
V_n: 20.0 kV
",
+ "Index: 94
Name: Bus 57
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 95
Name: Bus 58
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 98
Name: Bus 59
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 100
Name: Bus 60
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 101
Name: Bus 61
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 102
Name: Bus 62
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.118 MW
",
+ "Index: 103
Name: Bus 63
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 104
Name: Bus 64
V_n: 20.0 kV
",
+ "Index: 106
Name: Bus 65
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.295 MW
",
+ "Index: 107
Name: Bus 66
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.049 MW
",
+ "Index: 108
Name: Bus 67
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 109
Name: Bus 68
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.049 MW
",
+ "Index: 110
Name: Bus 69
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 111
Name: Bus 70
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 116
Name: Bus 71
V_n: 20.0 kV
",
+ "Index: 117
Name: Bus 72
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.140 MW
",
+ "Index: 118
Name: Bus 73
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 119
Name: Bus 74
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 120
Name: Bus 75
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.093 MW
",
+ "Index: 126
Name: Bus 76
V_n: 20.0 kV
",
+ "Index: 129
Name: Bus 77
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.095 MW
",
+ "Index: 131
Name: Bus 78
V_n: 20.0 kV
",
+ "Index: 132
Name: Bus 79
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 133
Name: Bus 80
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 134
Name: Bus 81
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 136
Name: Bus 82
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 137
Name: Bus 83
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 138
Name: Bus 84
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 140
Name: Bus 85
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.122 MW
",
+ "Index: 141
Name: Bus 86
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 142
Name: Bus 87
V_n: 20.0 kV
",
+ "Index: 143
Name: Bus 88
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.155 MW
",
+ "Index: 144
Name: Bus 89
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 145
Name: Bus 90
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 146
Name: Bus 91
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.233 MW
",
+ "Index: 147
Name: Bus 92
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.137 MW
",
+ "Index: 148
Name: Bus 93
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.093 MW
",
+ "Index: 149
Name: Bus 94
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 150
Name: Bus 95
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.093 MW
",
+ "Index: 153
Name: Bus 96
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 155
Name: Bus 97
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 157
Name: Bus 98
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 159
Name: Bus 99
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 161
Name: Bus 100
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 162
Name: Bus 101
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 167
Name: Bus 102
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.109 MW
",
+ "Index: 168
Name: Bus 103
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.109 MW
",
+ "Index: 169
Name: Bus 104
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.109 MW
",
+ "Index: 170
Name: Bus 105
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.118 MW
",
+ "Index: 171
Name: Bus 106
V_n: 20.0 kV
",
+ "Index: 172
Name: Bus 107
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.214 MW
",
+ "Index: 173
Name: Bus 108
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 174
Name: Bus 109
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.118 MW
",
+ "Index: 176
Name: Bus 110
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 178
Name: Bus 111
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 181
Name: Bus 112
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 184
Name: Bus 113
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 186
Name: Bus 114
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 188
Name: Bus 115
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 189
Name: Bus 116
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 190
Name: Bus 117
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 192
Name: Bus 118
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 194
Name: Bus 119
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.039 MW
",
+ "Index: 195
Name: Bus 120
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.039 MW
",
+ "Index: 196
Name: Bus 121
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 197
Name: Bus 122
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 198
Name: Bus 123
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 199
Name: Bus 124
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 200
Name: Bus 125
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 201
Name: Bus 126
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 205
Name: Bus 127
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.118 MW
",
+ "Index: 207
Name: Bus 128
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.118 MW
",
+ "Index: 210
Name: Bus 129
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 213
Name: Bus 130
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.108 MW
",
+ "Index: 215
Name: Bus 131
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 216
Name: Bus 132
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.069 MW
",
+ "Index: 219
Name: Bus 133
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.100 MW
",
+ "Index: 221
Name: Bus 134
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.060 MW
",
+ "Index: 223
Name: Bus 135
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.150 MW
",
+ "Index: 224
Name: Bus 136
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.150 MW
",
+ "Index: 227
Name: Bus 137
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.100 MW
",
+ "Index: 229
Name: Bus 138
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.060 MW
",
+ "Index: 231
Name: Bus 139
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.060 MW
",
+ "Index: 235
Name: Bus 140
V_n: 20.0 kV
Load: 0.500 MW
",
+ "Index: 236
Name: Bus 141
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.160 MW
",
+ "Index: 237
Name: Bus 142
V_n: 20.0 kV
Static generation: 0.150 MW
",
+ "Index: 238
Name: Bus 143
V_n: 20.0 kV
",
+ "Index: 239
Name: Bus 144
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.090 MW
",
+ "Index: 240
Name: Bus 145
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.122 MW
",
+ "Index: 241
Name: Bus 146
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.076 MW
",
+ "Index: 242
Name: Bus 147
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.122 MW
",
+ "Index: 243
Name: Bus 148
V_n: 20.0 kV
",
+ "Index: 244
Name: Bus 149
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.137 MW
",
+ "Index: 245
Name: Bus 150
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.198 MW
",
+ "Index: 246
Name: Bus 151
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 247
Name: Bus 152
V_n: 20.0 kV
",
+ "Index: 248
Name: Bus 153
V_n: 20.0 kV
Static generation: 0.295 MW
",
+ "Index: 253
Name: Bus 154
V_n: 20.0 kV
Static generation: 0.355 MW
",
+ "Index: 269
Name: Bus 155
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.309 MW
",
+ "Index: 271
Name: Bus 156
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.109 MW
",
+ "Index: 273
Name: Bus 157
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.095 MW
",
+ "Index: 275
Name: Bus 158
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 281
Name: Bus 159
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 285
Name: Bus 160
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 286
Name: Bus 161
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.054 MW
",
+ "Index: 287
Name: Bus 162
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 288
Name: Bus 163
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 289
Name: Bus 164
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.191 MW
",
+ "Index: 290
Name: Bus 165
V_n: 20.0 kV
Load: 0.630 MW
Static generation: 0.198 MW
",
+ "Index: 298
Name: Bus 166
V_n: 20.0 kV
Static generation: 0.300 MW
",
+ "Index: 301
Name: Bus 167
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.054 MW
",
+ "Index: 303
Name: Bus 168
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 304
Name: Bus 169
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 305
Name: Bus 170
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 312
Name: Bus 171
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 313
Name: Bus 172
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 314
Name: Bus 173
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 315
Name: Bus 174
V_n: 20.0 kV
Load: 0.400 MW
Static generation: 0.068 MW
",
+ "Index: 316
Name: Bus 175
V_n: 20.0 kV
Load: 0.250 MW
Static generation: 0.041 MW
",
+ "Index: 317
Name: Bus 176
V_n: 20.0 kV
",
+ "Index: 318
Name: Bus 177
V_n: 110.0 kV
",
+ "Index: 319
Name: Bus 178
V_n: 20.0 kV
"
+ ],
+ "type": "scatter",
+ "x": [
+ 7.76522567,
+ 7.77880954,
+ 7.77919577,
+ 7.77520469,
+ 7.76606485,
+ 7.76739671,
+ 7.75852885,
+ 7.76574338,
+ 7.76946387,
+ 7.78665902,
+ 7.79905951,
+ 7.81661465,
+ 7.82727201,
+ 7.84538508,
+ 7.83405306,
+ 7.87771765,
+ 7.81386611,
+ 7.87688954,
+ 7.93125749,
+ 7.91396063,
+ 7.87852914,
+ 7.87625272,
+ 7.79891555,
+ 7.88824433,
+ 7.79950378,
+ 7.87260819,
+ 7.81894107,
+ 7.87520041,
+ 7.78600346,
+ 7.87750063,
+ 7.78701848,
+ 7.80501543,
+ 7.87725311,
+ 7.8112944,
+ 7.81137059,
+ 7.88088449,
+ 7.79674274,
+ 7.80752534,
+ 7.91396063,
+ 7.81800216,
+ 7.81599919,
+ 7.8959583,
+ 7.80673406,
+ 7.88830762,
+ 7.80946722,
+ 7.80466609,
+ 7.83584018,
+ 7.87808299,
+ 7.88212331,
+ 7.82260854,
+ 7.88546159,
+ 7.88517175,
+ 7.82449029,
+ 7.88777356,
+ 7.79305306,
+ 7.75706106,
+ 7.90923486,
+ 7.90933438,
+ 7.90828612,
+ 7.91778262,
+ 7.91291408,
+ 7.81078043,
+ 7.91393385,
+ 7.81753115,
+ 7.81812248,
+ 7.81719863,
+ 7.91378673,
+ 7.81213406,
+ 7.89617371,
+ 7.81434875,
+ 7.83782535,
+ 7.83571694,
+ 7.88344689,
+ 7.88023004,
+ 7.88076055,
+ 7.88432076,
+ 7.77637635,
+ 7.75752837,
+ 7.81440186,
+ 7.90115002,
+ 7.81265378,
+ 7.90485626,
+ 7.84164512,
+ 7.90759827,
+ 7.83058701,
+ 7.81375095,
+ 7.82229551,
+ 7.90302727,
+ 7.87666867,
+ 7.81192866,
+ 7.87990442,
+ 7.8758161,
+ 7.81550141,
+ 7.88260716,
+ 7.81702049,
+ 7.87715626,
+ 7.75962984,
+ 7.75792025,
+ 7.75339537,
+ 7.76124005,
+ 7.93773871,
+ 7.93829196,
+ 7.75838011,
+ 7.75598728,
+ 7.78157825,
+ 7.83613832,
+ 7.77111891,
+ 7.81672668,
+ 7.93283542,
+ 7.93628735,
+ 7.77603927,
+ 7.77032597,
+ 7.75269597,
+ 7.75385941,
+ 7.74517856,
+ 7.75456734,
+ 7.81593058,
+ 7.8195498,
+ 7.80022205,
+ 7.90263858,
+ 7.88846812,
+ 7.81328782,
+ 7.76147904,
+ 7.75618441,
+ 7.75569132,
+ 7.75578023,
+ 7.89989694,
+ 7.89437546,
+ 7.89638358,
+ 7.8884535,
+ 7.90130341,
+ 7.88603646,
+ 7.8893131,
+ 7.90172272,
+ 7.89506435,
+ 7.90205872,
+ 7.90849453,
+ 7.90443237,
+ 7.90591947,
+ 7.9083386,
+ 7.90432357,
+ 7.90130481,
+ 7.84263834,
+ 7.89470796,
+ 7.89613192,
+ 7.76659341,
+ 7.7617981,
+ 7.77150376,
+ 7.77599056,
+ 7.77518896,
+ 7.77526664,
+ 7.75527749,
+ 7.86375666,
+ 7.80577582,
+ 7.76396796,
+ 7.81091684,
+ 7.75387463,
+ 7.7490983,
+ 7.78580944,
+ 7.7512397,
+ 7.77541442,
+ 7.77756681,
+ 7.77569591,
+ 7.77670102,
+ 7.8060588,
+ 7.76944157,
+ 7.78873191,
+ 7.76226955,
+ 7.7644815,
+ 7.76147033,
+ 7.75612888,
+ 7.74776625,
+ 7.74426069,
+ 7.75780411,
+ 7.74990855,
+ 7.75312516,
+ 7.8790417,
+ 7.76153339,
+ 7.76153339
+ ],
+ "y": [
+ 48.41091584,
+ 48.40987065,
+ 48.41203811,
+ 48.40610337,
+ 48.41242444,
+ 48.42373656,
+ 48.43345788,
+ 48.41987793,
+ 48.40913221,
+ 48.43625936,
+ 48.43759153,
+ 48.44215898,
+ 48.46648941,
+ 48.42296455,
+ 48.46664643,
+ 48.45713891,
+ 48.45138395,
+ 48.44659344,
+ 48.3980943,
+ 48.4569382,
+ 48.40552685,
+ 48.44299303,
+ 48.46284776,
+ 48.45231709,
+ 48.46870231,
+ 48.45794147,
+ 48.46584214,
+ 48.46134835,
+ 48.4585943,
+ 48.46363931,
+ 48.46045784,
+ 48.46296614,
+ 48.46499297,
+ 48.466147,
+ 48.38535297,
+ 48.46626641,
+ 48.46588038,
+ 48.46584322,
+ 48.4569382,
+ 48.45286283,
+ 48.45200045,
+ 48.45361129,
+ 48.43815272,
+ 48.45601148,
+ 48.43003727,
+ 48.43251067,
+ 48.47002488,
+ 48.45477828,
+ 48.45630215,
+ 48.45231101,
+ 48.4585246,
+ 48.45375027,
+ 48.45412175,
+ 48.43320652,
+ 48.46585031,
+ 48.36812437,
+ 48.4561543,
+ 48.42618849,
+ 48.42418937,
+ 48.42400659,
+ 48.42255372,
+ 48.42871494,
+ 48.42590629,
+ 48.43283117,
+ 48.42974203,
+ 48.4281192,
+ 48.42043868,
+ 48.43725275,
+ 48.41100311,
+ 48.43503248,
+ 48.3990085,
+ 48.40021513,
+ 48.46135559,
+ 48.46216934,
+ 48.45936355,
+ 48.46419159,
+ 48.43784809,
+ 48.3495233,
+ 48.38940745,
+ 48.42189392,
+ 48.39170089,
+ 48.42317236,
+ 48.40414471,
+ 48.42108182,
+ 48.39753675,
+ 48.38919055,
+ 48.38807328,
+ 48.42556885,
+ 48.47484423,
+ 48.38755402,
+ 48.46999586,
+ 48.47236011,
+ 48.38288709,
+ 48.46302758,
+ 48.38429982,
+ 48.46740551,
+ 48.34441059,
+ 48.32845845,
+ 48.32979038,
+ 48.32945775,
+ 48.39605777,
+ 48.39911502,
+ 48.34834127,
+ 48.38553948,
+ 48.36717009,
+ 48.40115573,
+ 48.40810119,
+ 48.38789817,
+ 48.40163972,
+ 48.40091852,
+ 48.35663792,
+ 48.35975183,
+ 48.34979926,
+ 48.34577289,
+ 48.34907864,
+ 48.35261081,
+ 48.46357677,
+ 48.45155157,
+ 48.46640752,
+ 48.4152001,
+ 48.41556286,
+ 48.43169169,
+ 48.35023997,
+ 48.34562366,
+ 48.34750562,
+ 48.34396313,
+ 48.41219988,
+ 48.41295983,
+ 48.41424248,
+ 48.41021512,
+ 48.41377255,
+ 48.41239165,
+ 48.41271759,
+ 48.40051529,
+ 48.40360449,
+ 48.39529931,
+ 48.39773842,
+ 48.39390775,
+ 48.39621703,
+ 48.3949975,
+ 48.42675459,
+ 48.39757192,
+ 48.39811545,
+ 48.40549008,
+ 48.3979666,
+ 48.41394964,
+ 48.41348695,
+ 48.41297284,
+ 48.41297438,
+ 48.4106662,
+ 48.40850593,
+ 48.38787178,
+ 48.40965934,
+ 48.39606378,
+ 48.39721686,
+ 48.43490897,
+ 48.38198803,
+ 48.38651875,
+ 48.36588431,
+ 48.38363665,
+ 48.3593875,
+ 48.36261088,
+ 48.36446775,
+ 48.36133205,
+ 48.4359944,
+ 48.41414363,
+ 48.4038838,
+ 48.38622196,
+ 48.38725384,
+ 48.38881634,
+ 48.38127334,
+ 48.38593046,
+ 48.38747799,
+ 48.38819904,
+ 48.38849988,
+ 48.33198343,
+ 48.41572609,
+ 48.43987488,
+ 48.43987488
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": true,
+ "text": "Line 5",
+ "type": "scatter",
+ "x": [
+ 7.78157825,
+ 7.78241594,
+ 7.78757125,
+ 7.80563692,
+ 7.81137059
+ ],
+ "y": [
+ 48.36717009,
+ 48.367589,
+ 48.37274714,
+ 48.38813105,
+ 48.38535297
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 12",
+ "type": "scatter",
+ "x": [
+ 7.75598728,
+ 7.75493654,
+ 7.75226417,
+ 7.7490983
+ ],
+ "y": [
+ 48.38553948,
+ 48.38515046,
+ 48.38528923,
+ 48.38651875
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 14",
+ "type": "scatter",
+ "x": [
+ 7.75598728,
+ 7.75586722,
+ 7.7565325,
+ 7.75620547,
+ 7.75669407,
+ 7.75527749
+ ],
+ "y": [
+ 48.38553948,
+ 48.38577499,
+ 48.38647184,
+ 48.38674957,
+ 48.38741536,
+ 48.38787178
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 17",
+ "type": "scatter",
+ "x": [
+ 7.76396796,
+ 7.77111891
+ ],
+ "y": [
+ 48.39721686,
+ 48.40810119
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 18",
+ "type": "scatter",
+ "x": [
+ 7.77111891,
+ 7.76965603,
+ 7.76946387
+ ],
+ "y": [
+ 48.40810119,
+ 48.40897041,
+ 48.40913221
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 46",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77749826,
+ 7.78873191
+ ],
+ "y": [
+ 48.40850593,
+ 48.40904312,
+ 48.4038838
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 47",
+ "type": "scatter",
+ "x": [
+ 7.78873191,
+ 7.80573238,
+ 7.80577582
+ ],
+ "y": [
+ 48.4038838,
+ 48.39607413,
+ 48.39606378
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 50",
+ "type": "scatter",
+ "x": [
+ 7.81265378,
+ 7.81224648,
+ 7.81164404,
+ 7.80993094,
+ 7.80608736,
+ 7.80577582
+ ],
+ "y": [
+ 48.39170089,
+ 48.39208848,
+ 48.3932605,
+ 48.3941038,
+ 48.39455474,
+ 48.39606378
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 55",
+ "type": "scatter",
+ "x": [
+ 7.76396796,
+ 7.76495858,
+ 7.76629087,
+ 7.7659259,
+ 7.76376563,
+ 7.76270002,
+ 7.76157105,
+ 7.76147033
+ ],
+ "y": [
+ 48.39721686,
+ 48.39694908,
+ 48.39667324,
+ 48.39581646,
+ 48.39356873,
+ 48.39201827,
+ 48.38930585,
+ 48.38881634
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 116",
+ "type": "scatter",
+ "x": [
+ 7.75780411,
+ 7.75917051,
+ 7.76226955
+ ],
+ "y": [
+ 48.38819904,
+ 48.38730208,
+ 48.38622196
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 117",
+ "type": "scatter",
+ "x": [
+ 7.76226955,
+ 7.76344386,
+ 7.7644815
+ ],
+ "y": [
+ 48.38622196,
+ 48.38591421,
+ 48.38725384
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 118",
+ "type": "scatter",
+ "x": [
+ 7.7644815,
+ 7.76213031,
+ 7.76276391,
+ 7.76147033
+ ],
+ "y": [
+ 48.38725384,
+ 48.38794756,
+ 48.38852075,
+ 48.38881634
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 120",
+ "type": "scatter",
+ "x": [
+ 7.75780411,
+ 7.75698634,
+ 7.75516628,
+ 7.75527749
+ ],
+ "y": [
+ 48.38819904,
+ 48.38848522,
+ 48.38875367,
+ 48.38787178
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 121",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75423985,
+ 7.75489924,
+ 7.75490995,
+ 7.75612888
+ ],
+ "y": [
+ 48.38198803,
+ 48.38177685,
+ 48.38177159,
+ 48.38124748,
+ 48.38127334
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 123",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75041699,
+ 7.7512397
+ ],
+ "y": [
+ 48.38198803,
+ 48.38256216,
+ 48.38363665
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 125",
+ "type": "scatter",
+ "x": [
+ 7.75387463,
+ 7.75471952,
+ 7.75706106
+ ],
+ "y": [
+ 48.38198803,
+ 48.37590247,
+ 48.36812437
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 134",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77576803,
+ 7.77520469
+ ],
+ "y": [
+ 48.40850593,
+ 48.40798048,
+ 48.40610337
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "line": {
+ "color": "rgb(255, 0, 0)",
+ "dash": "solid",
+ "width": 1
+ },
+ "mode": "lines",
+ "name": "intersecting lines",
+ "showlegend": false,
+ "text": "Line 137",
+ "type": "scatter",
+ "x": [
+ 7.77526664,
+ 7.77583421,
+ 7.77591886,
+ 7.77518896
+ ],
+ "y": [
+ 48.40850593,
+ 48.40895948,
+ 48.41002749,
+ 48.4106662
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "legendgroup": "lines",
+ "marker": {
+ "color": "rgb(255, 0, 0)",
+ "size": 1,
+ "symbol": "circle"
+ },
+ "mode": "markers",
+ "name": "edge_center",
+ "showlegend": false,
+ "type": "scatter",
+ "x": [
+ 7.796604085,
+ 7.753600355,
+ 7.75644977,
+ 7.767543435,
+ 7.77038747,
+ 7.783115085,
+ 7.797232145000001,
+ 7.80800915,
+ 7.7648457650000005,
+ 7.76072003,
+ 7.76396268,
+ 7.763305904999999,
+ 7.75607631,
+ 7.754904595,
+ 7.75214581,
+ 7.75589029,
+ 7.77548636,
+ 7.775876535
+ ],
+ "y": [
+ 48.380439095,
+ 48.385219844999995,
+ 48.387082465,
+ 48.402659025,
+ 48.408535799999996,
+ 48.40646346,
+ 48.399978965,
+ 48.39432927,
+ 48.394692594999995,
+ 48.38676202,
+ 48.386584025000005,
+ 48.3876007,
+ 48.388619445,
+ 48.381509535,
+ 48.382275095,
+ 48.37201342,
+ 48.407041925,
+ 48.409493485
+ ]
+ },
+ {
+ "fill": "toself",
+ "fillcolor": "rgba(255, 165, 0, 0.2)",
+ "line": {
+ "color": "orange",
+ "width": 0.5
+ },
+ "mode": "lines",
+ "name": "radius",
+ "type": "scatter",
+ "x": [
+ 7.810765587871878,
+ 7.8106677617774745,
+ 7.810284889412847,
+ 7.809620689511773,
+ 7.80868158796014,
+ 7.807476654787392,
+ 7.806017515821131,
+ 7.804318239893644,
+ 7.802395202718501,
+ 7.800266928772189,
+ 7.797953912719253,
+ 7.795478422107161,
+ 7.792864283228295,
+ 7.790136652199385,
+ 7.787321773442097,
+ 7.784446727862211,
+ 7.78153917311691,
+ 7.778627078430524,
+ 7.775738456467715,
+ 7.772901094799059,
+ 7.7701422894976515,
+ 7.767488583386114,
+ 7.764965511411912,
+ 7.7625973555647985,
+ 7.760406911664869,
+ 7.758415270242596,
+ 7.756641613605075,
+ 7.75510303103586,
+ 7.753814353910397,
+ 7.752788012326605,
+ 7.752033914651572,
+ 7.7515593511730385,
+ 7.751368922818724,
+ 7.751464495671189,
+ 7.751845181761232,
+ 7.75250734637233,
+ 7.753444641833605,
+ 7.754648067522638,
+ 7.756106055430859,
+ 7.757804581108197,
+ 7.759727297693585,
+ 7.761855693032329,
+ 7.764169267795486,
+ 7.766645732964237,
+ 7.769261224793018,
+ 7.771990535169408,
+ 7.774807355131724,
+ 7.777684529170111,
+ 7.7805943178263135,
+ 7.783508666021535,
+ 7.786399474482693,
+ 7.7892388716052094,
+ 7.791999483085885,
+ 7.79465469668231,
+ 7.7971789195054155,
+ 7.799547825328778,
+ 7.801738589500652,
+ 7.8037301091720055,
+ 7.805503206703785,
+ 7.807040814287756,
+ 7.8083281385541365,
+ 7.809352801055552,
+ 7.8101049578160415,
+ 7.810577393136094,
+ 7.810765587871878
+ ],
+ "y": [
+ 48.39008484020486,
+ 48.38814455055748,
+ 48.386219988990426,
+ 48.38432968754383,
+ 48.38249184632931,
+ 48.38072415842748,
+ 48.37904363973767,
+ 48.3774664654094,
+ 48.376007814419005,
+ 48.374681723774806,
+ 48.373500953739835,
+ 48.37247686535485,
+ 48.371619311425,
+ 48.370936542005055,
+ 48.37043512527882,
+ 48.370119884582365,
+ 48.3699938521666,
+ 48.37005824013639,
+ 48.370312428841046,
+ 48.3707539728248,
+ 48.371378624281405,
+ 48.37218037379024,
+ 48.373151507948194,
+ 48.374282683351645,
+ 48.375563016227744,
+ 48.37698018686498,
+ 48.37852055785215,
+ 48.38016930500276,
+ 48.38191055971954,
+ 48.38372756144352,
+ 48.385602818733815,
+ 48.387518277439725,
+ 48.38945549435633,
+ 48.39139581469939,
+ 48.393320551696085,
+ 48.39521116656465,
+ 48.397049447148795,
+ 48.39881768348325,
+ 48.400498838916576,
+ 48.402076713547686,
+ 48.40353610145513,
+ 48.40486293732134,
+ 48.406044432253736,
+ 48.407069197362,
+ 48.40792735384139,
+ 48.4086106284868,
+ 48.40911243370284,
+ 48.40942793122652,
+ 48.40955407893841,
+ 48.409489660302576,
+ 48.40923529614661,
+ 48.408793438665676,
+ 48.40816834770915,
+ 48.40736604958169,
+ 48.40639427876253,
+ 48.405262403113596,
+ 48.403981333308515,
+ 48.40256341736819,
+ 48.40102232133412,
+ 48.399372897243836,
+ 48.397631040110234,
+ 48.395813533363906,
+ 48.39393788774903,
+ 48.392022172339374,
+ 48.39008484020486
+ ]
+ },
+ {
+ "marker": {
+ "color": "orange",
+ "size": 10
+ },
+ "mode": "markers",
+ "name": "reference point",
+ "type": "scatter",
+ "x": [
+ 7.7810670720720925
+ ],
+ "y": [
+ 48.3897749246129
+ ]
+ },
+ {
+ "hoverinfo": "text",
+ "marker": {
+ "color": "rgb(255, 0, 0)",
+ "size": 5,
+ "symbol": "circle"
+ },
+ "mode": "markers",
+ "name": "buses within radius",
+ "text": [
+ "Bus 3",
+ "Bus 103",
+ "Bus 106",
+ "Bus 150",
+ "Bus 151",
+ "Bus 153",
+ "Bus 154",
+ "Bus 156",
+ "Bus 166",
+ "Bus 167",
+ "Bus 168",
+ "Bus 169",
+ "Bus 170",
+ "Bus 173"
+ ],
+ "type": "scatter",
+ "x": [
+ 7.77520469,
+ 7.75598728,
+ 7.77111891,
+ 7.77526664,
+ 7.75527749,
+ 7.80577582,
+ 7.76396796,
+ 7.75387463,
+ 7.78873191,
+ 7.76226955,
+ 7.7644815,
+ 7.76147033,
+ 7.75612888,
+ 7.75780411
+ ],
+ "y": [
+ 48.40610337,
+ 48.38553948,
+ 48.40810119,
+ 48.40850593,
+ 48.38787178,
+ 48.39606378,
+ 48.39721686,
+ 48.38198803,
+ 48.4038838,
+ 48.38622196,
+ 48.38725384,
+ 48.38881634,
+ 48.38127334,
+ 48.38819904
+ ]
+ }
+ ],
+ "layout": {
+ "autosize": true,
+ "height": 528.1109895327797,
+ "hovermode": "closest",
+ "legend": {
+ "itemsizing": "constant"
+ },
+ "margin": {
+ "b": 5,
+ "l": 5,
+ "r": 5,
+ "t": 5
+ },
+ "showlegend": true,
+ "template": {
+ "data": {
+ "bar": [
+ {
+ "error_x": {
+ "color": "#2a3f5f"
+ },
+ "error_y": {
+ "color": "#2a3f5f"
+ },
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "bar"
+ }
+ ],
+ "barpolar": [
+ {
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "barpolar"
+ }
+ ],
+ "carpet": [
+ {
+ "aaxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "baxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "type": "carpet"
+ }
+ ],
+ "choropleth": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "choropleth"
+ }
+ ],
+ "contour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "contour"
+ }
+ ],
+ "contourcarpet": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "contourcarpet"
+ }
+ ],
+ "heatmap": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "heatmap"
+ }
+ ],
+ "heatmapgl": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "heatmapgl"
+ }
+ ],
+ "histogram": [
+ {
+ "marker": {
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "histogram"
+ }
+ ],
+ "histogram2d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2d"
+ }
+ ],
+ "histogram2dcontour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2dcontour"
+ }
+ ],
+ "mesh3d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "mesh3d"
+ }
+ ],
+ "parcoords": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "parcoords"
+ }
+ ],
+ "pie": [
+ {
+ "automargin": true,
+ "type": "pie"
+ }
+ ],
+ "scatter": [
+ {
+ "fillpattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ },
+ "type": "scatter"
+ }
+ ],
+ "scatter3d": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatter3d"
+ }
+ ],
+ "scattercarpet": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattercarpet"
+ }
+ ],
+ "scattergeo": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergeo"
+ }
+ ],
+ "scattergl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergl"
+ }
+ ],
+ "scattermapbox": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattermapbox"
+ }
+ ],
+ "scatterpolar": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolar"
+ }
+ ],
+ "scatterpolargl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolargl"
+ }
+ ],
+ "scatterternary": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterternary"
+ }
+ ],
+ "surface": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "surface"
+ }
+ ],
+ "table": [
+ {
+ "cells": {
+ "fill": {
+ "color": "#EBF0F8"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "header": {
+ "fill": {
+ "color": "#C8D4E3"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "type": "table"
+ }
+ ]
+ },
+ "layout": {
+ "annotationdefaults": {
+ "arrowcolor": "#2a3f5f",
+ "arrowhead": 0,
+ "arrowwidth": 1
+ },
+ "autotypenumbers": "strict",
+ "coloraxis": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "colorscale": {
+ "diverging": [
+ [
+ 0,
+ "#8e0152"
+ ],
+ [
+ 0.1,
+ "#c51b7d"
+ ],
+ [
+ 0.2,
+ "#de77ae"
+ ],
+ [
+ 0.3,
+ "#f1b6da"
+ ],
+ [
+ 0.4,
+ "#fde0ef"
+ ],
+ [
+ 0.5,
+ "#f7f7f7"
+ ],
+ [
+ 0.6,
+ "#e6f5d0"
+ ],
+ [
+ 0.7,
+ "#b8e186"
+ ],
+ [
+ 0.8,
+ "#7fbc41"
+ ],
+ [
+ 0.9,
+ "#4d9221"
+ ],
+ [
+ 1,
+ "#276419"
+ ]
+ ],
+ "sequential": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "sequentialminus": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ]
+ },
+ "colorway": [
+ "#636efa",
+ "#EF553B",
+ "#00cc96",
+ "#ab63fa",
+ "#FFA15A",
+ "#19d3f3",
+ "#FF6692",
+ "#B6E880",
+ "#FF97FF",
+ "#FECB52"
+ ],
+ "font": {
+ "color": "#2a3f5f"
+ },
+ "geo": {
+ "bgcolor": "white",
+ "lakecolor": "white",
+ "landcolor": "#E5ECF6",
+ "showlakes": true,
+ "showland": true,
+ "subunitcolor": "white"
+ },
+ "hoverlabel": {
+ "align": "left"
+ },
+ "hovermode": "closest",
+ "mapbox": {
+ "style": "light"
+ },
+ "paper_bgcolor": "white",
+ "plot_bgcolor": "#E5ECF6",
+ "polar": {
+ "angularaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "radialaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "scene": {
+ "xaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "yaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "zaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ }
+ },
+ "shapedefaults": {
+ "line": {
+ "color": "#2a3f5f"
+ }
+ },
+ "ternary": {
+ "aaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "baxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "caxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "title": {
+ "x": 0.05
+ },
+ "xaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ },
+ "yaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ }
+ }
+ },
+ "title": {
+ "font": {
+ "size": 16
+ }
+ },
+ "width": 700,
+ "xaxis": {
+ "autorange": true,
+ "range": [
+ 7.730316686096759,
+ 7.952235963903241
+ ],
+ "showgrid": false,
+ "showticklabels": false,
+ "type": "linear",
+ "zeroline": false
+ },
+ "yaxis": {
+ "autorange": true,
+ "range": [
+ 48.318085289702445,
+ 48.48521739029756
+ ],
+ "showgrid": false,
+ "showticklabels": false,
+ "type": "linear",
+ "zeroline": false
+ }
+ }
+ },
+ "image/png": "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",
+ "text/html": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "x, y = circle_polygon.exterior.xy\n",
+ "polygon_trace = go.Scatter(\n",
+ " x=list(x), \n",
+ " y=list(y), \n",
+ " fill=\"toself\",\n",
+ " mode=\"lines\",\n",
+ " line=dict(color=\"orange\", width=0.5),\n",
+ " fillcolor=\"rgba(255, 165, 0, 0.2)\",\n",
+ " name=\"radius\"\n",
+ ")\n",
+ "\n",
+ "point_trace = go.Scatter(\n",
+ " x=[circle_polygon.centroid.x], \n",
+ " y=[circle_polygon.centroid.y], \n",
+ " mode=\"markers\",\n",
+ " marker=dict(color=\"orange\", size=10),\n",
+ " name=\"reference point\"\n",
+ ")\n",
+ "lt = create_line_trace(net, lines=lines_intersect, color=\"red\", trace_name='intersecting lines')\n",
+ "bt = create_bus_trace(net, buses=buses_within, color=\"red\", trace_name=\"buses within radius\")\n",
+ "fig = simple_plotly(net, auto_open=False, additional_traces=lt)\n",
+ "fig.add_trace(polygon_trace)\n",
+ "fig.add_trace(point_trace)\n",
+ "fig.add_trace(bt[0])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7e7917d4-c696-459c-aa59-df11bb2ffac7",
+ "metadata": {},
+ "source": [
+ "It is also possible to load the GeoJSON, or view the geo column as GeoSeries or a Series with shapely objects."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "3bfe1268-5b40-44c6-b194-aced9ee9d07d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 {\"coordinates\": [7.765225672614365, 48.41091584192147], \"type\": \"Point\"}\n",
+ "1 {\"coordinates\": [7.778809539550178, 48.40987064550492], \"type\": \"Point\"}\n",
+ "2 {\"coordinates\": [7.779195765893586, 48.4120381144602], \"type\": \"Point\"}\n",
+ "3 {\"coordinates\": [7.775204689771646, 48.40610336882051], \"type\": \"Point\"}\n",
+ "4 {\"coordinates\": [7.76606484746611, 48.4124244421834], \"type\": \"Point\"}\n",
+ "Name: geo, dtype: object"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.head() # entries are strings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "f4f49408-5d9b-4083-893b-e857c999befd",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 {'type': 'Point', 'coordinates': [7.76522567, 48.41091584]}\n",
+ "1 {'type': 'Point', 'coordinates': [7.77880954, 48.40987065]}\n",
+ "2 {'type': 'Point', 'coordinates': [7.77919577, 48.41203811]}\n",
+ "3 {'type': 'Point', 'coordinates': [7.77520469, 48.40610337]}\n",
+ "4 {'type': 'Point', 'coordinates': [7.76606485, 48.41242444]}\n",
+ "Name: geo, dtype: object"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.geojson.as_geo_obj.head() # entries are dicts"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "dfbcd7ff-aa5d-4d8f-aaaf-3909dd4fd654",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 POINT (7.76523 48.41092)\n",
+ "1 POINT (7.77881 48.40987)\n",
+ "2 POINT (7.7792 48.41204)\n",
+ "3 POINT (7.7752 48.4061)\n",
+ "4 POINT (7.76606 48.41242)\n",
+ "dtype: geometry"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.geojson.as_geoseries.head() # GeoSeries "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "fc2c3aba-9897-47a3-b076-0fca36134ad2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 POINT (7.765225672614365 48.41091584192147)\n",
+ "1 POINT (7.778809539550178 48.40987064550492)\n",
+ "2 POINT (7.779195765893586 48.4120381144602)\n",
+ "3 POINT (7.775204689771646 48.40610336882051)\n",
+ "4 POINT (7.76606484746611 48.4124244421834)\n",
+ "Name: geo, dtype: object"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.geojson.as_shapely_obj.head() # pandas Series with shapely objects"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9240803c-ce51-4086-af42-a79192c8fcd7",
+ "metadata": {},
+ "source": [
+ "It is also possible to get the coordinates or the geometry type from the GeoJSON. \n",
+ "**Note that it is not recommended to use ._coords in applications, because the projection definition is lost!**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "be589243-c803-48e5-a6ee-ab1140ca350e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 [7.76522567, 48.41091584]\n",
+ "1 [7.77880954, 48.40987065]\n",
+ "2 [7.77919577, 48.41203811]\n",
+ "3 [7.77520469, 48.40610337]\n",
+ "4 [7.76606485, 48.41242444]\n",
+ "Name: geo, dtype: object"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.geojson._coords.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "749ec31d-cde0-4d21-b2d9-fe5dd424e5a5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 Point\n",
+ "1 Point\n",
+ "2 Point\n",
+ "3 Point\n",
+ "4 Point\n",
+ "Name: geo, dtype: object"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "net.bus.geo.geojson.type.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "00ac6187-dc91-4360-b1f5-edbbb8f2710f",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/tutorials/minimal_example.ipynb b/tutorials/minimal_example.ipynb
index 2a33f4eb8..9d9e3f1c1 100644
--- a/tutorials/minimal_example.ipynb
+++ b/tutorials/minimal_example.ipynb
@@ -18,9 +18,12 @@
},
{
"cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-04T19:28:40.415709Z",
+ "start_time": "2024-09-04T19:28:31.792136Z"
+ }
+ },
"source": [
"import pandapower as pp\n",
"\n",
@@ -39,7 +42,9 @@
"#create branch elements\n",
"trafo = pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, std_type=\"0.4 MVA 20/0.4 kV\", name=\"Trafo\")\n",
"line = pp.create_line(net, from_bus=bus2, to_bus=bus3, length_km=0.1, std_type=\"NAYY 4x50 SE\", name=\"Line\")"
- ]
+ ],
+ "outputs": [],
+ "execution_count": 1
},
{
"cell_type": "markdown",
@@ -52,11 +57,24 @@
},
{
"cell_type": "code",
- "execution_count": 2,
- "metadata": {},
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-04T19:28:40.446233Z",
+ "start_time": "2024-09-04T19:28:40.419268Z"
+ }
+ },
+ "source": [
+ "net.bus"
+ ],
"outputs": [
{
"data": {
+ "text/plain": [
+ " name vn_kv type zone in_service geo\n",
+ "0 Bus 1 20.0 b None True None\n",
+ "1 Bus 2 0.4 b None True None\n",
+ "2 Bus 3 0.4 b None True None"
+ ],
"text/html": [
"\n",
"