diff --git a/src/main/java/edu/ie3/netpad/exception/GridManipulationException.java b/src/main/java/edu/ie3/netpad/exception/GridManipulationException.java
new file mode 100644
index 0000000..1f4bed6
--- /dev/null
+++ b/src/main/java/edu/ie3/netpad/exception/GridManipulationException.java
@@ -0,0 +1,16 @@
+/*
+ * © 2020. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+*/
+package edu.ie3.netpad.exception;
+
+public class GridManipulationException extends Exception {
+  public GridManipulationException(String message) {
+    super(message);
+  }
+
+  public GridManipulationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}
diff --git a/src/main/java/edu/ie3/netpad/grid/controller/GridController.java b/src/main/java/edu/ie3/netpad/grid/controller/GridController.java
index ed9add4..0df65af 100644
--- a/src/main/java/edu/ie3/netpad/grid/controller/GridController.java
+++ b/src/main/java/edu/ie3/netpad/grid/controller/GridController.java
@@ -5,21 +5,25 @@
 */
 package edu.ie3.netpad.grid.controller;
 
+import static java.lang.Math.*;
+
 import edu.ie3.datamodel.graph.SubGridGate;
 import edu.ie3.datamodel.graph.SubGridTopologyGraph;
 import edu.ie3.datamodel.models.UniqueEntity;
 import edu.ie3.datamodel.models.input.InputEntity;
+import edu.ie3.datamodel.models.input.MeasurementUnitInput;
 import edu.ie3.datamodel.models.input.NodeInput;
-import edu.ie3.datamodel.models.input.connector.LineInput;
-import edu.ie3.datamodel.models.input.connector.Transformer2WInput;
-import edu.ie3.datamodel.models.input.container.GridContainer;
-import edu.ie3.datamodel.models.input.container.JointGridContainer;
-import edu.ie3.datamodel.models.input.container.SubGridContainer;
+import edu.ie3.datamodel.models.input.connector.*;
+import edu.ie3.datamodel.models.input.container.*;
+import edu.ie3.datamodel.models.input.graphics.LineGraphicInput;
+import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput;
 import edu.ie3.datamodel.models.input.system.LoadInput;
 import edu.ie3.datamodel.models.input.system.PvInput;
 import edu.ie3.datamodel.models.input.system.StorageInput;
 import edu.ie3.datamodel.models.input.system.SystemParticipantInput;
 import edu.ie3.datamodel.utils.ContainerUtils;
+import edu.ie3.datamodel.utils.GridAndGeoUtils;
+import edu.ie3.netpad.exception.GridManipulationException;
 import edu.ie3.netpad.grid.GridModel;
 import edu.ie3.netpad.grid.GridModification;
 import edu.ie3.netpad.grid.ModifiedSubGridData;
@@ -30,20 +34,33 @@
 import edu.ie3.netpad.io.event.SaveGridEvent;
 import edu.ie3.netpad.map.event.MapEvent;
 import edu.ie3.netpad.tool.controller.ToolController;
+import edu.ie3.netpad.tool.controller.ToolDialogs;
 import edu.ie3.netpad.tool.event.FixLineLengthRequestEvent;
 import edu.ie3.netpad.tool.event.LayoutGridRequestEvent;
 import edu.ie3.netpad.tool.event.LayoutGridResponse;
 import edu.ie3.netpad.tool.event.ToolEvent;
 import edu.ie3.netpad.tool.grid.LineLengthFixer;
 import edu.ie3.netpad.tool.grid.LineLengthResolutionMode;
+import edu.ie3.util.geo.GeoUtils;
+import edu.ie3.util.quantities.PowerSystemUnits;
 import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ChangeListener;
+import javax.measure.Quantity;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Length;
+import net.morbz.osmonaut.osm.LatLon;
+import org.jgrapht.graph.DirectedAcyclicGraph;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.LineString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import tech.units.indriya.ComparableQuantity;
+import tech.units.indriya.quantity.Quantities;
+import tech.units.indriya.unit.Units;
 
 /**
  * //ToDo: Class Description
@@ -90,7 +107,6 @@ public Map<UUID, GridModel> getSubGrids() {
   }
 
   private void handleReadGridEvent(ReadGridEvent newValue) {
-
     // clear subGrids
     subGrids.clear();
 
@@ -225,6 +241,547 @@ private ChangeListener<ToolEvent> toolEventListener() {
     };
   }
 
+  /**
+   * Fix the line length discrepancy based on the user given {@link ToolDialogs.FixLineLengthData}
+   *
+   * @param resolutionMode Selected resolution mode
+   * @param selectedSubnets Subnets to apply adjustments to
+   */
+  public void fixLineLength(LineLengthResolutionMode resolutionMode, Set<Integer> selectedSubnets) {
+    JointGridContainer updatedGrid;
+
+    /* Act depending on the chosen resolution mode */
+    switch (resolutionMode) {
+      case GEOGRAPHICAL:
+        updatedGrid = setElectricalToGeographicalLineLength(selectedSubnets);
+        break;
+      case ELECTRICAL:
+        updatedGrid = setGeographicalToElectricalLineLength(selectedSubnets);
+        break;
+      default:
+        log.error("Unknown resolution mode '{}'", resolutionMode);
+        return;
+    }
+
+    /* Build a new event and inform the listeners about the "new" / adapted grid model */
+    handleReadGridEvent(new ReadGridEvent(updatedGrid));
+  }
+
+  /**
+   * Sets the electrical length of all lines within the selected sub nets to the length of their
+   * geographical line string if apparent. If not, it is set to the geographical distance between
+   * start and end node.
+   *
+   * @param selectedSubnets Subnets to apply adjustments to
+   * @return A {@link JointGridContainer} with updated line models
+   * @deprecated This better fits in {@link GridAndGeoUtils}
+   */
+  @Deprecated
+  private JointGridContainer setElectricalToGeographicalLineLength(Set<Integer> selectedSubnets) {
+    /* Adjust the electrical line length to be the same as the geographical distance */
+    List<SubGridContainer> subGridContainers =
+        subGrids.values().parallelStream()
+            .map(GridModel::getSubGridContainer)
+            .map(
+                subGridContainer -> {
+                  if (!selectedSubnets.contains(subGridContainer.getSubnet())) {
+                    /* If this grid isn't selected, hand it back, as it is */
+                    return subGridContainer;
+                  } else {
+                    /* Update all lines */
+                    Set<LineInput> lines =
+                        subGridContainer.getRawGrid().getLines().parallelStream()
+                            .map(GridController::setLineLengthToGeographicDistance)
+                            .collect(Collectors.toSet());
+
+                    /* Put together, what has been there before */
+                    RawGridElements rawGrid =
+                        new RawGridElements(
+                            subGridContainer.getRawGrid().getNodes(),
+                            lines,
+                            subGridContainer.getRawGrid().getTransformer2Ws(),
+                            subGridContainer.getRawGrid().getTransformer3Ws(),
+                            subGridContainer.getRawGrid().getSwitches(),
+                            subGridContainer.getRawGrid().getMeasurementUnits());
+                    return new SubGridContainer(
+                        subGridContainer.getGridName(),
+                        subGridContainer.getSubnet(),
+                        rawGrid,
+                        subGridContainer.getSystemParticipants(),
+                        subGridContainer.getGraphics());
+                  }
+                })
+            .collect(Collectors.toList());
+
+    /* Assemble all sub grids to one container */
+    return ContainerUtils.combineToJointGrid(subGridContainers);
+  }
+
+  /**
+   * Adjusts the line length to the length of their geographical line string if apparent. If not, it
+   * is set to the geographical distance between start and end node.
+   *
+   * @param line line model to adjust
+   * @return The adjusted line model
+   * @deprecated This better fits in {@link GridAndGeoUtils}
+   */
+  @Deprecated
+  private static LineInput setLineLengthToGeographicDistance(LineInput line) {
+    ComparableQuantity<Length> lineLength;
+    lineLength =
+        lengthOfLineString(line.getGeoPosition())
+            .orElseGet(
+                () -> {
+                  log.warn(
+                      "Cannot determine the length of the line string of line '{}' as it only contains one coordinate."
+                          + " Take distance between it's nodes instead.",
+                      line);
+                  return GridAndGeoUtils.distanceBetweenNodes(line.getNodeA(), line.getNodeB());
+                });
+    return line.copy().length(lineLength).build();
+  }
+
+  /**
+   * Calculate the length of a line string
+   *
+   * @param lineString The line string to calculate the length of
+   * @return An option to the length, if it can be determined
+   * @deprecated This method should be transferred to PowerSystemUtils
+   */
+  @Deprecated
+  private static Optional<ComparableQuantity<Length>> lengthOfLineString(LineString lineString) {
+    Coordinate[] coordinates = lineString.getCoordinates();
+
+    if (coordinates.length == 1) {
+      return Optional.empty();
+    }
+
+    /* Go over the line piecewise and sum up the distance */
+    Coordinate a = coordinates[0];
+    Coordinate b = coordinates[1];
+    ComparableQuantity<Length> length = GeoUtils.calcHaversine(a.x, a.y, b.x, b.y);
+    for (int coordIndex = 2; coordIndex < coordinates.length; coordIndex++) {
+      a = b;
+      b = coordinates[coordIndex];
+      length = length.add(GeoUtils.calcHaversine(a.x, a.y, b.x, b.y));
+    }
+
+    return Optional.of(length);
+  }
+
+  /**
+   * Update the lines and nodes in the given joint grid container geo position
+   *
+   * @param selectedSubnets Set of selected sub grid numbers
+   * @return The updated grid container
+   * @deprecated This better fits in {@link GridAndGeoUtils}
+   */
+  @Deprecated
+  private JointGridContainer setGeographicalToElectricalLineLength(Set<Integer> selectedSubnets) {
+    /*
+     * TODO CK
+     *  1) Go through sub grid containers considering a "tree order" (from upper voltage level to lower)
+     *  2) Adapt the position of underlying grids according to the updated position of the upper grid
+     */
+
+    List<SubGridContainer> subGridContainers =
+        subGrids.values().parallelStream()
+            .map(GridModel::getSubGridContainer)
+            .map(
+                subGridContainer -> {
+                  if (selectedSubnets.contains(subGridContainer.getSubnet()))
+                    try {
+                      return setGeographicalToElectricalLineLength(subGridContainer);
+                    } catch (GridManipulationException e) {
+                      log.error(
+                          "Cannot adapt sub grid container '"
+                              + subGridContainer.getSubnet()
+                              + "'. Return the original one.",
+                          e);
+                      return subGridContainer;
+                    }
+                  else return subGridContainer;
+                })
+            .collect(Collectors.toList());
+
+    /* Assemble all sub grids to one container */
+    return ContainerUtils.combineToJointGrid(subGridContainers);
+  }
+
+  /**
+   * Go through each sub grid container and update the lines and nodes in geo position
+   *
+   * @param subGridContainer The sub grid container to adapt
+   * @return The updated grid container
+   * @throws GridManipulationException If the adaption of geographic position is not possible
+   * @deprecated This better fits in {@link GridAndGeoUtils}
+   */
+  @Deprecated
+  private SubGridContainer setGeographicalToElectricalLineLength(SubGridContainer subGridContainer)
+      throws GridManipulationException {
+    /* Determine the slack node as the starting point of the traversal through the grid */
+    Set<NodeInput> transformerNodes =
+        subGridContainer.getRawGrid().getTransformer2Ws().stream()
+            .map(Transformer2WInput::getNodeB)
+            .collect(Collectors.toSet());
+    transformerNodes.addAll(
+        subGridContainer.getRawGrid().getTransformer3Ws().stream()
+            .map(Transformer3WInput::getNodeB)
+            .collect(Collectors.toSet()));
+    transformerNodes.addAll(
+        subGridContainer.getRawGrid().getTransformer3Ws().stream()
+            .map(Transformer3WInput::getNodeC)
+            .collect(Collectors.toSet()));
+    if (transformerNodes.size() > 1)
+      throw new GridManipulationException(
+          "There is more than one starting node in subnet '"
+              + subGridContainer.getSubnet()
+              + "'. Currently only star topology is supported.");
+    NodeInput startNode =
+        transformerNodes.stream()
+            .findFirst()
+            .orElseThrow(
+                () ->
+                    new GridManipulationException(
+                        "Cannot determine the starting node of subnet '"
+                            + subGridContainer.getSubnet()
+                            + "'."));
+
+    /* Build a topology graph of lines and switches to ensure, that the sub grid is a acyclic star-type topology */
+    DirectedAcyclicGraph<NodeInput, ConnectorInput> topologyGraph =
+        new DirectedAcyclicGraph<>(ConnectorInput.class);
+    try {
+      subGridContainer.getRawGrid().allEntitiesAsList().stream()
+          .filter(
+              element ->
+                  LineInput.class.isAssignableFrom(element.getClass())
+                      || SwitchInput.class.isAssignableFrom(element.getClass()))
+          .map(element -> (ConnectorInput) element)
+          .forEach(
+              connector -> {
+                /* Build the topology graph */
+                topologyGraph.addVertex(connector.getNodeA());
+                topologyGraph.addVertex(connector.getNodeB());
+                topologyGraph.addEdge(connector.getNodeA(), connector.getNodeB(), connector);
+              });
+    } catch (IllegalArgumentException e) {
+      throw new GridManipulationException(
+          "The given sub grid topology of sub net '"
+              + subGridContainer.getSubnet()
+              + "' is not suitable for this operation. It has to be acyclic.",
+          e);
+    }
+
+    /* Start from the slack node and traverse downwards */
+    Map<UUID, NodeInput> nodeMapping =
+        new HashMap<>(subGridContainer.getRawGrid().getNodes().size());
+    Set<LineInput> updatedLines = new HashSet<>(subGridContainer.getRawGrid().getLines().size());
+    nodeMapping.put(startNode.getUuid(), startNode);
+    traverseAndUpdateLines(startNode, topologyGraph, nodeMapping, updatedLines);
+
+    return update(subGridContainer, nodeMapping, updatedLines);
+  }
+
+  /**
+   * Traverses through the topology graph with depth-first-search and update the positions of the
+   * nodes and lines.
+   *
+   * @param startNode Node, at which the traversal starts
+   * @param topologyGraph Graph, that depicts the sub grid containers topology
+   * @param nodeMapping Mapping from "old" node's uuid to new node model
+   * @param updatedLines Collection of updated line models
+   * @throws GridManipulationException If no updated version of the given start node can be
+   *     determined
+   * @deprecated This better fits in {@link GridAndGeoUtils}
+   */
+  @Deprecated
+  private void traverseAndUpdateLines(
+      NodeInput startNode,
+      DirectedAcyclicGraph<NodeInput, ConnectorInput> topologyGraph,
+      Map<UUID, NodeInput> nodeMapping,
+      Set<LineInput> updatedLines)
+      throws GridManipulationException {
+    Set<LineInput> descendantLines =
+        topologyGraph.edgesOf(startNode).stream()
+            .filter(
+                connector ->
+                    LineInput.class.isAssignableFrom(connector.getClass())
+                        && updatedLines.stream()
+                            .noneMatch(ul -> ul.getUuid().equals(connector.getUuid())))
+            .map(connector -> (LineInput) connector)
+            .collect(Collectors.toSet());
+    for (LineInput line : descendantLines) {
+      /* Determine the bearing (we are still operating on the "old" lines and nodes) */
+      Coordinate coordinateA = startNode.getGeoPosition().getCoordinate();
+      NodeInput nodeB = line.getNodeA().equals(startNode) ? line.getNodeB() : line.getNodeA();
+      Coordinate coordinateB = nodeB.getGeoPosition().getCoordinate();
+      ComparableQuantity<Angle> bearing =
+          getBearing(
+              new LatLon(coordinateA.y, coordinateA.x), new LatLon(coordinateB.y, coordinateB.x));
+
+      /* Determine the new geo position */
+      NodeInput updatedNodeA = nodeMapping.get(startNode.getUuid());
+      if (Objects.isNull(updatedNodeA))
+        throw new GridManipulationException(
+            "Cannot update grid, as there is an issue with updated nodes");
+      Coordinate updatedCoordinateA = updatedNodeA.getGeoPosition().getCoordinate();
+      LatLon latLonB =
+          secondCoordinateWithDistanceAndBearing(
+              new LatLon(updatedCoordinateA.y, updatedCoordinateA.x), line.getLength(), bearing);
+
+      /* Copy node B */
+      NodeInput updatedNodeB = nodeB.copy().geoPosition(GeoUtils.latlonToPoint(latLonB)).build();
+      nodeMapping.put(nodeB.getUuid(), updatedNodeB);
+
+      /* Adapt the line */
+      LineInput updatedLine =
+          line.copy()
+              .nodeA(updatedNodeA)
+              .nodeB(updatedNodeB)
+              .geoPosition(
+                  GridAndGeoUtils.buildSafeLineStringBetweenNodes(updatedNodeA, updatedNodeB))
+              .build();
+      updatedLines.add(updatedLine);
+
+      /* Go deeper at the node, that we last have traveled */
+      traverseAndUpdateLines(nodeB, topologyGraph, nodeMapping, updatedLines);
+    }
+  }
+
+  /**
+   * Updates the whole container by replacing the nodes in each element and set the updated lines
+   *
+   * @param container The container to update
+   * @param nodeMapping Mapping from "old" node's uuid to new node model
+   * @param updatedLines Collection of updated line models
+   * @param <C> Type of the container to update
+   * @return The updated container
+   */
+  private <C extends GridContainer> C update(
+      C container, Map<UUID, NodeInput> nodeMapping, Set<LineInput> updatedLines) {
+    /* Update the raw grid */
+    RawGridElements rawGrid = container.getRawGrid();
+    Set<NodeInput> nodes =
+        rawGrid.getNodes().stream()
+            .map(node -> nodeMapping.getOrDefault(node.getUuid(), node))
+            .collect(Collectors.toSet());
+    /* If there is an updated line with the same uuid, take this one, otherwise take the existing one. */
+    Set<LineInput> lines =
+        rawGrid.getLines().stream()
+            .map(
+                line ->
+                    updatedLines.stream()
+                        .filter(updatedLine -> updatedLine.getUuid().equals(line.getUuid()))
+                        .findFirst()
+                        .orElse(line))
+            .map(
+                line ->
+                    line.copy()
+                        .nodeA(nodeMapping.getOrDefault(line.getNodeA().getUuid(), line.getNodeA()))
+                        .nodeB(nodeMapping.getOrDefault(line.getNodeB().getUuid(), line.getNodeB()))
+                        .build())
+            .collect(Collectors.toSet());
+    Set<Transformer2WInput> transformers2w =
+        rawGrid.getTransformer2Ws().stream()
+            .map(
+                transformer ->
+                    transformer
+                        .copy()
+                        .nodeA(
+                            nodeMapping.getOrDefault(
+                                transformer.getNodeA().getUuid(), transformer.getNodeA()))
+                        .nodeB(
+                            nodeMapping.getOrDefault(
+                                transformer.getNodeB().getUuid(), transformer.getNodeB()))
+                        .build())
+            .collect(Collectors.toSet());
+    Set<Transformer3WInput> transformers3w =
+        rawGrid.getTransformer3Ws().stream()
+            .map(
+                transformer ->
+                    transformer
+                        .copy()
+                        .nodeA(
+                            nodeMapping.getOrDefault(
+                                transformer.getNodeA().getUuid(), transformer.getNodeA()))
+                        .nodeB(
+                            nodeMapping.getOrDefault(
+                                transformer.getNodeB().getUuid(), transformer.getNodeB()))
+                        .nodeC(
+                            nodeMapping.getOrDefault(
+                                transformer.getNodeC().getUuid(), transformer.getNodeC()))
+                        .build())
+            .collect(Collectors.toSet());
+    Set<SwitchInput> switches =
+        rawGrid.getSwitches().stream()
+            .map(
+                switcher ->
+                    switcher
+                        .copy()
+                        .nodeA(
+                            nodeMapping.getOrDefault(
+                                switcher.getNodeA().getUuid(), switcher.getNodeA()))
+                        .nodeB(
+                            nodeMapping.getOrDefault(
+                                switcher.getNodeB().getUuid(), switcher.getNodeB()))
+                        .build())
+            .collect(Collectors.toSet());
+    Set<MeasurementUnitInput> measurements =
+        rawGrid.getMeasurementUnits().stream()
+            .map(
+                measurement ->
+                    measurement
+                        .copy()
+                        .node(
+                            nodeMapping.getOrDefault(
+                                measurement.getNode().getUuid(), measurement.getNode()))
+                        .build())
+            .collect(Collectors.toSet());
+    RawGridElements updatedRawGridElements =
+        new RawGridElements(nodes, lines, transformers2w, transformers3w, switches, measurements);
+
+    /* Update system participants */
+    List<SystemParticipantInput> updatedElements =
+        container.getSystemParticipants().allEntitiesAsList().stream()
+            .map(
+                participant ->
+                    participant
+                        .copy()
+                        .node(
+                            nodeMapping.getOrDefault(
+                                participant.getNode().getUuid(), participant.getNode()))
+                        .build())
+            .collect(Collectors.toList());
+    SystemParticipants updatedParticipants = new SystemParticipants(updatedElements);
+
+    /* Update graphic elements */
+    GraphicElements graphics = container.getGraphics();
+    Set<NodeGraphicInput> nodeGraphics =
+        graphics.getNodeGraphics().stream()
+            .map(
+                graphic ->
+                    graphic
+                        .copy()
+                        .node(
+                            nodeMapping.getOrDefault(
+                                graphic.getNode().getUuid(), graphic.getNode()))
+                        .build())
+            .collect(Collectors.toSet());
+    Map<UUID, LineInput> lineMapping =
+        updatedLines.stream().collect(Collectors.toMap(UniqueEntity::getUuid, line -> line));
+    Set<LineGraphicInput> lineGraphics =
+        graphics.getLineGraphics().stream()
+            .map(
+                graphic ->
+                    graphic
+                        .copy()
+                        .line(
+                            lineMapping.getOrDefault(
+                                graphic.getLine().getUuid(), graphic.getLine()))
+                        .build())
+            .collect(Collectors.toSet());
+    GraphicElements updatedGraphics = new GraphicElements(nodeGraphics, lineGraphics);
+
+    if (JointGridContainer.class.isAssignableFrom(container.getClass()))
+      return (C)
+          new JointGridContainer(
+              container.getGridName(),
+              updatedRawGridElements,
+              updatedParticipants,
+              updatedGraphics);
+    else
+      return (C)
+          new SubGridContainer(
+              container.getGridName(),
+              ((SubGridContainer) container).getSubnet(),
+              updatedRawGridElements,
+              updatedParticipants,
+              updatedGraphics);
+  }
+
+  /**
+   * Determine the bearing between two coordinates on the earth surface.
+   *
+   * @param latLon1 First coordinate
+   * @param latLon2 Second coordinate
+   * @return The bearing in {@link PowerSystemUnits#DEGREE_GEOM}
+   * @deprecated This better fits in {@link GeoUtils}
+   */
+  @Deprecated
+  private static ComparableQuantity<Angle> getBearing(LatLon latLon1, LatLon latLon2) {
+    double lat1Rad = toRadians(latLon1.getLat());
+    double long1Rad = toRadians(latLon1.getLon());
+    double lat2Rad = toRadians(latLon2.getLat());
+    double long2Rad = toRadians(latLon2.getLon());
+
+    /* Determine distance between both points in km */
+    double distance =
+        GeoUtils.calcHaversine(
+                latLon1.getLat(), latLon1.getLon(), latLon2.getLat(), latLon2.getLon())
+            .getValue()
+            .doubleValue();
+
+    /* Calculate the portion of the given distance from a full turnaround around the earth */
+    double portionOfFullTurnaround =
+        distance / GeoUtils.EARTH_RADIUS.to(PowerSystemUnits.KILOMETRE).getValue().doubleValue();
+
+    double bearing =
+        toDegrees(
+            asin(
+                (tan(long2Rad - long1Rad)
+                        * (cos(portionOfFullTurnaround) - sin(lat1Rad) * sin(lat2Rad)))
+                    / (sin(portionOfFullTurnaround) * cos(lat1Rad))));
+
+    /* Adapt the bearing (+/-90°) in order to meet our understanding of the bearing (0...360°) */
+    if (lat2Rad <= lat1Rad) bearing = 180 - bearing;
+    else if (long2Rad < long1Rad) bearing = 360 + bearing;
+
+    return Quantities.getQuantity(bearing, PowerSystemUnits.DEGREE_GEOM);
+  }
+
+  /**
+   * Calculates a second coordinate in relation to a start coordinate, a bearing and a given
+   * distance. Many thanks to <a href="https://github.com/shayanjm">shayanjm<a/> for his very
+   * helpful <a href="https://gist.github.com/shayanjm/451a3242685225aa934b">Clojure-Gist</a>, which
+   * served as a blue print for this implementation
+   *
+   * @param start Start position
+   * @param distanceQty Intended distance between start and target position
+   * @param bearingQty Intended bearing between start and target position (0° points northbound,
+   *     increasing clockwise)
+   * @return The second coordinate with intended distance and bearing with reference to the start
+   *     coordinate
+   * @deprecated This better fits in {@link GeoUtils}
+   */
+  @Deprecated
+  private static LatLon secondCoordinateWithDistanceAndBearing(
+      LatLon start, Quantity<Length> distanceQty, Quantity<Angle> bearingQty) {
+    /* Do the unit conversions, so that the input complies to specifications */
+    double distance = distanceQty.to(PowerSystemUnits.KILOMETRE).getValue().doubleValue();
+    double bearing = bearingQty.to(Units.RADIAN).getValue().doubleValue();
+    double latStart = toRadians(start.getLat());
+    double longStart = toRadians(start.getLon());
+
+    /* Calculate the portion of the given distance from a full turnaround around the earth */
+    double portionOfFullTurnaround =
+        distance / GeoUtils.EARTH_RADIUS.to(PowerSystemUnits.KILOMETRE).getValue().doubleValue();
+
+    /* Calculate the target coordinate */
+    double targetLatRad =
+        asin(
+            sin(latStart) * cos(portionOfFullTurnaround)
+                + cos(latStart)
+                    * sin(portionOfFullTurnaround)
+                    * cos(bearing)); // Do not convert to degrees. Is used in second formula.
+    double targetLongRad =
+        longStart
+            + atan2(
+                sin(bearing) * sin(portionOfFullTurnaround) * cos(latStart),
+                cos(portionOfFullTurnaround) - sin(latStart) * sin(targetLatRad));
+
+    return new LatLon(toDegrees(targetLatRad), toDegrees(targetLongRad));
+  }
+
   private ChangeListener<IOEvent> ioEventListener() {
     return (observable, oldValue, newValue) -> {
       if (newValue instanceof ReadGridEvent) {
diff --git a/src/main/java/edu/ie3/netpad/tool/controller/ToolDialogs.java b/src/main/java/edu/ie3/netpad/tool/controller/ToolDialogs.java
index 0578493..379c47a 100644
--- a/src/main/java/edu/ie3/netpad/tool/controller/ToolDialogs.java
+++ b/src/main/java/edu/ie3/netpad/tool/controller/ToolDialogs.java
@@ -44,11 +44,10 @@ public static Dialog<FixLineLengthData> fixLineLengthDialog() {
     ToggleButton electricalBtn = new RadioButton("Electrical → Geographical");
     electricalBtn.setUserData(ELECTRICAL);
     electricalBtn.setToggleGroup(tglGrp);
-    electricalBtn.setDisable(true);
     ToggleButton geographicalBtn = new RadioButton("Geographical → Electrical");
     geographicalBtn.setUserData(GEOGRAPHICAL);
     geographicalBtn.setToggleGroup(tglGrp);
-    tglGrp.selectToggle(geographicalBtn);
+    tglGrp.selectToggle(electricalBtn);
     gridPane.addRow(0, modeLbl, electricalBtn);
     gridPane.add(geographicalBtn, 1, 1);
 
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 16fea71..5ea8494 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -42,6 +42,10 @@
             <AppenderRef ref="Console" level="info"/>
             <AppenderRef ref="RF" level="debug"/>
         </asyncRoot>
+        <logger name="edu.ie3.netpad" additivity="false">
+            <AppenderRef ref="Console" level="info"/>
+            <AppenderRef ref="RF" level="debug"/>
+        </logger>
         <logger name="edu.ie3.datamodel" additivity="false">
             <AppenderRef ref="Console" level="off"/>
             <AppenderRef ref="RF-psdm" level="debug"/>
diff --git a/src/test/groovy/edu/ie3/netpad/grid/controller/GridControllerTest.groovy b/src/test/groovy/edu/ie3/netpad/grid/controller/GridControllerTest.groovy
index e42caee..bb54fe2 100644
--- a/src/test/groovy/edu/ie3/netpad/grid/controller/GridControllerTest.groovy
+++ b/src/test/groovy/edu/ie3/netpad/grid/controller/GridControllerTest.groovy
@@ -5,11 +5,89 @@
  */
 package edu.ie3.netpad.grid.controller
 
-import edu.ie3.netpad.test.common.SampleData
+import edu.ie3.datamodel.models.OperationTime
+import edu.ie3.datamodel.models.StandardUnits
+import edu.ie3.datamodel.models.input.NodeInput
+import edu.ie3.datamodel.models.input.OperatorInput
+import edu.ie3.datamodel.models.input.connector.LineInput
+import edu.ie3.datamodel.models.input.connector.type.LineTypeInput
+import edu.ie3.datamodel.models.input.container.GridContainer
+import edu.ie3.datamodel.models.input.system.characteristic.OlmCharacteristicInput
+import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils
+import edu.ie3.datamodel.utils.GridAndGeoUtils
+import edu.ie3.netpad.io.controller.IoController
+import edu.ie3.netpad.io.event.ReadGridEvent
 import edu.ie3.netpad.util.SampleGridFactory
+import edu.ie3.test.common.grids.LengthAdaptionTestGrid
+import edu.ie3.util.quantities.PowerSystemUnits
+import edu.ie3.util.quantities.QuantityUtil
+import net.morbz.osmonaut.osm.LatLon
+import org.locationtech.jts.geom.Coordinate
+import spock.lang.Shared
 import spock.lang.Specification
+import spock.lang.Unroll
+import tech.units.indriya.quantity.Quantities
 
-class GridControllerTest extends Specification implements SampleData {
+import javax.measure.Quantity
+import javax.measure.quantity.Length
+import java.util.stream.Collectors
+
+import edu.ie3.util.geo.GeoUtils
+
+class GridControllerTest extends Specification implements LengthAdaptionTestGrid {
+
+	@Shared
+	LineInput testLine
+
+	def setupSpec() {
+		/* Build the test line */
+		def nodeA = new NodeInput(
+				UUID.randomUUID(),
+				"nodeA",
+				OperatorInput.NO_OPERATOR_ASSIGNED,
+				OperationTime.notLimited(),
+				Quantities.getQuantity(1d, PowerSystemUnits.PU),
+				false,
+				GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(51.49292, 7.41197)),
+				GermanVoltageLevelUtils.LV,
+				1
+				)
+
+		def nodeB = new NodeInput(
+				UUID.randomUUID(),
+				"nodeB",
+				OperatorInput.NO_OPERATOR_ASSIGNED,
+				OperationTime.notLimited(),
+				Quantities.getQuantity(1d, PowerSystemUnits.PU),
+				false,
+				GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(51.49404, 7.41279)),
+				GermanVoltageLevelUtils.LV,
+				1
+				)
+
+		testLine = new LineInput(
+				UUID.randomUUID(),
+				"testLine",
+				OperatorInput.NO_OPERATOR_ASSIGNED,
+				OperationTime.notLimited(),
+				nodeA,
+				nodeB,
+				1,
+				new LineTypeInput(
+				UUID.randomUUID(),
+				"testType",
+				Quantities.getQuantity(0d, StandardUnits.ADMITTANCE_PER_LENGTH),
+				Quantities.getQuantity(0d, StandardUnits.ADMITTANCE_PER_LENGTH),
+				Quantities.getQuantity(0d, StandardUnits.IMPEDANCE_PER_LENGTH),
+				Quantities.getQuantity(0d, StandardUnits.IMPEDANCE_PER_LENGTH),
+				Quantities.getQuantity(0d, StandardUnits.ELECTRIC_CURRENT_MAGNITUDE),
+				Quantities.getQuantity(0.4, StandardUnits.RATED_VOLTAGE_MAGNITUDE)
+				),
+				Quantities.getQuantity(0d, PowerSystemUnits.KILOMETRE),
+				GridAndGeoUtils.buildSafeLineStringBetweenNodes(nodeA, nodeB),
+				OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+				)
+	}
 
 	def "A GridController should find the correct grid based from a valid mapping of grid id and a set of entity ids"() {
 		given:
@@ -47,7 +125,280 @@ class GridControllerTest extends Specification implements SampleData {
 
 		def subGridUuid = GridController.instance.findSubGridUuid(validMapping, sampleGrid)
 
-		subGridUuid.isPresent()
+		subGridUuid.present
 		subGridUuid == Optional.of(gridUuid)
 	}
+
+	def "A GridController is able to calculate the correct total length of a LineString"() {
+		given:
+		def coordinates = [
+			new Coordinate(7.41197, 51.49292),
+			new Coordinate(7.41183, 51.49333),
+			new Coordinate(7.41189, 51.49341),
+			new Coordinate(7.41172, 51.49391),
+			new Coordinate(7.41279, 51.49404)
+		] as Coordinate[]
+
+		def lineString = GeoUtils.DEFAULT_GEOMETRY_FACTORY.createLineString(coordinates)
+		def expectedLength = Quantities.getQuantity(0.2372622519686716860237276, PowerSystemUnits.KILOMETRE)
+
+		when:
+		def actualLength = GridController.lengthOfLineString(lineString)
+
+		then:
+		actualLength.present
+		QuantityUtil.isEquivalentAbs(actualLength.get(), expectedLength)
+	}
+
+	/* Remark: The emtpy Optional being returned when handing in a LineString with only one node cannot be tested, as
+	 * a LineString cannot be created with one coordinate only */
+
+	def "A GridController is able to adjust the electrical line length to it's line string's total length"() {
+		given:
+		def coordinates = [
+			new Coordinate(7.41197, 51.49292),
+			new Coordinate(7.41183, 51.49333),
+			new Coordinate(7.41189, 51.49341),
+			new Coordinate(7.41172, 51.49391),
+			new Coordinate(7.41279, 51.49404)
+		] as Coordinate[]
+		def lineString = GeoUtils.DEFAULT_GEOMETRY_FACTORY.createLineString(coordinates)
+		def line = testLine.copy().geoPosition(lineString).build()
+		def expectedLength = Quantities.getQuantity(0.2372622519686716860237276, PowerSystemUnits.KILOMETRE)
+
+		when:
+		def updateLine = GridController.setLineLengthToGeographicDistance(line)
+
+		then:
+		QuantityUtil.isEquivalentAbs(updateLine.length, expectedLength)
+	}
+
+	def "A GridController is capable of adjusting the electrical line length to actual length within a selected subnet"() {
+		given:
+		/* Load sample grid and announce it to the grid controller */
+		def sampleGrid = SampleGridFactory.sampleJointGrid()
+		IoController.instance.notifyListener(new ReadGridEvent(sampleGrid))
+
+		def expectedLineLengths = [
+			/* subnet 1 */
+			(UUID.fromString("92ec3bcf-1777-4d38-af67-0bf7c9fa73c7")): Quantities.getQuantity(0.13570403123164909653797, PowerSystemUnits.KILOMETRE),
+			(UUID.fromString("4dd1bde7-0ec9-4540-ac9e-008bc5f883ba")): Quantities.getQuantity(0.065091844094861731826615, PowerSystemUnits.KILOMETRE),
+			(UUID.fromString("d0f36763-c11e-46a4-bf6b-e57fb06fd8d8")): Quantities.getQuantity(0.11430643088441233981695, PowerSystemUnits.KILOMETRE),
+
+			/* subnet 2 (will be unchanged) */
+			(UUID.fromString("b83b93ed-7468-47c2-aed9-48e554c428c7")): Quantities.getQuantity(1.11308358844200193288058, PowerSystemUnits.KILOMETRE),
+			(UUID.fromString("571e8b88-dd9d-4542-89ed-b7f37916d775")): Quantities.getQuantity(2.65621973769665467422535, PowerSystemUnits.KILOMETRE),
+			(UUID.fromString("7197e24f-97cd-4764-ae22-40cdc2f26dd2")): Quantities.getQuantity(1.82710747893781441715269, PowerSystemUnits.KILOMETRE),
+		]
+
+		def selectedSubnets = [1] as Set
+
+		when:
+		def actual = GridController.instance.setElectricalToGeographicalLineLength(selectedSubnets)
+		def actualLineLengths = actual.rawGrid.lines.stream().collect(Collectors.toMap(
+				{ k -> ((LineInput) k).uuid },
+				{ v -> ((LineInput) v).length }))
+
+		then:
+		/* Check each line's length */
+		expectedLineLengths.forEach { UUID uuid, Quantity<Length> expectedLength ->
+			def actualLength = actualLineLengths.get(uuid)
+
+			assert Objects.nonNull(actualLength)
+			assert QuantityUtil.isEquivalentAbs(expectedLength, actualLength)
+		}
+	}
+
+	@Unroll
+	def "A GridController is able to determine the bearing to #bearing degree between #latLon1 and #latLon2 correctly"() {
+		when:
+		def actual = GridController.getBearing(latLon1, latLon2)
+
+		then:
+		actual.unit == PowerSystemUnits.DEGREE_GEOM
+		Math.abs(bearing - actual.value.doubleValue()) < 1E-2
+
+		where:
+		latLon1                           | latLon2                                           || bearing
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.493311252841195, 7.4116482)         || 0.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.490679705804766, 7.421849967564311) || 45.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.4843281, 7.426073668191069)         || 90.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.47797560937315, 7.421847125806461)  || 135.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.4753449471588, 7.4116482)           || 180.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.47797560937315, 7.401449274193539)  || 225.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.4843281, 7.397222731808931)         || 270.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.490679705804766, 7.401446432435688) || 315.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(53.60884374694267, 7.4116482)          || 0.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(52.9608245636982, 9.90581664831644)    || 45.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.4348704962085, 10.820806952802956)  || 90.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(49.958281440399226, 9.746834735372158) || 135.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(49.35981245305733, 7.4116482)          || 180.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(49.958281440399226, 5.076461664627842) || 225.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(51.4348704962085, 4.0024894471970445)  || 270.0
+		new LatLon(51.4843281, 7.4116482) | new LatLon(52.9608245636982, 4.91747975168356)    || 315.0
+	}
+
+	@Unroll
+	def "A GridController is able to determine a second position #distance km away from start with a bearing of #bearing degree."() {
+		when:
+		def actual = GridController.secondCoordinateWithDistanceAndBearing(
+				start,
+				Quantities.getQuantity(distance, PowerSystemUnits.KILOMETRE),
+				Quantities.getQuantity(bearing, PowerSystemUnits.DEGREE_GEOM)
+				)
+
+		then:
+		Math.abs(expectedPosition.lat - actual.lat) < 1E-6
+		Math.abs(expectedPosition.lon - actual.lon) < 1E-6
+
+		/* The difference between targeted and actual distance is in the order of E-13 in this test. As the above
+		 * mentioned snippet does not really point out, what the bearing is, an actual validation is quite hard. */
+
+		where:
+		start                             | bearing | distance || expectedPosition
+		new LatLon(51.4843281, 7.4116482) | 0.0     | 1.0      || new LatLon(51.493311252841195, 7.4116482)
+		new LatLon(51.4843281, 7.4116482) | 45.0    | 1.0      || new LatLon(51.490679705804766, 7.421849967564311)
+		new LatLon(51.4843281, 7.4116482) | 90.0    | 1.0      || new LatLon(51.4843281, 7.426073668191069)
+		new LatLon(51.4843281, 7.4116482) | 135.0   | 1.0      || new LatLon(51.47797560937315, 7.421847125806461)
+		new LatLon(51.4843281, 7.4116482) | 180.0   | 1.0      || new LatLon(51.4753449471588, 7.4116482)
+		new LatLon(51.4843281, 7.4116482) | 225.0   | 1.0      || new LatLon(51.47797560937315, 7.401449274193539)
+		new LatLon(51.4843281, 7.4116482) | 270.0   | 1.0      || new LatLon(51.4843281, 7.397222731808931)
+		new LatLon(51.4843281, 7.4116482) | 315.0   | 1.0      || new LatLon(51.490679705804766, 7.401446432435688)
+		new LatLon(51.4843281, 7.4116482) | 0.0     | 236.5    || new LatLon(53.60884374694267, 7.4116482)
+		new LatLon(51.4843281, 7.4116482) | 45.0    | 236.5    || new LatLon(52.9608245636982, 9.90581664831644)
+		new LatLon(51.4843281, 7.4116482) | 90.0    | 236.5    || new LatLon(51.4348704962085, 10.820806952802956)
+		new LatLon(51.4843281, 7.4116482) | 135.0   | 236.5    || new LatLon(49.958281440399226, 9.746834735372158)
+		new LatLon(51.4843281, 7.4116482) | 180.0   | 236.5    || new LatLon(49.35981245305733, 7.4116482)
+		new LatLon(51.4843281, 7.4116482) | 225.0   | 236.5    || new LatLon(49.958281440399226, 5.076461664627842)
+		new LatLon(51.4843281, 7.4116482) | 270.0   | 236.5    || new LatLon(51.4348704962085, 4.0024894471970445)
+		new LatLon(51.4843281, 7.4116482) | 315.0   | 236.5    || new LatLon(52.9608245636982, 4.91747975168356)
+	}
+
+	def "A GridController is able to update nodes in a grid container"() {
+		given:
+		IoController.instance.notifyListener(new ReadGridEvent(testGrid))
+
+		def updatedNodeA = nodeA.copy().subnet(3).build()
+		def nodeMapping = new HashMap<UUID, NodeInput>()
+		nodeMapping.put(updatedNodeA.uuid, updatedNodeA)
+
+		def expectedNodes = [
+			(nodeA.uuid): updatedNodeA,
+			(nodeB.uuid): nodeB,
+			(nodeC.uuid): nodeC,
+			(nodeD.uuid): nodeD,
+			(nodeE.uuid): nodeE,
+			(nodeF.uuid): nodeF,
+			(nodeG.uuid): nodeG
+		]
+
+		when:
+		def actual = GridController.instance.update(testGrid as GridContainer, nodeMapping, [] as Set<LineInput>)
+		def uuidToNode = actual
+				.rawGrid
+				.nodes
+				.stream()
+				.collect(
+				Collectors.toMap(
+				{ node -> ((NodeInput) node).uuid }, { node ->
+					((NodeInput) node)
+				}
+				)
+				)
+
+		then:
+		uuidToNode.size() == expectedNodes.size()
+		uuidToNode.forEach { uuid, node ->
+			assert expectedNodes.get(uuid) == node
+		}
+	}
+
+	def "A GridController is able to update lines in a grid container"() {
+		given:
+		def updatedLineBC = lineBC.copy().length(Quantities.getQuantity(3d, PowerSystemUnits.KILOMETRE)).build()
+		def updatedLineCD = lineCD.copy().length(Quantities.getQuantity(3d, PowerSystemUnits.KILOMETRE)).build()
+		def updatedLines = new HashSet<LineInput>()
+		updatedLines.add(updatedLineBC)
+		updatedLines.add(updatedLineCD)
+
+		def expectedLines = new HashMap<UUID, LineInput>()
+		expectedLines.put(lineBC.uuid, updatedLineBC)
+		expectedLines.put(lineCD.uuid, updatedLineCD)
+		expectedLines.put(lineCE.uuid, lineCE)
+		expectedLines.put(lineEF.uuid, lineEF)
+		expectedLines.put(lineEG.uuid, lineEG)
+
+		when:
+		def actual = GridController.instance.update(testGrid as GridContainer, [:] as Map<UUID, NodeInput>, updatedLines)
+		def uuidToLine = actual
+				.rawGrid
+				.lines
+				.stream()
+				.collect(
+				Collectors.toMap(
+				{ line -> ((LineInput) line).uuid }, { line ->
+					((LineInput) line)
+				}
+				)
+				)
+
+		then:
+		uuidToLine.size() == expectedLines.size()
+		uuidToLine.forEach { uuid, node ->
+			assert expectedLines.get(uuid) == node
+		}
+	}
+
+	def "A GridController is able to traverse a sub grid and adjust the line length"() {
+		given:
+		def subGrid = testGrid.subGridTopologyGraph
+				.vertexSet()
+				.stream()
+				.filter({ subgrid -> subgrid.subnet == 2 })
+				.findFirst()
+				.orElseThrow({ -> new RuntimeException("Someone has stolen subnet 2...") })
+
+		def expectedNodeLocations = [
+			(UUID.fromString("36514e92-e6d9-4a7e-85b1-175ec6e27216")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.411931, 51.493045)),
+			(UUID.fromString("78beb137-45e2-43e3-8baa-1c25f0c91616")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.411931, 51.493045)),
+			(UUID.fromString("83586a39-8a55-4b10-a034-7ccfe6a451cb")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.406760294855038, 51.51527105298355)),
+			(UUID.fromString("a0746324-3c74-4a03-9e45-41ae2880ad8d")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.398784924455003, 51.53717392365705)),
+			(UUID.fromString("1e755e89-7bfb-4987-9bee-358ac1892313")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.441181742043899, 51.5220222908142)),
+			(UUID.fromString("7dc3d14b-3536-43b8-96f4-0f43b26854f8")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.476588680897974, 51.52638713859204)),
+			(UUID.fromString("292ea9b1-79f8-4615-bad5-c0d33b17527d")): GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint(new Coordinate(7.45062367268736, 51.54369850948029))
+		]
+
+		when:
+		def actual = GridController.instance.setGeographicalToElectricalLineLength(subGrid)
+
+		then:
+		"all line length differ less than 1mm and line string as well as nodes do match"
+		actual.rawGrid.lines.forEach {
+			def pointA = it.nodeA.geoPosition
+			def pointB = it.nodeB.geoPosition
+			def geographicalDistance = GeoUtils.calcHaversine(pointA.y, pointA.x, pointB.y, pointB.x)
+
+			assert QuantityUtil.isEquivalentAbs(geographicalDistance, it.length, 10E-6)
+
+			def lineStringStart = it.geoPosition.startPoint
+			def lineStringEnd = it.geoPosition.endPoint
+
+			assert (
+			lineStringStart.equalsExact(pointA, 1E-6)
+			&& lineStringEnd.equalsExact(pointB, 1E-6)
+			) || (
+			lineStringStart.equalsExact(pointB, 1E-6)
+			&& lineStringEnd.equalsExact(pointA, 1E-6)
+			)
+		}
+
+		"all nodes are at it's foreseen place"
+		actual.rawGrid.nodes.forEach {
+			def expectedPosition = expectedNodeLocations.get(it.uuid)
+			if (Objects.isNull(expectedPosition))
+				throw new RuntimeException("Somebody has stolen the expected position of '" + it + "'")
+
+			assert expectedPosition.equalsExact(it.geoPosition, 1E-6)
+		}
+	}
 }
diff --git a/src/test/groovy/edu/ie3/test/common/grids/LengthAdaptionTestGrid.groovy b/src/test/groovy/edu/ie3/test/common/grids/LengthAdaptionTestGrid.groovy
new file mode 100644
index 0000000..f24dd63
--- /dev/null
+++ b/src/test/groovy/edu/ie3/test/common/grids/LengthAdaptionTestGrid.groovy
@@ -0,0 +1,259 @@
+/*
+ * © 2020. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+ */
+package edu.ie3.test.common.grids
+
+import edu.ie3.datamodel.models.OperationTime
+import edu.ie3.datamodel.models.input.NodeInput
+import edu.ie3.datamodel.models.input.OperatorInput
+import edu.ie3.datamodel.models.input.connector.LineInput
+import edu.ie3.datamodel.models.input.connector.Transformer2WInput
+import edu.ie3.datamodel.models.input.connector.type.LineTypeInput
+import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput
+import edu.ie3.datamodel.models.input.container.GraphicElements
+import edu.ie3.datamodel.models.input.container.JointGridContainer
+import edu.ie3.datamodel.models.input.container.RawGridElements
+import edu.ie3.datamodel.models.input.container.SystemParticipants
+import edu.ie3.datamodel.models.input.system.characteristic.OlmCharacteristicInput
+import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils
+import edu.ie3.util.quantities.PowerSystemUnits
+import org.locationtech.jts.geom.LineString
+import org.locationtech.jts.geom.Point
+import org.locationtech.jts.io.geojson.GeoJsonReader
+import tech.units.indriya.quantity.Quantities
+import tech.units.indriya.unit.Units
+
+import javax.measure.MetricPrefix
+
+import static tech.units.indriya.unit.Units.SIEMENS
+
+/**
+ * This is a star-topology grid, that is at the first hand used to test the adaption of geo positions in order to meet
+ * the electrical line length
+ */
+trait LengthAdaptionTestGrid {
+	private static final GeoJsonReader geoJsonReader = new GeoJsonReader()
+
+	/* === Nodes === */
+	NodeInput nodeA = new NodeInput(
+	UUID.fromString("36514e92-e6d9-4a7e-85b1-175ec6e27216"),
+	"node_a",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	true,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.411931,51.493045],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.MV_20KV,
+	1
+	)
+	NodeInput nodeB = new NodeInput(
+	UUID.fromString("78beb137-45e2-43e3-8baa-1c25f0c91616"),
+	"node_b",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.411931,51.493045],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+	NodeInput nodeC = new NodeInput(
+	UUID.fromString("83586a39-8a55-4b10-a034-7ccfe6a451cb"),
+	"node_c",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.411728,51.493918],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+	NodeInput nodeD = new NodeInput(
+	UUID.fromString("a0746324-3c74-4a03-9e45-41ae2880ad8d"),
+	"node_d",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.411497,51.494553],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+	NodeInput nodeE = new NodeInput(
+	UUID.fromString("1e755e89-7bfb-4987-9bee-358ac1892313"),
+	"node_e",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.412838,51.494136],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+	NodeInput nodeF = new NodeInput(
+	UUID.fromString("7dc3d14b-3536-43b8-96f4-0f43b26854f8"),
+	"node_f",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.413761,51.494250],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+	NodeInput nodeG = new NodeInput(
+	UUID.fromString("292ea9b1-79f8-4615-bad5-c0d33b17527d"),
+	"node_g",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	Quantities.getQuantity(1d, PowerSystemUnits.PU),
+	false,
+	geoJsonReader.read("{\"type\":\"Point\",\"coordinates\":[7.413123,51.494791],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as Point,
+	GermanVoltageLevelUtils.LV,
+	2
+	)
+
+	/* === Transformers === */
+	def transformerType = new Transformer2WTypeInput(
+	UUID.fromString("08559390-d7c0-4427-a2dc-97ba312ae0ac"),
+	"MS-NS_1",
+	Quantities.getQuantity(10.078, Units.OHM),
+	Quantities.getQuantity(23.312, Units.OHM),
+	Quantities.getQuantity(630.0, PowerSystemUnits.KILOVOLTAMPERE),
+	Quantities.getQuantity(20.0, PowerSystemUnits.KILOVOLT),
+	Quantities.getQuantity(0.4, PowerSystemUnits.KILOVOLT),
+	Quantities.getQuantity(0.0, MetricPrefix.NANO(SIEMENS)),
+	Quantities.getQuantity(0.0, MetricPrefix.NANO(SIEMENS)),
+	Quantities.getQuantity(0.5, Units.PERCENT),
+	Quantities.getQuantity(0.0, PowerSystemUnits.DEGREE_GEOM),
+	false,
+	0,
+	-10,
+	10
+	)
+	Transformer2WInput transformer = new Transformer2WInput(
+	UUID.fromString("e691ebc3-fcd6-420d-8fc6-ecf45e88c86c"),
+	"transformer",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeA,
+	nodeB,
+	1,
+	transformerType,
+	0,
+	false
+	)
+
+	/* === Lines === */
+	def lineType = new LineTypeInput(
+	UUID.fromString("3bed3eb3-9790-4874-89b5-a5434d408088"),
+	"lineType",
+	Quantities.getQuantity(0.00322, PowerSystemUnits.MICRO_SIEMENS_PER_KILOMETRE),
+	Quantities.getQuantity(0d, PowerSystemUnits.MICRO_SIEMENS_PER_KILOMETRE),
+	Quantities.getQuantity(0.437, PowerSystemUnits.OHM_PER_KILOMETRE),
+	Quantities.getQuantity(0.356, PowerSystemUnits.OHM_PER_KILOMETRE),
+	Quantities.getQuantity(300d, Units.AMPERE),
+	Quantities.getQuantity(0.4, PowerSystemUnits.KILOVOLT)
+	)
+	LineInput lineBC = new LineInput(
+	UUID.fromString("57be16a6-e55a-4177-915c-d44b5dc7c78a"),
+	"b_c",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeB,
+	nodeC,
+	1,
+	lineType,
+	Quantities.getQuantity(2.5, PowerSystemUnits.KILOMETRE),
+	geoJsonReader.read("{\"type\":\"LineString\",\"coordinates\":[[7.411931,51.493045],[7.411728,51.493918]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as LineString,
+	OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+	)
+	LineInput lineCD = new LineInput(
+	UUID.fromString("f7c1d0f8-4464-4243-ab0b-bfb048e8b1a9"),
+	"c_d",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeC,
+	nodeD,
+	1,
+	lineType,
+	Quantities.getQuantity(2.5, PowerSystemUnits.KILOMETRE),
+	geoJsonReader.read("{\"type\":\"LineString\",\"coordinates\":[[7.411728,51.493918],[7.411497,51.494553]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as LineString,
+	OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+	)
+	LineInput lineCE = new LineInput(
+	UUID.fromString("959d901a-8403-4b24-a99f-ea07a7c924a4"),
+	"c_e",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeC,
+	nodeE,
+	1,
+	lineType,
+	Quantities.getQuantity(2.5, PowerSystemUnits.KILOMETRE),
+	geoJsonReader.read("{\"type\":\"LineString\",\"coordinates\":[[7.411728,51.493918],[7.412838,51.494136]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as LineString,
+	OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+	)
+	LineInput lineEF = new LineInput(
+	UUID.fromString("c709c1da-cab2-4ad3-8211-1fa765ec7c45"),
+	"e_f",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeE,
+	nodeF,
+	1,
+	lineType,
+	Quantities.getQuantity(2.5, PowerSystemUnits.KILOMETRE),
+	geoJsonReader.read("{\"type\":\"LineString\",\"coordinates\":[[7.412838,51.494136],[7.413761,51.494250]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as LineString,
+	OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+	)
+	LineInput lineEG = new LineInput(
+	UUID.fromString("2fefea62-53c7-4923-97a0-f4e23b14143f"),
+	"e_g",
+	OperatorInput.NO_OPERATOR_ASSIGNED,
+	OperationTime.notLimited(),
+	nodeE,
+	nodeG,
+	1,
+	lineType,
+	Quantities.getQuantity(2.5, PowerSystemUnits.KILOMETRE),
+	geoJsonReader.read("{\"type\":\"LineString\",\"coordinates\":[[7.412838,51.494136],[7.413123,51.494791]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}") as LineString,
+	OlmCharacteristicInput.CONSTANT_CHARACTERISTIC
+	)
+
+	/* Put everything together */
+	JointGridContainer testGrid = new JointGridContainer(
+	"lengthAdaptionTestGrid",
+	new RawGridElements(
+	[
+		nodeA,
+		nodeB,
+		nodeC,
+		nodeD,
+		nodeE,
+		nodeF,
+		nodeG
+	] as Set,
+	[
+		lineBC,
+		lineCD,
+		lineCE,
+		lineEF,
+		lineEG
+	] as Set,
+	[transformer] as Set,
+	[] as Set,
+	[] as Set,
+	[] as Set
+	),
+	new SystemParticipants(
+	[] as Set
+	),
+	new GraphicElements(
+	[] as Set,
+	[] as Set,
+	)
+	)
+}
\ No newline at end of file
diff --git a/src/test/resources/grids/geographicalToElectricDistance/line_input.csv b/src/test/resources/grids/geographicalToElectricDistance/line_input.csv
new file mode 100644
index 0000000..04046bb
--- /dev/null
+++ b/src/test/resources/grids/geographicalToElectricDistance/line_input.csv
@@ -0,0 +1,6 @@
+uuid,geo_position,id,length,node_a,node_b,olm_characteristic,operates_from,operates_until,operator,parallel_devices,type
+57be16a6-e55a-4177-915c-d44b5dc7c78a,"{""type"":""LineString"",""coordinates"":[[7.411931,51.493045],[7.411728,51.493918]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",b_c,2.5,78beb137-45e2-43e3-8baa-1c25f0c91616,83586a39-8a55-4b10-a034-7ccfe6a451cb,olm:{(0.00,1.00)},,,,1,3bed3eb3-9790-4874-89b5-a5434d408088
+f7c1d0f8-4464-4243-ab0b-bfb048e8b1a9,"{""type"":""LineString"",""coordinates"":[[7.411728,51.493918],[7.411497,51.494553]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",c_d,2.5,83586a39-8a55-4b10-a034-7ccfe6a451cb,a0746324-3c74-4a03-9e45-41ae2880ad8d,olm:{(0.00,1.00)},,,,1,3bed3eb3-9790-4874-89b5-a5434d408088
+959d901a-8403-4b24-a99f-ea07a7c924a4,"{""type"":""LineString"",""coordinates"":[[7.411728,51.493918],[7.412838,51.494136]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",c_e,2.5,83586a39-8a55-4b10-a034-7ccfe6a451cb,1e755e89-7bfb-4987-9bee-358ac1892313,olm:{(0.00,1.00)},,,,1,3bed3eb3-9790-4874-89b5-a5434d408088
+c709c1da-cab2-4ad3-8211-1fa765ec7c45,"{""type"":""LineString"",""coordinates"":[[7.412838,51.494136],[7.413761,51.494250]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",e_f,2.5,1e755e89-7bfb-4987-9bee-358ac1892313,7dc3d14b-3536-43b8-96f4-0f43b26854f8,olm:{(0.00,1.00)},,,,1,3bed3eb3-9790-4874-89b5-a5434d408088
+2fefea62-53c7-4923-97a0-f4e23b14143f,"{""type"":""LineString"",""coordinates"":[[7.412838,51.494136],[7.413123,51.494791]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",e_g,2.5,1e755e89-7bfb-4987-9bee-358ac1892313,292ea9b1-79f8-4615-bad5-c0d33b17527d,olm:{(0.00,1.00)},,,,1,3bed3eb3-9790-4874-89b5-a5434d408088
\ No newline at end of file
diff --git a/src/test/resources/grids/geographicalToElectricDistance/line_type_input.csv b/src/test/resources/grids/geographicalToElectricDistance/line_type_input.csv
new file mode 100644
index 0000000..1333d8b
--- /dev/null
+++ b/src/test/resources/grids/geographicalToElectricDistance/line_type_input.csv
@@ -0,0 +1,2 @@
+uuid,b,g,i_max,id,r,v_rated,x
+3bed3eb3-9790-4874-89b5-a5434d408088,0.00322,0.0,300.0,lineType,0.437,0.4,0.356
\ No newline at end of file
diff --git a/src/test/resources/grids/geographicalToElectricDistance/node_input.csv b/src/test/resources/grids/geographicalToElectricDistance/node_input.csv
new file mode 100644
index 0000000..2c26424
--- /dev/null
+++ b/src/test/resources/grids/geographicalToElectricDistance/node_input.csv
@@ -0,0 +1,8 @@
+uuid,geo_position,id,operates_from,operates_until,operator,slack,subnet,v_rated,v_target,volt_lvl
+36514e92-e6d9-4a7e-85b1-175ec6e27216,"{""type"":""Point"",""coordinates"":[7.411931,51.493045],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_a,"","","",true,1,20.0,1.0,MV
+78beb137-45e2-43e3-8baa-1c25f0c91616,"{""type"":""Point"",""coordinates"":[7.411931,51.493045],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_b,"","","",false,2,0.4,1.0,LV
+83586a39-8a55-4b10-a034-7ccfe6a451cb,"{""type"":""Point"",""coordinates"":[7.411728,51.493918],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_c,"","","",false,2,0.4,1.0,LV
+a0746324-3c74-4a03-9e45-41ae2880ad8d,"{""type"":""Point"",""coordinates"":[7.411497,51.494553],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_d,"","","",false,2,0.4,1.0,LV
+1e755e89-7bfb-4987-9bee-358ac1892313,"{""type"":""Point"",""coordinates"":[7.412838,51.494136],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_e,"","","",false,2,0.4,1.0,LV
+7dc3d14b-3536-43b8-96f4-0f43b26854f8,"{""type"":""Point"",""coordinates"":[7.413761,51.494250],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_f,"","","",false,2,0.4,1.0,LV
+292ea9b1-79f8-4615-bad5-c0d33b17527d,"{""type"":""Point"",""coordinates"":[7.413123,51.494791],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_g,"","","",false,2,0.4,1.0,LV
\ No newline at end of file
diff --git a/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_input.csv b/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_input.csv
new file mode 100644
index 0000000..6c5a4b8
--- /dev/null
+++ b/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_input.csv
@@ -0,0 +1,2 @@
+uuid,auto_tap,id,node_a,node_b,operates_from,operates_until,operator,parallel_devices,tap_pos,type
+e691ebc3-fcd6-420d-8fc6-ecf45e88c86c,false,transformer,36514e92-e6d9-4a7e-85b1-175ec6e27216,78beb137-45e2-43e3-8baa-1c25f0c91616,,,,1,0,08559390-d7c0-4427-a2dc-97ba312ae0ac
\ No newline at end of file
diff --git a/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_type_input.csv b/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_type_input.csv
new file mode 100644
index 0000000..8bcdcac
--- /dev/null
+++ b/src/test/resources/grids/geographicalToElectricDistance/transformer_2_w_type_input.csv
@@ -0,0 +1,2 @@
+uuid,b_m,d_phi,d_v,g_m,id,r_sc,s_rated,tap_max,tap_min,tap_neutr,tap_side,v_rated_a,v_rated_b,x_sc
+08559390-d7c0-4427-a2dc-97ba312ae0ac,0.0,0.0,0.5,0.0,MS-NS_1,10.078,630.0,10,-10,0,false,20.0,0.4,23.312
\ No newline at end of file