【问题标题】:Graphhopper can't route using dynamic edge weights?Graphhopper 无法使用动态边权重进行路由?
【发布时间】:2019-11-21 04:12:24
【问题描述】:

我们正在考虑制作一些特殊的边,暂时不要在路由中使用。

我发现了一个与我们的问题非常相似的问题: Does GraphHopper support dynamic edge weights? 所以我不使用 CH 算法,在过滤掉我需要的边缘后将它们的距离更改为巨大的值。

基础是我在class GraphHopper 中添加的全部两个方法。我加了hopper.flush,结果还是不对。

我写的方法processChange()试图表示流量数据的反馈。如果您提供交通拥堵的位置(纬度和经度)或 施工并致电processChange()。它将选择距离该位置点一米的边,并将这些边的距离更改为 10000000,以便这些边暂时不会用于路由。 pointToLine()的方法只是计算位置点到边的距离。

public static GraphHopper processChange(double[] dirtyCoor){
    double[] dirtyPoint;
    dirtyPoint = dirtyCoor;

    GraphHopper hopper = new GraphHopper();
    hopper.setGraphHopperLocation("gh-problem")
            .setEncodingManager(new EncodingManager("car"))
            .setOSMFile("foshan.osm")
            .forServer()
            .setCHWeighting("no")
            .setCHEnable(false);
    hopper.importOrLoad();

    GraphStorage g =hopper.getGraph();

    AllEdgesIterator edges = g.getAllEdges();
    int n =edges.getCount();

    EdgeIterator iter = g.getAllEdges();

    int[] edgeIds;
    edgeIds = new int[n];
    int[] startNodeId;
    startNodeId = new int[n];
    int[] endNodeId;
    endNodeId = new int[n];
    double[] SNlat;
    double[] SNlon;
    double[] ENlat;
    double[] ENlon;
    SNlat = new double[n];
    SNlon = new double[n];
    ENlat = new double[n];
    ENlon = new double[n];

    int i=0;
    while (iter.next()) {
        int edgeId = iter.getEdge();
        edgeIds[i] = edgeId;

        int nodeA = iter.getBaseNode();
        int nodeB = iter.getAdjNode();
        startNodeId[i] = nodeA;
        endNodeId[i] = nodeB;

        NodeAccess nodeAccess = g.getNodeAccess();
        double lat = nodeAccess.getLatitude(nodeA);
        double lon = nodeAccess.getLongitude(nodeA);
        SNlat[i] = lat;
        SNlon[i] = lon;

        double adjLat = nodeAccess.getLatitude(nodeB);
        double adjLon = nodeAccess.getLongitude(nodeB);
        ENlat[i] = adjLat;
        ENlon[i] = adjLon;

        double distance = pointToLine(SNlat[i],SNlon[i],ENlat[i],ENlon[i],dirtyPoint[0],dirtyPoint[1]);

        if (distance <= 1){
            double preDist = iter.getDistance();

            iter.setDistance(1000000);
            double cDist = iter.getDistance();

        }
      i=i+1;
    }

    hopper.flush();
    hopper.setGraph(g);

    //routeing test
    double[] orig = new double[]{23.0389909, 113.096614};
    double[] dest = new double[]{23.0389031, 113.1028902};

    GHRequest request = new GHRequest(orig[0], orig[1], dest[0], dest[1]);
    request.setWeighting("fastest");
    request.setVehicle("car");

    GHResponse route = hopper.route(request);

    double time=route.getMillis();
    double dis=route.getDistance();

    System.out.println("distance=" + dis);
    System.out.println("time=" + time);

    return hopper;
}




public static double pointToLine(double SNlat, double SNlon, double ENlat, double ENlon, double DPlat, double DPlon) {
    double space = 0;

    double edgeLength = new DistanceCalcEarth().calcDist(SNlat, SNlon, ENlat, ENlon);
    double SN2DP = new DistanceCalcEarth().calcDist(SNlat, SNlon, DPlat, DPlon);
    double EN2DP = new DistanceCalcEarth().calcDist(ENlat, ENlon, DPlat, DPlon);

    if (Math.abs((SN2DP + EN2DP) - edgeLength)<=0.000001){
        space = 0;
        return space;
    }
    else{
        double p = (edgeLength + EN2DP + SN2DP) / 2;
        double s = Math.sqrt(p * (p - edgeLength) * (p - SN2DP) * (p - EN2DP));
        space = 2 * s / edgeLength;
        return space;
    }

}

我输出之前的距离并改变距离以查看它的工作量:

preDistance is: 339.245     changed distance is: 1000000.0

但是当我路由时,我发现距离仍然没有改变。为什么会发生这种情况? route.getDistance 会从 edge.getDistance() 中读取不同的值吗?边权重值是存储在 gh 文件中还是 gh 文件只存储边的 id 和由它构成的节点的 id?

【问题讨论】:

    标签: graphhopper


    【解决方案1】:

    您需要通过prepare.chWeighting=no启用灵活模式

    例如请参阅this blog 帖子,其中我描述了如何实时整合交通数据

    【讨论】:

    • 啊,好吧。看来您已经禁用了此功能。嗯,也许您中间有重新加载,您需要在此之前执行 graph.flush 吗?
    • 我添加了一个 hopper.flush 但结果仍然不正确。我是使用 Graphhopper 的新手。我添加flush()的地方不对吗?我在这里发布整个代码。 @Karussell
    • 如果中间没有重新加载,则无需调用flush。你确定if (distance &lt;= 1) 被调用了吗?
    • 是的,我确定调用了 if (distance &lt;= 1)。我输出了边的 ID 和节点的 ID 来检查是否有任何选择的边,结果是:changeEdgeID is: 2980 startNodeId[i]: 1725 endNodeId[i]: 1727changeEdgeID is: 2981 startNodeId[i]: 1723 endNodeId[i]: 1725。我选择一条经过这两条边的路线,输出距离和时间,然后调用processChange() 并再次路线。调用processChange后输出的距离和时间应该会有所不同,但不会改变。
    • 边权重值是否存储在 gh 文件中? 'route.getdistance()' 是从 gh 文件中读取边缘的距离还是找到边缘的起始节点和结束节点,然后计算两个节点之间的距离? @karussell
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 2016-11-13
    相关资源
    最近更新 更多