Exemplo n.º 1
0
  private void assignVolumesToLinks(final NetworkImpl network) {
    computeTotalLinkCapacities(network);

    Iterator<Integer> n_it = this.fromZone.getNodes().iterator();
    while (n_it.hasNext()) {
      Integer n_i = n_it.next();
      Node node = network.getNodes().get(Id.create(n_i, Node.class));

      for (Link l : node.getOutLinks().values()) {
        if (this.totalOutLinkCapacity > 0.0) {
          this.outLinkVolumes.add(
              new MyLink(l.getId(), this.volume * l.getCapacity() / this.totalOutLinkCapacity));
        } else {
          this.outLinkVolumes.add(new MyLink(l.getId(), 0.0));
        }
      }
    }

    n_it = this.toZone.getNodes().iterator();
    while (n_it.hasNext()) {
      Integer n_i = n_it.next();
      Node node = network.getNodes().get(Id.create(n_i, Node.class));

      for (Link l : node.getInLinks().values()) {
        if (this.totalInLinkCapacity > 0.0) {
          this.inLinkVolumes.add(
              new MyLink(l.getId(), this.volume * l.getCapacity() / this.totalInLinkCapacity));
        } else {
          this.inLinkVolumes.add(new MyLink(l.getId(), 0.0));
        }
      } // for
    } // while
  } // assignVolumesToLinks
Exemplo n.º 2
0
 private void expandLandmarkFrom() {
   LandmarksFromTravelTimeComparator comparator =
       new LandmarksFromTravelTimeComparator(this.nodeData, this.landmarkIdx);
   PriorityQueue<Node> pendingNodes = new PriorityQueue<>(100, comparator);
   LandmarksData role = (LandmarksData) this.nodeData.get(this.landmark);
   role.setToLandmarkTravelTime(this.landmarkIdx, 0.0);
   role.setFromLandmarkTravelTime(this.landmarkIdx, 0.0);
   pendingNodes.add(this.landmark);
   while (!pendingNodes.isEmpty()) {
     Node node = pendingNodes.poll();
     double fromTravTime =
         ((LandmarksData) this.nodeData.get(node)).getFromLandmarkTravelTime(this.landmarkIdx);
     LandmarksData role2;
     for (Link l : node.getOutLinks().values()) {
       Node n;
       n = l.getToNode();
       double linkTravTime = this.costFunction.getLinkMinimumTravelDisutility(l);
       role2 = (LandmarksData) this.nodeData.get(n);
       double totalTravelTime = fromTravTime + linkTravTime;
       if (role2.getFromLandmarkTravelTime(this.landmarkIdx) > totalTravelTime) {
         role2.setFromLandmarkTravelTime(this.landmarkIdx, totalTravelTime);
         pendingNodes.add(n);
       }
     }
   }
 }
Exemplo n.º 3
0
  // Create external Facilities that are used by transit traffic agents.
  private static void createExternalFacilities(Scenario scenario, Set<Id<Node>> externalNodes) {

    ActivityFacilities activityFacilities = scenario.getActivityFacilities();
    ActivityFacilitiesFactory factory = activityFacilities.getFactory();

    /*
     * We check for all OutLinks of all external nodes if they already host a facility. If not,
     * a new facility with a tta ActivityOption will be created and added.
     */
    for (Id<Node> id : externalNodes) {
      Node externalNode = scenario.getNetwork().getNodes().get(id);

      for (Link externalLink : externalNode.getOutLinks().values()) {
        ActivityFacility facility = activityFacilities.getFacilities().get(externalLink.getId());

        // if already a facility exists we have nothing left to do
        if (facility != null) continue;

        /*
         * No Facility exists at that link therefore we create and add a new one.
         */
        double fromX = externalLink.getFromNode().getCoord().getX();
        double fromY = externalLink.getFromNode().getCoord().getY();
        double toX = externalLink.getToNode().getCoord().getX();
        double toY = externalLink.getToNode().getCoord().getY();

        double dX = toX - fromX;
        double dY = toY - fromY;

        double length = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2));

        double centerX = externalLink.getCoord().getX();
        double centerY = externalLink.getCoord().getY();

        /*
         * Unit vector that directs with an angle of 90° away from the link.
         */
        double unitVectorX = dY / length;
        double unitVectorY = -dX / length;

        Coord coord = new Coord(centerX + unitVectorX, centerY + unitVectorY);

        facility =
            activityFacilities
                .getFactory()
                .createActivityFacility(
                    Id.create(externalLink.getId().toString(), ActivityFacility.class), coord);
        activityFacilities.addActivityFacility(facility);
        ((ActivityFacilityImpl) facility).setLinkId(externalLink.getId());

        ActivityOption activityOption = factory.createActivityOption(ttaActivityType);
        activityOption.addOpeningTime(new OpeningTimeImpl(0 * 3600, 24 * 3600));
        activityOption.setCapacity(capacity);
        facility.addActivityOption(activityOption);
      }
    }
  }
  /**
   * Expands the given Node in the routing algorithm; may be overridden in sub-classes.
   *
   * @param outNode The Node to be expanded.
   * @param toNode The target Node of the route.
   * @param pendingNodes The set of pending nodes so far.
   */
  protected void relaxNode(
      final Node outNode, final Node toNode, final RouterPriorityQueue<Node> pendingNodes) {

    DijkstraNodeData outData = getData(outNode);
    double currTime = outData.getTime();
    double currCost = outData.getCost();
    for (Link l : outNode.getOutLinks().values()) {
      relaxNodeLogic(l, pendingNodes, currTime, currCost, toNode, null);
    }
  }
Exemplo n.º 5
0
 public void add() {
   List<Link> links = ((BusLaneAdderPanel) layersPanels.get(PanelIds.ONE)).getLinks();
   Node prevNode = links.get(0).getFromNode();
   for (Link link : links)
     if (!link.getAllowedModes().contains("bus")) {
       exitSave();
       JOptionPane.showMessageDialog(this, "Wrong path, network saved");
     }
   for (int i = 0; i < links.size(); i++) {
     Link link = links.get(i);
     Node node = null;
     if (link.getNumberOfLanes() == 1) {
       Set<String> modes = new HashSet<String>();
       modes.add("bus");
       link.setAllowedModes(modes);
       node = link.getToNode();
     } else {
       Node oldNode = link.getToNode();
       if (i == links.size() - 1 || oldNode.getInLinks().size() + oldNode.getOutLinks().size() > 2)
         node = oldNode;
       else {
         node =
             network
                 .getFactory()
                 .createNode(
                     Id.createNodeId("fl" + oldNode.getId().toString()), oldNode.getCoord());
         network.addNode(node);
       }
       LinkImpl newLink =
           (LinkImpl)
               network
                   .getFactory()
                   .createLink(Id.createLinkId("fl" + link.getId().toString()), prevNode, node);
       Set<String> modes = new HashSet<String>();
       modes.add("car");
       newLink.setAllowedModes(modes);
       newLink.setCapacity(link.getCapacity());
       newLink.setFreespeed(link.getFreespeed());
       newLink.setLength(link.getLength());
       newLink.setNumberOfLanes(link.getNumberOfLanes() - 1);
       newLink.setOrigId(((LinkImpl) link).getOrigId());
       newLink.setType(((LinkImpl) link).getType());
       network.addLink(newLink);
       Set<String> modes2 = new HashSet<String>();
       modes2.add("bus");
       link.setAllowedModes(modes2);
       link.setCapacity(900);
       link.setNumberOfLanes(1);
     }
     prevNode = node;
   }
   ((BusLaneAdderPanel) layersPanels.get(PanelIds.ONE)).clearSelection();
 }
Exemplo n.º 6
0
  private void relaxNode(final Node n, PriorityQueue<Node> pendingNodes) {
    NodeData nData = nodeData.get(n.getId());
    double currTime = nData.getTime();
    double currCost = nData.getCost();
    for (Link l : n.getOutLinks().values()) {
      Node nn = l.getToNode();
      NodeData nnData = nodeData.get(nn.getId());
      if (nnData == null) {
        nnData = new NodeData();
        this.nodeData.put(nn.getId(), nnData);
      }
      double visitCost =
          currCost + tcFunction.getLinkTravelDisutility(l, currTime, PERSON, VEHICLE);
      double visitTime = currTime + ttFunction.getLinkTravelTime(l, currTime, PERSON, VEHICLE);

      if (visitCost < nnData.getCost()) {
        pendingNodes.remove(nn);
        nnData.visit(n.getId(), visitCost, visitTime);
        additionalComputationsHook(l, currTime);
        pendingNodes.add(nn);
      }
    }
  }
Exemplo n.º 7
0
  private void decomposePassPaths(Map<Link, Set<Path>> routes, MLCell j) {
    Network network = optimContext.network;
    Map<Id<Node>, ? extends Node> nodenetwork = network.getNodes();
    ArrayList<MLArray> paths = j.cells();
    for (MLArray path : paths) {
      MLCell cellpath = (MLCell) path;
      if (path.getM() != 0) {
        List<Node> nodelist = new ArrayList<Node>();
        List<Link> linklist = new ArrayList<Link>();
        MLDouble route = (MLDouble) (cellpath.get(0));
        double[][] nodes = route.getArray();
        for (int i = 0; i < nodes.length - 1; i++) {
          int currnode = (int) nodes[i][0];
          int nextnode = (int) nodes[i + 1][0];
          Node start = nodenetwork.get(Id.createNodeId(Integer.toString(currnode)));
          Node finish = nodenetwork.get(Id.createNodeId(Integer.toString(nextnode)));
          nodelist.add(start);
          Collection<? extends Link> possiblelinks = start.getOutLinks().values();
          for (Link l : possiblelinks) {
            if (l.getToNode().equals(finish)) {
              linklist.add(l);
              break;
            }
          }
          if (i == nodes.length - 2) {
            nodelist.add(finish);
          }

          Path temppath = convertNodeListtoPath(nodelist, linklist);
          if (routes.get(linklist.get(0)) == null) { // add path to routelist
            routes.put(linklist.get(0), new HashSet<Path>());
          }
          routes.get(linklist.get(0)).add(temppath);
        }
      }
    }
  }
Exemplo n.º 8
0
  private void computeTotalLinkCapacities(final NetworkImpl network) {
    this.totalOutLinkCapacity = 0.0;
    this.totalInLinkCapacity = 0.0;

    Iterator<Integer> n_it = this.fromZone.getNodes().iterator();
    while (n_it.hasNext()) {
      Integer n_i = n_it.next();
      Node node = network.getNodes().get(Id.create(n_i, Node.class));

      for (Link l : node.getOutLinks().values()) {
        this.totalOutLinkCapacity += l.getCapacity();
      }
    }

    n_it = this.toZone.getNodes().iterator();
    while (n_it.hasNext()) {
      Integer n_i = n_it.next();
      Node node = network.getNodes().get(Id.create(n_i, Node.class));

      for (Link l : node.getInLinks().values()) {
        this.totalInLinkCapacity += l.getCapacity();
      } // for
    }
  }
Exemplo n.º 9
0
  /* (non-Javadoc)
   * @see org.matsim.core.api.internal.NetworkRunnable#run(org.matsim.api.core.v01.network.Network)
   */
  @Override
  public void run(Network network) {
    Queue<Node> pendingNodes = new LinkedList<Node>(network.getNodes().values());

    double[] env = NetworkUtils.getBoundingBox(pendingNodes);
    QuadTree<Node> quadTree = new QuadTree<Node>(env[0], env[1], env[2], env[3]);
    for (Node node : pendingNodes) {
      quadTree.put(node.getCoord().getX(), node.getCoord().getY(), node);
    }

    long linkIdCounter = 100000000000L;

    while (!pendingNodes.isEmpty()) {
      Node node = pendingNodes.poll();

      double radius = 30;

      double minx = node.getCoord().getX() - radius;
      double miny = node.getCoord().getY() - radius;
      double maxx = node.getCoord().getX() + radius;
      double maxy = node.getCoord().getY() + radius;

      Set<Node> intersectionNodes = new HashSet<Node>(20);
      quadTree.getRectangle(minx, miny, maxx, maxy, intersectionNodes);

      if (intersectionNodes.size() > 1) {
        Set<Node> sourceNodes = new HashSet<Node>();
        Map<Node, Set<Link>> inLinks = new HashMap<Node, Set<Link>>();
        Set<Node> targetNodes = new HashSet<Node>();
        Map<Node, Set<Link>> outLinks = new HashMap<Node, Set<Link>>();

        for (Node intersectionNode : intersectionNodes) {
          for (Link link : intersectionNode.getInLinks().values()) {
            Node fromNode = link.getFromNode();

            double x = fromNode.getCoord().getX();
            double y = fromNode.getCoord().getY();

            if (!(x > minx && y > miny && x < maxx && y < maxy)) {
              sourceNodes.add(fromNode);

              Set<Link> links = inLinks.get(fromNode);
              if (links == null) {
                links = new HashSet<Link>();
                inLinks.put(fromNode, links);
              }
              links.add(link);
            }
          }

          for (Link link : intersectionNode.getOutLinks().values()) {
            Node toNode = link.getToNode();

            double x = toNode.getCoord().getX();
            double y = toNode.getCoord().getY();

            if (!(x > minx && y > miny && x < maxx && y < maxy)) {
              targetNodes.add(toNode);

              Set<Link> links = outLinks.get(toNode);
              if (links == null) {
                links = new HashSet<Link>();
                outLinks.put(toNode, links);
              }
              links.add(link);
            }
          }
        }

        for (Node intersectionNode : intersectionNodes) {
          network.removeNode(intersectionNode.getId());
          quadTree.remove(
              intersectionNode.getCoord().getX(),
              intersectionNode.getCoord().getY(),
              intersectionNode);
          pendingNodes.remove(intersectionNode);
        }

        NetworkFactory factory = network.getFactory();

        Node centerNode = factory.createNode(node.getId(), centerOfMass(intersectionNodes));
        network.addNode(centerNode);
        quadTree.put(centerNode.getCoord().getX(), centerNode.getCoord().getY(), centerNode);

        for (Node source : sourceNodes) {
          Link newLink =
              factory.createLink(Id.create(linkIdCounter++, Link.class), source, centerNode);
          network.addLink(newLink);
          Set<Link> origLinks = inLinks.get(source);
          assignProps(origLinks, newLink);
        }

        for (Node target : targetNodes) {
          Link newLink =
              factory.createLink(Id.create(linkIdCounter++, Link.class), centerNode, target);
          network.addLink(newLink);
          Set<Link> origLinks = outLinks.get(target);
          assignProps(origLinks, newLink);
        }
      }
    }
  }
Exemplo n.º 10
0
  @Override
  public Path calcLeastCostPath(
      Node fromNode, Node toNode, double starttime, Person person, Vehicle vehicle) {

    List<Node> nodes = new ArrayList<>();
    List<Link> links = new ArrayList<>();
    double travelTime = starttime;
    double travelCost = 0;
    Node currentNode = fromNode;
    if (networkPainter != null) {
      networkPainter.addForegroundPixel(fromNode.getId());
      networkPainter.addForegroundPixel(toNode.getId());
    }
    while (currentNode != toNode) {
      Object[] outLinks = currentNode.getOutLinks().values().toArray();
      // come up witha set of costs based on how much nearer (eucl) the link brings you to your
      // destination,
      // use them as probabilities of selecting the link
      double[] cumulativeWeights = new double[outLinks.length];
      double[] weights = new double[outLinks.length];
      double[] dists = new double[outLinks.length];
      double minCost = Double.POSITIVE_INFINITY;
      double maxCost = 0;
      Link selection = null;
      for (int i = 0; i < outLinks.length; i++) {
        double linkCost =
            CoordUtils.calcEuclideanDistance(
                toNode.getCoord(), ((Link) outLinks[i]).getToNode().getCoord());
        if (((Link) outLinks[i])
            .getToNode()
            .equals(toNode)) { // found destination, stop mucking about
          selection = (Link) outLinks[i];
          break;
        }
        dists[i] = linkCost;
        minCost = Math.min(minCost, linkCost);
        maxCost = Math.max(maxCost, linkCost);
      }
      for (int i = 0; i < outLinks.length; i++) {
        double linkCost = dists[i] - minCost;
        if (links.contains(outLinks[i]) || nodes.contains(((Link) outLinks[i]).getToNode())) {
          linkCost = 1e6 * (maxCost - minCost);
        }
        linkCost = Math.exp(-beta * linkCost);
        linkCost = linkCost == 1 ? 2 : linkCost;
        cumulativeWeights[i] = i > 0 ? cumulativeWeights[i - 1] + linkCost : linkCost;
        weights[i] = linkCost;
      }
      if (selection == null) {
        // sample if the destination has not been found
        double sampleProb =
            MatsimRandom.getRandom().nextDouble() * cumulativeWeights[cumulativeWeights.length - 1];
        for (int i = 0; i < outLinks.length; i++) {
          if (cumulativeWeights[i] >= sampleProb) {
            selection = (Link) outLinks[i];
            links.add(selection);
            nodes.add(currentNode);
            travelCost +=
                travelCosts.getLinkTravelDisutility(selection, travelTime, person, vehicle);
            travelTime += travelTimes.getLinkTravelTime(selection, travelTime, person, vehicle);
            break;
          }
        }
      }
      if (networkPainter != null) {
        networkPainter.addForegroundLine(selection.getId());
        try {
          Thread.sleep(200);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      currentNode = selection.getToNode();
    }
    if (networkPainter != null) {
      try {
        Thread.sleep(500);
        networkPainter.clearForeground();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    return new Path(nodes, links, travelTime, travelCost);
  }
  private void run2(final Network network) throws Exception {
    log.info("running " + this.getClass().getName() + " module...");
    NetworkExpandNode neModule =
        new NetworkExpandNode(network, expansionRadius, this.linkSeparation);

    TreeMap<String, TreeMap<Integer, Id<Link>>> mSequences = new TreeMap<>();

    try (FileInputStream fis = new FileInputStream(this.mpDbfFileName)) {
      DbaseFileReader r =
          new DbaseFileReader(fis.getChannel(), true, IOUtils.CHARSET_WINDOWS_ISO88591);
      // get header indices
      int mpIdNameIndex = -1;
      int mpSeqNrNameIndex = -1;
      int mpTrpelIDNameIndex = -1;
      for (int i = 0; i < r.getHeader().getNumFields(); i++) {
        if (r.getHeader().getFieldName(i).equals(MP_ID_NAME)) {
          mpIdNameIndex = i;
        }
        if (r.getHeader().getFieldName(i).equals(MP_SEQNR_NAME)) {
          mpSeqNrNameIndex = i;
        }
        if (r.getHeader().getFieldName(i).equals(MP_TRPELID_NAME)) {
          mpTrpelIDNameIndex = i;
        }
      }
      if (mpIdNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_ID_NAME + "' not found.");
      }
      if (mpSeqNrNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_SEQNR_NAME + "' not found.");
      }
      if (mpTrpelIDNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_TRPELID_NAME + "' not found.");
      }
      log.trace("  FieldName-->Index:");
      log.trace("    " + MP_ID_NAME + "-->" + mpIdNameIndex);
      log.trace("    " + MP_SEQNR_NAME + "-->" + mpSeqNrNameIndex);
      log.trace("    " + MP_TRPELID_NAME + "-->" + mpTrpelIDNameIndex);

      // create mp data structure
      // TreeMap<mpId,TreeMap<mpSeqNr,linkId>>
      log.info("  parsing meneuver paths dbf file...");
      while (r.hasNext()) {
        Object[] entries = r.readEntry();
        String mpId = entries[mpIdNameIndex].toString();
        int mpSeqNr = Integer.parseInt(entries[mpSeqNrNameIndex].toString());
        Id<Link> linkId = Id.create(entries[mpTrpelIDNameIndex].toString(), Link.class);
        TreeMap<Integer, Id<Link>> mSequence = mSequences.get(mpId);
        if (mSequence == null) {
          mSequence = new TreeMap<>();
          mSequences.put(mpId, mSequence);
        }
        if (mSequence.put(mpSeqNr, linkId) != null) {
          fis.close();
          throw new IllegalArgumentException(
              MP_ID_NAME + "=" + mpId + ": " + MP_SEQNR_NAME + " " + mpSeqNr + " already exists.");
        }
      }
      log.info("    " + mSequences.size() + " maneuvers sequences stored.");
      log.info("  done.");
      r.close();
    }

    // store the maneuver list of the nodes
    // TreeMap<NodeId,ArrayList<Tuple<MnId,MnFeatType>>>
    log.info("  parsing meneuver shape file...");
    TreeMap<Id<Node>, ArrayList<Tuple<String, Integer>>> maneuvers = new TreeMap<>();
    SimpleFeatureSource fs = ShapeFileReader.readDataFile(this.mnShpFileName);
    SimpleFeatureIterator fIt = fs.getFeatures().features();
    while (fIt.hasNext()) {
      SimpleFeature f = fIt.next();
      int featType = Integer.parseInt(f.getAttribute(MN_FEATTYP_NAME).toString());
      if ((featType == 2103) || (featType == 2102) || (featType == 2101)) {
        // keep 'Prohibited Maneuver' (2103), 'Restricted Maneuver' (2102) and 'Calculated/Derived
        // Prohibited Maneuver' (2101)
        Id<Node> nodeId = Id.create(f.getAttribute(MN_JNCTID_NAME).toString(), Node.class);
        ArrayList<Tuple<String, Integer>> ms = maneuvers.get(nodeId);
        if (ms == null) {
          ms = new ArrayList<>();
        }
        Tuple<String, Integer> m = new Tuple<>(f.getAttribute(MN_ID_NAME).toString(), featType);
        ms.add(m);
        maneuvers.put(nodeId, ms);
      } else if ((featType == 9401) || (featType == 2104)) {
        // ignore 'Bifurcation' (9401) and 'Priority Maneuver' (2104)
      } else {
        throw new IllegalArgumentException(
            "mnId="
                + f.getAttribute(MN_ID_NAME)
                + ": "
                + MN_FEATTYP_NAME
                + "="
                + featType
                + " not known.");
      }
    }
    fIt.close();
    log.info("    " + maneuvers.size() + " nodes with maneuvers stored.");
    log.info("  done.");

    // create a maneuver matrix for each given node and
    // expand those nodes
    log.info("  expand nodes according to the given manveuvers...");
    int nodesIgnoredCnt = 0;
    int nodesAssignedCnt = 0;
    int maneuverIgnoredCnt = 0;
    int maneuverAssignedCnt = 0;
    int virtualNodesCnt = 0;
    int virtualLinksCnt = 0;
    for (Map.Entry<Id<Node>, ArrayList<Tuple<String, Integer>>> entry : maneuvers.entrySet()) {
      Id<Node> nodeId = entry.getKey();
      if (network.getNodes().get(nodeId) == null) {
        log.trace(
            "  nodeid="
                + nodeId
                + ": maneuvers exist for that node but node is missing. Ignoring and proceeding anyway...");
        nodesIgnoredCnt++;
      } else {
        // node found
        Node n = network.getNodes().get(nodeId);
        // init maneuver matrix
        // TreeMap<fromLinkId,TreeMap<toLinkId,turnAllowed>>
        TreeMap<Id<Link>, TreeMap<Id<Link>, Boolean>> mmatrix = new TreeMap<>();
        // assign maneuvers for given node to the matrix
        ArrayList<Tuple<String, Integer>> ms = entry.getValue();
        for (Tuple<String, Integer> m : ms) {
          // get maneuver path sequence for given maneuver
          TreeMap<Integer, Id<Link>> mSequence = mSequences.get(m.getFirst());
          if (mSequence == null) {
            throw new Exception(
                "nodeid=" + nodeId + "; mnId=" + m.getFirst() + ": no maneuver sequence given.");
          }
          if (mSequence.size() < 2) {
            throw new Exception(
                "nodeid="
                    + nodeId
                    + "; mnId="
                    + m.getFirst()
                    + ": mSequenceSize="
                    + mSequence.size()
                    + " not alowed!");
          }
          // get the first element of the sequence, defining the start link for the maneuver
          Id<Link> firstLinkid = mSequence.values().iterator().next();
          // go through each other element (target link of the maneuver) of the sequence by sequence
          // number
          for (Id<Link> otherLinkId : mSequence.values()) {
            // get the start link and the target link of the maneuver
            Link inLink = n.getInLinks().get(Id.create(firstLinkid + "FT", Link.class));
            if (inLink == null) {
              inLink = n.getInLinks().get(Id.create(firstLinkid + "TF", Link.class));
            }
            Link outLink = n.getOutLinks().get(Id.create(otherLinkId + "FT", Link.class));
            if (outLink == null) {
              outLink = n.getOutLinks().get(Id.create(otherLinkId + "TF", Link.class));
            }
            if ((inLink != null) && (outLink != null)) {
              // start and target link found and they are incident to the given node
              if (m.getSecond() == 2102) {
                // restricted maneuver: given start and target link path is allowed to drive
                // store it to the matrix
                TreeMap<Id<Link>, Boolean> outLinkMap = mmatrix.get(inLink.getId());
                if (outLinkMap == null) {
                  outLinkMap = new TreeMap<>();
                }
                outLinkMap.put(outLink.getId(), Boolean.TRUE);
                mmatrix.put(inLink.getId(), outLinkMap);
              } else {
                // prohibited maneuver: given start and target link path is not allowed to drive
                // store it to the matrix
                TreeMap<Id<Link>, Boolean> outLinkMap = mmatrix.get(inLink.getId());
                if (outLinkMap == null) {
                  outLinkMap = new TreeMap<>();
                }
                outLinkMap.put(outLink.getId(), Boolean.FALSE);
                mmatrix.put(inLink.getId(), outLinkMap);
              }
              maneuverAssignedCnt++;
            } else {
              maneuverIgnoredCnt++;
            }
          }
        }
        // complete the matrix
        for (TreeMap<Id<Link>, Boolean> fromLinkEntry : mmatrix.values()) {
          // detect inlinks with restricted maneuvers
          boolean hasRestrictedManeuver = false;
          for (Boolean b : fromLinkEntry.values()) {
            if (b) {
              hasRestrictedManeuver = true;
            }
          }
          // add missing toLink maneuvers
          for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
            if (!fromLinkEntry.containsKey(toLinkId)) {
              fromLinkEntry.put(toLinkId, !hasRestrictedManeuver);
            }
          }
        }
        // add allowed maneuvers for fromLinks which were not assigned yet.
        for (Id<Link> fromLinkId : n.getInLinks().keySet()) {
          if (!mmatrix.containsKey(fromLinkId)) {
            mmatrix.put(fromLinkId, new TreeMap<Id<Link>, Boolean>());
            for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
              mmatrix.get(fromLinkId).put(toLinkId, Boolean.TRUE);
            }
          }
        }
        // remove all U-turns from the matrix
        if (this.removeUTurns) {
          for (Id<Link> fromLinkId : n.getInLinks().keySet()) {
            String str1 = fromLinkId.toString().substring(0, fromLinkId.toString().length() - 2);
            for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
              String str2 = toLinkId.toString().substring(0, toLinkId.toString().length() - 2);
              if (str1.equals(str2)) {
                mmatrix.get(fromLinkId).put(toLinkId, Boolean.FALSE);
              }
            }
          }
        }
        // create arraylist with turn tuples
        ArrayList<TurnInfo> turns = new ArrayList<>();
        for (Map.Entry<Id<Link>, TreeMap<Id<Link>, Boolean>> fromLinkEntry : mmatrix.entrySet()) {
          Id<Link> fromLinkId = fromLinkEntry.getKey();
          for (Map.Entry<Id<Link>, Boolean> toLinkEntry : fromLinkEntry.getValue().entrySet()) {
            if (toLinkEntry.getValue()) {
              turns.add(new TurnInfo(fromLinkId, toLinkEntry.getKey()));
            }
          }
        }
        // expand the node
        Tuple<List<Node>, List<Link>> t = neModule.expandNode(nodeId, turns);
        virtualNodesCnt += t.getFirst().size();
        virtualLinksCnt += t.getSecond().size();
        nodesAssignedCnt++;
      }
    }
    log.info("    " + nodesAssignedCnt + " nodes expanded.");
    log.info("    " + maneuverAssignedCnt + " maneuvers assigned.");
    log.info("    " + virtualNodesCnt + " new nodes created.");
    log.info("    " + virtualLinksCnt + " new links created.");
    log.info(
        "    " + nodesIgnoredCnt + " nodes with given maneuvers (2103, 2102 or 2101) ignored.");
    log.info("    " + maneuverIgnoredCnt + " maneuvers ignored (while node was found).");
    log.info("  done.");
    log.info("done.");
  }