public boolean setElevationProfile(
      PackedCoordinateSequence elev, boolean computed, boolean slopeLimit) {
    if (elev == null || elev.size() < 2) {
      return false;
    }

    if (slopeOverride && !computed) {
      return false;
    }

    elevationProfile = elev;

    // compute the various costs of the elevation changes
    double lengthMultiplier = ElevationUtils.getLengthMultiplierFromElevation(elev);
    if (Double.isNaN(lengthMultiplier)) {
      LOG.error("lengthMultiplier from elevation profile is NaN, setting to 1");
      lengthMultiplier = 1;
    }

    length *= lengthMultiplier;
    bicycleSafetyEffectiveLength *= lengthMultiplier;

    SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, slopeLimit);
    slopeSpeedEffectiveLength = costs.slopeSpeedEffectiveLength;
    maxSlope = costs.maxSlope;
    slopeWorkCost = costs.slopeWorkCost;
    bicycleSafetyEffectiveLength += costs.slopeSafetyCost;
    flattened = costs.flattened;

    return costs.flattened;
  }
示例#2
0
  public void testTriangle() {
    Coordinate c1 = new Coordinate(-122.575033, 45.456773);
    Coordinate c2 = new Coordinate(-122.576668, 45.451426);

    Vertex v1 = new Vertex("v1", c1, null);
    Vertex v2 = new Vertex("v2", c2, null);

    GeometryFactory factory = new GeometryFactory();
    LineString geometry = factory.createLineString(new Coordinate[] {c1, c2});

    double length = 650.0;

    PlainStreetEdge testStreet =
        new PlainStreetEdge(
            v1, v2, geometry, "Test Lane", length, StreetTraversalPermission.ALL, false);
    testStreet.setBicycleSafetyEffectiveLength(length * 0.74); // a safe street

    Coordinate[] profile =
        new Coordinate[] {
          new Coordinate(0, 0), // slope = 0.1
          new Coordinate(length / 2, length / 20.0),
          new Coordinate(length, 0) // slope = -0.1
        };
    PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile);
    testStreet.setElevationProfile(elev);

    double trueLength = ElevationUtils.getLengthMultiplierFromElevation(elev) * length;
    testStreet.setSlopeSpeedEffectiveLength(trueLength); // normalize length

    SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, "test");

    TraverseOptions options = new TraverseOptions(TraverseMode.BICYCLE);
    options.optimizeFor = OptimizeType.TRIANGLE;
    options.speed = 6.0;
    options.walkReluctance = 1;

    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(1);
    State startState = new State(v1, options);

    State result = testStreet.traverse(startState);
    double timeWeight = result.getWeight();
    double expectedSpeedWeight = trueLength / options.speed;
    assertEquals(expectedSpeedWeight, timeWeight);

    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(1);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double slopeWeight = result.getWeight();
    assertTrue(length * 1.5 / options.speed < slopeWeight);
    assertTrue(length * 1.5 * 10 / options.speed > slopeWeight);

    options.setTriangleSafetyFactor(1);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double safetyWeight = result.getWeight();
    double slopeSafety = costs.slopeSafetyCost;
    double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / options.speed;
    assertTrue(expectedSafetyWeight - safetyWeight < 0.00001);

    final double ONE_THIRD = 1 / 3.0;
    options.setTriangleSafetyFactor(ONE_THIRD);
    options.setTriangleSlopeFactor(ONE_THIRD);
    options.setTriangleTimeFactor(ONE_THIRD);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double averageWeight = result.getWeight();
    assertTrue(
        Math.abs(
                safetyWeight * ONE_THIRD
                    + slopeWeight * ONE_THIRD
                    + timeWeight * ONE_THIRD
                    - averageWeight)
            < 0.00000001);
  }