使用 GraphHopper 在路线上查找点

Find point on the route using GraphHopper

我正在使用 GraphHopper 寻找点之间的路线。如果车辆以 x 的平均速度移动,我想在给定时间 t 预测车辆的位置。 GraphHopper 有一个用于查找等时线的模块,但我不知道如何在一条路线上 运行 它。下面是我目前使用的代码

    List<GHPoint> points = new ArrayList<>();

    points.add(origin);

    for (GHPoint pnt : waypoints) {
        points.add(pnt);
    }

    points.add(destination);

    GHRequest req = new GHRequest(points).
            setWeighting("shortest").
            setVehicle("car").              
            setLocale(Locale.US);

    GHResponse rsp = graphHopper.route(req);

    // first check for errors
    if(rsp.hasErrors()) {
        // handle them!
        // rsp.getErrors()
        List<Throwable> errors = rsp.getErrors();
        return null;
    }

    PathWrapper bestPath = rsp.getBest();

要解决您的问题,您可以使用位于 here.

Isochrone Request API

要预测 Point B 您的车辆可能在哪里,我们需要提供下一个参数:

  1. point - 指定起始坐标,required param;
  2. time_limit - 指定车辆应该行驶的时间。马上。这是魔法,在这里提供您的 t 参数;
  3. vehicle - 应为其计算路线的车辆配置文件。默认为 car;
  4. distance_limit - 指定车辆应该行驶的距离。以米为单位。您可以使用 (t x v) 公式计算它,因为您指定车辆以平均速度行驶。

就是这样。 GraphHopper API returns 给你 GeoJson 格式的多边形列表。

示例:

int t = 600; // in seconds
int v = 10;  // in meters per second
int s = t * v; // in meters
IsochroneApi isochrone = new IsochroneApi();
isochrone.setApiClient(GHApiUtil.createClient());
try {
    // Please note: the request string for the point has the order "lat,lon" but the response contains
    // an array with the order [lon,lat]
    IsochroneResponse rsp = isochrone.getIsochrone("51.183728,14.42801", t, s, VehicleProfileId.CAR,
            3, false, "fastest");
    final IsochroneResponsePolygon isochrone0 = rsp.getPolygons().get(0);
    List<List<BigDecimal>> exteriorRing = isochrone0.getGeometry().getCoordinates().get(0);
    System.out.println(exteriorRing);
    double lon0 = ((Number) exteriorRing.get(0).get(0)).doubleValue();
    double lat0 = ((Number) exteriorRing.get(0).get(1)).doubleValue();
    System.out.println("first coord " + lat0 + ", " + lon0);
} catch (Exception ex) {
    throw new RuntimeException(ex);
}

感谢@Jamie,我通过在 LineString 中删除坐标列表得到了插值点。您可以使用 getPoints().toLineString 方法获取 LineString,即 bestPath.getPoints().toLineString(false)。

距离是这样计算的

   distance = (avgSpeedKMPerHr/ 3.6 ) * timeSec;

下面是使用的函数

  //distacne in meters which was calucletd 
public Point interpolatePointAlogLine(LineString line,double distance) throws 
   NoSuchAuthorityCodeException, FactoryException
{       
    GeodeticCalculator calculator = new GeodeticCalculator(CRS.decode("EPSG:4326")); 
    GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326);

    List<Coordinate> coordinates = new ArrayList<Coordinate>();
    Collections.addAll(coordinates, line.getCoordinates());
    double accumulatedLength = 0;

    if(distance >= line.getLength())
        return geometryFactory.createPoint(line.getEndPoint());

    for (int i = 0; i < coordinates.size(); i++)
    {

        Coordinate c1 = coordinates.get(i);
        Coordinate c2 = coordinates.get(i + 1);

        calculator.setStartingGeographicPoint(c1.x, c1.y);
        calculator.setDestinationGeographicPoint(c2.x, c2.y);

        double length = calculator.getOrthodromicDistance();

        if (length + accumulatedLength >= distance) 
        {
            double offsetLength = distance - accumulatedLength;
            double ratio = offsetLength / length;
            double dx = c2.x - c1.x;
            double dy = c2.y - c1.y;

            Coordinate iPoint = new Coordinate(c1.x + (dx * ratio), 
                    c1.y + (dy * ratio));

            return geometryFactory.createPoint(iPoint));
        }
        else {
            accumulatedLength += length;
        }
    }
    return null;
}