From ad56c6f27b6950977064a38dcd0013b786848020 Mon Sep 17 00:00:00 2001 From: Subrina0013 Date: Tue, 8 Sep 2020 13:05:55 -0400 Subject: [PATCH 1/2] Add custom weighting classes and update edge speed. Custom weighting files are added ('FastestDynamicWeightingSIGMA' and 'AvoidEdgesWeightingSIGMA'). Added files for updating speed ('DataUpdaterSIgmaTest', 'RoadEntrySigmaTest'). DataUpdaterSIgmaTest uses a list of edges and update the speed of those edges. An DataUpdaterSIgmaTest object is created in the main file 'MyImport_DataUpdater' and need to be used . --- config-example.yml | 12 +- config.yml | 11 +- .../java/com/graphhopper/GraphHopper.java | 4 +- .../weighting/AvoidEdgesWeightingSIGMA.java | 81 ++++++++++ .../weighting/FastestDynamicWeighting.java | 110 +++++++++++++ .../osmidexample/DataUpdaterSigmaTest.java | 81 ++++++++++ .../osmidexample/MyImport_dataUpdater.java | 149 ++++++++++++++++++ .../osmidexample/RoadEntrySigmaTest.java | 33 ++++ 8 files changed, 470 insertions(+), 11 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/AvoidEdgesWeightingSIGMA.java create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/FastestDynamicWeighting.java create mode 100644 osm-id-mapping/src/main/java/com/graphhopper/osmidexample/DataUpdaterSigmaTest.java create mode 100644 osm-id-mapping/src/main/java/com/graphhopper/osmidexample/MyImport_dataUpdater.java create mode 100644 osm-id-mapping/src/main/java/com/graphhopper/osmidexample/RoadEntrySigmaTest.java diff --git a/config-example.yml b/config-example.yml index 3b6273de5..87eadc610 100644 --- a/config-example.yml +++ b/config-example.yml @@ -45,14 +45,14 @@ graphhopper: # To enable finite u-turn costs use something like fastest|u_turn_costs=30, where 30 are the u-turn costs in seconds # (given as integer). Note that since the u-turn costs are given in seconds the weighting you use should also # calculate the weight in seconds. The u-turn costs will only be applied for edge_based, see below. - prepare.ch.weightings: fastest + # prepare.ch.weightings: fastest # To enable turn-costs in speed mode (contraction hierarchies) edge-based graph traversal and a more elaborate # pre-processing is required. Using this option you can either turn off the edge-based pre-processing (choose 'off'), # use edge-based pre-processing for all encoders/vehicles with turn_costs=true (choose 'edge_or_node') or use node-based # pre-processing for all encoders/vehicles and additional edge-based pre-processing for all encoders/vehicles with # turn_costs=true (choose 'edge_and_node'). - prepare.ch.edge_based: off + # prepare.ch.edge_based: off # Disable the speed mode. Should be used only with routing.max_visited_nodes or when the hybrid mode is enabled instead @@ -65,10 +65,12 @@ graphhopper: # The hybrid mode can be enabled with - # prepare.lm.weightings: fastest + prepare.lm.weightings: fastest + # should i also include 'FastestDynamic' to use that? + # prepare.lm.weightings: fastestDynamic # To tune the performance vs. memory usage for the hybrid mode use - # prepare.lm.landmarks: 16 + prepare.lm.landmarks: 16 # Make landmark preparation parallel if you have enough RAM. Change this only if you know what you are doing and if the default worked for you. # prepare.lm.threads: 1 @@ -91,7 +93,7 @@ graphhopper: # If enabled, allows a user to run flexibility requests even if speed mode is enabled. Every request then has to include a hint ch.disable=true. # Attention, non-CH route calculations take way more time and resources, compared to CH routing. # A possible attacker might exploit this to slow down your service. Only enable it if you need it and with routing.maxVisitedNodes - # routing.ch.disabling_allowed: true + routing.ch.disabling_allowed: true # If enabled, allows a user to run flexible mode requests even if the hybrid mode is enabled. Every such request then has to include a hint routing.lm.disable=true. diff --git a/config.yml b/config.yml index 8018d6be0..1bea68977 100644 --- a/config.yml +++ b/config.yml @@ -45,7 +45,7 @@ graphhopper: # To enable finite u-turn costs use something like fastest|u_turn_costs=30, where 30 are the u-turn costs in seconds # (given as integer). Note that since the u-turn costs are given in seconds the weighting you use should also # calculate the weight in seconds. The u-turn costs will only be applied for edge_based, see below. - prepare.ch.weightings: fastest + # prepare.ch.weightings: fastest # To enable turn-costs in speed mode (contraction hierarchies) edge-based graph traversal and a more elaborate # pre-processing is required. Using this option you can either turn off the edge-based pre-processing (choose 'off'), @@ -56,7 +56,8 @@ graphhopper: # Disable the speed mode. Should be used only with routing.max_visited_nodes or when the hybrid mode is enabled instead - # prepare.ch.weightings: no + prepare.ch.weightings: no + # prepare.lm.weightings: fastestDynamic # To make CH preparation faster for multiple flagEncoders you can increase the default threads if you have enough RAM. @@ -65,10 +66,10 @@ graphhopper: # The hybrid mode can be enabled with - # prepare.lm.weightings: fastest + prepare.lm.weightings: fastest # To tune the performance vs. memory usage for the hybrid mode use - # prepare.lm.landmarks: 16 + prepare.lm.landmarks: 16 # Make landmark preparation parallel if you have enough RAM. Change this only if you know what you are doing and if the default worked for you. # prepare.lm.threads: 1 @@ -91,7 +92,7 @@ graphhopper: # If enabled, allows a user to run flexibility requests even if speed mode is enabled. Every request then has to include a hint ch.disable=true. # Attention, non-CH route calculations take way more time and resources, compared to CH routing. # A possible attacker might exploit this to slow down your service. Only enable it if you need it and with routing.maxVisitedNodes - # routing.ch.disabling_allowed: true + routing.ch.disabling_allowed: true # If enabled, allows a user to run flexible mode requests even if the hybrid mode is enabled. Every such request then has to include a hint routing.lm.disable=true. diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index d98aa3e00..906c706a7 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -744,7 +744,7 @@ public boolean load(String graphHopperFolder) { GHLock lock = null; try { - // create locks only if writes are allowed, if they are not allowed a lock cannot be created + // create locks only if writes are allowed, if they are not allowed a lock cannot be created // (e.g. on a read only filesystem locks would fail) if (ghStorage.getDirectory().getDefaultType().isStoring() && isAllowWrites()) { lockFactory.setLockDir(new File(ghLocation)); @@ -906,6 +906,8 @@ public Weighting createWeighting(HintsMap hintsMap, FlagEncoder encoder, Graph g weighting = new PriorityWeighting(encoder, hintsMap); else weighting = new FastestWeighting(encoder, hintsMap); + } else if ("fastestDynamic".equalsIgnoreCase(weightingStr)) { + weighting = new FastestDynamicWeighting(encoder, hintsMap); } else if ("curvature".equalsIgnoreCase(weightingStr)) { if (encoder.supports(CurvatureWeighting.class)) weighting = new CurvatureWeighting(encoder, hintsMap); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/AvoidEdgesWeightingSIGMA.java b/core/src/main/java/com/graphhopper/routing/weighting/AvoidEdgesWeightingSIGMA.java new file mode 100644 index 000000000..c174c550c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/AvoidEdgesWeightingSIGMA.java @@ -0,0 +1,81 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.routing.weighting; + +import com.carrotsearch.hppc.IntSet; +import com.graphhopper.coll.GHIntHashSet; +import com.graphhopper.util.EdgeIteratorState; + +import java.util.Collection; + +/** + * Rates already used Paths worse. + * + * @author Tunaggina + */ + +public class AvoidEdgesWeightingSIGMA extends AbstractAdjustedWeighting { + // contains the edge IDs of the already visited edges + // protected final IntSet avoidedEdges = new GHIntHashSet(); + private IntSet avoidedEdges = new GHIntHashSet(); + + private double edgePenaltyFactor = 5.0; + + public AvoidEdgesWeightingSIGMA(Weighting superWeighting) { + super(superWeighting); + } + + public AvoidEdgesWeightingSIGMA setEdgePenaltyFactor(double edgePenaltyFactor) { + this.edgePenaltyFactor = edgePenaltyFactor; + return this; + } + + /** + * This method adds the specified path to this weighting which should be penalized in the + * calcWeight method. + */ + // when visitedEdges is protected.... + + // public void addEdges(Collection edges) { + // for (EdgeIteratorState edge : edges) { + // visitedEdges.add(edge.getEdge()); + // } + // } + + public void setAvoidedEdges(IntSet avoidedEdges) { + this.avoidedEdges = avoidedEdges; + } + + @Override + public double getMinWeight(double distance) { + return superWeighting.getMinWeight(distance); + } + + @Override + public double calcWeight(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { + double weight = superWeighting.calcWeight(edgeState, reverse, prevOrNextEdgeId); + if (avoidedEdges.contains(edgeState.getEdge())) + return weight * edgePenaltyFactor; + return weight; + } + + @Override + public String getName() { + return "avoid_edges_Sigma"; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/weighting/FastestDynamicWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/FastestDynamicWeighting.java new file mode 100644 index 000000000..7493fb173 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/FastestDynamicWeighting.java @@ -0,0 +1,110 @@ +package com.graphhopper.routing.weighting; + +import com.carrotsearch.hppc.IntFloatHashMap; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.HintsMap; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.PMap; +import com.graphhopper.util.Parameters.Routing; +import java.util.List; + +/** + * Calculates the fastest route with the specified vehicle (VehicleEncoder). Calculates the weight + * in seconds. Updates the weight for MyImport_Sigma.java + *

+ * + * @author Tunaggina + */ + + +public class FastestDynamicWeighting extends AbstractWeighting { + + protected final static double SPEED_CONV = 3.6; + private final double headingPenalty; + private final long headingPenaltyMillis; + private final double maxSpeed; + private double dynamicEdgePenaltyFactor = 50.0 ; //0.01 + + // need to correspond "myWeighedEdges" to "count10" in "MyImport_Sigma" + // list of the edges that have been traversed. + private List myWeighedEdges = new ArrayList(); + + // private List getCountLog(){ + // return null; + // } + + // I am trying to get the values directly..however, as 'Weighting' class does not have any parameter for that, + // it will not take this value. To do this, I think we need to add another parameter "customWeight" along with FlagEncoder + // and PMap. If that parameter is empty= it won't impact anything. if the parameter has the arraylist of edges= then it consider. + public FastestDynamicWeighting(FlagEncoder encoder, PMap map) { + super(encoder); + headingPenalty = map.getDouble(Routing.HEADING_PENALTY, Routing.DEFAULT_HEADING_PENALTY); + headingPenaltyMillis = Math.round(headingPenalty * 1000); + maxSpeed = encoder.getMaxSpeed() / SPEED_CONV; + // this.myWeighedEdges = getCountLog(); + this.myWeighedEdges = getMyWeighedEdges(); + } + + public FastestDynamicWeighting(FlagEncoder encoder) { + this(encoder, new HintsMap(0)); + } + + private List getMyWeighedEdges(){ + return myWeighedEdges; + } + + public void setMyWeighedEdges(List myWeighedEdges) { + this.myWeighedEdges = myWeighedEdges; + } + + @Override + public double getMinWeight(double distance) { + return distance / maxSpeed; + } + + @Override + public double calcWeight(EdgeIteratorState edge, boolean reverse, int prevOrNextEdgeId) { + double speed = reverse ? edge.getReverse(avSpeedEnc) : edge.get(avSpeedEnc); + if (speed == 0) + return Double.POSITIVE_INFINITY; + + double time = edge.getDistance() / speed * SPEED_CONV; + + // add direction penalties at start/stop/via points + boolean unfavoredEdge = edge.get(EdgeIteratorState.UNFAVORED_EDGE); + if (unfavoredEdge) + time += headingPenalty; + + // get the value of the edge + if (myWeighedEdges.contains(edge.getEdge())) + time= time + time * dynamicEdgePenaltyFactor ; + + return time ; + } + + + @Override + public long calcMillis(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { + // TODO move this to AbstractWeighting? see #485 + long time = 0; + boolean unfavoredEdge = edgeState.get(EdgeIteratorState.UNFAVORED_EDGE); + if (unfavoredEdge) + time += headingPenaltyMillis; + + return time + super.calcMillis(edgeState, reverse, prevOrNextEdgeId); + } + + @Override + public String getName() { + return "fastestDynamic"; + } + +} + + /* + // i also tried to make it public (like AvoiEdgesWeighting class) but the weighting class does not allow + + public void setMyWeighedEdges(List avoidedEdges) { //just the edge_ids that needed to be avoided + this.myWeighedEdges = myWeighedEdges; + } + */ diff --git a/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/DataUpdaterSigmaTest.java b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/DataUpdaterSigmaTest.java new file mode 100644 index 000000000..b310c20ff --- /dev/null +++ b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/DataUpdaterSigmaTest.java @@ -0,0 +1,81 @@ +package com.graphhopper.osmidexample; + +import com.graphhopper.GraphHopper; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.AbstractFlagEncoder; +import com.graphhopper.storage.Graph; +import com.graphhopper.storage.index.LocationIndex; +import com.graphhopper.storage.index.QueryResult; +import com.graphhopper.util.EdgeIteratorState; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Tunaggina + */ + +public class DataUpdaterSigmaTest { + + private MyGraphHopper hopper; + + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final Lock writeLock; + private RoadEntrySigmaTest currentRoads = new RoadEntrySigmaTest(); + +// private ArrayList currentRoads = new RoadEntrySigma(); +// private ArrayList myEdgeIds = new ArrayList(); //the list of our edge-ids need to be avoided. +// IntSet myEdgeIds = new GHIntHashSet(); +// public ArrayList getMyEdgeIds(){ +// return myEdgeIds; +// } +// public void setMyEdgeIds(ArrayList myEdgeIds) { +// this.myEdgeIds = myEdgeIds;} + + public DataUpdaterSigmaTest(Lock writeLock) { + this.writeLock = writeLock; + } + // when using only RoadEntry + public void feedEntry(RoadEntrySigmaTest data) { + writeLock.lock(); + try { + lockedFeedEntry((List) data); + } finally { + writeLock.unlock(); + } + } + + public void lockedFeedEntry(List data) { + currentRoads.setMyAvoidedEdges(data); + logger.info(String.format("currentroads: %s", currentRoads)); + Graph graph = hopper.getGraphHopperStorage(); + + FlagEncoder carEncoder = hopper.getEncodingManager().getEncoder("car_exp"); + + int errors = 0; + int updates = 0; + + // change speed for each edge on the graph. + List myIds = currentRoads.getMyAvoidedEdges(); + for(int i=0 ; i< myIds.size(); ++i) { + int edgeId = myIds.get(i); + EdgeIteratorState edge = graph.getEdgeIteratorState(edgeId, Integer.MIN_VALUE); + // FlagEncoder does not have 'getSpeed' and 'setSpeed' method anymore.. AbstractFlagEncoder has these methods. + // probably need to use AbstractFlagEncoder + double oldSpeed = carEncoder.getSpeed(edge.getFlags()); +// double oldSpeed = carEncoder.getMaxSpeed(); + double newValue = oldSpeed * 0.5; + edge.setFlags(carEncoder.setSpeed(edge.getFlags(), newValue)); + logger.info(("Speed change at ") + edgeId + (" Old: ") + oldSpeed + (", new:")); + } + + } + } diff --git a/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/MyImport_dataUpdater.java b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/MyImport_dataUpdater.java new file mode 100644 index 000000000..1b6bb5425 --- /dev/null +++ b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/MyImport_dataUpdater.java @@ -0,0 +1,149 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.osmidexample; + +import com.graphhopper.GHRequest; +import com.graphhopper.GHResponse; +import com.graphhopper.routing.Path; +import com.graphhopper.routing.VirtualEdgeIteratorState; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.util.EdgeIteratorState; +import com.opencsv.CSVWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.util.*; + + +/** + * Start with the following command line settings: + * + * config=config.properties osmreader.osm=area.pbf + * + * @author Peter Karich + */ +public class MyImport_dataUpdater { +// private DataUpdaterSigmaTest updater; + + public static void main(String[] args) { + //just to log all the traversed edges + List usedEdges = new ArrayList(); + //list of edges that need to block : testing + List avoidEdges = new ArrayList(Arrays.asList(917757, 382491, 401432, 472388, 920976, 785218, + 369751,369749, 472384, 775624,762019,125371,129355,775627,474159,474437)); + + //trying to use 'feed' method to change the speed of the edges. + DataUpdaterSigmaTest updater = null; + updater.feedEntry((RoadEntrySigmaTest) avoidEdges); + + MyGraphHopper graphHopper = new MyGraphHopper(); + graphHopper.setDataReaderFile("./data/dc-baltimore_maryland.osm.pbf"); + // where to store graphhopper files? + graphHopper.setGraphHopperLocation("./data/dc-baltimore_maryland.osm-gh"); + graphHopper.setEncodingManager(EncodingManager.create("car_exp")); + graphHopper.setCHEnabled(false); + graphHopper.importOrLoad(); + + Logger logger = LoggerFactory.getLogger(MyImport_dataUpdater.class); + logger.info("avoidEdges" + avoidEdges); + + //read OD file, contains two coordinate pairs +// try (BufferedReader csvReader = new BufferedReader(new FileReader("./data/od_coords_3ways.csv"))) { + try (BufferedReader csvReader = new BufferedReader(new FileReader("./data/test1.csv"))) { + + File route_file = new File("./data/test_result2.csv"); // output file for routes + try { + // create CSVWriter object filewriter object as parameter + CSVWriter route_writer = new CSVWriter(new FileWriter(route_file)); + + // adding header to csv + String[] out_header = { "i_id", "osm_id", "count" }; + route_writer.writeNext(out_header); + + String header = csvReader.readLine(); + String row = null; + int count = 0; //shortest path count + while ((row = csvReader.readLine()) != null) { + count++; System.out.println(count); + if (count%10000 == 0) System.out.println(count); // route count -> include also in output as first attribute + + long old_osmway = -1; + + String[] data = row.split(","); + + GHResponse rsp = new GHResponse(); + List paths = graphHopper.calcPaths(new GHRequest( + Float.parseFloat(data[3]), + Float.parseFloat(data[2]), + Float.parseFloat(data[5]), + Float.parseFloat(data[4])). + setWeighting("fastest").setVehicle("car").setPathDetails(Arrays.asList("average_speed", "edge_id", "time")), rsp); + // List paths = graphHopper.calcPaths(new GHRequest(38.836515, -77.310709, 38.872872, -77.229750).setWeighting("fastest").setVehicle("car").setPathDetails(Arrays.asList("average_speed", "edge_id", "time")), rsp); + + if (!paths.isEmpty()) { + Path path0 = paths.get(0); + for (EdgeIteratorState edge : path0.calcEdges()) { + int edgeId = edge.getEdge(); + String vInfo = ""; + if (edge instanceof VirtualEdgeIteratorState) { + // first, via and last edges can be virtual + VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) edge; + edgeId = vEdge.getOriginalEdgeKey() / 2; + vInfo = "v"; + } + + usedEdges.add(edgeId); +// logger.info("edgeid: "+ edgeId); + + try { + long osm_way = graphHopper.getOSMWay(edgeId); + if (old_osmway != osm_way) { + old_osmway = osm_way; // output edgeId only if it is not the same as previous +// String[] segment = {String.valueOf(count), vInfo, String.valueOf(edgeId), String.valueOf(osm_way), data[8]}; + String[] segment = {String.valueOf(edgeId),String.valueOf(osm_way), data[8]}; + + route_writer.writeNext(segment); + } + + } catch (Exception e) { +// String[] segment = {String.valueOf(count), vInfo, String.valueOf(edgeId)}; + String[] segment = {""}; + + route_writer.writeNext(segment); + } + } + } + // do something with the data + } + logger.info(String.valueOf(usedEdges)); + // closing writer connection + route_writer.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/RoadEntrySigmaTest.java b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/RoadEntrySigmaTest.java new file mode 100644 index 000000000..2871e75cc --- /dev/null +++ b/osm-id-mapping/src/main/java/com/graphhopper/osmidexample/RoadEntrySigmaTest.java @@ -0,0 +1,33 @@ +package com.graphhopper.osmidexample; + +import java.util.List; + +/** + * + * @author Tunaggina + */ +public class RoadEntrySigmaTest { + + private List myAvoidedEdges; + + public RoadEntrySigmaTest() { + } + + public RoadEntrySigmaTest(List myAvoidedEdges) { + this.myAvoidedEdges = myAvoidedEdges; + } + + public List getMyAvoidedEdges() { + return myAvoidedEdges; + } + + public void setMyAvoidedEdges(List myAvoidedEdges) { + this.myAvoidedEdges = myAvoidedEdges; + } + + + @Override + public String toString() { + return "myAvoidedEdges:" + myAvoidedEdges; + } +} From d57a486bf4f83b46d70ab757dd5b1cf369bfa958 Mon Sep 17 00:00:00 2001 From: Subrina0013 Date: Wed, 16 Sep 2020 23:22:56 -0400 Subject: [PATCH 2/2] Updating CerExpFlagEncoder to update speed of an edge based on the traffic. --- .../routing/util/AbstractFlagEncoder.java | 3 +- .../routing/util/CarExpFlagEncoder.java | 44 +++++++++++++++++-- osm-id-mapping/config.properties | 2 +- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java index 6fa3f8745..dc8bee8ee 100644 --- a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java @@ -537,7 +537,8 @@ public final BooleanEncodedValue getAccessEnc() { * * @Deprecated */ - protected void setSpeed(boolean reverse, IntsRef edgeFlags, double speed) { + // protected void setSpeed(boolean reverse, IntsRef edgeFlags, double speed) { + public void setSpeed(boolean reverse, IntsRef edgeFlags, double speed) { if (speed < 0 || Double.isNaN(speed)) throw new IllegalArgumentException("Speed cannot be negative or NaN: " + speed + ", flags:" + BitUtil.LITTLE.toBitString(edgeFlags)); diff --git a/core/src/main/java/com/graphhopper/routing/util/CarExpFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/CarExpFlagEncoder.java index bd3e653be..50052b3c4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarExpFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarExpFlagEncoder.java @@ -51,6 +51,10 @@ public class CarExpFlagEncoder extends AbstractFlagEncoder { */ protected final Map defaultSpeedMap = new HashMap<>(); + // blockedEdgesTop10 is the list of edges of concern, blockedEdgesTop10LF key-value pair where key=osmId, value=how many cars took that edge. + public long[] blockedEdgesTop10; + public HashMap blockedEdgesTop10LF; + public CarExpFlagEncoder() { this(5, 5, 0); } @@ -102,7 +106,7 @@ public CarExpFlagEncoder(int speedBits, double speedFactor, int maxTurnCosts) { trackTypeSpeedMap.put("grade1", 20); // paved trackTypeSpeedMap.put("grade2", 15); // now unpaved - gravel mixed with ... - trackTypeSpeedMap.put("grade3", 10); // ... hard and soft materials + trackTypeSpeedMap.put("grade3", 10); // ... hard and soft materials badSurfaceSpeedMap.add("cobblestone"); badSurfaceSpeedMap.add("grass_paver"); @@ -155,6 +159,9 @@ public int getVersion() { return 2; } + public void setBlockedEdgesTop10LF(HashMap blockedEdgesTop10LF){this.blockedEdgesTop10LF = blockedEdgesTop10LF;} + public HashMap getBlockedEdgesTop10LF(){ return blockedEdgesTop10LF; } + /** * Define the place of the speedBits in the edge flags for car. */ @@ -248,6 +255,8 @@ public long handleRelationTags(long oldRelationFlags, ReaderRelation relation) { @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.Access accept, long relationFlags) { + long wayID= way.getId(); + if (accept.canSkip()) return edgeFlags; @@ -273,13 +282,42 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.A accessEnc.setBool(true, edgeFlags, true); } - } else { + if (blockedEdgesTop10LF.containsKey(wayID)) { + double edgeVal = blockedEdgesTop10LF.get(wayID); + // say for every time the edge is traversed speed is reduced by .001. for example: if an edge has 10,000 car the speed reduced by 10. + double newSpeed = speed - (edgeVal * .001); + if (newSpeed >= speed) { + setSpeed(false, edgeFlags, 0); + if (speedTwoDirections) + setSpeed(true, edgeFlags, 0); + } else { + setSpeed(false, edgeFlags, newSpeed); + if (speedTwoDirections) + setSpeed(true, edgeFlags, newSpeed); + } + } + } + else { double ferrySpeed = getFerrySpeed(way); accessEnc.setBool(false, edgeFlags, true); accessEnc.setBool(true, edgeFlags, true); setSpeed(false, edgeFlags, ferrySpeed); if (speedTwoDirections) setSpeed(true, edgeFlags, ferrySpeed); + + if (blockedEdgesTop10LF.containsKey(wayID)) { + double edgeVal = blockedEdgesTop10LF.get(wayID); + double newSpeed = ferrySpeed - (edgeVal * .001); + if (newSpeed >= ferrySpeed) { + setSpeed(false, edgeFlags, 0); + if (speedTwoDirections) + setSpeed(true, edgeFlags, 0); + } else { + setSpeed(false, edgeFlags, newSpeed); + if (speedTwoDirections) + setSpeed(true, edgeFlags, newSpeed); + } + } } for (String restriction : restrictions) { @@ -362,6 +400,6 @@ protected double applyBadSurfaceSpeed(ReaderWay way, double speed) { @Override public String toString() { - return "car"; + return "car_exp"; } } diff --git a/osm-id-mapping/config.properties b/osm-id-mapping/config.properties index cc7c7e119..c1ec1316c 100755 --- a/osm-id-mapping/config.properties +++ b/osm-id-mapping/config.properties @@ -6,7 +6,7 @@ graph.dataaccess=RAM_STORE # use contraction hierarchies to speed things up. requires more RAM/disc space for holding the graph #prepare.chWeighting=no -prepare.chWeighting=fastest +#prepare.chWeighting=fastest graph.flagEncoders=car # graph.bytesForFlags=8