예제 #1
0
 public void add(PointList points) {
   int newSize = size + points.getSize();
   incCap(newSize);
   for (int i = 0; i < points.getSize(); i++) {
     int tmp = size + i;
     latitudes[tmp] = points.getLatitude(i);
     longitudes[tmp] = points.getLongitude(i);
     if (is3D) elevations[tmp] = points.getElevation(i);
   }
   size = newSize;
 }
예제 #2
0
  @Test
  public void testBoth() throws Exception {
    PointList list =
        Helper.createPointList(
            38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 50.3139, 10.612793, 50.04303, 9.497681);
    String str = WebHelper.encodePolyline(list);
    assertEquals(list, WebHelper.decodePolyline(str, list.size()));

    list =
        Helper.createPointList(38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 40.70001, -120.95001);
    str = WebHelper.encodePolyline(list);
    assertEquals(list, WebHelper.decodePolyline(str, list.size()));
  }
예제 #3
0
 public PointList clone(boolean reverse) {
   PointList clonePL = new PointList(size, is3D);
   if (is3D)
     for (int i = 0; i < size; i++) {
       clonePL.add(latitudes[i], longitudes[i], elevations[i]);
     }
   else
     for (int i = 0; i < size; i++) {
       clonePL.add(latitudes[i], longitudes[i]);
     }
   if (reverse) clonePL.reverse();
   return clonePL;
 }
  @Override
  public int addEdge(TLongList osmIds, int flags) {
    PointList pointList = new PointList(osmIds.size());
    int successfullyAdded = 0;
    int firstNode = -1;
    int lastIndex = osmIds.size() - 1;
    int lastInBoundsPillarNode = -1;
    for (int i = 0; i < osmIds.size(); i++) {
      long osmId = osmIds.get(i);
      int tmpNode = osmIdToIndexMap.get(osmId);
      if (tmpNode == EMPTY) continue;
      // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds)
      if (tmpNode == TOWER_NODE) continue;
      if (tmpNode == PILLAR_NODE) {
        // In some cases no node information is saved for the specified osmId.
        // ie. a way references a <node> which does not exist in the current file.
        // => if the node before was a pillar node then convert into to tower node (as it is also
        // end-standing).
        if (!pointList.isEmpty() && lastInBoundsPillarNode > -TOWER_NODE) {
          // transform the pillar node to a tower node
          tmpNode = lastInBoundsPillarNode;
          tmpNode = handlePillarNode(tmpNode, osmId, null, true);
          tmpNode = -tmpNode - 3;
          if (pointList.size() > 1 && firstNode >= 0) {
            // TOWER node
            successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
            pointList.clear();
            pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
          }
          firstNode = tmpNode;
          lastInBoundsPillarNode = -1;
        }
        continue;
      }

      if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE)
        throw new AssertionError("Mapped index not in correct bounds " + tmpNode + ", " + osmId);

      if (tmpNode > -TOWER_NODE) {
        boolean convertToTowerNode = i == 0 || i == lastIndex;
        if (!convertToTowerNode) lastInBoundsPillarNode = tmpNode;

        // PILLAR node, but convert to towerNode if end-standing
        tmpNode = handlePillarNode(tmpNode, osmId, pointList, convertToTowerNode);
      }

      if (tmpNode < TOWER_NODE) {
        // TOWER node
        tmpNode = -tmpNode - 3;
        pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        if (firstNode >= 0) {
          successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
          pointList.clear();
          pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        }
        firstNode = tmpNode;
      }
    }
    return successfullyAdded;
  }
예제 #5
0
  int addEdge(int fromIndex, int toIndex, PointList pointList, int flags) {
    double towerNodeDistance = 0;
    double prevLat = pointList.latitude(0);
    double prevLon = pointList.longitude(0);
    double lat;
    double lon;
    PointList pillarNodes = new PointList(pointList.size() - 2);
    int nodes = pointList.size();
    for (int i = 1; i < nodes; i++) {
      lat = pointList.latitude(i);
      lon = pointList.longitude(i);
      towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon);
      prevLat = lat;
      prevLon = lon;
      if (nodes > 2 && i < nodes - 1) pillarNodes.add(lat, lon);
    }
    if (towerNodeDistance == 0) {
      // As investigation shows often two paths should have crossed via one identical point
      // but end up in two very close points. later this will be removed/fixed while
      // removing short edges where one node is of degree 2
      zeroCounter++;
      towerNodeDistance = 0.0001;
    }

    EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags);
    if (nodes > 2) iter.wayGeometry(pillarNodes);
    return nodes;
  }
  @Test
  public void testSimpleDelete2() {
    graph = createGraph();
    NodeAccess na = graph.getNodeAccess();
    assertEquals(-1, getIdOf(graph, 12));
    na.setNode(9, 9, 1);
    assertEquals(-1, getIdOf(graph, 12));

    na.setNode(11, 11, 1);
    na.setNode(12, 12, 1);

    // mini subnetwork which gets completely removed:
    graph.edge(5, 10, 510, true);
    graph.markNodeRemoved(5);
    graph.markNodeRemoved(10);

    PointList pl = new PointList();
    pl.add(1, 2, Double.NaN);
    pl.add(1, 3, Double.NaN);
    graph.edge(9, 11, 911, true).setWayGeometry(pl);
    graph.edge(9, 12, 912, true).setWayGeometry(pl);

    assertEquals(13, graph.getNodes());
    assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph));

    // perform deletion
    graph.optimize();

    assertEquals(11, graph.getNodes());
    assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph));

    int id11 = getIdOf(graph, 11); // is now 10
    int id12 = getIdOf(graph, 12); // is now 5
    int id9 = getIdOf(graph, 9); // is now 9
    assertEquals(
        GHUtility.asSet(id12, id11), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id9)));
    assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id11)));
    assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id12)));

    EdgeIterator iter = carAllExplorer.setBaseNode(id9);
    assertTrue(iter.next());
    assertEquals(id12, iter.getAdjNode());
    assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7);

    assertTrue(iter.next());
    assertEquals(id11, iter.getAdjNode());
    assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7);
  }
  /** @return converted tower node */
  private int handlePillarNode(
      int tmpNode, long osmId, PointList pointList, boolean convertToTowerNode) {
    tmpNode = tmpNode - 3;
    int intlat = pillarLats.getInt(tmpNode);
    int intlon = pillarLons.getInt(tmpNode);
    if (intlat == Integer.MAX_VALUE || intlon == Integer.MAX_VALUE)
      throw new AssertionError(
          "Conversation pillarNode to towerNode already happended!? "
              + "osmId:"
              + osmId
              + " pillarIndex:"
              + tmpNode);

    double tmpLat = Helper.intToDegree(intlat);
    double tmpLon = Helper.intToDegree(intlon);

    if (convertToTowerNode) {
      // convert pillarNode type to towerNode, make pillar values invalid
      pillarLons.setInt(tmpNode, Integer.MAX_VALUE);
      pillarLats.setInt(tmpNode, Integer.MAX_VALUE);
      tmpNode = addTowerNode(osmId, tmpLat, tmpLon);
    } else pointList.add(tmpLat, tmpLon);

    return tmpNode;
  }
  @Override
  public int addEdge(TLongList nodes, int flags) {
    PointList pointList = new PointList(nodes.size());
    int successfullyAdded = 0;
    int firstNode = -1;
    int lastIndex = nodes.size() - 1;
    int lastInBoundsPillarNode = -1;
    for (int i = 0; i < nodes.size(); i++) {
      long osmId = nodes.get(i);
      int tmpNode = osmIdToIndexMap.get(osmId);
      if (tmpNode == EMPTY) continue;
      // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds)
      if (tmpNode == TOWER_NODE) continue;
      if (tmpNode == PILLAR_NODE) {
        // no pillarLats,pillarLons was saved for tmpNode
        // so if there are any existing pillar nodes we need to create an edge out of them
        if (!pointList.isEmpty() && lastInBoundsPillarNode >= 3) {
          // transform the pillar node to a tower node
          tmpNode = lastInBoundsPillarNode;
          tmpNode = handlePillarNode(tmpNode, osmId, null, true);
          tmpNode = -tmpNode - 3;
          if (pointList.size() > 1 && firstNode >= 0) {
            // TOWER node
            successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
            pointList.clear();
            pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
          }
          firstNode = tmpNode;
          lastInBoundsPillarNode = -1;
        }
        continue;
      }

      if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE)
        throw new AssertionError("Mapped index not in correct bounds " + tmpNode);

      if (tmpNode > -TOWER_NODE) {
        lastInBoundsPillarNode = tmpNode;
        // PILLAR node, but convert to towerNode if end-standing
        tmpNode = handlePillarNode(tmpNode, osmId, pointList, i == 0 || i == lastIndex);
      }

      if (tmpNode < TOWER_NODE) {
        // TOWER node
        tmpNode = -tmpNode - 3;
        pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        if (firstNode >= 0) {
          successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
          pointList.clear();
          pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        }
        firstNode = tmpNode;
      }
    }
    return successfullyAdded;
  }
 public static void assertPList(PointList expected, PointList list) {
   assertEquals("size of point lists is not equal", expected.getSize(), list.getSize());
   for (int i = 0; i < expected.getSize(); i++) {
     assertEquals(expected.getLatitude(i), list.getLatitude(i), 1e-4);
     assertEquals(expected.getLongitude(i), list.getLongitude(i), 1e-4);
   }
 }
예제 #10
0
  public PointList copy(int from, int end) {
    if (from > end) throw new IllegalArgumentException("from must be smaller or equals to end");
    if (from < 0 || end > size)
      throw new IllegalArgumentException(
          "Illegal interval: " + from + ", " + end + ", size:" + size);

    PointList copyPL = new PointList(size, is3D);
    if (is3D)
      for (int i = from; i < end; i++) {
        copyPL.add(latitudes[i], longitudes[i], elevations[i]);
      }
    else
      for (int i = from; i < end; i++) {
        copyPL.add(latitudes[i], longitudes[i], Double.NaN);
      }

    return copyPL;
  }
예제 #11
0
  @Override
  public boolean equals(Object obj) {
    if (obj == null) return false;

    PointList other = (PointList) obj;
    if (other.isEmpty() && other.isEmpty()) return true;

    if (this.getSize() != other.getSize() || this.is3D() != other.is3D()) return false;

    for (int i = 0; i < size; i++) {
      if (!NumHelper.equalsEps(latitudes[i], other.latitudes[i])) return false;

      if (!NumHelper.equalsEps(longitudes[i], other.longitudes[i])) return false;

      if (is3D && !NumHelper.equalsEps(elevations[i], other.elevations[i])) return false;
    }
    return true;
  }
예제 #12
0
  public TestAlgoCollector assertDistance(
      AlgoHelperEntry algoEntry, List<QueryResult> queryList, OneRun oneRun) {
    List<Path> altPaths = new ArrayList<Path>();
    QueryGraph queryGraph = new QueryGraph(algoEntry.getQueryGraph());
    queryGraph.lookup(queryList);
    AlgorithmOptions opts = algoEntry.opts;
    FlagEncoder encoder = opts.getFlagEncoder();
    if (encoder.supports(TurnWeighting.class))
      algoEntry.setAlgorithmOptions(
          AlgorithmOptions.start(opts)
              .weighting(
                  new TurnWeighting(
                      opts.getWeighting(),
                      opts.getFlagEncoder(),
                      (TurnCostExtension) queryGraph.getExtension()))
              .build());

    for (int i = 0; i < queryList.size() - 1; i++) {
      RoutingAlgorithm algo = algoEntry.createAlgo(queryGraph);
      Path path =
          algo.calcPath(queryList.get(i).getClosestNode(), queryList.get(i + 1).getClosestNode());
      // System.out.println(path.calcInstructions().createGPX("temp", 0, "GMT"));
      altPaths.add(path);
    }

    PathMerger pathMerger =
        new PathMerger().setCalcPoints(true).setSimplifyResponse(false).setEnableInstructions(true);
    AltResponse rsp = new AltResponse();
    pathMerger.doWork(rsp, altPaths, trMap.getWithFallBack(Locale.US));

    if (rsp.hasErrors()) {
      errors.add(
          algoEntry
              + " response contains errors. Expected distance: "
              + rsp.getDistance()
              + ", expected points: "
              + oneRun
              + ". "
              + queryList
              + ", errors:"
              + rsp.getErrors());
      return this;
    }

    PointList pointList = rsp.getPoints();
    double tmpDist = pointList.calcDistance(distCalc);
    if (Math.abs(rsp.getDistance() - tmpDist) > 2) {
      errors.add(
          algoEntry
              + " path.getDistance was  "
              + rsp.getDistance()
              + "\t pointList.calcDistance was "
              + tmpDist
              + "\t (expected points "
              + oneRun.getLocs()
              + ", expected distance "
              + oneRun.getDistance()
              + ") "
              + queryList);
    }

    if (Math.abs(rsp.getDistance() - oneRun.getDistance()) > 2) {
      errors.add(
          algoEntry
              + " returns path not matching the expected distance of "
              + oneRun.getDistance()
              + "\t Returned was "
              + rsp.getDistance()
              + "\t (expected points "
              + oneRun.getLocs()
              + ", was "
              + pointList.getSize()
              + ") "
              + queryList);
    }

    // There are real world instances where A-B-C is identical to A-C (in meter precision).
    if (Math.abs(pointList.getSize() - oneRun.getLocs()) > 1) {
      errors.add(
          algoEntry
              + " returns path not matching the expected points of "
              + oneRun.getLocs()
              + "\t Returned was "
              + pointList.getSize()
              + "\t (expected distance "
              + oneRun.getDistance()
              + ", was "
              + rsp.getDistance()
              + ") "
              + queryList);
    }
    return this;
  }
 public void suggest(File locationFile, int locationListSize, File outputFile, int hubSize) {
   // WARNING: this code is VERY DIRTY.
   // It's JUST good enough to generate the hubs for Belgium once (because we only need to
   // determine them once).
   // Further research to generate good hubs is needed.
   List<AirLocation> locationList = readAirLocationFile(locationFile);
   if (locationListSize > locationList.size()) {
     throw new IllegalArgumentException(
         "The locationListSize ("
             + locationListSize
             + ") is larger than the locationList size ("
             + locationList.size()
             + ").");
   }
   locationList = subselectLocationList(locationListSize, locationList);
   Map<Point, Point> fromPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10);
   Map<Point, Point> toPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10);
   int rowIndex = 0;
   double maxAirDistance = 0.0;
   for (AirLocation fromAirLocation : locationList) {
     for (AirLocation toAirLocation : locationList) {
       double airDistance = fromAirLocation.getAirDistanceDouble(toAirLocation);
       if (airDistance > maxAirDistance) {
         maxAirDistance = airDistance;
       }
     }
   }
   double airDistanceThreshold = maxAirDistance / 10.0;
   for (AirLocation fromAirLocation : locationList) {
     for (AirLocation toAirLocation : locationList) {
       double distance;
       if (fromAirLocation != toAirLocation) {
         GHRequest request =
             new GHRequest(
                     fromAirLocation.getLatitude(),
                     fromAirLocation.getLongitude(),
                     toAirLocation.getLatitude(),
                     toAirLocation.getLongitude())
                 .setVehicle("car");
         GHResponse response = graphHopper.route(request);
         if (response.hasErrors()) {
           throw new IllegalStateException(
               "GraphHopper gave " + response.getErrors().size() + " errors. First error chained.",
               response.getErrors().get(0));
         }
         // Distance should be in km, not meter
         distance = response.getDistance() / 1000.0;
         if (distance == 0.0) {
           throw new IllegalArgumentException(
               "The fromAirLocation ("
                   + fromAirLocation
                   + ") and toAirLocation ("
                   + toAirLocation
                   + ") are the same.");
         }
         PointList ghPointList = response.getPoints();
         PointPart previousFromPointPart = null;
         PointPart previousToPointPart = null;
         double previousLatitude = Double.NaN;
         double previousLongitude = Double.NaN;
         for (int i = 0; i < ghPointList.size(); i++) {
           double latitude = ghPointList.getLatitude(i);
           double longitude = ghPointList.getLongitude(i);
           if (latitude == previousLatitude && longitude == previousLongitude) {
             continue;
           }
           if (calcAirDistance(
                   latitude,
                   longitude,
                   fromAirLocation.getLatitude(),
                   fromAirLocation.getLongitude())
               < airDistanceThreshold) {
             Point fromPoint = new Point(latitude, longitude);
             Point oldFromPoint = fromPointMap.get(fromPoint);
             if (oldFromPoint == null) {
               // Initialize fromPoint instance
               fromPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>();
               fromPointMap.put(fromPoint, fromPoint);
             } else {
               // Reuse existing fromPoint instance
               fromPoint = oldFromPoint;
             }
             PointPart fromPointPart = fromPoint.pointPartMap.get(fromAirLocation);
             if (fromPointPart == null) {
               fromPointPart = new PointPart(fromPoint, fromAirLocation);
               fromPoint.pointPartMap.put(fromAirLocation, fromPointPart);
               fromPointPart.previousPart = previousFromPointPart;
             }
             fromPointPart.count++;
             previousFromPointPart = fromPointPart;
           }
           if (calcAirDistance(
                   latitude, longitude, toAirLocation.getLatitude(), toAirLocation.getLongitude())
               < airDistanceThreshold) {
             Point toPoint = new Point(latitude, longitude);
             Point oldToPoint = toPointMap.get(toPoint);
             if (oldToPoint == null) {
               // Initialize toPoint instance
               toPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>();
               toPointMap.put(toPoint, toPoint);
             } else {
               // Reuse existing toPoint instance
               toPoint = oldToPoint;
             }
             // Basically do the same as fromPointPart, but while traversing in the other direction
             PointPart toPointPart = toPoint.pointPartMap.get(toAirLocation);
             boolean newToPointPart = false;
             if (toPointPart == null) {
               toPointPart = new PointPart(toPoint, toAirLocation);
               toPoint.pointPartMap.put(toAirLocation, toPointPart);
               newToPointPart = true;
             }
             if (previousToPointPart != null) {
               previousToPointPart.previousPart = toPointPart;
             }
             toPointPart.count++;
             if (newToPointPart) {
               previousToPointPart = toPointPart;
             } else {
               previousToPointPart = null;
             }
           }
           previousLatitude = latitude;
           previousLongitude = longitude;
         }
       }
     }
     logger.debug("  Finished routes for rowIndex {}/{}", rowIndex, locationList.size());
     rowIndex++;
   }
   Set<Point> hubPointList = new LinkedHashSet<Point>(20);
   extractFromHubs(new ArrayList<Point>(fromPointMap.values()), hubPointList, (hubSize + 1) / 2);
   extractFromHubs(new ArrayList<Point>(toPointMap.values()), hubPointList, hubSize / 2);
   logger.info("Writing hubs...");
   BufferedWriter vrpWriter = null;
   try {
     vrpWriter =
         new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
     vrpWriter.write("HUB_COORD_SECTION\n");
     int id = 0;
     for (Point point : hubPointList) {
       vrpWriter.write("" + id + " " + point.latitude + " " + point.longitude + " " + id + "\n");
       id++;
     }
     vrpWriter.write("\n\nGOOGLE MAPS\n");
     for (Point point : hubPointList) {
       vrpWriter.write("" + id + "\t0\t" + point.latitude + "," + point.longitude + "\n");
       id++;
     }
   } catch (IOException e) {
     throw new IllegalArgumentException(
         "Could not read the locationFile ("
             + locationFile.getName()
             + ") or write the vrpOutputFile ("
             + outputFile.getName()
             + ").",
         e);
   } finally {
     IOUtils.closeQuietly(vrpWriter);
   }
   // Throw in google docs spreadsheet and use add-on Mapping Sheets to visualize.
 }
예제 #14
0
  @Override
  public GHResponse route(GHRequest request) {
    request.check();
    StopWatch sw = new StopWatch().start();
    GHResponse rsp = new GHResponse();

    if (!setSupportsVehicle(request.getVehicle())) {
      rsp.addError(
          new IllegalArgumentException(
              "Vehicle "
                  + request.getVehicle()
                  + " unsupported. Supported are: "
                  + getEncodingManager()));
      return rsp;
    }

    EdgeFilter edgeFilter = new DefaultEdgeFilter(encodingManager.getEncoder(request.getVehicle()));
    int from =
        index
            .findClosest(request.getFrom().lat, request.getFrom().lon, edgeFilter)
            .getClosestNode();
    int to =
        index.findClosest(request.getTo().lat, request.getTo().lon, edgeFilter).getClosestNode();
    String debug = "idLookup:" + sw.stop().getSeconds() + "s";

    if (from < 0)
      rsp.addError(new IllegalArgumentException("Cannot find point 1: " + request.getFrom()));

    if (to < 0)
      rsp.addError(new IllegalArgumentException("Cannot find point 2: " + request.getTo()));

    if (from == to) rsp.addError(new IllegalArgumentException("Point 1 is equal to point 2"));

    sw = new StopWatch().start();
    RoutingAlgorithm algo = null;

    if (chUsage) {
      if (request.getAlgorithm().equals("dijkstrabi")) algo = prepare.createAlgo();
      else if (request.getAlgorithm().equals("astarbi"))
        algo = ((PrepareContractionHierarchies) prepare).createAStar();
      else
        rsp.addError(
            new IllegalStateException(
                "Only dijkstrabi and astarbi is supported for LevelGraph (using contraction hierarchies)!"));

    } else {
      prepare =
          NoOpAlgorithmPreparation.createAlgoPrepare(
              graph,
              request.getAlgorithm(),
              encodingManager.getEncoder(request.getVehicle()),
              request.getType());
      algo = prepare.createAlgo();
    }

    if (rsp.hasErrors()) {
      return rsp;
    }
    debug += ", algoInit:" + sw.stop().getSeconds() + "s";

    sw = new StopWatch().start();
    Path path = algo.calcPath(from, to);
    debug +=
        ", "
            + algo.getName()
            + "-routing:"
            + sw.stop().getSeconds()
            + "s"
            + ", "
            + path.getDebugInfo();
    PointList points = path.calcPoints();
    simplifyRequest = request.getHint("simplifyRequest", simplifyRequest);
    if (simplifyRequest) {
      sw = new StopWatch().start();
      int orig = points.getSize();
      double minPathPrecision = request.getHint("douglas.minprecision", 1d);
      if (minPathPrecision > 0) {
        new DouglasPeucker().setMaxDistance(minPathPrecision).simplify(points);
      }
      debug +=
          ", simplify (" + orig + "->" + points.getSize() + "):" + sw.stop().getSeconds() + "s";
    }

    enableInstructions = request.getHint("instructions", enableInstructions);
    if (enableInstructions) {
      sw = new StopWatch().start();
      rsp.setInstructions(path.calcInstructions());
      debug += ", instructions:" + sw.stop().getSeconds() + "s";
    }
    return rsp.setPoints(points)
        .setDistance(path.getDistance())
        .setTime(path.getTime())
        .setDebugInfo(debug);
  }
예제 #15
0
  public static PathWrapper createPathWrapper(
      JSONObject path, boolean tmpCalcPoints, boolean tmpInstructions, boolean tmpElevation) {
    PathWrapper pathWrapper = new PathWrapper();
    pathWrapper.addErrors(readErrors(path));
    if (pathWrapper.hasErrors()) return pathWrapper;

    if (path.has("snapped_waypoints")) {
      String snappedPointStr = path.getString("snapped_waypoints");
      PointList snappedPoints = WebHelper.decodePolyline(snappedPointStr, 5, tmpElevation);
      pathWrapper.setWaypoints(snappedPoints);
    }

    if (tmpCalcPoints) {
      String pointStr = path.getString("points");
      PointList pointList = WebHelper.decodePolyline(pointStr, 100, tmpElevation);
      pathWrapper.setPoints(pointList);

      if (tmpInstructions) {
        JSONArray instrArr = path.getJSONArray("instructions");

        InstructionList il = new InstructionList(null);
        int viaCount = 1;
        for (int instrIndex = 0; instrIndex < instrArr.length(); instrIndex++) {
          JSONObject jsonObj = instrArr.getJSONObject(instrIndex);
          double instDist = jsonObj.getDouble("distance");
          String text = jsonObj.getString("text");
          long instTime = jsonObj.getLong("time");
          int sign = jsonObj.getInt("sign");
          JSONArray iv = jsonObj.getJSONArray("interval");
          int from = iv.getInt(0);
          int to = iv.getInt(1);
          PointList instPL = new PointList(to - from, tmpElevation);
          for (int j = from; j <= to; j++) {
            instPL.add(pointList, j);
          }

          InstructionAnnotation ia = InstructionAnnotation.EMPTY;
          if (jsonObj.has("annotation_importance") && jsonObj.has("annotation_text")) {
            ia =
                new InstructionAnnotation(
                    jsonObj.getInt("annotation_importance"),
                    jsonObj.getString("annotation_text"),
                    0,
                    false);
          }

          Instruction instr;
          if (sign == Instruction.USE_ROUNDABOUT || sign == Instruction.LEAVE_ROUNDABOUT) {
            RoundaboutInstruction ri = new RoundaboutInstruction(sign, text, ia, instPL);

            if (jsonObj.has("exit_number")) {
              ri.setExitNumber(jsonObj.getInt("exit_number"));
            }

            if (jsonObj.has("turn_angle")) {
              // TODO provide setTurnAngle setter
              double angle = jsonObj.getDouble("turn_angle");
              ri.setDirOfRotation(angle);
              ri.setRadian((angle < 0 ? -Math.PI : Math.PI) - angle);
            }

            instr = ri;
          } else if (sign == Instruction.REACHED_VIA) {
            ViaInstruction tmpInstr = new ViaInstruction(text, ia, instPL);
            tmpInstr.setViaCount(viaCount);
            viaCount++;
            instr = tmpInstr;
          } else if (sign == Instruction.FINISH) {
            instr = new FinishInstruction(instPL, 0);
          } else {
            instr = new Instruction(sign, text, ia, instPL);
          }

          // The translation is done from the routing service so just use the provided string
          // instead of creating a combination with sign and name etc
          instr.setUseRawName();

          instr.setDistance(instDist).setTime(instTime);
          il.add(instr);
        }
        pathWrapper.setInstructions(il);
      }
    }

    double distance = path.getDouble("distance");
    long time = path.getLong("time");
    pathWrapper.setDistance(distance).setTime(time);
    return pathWrapper;
  }
예제 #16
0
  @Override
  public GHResponse route(GHRequest request) {
    StopWatch sw = new StopWatch().start();
    double took = 0;
    try {
      String url =
          serviceUrl
              + "?point="
              + request.getFrom().lat
              + ","
              + request.getFrom().lon
              + "&point="
              + request.getTo().lat
              + ","
              + request.getTo().lon
              + "&type=json"
              + "&points_encoded="
              + pointsEncoded
              + "&min_path_precision="
              + request.getHint("douglas.minprecision", 1)
              + "&algo="
              + request.getAlgorithm();
      String str = downloader.downloadAsString(url);
      JSONObject json = new JSONObject(str);
      took = json.getJSONObject("info").getDouble("took");
      JSONArray paths = json.getJSONArray("paths");
      JSONObject firstPath = paths.getJSONObject(0);

      boolean is3D = false;
      if (firstPath.has("points_dim")) is3D = "3".equals(firstPath.getString("points_dim"));
      double distance = firstPath.getDouble("distance");
      int time = firstPath.getInt("time");
      PointList pointList;
      if (pointsEncoded) {
        pointList = WebHelper.decodePolyline(firstPath.getString("points"), 100, is3D);
      } else {
        JSONArray coords = firstPath.getJSONObject("points").getJSONArray("coordinates");
        pointList = new PointList(coords.length(), is3D);
        for (int i = 0; i < coords.length(); i++) {
          JSONArray arr = coords.getJSONArray(i);
          double lon = arr.getDouble(0);
          double lat = arr.getDouble(1);
          if (is3D) pointList.add(lat, lon, arr.getDouble(2));
          else pointList.add(lat, lon);
        }
      }
      GHResponse res = new GHResponse();
      if (instructions) {
        JSONArray instrArr = firstPath.getJSONArray("instructions");

        InstructionList il = new InstructionList();
        for (int instrIndex = 0; instrIndex < instrArr.length(); instrIndex++) {
          JSONObject jsonObj = instrArr.getJSONObject(instrIndex);
          double instDist = jsonObj.getDouble("distance");
          String text = jsonObj.getString("text");
          long instTime = jsonObj.getLong("time");
          int sign = jsonObj.getInt("sign");
          JSONArray iv = jsonObj.getJSONArray("interval");
          int from = iv.getInt(0);
          int to = iv.getInt(1);
          PointList instPL = new PointList(to - from, is3D);
          for (int j = from; j <= to; j++) {
            instPL.add(pointList, j);
          }

          // TODO way and payment type
          Instruction instr =
              new Instruction(sign, text, -1, -1, instPL).setDistance(instDist).setTime(instTime);
          il.add(instr);
        }
        res.setInstructions(il);
      }
      return res.setPoints(pointList).setDistance(distance).setMillis(time);
    } catch (Exception ex) {
      throw new RuntimeException(
          "Problem while fetching path " + request.getFrom() + "->" + request.getTo(), ex);
    } finally {
      logger.debug("Full request took:" + sw.stop().getSeconds() + ", API took:" + took);
    }
  }