Commit 1ef4ad19 authored by DaGal's avatar DaGal

Add support for a tomcat deploy in a WAR

parent fb1feab9
......@@ -17,11 +17,21 @@
*/
package com.graphhopper.routing.template;
import java.util.ArrayList;
import java.util.List;
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.PathWrapper;
import com.graphhopper.routing.*;
import com.graphhopper.routing.util.*;
import com.graphhopper.routing.AlgorithmOptions;
import com.graphhopper.routing.Path;
import com.graphhopper.routing.QueryGraph;
import com.graphhopper.routing.RoutingAlgorithm;
import com.graphhopper.routing.RoutingAlgorithmFactory;
import com.graphhopper.routing.util.DefaultEdgeFilter;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.util.NameSimilarityEdgeFilter;
import com.graphhopper.storage.index.LocationIndex;
import com.graphhopper.storage.index.QueryResult;
import com.graphhopper.util.EdgeIteratorState;
......@@ -32,132 +42,129 @@ import com.graphhopper.util.Translation;
import com.graphhopper.util.exceptions.PointNotFoundException;
import com.graphhopper.util.shapes.GHPoint;
import java.util.ArrayList;
import java.util.List;
/**
* Implementation of calculating a route with multiple via points.
*
* @author Peter Karich
*/
public class ViaRoutingTemplate extends AbstractRoutingTemplate implements RoutingTemplate {
protected final GHRequest ghRequest;
protected final GHResponse ghResponse;
protected final PathWrapper altResponse = new PathWrapper();
private final LocationIndex locationIndex;
// result from route
protected List<Path> pathList;
public ViaRoutingTemplate(GHRequest ghRequest, GHResponse ghRsp, LocationIndex locationIndex) {
this.locationIndex = locationIndex;
this.ghRequest = ghRequest;
this.ghResponse = ghRsp;
}
@Override
public List<QueryResult> lookup(List<GHPoint> points, FlagEncoder encoder) {
if (points.size() < 2)
throw new IllegalArgumentException("At least 2 points have to be specified, but was:" + points.size());
EdgeFilter edgeFilter = new DefaultEdgeFilter(encoder);
queryResults = new ArrayList<>(points.size());
for (int placeIndex = 0; placeIndex < points.size(); placeIndex++) {
GHPoint point = points.get(placeIndex);
QueryResult res;
if (ghRequest.hasPointHints()) {
res = locationIndex.findClosest(point.lat, point.lon, new NameSimilarityEdgeFilter(edgeFilter, ghRequest.getPointHints().get(placeIndex)));
if (!res.isValid()) {
res = locationIndex.findClosest(point.lat, point.lon, edgeFilter);
}
} else {
res = locationIndex.findClosest(point.lat, point.lon, edgeFilter);
}
if (!res.isValid())
ghResponse.addError(new PointNotFoundException("Cannot find point " + placeIndex + ": " + point, placeIndex));
queryResults.add(res);
}
return queryResults;
}
@Override
public List<Path> calcPaths(QueryGraph queryGraph, RoutingAlgorithmFactory algoFactory, AlgorithmOptions algoOpts) {
long visitedNodesSum = 0L;
boolean viaTurnPenalty = ghRequest.getHints().getBool(Routing.PASS_THROUGH, false);
int pointCounts = ghRequest.getPoints().size();
pathList = new ArrayList<>(pointCounts - 1);
QueryResult fromQResult = queryResults.get(0);
StopWatch sw;
for (int placeIndex = 1; placeIndex < pointCounts; placeIndex++) {
if (placeIndex == 1) {
// enforce start direction
queryGraph.enforceHeading(fromQResult.getClosestNode(), ghRequest.getFavoredHeading(0), false);
} else if (viaTurnPenalty) {
// enforce straight start after via stop
Path prevRoute = pathList.get(placeIndex - 2);
if (prevRoute.getEdgeCount() > 0) {
EdgeIteratorState incomingVirtualEdge = prevRoute.getFinalEdge();
queryGraph.unfavorVirtualEdgePair(fromQResult.getClosestNode(), incomingVirtualEdge.getEdge());
}
}
QueryResult toQResult = queryResults.get(placeIndex);
// enforce end direction
queryGraph.enforceHeading(toQResult.getClosestNode(), ghRequest.getFavoredHeading(placeIndex), true);
sw = new StopWatch().start();
RoutingAlgorithm algo = algoFactory.createAlgo(queryGraph, algoOpts);
String debug = ", algoInit:" + sw.stop().getSeconds() + "s";
sw = new StopWatch().start();
List<Path> tmpPathList = algo.calcPaths(fromQResult.getClosestNode(), toQResult.getClosestNode());
debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s";
if (tmpPathList.isEmpty())
throw new IllegalStateException("At least one path has to be returned for " + fromQResult + " -> " + toQResult);
int idx = 0;
for (Path path : tmpPathList) {
if (path.getTime() < 0)
throw new RuntimeException("Time was negative " + path.getTime() + " for index " + idx + ". Please report as bug and include:" + ghRequest);
pathList.add(path);
debug += ", " + path.getDebugInfo();
idx++;
}
altResponse.addDebugInfo(debug);
// reset all direction enforcements in queryGraph to avoid influencing next path
queryGraph.clearUnfavoredStatus();
if (algo.getVisitedNodes() >= algoOpts.getMaxVisitedNodes())
throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
visitedNodesSum += algo.getVisitedNodes();
fromQResult = toQResult;
}
ghResponse.getHints().put("visited_nodes.sum", visitedNodesSum);
ghResponse.getHints().put("visited_nodes.average", (float) visitedNodesSum / (pointCounts - 1));
return pathList;
}
@Override
public boolean isReady(PathMerger pathMerger, Translation tr) {
if (ghRequest.getPoints().size() - 1 != pathList.size())
throw new RuntimeException("There should be exactly one more points than paths. points:" + ghRequest.getPoints().size() + ", paths:" + pathList.size());
altResponse.setWaypoints(getWaypoints());
ghResponse.add(altResponse);
pathMerger.doWork(altResponse, pathList, tr);
return true;
}
@Override
public int getMaxRetries() {
return 1;
}
protected final GHRequest ghRequest;
protected final GHResponse ghResponse;
protected final PathWrapper altResponse = new PathWrapper();
private final LocationIndex locationIndex;
// result from route
protected List<Path> pathList;
public ViaRoutingTemplate(GHRequest ghRequest, GHResponse ghRsp, LocationIndex locationIndex) {
this.locationIndex = locationIndex;
this.ghRequest = ghRequest;
this.ghResponse = ghRsp;
}
@Override
public List<QueryResult> lookup(List<GHPoint> points, FlagEncoder encoder) {
if (points.size() < 2)
throw new IllegalArgumentException("At least 2 points have to be specified, but was:" + points.size());
EdgeFilter edgeFilter = new DefaultEdgeFilter(encoder);
queryResults = new ArrayList<>(points.size());
for (int placeIndex = 0; placeIndex < points.size(); placeIndex++) {
GHPoint point = points.get(placeIndex);
QueryResult res;
if (ghRequest.hasPointHints()) {
res = locationIndex.findClosest(point.lat, point.lon, new NameSimilarityEdgeFilter(edgeFilter, ghRequest.getPointHints().get(placeIndex)));
if (!res.isValid()) {
res = locationIndex.findClosest(point.lat, point.lon, edgeFilter);
}
} else {
res = locationIndex.findClosest(point.lat, point.lon, edgeFilter);
}
if (!res.isValid())
ghResponse.addError(new PointNotFoundException("Cannot find point " + placeIndex + ": " + point, placeIndex));
queryResults.add(res);
}
return queryResults;
}
@Override
public List<Path> calcPaths(QueryGraph queryGraph, RoutingAlgorithmFactory algoFactory, AlgorithmOptions algoOpts) {
long visitedNodesSum = 0L;
boolean viaTurnPenalty = ghRequest.getHints().getBool(Routing.PASS_THROUGH, false);
int pointCounts = ghRequest.getPoints().size();
pathList = new ArrayList<>(pointCounts - 1);
QueryResult fromQResult = queryResults.get(0);
StopWatch sw;
for (int placeIndex = 1; placeIndex < pointCounts; placeIndex++) {
if (placeIndex == 1) {
// enforce start direction
queryGraph.enforceHeading(fromQResult.getClosestNode(), ghRequest.getFavoredHeading(0), false);
} else if (viaTurnPenalty) {
// enforce straight start after via stop
Path prevRoute = pathList.get(placeIndex - 2);
if (prevRoute.getEdgeCount() > 0) {
EdgeIteratorState incomingVirtualEdge = prevRoute.getFinalEdge();
queryGraph.unfavorVirtualEdgePair(fromQResult.getClosestNode(), incomingVirtualEdge.getEdge());
}
}
QueryResult toQResult = queryResults.get(placeIndex);
// enforce end direction
queryGraph.enforceHeading(toQResult.getClosestNode(), ghRequest.getFavoredHeading(placeIndex), true);
sw = new StopWatch().start();
RoutingAlgorithm algo = algoFactory.createAlgo(queryGraph, algoOpts);
String debug = ", algoInit:" + sw.stop().getSeconds() + "s";
sw = new StopWatch().start();
List<Path> tmpPathList = algo.calcPaths(fromQResult.getClosestNode(), toQResult.getClosestNode());
debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s";
if (tmpPathList.isEmpty())
throw new IllegalStateException("At least one path has to be returned for " + fromQResult + " -> " + toQResult);
int idx = 0;
for (Path path : tmpPathList) {
if (path.getTime() < 0)
throw new RuntimeException("Time was negative " + path.getTime() + " for index " + idx + ". Please report as bug and include:" + ghRequest);
pathList.add(path);
debug += ", " + path.getDebugInfo();
idx++;
}
altResponse.addDebugInfo(debug);
// reset all direction enforcements in queryGraph to avoid influencing next path
queryGraph.clearUnfavoredStatus();
if (algo.getVisitedNodes() >= algoOpts.getMaxVisitedNodes())
throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
visitedNodesSum += algo.getVisitedNodes();
fromQResult = toQResult;
}
ghResponse.getHints().put("visited_nodes.sum", visitedNodesSum);
ghResponse.getHints().put("visited_nodes.average", (float) visitedNodesSum / (pointCounts - 1));
return pathList;
}
@Override
public boolean isReady(PathMerger pathMerger, Translation tr) {
if (ghRequest.getPoints().size() - 1 != pathList.size())
throw new RuntimeException("There should be exactly one more points than paths. points:" + ghRequest.getPoints().size() + ", paths:" + pathList.size());
altResponse.setWaypoints(getWaypoints());
ghResponse.add(altResponse);
pathMerger.doWork(altResponse, pathList, tr);
return true;
}
@Override
public int getMaxRetries() {
return 1;
}
}
......@@ -26,6 +26,9 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Stores command line options in a map. The capitalization of the key is ignored.
* <p>
......@@ -33,97 +36,98 @@ import java.util.Properties;
* @author Peter Karich
*/
public class CmdArgs extends PMap {
private static final Logger logger = LoggerFactory.getLogger(CmdArgs.class);
public CmdArgs() {
}
public CmdArgs(Map<String, String> map) {
super(map);
}
/**
* @param fileStr the file name of config.properties
* @param systemProperty the property name of the configuration. E.g. -Dgraphhopper.config
*/
public static CmdArgs readFromConfig(String fileStr, String systemProperty) throws IOException {
if (systemProperty.startsWith("-D"))
systemProperty = systemProperty.substring(2);
String configLocation = System.getProperty(systemProperty);
if (Helper.isEmpty(configLocation))
configLocation = fileStr;
Map<String, String> map = new LinkedHashMap<String, String>();
Helper.loadProperties(map, new InputStreamReader(new FileInputStream(
new File(configLocation).getAbsoluteFile()), Helper.UTF_CS));
CmdArgs args = new CmdArgs();
args.merge(map);
// overwrite with system settings
Properties props = System.getProperties();
for (Entry<Object, Object> e : props.entrySet()) {
String k = ((String) e.getKey());
String v = ((String) e.getValue());
if (k.startsWith("graphhopper.")) {
k = k.substring("graphhopper.".length());
args.put(k, v);
}
}
return args;
}
/**
* This method creates a CmdArgs object from the specified string array (a list of key=value pairs).
*/
public static CmdArgs read(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
for (String arg : args) {
int index = arg.indexOf("=");
if (index <= 0) {
continue;
}
String key = arg.substring(0, index);
if (key.startsWith("-")) {
key = key.substring(1);
}
if (key.startsWith("-")) {
key = key.substring(1);
}
String value = arg.substring(index + 1);
String old = map.put(key.toLowerCase(), value);
if (old != null)
throw new IllegalArgumentException("Pair '" + key.toLowerCase() + "'='" + value + "' not possible to " +
"add to the CmdArgs-object as the key already exists with '" + old + "'");
}
return new CmdArgs(map);
}
/**
* Command line configuration overwrites the ones in the config file.
*
* @return a new CmdArgs object if necessary.
*/
public static CmdArgs readFromConfigAndMerge(CmdArgs args, String configKey, String configSysAttr) {
String configVal = args.get(configKey, "../conf/graphhopper.config");
if (!Helper.isEmpty(configVal)) {
try {
CmdArgs tmp = CmdArgs.readFromConfig(configVal, configSysAttr);
tmp.merge(args);
return tmp;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
return args;
}
public CmdArgs() {
}
public CmdArgs(Map<String, String> map) {
super(map);
}
/**
* @param fileStr the file name of config.properties
* @param systemProperty the property name of the configuration. E.g. -Dgraphhopper.config
*/
public static CmdArgs readFromConfig(String fileStr, String systemProperty) throws IOException {
if (systemProperty.startsWith("-D"))
systemProperty = systemProperty.substring(2);
String configLocation = System.getProperty(systemProperty);
if (Helper.isEmpty(configLocation))
configLocation = fileStr;
Map<String, String> map = new LinkedHashMap<String, String>();
Helper.loadProperties(map, new InputStreamReader(new FileInputStream(
new File(configLocation).getAbsoluteFile()), Helper.UTF_CS));
CmdArgs args = new CmdArgs();
args.merge(map);
// overwrite with system settings
Properties props = System.getProperties();
for (Entry<Object, Object> e : props.entrySet()) {
String k = ((String) e.getKey());
String v = ((String) e.getValue());
if (k.startsWith("graphhopper.")) {
k = k.substring("graphhopper.".length());
args.put(k, v);
}
}
return args;
}
/**
* This method creates a CmdArgs object from the specified string array (a list of key=value pairs).
*/
public static CmdArgs read(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
for (String arg : args) {
int index = arg.indexOf("=");
if (index <= 0) {
continue;
}
String key = arg.substring(0, index);
if (key.startsWith("-")) {
key = key.substring(1);
}
if (key.startsWith("-")) {
key = key.substring(1);
}
String value = arg.substring(index + 1);
String old = map.put(key.toLowerCase(), value);
if (old != null)
throw new IllegalArgumentException("Pair '" + key.toLowerCase() + "'='" + value + "' not possible to " +
"add to the CmdArgs-object as the key already exists with '" + old + "'");
}
return new CmdArgs(map);
}
/**
* Command line configuration overwrites the ones in the config file.
*
* @return a new CmdArgs object if necessary.
*/
public static CmdArgs readFromConfigAndMerge(CmdArgs args, String configKey, String configSysAttr) {
String configVal = args.get(configKey, "");
if (!Helper.isEmpty(configVal)) {
try {
CmdArgs tmp = CmdArgs.readFromConfig(configVal, configSysAttr);
tmp.merge(args);
return tmp;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
return args;
}
@Override
public CmdArgs put(String key, Object str) {
super.put(key, str);
return this;
}
@Override
public CmdArgs put(String key, Object str) {
super.put(key, str);
return this;
}
}
#!/bin/bash
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required for handling Windows cr/lf
(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required for handling Windows cr/lf
# See StackOverflow answer http://stackoverflow.com/a/14607651
GH_CLASS=com.graphhopper.tools.Import
......@@ -43,11 +43,11 @@ function printUsage {
}
if [ "$ACTION" = "" ]; then
echo "## action $ACTION not found. try"
echo "## action $ACTION not found. try"
printUsage
fi
function ensureOsm {
function ensureOsm {
if [ "$OSM_FILE" = "" ]; then
# skip
return
......@@ -55,21 +55,21 @@ function ensureOsm {
echo "File not found '$OSM_FILE'. Press ENTER to get it from: $LINK"
echo "Press CTRL+C if you do not have enough disc space or you don't want to download several MB."
read -e
echo "## now downloading OSM file from $LINK and extracting to $OSM_FILE"
if [ ${OSM_FILE: -4} == ".pbf" ]; then
wget -S -nv -O "$OSM_FILE" "$LINK"
elif [ ${OSM_FILE: -4} == ".ghz" ]; then
wget -S -nv -O "$OSM_FILE" "$LINK"
cd $DATADIR && unzip "$BASENAME" -d "$NAME-gh"
else
else
# make sure aborting download does not result in loading corrupt osm file
TMP_OSM=temp.osm
wget -S -nv -O - "$LINK" | bzip2 -d > $TMP_OSM
mv $TMP_OSM "$OSM_FILE"
fi
if [[ ! -s "$OSM_FILE" ]]; then
echo "ERROR couldn't download or extract OSM file $OSM_FILE ... exiting"
exit
......@@ -135,8 +135,8 @@ elif [ "$ACTION" = "eclipse" ]; then
elif [ "$ACTION" = "build" ]; then
packageCoreJar
exit
exit
elif [ "$ACTION" = "buildweb" ]; then
execMvn --projects web -am -DskipTests=true package
exit
......@@ -147,7 +147,7 @@ elif [ "$ACTION" = "extract" ]; then
#echo "$URL"
wget -O extract.osm "$URL"
exit
elif [ "$ACTION" = "android" ]; then
execMvn -P include-android --projects android/app -am package android:deploy android:run
exit
......@@ -194,10 +194,10 @@ JAR=tools/target/graphhopper-tools-$VERSION-jar-with-dependencies.jar
LINK=$(echo $NAME | tr '_' '/')
if [ "$FILE" == "-" ]; then
LINK=
elif [ ${FILE: -4} == ".osm" ]; then
elif [ ${FILE: -4} == ".osm" ]; then
LINK="http://download.geofabrik.de/$LINK-latest.osm.bz2"
elif [ ${FILE: -4} == ".ghz" ]; then
LINK="http://graphhopper.com/public/maps/0.1/$FILE"
LINK="http://graphhopper.com/public/maps/0.1/$FILE"
elif [ ${FILE: -4} == ".pbf" ]; then
LINK="http://download.geofabrik.de/$LINK-latest.osm.pbf"
else
......@@ -206,7 +206,7 @@ else
fi
if [ "$JAVA_OPTS" = "" ]; then
JAVA_OPTS="-Xmx1000m -Xms1000m -server"
JAVA_OPTS="-Xmx2000m -Xms2000m -server"
fi
ensureOsm
......@@ -216,7 +216,7 @@ echo "## now $ACTION. JAVA_OPTS=$JAVA_OPTS"
if [ "$ACTION" = "ui" ] || [ "$ACTION" = "web" ]; then
export MAVEN_OPTS="$MAVEN_OPTS $JAVA_OPTS"
if [ "$JETTY_PORT" = "" ]; then
if [ "$JETTY_PORT" = "" ]; then
JETTY_PORT=8989
fi
WEB_JAR="$GH_HOME/web/target/graphhopper-web-$VERSION-with-dep.jar"
......@@ -238,7 +238,7 @@ if [ "$ACTION" = "ui" ] || [ "$ACTION" = "web" ]; then
if [ "$GH_PID_FILE" != "" ]; then
echo $! > $GH_PID_FILE
fi
exit $?
exit $?
fi