We are thinking to make some special edges not to use in the routing temporarily.
I found a question very similar to our question: Does GraphHopper support dynamic edge weights? So I not use the CH algorithm, change their distance to huge value after I filter out the edges I need.
Underlying are the whole two method I add in class GraphHopper
. I added a hopper.flush
but the result still not right.
I write the method processChange()
trying to represent the feedback of traffic data. If you give the location(lat&lon) where having a traffic jam or
construction and call the processChange()
. It will choose the edges which are one meter away from this location point and change the distance of these edges to 10000000 so that these edges will not to use in the routing temporarily.
The method pointToLine()
is just to calculate the distance between the location point to a edge.
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;
}
}
I output the previous distance and changed distance to see dose it work:
preDistance is: 339.245 changed distance is: 1000000.0
But when I route, I found the distance still not change. Why will this happen? Does route.getDistance will read diffierent value from edge.getDistance()? Do edges weight values be stored in the gh-file or the gh-file just store the edge's id and the nodes' id constituted of it?