@Test
  public void testCopyTo() {
    graph = createGraph();
    initExampleGraph(graph);
    GraphStorage gs = newRAMGraph();
    gs.setSegmentSize(8000);
    gs.create(10);
    try {
      graph.copyTo(gs);
      checkExampleGraph(gs);
    } catch (Exception ex) {
      ex.printStackTrace();
      assertTrue(ex.toString(), false);
    }

    try {
      Helper.close((Closeable) graph);
      graph = createGraph();
      gs.copyTo(graph);
      checkExampleGraph(graph);
    } catch (Exception ex) {
      ex.printStackTrace();
      assertTrue(ex.toString(), false);
    }
    Helper.close((Closeable) graph);
  }
示例#2
0
  private void optimize() {
    logger.info("optimizing ... (" + Helper.getMemInfo() + ")");
    graph.optimize();
    logger.info("finished optimize (" + Helper.getMemInfo() + ")");

    // move this into the GraphStorage.optimize method?
    if (sortGraph) {
      logger.info("sorting ... (" + Helper.getMemInfo() + ")");
      GraphStorage newGraph = GHUtility.newStorage(graph);
      GHUtility.sortDFS(graph, newGraph);
      graph = newGraph;
    }
  }
示例#3
0
 /**
  * This file can be an osm xml (.osm), a compressed xml (.osm.zip or .osm.gz) or a protobuf file
  * (.pbf).
  */
 public GraphHopper setOSMFile(String osmFileStr) {
   if (Helper.isEmpty(osmFileStr)) {
     throw new IllegalArgumentException("OSM file cannot be empty.");
   }
   osmFile = osmFileStr;
   return this;
 }
示例#4
0
 private void flush() {
   logger.info(
       "flushing graph "
           + graph.toString()
           + ", details:"
           + graph.toDetailsString()
           + ", "
           + Helper.getMemInfo()
           + ")");
   graph.flush();
 }
  @Test
  public void testEnabledElevation() {
    graph = createGraph(defaultGraphLoc, true);
    NodeAccess na = graph.getNodeAccess();
    assertTrue(na.is3D());
    na.setNode(0, 10, 20, -10);
    na.setNode(1, 11, 2, 100);
    assertEquals(-10, na.getEle(0), 1e-1);
    assertEquals(100, na.getEle(1), 1e-1);

    graph.edge(0, 1).setWayGeometry(Helper.createPointList3D(10, 27, 72, 11, 20, 1));
    assertEquals(
        Helper.createPointList3D(10, 27, 72, 11, 20, 1),
        GHUtility.getEdge(graph, 0, 1).fetchWayGeometry(0));
    assertEquals(
        Helper.createPointList3D(10, 20, -10, 10, 27, 72, 11, 20, 1, 11, 2, 100),
        GHUtility.getEdge(graph, 0, 1).fetchWayGeometry(3));
    assertEquals(
        Helper.createPointList3D(11, 2, 100, 11, 20, 1, 10, 27, 72, 10, 20, -10),
        GHUtility.getEdge(graph, 1, 0).fetchWayGeometry(3));
  }
  @Test
  public void testCopyProperties() {
    graph = createGraph();
    EdgeIteratorState edge =
        graph.edge(1, 3, 10, false).setName("testing").setWayGeometry(Helper.createPointList(1, 2));

    EdgeIteratorState newEdge = graph.edge(1, 3, 10, false);
    edge.copyPropertiesTo(newEdge);
    assertEquals(edge.getName(), newEdge.getName());
    assertEquals(edge.getDistance(), newEdge.getDistance(), 1e-7);
    assertEquals(edge.getFlags(), newEdge.getFlags());
    assertEquals(edge.fetchWayGeometry(0), newEdge.fetchWayGeometry(0));
  }
示例#7
0
 public void prepare() {
   boolean tmpPrepare = doPrepare && prepare != null;
   graph.getProperties().put("prepare.done", tmpPrepare);
   if (tmpPrepare) {
     if (prepare instanceof PrepareContractionHierarchies
         && encodingManager.getVehicleCount() > 1) {
       throw new IllegalArgumentException(
           "Contraction hierarchies preparation "
               + "requires (at the moment) only one vehicle. But was:"
               + encodingManager);
     }
     logger.info("calling prepare.doWork ... (" + Helper.getMemInfo() + ")");
     prepare.doWork();
   }
 }
  @Test
  public void testDetachEdge() {
    graph = createGraph();
    graph.edge(0, 1, 2, true);
    long flags = carEncoder.setProperties(10, true, false);
    graph.edge(0, 2, 2, true).setWayGeometry(Helper.createPointList(1, 2, 3, 4)).setFlags(flags);
    graph.edge(1, 2, 2, true);

    EdgeIterator iter = graph.createEdgeExplorer().setBaseNode(0);
    try {
      // currently not possible to detach without next, without introducing a new property inside
      // EdgeIterable
      iter.detach(false);
      assertTrue(false);
    } catch (Exception ex) {
    }

    iter.next();
    EdgeIteratorState edgeState2 = iter.detach(false);
    assertEquals(2, iter.getAdjNode());
    assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertEquals(2, edgeState2.getAdjNode());
    assertTrue(carEncoder.isBool(edgeState2.getFlags(), FlagEncoder.K_FORWARD));

    EdgeIteratorState edgeState3 = iter.detach(true);
    assertEquals(0, edgeState3.getAdjNode());
    assertEquals(2, edgeState3.getBaseNode());
    assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertFalse(carEncoder.isBool(edgeState3.getFlags(), FlagEncoder.K_FORWARD));
    assertEquals(GHUtility.getEdge(graph, 0, 2).getFlags(), edgeState2.getFlags());
    assertEquals(GHUtility.getEdge(graph, 2, 0).getFlags(), edgeState3.getFlags());

    iter.next();
    assertEquals(1, iter.getAdjNode());
    assertEquals(2, edgeState2.getAdjNode());
    assertEquals(2, edgeState3.getBaseNode());

    assertEquals(0, iter.fetchWayGeometry(0).size());
    assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1);

    // #162 a directed self referencing edge should be able to reverse its state too
    graph.edge(3, 3, 2, true).setFlags(flags);
    EdgeIterator iter2 = graph.createEdgeExplorer().setBaseNode(3);
    iter2.next();
    assertEquals(edgeState2.getFlags(), iter2.detach(false).getFlags());
    assertEquals(edgeState3.getFlags(), iter2.detach(true).getFlags());
  }
  @Test
  public void testGetLocations() {
    graph = createGraph();
    NodeAccess na = graph.getNodeAccess();
    na.setNode(0, 12, 23);
    na.setNode(1, 22, 23);
    assertEquals(2, graph.getNodes());

    graph.edge(0, 1, 10, true);
    assertEquals(2, graph.getNodes());

    graph.edge(0, 2, 10, true);
    assertEquals(3, graph.getNodes());
    Helper.close((Closeable) graph);

    graph = createGraph();
    assertEquals(0, graph.getNodes());
  }
示例#10
0
 protected void cleanUp() {
   int prev = graph.getNodes();
   PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(graph, encodingManager);
   logger.info("start finding subnetworks, " + Helper.getMemInfo());
   preparation.doWork();
   int n = graph.getNodes();
   // calculate remaining subnetworks
   int remainingSubnetworks = preparation.findSubnetworks().size();
   logger.info(
       "edges: "
           + graph.getAllEdges().getMaxId()
           + ", nodes "
           + n
           + ", there were "
           + preparation.getSubNetworks()
           + " subnetworks. removed them => "
           + (prev - n)
           + " less nodes. Remaining subnetworks:"
           + remainingSubnetworks);
 }
  @Test
  public void testClone() {
    graph = createGraph();
    graph.edge(1, 2, 10, true);
    NodeAccess na = graph.getNodeAccess();
    na.setNode(0, 12, 23);
    na.setNode(1, 8, 13);
    na.setNode(2, 2, 10);
    na.setNode(3, 5, 9);
    graph.edge(1, 3, 10, true);

    Graph clone = graph.copyTo(createGraph(locationParent + "/clone", false));
    assertEquals(graph.getNodes(), clone.getNodes());
    assertEquals(
        count(carOutExplorer.setBaseNode(1)),
        count(clone.createEdgeExplorer(carOutFilter).setBaseNode(1)));
    clone.edge(1, 4, 10, true);
    assertEquals(3, count(clone.createEdgeExplorer(carOutFilter).setBaseNode(1)));
    assertEquals(graph.getBounds(), clone.getBounds());
    Helper.close((Closeable) clone);
  }
示例#12
0
 private void initIndex() {
   Directory dir = graph.getDirectory();
   if (preciseIndexResolution > 0) {
     Location2NodesNtree tmpIndex;
     if (graph instanceof LevelGraph) {
       tmpIndex = new Location2NodesNtreeLG((LevelGraph) graph, dir);
     } else {
       tmpIndex = new Location2NodesNtree(graph, dir);
     }
     tmpIndex.setResolution(preciseIndexResolution);
     tmpIndex.setEdgeCalcOnFind(edgeCalcOnSearch);
     tmpIndex.setSearchRegion(searchRegion);
     index = tmpIndex;
   } else {
     index = new Location2IDQuadtree(graph, dir);
     index.setResolution(Helper.calcIndexSize(graph.getBounds()));
   }
   if (!index.loadExisting()) {
     index.prepareIndex();
   }
 }
示例#13
0
  protected OSMReader importOSM(String _osmFile) throws IOException {
    if (graph == null) throw new IllegalStateException("Load or init graph before import OSM data");

    setOSMFile(_osmFile);
    File osmTmpFile = new File(osmFile);
    if (!osmTmpFile.exists()) {
      throw new IllegalStateException(
          "Your specified OSM file does not exist:" + osmTmpFile.getAbsolutePath());
    }

    logger.info("start creating graph from " + osmFile);
    OSMReader reader =
        new OSMReader(graph, expectedCapacity)
            .setWorkerThreads(workerThreads)
            .setEncodingManager(encodingManager)
            .setWayPointMaxDistance(wayPointMaxDistance)
            .setEnableInstructions(enableInstructions);
    logger.info("using " + graph.toString() + ", memory:" + Helper.getMemInfo());
    reader.doOSM2Graph(osmTmpFile);
    return reader;
  }
示例#14
0
  /**
   * Opens or creates a graph. The specified args need a property 'graph' (a folder) and if no such
   * folder exist it'll create a graph from the provided osm file (property 'osm'). A property
   * 'size' is used to preinstantiate a datastructure/graph to avoid over-memory allocation or
   * reallocation (default is 5mio)
   *
   * <p>
   *
   * @param graphHopperFolder is the folder containing graphhopper files (which can be compressed
   *     too)
   */
  @Override
  public boolean load(String graphHopperFolder) {
    if (Helper.isEmpty(graphHopperFolder))
      throw new IllegalStateException("graphHopperLocation is not specified. call init before");

    if (graph != null) throw new IllegalStateException("graph is already loaded");

    if (graphHopperFolder.endsWith("-gh")) {
      // do nothing
    } else if (graphHopperFolder.endsWith(".osm") || graphHopperFolder.endsWith(".xml")) {
      throw new IllegalArgumentException("To import an osm file you need to use importOrLoad");
    } else if (graphHopperFolder.indexOf(".") < 0) {
      if (new File(graphHopperFolder + "-gh").exists()) graphHopperFolder += "-gh";
    } else {
      File compressed = new File(graphHopperFolder + ".ghz");
      if (compressed.exists() && !compressed.isDirectory()) {
        try {
          new Unzipper().unzip(compressed.getAbsolutePath(), graphHopperFolder, removeZipped);
        } catch (IOException ex) {
          throw new RuntimeException(
              "Couldn't extract file " + compressed.getAbsolutePath() + " to " + graphHopperFolder,
              ex);
        }
      }
    }
    setGraphHopperLocation(graphHopperFolder);

    GHDirectory dir = new GHDirectory(ghLocation, dataAccessType);
    if (chUsage) graph = new LevelGraphStorage(dir, encodingManager);
    else graph = new GraphStorage(dir, encodingManager);

    graph.setSegmentSize(defaultSegmentSize);
    if (!graph.loadExisting()) return false;

    postProcessing();
    initIndex();
    return true;
  }
示例#15
0
  @Test
  public void testMonacoWithInstructions() {
    String osmFile = "files/monaco.osm.gz";
    String graphFile = "target/graph-monaco";
    String vehicle = "FOOT";
    String importVehicles = "FOOT";
    String weightCalcStr = "shortest";

    try {
      // make sure we are using fresh graphhopper files with correct vehicle
      Helper.removeDir(new File(graphFile));
      GraphHopper hopper =
          new GraphHopper()
              .setInMemory(true)
              .setOSMFile(osmFile)
              .disableCHShortcuts()
              .setGraphHopperLocation(graphFile)
              .setEncodingManager(new EncodingManager(importVehicles))
              .importOrLoad();

      Graph g = hopper.getGraph();
      GHResponse rsp =
          hopper.route(
              new GHRequest(43.727687, 7.418737, 43.74958, 7.436566)
                  .setAlgorithm("astar")
                  .setVehicle(vehicle)
                  .setWeighting(weightCalcStr));

      assertEquals(3437.6, rsp.getDistance(), .1);
      assertEquals(87, rsp.getPoints().getSize());

      InstructionList il = rsp.getInstructions();
      assertEquals(13, il.size());
      Translation tr = trMap.getWithFallBack(Locale.US);
      List<String> iList = il.createDescription(tr);
      // TODO roundabout fine tuning -> enter + leave roundabout (+ two rounabouts -> is it
      // necessary if we do not leave the street?)
      assertEquals("Continue onto Avenue des Guelfes", iList.get(0));
      assertEquals("Turn slight left onto Avenue des Papalins", iList.get(1));
      assertEquals("Turn sharp right onto Quai Jean-Charles Rey", iList.get(2));
      assertEquals("Turn left onto road", iList.get(3));
      assertEquals("Turn right onto Avenue Albert II", iList.get(4));

      List<Double> dists = il.createDistances();
      assertEquals(11, dists.get(0), 1);
      assertEquals(289, dists.get(1), 1);
      assertEquals(10, dists.get(2), 1);
      assertEquals(43, dists.get(3), 1);
      assertEquals(122, dists.get(4), 1);
      assertEquals(447, dists.get(5), 1);

      List<Long> times = il.createMillis();
      assertEquals(7, times.get(0) / 1000);
      assertEquals(207, times.get(1) / 1000);
      assertEquals(7, times.get(2) / 1000);
      assertEquals(30, times.get(3) / 1000);
      assertEquals(87, times.get(4) / 1000);
      assertEquals(321, times.get(5) / 1000);

      List<GPXEntry> list = rsp.getInstructions().createGPXList();
      assertEquals(123, list.size());
      final long lastEntryMillis = list.get(list.size() - 1).getMillis();
      final long totalResponseMillis = rsp.getMillis();
      assertEquals(totalResponseMillis, lastEntryMillis);

    } catch (Exception ex) {
      throw new RuntimeException("cannot handle osm file " + osmFile, ex);
    } finally {
      Helper.removeDir(new File(graphFile));
    }
  }
  @Test
  public void testPillarNodes() {
    graph = createGraph();
    NodeAccess na = graph.getNodeAccess();
    na.setNode(0, 0.01, 0.01);
    na.setNode(4, 0.4, 0.4);
    na.setNode(14, 0.14, 0.14);
    na.setNode(10, 0.99, 0.99);

    PointList pointList = Helper.createPointList(1, 1, 1, 2, 1, 3);
    graph
        .edge(0, 4)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);
    pointList = Helper.createPointList(1, 5, 1, 6, 1, 7, 1, 8, 1, 9);
    graph
        .edge(4, 10)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);
    pointList = Helper.createPointList(1, 13, 1, 12, 1, 11);
    graph
        .edge(14, 0)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);

    EdgeIterator iter = carAllExplorer.setBaseNode(0);
    assertTrue(iter.next());
    assertEquals(14, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 11, 1, 12, 1, 13.0), iter.fetchWayGeometry(0));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 11, 1, 12, 1, 13.0), iter.fetchWayGeometry(1));
    assertPList(
        Helper.createPointList(1, 11, 1, 12, 1, 13.0, 0.14, 0.14), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 11, 1, 12, 1, 13.0, 0.14, 0.14),
        iter.fetchWayGeometry(3));

    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(0));
    assertPList(Helper.createPointList(0.01, 0.01, 1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(1));
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3, 0.4, 0.4), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 1, 1, 2, 1, 3, 0.4, 0.4), iter.fetchWayGeometry(3));

    assertFalse(iter.next());

    iter = carOutExplorer.setBaseNode(0);
    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(0));
    assertFalse(iter.next());

    iter = carInExplorer.setBaseNode(10);
    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 9, 1, 8, 1, 7, 1, 6, 1, 5), iter.fetchWayGeometry(0));
    assertPList(
        Helper.createPointList(0.99, 0.99, 1, 9, 1, 8, 1, 7, 1, 6, 1, 5), iter.fetchWayGeometry(1));
    assertPList(
        Helper.createPointList(1, 9, 1, 8, 1, 7, 1, 6, 1, 5, 0.4, 0.4), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.99, 0.99, 1, 9, 1, 8, 1, 7, 1, 6, 1, 5, 0.4, 0.4),
        iter.fetchWayGeometry(3));
    assertFalse(iter.next());
  }
 @After
 public void tearDown() {
   Helper.close((Closeable) graph);
   Helper.removeDir(new File(locationParent));
 }
 @Before
 public void setUp() {
   Helper.removeDir(new File(locationParent));
 }
  void contractNodes() {
    meanDegree = g.getAllEdges().getMaxId() / g.getNodes();
    int level = 1;
    counter = 0;
    int initSize = sortedNodes.getSize();
    int logSize =
        (int) Math.round(Math.max(10, sortedNodes.getSize() / 100 * logMessagesPercentage));
    if (logMessagesPercentage == 0) logSize = Integer.MAX_VALUE;

    // preparation takes longer but queries are slightly faster with preparation
    // => enable it but call not so often
    boolean periodicUpdate = true;
    StopWatch periodSW = new StopWatch();
    int updateCounter = 0;
    int periodicUpdatesCount =
        Math.max(10, sortedNodes.getSize() / 100 * periodicUpdatesPercentage);
    if (periodicUpdatesPercentage == 0) periodicUpdate = false;

    // disable as preparation is slower and query time does not benefit
    int lastNodesLazyUpdates =
        lastNodesLazyUpdatePercentage == 0
            ? 0
            : sortedNodes.getSize() / 100 * lastNodesLazyUpdatePercentage;
    StopWatch lazySW = new StopWatch();

    // Recompute priority of uncontracted neighbors.
    // Without neighborupdates preparation is faster but we need them
    // to slightly improve query time. Also if not applied too often it decreases the shortcut
    // number.
    boolean neighborUpdate = true;
    if (neighborUpdatePercentage == 0) neighborUpdate = false;

    StopWatch neighborSW = new StopWatch();
    LevelGraphStorage lg = ((LevelGraphStorage) g);
    while (!sortedNodes.isEmpty()) {
      // periodically update priorities of ALL nodes
      if (periodicUpdate && counter > 0 && counter % periodicUpdatesCount == 0) {
        periodSW.start();
        sortedNodes.clear();
        int len = g.getNodes();
        for (int node = 0; node < len; node++) {
          if (g.getLevel(node) != 0) continue;

          int priority = oldPriorities[node] = calculatePriority(node);
          sortedNodes.insert(node, priority);
        }
        periodSW.stop();
        updateCounter++;
      }

      if (counter % logSize == 0) {
        // TODO necessary?
        System.gc();
        logger.info(
            Helper.nf(counter)
                + ", updates:"
                + updateCounter
                + ", nodes: "
                + Helper.nf(sortedNodes.getSize())
                + ", shortcuts:"
                + Helper.nf(newShortcuts)
                + ", dijkstras:"
                + Helper.nf(dijkstraCount)
                + ", t(dijk):"
                + (int) dijkstraSW.getSeconds()
                + ", t(period):"
                + (int) periodSW.getSeconds()
                + ", t(lazy):"
                + (int) lazySW.getSeconds()
                + ", t(neighbor):"
                + (int) neighborSW.getSeconds()
                + ", meanDegree:"
                + (long) meanDegree
                + ", algo:"
                + algo.getMemoryUsageAsString()
                + ", "
                + Helper.getMemInfo());
        dijkstraSW = new StopWatch();
        periodSW = new StopWatch();
        lazySW = new StopWatch();
        neighborSW = new StopWatch();
      }

      counter++;
      int polledNode = sortedNodes.pollKey();
      if (sortedNodes.getSize() < lastNodesLazyUpdates) {
        lazySW.start();
        int priority = oldPriorities[polledNode] = calculatePriority(polledNode);
        if (!sortedNodes.isEmpty() && priority > sortedNodes.peekValue()) {
          // current node got more important => insert as new value and contract it later
          sortedNodes.insert(polledNode, priority);
          lazySW.stop();
          continue;
        }
        lazySW.stop();
      }

      // contract!
      newShortcuts += addShortcuts(polledNode);
      g.setLevel(polledNode, level);
      level++;

      EdgeSkipIterator iter = vehicleAllExplorer.setBaseNode(polledNode);
      while (iter.next()) {
        int nn = iter.getAdjNode();
        if (g.getLevel(nn) != 0)
          // already contracted no update necessary
          continue;

        if (neighborUpdate && rand.nextInt(100) < neighborUpdatePercentage) {
          neighborSW.start();
          int oldPrio = oldPriorities[nn];
          int priority = oldPriorities[nn] = calculatePriority(nn);
          if (priority != oldPrio) sortedNodes.update(nn, oldPrio, priority);

          neighborSW.stop();
        }

        if (removesHigher2LowerEdges) lg.disconnect(vehicleAllTmpExplorer, iter);
      }
    }

    // Preparation works only once so we can release temporary data.
    // The preparation object itself has to be intact to create the algorithm.
    close();
    logger.info(
        "took:"
            + (int) allSW.stop().getSeconds()
            + ", new shortcuts: "
            + newShortcuts
            + ", "
            + prepareWeighting
            + ", "
            + prepareEncoder
            + ", removeHigher2LowerEdges:"
            + removesHigher2LowerEdges
            + ", dijkstras:"
            + dijkstraCount
            + ", t(dijk):"
            + (int) dijkstraSW.getSeconds()
            + ", t(period):"
            + (int) periodSW.getSeconds()
            + ", t(lazy):"
            + (int) lazySW.getSeconds()
            + ", t(neighbor):"
            + (int) neighborSW.getSeconds()
            + ", meanDegree:"
            + (long) meanDegree
            + ", initSize:"
            + initSize
            + ", periodic:"
            + periodicUpdatesPercentage
            + ", lazy:"
            + lastNodesLazyUpdatePercentage
            + ", neighbor:"
            + neighborUpdatePercentage);
  }
示例#20
0
  public GraphHopper init(CmdArgs args) throws IOException {
    if (!Helper.isEmpty(args.get("config", ""))) {
      CmdArgs tmp = CmdArgs.readFromConfig(args.get("config", ""), "graphhopper.config");
      // command line configuration overwrites the ones in the config file
      tmp.merge(args);
      args = tmp;
    }

    String tmpOsmFile = args.get("osmreader.osm", "");
    if (!Helper.isEmpty(tmpOsmFile)) osmFile = tmpOsmFile;

    String graphHopperFolder = args.get("graph.location", "");
    if (Helper.isEmpty(graphHopperFolder) && Helper.isEmpty(ghLocation)) {
      if (Helper.isEmpty(osmFile))
        throw new IllegalArgumentException("You need to specify an OSM file.");

      graphHopperFolder = Helper.pruneFileEnd(osmFile) + "-gh";
    }

    // graph
    setGraphHopperLocation(graphHopperFolder);
    expectedCapacity = args.getLong("graph.expectedCapacity", expectedCapacity);
    defaultSegmentSize = args.getInt("graph.dataaccess.segmentSize", defaultSegmentSize);
    String dataAccess = args.get("graph.dataaccess", "RAM_STORE").toUpperCase();
    if (dataAccess.contains("MMAP")) {
      setMemoryMapped();
    } else {
      if (dataAccess.contains("SAVE") || dataAccess.contains("INMEMORY"))
        throw new IllegalStateException(
            "configuration names for dataAccess changed. Use eg. RAM or RAM_STORE");

      if (dataAccess.contains("RAM_STORE")) setInMemory(true, true);
      else setInMemory(true, false);
    }

    if (dataAccess.contains("SYNC")) dataAccessType = new DAType(dataAccessType, true);

    sortGraph = args.getBool("graph.doSort", sortGraph);
    removeZipped = args.getBool("graph.removeZipped", removeZipped);

    // prepare
    doPrepare = args.getBool("prepare.doPrepare", doPrepare);
    String chShortcuts = args.get("prepare.chShortcuts", "no");
    boolean levelGraph =
        "true".equals(chShortcuts)
            || "fastest".equals(chShortcuts)
            || "shortest".equals(chShortcuts);
    if (levelGraph) setCHShortcuts(true, !"shortest".equals(chShortcuts));

    if (args.has("prepare.updates.periodic"))
      periodicUpdates = args.getInt("prepare.updates.periodic", periodicUpdates);

    if (args.has("prepare.updates.lazy"))
      lazyUpdates = args.getInt("prepare.updates.lazy", lazyUpdates);

    if (args.has("prepare.updates.neighbor"))
      neighborUpdates = args.getInt("prepare.updates.neighbor", neighborUpdates);

    // routing
    defaultAlgorithm = args.get("routing.defaultAlgorithm", defaultAlgorithm);

    // osm import
    wayPointMaxDistance = args.getDouble("osmreader.wayPointMaxDistance", wayPointMaxDistance);
    String type = args.get("osmreader.acceptWay", "CAR");
    encodingManager = new EncodingManager(type);
    workerThreads = args.getInt("osmreader.workerThreads", workerThreads);
    enableInstructions = args.getBool("osmreader.instructions", enableInstructions);

    // index
    preciseIndexResolution = args.getInt("index.highResolution", preciseIndexResolution);
    return this;
  }